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.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index e01408429ad6..dc602a61233f 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -273,26 +273,24 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
273 void *data, unsigned long stack) 273 void *data, unsigned long stack)
274{ 274{
275 struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; 275 struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices];
276 struct { 276 unsigned long source_cpu = stap();
277 unsigned long stack;
278 void *func;
279 void *data;
280 unsigned long source;
281 } restart = { stack, func, data, stap() };
282 277
283 __load_psw_mask(psw_kernel_bits); 278 __load_psw_mask(psw_kernel_bits);
284 if (pcpu->address == restart.source) 279 if (pcpu->address == source_cpu)
285 func(data); /* should not return */ 280 func(data); /* should not return */
286 /* Stop target cpu (if func returns this stops the current cpu). */ 281 /* Stop target cpu (if func returns this stops the current cpu). */
287 pcpu_sigp_retry(pcpu, SIGP_STOP, 0); 282 pcpu_sigp_retry(pcpu, SIGP_STOP, 0);
288 /* Restart func on the target cpu and stop the current cpu. */ 283 /* Restart func on the target cpu and stop the current cpu. */
289 memcpy_absolute(&lc->restart_stack, &restart, sizeof(restart)); 284 mem_assign_absolute(lc->restart_stack, stack);
285 mem_assign_absolute(lc->restart_fn, (unsigned long) func);
286 mem_assign_absolute(lc->restart_data, (unsigned long) data);
287 mem_assign_absolute(lc->restart_source, source_cpu);
290 asm volatile( 288 asm volatile(
291 "0: sigp 0,%0,%2 # sigp restart to target cpu\n" 289 "0: sigp 0,%0,%2 # sigp restart to target cpu\n"
292 " brc 2,0b # busy, try again\n" 290 " brc 2,0b # busy, try again\n"
293 "1: sigp 0,%1,%3 # sigp stop to current cpu\n" 291 "1: sigp 0,%1,%3 # sigp stop to current cpu\n"
294 " brc 2,1b # busy, try again\n" 292 " brc 2,1b # busy, try again\n"
295 : : "d" (pcpu->address), "d" (restart.source), 293 : : "d" (pcpu->address), "d" (source_cpu),
296 "K" (SIGP_RESTART), "K" (SIGP_STOP) 294 "K" (SIGP_RESTART), "K" (SIGP_STOP)
297 : "0", "1", "cc"); 295 : "0", "1", "cc");
298 for (;;) ; 296 for (;;) ;