Skip to content

Commit a37f269

Browse files
tlendackyhansendc
authored andcommitted
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. Commit bcce829 ("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: bcce829 ("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
1 parent edc0a2b commit a37f269

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

arch/x86/kernel/head_64.S

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ SYM_CODE_START_NOALIGN(startup_64)
7777
call startup_64_setup_env
7878
popq %rsi
7979

80+
/* Now switch to __KERNEL_CS so IRET works reliably */
81+
pushq $__KERNEL_CS
82+
leaq .Lon_kernel_cs(%rip), %rax
83+
pushq %rax
84+
lretq
85+
86+
.Lon_kernel_cs:
87+
UNWIND_HINT_END_OF_STACK
88+
8089
#ifdef CONFIG_AMD_MEM_ENCRYPT
8190
/*
8291
* Activate SEV/SME memory encryption if supported/enabled. This needs to
@@ -90,15 +99,6 @@ SYM_CODE_START_NOALIGN(startup_64)
9099
popq %rsi
91100
#endif
92101

93-
/* Now switch to __KERNEL_CS so IRET works reliably */
94-
pushq $__KERNEL_CS
95-
leaq .Lon_kernel_cs(%rip), %rax
96-
pushq %rax
97-
lretq
98-
99-
.Lon_kernel_cs:
100-
UNWIND_HINT_END_OF_STACK
101-
102102
/* Sanitize CPU configuration */
103103
call verify_cpu
104104

0 commit comments

Comments
 (0)