From a91b700e385e7484ab7286b3ba7ea2efbd59480e Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Thu, 7 Jan 2021 12:48:11 -0600 Subject: [PATCH 1/1] Ovmf/ResetVector: Simplify and consolidate the SEV features checks BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3108 Simplify and consolidate the SEV and SEV-ES checks into a single routine. This new routine will use CPUID to check for the appropriate CPUID leaves and the required values, as well as read the non-interceptable SEV status MSR (0xc0010131) to check SEV and SEV-ES enablement. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Brijesh Singh Reviewed-by: Laszlo Ersek Signed-off-by: Tom Lendacky Message-Id: <43a660624c32b5f6c2610bf42ee39101c21aff68.1610045305.git.thomas.lendacky@amd.com> --- OvmfPkg/ResetVector/Ia32/PageTables64.asm | 75 ++++++++++++++--------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm index 7c72128a84..4032719c30 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm @@ -3,6 +3,7 @@ ; Sets the CR3 register for 64-bit paging ; ; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+; Copyright (c) 2017 - 2020, Advanced Micro Devices, Inc. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;------------------------------------------------------------------------------ @@ -62,18 +63,22 @@ BITS 32 %define CPUID_INSN_LEN 2 -; Check if Secure Encrypted Virtualization (SEV) feature is enabled +; Check if Secure Encrypted Virtualization (SEV) features are enabled. +; +; Register usage is tight in this routine, so multiple calls for the +; same CPUID and MSR data are performed to keep things simple. ; ; Modified: EAX, EBX, ECX, EDX, ESP ; ; If SEV is enabled then EAX will be at least 32. ; If SEV is disabled then EAX will be zero. ; -CheckSevFeature: +CheckSevFeatures: ; Set the first byte of the workarea to zero to communicate to the SEC ; phase that SEV-ES is not enabled. If SEV-ES is enabled, the CPUID ; instruction will trigger a #VC exception where the first byte of the - ; workarea will be set to one. + ; workarea will be set to one or, if CPUID is not being intercepted, + ; the MSR check below will set the first byte of the workarea to one. mov byte[SEV_ES_WORK_AREA], 0 ; @@ -97,21 +102,41 @@ CheckSevFeature: cmp eax, 0x8000001f jl NoSev - ; Check for memory encryption feature: + ; Check for SEV memory encryption feature: ; CPUID Fn8000_001F[EAX] - Bit 1 ; CPUID raises a #VC exception if running as an SEV-ES guest - mov eax, 0x8000001f + mov eax, 0x8000001f cpuid bt eax, 1 jnc NoSev - ; Check if memory encryption is enabled + ; Check if SEV memory encryption is enabled ; MSR_0xC0010131 - Bit 0 (SEV enabled) mov ecx, 0xc0010131 rdmsr bt eax, 0 jnc NoSev + ; 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 + mov eax, 0x8000001f + cpuid + bt eax, 3 + jnc GetSevEncBit + + ; Check if SEV-ES is enabled + ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) + mov ecx, 0xc0010131 + rdmsr + bt eax, 1 + jnc GetSevEncBit + + ; Set the first byte of the workarea to one to communicate to the SEC + ; phase that SEV-ES is enabled. + mov byte[SEV_ES_WORK_AREA], 1 + +GetSevEncBit: ; Get pte bit position to enable memory encryption ; CPUID Fn8000_001F[EBX] - Bits 5:0 ; @@ -132,45 +157,35 @@ SevExit: pop eax mov esp, 0 - OneTimeCallRet CheckSevFeature + OneTimeCallRet CheckSevFeatures ; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature ; is enabled. ; -; Modified: EAX, EBX, ECX +; Modified: EAX ; ; If SEV-ES is enabled then EAX will be non-zero. ; If SEV-ES is disabled then EAX will be zero. ; -CheckSevEsFeature: +IsSevEsEnabled: xor eax, eax - ; SEV-ES can't be enabled if SEV isn't, so first check the encryption - ; mask. - test edx, edx - jz NoSevEs - - ; Save current value of encryption mask - mov ebx, edx - - ; Check if SEV-ES is enabled - ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) - mov ecx, 0xc0010131 - rdmsr - and eax, 2 + ; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if + ; SEV-ES is enabled. + cmp byte[SEV_ES_WORK_AREA], 1 + jne SevEsDisabled - ; Restore encryption mask - mov edx, ebx + mov eax, 1 -NoSevEs: - OneTimeCallRet CheckSevEsFeature +SevEsDisabled: + OneTimeCallRet IsSevEsEnabled ; ; Modified: EAX, EBX, ECX, EDX ; SetCr3ForPageTables64: - OneTimeCall CheckSevFeature + OneTimeCall CheckSevFeatures xor edx, edx test eax, eax jz SevNotActive @@ -229,7 +244,7 @@ pageTableEntriesLoop: mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx loop pageTableEntriesLoop - OneTimeCall CheckSevEsFeature + OneTimeCall IsSevEsEnabled test eax, eax jz SetCr3 @@ -336,8 +351,8 @@ SevEsIdtVmmComm: ; If we're here, then we are an SEV-ES guest and this ; was triggered by a CPUID instruction ; - ; Set the first byte of the workarea to one to communicate to the SEC - ; phase that SEV-ES is enabled. + ; Set the first byte of the workarea to one to communicate that + ; a #VC was taken. mov byte[SEV_ES_WORK_AREA], 1 pop ecx ; Error code -- 2.39.2