LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATH 1/1] Kexec jump - v2 - kexec jump
@ 2007-07-15  7:13 Huang, Ying
  2007-07-31  9:51 ` Pavel Machek
  0 siblings, 1 reply; 8+ messages in thread
From: Huang, Ying @ 2007-07-15  7:13 UTC (permalink / raw)
  To: Eric W. Biederman, Pavel Machek, nigel, Rafael J. Wysocki,
	Jeremy Maitin-Shepard, Alan Stern, Andrew Morton, david
  Cc: linux-kernel, linux-pm, Kexec Mailing List

This patch implement the functionality of jumping from kexeced kernel
to original kernel.

A new reboot command named LINUX_REBOOT_CMD_KJUMP is defined to
trigger the jumping to (executing) the new kernel or jumping back to
the original kernel.

To support jumping back from kexeced kernel, before executing the new
kernel, the devices are put into quiescent state (to be fully
implemented), and the state of devices and CPU is saved. After jumping
back from kexeced kernel, the state of devices and CPU are restored
accordingly. The devices/CPU state save/restore code of software
suspend is called to implement corresponding function.

Signed-off-by: Huang Ying <ying.huang@intel.com>

---

 arch/i386/Kconfig                |    7 +++
 arch/i386/kernel/Makefile        |    1 
 arch/i386/kernel/kexec_jump.S    |   74 +++++++++++++++++++++++++++++++++++++
 arch/i386/kernel/machine_kexec.c |   59 +++++++++++++++++++++++++++++
 include/asm-i386/kexec.h         |    4 ++
 include/linux/kexec.h            |   17 ++++++++
 include/linux/reboot.h           |    1 
 kernel/kexec.c                   |   78 +++++++++++++++++++++++++++++++++++++++
 kernel/ksysfs.c                  |   12 ++++++
 kernel/sys.c                     |    8 ++++
 10 files changed, 261 insertions(+)

Index: linux-2.6/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/i386/kernel/Makefile	2007-07-14 14:52:45.000000000 +0800
+++ linux-2.6/arch/i386/kernel/Makefile	2007-07-14 17:50:50.000000000 +0800
@@ -27,6 +27,7 @@
 obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
+obj-$(CONFIG_KEXEC_JUMP)	+= kexec_jump.o
 obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
 obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
Index: linux-2.6/arch/i386/kernel/machine_kexec.c
===================================================================
--- linux-2.6.orig/arch/i386/kernel/machine_kexec.c	2007-07-14 14:52:45.000000000 +0800
+++ linux-2.6/arch/i386/kernel/machine_kexec.c	2007-07-15 11:22:23.000000000 +0800
@@ -10,6 +10,7 @@
 #include <linux/kexec.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/highmem.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
@@ -169,3 +170,61 @@
 	return 0;
 }
 early_param("crashkernel", parse_crashkernel);
+
+#ifdef CONFIG_KEXEC_JUMP
+int machine_kexec_jump(void)
+{
+	asmlinkage int (*real_jump)(void *buf);
+	unsigned long jump_buf_pfn;
+	void *jump_buf;
+
+	if (!(kexec_flags & KEXEC_FLAGS_IS_KEXECED_KERNEL) &&
+	    !kexec_crash_image)
+		return -EINVAL;
+	jump_buf_pfn = kexec_get_jump_buf_pfn(0);
+	if (!jump_buf_pfn)
+		return -EINVAL;
+	jump_buf = kmap_atomic_pfn(jump_buf_pfn, KM_PTE0);
+	memcpy(jump_buf + PAGE_SIZE/2, machine_kexec_real_jump, PAGE_SIZE/2);
+	real_jump = jump_buf + PAGE_SIZE/2;
+
+	if (!real_jump(jump_buf))
+		machine_kexec(kexec_crash_image);
+	kunmap_atomic(jump_buf, KM_PTE0);
+	return 0;
+}
+
+static unsigned long kexec_backup_addr = ~0UL;
+
+/* kexec_backup= specifies the location of backuped 0~640k memory of
+ * crashed kernel.
+ */
+static int __init parse_kexec_backup(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	kexec_backup_addr = memparse(arg, &arg);
+	return 0;
+}
+early_param("kexec_backup", parse_kexec_backup);
+
+void kexec_restore_backup(void)
+{
+	void *vaddr;
+	void *vaddr_backup;
+	unsigned long paddr;
+
+	if (kexec_backup_addr == ~0UL)
+		return;
+
+	for (paddr = 0; paddr < 640 * 1024; paddr += PAGE_SIZE) {
+		vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT, KM_PTE0);
+		vaddr_backup = kmap_atomic_pfn((paddr+kexec_backup_addr) >> PAGE_SHIFT,
+					       KM_PTE1);
+		memcpy(vaddr, vaddr_backup, PAGE_SIZE);
+		kunmap_atomic(vaddr, KM_PTE0);
+		kunmap_atomic(vaddr_backup, KM_PTE1);
+	}
+}
+#endif /* CONFIG_KEXEC_JUMP */
Index: linux-2.6/include/asm-i386/kexec.h
===================================================================
--- linux-2.6.orig/include/asm-i386/kexec.h	2007-07-14 14:52:45.000000000 +0800
+++ linux-2.6/include/asm-i386/kexec.h	2007-07-14 21:21:16.000000000 +0800
@@ -94,6 +94,10 @@
 		unsigned long start_address,
 		unsigned int has_pae) ATTRIB_NORET;
 
+#ifdef CONFIG_KEXEC_JUMP
+extern asmlinkage int machine_kexec_real_jump(void *buf);
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _I386_KEXEC_H */
Index: linux-2.6/include/linux/kexec.h
===================================================================
--- linux-2.6.orig/include/linux/kexec.h	2007-07-14 14:52:45.000000000 +0800
+++ linux-2.6/include/linux/kexec.h	2007-07-15 11:22:57.000000000 +0800
@@ -1,6 +1,11 @@
 #ifndef LINUX_KEXEC_H
 #define LINUX_KEXEC_H
 
+#ifdef CONFIG_KEXEC_JUMP
+#define KEXEC_FLAGS_IS_KEXECED_KERNEL     0x1
+#endif /* CONFIG_KEXEC_JUMP */
+
+#ifndef __ASSEMBLY__
 #ifdef CONFIG_KEXEC
 #include <linux/types.h>
 #include <linux/list.h>
@@ -161,4 +166,16 @@
 static inline void crash_kexec(struct pt_regs *regs) { }
 static inline int kexec_should_crash(struct task_struct *p) { return 0; }
 #endif /* CONFIG_KEXEC */
+
+#ifdef CONFIG_KEXEC_JUMP
+extern int kexec_flags;
+extern int machine_kexec_jump(void);
+extern int kexec_jump(void);
+extern unsigned long kexec_get_jump_buf_pfn(int alloc);
+extern void kexec_restore_backup(void);
+#else
+static inline int kexec_jump(void) { return 0; }
+#endif /* CONFIG_KEXEC_JUMP */
+#endif /* !__ASSEMBLY__ */
+
 #endif /* LINUX_KEXEC_H */
Index: linux-2.6/kernel/kexec.c
===================================================================
--- linux-2.6.orig/kernel/kexec.c	2007-07-14 14:52:45.000000000 +0800
+++ linux-2.6/kernel/kexec.c	2007-07-15 12:57:25.000000000 +0800
@@ -22,6 +22,9 @@
 #include <linux/hardirq.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/suspend.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -1135,3 +1138,78 @@
 	return 0;
 }
 module_init(crash_notes_memory_init)
+
+#ifdef CONFIG_KEXEC_JUMP
+int kexec_flags;
+
+static unsigned long kexec_jump_buf_pfn;
+
+static int __init parse_kexec_jump_buf_pfn(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	kexec_jump_buf_pfn = memparse(arg, &arg);
+	kexec_flags |= KEXEC_FLAGS_IS_KEXECED_KERNEL;
+	return 0;
+}
+early_param("kexec_jump_buf_pfn", parse_kexec_jump_buf_pfn);
+
+unsigned long kexec_get_jump_buf_pfn(int alloc)
+{
+	struct page *jump_buf_page;
+
+	if (!kexec_jump_buf_pfn && alloc) {
+		jump_buf_page = alloc_page(GFP_KERNEL);
+		kexec_jump_buf_pfn = page_to_pfn(jump_buf_page);
+	}
+	return kexec_jump_buf_pfn;
+}
+
+int kexec_jump(void)
+{
+	int error;
+
+	if (!(kexec_flags & KEXEC_FLAGS_IS_KEXECED_KERNEL) &&
+	    !kexec_crash_image)
+		return -EINVAL;
+	error = device_suspend(PMSG_FREEZE);
+	if (error)
+		goto Resume_devices;
+	error = disable_nonboot_cpus();
+	if (error)
+		goto Enable_cpus;
+	local_irq_disable();
+	/* At this point, device_suspend() has been called, but *not*
+	 * device_power_down(). We *must* device_power_down() now.
+	 * Otherwise, drivers for some devices (e.g. interrupt controllers)
+	 * become desynchronized with the actual state of the hardware
+	 * at resume time, and evil weirdness ensues.
+	 */
+	error = device_power_down(PMSG_FREEZE);
+	if (error)
+		goto Enable_irqs;
+
+	if (kexec_flags & KEXEC_FLAGS_IS_KEXECED_KERNEL)
+		kexec_restore_backup();
+	save_processor_state();
+	error = machine_kexec_jump();
+	restore_processor_state();
+
+	/* NOTE:  device_power_up() is just a resume() for devices
+	 * that suspended with irqs off ... no overall powerup.
+	 */
+	device_power_up();
+ Enable_irqs:
+	local_irq_enable();
+ Enable_cpus:
+	enable_nonboot_cpus();
+ Resume_devices:
+	device_resume();
+	if (!error) {
+		kimage_free(kexec_crash_image);
+		kexec_crash_image = NULL;
+	}
+	return error;
+}
+#endif /* CONFIG_KEXEC_JUMP */
Index: linux-2.6/kernel/ksysfs.c
===================================================================
--- linux-2.6.orig/kernel/ksysfs.c	2007-07-14 14:52:45.000000000 +0800
+++ linux-2.6/kernel/ksysfs.c	2007-07-14 17:55:46.000000000 +0800
@@ -60,6 +60,15 @@
 	return sprintf(page, "%d\n", !!kexec_crash_image);
 }
 KERNEL_ATTR_RO(kexec_crash_loaded);
+
+#ifdef CONFIG_KEXEC_JUMP
+static ssize_t kexec_jump_buf_pfn_show(struct kset *kset, char *page)
+{
+	return sprintf(page, "0x%lx\n", kexec_get_jump_buf_pfn(1));
+}
+
+KERNEL_ATTR_RO(kexec_jump_buf_pfn);
+#endif
 #endif /* CONFIG_KEXEC */
 
 decl_subsys(kernel, NULL, NULL);
@@ -73,6 +82,9 @@
 #ifdef CONFIG_KEXEC
 	&kexec_loaded_attr.attr,
 	&kexec_crash_loaded_attr.attr,
+#ifdef CONFIG_KEXEC_JUMP
+	&kexec_jump_buf_pfn_attr.attr,
+#endif
 #endif
 	NULL
 };
Index: linux-2.6/arch/i386/kernel/kexec_jump.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/arch/i386/kernel/kexec_jump.S	2007-07-15 11:26:51.000000000 +0800
@@ -0,0 +1,74 @@
+/*
+ * kexec_jump.S - Jump between normal kernel and kexeced kernel
+ * Copyright (C) 2007 Huang Ying <ying.huang@intel.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/kexec.h>
+#include <asm/page.h>
+#include <asm/kexec.h>
+
+/*
+ * Must be relocatable PIC code callable as a C function
+ */
+#define HALF_PAGE_ALIGNED (1 << (PAGE_SHIFT-1))
+
+#define EBX	0x0
+#define ESI	0x4
+#define EDI	0x8
+#define EBP	0xc
+#define ESP	0x10
+#define CR0	0x14
+#define CR3	0x18
+#define CR4	0x1c
+#define FLAG	0x20
+#define RET	0x24
+
+	.text
+	.align HALF_PAGE_ALIGNED
+	.globl machine_kexec_real_jump
+machine_kexec_real_jump:
+	movl	4(%esp), %edx
+	movl	kexec_flags, %ecx
+	andl	$KEXEC_FLAGS_IS_KEXECED_KERNEL, %ecx
+	jnz	1f
+	movl	%ebx, EBX(%edx)
+	movl	%esi, ESI(%edx)
+	movl	%edi, EDI(%edx)
+	movl	%ebp, EBP(%edx)
+	movl	%esp, ESP(%edx)
+	movl	%cr0, %eax
+	movl	%eax, CR0(%edx)
+	movl	%cr3, %eax
+	movl	%eax, CR3(%edx)
+	movl	%cr4, %eax
+	movl	%eax, CR4(%edx)
+	pushf
+	popl	%eax
+	movl	%eax, FLAG(%edx)
+	movl	(%esp), %eax
+	movl	%eax, RET(%edx)
+	mov	$0, %eax
+	ret
+1:
+	movl	EBX(%edx), %ebx
+	movl	ESI(%edx), %esi
+	movl	EDI(%edx), %edi
+	movl	EBP(%edx), %ebp
+	movl	FLAG(%edx), %eax
+	pushl	%eax
+	popf
+	movl	ESP(%edx), %esp
+	movl	CR4(%edx), %eax
+	movl	%eax, %cr4
+	movl	CR3(%edx), %eax
+	movl	%eax, %cr3
+	movl	CR0(%edx), %eax
+	movl	%eax, %cr0
+	movl	RET(%edx), %eax
+	movl	%eax, (%esp)
+	mov	$1, %eax
+	ret
Index: linux-2.6/kernel/sys.c
===================================================================
--- linux-2.6.orig/kernel/sys.c	2007-07-14 16:45:21.000000000 +0800
+++ linux-2.6/kernel/sys.c	2007-07-14 17:39:47.000000000 +0800
@@ -940,6 +940,14 @@
 		unlock_kernel();
 		return -EINVAL;
 
+	case LINUX_REBOOT_CMD_KJUMP:
+		{
+			int ret;
+			ret = kexec_jump();
+			unlock_kernel();
+			return ret;
+		}
+
 #ifdef CONFIG_SOFTWARE_SUSPEND
 	case LINUX_REBOOT_CMD_SW_SUSPEND:
 		{
Index: linux-2.6/include/linux/reboot.h
===================================================================
--- linux-2.6.orig/include/linux/reboot.h	2007-07-14 17:29:58.000000000 +0800
+++ linux-2.6/include/linux/reboot.h	2007-07-14 20:43:04.000000000 +0800
@@ -33,6 +33,7 @@
 #define	LINUX_REBOOT_CMD_RESTART2	0xA1B2C3D4
 #define	LINUX_REBOOT_CMD_SW_SUSPEND	0xD000FCE2
 #define	LINUX_REBOOT_CMD_KEXEC		0x45584543
+#define	LINUX_REBOOT_CMD_KJUMP		0x3928A5FD
 
 
 #ifdef __KERNEL__
Index: linux-2.6/arch/i386/Kconfig
===================================================================
--- linux-2.6.orig/arch/i386/Kconfig	2007-07-14 17:52:02.000000000 +0800
+++ linux-2.6/arch/i386/Kconfig	2007-07-14 19:08:37.000000000 +0800
@@ -813,6 +813,13 @@
           PHYSICAL_START.
 	  For more details see Documentation/kdump/kdump.txt
 
+config KEXEC_JUMP
+	bool "kexec jump (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	depends on PM && X86_32 && KEXEC
+	---help---
+	  Jump back from kexeced kernel to orignal kernel.
+
 config PHYSICAL_START
 	hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
 	default "0x100000"

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-07-15  7:13 [PATH 1/1] Kexec jump - v2 - kexec jump Huang, Ying
@ 2007-07-31  9:51 ` Pavel Machek
  2007-08-01  7:56   ` Huang, Ying
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2007-07-31  9:51 UTC (permalink / raw)
  To: Huang, Ying
  Cc: Eric W. Biederman, nigel, Rafael J. Wysocki,
	Jeremy Maitin-Shepard, Alan Stern, Andrew Morton, david,
	linux-kernel, linux-pm, Kexec Mailing List

Hi!

> This patch implement the functionality of jumping from kexeced kernel
> to original kernel.
> 
> A new reboot command named LINUX_REBOOT_CMD_KJUMP is defined to
> trigger the jumping to (executing) the new kernel or jumping back to
> the original kernel.

Could we get two reboot commands? Exec loaded kernel seems to be quite
different operation than "jump back".

How do I test these patches? kexec -p <bzImage>, then kexec -j?


> +static unsigned long kexec_backup_addr = ~0UL;
> +
> +/* kexec_backup= specifies the location of backuped 0~640k memory of
> + * crashed kernel.
> + */
> +static int __init parse_kexec_backup(char *arg)
> +{
> +	if (!arg)
> +		return -EINVAL;
> +
> +	kexec_backup_addr = memparse(arg, &arg);
> +	return 0;
> +}
> +early_param("kexec_backup", parse_kexec_backup);

New kernel parameters should be documented. (Plus I do not know how to
use this one, please help :-).


> +int kexec_flags;
> +
> +static unsigned long kexec_jump_buf_pfn;
> +
> +static int __init parse_kexec_jump_buf_pfn(char *arg)
> +{
> +	if (!arg)
> +		return -EINVAL;
> +
> +	kexec_jump_buf_pfn = memparse(arg, &arg);
> +	kexec_flags |= KEXEC_FLAGS_IS_KEXECED_KERNEL;
> +	return 0;
> +}
> +early_param("kexec_jump_buf_pfn", parse_kexec_jump_buf_pfn);

This one should be documented, too, I'd guess. (Is that internal,
kernel-to-kernel communication?)

									Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-07-31  9:51 ` Pavel Machek
