x86/head/64: Switch to KERNEL_CS as soon as new GDT is installed
The call to startup_64_setup_env() will install a new GDT but does not actually switch to using the KERNEL_CS entry until returning from the function call. Commitbcce829083
("x86/sev: Detect/setup SEV/SME features earlier in boot") moved the call to sme_enable() earlier in the boot process and in between the call to startup_64_setup_env() and the switch to KERNEL_CS. An SEV-ES or an SEV-SNP guest will trigger #VC exceptions during the call to sme_enable() and if the CS pushed on the stack as part of the exception and used by IRETQ is not mapped by the new GDT, then problems occur. Today, the current CS when entering startup_64 is the kernel CS value because it was set up by the decompressor code, so no issue is seen. However, a recent patchset that looked to avoid using the legacy decompressor during an EFI boot exposed this bug. At entry to startup_64, the CS value is that of EFI and is not mapped in the new kernel GDT. So when a #VC exception occurs, the CS value used by IRETQ is not valid and the guest boot crashes. Fix this issue by moving the block that switches to the KERNEL_CS value to be done immediately after returning from startup_64_setup_env(). Fixes:bcce829083
("x86/sev: Detect/setup SEV/SME features earlier in boot") Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Joerg Roedel <jroedel@suse.de> Link: https://lore.kernel.org/all/6ff1f28af2829cc9aea357ebee285825f90a431f.1684340801.git.thomas.lendacky%40amd.com
This commit is contained in:
parent
edc0a2b595
commit
a37f2699c3
@ -77,6 +77,15 @@ SYM_CODE_START_NOALIGN(startup_64)
|
||||
call startup_64_setup_env
|
||||
popq %rsi
|
||||
|
||||
/* Now switch to __KERNEL_CS so IRET works reliably */
|
||||
pushq $__KERNEL_CS
|
||||
leaq .Lon_kernel_cs(%rip), %rax
|
||||
pushq %rax
|
||||
lretq
|
||||
|
||||
.Lon_kernel_cs:
|
||||
UNWIND_HINT_END_OF_STACK
|
||||
|
||||
#ifdef CONFIG_AMD_MEM_ENCRYPT
|
||||
/*
|
||||
* Activate SEV/SME memory encryption if supported/enabled. This needs to
|
||||
@ -90,15 +99,6 @@ SYM_CODE_START_NOALIGN(startup_64)
|
||||
popq %rsi
|
||||
#endif
|
||||
|
||||
/* Now switch to __KERNEL_CS so IRET works reliably */
|
||||
pushq $__KERNEL_CS
|
||||
leaq .Lon_kernel_cs(%rip), %rax
|
||||
pushq %rax
|
||||
lretq
|
||||
|
||||
.Lon_kernel_cs:
|
||||
UNWIND_HINT_END_OF_STACK
|
||||
|
||||
/* Sanitize CPU configuration */
|
||||
call verify_cpu
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user