diff options
-rw-r--r-- | arch/s390/boot/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/boot/alternative.c | 3 | ||||
-rw-r--r-- | arch/s390/boot/boot.h | 2 | ||||
-rw-r--r-- | arch/s390/boot/startup.c | 5 | ||||
-rw-r--r-- | arch/s390/include/asm/alternative.h | 12 | ||||
-rw-r--r-- | arch/s390/kernel/alternative.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/vmlinux.lds.S | 2 |
7 files changed, 27 insertions, 4 deletions
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index e7658997452b..5d8cb7e3b096 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -39,7 +39,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char obj-y := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o -obj-y += version.o pgm_check_info.o ctype.o ipl_data.o relocs.o +obj-y += version.o pgm_check_info.o ctype.o ipl_data.o relocs.o alternative.o obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o diff --git a/arch/s390/boot/alternative.c b/arch/s390/boot/alternative.c new file mode 100644 index 000000000000..abc08d2c873d --- /dev/null +++ b/arch/s390/boot/alternative.c @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "../kernel/alternative.c" diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index 18027fdc92b0..ed2f0ec24f0d 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h @@ -30,6 +30,8 @@ struct vmlinux_info { unsigned long init_mm_off; unsigned long swapper_pg_dir_off; unsigned long invalid_pg_dir_off; + unsigned long alt_instructions; + unsigned long alt_instructions_end; #ifdef CONFIG_KASAN unsigned long kasan_early_shadow_page_off; unsigned long kasan_early_shadow_pte_off; diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index cc8753c0c121..cca2f1bad33c 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -376,6 +376,8 @@ static void kaslr_adjust_vmlinux_info(long offset) vmlinux.init_mm_off += offset; vmlinux.swapper_pg_dir_off += offset; vmlinux.invalid_pg_dir_off += offset; + vmlinux.alt_instructions += offset; + vmlinux.alt_instructions_end += offset; #ifdef CONFIG_KASAN vmlinux.kasan_early_shadow_page_off += offset; vmlinux.kasan_early_shadow_pte_off += offset; @@ -507,6 +509,9 @@ void startup_kernel(void) kaslr_adjust_got(__kaslr_offset); setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit); copy_bootdata(); + __apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions, + (struct alt_instr *)_vmlinux_info.alt_instructions_end, + ALT_CTX_EARLY); /* * Save KASLR offset for early dumps, before vmcore_info is set. diff --git a/arch/s390/include/asm/alternative.h b/arch/s390/include/asm/alternative.h index 5b931070be16..32c208332e57 100644 --- a/arch/s390/include/asm/alternative.h +++ b/arch/s390/include/asm/alternative.h @@ -27,15 +27,21 @@ * alternative should be applied. */ -#define ALT_CTX_LATE 1 -#define ALT_CTX_ALL ALT_CTX_LATE +#define ALT_CTX_EARLY 1 +#define ALT_CTX_LATE 2 +#define ALT_CTX_ALL (ALT_CTX_EARLY | ALT_CTX_LATE) -#define ALT_TYPE_FACILITY 0 +#define ALT_TYPE_FACILITY_EARLY 0 +#define ALT_TYPE_FACILITY 1 #define ALT_DATA_SHIFT 0 #define ALT_TYPE_SHIFT 20 #define ALT_CTX_SHIFT 28 +#define ALT_FACILITY_EARLY(facility) (ALT_CTX_EARLY << ALT_CTX_SHIFT | \ + ALT_TYPE_FACILITY_EARLY << ALT_TYPE_SHIFT | \ + (facility) << ALT_DATA_SHIFT) + #define ALT_FACILITY(facility) (ALT_CTX_LATE << ALT_CTX_SHIFT | \ ALT_TYPE_FACILITY << ALT_TYPE_SHIFT | \ (facility) << ALT_DATA_SHIFT) diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c index ecabdff89bce..de89c9e8b1a3 100644 --- a/arch/s390/kernel/alternative.c +++ b/arch/s390/kernel/alternative.c @@ -18,9 +18,14 @@ void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsign if (!(a->ctx & ctx)) continue; switch (a->type) { + case ALT_TYPE_FACILITY_EARLY: + replace = test_facility(a->data); + break; +#ifndef __DECOMPRESSOR case ALT_TYPE_FACILITY: replace = __test_facility(a->data, alt_stfle_fac_list); break; +#endif default: replace = false; } diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 5128ccee9c67..975c654cf5a5 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -222,6 +222,8 @@ SECTIONS QUAD(init_mm) QUAD(swapper_pg_dir) QUAD(invalid_pg_dir) + QUAD(__alt_instructions) + QUAD(__alt_instructions_end) #ifdef CONFIG_KASAN QUAD(kasan_early_shadow_page) QUAD(kasan_early_shadow_pte) |