@ 2007-08-01  7:56   ` Huang, Ying
  2007-08-05 18:50     ` Pavel Machek
  2007-08-16 10:26     ` [linux-pm] " Pavel Machek
  0 siblings, 2 replies; 8+ messages in thread
From: Huang, Ying @ 2007-08-01  7:56 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Eric W. Biederman, nigel, Rafael J. Wysocki,
	Jeremy Maitin-Shepard, Alan Stern, Andrew Morton, david,
	linux-kernel, linux-pm, Kexec Mailing List

On Tue, 2007-07-31 at 11:51 +0200, Pavel Machek wrote:
> Hi!
> 
> > This patch implement the functionality of jumping from kexeced kernel
> > to original kernel.
> > 
> > A new reboot command named LINUX_REBOOT_CMD_KJUMP is defined to
> > trigger the jumping to (executing) the new kernel or jumping back to
> > the original kernel.
> 
> Could we get two reboot commands? Exec loaded kernel seems to be quite
> different operation than "jump back".

Exec loaded kernel for jumping back is also different from exec loaded
kernel normally.

Maybe the two reboot operations in kexec jump can be seen as "jump to"
and "jump back"?

> How do I test these patches? kexec -p <bzImage>, then kexec -j?

Yes.

> > +static unsigned long kexec_backup_addr = ~0UL;
> > +
> > +/* kexec_backup= specifies the location of backuped 0~640k memory of
> > + * crashed kernel.
> > + */
> > +static int __init parse_kexec_backup(char *arg)
> > +{
> > +	if (!arg)
> > +		return -EINVAL;
> > +
> > +	kexec_backup_addr = memparse(arg, &arg);
> > +	return 0;
> > +}
> > +early_param("kexec_backup", parse_kexec_backup);
> 
> New kernel parameters should be documented. (Plus I do not know how to
> use this one, please help :-).

This kernel parameter will be added to kernel command line by
kexec-tools automatically.

I will add corresponding document in next version.

> 
> > +int kexec_flags;
> > +
> > +static unsigned long kexec_jump_buf_pfn;
> > +
> > +static int __init parse_kexec_jump_buf_pfn(char *arg)
> > +{
> > +	if (!arg)
> > +		return -EINVAL;
> > +
> > +	kexec_jump_buf_pfn = memparse(arg, &arg);
> > +	kexec_flags |= KEXEC_FLAGS_IS_KEXECED_KERNEL;
> > +	return 0;
> > +}
> > +early_param("kexec_jump_buf_pfn", parse_kexec_jump_buf_pfn);
> 
> This one should be documented, too, I'd guess. (Is that internal,
> kernel-to-kernel communication?)

Document will be added in next version too.

This parameter is used for kernel-to-kernel communication. But now, it
must be setup by user, as in usage guide.

Best Regards,
Huang Ying

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-08-01  7:56   ` Huang, Ying
@ 2007-08-05 18:50     ` Pavel Machek
  2007-08-16 10:26     ` [linux-pm] " Pavel Machek
  1 sibling, 0 replies; 8+ messages in thread
