Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Heiko Carstens and committed by
Vasily Gorbik
e16d02ee fbbd1407

+36
+16
arch/s390/include/asm/text-patching.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _ASM_S390_TEXT_PATCHING_H 4 + #define _ASM_S390_TEXT_PATCHING_H 5 + 6 + #include <asm/barrier.h> 7 + 8 + static __always_inline void sync_core(void) 9 + { 10 + bcr_serialize(); 11 + } 12 + 13 + void text_poke_sync(void); 14 + void text_poke_sync_lock(void); 15 + 16 + #endif /* _ASM_S390_TEXT_PATCHING_H */
+20
arch/s390/kernel/alternative.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <linux/module.h> 3 + #include <linux/cpu.h> 4 + #include <linux/smp.h> 5 + #include <asm/text-patching.h> 3 6 #include <asm/alternative.h> 4 7 #include <asm/facility.h> 5 8 #include <asm/nospec-branch.h> ··· 112 109 void __init apply_alternative_instructions(void) 113 110 { 114 111 apply_alternatives(__alt_instructions, __alt_instructions_end); 112 + } 113 + 114 + static void do_sync_core(void *info) 115 + { 116 + sync_core(); 117 + } 118 + 119 + void text_poke_sync(void) 120 + { 121 + on_each_cpu(do_sync_core, NULL, 1); 122 + } 123 + 124 + void text_poke_sync_lock(void) 125 + { 126 + cpus_read_lock(); 127 + text_poke_sync(); 128 + cpus_read_unlock(); 115 129 }