Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-18 Thread Huang, Ying
On Tue, 2007-12-11 at 02:27 -0700, Eric W. Biederman wrote:
> "Huang, Ying" <[EMAIL PROTECTED]> writes:
> 
> > On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
> >> "Huang, Ying" <[EMAIL PROTECTED]> writes:
> > [...]
> >> >  /*
> >> >   * 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)
> >> >  {
> >> 
> >> Why do we need var arg support?
> >> Can't we do that with a shim we load from user space?
> >
> > If all parameters are provided in user space, the usage model may be as
> > follow:
> >
> > - sys_kexec_load() /* with executable/data/parameters(A) loaded */
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
> > parameters(A)*/
> > - /* jump back */
> > - sys_kexec_load() /* with executable/data/parameters(B) loaded */
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
> > parameters(B)*/
> > - /* jump back */
> >
> > That is, the kexec image should be re-loaded if the parameters are
> > different, and there can be no state reserved in kexec image. This is OK
> > for original kexec implementation, because there is no jumping back.
> > But, for kexec with jumping back, another usage model may be useful too.
> >
> > - sys_kexec_load() /* with executable/data loaded */
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical 
> > mode
> > code with parameters(A)*/
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical 
> > mode
> > code with parameters(B)*/
> >
> > This way the kexec image need not to be re-loaded, and the state of
> > kexec image can be reserved across several invoking.
> 
> Interesting.  We wind up preserving the code in between invocations.
> 
> I don't know about your particular issue, but I can see that clearly
> we need a way to read values back from our target image.
> 
> And if we can read everything back one way to proceed is to read
> everything out modify it and then write it back.
> 
> Amending a kexec image that is already stored may also make sense.
> 
> I'm not convinced that the var arg parameters make sense, but you
> added them because of a real need.
> 
> The kexec function is split into two separate calls so that we can
> unmount the filesystem the kexec image comes from before actually
> doing the kexec.

My real issue is that I need a kind of "kernel to kernel" communication
method. The var args is just a convenient way to pass an array of
unsigned longs between two kernels. The reason is as follow:

The kexec based hibernating process is as follow:

h1. put devices in quiescent state
h2. save devices/CPU state
h3. jump to kexeced kernel (kernel B)
*h4. normal kernel boot of kernel B
*h5. save devices/CPU state
*h6. jump back to original kernel (kernel A)
h7. restore devices/CPU state
h8. put devices in quiescent state
h9. put devices in low power state
h10. execute necessary ACPI method (prepare to sleep)
h11. save devices/CPU state
h12. jump to kernel B
*h13. execute necessary ACPI method (wake up)
*h14. restore devices/CPU state
*h15. put devices in normal power state
*h16. write memory image of kernel A into disk
*h17. put system into ACPI S4 state

The kexec based resuming process is as follow:

*r1. boot the resuming kernel (kernel C)
*r2. restore the memory image of kernel A
*r3. put devices in quiescent state
*r4. execute necessary ACPI method (prepare to resume)
*r5. jump to kernel A
r6. execute necessary ACPI method (wake up)
r7. restore devices/CPU state

Where, line begin with "*" is executed in kernel B and kernel C, others
are executed in kernel A.

The kernel A need to distinguish the difference between h7 and r6, while
the kernel B/C need to distinguish between *h13 and normal jump back.
The different kernel action need to be taken depends on the action of
peer kernel. Now, this is solved by kernel-kernel communication, a
command word is passed to peer kernel to inform the action required.

I remember you have said before that you think it is better to use only
"user space to user space" communication between kernel A and kernel B.
This is OK for normal kexec. But if the kexec jump is used for multiple
functions with early kernel action involved (normal kexec jump, kexec
jump to hibernate, kexec jump to resume), it is necessary to use "kernel
to kernel" communication.

The var args in the patch is just an array of unsigned longs, it can be
expresses as follow too.

int kexec_call(struct kimage *image, unsigned long *ret, unsigned int
argc, unsigned long argv[]);

The var args version is as follow.

int kexec_call(struct kimage *image, unsigned long *ret, unsigned int
argc, ...);

Best Regards,
Huang Ying

--
To unsubscribe from this list: send the 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-18 Thread Huang, Ying
On Tue, 2007-12-11 at 02:27 -0700, Eric W. Biederman wrote:
 Huang, Ying [EMAIL PROTECTED] writes:
 
  On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
  Huang, Ying [EMAIL PROTECTED] writes:
  [...]
/*
 * 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)
{
  
  Why do we need var arg support?
  Can't we do that with a shim we load from user space?
 
  If all parameters are provided in user space, the usage model may be as
  follow:
 
  - sys_kexec_load() /* with executable/data/parameters(A) loaded */
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
  parameters(A)*/
  - /* jump back */
  - sys_kexec_load() /* with executable/data/parameters(B) loaded */
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
  parameters(B)*/
  - /* jump back */
 
  That is, the kexec image should be re-loaded if the parameters are
  different, and there can be no state reserved in kexec image. This is OK
  for original kexec implementation, because there is no jumping back.
  But, for kexec with jumping back, another usage model may be useful too.
 
  - sys_kexec_load() /* with executable/data loaded */
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical 
  mode
  code with parameters(A)*/
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical 
  mode
  code with parameters(B)*/
 
  This way the kexec image need not to be re-loaded, and the state of
  kexec image can be reserved across several invoking.
 
 Interesting.  We wind up preserving the code in between invocations.
 
 I don't know about your particular issue, but I can see that clearly
 we need a way to read values back from our target image.
 
 And if we can read everything back one way to proceed is to read
 everything out modify it and then write it back.
 
 Amending a kexec image that is already stored may also make sense.
 
 I'm not convinced that the var arg parameters make sense, but you
 added them because of a real need.
 
 The kexec function is split into two separate calls so that we can
 unmount the filesystem the kexec image comes from before actually
 doing the kexec.

