]> git.baikalelectronics.ru Git - kernel.git/commitdiff
s390/smp: cleanup target CPU callback starting
authorAlexander Gordeev <agordeev@linux.ibm.com>
Thu, 17 Mar 2022 14:03:01 +0000 (15:03 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:24:12 +0000 (14:24 +0200)
[ Upstream commit 901fa64cb2d7e2ac4560d168193be9a30c3d2b26 ]

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 <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/s390/kernel/smp.c

index e57eb2260b902e2c47f29fffdd8460c93b21bdb4..982b72ca677c28aeb9a6c530712a66b3a6fe479c 100644 (file)
@@ -328,10 +328,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"