]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MpLib: add support to register GHCB GPA when SEV-SNP is enabled
authorBrijesh Singh <brijesh.singh@amd.com>
Thu, 9 Dec 2021 03:27:54 +0000 (11:27 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 9 Dec 2021 06:28:10 +0000 (06:28 +0000)
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

An SEV-SNP guest requires that the physical address of the GHCB must
be registered with the hypervisor before using it. See the GHCB
specification section 2.3.2 for more details.

Cc: Michael Roth <michael.roth@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
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: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Ray Ni <ray.ni@Intel.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
UefiCpuPkg/Library/MpInitLib/MpEqu.inc
UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm

index 2e9368a374a4b5f3ea2137a2b2638b9278374a91..01668638f245c84983d3fd5ec8a0efd74917bcc3 100644 (file)
@@ -92,6 +92,7 @@ struc MP_CPU_EXCHANGE_INFO
   .ModeHighSegment:              CTYPE_UINT16 1\r
   .Enable5LevelPaging:           CTYPE_BOOLEAN 1\r
   .SevEsIsEnabled:               CTYPE_BOOLEAN 1\r
+  .SevSnpIsEnabled               CTYPE_BOOLEAN 1\r
   .GhcbBase:                     CTYPE_UINTN 1\r
 endstruc\r
 \r
index 64fddb497e1e7f59c93a95e56690cfe7719c408d..44a011ba75dea8362ebecc33205257a0f4098367 100644 (file)
@@ -896,8 +896,9 @@ FillExchangeInfoData (
   ExchangeInfo->Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);\r
   DEBUG ((DEBUG_INFO, "%a: 5-Level Paging = %d\n", gEfiCallerBaseName, ExchangeInfo->Enable5LevelPaging));\r
 \r
-  ExchangeInfo->SevEsIsEnabled = CpuMpData->SevEsIsEnabled;\r
-  ExchangeInfo->GhcbBase       = (UINTN)CpuMpData->GhcbBase;\r
+  ExchangeInfo->SevEsIsEnabled  = CpuMpData->SevEsIsEnabled;\r
+  ExchangeInfo->SevSnpIsEnabled = CpuMpData->SevSnpIsEnabled;\r
+  ExchangeInfo->GhcbBase        = (UINTN)CpuMpData->GhcbBase;\r
 \r
   //\r
   // Get the BSP's data of GDT and IDT\r
@@ -1847,9 +1848,10 @@ MpInitLibInitialize (
   CpuMpData->CpuData          = (CPU_AP_DATA *)(CpuMpData + 1);\r
   CpuMpData->CpuInfoInHob     = (UINT64)(UINTN)(CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
   InitializeSpinLock (&CpuMpData->MpLock);\r
-  CpuMpData->SevEsIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevEs);\r
-  CpuMpData->SevEsAPBuffer  = (UINTN)-1;\r
-  CpuMpData->GhcbBase       = PcdGet64 (PcdGhcbBase);\r
+  CpuMpData->SevEsIsEnabled  = ConfidentialComputingGuestHas (CCAttrAmdSevEs);\r
+  CpuMpData->SevSnpIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevSnp);\r
+  CpuMpData->SevEsAPBuffer   = (UINTN)-1;\r
+  CpuMpData->GhcbBase        = PcdGet64 (PcdGhcbBase);\r
 \r
   //\r
   // Make sure no memory usage outside of the allocated buffer.\r
index a84df60519ed75a7cd3e5fe251a2dfbbc15bb536..56de3bfb1ccf71b4e1140adb76911ccc626f19e8 100644 (file)
@@ -222,6 +222,7 @@ typedef struct {
   //\r
   BOOLEAN            Enable5LevelPaging;\r
   BOOLEAN            SevEsIsEnabled;\r
+  BOOLEAN            SevSnpIsEnabled;\r
   UINTN              GhcbBase;\r
 } MP_CPU_EXCHANGE_INFO;\r
 \r
@@ -291,6 +292,7 @@ struct _CPU_MP_DATA {
   BOOLEAN        WakeUpByInitSipiSipi;\r
 \r
   BOOLEAN        SevEsIsEnabled;\r
+  BOOLEAN        SevSnpIsEnabled;\r
   UINTN          SevEsAPBuffer;\r
   UINTN          SevEsAPResetStackStart;\r
   CPU_MP_DATA    *NewCpuMpData;\r
index 0ccafe25eca4cfdb85029342cd3869e76964b77f..0034920b2f6b1785e359b95c2e6a5865668b7fc0 100644 (file)
 \r
 %define SIZE_4KB    0x1000\r
 \r
+RegisterGhcbGpa:\r
+    ;\r
+    ; Register GHCB GPA when SEV-SNP is enabled\r
+    ;\r
+    lea        edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpIsEnabled)]\r
+    cmp        byte [edi], 1        ; SevSnpIsEnabled\r
+    jne        RegisterGhcbGpaDone\r
+\r
+    ; Save the rdi and rsi to used for later comparison\r
+    push       rdi\r
+    push       rsi\r
+    mov        edi, eax\r
+    mov        esi, edx\r
+    or         eax, 18              ; Ghcb registration request\r
+    wrmsr\r
+    rep vmmcall\r
+    rdmsr\r
+    mov        r12, rax\r
+    and        r12, 0fffh\r
+    cmp        r12, 19              ; Ghcb registration response\r
+    jne        GhcbGpaRegisterFailure\r
+\r
+    ; Verify that GPA is not changed\r
+    and        eax, 0fffff000h\r
+    cmp        edi, eax\r
+    jne        GhcbGpaRegisterFailure\r
+    cmp        esi, edx\r
+    jne        GhcbGpaRegisterFailure\r
+    pop        rsi\r
+    pop        rdi\r
+    jmp        RegisterGhcbGpaDone\r
+\r
+    ;\r
+    ; Request the guest termination\r
+    ;\r
+GhcbGpaRegisterFailure:\r
+    xor        edx, edx\r
+    mov        eax, 256             ; GHCB terminate\r
+    wrmsr\r
+    rep vmmcall\r
+\r
+    ; We should not return from the above terminate request, but if we do\r
+    ; then enter into the hlt loop.\r
+DoHltLoop:\r
+    cli\r
+    hlt\r
+    jmp        DoHltLoop\r
+\r
+RegisterGhcbGpaDone:\r
+    OneTimeCallRet    RegisterGhcbGpa\r
+\r
 ;\r
 ; The function checks whether SEV-ES is enabled, if enabled\r
 ; then setup the GHCB page.\r
@@ -39,6 +90,9 @@ SevEsSetupGhcb:
     mov        rdx, rax\r
     shr        rdx, 32\r
     mov        rcx, 0xc0010130\r
+\r
+    OneTimeCall RegisterGhcbGpa\r
+\r
     wrmsr\r
 \r
 SevEsSetupGhcbExit:\r