summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/alternative.c
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2021-10-01 12:47:01 +0200
committerVasily Gorbik <gor@linux.ibm.com>2021-10-11 20:55:58 +0200
commite16d02ee3f348900a0a2cf41931b204e2042f5e3 (patch)
treef4f16a8d00d83b5b78f328441efd00d4c84eb07d /arch/s390/kernel/alternative.c
parentfbbd140737121637b98aef53440c7a2676e412cf (diff)
s390: introduce text_poke_sync()
Introduce a text_poke_sync() similar to what x86 has. This can be used to execute a serializing instruction on all CPUs (including the current one). Note: according to the Principles of Operation an IPI (= interrupt) will already serialize a CPU, however it is better to be explicit. In addition on_each_cpu() makes sure that also the current CPU get serialized - just to make sure that possible preemption can prevent some theoretical case where a CPU will not be serialized. Therefore text_poke_sync() has to be used whenever code got modified, just to avoid to rely on implicit serialization. Also introduce text_poke_sync_lock() which will also disable CPU hotplug, to prevent that any CPU is just going online with a prefetched old version of a modified instruction. Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/alternative.c')
-rw-r--r--arch/s390/kernel/alternative.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c
index c22ea1c3ef84..cce0ddee2d02 100644
--- a/arch/s390/kernel/alternative.c
+++ b/arch/s390/kernel/alternative.c
@@ -1,5 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <asm/text-patching.h>
#include <asm/alternative.h>
#include <asm/facility.h>
#include <asm/nospec-branch.h>
@@ -110,3 +113,20 @@ void __init apply_alternative_instructions(void)
{
apply_alternatives(__alt_instructions, __alt_instructions_end);
}
+
+static void do_sync_core(void *info)
+{
+ sync_core();
+}
+
+void text_poke_sync(void)
+{
+ on_each_cpu(do_sync_core, NULL, 1);
+}
+
+void text_poke_sync_lock(void)
+{
+ cpus_read_lock();
+ text_poke_sync();
+ cpus_read_unlock();
+}