aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gordeev <[email protected]>2022-03-17 15:03:01 +0100
committerVasily Gorbik <[email protected]>2022-03-27 22:18:39 +0200
commitdc2ab23b992c9d5dab93b9bf01b10b10465e537e (patch)
tree654570d5808bf8caebf58541b1d459501a1af726
parentafacda5faabdfe0f0e91e89db3ff1dc0b46f669a (diff)
s390/smp: cleanup target CPU callback starting
Macro mem_assign_absolute() is used to initialize a target CPU lowcore callback parameters. But despite the macro name it writes to the absolute lowcore only if the target CPU is offline. In case the CPU is online the macro does implicitly write to the normal memory. That behaviour is correct, but extremely subtle. Sacrifice few program bits in favour of clarity and distinguish between online vs offline CPUs and normal vs absolute lowcore pointer. Reviewed-by: Heiko Carstens <[email protected]> Signed-off-by: Alexander Gordeev <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
-rw-r--r--arch/s390/kernel/smp.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 127da1850b06..b7e56fabe387 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -326,10 +326,17 @@ static void pcpu_delegate(struct pcpu *pcpu,
/* Stop target cpu (if func returns this stops the current cpu). */
pcpu_sigp_retry(pcpu, SIGP_STOP, 0);
/* Restart func on the target cpu and stop the current cpu. */
- mem_assign_absolute(lc->restart_stack, stack);
- mem_assign_absolute(lc->restart_fn, (unsigned long) func);
- mem_assign_absolute(lc->restart_data, (unsigned long) data);
- mem_assign_absolute(lc->restart_source, source_cpu);
+ if (lc) {
+ lc->restart_stack = stack;
+ lc->restart_fn = (unsigned long)func;
+ lc->restart_data = (unsigned long)data;
+ lc->restart_source = source_cpu;
+ } else {
+ mem_assign_absolute(lc->restart_stack, stack);
+ mem_assign_absolute(lc->restart_fn, (unsigned long)func);
+ mem_assign_absolute(lc->restart_data, (unsigned long)data);
+ mem_assign_absolute(lc->restart_source, source_cpu);
+ }
__bpon();
asm volatile(
"0: sigp 0,%0,%2 # sigp restart to target cpu\n"