Mailing List Archive

When a foreign page is mapped via a grant reference, it
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID dede6fb4c90e7b4dee20befc8269c28379a7c6bb
# Parent 13b2e5c945956657aa330a6182f204c46ba626af
When a foreign page is mapped via a grant reference, it
must also be unmapped explicitly via the grant-table
interface (GNTTABOP_unmap_grant_ref). If not, the guest
ends up with a dangling grant reference that is not cleared
up until the guest dies.

Because this can obviously lead to deferred hard-to-debug
problems, debug builds of Xen use a 'spare' PTE flag to
track granted mappings and to crash a domain if it attempts
to free such a PTE without using GNTTABOP_unmap_grant_ref.

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

diff -r 13b2e5c94595 -r dede6fb4c90e xen/arch/ia64/xen/grant_table.c
--- a/xen/arch/ia64/xen/grant_table.c Tue Nov 22 11:04:03 2005
+++ b/xen/arch/ia64/xen/grant_table.c Tue Nov 22 14:53:22 2005
@@ -1054,114 +1054,6 @@
return rc;
}

-int
-gnttab_check_unmap(
- struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
-{
- /* Called when put_page is invoked on a page belonging to a foreign domain.
- * Instead of decrementing the frame table ref count, locate the grant
- * table entry, if any, and if found, decrement that count.
- * Called a _lot_ at domain creation because pages mapped by priv domains
- * also traverse this.
- */
-
- /* Note: If the same frame is mapped multiple times, and then one of
- * the ptes is overwritten, which maptrack handle gets invalidated?
- * Advice: Don't do it. Explicitly unmap.
- */
-
- unsigned int handle, ref, refcount;
- grant_table_t *lgt, *rgt;
- active_grant_entry_t *act;
- grant_mapping_t *map;
- int found = 0;
-
- lgt = ld->grant_table;
-
-#if GRANT_DEBUG_VERBOSE
- if ( ld->domain_ id != 0 ) {
- DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
- rd->domain_id, ld->domain_id, frame, readonly);
- }
-#endif
-
- /* Fast exit if we're not mapping anything using grant tables */
- if ( lgt->map_count == 0 )
- return 0;
-
- if ( get_domain(rd) == 0 ) {
- DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n",
- rd->domain_id);
- return 0;
- }
-
- rgt = rd->grant_table;
-
- for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) {
-
- map = &lgt->maptrack[handle];
-
- if ( map->domid != rd->domain_id )
- continue;
-
- if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
- ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) {
-
- ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
- act = &rgt->active[ref];
-
- spin_lock(&rgt->lock);
-
- if ( act->frame != frame ) {
- spin_unlock(&rgt->lock);
- continue;
- }
-
- refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
- : GNTPIN_hstw_mask );
-
- if ( refcount == 0 ) {
- spin_unlock(&rgt->lock);
- continue;
- }
-
- /* gotcha */
- DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
- rd->domain_id, ld->domain_id, frame, readonly);
-
- if ( readonly )
- act->pin -= GNTPIN_hstr_inc;
- else {
- act->pin -= GNTPIN_hstw_inc;
-
- /* any more granted writable mappings? */
- if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) {
- clear_bit(_GTF_writing, &rgt->shared[ref].flags);
- put_page_type(&frame_table[frame]);
- }
- }
-
- if ( act->pin == 0 ) {
- clear_bit(_GTF_reading, &rgt->shared[ref].flags);
- put_page(&frame_table[frame]);
- }
-
- spin_unlock(&rgt->lock);
-
- clear_bit(GNTMAP_host_map, &map->ref_and_flags);
-
- if ( !(map->ref_and_flags & GNTMAP_device_map) )
- put_maptrack_handle(lgt, handle);
-
- found = 1;
- break;
- }
- }
- put_domain(rd);
-
- return found;
-}
-
int
gnttab_prepare_for_transfer(
struct domain *rd, struct domain *ld, grant_ref_t ref)
@@ -1355,8 +1247,10 @@
}

