HyperPlatform Programmer's Reference
asm.h
Go to the documentation of this file.
1 // Copyright (c) 2015-2017, Satoshi Tanda. All rights reserved.
2 // Use of this source code is governed by a MIT-style license that can be
3 // found in the LICENSE file.
4 
7 
8 #ifndef HYPERPLATFORM_ASM_H_
9 #define HYPERPLATFORM_ASM_H_
10 
11 #include "ia32_type.h"
12 
13 extern "C" {
15 //
16 // macro utilities
17 //
18 
20 //
21 // constants and macros
22 //
23 
25 //
26 // types
27 //
28 
30 //
31 // prototypes
32 //
33 
38 bool __stdcall AsmInitializeVm(
39  _In_ void (*vm_initialization_routine)(_In_ ULONG_PTR, _In_ ULONG_PTR,
40  _In_opt_ void *),
41  _In_opt_ void *context);
42 
44 void __stdcall AsmVmmEntryPoint();
45 
50 unsigned char __stdcall AsmVmxCall(_In_ ULONG_PTR hypercall_number,
51  _In_opt_ void *context);
52 
55 void __stdcall AsmWriteGDT(_In_ const Gdtr *gdtr);
56 
59 void __stdcall AsmReadGDT(_Out_ Gdtr *gdtr);
60 
63 USHORT __stdcall AsmReadLDTR();
64 
67 void __stdcall AsmWriteTR(_In_ USHORT task_register);
68 
71 USHORT __stdcall AsmReadTR();
72 
75 void __stdcall AsmWriteES(_In_ USHORT segment_selector);
76 
79 USHORT __stdcall AsmReadES();
80 
83 void __stdcall AsmWriteCS(_In_ USHORT segment_selector);
84 
87 USHORT __stdcall AsmReadCS();
88 
91 void __stdcall AsmWriteSS(_In_ USHORT segment_selector);
92 
95 USHORT __stdcall AsmReadSS();
96 
99 void __stdcall AsmWriteDS(_In_ USHORT segment_selector);
100 
103 USHORT __stdcall AsmReadDS();
104 
107 void __stdcall AsmWriteFS(_In_ USHORT segment_selector);
108 
111 USHORT __stdcall AsmReadFS();
112 
115 void __stdcall AsmWriteGS(_In_ USHORT segment_selector);
116 
119 USHORT __stdcall AsmReadGS();
120 
124 ULONG_PTR __stdcall AsmLoadAccessRightsByte(_In_ ULONG_PTR segment_selector);
125 
127 void __stdcall AsmInvalidateInternalCaches();
128 
131 void __stdcall AsmWriteCR2(_In_ ULONG_PTR cr2_value);
132 
137 unsigned char __stdcall AsmInvept(
138  _In_ InvEptType invept_type,
139  _In_ const InvEptDescriptor *invept_descriptor);
140 
145 unsigned char __stdcall AsmInvvpid(
146  _In_ InvVpidType invvpid_type,
147  _In_ const InvVpidDescriptor *invvpid_descriptor);
148 
150 //
151 // variables
152 //
153 
155 //
156 // implementations
157 //
158 
161 inline void __sgdt(_Out_ void *gdtr) { AsmReadGDT(static_cast<Gdtr *>(gdtr)); }
162 
165 inline void __lgdt(_In_ void *gdtr) { AsmWriteGDT(static_cast<Gdtr *>(gdtr)); }
166 
167 // Followings are oringal implementations of Microsoft VMX intrinsic functions
168 // which are not avaiable on x86.
169 #if defined(_X86_)
170 
175 inline unsigned char __vmx_on(
176  _In_ unsigned __int64 *vms_support_physical_address) {
177  FlagRegister flags = {};
178  PHYSICAL_ADDRESS physical_address = {};
179  physical_address.QuadPart = *vms_support_physical_address;
180  __asm {
181  push physical_address.HighPart
182  push physical_address.LowPart
183 
184  _emit 0xF3
185  _emit 0x0F
186  _emit 0xC7
187  _emit 0x34
188  _emit 0x24 // VMXON [ESP]
189 
190  pushfd
191  pop flags.all
192 
193  add esp, 8
194  }
195  if (flags.fields.cf) {
196  return 2;
197  }
198  if (flags.fields.zf) {
199  return 1;
200  }
201  return 0;
202 }
203 
208 inline unsigned char __vmx_vmclear(
209  _In_ unsigned __int64 *vmcs_physical_address) {
210  FlagRegister flags = {};
211  PHYSICAL_ADDRESS physical_address = {};
212  physical_address.QuadPart = *vmcs_physical_address;
213  __asm {
214  push physical_address.HighPart
215  push physical_address.LowPart
216 
217  _emit 0x66
218  _emit 0x0F
219  _emit 0xc7
220  _emit 0x34
221  _emit 0x24 // VMCLEAR [ESP]
222 
223  pushfd
224  pop flags.all
225 
226  add esp, 8
227  }
228  if (flags.fields.cf) {
229  return 2;
230  }
231  if (flags.fields.zf) {
232  return 1;
233  }
234  return 0;
235 }
236 
239 inline unsigned char __vmx_vmlaunch() {
240  FlagRegister flags = {};
241  __asm {
242  _emit 0x0f
243  _emit 0x01
244  _emit 0xc2 // VMLAUNCH
245 
246  pushfd
247  pop flags.all
248  }
249  if (flags.fields.cf) {
250  return 2;
251  }
252  if (flags.fields.zf) {
253  return 1;
254  }
255  /* UNREACHABLE */
256  return 0;
257 }
258 
262 inline unsigned char __vmx_vmptrld(
263  _In_ unsigned __int64 *vmcs_physical_address) {
264  FlagRegister flags = {};
265  PHYSICAL_ADDRESS physical_address = {};
266  physical_address.QuadPart = *vmcs_physical_address;
267  __asm {
268  push physical_address.HighPart
269  push physical_address.LowPart
270 
271  _emit 0x0F
272  _emit 0xC7
273  _emit 0x34
274  _emit 0x24 // VMPTRLD [ESP]
275 
276  pushfd
277  pop flags.all
278 
279  add esp, 8
280  }
281  if (flags.fields.cf) {
282  return 2;
283  }
284  if (flags.fields.zf) {
285  return 1;
286  }
287  return 0;
288 }
289 
295 inline unsigned char __vmx_vmread(_In_ size_t field,
296  _Out_ size_t *field_value) {
297  FlagRegister flags = {};
298  __asm {
299  pushad
300  mov eax, field
301 
302  _emit 0x0F
303  _emit 0x78
304  _emit 0xC3 // VMREAD EBX, EAX
305 
306  pushfd
307  pop flags.all
308 
309  mov eax, field_value
310  mov [eax], ebx
311  popad
312  }
313  if (flags.fields.cf) {
314  return 2;
315  }
316  if (flags.fields.zf) {
317  return 1;
318  }
319  return 0;
320 }
321 
326 inline unsigned char __vmx_vmwrite(_In_ size_t field, _In_ size_t field_value) {
327  FlagRegister flags = {};
328  __asm {
329  pushad
330  push field_value
331  mov eax, field
332 
333  _emit 0x0F
334  _emit 0x79
335  _emit 0x04
336  _emit 0x24 // VMWRITE EAX, [ESP]
337 
338  pushfd
339  pop flags.all
340 
341  add esp, 4
342  popad
343  }
344  if (flags.fields.cf) {
345  return 2;
346  }
347  if (flags.fields.zf) {
348  return 1;
349  }
350  return 0;
351 }
352 
353 #endif
354 
355 } // extern "C"
356 
357 #endif // HYPERPLATFORM_ASM_H_
void __stdcall AsmWriteCS(_In_ USHORT segment_selector)
Writes to CS.
void __stdcall AsmWriteFS(_In_ USHORT segment_selector)
Writes to FS.
USHORT __stdcall AsmReadGS()
Reads GS.
USHORT __stdcall AsmReadCS()
Reads CS.
USHORT __stdcall AsmReadTR()
Reads STR.
USHORT __stdcall AsmReadDS()
Reads DS.
ULONG_PTR cf
[0] Carry flag
Definition: ia32_type.h:45
InvVpidType
See: INVVPID Descriptor.
Definition: ia32_type.h:1612
void __stdcall AsmWriteGDT(_In_ const Gdtr *gdtr)
Writes to GDT.
USHORT __stdcall AsmReadES()
Reads ES.
void __sgdt(_Out_ void *gdtr)
Writes to GDT.
Definition: asm.h:161
void __stdcall AsmReadGDT(_Out_ Gdtr *gdtr)
Reads SGDT.
InvEptType
See: INVEPT Descriptor.
Definition: ia32_type.h:1597
bool __stdcall AsmInitializeVm(_In_ void(*vm_initialization_routine)(_In_ ULONG_PTR, _In_ ULONG_PTR, _In_opt_ void *), _In_opt_ void *context)
A wrapper for vm_initialization_routine.
struct FlagRegister::@1 fields
USHORT __stdcall AsmReadLDTR()
Reads SLDT.
ULONG_PTR all
Definition: ia32_type.h:43
unsigned char __stdcall AsmVmxCall(_In_ ULONG_PTR hypercall_number, _In_opt_ void *context)
Executes VMCALL with the given hypercall number and a context.
USHORT __stdcall AsmReadSS()
Reads SS.
void __stdcall AsmWriteTR(_In_ USHORT task_register)
Writes to TR.
unsigned char __stdcall AsmInvept(_In_ InvEptType invept_type, _In_ const InvEptDescriptor *invept_descriptor)
Invalidates translations derived from EPT.
See: SYSTEM FLAGS AND FIELDS IN THE EFLAGS REGISTER.
Definition: ia32_type.h:42
ULONG_PTR zf
[6] Zero flag
Definition: ia32_type.h:51
See: INVEPT Descriptor.
Definition: ia32_type.h:1590
USHORT __stdcall AsmReadFS()
Reads FS.
void __stdcall AsmWriteGS(_In_ USHORT segment_selector)
Writes to GS.
ULONG_PTR __stdcall AsmLoadAccessRightsByte(_In_ ULONG_PTR segment_selector)
Loads access rights byte.
void __stdcall AsmWriteSS(_In_ USHORT segment_selector)
Writes to SS.
Defines constants and structures defined by the x86-64 architecture.
unsigned char __stdcall AsmInvvpid(_In_ InvVpidType invvpid_type, _In_ const InvVpidDescriptor *invvpid_descriptor)
Invalidate translations based on VPID.
void __stdcall AsmVmmEntryPoint()
An entry point of VMM where gets called whenever VM-exit occurred.
void __stdcall AsmWriteCR2(_In_ ULONG_PTR cr2_value)
Writes to CR2.
void __lgdt(_In_ void *gdtr)
Reads SGDT.
Definition: asm.h:165
See: MEMORY-MANAGEMENT REGISTERS.
Definition: ia32_type.h:223
See: INVVPID Descriptor.
Definition: ia32_type.h:1603
void __stdcall AsmInvalidateInternalCaches()
Invalidates internal caches.
void __stdcall AsmWriteES(_In_ USHORT segment_selector)
Writes to ES.
void __stdcall AsmWriteDS(_In_ USHORT segment_selector)
Writes to DS.