diff options
-rw-r--r-- | arch/ppc64/kernel/iSeries_htab.c | 19 | ||||
-rw-r--r-- | arch/ppc64/kernel/iSeries_setup.c | 60 | ||||
-rw-r--r-- | arch/ppc64/mm/hash_utils.c | 15 | ||||
-rw-r--r-- | include/asm-ppc64/mmu.h | 4 |
4 files changed, 34 insertions, 64 deletions
diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c index 2192055a90a0..9a2be3abf349 100644 --- a/arch/ppc64/kernel/iSeries_htab.c +++ b/arch/ppc64/kernel/iSeries_htab.c | |||
@@ -84,6 +84,25 @@ static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va, | |||
84 | return (secondary << 3) | (slot & 7); | 84 | return (secondary << 3) | (slot & 7); |
85 | } | 85 | } |
86 | 86 | ||
87 | long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, | ||
88 | unsigned long va, unsigned long prpn, unsigned long vflags, | ||
89 | unsigned long rflags) | ||
90 | { | ||
91 | long slot; | ||
92 | hpte_t lhpte; | ||
93 | |||
94 | slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT); | ||
95 | |||
96 | if (lhpte.v & HPTE_V_VALID) { | ||
97 | /* Bolt the existing HPTE */ | ||
98 | HvCallHpt_setSwBits(slot, 0x10, 0); | ||
99 | HvCallHpt_setPp(slot, PP_RWXX); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags); | ||
104 | } | ||
105 | |||
87 | static unsigned long iSeries_hpte_getword0(unsigned long slot) | 106 | static unsigned long iSeries_hpte_getword0(unsigned long slot) |
88 | { | 107 | { |
89 | hpte_t hpte; | 108 | hpte_t hpte; |
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 75d8db4eaac6..49d0f9999682 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
@@ -75,7 +75,6 @@ extern void ppcdbg_initialize(void); | |||
75 | 75 | ||
76 | static void build_iSeries_Memory_Map(void); | 76 | static void build_iSeries_Memory_Map(void); |
77 | static void setup_iSeries_cache_sizes(void); | 77 | static void setup_iSeries_cache_sizes(void); |
78 | static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); | ||
79 | static int iseries_shared_idle(void); | 78 | static int iseries_shared_idle(void); |
80 | static int iseries_dedicated_idle(void); | 79 | static int iseries_dedicated_idle(void); |
81 | #ifdef CONFIG_PCI | 80 | #ifdef CONFIG_PCI |
@@ -383,9 +382,6 @@ static void __init iSeries_init_early(void) | |||
383 | } | 382 | } |
384 | } | 383 | } |
385 | 384 | ||
386 | /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */ | ||
387 | iSeries_bolt_kernel(0, systemcfg->physicalMemorySize); | ||
388 | |||
389 | lmb_init(); | 385 | lmb_init(); |
390 | lmb_add(0, systemcfg->physicalMemorySize); | 386 | lmb_add(0, systemcfg->physicalMemorySize); |
391 | lmb_analyze(); | 387 | lmb_analyze(); |
@@ -637,62 +633,6 @@ static void __init setup_iSeries_cache_sizes(void) | |||
637 | } | 633 | } |
638 | 634 | ||
639 | /* | 635 | /* |
640 | * Create a pte. Used during initialization only. | ||
641 | */ | ||
642 | static void iSeries_make_pte(unsigned long va, unsigned long pa, | ||
643 | int mode) | ||
644 | { | ||
645 | hpte_t local_hpte, rhpte; | ||
646 | unsigned long hash, vpn; | ||
647 | long slot; | ||
648 | |||
649 | vpn = va >> PAGE_SHIFT; | ||
650 | hash = hpt_hash(vpn, 0); | ||
651 | |||
652 | local_hpte.r = pa | mode; | ||
653 | local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | ||
654 | | HPTE_V_BOLTED | HPTE_V_VALID; | ||
655 | |||
656 | slot = HvCallHpt_findValid(&rhpte, vpn); | ||
657 | if (slot < 0) { | ||
658 | /* Must find space in primary group */ | ||
659 | panic("hash_page: hpte already exists\n"); | ||
660 | } | ||
661 | HvCallHpt_addValidate(slot, 0, &local_hpte); | ||
662 | } | ||
663 | |||
664 | /* | ||
665 | * Bolt the kernel addr space into the HPT | ||
666 | */ | ||
667 | static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) | ||
668 | { | ||
669 | unsigned long pa; | ||
670 | unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; | ||
671 | hpte_t hpte; | ||
672 | |||
673 | for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { | ||
674 | unsigned long ea = (unsigned long)__va(pa); | ||
675 | unsigned long vsid = get_kernel_vsid(ea); | ||
676 | unsigned long va = (vsid << 28) | (pa & 0xfffffff); | ||
677 | unsigned long vpn = va >> PAGE_SHIFT; | ||
678 | unsigned long slot = HvCallHpt_findValid(&hpte, vpn); | ||
679 | |||
680 | /* Make non-kernel text non-executable */ | ||
681 | if (!in_kernel_text(ea)) | ||
682 | mode_rw |= HW_NO_EXEC; | ||
683 | |||
684 | if (hpte.v & HPTE_V_VALID) { | ||
685 | /* HPTE exists, so just bolt it */ | ||
686 | HvCallHpt_setSwBits(slot, 0x10, 0); | ||
687 | /* And make sure the pp bits are correct */ | ||
688 | HvCallHpt_setPp(slot, PP_RWXX); | ||
689 | } else | ||
690 | /* No HPTE exists, so create a new bolted one */ | ||
691 | iSeries_make_pte(va, phys_to_abs(pa), mode_rw); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | /* | ||
696 | * Document me. | 636 | * Document me. |
697 | */ | 637 | */ |
698 | static void __init iSeries_setup_arch(void) | 638 | static void __init iSeries_setup_arch(void) |
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 36cf474b3d36..83507438d6a0 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c | |||
@@ -90,7 +90,6 @@ static inline void loop_forever(void) | |||
90 | ; | 90 | ; |
91 | } | 91 | } |
92 | 92 | ||
93 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
94 | static inline void create_pte_mapping(unsigned long start, unsigned long end, | 93 | static inline void create_pte_mapping(unsigned long start, unsigned long end, |
95 | unsigned long mode, int large) | 94 | unsigned long mode, int large) |
96 | { | 95 | { |
@@ -111,7 +110,7 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, | |||
111 | unsigned long vpn, hash, hpteg; | 110 | unsigned long vpn, hash, hpteg; |
112 | unsigned long vsid = get_kernel_vsid(addr); | 111 | unsigned long vsid = get_kernel_vsid(addr); |
113 | unsigned long va = (vsid << 28) | (addr & 0xfffffff); | 112 | unsigned long va = (vsid << 28) | (addr & 0xfffffff); |
114 | int ret; | 113 | int ret = -1; |
115 | 114 | ||
116 | if (large) | 115 | if (large) |
117 | vpn = va >> HPAGE_SHIFT; | 116 | vpn = va >> HPAGE_SHIFT; |
@@ -129,16 +128,25 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, | |||
129 | 128 | ||
130 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | 129 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); |
131 | 130 | ||
131 | #ifdef CONFIG_PPC_ISERIES | ||
132 | if (systemcfg->platform & PLATFORM_ISERIES_LPAR) | ||
133 | ret = iSeries_hpte_bolt_or_insert(hpteg, va, | ||
134 | virt_to_abs(addr) >> PAGE_SHIFT, | ||
135 | vflags, tmp_mode); | ||
136 | else | ||
137 | #endif | ||
132 | #ifdef CONFIG_PPC_PSERIES | 138 | #ifdef CONFIG_PPC_PSERIES |
133 | if (systemcfg->platform & PLATFORM_LPAR) | 139 | if (systemcfg->platform & PLATFORM_LPAR) |
134 | ret = pSeries_lpar_hpte_insert(hpteg, va, | 140 | ret = pSeries_lpar_hpte_insert(hpteg, va, |
135 | virt_to_abs(addr) >> PAGE_SHIFT, | 141 | virt_to_abs(addr) >> PAGE_SHIFT, |
136 | vflags, tmp_mode); | 142 | vflags, tmp_mode); |
137 | else | 143 | else |
138 | #endif /* CONFIG_PPC_PSERIES */ | 144 | #endif |
145 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
139 | ret = native_hpte_insert(hpteg, va, | 146 | ret = native_hpte_insert(hpteg, va, |
140 | virt_to_abs(addr) >> PAGE_SHIFT, | 147 | virt_to_abs(addr) >> PAGE_SHIFT, |
141 | vflags, tmp_mode); | 148 | vflags, tmp_mode); |
149 | #endif | ||
142 | 150 | ||
143 | if (ret == -1) { | 151 | if (ret == -1) { |
144 | ppc64_terminate_msg(0x20, "create_pte_mapping"); | 152 | ppc64_terminate_msg(0x20, "create_pte_mapping"); |
@@ -261,7 +269,6 @@ void __init htab_initialize(void) | |||
261 | } | 269 | } |
262 | #undef KB | 270 | #undef KB |
263 | #undef MB | 271 | #undef MB |
264 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
265 | 272 | ||
266 | /* | 273 | /* |
267 | * Called by asm hashtable.S for doing lazy icache flush | 274 | * Called by asm hashtable.S for doing lazy icache flush |
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index d2b0b796d35e..e0505acb77d9 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h | |||
@@ -206,6 +206,10 @@ extern long native_hpte_insert(unsigned long hpte_group, unsigned long va, | |||
206 | unsigned long prpn, | 206 | unsigned long prpn, |
207 | unsigned long vflags, unsigned long rflags); | 207 | unsigned long vflags, unsigned long rflags); |
208 | 208 | ||
209 | extern long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, | ||
210 | unsigned long va, unsigned long prpn, | ||
211 | unsigned long vflags, unsigned long rflags); | ||
212 | |||
209 | extern void stabs_alloc(void); | 213 | extern void stabs_alloc(void); |
210 | 214 | ||
211 | #endif /* __ASSEMBLY__ */ | 215 | #endif /* __ASSEMBLY__ */ |