Skip to contentSkip to conversation

sh: add kexec jump support

PATCH New Magnus Damm 1 participant 1 message Mar 18, 2009 SuperH

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sh: add kexec jump support

From: Magnus Damm <[email protected]>

Add kexec jump support to the SuperH architecture.

Similar to the x86 implementation, with the following exceptions:

- Instead of separating the assembly code flow into two parts for regular kexec and kexec jump we use a single code path. In the assembly snippet regular kexec is just kexec jump that never comes back.

- Instead of using a swap page when moving data between pages the page copy assembly routine has been modified to exchange the data between the pages using registers.

---

Apply on top of the previously posted vbr and p1 patches.

Tested with regular kexec and kexec jump (no return) and kexec jump with kernel returning early from head_32.S.

Kexec tools a few patches for kexec jump support on SuperH.

 arch/sh/Kconfig                  |    7 +
 arch/sh/kernel/machine_kexec.c   |   18 ++-
 arch/sh/kernel/relocate_kernel.S |  197 ++++++++++++++++++++++++++++++++------
 3 files changed, 190 insertions(+), 32 deletions(-)
arch/sh/Kconfig +7 -0
@@ -558,6 +558,13 @@ config CRASH_DUMP
 
 	  For more details see Documentation/kdump/kdump.txt
 
+config KEXEC_JUMP
+	bool "kexec jump (EXPERIMENTAL)"
+	depends on SUPERH32 && KEXEC && HIBERNATION && EXPERIMENTAL
+	help
+	  Jump between original kernel and kexeced kernel and invoke
+	  code via KEXEC
+
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on PROC_FS
arch/sh/kernel/machine_kexec.c +14 -4
@@ -14,16 +14,16 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/numa.h>
+#include <linux/suspend.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
-typedef NORET_TYPE void (*relocate_new_kernel_t)(
-				unsigned long indirection_page,
-				unsigned long reboot_code_buffer,
-				unsigned long start_address) ATTRIB_NORET;
+typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
+				      unsigned long reboot_code_buffer,
+				      unsigned long start_address);
 
 extern const unsigned char relocate_new_kernel[];
 extern const unsigned int relocate_new_kernel_size;
@@ -77,6 +77,11 @@ void machine_kexec(struct kimage *image)
 	unsigned long reboot_code_buffer;
 	relocate_new_kernel_t rnk;
 
+#ifdef CONFIG_KEXEC_JUMP
+	if (image->preserve_context)
+		save_processor_state();
+#endif
+
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
 
@@ -101,6 +106,11 @@ void machine_kexec(struct kimage *image)
 	/* now call it */
 	rnk = (relocate_new_kernel_t) reboot_code_buffer;
 	(*rnk)(page_list, reboot_code_buffer, P1SEGADDR(image->start));
+
+#ifdef CONFIG_KEXEC_JUMP
+	if (image->preserve_context)
+		restore_processor_state();
+#endif
 }
 
 void arch_crash_save_vmcoreinfo(void)
arch/sh/kernel/relocate_kernel.S +169 -28

244 lines not on this page · raw message