HyperDbg Debugger
Loading...
Searching...
No Matches
Hv.h File Reference

This file contains the headers for Hypervisor Routines which have to be called by external codes. More...

Go to the source code of this file.

Functions

BOOLEAN HvSetGuestSelector (PVOID GdtBase, UINT32 SegmentRegister, UINT16 Selector)
 Set Guest Selector Registers.
 
UINT32 HvAdjustControls (UINT32 Ctl, UINT32 Msr)
 Returns the Cpu Based and Secondary Processor Based Controls and other controls based on hardware support.
 
VOID HvHandleCpuid (VIRTUAL_MACHINE_STATE *VCpu)
 Handle Cpuid.
 
VOID HvFillGuestSelectorData (PVOID GdtBase, UINT32 SegmentRegister, UINT16 Selector)
 Fill guest selector data.
 
VOID HvHandleControlRegisterAccess (VIRTUAL_MACHINE_STATE *VCpu, VMX_EXIT_QUALIFICATION_MOV_CR *CrExitQualification)
 Handle Guest's Control Registers Access.
 
VOID HvResumeToNextInstruction ()
 Resume GUEST_RIP to next instruction.
 
VOID HvSuppressRipIncrement (VIRTUAL_MACHINE_STATE *VCpu)
 Suppress the incrementation of RIP.
 
VOID HvPerformRipIncrement (VIRTUAL_MACHINE_STATE *VCpu)
 Perform the incrementation of RIP.
 
VOID HvSetMonitorTrapFlag (BOOLEAN Set)
 Set or unset the monitor trap flags.
 
VOID HvSetRflagTrapFlag (BOOLEAN Set)
 Set the rflag's trap flag.
 
VOID HvSetLoadDebugControls (BOOLEAN Set)
 Set LOAD DEBUG CONTROLS on Vm-entry controls.
 
VOID HvSetSaveDebugControls (BOOLEAN Set)
 Set SAVE DEBUG CONTROLS on Vm-exit controls.
 
VOID HvRestoreRegisters ()
 Reset GDTR/IDTR and other old when you do vmxoff as the patchguard will detect them left modified.
 
VOID HvSetPmcVmexit (BOOLEAN Set)
 Set vm-exit for rdpmc instructions.
 
VOID HvSetMovControlRegsExiting (BOOLEAN Set, UINT64 ControlRegister, UINT64 MaskRegister)
 Set vm-exit for mov-to-cr0/4.
 