void
-gnttab_release_dev_mappings(grant_table_t *gt)
-{
+gnttab_release_mappings(
+ struct domain *ld)
+{
+ grant_table_t *gt = ld->grant_table;
grant_mapping_t *map;
domid_t dom;
grant_ref_t ref;
@@ -1365,8 +1259,6 @@
unsigned long frame;
active_grant_entry_t *act;
grant_entry_t *sha;
-
- ld = current->domain;

for ( handle = 0; handle < gt->maptrack_limit; handle++ )
{
diff -r 13b2e5c94595 -r dede6fb4c90e xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Tue Nov 22 11:04:03 2005
+++ b/xen/arch/x86/domain.c Tue Nov 22 14:53:22 2005
@@ -960,8 +960,7 @@

ptwr_destroy(d);

- /* Release device mappings of other domains */
- gnttab_release_dev_mappings(d->grant_table);
+ gnttab_release_mappings(d);

/* Drop the in-use references to page-table bases. */
for_each_vcpu ( d, v )
diff -r 13b2e5c94595 -r dede6fb4c90e xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Nov 22 11:04:03 2005
+++ b/xen/arch/x86/mm.c Tue Nov 22 14:53:22 2005
@@ -594,23 +594,26 @@
return;

e = page_get_owner(page);
- if ( unlikely(e != d) )
- {
- /*
- * Unmap a foreign page that may have been mapped via a grant table.
- * Note that this can fail for a privileged domain that can map foreign
- * pages via MMUEXT_SET_FOREIGNDOM. Such domains can have some mappings
- * counted via a grant entry and some counted directly in the page
- * structure's reference count. Note that reference counts won't get
- * dangerously confused as long as we always try to decrement the
- * grant entry first. We may end up with a mismatch between which
- * mappings and which unmappings are counted via the grant entry, but
- * really it doesn't matter as privileged domains have carte blanche.
- */
- if (likely(gnttab_check_unmap(e, d, pfn,
- !(l1e_get_flags(l1e) & _PAGE_RW))))
- return;
- /* Assume this mapping was made via MMUEXT_SET_FOREIGNDOM... */
+
+ /*
+ * Check if this is a mapping that was established via a grant reference.
+ * If it was then we should not be here: we require that such mappings are
+ * explicitly destroyed via the grant-table interface.
+ *
+ * The upshot of this is that the guest can end up with active grants that
+ * it cannot destroy (because it no longer has a PTE to present to the
+ * grant-table interface). This can lead to subtle hard-to-catch bugs,
+ * hence a special grant PTE flag can be enabled to catch the bug early.
+ *
+ * (Note that the undestroyable active grants are not a security hole in
+ * Xen. All active grants can safely be cleaned up when the domain dies.)
+ */
+ if ( (l1e_get_flags(l1e) & _PAGE_GNTTAB) &&
+ !(d->domain_flags & (DOMF_shutdown|DOMF_dying)) )
+ {
+ MEM_LOG("Attempt to implicitly unmap a granted PTE %" PRIpte,
+ l1e_get_intpte(l1e));
+ domain_crash(d);
}

if ( l1e_get_flags(l1e) & _PAGE_RW )
@@ -2317,7 +2320,6 @@

ASSERT(spin_is_locked(&d->big_lock));
ASSERT(!shadow_mode_refcounts(d));
- ASSERT((l1e_get_flags(_nl1e) & L1_DISALLOW_MASK) == 0);

gpfn = pte_addr >> PAGE_SHIFT;
mfn = __gpfn_to_mfn(d, gpfn);
@@ -2452,7 +2454,6 @@

ASSERT(spin_is_locked(&d->big_lock));
ASSERT(!shadow_mode_refcounts(d));
- ASSERT((l1e_get_flags(_nl1e) & L1_DISALLOW_MASK) == 0);

/*
* This is actually overkill - we don't need to sync the L1 itself,
diff -r 13b2e5c94595 -r dede6fb4c90e xen/common/grant_table.c
--- a/xen/common/grant_table.c Tue Nov 22 11:04:03 2005
+++ b/xen/common/grant_table.c Tue Nov 22 14:53:22 2005
@@ -31,17 +31,11 @@
#include <acm/acm_hooks.h>
#include <xen/trace.h>

-#if defined(CONFIG_X86_64)
-#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#else
-#define GRANT_PTE_FLAGS (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY)
-#endif
-
-#define PIN_FAIL(_lbl, _rc, _f, _a...) \
- do { \
- DPRINTK( _f, ## _a ); \
- rc = (_rc); \
- goto _lbl; \
+#define PIN_FAIL(_lbl, _rc, _f, _a...) \
+ do { \
+ DPRINTK( _f, ## _a ); \
+ rc = (_rc); \
+ goto _lbl; \
} while ( 0 )

static inline int
@@ -519,12 +513,12 @@

/* If just unmapped a writable mapping, mark as dirtied */
if ( unlikely(shadow_mode_log_dirty(rd)) &&
- !( flags & GNTMAP_readonly ) )
+ !(flags & GNTMAP_readonly) )
mark_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 ) ) )
+ if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
+ !(flags & GNTMAP_readonly) )
{
clear_bit(_GTF_writing, &sha->flags);
put_page_type(&frame_table[frame]);
@@ -880,108 +874,6 @@
return rc;
}

