aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-10-23 16:37:24 -0400
committerThomas Gleixner <tglx@linutronix.de>2007-10-23 16:37:24 -0400
commit0de80bcc2baed116a569c38cbc38c5dcb945d14d (patch)
tree5eef7beda7307be2e8949f1bf0e7f84799d8ae31 /arch/x86
parentef685298b4b3dead1efa1d47cd27ced0f2673254 (diff)
x86: Save registers in saved_context during suspend and hibernation
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>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/acpi/wakeup_64.S101
-rw-r--r--arch/x86/kernel/asm-offsets_64.c28
-rw-r--r--arch/x86/kernel/suspend_64.c6
-rw-r--r--arch/x86/kernel/suspend_asm_64.S72
4 files changed, 118 insertions, 89 deletions
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S
index 55608ec2ed72..5ed3bc5c61d7 100644
--- a/arch/x86/kernel/acpi/wakeup_64.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -4,6 +4,7 @@
4#include <asm/pgtable.h> 4#include <asm/pgtable.h>
5#include <asm/page.h> 5#include <asm/page.h>
6#include <asm/msr.h> 6#include <asm/msr.h>
7#include <asm/asm-offsets.h>
7 8
8# Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2 9# Copyright 2003 Pavel Machek <pavel@suse.cz>, distribute under GPLv2
9# 10#
@@ -342,31 +343,32 @@ do_suspend_lowlevel:
342 xorl %eax, %eax 343 xorl %eax, %eax
343 call save_processor_state 344 call save_processor_state
344 345
345 movq %rsp, saved_context_esp(%rip) 346 movq $saved_context, %rax
346 movq %rax, saved_context_eax(%rip) 347 movq %rsp, pt_regs_rsp(%rax)
347 movq %rbx, saved_context_ebx(%rip) 348 movq %rbp, pt_regs_rbp(%rax)
348 movq %rcx, saved_context_ecx(%rip) 349 movq %rsi, pt_regs_rsi(%rax)
349 movq %rdx, saved_context_edx(%rip) 350 movq %rdi, pt_regs_rdi(%rax)
350 movq %rbp, saved_context_ebp(%rip) 351 movq %rbx, pt_regs_rbx(%rax)
351 movq %rsi, saved_context_esi(%rip) 352 movq %rcx, pt_regs_rcx(%rax)
352 movq %rdi, saved_context_edi(%rip) 353 movq %rdx, pt_regs_rdx(%rax)
353 movq %r8, saved_context_r08(%rip) 354 movq %r8, pt_regs_r8(%rax)
354 movq %r9, saved_context_r09(%rip) 355 movq %r9, pt_regs_r9(%rax)
355 movq %r10, saved_context_r10(%rip) 356 movq %r10, pt_regs_r10(%rax)
356 movq %r11, saved_context_r11(%rip) 357 movq %r11, pt_regs_r11(%rax)
357 movq %r12, saved_context_r12(%rip) 358 movq %r12, pt_regs_r12(%rax)
358 movq %r13, saved_context_r13(%rip) 359 movq %r13, pt_regs_r13(%rax)
359 movq %r14, saved_context_r14(%rip) 360 movq %r14, pt_regs_r14(%rax)
360 movq %r15, saved_context_r15(%rip) 361 movq %r15, pt_regs_r15(%rax)
361 pushfq ; popq saved_context_eflags(%rip) 362 pushfq
363 popq pt_regs_eflags(%rax)
362 364
363 movq $.L97, saved_rip(%rip) 365 movq $.L97, saved_rip(%rip)
364 366
365 movq %rsp,saved_rsp 367 movq %rsp, saved_rsp
366 movq %rbp,saved_rbp 368 movq %rbp, saved_rbp
367 movq %rbx,saved_rbx 369 movq %rbx, saved_rbx
368 movq %rdi,saved_rdi 370 movq %rdi, saved_rdi
369 movq %rsi,saved_rsi 371 movq %rsi, saved_rsi
370 372
371 addq $8, %rsp 373 addq $8, %rsp
372 movl $3, %edi 374 movl $3, %edi
@@ -377,32 +379,35 @@ do_suspend_lowlevel:
377.L99: 379.L99:
378 .align 4 380 .align 4
379 movl $24, %eax 381 movl $24, %eax
380 movw %ax, %ds 382 movw %ax, %ds
381 movq saved_context+58(%rip), %rax 383
382 movq %rax, %cr4 384 /* We don't restore %rax, it must be 0 anyway */
383 movq saved_context+50(%rip), %rax 385 movq $saved_context, %rax
384 movq %rax, %cr3 386 movq saved_context_cr4(%rax), %rbx
385 movq saved_context+42(%rip), %rax 387 movq %rbx, %cr4
386 movq %rax, %cr2 388 movq saved_context_cr3(%rax), %rbx
387 movq saved_context+34(%rip), %rax 389 movq %rbx, %cr3
388 movq %rax, %cr0 390 movq saved_context_cr2(%rax), %rbx
389 pushq saved_context_eflags(%rip) ; popfq 391 movq %rbx, %cr2
390 movq saved_context_esp(%rip), %rsp 392 movq saved_context_cr0(%rax), %rbx
391 movq saved_context_ebp(%rip), %rbp 393 movq %rbx, %cr0
392 movq saved_context_eax(%rip), %rax 394 pushq pt_regs_eflags(%rax)
393 movq saved_context_ebx(%rip), %rbx 395 popfq
394 movq saved_context_ecx(%rip), %rcx 396 movq pt_regs_rsp(%rax), %rsp
395 movq saved_context_edx(%rip), %rdx 397 movq pt_regs_rbp(%rax), %rbp
396 movq saved_context_esi(%rip), %rsi 398 movq pt_regs_rsi(%rax), %rsi
397 movq saved_context_edi(%rip), %rdi 399 movq pt_regs_rdi(%rax), %rdi
398 movq saved_context_r08(%rip), %r8 400 movq pt_regs_rbx(%rax), %rbx
399 movq saved_context_r09(%rip), %r9 401 movq pt_regs_rcx(%rax), %rcx
400 movq saved_context_r10(%rip), %r10 402 movq pt_regs_rdx(%rax), %rdx
401 movq saved_context_r11(%rip), %r11 403 movq pt_regs_r8(%rax), %r8
402 movq saved_context_r12(%rip), %r12 404 movq pt_regs_r9(%rax), %r9
403 movq saved_context_r13(%rip), %r13 405 movq pt_regs_r10(%rax), %r10
404 movq saved_context_r14(%rip), %r14 406 movq pt_regs_r11(%rax), %r11
405 movq saved_context_r15(%rip), %r15 407 movq pt_regs_r12(%rax), %r12
408 movq pt_regs_r13(%rax), %r13
409 movq pt_regs_r14(%rax), %r14
410 movq pt_regs_r15(%rax), %r15
406 411
407 xorl %eax, %eax 412 xorl %eax, %eax
408 addq $8, %rsp 413 addq $8, %rsp
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 778953bc636c..7e50bda565b4 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -76,6 +76,34 @@ int main(void)
76 DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); 76 DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
77 DEFINE(pbe_next, offsetof(struct pbe, next)); 77 DEFINE(pbe_next, offsetof(struct pbe, next));
78 BLANK(); 78 BLANK();
79#define ENTRY(entry) DEFINE(pt_regs_ ## entry, offsetof(struct pt_regs, entry))
80 ENTRY(rbx);
81 ENTRY(rbx);
82 ENTRY(rcx);
83 ENTRY(rdx);
84 ENTRY(rsp);
85 ENTRY(rbp);
86 ENTRY(rsi);
87 ENTRY(rdi);
88 ENTRY(r8);
89 ENTRY(r9);
90 ENTRY(r10);
91 ENTRY(r11);
92 ENTRY(r12);
93 ENTRY(r13);
94 ENTRY(r14);
95 ENTRY(r15);
96 ENTRY(eflags);
97 BLANK();
98#undef ENTRY
99#define ENTRY(entry) DEFINE(saved_context_ ## entry, offsetof(struct saved_context, entry))
100 ENTRY(cr0);
101 ENTRY(cr2);
102 ENTRY(cr3);
103 ENTRY(cr4);
104 ENTRY(cr8);
105 BLANK();
106#undef ENTRY
79 DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); 107 DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
80 BLANK(); 108 BLANK();
81 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); 109 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index bc9f59c246fd..db284ef44d53 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -19,12 +19,6 @@ extern const void __nosave_begin, __nosave_end;
19 19
20struct saved_context saved_context; 20struct saved_context saved_context;
21 21
22unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx;
23unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
24unsigned long saved_context_r08, saved_context_r09, saved_context_r10, saved_context_r11;
25unsigned long saved_context_r12, saved_context_r13, saved_context_r14, saved_context_r15;
26unsigned long saved_context_eflags;
27
28void __save_processor_state(struct saved_context *ctxt) 22void __save_processor_state(struct saved_context *ctxt)
29{ 23{
30 kernel_fpu_begin(); 24 kernel_fpu_begin();
diff --git a/arch/x86/kernel/suspend_asm_64.S b/arch/x86/kernel/suspend_asm_64.S
index 48344b666d2c..72f952103e50 100644
--- a/arch/x86/kernel/suspend_asm_64.S
+++ b/arch/x86/kernel/suspend_asm_64.S
@@ -17,24 +17,24 @@
17#include <asm/asm-offsets.h> 17#include <asm/asm-offsets.h>
18 18
19ENTRY(swsusp_arch_suspend) 19ENTRY(swsusp_arch_suspend)
20 20 movq $saved_context, %rax
21 movq %rsp, saved_context_esp(%rip) 21 movq %rsp, pt_regs_rsp(%rax)
22 movq %rax, saved_context_eax(%rip) 22 movq %rbp, pt_regs_rbp(%rax)
23 movq %rbx, saved_context_ebx(%rip) 23 movq %rsi, pt_regs_rsi(%rax)
24 movq %rcx, saved_context_ecx(%rip) 24 movq %rdi, pt_regs_rdi(%rax)
25 movq %rdx, saved_context_edx(%rip) 25 movq %rbx, pt_regs_rbx(%rax)
26 movq %rbp, saved_context_ebp(%rip) 26 movq %rcx, pt_regs_rcx(%rax)
27 movq %rsi, saved_context_esi(%rip) 27 movq %rdx, pt_regs_rdx(%rax)
28 movq %rdi, saved_context_edi(%rip) 28 movq %r8, pt_regs_r8(%rax)
29 movq %r8, saved_context_r08(%rip) 29 movq %r9, pt_regs_r9(%rax)
30 movq %r9, saved_context_r09(%rip) 30 movq %r10, pt_regs_r10(%rax)
31 movq %r10, saved_context_r10(%rip) 31 movq %r11, pt_regs_r11(%rax)
32 movq %r11, saved_context_r11(%rip) 32 movq %r12, pt_regs_r12(%rax)
33 movq %r12, saved_context_r12(%rip) 33 movq %r13, pt_regs_r13(%rax)
34 movq %r13, saved_context_r13(%rip) 34 movq %r14, pt_regs_r14(%rax)
35 movq %r14, saved_context_r14(%rip) 35 movq %r15, pt_regs_r15(%rax)
36 movq %r15, saved_context_r15(%rip) 36 pushfq
37 pushfq ; popq saved_context_eflags(%rip) 37 popq pt_regs_eflags(%rax)
38 38
39 /* save the address of restore_registers */ 39 /* save the address of restore_registers */
40 movq $restore_registers, %rax 40 movq $restore_registers, %rax
@@ -113,23 +113,25 @@ ENTRY(restore_registers)
113 movq %rcx, %cr3 113 movq %rcx, %cr3
114 movq %rax, %cr4; # turn PGE back on 114 movq %rax, %cr4; # turn PGE back on
115 115
116 movq saved_context_esp(%rip), %rsp 116 /* We don't restore %rax, it must be 0 anyway */
117 movq saved_context_ebp(%rip), %rbp 117 movq $saved_context, %rax
118 /* restore GPRs (we don't restore %rax, it must be 0 anyway) */ 118 movq pt_regs_rsp(%rax), %rsp
119 movq saved_context_ebx(%rip), %rbx 119 movq pt_regs_rbp(%rax), %rbp
120 movq saved_context_ecx(%rip), %rcx 120 movq pt_regs_rsi(%rax), %rsi
121 movq saved_context_edx(%rip), %rdx 121 movq pt_regs_rdi(%rax), %rdi
122 movq saved_context_esi(%rip), %rsi 122 movq pt_regs_rbx(%rax), %rbx
123 movq saved_context_edi(%rip), %rdi 123 movq pt_regs_rcx(%rax), %rcx
124 movq saved_context_r08(%rip), %r8 124 movq pt_regs_rdx(%rax), %rdx
125 movq saved_context_r09(%rip), %r9 125 movq pt_regs_r8(%rax), %r8
126 movq saved_context_r10(%rip), %r10 126 movq pt_regs_r9(%rax), %r9
127 movq saved_context_r11(%rip), %r11 127 movq pt_regs_r10(%rax), %r10
128 movq saved_context_r12(%rip), %r12 128 movq pt_regs_r11(%rax), %r11
129 movq saved_context_r13(%rip), %r13 129 movq pt_regs_r12(%rax), %r12
130 movq saved_context_r14(%rip), %r14 130 movq pt_regs_r13(%rax), %r13
131 movq saved_context_r15(%rip), %r15 131 movq pt_regs_r14(%rax), %r14
132 pushq saved_context_eflags(%rip) ; popfq 132 movq pt_regs_r15(%rax), %r15
133 pushq pt_regs_eflags(%rax)
134 popfq
133 135
134 xorq %rax, %rax 136 xorq %rax, %rax
135 137