aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r--arch/s390/kernel/smp.c54
1 files changed, 27 insertions, 27 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index a668993ff577..db8f1115a3bf 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -59,14 +59,13 @@ enum {
59 CPU_STATE_CONFIGURED, 59 CPU_STATE_CONFIGURED,
60}; 60};
61 61
62static DEFINE_PER_CPU(struct cpu *, cpu_device);
63
62struct pcpu { 64struct pcpu {
63 struct cpu *cpu;
64 struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ 65 struct _lowcore *lowcore; /* lowcore page(s) for the cpu */
65 unsigned long async_stack; /* async stack for the cpu */
66 unsigned long panic_stack; /* panic stack for the cpu */
67 unsigned long ec_mask; /* bit mask for ec_xxx functions */ 66 unsigned long ec_mask; /* bit mask for ec_xxx functions */
68 int state; /* physical cpu state */ 67 signed char state; /* physical cpu state */
69 int polarization; /* physical polarization */ 68 signed char polarization; /* physical polarization */
70 u16 address; /* physical cpu address */ 69 u16 address; /* physical cpu address */
71}; 70};
72 71
@@ -173,25 +172,30 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
173 pcpu_sigp_retry(pcpu, order, 0); 172 pcpu_sigp_retry(pcpu, order, 0);
174} 173}
175 174
175#define ASYNC_FRAME_OFFSET (ASYNC_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE)
176#define PANIC_FRAME_OFFSET (PAGE_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE)
177
176static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) 178static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
177{ 179{
180 unsigned long async_stack, panic_stack;
178 struct _lowcore *lc; 181 struct _lowcore *lc;
179 182
180 if (pcpu != &pcpu_devices[0]) { 183 if (pcpu != &pcpu_devices[0]) {
181 pcpu->lowcore = (struct _lowcore *) 184 pcpu->lowcore = (struct _lowcore *)
182 __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER); 185 __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
183 pcpu->async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); 186 async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
184 pcpu->panic_stack = __get_free_page(GFP_KERNEL); 187 panic_stack = __get_free_page(GFP_KERNEL);
185 if (!pcpu->lowcore || !pcpu->panic_stack || !pcpu->async_stack) 188 if (!pcpu->lowcore || !panic_stack || !async_stack)
186 goto out; 189 goto out;
190 } else {
191 async_stack = pcpu->lowcore->async_stack - ASYNC_FRAME_OFFSET;
192 panic_stack = pcpu->lowcore->panic_stack - PANIC_FRAME_OFFSET;
187 } 193 }
188 lc = pcpu->lowcore; 194 lc = pcpu->lowcore;
189 memcpy(lc, &S390_lowcore, 512); 195 memcpy(lc, &S390_lowcore, 512);
190 memset((char *) lc + 512, 0, sizeof(*lc) - 512); 196 memset((char *) lc + 512, 0, sizeof(*lc) - 512);
191 lc->async_stack = pcpu->async_stack + ASYNC_SIZE 197 lc->async_stack = async_stack + ASYNC_FRAME_OFFSET;
192 - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); 198 lc->panic_stack = panic_stack + PANIC_FRAME_OFFSET;
193 lc->panic_stack = pcpu->panic_stack + PAGE_SIZE
194 - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
195 lc->cpu_nr = cpu; 199 lc->cpu_nr = cpu;
196 lc->spinlock_lockval = arch_spin_lockval(cpu); 200 lc->spinlock_lockval = arch_spin_lockval(cpu);
197#ifndef CONFIG_64BIT 201#ifndef CONFIG_64BIT
@@ -212,8 +216,8 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
212 return 0; 216 return 0;
213out: 217out:
214 if (pcpu != &pcpu_devices[0]) { 218 if (pcpu != &pcpu_devices[0]) {
215 free_page(pcpu->panic_stack); 219 free_page(panic_stack);
216 free_pages(pcpu->async_stack, ASYNC_ORDER); 220 free_pages(async_stack, ASYNC_ORDER);
217 free_pages((unsigned long) pcpu->lowcore, LC_ORDER); 221 free_pages((unsigned long) pcpu->lowcore, LC_ORDER);
218 } 222 }
219 return -ENOMEM; 223 return -ENOMEM;
@@ -235,11 +239,11 @@ static void pcpu_free_lowcore(struct pcpu *pcpu)
235#else 239#else
236 vdso_free_per_cpu(pcpu->lowcore); 240 vdso_free_per_cpu(pcpu->lowcore);
237#endif 241#endif
238 if (pcpu != &pcpu_devices[0]) { 242 if (pcpu == &pcpu_devices[0])
239 free_page(pcpu->panic_stack); 243 return;
240 free_pages(pcpu->async_stack, ASYNC_ORDER); 244 free_page(pcpu->lowcore->panic_stack-PANIC_FRAME_OFFSET);
241 free_pages((unsigned long) pcpu->lowcore, LC_ORDER); 245 free_pages(pcpu->lowcore->async_stack-ASYNC_FRAME_OFFSET, ASYNC_ORDER);
242 } 246 free_pages((unsigned long) pcpu->lowcore, LC_ORDER);
243} 247}
244 248
245#endif /* CONFIG_HOTPLUG_CPU */ 249#endif /* CONFIG_HOTPLUG_CPU */
@@ -366,7 +370,8 @@ void smp_call_online_cpu(void (*func)(void *), void *data)
366void smp_call_ipl_cpu(void (*func)(void *), void *data) 370void smp_call_ipl_cpu(void (*func)(void *), void *data)
367{ 371{
368 pcpu_delegate(&pcpu_devices[0], func, data, 372 pcpu_delegate(&pcpu_devices[0], func, data,
369 pcpu_devices->panic_stack + PAGE_SIZE); 373 pcpu_devices->lowcore->panic_stack -
374 PANIC_FRAME_OFFSET + PAGE_SIZE);
370} 375}
371 376
372int smp_find_processor_id(u16 address) 377int smp_find_processor_id(u16 address)
@@ -935,10 +940,6 @@ void __init smp_prepare_boot_cpu(void)
935 pcpu->state = CPU_STATE_CONFIGURED; 940 pcpu->state = CPU_STATE_CONFIGURED;
936 pcpu->address = stap(); 941 pcpu->address = stap();
937 pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); 942 pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();
938 pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE
939 + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
940 pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE
941 + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
942 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 943 S390_lowcore.percpu_offset = __per_cpu_offset[0];
943 smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); 944 smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN);
944 set_cpu_present(0, true); 945 set_cpu_present(0, true);
@@ -1078,8 +1079,7 @@ static int smp_cpu_notify(struct notifier_block *self, unsigned long action,
1078 void *hcpu) 1079 void *hcpu)
1079{ 1080{
1080 unsigned int cpu = (unsigned int)(long)hcpu; 1081 unsigned int cpu = (unsigned int)(long)hcpu;
1081 struct cpu *c = pcpu_devices[cpu].cpu; 1082 struct device *s = &per_cpu(cpu_device, cpu)->dev;
1082 struct device *s = &c->dev;
1083 int err = 0; 1083 int err = 0;
1084 1084
1085 switch (action & ~CPU_TASKS_FROZEN) { 1085 switch (action & ~CPU_TASKS_FROZEN) {
@@ -1102,7 +1102,7 @@ static int smp_add_present_cpu(int cpu)
1102 c = kzalloc(sizeof(*c), GFP_KERNEL); 1102 c = kzalloc(sizeof(*c), GFP_KERNEL);
1103 if (!c) 1103 if (!c)
1104 return -ENOMEM; 1104 return -ENOMEM;
1105 pcpu_devices[cpu].cpu = c; 1105 per_cpu(cpu_device, cpu) = c;
1106 s = &c->dev; 1106 s = &c->dev;
1107 c->hotpluggable = 1; 1107 c->hotpluggable = 1;
1108 rc = register_cpu(c, cpu); 1108 rc = register_cpu(c, cpu);