Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Wei Huang and committed by
Thomas Gleixner
b677dfae 00ae831d

+9 -1
+8
arch/x86/boot/compressed/head_64.S
··· 600 600 leal TRAMPOLINE_32BIT_PGTABLE_OFFSET(%ecx), %eax 601 601 movl %eax, %cr3 602 602 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 + 603 611 /* Enable PAE and LA57 (if required) paging modes */ 604 612 movl $X86_CR4_PAE, %eax 605 613 cmpl $0, %edx
+1 -1
arch/x86/boot/compressed/pgtable.h
··· 6 6 #define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 7 7 8 8 #define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE 9 - #define TRAMPOLINE_32BIT_CODE_SIZE 0x60 9 + #define TRAMPOLINE_32BIT_CODE_SIZE 0x70 10 10 11 11 #define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE 12 12