aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/Kconfig2
-rw-r--r--arch/sparc64/kernel/ktlb.S16
-rw-r--r--arch/sparc64/mm/init.c52
-rw-r--r--include/asm-sparc64/pgtable.h3
4 files changed, 72 insertions, 1 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 33dabf588bdd..2f22fa90461a 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -240,10 +240,10 @@ config ARCH_SELECT_MEMORY_MODEL
240 240
241config ARCH_SPARSEMEM_ENABLE 241config ARCH_SPARSEMEM_ENABLE
242 def_bool y 242 def_bool y
243 select SPARSEMEM_VMEMMAP_ENABLE
243 244
244config ARCH_SPARSEMEM_DEFAULT 245config ARCH_SPARSEMEM_DEFAULT
245 def_bool y 246 def_bool y
246 select SPARSEMEM_STATIC
247 247
248source "mm/Kconfig" 248source "mm/Kconfig"
249 249
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index d4024ac0d619..964527d2ffa0 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -226,6 +226,15 @@ kvmap_dtlb_load:
226 ba,pt %xcc, sun4v_dtlb_load 226 ba,pt %xcc, sun4v_dtlb_load
227 mov %g5, %g3 227 mov %g5, %g3
228 228
229kvmap_vmemmap:
230 sub %g4, %g5, %g5
231 srlx %g5, 22, %g5
232 sethi %hi(vmemmap_table), %g1
233 sllx %g5, 3, %g5
234 or %g1, %lo(vmemmap_table), %g1
235 ba,pt %xcc, kvmap_dtlb_load
236 ldx [%g1 + %g5], %g5
237
229kvmap_dtlb_nonlinear: 238kvmap_dtlb_nonlinear:
230 /* Catch kernel NULL pointer derefs. */ 239 /* Catch kernel NULL pointer derefs. */
231 sethi %hi(PAGE_SIZE), %g5 240 sethi %hi(PAGE_SIZE), %g5
@@ -233,6 +242,13 @@ kvmap_dtlb_nonlinear:
233 bleu,pn %xcc, kvmap_dtlb_longpath 242 bleu,pn %xcc, kvmap_dtlb_longpath
234 nop 243 nop
235 244
245 /* Do not use the TSB for vmemmap. */
246 mov (VMEMMAP_BASE >> 24), %g5
247 sllx %g5, 24, %g5
248 cmp %g4,%g5
249 bgeu,pn %xcc, kvmap_vmemmap
250 nop
251
236 KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load) 252 KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
237 253
238kvmap_dtlb_tsbmiss: 254kvmap_dtlb_tsbmiss:
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index f0ab9aab308f..69538d1aa0ad 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1645,6 +1645,58 @@ EXPORT_SYMBOL(_PAGE_E);
1645unsigned long _PAGE_CACHE __read_mostly; 1645unsigned long _PAGE_CACHE __read_mostly;
1646EXPORT_SYMBOL(_PAGE_CACHE); 1646EXPORT_SYMBOL(_PAGE_CACHE);
1647 1647
1648#ifdef CONFIG_SPARSEMEM_VMEMMAP
1649
1650#define VMEMMAP_CHUNK_SHIFT 22
1651#define VMEMMAP_CHUNK (1UL << VMEMMAP_CHUNK_SHIFT)
1652#define VMEMMAP_CHUNK_MASK ~(VMEMMAP_CHUNK - 1UL)
1653#define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
1654
1655#define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
1656 sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
1657unsigned long vmemmap_table[VMEMMAP_SIZE];
1658
1659int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
1660{
1661 unsigned long vstart = (unsigned long) start;
1662 unsigned long vend = (unsigned long) (start + nr);
1663 unsigned long phys_start = (vstart - VMEMMAP_BASE);
1664 unsigned long phys_end = (vend - VMEMMAP_BASE);
1665 unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK;
1666 unsigned long end = VMEMMAP_ALIGN(phys_end);
1667 unsigned long pte_base;
1668
1669 pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4U |
1670 _PAGE_CP_4U | _PAGE_CV_4U |
1671 _PAGE_P_4U | _PAGE_W_4U);
1672 if (tlb_type == hypervisor)
1673 pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
1674 _PAGE_CP_4V | _PAGE_CV_4V |
1675 _PAGE_P_4V | _PAGE_W_4V);
1676
1677 for (; addr < end; addr += VMEMMAP_CHUNK) {
1678 unsigned long *vmem_pp =
1679 vmemmap_table + (addr >> VMEMMAP_CHUNK_SHIFT);
1680 void *block;
1681
1682 if (!(*vmem_pp & _PAGE_VALID)) {
1683 block = vmemmap_alloc_block(1UL << 22, node);
1684 if (!block)
1685 return -ENOMEM;
1686
1687 *vmem_pp = pte_base | __pa(block);
1688
1689 printk(KERN_INFO "[%p-%p] page_structs=%lu "
1690 "node=%d entry=%lu/%lu\n", start, block, nr,
1691 node,
1692 addr >> VMEMMAP_CHUNK_SHIFT,
1693 VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
1694 }
1695 }
1696 return 0;
1697}
1698#endif /* CONFIG_SPARSEMEM_VMEMMAP */
1699
1648static void prot_init_common(unsigned long page_none, 1700static void prot_init_common(unsigned long page_none,
1649 unsigned long page_shared, 1701 unsigned long page_shared,
1650 unsigned long page_copy, 1702 unsigned long page_copy,
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 0393380d754a..3167ccff64f8 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -42,6 +42,9 @@
42#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) 42#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
43#define VMALLOC_START _AC(0x0000000100000000,UL) 43#define VMALLOC_START _AC(0x0000000100000000,UL)
44#define VMALLOC_END _AC(0x0000000200000000,UL) 44#define VMALLOC_END _AC(0x0000000200000000,UL)
45#define VMEMMAP_BASE _AC(0x0000000200000000,UL)
46
47#define vmemmap ((struct page *)VMEMMAP_BASE)
45 48
46/* XXX All of this needs to be rethought so we can take advantage 49/* XXX All of this needs to be rethought so we can take advantage
47 * XXX cheetah's full 64-bit virtual address space, ie. no more hole 50 * XXX cheetah's full 64-bit virtual address space, ie. no more hole