All of lore.kernel.org
 help / color / mirror / Atom feed
* RE: [RESEND] Question about recursive mappings
@ 2006-05-24  9:34 Ian Pratt
  2006-05-24 20:12 ` Mathieu Ropert
  0 siblings, 1 reply; 11+ messages in thread
From: Ian Pratt @ 2006-05-24  9:34 UTC (permalink / raw)
  To: Mathieu Ropert, Keir Fraser; +Cc: xen-devel

> About the possible fix, won't something like trying a
> get_linear_pagetable() at all level works? Will it cause too 
> much overhead?
> Generally speaking, is allowing a R/O mapping of another 
> table the domain own (whichever level it is) safe? At first 
> thought, i don't see any way of exploiting it.

Yes, it's safe, you just need to get the 'general' ref count right,
which as I recall, depends on whether the page you're mapping is in the
same page table, or a foreign page table. The va back pointer means that
there is a unique 'normal' place in each pagetable where a given page
can be mapped, so you can easily inspect (via xen's linear mapping) to
see whether the page belongs to the current pagetable or not.

One thing we do have to watch out for is when we introduce super page
mappings, as you have to be careful about using linear page tables in
this context -- the x86 pagetable format doesn't allow you to generate a
trap if a linear mapping attempts to misuse a superpage. That's not your
worry right now :-) 

Ian

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-24  9:34 [RESEND] Question about recursive mappings Ian Pratt
@ 2006-05-24 20:12 ` Mathieu Ropert
  2006-05-24 20:16   ` Keir Fraser
  0 siblings, 1 reply; 11+ messages in thread
From: Mathieu Ropert @ 2006-05-24 20:12 UTC (permalink / raw)
  To: Ian Pratt; +Cc: xen-devel

Ian Pratt wrote:

>>About the possible fix, won't something like trying a
>>get_linear_pagetable() at all level works? Will it cause too 
>>much overhead?
>>Generally speaking, is allowing a R/O mapping of another 
>>table the domain own (whichever level it is) safe? At first 
>>thought, i don't see any way of exploiting it.
>>    
>>
>
>Yes, it's safe, you just need to get the 'general' ref count right,
>which as I recall, depends on whether the page you're mapping is in the
>same page table, or a foreign page table. The va back pointer means that
>there is a unique 'normal' place in each pagetable where a given page
>can be mapped, so you can easily inspect (via xen's linear mapping) to
>see whether the page belongs to the current pagetable or not.
>
>One thing we do have to watch out for is when we introduce super page
>mappings, as you have to be careful about using linear page tables in
>this context -- the x86 pagetable format doesn't allow you to generate a
>trap if a linear mapping attempts to misuse a superpage. That's not your
>worry right now :-) 
>
>Ian
>  
>
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.

Mathieu

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-24 20:12 ` Mathieu Ropert
@ 2006-05-24 20:16   ` Keir Fraser
  2006-05-26  9:27     ` Mathieu Ropert
  2006-05-29 11:43     ` Mathieu Ropert
  0 siblings, 2 replies; 11+ messages in thread
From: Keir Fraser @ 2006-05-24 20:16 UTC (permalink / raw)
  To: Mathieu Ropert; +Cc: Ian Pratt, xen-devel


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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-24 20:16   ` Keir Fraser
@ 2006-05-26  9:27     ` Mathieu Ropert
  2006-05-29 11:43     ` Mathieu Ropert
  1 sibling, 0 replies; 11+ messages in thread
From: Mathieu Ropert @ 2006-05-26  9:27 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Ian Pratt, xen-devel

[-- Attachment #1: Type: text/plain, Size: 1050 bytes --]

Keir Fraser wrote:

>
> 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
>
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).
Applies to cset 10166.

Mathieu

Signed-off-by: Mathieu Ropert <mro@adviseo.fr>



[-- Attachment #2: linear_pagetables.patch --]
[-- Type: text/x-patch, Size: 6533 bytes --]

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)

[-- 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] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-24 20:16   ` Keir Fraser
  2006-05-26  9:27     ` Mathieu Ropert
