diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-26 18:02:34 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-26 18:06:22 -0400 |
commit | 73201dbec64aebf6b0dca855b523f437972dc7bb (patch) | |
tree | fdedca7d530ffda4fcb53cb084ad993555c2f948 /arch/x86/realmode | |
parent | 5a5a51db78ef24aa61a4cb2ae36f07f6fa37356d (diff) |
x86, suspend: On wakeup always initialize cr4 and EFER
We already have a flag word to indicate the existence of MISC_ENABLES,
so use the same flag word to indicate existence of cr4 and EFER, and
always restore them if they exist. That way if something passes a
nonzero value when the value *should* be zero, we will still
initialize it.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Link: http://lkml.kernel.org/r/1348529239-17943-1-git-send-email-hpa@linux.intel.com
Diffstat (limited to 'arch/x86/realmode')
-rw-r--r-- | arch/x86/realmode/rm/wakeup.h | 2 | ||||
-rw-r--r-- | arch/x86/realmode/rm/wakeup_asm.S | 29 |
2 files changed, 21 insertions, 10 deletions
diff --git a/arch/x86/realmode/rm/wakeup.h b/arch/x86/realmode/rm/wakeup.h index 9317e0042f24..7dd86a419f5d 100644 --- a/arch/x86/realmode/rm/wakeup.h +++ b/arch/x86/realmode/rm/wakeup.h | |||
@@ -36,5 +36,7 @@ extern struct wakeup_header wakeup_header; | |||
36 | 36 | ||
37 | /* Wakeup behavior bits */ | 37 | /* Wakeup behavior bits */ |
38 | #define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 | 38 | #define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 |
39 | #define WAKEUP_BEHAVIOR_RESTORE_CR4 1 | ||
40 | #define WAKEUP_BEHAVIOR_RESTORE_EFER 2 | ||
39 | 41 | ||
40 | #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ | 42 | #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ |
diff --git a/arch/x86/realmode/rm/wakeup_asm.S b/arch/x86/realmode/rm/wakeup_asm.S index 8905166b0bbb..e56479e58053 100644 --- a/arch/x86/realmode/rm/wakeup_asm.S +++ b/arch/x86/realmode/rm/wakeup_asm.S | |||
@@ -74,9 +74,18 @@ ENTRY(wakeup_start) | |||
74 | 74 | ||
75 | lidtl wakeup_idt | 75 | lidtl wakeup_idt |
76 | 76 | ||
77 | /* Clear the EFLAGS */ | 77 | /* Clear the EFLAGS but remember if we have EFLAGS.ID */ |
78 | pushl $0 | 78 | movl $X86_EFLAGS_ID, %ecx |
79 | pushl %ecx | ||
79 | popfl | 80 | popfl |
81 | pushfl | ||
82 | popl %edi | ||
83 | pushl $0 | ||
84 | popfl | ||
85 | pushfl | ||
86 | popl %edx | ||
87 | xorl %edx, %edi | ||
88 | andl %ecx, %edi /* %edi is zero iff CPUID & %cr4 are missing */ | ||
80 | 89 | ||
81 | /* Check header signature... */ | 90 | /* Check header signature... */ |
82 | movl signature, %eax | 91 | movl signature, %eax |
@@ -93,8 +102,8 @@ ENTRY(wakeup_start) | |||
93 | 102 | ||
94 | /* Restore MISC_ENABLE before entering protected mode, in case | 103 | /* Restore MISC_ENABLE before entering protected mode, in case |
95 | BIOS decided to clear XD_DISABLE during S3. */ | 104 | BIOS decided to clear XD_DISABLE during S3. */ |
96 | movl pmode_behavior, %eax | 105 | movl pmode_behavior, %edi |
97 | btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax | 106 | btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %edi |
98 | jnc 1f | 107 | jnc 1f |
99 | 108 | ||
100 | movl pmode_misc_en, %eax | 109 | movl pmode_misc_en, %eax |
@@ -110,15 +119,15 @@ ENTRY(wakeup_start) | |||
110 | movl pmode_cr3, %eax | 119 | movl pmode_cr3, %eax |
111 | movl %eax, %cr3 | 120 | movl %eax, %cr3 |
112 | 121 | ||
113 | movl pmode_cr4, %ecx | 122 | btl $WAKEUP_BEHAVIOR_RESTORE_CR4, %edi |
114 | jecxz 1f | 123 | jz 1f |
115 | movl %ecx, %cr4 | 124 | movl pmode_cr4, %eax |
125 | movl %eax, %cr4 | ||
116 | 1: | 126 | 1: |
127 | btl $WAKEUP_BEHAVIOR_RESTORE_EFER, %edi | ||
128 | jz 1f | ||
117 | movl pmode_efer, %eax | 129 | movl pmode_efer, %eax |
118 | movl pmode_efer + 4, %edx | 130 | movl pmode_efer + 4, %edx |
119 | movl %eax, %ecx | ||
120 | orl %edx, %ecx | ||
121 | jz 1f | ||
122 | movl $MSR_EFER, %ecx | 131 | movl $MSR_EFER, %ecx |
123 | wrmsr | 132 | wrmsr |
124 | 1: | 133 | 1: |