-int
-gnttab_check_unmap(
- struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
-{
- /* Called when put_page is invoked on a page belonging to a foreign domain.
- * Instead of decrementing the frame table ref count, locate the grant
- * table entry, if any, and if found, decrement that count.
- * Called a _lot_ at domain creation because pages mapped by priv domains
- * also traverse this.
- */
-
- /* Note: If the same frame is mapped multiple times, and then one of
- * the ptes is overwritten, which maptrack handle gets invalidated?
- * Advice: Don't do it. Explicitly unmap.
- */
-
- unsigned int handle, ref, refcount;
- grant_table_t *lgt, *rgt;
- active_grant_entry_t *act;
- grant_mapping_t *map;
- int found = 0;
-
- lgt = ld->grant_table;
-
- /* Fast exit if we're not mapping anything using grant tables */
- if ( lgt->map_count == 0 )
- return 0;
-
- if ( get_domain(rd) == 0 )
- {
- DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n",
- rd->domain_id);
- return 0;
- }
-
- rgt = rd->grant_table;
-
- for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) {
-
- map = &lgt->maptrack[handle];
-
- if ( map->domid != rd->domain_id )
- continue;
-
- if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
- ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) {
-
- ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
- act = &rgt->active[ref];
-
- spin_lock(&rgt->lock);
-
- if ( act->frame != frame ) {
- spin_unlock(&rgt->lock);
- continue;
- }
-
- refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
- : GNTPIN_hstw_mask );
-
- if ( refcount == 0 ) {
- spin_unlock(&rgt->lock);
- continue;
- }
-
- /* gotcha */
- DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
- rd->domain_id, ld->domain_id, frame, readonly);
-
- if ( readonly )
- act->pin -= GNTPIN_hstr_inc;
- else {
- act->pin -= GNTPIN_hstw_inc;
-
- /* any more granted writable mappings? */
- if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) {
- clear_bit(_GTF_writing, &rgt->shared[ref].flags);
- put_page_type(&frame_table[frame]);
- }
- }
-
- if ( act->pin == 0 ) {
- clear_bit(_GTF_reading, &rgt->shared[ref].flags);
- put_page(&frame_table[frame]);
- }
-
- spin_unlock(&rgt->lock);
-
- clear_bit(GNTMAP_host_map, &map->ref_and_flags);
-
- if ( !(map->ref_and_flags & GNTMAP_device_map) )
- put_maptrack_handle(lgt, handle);
-
- found = 1;
- break;
- }
- }
- put_domain(rd);
-
- return found;
-}
-
int
gnttab_prepare_for_transfer(
struct domain *rd, struct domain *ld, grant_ref_t ref)
@@ -1124,70 +1016,85 @@
}

void
-gnttab_release_dev_mappings(grant_table_t *gt)
-{
- grant_mapping_t *map;
- domid_t dom;
- grant_ref_t ref;
- u16 handle;
- struct domain *ld, *rd;
- unsigned long frame;
- active_grant_entry_t *act;
- grant_entry_t *sha;
-
- ld = current->domain;
+gnttab_release_mappings(
+ struct domain *d)
+{
+ grant_table_t *gt = d->grant_table;
+ grant_mapping_t *map;
+ grant_ref_t ref;
+ u16 handle;
+ struct domain *rd;
+ active_grant_entry_t *act;
+ grant_entry_t *sha;
+
+ BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));

for ( handle = 0; handle < gt->maptrack_limit; handle++ )
{
map = &gt->maptrack[handle];
-
- if ( !(map->ref_and_flags & GNTMAP_device_map) )
+ if ( !(map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) )
continue;

- dom = map->domid;
ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;

DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
- handle, ref, map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
-
- if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
- unlikely(ld == rd) )
- {
- if ( rd != NULL )
- put_domain(rd);
- printk(KERN_WARNING "Grant release: No dom%d\n", dom);
- continue;
- }
+ handle, ref, map->ref_and_flags & MAPTRACK_GNTMAP_MASK,
+ map->domid);
+
+ rd = find_domain_by_id(map->domid);
+ BUG_ON(rd == NULL);
+
+ spin_lock(&rd->grant_table->lock);

