]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/ResetVector: move the GHCB page setup in AmdSev.asm
authorBrijesh Singh <brijesh.singh@amd.com>
Tue, 17 Aug 2021 13:46:51 +0000 (21:46 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 27 Aug 2021 12:10:40 +0000 (12:10 +0000)
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

While build the initial page table, the SetCr3ForPageTables64 checks
whether SEV-ES is enabled. If so, clear the page encryption mask from the
GHCB page. Move the logic to clear the page encryption mask in the
AmdSev.asm.

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>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
OvmfPkg/ResetVector/Ia32/AmdSev.asm
OvmfPkg/ResetVector/Ia32/PageTables64.asm

index 87d81b01e263806ea9bf5e679a3e9dc6b9e9442f..250ac8d8b1806341b0229287546bc11d3825fdd4 100644 (file)
@@ -44,6 +44,27 @@ BITS    32
 ; The unexpected response code\r
 %define TERM_UNEXPECTED_RESP_CODE   2\r
 \r
+%define PAGE_PRESENT            0x01\r
+%define PAGE_READ_WRITE         0x02\r
+%define PAGE_USER_SUPERVISOR    0x04\r
+%define PAGE_WRITE_THROUGH      0x08\r
+%define PAGE_CACHE_DISABLE     0x010\r
+%define PAGE_ACCESSED          0x020\r
+%define PAGE_DIRTY             0x040\r
+%define PAGE_PAT               0x080\r
+%define PAGE_GLOBAL           0x0100\r
+%define PAGE_2M_MBO            0x080\r
+%define PAGE_2M_PAT          0x01000\r
+\r
+%define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \\r
+                          PAGE_DIRTY + \\r
+                          PAGE_READ_WRITE + \\r
+                          PAGE_PRESENT)\r
+\r
+%define PAGE_PDP_ATTR (PAGE_ACCESSED + \\r
+                       PAGE_READ_WRITE + \\r
+                       PAGE_PRESENT)\r
+\r
 \r
 ; Macro is used to issue the MSR protocol based VMGEXIT. The caller is\r
 ; responsible to populate values in the EDX:EAX registers. After the vmmcall\r
@@ -117,6 +138,70 @@ BITS    32
 SevEsUnexpectedRespTerminate:\r
     TerminateVmgExit    TERM_UNEXPECTED_RESP_CODE\r
 \r