My real issue is that I need a kind of kernel to kernel communication
method. The var args is just a convenient way to pass an array of
unsigned longs between two kernels. The reason is as follow:

The kexec based hibernating process is as follow:

h1. put devices in quiescent state
h2. save devices/CPU state
h3. jump to kexeced kernel (kernel B)
*h4. normal kernel boot of kernel B
*h5. save devices/CPU state
*h6. jump back to original kernel (kernel A)
h7. restore devices/CPU state
h8. put devices in quiescent state
h9. put devices in low power state
h10. execute necessary ACPI method (prepare to sleep)
h11. save devices/CPU state
h12. jump to kernel B
*h13. execute necessary ACPI method (wake up)
*h14. restore devices/CPU state
*h15. put devices in normal power state
*h16. write memory image of kernel A into disk
*h17. put system into ACPI S4 state

The kexec based resuming process is as follow:

*r1. boot the resuming kernel (kernel C)
*r2. restore the memory image of kernel A
*r3. put devices in quiescent state
*r4. execute necessary ACPI method (prepare to resume)
*r5. jump to kernel A
r6. execute necessary ACPI method (wake up)
r7. restore devices/CPU state

Where, line begin with * is executed in kernel B and kernel C, others
are executed in kernel A.

The kernel A need to distinguish the difference between h7 and r6, while
the kernel B/C need to distinguish between *h13 and normal jump back.
The different kernel action need to be taken depends on the action of
peer kernel. Now, this is solved by kernel-kernel communication, a
command word is passed to peer kernel to inform the action required.

I remember you have said before that you think it is better to use only
user space to user space communication between kernel A and kernel B.
This is OK for normal kexec. But if the kexec jump is used for multiple
functions with early kernel action involved (normal kexec jump, kexec
jump to hibernate, kexec jump to resume), it is necessary to use kernel
to kernel communication.

The var args in the patch is just an array of unsigned longs, it can be
expresses as follow too.

int kexec_call(struct kimage *image, unsigned long *ret, unsigned int
argc, unsigned long argv[]);

The var args version is as follow.

int kexec_call(struct kimage *image, unsigned long *ret, unsigned int
argc, ...);

Best Regards,
Huang Ying

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-11 Thread Huang, Ying
On Tue, 2007-12-11 at 02:27 -0700, Eric W. Biederman wrote:
> "Huang, Ying" <[EMAIL PROTECTED]> writes:
> 
> > On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
> >> "Huang, Ying" <[EMAIL PROTECTED]> writes:
> > [...]
> >> >  /*
> >> >   * 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)
> >> >  {
> >> 
> >> Why do we need var arg support?
> >> Can't we do that with a shim we load from user space?
> >
> > If all parameters are provided in user space, the usage model may be as
> > follow:
> >
> > - sys_kexec_load() /* with executable/data/parameters(A) loaded */
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
> > parameters(A)*/
> > - /* jump back */
> > - sys_kexec_load() /* with executable/data/parameters(B) loaded */
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
> > parameters(B)*/
> > - /* jump back */
> >
> > That is, the kexec image should be re-loaded if the parameters are
> > different, and there can be no state reserved in kexec image. This is OK
> > for original kexec implementation, because there is no jumping back.
> > But, for kexec with jumping back, another usage model may be useful too.
> >
> > - sys_kexec_load() /* with executable/data loaded */
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical 
> > mode
> > code with parameters(A)*/
> > - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical 
> > mode
> > code with parameters(B)*/
> >
> > This way the kexec image need not to be re-loaded, and the state of
> > kexec image can be reserved across several invoking.
> 
> Interesting.  We wind up preserving the code in between invocations.
> 
> I don't know about your particular issue, but I can see that clearly
> we need a way to read values back from our target image.
> 
> And if we can read everything back one way to proceed is to read
> everything out modify it and then write it back.
> 
> Amending a kexec image that is already stored may also make sense.
> 
> I'm not convinced that the var arg parameters make sense, but you
> added them because of a real need.
> 
> The kexec function is split into two separate calls so that we can
> unmount the filesystem the kexec image comes from before actually
> doing the kexec.

Yes. Reading/Modifying the loaded kexec image is another way to do
necessary communication between the first kernel and the second kernel.
In fact, the patch [4/4] of this series with title:

[PATCH 4/4 -mm] kexec based hibernation -v7 : kimgcore

provide a ELF CORE file in /proc (/proc/kimgcore) to read the loaded
kexec image. The writing function can be added easily.

But I think communication between the first kernel and the second kernel
via reading/modifying the loaded kernel image is not very convenient
way. The usage mode may be as follow:

