[edk2-devel] [PATCH RFC v2 16/28] OvmfPkg/MemEncryptSevLib: Extend Es Workarea to include hv features

Brijesh Singh posted 28 patches 1 month, 2 weeks ago

[edk2-devel] [PATCH RFC v2 16/28] OvmfPkg/MemEncryptSevLib: Extend Es Workarea to include hv features

Posted by Brijesh Singh 1 month, 2 weeks ago
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The GHCB Version 2 introduces advertisement of features that are supported
by the hypervisor. The features value is saved in the SevEs workarea. Save
the value in the PCD for the later use.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 OvmfPkg/Include/Library/MemEncryptSevLib.h |   2 +
 OvmfPkg/PlatformPei/AmdSev.c               |  26 +++++
 OvmfPkg/PlatformPei/PlatformPei.inf        |   1 +
 OvmfPkg/ResetVector/Ia32/PageTables64.asm  | 122 ++++++++++++++++++++
 OvmfPkg/ResetVector/ResetVector.nasmb      |   1 +
 5 files changed, 152 insertions(+)

diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 03e476ef2a..42caa6497b 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -55,6 +55,8 @@ typedef struct _SEC_SEV_ES_WORK_AREA {
   UINT64   RandomData;
 
   UINT64   EncryptionMask;
+
+  UINT64   HypervisorFeatures;
 } SEC_SEV_ES_WORK_AREA;
 
 //
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 67b78fd5fa..81e40e0889 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -43,6 +43,27 @@ AmdSevSnpInitialize (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
+/**
+
+  Function to set the PcdHypervisorFeatures.
+**/
+STATIC
+VOID
+AmdSevHypervisorFeatures (
+  VOID
+  )
+{
+  SEC_SEV_ES_WORK_AREA  *SevEsWorkArea;
+  RETURN_STATUS         PcdStatus;
+
+  SevEsWorkArea = (SEC_SEV_ES_WORK_AREA *) FixedPcdGet32 (PcdSevEsWorkAreaBase);
+
+  PcdStatus = PcdSet64S (PcdGhcbHypervisorFeatures, SevEsWorkArea->HypervisorFeatures);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  DEBUG ((DEBUG_INFO, "GHCB Hypervisor Features=0x%Lx\n", SevEsWorkArea->HypervisorFeatures));
+}
+
 /**
 
   Initialize SEV-ES support if running as an SEV-ES guest.
@@ -73,6 +94,11 @@ AmdSevEsInitialize (
   PcdStatus = PcdSetBoolS (PcdSevEsIsEnabled, TRUE);
   ASSERT_RETURN_ERROR (PcdStatus);
 
+  //
+  // Set the hypervisor features PCD.
+  //
+  AmdSevHypervisorFeatures ();
+
   //
   // Allocate GHCB and per-CPU variable pages.
   //   Since the pages must survive across the UEFI to OS transition
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 3aef0773b1..89c8e9627c 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -111,6 +111,7 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
   gUefiCpuPkgTokenSpaceGuid.PcdSevSnpIsEnabled
+  gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures
 
 [FixedPcd]
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
index 6838cdeec9..6bf4a3524a 100644
--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm
+++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm
@@ -62,6 +62,16 @@ BITS    32
 %define GHCB_CPUID_REGISTER_SHIFT  30
 %define CPUID_INSN_LEN              2
 
+; GHCB SEV Information MSR protocol
+%define GHCB_SEV_INFORMATION_REQUEST    2
+%define GHCB_SEV_INFORMATION_RESPONSE   1
+
+; GHCB Hypervisor features MSR protocol
+%define GHCB_HYPERVISOR_FEATURES_REQUEST    128
+%define GHCB_HYPERVISOR_FEATURES_RESPONSE   129
+
+; GHCB request to terminate protocol values
+%define GHCB_GENERAL_TERMINATE_REQUEST    255
 
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.
 ;
@@ -86,6 +96,13 @@ CheckSevFeatures:
     ; will set it to 1.
     mov       byte[SEV_ES_WORK_AREA_SNP], 0
 
+    ; Set the Hypervisor features field in the workarea to zero to communicate
+    ; to the hypervisor features to the SEC phase. The hypervisor feature is
+    ; filled during the call to CheckHypervisorFeatures.
+    mov     eax, 0
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], eax
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], eax
+
     ;
     ; Set up exception handlers to check for SEV-ES
     ;   Load temporary RAM stack based on PCDs (see SevEsIdtVmmComm for
@@ -225,6 +242,106 @@ IsSevEsEnabled:
 SevEsDisabled:
     OneTimeCallRet IsSevEsEnabled
 
+; The version 2 of GHCB specification added the support to query the hypervisor features.
+; If the GHCB version is greather than 2 then read the hypervisor features.
+;
+; Modified:  EAX, EBX, ECX, EDX
+;
+CheckHypervisorFeatures:
+    ; Get the SEV Information
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[11:0]  = SEV information request
+    ;
+    mov     edx, 0
+    mov     eax, GHCB_SEV_INFORMATION_REQUEST
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+    ;
+    ; SEV Information Response GHCB MSR
+    ;   GHCB_MSR[63:48] = Maximum protocol version
+    ;   GHCB_MSR[47:32] = Minimum protocol version
+    ;   GHCB_MSR[11:0]  = SEV information response
+    ;
+    mov     ecx, 0xc0010130
+    rdmsr
+    and     eax, 0xfff
+    cmp     eax, GHCB_SEV_INFORMATION_RESPONSE
+    jnz     TerminateSevGuestLaunch
+    shr     edx, 16
+    cmp     edx, 2
+    jl      CheckHypervisorFeaturesDone
+
+    ; Get the hypervisor features
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[11:0]  = Hypervisor features request
+    ;
+    mov     edx, 0
+    mov     eax, GHCB_HYPERVISOR_FEATURES_REQUEST
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+    ;
+    ; Hypervisor features reponse
+    ;   GHCB_MSR[63:12] = Features bitmap
+    ;   GHCB_MSR[11:0]  = Hypervisor features response
+    ;
+    mov     ecx, 0xc0010130
+    rdmsr
+    mov     ebx, eax
+    and     eax, 0xfff
+    cmp     eax, GHCB_HYPERVISOR_FEATURES_RESPONSE
+    jnz     TerminateSevGuestLaunch
+
+    shr     ebx, 12
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES], ebx
+    mov     dword[SEV_ES_WORK_AREA_HYPERVISOR_FEATURES + 4], edx
+
+    jmp     CheckHypervisorFeaturesDone
+TerminateSevGuestLaunch:
+    ;
+    ; Setup GHCB MSR
+    ;   GHCB_MSR[23:16] = 0
+    ;   GHCB_MSR[15:12] = 0
+    ;   GHCB_MSR[11:0]  = Terminate Request
+    ;
+    mov     edx, 0
+    mov     eax, GHCB_GENERAL_TERMINATE_REQUEST
+    mov     ecx, 0xc0010130
+    wrmsr
+
+    ;
+    ; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
+    ; mode, so work around this by temporarily switching to 64-bit mode.
+    ;
+BITS    64
+    rep     vmmcall
+BITS    32
+
+TerminateSevGuestLaunchHlt:
+    cli
+    hlt
+    jmp     TerminateSevGuestLaunchHlt
+
+CheckHypervisorFeaturesDone:
+    OneTimeCallRet CheckHypervisorFeatures
+
 ;
 ; Modified:  EAX, EBX, ECX, EDX
 ;
@@ -328,6 +445,11 @@ clearGhcbMemoryLoop:
     mov     dword[ecx * 4 + GHCB_BASE - 4], eax
     loop    clearGhcbMemoryLoop
 
+    ;
+    ; It is SEV-ES guest, query the Hypervisor features
+    ;
+    OneTimeCall   CheckHypervisorFeatures
+
 SetCr3:
     ;
     ; Set CR3 now that the paging structures are available
diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb
index 34b900127e..465038e39d 100644
--- a/OvmfPkg/ResetVector/ResetVector.nasmb
+++ b/OvmfPkg/ResetVector/ResetVector.nasmb
@@ -76,6 +76,7 @@
   %define SEV_ES_WORK_AREA_SNP (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 1)
   %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)
   %define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)
+  %define SEV_ES_WORK_AREA_HYPERVISOR_FEATURES (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24)
   %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))
 %include "Ia32/Flat32ToFlat64.asm"
 %include "Ia32/PageTables64.asm"
-- 
2.17.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#74643): https://edk2.groups.io/g/devel/message/74643
Mute This Topic: https://groups.io/mt/82479065/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-