+; If SEV-ES is enabled then initialize and make the GHCB page shared\r
+SevClearPageEncMaskForGhcbPage:\r
+    ; Check if SEV is enabled\r
+    cmp       byte[WORK_AREA_GUEST_TYPE], 1\r
+    jnz       SevClearPageEncMaskForGhcbPageExit\r
+\r
+    ; Check if SEV-ES is enabled\r
+    cmp       byte[SEV_ES_WORK_AREA], 1\r
+    jnz       SevClearPageEncMaskForGhcbPageExit\r
+\r
+    ;\r
+    ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.\r
+    ; This requires the 2MB page for this range be broken down into 512 4KB\r
+    ; pages.  All will be marked encrypted, except for the GHCB.\r
+    ;\r
+    mov     ecx, (GHCB_BASE >> 21)\r
+    mov     eax, GHCB_PT_ADDR + PAGE_PDP_ATTR\r
+    mov     [ecx * 8 + PT_ADDR (0x2000)], eax\r
+\r
+    ;\r
+    ; Page Table Entries (512 * 4KB entries => 2MB)\r
+    ;\r
+    mov     ecx, 512\r
+pageTableEntries4kLoop:\r
+    mov     eax, ecx\r
+    dec     eax\r
+    shl     eax, 12\r
+    add     eax, GHCB_BASE & 0xFFE0_0000\r
+    add     eax, PAGE_4K_PDE_ATTR\r
+    mov     [ecx * 8 + GHCB_PT_ADDR - 8], eax\r
+    mov     [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx\r
+    loop    pageTableEntries4kLoop\r
+\r
+    ;\r
+    ; Clear the encryption bit from the GHCB entry\r
+    ;\r
+    mov     ecx, (GHCB_BASE & 0x1F_FFFF) >> 12\r
+    mov     [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0\r
+\r
+    mov     ecx, GHCB_SIZE / 4\r
+    xor     eax, eax\r
+clearGhcbMemoryLoop:\r
+    mov     dword[ecx * 4 + GHCB_BASE - 4], eax\r
+    loop    clearGhcbMemoryLoop\r
+\r
+SevClearPageEncMaskForGhcbPageExit:\r
+    OneTimeCallRet SevClearPageEncMaskForGhcbPage\r
+\r
+; Check if SEV is enabled, and get the C-bit mask above 31.\r
+; Modified: EDX\r
+;\r
+; The value is returned in the EDX\r
+GetSevCBitMaskAbove31:\r
+    xor       edx, edx\r
+\r
+    ; Check if SEV is enabled\r
+    cmp       byte[WORK_AREA_GUEST_TYPE], 1\r
+    jnz       GetSevCBitMaskAbove31Exit\r
+\r
+    mov       edx, dword[SEV_ES_WORK_AREA_ENC_MASK + 4]\r
+\r
+GetSevCBitMaskAbove31Exit:\r
+    OneTimeCallRet GetSevCBitMaskAbove31\r
+\r
 ; Check if Secure Encrypted Virtualization (SEV) features are enabled.\r
 ;\r
 ; Register usage is tight in this routine, so multiple calls for the\r
@@ -249,32 +334,6 @@ SevExit:
 \r
     OneTimeCallRet CheckSevFeatures\r
 \r
-; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature\r
-; is enabled.\r
-;\r
-; Modified:  EAX\r
-;\r
-; If SEV-ES is enabled then EAX will be non-zero.\r
-; If SEV-ES is disabled then EAX will be zero.\r
-;\r
-IsSevEsEnabled:\r
-    xor       eax, eax\r
-\r
-    ; During CheckSevFeatures, the WORK_AREA_GUEST_TYPE is set\r
-    ; to 1 if SEV is enabled.\r
-    cmp       byte[WORK_AREA_GUEST_TYPE], 1\r
-    jne       SevEsDisabled\r
-\r
-    ; During CheckSevFeatures, the SEV_ES_WORK_AREA was set to 1 if\r
-    ; SEV-ES is enabled.\r
-    cmp       byte[SEV_ES_WORK_AREA], 1\r
-    jne       SevEsDisabled\r
-\r
-    mov       eax, 1\r
-\r
-SevEsDisabled:\r
-    OneTimeCallRet IsSevEsEnabled\r
-\r
 ; Start of #VC exception handling routines\r
 ;\r
 \r
index f688909f1c7d00b6dc2edee5ca1566f4a35642d7..07b6ca07090947655ce84df62ce5b8c40861d3b8 100644 (file)
@@ -46,16 +46,13 @@ SetCr3ForPageTables64:
     ; work area when detected.\r
     mov     byte[WORK_AREA_GUEST_TYPE], 0\r
 \r
+    ; Check whether the SEV is active and populate the SevEsWorkArea\r
     OneTimeCall   CheckSevFeatures\r
-    xor     edx, edx\r
-    test    eax, eax\r
-    jz      SevNotActive\r
 \r
-    ; If SEV is enabled, C-bit is always above 31\r
-    sub     eax, 32\r
-    bts     edx, eax\r
-\r
-SevNotActive:\r
+    ; If SEV is enabled, the C-bit position is always above 31.\r
+    ; The mask will be saved in the EDX and applied during the\r
+    ; the page table build below.\r
+    OneTimeCall   GetSevCBitMaskAbove31\r
 \r
     ;\r
     ; For OVMF, build some initial page tables at\r
@@ -105,44 +102,8 @@ pageTableEntriesLoop:
     mov     [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx\r
     loop    pageTableEntriesLoop\r
 \r
-    OneTimeCall   IsSevEsEnabled\r
-    test    eax, eax\r
-    jz      SetCr3\r
-\r
-    ;\r
-    ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.\r
-    ; This requires the 2MB page for this range be broken down into 512 4KB\r
-    ; pages.  All will be marked encrypted, except for the GHCB.\r
-    ;\r
-    mov     ecx, (GHCB_BASE >> 21)\r
-    mov     eax, GHCB_PT_ADDR + PAGE_PDP_ATTR\r
-    mov     [ecx * 8 + PT_ADDR (0x2000)], eax\r
-\r
-    ;\r
-    ; Page Table Entries (512 * 4KB entries => 2MB)\r
-    ;\r
-    mov     ecx, 512\r
-pageTableEntries4kLoop:\r
-    mov     eax, ecx\r
-    dec     eax\r
-    shl     eax, 12\r
-    add     eax, GHCB_BASE & 0xFFE0_0000\r
-    add     eax, PAGE_4K_PDE_ATTR\r
-    mov     [ecx * 8 + GHCB_PT_ADDR - 8], eax\r
-    mov     [(ecx * 8 + GHCB_PT_ADDR - 8) + 4], edx\r
-    loop    pageTableEntries4kLoop\r
-\r
-    ;\r
-    ; Clear the encryption bit from the GHCB entry\r
-    ;\r
-    mov     ecx, (GHCB_BASE & 0x1F_FFFF) >> 12\r
-    mov     [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0\r
-\r
-    mov     ecx, GHCB_SIZE / 4\r
-    xor     eax, eax\r
-clearGhcbMemoryLoop:\r
-    mov     dword[ecx * 4 + GHCB_BASE - 4], eax\r
-    loop    clearGhcbMemoryLoop\r
+    ; Clear the C-bit from the GHCB page if the SEV-ES is enabled.\r
+    OneTimeCall   SevClearPageEncMaskForGhcbPage\r
 \r
 SetCr3:\r
     ;\r