- sys_kexec_load() /* with executable/data loaded */
- modify the loaded kexec image to set the parameters (A)
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(A)*/
- In physical mode code, check the parameters A and executing accordingly
- modify the loaded kexec image to set the parameters (B)
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(B)*/
- In physical mode code, check the parameters B and executing accordingly

There are some issues with this usage model:

- Some parameters in kernel needed to be exported (such as the
kimage->head to let the second kernel to read the memory contents of
backupped memory).

- The physical mode code invoker (the first kernel) need to know where
to write the parameters. A common protocol or a protocol case by case
should be defined. For example, the memory address after the entry point
of kexec image is a good candidate. But for Linux kernel, there are two
types of entry point, the "jump back entry" or "purgatory". Maybe
different protocol should be defined for these two types of entry point.

- For the user space of the second kernel to get the parameters. A
interface (maybe a file in /proc or /sys) should be provided to export
the parameters to user space.

So I think the current parameters passing mechanism may be more simple
and convenient (defined in Document/i386/jump_back_protocol.txt in the
patch).

There is only one user of var args. But I think it is simple to be
implemented and may be used by others.

> If extensive user space shutdown or startup is needed I will argue
> that doing the work in the sys_reboot call is the wrong place to
> do it.  Although if a jump back is happening we should not need
> much restart.

Now, the user space is not shut down or started up across kexec/jump
back, just 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-11 Thread Eric W. Biederman
"Huang, Ying" <[EMAIL PROTECTED]> writes:

> On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
>> "Huang, Ying" <[EMAIL PROTECTED]> writes:
> [...]
>> >  /*
>> >   * 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)
>> >  {
>> 
>> Why do we need var arg support?
>> Can't we do that with a shim we load from user space?
>
> If all parameters are provided in user space, the usage model may be as
> follow:
>
> - sys_kexec_load() /* with executable/data/parameters(A) loaded */
> - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
> parameters(A)*/
> - /* jump back */
> - sys_kexec_load() /* with executable/data/parameters(B) loaded */
> - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
> parameters(B)*/
> - /* jump back */
>
> That is, the kexec image should be re-loaded if the parameters are
> different, and there can be no state reserved in kexec image. This is OK
> for original kexec implementation, because there is no jumping back.
> But, for kexec with jumping back, another usage model may be useful too.
>
> - sys_kexec_load() /* with executable/data loaded */
> - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical mode
> code with parameters(A)*/
> - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical mode
> code with parameters(B)*/
>
> This way the kexec image need not to be re-loaded, and the state of
> kexec image can be reserved across several invoking.

Interesting.  We wind up preserving the code in between invocations.

I don't know about your particular issue, but I can see that clearly
we need a way to read values back from our target image.

And if we can read everything back one way to proceed is to read
everything out modify it and then write it back.

Amending a kexec image that is already stored may also make sense.

I'm not convinced that the var arg parameters make sense, but you
added them because of a real need.

The kexec function is split into two separate calls so that we can
unmount the filesystem the kexec image comes from before actually
doing the kexec.

If extensive user space shutdown or startup is needed I will argue
that doing the work in the sys_reboot call is the wrong place to
do it.  Although if a jump back is happening we should not need
much restart.

Can you generate a minimal patch with just the minimal necessary
support to return from a kexec operation?

> Another usage model may be useful is invoking the kexec image (such as
> firmware) from kernel space.
>
> - kmalloc the needed memory and loaded the firmware image (if needed)
> - sys_kexec_load() with a fake image (one segment with size 0), the
> entry point of the fake image is the entry point of the firmware image.
> - kexec_call(fake_image, ...) /* maybe change entry point if needed */
>
> This way, some kernel code can invoke the firmware in physical mode just
> like invoking an ordinary function.

That certainly seems interesting.  But that doesn't justify the vararg
part of this.

> [...]
>> > -  /* The segment registers are funny things, they have both a
>> > -   * visible and an invisible part.  Whenever the visible part is
>> > -   * set to a specific selector, the invisible part is loaded
>> > -   * with from a table in memory.  At no other time is the
>> > -   * descriptor table in memory accessed.
>> > -   *
>> > -   * I take advantage of this here by force loading the
>> > -   * segments, before I zap the gdt with an invalid value.
>> > -   */
>> > -  load_segments();
>> > -  /* The gdt & idt are now invalid.
>> > -   * If you want to load them you must set up your own idt & gdt.
>> > -   */
>> > -  set_gdt(phys_to_virt(0),0);
>> > -  set_idt(phys_to_virt(0),0);
>> > +  if (image->preserve_cpu_ext) {
>> > +  /* The segment registers are funny things, they have
>> > +   * both a visible and an invisible part.  Whenever the
>> > +   * visible part is set to a specific selector, the
>> > +   * invisible part is loaded with from a table in
>> > +   * memory.  At no other time is the descriptor table
>> > +   * in memory accessed.
>> > +   *
>> > +   * I take advantage of this here by force loading the
>> > +   * segments, before I zap the gdt with an invalid
>> > +   * value.
>> > +   */
>> > +  load_segments();
>> > +  /* The gdt & idt are now invalid.  If you want to load
>> > +   * them you must set up your own idt & gdt.
>> > +   */
>> > +  set_gdt(phys_to_virt(0), 0);
>> > +  set_idt(phys_to_virt(0), 0);
>> > +  }
>> 
>> We can't keep the same idt and gdt as the pages they are on will be
>> 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-11 Thread Eric W. Biederman
Huang, Ying [EMAIL PROTECTED] writes:

 On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
 Huang, Ying [EMAIL PROTECTED] writes:
 [...]
   /*
* 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)
   {
 
 Why do we need var arg support?
 Can't we do that with a shim we load from user space?

 If all parameters are provided in user space, the usage model may be as
 follow:

 - sys_kexec_load() /* with executable/data/parameters(A) loaded */
 - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
 parameters(A)*/
 - /* jump back */
 - sys_kexec_load() /* with executable/data/parameters(B) loaded */
 - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
 parameters(B)*/
 - /* jump back */

 That is, the kexec image should be re-loaded if the parameters are
 different, and there can be no state reserved in kexec image. This is OK
 for original kexec implementation, because there is no jumping back.
 But, for kexec with jumping back, another usage model may be useful too.

 - sys_kexec_load() /* with executable/data loaded */
 - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical mode
 code with parameters(A)*/
 - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical mode
 code with parameters(B)*/

 This way the kexec image need not to be re-loaded, and the state of
 kexec image can be reserved across several invoking.

