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

Configure Feed

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

x86/fred: Fix early boot failures on SEV-ES/SNP guests

FRED-enabled SEV-(ES,SNP) guests fail to boot due to the following issues
in the early boot sequence:

* FRED does not have a #VC exception handler in the dispatch logic

* Early FRED #VC exceptions attempt to use uninitialized per-CPU GHCBs
instead of boot_ghcb

Add X86_TRAP_VC case to fred_hwexc() with a new exc_vmm_communication()
function that provides the unified entry point FRED requires, dispatching
to existing user/kernel handlers based on privilege level. The function is
already declared via DECLARE_IDTENTRY_VC().

Fix early GHCB access by falling back to boot_ghcb in
__sev_{get,put}_ghcb() when per-CPU GHCBs are not yet initialized.

Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Cc: <stable@kernel.org> # 6.12+
Link: https://patch.msgid.link/20260318075654.1792916-4-nikunj@amd.com

authored by

Nikunj A Dadhania and committed by
Borislav Petkov (AMD)
3645eb7e 411df123

+20
+6
arch/x86/coco/sev/noinstr.c
··· 121 121 122 122 WARN_ON(!irqs_disabled()); 123 123 124 + if (!sev_cfg.ghcbs_initialized) 125 + return boot_ghcb; 126 + 124 127 data = this_cpu_read(runtime_data); 125 128 ghcb = &data->ghcb_page; 126 129 ··· 166 163 struct ghcb *ghcb; 167 164 168 165 WARN_ON(!irqs_disabled()); 166 + 167 + if (!sev_cfg.ghcbs_initialized) 168 + return; 169 169 170 170 data = this_cpu_read(runtime_data); 171 171 ghcb = &data->ghcb_page;
+14
arch/x86/entry/entry_fred.c
··· 177 177 } 178 178 } 179 179 180 + #ifdef CONFIG_AMD_MEM_ENCRYPT 181 + noinstr void exc_vmm_communication(struct pt_regs *regs, unsigned long error_code) 182 + { 183 + if (user_mode(regs)) 184 + return user_exc_vmm_communication(regs, error_code); 185 + else 186 + return kernel_exc_vmm_communication(regs, error_code); 187 + } 188 + #endif 189 + 180 190 static noinstr void fred_hwexc(struct pt_regs *regs, unsigned long error_code) 181 191 { 182 192 /* Optimize for #PF. That's the only exception which matters performance wise */ ··· 217 207 #ifdef CONFIG_X86_CET 218 208 case X86_TRAP_CP: return exc_control_protection(regs, error_code); 219 209 #endif 210 + #ifdef CONFIG_AMD_MEM_ENCRYPT 211 + case X86_TRAP_VC: return exc_vmm_communication(regs, error_code); 212 + #endif 213 + 220 214 default: return fred_bad_type(regs, error_code); 221 215 } 222 216