Skip to content

Commit b677dfa

Browse files
huangweiKAGA-KOKO
authored andcommitted
x86/boot/compressed/64: Set EFER.LME=1 in 32-bit trampoline before returning to long mode
In some old AMD KVM implementation, guest's EFER.LME bit is cleared by KVM when the hypervsior detects that the guest sets CR0.PG to 0. This causes the guest OS to reboot when it tries to return from 32-bit trampoline code because the CPU is in incorrect state: CR4.PAE=1, CR0.PG=1, CS.L=1, but EFER.LME=0. As a precaution, set EFER.LME=1 as part of long mode activation procedure. This extra step won't cause any harm when Linux is booted on a bare-metal machine. Signed-off-by: Wei Huang <wei@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: bp@alien8.de Cc: hpa@zytor.com Link: https://lkml.kernel.org/r/20190104054411.12489-1-wei@redhat.com
1 parent 00ae831 commit b677dfa

File tree

2 files changed

+9
-1
lines changed

2 files changed

+9
-1
lines changed

arch/x86/boot/compressed/head_64.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,14 @@ ENTRY(trampoline_32bit_src)
600600
leal TRAMPOLINE_32BIT_PGTABLE_OFFSET(%ecx), %eax
601601
movl %eax, %cr3
602602
3:
603+
/* Set EFER.LME=1 as a precaution in case hypervsior pulls the rug */
604+
pushl %ecx
605+
movl $MSR_EFER, %ecx
606+
rdmsr
607+
btsl $_EFER_LME, %eax
608+
wrmsr
609+
popl %ecx
610+
603611
/* Enable PAE and LA57 (if required) paging modes */
604612
movl $X86_CR4_PAE, %eax
605613
cmpl $0, %edx

arch/x86/boot/compressed/pgtable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0
77

88
#define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE
9-
#define TRAMPOLINE_32BIT_CODE_SIZE 0x60
9+
#define TRAMPOLINE_32BIT_CODE_SIZE 0x70
1010

1111
#define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE
1212

0 commit comments

Comments
 (0)