Skip to contentSkip to conversation

Hibernation: Document __save_processor_state() on x86-64

PATCH In review Rafael J. Wysocki 4 participants 28 messages Dec 28, 2007 – Dec 31, 2007 x86

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Hibernation: Document __save_processor_state() on x86-64

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/x86/kernel/suspend_64.c +20 -0
Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */
 void __save_processor_state(struct saved_context *ctxt)
 {
 	kernel_fpu_begin();
@@ -69,6 +84,11 @@ static void do_fpu_end(void)
 	kernel_fpu_end();
 }
 
+/**
+ *	__restore_processor_state - restore the contents of CPU registers saved
+ *		by __save_processor_state()
+ *	@ctxt - structure to load the registers contents from
+ */
 void __restore_processor_state(struct saved_context *ctxt)
 {
 	/*
#1 lore raw

Hi!

Quoted 25 lines

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================

arch/x86/kernel/suspend_64.c +5 -0
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *

arch/x86/kernel/suspend_64.c extern const void __nosave_begin, __nosa · line 36

Quoted 10 lines
arch/x86/kernel/suspend_64.c +10 -0
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */

Maybe this warning should be appended to struct saved_context definition? Reordering its fields (etc) would be bad news, too, and documentation near data structures is easier to find...

Thanks,
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#2 lore raw
Quoted 32 lines · Pavel Machek

Hi!

Quoted 30 lines

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================

arch/x86/kernel/suspend_64.c +10 -0
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
Quoted 8 lines

arch/x86/kernel/suspend_64.c extern const void __nosave_begin, __nosa · line 36

Quoted 5 lines
arch/x86/kernel/suspend_64.c +5 -0
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */

Maybe this warning should be appended to struct saved_context definition? Reordering its fields (etc) would be bad news, too,

Hmm, I think they can be reordered without any problem. It's always the same kernel using them, although at different times.

Quoted 1 line

and documentation near data structures is easier to find...

Well, I'll add a coment next to the definition of struct saved_context to explain what it's for, but IMO the behavior of __save_processor_state() is what _really_ matters (ie. it doesn't matter how and where exactly it saves the registers as long as __restore_processor_state() can restore their "old" values).

Greetings,
Rafael

#3 lore raw
Quoted 42 lines · Rafael J. Wysocki
Quoted 32 lines · Pavel Machek

Hi!

Quoted 30 lines

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================

arch/x86/kernel/suspend_64.c +10 -0
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
Quoted 8 lines

arch/x86/kernel/suspend_64.c extern const void __nosave_begin, __nosa · line 36

Quoted 5 lines
arch/x86/kernel/suspend_64.c +5 -0
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */

Maybe this warning should be appended to struct saved_context definition? Reordering its fields (etc) would be bad news, too,

Quoted 2 lines

Hmm, I think they can be reordered without any problem. It's always the same kernel using them, although at different times.

Aha... ok, then. I misunderstood how it works.

Quoted 7 lines
Quoted 1 line

and documentation near data structures is easier to find...

Well, I'll add a coment next to the definition of struct saved_context to explain what it's for, but IMO the behavior of __save_processor_state() is what _really_ matters (ie. it doesn't matter how and where exactly it saves the registers as long as __restore_processor_state() can restore their "old" values).

Yep, right.

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#4 lore raw
In reply to Rafael J. Wysocki
Quoted 42 lines · Rafael J. Wysocki
Quoted 32 lines · Pavel Machek

Hi!

Quoted 30 lines

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================

arch/x86/kernel/suspend_64.c +10 -0
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
Quoted 8 lines

arch/x86/kernel/suspend_64.c extern const void __nosave_begin, __nosa · line 36

Quoted 5 lines
arch/x86/kernel/suspend_64.c +5 -0
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */

Maybe this warning should be appended to struct saved_context definition? Reordering its fields (etc) would be bad news, too,

Quoted 2 lines

Hmm, I think they can be reordered without any problem. It's always the same kernel using them, although at different times.

Aha... ok, then. I misunderstood how it works.

Quoted 7 lines
Quoted 1 line

and documentation near data structures is easier to find...

Well, I'll add a coment next to the definition of struct saved_context to explain what it's for, but IMO the behavior of __save_processor_state() is what _really_ matters (ie. it doesn't matter how and where exactly it saves the registers as long as __restore_processor_state() can restore their "old" values).

Yep, right.

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#5 lore raw
In reply to Pavel Machek
Quoted 32 lines · Pavel Machek

Hi!

Quoted 30 lines

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================

arch/x86/kernel/suspend_64.c +10 -0
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
Quoted 8 lines

arch/x86/kernel/suspend_64.c extern const void __nosave_begin, __nosa · line 36

Quoted 5 lines
arch/x86/kernel/suspend_64.c +5 -0
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */

Maybe this warning should be appended to struct saved_context definition? Reordering its fields (etc) would be bad news, too,

Hmm, I think they can be reordered without any problem. It's always the same kernel using them, although at different times.

Quoted 1 line

and documentation near data structures is easier to find...

Well, I'll add a coment next to the definition of struct saved_context to explain what it's for, but IMO the behavior of __save_processor_state() is what _really_ matters (ie. it doesn't matter how and where exactly it saves the registers as long as __restore_processor_state() can restore their "old" values).

Greetings,
Rafael

#6 lore raw
In reply to Rafael J. Wysocki

Hi!

Quoted 25 lines

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

---
 arch/x86/kernel/suspend_64.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linux-2.6/arch/x86/kernel/suspend_64.c
===================================================================

arch/x86/kernel/suspend_64.c +5 -0
@@ -19,6 +19,21 @@ extern const void __nosave_begin, __nosa
 
 struct saved_context saved_context;
 
+/**
+ *	__save_processor_state - save CPU registers before creating a
+ *		hibernation image and before restoring the memory state from it
+ *	@ctxt - structure to store the registers contents in
+ *

arch/x86/kernel/suspend_64.c extern const void __nosave_begin, __nosa · line 36

Quoted 10 lines
arch/x86/kernel/suspend_64.c +10 -0
+ *	NOTE: If there is a CPU register the modification of which by the
+ *	boot kernel (ie. the kernel used for loading the hibernation image)
+ *	might affect the operations of the restored target kernel (ie. the one
+ *	saved in the hibernation image), then its contents must be saved by this
+ *	function.  In other words, if kernel A is hibernated and different
+ *	kernel B is used for loading the hibernation image into memory, the
+ *	kernel A's __save_processor_state() function must save all registers
+ *	needed by kernel A, so that it can operate correctly after the resume
+ *	regardless of what kernel B does in the meantime.
+ */

Maybe this warning should be appended to struct saved_context definition? Reordering its fields (etc) would be bad news, too, and documentation near data structures is easier to find...

Thanks,
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#7 lore raw
In reply to Rafael J. Wysocki
Quoted 5 lines · Rafael J. Wysocki

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

ok - so i guess i should drop this from x86.git:

@@ -53,7 +53,6 @@ void __save_processor_state(struct saved

         ctxt->cr2 = read_cr2();
         ctxt->cr3 = read_cr3();
         ctxt->cr4 = read_cr4();

- ctxt->cr8 = read_cr8();
}

right? But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

Ingo

#8 lore raw
In reply to Rafael J. Wysocki
Quoted 5 lines · Rafael J. Wysocki

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

ok - so i guess i should drop this from x86.git:

@@ -53,7 +53,6 @@ void __save_processor_state(struct saved

         ctxt->cr2 = read_cr2();
         ctxt->cr3 = read_cr3();
         ctxt->cr4 = read_cr4();

- ctxt->cr8 = read_cr8();
}

right? But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

Ingo

#9 lore raw
Quoted 11 lines · Ingo Molnar
Quoted 5 lines · Rafael J. Wysocki

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

ok - so i guess i should drop this from x86.git:

Quoted 8 lines

@@ -53,7 +53,6 @@ void __save_processor_state(struct saved

         ctxt->cr2 = read_cr2();
         ctxt->cr3 = read_cr3();
         ctxt->cr4 = read_cr4();

- ctxt->cr8 = read_cr8();
}

right?

Well, if cr8 is used for anything that matters, then yes.

Quoted 2 lines

But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

The boot kernel may be different from the kernel within the image, if that's what you're asking for.

Rafael

#10 lore raw
Quoted 5 lines · Rafael J. Wysocki
Quoted 2 lines

But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

The boot kernel may be different from the kernel within the image, if that's what you're asking for.

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

Ingo

#11 lore raw
In reply to Rafael J. Wysocki
Quoted 5 lines · Rafael J. Wysocki
Quoted 2 lines

But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

The boot kernel may be different from the kernel within the image, if that's what you're asking for.

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

Ingo

#12 lore raw
Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Rafael J. Wysocki
Quoted 2 lines

But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

Quoted 6 lines
Quoted 2 lines

The boot kernel may be different from the kernel within the image, if that's what you're asking for.

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

On x86-64 it can be almost totally different (by restoring a hibernation image we replace the entire contents of RAM with almost no constraints).

[Well, using a relocatable kernel for restoring an image with nonrelocatable one or vice versa is rather not the best idea, but everything else should work in theory.]

On i386 the boot kernel is still required to be the same as the one in the image.

Greetings,
Rafael

#13 lore raw
Quoted 8 lines · Rafael J. Wysocki
Quoted 3 lines

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

On x86-64 it can be almost totally different (by restoring a hibernation image we replace the entire contents of RAM with almost no constraints).

Quoted 6 lines

[Well, using a relocatable kernel for restoring an image with nonrelocatable one or vice versa is rather not the best idea, but everything else should work in theory.]

On i386 the boot kernel is still required to be the same as the one in the image.

what's exactly in the hibernation image? Dirty data i suppose - but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

Ingo

#14 lore raw
In reply to Rafael J. Wysocki
Quoted 8 lines · Rafael J. Wysocki
Quoted 3 lines

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

On x86-64 it can be almost totally different (by restoring a hibernation image we replace the entire contents of RAM with almost no constraints).

Quoted 6 lines

[Well, using a relocatable kernel for restoring an image with nonrelocatable one or vice versa is rather not the best idea, but everything else should work in theory.]

On i386 the boot kernel is still required to be the same as the one in the image.

what's exactly in the hibernation image? Dirty data i suppose - but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

Ingo

#15 lore raw
Quoted 11 lines · Ingo Molnar
Quoted 8 lines · Rafael J. Wysocki
Quoted 3 lines

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

On x86-64 it can be almost totally different (by restoring a hibernation image we replace the entire contents of RAM with almost no constraints).

Quoted 8 lines
Quoted 6 lines

[Well, using a relocatable kernel for restoring an image with nonrelocatable one or vice versa is rather not the best idea, but everything else should work in theory.]

On i386 the boot kernel is still required to be the same as the one in the image.

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

Rafael

#16 lore raw
Quoted 10 lines · Rafael J. Wysocki
Quoted 1 line

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Ingo

#17 lore raw
Quoted 10 lines · Ingo Molnar
Quoted 7 lines · Rafael J. Wysocki
Quoted 1 line

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

Quoted 8 lines
Quoted 3 lines

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Well, not exactly. The support for different boot and image kernels has only been merged recently, but we can use the current git to restore 2.6.24-rc6-mm1, for example.

The trick is to pass a little additional information in the image header that can be used by the boot kernel to locate the entry point to the image kernel and the image kernel's page tables.

Rafael

#18 lore raw
Quoted 6 lines · Rafael J. Wysocki
Quoted 5 lines

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Quoted 7 lines

Well, not exactly. The support for different boot and image kernels has only been merged recently, but we can use the current git to restore 2.6.24-rc6-mm1, for example.

The trick is to pass a little additional information in the image header that can be used by the boot kernel to locate the entry point to the image kernel and the image kernel's page tables.

ok - i thought you meant that there's a general capability to resume across kernel versions. (which would be close to impossible without some major surgery.)

btw., in what way is this different from kexec?

Ingo

#19 lore raw
In reply to Rafael J. Wysocki
Quoted 6 lines · Rafael J. Wysocki
Quoted 5 lines

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Quoted 7 lines

Well, not exactly. The support for different boot and image kernels has only been merged recently, but we can use the current git to restore 2.6.24-rc6-mm1, for example.

The trick is to pass a little additional information in the image header that can be used by the boot kernel to locate the entry point to the image kernel and the image kernel's page tables.

ok - i thought you meant that there's a general capability to resume across kernel versions. (which would be close to impossible without some major surgery.)

btw., in what way is this different from kexec?

Ingo

#20 lore raw
Quoted 13 lines · Ingo Molnar
Quoted 10 lines · Rafael J. Wysocki
Quoted 5 lines

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Well, not exactly. The support for different boot and image kernels has only been merged recently, but we can use the current git to restore 2.6.24-rc6-mm1, for example.

Quoted 7 lines
Quoted 3 lines

The trick is to pass a little additional information in the image header that can be used by the boot kernel to locate the entry point to the image kernel and the image kernel's page tables.

ok - i thought you meant that there's a general capability to resume across kernel versions. (which would be close to impossible without some major surgery.)

Well, there will be one. :-) For example, one should be able to use a 2.6.25+ boot kernel to load the image containing 2.6.24-rc6 and restore the memory state from it.

Quoted 1 line

btw., in what way is this different from kexec?

Not that much different indeed. The hibernation code is more focused on restoring the pre-hibernation state of the system rather than anything else, plus on ACPI systems we try to handle the platform in accordance with the specification (to some extent - you'd have to use a non-ACPI boot kernel to follow the specification literally, which is possible but not straightforward).

Rafael

#21 lore raw
In reply to Ingo Molnar
Quoted 13 lines · Ingo Molnar
Quoted 10 lines · Rafael J. Wysocki
Quoted 5 lines

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Well, not exactly. The support for different boot and image kernels has only been merged recently, but we can use the current git to restore 2.6.24-rc6-mm1, for example.

Quoted 7 lines
Quoted 3 lines

The trick is to pass a little additional information in the image header that can be used by the boot kernel to locate the entry point to the image kernel and the image kernel's page tables.

ok - i thought you meant that there's a general capability to resume across kernel versions. (which would be close to impossible without some major surgery.)

Well, there will be one. :-) For example, one should be able to use a 2.6.25+ boot kernel to load the image containing 2.6.24-rc6 and restore the memory state from it.

Quoted 1 line

btw., in what way is this different from kexec?

Not that much different indeed. The hibernation code is more focused on restoring the pre-hibernation state of the system rather than anything else, plus on ACPI systems we try to handle the platform in accordance with the specification (to some extent - you'd have to use a non-ACPI boot kernel to follow the specification literally, which is possible but not straightforward).

Rafael

#22 lore raw
In reply to Ingo Molnar
Quoted 10 lines · Ingo Molnar
Quoted 7 lines · Rafael J. Wysocki
Quoted 1 line

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

Quoted 8 lines
Quoted 3 lines

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

Well, not exactly. The support for different boot and image kernels has only been merged recently, but we can use the current git to restore 2.6.24-rc6-mm1, for example.

The trick is to pass a little additional information in the image header that can be used by the boot kernel to locate the entry point to the image kernel and the image kernel's page tables.

Rafael

#23 lore raw
In reply to Ingo Molnar
Quoted 10 lines · Ingo Molnar
Quoted 7 lines · Rafael J. Wysocki
Quoted 1 line

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

Quoted 8 lines
Quoted 3 lines

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

I suspect here is a slight misunderstanding: It will never be possible to switch a kernel with a hibernation/resume cycle.
The new thing is, that you can use a 2.6.24-SLUB-kernel to load a 2.6.12-SLAB-kernel(*) and then have the *2.6.12* kernel continue to run.

The jump that Rafael talks about is a complete switchover from the kernel doing the resume to the old kernel (and all of its data structures) from the hibernation image. The now again running old kernel will discard any internal data from the resuming kernel and so it is not important if there was a SLAB vs SLUB difference.

In some way you could see the kernel loading the image as a gigantic bootloader and just as is does not matter if you use lilo or grub it should no longer matter what bootloader/kernel was used for resuming, now that a ABI for the resume has been defined.

Torsten

(*): 2.6.12 might not work, as Rafael said the feature supporting different kernel versions was only merge recently.

#24 lore raw
In reply to Ingo Molnar
Quoted 10 lines · Ingo Molnar
Quoted 7 lines · Rafael J. Wysocki
Quoted 1 line

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

Quoted 8 lines
Quoted 3 lines

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

ok, just to make sure we are talking about the same thing. Do you mean we can restore an image saved by v2.6.12 into v2.6.24? I.e. a 2.6.24 kernel will be able to run a 2.6.12 kernel's hibernation image, with all the kernel internal data from v2.6.12, etc? No way can that work.

I suspect here is a slight misunderstanding: It will never be possible to switch a kernel with a hibernation/resume cycle.
The new thing is, that you can use a 2.6.24-SLUB-kernel to load a 2.6.12-SLAB-kernel(*) and then have the *2.6.12* kernel continue to run.

The jump that Rafael talks about is a complete switchover from the kernel doing the resume to the old kernel (and all of its data structures) from the hibernation image. The now again running old kernel will discard any internal data from the resuming kernel and so it is not important if there was a SLAB vs SLUB difference.

In some way you could see the kernel loading the image as a gigantic bootloader and just as is does not matter if you use lilo or grub it should no longer matter what bootloader/kernel was used for resuming, now that a ABI for the resume has been defined.

Torsten

(*): 2.6.12 might not work, as Rafael said the feature supporting different kernel versions was only merge recently.

#25 lore raw
In reply to Ingo Molnar
Quoted 11 lines · Ingo Molnar
Quoted 8 lines · Rafael J. Wysocki
Quoted 3 lines

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

On x86-64 it can be almost totally different (by restoring a hibernation image we replace the entire contents of RAM with almost no constraints).

Quoted 8 lines
Quoted 6 lines

[Well, using a relocatable kernel for restoring an image with nonrelocatable one or vice versa is rather not the best idea, but everything else should work in theory.]

On i386 the boot kernel is still required to be the same as the one in the image.

what's exactly in the hibernation image? Dirty data i suppose

No, everything, including the kernel code, page tables etc. :-)

Quoted 2 lines

- but what about kernel-internal pages. What if we go from SLAB to SLUB? What if the size of a structure changes? Etc.

We can go from SLAB to SLUB just fine, it doesn't matter. The only thing that matters is we have to jump to the right address at the end of core_restore_code() (defined in arch/x86/kernel/suspend_asm_64.S).

Rafael

#26 lore raw
In reply to Ingo Molnar
Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Rafael J. Wysocki
Quoted 2 lines

But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

Quoted 6 lines
Quoted 2 lines

The boot kernel may be different from the kernel within the image, if that's what you're asking for.

how different can it be, for resume to work? I mean, we'll have deeply kernel version dependent variables in RAM. Am i missing something obvious?

On x86-64 it can be almost totally different (by restoring a hibernation image we replace the entire contents of RAM with almost no constraints).

[Well, using a relocatable kernel for restoring an image with nonrelocatable one or vice versa is rather not the best idea, but everything else should work in theory.]

On i386 the boot kernel is still required to be the same as the one in the image.

Greetings,
Rafael

#27 lore raw
In reply to Ingo Molnar
Quoted 11 lines · Ingo Molnar
Quoted 5 lines · Rafael J. Wysocki

From: Rafael J. Wysocki <[email protected]>

Document the fact that __save_processor_state() has to save all CPU registers referred to by the kernel in case a different kernel is used to load and restore a hibernation image containing it.

ok - so i guess i should drop this from x86.git:

Quoted 8 lines

@@ -53,7 +53,6 @@ void __save_processor_state(struct saved

         ctxt->cr2 = read_cr2();
         ctxt->cr3 = read_cr3();
         ctxt->cr4 = read_cr4();

- ctxt->cr8 = read_cr8();
}

right?

Well, if cr8 is used for anything that matters, then yes.

Quoted 2 lines

But i'm wondering - are we really ever resuming to a different kernel version, for this to be an issue?

The boot kernel may be different from the kernel within the image, if that's what you're asking for.

Rafael