aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ppc64/kernel/iSeries_htab.c19
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c60
-rw-r--r--arch/ppc64/mm/hash_utils.c15
-rw-r--r--include/asm-ppc64/mmu.h4
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
87long 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
87static unsigned long iSeries_hpte_getword0(unsigned long slot) 106static 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
76static void build_iSeries_Memory_Map(void); 76static void build_iSeries_Memory_Map(void);
77static void setup_iSeries_cache_sizes(void); 77static void setup_iSeries_cache_sizes(void);
78static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
79static int iseries_shared_idle(void); 78static int iseries_shared_idle(void);
80static int iseries_dedicated_idle(void); 79static 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 */
642static 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 */
667static 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 */
698static void __init iSeries_setup_arch(void) 638static 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
94static inline void create_pte_mapping(unsigned long start, unsigned long end, 93static 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
209extern 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
209extern void stabs_alloc(void); 213extern void stabs_alloc(void);
210 214
211#endif /* __ASSEMBLY__ */ 215#endif /* __ASSEMBLY__ */