* [PATCH] x86: guest_walk_tables() should check invalid bits on large page entries
@ 2011-03-28 8:11 Jan Beulich
2011-04-04 9:49 ` Tim Deegan
0 siblings, 1 reply; 2+ messages in thread
From: Jan Beulich @ 2011-03-28 8:11 UTC (permalink / raw)
To: Tim Deegan; +Cc: xen-devel@lists.xensource.com
[-- Attachment #1: Type: text/plain, Size: 1700 bytes --]
The PSE handling doesn't check bits 1...8 (or 1...9 for non-PAE guests)
being zero, thus allowing bad (not 2Mb/4Mb aligned) large pages to be
handled.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/mm/guest_walk.c
+++ b/xen/arch/x86/mm/guest_walk.c
@@ -231,9 +231,28 @@ guest_walk_tables(struct vcpu *v, struct
/* _PAGE_PSE_PAT not set: remove _PAGE_PAT from flags. */
flags &= ~_PAGE_PAT;
+#define GUEST_L2_GFN_ALIGN (1 << (GUEST_L2_PAGETABLE_SHIFT - \
+ GUEST_L1_PAGETABLE_SHIFT))
+ if ( gfn_x(start) & (GUEST_L2_GFN_ALIGN - 1) & ~0x1 )
+ {
+#if GUEST_PAGING_LEVELS == 2
+ /*
+ * Note that _PAGE_INVALID_BITS is zero in this case, yielding a
+ * no-op here.
+ *
+ * Architecturally, the walk should fail if bit 21 is set (others
+ * aren't being checked at least in PSE36 mode), but we'll ignore
+ * this here in order to avoid specifying a non-natural, non-zero
+ * _PAGE_INVALID_BITS value just for that case.
+ */
+#endif
+ rc |= _PAGE_INVALID_BITS;
+ }
+
/* Increment the pfn by the right number of 4k pages.
- * The ~0x1 is to mask out the PAT bit mentioned above. */
- start = _gfn((gfn_x(start) & ~0x1) + guest_l1_table_offset(va));
+ * Mask out PAT and invalid bits. */
+ start = _gfn((gfn_x(start) & ~(GUEST_L2_GFN_ALIGN - 1)) +
+ guest_l1_table_offset(va));
gw->l1e = guest_l1e_from_gfn(start, flags);
gw->l1mfn = _mfn(INVALID_MFN);
}
[-- Attachment #2: x86-guest-walk-pse-invalid.patch --]
[-- Type: text/plain, Size: 1694 bytes --]
The PSE handling doesn't check bits 1...8 (or 1...9 for non-PAE guests)
being zero, thus allowing bad (not 2Mb/4Mb aligned) large pages to be
handled.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
--- a/xen/arch/x86/mm/guest_walk.c
+++ b/xen/arch/x86/mm/guest_walk.c
@@ -231,9 +231,28 @@ guest_walk_tables(struct vcpu *v, struct
/* _PAGE_PSE_PAT not set: remove _PAGE_PAT from flags. */
flags &= ~_PAGE_PAT;
+#define GUEST_L2_GFN_ALIGN (1 << (GUEST_L2_PAGETABLE_SHIFT - \
+ GUEST_L1_PAGETABLE_SHIFT))
+ if ( gfn_x(start) & (GUEST_L2_GFN_ALIGN - 1) & ~0x1 )
+ {
+#if GUEST_PAGING_LEVELS == 2
+ /*
+ * Note that _PAGE_INVALID_BITS is zero in this case, yielding a
+ * no-op here.
+ *
+ * Architecturally, the walk should fail if bit 21 is set (others
+ * aren't being checked at least in PSE36 mode), but we'll ignore
+ * this here in order to avoid specifying a non-natural, non-zero
+ * _PAGE_INVALID_BITS value just for that case.
+ */
+#endif
+ rc |= _PAGE_INVALID_BITS;
+ }
+
/* Increment the pfn by the right number of 4k pages.
- * The ~0x1 is to mask out the PAT bit mentioned above. */
- start = _gfn((gfn_x(start) & ~0x1) + guest_l1_table_offset(va));
+ * Mask out PAT and invalid bits. */
+ start = _gfn((gfn_x(start) & ~(GUEST_L2_GFN_ALIGN - 1)) +
+ guest_l1_table_offset(va));
gw->l1e = guest_l1e_from_gfn(start, flags);
gw->l1mfn = _mfn(INVALID_MFN);
}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-04-04 9:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-28 8:11 [PATCH] x86: guest_walk_tables() should check invalid bits on large page entries Jan Beulich
2011-04-04 9:49 ` Tim Deegan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).