From: Pavel Machek @ 2007-08-05 18:50 UTC (permalink / raw)
  To: Huang, Ying
  Cc: Eric W. Biederman, nigel, Rafael J. Wysocki,
	Jeremy Maitin-Shepard, Alan Stern, Andrew Morton, david,
	linux-kernel, linux-pm, Kexec Mailing List

Hi!

> > > This patch implement the functionality of jumping from kexeced kernel
> > > to original kernel.
> > > 
> > > A new reboot command named LINUX_REBOOT_CMD_KJUMP is defined to
> > > trigger the jumping to (executing) the new kernel or jumping back to
> > > the original kernel.
> > 
> > Could we get two reboot commands? Exec loaded kernel seems to be quite
> > different operation than "jump back".
> 
> Exec loaded kernel for jumping back is also different from exec loaded
> kernel normally.
> 
> Maybe the two reboot operations in kexec jump can be seen as "jump to"
> and "jump back"?

Yes, that would be better.

> Document will be added in next version too.
> 
> This parameter is used for kernel-to-kernel communication. But now, it
> must be setup by user, as in usage guide.

Thanks for your help :-).
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [linux-pm] Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-08-01  7:56   ` Huang, Ying
  2007-08-05 18:50     ` Pavel Machek
@ 2007-08-16 10:26     ` Pavel Machek
  2007-08-17  6:15       ` Huang, Ying
  1 sibling, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2007-08-16 10:26 UTC (permalink / raw)
  To: Huang, Ying
  Cc: david, nigel, Kexec Mailing List, linux-kernel,
	Eric W. Biederman, Andrew Morton, linux-pm,
	Jeremy Maitin-Shepard