Interesting.  We wind up preserving the code in between invocations.

I don't know about your particular issue, but I can see that clearly
we need a way to read values back from our target image.

And if we can read everything back one way to proceed is to read
everything out modify it and then write it back.

Amending a kexec image that is already stored may also make sense.

I'm not convinced that the var arg parameters make sense, but you
added them because of a real need.

The kexec function is split into two separate calls so that we can
unmount the filesystem the kexec image comes from before actually
doing the kexec.

If extensive user space shutdown or startup is needed I will argue
that doing the work in the sys_reboot call is the wrong place to
do it.  Although if a jump back is happening we should not need
much restart.

Can you generate a minimal patch with just the minimal necessary
support to return from a kexec operation?

 Another usage model may be useful is invoking the kexec image (such as
 firmware) from kernel space.

 - kmalloc the needed memory and loaded the firmware image (if needed)
 - sys_kexec_load() with a fake image (one segment with size 0), the
 entry point of the fake image is the entry point of the firmware image.
 - kexec_call(fake_image, ...) /* maybe change entry point if needed */

 This way, some kernel code can invoke the firmware in physical mode just
 like invoking an ordinary function.

That certainly seems interesting.  But that doesn't justify the vararg
part of this.

 [...]
  -  /* The segment registers are funny things, they have both a
  -   * visible and an invisible part.  Whenever the visible part is
  -   * set to a specific selector, the invisible part is loaded
  -   * with from a table in memory.  At no other time is the
  -   * descriptor table in memory accessed.
  -   *
  -   * I take advantage of this here by force loading the
  -   * segments, before I zap the gdt with an invalid value.
  -   */
  -  load_segments();
  -  /* The gdt  idt are now invalid.
  -   * If you want to load them you must set up your own idt  gdt.
  -   */
  -  set_gdt(phys_to_virt(0),0);
  -  set_idt(phys_to_virt(0),0);
  +  if (image-preserve_cpu_ext) {
  +  /* The segment registers are funny things, they have
  +   * both a visible and an invisible part.  Whenever the
  +   * visible part is set to a specific selector, the
  +   * invisible part is loaded with from a table in
  +   * memory.  At no other time is the descriptor table
  +   * in memory accessed.
  +   *
  +   * I take advantage of this here by force loading the
  +   * segments, before I zap the gdt with an invalid
  +   * value.
  +   */
  +  load_segments();
  +  /* The gdt  idt are now invalid.  If you want to load
  +   * them you must set up your own idt  gdt.
  +   */
  +  set_gdt(phys_to_virt(0), 0);
  +  set_idt(phys_to_virt(0), 0);
  +  }
 
 We can't keep the same idt and gdt as the pages they are on will be
 overwritten/reused.  So explictily stomping on them sounds better
 so they never work.  We can restore them on kernel reentry.

 The original idea about this code is:

 If the kexec image is 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-11 Thread Huang, Ying
On Tue, 2007-12-11 at 02:27 -0700, Eric W. Biederman wrote:
 Huang, Ying [EMAIL PROTECTED] writes:
 
  On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
  Huang, Ying [EMAIL PROTECTED] writes:
  [...]
/*
 * 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)
{
  
  Why do we need var arg support?
  Can't we do that with a shim we load from user space?
 
  If all parameters are provided in user space, the usage model may be as
  follow:
 
  - sys_kexec_load() /* with executable/data/parameters(A) loaded */
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
  parameters(A)*/
  - /* jump back */
  - sys_kexec_load() /* with executable/data/parameters(B) loaded */
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with
  parameters(B)*/
  - /* jump back */
 
  That is, the kexec image should be re-loaded if the parameters are
  different, and there can be no state reserved in kexec image. This is OK
  for original kexec implementation, because there is no jumping back.
  But, for kexec with jumping back, another usage model may be useful too.
 
  - sys_kexec_load() /* with executable/data loaded */
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical 
  mode
  code with parameters(A)*/
  - sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical 
  mode
  code with parameters(B)*/
 
  This way the kexec image need not to be re-loaded, and the state of
  kexec image can be reserved across several invoking.
 
 Interesting.  We wind up preserving the code in between invocations.
 
 I don't know about your particular issue, but I can see that clearly
 we need a way to read values back from our target image.
 
 And if we can read everything back one way to proceed is to read
 everything out modify it and then write it back.
 
 Amending a kexec image that is already stored may also make sense.
 
 I'm not convinced that the var arg parameters make sense, but you
 added them because of a real need.
 
 The kexec function is split into two separate calls so that we can
 unmount the filesystem the kexec image comes from before actually
 doing the kexec.

