From: "Huang, Ying" <ying.huang@intel.com>
To: Vivek Goyal <vgoyal@redhat.com>
Cc: nigel@nigel.suspend2.net,
Kexec Mailing List <kexec@lists.infradead.org>,
linux-kernel@vger.kernel.org, "Rafael J. Wysocki" <rjw@sisk.pl>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Pavel Machek <pavel@ucw.cz>,
Andrew Morton <akpm@linux-foundation.org>,
linux-pm@lists.linux-foundation.org,
Jeremy Maitin-Shepard <jbms@cmu.edu>
Subject: Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump
Date: Tue, 11 Dec 2007 08:51:36 +0000 [thread overview]
Message-ID: <1197363096.24045.92.camel@caritas-dev.intel.com> (raw)
In-Reply-To: <20071210195553.GB27124@redhat.com>
On Mon, 2007-12-10 at 14:55 -0500, Vivek Goyal wrote:
> On Fri, Dec 07, 2007 at 03:53:30PM +0000, Huang, Ying wrote:
> > This patch implements the functionality of jumping between the kexeced
> > kernel and the original kernel.
> >
>
> Hi,
>
> I am just going through your patches and trying to understand it. Don't
> understand many things. Asking is easy so here you go...
>
> > To support jumping between two kernels, before jumping to (executing)
> > the new kernel and jumping back to the original kernel, the devices
> > are put into quiescent state, and the state of devices and CPU is
> > saved. After jumping back from kexeced kernel and jumping to the new
> > 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.
> >
>
> I need jumping back to restore a already hibernated kernel image? Can
> you please tell little more about jumping back and why it is needed?
Now, the jumping back is used to implement "kexec based hibernation",
which uses kexec/kdump to save the memory image of hibernated kernel
during hibernating, and uses /dev/oldmem to restore the memory image of
hibernated kernel and jump back to the hibernated kernel to continue
run.
The other usage model maybe include:
- Dump the system memory image then continue to run, that is, get some
memory snapshot of system during system running.
- Cooperative multi-task of different OS. You can load another OS (B)
from current OS (A), and jump between the two OSes upon needed.
- Call some code (such as firmware, etc) in physical mode.
> > To support jumping without reserving memory. One shadow backup page
> > (source page) is allocated for each page used by new (kexeced) kernel
> > (destination page). When do kexec_load, the image of new kernel is
> > loaded into source pages, and before executing, the destination pages
> > and the source pages are swapped, so the contents of destination pages
> > are backupped. Before jumping to the new (kexeced) kernel and after
> > jumping back to the original kernel, the destination pages and the
> > source pages are swapped too.
> >
>
> Ok, so due to swapping of source and destination pages first kernel's data
> is still preserved. How do I get the dynamic memory required for second
> kernel boot (without writing first kernel's data)?
All dynamic memory required for second kernel should be "loaded" by
sys_kexec_load in first kernel. For example, not only the Linux kernel
should be loaded at 1M, the memory 0~16M (exclude kernel) should be
"loaded" (all zero) by /sbin/kexec via sys_kexec_load too.
> > A jump back protocol for kexec is defined and documented. It is an
> > extension to ordinary function calling protocol. So, the facility
> > provided by this patch can be used to call ordinary C function in real
> > mode.
> >
> > A set of flags for sys_kexec_load are added to control which state are
> > saved/restored before/after real mode code executing. For example, you
> > can specify the device state and FPU state are saved/restored
> > before/after real mode code executing.
> >
> > The states (exclude CPU state) save/restore code can be overridden
> > based on the "command" parameter of kexec jump. Because more states
> > need to be saved/restored by hibernating/resuming.
> >
> > Signed-off-by: Huang Ying <ying.huang@intel.com>
> >
> > ---
> > Documentation/i386/jump_back_protocol.txt | 103 ++++++++++++++
> > arch/powerpc/kernel/machine_kexec.c | 2
> > arch/ppc/kernel/machine_kexec.c | 2
> > arch/sh/kernel/machine_kexec.c | 2
> > arch/x86/kernel/machine_kexec_32.c | 88 +++++++++---
> > arch/x86/kernel/machine_kexec_64.c | 2
> > arch/x86/kernel/relocate_kernel_32.S | 214 +++++++++++++++++++++++++++---
> > include/asm-x86/kexec_32.h | 39 ++++-
> > include/linux/kexec.h | 40 +++++
> > kernel/kexec.c | 188 ++++++++++++++++++++++++++
> > kernel/power/Kconfig | 2
> > kernel/sys.c | 35 +++-
> > 12 files changed, 648 insertions(+), 69 deletions(-)
> >
> > --- a/arch/x86/kernel/machine_kexec_32.c
> > +++ b/arch/x86/kernel/machine_kexec_32.c
> > @@ -20,6 +20,7 @@
> > #include <asm/cpufeature.h>
> > #include <asm/desc.h>
> > #include <asm/system.h>
> > +#include <asm/cacheflush.h>
> >
> > #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
> > static u32 kexec_pgd[1024] PAGE_ALIGNED;
> > @@ -83,10 +84,14 @@ static void load_segments(void)
> > * reboot code buffer to allow us to avoid allocations
> > * later.
> > *
> > - * Currently nothing.
> > + * Turn off NX bit for control page.
> > */
> > int machine_kexec_prepare(struct kimage *image)
> > {
> > + if (nx_enabled) {
> > + change_page_attr(image->control_code_page, 1, PAGE_KERNEL_EXEC);
> > + global_flush_tlb();
> > + }
> > return 0;
> > }
> >
> > @@ -96,25 +101,59 @@ int machine_kexec_prepare(struct kimage
> > */
> > void machine_kexec_cleanup(struct kimage *image)
> > {
> > + if (nx_enabled) {
> > + change_page_attr(image->control_code_page, 1, PAGE_KERNEL);
> > + global_flush_tlb();
> > + }
> > +}
> > +
> > +void machine_kexec(struct kimage *image)
> > +{
> > + machine_kexec_call(image, NULL, 0);
> > }
> >
> > /*
> > * Do not allocate memory (or fail in any way) in machine_kexec().
> > * We are past the point of no return, committed to rebooting now.
> > */
> > -NORET_TYPE void machine_kexec(struct kimage *image)
> > +int machine_kexec_vcall(struct kimage *image, unsigned long *ret,
> > + unsigned int argc, va_list args)
> > {
> > unsigned long page_list[PAGES_NR];
> > void *control_page;
> > + asmlinkage NORET_TYPE void
> > + (*relocate_kernel_ptr)(unsigned long indirection_page,
> > + unsigned long control_page,
> > + unsigned long start_address,
> > + unsigned int has_pae) ATTRIB_NORET;
> >
> > /* Interrupts aren't acceptable while we reboot */
> > local_irq_disable();
> >
> > control_page = page_address(image->control_code_page);
> > - memcpy(control_page, relocate_kernel, PAGE_SIZE);
> > + memcpy(control_page, relocate_page, PAGE_SIZE/2);
> > + KCALL_MAGIC(control_page) = 0;
> >
>
> Is 2K sufficient for all the code in relocate_kernel_32.S? What's the
> current size?
The current size is 0x2d7 (727). I got it though objdump,
machine_crash_shutdown - relocate_page. I think we have enough space.
> > + if (image->preserve_cpu) {
> > + unsigned int i;
> > + KCALL_MAGIC(control_page) = KCALL_MAGIC_NUMBER;
> > + KCALL_ARGC(control_page) = argc;
> > + for (i = 0; i < argc; i++)
> > + KCALL_ARGS(control_page)[i] = \
> > + va_arg(args, unsigned long);
> > +
> > + if (kexec_call_save_cpu(control_page)) {
> > + image->start = KCALL_ENTRY(control_page);
>
> Who fills the entry point at offset 0x200?
The entry point is filled by assembler code in reloate_kernel_32.S upon
jumping back. You can find it by "grep ENTRY relocate_kernel_32.S".
>
> [..]
> > extern int machine_kexec_prepare(struct kimage *image);
> > extern void machine_kexec_cleanup(struct kimage *image);
> > extern asmlinkage long sys_kexec_load(unsigned long entry,
> > unsigned long nr_segments,
> > struct kexec_segment __user *segments,
> > unsigned long flags);
> > +extern int kexec_call(struct kimage *image, unsigned long *ret,
> > + unsigned int argc, ...);
>
> Who is using kexec_call(). I can't seem to locate the caller of it.
There is no user of kexec_call() now. But I think it may be useful as a
physical mode caller for some firmware code.
Best Regards,
Huang Ying
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
WARNING: multiple messages have this Message-ID (diff)
From: "Huang, Ying" <ying.huang@intel.com>
To: Vivek Goyal <vgoyal@redhat.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
Pavel Machek <pavel@ucw.cz>,
nigel@nigel.suspend2.net, "Rafael J. Wysocki" <rjw@sisk.pl>,
Andrew Morton <akpm@linux-foundation.org>,
Jeremy Maitin-Shepard <jbms@cmu.edu>,
linux-pm@lists.linux-foundation.org,
Kexec Mailing List <kexec@lists.infradead.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump
Date: Tue, 11 Dec 2007 08:51:36 +0000 [thread overview]
Message-ID: <1197363096.24045.92.camel@caritas-dev.intel.com> (raw)
In-Reply-To: <20071210195553.GB27124@redhat.com>
On Mon, 2007-12-10 at 14:55 -0500, Vivek Goyal wrote:
> On Fri, Dec 07, 2007 at 03:53:30PM +0000, Huang, Ying wrote:
> > This patch implements the functionality of jumping between the kexeced
> > kernel and the original kernel.
> >
>
> Hi,
>
> I am just going through your patches and trying to understand it. Don't
> understand many things. Asking is easy so here you go...
>
> > To support jumping between two kernels, before jumping to (executing)
> > the new kernel and jumping back to the original kernel, the devices
> > are put into quiescent state, and the state of devices and CPU is
> > saved. After jumping back from kexeced kernel and jumping to the new
> > 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.
> >
>
> I need jumping back to restore a already hibernated kernel image? Can
> you please tell little more about jumping back and why it is needed?
Now, the jumping back is used to implement "kexec based hibernation",
which uses kexec/kdump to save the memory image of hibernated kernel
during hibernating, and uses /dev/oldmem to restore the memory image of
hibernated kernel and jump back to the hibernated kernel to continue
run.
The other usage model maybe include:
- Dump the system memory image then continue to run, that is, get some
memory snapshot of system during system running.
- Cooperative multi-task of different OS. You can load another OS (B)
from current OS (A), and jump between the two OSes upon needed.
- Call some code (such as firmware, etc) in physical mode.
> > To support jumping without reserving memory. One shadow backup page
> > (source page) is allocated for each page used by new (kexeced) kernel
> > (destination page). When do kexec_load, the image of new kernel is
> > loaded into source pages, and before executing, the destination pages
> > and the source pages are swapped, so the contents of destination pages
> > are backupped. Before jumping to the new (kexeced) kernel and after
> > jumping back to the original kernel, the destination pages and the
> > source pages are swapped too.
> >
>
> Ok, so due to swapping of source and destination pages first kernel's data
> is still preserved. How do I get the dynamic memory required for second
> kernel boot (without writing first kernel's data)?
All dynamic memory required for second kernel should be "loaded" by
sys_kexec_load in first kernel. For example, not only the Linux kernel
should be loaded at 1M, the memory 0~16M (exclude kernel) should be
"loaded" (all zero) by /sbin/kexec via sys_kexec_load too.
> > A jump back protocol for kexec is defined and documented. It is an
> > extension to ordinary function calling protocol. So, the facility
> > provided by this patch can be used to call ordinary C function in real
> > mode.
> >
> > A set of flags for sys_kexec_load are added to control which state are
> > saved/restored before/after real mode code executing. For example, you
> > can specify the device state and FPU state are saved/restored
> > before/after real mode code executing.
> >
> > The states (exclude CPU state) save/restore code can be overridden
> > based on the "command" parameter of kexec jump. Because more states
> > need to be saved/restored by hibernating/resuming.
> >
> > Signed-off-by: Huang Ying <ying.huang@intel.com>
> >
> > ---
> > Documentation/i386/jump_back_protocol.txt | 103 ++++++++++++++
> > arch/powerpc/kernel/machine_kexec.c | 2
> > arch/ppc/kernel/machine_kexec.c | 2
> > arch/sh/kernel/machine_kexec.c | 2
> > arch/x86/kernel/machine_kexec_32.c | 88 +++++++++---
> > arch/x86/kernel/machine_kexec_64.c | 2
> > arch/x86/kernel/relocate_kernel_32.S | 214 +++++++++++++++++++++++++++---
> > include/asm-x86/kexec_32.h | 39 ++++-
> > include/linux/kexec.h | 40 +++++
> > kernel/kexec.c | 188 ++++++++++++++++++++++++++
> > kernel/power/Kconfig | 2
> > kernel/sys.c | 35 +++-
> > 12 files changed, 648 insertions(+), 69 deletions(-)
> >
> > --- a/arch/x86/kernel/machine_kexec_32.c
> > +++ b/arch/x86/kernel/machine_kexec_32.c
> > @@ -20,6 +20,7 @@
> > #include <asm/cpufeature.h>
> > #include <asm/desc.h>
> > #include <asm/system.h>
> > +#include <asm/cacheflush.h>
> >
> > #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
> > static u32 kexec_pgd[1024] PAGE_ALIGNED;
> > @@ -83,10 +84,14 @@ static void load_segments(void)
> > * reboot code buffer to allow us to avoid allocations
> > * later.
> > *
> > - * Currently nothing.
> > + * Turn off NX bit for control page.
> > */
> > int machine_kexec_prepare(struct kimage *image)
> > {
> > + if (nx_enabled) {
> > + change_page_attr(image->control_code_page, 1, PAGE_KERNEL_EXEC);
> > + global_flush_tlb();
> > + }
> > return 0;
> > }
> >
> > @@ -96,25 +101,59 @@ int machine_kexec_prepare(struct kimage
> > */
> > void machine_kexec_cleanup(struct kimage *image)
> > {
> > + if (nx_enabled) {
> > + change_page_attr(image->control_code_page, 1, PAGE_KERNEL);
> > + global_flush_tlb();
> > + }
> > +}
> > +
> > +void machine_kexec(struct kimage *image)
> > +{
> > + machine_kexec_call(image, NULL, 0);
> > }
> >
> > /*
> > * Do not allocate memory (or fail in any way) in machine_kexec().
> > * We are past the point of no return, committed to rebooting now.
> > */
> > -NORET_TYPE void machine_kexec(struct kimage *image)
> > +int machine_kexec_vcall(struct kimage *image, unsigned long *ret,
> > + unsigned int argc, va_list args)
> > {
> > unsigned long page_list[PAGES_NR];
> > void *control_page;
> > + asmlinkage NORET_TYPE void
> > + (*relocate_kernel_ptr)(unsigned long indirection_page,
> > + unsigned long control_page,
> > + unsigned long start_address,
> > + unsigned int has_pae) ATTRIB_NORET;
> >
> > /* Interrupts aren't acceptable while we reboot */
> > local_irq_disable();
> >
> > control_page = page_address(image->control_code_page);
> > - memcpy(control_page, relocate_kernel, PAGE_SIZE);
> > + memcpy(control_page, relocate_page, PAGE_SIZE/2);
> > + KCALL_MAGIC(control_page) = 0;
> >
>
> Is 2K sufficient for all the code in relocate_kernel_32.S? What's the
> current size?
The current size is 0x2d7 (727). I got it though objdump,
machine_crash_shutdown - relocate_page. I think we have enough space.
> > + if (image->preserve_cpu) {
> > + unsigned int i;
> > + KCALL_MAGIC(control_page) = KCALL_MAGIC_NUMBER;
> > + KCALL_ARGC(control_page) = argc;
> > + for (i = 0; i < argc; i++)
> > + KCALL_ARGS(control_page)[i] = \
> > + va_arg(args, unsigned long);
> > +
> > + if (kexec_call_save_cpu(control_page)) {
> > + image->start = KCALL_ENTRY(control_page);
>
> Who fills the entry point at offset 0x200?
The entry point is filled by assembler code in reloate_kernel_32.S upon
jumping back. You can find it by "grep ENTRY relocate_kernel_32.S".
>
> [..]
> > extern int machine_kexec_prepare(struct kimage *image);
> > extern void machine_kexec_cleanup(struct kimage *image);
> > extern asmlinkage long sys_kexec_load(unsigned long entry,
> > unsigned long nr_segments,
> > struct kexec_segment __user *segments,
> > unsigned long flags);
> > +extern int kexec_call(struct kimage *image, unsigned long *ret,
> > + unsigned int argc, ...);
>
> Who is using kexec_call(). I can't seem to locate the caller of it.
There is no user of kexec_call() now. But I think it may be useful as a
physical mode caller for some firmware code.
Best Regards,
Huang Ying
next prev parent reply other threads:[~2007-12-11 0:52 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-07 15:53 [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump Huang, Ying
2007-12-07 15:53 ` Huang, Ying
2007-12-08 23:53 ` Pavel Machek
2007-12-08 23:53 ` Pavel Machek
2007-12-08 23:53 ` Pavel Machek
2007-12-09 0:19 ` Rafael J. Wysocki
2007-12-09 0:19 ` Rafael J. Wysocki
2007-12-09 0:19 ` Rafael J. Wysocki
2007-12-09 1:06 ` Eric W. Biederman
2007-12-09 1:06 ` Eric W. Biederman
2007-12-09 1:06 ` Eric W. Biederman
2007-12-10 19:55 ` Vivek Goyal
2007-12-10 19:55 ` Vivek Goyal
2007-12-10 19:55 ` Vivek Goyal
2007-12-11 8:51 ` Huang, Ying
2007-12-11 8:51 ` Huang, Ying [this message]
2007-12-11 8:51 ` Huang, Ying
2007-12-10 22:31 ` Vivek Goyal
2007-12-10 22:31 ` Vivek Goyal
2007-12-11 8:55 ` Huang, Ying
2007-12-11 8:55 ` Huang, Ying
2007-12-11 8:55 ` Huang, Ying
2007-12-10 22:31 ` Vivek Goyal
2007-12-11 2:25 ` Eric W. Biederman
2007-12-11 2:25 ` Eric W. Biederman
2007-12-11 2:25 ` Eric W. Biederman
2007-12-11 15:50 ` Huang, Ying
2007-12-11 15:50 ` Huang, Ying
2007-12-11 9:27 ` Eric W. Biederman
2007-12-11 9:27 ` Eric W. Biederman
2007-12-11 9:27 ` Eric W. Biederman
2007-12-12 6:27 ` Huang, Ying
2007-12-12 6:27 ` Huang, Ying
2007-12-12 6:27 ` Huang, Ying
2007-12-18 8:34 ` Huang, Ying
2007-12-18 8:34 ` Huang, Ying
2007-12-18 8:34 ` Huang, Ying
2007-12-11 15:50 ` Huang, Ying
-- strict thread matches above, loose matches on Subject: below --
2007-12-07 15:53 Huang, Ying
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1197363096.24045.92.camel@caritas-dev.intel.com \
--to=ying.huang@intel.com \
--cc=akpm@linux-foundation.org \
--cc=ebiederm@xmission.com \
--cc=jbms@cmu.edu \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=nigel@nigel.suspend2.net \
--cc=pavel@ucw.cz \
--cc=rjw@sisk.pl \
--cc=vgoyal@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.