|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RESEND] Question about recursive mappings
Keir Fraser wrote: Here's the patch that solves my issue. I've only tested it for x86_64, so any feedback on x86/PAE would be appreciated. Tried to make mutually recursive tables and destroy the domain as you suggested, no problem encountered. Note that the union i used may seem a bit overkill, but i didn't saw any other way to make it generic (even if brutal casting should work on any x86/x86_64 arch).On 24 May 2006, at 21:12, Mathieu Ropert wrote:Ok, i've done a little patch which seems to resolve the issue on my test setup. Basically, i've modified get_linear_pagetable(), added a level parameter and call it for each level but level 1. I need to do a little more test before i post the patch. As tomorrow is a national day, it should be ready friday.Can you try creating some mutually recursive pagetables (i.e., one linearly maps the other, and vice versa) and then try 'xm destroy'ing the domain?-- Keir Applies to cset 10166. Mathieu Signed-off-by: Mathieu Ropert <mro@xxxxxxxxxx> diff -u -r a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c 2006-05-26 11:05:08.000000000 +0200
+++ b/xen/arch/x86/mm.c 2006-05-26 11:14:33.000000000 +0200
@@ -415,7 +415,7 @@
*/
static int
get_linear_pagetable(
- root_pgentry_t re, unsigned long re_pfn, struct domain *d)
+ pgentry_t re, unsigned long re_pfn, struct domain *d, int level)
{
unsigned long x, y;
struct page_info *page;
@@ -423,13 +423,13 @@
ASSERT( !shadow_mode_refcounts(d) );
- if ( (root_get_flags(re) & _PAGE_RW) )
+ if ( (pgentry_get_flags(re, level) & _PAGE_RW) )
{
MEM_LOG("Attempt to create linear p.t. with write perms");
return 0;
}
- if ( (pfn = root_get_pfn(re)) != re_pfn )
+ if ( (pfn = pgentry_get_pfn(re, level)) != re_pfn )
{
/* Make sure the mapped frame belongs to the correct domain. */
if ( unlikely(!get_page_from_pagenr(pfn, d)) )
@@ -444,8 +444,7 @@
do {
x = y;
if ( unlikely((x & PGT_count_mask) == PGT_count_mask) ||
- unlikely((x & (PGT_type_mask|PGT_validated)) !=
- (PGT_root_page_table|PGT_validated)) )
+ unlikely(!(x & PGT_validated) || !is_ptp(x)))
{
put_page(page);
return 0;
@@ -532,9 +531,12 @@
vaddr <<= PGT_va_shift;
rc = get_page_and_type_from_pagenr(
l2e_get_pfn(l2e), PGT_l1_page_table | vaddr, d);
-#if CONFIG_PAGING_LEVELS == 2
- if ( unlikely(!rc) )
- rc = get_linear_pagetable(l2e, pfn, d);
+#if CONFIG_PAGING_LEVELS >= 2
+ if ( unlikely(!rc) ) {
+ pgentry_t re;
+ re.l2.l2 = l2e.l2;
+ rc = get_linear_pagetable(re, pfn, d, 2);
+ }
#endif
return rc;
}
@@ -564,9 +566,12 @@
rc = get_page_and_type_from_pagenr(
l3e_get_pfn(l3e),
PGT_l2_page_table | vaddr, d);
-#if CONFIG_PAGING_LEVELS == 3
- if ( unlikely(!rc) )
- rc = get_linear_pagetable(l3e, pfn, d);
+#if CONFIG_PAGING_LEVELS >= 3
+ if ( unlikely(!rc) ) {
+ pgentry_t re;
+ re.l3.l3 = l3e.l3;
+ rc = get_linear_pagetable(re, pfn, d, 3);
+ }
#endif
return rc;
}
@@ -597,8 +602,11 @@
l4e_get_pfn(l4e),
PGT_l3_page_table | vaddr, d);
- if ( unlikely(!rc) )
- rc = get_linear_pagetable(l4e, pfn, d);
+ if ( unlikely(!rc) ) {
+ pgentry_t re;
+ re.l4.l4 = l4e.l4;
+ rc = get_linear_pagetable(re, pfn, d, 4);
+ }
return rc;
}
diff -u -r a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h 2006-05-26 11:05:09.000000000 +0200
+++ b/xen/include/asm-x86/page.h 2006-05-24 12:49:42.000000000 +0200
@@ -176,6 +176,67 @@
#define pagetable_get_pfn(x) ((x).pfn)
#define mk_pagetable(pa) \
({ pagetable_t __p; __p.pfn = (pa) >> PAGE_SHIFT; __p; })
+
+typedef union {
+ l1_pgentry_t l1;
+#if CONFIG_PAGING_LEVELS >= 2
+ l2_pgentry_t l2;
+#if CONFIG_PAGING_LEVELS >= 3
+ l3_pgentry_t l3;
+#if CONFIG_PAGING_LEVELS == 4
+ l4_pgentry_t l4;
+#endif /* LEVELS == 4 */
+#endif /* LEVELS >= 3 */
+#endif /* LEVELS >= 2 */
+} pgentry_t;
+
+static inline intpte_t pgentry_get_flags(pgentry_t p, int level)
+{
+ switch (level)
+ {
+ case 1:
+ return l1e_get_flags(p.l1);
+#if CONFIG_PAGING_LEVELS >= 2
+ case 2:
+ return l2e_get_flags(p.l2);
+#if CONFIG_PAGING_LEVELS >= 3
+ case 3:
+ return l3e_get_flags(p.l3);
+#if CONFIG_PAGING_LEVELS == 4
+ case 4:
+ return l4e_get_flags(p.l4);
+#endif /* LEVELS == 4 */
+#endif /* LEVELS >= 3 */
+#endif /* LEVELS >= 2 */
+ default:
+ /* should not happen */
+ return 0;
+ }
+}
+
+static inline intpte_t pgentry_get_pfn(pgentry_t p, int level)
+{
+ switch (level)
+ {
+ case 1:
+ return l1e_get_pfn(p.l1);
+#if CONFIG_PAGING_LEVELS >= 2
+ case 2:
+ return l2e_get_pfn(p.l2);
+#if CONFIG_PAGING_LEVELS >= 3
+ case 3:
+ return l3e_get_pfn(p.l3);
+#if CONFIG_PAGING_LEVELS == 4
+ case 4:
+ return l4e_get_pfn(p.l4);
+#endif /* LEVELS == 4 */
+#endif /* LEVELS >= 3 */
+#endif /* LEVELS >= 2 */
+ default:
+ /* should not happen */
+ return 0;
+ }
+}
#endif
#define clear_page(_p) memset((void *)(_p), 0, PAGE_SIZE)
diff -u -r a/xen/include/asm-x86/x86_32/page-2level.h
b/xen/include/asm-x86/x86_32/page-2level.h
--- a/xen/include/asm-x86/x86_32/page-2level.h 2006-05-26 11:05:09.000000000
+0200
+++ b/xen/include/asm-x86/x86_32/page-2level.h 2006-05-26 11:09:56.000000000
+0200
@@ -28,6 +28,11 @@
#endif /* !__ASSEMBLY__ */
+/* Check if page type is page table (any level) */
+#define is_ptp(x) \
+ ((x & PGT_type_mask) == PGT_l1_page_table \
+ || (x & PGT_type_mask) == PGT_l2_page_table)
+
/* root table */
#define root_get_pfn l2e_get_pfn
#define root_get_flags l2e_get_flags
diff -u -r a/xen/include/asm-x86/x86_32/page-3level.h
b/xen/include/asm-x86/x86_32/page-3level.h
--- a/xen/include/asm-x86/x86_32/page-3level.h 2006-05-26 11:05:09.000000000
+0200
+++ b/xen/include/asm-x86/x86_32/page-3level.h 2006-05-26 11:10:47.000000000
+0200
@@ -38,6 +38,12 @@
#endif /* !__ASSEMBLY__ */
+/* Check if page type is page table (any level) */
+#define is_ptp(x) \
+ ((x & PGT_type_mask) == PGT_l1_page_table \
+ || (x & PGT_type_mask) == PGT_l2_page_table \
+ || (x & PGT_type_mask) == PGT_l3_page_table)
+
/* root table */
#define root_get_pfn l3e_get_pfn
#define root_get_flags l3e_get_flags
diff -u -r a/xen/include/asm-x86/x86_64/page.h
b/xen/include/asm-x86/x86_64/page.h
--- a/xen/include/asm-x86/x86_64/page.h 2006-05-26 11:05:09.000000000 +0200
+++ b/xen/include/asm-x86/x86_64/page.h 2006-05-26 11:07:46.000000000 +0200
@@ -41,6 +41,13 @@
#endif /* !__ASSEMBLY__ */
+/* Check if page type is page table (any level) */
+#define is_ptp(x) \
+ ((x & PGT_type_mask) == PGT_l1_page_table \
+ || (x & PGT_type_mask) == PGT_l2_page_table \
+ || (x & PGT_type_mask) == PGT_l3_page_table \
+ || (x & PGT_type_mask) == PGT_l4_page_table)
+
/* Given a virtual address, get an entry offset into a linear page table. */
#define l1_linear_offset(_a) (((_a) & VADDR_MASK) >> L1_PAGETABLE_SHIFT)
#define l2_linear_offset(_a) (((_a) & VADDR_MASK) >> L2_PAGETABLE_SHIFT)
_______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |