[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: PAE linear page tables.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1173710820 0 # Node ID b01d4f415f5fc9671b20263470c4cf2e337a29d5 # Parent 6d2328b353c842f7490ad81e20786a398a1e2ad5 x86: PAE linear page tables. 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. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- xen/arch/x86/domain.c | 28 +++++++++---- xen/arch/x86/mm.c | 102 +++++++++++++++++++++++++++----------------------- 2 files changed, 75 insertions(+), 55 deletions(-) diff -r 6d2328b353c8 -r b01d4f415f5f xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Mar 12 14:11:43 2007 +0000 +++ b/xen/arch/x86/domain.c Mon Mar 12 14:47:00 2007 +0000 @@ -1386,7 +1386,8 @@ int hypercall_xlat_continuation(unsigned } #endif -static void relinquish_memory(struct domain *d, struct list_head *list) +static void relinquish_memory(struct domain *d, struct list_head *list, + unsigned long type) { struct list_head *ent; struct page_info *page; @@ -1415,23 +1416,24 @@ static void relinquish_memory(struct dom put_page(page); /* - * Forcibly invalidate base page tables at this point to break circular - * 'linear page table' references. This is okay because MMU structures - * are not shared across domains and this domain is now dead. Thus base - * tables are not in use so a non-zero count means circular reference. + * Forcibly invalidate top-most, still valid page tables at this point + * to break circular 'linear page table' references. This is okay + * because MMU structures are not shared across domains and this domain + * is now dead. Thus top-most valid tables are not in use so a non-zero + * count means circular reference. */ y = page->u.inuse.type_info; for ( ; ; ) { x = y; if ( likely((x & (PGT_type_mask|PGT_validated)) != - (PGT_base_page_table|PGT_validated)) ) + (type|PGT_validated)) ) break; y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated); if ( likely(y == x) ) { - free_page_type(page, PGT_base_page_table); + free_page_type(page, type); break; } } @@ -1529,8 +1531,16 @@ void domain_relinquish_resources(struct destroy_gdt(v); /* Relinquish every page of memory. */ - relinquish_memory(d, &d->xenpage_list); - relinquish_memory(d, &d->page_list); +#if CONFIG_PAGING_LEVELS >= 4 + relinquish_memory(d, &d->xenpage_list, PGT_l4_page_table); + relinquish_memory(d, &d->page_list, PGT_l4_page_table); +#endif +#if CONFIG_PAGING_LEVELS >= 3 + relinquish_memory(d, &d->xenpage_list, PGT_l3_page_table); + relinquish_memory(d, &d->page_list, PGT_l3_page_table); +#endif + relinquish_memory(d, &d->xenpage_list, PGT_l2_page_table); + relinquish_memory(d, &d->page_list, PGT_l2_page_table); /* Free page used by xen oprofile buffer */ free_xenoprof_pages(d); diff -r 6d2328b353c8 -r b01d4f415f5f xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Mon Mar 12 14:11:43 2007 +0000 +++ b/xen/arch/x86/mm.c Mon Mar 12 14:47:00 2007 +0000 @@ -517,7 +517,6 @@ static int get_page_and_type_from_pagenr return 1; } -#ifndef CONFIG_X86_PAE /* We do not support guest linear mappings on PAE. */ /* * We allow root tables to map each other (a.k.a. linear page tables). It * needs some special care with reference counts and access permissions: @@ -530,48 +529,54 @@ static int get_page_and_type_from_pagenr * frame if it is mapped by a different root table. This is sufficient and * also necessary to allow validation of a root table mapping itself. */ -static int -get_linear_pagetable( - root_pgentry_t re, unsigned long re_pfn, struct domain *d) -{ - unsigned long x, y; - struct page_info *page; - unsigned long pfn; - - if ( (root_get_flags(re) & _PAGE_RW) ) - { - MEM_LOG("Attempt to create linear p.t. with write perms"); - return 0; - } - - if ( (pfn = root_get_pfn(re)) != re_pfn ) - { - /* 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_root_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 */ +#define define_get_linear_pagetable(name1, name2) \ +static int \ +get_##name1##_linear_pagetable( \ + name1##_pgentry_t pde, unsigned long pde_pfn, struct domain *d) \ +{ \ + unsigned long x, y; \ + struct page_info *page; \ + unsigned long pfn; \ + \ + if ( (name2##_get_flags(pde) & _PAGE_RW) ) \ + { \ + MEM_LOG("Attempt to create linear p.t. with write perms"); \ + return 0; \ + } \ + \ + if ( (pfn = name2##_get_pfn(pde)) != pde_pfn ) \ + { \ + /* Make sure the mapped frame belongs to the correct domain. */ \ + if ( unlikely(!get_page_from_pagenr(pfn, d)) ) \ + return 0; \ + \ + /* \ + * Ensure that the mapped frame is an already-validated page 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_##name1##_page_table|PGT_validated)) ) \ + { \ + put_page(page); \ + return 0; \ + } \ + } \ + while ( (y = cmpxchg(&page->u.inuse.type_info, x, x + 1)) != x ); \ + } \ + \ + return 1; \ +} +#if !defined(CONFIG_X86_PAE) +define_get_linear_pagetable(root,root) +#endif +#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) +define_get_linear_pagetable(l2,l2e) +#endif int get_page_from_l1e( @@ -649,10 +654,15 @@ get_page_from_l2e( } rc = get_page_and_type_from_pagenr(l2e_get_pfn(l2e), PGT_l1_page_table, d); + if ( unlikely(!rc) ) + { #if CONFIG_PAGING_LEVELS == 2 - if ( unlikely(!rc) ) - rc = get_linear_pagetable(l2e, pfn, d); + rc = get_root_linear_pagetable(l2e, pfn, d); +#else + rc = get_l2_linear_pagetable(l2e, pfn, d); #endif + } + return rc; } @@ -697,7 +707,7 @@ get_page_from_l4e( rc = get_page_and_type_from_pagenr(l4e_get_pfn(l4e), PGT_l3_page_table, d); if ( unlikely(!rc) ) - rc = get_linear_pagetable(l4e, pfn, d); + rc = get_root_linear_pagetable(l4e, pfn, d); return rc; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |