Commit be9dc613 authored by Mikael Pettersson's avatar Mikael Pettersson Committed by Linus Torvalds

[PATCH] restore sysenter MSRs at APM resume

This changes apm.c to invoke suspend.c's save and restore processor
state procedures around suspends, which fixes the SYSENTER MSR problem.

The patch also decouples sysenter.c from SOFTWARE_SUSPEND: the variables
used (only!) in suspend_asm.S are moved there, and the include file now
declares the procedures called from apm.c (previously they were only
called from suspend_asm.S).
parent 8e68fd15
...@@ -17,7 +17,7 @@ obj-$(CONFIG_MCA) += mca.o ...@@ -17,7 +17,7 @@ obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_APM) += apm.o suspend.o
obj-$(CONFIG_X86_SMP) += smp.o smpboot.o obj-$(CONFIG_X86_SMP) += smp.o smpboot.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_MPPARSE) += mpparse.o
......
...@@ -226,6 +226,7 @@ ...@@ -226,6 +226,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/suspend.h>
#include "io_ports.h" #include "io_ports.h"
...@@ -1212,7 +1213,9 @@ static int suspend(int vetoable) ...@@ -1212,7 +1213,9 @@ static int suspend(int vetoable)
spin_unlock(&i8253_lock); spin_unlock(&i8253_lock);
write_sequnlock_irq(&xtime_lock); write_sequnlock_irq(&xtime_lock);
save_processor_state();
err = set_system_power_state(APM_STATE_SUSPEND); err = set_system_power_state(APM_STATE_SUSPEND);
restore_processor_state();
write_seqlock_irq(&xtime_lock); write_seqlock_irq(&xtime_lock);
spin_lock(&i8253_lock); spin_lock(&i8253_lock);
......
...@@ -27,9 +27,7 @@ ...@@ -27,9 +27,7 @@
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
static struct saved_context saved_context; static struct saved_context saved_context;
unsigned long saved_context_eax, saved_context_ebx, saved_context_ecx, saved_context_edx; static void fix_processor_context(void);
unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
unsigned long saved_context_eflags;
extern void enable_sep_cpu(void *); extern void enable_sep_cpu(void *);
...@@ -107,7 +105,7 @@ void restore_processor_state(void) ...@@ -107,7 +105,7 @@ void restore_processor_state(void)
do_fpu_end(); do_fpu_end();
} }
void fix_processor_context(void) static void fix_processor_context(void)
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
struct tss_struct * t = init_tss + cpu; struct tss_struct * t = init_tss + cpu;
......
...@@ -6,6 +6,28 @@ ...@@ -6,6 +6,28 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/page.h> #include <asm/page.h>
.data
saved_context_eax:
.long 0
saved_context_ebx:
.long 0
saved_context_ecx:
.long 0
saved_context_edx:
.long 0
saved_context_esp:
.long 0
saved_context_ebp:
.long 0
saved_context_esi:
.long 0
saved_context_edi:
.long 0
saved_context_eflags:
.long 0
.text
ENTRY(do_magic) ENTRY(do_magic)
pushl %ebx pushl %ebx
cmpl $0,8(%esp) cmpl $0,8(%esp)
......
...@@ -30,18 +30,14 @@ struct saved_context { ...@@ -30,18 +30,14 @@ struct saved_context {
unsigned long return_address; unsigned long return_address;
} __attribute__((packed)); } __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_eflags;
#define loaddebug(thread,register) \ #define loaddebug(thread,register) \
__asm__("movl %0,%%db" #register \ __asm__("movl %0,%%db" #register \
: /* no output */ \ : /* no output */ \
:"r" ((thread)->debugreg[register])) :"r" ((thread)->debugreg[register]))
extern void fix_processor_context(void); extern void save_processor_state(void);
extern void restore_processor_state(void);
extern void do_magic(int resume); extern void do_magic(int resume);
#ifdef CONFIG_ACPI_SLEEP #ifdef CONFIG_ACPI_SLEEP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment