1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright IBM Corp. 2007, 2009 4 * Author(s): Hongjie Yang <hongjie@us.ibm.com>, 5 */ 6 7 #define KMSG_COMPONENT "setup" 8 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 9 10 #include <linux/sched/debug.h> 11 #include <linux/cpufeature.h> 12 #include <linux/compiler.h> 13 #include <linux/init.h> 14 #include <linux/errno.h> 15 #include <linux/string.h> 16 #include <linux/ctype.h> 17 #include <linux/lockdep.h> 18 #include <linux/extable.h> 19 #include <linux/pfn.h> 20 #include <linux/uaccess.h> 21 #include <linux/kernel.h> 22 #include <asm/asm-extable.h> 23 #include <linux/memblock.h> 24 #include <asm/access-regs.h> 25 #include <asm/machine.h> 26 #include <asm/diag.h> 27 #include <asm/ebcdic.h> 28 #include <asm/fpu.h> 29 #include <asm/ipl.h> 30 #include <asm/lowcore.h> 31 #include <asm/processor.h> 32 #include <asm/sections.h> 33 #include <asm/setup.h> 34 #include <asm/sysinfo.h> 35 #include <asm/cpcmd.h> 36 #include <asm/sclp.h> 37 #include <asm/facility.h> 38 #include <asm/boot_data.h> 39 #include "entry.h" 40 41 #define __decompressor_handled_param(func, param) \ 42 static int __init ignore_decompressor_param_##func(char *s) \ 43 { \ 44 return 0; \ 45 } \ 46 early_param(#param, ignore_decompressor_param_##func) 47 48 #define decompressor_handled_param(param) __decompressor_handled_param(param, param) 49 50 decompressor_handled_param(mem); 51 decompressor_handled_param(vmalloc); 52 decompressor_handled_param(dfltcc); 53 decompressor_handled_param(facilities); 54 decompressor_handled_param(nokaslr); 55 decompressor_handled_param(cmma); 56 decompressor_handled_param(relocate_lowcore); 57 decompressor_handled_param(bootdebug); 58 __decompressor_handled_param(debug_alternative, debug-alternative); 59 #if IS_ENABLED(CONFIG_KVM) 60 decompressor_handled_param(prot_virt); 61 #endif 62 63 static void __init kasan_early_init(void) 64 { 65 #ifdef CONFIG_KASAN 66 init_task.kasan_depth = 0; 67 pr_info("KernelAddressSanitizer initialized\n"); 68 #endif 69 } 70 71 /* 72 * Initialize storage key for kernel pages 73 */ 74 static noinline __init void init_kernel_storage_key(void) 75 { 76 #if PAGE_DEFAULT_KEY 77 unsigned long end_pfn, init_pfn; 78 79 end_pfn = PFN_UP(__pa(_end)); 80 81 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) 82 page_set_storage_key(init_pfn << PAGE_SHIFT, 83 PAGE_DEFAULT_KEY, 0); 84 #endif 85 } 86 87 static __initdata char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE); 88 89 /* Remove leading, trailing and double whitespace. */ 90 static inline void strim_all(char *str) 91 { 92 char *s; 93 94 s = strim(str); 95 if (s != str) 96 memmove(str, s, strlen(s)); 97 while (*str) { 98 if (!isspace(*str++)) 99 continue; 100 if (isspace(*str)) { 101 s = skip_spaces(str); 102 memmove(str, s, strlen(s) + 1); 103 } 104 } 105 } 106 107 static noinline __init void setup_arch_string(void) 108 { 109 struct sysinfo_1_1_1 *mach = (struct sysinfo_1_1_1 *)&sysinfo_page; 110 struct sysinfo_3_2_2 *vm = (struct sysinfo_3_2_2 *)&sysinfo_page; 111 char mstr[80], hvstr[17]; 112 113 if (stsi(mach, 1, 1, 1)) 114 return; 115 EBCASC(mach->manufacturer, sizeof(mach->manufacturer)); 116 EBCASC(mach->type, sizeof(mach->type)); 117 EBCASC(mach->model, sizeof(mach->model)); 118 EBCASC(mach->model_capacity, sizeof(mach->model_capacity)); 119 sprintf(mstr, "%-16.16s %-4.4s %-16.16s %-16.16s", 120 mach->manufacturer, mach->type, 121 mach->model, mach->model_capacity); 122 strim_all(mstr); 123 if (stsi(vm, 3, 2, 2) == 0 && vm->count) { 124 EBCASC(vm->vm[0].cpi, sizeof(vm->vm[0].cpi)); 125 sprintf(hvstr, "%-16.16s", vm->vm[0].cpi); 126 strim_all(hvstr); 127 } else { 128 sprintf(hvstr, "%s", 129 machine_is_lpar() ? "LPAR" : 130 machine_is_vm() ? "z/VM" : 131 machine_is_kvm() ? "KVM" : "unknown"); 132 } 133 dump_stack_set_arch_desc("%s (%s)", mstr, hvstr); 134 } 135 136 static __init void setup_topology(void) 137 { 138 int max_mnest; 139 140 if (!cpu_has_topology()) 141 return; 142 for (max_mnest = 6; max_mnest > 1; max_mnest--) { 143 if (stsi(&sysinfo_page, 15, 1, max_mnest) == 0) 144 break; 145 } 146 topology_max_mnest = max_mnest; 147 } 148 149 void __init __do_early_pgm_check(struct pt_regs *regs) 150 { 151 struct lowcore *lc = get_lowcore(); 152 unsigned long ip; 153 154 regs->int_code = lc->pgm_int_code; 155 regs->int_parm_long = lc->trans_exc_code; 156 ip = __rewind_psw(regs->psw, regs->int_code >> 16); 157 158 /* Monitor Event? Might be a warning */ 159 if ((regs->int_code & PGM_INT_CODE_MASK) == 0x40) { 160 if (report_bug(ip, regs) == BUG_TRAP_TYPE_WARN) 161 return; 162 } 163 if (fixup_exception(regs)) 164 return; 165 /* 166 * Unhandled exception - system cannot continue but try to get some 167 * helpful messages to the console. Use early_printk() to print 168 * some basic information in case it is too early for printk(). 169 */ 170 register_early_console(); 171 early_printk("PANIC: early exception %04x PSW: %016lx %016lx\n", 172 regs->int_code & 0xffff, regs->psw.mask, regs->psw.addr); 173 show_regs(regs); 174 disabled_wait(); 175 } 176 177 static noinline __init void setup_lowcore_early(void) 178 { 179 struct lowcore *lc = get_lowcore(); 180 psw_t psw; 181 182 psw.addr = (unsigned long)early_pgm_check_handler; 183 psw.mask = PSW_KERNEL_BITS; 184 lc->program_new_psw = psw; 185 lc->preempt_count = INIT_PREEMPT_COUNT; 186 lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); 187 lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); 188 } 189 190 static inline void save_vector_registers(void) 191 { 192 #ifdef CONFIG_CRASH_DUMP 193 if (cpu_has_vx()) 194 save_vx_regs(boot_cpu_vector_save_area); 195 #endif 196 } 197 198 static inline void setup_low_address_protection(void) 199 { 200 system_ctl_set_bit(0, CR0_LOW_ADDRESS_PROTECTION_BIT); 201 } 202 203 static inline void setup_access_registers(void) 204 { 205 unsigned int acrs[NUM_ACRS] = { 0 }; 206 207 restore_access_regs(acrs); 208 } 209 210 char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; 211 static void __init setup_boot_command_line(void) 212 { 213 /* copy arch command line */ 214 strscpy(boot_command_line, early_command_line, COMMAND_LINE_SIZE); 215 } 216 217 static void __init sort_amode31_extable(void) 218 { 219 sort_extable(__start_amode31_ex_table, __stop_amode31_ex_table); 220 } 221 222 void __init startup_init(void) 223 { 224 kasan_early_init(); 225 time_early_init(); 226 init_kernel_storage_key(); 227 lockdep_off(); 228 sort_amode31_extable(); 229 setup_lowcore_early(); 230 setup_arch_string(); 231 setup_boot_command_line(); 232 save_vector_registers(); 233 setup_topology(); 234 sclp_early_detect(); 235 setup_low_address_protection(); 236 setup_access_registers(); 237 lockdep_on(); 238 } 239