Guest User

Untitled

a guest
Dec 3rd, 2015
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.98 KB | None | 0 0
  1. From a550e9f996b20ea00866bf115f95b5aeb122de0c Mon Sep 17 00:00:00 2001
  2. From: Vojtech Bocek <vbocek@gmail.com>
  3. Date: Fri, 6 Dec 2013 22:56:29 +0100
  4. Subject: [PATCH] Implement kexec-hardboot
  5.  
  6. "Allows hard booting (i.e., with a full hardware reboot) to a kernel
  7. previously loaded in memory by kexec. This works around the problem of
  8. soft-booted kernel hangs due to improper device shutdown and/or
  9. reinitialization."
  10. More info in /arch/arm/Kconfig.
  11.  
  12. Original author: Mike Kasick <mike@kasick.org>
  13.  
  14. Vojtech Bocek <vbocek@gmail.com>:
  15. I've ported it to hammerhead, it is based of my mako/grouper port, which is
  16. based of Asus TF201 patch ported by Jens Andersen <jens.andersen@gmail.com>
  17.  
  18. Hammerhead is the first device I've ported this patch to which uses
  19. device tree binary instead of atags. It is also rather picky - its
  20. bootloader erases first 128MB of RAM on reboot, so following hacks had
  21. to be applied:
  22. * Copy dtb to location passed in r2 before jumping to kexecd' kernel,
  23. the kernel would just freeze when I left dtb above 128MB of RAM.
  24. * Copy kexecd' kernel to location in the first 128MB before jumping to it,
  25. the decompressor operates very slowly if the kernel is above the cached
  26. area, copying it lower and decompressing it afterwards is much faster.
  27.  
  28. Same as my mako/flo patches, the guest kernel does not require any
  29. modifications, kexec-hardboot is equivalent to standard kexec.
  30.  
  31. To support dtb, following commit was backported from the mainline:
  32. commit 4cabd1d9625c7d88acd143f4021fbef75394f154
  33. Author: Matthew Leach <matthew.leach@arm.com>
  34. Date: Fri Sep 21 18:56:02 2012 +0100
  35.  
  36. ARM: 7539/1: kexec: scan for dtb magic in segments
  37.  
  38. This patch allows a dtb to be passed to a new kernel using the kexec
  39. mechinism.
  40.  
  41. When loading segments from userspace, scan each segment's first four
  42. bytes for the dtb magic. If this is found set the kexec_boot_atags
  43. parameter to the relocate_kernel code to the phyical address of this
  44. segment.
  45.  
  46. and fixes of this commit:
  47. c564df4db85aac8d1d65a56176a0a25f46138064
  48. 2456f44dd7a9aaffc2cd21a13f78198b3d94da08
  49.  
  50. ayysir <dresadd09691@gmail.com>:
  51. kexec: use mem_text_write_kernel_word to set reboot_code_buffer args
  52. in order to avoid protection faults (writes to read-only
  53. kernel memory) when CONFIG_STRICT_MEMORY_RWX is enabled.
  54.  
  55. Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
  56. ---
  57. arch/arm/Kconfig | 26 ++++++++++++
  58. arch/arm/boot/compressed/head.S | 63 +++++++++++++++++++++++++++
  59. arch/arm/include/asm/kexec.h | 8 ++++
  60. arch/arm/kernel/machine_kexec.c | 58 +++++++++++++++++++++++--
  61. arch/arm/kernel/relocate_kernel.S | 75 +++++++++++++++++++++++++++++++++
  62. arch/arm/mach-msm/include/mach/memory.h | 13 ++++++
  63. arch/arm/mach-msm/lge/devices_lge.c | 25 +++++++++++
  64. arch/arm/mach-msm/restart.c | 28 ++++++++++++
  65. include/linux/kexec.h | 19 +++++++--
  66. kernel/kexec.c | 4 ++
  67. 10 files changed, 312 insertions(+), 7 deletions(-)
  68.  
  69. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
  70. index 69b2cd2..f853a89 100644
  71. --- a/arch/arm/Kconfig
  72. +++ b/arch/arm/Kconfig
  73. @@ -2212,6 +2212,32 @@ config ATAGS_PROC
  74. Should the atags used to boot the kernel be exported in an "atags"
  75. file in procfs. Useful with kexec.
  76.  
  77. +config KEXEC_HARDBOOT
  78. + bool "Support hard booting to a kexec kernel"
  79. + depends on KEXEC
  80. + help
  81. + Allows hard booting (i.e., with a full hardware reboot) to a kernel
  82. + previously loaded in memory by kexec. This works around the problem of
  83. + soft-booted kernel hangs due to improper device shutdown and/or
  84. + reinitialization. Support is comprised of two components:
  85. +
  86. + First, a "hardboot" flag is added to the kexec syscall to force a hard
  87. + reboot in relocate_new_kernel() (which requires machine-specific assembly
  88. + code). This also requires the kexec userspace tool to load the kexec'd
  89. + kernel in memory region left untouched by the bootloader (i.e., not
  90. + explicitly cleared and not overwritten by the boot kernel). Just prior
  91. + to reboot, the kexec kernel arguments are stashed in a machine-specific
  92. + memory page that must also be preserved. Note that this hardboot page
  93. + need not be reserved during regular kernel execution.
  94. +
  95. + Second, the zImage decompresor of the boot (bootloader-loaded) kernel is
  96. + modified to check the hardboot page for fresh kexec arguments, and if
  97. + present, attempts to jump to the kexec'd kernel preserved in memory.
  98. +
  99. + Note that hardboot support is only required in the boot kernel and any
  100. + kernel capable of performing a hardboot kexec. It is _not_ required by a
  101. + kexec'd kernel.
  102. +
  103. config CRASH_DUMP
  104. bool "Build kdump crash kernel (EXPERIMENTAL)"
  105. depends on EXPERIMENTAL
  106. diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
  107. index 64a6d6f..29e8a3a 100644
  108. --- a/arch/arm/boot/compressed/head.S
  109. +++ b/arch/arm/boot/compressed/head.S
  110. @@ -10,6 +10,11 @@
  111. */
  112. #include <linux/linkage.h>
  113.  
  114. +#ifdef CONFIG_KEXEC_HARDBOOT
  115. + #include <asm/kexec.h>
  116. + #include <asm/memory.h>
  117. +#endif
  118. +
  119. /*
  120. * Debugging stuff
  121. *
  122. @@ -135,6 +140,64 @@ start:
  123. 1: mov r7, r1 @ save architecture ID
  124. mov r8, r2 @ save atags pointer
  125.  
  126. +#ifdef CONFIG_KEXEC_HARDBOOT
  127. + /* Check hardboot page for a kexec kernel. */
  128. + ldr r3, =KEXEC_HB_PAGE_ADDR
  129. + ldr r0, [r3]
  130. + ldr r1, =KEXEC_HB_PAGE_MAGIC
  131. + teq r0, r1
  132. + bne not_booting_other
  133. +
  134. + /* Clear hardboot page magic to avoid boot loop. */
  135. + mov r0, #0
  136. + str r0, [r3]
  137. +
  138. + /*
  139. + * Copy dtb from location up high in memory to default location.
  140. + * Kernel freezes if this is not done.
  141. + */
  142. + ldr r1, [r3, #12] @ kexec_boot_atags
  143. + ldr r2, [r3, #16] @ kexec_boot_atags_len
  144. + mov r5, #0 @ iterator
  145. +catags_cpy:
  146. + ldr r0, [r1, r5] @ from kexec_boot_atags
  147. + str r0, [r8, r5] @ to atags_pointer
  148. + add r5, r5, #4
  149. + cmp r5, r2
  150. + blo catags_cpy
  151. +
  152. +#ifdef KEXEC_HB_KERNEL_LOC
  153. + /*
  154. + * Copy kernel from location up high in memory to location in first 128MB.
  155. + * Bootloader on hammerhead erases first 128MB of ram on reboot, so it can't
  156. + * be in there before reboot, but decompressing in location above 128MB takes
  157. + * a long time. This memcpy is much quicker, for some reason.
  158. + */
  159. + ldr r2, [r3, #4] @ kexec_start_address
  160. + ldr r4, [r3, #20] @ kexec_kernel_len
  161. + ldr r6, =KEXEC_HB_KERNEL_LOC @ target
  162. + mov r5, #0 @ iterator
  163. +kernel_cpy:
  164. + ldr r0, [r2, r5] @ from kexec_start_address
  165. + str r0, [r6, r5] @ to KEXEC_HB_KERNEL_LOC
  166. + add r5, r5, #4
  167. + cmp r5, r4
  168. + blo kernel_cpy
  169. +#else
  170. + ldr r6, [r3, #4] @ kexec_start_address
  171. +#endif
  172. +
  173. + /* set registers and boot kexecd' kernel */
  174. + mov r0, #0
  175. + ldr r1, [r3, #8] @ kexec_mach_type
  176. + mov r2, r8 @ atags pointer
  177. + mov pc, r6
  178. +
  179. + .ltorg
  180. +
  181. +not_booting_other:
  182. +#endif
  183. +
  184. #ifndef __ARM_ARCH_2__
  185. /*
  186. * Booting from Angel - need to enter SVC mode and disable
  187. diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
  188. index c2b9b4b..564c55b 100644
  189. --- a/arch/arm/include/asm/kexec.h
  190. +++ b/arch/arm/include/asm/kexec.h
  191. @@ -17,6 +17,10 @@
  192. #define KEXEC_ARM_ATAGS_OFFSET 0x1000
  193. #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
  194.  
  195. +#ifdef CONFIG_KEXEC_HARDBOOT
  196. + #define KEXEC_HB_PAGE_MAGIC 0x4a5db007
  197. +#endif
  198. +
  199. #ifndef __ASSEMBLY__
  200.  
  201. /**
  202. @@ -53,6 +57,10 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
  203. /* Function pointer to optional machine-specific reinitialization */
  204. extern void (*kexec_reinit)(void);
  205.  
  206. +#ifdef CONFIG_KEXEC_HARDBOOT
  207. +extern void (*kexec_hardboot_hook)(void);
  208. +#endif
  209. +
  210. #endif /* __ASSEMBLY__ */
  211.  
  212. #endif /* CONFIG_KEXEC */
  213. diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
  214. index c355aeb..2abfc8a 100644
  215. --- a/arch/arm/kernel/machine_kexec.c
  216. +++ b/arch/arm/kernel/machine_kexec.c
  217. @@ -14,6 +14,9 @@
  218. #include <asm/cacheflush.h>
  219. #include <asm/mach-types.h>
  220. #include <asm/system_misc.h>
  221. +#include <linux/memblock.h>
  222. +#include <linux/of_fdt.h>
  223. +#include <asm/mmu_writeable.h>
  224.  
  225. extern const unsigned char relocate_new_kernel[];
  226. extern const unsigned int relocate_new_kernel_size;
  227. @@ -22,6 +25,12 @@ extern unsigned long kexec_start_address;
  228. extern unsigned long kexec_indirection_page;
  229. extern unsigned long kexec_mach_type;
  230. extern unsigned long kexec_boot_atags;
  231. +#ifdef CONFIG_KEXEC_HARDBOOT
  232. +extern unsigned long kexec_hardboot;
  233. +extern unsigned long kexec_boot_atags_len;
  234. +extern unsigned long kexec_kernel_len;
  235. +void (*kexec_hardboot_hook)(void);
  236. +#endif
  237.  
  238. static atomic_t waiting_for_crash_ipi;
  239.  
  240. @@ -32,6 +41,37 @@ static atomic_t waiting_for_crash_ipi;
  241.  
  242. int machine_kexec_prepare(struct kimage *image)
  243. {
  244. + struct kexec_segment *current_segment;
  245. + __be32 header;
  246. + int i, err;
  247. +
  248. + /* No segment at default ATAGs address. try to locate
  249. + * a dtb using magic */
  250. + for (i = 0; i < image->nr_segments; i++) {
  251. + current_segment = &image->segment[i];
  252. +
  253. + err = memblock_is_region_memory(current_segment->mem,
  254. + current_segment->memsz);
  255. + if (!err)
  256. + return - EINVAL;
  257. +
  258. +#ifdef CONFIG_KEXEC_HARDBOOT
  259. + if(current_segment->mem == image->start)
  260. + mem_text_write_kernel_word(&kexec_kernel_len, current_segment->memsz);
  261. +#endif
  262. +
  263. + err = get_user(header, (__be32*)current_segment->buf);
  264. + if (err)
  265. + return err;
  266. +
  267. + if (be32_to_cpu(header) == OF_DT_HEADER)
  268. + {
  269. + mem_text_write_kernel_word(&kexec_boot_atags, current_segment->mem);
  270. +#ifdef CONFIG_KEXEC_HARDBOOT
  271. + mem_text_write_kernel_word(&kexec_boot_atags_len, current_segment->memsz);
  272. +#endif
  273. + }
  274. + }
  275. return 0;
  276. }
  277.  
  278. @@ -120,10 +160,14 @@ void machine_kexec(struct kimage *image)
  279. reboot_code_buffer = page_address(image->control_code_page);
  280.  
  281. /* Prepare parameters for reboot_code_buffer*/
  282. - kexec_start_address = image->start;
  283. - kexec_indirection_page = page_list;
  284. - kexec_mach_type = machine_arch_type;
  285. - kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
  286. + mem_text_write_kernel_word(&kexec_start_address, image->start);
  287. + mem_text_write_kernel_word(&kexec_indirection_page, page_list);
  288. + mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type);
  289. + if (!kexec_boot_atags)
  290. + mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET);
  291. +#ifdef CONFIG_KEXEC_HARDBOOT
  292. + mem_text_write_kernel_word(&kexec_hardboot, image->hardboot);
  293. +#endif
  294.  
  295. /* copy our kernel relocation code to the control code page */
  296. memcpy(reboot_code_buffer,
  297. @@ -137,5 +181,11 @@ void machine_kexec(struct kimage *image)
  298. if (kexec_reinit)
  299. kexec_reinit();
  300.  
  301. +#ifdef CONFIG_KEXEC_HARDBOOT
  302. + /* Run any final machine-specific shutdown code. */
  303. + if (image->hardboot && kexec_hardboot_hook)
  304. + kexec_hardboot_hook();
  305. +#endif
  306. +
  307. soft_restart(reboot_code_buffer_phys);
  308. }
  309. diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
  310. index d0cdedf..0e45ffc 100644
  311. --- a/arch/arm/kernel/relocate_kernel.S
  312. +++ b/arch/arm/kernel/relocate_kernel.S
  313. @@ -4,6 +4,15 @@
  314.  
  315. #include <asm/kexec.h>
  316.  
  317. +#ifdef CONFIG_KEXEC_HARDBOOT
  318. +#include <asm/memory.h>
  319. +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
  320. + #include <mach/iomap.h>
  321. +#elif defined(CONFIG_ARCH_APQ8064) || defined(CONFIG_ARCH_MSM8974)
  322. + #include <mach/msm_iomap.h>
  323. +#endif
  324. +#endif
  325. +
  326. .globl relocate_new_kernel
  327. relocate_new_kernel:
  328.  
  329. @@ -52,6 +61,12 @@ relocate_new_kernel:
  330. b 0b
  331.  
  332. 2:
  333. +#ifdef CONFIG_KEXEC_HARDBOOT
  334. + ldr r0, kexec_hardboot
  335. + teq r0, #0
  336. + bne hardboot
  337. +#endif
  338. +
  339. /* Jump to relocated kernel */
  340. mov lr,r1
  341. mov r0,#0
  342. @@ -60,6 +75,52 @@ relocate_new_kernel:
  343. ARM( mov pc, lr )
  344. THUMB( bx lr )
  345.  
  346. +#ifdef CONFIG_KEXEC_HARDBOOT
  347. +hardboot:
  348. + /* Stash boot arguments in hardboot page:
  349. + * 0: KEXEC_HB_PAGE_MAGIC
  350. + * 4: kexec_start_address
  351. + * 8: kexec_mach_type
  352. + * 12: kexec_boot_atags
  353. + * 16: kexec_boot_atags_len
  354. + * 20: kexec_kernel_len */
  355. + ldr r0, =KEXEC_HB_PAGE_ADDR
  356. + str r1, [r0, #4]
  357. + ldr r1, kexec_mach_type
  358. + str r1, [r0, #8]
  359. + ldr r1, kexec_boot_atags
  360. + str r1, [r0, #12]
  361. + ldr r1, kexec_boot_atags_len
  362. + str r1, [r0, #16]
  363. + ldr r1, kexec_kernel_len
  364. + str r1, [r0, #20]
  365. + ldr r1, =KEXEC_HB_PAGE_MAGIC
  366. + str r1, [r0]
  367. +
  368. +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
  369. + ldr r0, =TEGRA_PMC_BASE
  370. + ldr r1, [r0]
  371. + orr r1, r1, #0x10
  372. + str r1, [r0]
  373. +loop: b loop
  374. +#elif defined(CONFIG_ARCH_APQ8064)
  375. + /* Restart using the PMIC chip, see mach-msm/restart.c */
  376. + ldr r0, =APQ8064_TLMM_PHYS
  377. + mov r1, #0
  378. + str r1, [r0, #0x820] @ PSHOLD_CTL_SU
  379. +loop: b loop
  380. +#elif defined(CONFIG_ARCH_MSM8974)
  381. + /* Restart using the PMIC chip, see mach-msm/restart.c */
  382. + ldr r0, =MSM8974_MPM2_PSHOLD_PHYS
  383. + mov r1, #0
  384. + str r1, [r0, #0]
  385. +loop: b loop
  386. +#else
  387. +#error "No reboot method defined for hardboot."
  388. +#endif
  389. +
  390. + .ltorg
  391. +#endif
  392. .align
  393.  
  394. .globl kexec_start_address
  395. @@ -79,6 +140,20 @@ kexec_mach_type:
  396. kexec_boot_atags:
  397. .long 0x0
  398.  
  399. +#ifdef CONFIG_KEXEC_HARDBOOT
  400. + .globl kexec_boot_atags_len
  401. +kexec_boot_atags_len:
  402. + .long 0x0
  403. +
  404. + .globl kexec_kernel_len
  405. +kexec_kernel_len:
  406. + .long 0x0
  407. +
  408. + .globl kexec_hardboot
  409. +kexec_hardboot:
  410. + .long 0x0
  411. +#endif
  412. +
  413. relocate_new_kernel_end:
  414.  
  415. .globl relocate_new_kernel_size
  416. diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
  417. index 6119a3c..9a265f4 100644
  418. --- a/arch/arm/mach-msm/include/mach/memory.h
  419. +++ b/arch/arm/mach-msm/include/mach/memory.h
  420. @@ -20,6 +20,19 @@
  421. /* physical offset of RAM */
  422. #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
  423.  
  424. +#if defined(CONFIG_KEXEC_HARDBOOT)
  425. +#if defined(CONFIG_MACH_APQ8064_FLO)
  426. +#define KEXEC_HB_PAGE_ADDR UL(0x88C00000)
  427. +#elif defined(CONFIG_MACH_APQ8064_MAKO)
  428. +#define KEXEC_HB_PAGE_ADDR UL(0x88600000)
  429. +#elif defined(CONFIG_MACH_MSM8974_HAMMERHEAD)
  430. +#define KEXEC_HB_PAGE_ADDR UL(0x10100000)
  431. +#define KEXEC_HB_KERNEL_LOC UL(0x3208000)
  432. +#else
  433. +#error "Adress for kexec hardboot page not defined"
  434. +#endif
  435. +#endif
  436. +
  437. #define MAX_PHYSMEM_BITS 32
  438. #define SECTION_SIZE_BITS 28
  439.  
  440. diff --git a/arch/arm/mach-msm/lge/devices_lge.c b/arch/arm/mach-msm/lge/devices_lge.c
  441. index 3d176fc..c5b4e98 100644
  442. --- a/arch/arm/mach-msm/lge/devices_lge.c
  443. +++ b/arch/arm/mach-msm/lge/devices_lge.c
  444. @@ -27,6 +27,10 @@
  445. #endif
  446. #include <ram_console.h>
  447.  
  448. +#ifdef CONFIG_KEXEC_HARDBOOT
  449. +#include <linux/memblock.h>
  450. +#endif
  451. +
  452. #ifdef CONFIG_ANDROID_RAM_CONSOLE
  453. #define LGE_RAM_CONSOLE_SIZE (128 * SZ_1K * 2)
  454. static char bootreason[128] = {0,};
  455. @@ -113,6 +117,27 @@ static void __init lge_add_persist_ram_devices(void)
  456.  
  457. void __init lge_reserve(void)
  458. {
  459. +#ifdef CONFIG_KEXEC_HARDBOOT
  460. + // Reserve space for hardboot page - just after ram_console,
  461. + // at the start of second memory bank
  462. + int ret;
  463. + phys_addr_t start;
  464. + struct membank* bank;
  465. +
  466. + if (meminfo.nr_banks < 2) {
  467. + pr_err("%s: not enough membank\n", __func__);
  468. + return;
  469. + }
  470. +
  471. + bank = &meminfo.bank[1];
  472. + start = bank->start + SZ_1M + LGE_PERSISTENT_RAM_SIZE;
  473. + ret = memblock_remove(start, SZ_1M);
  474. + if(!ret)
  475. + pr_info("Hardboot page reserved at 0x%X\n", start);
  476. + else
  477. + pr_err("Failed to reserve space for hardboot page at 0x%X!\n", start);
  478. +#endif
  479. +
  480. #if defined(CONFIG_ANDROID_PERSISTENT_RAM)
  481. lge_add_persist_ram_devices();
  482. #endif
  483. diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
  484. index d208b4c..7e1caef 100644
  485. --- a/arch/arm/mach-msm/restart.c
  486. +++ b/arch/arm/mach-msm/restart.c
  487. @@ -41,6 +41,10 @@
  488. #include <mach/lge_handle_panic.h>
  489. #endif
  490.  
  491. +#ifdef CONFIG_KEXEC_HARDBOOT
  492. +#include <asm/kexec.h>
  493. +#endif
  494. +
  495. #define WDT0_RST 0x38
  496. #define WDT0_EN 0x40
  497. #define WDT0_BARK_TIME 0x4C
  498. @@ -353,6 +357,26 @@ static int __init msm_pmic_restart_init(void)
  499.  
  500. late_initcall(msm_pmic_restart_init);
  501.  
  502. +#ifdef CONFIG_KEXEC_HARDBOOT
  503. +static void msm_kexec_hardboot_hook(void)
  504. +{
  505. + set_dload_mode(0);
  506. +
  507. + // Set PMIC to restart-on-poweroff
  508. + pm8xxx_reset_pwr_off(1);
  509. +
  510. + // These are executed on normal reboot, but with kexec-hardboot,
  511. + // they reboot/panic the system immediately.
  512. +#if 0
  513. + qpnp_pon_system_pwr_off(PON_POWER_OFF_WARM_RESET);
  514. +
  515. + /* Needed to bypass debug image on some chips */
  516. + msm_disable_wdog_debug();
  517. + halt_spmi_pmic_arbiter();
  518. +#endif
  519. +}
  520. +#endif
  521. +
  522. static int __init msm_restart_init(void)
  523. {
  524. #ifdef CONFIG_MSM_DLOAD_MODE
  525. @@ -377,6 +401,10 @@ static int __init msm_restart_init(void)
  526. if (scm_is_call_available(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER) > 0)
  527. scm_pmic_arbiter_disable_supported = true;
  528.  
  529. +#ifdef CONFIG_KEXEC_HARDBOOT
  530. + kexec_hardboot_hook = msm_kexec_hardboot_hook;
  531. +#endif
  532. +
  533. return 0;
  534. }
  535. early_initcall(msm_restart_init);
  536. diff --git a/include/linux/kexec.h b/include/linux/kexec.h
  537. index af84a25..a4509ad 100644
  538. --- a/include/linux/kexec.h
  539. +++ b/include/linux/kexec.h
  540. @@ -111,6 +111,10 @@ struct kimage {
  541. #define KEXEC_TYPE_CRASH 1
  542. unsigned int preserve_context : 1;
  543.  
  544. +#ifdef CONFIG_KEXEC_HARDBOOT
  545. + unsigned int hardboot : 1;
  546. +#endif
  547. +
  548. #ifdef ARCH_HAS_KIMAGE_ARCH
  549. struct kimage_arch arch;
  550. #endif
  551. @@ -178,6 +182,11 @@ extern struct kimage *kexec_crash_image;
  552.  
  553. #define KEXEC_ON_CRASH 0x00000001
  554. #define KEXEC_PRESERVE_CONTEXT 0x00000002
  555. +
  556. +#ifdef CONFIG_KEXEC_HARDBOOT
  557. +#define KEXEC_HARDBOOT 0x00000004
  558. +#endif
  559. +
  560. #define KEXEC_ARCH_MASK 0xffff0000
  561.  
  562. /* These values match the ELF architecture values.
  563. @@ -196,10 +205,14 @@ extern struct kimage *kexec_crash_image;
  564. #define KEXEC_ARCH_MIPS ( 8 << 16)
  565.  
  566. /* List of defined/legal kexec flags */
  567. -#ifndef CONFIG_KEXEC_JUMP
  568. -#define KEXEC_FLAGS KEXEC_ON_CRASH
  569. -#else
  570. +#if defined(CONFIG_KEXEC_JUMP) && defined(CONFIG_KEXEC_HARDBOOT)
  571. +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT | KEXEC_HARDBOOT)
  572. +#elif defined(CONFIG_KEXEC_JUMP)
  573. #define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT)
  574. +#elif defined(CONFIG_KEXEC_HARDBOOT)
  575. +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_HARDBOOT)
  576. +#else
  577. +#define KEXEC_FLAGS (KEXEC_ON_CRASH)
  578. #endif
  579.  
  580. #define VMCOREINFO_BYTES (4096)
  581. diff --git a/kernel/kexec.c b/kernel/kexec.c
  582. index 4e2e472..aef7893 100644
  583. --- a/kernel/kexec.c
  584. +++ b/kernel/kexec.c
  585. @@ -1004,6 +1004,10 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
  586.  
  587. if (flags & KEXEC_PRESERVE_CONTEXT)
  588. image->preserve_context = 1;
  589. +#ifdef CONFIG_KEXEC_HARDBOOT
  590. + if (flags & KEXEC_HARDBOOT)
  591. + image->hardboot = 1;
  592. +#endif
  593. result = machine_kexec_prepare(image);
  594. if (result)
  595. goto out;
  596. --
  597. 1.8.5.1
Add Comment
Please, Sign In to add comment