Mailing List Archive

Merge with xen-ia64-unstable.hg.
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID 9b108cf447e5801d2f07fa12754b4b68387bc0b9
# Parent 5a790011259e7ab8e50c53acc79dc006e7305298
# Parent a4de51a2629f10bb12b2cea7dc4d2d5747e6ca78
Merge with xen-ia64-unstable.hg.

diff -r 5a790011259e -r 9b108cf447e5 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Wed Dec 21 17:56:19 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Wed Dec 21 18:52:00 2005
@@ -27,6 +27,12 @@
* IN THE SOFTWARE.
*/

+#include <asm-xen/evtchn.h>
+#include <asm-xen/gnttab.h>
+#include <asm-xen/xenbus.h>
+
+/* xenbus_probe.c */
+extern char *kasprintf(const char *fmt, ...);

#if 0
#define DPRINTK(fmt, args...) \
@@ -36,11 +42,6 @@
#endif


-#include <asm-xen/evtchn.h>
-#include <asm-xen/gnttab.h>
-#include <asm-xen/xenbus.h>
-
-
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
struct xenbus_watch *watch,
void (*callback)(struct xenbus_watch *,
@@ -70,16 +71,11 @@
const char **, unsigned int))
{
int err;
- char *state =
- kmalloc(strlen(path) + 1 + strlen(path2) + 1, GFP_KERNEL);
+ char *state = kasprintf("%s/%s", path, path2);
if (!state) {
xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
return -ENOMEM;
}
- strcpy(state, path);
- strcat(state, "/");
- strcat(state, path2);
-
err = xenbus_watch_path(dev, state, watch, callback);

if (err) {
@@ -126,16 +122,7 @@
*/
static char *error_path(struct xenbus_device *dev)
{
- char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
- 1, GFP_KERNEL);
- if (path_buffer == NULL) {
- return NULL;
- }
-
- strcpy(path_buffer, "error/");
- strcpy(path_buffer + strlen("error/"), dev->nodename);
-
- return path_buffer;
+ return kasprintf("error/%s", dev->nodename);
}


diff -r 5a790011259e -r 9b108cf447e5 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Dec 21 17:56:19 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Wed Dec 21 18:52:00 2005
@@ -505,7 +505,7 @@
}

