TianoCore EDK2 master
VmgExitLib.c
Go to the documentation of this file.
1
9#include <Base.h>
10#include <Uefi.h>
12#include <Library/VmgExitLib.h>
13#include <Register/Amd/Msr.h>
14
29UINT64
31 IN GHCB *Ghcb
32 )
33{
35 GHCB_EXIT_INFO ExitInfo;
36 UINT64 Status;
37
38 ExitInfo.Uint64 = Ghcb->SaveArea.SwExitInfo1;
39 ASSERT (
40 (ExitInfo.Elements.Lower32Bits == 0) ||
41 (ExitInfo.Elements.Lower32Bits == 1)
42 );
43
44 Status = 0;
45 if (ExitInfo.Elements.Lower32Bits == 0) {
46 return Status;
47 }
48
49 if (ExitInfo.Elements.Lower32Bits == 1) {
50 ASSERT (Ghcb->SaveArea.SwExitInfo2 != 0);
51
52 //
53 // Check that the return event is valid
54 //
55 Event.Uint64 = Ghcb->SaveArea.SwExitInfo2;
56 if (Event.Elements.Valid &&
57 (Event.Elements.Type == GHCB_EVENT_INJECTION_TYPE_EXCEPTION))
58 {
59 switch (Event.Elements.Vector) {
60 case GP_EXCEPTION:
61 case UD_EXCEPTION:
62 //
63 // Use returned event as return code
64 //
65 Status = Event.Uint64;
66 }
67 }
68 }
69
70 if (Status == 0) {
72
73 GpEvent.Uint64 = 0;
74 GpEvent.Elements.Vector = GP_EXCEPTION;
75 GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
76 GpEvent.Elements.Valid = 1;
77
78 Status = GpEvent.Uint64;
79 }
80
81 return Status;
82}
83
103UINT64
104EFIAPI
106 IN OUT GHCB *Ghcb,
107 IN UINT64 ExitCode,
108 IN UINT64 ExitInfo1,
109 IN UINT64 ExitInfo2
110 )
111{
112 Ghcb->SaveArea.SwExitCode = ExitCode;
113 Ghcb->SaveArea.SwExitInfo1 = ExitInfo1;
114 Ghcb->SaveArea.SwExitInfo2 = ExitInfo2;
115
116 VmgSetOffsetValid (Ghcb, GhcbSwExitCode);
117 VmgSetOffsetValid (Ghcb, GhcbSwExitInfo1);
118 VmgSetOffsetValid (Ghcb, GhcbSwExitInfo2);
119
120 //
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.
124 //
125 MemoryFence ();
126 AsmVmgExit ();
127 MemoryFence ();
128
129 return VmgExitErrorCheck (Ghcb);
130}
131
143VOID
144EFIAPI
146 IN OUT GHCB *Ghcb,
147 IN OUT BOOLEAN *InterruptState
148 )
149{
150 //
151 // Be sure that an interrupt can't cause a #VC while the GHCB is
152 // being used.
153 //
154 *InterruptState = GetInterruptState ();
155 if (*InterruptState) {
157 }
158
159 SetMem (&Ghcb->SaveArea, sizeof (Ghcb->SaveArea), 0);
160}
161
173VOID
174EFIAPI
176 IN OUT GHCB *Ghcb,
177 IN BOOLEAN InterruptState
178 )
179{
180 if (InterruptState) {
182 }
183}
184
195VOID
196EFIAPI
198 IN OUT GHCB *Ghcb,
199 IN GHCB_REGISTER Offset
200 )
201{
202 UINT32 OffsetIndex;
203 UINT32 OffsetBit;
204
205 OffsetIndex = Offset / 8;
206 OffsetBit = Offset % 8;
207
208 Ghcb->SaveArea.ValidBitmap[OffsetIndex] |= (1 << OffsetBit);
209}
210
224BOOLEAN
225EFIAPI
227 IN GHCB *Ghcb,
228 IN GHCB_REGISTER Offset
229 )
230{
231 UINT32 OffsetIndex;
232 UINT32 OffsetBit;
233
234 OffsetIndex = Offset / 8;
235 OffsetBit = Offset % 8;
236
237 return ((Ghcb->SaveArea.ValidBitmap[OffsetIndex] & (1 << OffsetBit)) != 0);
238}
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
BOOLEAN EFIAPI GetInterruptState(VOID)
Definition: CpuBreakpoint.c:86
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
VOID EFIAPI EnableInterrupts(VOID)
Definition: CpuBreakpoint.c:67
VOID EFIAPI DisableInterrupts(VOID)
Definition: CpuBreakpoint.c:54
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
#define ASSERT(Expression)
Definition: DebugLib.h:391
VOID EFIAPI VmgSetOffsetValid(IN OUT GHCB *Ghcb, IN GHCB_REGISTER Offset)
Definition: VmgExitLib.c:197
BOOLEAN EFIAPI VmgIsOffsetValid(IN GHCB *Ghcb, IN GHCB_REGISTER Offset)
Definition: VmgExitLib.c:226
UINT64 EFIAPI VmgExit(IN OUT GHCB *Ghcb, IN UINT64 ExitCode, IN UINT64 ExitInfo1, IN UINT64 ExitInfo2)
Definition: VmgExitLib.c:105
VOID EFIAPI VmgInit(IN OUT GHCB *Ghcb, IN OUT BOOLEAN *InterruptState)
Definition: VmgExitLib.c:145
STATIC UINT64 VmgExitErrorCheck(IN GHCB *Ghcb)
Definition: VmgExitLib.c:30
VOID EFIAPI VmgDone(IN OUT GHCB *Ghcb, IN BOOLEAN InterruptState)
Definition: VmgExitLib.c:175