Hi!

> > > +int kexec_flags;
> > > +
> > > +static unsigned long kexec_jump_buf_pfn;
> > > +
> > > +static int __init parse_kexec_jump_buf_pfn(char *arg)
> > > +{
> > > +	if (!arg)
> > > +		return -EINVAL;
> > > +
> > > +	kexec_jump_buf_pfn = memparse(arg, &arg);
> > > +	kexec_flags |= KEXEC_FLAGS_IS_KEXECED_KERNEL;
> > > +	return 0;
> > > +}
> > > +early_param("kexec_jump_buf_pfn", parse_kexec_jump_buf_pfn);
> > 
> > This one should be documented, too, I'd guess. (Is that internal,
> > kernel-to-kernel communication?)
> 
> Document will be added in next version too.

Ping... is there some next version?

I'm stuck at the tools side currently. kexec-1.101 just won't load the
kernel properly, and kexec-testing from git does not know -j option. I
tried hand-patching it, but got lots of scary rejects.

Is there chance for a patch against kexec-testing?
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [linux-pm] Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-08-16 10:26     ` [linux-pm] " Pavel Machek
@ 2007-08-17  6:15       ` Huang, Ying
  2007-08-21 10:14         ` Pavel Machek
  0 siblings, 1 reply; 8+ messages in thread
From: Huang, Ying @ 2007-08-17  6:15 UTC (permalink / raw)
  To: Pavel Machek
  Cc: david, nigel, Kexec Mailing List, linux-kernel,
	Eric W. Biederman, Andrew Morton, linux-pm,
	Jeremy Maitin-Shepard

Hi, Pavel,

On Thu, 2007-08-16 at 12:26 +0200, Pavel Machek wrote:
> Ping... is there some next version?
> 
> I'm stuck at the tools side currently. kexec-1.101 just won't load the
> kernel properly, and kexec-testing from git does not know -j option. I
> tried hand-patching it, but got lots of scary rejects.
> 
> Is there chance for a patch against kexec-testing?

I have some other work to do recently. So the next version will delay
for some while. :(

But now, I have a patch against kexec-tools-testing.

Best Regards,
Huang Ying

Index: kexec-tools/kexec/arch/i386/crashdump-x86.c
===================================================================
--- kexec-tools.orig/kexec/arch/i386/crashdump-x86.c	2007-08-17 13:48:51.000000000 +0800
+++ kexec-tools/kexec/arch/i386/crashdump-x86.c	2007-08-17 13:49:50.000000000 +0800
@@ -428,6 +428,29 @@
 	return 0;
 }
 
+/* Adds the kexec_backup= command line parameter to command line. */
+static int cmdline_add_backup(char *cmdline, unsigned long addr)
+{
+	int cmdlen, len, align = 1024;
+	char str[30], *ptr;
+
+	/* Passing in kexec_backup=xxxK format. Saves space required
+	 * in cmdline. Ensure 1K alignment*/
+	if (addr%align)
+		return -1;
+	addr = addr/align;
+	ptr = str;
+	strcpy(str, " kexec_backup=");
+	ptr += strlen(str);
+	ultoa(addr, ptr);
+	strcat(str, "K");
+	len = strlen(str);
+	cmdlen = strlen(cmdline) + len;
+	if (cmdlen > (COMMAND_LINE_SIZE - 1))
+		die("Command line overflow\n");
+	strcat(cmdline, str);
+	return 0;
+}
 
 /*
  * This routine is specific to i386 architecture to maintain the
@@ -575,6 +598,7 @@
 		return -1;
 	cmdline_add_memmap(mod_cmdline, memmap_p);
 	cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
+	cmdline_add_backup(mod_cmdline, info->backup_start);
 	return 0;
 }
 
Index: kexec-tools/kexec/kexec-syscall.h
===================================================================
--- kexec-tools.orig/kexec/kexec-syscall.h	2007-08-17 13:48:51.000000000 +0800
+++ kexec-tools/kexec/kexec-syscall.h	2007-08-17 13:49:50.000000000 +0800
@@ -21,6 +21,7 @@
 #define LINUX_REBOOT_CMD_KEXEC_OLD	0x81726354
 #define LINUX_REBOOT_CMD_KEXEC_OLD2	0x18263645
 #define LINUX_REBOOT_CMD_KEXEC		0x45584543
+#define LINUX_REBOOT_CMD_KJUMP		0x3928A5FD
 
 #ifdef __i386__
 #define __NR_kexec_load		283
@@ -63,6 +64,10 @@
 	return (long) syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_KEXEC, 0);
 }
 
+static inline long kexec_jump(void)
+{
+	return (long) syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_KJUMP, 0);
+}
 
 #define KEXEC_ON_CRASH  0x00000001
 #define KEXEC_ARCH_MASK 0xffff0000
Index: kexec-tools/kexec/kexec.c
===================================================================
--- kexec-tools.orig/kexec/kexec.c	2007-08-17 13:48:51.000000000 +0800
+++ kexec-tools/kexec/kexec.c	2007-08-17 13:49:50.000000000 +0800
@@ -716,6 +716,17 @@
 	return -1;
 }
 
+/*
+ *	Jump to the new kernel
+ */
+static int my_jump(void)
+{
+	int result;
+
+	result = kexec_jump();
+	return result;
+}
+
 static void version(void)
 {
 	printf(PACKAGE " " VERSION " released " RELEASE_DATE "\n");
@@ -743,6 +754,7 @@
 	       "                      If capture kernel is being unloaded\n"
 	       "                      specify -p with -u.\n"
 	       " -e, --exec           Execute a currently loaded kernel.\n"
+ 	       " -j, --jump           Jump to a currently loaded kernel or jump back to the previous kernel.\n"
 	       " -t, --type=TYPE      Specify the new kernel is of this type.\n"
 	       "     --mem-min=<addr> Specify the lowest memory address to\n"
 	       "                      load code into.\n"
@@ -803,6 +815,7 @@
 {
 	int do_load = 1;
 	int do_exec = 0;
+	int do_jump = 0;
 	int do_shutdown = 1;
 	int do_sync = 1;
 	int do_ifdown = 0;
@@ -858,6 +871,14 @@
 			do_ifdown = 1;
 			do_exec = 1;
 			break;
+		case OPT_JUMP:
+			do_load = 0;
+			do_shutdown = 0;
+			do_sync = 1;
+			do_ifdown = 0;
+			do_exec = 0;
+			do_jump = 1;
+			break;
 		case OPT_TYPE:
 			type = optarg;
 			break;
@@ -949,6 +970,9 @@
 	if ((result == 0) && do_exec) {
 		result = my_exec();
 	}
+	if ((result == 0) && do_jump) {
+		result = my_jump();
+	}
 
 	fflush(stdout);
 	fflush(stderr);
Index: kexec-tools/kexec/kexec.h
===================================================================
--- kexec-tools.orig/kexec/kexec.h	2007-08-17 13:48:51.000000000 +0800
+++ kexec-tools/kexec/kexec.h	2007-08-17 13:49:50.000000000 +0800
@@ -156,6 +156,7 @@
 #define OPT_FORCE		'f'
 #define OPT_NOIFDOWN		'x'
 #define OPT_EXEC		'e'
+#define OPT_JUMP		'j'
 #define OPT_LOAD		'l'
 #define OPT_UNLOAD		'u'
 #define OPT_TYPE		't'
@@ -172,13 +173,14 @@
 	{ "load",		0, 0, OPT_LOAD }, \
 	{ "unload",		0, 0, OPT_UNLOAD }, \
 	{ "exec",		0, 0, OPT_EXEC }, \
+ 	{ "jump",		0, 0, OPT_JUMP }, \
 	{ "type",		1, 0, OPT_TYPE }, \
 	{ "load-panic",         0, 0, OPT_PANIC }, \
 	{ "mem-min",		1, 0, OPT_MEM_MIN }, \
 	{ "mem-max",		1, 0, OPT_MEM_MAX }, \
 	{ "reuseinitrd",	0, 0, OPT_REUSE_INITRD }, \
 
-#define KEXEC_OPT_STR "hvdfxluet:p"
+#define KEXEC_OPT_STR "hvdfxluejt:p"
 
 extern void die(char *fmt, ...);
 extern void *xmalloc(size_t size);

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [linux-pm] Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-08-17  6:15       ` Huang, Ying
@ 2007-08-21 10:14         ` Pavel Machek
  2007-08-22  6:51           ` Huang, Ying
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2007-08-21 10:14 UTC (permalink / raw)
  To: Huang, Ying
  Cc: david, nigel, Kexec Mailing List, linux-kernel,
	Eric W. Biederman, Andrew Morton, linux-pm,
	Jeremy Maitin-Shepard

