Advertisement
Guest User

Untitled

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