2 X64 #VC Exception Handler functon.
4 Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/MemEncryptSevLib.h>
13 #include <Library/VmgExitLib.h>
14 #include <Register/Amd/Msr.h>
16 #include "VmgExitVcHandler.h"
19 Handle a #VC exception.
21 Performs the necessary processing to handle a #VC exception.
23 @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set
24 as value to use on error.
25 @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT
27 @retval EFI_SUCCESS Exception handled
28 @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to
30 @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to
37 IN OUT EFI_EXCEPTION_TYPE
*ExceptionType
,
38 IN OUT EFI_SYSTEM_CONTEXT SystemContext
41 MSR_SEV_ES_GHCB_REGISTER Msr
;
45 BOOLEAN InterruptState
;
46 SEV_ES_PER_CPU_DATA
*SevEsData
;
48 InterruptState
= GetInterruptState ();
53 Msr
.GhcbPhysicalAddress
= AsmReadMsr64 (MSR_SEV_ES_GHCB
);
54 ASSERT (Msr
.GhcbInfo
.Function
== 0);
55 ASSERT (Msr
.Ghcb
!= 0);
60 SevEsData
= (SEV_ES_PER_CPU_DATA
*) (Ghcb
+ 1);
64 // Check for maximum SEC #VC nesting.
66 if (SevEsData
->VcCount
> VMGEXIT_MAXIMUM_VC_COUNT
) {
67 VmgExitIssueAssert (SevEsData
);
68 } else if (SevEsData
->VcCount
> 1) {
72 // Be sure that the proper amount of pages are allocated
74 GhcbBackupSize
= (VMGEXIT_MAXIMUM_VC_COUNT
- 1) * sizeof (*Ghcb
);
75 if (GhcbBackupSize
> FixedPcdGet32 (PcdOvmfSecGhcbBackupSize
)) {
77 // Not enough SEC backup pages allocated.
79 VmgExitIssueAssert (SevEsData
);
83 // Save the active GHCB to a backup page.
84 // To access the correct backup page, increment the backup page pointer
85 // based on the current VcCount.
87 GhcbBackup
= (GHCB
*) FixedPcdGet32 (PcdOvmfSecGhcbBackupBase
);
88 GhcbBackup
+= (SevEsData
->VcCount
- 2);
90 CopyMem (GhcbBackup
, Ghcb
, sizeof (*Ghcb
));
93 VcRet
= InternalVmgExitHandleVc (Ghcb
, ExceptionType
, SystemContext
);
95 if (GhcbBackup
!= NULL
) {
97 // Restore the active GHCB from the backup page.
99 CopyMem (Ghcb
, GhcbBackup
, sizeof (*Ghcb
));
102 SevEsData
->VcCount
--;
104 if (InterruptState
) {