/* Simplified asprintf. */
-static char *kasprintf(const char *fmt, ...)
+char *kasprintf(const char *fmt, ...)
{
va_list ap;
unsigned int len;
diff -r 5a790011259e -r 9b108cf447e5 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Dec 21 17:56:19 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Wed Dec 21 18:52:00 2005
@@ -41,6 +41,9 @@
#include <asm-xen/xenbus.h>
#include "xenbus_comms.h"

+/* xenbus_probe.c */
+extern char *kasprintf(const char *fmt, ...);
+
#define streq(a, b) (strcmp((a), (b)) == 0)

struct xs_stored_msg {
@@ -276,18 +279,11 @@
{
char *buffer;

- buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1,
- GFP_KERNEL);
- if (buffer == NULL)
- return ERR_PTR(-ENOMEM);
-
- strcpy(buffer, dir);
- if (!streq(name, "")) {
- strcat(buffer, "/");
- strcat(buffer, name);
- }
-
- return buffer;
+ if (strlen(name) == 0)
+ buffer = kasprintf("%s", dir);
+ else
+ buffer = kasprintf("%s/%s", dir, name);
+ return (!buffer) ? ERR_PTR(-ENOMEM) : buffer;
}

static char **split(char *strings, unsigned int len, unsigned int *num)
diff -r 5a790011259e -r 9b108cf447e5 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Wed Dec 21 17:56:19 2005
+++ b/xen/arch/x86/domain.c Wed Dec 21 18:52:00 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 5a790011259e -r 9b108cf447e5 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Dec 21 17:56:19 2005
+++ b/xen/arch/x86/mm.c Wed Dec 21 18:52:00 2005
@@ -1930,105 +1930,6 @@
}
break;
}
-
- case MMUEXT_REASSIGN_PAGE:
- if ( unlikely(!IS_PRIV(d)) )
- {
- MEM_LOG("Dom %u has no reassignment priv", d->domain_id);
- okay = 0;
- break;
- }
-
- e = percpu_info[cpu].foreign;
- if ( unlikely(e == NULL) )
- {
- MEM_LOG("No FOREIGNDOM to reassign mfn %lx to", mfn);
- okay = 0;
- break;
- }
-
- /*
- * Grab both page_list locks, in order. This prevents the page from
- * disappearing elsewhere while we modify the owner, and we'll need
- * both locks if we're successful so that we can change lists.
- */
- if ( d < e )
- {
- spin_lock(&d->page_alloc_lock);
- spin_lock(&e->page_alloc_lock);
- }
- else
- {
- spin_lock(&e->page_alloc_lock);
- spin_lock(&d->page_alloc_lock);
- }
-
- /*
- * Check that 'e' will accept the page and has reservation
- * headroom. Also, a domain mustn't have PGC_allocated pages when
- * it is dying.
- */
- ASSERT(e->tot_pages <= e->max_pages);
- if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) ||
- unlikely(e->tot_pages == e->max_pages) ||
- unlikely(IS_XEN_HEAP_FRAME(page)) )
- {
- MEM_LOG("Transferee has no reservation headroom (%d,%d), or "
- "page is in Xen heap (%lx), or dom is dying (%ld).",
- e->tot_pages, e->max_pages, mfn, e->domain_flags);
- okay = 0;
- goto reassign_fail;
- }
-
- /*
- * The tricky bit: atomically change owner while there is just one
- * benign reference to the page (PGC_allocated). If that reference
- * disappears then the deallocation routine will safely spin.
- */
- _d = pickle_domptr(d);
- _nd = page->u.inuse._domain;
- y = page->count_info;
- do {
- x = y;
- if ( unlikely((x & (PGC_count_mask|PGC_allocated)) !=
- (1|PGC_allocated)) ||
- unlikely(_nd != _d) )
- {
- MEM_LOG("Bad page values %lx: ed=%p(%u), sd=%p,"
- " caf=%08x, taf=%" PRtype_info,
- page_to_pfn(page), d, d->domain_id,
- unpickle_domptr(_nd), x, page->u.inuse.type_info);
- okay = 0;
- goto reassign_fail;
- }
- __asm__ __volatile__(
- LOCK_PREFIX "cmpxchg8b %3"
- : "=d" (_nd), "=a" (y), "=c" (e),
- "=m" (*(volatile u64 *)(&page->count_info))
- : "0" (_d), "1" (x), "c" (e), "b" (x) );
- }
- while ( unlikely(_nd != _d) || unlikely(y != x) );
-
- /*
- * Unlink from 'd'. We transferred at least one reference to 'e',
- * so noone else is spinning to try to delete this page from 'd'.
- */
- d->tot_pages--;
- list_del(&page->list);
-
- /*
- * Add the page to 'e'. Someone may already have removed the last
- * reference and want to remove the page from 'e'. However, we have
- * the lock so they'll spin waiting for us.
- */
- if ( unlikely(e->tot_pages++ == 0) )
- get_knownalive_domain(e);
- list_add_tail(&page->list, &e->page_list);
-
- reassign_fail:
- spin_unlock(&d->page_alloc_lock);
- spin_unlock(&e->page_alloc_lock);
- break;

default:
MEM_LOG("Invalid extended pt command 0x%x", op.cmd);
diff -r 5a790011259e -r 9b108cf447e5 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Wed Dec 21 17:56:19 2005
+++ b/xen/arch/x86/setup.c Wed Dec 21 18:52:00 2005
@@ -488,8 +488,6 @@

start_of_day();

- grant_table_init();
-
shadow_mode_init();

/* initialize access control security module */
diff -r 5a790011259e -r 9b108cf447e5 xen/common/domain.c
--- a/xen/common/domain.c Wed Dec 21 17:56:19 2005
+++ b/xen/common/domain.c Wed Dec 21 18:52:00 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 5a790011259e -r 9b108cf447e5 xen/common/grant_table.c
--- a/xen/common/grant_table.c Wed Dec 21 17:56:19 2005
+++ b/xen/common/grant_table.c Wed Dec 21 18:52:00 2005
@@ -177,17 +177,19 @@

spin_lock(&rd->grant_table->lock);

