Skip to contentSkip to conversation

x86: a couple of misc patches

PATCH In review Jeremy Fitzhardinge 2 participants 4 messages Jan 10, 2008 – Jan 11, 2008

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

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

#1 lore raw

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
#2 lore raw

PATCH 1/1 x86: use common _PAGE_NOCACHE

In reply to Jeremy Fitzhardinge

Since 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 (unsigned 
 void __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 pt
 	if (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))
 
 
 /*
#3 lore raw
In reply to Jeremy Fitzhardinge
Quoted 3 lines

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?

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