]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Ovmf/ResetVector: Simplify and consolidate the SEV features checks
authorTom Lendacky <thomas.lendacky@amd.com>
Thu, 7 Jan 2021 18:48:11 +0000 (12:48 -0600)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 7 Jan 2021 19:34:39 +0000 (19:34 +0000)
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 <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <43a660624c32b5f6c2610bf42ee39101c21aff68.1610045305.git.thomas.lendacky@amd.com>

OvmfPkg/ResetVector/Ia32/PageTables64.asm

index 7c72128a84d69ef421e37ce7a7104180b11641d0..4032719c30755a2af644fd757494b949ef3af7bc 100644 (file)
@@ -3,6 +3,7 @@
 ; Sets the CR3 register for 64-bit paging\r
 ;\r
 ; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2017 - 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>\r
 ; SPDX-License-Identifier: BSD-2-Clause-Patent\r
 ;\r
 ;------------------------------------------------------------------------------\r
@@ -62,18 +63,22 @@ BITS    32
 %define CPUID_INSN_LEN              2\r
 \r
 \r
-; Check if Secure Encrypted Virtualization (SEV) feature is enabled\r
+; Check if Secure Encrypted Virtualization (SEV) features are enabled.\r
+;\r
+; Register usage is tight in this routine, so multiple calls for the\r
+; same CPUID and MSR data are performed to keep things simple.\r
 ;\r
 ; Modified:  EAX, EBX, ECX, EDX, ESP\r
 ;\r
 ; If SEV is enabled then EAX will be at least 32.\r
 ; If SEV is disabled then EAX will be zero.\r
 ;\r
-CheckSevFeature:\r
+CheckSevFeatures:\r
     ; Set the first byte of the workarea to zero to communicate to the SEC\r
     ; phase that SEV-ES is not enabled. If SEV-ES is enabled, the CPUID\r
     ; instruction will trigger a #VC exception where the first byte of the\r
-    ; workarea will be set to one.\r
+    ; workarea will be set to one or, if CPUID is not being intercepted,\r
+    ; the MSR check below will set the first byte of the workarea to one.\r
     mov     byte[SEV_ES_WORK_AREA], 0\r
 \r
     ;\r
@@ -97,21 +102,41 @@ CheckSevFeature:
     cmp       eax, 0x8000001f\r
     jl        NoSev\r
 \r
-    ; Check for memory encryption feature:\r
+    ; Check for SEV memory encryption feature:\r
     ; CPUID  Fn8000_001F[EAX] - Bit 1\r
     ;   CPUID raises a #VC exception if running as an SEV-ES guest\r
-    mov       eax,  0x8000001f\r
+    mov       eax, 0x8000001f\r
     cpuid\r
     bt        eax, 1\r
     jnc       NoSev\r
 \r
-    ; Check if memory encryption is enabled\r
+    ; Check if SEV memory encryption is enabled\r
     ;  MSR_0xC0010131 - Bit 0 (SEV enabled)\r
     mov       ecx, 0xc0010131\r
     rdmsr\r
     bt        eax, 0\r
     jnc       NoSev\r
 \r
+    ; Check for SEV-ES memory encryption feature:\r
+    ; CPUID  Fn8000_001F[EAX] - Bit 3\r
+    ;   CPUID raises a #VC exception if running as an SEV-ES guest\r
+    mov       eax, 0x8000001f\r
+    cpuid\r
+    bt        eax, 3\r
+    jnc       GetSevEncBit\r
+\r
+    ; Check if SEV-ES is enabled\r
+    ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)\r
+    mov       ecx, 0xc0010131\r
+    rdmsr\r
+    bt        eax, 1\r
+    jnc       GetSevEncBit\r
+\r
+    ; Set the first byte of the workarea to one to communicate to the SEC\r
+    ; phase that SEV-ES is enabled.\r
+    mov       byte[SEV_ES_WORK_AREA], 1\r
+\r
+GetSevEncBit:\r
     ; Get pte bit position to enable memory encryption\r
     ; CPUID Fn8000_001F[EBX] - Bits 5:0\r
     ;\r
@@ -132,45 +157,35 @@ SevExit:
     pop       eax\r
     mov       esp, 0\r
 \r
-    OneTimeCallRet CheckSevFeature\r
+    OneTimeCallRet CheckSevFeatures\r
 \r
 ; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature\r
 ; is enabled.\r
 ;\r
-; Modified:  EAX, EBX, ECX\r
+; Modified:  EAX\r
 ;\r
 ; If SEV-ES is enabled then EAX will be non-zero.\r
 ; If SEV-ES is disabled then EAX will be zero.\r
 ;\r
-CheckSevEsFeature:\r
+IsSevEsEnabled:\r
     xor       eax, eax\r
 \r
-    ; SEV-ES can't be enabled if SEV isn't, so first check the encryption\r
-    ; mask.\r
-    test      edx, edx\r
-    jz        NoSevEs\r
-\r
-    ; Save current value of encryption mask\r
-    mov       ebx, edx\r
-\r
-    ; Check if SEV-ES is enabled\r
-    ;  MSR_0xC0010131 - Bit 1 (SEV-ES enabled)\r
-    mov       ecx, 0xc0010131\r
-    rdmsr\r
-    and       eax, 2\r
+    ; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if\r
+    ; SEV-ES is enabled.\r
+    cmp       byte[SEV_ES_WORK_AREA], 1\r
+    jne       SevEsDisabled\r
 \r
-    ; Restore encryption mask\r
-    mov       edx, ebx\r
+    mov       eax, 1\r
 \r
-NoSevEs:\r
-    OneTimeCallRet CheckSevEsFeature\r
+SevEsDisabled:\r
+    OneTimeCallRet IsSevEsEnabled\r
 \r
 ;\r
 ; Modified:  EAX, EBX, ECX, EDX\r
 ;\r
 SetCr3ForPageTables64:\r
 \r
-    OneTimeCall   CheckSevFeature\r
+    OneTimeCall   CheckSevFeatures\r
     xor     edx, edx\r
     test    eax, eax\r
     jz      SevNotActive\r
@@ -229,7 +244,7 @@ pageTableEntriesLoop:
     mov     [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx\r
     loop    pageTableEntriesLoop\r
 \r
-    OneTimeCall   CheckSevEsFeature\r
+    OneTimeCall   IsSevEsEnabled\r
     test    eax, eax\r
     jz      SetCr3\r
 \r
@@ -336,8 +351,8 @@ SevEsIdtVmmComm:
     ; If we're here, then we are an SEV-ES guest and this\r
     ; was triggered by a CPUID instruction\r
     ;\r
-    ; Set the first byte of the workarea to one to communicate to the SEC\r
-    ; phase that SEV-ES is enabled.\r
+    ; Set the first byte of the workarea to one to communicate that\r
+    ; a #VC was taken.\r
     mov     byte[SEV_ES_WORK_AREA], 1\r
 \r
     pop     ecx                     ; Error code\r