Mailing List Archive

Fix gnttab_release_mappings -- it doesn't need to drop
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID b3edbeea3e797b7e56d13ab7ae126fbcd1fb6a70
# Parent 48eb10d7a2d608351023b14e45a9ddb7f99cab8a
Fix gnttab_release_mappings -- it doesn't need to drop
page refcnts for host mappings as they are already
destroyed by put_page_from_l1e(). Also call
gnttab_release_mappings later (after destroying
page-table references) and from common code rather than
arch/x86.

Also a few other misc gnttab cleanups.

Signed-off-by: Keir Fraser <keir@xensource.com>

diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Wed Dec 21 17:25:34 2005
+++ b/xen/arch/x86/domain.c Wed Dec 21 17:45:43 2005
@@ -957,8 +957,6 @@

ptwr_destroy(d);

- gnttab_release_mappings(d);
-
/* Drop the in-use references to page-table bases. */
for_each_vcpu ( d, v )
{
diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Wed Dec 21 17:25:34 2005
+++ b/xen/arch/x86/setup.c Wed Dec 21 17:45:43 2005
@@ -488,8 +488,6 @@

start_of_day();

- grant_table_init();
-
shadow_mode_init();

/* initialize access control security module */
diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/common/domain.c
--- a/xen/common/domain.c Wed Dec 21 17:25:34 2005
+++ b/xen/common/domain.c Wed Dec 21 17:45:43 2005
@@ -118,6 +118,7 @@
for_each_vcpu(d, v)
sched_rem_domain(v);
domain_relinquish_resources(d);
+ gnttab_release_mappings(d);
put_domain(d);

send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/common/grant_table.c
--- a/xen/common/grant_table.c Wed Dec 21 17:25:34 2005
+++ b/xen/common/grant_table.c Wed Dec 21 17:45:43 2005
@@ -611,6 +611,91 @@
spin_unlock(&gt->lock);

put_domain(d);
+ return 0;
+}
+
+/*
+ * Check that the given grant reference (rd,ref) allows 'ld' to transfer
+ * ownership of a page frame. If so, lock down the grant entry.
+ */
+static int
+gnttab_prepare_for_transfer(
+ struct domain *rd, struct domain *ld, grant_ref_t ref)
+{
+ grant_table_t *rgt;
+ grant_entry_t *sha;
+ domid_t sdom;
+ u16 sflags;
+ u32 scombo, prev_scombo;
+ int retries = 0;
+ unsigned long target_pfn;
+
+ if ( unlikely((rgt = rd->grant_table) == NULL) ||
+ unlikely(ref >= NR_GRANT_ENTRIES) )
+ {
+ DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
+ rd->domain_id, ref);
+ return 0;
+ }
+
+ spin_lock(&rgt->lock);
+
+ sha = &rgt->shared[ref];
+
+ sflags = sha->flags;
+ sdom = sha->domid;
+
+ for ( ; ; )
+ {
+ target_pfn = sha->frame;
+
+ if ( unlikely(target_pfn >= max_page ) )
+ {
+ DPRINTK("Bad pfn (%lx)\n", target_pfn);
+ goto fail;
+ }
+
+ if ( unlikely(sflags != GTF_accept_transfer) ||
+ unlikely(sdom != ld->domain_id) )
+ {
+ DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
+ sflags, sdom, ld->domain_id);
+ goto fail;
+ }
+
+ /* Merge two 16-bit values into a 32-bit combined update. */
+ /* NB. Endianness! */
+ prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
+
+ /* NB. prev_scombo is updated in place to seen value. */
+ if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo,
+ prev_scombo | GTF_transfer_committed)) )
+ {
+ DPRINTK("Fault while modifying shared flags and domid.\n");
+ goto fail;
+ }
+
+ /* Did the combined update work (did we see what we expected?). */
+ if ( likely(prev_scombo == scombo) )
+ break;
+
+ if ( retries++ == 4 )
+ {
+ DPRINTK("Shared grant entry is unstable.\n");
+ goto fail;
+ }
+
+ /* Didn't see what we expected. Split out the seen flags & dom. */
+ /* NB. Endianness! */
+ sflags = (u16)prev_scombo;
+ sdom = (u16)(prev_scombo >> 16);
+ }
+
+ spin_unlock(&rgt->lock);
+ return 1;
+
+ fail:
+ spin_unlock(&rgt->lock);
return 0;
}

@@ -763,87 +848,6 @@
}