@ 2006-05-29 11:43     ` Mathieu Ropert
  1 sibling, 0 replies; 11+ messages in thread
From: Mathieu Ropert @ 2006-05-29 11:43 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Ian Pratt, xen-devel

[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]

Keir Fraser wrote:

>
> 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
>
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).
Applies to cset 10166.

Mathieu

Signed-off-by: Mathieu Ropert <mro@adviseo.fr>




[-- Attachment #2: linear_pagetables.patch --]
[-- Type: text/x-patch, Size: 6534 bytes --]

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)


[-- 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] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-23  9:52 ` Keir Fraser
  2006-05-23 12:22   ` Mathieu Ropert
@ 2006-07-27 22:14   ` Bruce Rogers
  1 sibling, 0 replies; 11+ messages in thread
From: Bruce Rogers @ 2006-07-27 22:14 UTC (permalink / raw)
  To: Keir Fraser, Ian Pratt; +Cc: xen-devel, Mathieu Ropert

Is it still the case that we don't support recursive mappings for PAE
page tables?  NetWare relies on recursive mappings in both PAE and
non-PAE modes.  The non-PAE mode is working well, but now that I've
statred working on running with PAE it appears I'm hitting this issue.

- Bruce


>>> On 5/23/2006 at 3:52 AM, in message
<9e623acb8c30c70453a9b82b8b9a63b7@cl.cam.ac.uk>, Keir Fraser
<Keir.Fraser@cl.cam.ac.uk> wrote:

> On 23 May 2006, at 10:41, Ian Pratt wrote:
> 
>> Can you explain the pagtable structure a little better please. Does
the
>> L3 contain an entry point at itself (recursive), or at another L3
>> (foreign)?
>>
>> I've never come across non-root pagetable linear mappings other than
in
>> the crock that is PAE (3 level) where you have to use 4 entries in
an 
>> L2
>> to point to all the L2s due to the limited address space.
> 
> And that's something we don't currently support. A slightly more 
> generic linear pagetable logic that would permit us to support linear

> pagetables on PAE would be a good thing.
> 
>   -- Keir
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com 
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-23  9:52 ` Keir Fraser
@ 2006-05-23 12:22   ` Mathieu Ropert
  2006-07-27 22:14   ` Bruce Rogers
  1 sibling, 0 replies; 11+ messages in thread
From: Mathieu Ropert @ 2006-05-23 12:22 UTC (permalink / raw)
  To: Keir Fraser; +Cc: Ian Pratt, xen-devel

Keir Fraser wrote:

>
> On 23 May 2006, at 10:41, Ian Pratt wrote:
>
>> Can you explain the pagtable structure a little better please. Does the
>> L3 contain an entry point at itself (recursive), or at another L3
>> (foreign)?
>>
>> I've never come across non-root pagetable linear mappings other than in
>> the crock that is PAE (3 level) where you have to use 4 entries in an L2
>> to point to all the L2s due to the limited address space.
>
>
> And that's something we don't currently support. A slightly more 
> generic linear pagetable logic that would permit us to support linear 
> pagetables on PAE would be a good thing.
>
>  -- Keir
>

A bit more explanation:
- All my L4 tables (kernel and user) have one of their entries pointing 
on themselves.
- As I can't use the same tables in kernel and user mode on x86_64, the 
kernel table is always the same, and sometimes needs to map a user L4 to 
modify.
- In order to do that, i set an entry of the kernel L4 to the machine 
address of the wanted L4 user table. So my L4 user recursive entry is 
used as a L3 one in kernel tables.
- When i want to access a user table in kernel mode, i do 2 mmu updates:
1/ Set a L4 kernel table entry with the machine address of the L4 user 
table i want to change. This step currently works.
2/ Set the L4 user table recursive as valid (i clear the valid bit when 
i'm done with my changes, don't want the user to be able to read his 
page tables). This is where Xen refuse to update the tables.

About the possible fix, won't something like trying a 
get_linear_pagetable() at all level works? Will it cause too much overhead?
Generally speaking, is allowing a R/O mapping of another table the 
domain own (whichever level it is) safe? At first thought, i don't see 
any way of exploiting it.

Regards,
Mathieu

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-23  9:41 Ian Pratt
@ 2006-05-23  9:52 ` Keir Fraser
  2006-05-23 12:22   ` Mathieu Ropert
  2006-07-27 22:14   ` Bruce Rogers
  0 siblings, 2 replies; 11+ messages in thread
From: Keir Fraser @ 2006-05-23  9:52 UTC (permalink / raw)
  To: Ian Pratt; +Cc: xen-devel, Mathieu Ropert


On 23 May 2006, at 10:41, Ian Pratt wrote:

