x86: a couple of misc patches
Subsystems (4)
PATCH 1/1 x86: a couple of misc patches
Hi Ingo,
A couple of patches:
1. Fold _PAGE_GLOBAL back into 64-bit __PAGE_KERNEL*, and remove the MAKE_GLOBAL hack. Not sure if it will work, but the iounmap problem should have been fixed by Jan's patch.
2. I noticed the _PAGE_PCD|_PAGE_PWT combination being used a lot, so I created _PAGE_NOCACHE to wrap them up. asm-x86/fb.h uses plain _PAGE_PCD; should it be _PAGE_NOCACHE too?
Thanks,
J
PATCH 1/1 x86: fold _PAGE_GLOBAL into __PAGE_KERNEL
With the iounmap problem resolved, it should be OK to always set _PAGE_GLOBAL in __PAGE_KERNEL*.
--- arch/x86/mm/ioremap_64.c | 2 +- include/asm-x86/pgtable.h | 26 ++++++++++---------------- 2 files changed, 11 insertions(+), 17 deletions(-)
arch/x86/mm/ioremap_64.c +1 -1
@@ -50,7 +50,7 @@ ioremap_change_attr(unsigned long phys_a* memmap entry: */ err =change_page_attr_addr (vaddr, npages, -MAKE_GLOBAL (__PAGE_KERNEL|flags)); +__pgprot (__PAGE_KERNEL|flags));if (!err)global_flush_tlb (); }
include/asm-x86/pgtable.h +10 -16
@@ -68,7 +68,7 @@ extern unsigned long long __PAGE_KERNEL,#endif /* __ASSEMBLER__ */ #else #define __PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)#define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)#endif
@@ -80,21 +80,15 @@ extern unsigned long long __PAGE_KERNEL,#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) -#ifdef CONFIG_X86_32 -# define MAKE_GLOBAL (x) __pgprot((x)) -#else -# define MAKE_GLOBAL (x) __pgprot((x) | _PAGE_GLOBAL) -#endif - -#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) -#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) -#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX) -#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE) -#define PAGE_KERNEL_LARGE_EXEC MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC) -#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) -#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE) +#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) +#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) +#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) +#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) +#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)/* xwr */ #define __P000 PAGE_NONE
PATCH 1/1 x86: use common _PAGE_NOCACHE
In reply to Jeremy FitzhardingeSince it seems that every use of _PAGE_PCD also sets _PAGE_PWT, define _PAGE_NOCACHE with this combination.
--- arch/x86/mm/ioremap_32.c | 2 +- arch/x86/mm/ioremap_64.c | 2 +- arch/x86/pci/i386.c | 2 +- arch/x86/xen/mmu.c | 4 ++-- include/asm-x86/pgtable.h | 6 ++++-- include/asm-x86/pgtable_32.h | 2 +- include/asm-x86/pgtable_64.h | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-)
arch/x86/mm/ioremap_32.c +1 -1
@@ -119,7 +119,7 @@ void __iomem *ioremap_nocache (unsignedvoid __iomem *ioremap_nocache (unsigned long phys_addr,unsigned long size) {unsigned long last_addr; -void __iomem *p =__ioremap (phys_addr, size, _PAGE_PCD | _PAGE_PWT); +void __iomem *p =__ioremap (phys_addr, size, _PAGE_NOCACHE);if (!p)return p;
arch/x86/mm/ioremap_64.c +1 -1
@@ -142,7 +142,7 @@ EXPORT_SYMBOL(__ioremap);void __iomem *ioremap_nocache (unsigned long phys_addr,unsigned long size) { -return __ioremap (phys_addr, size, _PAGE_PCD | _PAGE_PWT); +return __ioremap (phys_addr, size, _PAGE_NOCACHE); }EXPORT_SYMBOL (ioremap_nocache);
arch/x86/pci/i386.c +1 -1
@@ -313,7 +313,7 @@ int pci_mmap_page_range(struct pci_dev **/ prot =pgprot_val (vma->vm_page_prot);if (boot_cpu_data.x86 >3 ) - prot |= _PAGE_PCD | _PAGE_PWT; + prot |= _PAGE_NOCACHE; vma->vm_page_prot =__pgprot (prot);/* Write-combine setting is ignored, it is changed via the mtrr
arch/x86/xen/mmu.c +2 -2
@@ -244,7 +244,7 @@ pte_t xen_make_pte(unsigned long long ptif (pte &1 ) pte =phys_to_machine (XPADDR (pte)).maddr; - pte &= ~(_PAGE_PCD | _PAGE_PWT); + pte &= ~_PAGE_NOCACHE;return (pte_t ){ .pte = pte }; }
@@ -293,7 +293,7 @@ pte_t xen_make_pte(unsigned long pte)if (pte & _PAGE_PRESENT) pte =phys_to_machine (XPADDR (pte)).maddr; - pte &= ~(_PAGE_PCD | _PAGE_PWT); + pte &= ~_PAGE_NOCACHE;return (pte_t ){ pte }; }
include/asm-x86/pgtable.h +4 -2
@@ -31,6 +31,8 @@#define _PAGE_UNUSED1 (_AC(1, UL)<<_PAGE_BIT_UNUSED1)#define _PAGE_UNUSED2 (_AC(1, UL)<<_PAGE_BIT_UNUSED2)#define _PAGE_UNUSED3 (_AC(1, UL)<<_PAGE_BIT_UNUSED3) + +#define _PAGE_NOCACHE (_PAGE_PCD | _PAGE_PWT)#if defined(CONFIG_X86_64 ) || defined(CONFIG_X86_PAE )#define _PAGE_NX (_AC(1, ULL) << _PAGE_BIT_NX)
@@ -74,9 +76,9 @@ extern unsigned long long __PAGE_KERNEL,#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) -#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_NOCACHE)#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_NOCACHE)#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
include/asm-x86/pgtable_32.h +1 -1
@@ -121,7 +121,7 @@ static inline void clone_pgd_range(pgd_t* it, this is a no-op. */ #define pgprot_noncached (prot) ((boot_cpu_data.x86 > 3) \ - ? (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) : (prot)) + ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE)) : (prot))/* * Conversion functions: convert a page and protection to a page entry,
include/asm-x86/pgtable_64.h +1 -1
@@ -167,7 +167,7 @@ static inline unsigned long pmd_bad(pmd_/* * Macro to mark a page protection value as "uncacheable". */ -#define pgprot_noncached (prot) (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) +#define pgprot_noncached (prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE))/*
Quoted 3 lines
2. I noticed the _PAGE_PCD|_PAGE_PWT combination being used a lot, so I created
_PAGE_NOCACHEto wrap them up.asm-x86/fb.huses plain_PAGE_PCD; should it be_PAGE_NOCACHEtoo?
Setting PCD but not PWT (or the other way around) is yielding not fully defined behavior (model specific) as per the doc, so it doen't seem to be too good an idea to use this. However, adding PWT here may not be what is desirable either (as it'll make the referenced memory UC unconditionally, whereas WC is generally more desirable here). It would seem to me, though, that PWT alone would be the better choice in this situation (despite this also yielding model specific behavior).
Jan