act = &rd->grant_table->active[ref];
sha = &rd->grant_table->shared[ref];

- spin_lock(&rd->grant_table->lock);
-
- if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) )
- {
- frame = act->frame;
-
- if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) &&
- ( (act->pin & GNTPIN_devw_mask) > 0 ) )
+ if ( map->ref_and_flags & GNTMAP_readonly )
+ {
+ if ( map->ref_and_flags & GNTMAP_device_map )
+ {
+ BUG_ON((act->pin & GNTPIN_devr_mask) == 0);
+ act->pin -= GNTPIN_devr_inc;
+ }
+
+ if ( map->ref_and_flags & GNTMAP_host_map )
+ {
+ BUG_ON((act->pin & GNTPIN_hstr_mask) == 0);
+ act->pin -= GNTPIN_hstr_inc;
+ }
+ }
+ else
+ {
+ if ( map->ref_and_flags & GNTMAP_device_map )
+ {
+ BUG_ON((act->pin & GNTPIN_devw_mask) == 0);
+ act->pin -= GNTPIN_devw_inc;
+ }
+
+ if ( map->ref_and_flags & GNTMAP_host_map )
+ {
+ BUG_ON((act->pin & GNTPIN_hstw_mask) == 0);
+ act->pin -= GNTPIN_hstw_inc;
+ }
+
+ if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
{
clear_bit(_GTF_writing, &sha->flags);
- put_page_type(&frame_table[frame]);
+ put_page_type(&frame_table[act->frame]);
}
-
- map->ref_and_flags &= ~GNTMAP_device_map;
- act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask);
- if ( act->pin == 0 )
- {
- clear_bit(_GTF_reading, &sha->flags);
- map->ref_and_flags = 0;
- put_page(&frame_table[frame]);
- }
+ }
+
+ if ( act->pin == 0 )
+ {
+ clear_bit(_GTF_reading, &sha->flags);
+ put_page(&frame_table[act->frame]);
}

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

put_domain(rd);
+
+ map->ref_and_flags = 0;
}
}

diff -r 13b2e5c94595 -r dede6fb4c90e xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h Tue Nov 22 11:04:03 2005
+++ b/xen/include/asm-x86/page.h Tue Nov 22 14:53:22 2005
@@ -273,6 +273,24 @@
#define _PAGE_AVAIL2 0x800U
#define _PAGE_AVAIL 0xE00U

+/*
+ * Debug option: Ensure that granted mappings are not implicitly unmapped.
+ * WARNING: This will need to be disabled to run OSes that use the spare PTE
+ * bits themselves (e.g., *BSD).
+ */
+#ifndef NDEBUG
+#define _PAGE_GNTTAB _PAGE_AVAIL2
+#else
+#define _PAGE_GNTTAB 0
+#endif
+
+/*
+ * Disallow unused flag bits plus PAT, PSE and GLOBAL. Also disallow GNTTAB
+ * if we are using it for grant-table debugging. Permit the NX bit if the
+ * hardware supports it.
+ */
+#define BASE_DISALLOW_MASK ((0xFFFFF180U | _PAGE_GNTTAB) & ~_PAGE_NX)
+
#define __PAGE_HYPERVISOR \
(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
#define __PAGE_HYPERVISOR_NOCACHE \
diff -r 13b2e5c94595 -r dede6fb4c90e xen/include/asm-x86/x86_32/page-2level.h
--- a/xen/include/asm-x86/x86_32/page-2level.h Tue Nov 22 11:04:03 2005
+++ b/xen/include/asm-x86/x86_32/page-2level.h Tue Nov 22 14:53:22 2005
@@ -1,5 +1,5 @@
-#ifndef __X86_32_PAGE_2L_H__
-#define __X86_32_PAGE_2L_H__
+#ifndef __X86_32_PAGE_2LEVEL_H__
+#define __X86_32_PAGE_2LEVEL_H__

#define L1_PAGETABLE_SHIFT 12
#define L2_PAGETABLE_SHIFT 22
@@ -52,7 +52,7 @@
#define get_pte_flags(x) ((int)(x) & 0xFFF)
#define put_pte_flags(x) ((intpte_t)((x) & 0xFFF))

-#define L1_DISALLOW_MASK (0xFFFFF180U) /* PAT/GLOBAL */
-#define L2_DISALLOW_MASK (0xFFFFF180U) /* PSE/GLOBAL */
+#define L1_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L2_DISALLOW_MASK BASE_DISALLOW_MASK

-#endif /* __X86_32_PAGE_2L_H__ */
+#endif /* __X86_32_PAGE_2LEVEL_H__ */
diff -r 13b2e5c94595 -r dede6fb4c90e xen/include/asm-x86/x86_32/page-3level.h
--- a/xen/include/asm-x86/x86_32/page-3level.h Tue Nov 22 11:04:03 2005
+++ b/xen/include/asm-x86/x86_32/page-3level.h Tue Nov 22 14:53:22 2005
@@ -1,5 +1,5 @@
-#ifndef __X86_32_PAGE_3L_H__
-#define __X86_32_PAGE_3L_H__
+#ifndef __X86_32_PAGE_3LEVEL_H__
+#define __X86_32_PAGE_3LEVEL_H__

#define L1_PAGETABLE_SHIFT 12
#define L2_PAGETABLE_SHIFT 21
@@ -65,8 +65,8 @@
#define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF))
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 32) | ((x) & 0xFFF))

