aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/paca.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/paca.c')
-rw-r--r--arch/powerpc/kernel/paca.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 10f0aadee95b..efeb88184182 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -7,7 +7,7 @@
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9 9
10#include <linux/threads.h> 10#include <linux/smp.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/memblock.h> 12#include <linux/memblock.h>
13 13
@@ -156,18 +156,29 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
156/* Put the paca pointer into r13 and SPRG_PACA */ 156/* Put the paca pointer into r13 and SPRG_PACA */
157void setup_paca(struct paca_struct *new_paca) 157void setup_paca(struct paca_struct *new_paca)
158{ 158{
159 /* Setup r13 */
159 local_paca = new_paca; 160 local_paca = new_paca;
160 mtspr(SPRN_SPRG_PACA, local_paca); 161
161#ifdef CONFIG_PPC_BOOK3E 162#ifdef CONFIG_PPC_BOOK3E
163 /* On Book3E, initialize the TLB miss exception frames */
162 mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); 164 mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
165#else
166 /* In HV mode, we setup both HPACA and PACA to avoid problems
167 * if we do a GET_PACA() before the feature fixups have been
168 * applied
169 */
170 if (cpu_has_feature(CPU_FTR_HVMODE_206))
171 mtspr(SPRN_SPRG_HPACA, local_paca);
163#endif 172#endif
173 mtspr(SPRN_SPRG_PACA, local_paca);
174
164} 175}
165 176
166static int __initdata paca_size; 177static int __initdata paca_size;
167 178
168void __init allocate_pacas(void) 179void __init allocate_pacas(void)
169{ 180{
170 int nr_cpus, cpu, limit; 181 int cpu, limit;
171 182
172 /* 183 /*
173 * We can't take SLB misses on the paca, and we want to access them 184 * We can't take SLB misses on the paca, and we want to access them
@@ -179,23 +190,18 @@ void __init allocate_pacas(void)
179 if (firmware_has_feature(FW_FEATURE_ISERIES)) 190 if (firmware_has_feature(FW_FEATURE_ISERIES))
180 limit = min(limit, HvPagesToMap * HVPAGESIZE); 191 limit = min(limit, HvPagesToMap * HVPAGESIZE);
181 192
182 nr_cpus = NR_CPUS; 193 paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
183 /* On iSeries we know we can never have more than 64 cpus */
184 if (firmware_has_feature(FW_FEATURE_ISERIES))
185 nr_cpus = min(64, nr_cpus);
186
187 paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpus);
188 194
189 paca = __va(memblock_alloc_base(paca_size, PAGE_SIZE, limit)); 195 paca = __va(memblock_alloc_base(paca_size, PAGE_SIZE, limit));
190 memset(paca, 0, paca_size); 196 memset(paca, 0, paca_size);
191 197
192 printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n", 198 printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n",
193 paca_size, nr_cpus, paca); 199 paca_size, nr_cpu_ids, paca);
194 200
195 allocate_lppacas(nr_cpus, limit); 201 allocate_lppacas(nr_cpu_ids, limit);
196 202
197 /* Can't use for_each_*_cpu, as they aren't functional yet */ 203 /* Can't use for_each_*_cpu, as they aren't functional yet */
198 for (cpu = 0; cpu < nr_cpus; cpu++) 204 for (cpu = 0; cpu < nr_cpu_ids; cpu++)
199 initialise_paca(&paca[cpu], cpu); 205 initialise_paca(&paca[cpu], cpu);
200} 206}
201 207