summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2019-02-27 10:52:42 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2019-03-01 02:00:41 -0500
commitb5e804598d594934407a1a8548d7b65341fe2617 (patch)
treedb43a2962d8f9c57fad49589ed450fedc5ce20fd
parentd8901f2b2d04841d75d62c28c18b8b6e57eb49de (diff)
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 <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/boot/boot.h1
-rw-r--r--arch/s390/boot/ipl_parm.c50
-rw-r--r--arch/s390/boot/startup.c1
3 files changed, 50 insertions, 2 deletions
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h
index fc41e2277ea8..8665497fd335 100644
--- a/arch/s390/boot/boot.h
+++ b/arch/s390/boot/boot.h
@@ -6,6 +6,7 @@ void startup_kernel(void);
6void detect_memory(void); 6void detect_memory(void);
7void store_ipl_parmblock(void); 7void store_ipl_parmblock(void);
8void setup_boot_command_line(void); 8void setup_boot_command_line(void);
9void parse_boot_command_line(void);
9void setup_memory_end(void); 10void setup_memory_end(void);
10 11
11#endif /* BOOT_BOOT_H */ 12#endif /* BOOT_BOOT_H */
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 9dab596be98e..94e5374c3630 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -5,6 +5,7 @@
5#include <asm/sclp.h> 5#include <asm/sclp.h>
6#include <asm/sections.h> 6#include <asm/sections.h>
7#include <asm/boot_data.h> 7#include <asm/boot_data.h>
8#include <asm/facility.h>
8#include "boot.h" 9#include "boot.h"
9 10
10char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; 11char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
@@ -143,8 +144,51 @@ void setup_boot_command_line(void)
143 append_ipl_block_parm(); 144 append_ipl_block_parm();
144} 145}
145 146
147static void modify_facility(unsigned long nr, bool clear)
148{
149 if (clear)
150 __clear_facility(nr, S390_lowcore.stfle_fac_list);
151 else
152 __set_facility(nr, S390_lowcore.stfle_fac_list);
153}
154
155static void modify_fac_list(char *str)
156{
157 unsigned long val, endval;
158 char *endp;
159 bool clear;
160
161 while (*str) {
162 clear = false;
163 if (*str == '!') {
164 clear = true;
165 str++;
166 }
167 val = simple_strtoull(str, &endp, 0);
168 if (str == endp)
169 break;
170 str = endp;
171 if (*str == '-') {
172 str++;
173 endval = simple_strtoull(str, &endp, 0);
174 if (str == endp)
175 break;
176 str = endp;
177 while (val <= endval) {
178 modify_facility(val, clear);
179 val++;
180 }
181 } else {
182 modify_facility(val, clear);
183 }
184 if (*str != ',')
185 break;
186 str++;
187 }
188}
189
146static char command_line_buf[COMMAND_LINE_SIZE] __section(.data); 190static char command_line_buf[COMMAND_LINE_SIZE] __section(.data);
147static void parse_mem_opt(void) 191void parse_boot_command_line(void)
148{ 192{
149 char *param, *val; 193 char *param, *val;
150 bool enabled; 194 bool enabled;
@@ -165,12 +209,14 @@ static void parse_mem_opt(void)
165 if (!rc && !enabled) 209 if (!rc && !enabled)
166 noexec_disabled = 1; 210 noexec_disabled = 1;
167 } 211 }
212
213 if (!strcmp(param, "facilities"))
214 modify_fac_list(val);
168 } 215 }
169} 216}
170 217
171void setup_memory_end(void) 218void setup_memory_end(void)
172{ 219{
173 parse_mem_opt();
174#ifdef CONFIG_CRASH_DUMP 220#ifdef CONFIG_CRASH_DUMP
175 if (!OLDMEM_BASE && early_ipl_block_valid && 221 if (!OLDMEM_BASE && early_ipl_block_valid &&
176 early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP && 222 early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP &&
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 4d441317cdeb..bdfc5549a299 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -53,6 +53,7 @@ void startup_kernel(void)
53 sclp_early_read_info(); 53 sclp_early_read_info();
54 store_ipl_parmblock(); 54 store_ipl_parmblock();
55 setup_boot_command_line(); 55 setup_boot_command_line();
56 parse_boot_command_line();
56 setup_memory_end(); 57 setup_memory_end();
57 detect_memory(); 58 detect_memory();
58 if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) { 59 if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {