diff options
author | David S. Miller <davem@davemloft.net> | 2014-09-27 00:19:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-05 19:53:38 -0400 |
commit | ac55c768143aa34cc3789c4820cbb0809a76fd9c (patch) | |
tree | f6bb7af5b71e7935169a778e3f7e7694fbd1416f /arch/sparc | |
parent | 473ad7f4fb005d1bb727e4ef27d370d28703a062 (diff) |
sparc64: Switch to 4-level page tables.
This has become necessary with chips that support more than 43-bits
of physical addressing.
Based almost entirely upon a patch by Bob Picco.
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Bob Picco <bob.picco@oracle.com>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/include/asm/page_64.h | 6 | ||||
-rw-r--r-- | arch/sparc/include/asm/pgalloc_64.h | 28 | ||||
-rw-r--r-- | arch/sparc/include/asm/pgtable_64.h | 37 | ||||
-rw-r--r-- | arch/sparc/include/asm/tsb.h | 10 | ||||
-rw-r--r-- | arch/sparc/kernel/smp_64.c | 7 | ||||
-rw-r--r-- | arch/sparc/mm/init_64.c | 31 |
6 files changed, 109 insertions, 10 deletions
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index bf109984a032..09ceb68e72b7 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h | |||
@@ -57,18 +57,21 @@ void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topa | |||
57 | typedef struct { unsigned long pte; } pte_t; | 57 | typedef struct { unsigned long pte; } pte_t; |
58 | typedef struct { unsigned long iopte; } iopte_t; | 58 | typedef struct { unsigned long iopte; } iopte_t; |
59 | typedef struct { unsigned long pmd; } pmd_t; | 59 | typedef struct { unsigned long pmd; } pmd_t; |
60 | typedef struct { unsigned long pud; } pud_t; | ||
60 | typedef struct { unsigned long pgd; } pgd_t; | 61 | typedef struct { unsigned long pgd; } pgd_t; |
61 | typedef struct { unsigned long pgprot; } pgprot_t; | 62 | typedef struct { unsigned long pgprot; } pgprot_t; |
62 | 63 | ||
63 | #define pte_val(x) ((x).pte) | 64 | #define pte_val(x) ((x).pte) |
64 | #define iopte_val(x) ((x).iopte) | 65 | #define iopte_val(x) ((x).iopte) |
65 | #define pmd_val(x) ((x).pmd) | 66 | #define pmd_val(x) ((x).pmd) |
67 | #define pud_val(x) ((x).pud) | ||
66 | #define pgd_val(x) ((x).pgd) | 68 | #define pgd_val(x) ((x).pgd) |
67 | #define pgprot_val(x) ((x).pgprot) | 69 | #define pgprot_val(x) ((x).pgprot) |
68 | 70 | ||
69 | #define __pte(x) ((pte_t) { (x) } ) | 71 | #define __pte(x) ((pte_t) { (x) } ) |
70 | #define __iopte(x) ((iopte_t) { (x) } ) | 72 | #define __iopte(x) ((iopte_t) { (x) } ) |
71 | #define __pmd(x) ((pmd_t) { (x) } ) | 73 | #define __pmd(x) ((pmd_t) { (x) } ) |
74 | #define __pud(x) ((pud_t) { (x) } ) | ||
72 | #define __pgd(x) ((pgd_t) { (x) } ) | 75 | #define __pgd(x) ((pgd_t) { (x) } ) |
73 | #define __pgprot(x) ((pgprot_t) { (x) } ) | 76 | #define __pgprot(x) ((pgprot_t) { (x) } ) |
74 | 77 | ||
@@ -77,18 +80,21 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
77 | typedef unsigned long pte_t; | 80 | typedef unsigned long pte_t; |
78 | typedef unsigned long iopte_t; | 81 | typedef unsigned long iopte_t; |
79 | typedef unsigned long pmd_t; | 82 | typedef unsigned long pmd_t; |
83 | typedef unsigned long pud_t; | ||
80 | typedef unsigned long pgd_t; | 84 | typedef unsigned long pgd_t; |
81 | typedef unsigned long pgprot_t; | 85 | typedef unsigned long pgprot_t; |
82 | 86 | ||
83 | #define pte_val(x) (x) | 87 | #define pte_val(x) (x) |
84 | #define iopte_val(x) (x) | 88 | #define iopte_val(x) (x) |
85 | #define pmd_val(x) (x) | 89 | #define pmd_val(x) (x) |
90 | #define pud_val(x) (x) | ||
86 | #define pgd_val(x) (x) | 91 | #define pgd_val(x) (x) |
87 | #define pgprot_val(x) (x) | 92 | #define pgprot_val(x) (x) |
88 | 93 | ||
89 | #define __pte(x) (x) | 94 | #define __pte(x) (x) |
90 | #define __iopte(x) (x) | 95 | #define __iopte(x) (x) |
91 | #define __pmd(x) (x) | 96 | #define __pmd(x) (x) |
97 | #define __pud(x) (x) | ||
92 | #define __pgd(x) (x) | 98 | #define __pgd(x) (x) |
93 | #define __pgprot(x) (x) | 99 | #define __pgprot(x) (x) |
94 | 100 | ||
diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h index 39a7ac49b00c..5e3187185b4a 100644 --- a/arch/sparc/include/asm/pgalloc_64.h +++ b/arch/sparc/include/asm/pgalloc_64.h | |||
@@ -15,6 +15,13 @@ | |||
15 | 15 | ||
16 | extern struct kmem_cache *pgtable_cache; | 16 | extern struct kmem_cache *pgtable_cache; |
17 | 17 | ||
18 | static inline void __pgd_populate(pgd_t *pgd, pud_t *pud) | ||
19 | { | ||
20 | pgd_set(pgd, pud); | ||
21 | } | ||
22 | |||
23 | #define pgd_populate(MM, PGD, PUD) __pgd_populate(PGD, PUD) | ||
24 | |||
18 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 25 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
19 | { | 26 | { |
20 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL); | 27 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL); |
@@ -25,7 +32,23 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
25 | kmem_cache_free(pgtable_cache, pgd); | 32 | kmem_cache_free(pgtable_cache, pgd); |
26 | } | 33 | } |
27 | 34 | ||
28 | #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) | 35 | static inline void __pud_populate(pud_t *pud, pmd_t *pmd) |
36 | { | ||
37 | pud_set(pud, pmd); | ||
38 | } | ||
39 | |||
40 | #define pud_populate(MM, PUD, PMD) __pud_populate(PUD, PMD) | ||
41 | |||
42 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
43 | { | ||
44 | return kmem_cache_alloc(pgtable_cache, | ||
45 | GFP_KERNEL|__GFP_REPEAT); | ||
46 | } | ||
47 | |||
48 | static inline void pud_free(struct mm_struct *mm, pud_t *pud) | ||
49 | { | ||
50 | kmem_cache_free(pgtable_cache, pud); | ||
51 | } | ||
29 | 52 | ||
30 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | 53 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) |
31 | { | 54 | { |
@@ -91,4 +114,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pte_t *pte, | |||
91 | #define __pmd_free_tlb(tlb, pmd, addr) \ | 114 | #define __pmd_free_tlb(tlb, pmd, addr) \ |
92 | pgtable_free_tlb(tlb, pmd, false) | 115 | pgtable_free_tlb(tlb, pmd, false) |
93 | 116 | ||
117 | #define __pud_free_tlb(tlb, pud, addr) \ | ||
118 | pgtable_free_tlb(tlb, pud, false) | ||
119 | |||
94 | #endif /* _SPARC64_PGALLOC_H */ | 120 | #endif /* _SPARC64_PGALLOC_H */ |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 3770bf5c6e1b..31ac919920a9 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -20,8 +20,6 @@ | |||
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
22 | 22 | ||
23 | #include <asm-generic/pgtable-nopud.h> | ||
24 | |||
25 | /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB). | 23 | /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB). |
26 | * The page copy blockops can use 0x6000000 to 0x8000000. | 24 | * The page copy blockops can use 0x6000000 to 0x8000000. |
27 | * The 8K TSB is mapped in the 0x8000000 to 0x8400000 range. | 25 | * The 8K TSB is mapped in the 0x8000000 to 0x8400000 range. |
@@ -55,13 +53,21 @@ | |||
55 | #define PMD_MASK (~(PMD_SIZE-1)) | 53 | #define PMD_MASK (~(PMD_SIZE-1)) |
56 | #define PMD_BITS (PAGE_SHIFT - 3) | 54 | #define PMD_BITS (PAGE_SHIFT - 3) |
57 | 55 | ||
58 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ | 56 | /* PUD_SHIFT determines the size of the area a third-level page |
59 | #define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS) | 57 | * table can map |
58 | */ | ||
59 | #define PUD_SHIFT (PMD_SHIFT + PMD_BITS) | ||
60 | #define PUD_SIZE (_AC(1,UL) << PUD_SHIFT) | ||
61 | #define PUD_MASK (~(PUD_SIZE-1)) | ||
62 | #define PUD_BITS (PAGE_SHIFT - 3) | ||
63 | |||
64 | /* PGDIR_SHIFT determines what a fourth-level page table entry can map */ | ||
65 | #define PGDIR_SHIFT (PUD_SHIFT + PUD_BITS) | ||
60 | #define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT) | 66 | #define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT) |
61 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 67 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
62 | #define PGDIR_BITS (PAGE_SHIFT - 3) | 68 | #define PGDIR_BITS (PAGE_SHIFT - 3) |
63 | 69 | ||
64 | #if (PGDIR_SHIFT + PGDIR_BITS) != 43 | 70 | #if (PGDIR_SHIFT + PGDIR_BITS) != 53 |
65 | #error Page table parameters do not cover virtual address space properly. | 71 | #error Page table parameters do not cover virtual address space properly. |
66 | #endif | 72 | #endif |
67 | 73 | ||
@@ -93,6 +99,7 @@ static inline bool kern_addr_valid(unsigned long addr) | |||
93 | /* Entries per page directory level. */ | 99 | /* Entries per page directory level. */ |
94 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) | 100 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) |
95 | #define PTRS_PER_PMD (1UL << PMD_BITS) | 101 | #define PTRS_PER_PMD (1UL << PMD_BITS) |
102 | #define PTRS_PER_PUD (1UL << PUD_BITS) | ||
96 | #define PTRS_PER_PGD (1UL << PGDIR_BITS) | 103 | #define PTRS_PER_PGD (1UL << PGDIR_BITS) |
97 | 104 | ||
98 | /* Kernel has a separate 44bit address space. */ | 105 | /* Kernel has a separate 44bit address space. */ |
@@ -101,6 +108,9 @@ static inline bool kern_addr_valid(unsigned long addr) | |||
101 | #define pmd_ERROR(e) \ | 108 | #define pmd_ERROR(e) \ |
102 | pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ | 109 | pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ |
103 | __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) | 110 | __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) |
111 | #define pud_ERROR(e) \ | ||
112 | pr_err("%s:%d: bad pud %p(%016lx) seen at (%pS)\n", \ | ||
113 | __FILE__, __LINE__, &(e), pud_val(e), __builtin_return_address(0)) | ||
104 | #define pgd_ERROR(e) \ | 114 | #define pgd_ERROR(e) \ |
105 | pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ | 115 | pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ |
106 | __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0)) | 116 | __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0)) |
@@ -779,6 +789,11 @@ static inline int pmd_present(pmd_t pmd) | |||
779 | #define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \ | 789 | #define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \ |
780 | !__kern_addr_valid(pud_val(pud))) | 790 | !__kern_addr_valid(pud_val(pud))) |
781 | 791 | ||
792 | #define pgd_none(pgd) (!pgd_val(pgd)) | ||
793 | |||
794 | #define pgd_bad(pgd) ((pgd_val(pgd) & ~PAGE_MASK) || \ | ||
795 | !__kern_addr_valid(pgd_val(pgd))) | ||
796 | |||
782 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 797 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
783 | void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 798 | void set_pmd_at(struct mm_struct *mm, unsigned long addr, |
784 | pmd_t *pmdp, pmd_t pmd); | 799 | pmd_t *pmdp, pmd_t pmd); |
@@ -815,10 +830,17 @@ static inline unsigned long __pmd_page(pmd_t pmd) | |||
815 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) | 830 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) |
816 | #define pud_present(pud) (pud_val(pud) != 0U) | 831 | #define pud_present(pud) (pud_val(pud) != 0U) |
817 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) | 832 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) |
833 | #define pgd_page_vaddr(pgd) \ | ||
834 | ((unsigned long) __va(pgd_val(pgd))) | ||
835 | #define pgd_present(pgd) (pgd_val(pgd) != 0U) | ||
836 | #define pgd_clear(pgdp) (pgd_val(*(pgd)) = 0UL) | ||
818 | 837 | ||
819 | /* Same in both SUN4V and SUN4U. */ | 838 | /* Same in both SUN4V and SUN4U. */ |
820 | #define pte_none(pte) (!pte_val(pte)) | 839 | #define pte_none(pte) (!pte_val(pte)) |
821 | 840 | ||
841 | #define pgd_set(pgdp, pudp) \ | ||
842 | (pgd_val(*(pgdp)) = (__pa((unsigned long) (pudp)))) | ||
843 | |||
822 | /* to find an entry in a page-table-directory. */ | 844 | /* to find an entry in a page-table-directory. */ |
823 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) | 845 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) |
824 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) | 846 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) |
@@ -826,6 +848,11 @@ static inline unsigned long __pmd_page(pmd_t pmd) | |||
826 | /* to find an entry in a kernel page-table-directory */ | 848 | /* to find an entry in a kernel page-table-directory */ |
827 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | 849 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) |
828 | 850 | ||
851 | /* Find an entry in the third-level page table.. */ | ||
852 | #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)) | ||
853 | #define pud_offset(pgdp, address) \ | ||
854 | ((pud_t *) pgd_page_vaddr(*(pgdp)) + pud_index(address)) | ||
855 | |||
829 | /* Find an entry in the second-level page table.. */ | 856 | /* Find an entry in the second-level page table.. */ |
830 | #define pmd_offset(pudp, address) \ | 857 | #define pmd_offset(pudp, address) \ |
831 | ((pmd_t *) pud_page_vaddr(*(pudp)) + \ | 858 | ((pmd_t *) pud_page_vaddr(*(pudp)) + \ |
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 90916f955cac..2e268b646348 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h | |||
@@ -145,6 +145,11 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
145 | andn REG2, 0x7, REG2; \ | 145 | andn REG2, 0x7, REG2; \ |
146 | ldx [REG1 + REG2], REG1; \ | 146 | ldx [REG1 + REG2], REG1; \ |
147 | brz,pn REG1, FAIL_LABEL; \ | 147 | brz,pn REG1, FAIL_LABEL; \ |
148 | sllx VADDR, 64 - (PUD_SHIFT + PUD_BITS), REG2; \ | ||
149 | srlx REG2, 64 - PAGE_SHIFT, REG2; \ | ||
150 | andn REG2, 0x7, REG2; \ | ||
151 | ldxa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ | ||
152 | brz,pn REG1, FAIL_LABEL; \ | ||
148 | sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ | 153 | sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ |
149 | srlx REG2, 64 - PAGE_SHIFT, REG2; \ | 154 | srlx REG2, 64 - PAGE_SHIFT, REG2; \ |
150 | andn REG2, 0x7, REG2; \ | 155 | andn REG2, 0x7, REG2; \ |
@@ -198,6 +203,11 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
198 | andn REG2, 0x7, REG2; \ | 203 | andn REG2, 0x7, REG2; \ |
199 | ldxa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \ | 204 | ldxa [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \ |
200 | brz,pn REG1, FAIL_LABEL; \ | 205 | brz,pn REG1, FAIL_LABEL; \ |
206 | sllx VADDR, 64 - (PUD_SHIFT + PUD_BITS), REG2; \ | ||
207 | srlx REG2, 64 - PAGE_SHIFT, REG2; \ | ||
208 | andn REG2, 0x7, REG2; \ | ||
209 | ldxa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ | ||
210 | brz,pn REG1, FAIL_LABEL; \ | ||
201 | sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ | 211 | sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ |
202 | srlx REG2, 64 - PAGE_SHIFT, REG2; \ | 212 | srlx REG2, 64 - PAGE_SHIFT, REG2; \ |
203 | andn REG2, 0x7, REG2; \ | 213 | andn REG2, 0x7, REG2; \ |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index f7ba87543e5f..c9300bfaee5a 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -1467,6 +1467,13 @@ static void __init pcpu_populate_pte(unsigned long addr) | |||
1467 | pud_t *pud; | 1467 | pud_t *pud; |
1468 | pmd_t *pmd; | 1468 | pmd_t *pmd; |
1469 | 1469 | ||
1470 | if (pgd_none(*pgd)) { | ||
1471 | pud_t *new; | ||
1472 | |||
1473 | new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); | ||
1474 | pgd_populate(&init_mm, pgd, new); | ||
1475 | } | ||
1476 | |||
1470 | pud = pud_offset(pgd, addr); | 1477 | pud = pud_offset(pgd, addr); |
1471 | if (pud_none(*pud)) { | 1478 | if (pud_none(*pud)) { |
1472 | pmd_t *new; | 1479 | pmd_t *new; |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index bd08ed49bbaa..091f846e6192 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -1390,6 +1390,13 @@ static unsigned long __ref kernel_map_range(unsigned long pstart, | |||
1390 | pmd_t *pmd; | 1390 | pmd_t *pmd; |
1391 | pte_t *pte; | 1391 | pte_t *pte; |
1392 | 1392 | ||
1393 | if (pgd_none(*pgd)) { | ||
1394 | pud_t *new; | ||
1395 | |||
1396 | new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); | ||
1397 | alloc_bytes += PAGE_SIZE; | ||
1398 | pgd_populate(&init_mm, pgd, new); | ||
1399 | } | ||
1393 | pud = pud_offset(pgd, vstart); | 1400 | pud = pud_offset(pgd, vstart); |
1394 | if (pud_none(*pud)) { | 1401 | if (pud_none(*pud)) { |
1395 | pmd_t *new; | 1402 | pmd_t *new; |
@@ -1856,7 +1863,12 @@ static void __init sun4v_linear_pte_xor_finalize(void) | |||
1856 | /* paging_init() sets up the page tables */ | 1863 | /* paging_init() sets up the page tables */ |
1857 | 1864 | ||
1858 | static unsigned long last_valid_pfn; | 1865 | static unsigned long last_valid_pfn; |
1859 | pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 1866 | |
1867 | /* These must be page aligned in order to not trigger the | ||
1868 | * alignment tests of pgd_bad() and pud_bad(). | ||
1869 | */ | ||
1870 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned (PAGE_SIZE))); | ||
1871 | static pud_t swapper_pud_dir[PTRS_PER_PUD] __attribute__ ((aligned (PAGE_SIZE))); | ||
1860 | 1872 | ||
1861 | static void sun4u_pgprot_init(void); | 1873 | static void sun4u_pgprot_init(void); |
1862 | static void sun4v_pgprot_init(void); | 1874 | static void sun4v_pgprot_init(void); |
@@ -1911,6 +1923,8 @@ void __init paging_init(void) | |||
1911 | { | 1923 | { |
1912 | unsigned long end_pfn, shift, phys_base; | 1924 | unsigned long end_pfn, shift, phys_base; |
1913 | unsigned long real_end, i; | 1925 | unsigned long real_end, i; |
1926 | pud_t *pud; | ||
1927 | pmd_t *pmd; | ||
1914 | int node; | 1928 | int node; |
1915 | 1929 | ||
1916 | setup_page_offset(); | 1930 | setup_page_offset(); |
@@ -2008,9 +2022,18 @@ void __init paging_init(void) | |||
2008 | 2022 | ||
2009 | memset(swapper_low_pmd_dir, 0, sizeof(swapper_low_pmd_dir)); | 2023 | memset(swapper_low_pmd_dir, 0, sizeof(swapper_low_pmd_dir)); |
2010 | 2024 | ||
2011 | /* Now can init the kernel/bad page tables. */ | 2025 | /* The kernel page tables we publish into what the rest of the |
2012 | pud_set(pud_offset(&swapper_pg_dir[0], 0), | 2026 | * world sees must be adjusted so that they see the PAGE_OFFSET |
2013 | swapper_low_pmd_dir + (shift / sizeof(pgd_t))); | 2027 | * address of these in-kerenel data structures. However right |
2028 | * here we must access them from the kernel image side, because | ||
2029 | * the trap tables haven't been taken over and therefore we cannot | ||
2030 | * take TLB misses in the PAGE_OFFSET linear mappings yet. | ||
2031 | */ | ||
2032 | pud = swapper_pud_dir + (shift / sizeof(pud_t)); | ||
2033 | pgd_set(&swapper_pg_dir[0], pud); | ||
2034 | |||
2035 | pmd = swapper_low_pmd_dir + (shift / sizeof(pmd_t)); | ||
2036 | pud_set(&swapper_pud_dir[0], pmd); | ||
2014 | 2037 | ||
2015 | inherit_prom_mappings(); | 2038 | inherit_prom_mappings(); |
2016 | 2039 | ||