Yes. Reading/Modifying the loaded kexec image is another way to do
necessary communication between the first kernel and the second kernel.
In fact, the patch [4/4] of this series with title:

[PATCH 4/4 -mm] kexec based hibernation -v7 : kimgcore

provide a ELF CORE file in /proc (/proc/kimgcore) to read the loaded
kexec image. The writing function can be added easily.

But I think communication between the first kernel and the second kernel
via reading/modifying the loaded kernel image is not very convenient
way. The usage mode may be as follow:

- sys_kexec_load() /* with executable/data loaded */
- modify the loaded kexec image to set the parameters (A)
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(A)*/
- In physical mode code, check the parameters A and executing accordingly
- modify the loaded kexec image to set the parameters (B)
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(B)*/
- In physical mode code, check the parameters B and executing accordingly

There are some issues with this usage model:

- Some parameters in kernel needed to be exported (such as the
kimage-head to let the second kernel to read the memory contents of
backupped memory).

- The physical mode code invoker (the first kernel) need to know where
to write the parameters. A common protocol or a protocol case by case
should be defined. For example, the memory address after the entry point
of kexec image is a good candidate. But for Linux kernel, there are two
types of entry point, the jump back entry or purgatory. Maybe
different protocol should be defined for these two types of entry point.

- For the user space of the second kernel to get the parameters. A
interface (maybe a file in /proc or /sys) should be provided to export
the parameters to user space.

So I think the current parameters passing mechanism may be more simple
and convenient (defined in Document/i386/jump_back_protocol.txt in the
patch).

There is only one user of var args. But I think it is simple to be
implemented and may be used by others.

 If extensive user space shutdown or startup is needed I will argue
 that doing the work in the sys_reboot call is the wrong place to
 do it.  Although if a jump back is happening we should not need
 much restart.

Now, the user space is not shut down or started up across kexec/jump
back, just the sys_reboot call is used to trigger the kexec/jump back.
Maybe sys_reboot is not the right place to do this. Can you recommended
a more 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Huang, Ying
On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
> "Huang, Ying" <[EMAIL PROTECTED]> writes:
[...]
> >  /*
> >   * 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)
> >  {
> 
> Why do we need var arg support?
> Can't we do that with a shim we load from user space?

If all parameters are provided in user space, the usage model may be as
follow:

- sys_kexec_load() /* with executable/data/parameters(A) loaded */
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(A)*/
- /* jump back */
- sys_kexec_load() /* with executable/data/parameters(B) loaded */
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(B)*/
- /* jump back */

That is, the kexec image should be re-loaded if the parameters are
different, and there can be no state reserved in kexec image. This is OK
for original kexec implementation, because there is no jumping back.
But, for kexec with jumping back, another usage model may be useful too.

- sys_kexec_load() /* with executable/data loaded */
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical mode 
code with parameters(A)*/
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical mode 
code with parameters(B)*/

This way the kexec image need not to be re-loaded, and the state of
kexec image can be reserved across several invoking.


Another usage model may be useful is invoking the kexec image (such as
firmware) from kernel space.

- kmalloc the needed memory and loaded the firmware image (if needed)
- sys_kexec_load() with a fake image (one segment with size 0), the
entry point of the fake image is the entry point of the firmware image.
- kexec_call(fake_image, ...) /* maybe change entry point if needed */

This way, some kernel code can invoke the firmware in physical mode just
like invoking an ordinary function.

[...]
> > -   /* The segment registers are funny things, they have both a
> > -* visible and an invisible part.  Whenever the visible part is
> > -* set to a specific selector, the invisible part is loaded
> > -* with from a table in memory.  At no other time is the
> > -* descriptor table in memory accessed.
> > -*
> > -* I take advantage of this here by force loading the
> > -* segments, before I zap the gdt with an invalid value.
> > -*/
> > -   load_segments();
> > -   /* The gdt & idt are now invalid.
> > -* If you want to load them you must set up your own idt & gdt.
> > -*/
> > -   set_gdt(phys_to_virt(0),0);
> > -   set_idt(phys_to_virt(0),0);
> > +   if (image->preserve_cpu_ext) {
> > +   /* The segment registers are funny things, they have
> > +* both a visible and an invisible part.  Whenever the
> > +* visible part is set to a specific selector, the
> > +* invisible part is loaded with from a table in
> > +* memory.  At no other time is the descriptor table
> > +* in memory accessed.
> > +*
> > +* I take advantage of this here by force loading the
> > +* segments, before I zap the gdt with an invalid
> > +* value.
> > +*/
> > +   load_segments();
> > +   /* The gdt & idt are now invalid.  If you want to load
> > +* them you must set up your own idt & gdt.
> > +*/
> > +   set_gdt(phys_to_virt(0), 0);
> > +   set_idt(phys_to_virt(0), 0);
> > +   }
> 
> We can't keep the same idt and gdt as the pages they are on will be
> overwritten/reused.  So explictily stomping on them sounds better
> so they never work.  We can restore them on kernel reentry.

