diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2021-01-07 12:48:11 -0600 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2021-01-07 19:34:39 +0000 |
commit | a91b700e385e7484ab7286b3ba7ea2efbd59480e (patch) | |
tree | 033eb6b195a8890dd1a91663c39b5b00a232983d /OvmfPkg | |
parent | 55ee36b0c490d9a6582e083bb3ac78a22d33053f (diff) | |
download | edk2-a91b700e385e7484ab7286b3ba7ea2efbd59480e.zip edk2-a91b700e385e7484ab7286b3ba7ea2efbd59480e.tar.gz edk2-a91b700e385e7484ab7286b3ba7ea2efbd59480e.tar.bz2 |
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 <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>
Diffstat (limited to 'OvmfPkg')
-rw-r--r-- | OvmfPkg/ResetVector/Ia32/PageTables64.asm | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm index 7c72128..4032719 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.<BR>
+; Copyright (c) 2017 - 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
; 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
|