2 VMGEXIT Support Library.
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/VmgExitLib.h>
13 #include <Register/Amd/Msr.h>
16 Check for VMGEXIT error
18 Check if the hypervisor has returned an error after completion of the VMGEXIT
19 by examining the SwExitInfo1 field of the GHCB.
21 @param[in] Ghcb A pointer to the GHCB
23 @retval 0 VMGEXIT succeeded.
24 @return Exception number to be propagated, VMGEXIT processing
34 GHCB_EVENT_INJECTION Event
;
35 GHCB_EXIT_INFO ExitInfo
;
38 ExitInfo
.Uint64
= Ghcb
->SaveArea
.SwExitInfo1
;
40 (ExitInfo
.Elements
.Lower32Bits
== 0) ||
41 (ExitInfo
.Elements
.Lower32Bits
== 1)
45 if (ExitInfo
.Elements
.Lower32Bits
== 0) {
49 if (ExitInfo
.Elements
.Lower32Bits
== 1) {
50 ASSERT (Ghcb
->SaveArea
.SwExitInfo2
!= 0);
53 // Check that the return event is valid
55 Event
.Uint64
= Ghcb
->SaveArea
.SwExitInfo2
;
56 if (Event
.Elements
.Valid
&&
57 (Event
.Elements
.Type
== GHCB_EVENT_INJECTION_TYPE_EXCEPTION
))
59 switch (Event
.Elements
.Vector
) {
63 // Use returned event as return code
65 Status
= Event
.Uint64
;
71 GHCB_EVENT_INJECTION GpEvent
;
74 GpEvent
.Elements
.Vector
= GP_EXCEPTION
;
75 GpEvent
.Elements
.Type
= GHCB_EVENT_INJECTION_TYPE_EXCEPTION
;
76 GpEvent
.Elements
.Valid
= 1;
78 Status
= GpEvent
.Uint64
;
87 Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and
88 then handles the return actions.
90 @param[in, out] Ghcb A pointer to the GHCB
91 @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode
93 @param[in] ExitInfo1 VMGEXIT information to be assigned to the
94 SwExitInfo1 field of the GHCB.
95 @param[in] ExitInfo2 VMGEXIT information to be assigned to the
96 SwExitInfo2 field of the GHCB.
98 @retval 0 VMGEXIT succeeded.
99 @return Exception number to be propagated, VMGEXIT
100 processing did not succeed.
112 Ghcb
->SaveArea
.SwExitCode
= ExitCode
;
113 Ghcb
->SaveArea
.SwExitInfo1
= ExitInfo1
;
114 Ghcb
->SaveArea
.SwExitInfo2
= ExitInfo2
;
116 VmgSetOffsetValid (Ghcb
, GhcbSwExitCode
);
117 VmgSetOffsetValid (Ghcb
, GhcbSwExitInfo1
);
118 VmgSetOffsetValid (Ghcb
, GhcbSwExitInfo2
);
121 // Guest memory is used for the guest-hypervisor communication, so fence
122 // the invocation of the VMGEXIT instruction to ensure GHCB accesses are
123 // synchronized properly.
129 return VmgExitErrorCheck (Ghcb
);
133 Perform pre-VMGEXIT initialization/preparation.
135 Performs the necessary steps in preparation for invoking VMGEXIT. Must be
136 called before setting any fields within the GHCB.
138 @param[in, out] Ghcb A pointer to the GHCB
139 @param[in, out] InterruptState A pointer to hold the current interrupt
140 state, used for restoring in VmgDone ()
147 IN OUT BOOLEAN
*InterruptState
151 // Be sure that an interrupt can't cause a #VC while the GHCB is
154 *InterruptState
= GetInterruptState ();
155 if (*InterruptState
) {
156 DisableInterrupts ();
159 SetMem (&Ghcb
->SaveArea
, sizeof (Ghcb
->SaveArea
), 0);
163 Perform post-VMGEXIT cleanup.
165 Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
166 called after obtaining needed fields within the GHCB.
168 @param[in, out] Ghcb A pointer to the GHCB
169 @param[in] InterruptState An indicator to conditionally (re)enable
177 IN BOOLEAN InterruptState
180 if (InterruptState
) {
186 Marks a field at the specified offset as valid in the GHCB.
188 The ValidBitmap area represents the areas of the GHCB that have been marked
189 valid. Set the bit in ValidBitmap for the input offset.
191 @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block
192 @param[in] Offset Qword offset in the GHCB to mark valid
199 IN GHCB_REGISTER Offset
205 OffsetIndex
= Offset
/ 8;
206 OffsetBit
= Offset
% 8;
208 Ghcb
->SaveArea
.ValidBitmap
[OffsetIndex
] |= (1 << OffsetBit
);
212 Checks if a specified offset is valid in the GHCB.
214 The ValidBitmap area represents the areas of the GHCB that have been marked
215 valid. Return whether the bit in the ValidBitmap is set for the input offset.
217 @param[in] Ghcb A pointer to the GHCB
218 @param[in] Offset Qword offset in the GHCB to mark valid
220 @retval TRUE Offset is marked valid in the GHCB
221 @retval FALSE Offset is not marked valid in the GHCB
228 IN GHCB_REGISTER Offset
234 OffsetIndex
= Offset
/ 8;
235 OffsetBit
= Offset
% 8;
237 return ((Ghcb
->SaveArea
.ValidBitmap
[OffsetIndex
] & (1 << OffsetBit
)) != 0);