The original idea about this code is:

If the kexec image is claimed that it need not to "perserving extensive
CPU state" (such as FPU/MMX/GDT/LDT/IDT/CS/DS/ES/FS/GS/SS etc), the
IDT/GDT/CS/DS/ES/FS/GS/SS are not touched in kexec image code. So the
segment registers need not to be set.

But this is not clear. At least more description should be provided for
each preserve flag.

> > /* now call it */
> > -   relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
> > -   image->start, cpu_has_pae);
> > +   relocate_kernel_ptr((unsigned long)image->head,
> > +   (unsigned long)page_list,
> > +   image->start, cpu_has_pae);
> 
> Why rename relocate_kernel?
> Ah.  I see.  You need to make it into a pointer again.  The crazy don't
> stop the pgd support strikes again.  It used to be named rnk.

You mean I should change the function pointer name to rnk to keep
consistency? I find rnk in IA64 implementation.

Best Regards,
Huang Ying
--
To unsubscribe 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Eric W. Biederman
"Huang, Ying" <[EMAIL PROTECTED]> writes:

> This patch implements the functionality of jumping between the kexeced
> kernel and the original kernel.
>
> 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.
>
> 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.
>
> 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 <[EMAIL PROTECTED]>
>
> ---
>  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 
>  #include 
>  #include 
> +#include 
>  
>  #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)
>  {

Why do we need var arg support?
Can't we do that with a shim we load from user space?

>   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;
>  
> + if (image->preserve_cpu) {
> + unsigned int i;
> + KCALL_MAGIC(control_page) = KCALL_MAGIC_NUMBER;
> 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Huang, Ying
On Mon, 2007-12-10 at 17:31 -0500, Vivek Goyal wrote:
> [..]
> >  
> > -#define KEXEC_ON_CRASH  0x0001
> > -#define KEXEC_ARCH_MASK 0x
> > +#define KEXEC_ON_CRASH 0x0001
> > +#define KEXEC_PRESERVE_CPU 0x0002
> > +#define KEXEC_PRESERVE_CPU_EXT 0x0004
> > +#define KEXEC_SINGLE_CPU   0x0008
> > +#define KEXEC_PRESERVE_DEVICE  0x0010
> > +#define KEXEC_PRESERVE_CONSOLE 0x0020
> 
> Hi,
> 
> Why do we need so many different flags for preserving different types
> of state (CPU, CPU_EXT, Device, console) ? To keep things simple,
> can't we can create just one flag KEXEC_PRESERVE_CONTEXT, which will
> indicate any special action required for preserving the previous kernel's
> context so that one can swith back to old kernel?

Yes. There are too many flags, especially when we have no users of these
flags now. It is better to use one flag such as KEXEC_PRESERVE_CONTEXT
now, and create the others required flags when really needed.

Best Regards,
Huang Ying
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Huang, Ying
On Mon, 2007-12-10 at 14:55 -0500, Vivek Goyal wrote:
> On Fri, Dec 07, 2007 at 03:53:30PM +, 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 <[EMAIL PROTECTED]>
> > 
> > ---
> >  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 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #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;
> >  }

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Vivek Goyal
On Fri, Dec 07, 2007 at 03:53:30PM +, Huang, Ying wrote:
> This patch implements the functionality of jumping between the kexeced
> kernel and the original kernel.
> 
> 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.
> 
> 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.
> 
> 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.
> 


[..]
>  
> -#define KEXEC_ON_CRASH  0x0001
> -#define KEXEC_ARCH_MASK 0x
> +#define KEXEC_ON_CRASH   0x0001
> +#define KEXEC_PRESERVE_CPU   0x0002
> +#define KEXEC_PRESERVE_CPU_EXT   0x0004
> +#define KEXEC_SINGLE_CPU 0x0008
> +#define KEXEC_PRESERVE_DEVICE0x0010
> +#define KEXEC_PRESERVE_CONSOLE   0x0020

Hi,

Why do we need so many different flags for preserving different types
of state (CPU, CPU_EXT, Device, console) ? To keep things simple,
can't we can create just one flag KEXEC_PRESERVE_CONTEXT, which will
indicate any special action required for preserving the previous kernel's
context so that one can swith back to old kernel?

Thanks
Vivek
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Vivek Goyal
On Fri, Dec 07, 2007 at 03:53:30PM +, 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?

> 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)?

> 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 <[EMAIL PROTECTED]>
> 
> ---
>  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 
>  #include 
>  #include 
> +#include 
>  
>  #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;
>  
>   /* 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Vivek Goyal
On Fri, Dec 07, 2007 at 03:53:30PM +, 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?

 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)?

 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 [EMAIL PROTECTED]
 
 ---
  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 */
   

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Vivek Goyal
On Fri, Dec 07, 2007 at 03:53:30PM +, Huang, Ying wrote:
 This patch implements the functionality of jumping between the kexeced
 kernel and the original kernel.
 
 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.
 
 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.
 
 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.
 


