From b5e804598d594934407a1a8548d7b65341fe2617 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Wed, 27 Feb 2019 16:52:42 +0100 Subject: [PATCH] s390: allow overriding facilities via command line Add "facilities=" command line option which allows to override facility bits returned by stfle. The main purpose of that is debugging aids which allows to test specific kernel behaviour depending on specific facilities presence. It also affects CPU alternatives. "facilities=" command line option format is comma separated list of integer values to be additionally set or cleared (if value is starting with "!"). Values ranges are also supported. e.g.: facilities=!130-160,159,167-169 Reviewed-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Martin Schwidefsky --- arch/s390/boot/boot.h | 1 + arch/s390/boot/ipl_parm.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-- arch/s390/boot/startup.c | 1 + 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index fc41e22..8665497 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h @@ -6,6 +6,7 @@ void startup_kernel(void); void detect_memory(void); void store_ipl_parmblock(void); void setup_boot_command_line(void); +void parse_boot_command_line(void); void setup_memory_end(void); #endif /* BOOT_BOOT_H */ diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index 9dab596..94e5374 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "boot.h" char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; @@ -143,8 +144,51 @@ void setup_boot_command_line(void) append_ipl_block_parm(); } +static void modify_facility(unsigned long nr, bool clear) +{ + if (clear) + __clear_facility(nr, S390_lowcore.stfle_fac_list); + else + __set_facility(nr, S390_lowcore.stfle_fac_list); +} + +static void modify_fac_list(char *str) +{ + unsigned long val, endval; + char *endp; + bool clear; + + while (*str) { + clear = false; + if (*str == '!') { + clear = true; + str++; + } + val = simple_strtoull(str, &endp, 0); + if (str == endp) + break; + str = endp; + if (*str == '-') { + str++; + endval = simple_strtoull(str, &endp, 0); + if (str == endp) + break; + str = endp; + while (val <= endval) { + modify_facility(val, clear); + val++; + } + } else { + modify_facility(val, clear); + } + if (*str != ',') + break; + str++; + } +} + static char command_line_buf[COMMAND_LINE_SIZE] __section(.data); -static void parse_mem_opt(void) +void parse_boot_command_line(void) { char *param, *val; bool enabled; @@ -165,12 +209,14 @@ static void parse_mem_opt(void) if (!rc && !enabled) noexec_disabled = 1; } + + if (!strcmp(param, "facilities")) + modify_fac_list(val); } } void setup_memory_end(void) { - parse_mem_opt(); #ifdef CONFIG_CRASH_DUMP if (!OLDMEM_BASE && early_ipl_block_valid && early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP && diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 4d44131..bdfc554 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -53,6 +53,7 @@ void startup_kernel(void) sclp_early_read_info(); store_ipl_parmblock(); setup_boot_command_line(); + parse_boot_command_line(); setup_memory_end(); detect_memory(); if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) { -- 2.7.4