VOID HvSetMovToCr3Vmexit (VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
 Set vm-exit for mov-to-cr3.
 
VOID HvWriteExceptionBitmap (UINT32 BitmapMask)
 Write to the exception bitmap.
 
UINT32 HvReadExceptionBitmap ()
 Read the exception bitmap.
 
VOID HvSetInterruptWindowExiting (BOOLEAN Set)
 Set Interrupt-window exiting.
 
VOID HvSetPmlEnableFlag (BOOLEAN Set)
 Set Page Modification Logging Enable bit.
 
VOID HvSetModeBasedExecutionEnableFlag (BOOLEAN Set)
 Set Mode-based Execution Control (MBEC) Enable bit.
 
VOID HvSetNmiWindowExiting (BOOLEAN Set)
 Set NMI-window exiting.
 
VOID HvHandleMovDebugRegister (VIRTUAL_MACHINE_STATE *VCpu)
 Handle Mov to Debug Registers Exitings.
 
VOID HvSetMovDebugRegsExiting (VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
 Set the Mov to Debug Registers Exiting.
 
VOID HvSetNmiExiting (BOOLEAN Set)
 Set the NMI Exiting.
 
VOID HvSetVmxPreemptionTimerExiting (BOOLEAN Set)
 Set the VMX Preemptiom Timer.
 
VOID HvSetExceptionBitmap (VIRTUAL_MACHINE_STATE *VCpu, UINT32 IdtIndex)
 Set exception bitmap in VMCS.
 
VOID HvUnsetExceptionBitmap (VIRTUAL_MACHINE_STATE *VCpu, UINT32 IdtIndex)
 Unset exception bitmap in VMCS.
 
VOID HvSetExternalInterruptExiting (VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
 Set the External Interrupt Exiting.
 
VOID HvEnableAndCheckForPreviousExternalInterrupts (VIRTUAL_MACHINE_STATE *VCpu)
 Checks to enable and reinject previous interrupts.
 
VOID HvSetRdtscExiting (VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
 Set the RDTSC/P Exiting.
 
UINT16 HvGetCsSelector ()
 Read CS selector.
 
UINT64 HvGetRflags ()
 Read guest's RFLAGS.
 
VOID HvSetRflags (UINT64 Rflags)
 Set guest's RFLAGS.
 
UINT64 HvGetRip ()
 Read guest's RIP.
 
VOID HvSetRip (UINT64 Rip)
 Set guest's RIP.
 
UINT64 HvGetInterruptibilityState ()
 Read guest's interruptibility state.
 
UINT64 HvClearSteppingBits (UINT64 Interruptibility)
 Clear STI and MOV SS bits.
 
VOID HvSetInterruptibilityState (UINT64 InterruptibilityState)
 Set guest's interruptibility state.
 
VOID HvInjectPendingExternalInterrupts (VIRTUAL_MACHINE_STATE *VCpu)
 Inject pending external interrupts.
 
VOID HvCheckAndEnableExternalInterrupts (VIRTUAL_MACHINE_STATE *VCpu)
 Check and enable external interrupts.
 
VOID HvDisableExternalInterruptsAndInterruptWindow (VIRTUAL_MACHINE_STATE *VCpu)
 Disable external-interrupts and interrupt window.
 
BOOLEAN HvInitVmm (VMM_CALLBACKS *VmmCallbacks)
 Initializes the hypervisor.
 
VOID HvEnableMtfAndChangeExternalInterruptState (VIRTUAL_MACHINE_STATE *VCpu)
 Enables MTF and adjust external interrupt state.
 
VOID HvPreventExternalInterrupts (VIRTUAL_MACHINE_STATE *VCpu)
 Adjust external interrupt state.
 

Detailed Description

This file contains the headers for Hypervisor Routines which have to be called by external codes.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)

DO NOT DIRECTLY CALL VMX FUNCTIONS, instead use these routines

Version
0.1
Date
2020-04-11

Function Documentation

◆ HvAdjustControls()

UINT32 HvAdjustControls ( UINT32 Ctl,
UINT32 Msr )

Returns the Cpu Based and Secondary Processor Based Controls and other controls based on hardware support.

Parameters
Ctl
Msr
Returns
UINT32

Returns the Cpu Based and Secondary Processor Based Controls and other controls based on hardware support.

Parameters
Ctl
Msr
Returns
UINT32 Returns the Cpu Based and Secondary Processor Based Controls and other controls based on hardware support
24{
25 MSR MsrValue = {0};
26
27 MsrValue.Flags = __readmsr(Msr);
28 Ctl &= MsrValue.Fields.High; /* bit == 0 in high word ==> must be zero */
29 Ctl |= MsrValue.Fields.Low; /* bit == 1 in low word ==> must be one */
30 return Ctl;
31}
General MSR Structure.
Definition Msr.h:23
struct _MSR::@1 Fields
UINT64 Flags
Definition Msr.h:30
ULONG Low
Definition Msr.h:26
ULONG High
Definition Msr.h:27

◆ HvCheckAndEnableExternalInterrupts()

VOID HvCheckAndEnableExternalInterrupts ( VIRTUAL_MACHINE_STATE * VCpu)

Check and enable external interrupts.

Parameters
VCpuThe virtual processor's state
Returns
VOID
1272{
1273 //
1274 // Check if we should enable interrupts in this core or not
1275 //
1277 {
1278 //
1279 // Enable normal interrupts
1280 //
1282
1283 //
1284 // Check if there is at least an interrupt that needs to be delivered
1285 //
1287
1289 }
1290}
#define FALSE
Definition BasicTypes.h:54
VOID HvSetExternalInterruptExiting(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
Set the External Interrupt Exiting.
Definition Hv.c:1055
VOID HvInjectPendingExternalInterrupts(VIRTUAL_MACHINE_STATE *VCpu)
Inject pending external interrupts.
Definition Hv.c:1249
BOOLEAN EnableExternalInterruptsOnContinue
Definition State.h:296

◆ HvClearSteppingBits()

UINT64 HvClearSteppingBits ( UINT64 Interruptibility)

Clear STI and MOV SS bits.

Returns
UINT64
1221{
1222 UINT64 InterruptibilityState = Interruptibility;
1223
1224 InterruptibilityState &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS);
1225
1226 return InterruptibilityState;
1227}
unsigned __int64 UINT64
Definition BasicTypes.h:21
#define GUEST_INTR_STATE_STI
GUEST_INTERRUPTIBILITY_INFO flags.
Definition Vmx.h:123
#define GUEST_INTR_STATE_MOV_SS
Definition Vmx.h:124

◆ HvDisableExternalInterruptsAndInterruptWindow()

VOID HvDisableExternalInterruptsAndInterruptWindow ( VIRTUAL_MACHINE_STATE * VCpu)

Disable external-interrupts and interrupt window.

Parameters
VCpuThe virtual processor's state
Returns
VOID
1301{
1302 //
1303 // Change guest interrupt-state
1304 //
1306
1307 //
1308 // Do not vm-exit on interrupt windows
1309 //
1311
1313}
#define TRUE
Definition BasicTypes.h:55
VOID HvSetInterruptWindowExiting(BOOLEAN Set)
Set Interrupt-window exiting.
Definition Hv.c:606

◆ HvEnableAndCheckForPreviousExternalInterrupts()

VOID HvEnableAndCheckForPreviousExternalInterrupts ( VIRTUAL_MACHINE_STATE * VCpu)

Checks to enable and reinject previous interrupts.

Parameters
VCpuThe virtual processor's state
SetSet or unset the External Interrupt Exiting
Returns
VOID
1073{
1074 //
1075 // Check if we should enable interrupts in this core or not,
1076 // we have another same check in SWITCHING CORES too
1077 //
1079 {
1080 //
1081 // Enable normal interrupts
1082 //
1084
1085 //
1086 // Check if there is at least an interrupt that needs to be delivered
1087 //
1088 if (VCpu->PendingExternalInterrupts[0] != NULL_ZERO)
1089 {
1090 //
1091 // Enable Interrupt-window exiting.
1092 //
1094 }
1095
1097 }
1098}
#define NULL_ZERO
Definition BasicTypes.h:51
BOOLEAN EnableExternalInterruptsOnContinueMtf
Definition State.h:297
UINT32 PendingExternalInterrupts[PENDING_INTERRUPTS_BUFFER_CAPACITY]
Definition State.h:322

◆ HvEnableMtfAndChangeExternalInterruptState()

VOID HvEnableMtfAndChangeExternalInterruptState ( VIRTUAL_MACHINE_STATE * VCpu)

Enables MTF and adjust external interrupt state.

Returns
VOID
Parameters
VCpuThe virtual processor's state
Returns
VOID
1390{
1391 //
1392 // We have to set Monitor trap flag and give it the HookedEntry to work with
1393 //
1395
1396 //
1397 // The following codes are added because we realized if the execution takes long then
1398 // the execution might be switched to another routines, thus, MTF might conclude on
1399 // another routine and we might (and will) trigger the same instruction soon
1400 //
1401
1402 //
1403 // Change guest interrupt-state
1404 //
1406
1407 //
1408 // Do not vm-exit on interrupt windows
1409 //
1411
1412 //
1413 // Indicate that we should enable external interrupts and configure external interrupt
1414 // window exiting somewhere at MTF
1415 //
1417}
VOID HvSetMonitorTrapFlag(BOOLEAN Set)
Set the monitor trap flag.
Definition Hv.c:349

◆ HvFillGuestSelectorData()

VOID HvFillGuestSelectorData ( PVOID GdtBase,
UINT32 SegmentRegister,
UINT16 Selector )

Fill guest selector data.

Parameters
GdtBase
SegmentRegister
Selector
Returns
VOID

Fill guest selector data.

Parameters
GdtBase
SegmentRegister
Selector
Returns
VOID
277{
279
281
282 if (Selector == 0x0)
283 {
285 }
286
289
290 VmxVmwrite64(VMCS_GUEST_ES_SELECTOR + SegmentRegister * 2, Selector);
291 VmxVmwrite64(VMCS_GUEST_ES_LIMIT + SegmentRegister * 2, SegmentSelector.Limit);
292 VmxVmwrite64(VMCS_GUEST_ES_ACCESS_RIGHTS + SegmentRegister * 2, SegmentSelector.Attributes.AsUInt);
293 VmxVmwrite64(VMCS_GUEST_ES_BASE + SegmentRegister * 2, SegmentSelector.Base);
294}
_Use_decl_annotations_ BOOLEAN SegmentGetDescriptor(PUCHAR GdtBase, UINT16 Selector, PVMX_SEGMENT_SELECTOR SegmentSelector)
Get Segment Descriptor.
Definition Segmentation.c:24
_In_ UINT16 Selector
Definition Segmentation.h:50
_In_ UINT16 _Out_ PVMX_SEGMENT_SELECTOR SegmentSelector
Definition Segmentation.h:51
UCHAR VmxVmwrite64(size_t Field, UINT64 FieldValue)
VMX VMWRITE instruction (64-bit)
Definition Vmx.c:122
Segment selector.
Definition DataTypes.h:436
UINT32 Limit
Definition DataTypes.h:439
VMX_SEGMENT_ACCESS_RIGHTS_TYPE Attributes
Definition DataTypes.h:438
UINT64 Base
Definition DataTypes.h:440
UINT32 AsUInt
Definition DataTypes.h:428
UINT32 Reserved1
Definition DataTypes.h:400
UINT32 Reserved2
Definition DataTypes.h:425
UINT32 Unusable
Definition DataTypes.h:424

◆ HvGetCsSelector()

UINT16 HvGetCsSelector ( )

Read CS selector.

Returns
UINT16
1133{
1134 //
1135 // Only 16 bit is needed however, vmwrite might write on other bits
1136 // and corrupt other variables, that's why we get 64bit
1137 //
1138 UINT64 CsSel = NULL64_ZERO;
1139
1140 __vmx_vmread(VMCS_GUEST_CS_SELECTOR, &CsSel);
1141
1142 return CsSel & 0xffff;
1143}
#define NULL64_ZERO
Definition BasicTypes.h:52

◆ HvGetInterruptibilityState()

UINT64 HvGetInterruptibilityState ( )

Read guest's interruptibility state.

Returns
UINT64
1206{
1207 UINT64 InterruptibilityState = NULL64_ZERO;
1208
1209 __vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
1210
1211 return InterruptibilityState;
1212}

◆ HvGetRflags()

UINT64 HvGetRflags ( )

Read guest's RFLAGS.

Returns
UINT64
1152{
1153 UINT64 Rflags = NULL64_ZERO;
1154
1155 __vmx_vmread(VMCS_GUEST_RFLAGS, &Rflags);
1156
1157 return Rflags;
1158}

◆ HvGetRip()

UINT64 HvGetRip ( )

Read guest's RIP.

Returns
UINT64
1179{
1180 UINT64 Rip = NULL64_ZERO;
1181
1182 __vmx_vmread(VMCS_GUEST_RIP, &Rip);
1183
1184 return Rip;
1185}

◆ HvHandleControlRegisterAccess()

VOID HvHandleControlRegisterAccess ( VIRTUAL_MACHINE_STATE * VCpu,
VMX_EXIT_QUALIFICATION_MOV_CR * CrExitQualification )

Handle Guest's Control Registers Access.

Parameters
VCpu
Returns
VOID

Handle Guest's Control Registers Access.

Parameters
VCpuThe virtual processor's state
Returns
VOID
138{
139 UINT64 * RegPtr;
140 UINT64 NewCr3;
141 CR3_TYPE NewCr3Reg;
142
143 RegPtr = (UINT64 *)&VCpu->Regs->rax + CrExitQualification->GeneralPurposeRegister;
144
145 //
146 // Because its RSP and as we didn't save RSP correctly (because of pushes)
147 // so we have make it points to the GUEST_RSP
148 //
149
150 //
151 // We handled it in vm-exit handler, commented
152 //
153
154 /*
155 if (CrExitQualification->Fields.Register == 4)
156 {
157 __vmx_vmread(VMCS_GUEST_RSP, &GuestRsp);
158 *RegPtr = GuestRsp;
159 }
160 */
161
162 switch (CrExitQualification->AccessType)
163 {
164 case VMX_EXIT_QUALIFICATION_ACCESS_MOV_TO_CR:
165 {
166 switch (CrExitQualification->ControlRegister)
167 {
168 case VMX_EXIT_QUALIFICATION_REGISTER_CR0:
169
170 VmxVmwrite64(VMCS_GUEST_CR0, *RegPtr);
171 VmxVmwrite64(VMCS_CTRL_CR0_READ_SHADOW, *RegPtr);
172
173 break;
174
175 case VMX_EXIT_QUALIFICATION_REGISTER_CR3:
176
177 NewCr3 = (*RegPtr & ~(1ULL << 63));
178 NewCr3Reg.Flags = NewCr3;
179
180 //
181 // Apply the new cr3
182 //
183 VmxVmwrite64(VMCS_GUEST_CR3, NewCr3Reg.Flags);
184
185 //
186 // Invalidate as we used VPID tags so the vm-exit won't
187 // normally (automatically) flush the TLB, we have to do
188 // it manually
189 //
191
192 //
193 // Call kernel debugger handler for mov to cr3 in kernel debugger
194 //
196
197 //
198 // Call user debugger handler of thread intercepting mechanism
199 //
201 {
203 }
204
205 //
206 // Call handler of the reversing machine
207 //
209 {
211 }
212
213 break;
214
215 case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
216
217 VmxVmwrite64(VMCS_GUEST_CR4, *RegPtr);
218 VmxVmwrite64(VMCS_CTRL_CR4_READ_SHADOW, *RegPtr);
219
220 break;
221
222 default:
223 LogWarning("Unsupported register 0x%x in handling control registers access",
224 CrExitQualification->ControlRegister);
225 break;
226 }
227 }
228 break;
229
230 case VMX_EXIT_QUALIFICATION_ACCESS_MOV_FROM_CR:
231 {
232 switch (CrExitQualification->ControlRegister)
233 {
234 case VMX_EXIT_QUALIFICATION_REGISTER_CR0:
235
236 __vmx_vmread(VMCS_GUEST_CR0, RegPtr);
237
238 break;
239
240 case VMX_EXIT_QUALIFICATION_REGISTER_CR3:
241
242 __vmx_vmread(VMCS_GUEST_CR3, RegPtr);
243
244 break;
245
246 case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
247
248 __vmx_vmread(VMCS_GUEST_CR4, RegPtr);
249
250 break;
251
252 default:
253 LogWarning("Unsupported register 0x%x in handling control registers access",
254 CrExitQualification->ControlRegister);
255 break;
256 }
257 }
258 break;
259
260 default:
261 LogWarning("Unsupported operation 0x%x in handling control registers access",
262 CrExitQualification->AccessType);
263 break;
264 }
265}
VOID InterceptionCallbackCr3VmexitsForThreadInterception(UINT32 CoreId, CR3_TYPE NewCr3)
routine callback to handle cr3 process change
Definition Callback.c:428
VOID InterceptionCallbackTriggerCr3ProcessChange(UINT32 CoreId)
routine callback to handle cr3 process change
Definition Callback.c:406
VOID ExecTrapHandleCr3Vmexit(VIRTUAL_MACHINE_STATE *VCpu)
Handle MOV to CR3 vm-exits for hooking mode execution.
Definition ExecTrap.c:847
BOOLEAN g_CheckPageFaultsAndMov2Cr3VmexitsWithUserDebugger
Whether the page-fault and cr3 vm-exits in vmx-root should check the #PFs or the PML4....
Definition GlobalVariables.h:114
BOOLEAN g_ExecTrapInitialized
Showes whether the execution trap handler is allowed to trigger an event or not.
Definition GlobalVariables.h:149
#define LogWarning(format,...)
Log in the case of warning.
Definition HyperDbgHyperLogIntrinsics.h:99
VOID VpidInvvpidSingleContext(UINT16 Vpid)
INVVPID Single Context.
Definition Vpid.c:62
#define VPID_TAG
VPID Tag.
Definition Vpid.h:30
CR3 Structure.
Definition BasicTypes.h:130
GUEST_REGS * Regs
Definition State.h:305
UINT32 CoreId
Definition State.h:306
UINT64 rax
Definition BasicTypes.h:75

◆ HvHandleCpuid()

VOID HvHandleCpuid ( VIRTUAL_MACHINE_STATE * VCpu)

Handle Cpuid.

Parameters
VCpu
Returns
VOID

Handle Cpuid.

Parameters
VCpuThe virtual processor's state
Returns
VOID
68{
69 INT32 CpuInfo[4];
70 PGUEST_REGS Regs = VCpu->Regs;
71
72 //
73 // Otherwise, issue the CPUID to the logical processor based on the indexes
74 // on the VP's GPRs.
75 //
76 __cpuidex(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
77
78 //
79 // check whether we are in transparent mode or not
80 // if we are in transparent mode then ignore the
81 // cpuid modifications e.g. hyperviosr name or bit
82 //
84 {
85 //
86 // Check if this was CPUID 1h, which is the features request
87 //
89 {
90 //
91 // Set the Hypervisor Present-bit in RCX, which Intel and AMD have both
92 // reserved for this indication
93 //
95 }
96 else if (Regs->rax == CPUID_HV_VENDOR_AND_MAX_FUNCTIONS)
97 {
98 //
99 // Return a maximum supported hypervisor CPUID leaf range and a vendor
100 // ID signature as required by the spec
101 //
102
103 CpuInfo[0] = HYPERV_CPUID_INTERFACE;
104 CpuInfo[1] = 'epyH'; // [HyperDbg]
105 CpuInfo[2] = 'gbDr';
106 CpuInfo[3] = 0;
107 }
108 else if (Regs->rax == HYPERV_CPUID_INTERFACE)
109 {
110 //
111 // Return non Hv#1 value. This indicate that our hypervisor does NOT
112 // conform to the Microsoft hypervisor interface.
113 //
114
115 CpuInfo[0] = '0#vH'; // Hv#0
116 CpuInfo[1] = CpuInfo[2] = CpuInfo[3] = 0;
117 }
118 }
119
120 //
121 // Copy the values from the logical processor registers into the VP GPRs
122 //
123 Regs->rax = CpuInfo[0];
124 Regs->rbx = CpuInfo[1];
125 Regs->rcx = CpuInfo[2];
126 Regs->rdx = CpuInfo[3];
127}
signed int INT32
Definition BasicTypes.h:44
BOOLEAN g_TransparentMode
Shows whether the debugger transparent mode is enabled (true) or not (false)
Definition GlobalVariables.h:75
#define HYPERV_CPUID_INTERFACE
Definition HypervTlfs.h:15
#define HYPERV_HYPERVISOR_PRESENT_BIT
Definition HypervTlfs.h:31
#define CPUID_PROCESSOR_AND_PROCESSOR_FEATURE_IDENTIFIERS
CPUID Features.
Definition Common.h:157
#define CPUID_HV_VENDOR_AND_MAX_FUNCTIONS
The Microsoft Hypervisor interface defined constants.
Definition Common.h:144
Definition BasicTypes.h:70
UINT64 rbx
Definition BasicTypes.h:78
UINT64 rcx
Definition BasicTypes.h:76
UINT64 rdx
Definition BasicTypes.h:77

◆ HvHandleMovDebugRegister()

VOID HvHandleMovDebugRegister ( VIRTUAL_MACHINE_STATE * VCpu)

Handle Mov to Debug Registers Exitings.

Parameters
VCpu
Returns
VOID
Parameters
VCpuThe virtual processor's state
Returns
VOID
749{
750 VMX_EXIT_QUALIFICATION_MOV_DR ExitQualification;
751 CR4 Cr4;
752 DR7 Dr7;
754 UINT64 * GpRegs = (UINT64 *)VCpu->Regs;
755
756 //
757 // The implementation is derived from Hvpp
758 //
759 VmxVmread64P(VMCS_EXIT_QUALIFICATION, &ExitQualification.AsUInt);
760
761 UINT64 GpRegister = GpRegs[ExitQualification.GeneralPurposeRegister];
762
763 //
764 // The MOV DR instruction causes a VM exit if the "MOV-DR exiting"
765 // VM-execution control is 1. Such VM exits represent an exception
766 // to the principles identified in Section 25.1.1 (Relative Priority
767 // of Faults and VM Exits) in that they take priority over the
768 // following: general-protection exceptions based on privilege level;
769 // and invalid-opcode exceptions that occur because CR4.DE = 1 and the
770 // instruction specified access to DR4 or DR5.
771 // (ref: Vol3C[25.1.3(Instructions That Cause VM Exits Conditionally)])
772 //
773 // TL;DR:
774 // CPU usually prioritizes exceptions. For example RDMSR executed
775 // at CPL = 3 won't cause VM-exit - it causes #GP instead. MOV DR
776 // is exception to this rule, as it ALWAYS cause VM-exit.
777 //
778 // Normally, CPU allows you to write to DR registers only at CPL=0,
779 // otherwise it causes #GP. Therefore we'll simulate the exact same
780 // behavior here.
781 //
782
783 Cs = GetGuestCs();
784
785 if (Cs.Attributes.DescriptorPrivilegeLevel != 0)
786 {
788
789 //
790 // Redo the instruction
791 //
793 return;
794 }
795
796 //
797 // Debug registers DR4 and DR5 are reserved when debug extensions
798 // are enabled (when the DE flag in control register CR4 is set)
799 // and attempts to reference the DR4 and DR5 registers cause
800 // invalid-opcode exceptions (#UD).
801 // When debug extensions are not enabled (when the DE flag is clear),
802 // these registers are aliased to debug registers DR6 and DR7.
803 // (ref: Vol3B[17.2.2(Debug Registers DR4 and DR5)])
804 //
805
806 //
807 // Read guest cr4
808 //
809 VmxVmread64P(VMCS_GUEST_CR4, &Cr4.AsUInt);
810
811 if (ExitQualification.DebugRegister == 4 || ExitQualification.DebugRegister == 5)
812 {
813 if (Cr4.DebuggingExtensions)
814 {
815 //
816 // re-inject #UD
817 //
819 return;
820 }
821 else
822 {
823 ExitQualification.DebugRegister += 2;
824 }
825 }
826
827 //
828 // Enables (when set) debug-register protection, which causes a
829 // debug exception to be generated prior to any MOV instruction
830 // that accesses a debug register. When such a condition is
831 // detected, the BD flag in debug status register DR6 is set prior
832 // to generating the exception. This condition is provided to
833 // support in-circuit emulators.
834 // When the emulator needs to access the debug registers, emulator
835 // software can set the GD flag to prevent interference from the
836 // program currently executing on the processor.
837 // The processor clears the GD flag upon entering to the debug
838 // exception handler, to allow the handler access to the debug
839 // registers.
840 // (ref: Vol3B[17.2.4(Debug Control Register (DR7)])
841 //
842
843 //
844 // Read the DR7
845 //
846 VmxVmread64P(VMCS_GUEST_DR7, &Dr7.AsUInt);
847
848 if (Dr7.GeneralDetect)
849 {
850 DR6 Dr6 = {
851 .AsUInt = __readdr(6),
852 .BreakpointCondition = 0,
853 .DebugRegisterAccessDetected = TRUE};
854
855 __writedr(6, Dr6.AsUInt);
856
857 Dr7.GeneralDetect = FALSE;
858
859 VmxVmwrite64(VMCS_GUEST_DR7, Dr7.AsUInt);
860
862
863 //
864 // Redo the instruction
865 //
867
868 return;
869 }
870
871 //
872 // In 64-bit mode, the upper 32 bits of DR6 and DR7 are reserved
873 // and must be written with zeros. Writing 1 to any of the upper
874 // 32 bits results in a #GP(0) exception.
875 // (ref: Vol3B[17.2.6(Debug Registers and Intel 64 Processors)])
876 //
877 if (ExitQualification.DirectionOfAccess == VMX_EXIT_QUALIFICATION_DIRECTION_MOV_TO_DR && (ExitQualification.DebugRegister == VMX_EXIT_QUALIFICATION_REGISTER_DR6 || ExitQualification.DebugRegister == VMX_EXIT_QUALIFICATION_REGISTER_DR7) && (GpRegister >> 32) != 0)
878 {
880
881 //
882 // Redo the instruction
883 //
885 return;
886 }
887
888 switch (ExitQualification.DirectionOfAccess)
889 {
890 case VMX_EXIT_QUALIFICATION_DIRECTION_MOV_TO_DR:
891 switch (ExitQualification.DebugRegister)
892 {
893 case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
894 __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
895 break;
896 case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
897 __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
898 break;
899 case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
900 __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
901 break;
902 case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
903 __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
904 break;
905 case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
906 __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
907 break;
908 case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
909 __writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
910 break;
911 default:
912 break;
913 }
914 break;
915
916 case VMX_EXIT_QUALIFICATION_DIRECTION_MOV_FROM_DR:
917 switch (ExitQualification.DebugRegister)
918 {
919 case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
920 GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
921 break;
922 case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
923 GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
924 break;
925 case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
926 GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
927 break;
928 case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
929 GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
930 break;
931 case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
932 GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
933 break;
934 case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
935 GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
936 break;
937 default:
938 break;
939 }
940
941 default:
942 break;
943 }
944}
VOID EventInjectUndefinedOpcode(VIRTUAL_MACHINE_STATE *VCpu)
Inject #UD to the guest (Invalid Opcode - Undefined Opcode)
Definition Events.c:79
VOID EventInjectDebugBreakpoint()
Inject Debug Breakpoint Exception.
Definition Events.c:112
VOID EventInjectGeneralProtection()
Inject #GP to the guest (Event Injection)
Definition Events.c:62
VOID HvSuppressRipIncrement(VIRTUAL_MACHINE_STATE *VCpu)
Suppress the incrementation of RIP.
Definition Hv.c:324
VMX_SEGMENT_SELECTOR GetGuestCs()
Get the Guest Cs Selector.
Definition ManageRegs.c:49
UCHAR VmxVmread64P(size_t Field, UINT64 *FieldValue)
VMX VMREAD instruction (64-bit)
Definition Vmx.c:72

◆ HvInitVmm()

BOOLEAN HvInitVmm ( VMM_CALLBACKS * VmmCallbacks)

Initializes the hypervisor.

Parameters
VmmCallbacks
Returns
BOOLEAN
1323{
1324 ULONG ProcessorsCount;
1325 BOOLEAN Result = FALSE;
1326
1327 //
1328 // Save the callbacks
1329 //
1330 RtlCopyMemory(&g_Callbacks, VmmCallbacks, sizeof(VMM_CALLBACKS));
1331
1332 //
1333 // Check and define compatibility checks and processor constraints
1334 //
1336
1337 //
1338 // we allocate virtual machine here because
1339 // we want to use its state (vmx-root or vmx non-root) in logs
1340 //
1342
1343 if (!Result)
1344 {
1345 return FALSE;
1346 }
1347
1348 //
1349 // We have a zeroed guest state
1350 //
1351 ProcessorsCount = KeQueryActiveProcessorCount(0);
1352
1353 //
1354 // Set the core's id and initialize memory mapper
1355 //
1356 for (UINT32 i = 0; i < ProcessorsCount; i++)
1357 {
1358 g_GuestState[i].CoreId = i;
1359 }
1360
1361 //
1362 // Initialize memory mapper
1363 //
1365
1366 //
1367 // Make sure that transparent-mode is disabled
1368 //
1370
1371 //
1372 // Not waiting for the interrupt-window to inject page-faults
1373 //
1375
1376 //
1377 // Initializes VMX
1378 //
1379 return VmxInitialize();
1380}
UCHAR BOOLEAN
Definition BasicTypes.h:39
unsigned int UINT32
Definition BasicTypes.h:48
unsigned long ULONG
Definition BasicTypes.h:37
VOID CompatibilityCheckPerformChecks()
Checks for the compatibility features based on current processor @detail NOTE: NOT ALL OF THE CHECKS ...
Definition CompatibilityChecks.c:153
BOOLEAN GlobalGuestStateAllocateZeroedMemory(VOID)
Allocate guest state memory.
Definition GlobalVariableManagement.c:20
VIRTUAL_MACHINE_STATE * g_GuestState
Save the state and variables related to virtualization on each to logical core.
Definition GlobalVariables.h:38
BOOLEAN g_WaitingForInterruptWindowToInjectPageFault
Shows whether the the VMM is waiting to inject a page-fault or not.
Definition GlobalVariables.h:179
VMM_CALLBACKS g_Callbacks
List of callbacks.
Definition GlobalVariables.h:32
VOID MemoryMapperInitialize()
Initialize the Memory Mapper.
Definition MemoryMapper.c:661
BOOLEAN VmxInitialize()
Initialize the VMX operation.
Definition Vmx.c:260
Prototype of each function needed by VMM module.
Definition VMM.h:181

◆ HvInjectPendingExternalInterrupts()

VOID HvInjectPendingExternalInterrupts ( VIRTUAL_MACHINE_STATE * VCpu)

Inject pending external interrupts.

Parameters
VCpuThe virtual processor's state
Returns
VOID
1250{
1251 //
1252 // Check if there is at least an interrupt that needs to be delivered
1253 //
1254 if (VCpu->PendingExternalInterrupts[0] != NULL_ZERO)
1255 {
1256 //
1257 // Enable Interrupt-window exiting.
1258 //
1260 }
1261}

◆ HvPerformRipIncrement()

VOID HvPerformRipIncrement ( VIRTUAL_MACHINE_STATE * VCpu)
externinline

Perform the incrementation of RIP.

Parameters
VCpuThe virtual processor's state
Returns
VOID
338{
339 VCpu->IncrementRip = TRUE;
340}
BOOLEAN IncrementRip
Definition State.h:292

◆ HvPreventExternalInterrupts()

VOID HvPreventExternalInterrupts ( VIRTUAL_MACHINE_STATE * VCpu)

Adjust external interrupt state.

Parameters
VCpuThe virtual processor's state
Returns
VOID
1427{
1428 //
1429 // Change guest interrupt-state
1430 //
1432
1433 //
1434 // Do not vm-exit on interrupt windows
1435 //
1437
1438 //
1439 // Indicate that we should enable external interrupts and configure external interrupt
1440 // window exiting somewhere at MTF
1441 //
1443}

◆ HvReadExceptionBitmap()

UINT32 HvReadExceptionBitmap ( )

Read the exception bitmap.

Returns
UINT32

Read the exception bitmap.

Should be called in vmx-root

Returns
UINT32
588{
589 UINT32 ExceptionBitmap = 0;
590
591 //
592 // Read the current bitmap
593 //
594 VmxVmread32P(VMCS_CTRL_EXCEPTION_BITMAP, &ExceptionBitmap);
595
596 return ExceptionBitmap;
597}
UCHAR VmxVmread32P(size_t Field, UINT32 *FieldValue)
VMX VMREAD instruction (32-bit)
Definition Vmx.c:86

◆ HvRestoreRegisters()

VOID HvRestoreRegisters ( )

Reset GDTR/IDTR and other old when you do vmxoff as the patchguard will detect them left modified.

Returns
VOID
464{
465 UINT64 FsBase;
466 UINT64 GsBase;
467 UINT64 GdtrBase;
468 UINT64 GdtrLimit;
469 UINT64 IdtrBase;
470 UINT64 IdtrLimit;
471
472 //
473 // Restore FS Base
474 //
475 __vmx_vmread(VMCS_GUEST_FS_BASE, &FsBase);
476 __writemsr(IA32_FS_BASE, FsBase);
477
478 //
479 // Restore Gs Base
480 //
481 __vmx_vmread(VMCS_GUEST_GS_BASE, &GsBase);
482 __writemsr(IA32_GS_BASE, GsBase);
483
484 //
485 // Restore GDTR
486 //
487 __vmx_vmread(VMCS_GUEST_GDTR_BASE, &GdtrBase);
488 __vmx_vmread(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
489
490 AsmReloadGdtr((void *)GdtrBase, (unsigned long)GdtrLimit);
491
492 //
493 // Restore IDTR
494 //
495 __vmx_vmread(VMCS_GUEST_IDTR_BASE, &IdtrBase);
496 __vmx_vmread(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
497
498 AsmReloadIdtr((void *)IdtrBase, (unsigned long)IdtrLimit);
499}
void AsmReloadIdtr(void *GdtBase, unsigned long GdtLimit)
Reload new IDTR.
void AsmReloadGdtr(void *GdtBase, unsigned long GdtLimit)
Reload new GDTR.

◆ HvResumeToNextInstruction()

VOID HvResumeToNextInstruction ( )

Resume GUEST_RIP to next instruction.

Returns
VOID

Resume GUEST_RIP to next instruction.

Returns
VOID
303{
304 UINT64 ResumeRIP = NULL64_ZERO;
305 UINT64 CurrentRIP = NULL64_ZERO;
306 size_t ExitInstructionLength = 0;
307
308 __vmx_vmread(VMCS_GUEST_RIP, &CurrentRIP);
309 __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
310
311 ResumeRIP = CurrentRIP + ExitInstructionLength;
312
313 VmxVmwrite64(VMCS_GUEST_RIP, ResumeRIP);
314}

◆ HvSetExceptionBitmap()

VOID HvSetExceptionBitmap ( VIRTUAL_MACHINE_STATE * VCpu,
UINT32 IdtIndex )

Set exception bitmap in VMCS.

Should be called in vmx-root

Parameters
IdtIndex
Returns
VOID

Should be called in vmx-root

Parameters
VCpuThe virtual processor's state
IdtIndexInterrupt Descriptor Table index of exception
Returns
VOID
1023{
1024 //
1025 // This is a wrapper to perform extra checks
1026 //
1027 ProtectedHvSetExceptionBitmap(VCpu, IdtIndex);
1028}
VOID ProtectedHvSetExceptionBitmap(VIRTUAL_MACHINE_STATE *VCpu, UINT32 IdtIndex)
Set exception bitmap in VMCS.
Definition ProtectedHv.c:75

◆ HvSetExternalInterruptExiting()

VOID HvSetExternalInterruptExiting ( VIRTUAL_MACHINE_STATE * VCpu,
BOOLEAN Set )

Set the External Interrupt Exiting.

Parameters
Set
Returns
VOID
Parameters
VCpuThe virtual processor's state
SetSet or unset the External Interrupt Exiting
Returns
VOID
1056{
1057 //
1058 // This is a wrapper to perform extra checks
1059 //
1061}
VOID ProtectedHvSetExternalInterruptExiting(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
Set the External Interrupt Exiting.
Definition ProtectedHv.c:258

◆ HvSetGuestSelector()

BOOLEAN HvSetGuestSelector ( PVOID GdtBase,
UINT32 SegmentRegister,
UINT16 Selector )

Set Guest Selector Registers.

Parameters
GdtBase
SegmentRegister
Selector
Returns
BOOLEAN

Set Guest Selector Registers.

Parameters
GdtBase
SegmentRegister
Selector
Returns
BOOLEAN
43{
46
47 if (Selector == 0x0)
48 {
50 }
51
52 VmxVmwrite64(VMCS_GUEST_ES_SELECTOR + SegmentRegister * 2, Selector);
53 VmxVmwrite64(VMCS_GUEST_ES_LIMIT + SegmentRegister * 2, SegmentSelector.Limit);
54 VmxVmwrite64(VMCS_GUEST_ES_ACCESS_RIGHTS + SegmentRegister * 2, SegmentSelector.Attributes.AsUInt);
55 VmxVmwrite64(VMCS_GUEST_ES_BASE + SegmentRegister * 2, SegmentSelector.Base);
56
57 return TRUE;
58}

◆ HvSetInterruptibilityState()

VOID HvSetInterruptibilityState ( UINT64 InterruptibilityState)

Set guest's interruptibility state.

Parameters
InterruptibilityState
Returns
VOID
1237{
1238 VmxVmwrite64(VMCS_GUEST_INTERRUPTIBILITY_STATE, InterruptibilityState);
1239}

◆ HvSetInterruptWindowExiting()

VOID HvSetInterruptWindowExiting ( BOOLEAN Set)

Set Interrupt-window exiting.

Parameters
Set
Returns
VOID
Parameters
SetSet or unset the Interrupt-window exiting
Returns
VOID
607{
608 UINT32 CpuBasedVmExecControls = 0;
609
610 //
611 // Read the previous flags
612 //
613 VmxVmread32P(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &CpuBasedVmExecControls);
614
615 //
616 // interrupt-window exiting
617 //
618 if (Set)
619 {
620 CpuBasedVmExecControls |= CPU_BASED_VIRTUAL_INTR_PENDING;
621 }
622 else
623 {
624 CpuBasedVmExecControls &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
625 }
626
627 //
628 // Set the new value
629 //
630 VmxVmwrite64(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, CpuBasedVmExecControls);
631}
#define CPU_BASED_VIRTUAL_INTR_PENDING
CPU-Based Controls.
Definition Vmx.h:44

◆ HvSetLoadDebugControls()

VOID HvSetLoadDebugControls ( BOOLEAN Set)

Set LOAD DEBUG CONTROLS on Vm-entry controls.

Parameters
SetSet or unset
Returns
VOID
403{
404 UINT32 VmentryControls = 0;
405
406 //
407 // Read the previous flags
408 //
409 VmxVmread32P(VMCS_CTRL_VMENTRY_CONTROLS, &VmentryControls);
410
411 if (Set)
412 {
413 VmentryControls |= VM_ENTRY_LOAD_DEBUG_CONTROLS;
414 }
415 else
416 {
417 VmentryControls &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS;
418 }
419
420 //
421 // Set the new value
422 //
423 VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
424}
#define VM_ENTRY_LOAD_DEBUG_CONTROLS
VM-entry Control Bits.
Definition Vmx.h:97

◆ HvSetModeBasedExecutionEnableFlag()

VOID HvSetModeBasedExecutionEnableFlag ( BOOLEAN Set)

Set Mode-based Execution Control (MBEC) Enable bit.

Parameters
SetSet or unset the MBEC
Returns
VOID
678{
679 UINT32 AdjSecCtrl;
680 UINT32 SecondaryProcBasedVmExecControls = 0;
681
682 //
683 // Read the previous flags
684 //
685 VmxVmread32P(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &SecondaryProcBasedVmExecControls);
686
687 //
688 // PML enable flag
689 //
690 if (Set)
691 {
692 SecondaryProcBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS2_MODE_BASED_EXECUTE_CONTROL_FOR_EPT_FLAG;
693 }
694 else
695 {
696 SecondaryProcBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS2_MODE_BASED_EXECUTE_CONTROL_FOR_EPT_FLAG;
697 }
698
699 AdjSecCtrl = HvAdjustControls(SecondaryProcBasedVmExecControls, IA32_VMX_PROCBASED_CTLS2);
700
701 //
702 // Set the new value
703 //
704 VmxVmwrite64(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, AdjSecCtrl);
705}
UINT32 HvAdjustControls(UINT32 Ctl, UINT32 Msr)
Adjust controls for VMCS based on processor capability.
Definition Hv.c:23

◆ HvSetMonitorTrapFlag()

VOID HvSetMonitorTrapFlag ( BOOLEAN Set)

Set or unset the monitor trap flags.

Parameters
Set
Returns
VOID

Set or unset the monitor trap flags.

Parameters
SetSet or unset the MTFs
Returns
VOID
350{
351 UINT32 CpuBasedVmExecControls = 0;
352
353 //
354 // Read the previous flags
355 //
356 VmxVmread32P(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &CpuBasedVmExecControls);
357
358 if (Set)
359 {
360 CpuBasedVmExecControls |= CPU_BASED_MONITOR_TRAP_FLAG;
361 }
362 else
363 {
364 CpuBasedVmExecControls &= ~CPU_BASED_MONITOR_TRAP_FLAG;
365 }
366
367 //
368 // Set the new value
369 //
370 VmxVmwrite64(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, CpuBasedVmExecControls);
371}
#define CPU_BASED_MONITOR_TRAP_FLAG
Definition Vmx.h:60

◆ HvSetMovControlRegsExiting()

VOID HvSetMovControlRegsExiting ( BOOLEAN Set,
UINT64 ControlRegister,
UINT64 MaskRegister )

Set vm-exit for mov-to-cr0/4.

Parameters
Set
ControlRegister
MaskRegister
Returns
VOID

Should be called in vmx-root

Parameters
Setor unset the vm-exits
ControlRegister
MaskRegister
Returns
VOID
544{
545 ProtectedHvSetMov2CrExiting(Set, ControlRegister, MaskRegister);
546}
VOID ProtectedHvSetMov2CrExiting(BOOLEAN Set, UINT64 ControlRegister, UINT64 MaskRegister)
Set MOV to CR0/4 Exiting.
Definition ProtectedHv.c:636

◆ HvSetMovDebugRegsExiting()

VOID HvSetMovDebugRegsExiting ( VIRTUAL_MACHINE_STATE * VCpu,
BOOLEAN Set )

Set the Mov to Debug Registers Exiting.

Parameters
Set
Returns
VOID

Set the Mov to Debug Registers Exiting.

Parameters
VCpuThe virtual processor's state
SetSet or unset the Mov to Debug Registers Exiting
Returns
VOID
1122{
1124}
VOID ProtectedHvSetMovDebugRegsExiting(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
Set MOV to HW Debug Regs Exiting.
Definition ProtectedHv.c:583

◆ HvSetMovToCr3Vmexit()

VOID HvSetMovToCr3Vmexit ( VIRTUAL_MACHINE_STATE * VCpu,
BOOLEAN Set )

Set vm-exit for mov-to-cr3.

Parameters
Set
Returns
VOID

Should be called in vmx-root

Parameters
VCpuThe virtual processor's state
SetSet or unset the vm-exits
Returns
VOID
559{
561}
VOID ProtectedHvSetMov2Cr3Exiting(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
Set MOV to CR3 Exiting.
Definition ProtectedHv.c:622

◆ HvSetNmiExiting()

VOID HvSetNmiExiting ( BOOLEAN Set)

Set the NMI Exiting.

Parameters
Set
Returns
VOID
Parameters
SetSet or unset the NMI Exiting
Returns
VOID
954{
955 UINT32 PinBasedControls = 0;
956 UINT32 VmExitControls = 0;
957
958 //
959 // Read the previous flags
960 //
961 VmxVmread32P(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, &PinBasedControls);
962 VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmExitControls);
963
964 if (Set)
965 {
967 VmExitControls |= VM_EXIT_ACK_INTR_ON_EXIT;
968 }
969 else
970 {
971 PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING;
972 VmExitControls &= ~VM_EXIT_ACK_INTR_ON_EXIT;
973 }
974
975 //
976 // Set the new value
977 //
978 VmxVmwrite64(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, PinBasedControls);
979 VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmExitControls);
980}
#define PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING
Definition Vmx.h:35
#define VM_EXIT_ACK_INTR_ON_EXIT
Definition Vmx.h:86

◆ HvSetNmiWindowExiting()

VOID HvSetNmiWindowExiting ( BOOLEAN Set)

Set NMI-window exiting.

Parameters
Set
Returns
VOID
Parameters
SetSet or unset the NMI-window exiting
Returns
VOID
715{
716 UINT32 CpuBasedVmExecControls = 0;
717
718 //
719 // Read the previous flags
720 //
721 VmxVmread32P(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &CpuBasedVmExecControls);
722
723 //
724 // interrupt-window exiting
725 //
726 if (Set)
727 {
728 CpuBasedVmExecControls |= CPU_BASED_VIRTUAL_NMI_PENDING;
729 }
730 else
731 {
732 CpuBasedVmExecControls &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
733 }
734
735 //
736 // Set the new value
737 //
738 VmxVmwrite64(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, CpuBasedVmExecControls);
739}
#define CPU_BASED_VIRTUAL_NMI_PENDING
Definition Vmx.h:56

◆ HvSetPmcVmexit()

VOID HvSetPmcVmexit ( BOOLEAN Set)

Set vm-exit for rdpmc instructions.

Parameters
Set
Returns
VOID

Should be called in vmx-root

Parameters
SetSet or unset the vm-exits
Returns
VOID
510{
511 UINT32 CpuBasedVmExecControls = 0;
512
513 //
514 // Read the previous flags
515 //
516 VmxVmread32P(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &CpuBasedVmExecControls);
517
518 if (Set)
519 {
520 CpuBasedVmExecControls |= CPU_BASED_RDPMC_EXITING;
521 }
522 else
523 {
524 CpuBasedVmExecControls &= ~CPU_BASED_RDPMC_EXITING;
525 }
526
527 //
528 // Set the new value
529 //
530 VmxVmwrite64(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, CpuBasedVmExecControls);
531}
#define CPU_BASED_RDPMC_EXITING
Definition Vmx.h:49

◆ HvSetPmlEnableFlag()

VOID HvSetPmlEnableFlag ( BOOLEAN Set)

Set Page Modification Logging Enable bit.

Parameters
SetSet or unset the PML
Returns
VOID
641{
642 UINT32 AdjSecCtrl;
643 UINT32 SecondaryProcBasedVmExecControls = 0;
644
645 //
646 // Read the previous flags
647 //
648 VmxVmread32P(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, &SecondaryProcBasedVmExecControls);
649
650 //
651 // PML enable flag
652 //
653 if (Set)
654 {
655 SecondaryProcBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS2_ENABLE_PML_FLAG;
656 }
657 else
658 {
659 SecondaryProcBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS2_ENABLE_PML_FLAG;
660 }
661
662 AdjSecCtrl = HvAdjustControls(SecondaryProcBasedVmExecControls, IA32_VMX_PROCBASED_CTLS2);
663
664 //
665 // Set the new value
666 //
667 VmxVmwrite64(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, AdjSecCtrl);
668}

◆ HvSetRdtscExiting()

VOID HvSetRdtscExiting ( VIRTUAL_MACHINE_STATE * VCpu,
BOOLEAN Set )

Set the RDTSC/P Exiting.

Parameters
Set
Returns
VOID
Parameters
VCpuThe virtual processor's state
SetSet or unset the RDTSC/P Exiting
Returns
VOID
1109{
1110 ProtectedHvSetRdtscExiting(VCpu, Set);
1111}
VOID ProtectedHvSetRdtscExiting(VIRTUAL_MACHINE_STATE *VCpu, BOOLEAN Set)
Set the RDTSC/P Exiting.
Definition ProtectedHv.c:558

◆ HvSetRflags()

VOID HvSetRflags ( UINT64 Rflags)

Set guest's RFLAGS.

Parameters
Rflags
Returns
VOID
1168{
1169 VmxVmwrite64(VMCS_GUEST_RFLAGS, Rflags);
1170}

◆ HvSetRflagTrapFlag()

VOID HvSetRflagTrapFlag ( BOOLEAN Set)

Set the rflag's trap flag.

Parameters
SetSet or unset the TF
Returns
VOID
382{
383 RFLAGS Rflags = {0};
384
385 //
386 // Unset the trap-flag, as we set it before we have to mask it now
387 //
388 Rflags.AsUInt = HvGetRflags();
389
390 Rflags.TrapFlag = Set;
391
392 HvSetRflags(Rflags.AsUInt);
393}
UINT64 HvGetRflags()
Read guest's RFLAGS.
Definition Hv.c:1151
VOID HvSetRflags(UINT64 Rflags)
Set guest's RFLAGS.
Definition Hv.c:1167

◆ HvSetRip()

VOID HvSetRip ( UINT64 Rip)

Set guest's RIP.

Parameters
Rip
Returns
VOID
1195{
1196 VmxVmwrite64(VMCS_GUEST_RIP, Rip);
1197}

◆ HvSetSaveDebugControls()

VOID HvSetSaveDebugControls ( BOOLEAN Set)

Set SAVE DEBUG CONTROLS on Vm-exit controls.

Parameters
SetSet or unset
Returns
VOID
434{
435 UINT32 VmexitControls = 0;
436
437 //
438 // Read the previous flags
439 //
440 VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmexitControls);
441
442 if (Set)
443 {
444 VmexitControls |= VM_EXIT_SAVE_DEBUG_CONTROLS;
445 }
446 else
447 {
448 VmexitControls &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
449 }
450
451 //
452 // Set the new value
453 //
454 VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
455}
#define VM_EXIT_SAVE_DEBUG_CONTROLS
VM-exit Control Bits.
Definition Vmx.h:83

◆ HvSetVmxPreemptionTimerExiting()

VOID HvSetVmxPreemptionTimerExiting ( BOOLEAN Set)

Set the VMX Preemptiom Timer.

Parameters
Set
Returns
VOID

Set the VMX Preemptiom Timer.

Parameters
SetSet or unset the VMX preemption timer
Returns
VOID
990{
991 UINT32 PinBasedControls = 0;
992
993 //
994 // Read the previous flags
995 //
996 VmxVmread32P(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, &PinBasedControls);
997
998 if (Set)
999 {
1001 }
1002 else
1003 {
1004 PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER;
1005 }
1006
1007 //
1008 // Set the new value
1009 //
1010 VmxVmwrite64(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, PinBasedControls);
1011}
#define PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER
Definition Vmx.h:37

◆ HvSuppressRipIncrement()

VOID HvSuppressRipIncrement ( VIRTUAL_MACHINE_STATE * VCpu)
externinline

Suppress the incrementation of RIP.

Parameters
VCpuThe virtual processor's state
Returns
VOID
325{
326 VCpu->IncrementRip = FALSE;
327}

◆ HvUnsetExceptionBitmap()

VOID HvUnsetExceptionBitmap ( VIRTUAL_MACHINE_STATE * VCpu,
UINT32 IdtIndex )

Unset exception bitmap in VMCS.

Should be called in vmx-root

Parameters
IdtIndex
Returns
VOID

Should be called in vmx-root

Parameters
VCpuThe virtual processor's state
IdtIndexInterrupt Descriptor Table index of exception
Returns
VOID
1040{
1041 //
1042 // This is a wrapper to perform extra checks
1043 //
1044 ProtectedHvUnsetExceptionBitmap(VCpu, IdtIndex);
1045}
VOID ProtectedHvUnsetExceptionBitmap(VIRTUAL_MACHINE_STATE *VCpu, UINT32 IdtIndex)
Unset exception bitmap in VMCS.
Definition ProtectedHv.c:108

◆ HvWriteExceptionBitmap()

VOID HvWriteExceptionBitmap ( UINT32 BitmapMask)

Write to the exception bitmap.

Parameters
BitmapMask
Returns
VOID

Write to the exception bitmap.

Should be called in vmx-root

Parameters
BitmapMaskThe content to write on exception bitmap
Returns
VOID
573{
574 //
575 // Set the new value
576 //
577 VmxVmwrite64(VMCS_CTRL_EXCEPTION_BITMAP, BitmapMask);
578}