[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/PAE partially linear page table support
While full linear page table support makes little sense (and would be more complicated to implement), partial linear page table support is almost identical to that in non-PAE, and is used (at least) by NetWare. Of course, the question here is whether this shouldn't be generalized - all validated page tables (except for top level PAE) could be allowed to be installed at lower levels using the same scheme. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> Index: 2007-02-07/xen/arch/x86/mm.c =================================================================== --- 2007-02-07.orig/xen/arch/x86/mm.c 2007-02-07 16:08:05.000000000 +0100 +++ 2007-02-07/xen/arch/x86/mm.c 2007-02-07 16:31:33.000000000 +0100 @@ -547,7 +547,7 @@ get_linear_pagetable( return 0; /* - * Make sure that the mapped frame is an already-validated L2 table. + * Make sure that the mapped frame is an already-validated root table. * If so, atomically increment the count (checking for overflow). */ page = mfn_to_page(pfn); @@ -569,6 +569,51 @@ get_linear_pagetable( } #endif /* !CONFIG_X86_PAE */ +#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) +static int +get_l2_linear_pagetable( + l2_pgentry_t l2e, unsigned long l2e_pfn, struct domain *d) +{ + unsigned long pfn; + + if ( (l2e_get_flags(l2e) & _PAGE_RW) ) + { + MEM_LOG("Attempt to create linear p.t. with write perms"); + return 0; + } + + if ( (pfn = l2e_get_pfn(l2e)) != l2e_pfn ) + { + unsigned long x, y; + struct page_info *page; + + /* Make sure the mapped frame belongs to the correct domain. */ + if ( unlikely(!get_page_from_pagenr(pfn, d)) ) + return 0; + + /* + * Make sure that the mapped frame is an already-validated L2 table. + * If so, atomically increment the count (checking for overflow). + */ + page = mfn_to_page(pfn); + y = page->u.inuse.type_info; + do { + x = y; + if ( unlikely((x & PGT_count_mask) == PGT_count_mask) || + unlikely((x & (PGT_type_mask|PGT_validated)) != + (PGT_l2_page_table|PGT_validated)) ) + { + put_page(page); + return 0; + } + } + while ( (y = cmpxchg(&page->u.inuse.type_info, x, x + 1)) != x ); + } + + return 1; +} +#endif /* !CONFIG_X86_PAE */ + int get_page_from_l1e( l1_pgentry_t l1e, struct domain *d) @@ -645,10 +690,16 @@ get_page_from_l2e( } rc = get_page_and_type_from_pagenr(l2e_get_pfn(l2e), PGT_l1_page_table, d); -#if CONFIG_PAGING_LEVELS == 2 if ( unlikely(!rc) ) + { +#if CONFIG_PAGING_LEVELS == 2 rc = get_linear_pagetable(l2e, pfn, d); +#else + if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) ) + rc = get_l2_linear_pagetable(l2e, pfn, d); #endif + } + return rc; } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |