jnz SevClearPageEncMaskForGhcbPageExit\r
\r
; Check if SEV-ES is enabled\r
- cmp byte[SEV_ES_WORK_AREA], 1\r
- jnz SevClearPageEncMaskForGhcbPageExit\r
+ mov ecx, 1\r
+ bt [SEV_ES_WORK_AREA_STATUS_MSR], ecx\r
+ jnc SevClearPageEncMaskForGhcbPageExit\r
\r
;\r
; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted.\r
; If SEV is disabled then EAX will be zero.\r
;\r
CheckSevFeatures:\r
- ; Set the first byte of the workarea to zero to communicate to the SEC\r
- ; phase that SEV-ES is not enabled. If SEV-ES is enabled, the CPUID\r
- ; instruction will trigger a #VC exception where the first byte of the\r
- ; workarea will be set to one or, if CPUID is not being intercepted,\r
- ; the MSR check below will set the first byte of the workarea to one.\r
- mov byte[SEV_ES_WORK_AREA], 0\r
+ ;\r
+ ; Clear the workarea, if SEV is enabled then later part of routine\r
+ ; will populate the workarea fields.\r
+ ;\r
+ mov ecx, SEV_ES_WORK_AREA_SIZE\r
+ mov eax, SEV_ES_WORK_AREA\r
+ClearSevEsWorkArea:\r
+ mov byte [eax], 0\r
+ inc eax\r
+ loop ClearSevEsWorkArea\r
\r
;\r
; Set up exception handlers to check for SEV-ES\r
; Set the work area header to indicate that the SEV is enabled\r
mov byte[WORK_AREA_GUEST_TYPE], 1\r
\r
+ ; Save the SevStatus MSR value in the workarea\r
+ mov [SEV_ES_WORK_AREA_STATUS_MSR], eax\r
+ mov [SEV_ES_WORK_AREA_STATUS_MSR + 4], edx\r
+\r
; Check for SEV-ES memory encryption feature:\r
; CPUID Fn8000_001F[EAX] - Bit 3\r
; CPUID raises a #VC exception if running as an SEV-ES guest\r
bt eax, 1\r
jnc GetSevEncBit\r
\r
- ; Set the first byte of the workarea to one to communicate to the SEC\r
- ; phase that SEV-ES is enabled.\r
- mov byte[SEV_ES_WORK_AREA], 1\r
-\r
GetSevEncBit:\r
; Get pte bit position to enable memory encryption\r
; CPUID Fn8000_001F[EBX] - Bits 5:0\r
;\r
; Perform an SEV-ES sanity check by seeing if a #VC exception occurred.\r
;\r
- cmp byte[SEV_ES_WORK_AREA], 0\r
+ ; If SEV-ES is enabled, the CPUID instruction will trigger a #VC exception\r
+ ; where the RECEIVED_VC offset in the workarea will be set to one.\r
+ ;\r
+ cmp byte[SEV_ES_WORK_AREA_RECEIVED_VC], 0\r
jz NoSevPass\r
\r
;\r
; If we're here, then we are an SEV-ES guest and this\r
; was triggered by a CPUID instruction\r
;\r
- ; Set the first byte of the workarea to one to communicate that\r
+ ; Set the recievedVc field in the workarea to communicate that\r
; a #VC was taken.\r
- mov byte[SEV_ES_WORK_AREA], 1\r
+ mov byte[SEV_ES_WORK_AREA_RECEIVED_VC], 1\r
\r
pop ecx ; Error code\r
cmp ecx, 0x72 ; Be sure it was CPUID\r
%define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase))\r
%define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize))\r
%define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase))\r
+ %define SEV_ES_WORK_AREA_SIZE 25\r
+ %define SEV_ES_WORK_AREA_STATUS_MSR (FixedPcdGet32 (PcdSevEsWorkAreaBase))\r
%define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 8)\r
%define SEV_ES_WORK_AREA_ENC_MASK (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 16)\r
+ %define SEV_ES_WORK_AREA_RECEIVED_VC (FixedPcdGet32 (PcdSevEsWorkAreaBase) + 24)\r
%define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize))\r
%define SEV_SNP_SECRETS_BASE (FixedPcdGet32 (PcdOvmfSnpSecretsBase))\r
%define SEV_SNP_SECRETS_SIZE (FixedPcdGet32 (PcdOvmfSnpSecretsSize))\r