> Can you explain the pagtable structure a little better please. Does the
> L3 contain an entry point at itself (recursive), or at another L3
> (foreign)?
>
> I've never come across non-root pagetable linear mappings other than in
> the crock that is PAE (3 level) where you have to use 4 entries in an 
> L2
> to point to all the L2s due to the limited address space.

And that's something we don't currently support. A slightly more 
generic linear pagetable logic that would permit us to support linear 
pagetables on PAE would be a good thing.

  -- Keir

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [RESEND] Question about recursive mappings
@ 2006-05-23  9:41 Ian Pratt
  2006-05-23  9:52 ` Keir Fraser
  0 siblings, 1 reply; 11+ messages in thread
From: Ian Pratt @ 2006-05-23  9:41 UTC (permalink / raw)
  To: Mathieu Ropert, xen-devel

> Done some investingations in the mm code of Xen, i think the 
> problem is that linear page tables entries are checked only 
> on level 4 entries.
> In my case, my recursive entry is in a L3 table, already 
> validated as another type, hence not "valid" for Xen.

Can you explain the pagtable structure a little better please. Does the
L3 contain an entry point at itself (recursive), or at another L3
(foreign)?

I've never come across non-root pagetable linear mappings other than in
the crock that is PAE (3 level) where you have to use 4 entries in an L2
to point to all the L2s due to the limited address space.

What OS are you porting? Was it written for 3-level pagetables, with the
x86 4th level being added on as an afterthought, perhaps with only a
single L4 for the system and just one entry being used?

> Will authorizing L3 or L2 recursive mappings induce a 
> security hole or vulnerability?
> If not, I'll try to make a patch to address this issue (any 
> hint welcome :)).

I'm sure it can be done safely, but you'd best wrap a damp towel around
your head while thinking about how. I wouldn't want to slow down the
common case...

Ian 
 
> Regards,
> Mathieu
> 
> Mathieu Ropert wrote:
> 
> > [Previous one didn't hit list after 3 days, trying a 
> resend, sorry if 
> > both finally show up]
> >
> > Hi,
> >
> > are recursive mappings (ie: a page table entry pointing back to 
> > itself) supported by Xen (on x86_64 at least)?
> > I'm asking cause i'm seeing many error logs from get_page_type() 
> > telling something like "saw L3_page_table expected 
> L2_page_table" or 
> > "saw L4_page_table expected L3_page_table" (finally leading to a 
> > failing mmu_update, i guess others happens on user 
> pagetables switches).
> > Or maybe is there any workaround needed? (I think i saw 
> something like 
> > setting entry to 0 first then to the recursive entry somewhere, but 
> > can't remember where).
> > By the way, i'm using recursive mappings in kernel page directory 
> > (which seems ok) and i temporay make user page directory recursive 
> > when i map a user PGD in kernel space (mapping user PGD to 
> a L4 entry 
> > of kernel tables, then using kernel L4 slot and user PGD recursive 
> > entry to access user page tables).
> >
> > [edit]
> > Done some little research about the problem. Seems like 
> NetBSD use the 
> > same thing and works, but there is no x86_64 ports for now. I'm 
> > starting to think that may be a x86_64 issue, maybe because 
> recursive 
> > mappings don't lead to conflicting types with only 2 levels.
> > Xen interface states that a page can only be of one type (PGD, PT, 
> > LDT, GDT  and R/W). I don't know why there is a need to distinguish 
> > page table levels, but i'm afraid this restriction will 
> conflit with 
> > some MMU implementation on x86_64 like NetBSD and OpenBSD, 
> and maybe 
> > others (FreeBSD on top of my mind, don't know how much the pmap 
> > implementation diverged).
> > [/edit]
> >
> > Regards,
> >
> > Mathieu
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xensource.com
> > http://lists.xensource.com/xen-devel
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND] Question about recursive mappings
  2006-05-22  9:15 Mathieu Ropert
@ 2006-05-22 15:18 ` Mathieu Ropert
  0 siblings, 0 replies; 11+ messages in thread
From: Mathieu Ropert @ 2006-05-22 15:18 UTC (permalink / raw)
  To: xen-devel

Done some investingations in the mm code of Xen, i think the problem is 
that linear page tables entries are checked only on level 4 entries.
In my case, my recursive entry is in a L3 table, already validated as 
another type, hence not "valid" for Xen.
Will authorizing L3 or L2 recursive mappings induce a security hole or 
vulnerability?
If not, I'll try to make a patch to address this issue (any hint welcome 
:)).

