x86: Save registers in saved_context during suspend and hibernation
authorRafael J. Wysocki <rjw@sisk.pl>
Tue, 23 Oct 2007 20:37:24 +0000 (22:37 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 23 Oct 2007 20:37:24 +0000 (22:37 +0200)
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>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/kernel/acpi/wakeup_64.S
arch/x86/kernel/asm-offsets_64.c
arch/x86/kernel/suspend_64.c
arch/x86/kernel/suspend_asm_64.S
include/asm-x86/suspend_64.h

index 55608ec2ed721dff6e0cd9c705e628763bfea039..5ed3bc5c61d78d76ce9ddbacca5254372db56b6a 100644 (file)
@@ -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
 #
@@ -342,31 +343,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
@@ -377,32 +379,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
index 778953bc636c4b5d29872063626d7ffa781ad659..7e50bda565b4ac09907b07d09ca4e0586d29ce44 100644 (file)
@@ -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 bc9f59c246fd99890da74eec868d92cc3f8f7f2b..db284ef44d536a65850d7d0e10a1e2f3de9847c0 100644 (file)
@@ -19,12 +19,6 @@ extern const void __nosave_begin, __nosave_end;
 
 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 48344b666d2c2e60f56d3393d82ecc48e0b9388f..72f952103e50252f025c62232bf86b0b8b55d4a1 100644 (file)
 #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)
 
        /* save the address of restore_registers */
        movq    $restore_registers, %rax
@@ -113,23 +113,25 @@ ENTRY(restore_registers)
        movq    %rcx, %cr3
        movq    %rax, %cr4;  # turn PGE back on
 
-       movq saved_context_esp(%rip), %rsp
-       movq saved_context_ebp(%rip), %rbp
-       /* restore GPRs (we 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 9440a7a1b99ab55fdb38e70333cdcdf9bc83e1d0..c505a76bcf6e93862b9e77dcccbe3afa02b14629 100644 (file)
@@ -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,29 +33,16 @@ 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);
 extern char core_restore_code;
 extern char restore_registers;
+
+#endif /* __ASM_X86_64_SUSPEND_H */