[edk2-devel] [PATCH v11 08/32] OvmfPkg/ResetVector: use SEV-SNP-validated CPUID values

Brijesh Singh via groups.io brijesh.singh=amd.com at groups.io
Sat Oct 23 04:13:25 UTC 2021


From: Michael Roth <michael.roth at amd.com>

CPUID instructions are issued during early boot to do things like probe
for SEV support. Currently these are handled by a minimal #VC handler
that uses the MSR-based GHCB protocol to fetch the CPUID values from
the hypervisor. When SEV-SNP is enabled, use the firmware-validated
CPUID values from the CPUID page instead [1].

[1]: SEV SNP Firmware ABI Specification, Rev. 0.8, 8.13.2.6

Cc: Michael Roth <michael.roth at amd.com>
Cc: James Bottomley <jejb at linux.ibm.com>
Cc: Min Xu <min.m.xu at intel.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Jordan Justen <jordan.l.justen at intel.com>
Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
Cc: Erdem Aktas <erdemaktas at google.com>
Cc: Gerd Hoffmann <kraxel at redhat.com>
Acked-by: Jiewen Yao <Jiewen.yao at intel.com>
Acked-by: Gerd Hoffmann <kraxel at redhat.com>
Signed-off-by: Michael Roth <michael.roth at amd.com>
Signed-off-by: Brijesh Singh <brijesh.singh at amd.com>
---
 OvmfPkg/ResetVector/Ia32/AmdSev.asm | 80 +++++++++++++++++++++++++++--
 1 file changed, 75 insertions(+), 5 deletions(-)

diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
index 48d9178168b0..1f827da3b929 100644
--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm
+++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm
@@ -34,6 +34,18 @@ BITS    32
 %define GHCB_CPUID_REGISTER_SHIFT  30
 %define CPUID_INSN_LEN              2
 
+; #VC handler offsets/sizes for accessing SNP CPUID page
+;
+%define SNP_CPUID_ENTRY_SZ         48
+%define SNP_CPUID_COUNT             0
+%define SNP_CPUID_ENTRY            16
+%define SNP_CPUID_ENTRY_EAX_IN      0
+%define SNP_CPUID_ENTRY_ECX_IN      4
+%define SNP_CPUID_ENTRY_EAX        24
+%define SNP_CPUID_ENTRY_EBX        28
+%define SNP_CPUID_ENTRY_ECX        32
+%define SNP_CPUID_ENTRY_EDX        36
+
 
 %define SEV_GHCB_MSR                0xc0010130
 %define SEV_STATUS_MSR              0xc0010131
@@ -335,11 +347,61 @@ SevEsIdtNotCpuid:
     TerminateVmgExit TERM_VC_NOT_CPUID
     iret
 
-    ;
-    ; Total stack usage for the #VC handler is 44 bytes:
-    ;   - 12 bytes for the exception IRET (after popping error code)
-    ;   - 32 bytes for the local variables.
-    ;
+; Use the SNP CPUID page to handle the cpuid lookup
+;
+;  Modified: EAX, EBX, ECX, EDX
+;
+;  Relies on the stack setup/usage in #VC handler:
+;
+;    On entry,
+;      [esp + VC_CPUID_FUNCTION] contains EAX input to cpuid instruction
+;
+;    On return, stores corresponding results of CPUID lookup in:
+;      [esp + VC_CPUID_RESULT_EAX]
+;      [esp + VC_CPUID_RESULT_EBX]
+;      [esp + VC_CPUID_RESULT_ECX]
+;      [esp + VC_CPUID_RESULT_EDX]
+;
+SnpCpuidLookup:
+    mov     eax, [esp + VC_CPUID_FUNCTION]
+    mov     ebx, [CPUID_BASE + SNP_CPUID_COUNT]
+    mov     ecx, CPUID_BASE + SNP_CPUID_ENTRY
+    ; Zero these out now so we can simply return if lookup fails
+    mov     dword[esp + VC_CPUID_RESULT_EAX], 0
+    mov     dword[esp + VC_CPUID_RESULT_EBX], 0
+    mov     dword[esp + VC_CPUID_RESULT_ECX], 0
+    mov     dword[esp + VC_CPUID_RESULT_EDX], 0
+
+SnpCpuidCheckEntry:
+    cmp     ebx, 0
+    je      VmmDoneSnpCpuid
+    cmp     dword[ecx + SNP_CPUID_ENTRY_EAX_IN], eax
+    jne     SnpCpuidCheckEntryNext
+    ; As with SEV-ES handler we assume requested CPUID sub-leaf/index is 0
+    cmp     dword[ecx + SNP_CPUID_ENTRY_ECX_IN], 0
+    je      SnpCpuidEntryFound
+
+SnpCpuidCheckEntryNext:
+    dec     ebx
+    add     ecx, SNP_CPUID_ENTRY_SZ
+    jmp     SnpCpuidCheckEntry
+
+SnpCpuidEntryFound:
+    mov     eax, [ecx + SNP_CPUID_ENTRY_EAX]
+    mov     [esp + VC_CPUID_RESULT_EAX], eax
+    mov     eax, [ecx + SNP_CPUID_ENTRY_EBX]
+    mov     [esp + VC_CPUID_RESULT_EBX], eax
+    mov     eax, [ecx + SNP_CPUID_ENTRY_EDX]
+    mov     [esp + VC_CPUID_RESULT_ECX], eax
+    mov     eax, [ecx + SNP_CPUID_ENTRY_ECX]
+    mov     [esp + VC_CPUID_RESULT_EDX], eax
+    jmp     VmmDoneSnpCpuid
+
+;
+; Total stack usage for the #VC handler is 44 bytes:
+;   - 12 bytes for the exception IRET (after popping error code)
+;   - 32 bytes for the local variables.
+;
 SevEsIdtVmmComm:
     ;
     ; If we're here, then we are an SEV-ES guest and this
@@ -367,6 +429,13 @@ SevEsIdtVmmComm:
     ; Save the CPUID function being requested
     mov     [esp + VC_CPUID_FUNCTION], eax
 
+    ; If SEV-SNP is enabled, use the CPUID page to handle the CPUID
+    ; instruction.
+    mov     ecx, SEV_STATUS_MSR
+    rdmsr
+    bt      eax, 2
+    jc      SnpCpuidLookup
+
     ; The GHCB CPUID protocol uses the following mapping to request
     ; a specific register:
     ;   0 => EAX, 1 => EBX, 2 => ECX, 3 => EDX
@@ -424,6 +493,7 @@ VmmDone:
     mov     ecx, SEV_GHCB_MSR
     wrmsr
 
+VmmDoneSnpCpuid:
     mov     eax, [esp + VC_CPUID_RESULT_EAX]
     mov     ebx, [esp + VC_CPUID_RESULT_EBX]
     mov     ecx, [esp + VC_CPUID_RESULT_ECX]
-- 
2.25.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#82573): https://edk2.groups.io/g/devel/message/82573
Mute This Topic: https://groups.io/mt/86530717/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list