[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] CONFIG_XEN_COMPAT_030002 broken?
Gerd Hoffmann wrote: >> So far we have maintained the COMPAT code to be easily entirely strippable. >> So the change to pmd_bad() should either use kernel_page_user rather than >> _PAGE_USER, or its definition should be conditional on the COMPAT flag. > > Both ways should have the same effect as kernel_page_user is defined to > 0 for the non-compat case. Well, thinko in there, wasn't that simple. Went with the #ifdef, new version attached. cheers, Gerd -- Gerd Hoffmann <kraxel@xxxxxxx> http://www.suse.de/~kraxel/julika-dora.jpeg --- linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c | 3 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c | 51 +++++++++- linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h | 22 +++- 3 files changed, 70 insertions(+), 6 deletions(-) Index: build-64-testing-11774/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c =================================================================== --- build-64-testing-11774.orig/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c +++ build-64-testing-11774/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c @@ -250,6 +250,9 @@ void __iomem * __ioremap(unsigned long p area->phys_addr = phys_addr; addr = (void __iomem *) area->addr; flags |= _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED; +#if defined(__x86_64__) + flags |= kernel_page_user; +#endif if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr, phys_addr>>PAGE_SHIFT, size, __pgprot(flags), domid)) { Index: build-64-testing-11774/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c =================================================================== --- build-64-testing-11774.orig/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c +++ build-64-testing-11774/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c @@ -56,6 +56,11 @@ struct dma_mapping_ops* dma_ops; EXPORT_SYMBOL(dma_ops); +#ifdef CONFIG_XEN_COMPAT_030002 +unsigned long kernel_page_user = _PAGE_USER; +EXPORT_SYMBOL(kernel_page_user); +#endif + extern unsigned long *contiguous_bitmap; static unsigned long dma_reserve __initdata; @@ -507,7 +512,49 @@ static void __meminit phys_pud_init(pud_ spin_unlock(&init_mm.page_table_lock); } __flush_tlb(); -} +} + +#ifdef CONFIG_XEN_COMPAT_030002 +/* + * should we set _PAGE_USER for kernel pages? + * - must be set when running on xen 3.0.2 + * - should not be set on xen 3.0.3 (kills tlb flush optimization). + */ +static void __init check_page_user_flag(unsigned long *pmd) +{ + unsigned long addr, *pte; + mmu_update_t u; + + addr = pmd[pmd_index(__START_KERNEL_map)]; + addr_to_page(addr, pte); + + /* try to clear _PAGE_USER */ + u.ptr = virt_to_machine(pte); + u.val = pte[0] & ~_PAGE_USER; + if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) { + printk("%s: clear _PAGE_USER: mmu_update failed\n", __FUNCTION__); + return; + } + + if (pte[0] & _PAGE_USER) { + /* xen 3.0.3 automagically sets _PAGE_USER */ + printk("%s: xen 3.0.3+ detected\n", __FUNCTION__); + kernel_page_user = 0; + return; + } + printk("%s: xen 3.0.2 detected\n", __FUNCTION__); + kernel_page_user = _PAGE_USER; + + /* restore previous state */ + u.ptr = virt_to_machine(pte); + u.val = pte[0] | _PAGE_USER; + if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) { + printk("%s: set _PAGE_USER: mmu_update failed\n", __FUNCTION__); + } +} +#else +static void __init check_page_user_flag(unsigned long *pmd) {} +#endif void __init xen_init_pt(void) { @@ -524,6 +571,8 @@ void __init xen_init_pt(void) addr = page[pud_index(__START_KERNEL_map)]; addr_to_page(addr, page); + check_page_user_flag(page); + /* Construct mapping of initial pte page in our own directories. */ init_level4_pgt[pgd_index(__START_KERNEL_map)] = mk_kernel_pgd(__pa_symbol(level3_kernel_pgt)); Index: build-64-testing-11774/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h =================================================================== --- build-64-testing-11774.orig/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h +++ build-64-testing-11774/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h @@ -205,8 +205,14 @@ static inline pte_t ptep_get_and_clear_f #define _PAGE_PROTNONE 0x080 /* If not present */ #define _PAGE_NX (1UL<<_PAGE_BIT_NX) +#ifdef CONFIG_XEN_COMPAT_030002 +extern unsigned long kernel_page_user; +#else +#define kernel_page_user 0 +#endif + #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | kernel_page_user) #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -218,14 +224,15 @@ static inline pte_t ptep_get_and_clear_f #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) + #define __PAGE_KERNEL \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | kernel_page_user ) #define __PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | kernel_page_user ) #define __PAGE_KERNEL_NOCACHE \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | kernel_page_user ) #define __PAGE_KERNEL_RO \ - (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) + (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | kernel_page_user ) #define __PAGE_KERNEL_VSYSCALL \ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define __PAGE_KERNEL_VSYSCALL_NOCACHE \ @@ -235,6 +242,7 @@ static inline pte_t ptep_get_and_clear_f #define __PAGE_KERNEL_LARGE_EXEC \ (__PAGE_KERNEL_EXEC | _PAGE_PSE) + /* * We don't support GLOBAL page in xenolinux64 */ @@ -422,7 +430,11 @@ static inline pud_t *pud_offset_k(pgd_t can temporarily clear it. */ #define pmd_present(x) (pmd_val(x)) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#ifdef CONFIG_XEN_COMPAT_030002 +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_USER & ~_PAGE_PRESENT)) +#else #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT)) +#endif #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot))) #define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |