diff options
Diffstat (limited to 'arch/powerpc/kernel/paca.c')
-rw-r--r-- | arch/powerpc/kernel/paca.c | 30 |
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 */ |
157 | void setup_paca(struct paca_struct *new_paca) | 157 | void 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 | ||
166 | static int __initdata paca_size; | 177 | static int __initdata paca_size; |
167 | 178 | ||
168 | void __init allocate_pacas(void) | 179 | void __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 | ||