[..]
  
 -#define KEXEC_ON_CRASH  0x0001
 -#define KEXEC_ARCH_MASK 0x
 +#define KEXEC_ON_CRASH   0x0001
 +#define KEXEC_PRESERVE_CPU   0x0002
 +#define KEXEC_PRESERVE_CPU_EXT   0x0004
 +#define KEXEC_SINGLE_CPU 0x0008
 +#define KEXEC_PRESERVE_DEVICE0x0010
 +#define KEXEC_PRESERVE_CONSOLE   0x0020

Hi,

Why do we need so many different flags for preserving different types
of state (CPU, CPU_EXT, Device, console) ? To keep things simple,
can't we can create just one flag KEXEC_PRESERVE_CONTEXT, which will
indicate any special action required for preserving the previous kernel's
context so that one can swith back to old kernel?

Thanks
Vivek
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Huang, Ying
On Mon, 2007-12-10 at 14:55 -0500, Vivek Goyal wrote:
 On Fri, Dec 07, 2007 at 03:53:30PM +, 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 [EMAIL PROTECTED]
  
  ---
   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 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Huang, Ying
On Mon, 2007-12-10 at 17:31 -0500, Vivek Goyal wrote:
 [..]
   
  -#define KEXEC_ON_CRASH  0x0001
  -#define KEXEC_ARCH_MASK 0x
  +#define KEXEC_ON_CRASH 0x0001
  +#define KEXEC_PRESERVE_CPU 0x0002
  +#define KEXEC_PRESERVE_CPU_EXT 0x0004
  +#define KEXEC_SINGLE_CPU   0x0008
  +#define KEXEC_PRESERVE_DEVICE  0x0010
  +#define KEXEC_PRESERVE_CONSOLE 0x0020
 
 Hi,
 
 Why do we need so many different flags for preserving different types
 of state (CPU, CPU_EXT, Device, console) ? To keep things simple,
 can't we can create just one flag KEXEC_PRESERVE_CONTEXT, which will
 indicate any special action required for preserving the previous kernel's
 context so that one can swith back to old kernel?

Yes. There are too many flags, especially when we have no users of these
flags now. It is better to use one flag such as KEXEC_PRESERVE_CONTEXT
now, and create the others required flags when really needed.

