core.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Code to handle transition of Linux booting another kernel.
  4. *
  5. * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
  6. * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
  7. * Copyright (C) 2005 IBM Corporation.
  8. */
  9. #include <linux/kexec.h>
  10. #include <linux/reboot.h>
  11. #include <linux/threads.h>
  12. #include <linux/memblock.h>
  13. #include <linux/of.h>
  14. #include <linux/irq.h>
  15. #include <linux/ftrace.h>
  16. #include <asm/kdump.h>
  17. #include <asm/machdep.h>
  18. #include <asm/pgalloc.h>
  19. #include <asm/sections.h>
  20. #include <asm/setup.h>
  21. #include <asm/firmware.h>
  22. #define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG)
  23. #define __be_word __PASTE(__be, BITS_PER_LONG)
  24. #ifdef CONFIG_CRASH_DUMP
  25. void machine_crash_shutdown(struct pt_regs *regs)
  26. {
  27. default_machine_crash_shutdown(regs);
  28. }
  29. #endif
  30. void machine_kexec_cleanup(struct kimage *image)
  31. {
  32. }
  33. /*
  34. * Do not allocate memory (or fail in any way) in machine_kexec().
  35. * We are past the point of no return, committed to rebooting now.
  36. */
  37. void machine_kexec(struct kimage *image)
  38. {
  39. int save_ftrace_enabled;
  40. save_ftrace_enabled = __ftrace_enabled_save();
  41. this_cpu_disable_ftrace();
  42. if (ppc_md.machine_kexec)
  43. ppc_md.machine_kexec(image);
  44. else
  45. default_machine_kexec(image);
  46. this_cpu_enable_ftrace();
  47. __ftrace_enabled_restore(save_ftrace_enabled);
  48. /* Fall back to normal restart if we're still alive. */
  49. machine_restart(NULL);
  50. for(;;);
  51. }
  52. #ifdef CONFIG_CRASH_RESERVE
  53. static unsigned long long crashk_cma_size;
  54. static unsigned long long __init get_crash_base(unsigned long long crash_base)
  55. {
  56. #ifndef CONFIG_NONSTATIC_KERNEL
  57. if (crash_base != KDUMP_KERNELBASE)
  58. printk("Crash kernel location must be 0x%x\n",
  59. KDUMP_KERNELBASE);
  60. return KDUMP_KERNELBASE;
  61. #else
  62. unsigned long long crash_base_align;
  63. if (!crash_base) {
  64. #ifdef CONFIG_PPC64
  65. /*
  66. * On the LPAR platform place the crash kernel to mid of
  67. * RMA size (max. of 512MB) to ensure the crash kernel
  68. * gets enough space to place itself and some stack to be
  69. * in the first segment. At the same time normal kernel
  70. * also get enough space to allocate memory for essential
  71. * system resource in the first segment. Keep the crash
  72. * kernel starts at 128MB offset on other platforms.
  73. */
  74. if (firmware_has_feature(FW_FEATURE_LPAR))
  75. crash_base = min_t(u64, ppc64_rma_size / 2, SZ_512M);
  76. else
  77. crash_base = min_t(u64, ppc64_rma_size / 2, SZ_128M);
  78. #else
  79. crash_base = KDUMP_KERNELBASE;
  80. #endif
  81. }
  82. crash_base_align = PAGE_ALIGN(crash_base);
  83. if (crash_base != crash_base_align)
  84. pr_warn("Crash kernel base must be aligned to 0x%lx\n", PAGE_SIZE);
  85. return crash_base_align;
  86. #endif
  87. }
  88. void __init arch_reserve_crashkernel(void)
  89. {
  90. unsigned long long crash_size, crash_base, crash_end;
  91. unsigned long long kernel_start, kernel_size;
  92. unsigned long long total_mem_sz;
  93. int ret;
  94. total_mem_sz = memory_limit ? memory_limit : memblock_phys_mem_size();
  95. /* use common parsing */
  96. ret = parse_crashkernel(boot_command_line, total_mem_sz, &crash_size,
  97. &crash_base, NULL, &crashk_cma_size, NULL);
  98. if (ret)
  99. return;
  100. crash_base = get_crash_base(crash_base);
  101. crash_end = crash_base + crash_size - 1;
  102. kernel_start = __pa(_stext);
  103. kernel_size = _end - _stext;
  104. /* The crash region must not overlap the current kernel */
  105. if ((kernel_start + kernel_size > crash_base) && (kernel_start <= crash_end)) {
  106. pr_warn("Crash kernel can not overlap current kernel\n");
  107. return;
  108. }
  109. reserve_crashkernel_generic(crash_size, crash_base, 0, false);
  110. }
  111. void __init kdump_cma_reserve(void)
  112. {
  113. if (crashk_cma_size)
  114. reserve_crashkernel_cma(crashk_cma_size);
  115. }
  116. int __init overlaps_crashkernel(unsigned long start, unsigned long size)
  117. {
  118. return (start + size) > crashk_res.start && start <= crashk_res.end;
  119. }
  120. /* Values we need to export to the second kernel via the device tree. */
  121. static __be_word crashk_base;
  122. static __be_word crashk_size;
  123. static __be_word mem_limit;
  124. static struct property crashk_base_prop = {
  125. .name = "linux,crashkernel-base",
  126. .length = sizeof(__be_word),
  127. .value = &crashk_base
  128. };
  129. static struct property crashk_size_prop = {
  130. .name = "linux,crashkernel-size",
  131. .length = sizeof(__be_word),
  132. .value = &crashk_size,
  133. };
  134. static struct property memory_limit_prop = {
  135. .name = "linux,memory-limit",
  136. .length = sizeof(__be_word),
  137. .value = &mem_limit,
  138. };
  139. static void __init export_crashk_values(struct device_node *node)
  140. {
  141. /* There might be existing crash kernel properties, but we can't
  142. * be sure what's in them, so remove them. */
  143. of_remove_property(node, of_find_property(node,
  144. "linux,crashkernel-base", NULL));
  145. of_remove_property(node, of_find_property(node,
  146. "linux,crashkernel-size", NULL));
  147. if (crashk_res.start != 0) {
  148. crashk_base = cpu_to_be_ulong(crashk_res.start),
  149. of_add_property(node, &crashk_base_prop);
  150. crashk_size = cpu_to_be_ulong(resource_size(&crashk_res));
  151. of_add_property(node, &crashk_size_prop);
  152. }
  153. /*
  154. * memory_limit is required by the kexec-tools to limit the
  155. * crash regions to the actual memory used.
  156. */
  157. mem_limit = cpu_to_be_ulong(memory_limit);
  158. of_update_property(node, &memory_limit_prop);
  159. }
  160. #endif /* CONFIG_CRASH_RESERVE */
  161. static __be_word kernel_end;
  162. static struct property kernel_end_prop = {
  163. .name = "linux,kernel-end",
  164. .length = sizeof(__be_word),
  165. .value = &kernel_end,
  166. };
  167. static int __init kexec_setup(void)
  168. {
  169. struct device_node *node;
  170. node = of_find_node_by_path("/chosen");
  171. if (!node)
  172. return -ENOENT;
  173. /* remove any stale properties so ours can be found */
  174. of_remove_property(node, of_find_property(node, kernel_end_prop.name,
  175. NULL));
  176. /* information needed by userspace when using default_machine_kexec */
  177. kernel_end = cpu_to_be_ulong(__pa(_end));
  178. of_add_property(node, &kernel_end_prop);
  179. #ifdef CONFIG_CRASH_RESERVE
  180. export_crashk_values(node);
  181. #endif
  182. of_node_put(node);
  183. return 0;
  184. }
  185. late_initcall(kexec_setup);