## Number of page frames to use for storing grant table entries.\r
gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames|4|UINT32|0x33\r
\r
+ ## Specify the extra page table needed to mark the GHCB as unencrypted.\r
+ # The value should be a multiple of 4KB for each.\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase|0x0|UINT32|0x3e\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize|0x0|UINT32|0x3f\r
+\r
+ ## The base address of the SEC GHCB page used by SEV-ES.\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase|0|UINT32|0x40\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize|0|UINT32|0x41\r
+\r
[PcdsDynamic, PcdsDynamicEx]\r
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10\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_2M_PDE_ATTR (PAGE_2M_MBO + \\r
PAGE_ACCESSED + \\r
PAGE_DIRTY + \\r
SevExit:\r
OneTimeCallRet CheckSevFeature\r
\r
+; Check if Secure Encrypted Virtualization - Encrypted State (SEV-ES) feature\r
+; is enabled.\r
+;\r
+; Modified: EAX, EBX, ECX\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
+CheckSevEsFeature:\r
+ xor eax, eax\r
+\r
+ ; SEV-ES can't be enabled if SEV isn't, so first check the encryption\r
+ ; mask.\r
+ test edx, edx\r
+ jz NoSevEs\r
+\r
+ ; Save current value of encryption mask\r
+ mov ebx, edx\r
+\r
+ ; Check if SEV-ES is enabled\r
+ ; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)\r
+ mov ecx, 0xc0010131\r
+ rdmsr\r
+ and eax, 2\r
+\r
+ ; Restore encryption mask\r
+ mov edx, ebx\r
+\r
+NoSevEs:\r
+ OneTimeCallRet CheckSevEsFeature\r
+\r
;\r
; Modified: EAX, EBX, ECX, EDX\r
;\r
mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx\r
loop pageTableEntriesLoop\r
\r
+ OneTimeCall CheckSevEsFeature\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
+\r
+SetCr3:\r
;\r
; Set CR3 now that the paging structures are available\r
;\r
[Packages]\r
OvmfPkg/OvmfPkg.dec\r
MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
UefiCpuPkg/UefiCpuPkg.dec\r
\r
[BuildOptions]\r
*_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/\r
\r
[Pcd]\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize\r
%error "This implementation inherently depends on PcdOvmfSecPageTablesSize"\r
%endif\r
\r
+ %if (FixedPcdGet32 (PcdOvmfSecGhcbPageTableSize) != 0x1000)\r
+ %error "This implementation inherently depends on PcdOvmfSecGhcbPageTableSize"\r
+ %endif\r
+\r
+ %if (FixedPcdGet32 (PcdOvmfSecGhcbSize) != 0x2000)\r
+ %error "This implementation inherently depends on PcdOvmfSecGhcbSize"\r
+ %endif\r
+\r
+ %if ((FixedPcdGet32 (PcdOvmfSecGhcbBase) >> 21) != \\r
+ ((FixedPcdGet32 (PcdOvmfSecGhcbBase) + FixedPcdGet32 (PcdOvmfSecGhcbSize) - 1) >> 21))\r
+ %error "This implementation inherently depends on PcdOvmfSecGhcbBase not straddling a 2MB boundary"\r
+ %endif\r
+\r
%define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))\r
%include "Ia32/Flat32ToFlat64.asm"\r
+\r
+ %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))\r
+ %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))\r
+ %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))\r
%include "Ia32/PageTables64.asm"\r
%endif\r
\r