BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275
Virtual Machine Privilege Level (VMPL) is an optional feature in the SEV-SNP architecture, which allows a guest VM to divide its address space into four levels. The level can be used to provide the hardware isolated abstraction layers with a VM. The VMPL0 is the highest privilege, and VMPL3 is the least privilege. Certain operations must be done by the VMPL0 software, such as: * Validate or invalidate memory range (PVALIDATE instruction) * Allocate VMSA page (RMPADJUST instruction when VMSA=1) The initial SEV-SNP support assumes that it's running on VMPL0. Let's add a check to make sure that we are running at VMPL0 before continuing the boot. There is no easy method to query the current VMPL level. One simple approach is to call PVALIDATE instruction and if the instruction causes a #GP then its SEV-SNP guest is not booted under VMPL0. See the AMD APL volume 3 (PVALIDATE) for additional information on the PVALIDATE. Cc: James Bottomley <j...@linux.ibm.com> Cc: Min Xu <min.m...@intel.com> Cc: Jiewen Yao <jiewen....@intel.com> Cc: Tom Lendacky <thomas.lenda...@amd.com> Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> Cc: Laszlo Ersek <ler...@redhat.com> Cc: Erdem Aktas <erdemak...@google.com> Signed-off-by: Brijesh Singh <brijesh.si...@amd.com> --- OvmfPkg/ResetVector/Ia32/AmdSev.asm | 89 ++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm index b6f33d049a43..a9101ca8b8b2 100644 --- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm +++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm @@ -53,6 +53,12 @@ BITS 32 ; Hypervisor does not support SEV-SNP feature %define TERM_HV_UNSUPPORTED_FEATURE 4 +; SEV-SNP guest is not launched at VMPL-0 +%define TERM_SNP_NOT_VMPL0 5 + +; The #VC is not for PVALIDATE +%define TERM_VC_NOT_PVALIDATE 6 + ; GHCB SEV Information MSR protocol %define GHCB_SEV_INFORMATION_REQUEST 2 %define GHCB_SEV_INFORMATION_RESPONSE 1 @@ -139,6 +145,25 @@ BITS 32 SevEsUnexpectedRespTerminate: TerminateVmgExit TERM_UNEXPECTED_RESP_CODE +; Check whether we're booted under the VMPL-0. +; +; There is no straightforward way to query the current VMPL level. The simplest +; method is to use the PVALIDATE instruction to change the page state. If its +; not a VMPL-0 guest then PVALIDATE will cause #GP. +; +CheckSnpVmpl0: + ; This routine is part of the ROM, and should have been validated by the SNP + ; guest launch sequence. So its safe to re-validate the page containing + ; this routine. + mov eax, ADDR_OF(CheckSnpVmpl0) + mov ecx, 0 + mov edx, 1 + PVALIDATE + + ; We will reach here only if we are running at VMPL-0. + + OneTimeCallRet CheckSnpVmpl0 + ; Check if Secure Encrypted Virtualization (SEV) features are enabled. ; ; Register usage is tight in this routine, so multiple calls for the @@ -193,6 +218,17 @@ CheckSevFeatures: bt eax, 0 jnc NoSev + ; Check if we're SEV-SNP guest and booted under VMPL-0. + ; + ; This check should happen here because the PVALIDATE instruction + ; used in the check will cause an exception. The IDT is active + ; during the CheckSevFeatures only. + ; + bt eax, 2 + jnc SkipCheckSnpVmpl0 + OneTimeCall CheckSnpVmpl0 + +SkipCheckSnpVmpl0: ; Check for SEV-ES memory encryption feature: ; CPUID Fn8000_001F[EAX] - Bit 3 ; CPUID raises a #VC exception if running as an SEV-ES guest @@ -393,6 +429,36 @@ IsSevEsEnabled: SevEsDisabled: OneTimeCallRet IsSevEsEnabled +; Start handling of #GP exception handling routines +; +SevEsIdtNotPvalidate: + TerminateVmgExit TERM_VC_NOT_PVALIDATE + iret + +SevSnpGpException: + ; + ; If we're here, then we are an SEV-SNP guest and this + ; was triggered by a PVALIDATE instruction. + ; + ; Verify that its an PVALIDATE instruction + ; The exception stack looks like this: + ; +---------+ + ; | .... | + ; | eip | + ; | err code| + ; +---------+ + pop ebx + pop ebx + mov ecx, [ebx] + cmp ecx, 0xff010ff2 ; Compare EIP with PVALIDATE menomics + jne SevEsIdtNotPvalidate + + ; The #GP was triggered by the PVALIDATE instruction, this will happen + ; only when we're not running at VMPL-0 + ; + TerminateVmgExit TERM_SNP_NOT_VMPL0 + iret + ; Start of #VC exception handling routines ; @@ -522,15 +588,34 @@ ALIGN 16 ; IDT_BASE: ; -; Vectors 0 - 28 (No handlers) +; Vectors 0 - 12 (No handlers) ; -%rep 29 +%rep 13 dw 0 ; Offset low bits 15..0 dw 0x10 ; Selector db 0 ; Reserved db 0x8E ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32) dw 0 ; Offset high bits 31..16 %endrep +; +; Vector 13 (GP Exception) +; + dw (ADDR_OF(SevSnpGpException) & 0xffff) ; Offset low bits 15..0 + dw 0x10 ; Selector + db 0 ; Reserved + db 0x8E ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32) + dw (ADDR_OF(SevSnpGpException) >> 16) ; Offset high bits 31..16 +; +; Vectors 14 - 28 (No handlers) +; +%rep 15 + dw 0 ; Offset low bits 15..0 + dw 0x10 ; Selector + db 0 ; Reserved + db 0x8E ; Gate Type (IA32_IDT_GATE_TYPE_INTERRUPT_32) + dw 0 ; Offset high bits 31..16 +%endrep + ; ; Vector 29 (VMM Communication Exception) ; -- 2.17.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#77344): https://edk2.groups.io/g/devel/message/77344 Mute This Topic: https://groups.io/mt/83891523/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-