* [PATCH] x86_64: Save registers in saved_context during suspend and hibernation
@ 2007-08-13 21:47 Rafael J. Wysocki
2007-08-13 22:52 ` Andi Kleen
0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2007-08-13 21:47 UTC (permalink / raw)
To: pm list; +Cc: discuss, Andi Kleen, Pavel Machek
From: Rafael J. Wysocki <rjw@sisk.pl>
During hibernation and suspend on x86_64 save CPU registers in the saved_context
structure rather than in a handful of separate variables.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
arch/x86_64/kernel/acpi/wakeup.S | 101 ++++++++++++++++++++-------------------
arch/x86_64/kernel/asm-offsets.c | 22 ++++++++
arch/x86_64/kernel/suspend.c | 6 --
arch/x86_64/kernel/suspend_asm.S | 72 ++++++++++++++-------------
include/asm-x86_64/suspend.h | 39 ++++++++-------
5 files changed, 135 insertions(+), 105 deletions(-)
Index: linux-2.6.23-rc2/arch/x86_64/kernel/asm-offsets.c
===================================================================
--- linux-2.6.23-rc2.orig/arch/x86_64/kernel/asm-offsets.c 2007-08-12 12:07:51.000000000 +0200
+++ linux-2.6.23-rc2/arch/x86_64/kernel/asm-offsets.c 2007-08-13 21:38:24.000000000 +0200
@@ -76,6 +76,28 @@ int main(void)
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
BLANK();
+ DEFINE(saved_context_rbx, offsetof(struct saved_context, rbx));
+ DEFINE(saved_context_rcx, offsetof(struct saved_context, rcx));
+ DEFINE(saved_context_rdx, offsetof(struct saved_context, rdx));
+ DEFINE(saved_context_rsp, offsetof(struct saved_context, rsp));
+ DEFINE(saved_context_rbp, offsetof(struct saved_context, rbp));
+ DEFINE(saved_context_rsi, offsetof(struct saved_context, rsi));
+ DEFINE(saved_context_rdi, offsetof(struct saved_context, rdi));
+ DEFINE(saved_context_r8, offsetof(struct saved_context, r8));
+ DEFINE(saved_context_r9, offsetof(struct saved_context, r9));
+ DEFINE(saved_context_r10, offsetof(struct saved_context, r10));
+ DEFINE(saved_context_r11, offsetof(struct saved_context, r11));
+ DEFINE(saved_context_r12, offsetof(struct saved_context, r12));
+ DEFINE(saved_context_r13, offsetof(struct saved_context, r13));
+ DEFINE(saved_context_r14, offsetof(struct saved_context, r14));
+ DEFINE(saved_context_r15, offsetof(struct saved_context, r15));
+ DEFINE(saved_context_rflags, offsetof(struct saved_context, rflags));
+ DEFINE(saved_context_cr0, offsetof(struct saved_context, cr0));
+ DEFINE(saved_context_cr2, offsetof(struct saved_context, cr2));
+ DEFINE(saved_context_cr3, offsetof(struct saved_context, cr3));
+ DEFINE(saved_context_cr4, offsetof(struct saved_context, cr4));
+ DEFINE(saved_context_cr8, offsetof(struct saved_context, cr8));
+ BLANK();
DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
BLANK();
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
Index: linux-2.6.23-rc2/include/asm-x86_64/suspend.h
===================================================================
--- linux-2.6.23-rc2.orig/include/asm-x86_64/suspend.h 2007-08-12 12:07:51.000000000 +0200
+++ linux-2.6.23-rc2/include/asm-x86_64/suspend.h 2007-08-13 21:38:38.000000000 +0200
@@ -3,6 +3,9 @@
* Based on code
* Copyright 2001 Patrick Mochel <mochel@osdl.org>
*/
+#ifndef __ASM_X86_64_SUSPEND_H
+#define __ASM_X86_64_SUSPEND_H
+
#include <asm/desc.h>
#include <asm/i387.h>
@@ -12,8 +15,24 @@ arch_prepare_suspend(void)
return 0;
}
-/* Image of the saved processor state. If you touch this, fix acpi_wakeup.S. */
+/* Image of the saved processor state. If you touch this, fix acpi/wakeup.S. */
struct saved_context {
+ unsigned long rax;
+ unsigned long rbx;
+ unsigned long rcx;
+ unsigned long rdx;
+ unsigned long rsp;
+ unsigned long rbp;
+ unsigned long rsi;
+ unsigned long rdi;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long r11;
+ unsigned long r12;
+ unsigned long r13;
+ unsigned long r14;
+ unsigned long r15;
u16 ds, es, fs, gs, ss;
unsigned long gs_base, gs_kernel_base, fs_base;
unsigned long cr0, cr2, cr3, cr4, cr8;
@@ -29,27 +48,15 @@ struct saved_context {
unsigned long tr;
unsigned long safety;
unsigned long return_address;
- unsigned long eflags;
+ unsigned long rflags;
} __attribute__((packed));
-/* We'll access these from assembly, so we'd better have them outside struct */
-extern unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
-extern unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
-extern unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
-extern unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
-extern unsigned long saved_context_eflags;
-
#define loaddebug(thread,register) \
set_debugreg((thread)->debugreg##register, register)
extern void fix_processor_context(void);
-extern unsigned long saved_rip;
-extern unsigned long saved_rsp;
-extern unsigned long saved_rbp;
-extern unsigned long saved_rbx;
-extern unsigned long saved_rsi;
-extern unsigned long saved_rdi;
-
/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
+
+#endif /* __ASM_X86_64_SUSPEND_H */
Index: linux-2.6.23-rc2/arch/x86_64/kernel/suspend.c
===================================================================
--- linux-2.6.23-rc2.orig/arch/x86_64/kernel/suspend.c 2007-08-12 12:07:51.000000000 +0200
+++ linux-2.6.23-rc2/arch/x86_64/kernel/suspend.c 2007-08-13 21:38:24.000000000 +0200
@@ -19,12 +19,6 @@ extern const void __nosave_begin, __nosa
struct saved_context saved_context;
-unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
-unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
-unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
-unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
-unsigned long saved_context_eflags;
-
void __save_processor_state(struct saved_context *ctxt)
{
kernel_fpu_begin();
Index: linux-2.6.23-rc2/arch/x86_64/kernel/suspend_asm.S
===================================================================
--- linux-2.6.23-rc2.orig/arch/x86_64/kernel/suspend_asm.S 2007-08-12 12:07:51.000000000 +0200
+++ linux-2.6.23-rc2/arch/x86_64/kernel/suspend_asm.S 2007-08-13 21:38:24.000000000 +0200
@@ -17,24 +17,24 @@
#include <asm/asm-offsets.h>
ENTRY(swsusp_arch_suspend)
-
- movq %rsp, saved_context_esp(%rip)
- movq %rax, saved_context_eax(%rip)
- movq %rbx, saved_context_ebx(%rip)
- movq %rcx, saved_context_ecx(%rip)
- movq %rdx, saved_context_edx(%rip)
- movq %rbp, saved_context_ebp(%rip)
- movq %rsi, saved_context_esi(%rip)
- movq %rdi, saved_context_edi(%rip)
- movq %r8, saved_context_r08(%rip)
- movq %r9, saved_context_r09(%rip)
- movq %r10, saved_context_r10(%rip)
- movq %r11, saved_context_r11(%rip)
- movq %r12, saved_context_r12(%rip)
- movq %r13, saved_context_r13(%rip)
- movq %r14, saved_context_r14(%rip)
- movq %r15, saved_context_r15(%rip)
- pushfq ; popq saved_context_eflags(%rip)
+ movq $saved_context, %rax
+ movq %rsp, saved_context_rsp(%rax)
+ movq %rbp, saved_context_rbp(%rax)
+ movq %rsi, saved_context_rsi(%rax)
+ movq %rdi, saved_context_rdi(%rax)
+ movq %rbx, saved_context_rbx(%rax)
+ movq %rcx, saved_context_rcx(%rax)
+ movq %rdx, saved_context_rdx(%rax)
+ movq %r8, saved_context_r8(%rax)
+ movq %r9, saved_context_r9(%rax)
+ movq %r10, saved_context_r10(%rax)
+ movq %r11, saved_context_r11(%rax)
+ movq %r12, saved_context_r12(%rax)
+ movq %r13, saved_context_r13(%rax)
+ movq %r14, saved_context_r14(%rax)
+ movq %r15, saved_context_r15(%rax)
+ pushfq
+ popq saved_context_rflags(%rax)
call swsusp_save
ret
@@ -87,23 +87,25 @@ done:
movl $24, %eax
movl %eax, %ds
- movq saved_context_esp(%rip), %rsp
- movq saved_context_ebp(%rip), %rbp
- /* Don't restore %rax, it must be 0 anyway */
- movq saved_context_ebx(%rip), %rbx
- movq saved_context_ecx(%rip), %rcx
- movq saved_context_edx(%rip), %rdx
- movq saved_context_esi(%rip), %rsi
- movq saved_context_edi(%rip), %rdi
- movq saved_context_r08(%rip), %r8
- movq saved_context_r09(%rip), %r9
- movq saved_context_r10(%rip), %r10
- movq saved_context_r11(%rip), %r11
- movq saved_context_r12(%rip), %r12
- movq saved_context_r13(%rip), %r13
- movq saved_context_r14(%rip), %r14
- movq saved_context_r15(%rip), %r15
- pushq saved_context_eflags(%rip) ; popfq
+ /* We don't restore %rax, it must be 0 anyway */
+ movq $saved_context, %rax
+ movq saved_context_rsp(%rax), %rsp
+ movq saved_context_rbp(%rax), %rbp
+ movq saved_context_rsi(%rax), %rsi
+ movq saved_context_rdi(%rax), %rdi
+ movq saved_context_rbx(%rax), %rbx
+ movq saved_context_rcx(%rax), %rcx
+ movq saved_context_rdx(%rax), %rdx
+ movq saved_context_r8(%rax), %r8
+ movq saved_context_r9(%rax), %r9
+ movq saved_context_r10(%rax), %r10
+ movq saved_context_r11(%rax), %r11
+ movq saved_context_r12(%rax), %r12
+ movq saved_context_r13(%rax), %r13
+ movq saved_context_r14(%rax), %r14
+ movq saved_context_r15(%rax), %r15
+ pushq saved_context_rflags(%rax)
+ popfq
xorq %rax, %rax
Index: linux-2.6.23-rc2/arch/x86_64/kernel/acpi/wakeup.S
===================================================================
--- linux-2.6.23-rc2.orig/arch/x86_64/kernel/acpi/wakeup.S 2007-08-04 11:59:25.000000000 +0200
+++ linux-2.6.23-rc2/arch/x86_64/kernel/acpi/wakeup.S 2007-08-12 13:38:05.000000000 +0200
@@ -4,6 +4,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/msr.h>
+#include <asm/asm-offsets.h>
# Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
#
@@ -395,31 +396,32 @@ do_suspend_lowlevel:
xorl %eax, %eax
call save_processor_state
- movq %rsp, saved_context_esp(%rip)
- movq %rax, saved_context_eax(%rip)
- movq %rbx, saved_context_ebx(%rip)
- movq %rcx, saved_context_ecx(%rip)
- movq %rdx, saved_context_edx(%rip)
- movq %rbp, saved_context_ebp(%rip)
- movq %rsi, saved_context_esi(%rip)
- movq %rdi, saved_context_edi(%rip)
- movq %r8, saved_context_r08(%rip)
- movq %r9, saved_context_r09(%rip)
- movq %r10, saved_context_r10(%rip)
- movq %r11, saved_context_r11(%rip)
- movq %r12, saved_context_r12(%rip)
- movq %r13, saved_context_r13(%rip)
- movq %r14, saved_context_r14(%rip)
- movq %r15, saved_context_r15(%rip)
- pushfq ; popq saved_context_eflags(%rip)
+ movq $saved_context, %rax
+ movq %rsp, saved_context_rsp(%rax)
+ movq %rbp, saved_context_rbp(%rax)
+ movq %rsi, saved_context_rsi(%rax)
+ movq %rdi, saved_context_rdi(%rax)
+ movq %rbx, saved_context_rbx(%rax)
+ movq %rcx, saved_context_rcx(%rax)
+ movq %rdx, saved_context_rdx(%rax)
+ movq %r8, saved_context_r8(%rax)
+ movq %r9, saved_context_r9(%rax)
+ movq %r10, saved_context_r10(%rax)
+ movq %r11, saved_context_r11(%rax)
+ movq %r12, saved_context_r12(%rax)
+ movq %r13, saved_context_r13(%rax)
+ movq %r14, saved_context_r14(%rax)
+ movq %r15, saved_context_r15(%rax)
+ pushfq
+ popq saved_context_rflags(%rax)
movq $.L97, saved_rip(%rip)
- movq %rsp,saved_rsp
- movq %rbp,saved_rbp
- movq %rbx,saved_rbx
- movq %rdi,saved_rdi
- movq %rsi,saved_rsi
+ movq %rsp, saved_rsp
+ movq %rbp, saved_rbp
+ movq %rbx, saved_rbx
+ movq %rdi, saved_rdi
+ movq %rsi, saved_rsi
addq $8, %rsp
movl $3, %edi
@@ -430,32 +432,35 @@ do_suspend_lowlevel:
.L99:
.align 4
movl $24, %eax
- movw %ax, %ds
- movq saved_context+58(%rip), %rax
- movq %rax, %cr4
- movq saved_context+50(%rip), %rax
- movq %rax, %cr3
- movq saved_context+42(%rip), %rax
- movq %rax, %cr2
- movq saved_context+34(%rip), %rax
- movq %rax, %cr0
- pushq saved_context_eflags(%rip) ; popfq
- movq saved_context_esp(%rip), %rsp
- movq saved_context_ebp(%rip), %rbp
- movq saved_context_eax(%rip), %rax
- movq saved_context_ebx(%rip), %rbx
- movq saved_context_ecx(%rip), %rcx
- movq saved_context_edx(%rip), %rdx
- movq saved_context_esi(%rip), %rsi
- movq saved_context_edi(%rip), %rdi
- movq saved_context_r08(%rip), %r8
- movq saved_context_r09(%rip), %r9
- movq saved_context_r10(%rip), %r10
- movq saved_context_r11(%rip), %r11
- movq saved_context_r12(%rip), %r12
- movq saved_context_r13(%rip), %r13
- movq saved_context_r14(%rip), %r14
- movq saved_context_r15(%rip), %r15
+ movw %ax, %ds
+
+ /* We don't restore %rax, it must be 0 anyway */
+ movq $saved_context, %rax
+ movq saved_context_cr4(%rax), %rbx
+ movq %rbx, %cr4
+ movq saved_context_cr3(%rax), %rbx
+ movq %rbx, %cr3
+ movq saved_context_cr2(%rax), %rbx
+ movq %rbx, %cr2
+ movq saved_context_cr0(%rax), %rbx
+ movq %rbx, %cr0
+ pushq saved_context_rflags(%rax)
+ popfq
+ movq saved_context_rsp(%rax), %rsp
+ movq saved_context_rbp(%rax), %rbp
+ movq saved_context_rsi(%rax), %rsi
+ movq saved_context_rdi(%rax), %rdi
+ movq saved_context_rbx(%rax), %rbx
+ movq saved_context_rcx(%rax), %rcx
+ movq saved_context_rdx(%rax), %rdx
+ movq saved_context_r8(%rax), %r8
+ movq saved_context_r9(%rax), %r9
+ movq saved_context_r10(%rax), %r10
+ movq saved_context_r11(%rax), %r11
+ movq saved_context_r12(%rax), %r12
+ movq saved_context_r13(%rax), %r13
+ movq saved_context_r14(%rax), %r14
+ movq saved_context_r15(%rax), %r15
xorl %eax, %eax
addq $8, %rsp
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [discuss] [PATCH] x86_64: Save registers in saved_context during suspend and hibernation
2007-08-13 22:52 ` Andi Kleen
@ 2007-08-13 22:26 ` Rafael J. Wysocki
2007-08-14 17:27 ` Rafael J. Wysocki
0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2007-08-13 22:26 UTC (permalink / raw)
To: Andi Kleen; +Cc: discuss, pm list, Pavel Machek
On Tuesday, 14 August 2007 00:52, Andi Kleen wrote:
> On Mon, Aug 13, 2007 at 11:47:06PM +0200, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rjw@sisk.pl>
> >
> > During hibernation and suspend on x86_64 save CPU registers in the saved_context
> > structure rather than in a handful of separate variables.
>
> Nice. These variables always annoyed me too when looking
> at that code.
>
> > DEFINE(pbe_next, offsetof(struct pbe, next));
> > BLANK();
> > + DEFINE(saved_context_rbx, offsetof(struct saved_context, rbx));
>
> But is there a reason you can't just use a pt_regs and then an array
> for the crNs ?
Hm, I think I can use pt_regs. I'll try to redo the patch to use it.
OTOH, crNs already are members of saved_context and are accessed from C.
I wouldn't like to change that code.
Greetings,
Rafael
--
"Premature optimization is the root of all evil." - Donald Knuth
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86_64: Save registers in saved_context during suspend and hibernation
2007-08-13 21:47 [PATCH] x86_64: Save registers in saved_context during suspend and hibernation Rafael J. Wysocki
@ 2007-08-13 22:52 ` Andi Kleen
2007-08-13 22:26 ` [discuss] " Rafael J. Wysocki
0 siblings, 1 reply; 5+ messages in thread
From: Andi Kleen @ 2007-08-13 22:52 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: discuss, pm list, Andi Kleen, Pavel Machek
On Mon, Aug 13, 2007 at 11:47:06PM +0200, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> During hibernation and suspend on x86_64 save CPU registers in the saved_context
> structure rather than in a handful of separate variables.
Nice. These variables always annoyed me too when looking
at that code.
> DEFINE(pbe_next, offsetof(struct pbe, next));
> BLANK();
> + DEFINE(saved_context_rbx, offsetof(struct saved_context, rbx));
But is there a reason you can't just use a pt_regs and then an array
for the crNs ?
-Andi
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [discuss] [PATCH] x86_64: Save registers in saved_context during suspend and hibernation
2007-08-13 22:26 ` [discuss] " Rafael J. Wysocki
@ 2007-08-14 17:27 ` Rafael J. Wysocki
2007-08-14 19:06 ` Pavel Machek
0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2007-08-14 17:27 UTC (permalink / raw)
To: Andi Kleen; +Cc: discuss, pm list, Pavel Machek
On Tuesday, 14 August 2007 00:26, Rafael J. Wysocki wrote:
> On Tuesday, 14 August 2007 00:52, Andi Kleen wrote:
> > On Mon, Aug 13, 2007 at 11:47:06PM +0200, Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rjw@sisk.pl>
> > >
> > > During hibernation and suspend on x86_64 save CPU registers in the saved_context
> > > structure rather than in a handful of separate variables.
> >
> > Nice. These variables always annoyed me too when looking
> > at that code.
> >
> > > DEFINE(pbe_next, offsetof(struct pbe, next));
> > > BLANK();
> > > + DEFINE(saved_context_rbx, offsetof(struct saved_context, rbx));
> >
> > But is there a reason you can't just use a pt_regs and then an array
> > for the crNs ?
>
> Hm, I think I can use pt_regs. I'll try to redo the patch to use it.
The updated patch (using pt_regs) is appended.
Greetings,
Rafael
---
From: Rafael J. Wysocki <rjw@sisk.pl>
During hibernation and suspend on x86_64 save CPU registers in the saved_context
structure rather than in a handful of separate variables.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
arch/x86_64/kernel/acpi/wakeup.S | 101 ++++++++++++++++++++-------------------
arch/x86_64/kernel/asm-offsets.c | 28 ++++++++++
arch/x86_64/kernel/suspend.c | 6 --
arch/x86_64/kernel/suspend_asm.S | 72 ++++++++++++++-------------
include/asm-x86_64/suspend.h | 23 ++------
5 files changed, 125 insertions(+), 105 deletions(-)
Index: linux-2.6.23-rc3/arch/x86_64/kernel/asm-offsets.c
===================================================================
--- linux-2.6.23-rc3.orig/arch/x86_64/kernel/asm-offsets.c 2007-08-14 00:12:16.000000000 +0200
+++ linux-2.6.23-rc3/arch/x86_64/kernel/asm-offsets.c 2007-08-14 00:48:19.000000000 +0200
@@ -76,6 +76,34 @@ int main(void)
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
BLANK();
+#define ENTRY(entry) DEFINE(pt_regs_ ## entry, offsetof(struct pt_regs, entry))
+ ENTRY(rbx);
+ ENTRY(rbx);
+ ENTRY(rcx);
+ ENTRY(rdx);
+ ENTRY(rsp);
+ ENTRY(rbp);
+ ENTRY(rsi);
+ ENTRY(rdi);
+ ENTRY(r8);
+ ENTRY(r9);
+ ENTRY(r10);
+ ENTRY(r11);
+ ENTRY(r12);
+ ENTRY(r13);
+ ENTRY(r14);
+ ENTRY(r15);
+ ENTRY(eflags);
+ BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(saved_context_ ## entry, offsetof(struct saved_context, entry))
+ ENTRY(cr0);
+ ENTRY(cr2);
+ ENTRY(cr3);
+ ENTRY(cr4);
+ ENTRY(cr8);
+ BLANK();
+#undef ENTRY
DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
BLANK();
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
Index: linux-2.6.23-rc3/include/asm-x86_64/suspend.h
===================================================================
--- linux-2.6.23-rc3.orig/include/asm-x86_64/suspend.h 2007-08-14 00:40:49.000000000 +0200
+++ linux-2.6.23-rc3/include/asm-x86_64/suspend.h 2007-08-14 00:50:43.000000000 +0200
@@ -3,6 +3,9 @@
* Based on code
* Copyright 2001 Patrick Mochel <mochel@osdl.org>
*/
+#ifndef __ASM_X86_64_SUSPEND_H
+#define __ASM_X86_64_SUSPEND_H
+
#include <asm/desc.h>
#include <asm/i387.h>
@@ -12,8 +15,9 @@ arch_prepare_suspend(void)
return 0;
}
-/* Image of the saved processor state. If you touch this, fix acpi_wakeup.S. */
+/* Image of the saved processor state. If you touch this, fix acpi/wakeup.S. */
struct saved_context {
+ struct pt_regs regs;
u16 ds, es, fs, gs, ss;
unsigned long gs_base, gs_kernel_base, fs_base;
unsigned long cr0, cr2, cr3, cr4, cr8;
@@ -29,27 +33,14 @@ struct saved_context {
unsigned long tr;
unsigned long safety;
unsigned long return_address;
- unsigned long eflags;
} __attribute__((packed));
-/* We'll access these from assembly, so we'd better have them outside struct */
-extern unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
-extern unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
-extern unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
-extern unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
-extern unsigned long saved_context_eflags;
-
#define loaddebug(thread,register) \
set_debugreg((thread)->debugreg##register, register)
extern void fix_processor_context(void);
-extern unsigned long saved_rip;
-extern unsigned long saved_rsp;
-extern unsigned long saved_rbp;
-extern unsigned long saved_rbx;
-extern unsigned long saved_rsi;
-extern unsigned long saved_rdi;
-
/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
+
+#endif /* __ASM_X86_64_SUSPEND_H */
Index: linux-2.6.23-rc3/arch/x86_64/kernel/suspend.c
===================================================================
--- linux-2.6.23-rc3.orig/arch/x86_64/kernel/suspend.c 2007-08-14 00:40:36.000000000 +0200
+++ linux-2.6.23-rc3/arch/x86_64/kernel/suspend.c 2007-08-14 00:41:28.000000000 +0200
@@ -19,12 +19,6 @@ extern const void __nosave_begin, __nosa
struct saved_context saved_context;
-unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
-unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
-unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
-unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
-unsigned long saved_context_eflags;
-
void __save_processor_state(struct saved_context *ctxt)
{
kernel_fpu_begin();
Index: linux-2.6.23-rc3/arch/x86_64/kernel/suspend_asm.S
===================================================================
--- linux-2.6.23-rc3.orig/arch/x86_64/kernel/suspend_asm.S 2007-08-14 00:12:16.000000000 +0200
+++ linux-2.6.23-rc3/arch/x86_64/kernel/suspend_asm.S 2007-08-14 00:52:45.000000000 +0200
@@ -17,24 +17,24 @@
#include <asm/asm-offsets.h>
ENTRY(swsusp_arch_suspend)
-
- movq %rsp, saved_context_esp(%rip)
- movq %rax, saved_context_eax(%rip)
- movq %rbx, saved_context_ebx(%rip)
- movq %rcx, saved_context_ecx(%rip)
- movq %rdx, saved_context_edx(%rip)
- movq %rbp, saved_context_ebp(%rip)
- movq %rsi, saved_context_esi(%rip)
- movq %rdi, saved_context_edi(%rip)
- movq %r8, saved_context_r08(%rip)
- movq %r9, saved_context_r09(%rip)
- movq %r10, saved_context_r10(%rip)
- movq %r11, saved_context_r11(%rip)
- movq %r12, saved_context_r12(%rip)
- movq %r13, saved_context_r13(%rip)
- movq %r14, saved_context_r14(%rip)
- movq %r15, saved_context_r15(%rip)
- pushfq ; popq saved_context_eflags(%rip)
+ movq $saved_context, %rax
+ movq %rsp, pt_regs_rsp(%rax)
+ movq %rbp, pt_regs_rbp(%rax)
+ movq %rsi, pt_regs_rsi(%rax)
+ movq %rdi, pt_regs_rdi(%rax)
+ movq %rbx, pt_regs_rbx(%rax)
+ movq %rcx, pt_regs_rcx(%rax)
+ movq %rdx, pt_regs_rdx(%rax)
+ movq %r8, pt_regs_r8(%rax)
+ movq %r9, pt_regs_r9(%rax)
+ movq %r10, pt_regs_r10(%rax)
+ movq %r11, pt_regs_r11(%rax)
+ movq %r12, pt_regs_r12(%rax)
+ movq %r13, pt_regs_r13(%rax)
+ movq %r14, pt_regs_r14(%rax)
+ movq %r15, pt_regs_r15(%rax)
+ pushfq
+ popq pt_regs_eflags(%rax)
call swsusp_save
ret
@@ -87,23 +87,25 @@ done:
movl $24, %eax
movl %eax, %ds
- movq saved_context_esp(%rip), %rsp
- movq saved_context_ebp(%rip), %rbp
- /* Don't restore %rax, it must be 0 anyway */
- movq saved_context_ebx(%rip), %rbx
- movq saved_context_ecx(%rip), %rcx
- movq saved_context_edx(%rip), %rdx
- movq saved_context_esi(%rip), %rsi
- movq saved_context_edi(%rip), %rdi
- movq saved_context_r08(%rip), %r8
- movq saved_context_r09(%rip), %r9
- movq saved_context_r10(%rip), %r10
- movq saved_context_r11(%rip), %r11
- movq saved_context_r12(%rip), %r12
- movq saved_context_r13(%rip), %r13
- movq saved_context_r14(%rip), %r14
- movq saved_context_r15(%rip), %r15
- pushq saved_context_eflags(%rip) ; popfq
+ /* We don't restore %rax, it must be 0 anyway */
+ movq $saved_context, %rax
+ movq pt_regs_rsp(%rax), %rsp
+ movq pt_regs_rbp(%rax), %rbp
+ movq pt_regs_rsi(%rax), %rsi
+ movq pt_regs_rdi(%rax), %rdi
+ movq pt_regs_rbx(%rax), %rbx
+ movq pt_regs_rcx(%rax), %rcx
+ movq pt_regs_rdx(%rax), %rdx
+ movq pt_regs_r8(%rax), %r8
+ movq pt_regs_r9(%rax), %r9
+ movq pt_regs_r10(%rax), %r10
+ movq pt_regs_r11(%rax), %r11
+ movq pt_regs_r12(%rax), %r12
+ movq pt_regs_r13(%rax), %r13
+ movq pt_regs_r14(%rax), %r14
+ movq pt_regs_r15(%rax), %r15
+ pushq pt_regs_eflags(%rax)
+ popfq
xorq %rax, %rax
Index: linux-2.6.23-rc3/arch/x86_64/kernel/acpi/wakeup.S
===================================================================
--- linux-2.6.23-rc3.orig/arch/x86_64/kernel/acpi/wakeup.S 2007-08-14 00:40:36.000000000 +0200
+++ linux-2.6.23-rc3/arch/x86_64/kernel/acpi/wakeup.S 2007-08-14 00:54:03.000000000 +0200
@@ -4,6 +4,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/msr.h>
+#include <asm/asm-offsets.h>
# Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
#
@@ -395,31 +396,32 @@ do_suspend_lowlevel:
xorl %eax, %eax
call save_processor_state
- movq %rsp, saved_context_esp(%rip)
- movq %rax, saved_context_eax(%rip)
- movq %rbx, saved_context_ebx(%rip)
- movq %rcx, saved_context_ecx(%rip)
- movq %rdx, saved_context_edx(%rip)
- movq %rbp, saved_context_ebp(%rip)
- movq %rsi, saved_context_esi(%rip)
- movq %rdi, saved_context_edi(%rip)
- movq %r8, saved_context_r08(%rip)
- movq %r9, saved_context_r09(%rip)
- movq %r10, saved_context_r10(%rip)
- movq %r11, saved_context_r11(%rip)
- movq %r12, saved_context_r12(%rip)
- movq %r13, saved_context_r13(%rip)
- movq %r14, saved_context_r14(%rip)
- movq %r15, saved_context_r15(%rip)
- pushfq ; popq saved_context_eflags(%rip)
+ movq $saved_context, %rax
+ movq %rsp, pt_regs_rsp(%rax)
+ movq %rbp, pt_regs_rbp(%rax)
+ movq %rsi, pt_regs_rsi(%rax)
+ movq %rdi, pt_regs_rdi(%rax)
+ movq %rbx, pt_regs_rbx(%rax)
+ movq %rcx, pt_regs_rcx(%rax)
+ movq %rdx, pt_regs_rdx(%rax)
+ movq %r8, pt_regs_r8(%rax)
+ movq %r9, pt_regs_r9(%rax)
+ movq %r10, pt_regs_r10(%rax)
+ movq %r11, pt_regs_r11(%rax)
+ movq %r12, pt_regs_r12(%rax)
+ movq %r13, pt_regs_r13(%rax)
+ movq %r14, pt_regs_r14(%rax)
+ movq %r15, pt_regs_r15(%rax)
+ pushfq
+ popq pt_regs_eflags(%rax)
movq $.L97, saved_rip(%rip)
- movq %rsp,saved_rsp
- movq %rbp,saved_rbp
- movq %rbx,saved_rbx
- movq %rdi,saved_rdi
- movq %rsi,saved_rsi
+ movq %rsp, saved_rsp
+ movq %rbp, saved_rbp
+ movq %rbx, saved_rbx
+ movq %rdi, saved_rdi
+ movq %rsi, saved_rsi
addq $8, %rsp
movl $3, %edi
@@ -430,32 +432,35 @@ do_suspend_lowlevel:
.L99:
.align 4
movl $24, %eax
- movw %ax, %ds
- movq saved_context+58(%rip), %rax
- movq %rax, %cr4
- movq saved_context+50(%rip), %rax
- movq %rax, %cr3
- movq saved_context+42(%rip), %rax
- movq %rax, %cr2
- movq saved_context+34(%rip), %rax
- movq %rax, %cr0
- pushq saved_context_eflags(%rip) ; popfq
- movq saved_context_esp(%rip), %rsp
- movq saved_context_ebp(%rip), %rbp
- movq saved_context_eax(%rip), %rax
- movq saved_context_ebx(%rip), %rbx
- movq saved_context_ecx(%rip), %rcx
- movq saved_context_edx(%rip), %rdx
- movq saved_context_esi(%rip), %rsi
- movq saved_context_edi(%rip), %rdi
- movq saved_context_r08(%rip), %r8
- movq saved_context_r09(%rip), %r9
- movq saved_context_r10(%rip), %r10
- movq saved_context_r11(%rip), %r11
- movq saved_context_r12(%rip), %r12
- movq saved_context_r13(%rip), %r13
- movq saved_context_r14(%rip), %r14
- movq saved_context_r15(%rip), %r15
+ movw %ax, %ds
+
+ /* We don't restore %rax, it must be 0 anyway */
+ movq $saved_context, %rax
+ movq saved_context_cr4(%rax), %rbx
+ movq %rbx, %cr4
+ movq saved_context_cr3(%rax), %rbx
+ movq %rbx, %cr3
+ movq saved_context_cr2(%rax), %rbx
+ movq %rbx, %cr2
+ movq saved_context_cr0(%rax), %rbx
+ movq %rbx, %cr0
+ pushq pt_regs_eflags(%rax)
+ popfq
+ movq pt_regs_rsp(%rax), %rsp
+ movq pt_regs_rbp(%rax), %rbp
+ movq pt_regs_rsi(%rax), %rsi
+ movq pt_regs_rdi(%rax), %rdi
+ movq pt_regs_rbx(%rax), %rbx
+ movq pt_regs_rcx(%rax), %rcx
+ movq pt_regs_rdx(%rax), %rdx
+ movq pt_regs_r8(%rax), %r8
+ movq pt_regs_r9(%rax), %r9
+ movq pt_regs_r10(%rax), %r10
+ movq pt_regs_r11(%rax), %r11
+ movq pt_regs_r12(%rax), %r12
+ movq pt_regs_r13(%rax), %r13
+ movq pt_regs_r14(%rax), %r14
+ movq pt_regs_r15(%rax), %r15
xorl %eax, %eax
addq $8, %rsp
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [discuss] [PATCH] x86_64: Save registers in saved_context during suspend and hibernation
2007-08-14 17:27 ` Rafael J. Wysocki
@ 2007-08-14 19:06 ` Pavel Machek
0 siblings, 0 replies; 5+ messages in thread
From: Pavel Machek @ 2007-08-14 19:06 UTC (permalink / raw)
To: Rafael J. Wysocki; +Cc: discuss, pm list, Andi Kleen
Hi!
> > > Nice. These variables always annoyed me too when looking
> > > at that code.
> > >
> > > > DEFINE(pbe_next, offsetof(struct pbe, next));
> > > > BLANK();
> > > > + DEFINE(saved_context_rbx, offsetof(struct saved_context, rbx));
> > >
> > > But is there a reason you can't just use a pt_regs and then an array
> > > for the crNs ?
> >
> > Hm, I think I can use pt_regs. I'll try to redo the patch to use it.
>
> The updated patch (using pt_regs) is appended.
Looks ok to me.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-08-14 19:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-13 21:47 [PATCH] x86_64: Save registers in saved_context during suspend and hibernation Rafael J. Wysocki
2007-08-13 22:52 ` Andi Kleen
2007-08-13 22:26 ` [discuss] " Rafael J. Wysocki
2007-08-14 17:27 ` Rafael J. Wysocki
2007-08-14 19:06 ` Pavel Machek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox