Guest User

Untitled

a guest
Dec 5th, 2015
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.20 KB | None | 0 0
  1. From a5c71c50da839c6932af1903bcc0036daa033f7e Mon Sep 17 00:00:00 2001
  2. From: Vojtech Bocek <[email protected]>
  3. Date: Mon, 30 Sep 2013 18:02:43 +0200
  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 <[email protected]>
  13.  
  14. Vojtech Bocek <[email protected]>:
  15. I've ported it to mako and flo, it is based of my grouper port, which is
  16. based of Asus TF201 patche ported by Jens Andersen <[email protected]>
  17.  
  18. I've moved atags copying from guest to the host kernel, which means there
  19. is no need to patch the guest kernel, assuming the --mem-min in kexec call
  20. is within the first 256MB of System RAM, otherwise it will take a long time
  21. to load. I've also fixed /proc/atags entry, which would give the kexec-tools
  22. userspace binary only the first 1024 bytes of atags,
  23. see arch/arm/kernel/atags.c for more details.
  24.  
  25. Other than that, memory-reservation code for the hardboot page and
  26. some assembler to do the watchdog reset on MSM chip are new for this device.
  27.  
  28. kexec: use mem_text_write_kernel_word to set reboot_code_buffer args
  29. in order to avoid protection faults (writes to read-only
  30. kernel memory) when CONFIG_STRICT_MEMORY_RWX is enabled.
  31.  
  32. Signed-off-by: Vojtech Bocek <[email protected]>
  33. ---
  34. arch/arm/Kconfig | 26 +++++++++
  35. arch/arm/boot/compressed/head.S | 96 +++++++++++++++++++++++++++++++++
  36. arch/arm/include/asm/kexec.h | 8 +++
  37. arch/arm/kernel/atags.c | 51 ++++++++++++------
  38. arch/arm/kernel/machine_kexec.c | 22 ++++++--
  39. arch/arm/kernel/relocate_kernel.S | 55 +++++++++++++++++++
  40. arch/arm/mach-msm/include/mach/memory.h | 10 ++++
  41. arch/arm/mach-msm/lge/devices_lge.c | 15 ++++++
  42. arch/arm/mach-msm/restart.c | 16 ++++++
  43. include/linux/kexec.h | 19 +++++--
  44. kernel/kexec.c | 4 ++
  45. 11 files changed, 298 insertions(+), 24 deletions(-)
  46.  
  47. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
  48. index c450e1d..a577ae7 100644
  49. --- a/arch/arm/Kconfig
  50. +++ b/arch/arm/Kconfig
  51. @@ -2180,6 +2180,32 @@ config ATAGS_PROC
  52. Should the atags used to boot the kernel be exported in an "atags"
  53. file in procfs. Useful with kexec.
  54.  
  55. +config KEXEC_HARDBOOT
  56. + bool "Support hard booting to a kexec kernel"
  57. + depends on KEXEC
  58. + help
  59. + Allows hard booting (i.e., with a full hardware reboot) to a kernel
  60. + previously loaded in memory by kexec. This works around the problem of
  61. + soft-booted kernel hangs due to improper device shutdown and/or
  62. + reinitialization. Support is comprised of two components:
  63. +
  64. + First, a "hardboot" flag is added to the kexec syscall to force a hard
  65. + reboot in relocate_new_kernel() (which requires machine-specific assembly
  66. + code). This also requires the kexec userspace tool to load the kexec'd
  67. + kernel in memory region left untouched by the bootloader (i.e., not
  68. + explicitly cleared and not overwritten by the boot kernel). Just prior
  69. + to reboot, the kexec kernel arguments are stashed in a machine-specific
  70. + memory page that must also be preserved. Note that this hardboot page
  71. + need not be reserved during regular kernel execution.
  72. +
  73. + Second, the zImage decompresor of the boot (bootloader-loaded) kernel is
  74. + modified to check the hardboot page for fresh kexec arguments, and if
  75. + present, attempts to jump to the kexec'd kernel preserved in memory.
  76. +
  77. + Note that hardboot support is only required in the boot kernel and any
  78. + kernel capable of performing a hardboot kexec. It is _not_ required by a
  79. + kexec'd kernel.
  80. +
  81. config CRASH_DUMP
  82. bool "Build kdump crash kernel (EXPERIMENTAL)"
  83. depends on EXPERIMENTAL
  84. diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
  85. index 64a6d6f..c7f1e64 100644
  86. --- a/arch/arm/boot/compressed/head.S
  87. +++ b/arch/arm/boot/compressed/head.S
  88. @@ -10,6 +10,11 @@
  89. */
  90. #include <linux/linkage.h>
  91.  
  92. +#ifdef CONFIG_KEXEC_HARDBOOT
  93. + #include <asm/kexec.h>
  94. + #include <asm/memory.h>
  95. +#endif
  96. +
  97. /*
  98. * Debugging stuff
  99. *
  100. @@ -135,6 +140,97 @@ start:
  101. 1: mov r7, r1 @ save architecture ID
  102. mov r8, r2 @ save atags pointer
  103.  
  104. +#ifdef CONFIG_KEXEC_HARDBOOT
  105. + /* Check hardboot page for a kexec kernel. */
  106. + ldr r3, =KEXEC_HB_PAGE_ADDR
  107. + ldr r0, [r3]
  108. + ldr r1, =KEXEC_HB_PAGE_MAGIC
  109. + teq r0, r1
  110. + bne not_booting_other
  111. +
  112. + /* Clear hardboot page magic to avoid boot loop. */
  113. + mov r0, #0
  114. + str r0, [r3]
  115. +
  116. +/* Copy the kernel tagged list (atags):
  117. + *
  118. + * The kernel requires atags to be located in a direct-mapped region,
  119. + * usually below the kernel in the first 16 kB of RAM. If they're above
  120. + * (the start of) the kernel, they need to be copied to a suitable
  121. + * location, e.g., the machine-defined params_phys.
  122. + *
  123. + * The assumption is that the tags will only be "out of place" if the
  124. + * decompressor code is also, so copying is implemented only in the "won't
  125. + * overwrite" case (which should be fixed). Still need to make sure that
  126. + * the copied tags don't overwrite either the kernel or decompressor code
  127. + * (or rather, the remainder of it since everything up to here has already
  128. + * been executed).
  129. + *
  130. + * Vojtech Bocek <[email protected]>: I've moved atags copying from guest
  131. + * kernel to the host and rewrote it from C to assembler in order to remove
  132. + * the need for guest kernel to be patched. I don't know assembler very well,
  133. + * so it doesn't look very good and I have no idea if I didn't accidentally
  134. + * break something, causing problems down the road. It's worked every time
  135. + * and I didn't notice any problems so far though.
  136. + *
  137. + * r4: zreladdr (kernel start)
  138. + * r8: kexec_boot_atags
  139. + * r2: boot_atags */
  140. + ldr r8, [r3, #12] @ kexec_boot_atags (r2: boot_atags)
  141. + ldr r4, =zreladdr @ zreladdr
  142. +
  143. + /* No need to copy atags if they're already below kernel */
  144. + cmp r8, r4
  145. + blo no_atags_cpy
  146. +
  147. + /* r0: min(zreladdr, pc) */
  148. + mov r0, pc
  149. + cmp r4, r0
  150. + movlo r0, r4
  151. +
  152. + /* Compute max space for atags, if max <= 0 don't copy. */
  153. + subs r5, r0, r2 @ max = min(zreladdr, pc) - dest
  154. + bls no_atags_cpy
  155. +
  156. + /* Copy atags to params_phys. */
  157. + /* r8 src, r2 dest, r5 max */
  158. +
  159. + ldr r0, [r8] @ first tag size
  160. + cmp r0, #0
  161. + moveq r4, #8
  162. + beq catags_empty
  163. + mov r4, r8
  164. +
  165. +catags_foreach:
  166. + lsl r0, r0, #2 @ Multiply by 4
  167. + ldr r0, [r4, r0]! @ Load next tag size to r0 and address to r4
  168. + cmp r0, #0
  169. + bne catags_foreach
  170. +
  171. + rsb r4, r8, r4 @ r4 -= r8 (get only size)
  172. + add r4, r4, #8 @ add size of the last tag
  173. +catags_empty:
  174. + cmp r5, r4 @ if(max <= size)
  175. + bcc no_atags_cpy
  176. +
  177. + mov r5, #0 @ iterator
  178. +catags_cpy:
  179. + ldr r0, [r8, r5]
  180. + str r0, [r2, r5]
  181. + add r5, r5, #4
  182. + cmp r5, r4
  183. + blo catags_cpy
  184. +
  185. +no_atags_cpy:
  186. + /* Load boot arguments and jump to kexec kernel. */
  187. + ldr r1, [r3, #8] @ kexec_mach_type
  188. + ldr pc, [r3, #4] @ kexec_start_address
  189. +
  190. + .ltorg
  191. +
  192. +not_booting_other:
  193. +#endif
  194. +
  195. #ifndef __ARM_ARCH_2__
  196. /*
  197. * Booting from Angel - need to enter SVC mode and disable
  198. diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
  199. index c2b9b4b..564c55b 100644
  200. --- a/arch/arm/include/asm/kexec.h
  201. +++ b/arch/arm/include/asm/kexec.h
  202. @@ -17,6 +17,10 @@
  203. #define KEXEC_ARM_ATAGS_OFFSET 0x1000
  204. #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
  205.  
  206. +#ifdef CONFIG_KEXEC_HARDBOOT
  207. + #define KEXEC_HB_PAGE_MAGIC 0x4a5db007
  208. +#endif
  209. +
  210. #ifndef __ASSEMBLY__
  211.  
  212. /**
  213. @@ -53,6 +57,10 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
  214. /* Function pointer to optional machine-specific reinitialization */
  215. extern void (*kexec_reinit)(void);
  216.  
  217. +#ifdef CONFIG_KEXEC_HARDBOOT
  218. +extern void (*kexec_hardboot_hook)(void);
  219. +#endif
  220. +
  221. #endif /* __ASSEMBLY__ */
  222.  
  223. #endif /* CONFIG_KEXEC */
  224. diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
  225. index 42a1a14..0cfd7e4 100644
  226. --- a/arch/arm/kernel/atags.c
  227. +++ b/arch/arm/kernel/atags.c
  228. @@ -4,29 +4,45 @@
  229. #include <asm/types.h>
  230. #include <asm/page.h>
  231.  
  232. +/*
  233. + * [PATCH] Backport arch/arm/kernel/atags.c from 3.10
  234. + *
  235. + * There is a bug in older kernels, causing kexec-tools binary to
  236. + * only read first 1024 bytes from /proc/atags. I guess the bug is
  237. + * somewhere in /fs/proc/, since I don't think the callback in atags.c
  238. + * does something wrong. It might affect all procfs files using that
  239. + * old read callback instead of fops. Doesn't matter though, since it
  240. + * was accidentally fixed when 3.10 removed it.
  241. + *
  242. + * This might have no particular effect on real devices, because the
  243. + * atags _might_ be organized "just right", but it might be very hard
  244. + * to track down on a device where it causes problems.
  245. + *
  246. + */
  247. +
  248. struct buffer {
  249. size_t size;
  250. char data[];
  251. };
  252.  
  253. -static int
  254. -read_buffer(char* page, char** start, off_t off, int count,
  255. - int* eof, void* data)
  256. -{
  257. - struct buffer *buffer = (struct buffer *)data;
  258. -
  259. - if (off >= buffer->size) {
  260. - *eof = 1;
  261. - return 0;
  262. - }
  263. -
  264. - count = min((int) (buffer->size - off), count);
  265. +static struct buffer* atags_buffer = NULL;
  266.  
  267. - memcpy(page, &buffer->data[off], count);
  268. -
  269. - return count;
  270. +static ssize_t atags_read(struct file *file, char __user *buf,
  271. + size_t count, loff_t *ppos)
  272. +{
  273. + // These are introduced in kernel 3.10. I don't want to backport
  274. + // the whole chunk, and other things (ram_console) use static
  275. + // variable to keep data too, so I guess it's okay.
  276. + //struct buffer *b = PDE_DATA(file_inode(file));
  277. + struct buffer *b = atags_buffer;
  278. + return simple_read_from_buffer(buf, count, ppos, b->data, b->size);
  279. }
  280.  
  281. +static const struct file_operations atags_fops = {
  282. + .read = atags_read,
  283. + .llseek = default_llseek,
  284. +};
  285. +
  286. #define BOOT_PARAMS_SIZE 1536
  287. static char __initdata atags_copy[BOOT_PARAMS_SIZE];
  288.  
  289. @@ -66,12 +82,13 @@ static int __init init_atags_procfs(void)
  290. b->size = size;
  291. memcpy(b->data, atags_copy, size);
  292.  
  293. - tags_entry = create_proc_read_entry("atags", 0400,
  294. - NULL, read_buffer, b);
  295. + tags_entry = proc_create_data("atags", 0400, NULL, &atags_fops, b);
  296.  
  297. if (!tags_entry)
  298. goto nomem;
  299.  
  300. + atags_buffer = b;
  301. +
  302. return 0;
  303.  
  304. nomem:
  305. diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
  306. index c355aeb..449394d 100644
  307. --- a/arch/arm/kernel/machine_kexec.c
  308. +++ b/arch/arm/kernel/machine_kexec.c
  309. @@ -14,6 +14,7 @@
  310. #include <asm/cacheflush.h>
  311. #include <asm/mach-types.h>
  312. #include <asm/system_misc.h>
  313. +#include <asm/mmu_writeable.h>
  314.  
  315. extern const unsigned char relocate_new_kernel[];
  316. extern const unsigned int relocate_new_kernel_size;
  317. @@ -22,6 +23,10 @@ extern unsigned long kexec_start_address;
  318. extern unsigned long kexec_indirection_page;
  319. extern unsigned long kexec_mach_type;
  320. extern unsigned long kexec_boot_atags;
  321. +#ifdef CONFIG_KEXEC_HARDBOOT
  322. +extern unsigned long kexec_hardboot;
  323. +void (*kexec_hardboot_hook)(void);
  324. +#endif
  325.  
  326. static atomic_t waiting_for_crash_ipi;
  327.  
  328. @@ -120,10 +125,13 @@ void machine_kexec(struct kimage *image)
  329. reboot_code_buffer = page_address(image->control_code_page);
  330.  
  331. /* Prepare parameters for reboot_code_buffer*/
  332. - kexec_start_address = image->start;
  333. - kexec_indirection_page = page_list;
  334. - kexec_mach_type = machine_arch_type;
  335. - kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
  336. + mem_text_write_kernel_word(&kexec_start_address, image->start);
  337. + mem_text_write_kernel_word(&kexec_indirection_page, page_list);
  338. + mem_text_write_kernel_word(&kexec_mach_type, machine_arch_type);
  339. + mem_text_write_kernel_word(&kexec_boot_atags, image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET);
  340. +#ifdef CONFIG_KEXEC_HARDBOOT
  341. + mem_text_write_kernel_word(&kexec_hardboot, image->hardboot);
  342. +#endif
  343.  
  344. /* copy our kernel relocation code to the control code page */
  345. memcpy(reboot_code_buffer,
  346. @@ -137,5 +145,11 @@ void machine_kexec(struct kimage *image)
  347. if (kexec_reinit)
  348. kexec_reinit();
  349.  
  350. +#ifdef CONFIG_KEXEC_HARDBOOT
  351. + /* Run any final machine-specific shutdown code. */
  352. + if (image->hardboot && kexec_hardboot_hook)
  353. + kexec_hardboot_hook();
  354. +#endif
  355. +
  356. soft_restart(reboot_code_buffer_phys);
  357. }
  358. diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
  359. index d0cdedf..f534293 100644
  360. --- a/arch/arm/kernel/relocate_kernel.S
  361. +++ b/arch/arm/kernel/relocate_kernel.S
  362. @@ -4,6 +4,15 @@
  363.  
  364. #include <asm/kexec.h>
  365.  
  366. +#ifdef CONFIG_KEXEC_HARDBOOT
  367. +#include <asm/memory.h>
  368. +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
  369. + #include <mach/iomap.h>
  370. +#elif defined(CONFIG_ARCH_APQ8064)
  371. + #include <mach/msm_iomap.h>
  372. +#endif
  373. +#endif
  374. +
  375. .globl relocate_new_kernel
  376. relocate_new_kernel:
  377.  
  378. @@ -52,6 +61,12 @@ relocate_new_kernel:
  379. b 0b
  380.  
  381. 2:
  382. +#ifdef CONFIG_KEXEC_HARDBOOT
  383. + ldr r0, kexec_hardboot
  384. + teq r0, #0
  385. + bne hardboot
  386. +#endif
  387. +
  388. /* Jump to relocated kernel */
  389. mov lr,r1
  390. mov r0,#0
  391. @@ -60,6 +75,40 @@ relocate_new_kernel:
  392. ARM( mov pc, lr )
  393. THUMB( bx lr )
  394.  
  395. +#ifdef CONFIG_KEXEC_HARDBOOT
  396. +hardboot:
  397. + /* Stash boot arguments in hardboot page:
  398. + * 0: KEXEC_HB_PAGE_MAGIC
  399. + * 4: kexec_start_address
  400. + * 8: kexec_mach_type
  401. + * 12: kexec_boot_atags */
  402. + ldr r0, =KEXEC_HB_PAGE_ADDR
  403. + str r1, [r0, #4]
  404. + ldr r1, kexec_mach_type
  405. + str r1, [r0, #8]
  406. + ldr r1, kexec_boot_atags
  407. + str r1, [r0, #12]
  408. + ldr r1, =KEXEC_HB_PAGE_MAGIC
  409. + str r1, [r0]
  410. +
  411. +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
  412. + ldr r0, =TEGRA_PMC_BASE
  413. + ldr r1, [r0]
  414. + orr r1, r1, #0x10
  415. + str r1, [r0]
  416. +loop: b loop
  417. +#elif defined(CONFIG_ARCH_APQ8064)
  418. + /* Restart using the PMIC chip, see mach-msm/restart.c */
  419. + ldr r0, =APQ8064_TLMM_PHYS
  420. + mov r1, #0
  421. + str r1, [r0, #0x820] @ PSHOLD_CTL_SU
  422. +loop: b loop
  423. +#else
  424. +#error "No reboot method defined for hardboot."
  425. +#endif
  426. +
  427. + .ltorg
  428. +#endif
  429. .align
  430.  
  431. .globl kexec_start_address
  432. @@ -79,6 +128,12 @@ kexec_mach_type:
  433. kexec_boot_atags:
  434. .long 0x0
  435.  
  436. +#ifdef CONFIG_KEXEC_HARDBOOT
  437. + .globl kexec_hardboot
  438. +kexec_hardboot:
  439. + .long 0x0
  440. +#endif
  441. +
  442. relocate_new_kernel_end:
  443.  
  444. .globl relocate_new_kernel_size
  445. diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
  446. index 8329611..d9f6b78 100644
  447. --- a/arch/arm/mach-msm/include/mach/memory.h
  448. +++ b/arch/arm/mach-msm/include/mach/memory.h
  449. @@ -20,6 +20,16 @@
  450. /* physical offset of RAM */
  451. #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
  452.  
  453. +#if defined(CONFIG_KEXEC_HARDBOOT)
  454. +#if defined(CONFIG_MACH_APQ8064_FLO)
  455. +#define KEXEC_HB_PAGE_ADDR UL(0x88C00000)
  456. +#elif defined(CONFIG_MACH_APQ8064_MAKO)
  457. +#define KEXEC_HB_PAGE_ADDR UL(0x88600000)
  458. +#else
  459. +#error "Adress for kexec hardboot page not defined"
  460. +#endif
  461. +#endif
  462. +
  463. #define MAX_PHYSMEM_BITS 32
  464. #define SECTION_SIZE_BITS 28
  465.  
  466. diff --git a/arch/arm/mach-msm/lge/devices_lge.c b/arch/arm/mach-msm/lge/devices_lge.c
  467. index 504cc1e..f74e4e7 100644
  468. --- a/arch/arm/mach-msm/lge/devices_lge.c
  469. +++ b/arch/arm/mach-msm/lge/devices_lge.c
  470. @@ -26,6 +26,10 @@
  471.  
  472. #include <ram_console.h>
  473.  
  474. +#ifdef CONFIG_KEXEC_HARDBOOT
  475. +#include <linux/memblock.h>
  476. +#endif
  477. +
  478. /* setting whether uart console is enalbed or disabled */
  479. static int uart_console_mode = 0;
  480.  
  481. @@ -187,6 +191,17 @@ void __init lge_add_persistent_ram(void)
  482.  
  483. void __init lge_reserve(void)
  484. {
  485. +#ifdef CONFIG_KEXEC_HARDBOOT
  486. + // Reserve space for hardboot page, just before the ram_console
  487. + struct membank* bank = &meminfo.bank[0];
  488. + phys_addr_t start = bank->start + bank->size - SZ_1M - LGE_PERSISTENT_RAM_SIZE;
  489. + int ret = memblock_remove(start, SZ_1M);
  490. + if(!ret)
  491. + pr_info("Hardboot page reserved at 0x%X\n", start);
  492. + else
  493. + pr_err("Failed to reserve space for hardboot page at 0x%X!\n", start);
  494. +#endif
  495. +
  496. lge_add_persistent_ram();
  497. }
  498.  
  499. diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
  500. index 8fac40c..74ef77a 100644
  501. --- a/arch/arm/mach-msm/restart.c
  502. +++ b/arch/arm/mach-msm/restart.c
  503. @@ -35,6 +35,10 @@
  504. #include "msm_watchdog.h"
  505. #include "timer.h"
  506.  
  507. +#ifdef CONFIG_KEXEC_HARDBOOT
  508. +#include <asm/kexec.h>
  509. +#endif
  510. +
  511. #define WDT0_RST 0x38
  512. #define WDT0_EN 0x40
  513. #define WDT0_BARK_TIME 0x4C
  514. @@ -322,6 +326,14 @@ static int __init msm_pmic_restart_init(void)
  515.  
  516. late_initcall(msm_pmic_restart_init);
  517.  
  518. +#ifdef CONFIG_KEXEC_HARDBOOT
  519. +static void msm_kexec_hardboot_hook(void)
  520. +{
  521. + // Set PMIC to restart-on-poweroff
  522. + pm8xxx_reset_pwr_off(1);
  523. +}
  524. +#endif
  525. +
  526. static int __init msm_restart_init(void)
  527. {
  528. #ifdef CONFIG_MSM_DLOAD_MODE
  529. @@ -337,6 +349,10 @@ static int __init msm_restart_init(void)
  530. restart_reason = MSM_IMEM_BASE + RESTART_REASON_ADDR;
  531. pm_power_off = msm_power_off;
  532.  
  533. +#ifdef CONFIG_KEXEC_HARDBOOT
  534. + kexec_hardboot_hook = msm_kexec_hardboot_hook;
  535. +#endif
  536. +
  537. return 0;
  538. }
  539. early_initcall(msm_restart_init);
  540. diff --git a/include/linux/kexec.h b/include/linux/kexec.h
  541. index af84a25..a4509ad 100644
  542. --- a/include/linux/kexec.h
  543. +++ b/include/linux/kexec.h
  544. @@ -111,6 +111,10 @@ struct kimage {
  545. #define KEXEC_TYPE_CRASH 1
  546. unsigned int preserve_context : 1;
  547.  
  548. +#ifdef CONFIG_KEXEC_HARDBOOT
  549. + unsigned int hardboot : 1;
  550. +#endif
  551. +
  552. #ifdef ARCH_HAS_KIMAGE_ARCH
  553. struct kimage_arch arch;
  554. #endif
  555. @@ -178,6 +182,11 @@ extern struct kimage *kexec_crash_image;
  556.  
  557. #define KEXEC_ON_CRASH 0x00000001
  558. #define KEXEC_PRESERVE_CONTEXT 0x00000002
  559. +
  560. +#ifdef CONFIG_KEXEC_HARDBOOT
  561. +#define KEXEC_HARDBOOT 0x00000004
  562. +#endif
  563. +
  564. #define KEXEC_ARCH_MASK 0xffff0000
  565.  
  566. /* These values match the ELF architecture values.
  567. @@ -196,10 +205,14 @@ extern struct kimage *kexec_crash_image;
  568. #define KEXEC_ARCH_MIPS ( 8 << 16)
  569.  
  570. /* List of defined/legal kexec flags */
  571. -#ifndef CONFIG_KEXEC_JUMP
  572. -#define KEXEC_FLAGS KEXEC_ON_CRASH
  573. -#else
  574. +#if defined(CONFIG_KEXEC_JUMP) && defined(CONFIG_KEXEC_HARDBOOT)
  575. +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT | KEXEC_HARDBOOT)
  576. +#elif defined(CONFIG_KEXEC_JUMP)
  577. #define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT)
  578. +#elif defined(CONFIG_KEXEC_HARDBOOT)
  579. +#define KEXEC_FLAGS (KEXEC_ON_CRASH | KEXEC_HARDBOOT)
  580. +#else
  581. +#define KEXEC_FLAGS (KEXEC_ON_CRASH)
  582. #endif
  583.  
  584. #define VMCOREINFO_BYTES (4096)
  585. diff --git a/kernel/kexec.c b/kernel/kexec.c
  586. index 4e2e472..aef7893 100644
  587. --- a/kernel/kexec.c
  588. +++ b/kernel/kexec.c
  589. @@ -1004,6 +1004,10 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
  590.  
  591. if (flags & KEXEC_PRESERVE_CONTEXT)
  592. image->preserve_context = 1;
  593. +#ifdef CONFIG_KEXEC_HARDBOOT
  594. + if (flags & KEXEC_HARDBOOT)
  595. + image->hardboot = 1;
  596. +#endif
  597. result = machine_kexec_prepare(image);
  598. if (result)
  599. goto out;
  600. --
  601. 1.8.4.rc3
Add Comment
Please, Sign In to add comment