--- xen-unstable//./xen/include/asm-x86/x86_32/page.h 2008-07-17 09:49:27.000000000 -0500 +++ xen-hpage/./xen/include/asm-x86/x86_32/page.h 2008-10-02 15:07:34.000000000 -0500 @@ -112,7 +112,7 @@ extern unsigned int PAGE_HYPERVISOR_NOCA * Disallow unused flag bits plus PAT/PSE, PCD, PWT and GLOBAL. * Permit the NX bit if the hardware supports it. */ -#define BASE_DISALLOW_MASK (0xFFFFF198U & ~_PAGE_NX) +#define BASE_DISALLOW_MASK (0xFFFFF118U & ~_PAGE_NX) #define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB) #define L2_DISALLOW_MASK (BASE_DISALLOW_MASK) --- xen-unstable//./xen/include/asm-x86/x86_64/page.h 2008-10-02 14:23:17.000000000 -0500 +++ xen-hpage/./xen/include/asm-x86/x86_64/page.h 2008-10-02 15:07:34.000000000 -0500 @@ -112,7 +112,7 @@ typedef l4_pgentry_t root_pgentry_t; * Permit the NX bit if the hardware supports it. * Note that range [62:52] is available for software use on x86/64. */ -#define BASE_DISALLOW_MASK (0xFF800198U & ~_PAGE_NX) +#define BASE_DISALLOW_MASK (0xFF800118U & ~_PAGE_NX) #define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB) #define L2_DISALLOW_MASK (BASE_DISALLOW_MASK) --- xen-unstable//./xen/arch/x86/mm.c 2008-10-02 14:23:17.000000000 -0500 +++ xen-hpage/./xen/arch/x86/mm.c 2008-10-02 16:00:47.000000000 -0500 @@ -759,11 +759,29 @@ get_page_from_l2e( MEM_LOG("Bad L2 flags %x", l2e_get_flags(l2e) & L2_DISALLOW_MASK); return -EINVAL; } + if ( l2e_get_flags(l2e) & _PAGE_PSE ) { + unsigned long mfn = l2e_get_pfn(l2e); + unsigned long m, me; + struct page_info *page = mfn_to_page(mfn); - rc = get_page_and_type_from_pagenr( - l2e_get_pfn(l2e), PGT_l1_page_table, d, 0); - if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) ) - rc = 0; + rc = get_page(page, d); + if (unlikely(!rc)) { + return rc; + } + + for (m = mfn+1, me = m + (L1_PAGETABLE_ENTRIES-1); m <= me; m++) { + get_page_from_pagenr(m, d); + } +#ifdef __x86_64__ + map_pages_to_xen((unsigned long)mfn_to_virt(mfn), mfn, L1_PAGETABLE_ENTRIES, + PAGE_HYPERVISOR | l2e_get_flags(l2e)); +#endif + } else { + rc = get_page_and_type_from_pagenr( + l2e_get_pfn(l2e), PGT_l1_page_table, d, 0); + if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) ) + rc = 0; + } return rc; } @@ -955,7 +973,18 @@ static int put_page_from_l2e(l2_pgentry_ if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && (l2e_get_pfn(l2e) != pfn) ) { - put_page_and_type(l2e_get_page(l2e)); + if (l2e_get_flags(l2e) & _PAGE_PSE) { + unsigned long mfn = l2e_get_pfn(l2e); + unsigned long m, me; + struct page_info *page = mfn_to_page(mfn); + + for (m = mfn+1, me = m + (L1_PAGETABLE_ENTRIES-1); m <= me; m++) { + put_page(mfn_to_page(m)); + } + put_page(page); + } else { + put_page_and_type(l2e_get_page(l2e)); + } return 0; } return 1;