]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VmgExitLib/SecVmgExitVcHandler.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Library / VmgExitLib / SecVmgExitVcHandler.c
CommitLineData
5667dc43
TL
1/** @file\r
2 X64 #VC Exception Handler functon.\r
3\r
4 Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include <Base.h>\r
10#include <Uefi.h>\r
11#include <Library/BaseMemoryLib.h>\r
12#include <Library/MemEncryptSevLib.h>\r
13#include <Library/VmgExitLib.h>\r
14#include <Register/Amd/Msr.h>\r
15\r
16#include "VmgExitVcHandler.h"\r
17\r
18/**\r
19 Handle a #VC exception.\r
20\r
21 Performs the necessary processing to handle a #VC exception.\r
22\r
23 @param[in, out] ExceptionType Pointer to an EFI_EXCEPTION_TYPE to be set\r
24 as value to use on error.\r
25 @param[in, out] SystemContext Pointer to EFI_SYSTEM_CONTEXT\r
26\r
27 @retval EFI_SUCCESS Exception handled\r
28 @retval EFI_UNSUPPORTED #VC not supported, (new) exception value to\r
29 propagate provided\r
30 @retval EFI_PROTOCOL_ERROR #VC handling failed, (new) exception value to\r
31 propagate provided\r
32\r
33**/\r
34EFI_STATUS\r
35EFIAPI\r
36VmgExitHandleVc (\r
37 IN OUT EFI_EXCEPTION_TYPE *ExceptionType,\r
38 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
39 )\r
40{\r
41 MSR_SEV_ES_GHCB_REGISTER Msr;\r
42 GHCB *Ghcb;\r
43 GHCB *GhcbBackup;\r
44 EFI_STATUS VcRet;\r
45 BOOLEAN InterruptState;\r
46 SEV_ES_PER_CPU_DATA *SevEsData;\r
47\r
48 InterruptState = GetInterruptState ();\r
49 if (InterruptState) {\r
50 DisableInterrupts ();\r
51 }\r
52\r
53 Msr.GhcbPhysicalAddress = AsmReadMsr64 (MSR_SEV_ES_GHCB);\r
54 ASSERT (Msr.GhcbInfo.Function == 0);\r
55 ASSERT (Msr.Ghcb != 0);\r
56\r
ac0a286f 57 Ghcb = Msr.Ghcb;\r
5667dc43
TL
58 GhcbBackup = NULL;\r
59\r
ac0a286f 60 SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);\r
5667dc43
TL
61 SevEsData->VcCount++;\r
62\r
63 //\r
64 // Check for maximum SEC #VC nesting.\r
65 //\r
66 if (SevEsData->VcCount > VMGEXIT_MAXIMUM_VC_COUNT) {\r
67 VmgExitIssueAssert (SevEsData);\r
68 } else if (SevEsData->VcCount > 1) {\r
69 UINTN GhcbBackupSize;\r
70\r
71 //\r
72 // Be sure that the proper amount of pages are allocated\r
73 //\r
74 GhcbBackupSize = (VMGEXIT_MAXIMUM_VC_COUNT - 1) * sizeof (*Ghcb);\r
75 if (GhcbBackupSize > FixedPcdGet32 (PcdOvmfSecGhcbBackupSize)) {\r
76 //\r
77 // Not enough SEC backup pages allocated.\r
78 //\r
79 VmgExitIssueAssert (SevEsData);\r
80 }\r
81\r
82 //\r
83 // Save the active GHCB to a backup page.\r
84 // To access the correct backup page, increment the backup page pointer\r
85 // based on the current VcCount.\r
86 //\r
ac0a286f 87 GhcbBackup = (GHCB *)FixedPcdGet32 (PcdOvmfSecGhcbBackupBase);\r
5667dc43
TL
88 GhcbBackup += (SevEsData->VcCount - 2);\r
89\r
90 CopyMem (GhcbBackup, Ghcb, sizeof (*Ghcb));\r
91 }\r
92\r
93 VcRet = InternalVmgExitHandleVc (Ghcb, ExceptionType, SystemContext);\r
94\r
95 if (GhcbBackup != NULL) {\r
96 //\r
97 // Restore the active GHCB from the backup page.\r
98 //\r
99 CopyMem (Ghcb, GhcbBackup, sizeof (*Ghcb));\r
100 }\r
101\r
102 SevEsData->VcCount--;\r
103\r
104 if (InterruptState) {\r
105 EnableInterrupts ();\r
106 }\r
107\r
108 return VcRet;\r
109}\r