[PATCH] x86_64: Save registers in saved_context during suspend and hibernation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Rafael J. Wysocki <rjw@xxxxxxx>

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@xxxxxxx>
---
 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@xxxxxxxx>
  */
+#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@xxxxxxx>, 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
_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux