# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID d14cb80574eefad2d2a782f561b617a0a9494da2
# Parent 36cf47cfea4e3c0197db6b8822398da4a3f624b3
Revert some of the bigger changes in c/s 9217 as these have been
causing problems for a few people:
1. HVM guests can now have page directories with unknown
back pointers (I think this is the cause of problems that
Jun Nakajima was seeing).
2. L1 pagetable pinning requests are no longer ignored (may
be the cause of problems Joe Bonasera was seeing).
3. The PGT_va_mutable flag has been reintroduced, but for
L1 pagetables only.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 36cf47cfea4e -r d14cb80574ee xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Mar 13 14:06:58 2006
+++ b/xen/arch/x86/mm.c Tue Mar 14 12:01:43 2006
@@ -778,6 +778,7 @@
{
unsigned long l2_backptr = l2_type & PGT_va_mask;
ASSERT(l2_backptr != PGT_va_unknown);
+ ASSERT(l2_backptr != PGT_va_mutable);
*backptr =
((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) |
(offset_in_l2 << L2_PAGETABLE_SHIFT);
@@ -792,6 +793,7 @@
{
unsigned long l2_backptr = l2_type & PGT_va_mask;
ASSERT(l2_backptr != PGT_va_unknown);
+ ASSERT(l2_backptr != PGT_va_mutable);
*backptr = ((l2_backptr >> PGT_va_shift) << L3_PAGETABLE_SHIFT) |
(offset_in_l2 << L2_PAGETABLE_SHIFT);
return 1;
@@ -802,6 +804,7 @@
{
unsigned long l3_backptr = l3_type & PGT_va_mask;
ASSERT(l3_backptr != PGT_va_unknown);
+ ASSERT(l3_backptr != PGT_va_mutable);
*backptr = ((l3_backptr >> PGT_va_shift) << L4_PAGETABLE_SHIFT) |
(offset_in_l3 << L3_PAGETABLE_SHIFT);
return 1;
@@ -1430,6 +1433,12 @@
x &= ~PGT_validated;
nx &= ~PGT_validated;
}
+ }
+ else if ( unlikely((nx & (PGT_pinned|PGT_type_mask|PGT_count_mask)) ==
+ (PGT_pinned|PGT_l1_page_table|1)) )
+ {
+ /* Page is now only pinned. Make the back pointer mutable again. */
+ nx |= PGT_va_mutable;
}
}
while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
@@ -1513,16 +1522,24 @@
get_gpfn_from_mfn(page_to_mfn(page)));
return 0;
}
+ else if ( (x & PGT_va_mask) == PGT_va_mutable )
+ {
+ /* The va backpointer is mutable, hence we update it. */
+ nx &= ~PGT_va_mask;
+ nx |= type; /* we know the actual type is correct */
+ }
else
{
ASSERT((type & PGT_va_mask) != (x & PGT_va_mask));
+ ASSERT((type & PGT_va_mask) != PGT_va_mutable);
#ifdef CONFIG_X86_PAE
/* We use backptr as extra typing. Cannot be unknown. */
if ( (type & PGT_type_mask) == PGT_l2_page_table )
return 0;
#endif
/* Fixme: add code to propagate va_unknown to subtables. */
- if ( (type & PGT_type_mask) >= PGT_l2_page_table )
+ if ( ((type & PGT_type_mask) >= PGT_l2_page_table) &&
+ !shadow_mode_refcounts(page_get_owner(page)) )
return 0;
/* This table is possibly mapped at multiple locations. */
nx &= ~PGT_va_mask;
@@ -1801,16 +1818,21 @@
switch ( op.cmd )
{
case MMUEXT_PIN_L1_TABLE:
+ type = PGT_l1_page_table | PGT_va_mutable;
+ goto pin_page;
+
case MMUEXT_PIN_L2_TABLE:
case MMUEXT_PIN_L3_TABLE:
case MMUEXT_PIN_L4_TABLE:
+ /* Ignore pinning of subdirectories. */
if ( (op.cmd - MMUEXT_PIN_L1_TABLE) != (CONFIG_PAGING_LEVELS - 1) )
break;
+ type = PGT_root_page_table;
+
+ pin_page:
if ( shadow_mode_refcounts(FOREIGNDOM) )
break;
-
- type = PGT_root_page_table;
okay = get_page_and_type_from_pagenr(mfn, type, FOREIGNDOM);
if ( unlikely(!okay) )
@@ -3350,7 +3372,7 @@
/* Get the L2 index at which this L1 p.t. is always mapped. */
l2_idx = page->u.inuse.type_info & PGT_va_mask;
- if ( unlikely(l2_idx == PGT_va_unknown) )
+ if ( unlikely(l2_idx >= PGT_va_unknown) )
goto emulate; /* Urk! This L1 is mapped in multiple L2 slots! */
l2_idx >>= PGT_va_shift;
diff -r 36cf47cfea4e -r d14cb80574ee xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h Mon Mar 13 14:06:58 2006
+++ b/xen/include/asm-x86/mm.h Tue Mar 14 12:01:43 2006
@@ -81,14 +81,18 @@
/* The 11 most significant bits of virt address if this is a page table. */
#define PGT_va_shift 16
#define PGT_va_mask (((1U<<11)-1)<<PGT_va_shift)
+ /* Is the back pointer still mutable (i.e. not fixed yet)? */
+#define PGT_va_mutable (((1U<<11)-1)<<PGT_va_shift)
/* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
-#define PGT_va_unknown (((1U<<11)-1)<<PGT_va_shift)
+#define PGT_va_unknown (((1U<<11)-2)<<PGT_va_shift)
#elif defined(__x86_64__)
/* The 27 most significant bits of virt address if this is a page table. */
#define PGT_va_shift 32
#define PGT_va_mask ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
+ /* Is the back pointer still mutable (i.e. not fixed yet)? */
+#define PGT_va_mutable ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
/* Is the back pointer unknown (e.g., p.t. is mapped at multiple VAs)? */
-#define PGT_va_unknown ((unsigned long)((1U<<28)-1)<<PGT_va_shift)
+#define PGT_va_unknown ((unsigned long)((1U<<28)-2)<<PGT_va_shift)
#endif
/* 16-bit count of uses of this frame as its current type. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|