Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73201dbe authored by H. Peter Anvin's avatar H. Peter Anvin
Browse files

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: default avatarH. 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
parent 5a5a51db
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -43,17 +43,22 @@ int acpi_suspend_lowlevel(void)

	header->video_mode = saved_video_mode;

	header->pmode_behavior = 0;

#ifndef CONFIG_64BIT
	store_gdt((struct desc_ptr *)&header->pmode_gdt);

	if (rdmsr_safe(MSR_EFER, &header->pmode_efer_low,
	if (!rdmsr_safe(MSR_EFER,
			&header->pmode_efer_low,
			&header->pmode_efer_high))
		header->pmode_efer_low = header->pmode_efer_high = 0;
		header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_EFER);
#endif /* !CONFIG_64BIT */

	header->pmode_cr0 = read_cr0();
	header->pmode_cr4 = read_cr4_safe();
	header->pmode_behavior = 0;
	if (__this_cpu_read(cpu_info.cpuid_level) >= 0) {
		header->pmode_cr4 = read_cr4();
		header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_CR4);
	}
	if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
			&header->pmode_misc_en_low,
			&header->pmode_misc_en_high))
+2 −0
Original line number Diff line number Diff line
@@ -36,5 +36,7 @@ extern struct wakeup_header wakeup_header;

/* Wakeup behavior bits */
#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE     0
#define WAKEUP_BEHAVIOR_RESTORE_CR4		1
#define WAKEUP_BEHAVIOR_RESTORE_EFER		2

#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
+19 −10
Original line number Diff line number Diff line
@@ -74,9 +74,18 @@ ENTRY(wakeup_start)

	lidtl	wakeup_idt

	/* Clear the EFLAGS */
	/* Clear the EFLAGS but remember if we have EFLAGS.ID */
	movl $X86_EFLAGS_ID, %ecx
	pushl %ecx
	popfl
	pushfl
	popl %edi
	pushl $0
	popfl
	pushfl
	popl %edx
	xorl %edx, %edi
	andl %ecx, %edi		/* %edi is zero iff CPUID & %cr4 are missing */

	/* Check header signature... */
	movl	signature, %eax
@@ -93,8 +102,8 @@ ENTRY(wakeup_start)

	/* Restore MISC_ENABLE before entering protected mode, in case
	   BIOS decided to clear XD_DISABLE during S3. */
	movl	pmode_behavior, %eax
	btl	$WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax
	movl	pmode_behavior, %edi
	btl	$WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %edi
	jnc	1f

	movl	pmode_misc_en, %eax
@@ -110,15 +119,15 @@ ENTRY(wakeup_start)
	movl	pmode_cr3, %eax
	movl	%eax, %cr3

	movl	pmode_cr4, %ecx
	jecxz	1f
	movl	%ecx, %cr4
	btl	$WAKEUP_BEHAVIOR_RESTORE_CR4, %edi
	jz	1f
	movl	pmode_cr4, %eax
	movl	%eax, %cr4
1:
	btl	$WAKEUP_BEHAVIOR_RESTORE_EFER, %edi
	jz	1f
	movl	pmode_efer, %eax
	movl	pmode_efer + 4, %edx
	movl	%eax, %ecx
	orl	%edx, %ecx
	jz	1f
	movl	$MSR_EFER, %ecx
	wrmsr
1: