2 CcExitLib Support Library.
4 Copyright (C) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
5 Copyright (C) 2020 - 2022, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/CcExitLib.h>
14 #include <Register/Amd/Msr.h>
17 Check for VMGEXIT error
19 Check if the hypervisor has returned an error after completion of the VMGEXIT
20 by examining the SwExitInfo1 field of the GHCB.
22 @param[in] Ghcb A pointer to the GHCB
24 @retval 0 VMGEXIT succeeded.
25 @return Exception number to be propagated, VMGEXIT processing
35 GHCB_EVENT_INJECTION Event
;
36 GHCB_EXIT_INFO ExitInfo
;
39 ExitInfo
.Uint64
= Ghcb
->SaveArea
.SwExitInfo1
;
41 (ExitInfo
.Elements
.Lower32Bits
== 0) ||
42 (ExitInfo
.Elements
.Lower32Bits
== 1)
46 if (ExitInfo
.Elements
.Lower32Bits
== 0) {
50 if (ExitInfo
.Elements
.Lower32Bits
== 1) {
51 ASSERT (Ghcb
->SaveArea
.SwExitInfo2
!= 0);
54 // Check that the return event is valid
56 Event
.Uint64
= Ghcb
->SaveArea
.SwExitInfo2
;
57 if (Event
.Elements
.Valid
&&
58 (Event
.Elements
.Type
== GHCB_EVENT_INJECTION_TYPE_EXCEPTION
))
60 switch (Event
.Elements
.Vector
) {
64 // Use returned event as return code
66 Status
= Event
.Uint64
;
72 GHCB_EVENT_INJECTION GpEvent
;
75 GpEvent
.Elements
.Vector
= GP_EXCEPTION
;
76 GpEvent
.Elements
.Type
= GHCB_EVENT_INJECTION_TYPE_EXCEPTION
;
77 GpEvent
.Elements
.Valid
= 1;
79 Status
= GpEvent
.Uint64
;
88 Sets the necessary fields of the GHCB, invokes the VMGEXIT instruction and
89 then handles the return actions.
91 @param[in, out] Ghcb A pointer to the GHCB
92 @param[in] ExitCode VMGEXIT code to be assigned to the SwExitCode
94 @param[in] ExitInfo1 VMGEXIT information to be assigned to the
95 SwExitInfo1 field of the GHCB.
96 @param[in] ExitInfo2 VMGEXIT information to be assigned to the
97 SwExitInfo2 field of the GHCB.
99 @retval 0 VMGEXIT succeeded.
100 @return Exception number to be propagated, VMGEXIT
101 processing did not succeed.
113 Ghcb
->SaveArea
.SwExitCode
= ExitCode
;
114 Ghcb
->SaveArea
.SwExitInfo1
= ExitInfo1
;
115 Ghcb
->SaveArea
.SwExitInfo2
= ExitInfo2
;
117 VmgSetOffsetValid (Ghcb
, GhcbSwExitCode
);
118 VmgSetOffsetValid (Ghcb
, GhcbSwExitInfo1
);
119 VmgSetOffsetValid (Ghcb
, GhcbSwExitInfo2
);
122 // Guest memory is used for the guest-hypervisor communication, so fence
123 // the invocation of the VMGEXIT instruction to ensure GHCB accesses are
124 // synchronized properly.
130 return VmgExitErrorCheck (Ghcb
);
134 Perform pre-VMGEXIT initialization/preparation.
136 Performs the necessary steps in preparation for invoking VMGEXIT. Must be
137 called before setting any fields within the GHCB.
139 @param[in, out] Ghcb A pointer to the GHCB
140 @param[in, out] InterruptState A pointer to hold the current interrupt
141 state, used for restoring in VmgDone ()
148 IN OUT BOOLEAN
*InterruptState
152 // Be sure that an interrupt can't cause a #VC while the GHCB is
155 *InterruptState
= GetInterruptState ();
156 if (*InterruptState
) {
157 DisableInterrupts ();
160 SetMem (&Ghcb
->SaveArea
, sizeof (Ghcb
->SaveArea
), 0);
164 Perform post-VMGEXIT cleanup.
166 Performs the necessary steps to cleanup after invoking VMGEXIT. Must be
167 called after obtaining needed fields within the GHCB.
169 @param[in, out] Ghcb A pointer to the GHCB
170 @param[in] InterruptState An indicator to conditionally (re)enable
178 IN BOOLEAN InterruptState
181 if (InterruptState
) {
187 Marks a field at the specified offset as valid in the GHCB.
189 The ValidBitmap area represents the areas of the GHCB that have been marked
190 valid. Set the bit in ValidBitmap for the input offset.
192 @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication Block
193 @param[in] Offset Qword offset in the GHCB to mark valid
200 IN GHCB_REGISTER Offset
206 OffsetIndex
= Offset
/ 8;
207 OffsetBit
= Offset
% 8;
209 Ghcb
->SaveArea
.ValidBitmap
[OffsetIndex
] |= (1 << OffsetBit
);
213 Checks if a specified offset is valid in the GHCB.
215 The ValidBitmap area represents the areas of the GHCB that have been marked
216 valid. Return whether the bit in the ValidBitmap is set for the input offset.
218 @param[in] Ghcb A pointer to the GHCB
219 @param[in] Offset Qword offset in the GHCB to mark valid
221 @retval TRUE Offset is marked valid in the GHCB
222 @retval FALSE Offset is not marked valid in the GHCB
229 IN GHCB_REGISTER Offset
235 OffsetIndex
= Offset
/ 8;
236 OffsetBit
= Offset
% 8;
238 return ((Ghcb
->SaveArea
.ValidBitmap
[OffsetIndex
] & (1 << OffsetBit
)) != 0);