Best Regards,
Huang Ying
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Eric W. Biederman
Huang, Ying [EMAIL PROTECTED] writes:

 This patch implements the functionality of jumping between the kexeced
 kernel and the original kernel.

 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.

 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.

 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 [EMAIL PROTECTED]

 ---
  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)
  {

Why do we need var arg support?
Can't we do that with a shim we load from user space?

   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;
  
 + if (image-preserve_cpu) {
 + unsigned int i;
 + KCALL_MAGIC(control_page) = KCALL_MAGIC_NUMBER;
 + KCALL_ARGC(control_page) = argc;
 + for (i = 0; i  

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-10 Thread Huang, Ying
On Mon, 2007-12-10 at 19:25 -0700, Eric W. Biederman wrote:
 Huang, Ying [EMAIL PROTECTED] writes:
[...]
   /*
* 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)
   {
 
 Why do we need var arg support?
 Can't we do that with a shim we load from user space?

If all parameters are provided in user space, the usage model may be as
follow:

- sys_kexec_load() /* with executable/data/parameters(A) loaded */
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(A)*/
- /* jump back */
- sys_kexec_load() /* with executable/data/parameters(B) loaded */
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,) /* execute physical mode code with 
parameters(B)*/
- /* jump back */

That is, the kexec image should be re-loaded if the parameters are
different, and there can be no state reserved in kexec image. This is OK
for original kexec implementation, because there is no jumping back.
But, for kexec with jumping back, another usage model may be useful too.

- sys_kexec_load() /* with executable/data loaded */
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(A)) /* execute physical mode 
code with parameters(A)*/
- sys_reboot(,,LINUX_REBOOT_CMD_KEXEC,parameters(B)) /* execute physical mode 
code with parameters(B)*/

This way the kexec image need not to be re-loaded, and the state of
kexec image can be reserved across several invoking.


Another usage model may be useful is invoking the kexec image (such as
firmware) from kernel space.

- kmalloc the needed memory and loaded the firmware image (if needed)
- sys_kexec_load() with a fake image (one segment with size 0), the
entry point of the fake image is the entry point of the firmware image.
- kexec_call(fake_image, ...) /* maybe change entry point if needed */

This way, some kernel code can invoke the firmware in physical mode just
like invoking an ordinary function.

[...]
  -   /* The segment registers are funny things, they have both a
  -* visible and an invisible part.  Whenever the visible part is
  -* set to a specific selector, the invisible part is loaded
  -* with from a table in memory.  At no other time is the
  -* descriptor table in memory accessed.
  -*
  -* I take advantage of this here by force loading the
  -* segments, before I zap the gdt with an invalid value.
  -*/
  -   load_segments();
  -   /* The gdt  idt are now invalid.
  -* If you want to load them you must set up your own idt  gdt.
  -*/
  -   set_gdt(phys_to_virt(0),0);
  -   set_idt(phys_to_virt(0),0);
  +   if (image-preserve_cpu_ext) {
  +   /* The segment registers are funny things, they have
  +* both a visible and an invisible part.  Whenever the
  +* visible part is set to a specific selector, the
  +* invisible part is loaded with from a table in
  +* memory.  At no other time is the descriptor table
  +* in memory accessed.
  +*
  +* I take advantage of this here by force loading the
  +* segments, before I zap the gdt with an invalid
  +* value.
  +*/
  +   load_segments();
  +   /* The gdt  idt are now invalid.  If you want to load
  +* them you must set up your own idt  gdt.
  +*/
  +   set_gdt(phys_to_virt(0), 0);
  +   set_idt(phys_to_virt(0), 0);
  +   }
 
 We can't keep the same idt and gdt as the pages they are on will be
 overwritten/reused.  So explictily stomping on them sounds better
 so they never work.  We can restore them on kernel reentry.

The original idea about this code is:

If the kexec image is claimed that it need not to perserving extensive
CPU state (such as FPU/MMX/GDT/LDT/IDT/CS/DS/ES/FS/GS/SS etc), the
IDT/GDT/CS/DS/ES/FS/GS/SS are not touched in kexec image code. So the
segment registers need not to be set.

But this is not clear. At least more description should be provided for
each preserve flag.

  /* now call it */
  -   relocate_kernel((unsigned long)image-head, (unsigned long)page_list,
  -   image-start, cpu_has_pae);
  +   relocate_kernel_ptr((unsigned long)image-head,
  +   (unsigned long)page_list,
  +   image-start, cpu_has_pae);
 
 Why rename relocate_kernel?
 Ah.  I see.  You need to make it into a pointer again.  The crazy don't
 stop the pgd support strikes again.  It used to be named rnk.

You mean I should change the function pointer name to rnk to keep
consistency? I find rnk in IA64 implementation.

Best Regards,
Huang Ying
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at 

Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-08 Thread Eric W. Biederman
"Rafael J. Wysocki" <[EMAIL PROTECTED]> writes:

>> I'm not kexec hacker... but maybe this is in good enough state to be
>> merged? It is useful on its own: kexec jump and back means we can dump
>> system then continue running, for example...
>
> As far as I'm concerned, patches [1/4] and [2/4] can go.
>
> The other two are not in that shape yet (especially the [3/4] patch).

Ok.  Then I will see if I can review these in the next couple days
and give some feedback.

At a quick skim through the code it appears there is some more infrastructure
then we need and things can still be simplified.

Since this applies in particular to the user space interface I'm not comfortable
with these patches going in just yet.

The unused KEXEC_PRESERVE_ flags especially give me pause.  Having something
like that, that isn't currently wired up sounds like a bad place to start.

Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-08 Thread Rafael J. Wysocki
On Sunday, 9 of December 2007, Pavel Machek wrote:
> Hi!
> 
> > This patch implements the functionality of jumping between the kexeced
> > kernel and the original kernel.
> > 
> > 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.
> > 
> > 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.
> > 
> > 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 <[EMAIL PROTECTED]>
> 
> I'm not kexec hacker... but maybe this is in good enough state to be
> merged? It is useful on its own: kexec jump and back means we can dump
> system then continue running, for example...

As far as I'm concerned, patches [1/4] and [2/4] can go.

The other two are not in that shape yet (especially the [3/4] patch).

Greetings,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-08 Thread Pavel Machek
Hi!

> This patch implements the functionality of jumping between the kexeced
> kernel and the original kernel.
> 
> 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.
> 
> 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.
> 
> 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 <[EMAIL PROTECTED]>

I'm not kexec hacker... but maybe this is in good enough state to be
merged? It is useful on its own: kexec jump and back means we can dump
system then continue running, for example...

Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-08 Thread Pavel Machek
Hi!

 This patch implements the functionality of jumping between the kexeced
 kernel and the original kernel.
 
 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.
 
 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.
 
 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 [EMAIL PROTECTED]

I'm not kexec hacker... but maybe this is in good enough state to be
merged? It is useful on its own: kexec jump and back means we can dump
system then continue running, for example...

Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-08 Thread Rafael J. Wysocki
On Sunday, 9 of December 2007, Pavel Machek wrote:
 Hi!
 
  This patch implements the functionality of jumping between the kexeced
  kernel and the original kernel.
  
  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.
  
  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.
  
  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 [EMAIL PROTECTED]
 
 I'm not kexec hacker... but maybe this is in good enough state to be
 merged? It is useful on its own: kexec jump and back means we can dump
 system then continue running, for example...

As far as I'm concerned, patches [1/4] and [2/4] can go.

The other two are not in that shape yet (especially the [3/4] patch).

Greetings,
Rafael
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/4 -mm] kexec based hibernation -v7 : kexec jump

2007-12-08 Thread Eric W. Biederman
Rafael J. Wysocki [EMAIL PROTECTED] writes:

 I'm not kexec hacker... but maybe this is in good enough state to be
 merged? It is useful on its own: kexec jump and back means we can dump
 system then continue running, for example...

 As far as I'm concerned, patches [1/4] and [2/4] can go.

 The other two are not in that shape yet (especially the [3/4] patch).

Ok.  Then I will see if I can review these in the next couple days
and give some feedback.

At a quick skim through the code it appears there is some more infrastructure
then we need and things can still be simplified.

Since this applies in particular to the user space interface I'm not comfortable
with these patches going in just yet.

The unused KEXEC_PRESERVE_ flags especially give me pause.  Having something
like that, that isn't currently wired up sounds like a bad place to start.

Eric
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/