Commit ea110474 authored by Venkatesh Pallipadi's avatar Venkatesh Pallipadi Committed by Linus Torvalds

[PATCH] S3 suspend/resume with noexec v2

This patch is required for S3 suspend-resume on noexec capable systems.  On
these systems, we need to save and restore MSR_EFER during S3
suspend-resume.
Signed-off-by: default avatar"Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 57f1f1ac
......@@ -59,6 +59,14 @@ wakeup_code:
movl $swapper_pg_dir-__PAGE_OFFSET, %eax
movl %eax, %cr3
testl $1, real_efer_save_restore - wakeup_code
jz 4f
# restore efer setting
movl real_save_efer_edx - wakeup_code, %edx
movl real_save_efer_eax - wakeup_code, %eax
mov $0xc0000080, %ecx
wrmsr
4:
# make sure %cr4 is set correctly (features, etc)
movl real_save_cr4 - wakeup_code, %eax
movl %eax, %cr4
......@@ -89,6 +97,9 @@ real_save_cr4: .long 0
real_magic: .long 0
video_mode: .long 0
video_flags: .long 0
real_efer_save_restore: .long 0
real_save_efer_edx: .long 0
real_save_efer_eax: .long 0
bogus_real_magic:
movw $0x0e00 + 'B', %fs:(0x12)
......@@ -223,6 +234,20 @@ ENTRY(acpi_copy_wakeup_routine)
sldt saved_ldt
str saved_tss
movl nx_enabled, %edx
movl %edx, real_efer_save_restore - wakeup_start (%eax)
testl $1, real_efer_save_restore - wakeup_start (%eax)
jz 2f
# save efer setting
pushl %eax
movl %eax, %ebx
mov $0xc0000080, %ecx
rdmsr
movl %edx, real_save_efer_edx - wakeup_start (%ebx)
movl %eax, real_save_efer_eax - wakeup_start (%ebx)
popl %eax
2:
movl %cr3, %edx
movl %edx, real_save_cr3 - wakeup_start (%eax)
movl %cr4, %edx
......
......@@ -438,8 +438,8 @@ static int __init noexec_setup(char *str)
__setup("noexec=", noexec_setup);
#ifdef CONFIG_X86_PAE
int nx_enabled = 0;
#ifdef CONFIG_X86_PAE
static void __init set_nx(void)
{
......
......@@ -39,9 +39,9 @@
/*
* These are used to make use of C type-checking..
*/
extern int nx_enabled;
#ifdef CONFIG_X86_PAE
extern unsigned long long __supported_pte_mask;
extern int nx_enabled;
typedef struct { unsigned long pte_low, pte_high; } pte_t;
typedef struct { unsigned long long pmd; } pmd_t;
typedef struct { unsigned long long pgd; } pgd_t;
......@@ -49,7 +49,6 @@ typedef struct { unsigned long long pgprot; } pgprot_t;
#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
#define HPAGE_SHIFT 21
#else
#define nx_enabled 0
typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
......
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