-#define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
-#define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */
-#define L3_DISALLOW_MASK (0xFFFFF1E6U) /* must-be-zero */
+#define L1_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L2_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */

-#endif /* __X86_32_PAGE_3L_H__ */
+#endif /* __X86_32_PAGE_3LEVEL_H__ */
diff -r 13b2e5c94595 -r dede6fb4c90e xen/include/asm-x86/x86_32/page.h
--- a/xen/include/asm-x86/x86_32/page.h Tue Nov 22 11:04:03 2005
+++ b/xen/include/asm-x86/x86_32/page.h Tue Nov 22 14:53:22 2005
@@ -23,6 +23,9 @@
extern unsigned int PAGE_HYPERVISOR_NOCACHE;
#endif

+#define GRANT_PTE_FLAGS \
+ (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_GNTTAB)
+
#endif /* __X86_32_PAGE_H__ */

/*
diff -r 13b2e5c94595 -r dede6fb4c90e xen/include/asm-x86/x86_64/page.h
--- a/xen/include/asm-x86/x86_64/page.h Tue Nov 22 11:04:03 2005
+++ b/xen/include/asm-x86/x86_64/page.h Tue Nov 22 14:53:22 2005
@@ -72,13 +72,16 @@
/* Bit 23 of a 24-bit flag mask. This corresponds to bit 63 of a pte.*/
#define _PAGE_NX (cpu_has_nx ? (1U<<23) : 0U)

-#define L1_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PAT/GLOBAL */
-#define L2_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* PSE/GLOBAL */
-#define L3_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* must-be-zero */
-#define L4_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX) /* must-be-zero */
+#define L1_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L2_DISALLOW_MASK BASE_DISALLOW_MASK
+#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
+#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)

#define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL)
#define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL)
+
+#define GRANT_PTE_FLAGS \
+ (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_GNTTAB|_PAGE_USER)

#endif /* __X86_64_PAGE_H__ */

diff -r 13b2e5c94595 -r dede6fb4c90e xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h Tue Nov 22 11:04:03 2005
+++ b/xen/include/xen/grant_table.h Tue Nov 22 14:53:22 2005
@@ -94,10 +94,6 @@
void grant_table_destroy(
struct domain *d);

-/* Destroy host-CPU mappings via a grant-table entry. */
-int gnttab_check_unmap(
- struct domain *rd, struct domain *ld, unsigned long frame, int readonly);
-
/*
* Check that the given grant reference (rd,ref) allows 'ld' to transfer
* ownership of a page frame. If so, lock down the grant entry.
@@ -106,8 +102,9 @@
gnttab_prepare_for_transfer(
struct domain *rd, struct domain *ld, grant_ref_t ref);

-/* Domain death release of granted device mappings of other domains.*/
+/* Domain death release of granted mappings of other domains' memory. */
void
-gnttab_release_dev_mappings(grant_table_t *gt);
+gnttab_release_mappings(
+ struct domain *d);

#endif /* __XEN_GRANT_H__ */

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