ia64/xen-unstable

changeset 12440:bb76a76985fe

[LINUX] x86/64: Fix backward compatibility to Xen 3.0.2.
This requires us to explicitly specify _PAGE_USER for kernel mappings.
Original patch by Jan Beulich <jbeulich@novell.com> and Gerd Hoffmann.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Nov 14 17:00:05 2006 +0000 (2006-11-14)
parents 680b37789200
children a07d6a05792e
files linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c	Tue Nov 14 11:21:26 2006 -0500
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c	Tue Nov 14 17:00:05 2006 +0000
     1.3 @@ -249,7 +249,7 @@ void __iomem * __ioremap(unsigned long p
     1.4  		return NULL;
     1.5  	area->phys_addr = phys_addr;
     1.6  	addr = (void __iomem *) area->addr;
     1.7 -	flags |= _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;
     1.8 +	flags |= _KERNPG_TABLE;
     1.9  	if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
    1.10  				     phys_addr>>PAGE_SHIFT,
    1.11  				     size, __pgprot(flags), domid)) {
     2.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Nov 14 11:21:26 2006 -0500
     2.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Nov 14 17:00:05 2006 +0000
     2.3 @@ -56,6 +56,11 @@
     2.4  struct dma_mapping_ops* dma_ops;
     2.5  EXPORT_SYMBOL(dma_ops);
     2.6  
     2.7 +#ifdef CONFIG_XEN_COMPAT_030002
     2.8 +unsigned int __kernel_page_user;
     2.9 +EXPORT_SYMBOL(__kernel_page_user);
    2.10 +#endif
    2.11 +
    2.12  extern unsigned long *contiguous_bitmap;
    2.13  
    2.14  static unsigned long dma_reserve __initdata;
    2.15 @@ -527,6 +532,33 @@ void __init xen_init_pt(void)
    2.16  	addr = page[pud_index(__START_KERNEL_map)];
    2.17  	addr_to_page(addr, page);
    2.18  
    2.19 +#ifdef CONFIG_XEN_COMPAT_030002
    2.20 +	/* On Xen 3.0.2 and older we may need to explicitly specify _PAGE_USER
    2.21 +	   in kernel PTEs. We check that here. */
    2.22 +	if (HYPERVISOR_xen_version(XENVER_version, NULL) <= 0x30000) {
    2.23 +		unsigned long *pg;
    2.24 +		pte_t pte;
    2.25 +
    2.26 +		/* Mess with the initial mapping of page 0. It's not needed. */
    2.27 +		BUILD_BUG_ON(__START_KERNEL <= __START_KERNEL_map);
    2.28 +		addr = page[pmd_index(__START_KERNEL_map)];
    2.29 +		addr_to_page(addr, pg);
    2.30 +		pte.pte = pg[pte_index(__START_KERNEL_map)];
    2.31 +		BUG_ON(!(pte.pte & _PAGE_PRESENT));
    2.32 +
    2.33 +		/* If _PAGE_USER isn't set, we obviously do not need it. */
    2.34 +		if (pte.pte & _PAGE_USER) {
    2.35 +			/* _PAGE_USER is needed, but is it set implicitly? */
    2.36 +			pte.pte &= ~_PAGE_USER;
    2.37 +			if ((HYPERVISOR_update_va_mapping(__START_KERNEL_map,
    2.38 +							  pte, 0) != 0) ||
    2.39 +			    !(pg[pte_index(__START_KERNEL_map)] & _PAGE_USER))
    2.40 +				/* We need to explicitly specify _PAGE_USER. */
    2.41 +				__kernel_page_user = _PAGE_USER;
    2.42 +		}
    2.43 +	}
    2.44 +#endif
    2.45 +
    2.46  	/* Construct mapping of initial pte page in our own directories. */
    2.47  	init_level4_pgt[pgd_index(__START_KERNEL_map)] = 
    2.48  		mk_kernel_pgd(__pa_symbol(level3_kernel_pgt));
     3.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h	Tue Nov 14 11:21:26 2006 -0500
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h	Tue Nov 14 17:00:05 2006 +0000
     3.3 @@ -205,8 +205,14 @@ static inline pte_t ptep_get_and_clear_f
     3.4  #define _PAGE_PROTNONE	0x080	/* If not present */
     3.5  #define _PAGE_NX        (1UL<<_PAGE_BIT_NX)
     3.6  
     3.7 +#ifdef CONFIG_XEN_COMPAT_030002
     3.8 +extern unsigned int __kernel_page_user;
     3.9 +#else
    3.10 +#define __kernel_page_user 0
    3.11 +#endif
    3.12 +
    3.13  #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
    3.14 -#define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
    3.15 +#define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
    3.16  
    3.17  #define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
    3.18  
    3.19 @@ -219,13 +225,13 @@ static inline pte_t ptep_get_and_clear_f
    3.20  #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
    3.21  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
    3.22  #define __PAGE_KERNEL \
    3.23 -	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
    3.24 +	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
    3.25  #define __PAGE_KERNEL_EXEC \
    3.26 -	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
    3.27 +	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | __kernel_page_user)
    3.28  #define __PAGE_KERNEL_NOCACHE \
    3.29 -	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
    3.30 +	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
    3.31  #define __PAGE_KERNEL_RO \
    3.32 -	(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
    3.33 +	(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
    3.34  #define __PAGE_KERNEL_VSYSCALL \
    3.35  	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
    3.36  #define __PAGE_KERNEL_VSYSCALL_NOCACHE \
    3.37 @@ -422,7 +428,8 @@ static inline pud_t *pud_offset_k(pgd_t 
    3.38     can temporarily clear it. */
    3.39  #define pmd_present(x)	(pmd_val(x))
    3.40  #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
    3.41 -#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
    3.42 +#define pmd_bad(x) ((pmd_val(x) & ~(PTE_MASK | _PAGE_USER | _PAGE_PRESENT)) \
    3.43 +		    != (_KERNPG_TABLE & ~(_PAGE_USER | _PAGE_PRESENT)))
    3.44  #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
    3.45  #define pmd_pfn(x)  ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
    3.46