- if ( act->pin == 0 )
- {
- /* CASE 1: Activating a previously inactive entry. */
-
+ if ( !act->pin ||
+ (!(dev_hst_ro_flags & GNTMAP_readonly) &&
+ !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
+ {
sflags = sha->flags;
sdom = sha->domid;

- /* This loop attempts to set the access (reading/writing) flags
+ /*
+ * This loop attempts to set the access (reading/writing) flags
* in the grant table entry. It tries a cmpxchg on the field
* up to five times, and then fails under the assumption that
- * the guest is misbehaving. */
+ * the guest is misbehaving.
+ */
for ( ; ; )
{
u32 scombo, prev_scombo, new_scombo;
@@ -196,7 +198,7 @@
unlikely(sdom != led->domain->domain_id) )
PIN_FAIL(unlock_out, GNTST_general_error,
"Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
- sflags, sdom, led->domain->domain_id);
+ sflags, sdom, led->domain->domain_id);

/* Merge two 16-bit values into a 32-bit combined update. */
/* NB. Endianness! */
@@ -232,132 +234,50 @@
sdom = (u16)(prev_scombo >> 16);
}

- /* rmb(); */ /* not on x86 */
-
- frame = __gpfn_to_mfn(rd, sha->frame);
-
- if ( unlikely(!pfn_valid(frame)) ||
- unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
- get_page(pfn_to_page(frame), rd) :
- get_page_and_type(pfn_to_page(frame), rd,
- PGT_writable_page))) )
- {
- clear_bit(_GTF_writing, &sha->flags);
- clear_bit(_GTF_reading, &sha->flags);
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Could not pin the granted frame (%lx)!\n", frame);
+ if ( !act->pin )
+ {
+ act->domid = sdom;
+ act->frame = __gpfn_to_mfn(rd, sha->frame);
+ }
+ }
+ else if ( (act->pin & 0x80808080U) != 0 )
+ PIN_FAIL(unlock_out, ENOSPC,
+ "Risk of counter overflow %08x\n", act->pin);
+
+ if ( dev_hst_ro_flags & GNTMAP_device_map )
+ act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
+ GNTPIN_devr_inc : GNTPIN_devw_inc;
+ if ( dev_hst_ro_flags & GNTMAP_host_map )
+ act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
+ GNTPIN_hstr_inc : GNTPIN_hstw_inc;
+
+ spin_unlock(&rd->grant_table->lock);
+
+ frame = act->frame;
+ if ( unlikely(!pfn_valid(frame)) ||
+ unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
+ get_page(pfn_to_page(frame), rd) :
+ get_page_and_type(pfn_to_page(frame), rd,
+ PGT_writable_page))) )
+ PIN_FAIL(undo_out, GNTST_general_error,
+ "Could not pin the granted frame (%lx)!\n", frame);
+
+ if ( dev_hst_ro_flags & GNTMAP_host_map )
+ {
+ rc = create_grant_host_mapping(addr, frame, dev_hst_ro_flags);
+ if ( rc != GNTST_okay )
+ {
+ if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
+ put_page_type(pfn_to_page(frame));
+ put_page(pfn_to_page(frame));
+ goto undo_out;
}

if ( dev_hst_ro_flags & GNTMAP_device_map )
- act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
- GNTPIN_devr_inc : GNTPIN_devw_inc;
- if ( dev_hst_ro_flags & GNTMAP_host_map )
- act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
- GNTPIN_hstr_inc : GNTPIN_hstw_inc;
- act->domid = sdom;
- act->frame = frame;
- }
- else
- {
- /* CASE 2: Active modications to an already active entry. */
-
- /*
- * A cheesy check for possible pin-count overflow.
- * A more accurate check cannot be done with a single comparison.
- */
- if ( (act->pin & 0x80808080U) != 0 )
- PIN_FAIL(unlock_out, ENOSPC,
- "Risk of counter overflow %08x\n", act->pin);
-
- sflags = sha->flags;
- frame = act->frame;
-
- if ( !(dev_hst_ro_flags & GNTMAP_readonly) &&
- !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
- {
- for ( ; ; )
- {
- u16 prev_sflags;
-
- if ( unlikely(sflags & GTF_readonly) )
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Attempt to write-pin a r/o grant entry.\n");
-
- prev_sflags = sflags;
-
- /* NB. prev_sflags is updated in place to seen value. */
- if ( unlikely(cmpxchg_user(&sha->flags, prev_sflags,
- prev_sflags | GTF_writing)) )
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Fault while modifying shared flags.\n");
-
- if ( likely(prev_sflags == sflags) )
- break;
-
- if ( retries++ == 4 )
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Shared grant entry is unstable.\n");
-
- sflags = prev_sflags;
- }
-
- if ( unlikely(!get_page_type(pfn_to_page(frame),
- PGT_writable_page)) )
- {
- clear_bit(_GTF_writing, &sha->flags);
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Attempt to write-pin a unwritable page.\n");
- }
- }
-
- if ( dev_hst_ro_flags & GNTMAP_device_map )
- act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
- GNTPIN_devr_inc : GNTPIN_devw_inc;
-
- if ( dev_hst_ro_flags & GNTMAP_host_map )
- act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
- GNTPIN_hstr_inc : GNTPIN_hstw_inc;
- }
-
- /*
- * At this point:
- * act->pin updated to reference count mappings.
- * sha->flags updated to indicate to granting domain mapping done.
- * frame contains the mfn.
- */
-
- spin_unlock(&rd->grant_table->lock);
-
- if ( dev_hst_ro_flags & GNTMAP_host_map )
- {
- rc = create_grant_host_mapping(addr, frame, dev_hst_ro_flags);
- if ( rc < 0 )
- {
- /* Failure: undo and abort. */
-
- spin_lock(&rd->grant_table->lock);
-
- if ( dev_hst_ro_flags & GNTMAP_readonly )
- {
- act->pin -= GNTPIN_hstr_inc;
- }
- else
- {
- act->pin -= GNTPIN_hstw_inc;
- if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
- {
- clear_bit(_GTF_writing, &sha->flags);
- put_page_type(pfn_to_page(frame));
- }
- }
-
- if ( act->pin == 0 )
- {
- clear_bit(_GTF_reading, &sha->flags);
- put_page(pfn_to_page(frame));
- }
-
- spin_unlock(&rd->grant_table->lock);
+ {
+ (void)get_page(pfn_to_page(frame), rd);
+ if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
+ get_page_type(pfn_to_page(frame), PGT_writable_page);
}
}

@@ -375,6 +295,24 @@
put_domain(rd);
return rc;

+ undo_out:
+ spin_lock(&rd->grant_table->lock);
+
+ if ( dev_hst_ro_flags & GNTMAP_device_map )
+ act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
+ GNTPIN_devr_inc : GNTPIN_devw_inc;
+ if ( dev_hst_ro_flags & GNTMAP_host_map )
+ act->pin -= (dev_hst_ro_flags & GNTMAP_readonly) ?
+ GNTPIN_hstr_inc : GNTPIN_hstw_inc;
+
+ if ( !(dev_hst_ro_flags & GNTMAP_readonly) &&
+ !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
+ clear_bit(_GTF_writing, &sha->flags);
+
+ if ( !act->pin )
+ clear_bit(_GTF_reading, &sha->flags);
+
+ spin_unlock(&rd->grant_table->lock);

unlock_out:
spin_unlock(&rd->grant_table->lock);
@@ -465,27 +403,42 @@
PIN_FAIL(unmap_out, GNTST_general_error,
"Bad frame number doesn't match gntref.\n");
if ( flags & GNTMAP_device_map )
- act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_devr_inc
- : GNTPIN_devw_inc;
-
- map->ref_and_flags &= ~GNTMAP_device_map;
- (void)__put_user(0, &uop->dev_bus_addr);
- }
-
- if ( (addr != 0) &&
- (flags & GNTMAP_host_map) &&
- ((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0))
+ {
+ ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask));
+ map->ref_and_flags &= ~GNTMAP_device_map;
+ if ( flags & GNTMAP_readonly )
+ {
+ act->pin -= GNTPIN_devr_inc;
+ put_page(pfn_to_page(frame));
+ }
+ else
+ {
+ act->pin -= GNTPIN_devw_inc;
+ put_page_and_type(pfn_to_page(frame));
+ }
+ }
+ }
+
+ if ( (addr != 0) && (flags & GNTMAP_host_map) )
{
if ( (rc = destroy_grant_host_mapping(addr, frame, flags)) < 0 )
goto unmap_out;

+ ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
map->ref_and_flags &= ~GNTMAP_host_map;
-
- act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_hstr_inc
- : GNTPIN_hstw_inc;
- }
-
- if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0)
+ if ( flags & GNTMAP_readonly )
+ {
+ act->pin -= GNTPIN_hstr_inc;
+ put_page(pfn_to_page(frame));
+ }
+ else
+ {
+ act->pin -= GNTPIN_hstw_inc;
+ put_page_and_type(pfn_to_page(frame));
+ }
+ }
+
+ if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
{
map->ref_and_flags = 0;
put_maptrack_handle(ld->grant_table, handle);
@@ -495,20 +448,12 @@
if ( !(flags & GNTMAP_readonly) )
gnttab_log_dirty(rd, frame);

- /* If the last writable mapping has been removed, put_page_type */
if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
!(flags & GNTMAP_readonly) )
- {
clear_bit(_GTF_writing, &sha->flags);
- put_page_type(pfn_to_page(frame));
- }

if ( act->pin == 0 )
- {
- act->frame = 0xdeadbeef;
clear_bit(_GTF_reading, &sha->flags);
- put_page(pfn_to_page(frame));
- }

unmap_out:
(void)__put_user(rc, &uop->status);
@@ -666,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;
}

@@ -818,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)
{
@@ -989,42 +938,42 @@
{
if ( map->ref_and_flags & GNTMAP_device_map )
{
- BUG_ON((act->pin & GNTPIN_devr_mask) == 0);
+ BUG_ON(!(act->pin & GNTPIN_devr_mask));
act->pin -= GNTPIN_devr_inc;
+ put_page(pfn_to_page(act->frame));
}

if ( map->ref_and_flags & GNTMAP_host_map )
{
- BUG_ON((act->pin & GNTPIN_hstr_mask) == 0);
+ BUG_ON(!(act->pin & GNTPIN_hstr_mask));
act->pin -= GNTPIN_hstr_inc;
+ /* Done implicitly when page tables are destroyed. */
+ /* put_page(pfn_to_page(act->frame)); */
}
}
else
{
if ( map->ref_and_flags & GNTMAP_device_map )
{
- BUG_ON((act->pin & GNTPIN_devw_mask) == 0);
+ BUG_ON(!(act->pin & GNTPIN_devw_mask));
act->pin -= GNTPIN_devw_inc;
+ put_page_and_type(pfn_to_page(act->frame));
}

if ( map->ref_and_flags & GNTMAP_host_map )
{
- BUG_ON((act->pin & GNTPIN_hstw_mask) == 0);
+ BUG_ON(!(act->pin & GNTPIN_hstw_mask));
act->pin -= GNTPIN_hstw_inc;
+ /* 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 )
- {
clear_bit(_GTF_writing, &sha->flags);
- put_page_type(pfn_to_page(act->frame));
- }
}

if ( act->pin == 0 )
- {
clear_bit(_GTF_reading, &sha->flags);
- put_page(pfn_to_page(act->frame));
- }

spin_unlock(&rd->grant_table->lock);

@@ -1039,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 5a790011259e -r 9b108cf447e5 xen/include/public/xen.h
--- a/xen/include/public/xen.h Wed Dec 21 17:56:19 2005
+++ b/xen/include/public/xen.h Wed Dec 21 18:52:00 2005
@@ -145,10 +145,6 @@
* cmd: MMUEXT_SET_LDT
* linear_addr: Linear address of LDT base (NB. must be page-aligned).
* nr_ents: Number of entries in LDT.
- *
- * cmd: MMUEXT_REASSIGN_PAGE
- * mfn: Machine frame number to be reassigned to the FD.
- * (NB. page must currently belong to the calling domain).
*/
#define MMUEXT_PIN_L1_TABLE 0
#define MMUEXT_PIN_L2_TABLE 1
@@ -164,14 +160,13 @@
#define MMUEXT_INVLPG_ALL 11
#define MMUEXT_FLUSH_CACHE 12
#define MMUEXT_SET_LDT 13
-#define MMUEXT_REASSIGN_PAGE 14
#define MMUEXT_NEW_USER_BASEPTR 15

#ifndef __ASSEMBLY__
struct mmuext_op {
unsigned int cmd;
union {
- /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR, REASSIGN_PAGE */
+ /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
unsigned long mfn;
/* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
unsigned long linear_addr;
diff -r 5a790011259e -r 9b108cf447e5 xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h Wed Dec 21 17:56:19 2005
+++ b/xen/include/xen/grant_table.h Wed Dec 21 18:52:00 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