mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
55ee36b0c4
commit
a91b700e38
|
@ -3,6 +3,7 @@
|
||||||
; Sets the CR3 register for 64-bit paging
|
; Sets the CR3 register for 64-bit paging
|
||||||
;
|
;
|
||||||
; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
|
; 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
|
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
;
|
;
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
@ -62,18 +63,22 @@ BITS 32
|
||||||
%define CPUID_INSN_LEN 2
|
%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
|
; Modified: EAX, EBX, ECX, EDX, ESP
|
||||||
;
|
;
|
||||||
; If SEV is enabled then EAX will be at least 32.
|
; If SEV is enabled then EAX will be at least 32.
|
||||||
; If SEV is disabled then EAX will be zero.
|
; 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
|
; 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
|
; 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
|
; 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
|
mov byte[SEV_ES_WORK_AREA], 0
|
||||||
|
|
||||||
;
|
;
|
||||||
|
@ -97,7 +102,7 @@ CheckSevFeature:
|
||||||
cmp eax, 0x8000001f
|
cmp eax, 0x8000001f
|
||||||
jl NoSev
|
jl NoSev
|
||||||
|
|
||||||
; Check for memory encryption feature:
|
; Check for SEV memory encryption feature:
|
||||||
; CPUID Fn8000_001F[EAX] - Bit 1
|
; CPUID Fn8000_001F[EAX] - Bit 1
|
||||||
; CPUID raises a #VC exception if running as an SEV-ES guest
|
; CPUID raises a #VC exception if running as an SEV-ES guest
|
||||||
mov eax, 0x8000001f
|
mov eax, 0x8000001f
|
||||||
|
@ -105,13 +110,33 @@ CheckSevFeature:
|
||||||
bt eax, 1
|
bt eax, 1
|
||||||
jnc NoSev
|
jnc NoSev
|
||||||
|
|
||||||
; Check if memory encryption is enabled
|
; Check if SEV memory encryption is enabled
|
||||||
; MSR_0xC0010131 - Bit 0 (SEV enabled)
|
; MSR_0xC0010131 - Bit 0 (SEV enabled)
|
||||||
mov ecx, 0xc0010131
|
mov ecx, 0xc0010131
|
||||||
rdmsr
|
rdmsr
|
||||||
bt eax, 0
|
bt eax, 0
|
||||||
jnc NoSev
|
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
|
; Get pte bit position to enable memory encryption
|
||||||
; CPUID Fn8000_001F[EBX] - Bits 5:0
|
; CPUID Fn8000_001F[EBX] - Bits 5:0
|
||||||
;
|
;
|
||||||
|
@ -132,45 +157,35 @@ SevExit:
|
||||||
pop eax
|
pop eax
|
||||||
mov esp, 0
|
mov esp, 0
|
||||||
|
|
||||||
OneTimeCallRet CheckSevFeature
|
OneTimeCallRet CheckSevFeatures
|
||||||
|
|
||||||
; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
|
; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature
|
||||||
; is enabled.
|
; is enabled.
|
||||||
;
|
;
|
||||||
; Modified: EAX, EBX, ECX
|
; Modified: EAX
|
||||||
;
|
;
|
||||||
; If SEV-ES is enabled then EAX will be non-zero.
|
; If SEV-ES is enabled then EAX will be non-zero.
|
||||||
; If SEV-ES is disabled then EAX will be zero.
|
; If SEV-ES is disabled then EAX will be zero.
|
||||||
;
|
;
|
||||||
CheckSevEsFeature:
|
IsSevEsEnabled:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
|
|
||||||
; SEV-ES can't be enabled if SEV isn't, so first check the encryption
|
; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if
|
||||||
; mask.
|
; SEV-ES is enabled.
|
||||||
test edx, edx
|
cmp byte[SEV_ES_WORK_AREA], 1
|
||||||
jz NoSevEs
|
jne SevEsDisabled
|
||||||
|
|
||||||
; Save current value of encryption mask
|
mov eax, 1
|
||||||
mov ebx, edx
|
|
||||||
|
|
||||||
; Check if SEV-ES is enabled
|
SevEsDisabled:
|
||||||
; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
|
OneTimeCallRet IsSevEsEnabled
|
||||||
mov ecx, 0xc0010131
|
|
||||||
rdmsr
|
|
||||||
and eax, 2
|
|
||||||
|
|
||||||
; Restore encryption mask
|
|
||||||
mov edx, ebx
|
|
||||||
|
|
||||||
NoSevEs:
|
|
||||||
OneTimeCallRet CheckSevEsFeature
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; Modified: EAX, EBX, ECX, EDX
|
; Modified: EAX, EBX, ECX, EDX
|
||||||
;
|
;
|
||||||
SetCr3ForPageTables64:
|
SetCr3ForPageTables64:
|
||||||
|
|
||||||
OneTimeCall CheckSevFeature
|
OneTimeCall CheckSevFeatures
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz SevNotActive
|
jz SevNotActive
|
||||||
|
@ -229,7 +244,7 @@ pageTableEntriesLoop:
|
||||||
mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
|
mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
|
||||||
loop pageTableEntriesLoop
|
loop pageTableEntriesLoop
|
||||||
|
|
||||||
OneTimeCall CheckSevEsFeature
|
OneTimeCall IsSevEsEnabled
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz SetCr3
|
jz SetCr3
|
||||||
|
|
||||||
|
@ -336,8 +351,8 @@ SevEsIdtVmmComm:
|
||||||
; If we're here, then we are an SEV-ES guest and this
|
; If we're here, then we are an SEV-ES guest and this
|
||||||
; was triggered by a CPUID instruction
|
; was triggered by a CPUID instruction
|
||||||
;
|
;
|
||||||
; Set the first byte of the workarea to one to communicate to the SEC
|
; Set the first byte of the workarea to one to communicate that
|
||||||
; phase that SEV-ES is enabled.
|
; a #VC was taken.
|
||||||
mov byte[SEV_ES_WORK_AREA], 1
|
mov byte[SEV_ES_WORK_AREA], 1
|
||||||
|
|
||||||
pop ecx ; Error code
|
pop ecx ; Error code
|
||||||
|
|
Loading…
Reference in New Issue