Regards,
Mathieu

Mathieu Ropert wrote:

> [Previous one didn't hit list after 3 days, trying a resend, sorry if 
> both finally show up]
>
> Hi,
>
> are recursive mappings (ie: a page table entry pointing back to itself)
> supported by Xen (on x86_64 at least)?
> I'm asking cause i'm seeing many error logs from get_page_type() telling
> something like "saw L3_page_table expected L2_page_table" or "saw
> L4_page_table expected L3_page_table" (finally leading to a failing 
> mmu_update, i guess others happens on user pagetables switches).
> Or maybe is there any workaround needed? (I think i saw something like
> setting entry to 0 first then to the recursive entry somewhere, but
> can't remember where).
> By the way, i'm using recursive mappings in kernel page directory (which
> seems ok) and i temporay make user page directory recursive when i map
> a user PGD in kernel space (mapping user PGD to a L4 entry of kernel 
> tables, then using kernel L4 slot and user PGD recursive entry to 
> access user page tables).
>
> [edit]
> Done some little research about the problem. Seems like NetBSD use the 
> same thing and works, but there is no x86_64 ports for now. I'm 
> starting to think that may be a x86_64 issue, maybe because recursive 
> mappings don't lead to conflicting types with only 2 levels.
> Xen interface states that a page can only be of one type (PGD, PT, 
> LDT, GDT  and R/W). I don't know why there is a need to distinguish 
> page table levels, but i'm afraid this restriction will conflit with 
> some MMU implementation on x86_64 like NetBSD and OpenBSD, and maybe 
> others (FreeBSD on top of my mind, don't know how much the pmap 
> implementation diverged).
> [/edit]
>
> Regards,
>
> Mathieu
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RESEND] Question about recursive mappings
@ 2006-05-22  9:15 Mathieu Ropert
  2006-05-22 15:18 ` Mathieu Ropert
  0 siblings, 1 reply; 11+ messages in thread
From: Mathieu Ropert @ 2006-05-22  9:15 UTC (permalink / raw)
  To: xen-devel

[Previous one didn't hit list after 3 days, trying a resend, sorry if 
both finally show up]

Hi,

are recursive mappings (ie: a page table entry pointing back to itself)
supported by Xen (on x86_64 at least)?
I'm asking cause i'm seeing many error logs from get_page_type() telling
something like "saw L3_page_table expected L2_page_table" or "saw
L4_page_table expected L3_page_table" (finally leading to a failing 
mmu_update, i guess others happens on user pagetables switches).
Or maybe is there any workaround needed? (I think i saw something like
setting entry to 0 first then to the recursive entry somewhere, but
can't remember where).
By the way, i'm using recursive mappings in kernel page directory (which
seems ok) and i temporay make user page directory recursive when i map
a user PGD in kernel space (mapping user PGD to a L4 entry of kernel 
tables, then using kernel L4 slot and user PGD recursive entry to access 
user page tables).

[edit]
Done some little research about the problem. Seems like NetBSD use the 
same thing and works, but there is no x86_64 ports for now. I'm starting 
to think that may be a x86_64 issue, maybe because recursive mappings 
don't lead to conflicting types with only 2 levels.
Xen interface states that a page can only be of one type (PGD, PT, LDT, 
GDT  and R/W). I don't know why there is a need to distinguish page 
table levels, but i'm afraid this restriction will conflit with some MMU 
implementation on x86_64 like NetBSD and OpenBSD, and maybe others 
(FreeBSD on top of my mind, don't know how much the pmap implementation 
diverged).
[/edit]

Regards,

Mathieu

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-07-27 22:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-24  9:34 [RESEND] Question about recursive mappings Ian Pratt
2006-05-24 20:12 ` Mathieu Ropert
2006-05-24 20:16   ` Keir Fraser
2006-05-26  9:27     ` Mathieu Ropert
2006-05-29 11:43     ` Mathieu Ropert
  -- strict thread matches above, loose matches on Subject: below --
2006-05-23  9:41 Ian Pratt
2006-05-23  9:52 ` Keir Fraser
2006-05-23 12:22   ` Mathieu Ropert
2006-07-27 22:14   ` Bruce Rogers
2006-05-22  9:15 Mathieu Ropert
2006-05-22 15:18 ` Mathieu Ropert

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.