]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/VmgExitLib/VmgExitLib.c
OvmfPkg/VmgExitLib: Add support for RDPMC NAE events
[mirror_edk2.git] / OvmfPkg / Library / VmgExitLib / VmgExitLib.c
CommitLineData
61bacc0f
TL
1/** @file\r
2 VMGEXIT Support Library.\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/VmgExitLib.h>\r
13#include <Register/Amd/Msr.h>\r
14\r
15/**\r
16 Check for VMGEXIT error\r
17\r
18 Check if the hypervisor has returned an error after completion of the VMGEXIT\r
19 by examining the SwExitInfo1 field of the GHCB.\r
20\r
21 @param[in] Ghcb A pointer to the GHCB\r
22\r
23 @retval 0 VMGEXIT succeeded.\r
24 @return Exception number to be propagated, VMGEXIT processing\r
25 did not succeed.\r
26\r
27**/\r
28STATIC\r
29UINT64\r
30VmgExitErrorCheck (\r
31 IN GHCB *Ghcb\r
32 )\r
33{\r
34 GHCB_EVENT_INJECTION Event;\r
35 GHCB_EXIT_INFO ExitInfo;\r
36 UINT64 Status;\r
37\r
38 ExitInfo.Uint64 = Ghcb->SaveArea.SwExitInfo1;\r
39 ASSERT ((ExitInfo.Elements.Lower32Bits == 0) ||\r
40 (ExitInfo.Elements.Lower32Bits == 1));\r
41\r
42 Status = 0;\r
43 if (ExitInfo.Elements.Lower32Bits == 0) {\r
44 return Status;\r
45 }\r
46\r
47 if (ExitInfo.Elements.Lower32Bits == 1) {\r
48 ASSERT (Ghcb->SaveArea.SwExitInfo2 != 0);\r
49\r
50 //\r
51 // Check that the return event is valid\r
52 //\r
53 Event.Uint64 = Ghcb->SaveArea.SwExitInfo2;\r
54 if (Event.Elements.Valid &&\r
55 Event.Elements.Type == GHCB_EVENT_INJECTION_TYPE_EXCEPTION) {\r
56 switch (Event.Elements.Vector) {\r
57 case GP_EXCEPTION:\r
58 case UD_EXCEPTION:\r
59 //\r
60 // Use returned event as return code\r
61 //\r
62 Status = Event.Uint64;\r
63 }\r
64 }\r
65 }\r
66\r
67 if (Status == 0) {\r
68 GHCB_EVENT_INJECTION GpEvent;\r
69\r
70 GpEvent.Uint64 = 0;\r
71 GpEvent.Elements.Vector = GP_EXCEPTION;\r
72 GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;\r
73 GpEvent.Elements.Valid = 1;\r
74\r
75 Status = GpEvent.Uint64;\r
76 }\r
77\r
78 return Status;\r
79}\r
80\r
81/**\r
82 Perform VMGEXIT.\r
83\r
84 Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and\r
85 then handles the return actions.\r
86\r
87 @param[in, out] Ghcb A pointer to the GHCB\r
88 @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode\r
89 field of the GHCB.\r
90 @param[in] ExitInfo1 VMGEXIT information to be assigned to the\r
91 SwExitInfo1 field of the GHCB.\r
92 @param[in] ExitInfo2 VMGEXIT information to be assigned to the\r
93 SwExitInfo2 field of the GHCB.\r
94\r
95 @retval 0 VMGEXIT succeeded.\r
96 @return Exception number to be propagated, VMGEXIT\r
97 processing did not succeed.\r
98\r
99**/\r
100UINT64\r
101EFIAPI\r
102VmgExit (\r
103 IN OUT GHCB *Ghcb,\r
104 IN UINT64 ExitCode,\r
105 IN UINT64 ExitInfo1,\r
106 IN UINT64 ExitInfo2\r
107 )\r
108{\r
109 Ghcb->SaveArea.SwExitCode = ExitCode;\r
110 Ghcb->SaveArea.SwExitInfo1 = ExitInfo1;\r
111 Ghcb->SaveArea.SwExitInfo2 = ExitInfo2;\r
112\r
113 //\r
114 // Guest memory is used for the guest-hypervisor communication, so fence\r
115 // the invocation of the VMGEXIT instruction to ensure GHCB accesses are\r
116 // synchronized properly.\r
117 //\r
118 MemoryFence ();\r
119 AsmVmgExit ();\r
120 MemoryFence ();\r
121\r
122 return VmgExitErrorCheck (Ghcb);\r
123}\r
124\r
125/**\r
126 Perform pre-VMGEXIT initialization/preparation.\r
127\r
128 Performs the necessary steps in preparation for invoking VMGEXIT. Must be\r
129 called before setting any fields within the GHCB.\r
130\r
131 @param[in, out] Ghcb A pointer to the GHCB\r
132\r
133**/\r
134VOID\r
135EFIAPI\r
136VmgInit (\r
137 IN OUT GHCB *Ghcb\r
138 )\r
139{\r
140 SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0);\r
141}\r
142\r
143/**\r
144 Perform post-VMGEXIT cleanup.\r
145\r
146 Performs the necessary steps to cleanup after invoking VMGEXIT. Must be\r
147 called after obtaining needed fields within the GHCB.\r
148\r
149 @param[in, out] Ghcb A pointer to the GHCB\r
150\r
151**/\r
152VOID\r
153EFIAPI\r
154VmgDone (\r
155 IN OUT GHCB *Ghcb\r
156 )\r
157{\r
158}\r
159\r