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

s390/cmma: move parsing of cmma kernel parameter to early boot code

The "cmma=" kernel command line parameter needs to be parsed early for
upcoming changes. Therefore move the parsing code.

Note that EX_TABLE handling of cmma_test_essa() needs to be open-coded,
since the early boot code doesn't have infrastructure for handling expected
exceptions.

Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
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
468a3bc2 92b519f3

+58 -42
+8
arch/s390/boot/ipl_parm.c
··· 3 3 #include <linux/init.h> 4 4 #include <linux/ctype.h> 5 5 #include <linux/pgtable.h> 6 + #include <asm/page-states.h> 6 7 #include <asm/ebcdic.h> 7 8 #include <asm/sclp.h> 8 9 #include <asm/sections.h> ··· 25 24 struct ipl_parameter_block __bootdata_preserved(ipl_block); 26 25 int __bootdata_preserved(ipl_block_valid); 27 26 int __bootdata_preserved(__kaslr_enabled); 27 + int __bootdata_preserved(cmma_flag) = 1; 28 28 29 29 unsigned long vmalloc_size = VMALLOC_DEFAULT_SIZE; 30 30 unsigned long memory_limit; ··· 296 294 297 295 if (!strcmp(param, "nokaslr")) 298 296 __kaslr_enabled = 0; 297 + 298 + if (!strcmp(param, "cmma")) { 299 + rc = kstrtobool(val, &enabled); 300 + if (!rc && !enabled) 301 + cmma_flag = 0; 302 + } 299 303 300 304 #if IS_ENABLED(CONFIG_KVM) 301 305 if (!strcmp(param, "prot_virt")) {
+44
arch/s390/boot/startup.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <linux/string.h> 3 3 #include <linux/elf.h> 4 + #include <asm/page-states.h> 4 5 #include <asm/boot_data.h> 5 6 #include <asm/sections.h> 6 7 #include <asm/maccess.h> ··· 56 55 machine.has_edat2 = 1; 57 56 if (test_facility(130)) 58 57 machine.has_nx = 1; 58 + } 59 + 60 + static int cmma_test_essa(void) 61 + { 62 + unsigned long reg1, reg2, tmp = 0; 63 + int rc = 1; 64 + psw_t old; 65 + 66 + /* Test ESSA_GET_STATE */ 67 + asm volatile( 68 + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" 69 + " epsw %[reg1],%[reg2]\n" 70 + " st %[reg1],0(%[psw_pgm])\n" 71 + " st %[reg2],4(%[psw_pgm])\n" 72 + " larl %[reg1],1f\n" 73 + " stg %[reg1],8(%[psw_pgm])\n" 74 + " .insn rrf,0xb9ab0000,%[tmp],%[tmp],%[cmd],0\n" 75 + " la %[rc],0\n" 76 + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" 77 + : [reg1] "=&d" (reg1), 78 + [reg2] "=&a" (reg2), 79 + [rc] "+&d" (rc), 80 + [tmp] "=&d" (tmp), 81 + "+Q" (S390_lowcore.program_new_psw), 82 + "=Q" (old) 83 + : [psw_old] "a" (&old), 84 + [psw_pgm] "a" (&S390_lowcore.program_new_psw), 85 + [cmd] "i" (ESSA_GET_STATE) 86 + : "cc", "memory"); 87 + return rc; 88 + } 89 + 90 + static void cmma_init(void) 91 + { 92 + if (!cmma_flag) 93 + return; 94 + if (cmma_test_essa()) { 95 + cmma_flag = 0; 96 + return; 97 + } 98 + if (test_facility(147)) 99 + cmma_flag = 2; 59 100 } 60 101 61 102 static void setup_lpp(void) ··· 349 306 setup_boot_command_line(); 350 307 parse_boot_command_line(); 351 308 detect_facilities(); 309 + cmma_init(); 352 310 sanitize_prot_virt_host(); 353 311 max_physmem_end = detect_max_physmem_end(); 354 312 setup_ident_map_size(max_physmem_end);
+4
arch/s390/include/asm/page-states.h
··· 7 7 #ifndef PAGE_STATES_H 8 8 #define PAGE_STATES_H 9 9 10 + #include <asm/sections.h> 11 + 10 12 #define ESSA_GET_STATE 0 11 13 #define ESSA_SET_STABLE 1 12 14 #define ESSA_SET_UNUSED 2 ··· 19 17 #define ESSA_SET_STABLE_NODAT 7 20 18 21 19 #define ESSA_MAX ESSA_SET_STABLE_NODAT 20 + 21 + extern int __bootdata_preserved(cmma_flag); 22 22 23 23 #endif
-1
arch/s390/include/asm/setup.h
··· 125 125 126 126 void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault); 127 127 128 - void cmma_init(void); 129 128 void cmma_init_nodat(void); 130 129 131 130 extern void (*_machine_restart)(char *command);
+1
arch/s390/kernel/early.c
··· 46 46 decompressor_handled_param(dfltcc); 47 47 decompressor_handled_param(facilities); 48 48 decompressor_handled_param(nokaslr); 49 + decompressor_handled_param(cmma); 49 50 #if IS_ENABLED(CONFIG_KVM) 50 51 decompressor_handled_param(prot_virt); 51 52 #endif
-2
arch/s390/mm/init.c
··· 164 164 165 165 pv_init(); 166 166 kfence_split_mapping(); 167 - /* Setup guest page hinting */ 168 - cmma_init(); 169 167 170 168 /* this will put all low memory onto the freelists */ 171 169 memblock_free_all();
+1 -39
arch/s390/mm/page-states.c
··· 18 18 #include <asm/facility.h> 19 19 #include <asm/page-states.h> 20 20 21 - static int cmma_flag = 1; 22 - 23 - static int __init cmma(char *str) 24 - { 25 - bool enabled; 26 - 27 - if (!kstrtobool(str, &enabled)) 28 - cmma_flag = enabled; 29 - return 1; 30 - } 31 - __setup("cmma=", cmma); 32 - 33 - static inline int cmma_test_essa(void) 34 - { 35 - unsigned long tmp = 0; 36 - int rc = -EOPNOTSUPP; 37 - 38 - /* test ESSA_GET_STATE */ 39 - asm volatile( 40 - " .insn rrf,0xb9ab0000,%[tmp],%[tmp],%[cmd],0\n" 41 - "0: la %[rc],0\n" 42 - "1:\n" 43 - EX_TABLE(0b, 1b) 44 - : [rc] "+&d" (rc), [tmp] "+&d" (tmp) 45 - : [cmd] "i" (ESSA_GET_STATE)); 46 - return rc; 47 - } 48 - 49 - void __init cmma_init(void) 50 - { 51 - if (!cmma_flag) 52 - return; 53 - if (cmma_test_essa()) { 54 - cmma_flag = 0; 55 - return; 56 - } 57 - if (test_facility(147)) 58 - cmma_flag = 2; 59 - } 21 + int __bootdata_preserved(cmma_flag); 60 22 61 23 static __always_inline void essa(unsigned long paddr, unsigned char cmd) 62 24 {