CVSROOT: /cvs Module name: src Changes by: bl...@cvs.openbsd.org 2025/06/23 05:33:39
Modified files: sys/arch/amd64/amd64: locore0.S sys/arch/amd64/include: ghcb.h trap.h vmmvar.h Log message: In locore0 handle #VC trap for AMD SEV-ES guest. When locore is executed by a SEV-ES enabled guest, the first CPUID instruction will raise a #VC trap that must be handled. However, at that point in time the guest does not know whether it is a guest at all, if it is running on an AMD CPU, if SEV-ES is enabled, etc. To resolve this chicken-egg situation, undconditionally setup a #VC trap handler. If we are not a SEV-ES enabled guest, or we are running on some non-AMD CPU, it will not raise #VC (hopefully). On Intel CPUs the vector for #VC is reserved. As vmd(8) configures the runtime for locore0 to be in 32 bit compatibility mode, a raised #VC exception will switch to long mode. Then the CPU will expect a 64 bit entry in the IDT. When running on KVM/qemu, locore0 is execute in 32 bit legacy mode. There the CPU will expect a 32 bit entry in the IDT. To accommodate both situations, set up both 64 and 32 bit handler in the IDT. Additionally, vmd(8) has to setup a long mode segment in the GDT. Both #VC trap handler use the MSR protocol to talk to the hypervisor to emulate CPUID. The MSR protocol only supports "simple" CPUID without subfunctions. Note: When SEV-ES is enabled, the hypervisor can not intercept writes to EFER beforehand, only after the write. Thus on vmm(4) with directly executed kernel, we are in compatibility mode and EFER_LMA is set. As resetting EFER_LMA raises #GP, we have to preserve it. from hshoexer@; OK mlarkin@