Hi!

> On Thu, 2007-08-16 at 12:26 +0200, Pavel Machek wrote:
> > Ping... is there some next version?
> > 
> > I'm stuck at the tools side currently. kexec-1.101 just won't load the
> > kernel properly, and kexec-testing from git does not know -j option. I
> > tried hand-patching it, but got lots of scary rejects.
> > 
> > Is there chance for a patch against kexec-testing?
> 
> I have some other work to do recently. So the next version will delay
> for some while. :(

Ok, I got it to work -- thanks a lot.

Yes, acpi=off is mandatory. Unfortunately, thinkpad x60 does not boot
with acpi=off (should we add another test to linux firmware kit?
Machines should still boot in acpi=off mode...). acpi=off noapic
nolapic nosmp makes it boot, and that in turn makes kjump work.

Screen is not refreshed on kjump back to original kernel, but I guess
that's to be expected. I did not play with framebuffer, yet.

Maybe it is time to move kjump functionality into -mm and
kexec-testing?

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [linux-pm] Re: [PATH 1/1] Kexec jump - v2 - kexec jump
  2007-08-21 10:14         ` Pavel Machek
@ 2007-08-22  6:51           ` Huang, Ying
  0 siblings, 0 replies; 8+ messages in thread
From: Huang, Ying @ 2007-08-22  6:51 UTC (permalink / raw)
  To: Pavel Machek
  Cc: david, nigel, Kexec Mailing List, linux-kernel,
	Eric W. Biederman, Andrew Morton, linux-pm,
	Jeremy Maitin-Shepard

On Tue, 2007-08-21 at 12:14 +0200, Pavel Machek wrote:
> Ok, I got it to work -- thanks a lot.
> 
> Yes, acpi=off is mandatory. Unfortunately, thinkpad x60 does not boot
> with acpi=off (should we add another test to linux firmware kit?
> Machines should still boot in acpi=off mode...). acpi=off noapic
> nolapic nosmp makes it boot, and that in turn makes kjump work.
> 
> Screen is not refreshed on kjump back to original kernel, but I guess
> that's to be expected. I did not play with framebuffer, yet.
> 
> Maybe it is time to move kjump functionality into -mm and
> kexec-testing?

Now I have worked out a full kexec based hibernation prototype,
including kexec, write out the image, reboot, restore the memory and
jump back. I will release it recently. :)

Best Regards,
Huang Ying

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-08-22  6:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-15  7:13 [PATH 1/1] Kexec jump - v2 - kexec jump Huang, Ying
2007-07-31  9:51 ` Pavel Machek
2007-08-01  7:56   ` Huang, Ying
2007-08-05 18:50     ` Pavel Machek
2007-08-16 10:26     ` [linux-pm] " Pavel Machek
2007-08-17  6:15       ` Huang, Ying
2007-08-21 10:14         ` Pavel Machek
2007-08-22  6:51           ` Huang, Ying

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).