Skip to contentSkip to conversation

- Map UV chipset space - pagetable

PATCH Applied Jack Steiner 3 participants 4 messages Jul 1, 2008 – Jul 10, 2008

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

PATCH 1/2 - Map UV chipset space - pagetable

Add boot-time function for creating additional 2MB page table entries for mapping chipset specific cached/uncached ranges.

---
 arch/x86/mm/init_64.c     |   40 ++++++++++++++++++++++++++++++++++++++++
 include/asm-x86/page_64.h |    4 ++++
 include/asm-x86/pgtable.h |    2 ++
 3 files changed, 46 insertions(+)
arch/x86/mm/init_64.c +40 -0
Index: linux/arch/x86/mm/init_64.c
===================================================================
@@ -198,6 +198,46 @@ set_pte_vaddr(unsigned long vaddr, pte_t
 }
 
 /*
+ * Create large page table mappings for a range of physical addresses.
+ */
+static void __init __init_extra_mapping(unsigned long phys, unsigned long size,
+						pgprot_t prot)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+
+	BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK));
+	for (; size; phys += PMD_SIZE, size -= PMD_SIZE) {
+		pgd = pgd_offset_k((unsigned long)__va(phys));
+		if (pgd_none(*pgd)) {
+			pud = (pud_t *) spp_getpage();
+			set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
+						_PAGE_USER));
+		}
+		pud = pud_offset(pgd, (unsigned long)__va(phys));
+		if (pud_none(*pud)) {
+			pmd = (pmd_t *) spp_getpage();
+			set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
+						_PAGE_USER));
+		}
+		pmd = pmd_offset(pud, phys);
+		BUG_ON(!pmd_none(*pmd));
+		set_pmd(pmd, __pmd(phys | pgprot_val(prot)));
+	}
+}
+
+void __init init_extra_mapping_wb(unsigned long phys, unsigned long size)
+{
+	__init_extra_mapping(phys, size, PAGE_KERNEL_LARGE);
+}
+
+void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
+{
+	__init_extra_mapping(phys, size, PAGE_KERNEL_LARGE_NOCACHE);
+}
+
+/*
  * The head.S code sets up the kernel high mapping:
  *
  *   from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
include/asm-x86/pgtable.h +2 -0
Index: linux/include/asm-x86/pgtable.h
===================================================================
@@ -101,6 +101,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
 #define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RX | _PAGE_USER)
 #define __PAGE_KERNEL_VSYSCALL_NOCACHE	(__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
 #define __PAGE_KERNEL_LARGE		(__PAGE_KERNEL | _PAGE_PSE)
+#define __PAGE_KERNEL_LARGE_NOCACHE	(__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
 #define __PAGE_KERNEL_LARGE_EXEC	(__PAGE_KERNEL_EXEC | _PAGE_PSE)
 
 #ifdef CONFIG_X86_32
@@ -118,6 +119,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
 #define PAGE_KERNEL_UC_MINUS		MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS)
 #define PAGE_KERNEL_EXEC_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE)
 #define PAGE_KERNEL_LARGE		MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
+#define PAGE_KERNEL_LARGE_NOCACHE	MAKE_GLOBAL(__PAGE_KERNEL_LARGE_NOCACHE)
 #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)
include/asm-x86/page_64.h +4 -0
Index: linux/include/asm-x86/page_64.h
===================================================================
@@ -84,6 +84,10 @@ extern unsigned long init_memory_mapping
 					 unsigned long end);
 
 extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+
+extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
+extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
+
 #endif	/* !__ASSEMBLY__ */
 
 #ifdef CONFIG_FLATMEM

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#2 lore raw
In reply to Jack Steiner

arch/x86/mm/init_64.c set_pte_vaddr(unsigned long vaddr, pte_t · line 210

Quoted 1 line · On Tue, 1 Jul 2008 14:45:32 -0500 Jack Steiner <[email protected]> wrote:
arch/x86/mm/init_64.c +1 -0
+	BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK));

BUG_ON(A || B) is usually a bad idea. If it goes bang, you'll really wish that it had been

	BUG_ON(A);
	BUG_ON(B);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
Quoted 9 lines · Andrew Morton

arch/x86/mm/init_64.c set_pte_vaddr(unsigned long vaddr, pte_t · line 210

Quoted 1 line · On Tue, 1 Jul 2008 14:45:32 -0500 Jack Steiner <[email protected]> wrote:
arch/x86/mm/init_64.c +1 -0
+	BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK));

BUG_ON(A || B) is usually a bad idea. If it goes bang, you'll really wish that it had been

	BUG_ON(A);
	BUG_ON(B);

if you check how it's used:

+ init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE);
+ init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE);

those base/size pairs are really supposed to be aligned on 2MB. I.e. this is a really 'impossible' scenario that is not really driven by any external factor (hw or driver detail) and a compact check for it is acceptable too.

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>