early.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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. #define KMSG_COMPONENT "setup"
  7. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  8. #include <linux/sched/debug.h>
  9. #include <linux/compiler.h>
  10. #include <linux/init.h>
  11. #include <linux/errno.h>
  12. #include <linux/string.h>
  13. #include <linux/ctype.h>
  14. #include <linux/lockdep.h>
  15. #include <linux/extable.h>
  16. #include <linux/pfn.h>
  17. #include <linux/uaccess.h>
  18. #include <linux/kernel.h>
  19. #include <asm/asm-extable.h>
  20. #include <linux/memblock.h>
  21. #include <asm/access-regs.h>
  22. #include <asm/diag.h>
  23. #include <asm/ebcdic.h>
  24. #include <asm/fpu.h>
  25. #include <asm/ipl.h>
  26. #include <asm/lowcore.h>
  27. #include <asm/processor.h>
  28. #include <asm/sections.h>
  29. #include <asm/setup.h>
  30. #include <asm/sysinfo.h>
  31. #include <asm/cpcmd.h>
  32. #include <asm/sclp.h>
  33. #include <asm/facility.h>
  34. #include <asm/boot_data.h>
  35. #include "entry.h"
  36. #define decompressor_handled_param(param) \
  37. static int __init ignore_decompressor_param_##param(char *s) \
  38. { \
  39. return 0; \
  40. } \
  41. early_param(#param, ignore_decompressor_param_##param)
  42. decompressor_handled_param(mem);
  43. decompressor_handled_param(vmalloc);
  44. decompressor_handled_param(dfltcc);
  45. decompressor_handled_param(facilities);
  46. decompressor_handled_param(nokaslr);
  47. decompressor_handled_param(cmma);
  48. decompressor_handled_param(relocate_lowcore);
  49. #if IS_ENABLED(CONFIG_KVM)
  50. decompressor_handled_param(prot_virt);
  51. #endif
  52. static void __init kasan_early_init(void)
  53. {
  54. #ifdef CONFIG_KASAN
  55. init_task.kasan_depth = 0;
  56. sclp_early_printk("KernelAddressSanitizer initialized\n");
  57. #endif
  58. }
  59. static void __init reset_tod_clock(void)
  60. {
  61. union tod_clock clk;
  62. if (store_tod_clock_ext_cc(&clk) == 0)
  63. return;
  64. /* TOD clock not running. Set the clock to Unix Epoch. */
  65. if (set_tod_clock(TOD_UNIX_EPOCH) || store_tod_clock_ext_cc(&clk))
  66. disabled_wait();
  67. memset(&tod_clock_base, 0, sizeof(tod_clock_base));
  68. tod_clock_base.tod = TOD_UNIX_EPOCH;
  69. get_lowcore()->last_update_clock = TOD_UNIX_EPOCH;
  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. end_pfn = PFN_UP(__pa(_end));
  79. for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
  80. page_set_storage_key(init_pfn << PAGE_SHIFT,
  81. PAGE_DEFAULT_KEY, 0);
  82. #endif
  83. }
  84. static __initdata char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE);
  85. static noinline __init void detect_machine_type(void)
  86. {
  87. struct sysinfo_3_2_2 *vmms = (struct sysinfo_3_2_2 *)&sysinfo_page;
  88. /* Check current-configuration-level */
  89. if (stsi(NULL, 0, 0, 0) <= 2) {
  90. get_lowcore()->machine_flags |= MACHINE_FLAG_LPAR;
  91. return;
  92. }
  93. /* Get virtual-machine cpu information. */
  94. if (stsi(vmms, 3, 2, 2) || !vmms->count)
  95. return;
  96. /* Detect known hypervisors */
  97. if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
  98. get_lowcore()->machine_flags |= MACHINE_FLAG_KVM;
  99. else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4))
  100. get_lowcore()->machine_flags |= MACHINE_FLAG_VM;
  101. }
  102. /* Remove leading, trailing and double whitespace. */
  103. static inline void strim_all(char *str)
  104. {
  105. char *s;
  106. s = strim(str);
  107. if (s != str)
  108. memmove(str, s, strlen(s));
  109. while (*str) {
  110. if (!isspace(*str++))
  111. continue;
  112. if (isspace(*str)) {
  113. s = skip_spaces(str);
  114. memmove(str, s, strlen(s) + 1);
  115. }
  116. }
  117. }
  118. static noinline __init void setup_arch_string(void)
  119. {
  120. struct sysinfo_1_1_1 *mach = (struct sysinfo_1_1_1 *)&sysinfo_page;
  121. struct sysinfo_3_2_2 *vm = (struct sysinfo_3_2_2 *)&sysinfo_page;
  122. char mstr[80], hvstr[17];
  123. if (stsi(mach, 1, 1, 1))
  124. return;
  125. EBCASC(mach->manufacturer, sizeof(mach->manufacturer));
  126. EBCASC(mach->type, sizeof(mach->type));
  127. EBCASC(mach->model, sizeof(mach->model));
  128. EBCASC(mach->model_capacity, sizeof(mach->model_capacity));
  129. sprintf(mstr, "%-16.16s %-4.4s %-16.16s %-16.16s",
  130. mach->manufacturer, mach->type,
  131. mach->model, mach->model_capacity);
  132. strim_all(mstr);
  133. if (stsi(vm, 3, 2, 2) == 0 && vm->count) {
  134. EBCASC(vm->vm[0].cpi, sizeof(vm->vm[0].cpi));
  135. sprintf(hvstr, "%-16.16s", vm->vm[0].cpi);
  136. strim_all(hvstr);
  137. } else {
  138. sprintf(hvstr, "%s",
  139. MACHINE_IS_LPAR ? "LPAR" :
  140. MACHINE_IS_VM ? "z/VM" :
  141. MACHINE_IS_KVM ? "KVM" : "unknown");
  142. }
  143. dump_stack_set_arch_desc("%s (%s)", mstr, hvstr);
  144. }
  145. static __init void setup_topology(void)
  146. {
  147. int max_mnest;
  148. if (!test_facility(11))
  149. return;
  150. get_lowcore()->machine_flags |= MACHINE_FLAG_TOPOLOGY;
  151. for (max_mnest = 6; max_mnest > 1; max_mnest--) {
  152. if (stsi(&sysinfo_page, 15, 1, max_mnest) == 0)
  153. break;
  154. }
  155. topology_max_mnest = max_mnest;
  156. }
  157. void __init __do_early_pgm_check(struct pt_regs *regs)
  158. {
  159. struct lowcore *lc = get_lowcore();
  160. unsigned long ip;
  161. regs->int_code = lc->pgm_int_code;
  162. regs->int_parm_long = lc->trans_exc_code;
  163. regs->last_break = lc->pgm_last_break;
  164. ip = __rewind_psw(regs->psw, regs->int_code >> 16);
  165. /* Monitor Event? Might be a warning */
  166. if ((regs->int_code & PGM_INT_CODE_MASK) == 0x40) {
  167. if (report_bug(ip, regs) == BUG_TRAP_TYPE_WARN)
  168. return;
  169. }
  170. if (fixup_exception(regs))
  171. return;
  172. /*
  173. * Unhandled exception - system cannot continue but try to get some
  174. * helpful messages to the console. Use early_printk() to print
  175. * some basic information in case it is too early for printk().
  176. */
  177. register_early_console();
  178. early_printk("PANIC: early exception %04x PSW: %016lx %016lx\n",
  179. regs->int_code & 0xffff, regs->psw.mask, regs->psw.addr);
  180. show_regs(regs);
  181. disabled_wait();
  182. }
  183. static noinline __init void setup_lowcore_early(void)
  184. {
  185. struct lowcore *lc = get_lowcore();
  186. psw_t psw;
  187. psw.addr = (unsigned long)early_pgm_check_handler;
  188. psw.mask = PSW_KERNEL_BITS;
  189. lc->program_new_psw = psw;
  190. lc->preempt_count = INIT_PREEMPT_COUNT;
  191. lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW);
  192. lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW);
  193. }
  194. static __init void detect_diag9c(void)
  195. {
  196. unsigned int cpu_address;
  197. int rc;
  198. cpu_address = stap();
  199. diag_stat_inc(DIAG_STAT_X09C);
  200. asm volatile(
  201. " diag %2,0,0x9c\n"
  202. "0: la %0,0\n"
  203. "1:\n"
  204. EX_TABLE(0b,1b)
  205. : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc");
  206. if (!rc)
  207. get_lowcore()->machine_flags |= MACHINE_FLAG_DIAG9C;
  208. }
  209. static __init void detect_machine_facilities(void)
  210. {
  211. if (test_facility(8)) {
  212. get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT1;
  213. system_ctl_set_bit(0, CR0_EDAT_BIT);
  214. }
  215. if (test_facility(78))
  216. get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT2;
  217. if (test_facility(3))
  218. get_lowcore()->machine_flags |= MACHINE_FLAG_IDTE;
  219. if (test_facility(50) && test_facility(73)) {
  220. get_lowcore()->machine_flags |= MACHINE_FLAG_TE;
  221. system_ctl_set_bit(0, CR0_TRANSACTIONAL_EXECUTION_BIT);
  222. }
  223. if (test_facility(51))
  224. get_lowcore()->machine_flags |= MACHINE_FLAG_TLB_LC;
  225. if (test_facility(129))
  226. system_ctl_set_bit(0, CR0_VECTOR_BIT);
  227. if (test_facility(130))
  228. get_lowcore()->machine_flags |= MACHINE_FLAG_NX;
  229. if (test_facility(133))
  230. get_lowcore()->machine_flags |= MACHINE_FLAG_GS;
  231. if (test_facility(139) && (tod_clock_base.tod >> 63)) {
  232. /* Enabled signed clock comparator comparisons */
  233. get_lowcore()->machine_flags |= MACHINE_FLAG_SCC;
  234. clock_comparator_max = -1ULL >> 1;
  235. system_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SIGN_BIT);
  236. }
  237. if (IS_ENABLED(CONFIG_PCI) && test_facility(153)) {
  238. get_lowcore()->machine_flags |= MACHINE_FLAG_PCI_MIO;
  239. /* the control bit is set during PCI initialization */
  240. }
  241. if (test_facility(194))
  242. get_lowcore()->machine_flags |= MACHINE_FLAG_RDP;
  243. if (test_facility(85))
  244. get_lowcore()->machine_flags |= MACHINE_FLAG_SEQ_INSN;
  245. }
  246. static inline void save_vector_registers(void)
  247. {
  248. #ifdef CONFIG_CRASH_DUMP
  249. if (test_facility(129))
  250. save_vx_regs(boot_cpu_vector_save_area);
  251. #endif
  252. }
  253. static inline void setup_low_address_protection(void)
  254. {
  255. system_ctl_set_bit(0, CR0_LOW_ADDRESS_PROTECTION_BIT);
  256. }
  257. static inline void setup_access_registers(void)
  258. {
  259. unsigned int acrs[NUM_ACRS] = { 0 };
  260. restore_access_regs(acrs);
  261. }
  262. char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
  263. static void __init setup_boot_command_line(void)
  264. {
  265. /* copy arch command line */
  266. strscpy(boot_command_line, early_command_line, COMMAND_LINE_SIZE);
  267. }
  268. static void __init sort_amode31_extable(void)
  269. {
  270. sort_extable(__start_amode31_ex_table, __stop_amode31_ex_table);
  271. }
  272. void __init startup_init(void)
  273. {
  274. kasan_early_init();
  275. reset_tod_clock();
  276. time_early_init();
  277. init_kernel_storage_key();
  278. lockdep_off();
  279. sort_amode31_extable();
  280. setup_lowcore_early();
  281. detect_machine_type();
  282. setup_arch_string();
  283. setup_boot_command_line();
  284. detect_diag9c();
  285. detect_machine_facilities();
  286. save_vector_registers();
  287. setup_topology();
  288. sclp_early_detect();
  289. setup_low_address_protection();
  290. setup_access_registers();
  291. lockdep_on();
  292. }