int
-gnttab_prepare_for_transfer(
- struct domain *rd, struct domain *ld, grant_ref_t ref)
-{
- grant_table_t *rgt;
- grant_entry_t *sha;
- domid_t sdom;
- u16 sflags;
- u32 scombo, prev_scombo;
- int retries = 0;
- unsigned long target_pfn;
-
- if ( unlikely((rgt = rd->grant_table) == NULL) ||
- unlikely(ref >= NR_GRANT_ENTRIES) )
- {
- DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
- rd->domain_id, ref);
- return 0;
- }
-
- spin_lock(&rgt->lock);
-
- sha = &rgt->shared[ref];
-
- sflags = sha->flags;
- sdom = sha->domid;
-
- for ( ; ; )
- {
- target_pfn = sha->frame;
-
- if ( unlikely(target_pfn >= max_page ) )
- {
- DPRINTK("Bad pfn (%lx)\n", target_pfn);
- goto fail;
- }
-
- if ( unlikely(sflags != GTF_accept_transfer) ||
- unlikely(sdom != ld->domain_id) )
- {
- DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
- sflags, sdom, ld->domain_id);
- goto fail;
- }
-
- /* Merge two 16-bit values into a 32-bit combined update. */
- /* NB. Endianness! */
- prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
-
- /* NB. prev_scombo is updated in place to seen value. */
- if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo,
- prev_scombo | GTF_transfer_committed)) )
- {
- DPRINTK("Fault while modifying shared flags and domid.\n");
- goto fail;
- }
-
- /* Did the combined update work (did we see what we expected?). */
- if ( likely(prev_scombo == scombo) )
- break;
-
- if ( retries++ == 4 )
- {
- DPRINTK("Shared grant entry is unstable.\n");
- goto fail;
- }
-
- /* Didn't see what we expected. Split out the seen flags & dom. */
- /* NB. Endianness! */
- sflags = (u16)prev_scombo;
- sdom = (u16)(prev_scombo >> 16);
- }
-
- spin_unlock(&rgt->lock);
- return 1;
-
- fail:
- spin_unlock(&rgt->lock);
- return 0;
-}
-
-int
grant_table_create(
struct domain *d)
{
@@ -943,7 +947,8 @@
{
BUG_ON(!(act->pin & GNTPIN_hstr_mask));
act->pin -= GNTPIN_hstr_inc;
- put_page(pfn_to_page(act->frame));
+ /* Done implicitly when page tables are destroyed. */
+ /* put_page(pfn_to_page(act->frame)); */
}
}
else
@@ -959,7 +964,8 @@
{
BUG_ON(!(act->pin & GNTPIN_hstw_mask));
act->pin -= GNTPIN_hstw_inc;
- put_page_and_type(pfn_to_page(act->frame));
+ /* Done implicitly when page tables are destroyed. */
+ /* put_page_and_type(pfn_to_page(act->frame)); */
}

if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
@@ -982,24 +988,17 @@
grant_table_destroy(
struct domain *d)
{
- grant_table_t *t;
-
- if ( (t = d->grant_table) != NULL )
- {
- /* Free memory relating to this grant table. */
- d->grant_table = NULL;
- free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
- free_xenheap_page(t->maptrack);
- xfree(t->active);
- xfree(t);
- }
-}
-
-void
-grant_table_init(
- void)
-{
- /* Nothing. */
+ grant_table_t *t = d->grant_table;
+
+ if ( t == NULL )
+ return;
+
+ free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
+ free_xenheap_page(t->maptrack);
+ xfree(t->active);
+ xfree(t);
+
+ d->grant_table = NULL;
}

/*
diff -r 48eb10d7a2d6 -r b3edbeea3e79 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h Wed Dec 21 17:25:34 2005
+++ b/xen/include/xen/grant_table.h Wed Dec 21 17:45:43 2005
@@ -84,23 +84,11 @@
spinlock_t lock;
} grant_table_t;

-/* Start-of-day system initialisation. */
-void grant_table_init(
- void);
-
/* Create/destroy per-domain grant table context. */
int grant_table_create(
struct domain *d);
void grant_table_destroy(
struct domain *d);
-
-/*
- * Check that the given grant reference (rd,ref) allows 'ld' to transfer
- * ownership of a page frame. If so, lock down the grant entry.
- */
-int
-gnttab_prepare_for_transfer(
- struct domain *rd, struct domain *ld, grant_ref_t ref);

/* Domain death release of granted mappings of other domains' memory. */
void

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog