├── .gitattributes ├── .gitignore ├── Makefile ├── README.md ├── cmd ├── cmdclean ├── vmlaunch_simple.c └── vmxon_simple.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | KERNEL_TREE_PATH?=/lib/modules/$(shell uname -r)/build 2 | 3 | obj-m := vmlaunch_simple.o 4 | 5 | all: vmlaunch_simple.ko 6 | 7 | vmlaunch_simple.ko: vmlaunch_simple.c 8 | make -C $(KERNEL_TREE_PATH) M=$(PWD) modules 9 | 10 | clean: 11 | make -C $(KERNEL_TREE_PATH) M=$(PWD) clean 12 | 13 | .PHONY: all clean 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | vmlaunch 2 | ======== 3 | 4 | Simple Driver code for vmlaunch 5 | The idea behind the driver is to demonstrate a real example of how to initialize 6 | the Virtual Machine Control Structure(VMCS) and to use Intel VT instructions to launch 7 | a virtual machine. The driver launches a guest (virtual machine) with vmlaunch, executes 8 | one instruction(that causes a vmexit) and then returns to the host. For the vmlaunch 9 | instruction to execute successfully, a lot of cpu state (host and guest state) needs 10 | to be initialized all of which is done by this driver. The driver also takes a simple 11 | approach in setting up the guest state by making it mirror the host state. This makes 12 | the design much simpler - for instance the guest does not need its own CR3, it shares 13 | it with the host. Inline assembly is used generously throughout the driver. 14 | 15 | One possible concern: 16 | The VMCS does not have a host state field for LDTs. After a vmexit, the processor 17 | loads the LDT selector to null. If a non-zero ldt selector is required before the 18 | module exits then the code after vmexit may require a lldt to establish 19 | the ldtr to a good state. 20 | 21 | -------------------------------------------------------------------------------- /cmd: -------------------------------------------------------------------------------- 1 | make 2 | -------------------------------------------------------------------------------- /cmdclean: -------------------------------------------------------------------------------- 1 | make clean 2 | -------------------------------------------------------------------------------- /vmlaunch_simple.c: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////// 2 | //Author: Vish Mohan 3 | //x86 Hardware Assisted virtualization: Intel VT 4 | //Description: A very basic driver that walks 5 | //through all the steps to do a successful vmlaunch. 6 | //After vmlaunch, the guest code does a vmcall and vmexits 7 | //back to the host. The guest state mirrors the host. 8 | 9 | //References: 10 | //1. Vol 3C, Intel Software Manual 11 | //2. vmx.c in the linux kernel 12 | //3. virtualizationtechnologyvt.blogspot.com 13 | 14 | //>sudo insmod vmlaunch_simple.ko 15 | //dmesg snapshot: 16 | //[ 420.894248] <1> In vmxon 17 | //[ 420.894252] <1> VMX supported CPU. 18 | //[ 420.894253] MSR 0x3A:Lock bit is on.VMXON bit is on.OK 19 | //[ 420.894255] <1> turned on cr4.vmxe 20 | //[ 420.894266] <1> Guest VMexit reason: 0x12 21 | //[ 420.894268] <1> Enable Interrupts 22 | //[ 420.894269] <1> Finished vmxon 23 | 24 | //>sudo rmmod vmlaunch_simple.ko 25 | //[ 509.458651] <1> Machine in vmxon: Attempting vmxoff 26 | //[ 509.458656] <1> vmxoff complete 27 | //[ 509.458658] <1> turned off cr4.vmxe 28 | //[ 509.458660] <1> freeing allocated vmcs region! 29 | //[ 509.458662] <1> freeing allocated io bitmapA region! 30 | //[ 509.458664] <1> freeing allocated io bitmapB region! 31 | //[ 509.458666] <1> freeing allocated msr bitmap region! 32 | //[ 509.458668] <1> freeing allocated virtual apic page region! 33 | //[ 509.458670] <1> freeing allocated vmxon region! 34 | /////////////////////////////////////////////// 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "vmxon_simple.h" 40 | 41 | MODULE_LICENSE("Dual BSD/GPL"); 42 | 43 | #define MYPAGE_SIZE 4096 44 | #define VMX_BASIC_MSR 0x480 45 | #define FEATURE_CONTROL_MSR 0x3A 46 | #define CPUID_VMX_BIT 5 47 | 48 | bool alloc_failure = false; 49 | int vmx_msr_addr = VMX_BASIC_MSR; 50 | int feature_control_msr_addr = FEATURE_CONTROL_MSR; 51 | int vmx_rev_id = 0; 52 | int vmxon_success = 0; 53 | int vmxoff_success = 0; 54 | int vmptrld_success = 0; 55 | int vmclear_success = 0; 56 | int vmwrite_success = 0; 57 | int vmread_success = 0; 58 | int vmlaunch_success = 0; 59 | char *vmxon_region; 60 | char *vmcs_guest_region; 61 | char *io_bitmap_a_region; 62 | char *io_bitmap_b_region; 63 | char *msr_bitmap_region; 64 | char *virtual_apic_page; 65 | 66 | long int vmxon_phy_region = 0; 67 | long int vmcs_phy_region = 0; 68 | long int io_bitmap_a_phy_region = 0; 69 | long int io_bitmap_b_phy_region = 0; 70 | long int msr_bitmap_phy_region = 0; 71 | long int virtual_apic_page_phy_region = 0; 72 | 73 | unsigned long value; 74 | long int rflags_value = 0; 75 | u16 tr_sel; //selector for task register 76 | 77 | static void do_vmclear(void); 78 | static void restore_registers(void); 79 | static void vmxon_exit(void); 80 | static unsigned long do_vmread(unsigned long field); 81 | 82 | #define MY_VMX_VMXON_RAX ".byte 0xf3, 0x0f, 0xc7, 0x30" 83 | #define MY_VMX_VMPTRLD_RAX ".byte 0x0f, 0xc7, 0x30" 84 | #define MY_VMX_VMCLEAR_RAX ".byte 0x66, 0x0f, 0xc7, 0x30" 85 | #define MY_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2" 86 | #define MY_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3" 87 | #define MY_VMX_VMREAD_RDX_RAX ".byte 0x0f, 0x78, 0xd0" 88 | #define MY_VMX_VMWRITE_RAX_RDX ".byte 0x0f, 0x79, 0xd0" 89 | #define MY_VMX_VMXOFF ".byte 0x0f, 0x01, 0xc4" 90 | #define MY_VMX_VMCALL ".byte 0x0f, 0x01, 0xc1" 91 | #define MY_HLT ".byte 0xf4" 92 | 93 | 94 | static unsigned long do_vmread(unsigned long field) { 95 | asm volatile (MY_VMX_VMREAD_RDX_RAX 96 | : "=a"(value) : "d"(field) : "cc"); 97 | 98 | return value; 99 | } 100 | 101 | /* different flavors of vmwrites */ 102 | static void do_vmwrite(unsigned long field, unsigned long value) { 103 | asm volatile (MY_VMX_VMWRITE_RAX_RDX 104 | : : "a"(value), "d"(field) : "cc"); 105 | asm volatile("jbe vmwrite_fail\n"); 106 | vmwrite_success = 1; 107 | asm volatile("jmp vmwrite_finish\n" 108 | "vmwrite_fail:\n" 109 | "pushfq\n" 110 | ); 111 | asm volatile ("popq %0\n" 112 | : 113 | :"m"(rflags_value) 114 | :"memory" 115 | ); 116 | vmwrite_success = 0; 117 | do_vmclear(); 118 | restore_registers(); 119 | vmxon_exit(); 120 | asm volatile("vmwrite_finish:\n"); 121 | } 122 | 123 | static void do_vmwrite16(unsigned long field, u16 value) { 124 | do_vmwrite(field, value); 125 | } 126 | 127 | static void do_vmwrite32(unsigned long field, u32 value) { 128 | do_vmwrite(field, value); 129 | } 130 | 131 | static void do_vmwrite64(unsigned long field, u64 value) { 132 | do_vmwrite(field, value); 133 | } 134 | 135 | static void initialize_16bit_host_guest_state(void) { 136 | unsigned long field,field1; 137 | u16 value; 138 | field = VMX_HOST_ES_SEL; 139 | field1 = VMX_GUEST_ES_SEL; 140 | asm ("movw %%es, %%ax\n" 141 | :"=a"(value) 142 | ); 143 | do_vmwrite16(field,value); 144 | do_vmwrite16(field1,value); 145 | 146 | field = VMX_HOST_CS_SEL; 147 | field1 = VMX_GUEST_CS_SEL; 148 | asm ("movw %%cs, %%ax\n" 149 | : "=a"(value)); 150 | do_vmwrite16(field,value); 151 | do_vmwrite16(field1,value); 152 | 153 | field = VMX_HOST_SS_SEL; 154 | field1 = VMX_GUEST_SS_SEL; 155 | asm ("movw %%ss, %%ax\n" 156 | : "=a"(value)); 157 | do_vmwrite16(field,value); 158 | do_vmwrite16(field1,value); 159 | 160 | field = VMX_HOST_DS_SEL; 161 | field1 = VMX_GUEST_DS_SEL; 162 | asm ("movw %%ds, %%ax\n" 163 | : "=a"(value)); 164 | do_vmwrite16(field,value); 165 | do_vmwrite16(field1,value); 166 | 167 | field = VMX_HOST_FS_SEL; 168 | field1 = VMX_GUEST_FS_SEL; 169 | asm ("movw %%fs, %%ax\n" 170 | : "=a"(value)); 171 | do_vmwrite16(field,value); 172 | do_vmwrite16(field1,value); 173 | 174 | field = VMX_HOST_GS_SEL; 175 | field1 = VMX_GUEST_GS_SEL; 176 | asm ("movw %%gs, %%ax\n" 177 | : "=a"(value)); 178 | do_vmwrite16(field,value); 179 | do_vmwrite16(field1,value); 180 | 181 | field = VMX_HOST_TR_SEL; 182 | field1 = VMX_GUEST_TR_SEL; 183 | asm("str %%ax\n" : "=a"(tr_sel)); 184 | do_vmwrite16(field,tr_sel); 185 | do_vmwrite16(field1,tr_sel); 186 | 187 | field = VMX_GUEST_LDTR_SEL; 188 | asm("sldt %%ax\n" : "=a"(value)); 189 | do_vmwrite16(field,value); 190 | 191 | } 192 | 193 | static void initialize_64bit_control(void) { 194 | unsigned long field; 195 | u64 value; 196 | 197 | field = VMX_IO_BITMAP_A_FULL; 198 | io_bitmap_a_phy_region = __pa(io_bitmap_a_region); 199 | value = io_bitmap_a_phy_region; 200 | do_vmwrite64(field,value); 201 | 202 | field = VMX_IO_BITMAP_B_FULL; 203 | io_bitmap_b_phy_region = __pa(io_bitmap_b_region); 204 | value = io_bitmap_b_phy_region; 205 | do_vmwrite64(field,value); 206 | 207 | field = VMX_MSR_BITMAP_FULL; 208 | msr_bitmap_phy_region = __pa(msr_bitmap_region); 209 | value = msr_bitmap_phy_region; 210 | do_vmwrite64(field,value); 211 | 212 | field = VMX_VIRTUAL_APIC_PAGE_ADDR_FULL; 213 | virtual_apic_page_phy_region = __pa(virtual_apic_page); 214 | value = virtual_apic_page_phy_region; 215 | do_vmwrite64(field,value); 216 | 217 | field = VMX_EXECUTIVE_VMCS_PTR_FULL; 218 | value = 0; 219 | do_vmwrite64(field,value); 220 | 221 | field = VMX_TSC_OFFSET_FULL; 222 | value = 0; 223 | do_vmwrite64(field,value); 224 | 225 | } 226 | 227 | static void initialize_64bit_host_guest_state(void) { 228 | unsigned long field; 229 | u64 value; 230 | field = VMX_VMS_LINK_PTR_FULL; 231 | value = 0xffffffffffffffffull; 232 | do_vmwrite64(field,value); 233 | field = VMX_GUEST_IA32_DEBUGCTL_FULL; 234 | value = 0; 235 | do_vmwrite64(field,value); 236 | } 237 | 238 | static void initialize_32bit_control(void) { 239 | unsigned long field; 240 | u32 value; 241 | 242 | field = VMX_PIN_VM_EXEC_CONTROLS; 243 | value = 0x1f ; 244 | do_vmwrite32(field,value); 245 | 246 | field = VMX_PROC_VM_EXEC_CONTROLS; 247 | value = 0x0401e172 ; 248 | do_vmwrite32(field,value); 249 | 250 | field = VMX_EXCEPTION_BITMAP; 251 | value = 0xffffffff ; 252 | do_vmwrite32(field,value); 253 | 254 | field = VMX_PF_EC_MASK; 255 | value = 0x0 ; 256 | do_vmwrite32(field,value); 257 | 258 | field = VMX_PF_EC_MATCH; 259 | value = 0 ; 260 | do_vmwrite32(field,value); 261 | 262 | field = VMX_CR3_TARGET_COUNT; 263 | value = 0 ; 264 | do_vmwrite32(field,value); 265 | 266 | field = VMX_EXIT_CONTROLS; 267 | value = 0x36fff ; 268 | do_vmwrite32(field,value); 269 | 270 | field = VMX_EXIT_MSR_STORE_COUNT; 271 | value = 0 ; 272 | do_vmwrite32(field,value); 273 | 274 | field = VMX_EXIT_MSR_LOAD_COUNT; 275 | value = 0 ; 276 | do_vmwrite32(field,value); 277 | 278 | field = VMX_ENTRY_CONTROLS; 279 | value = 0x13ff ; 280 | do_vmwrite32(field,value); 281 | 282 | field = VMX_ENTRY_MSR_LOAD_COUNT; 283 | value = 0 ; 284 | do_vmwrite32(field,value); 285 | 286 | field = VMX_ENTRY_INT_INFO_FIELD; 287 | value = 0 ; 288 | do_vmwrite32(field,value); 289 | 290 | field = VMX_ENTRY_EXCEPTION_EC; 291 | value = 0 ; 292 | do_vmwrite32(field,value); 293 | 294 | field = VMX_ENTRY_INSTR_LENGTH; 295 | value = 0 ; 296 | do_vmwrite32(field,value); 297 | 298 | field = VMX_TPR_THRESHOLD; 299 | value = 0 ; 300 | do_vmwrite32(field,value); 301 | } 302 | 303 | static void initialize_32bit_host_guest_state(void) { 304 | unsigned long field; 305 | u32 value; 306 | u64 gdtb; 307 | u64 trbase; 308 | u64 trbase_lo; 309 | u64 trbase_hi; 310 | u64 realtrbase; 311 | u64 idtb; 312 | u32 unusable_ar = 0x10000; 313 | u32 usable_ar; 314 | u16 sel_value; 315 | 316 | field = VMX_GUEST_ES_LIMIT; 317 | value = 0xffffffff ; 318 | do_vmwrite32(field,value); 319 | 320 | field = VMX_GUEST_ES_ATTR; 321 | value = unusable_ar; 322 | do_vmwrite32(field,value); 323 | 324 | field = VMX_GUEST_CS_LIMIT; 325 | value = 0xffffffff ; 326 | do_vmwrite32(field,value); 327 | 328 | asm ("movw %%cs, %%ax\n" 329 | : "=a"(sel_value)); 330 | asm("lar %%eax,%%eax\n" :"=a"(usable_ar) :"a"(sel_value)); 331 | usable_ar = usable_ar>>8; 332 | usable_ar &= 0xf0ff; //clear bits 11:8 333 | 334 | field = VMX_GUEST_CS_ATTR; 335 | do_vmwrite32(field,usable_ar); 336 | value = do_vmread(field); 337 | 338 | 339 | field = VMX_GUEST_SS_LIMIT; 340 | value = 0xffffffff ; 341 | do_vmwrite32(field,value); 342 | 343 | 344 | asm ("movw %%ss, %%ax\n" 345 | : "=a"(sel_value)); 346 | asm("lar %%eax,%%eax\n" :"=a"(usable_ar) :"a"(sel_value)); 347 | usable_ar = usable_ar>>8; 348 | usable_ar &= 0xf0ff; //clear bits 11:8 349 | 350 | field = VMX_GUEST_SS_ATTR; 351 | do_vmwrite32(field,usable_ar); 352 | 353 | field = VMX_GUEST_DS_LIMIT; 354 | value = 0xffffffff ; 355 | do_vmwrite32(field,value); 356 | 357 | field = VMX_GUEST_DS_ATTR; 358 | value = unusable_ar; 359 | do_vmwrite32(field,value); 360 | 361 | field = VMX_GUEST_FS_LIMIT; 362 | value = 0xffffffff ; 363 | do_vmwrite32(field,value); 364 | 365 | field = VMX_GUEST_FS_ATTR; 366 | value = unusable_ar; 367 | do_vmwrite32(field,value); 368 | 369 | field = VMX_GUEST_GS_LIMIT; 370 | value = 0xffffffff ; 371 | do_vmwrite32(field,value); 372 | 373 | field = VMX_GUEST_GS_ATTR; 374 | value = unusable_ar; 375 | do_vmwrite32(field,value); 376 | 377 | field = VMX_GUEST_LDTR_LIMIT; 378 | value = 0x0; 379 | do_vmwrite32(field,value); 380 | 381 | field = VMX_GUEST_LDTR_ATTR; 382 | value = unusable_ar; 383 | do_vmwrite32(field,value); 384 | 385 | field = VMX_GUEST_TR_LIMIT; 386 | asm volatile("mov %%rax, %%rax" 387 | : 388 | :"a"(tr_sel) 389 | ); 390 | asm("lsl %%eax, %%eax\n" :"=a"(value)); 391 | do_vmwrite32(field,value); 392 | 393 | //asm("str %%ax\n" : "=a"(sel_value)); 394 | asm("lar %%eax,%%eax\n" :"=a"(usable_ar) :"a"(tr_sel)); 395 | usable_ar = usable_ar>>8; 396 | 397 | field = VMX_GUEST_TR_ATTR; 398 | do_vmwrite32(field,usable_ar); 399 | 400 | asm("sgdt %0\n" : :"m"(gdtb)); 401 | value = gdtb&0x0ffff; 402 | gdtb = gdtb>>16; //base 403 | 404 | if((gdtb>>47&0x1)){ 405 | gdtb |= 0xffff000000000000ull; 406 | } 407 | 408 | 409 | field = VMX_GUEST_GDTR_LIMIT; 410 | do_vmwrite32(field,value); 411 | 412 | field = VMX_GUEST_GDTR_BASE; 413 | do_vmwrite64(field,gdtb); 414 | field = VMX_HOST_GDTR_BASE; 415 | do_vmwrite64(field,gdtb); 416 | 417 | //trbase = gdtb + 0x40; 418 | trbase = gdtb + tr_sel; 419 | if((trbase>>47&0x1)){ 420 | trbase |= 0xffff000000000000ull; 421 | } 422 | 423 | // SS segment override 424 | asm("mov %0,%%rax\n" 425 | ".byte 0x36\n" 426 | "movq (%%rax),%%rax\n" 427 | :"=a"(trbase_lo) :"0"(trbase) 428 | ); 429 | 430 | realtrbase = ((trbase_lo>>16) & (0x0ffff)) | (((trbase_lo>>32)&0x000000ff) << 16) | (((trbase_lo>>56)&0xff) << 24); 431 | 432 | // SS segment override for upper32 bits of base in ia32e mode 433 | asm("mov %0,%%rax\n" 434 | ".byte 0x36\n" 435 | "movq 8(%%rax),%%rax\n" 436 | :"=a"(trbase_hi) :"0"(trbase) 437 | ); 438 | 439 | realtrbase = realtrbase | (trbase_hi<<32) ; 440 | 441 | field = VMX_HOST_TR_BASE; 442 | do_vmwrite64(field,realtrbase); 443 | 444 | field = VMX_GUEST_TR_BASE; 445 | do_vmwrite64(field,realtrbase); 446 | 447 | 448 | asm("sidt %0\n" : :"m"(idtb)); 449 | value = idtb&0x0ffff; 450 | idtb = idtb>>16; //base 451 | 452 | if((idtb>>47&0x1)){ 453 | idtb |= 0xffff000000000000ull; 454 | } 455 | 456 | field = VMX_GUEST_IDTR_LIMIT; 457 | do_vmwrite32(field,value); 458 | 459 | field = VMX_GUEST_IDTR_BASE; 460 | do_vmwrite64(field,idtb); 461 | field = VMX_HOST_IDTR_BASE; 462 | do_vmwrite64(field,idtb); 463 | 464 | field = VMX_GUEST_INTERRUPTIBILITY_INFO; 465 | value = 0; 466 | do_vmwrite32(field,value); 467 | 468 | field = VMX_GUEST_ACTIVITY_STATE; 469 | value = 0; 470 | do_vmwrite32(field,value); 471 | 472 | field = VMX_GUEST_SMBASE; 473 | value = 0; 474 | do_vmwrite32(field,value); 475 | 476 | asm volatile("mov $0x174, %rcx\n"); 477 | asm("rdmsr\n"); 478 | asm("mov %%rax, %0\n" : :"m"(value):"memory"); 479 | field = VMX_HOST_IA32_SYSENTER_CS; 480 | do_vmwrite32(field,value); 481 | field = VMX_GUEST_IA32_SYSENTER_CS; 482 | do_vmwrite32(field,value); 483 | } 484 | 485 | static void initialize_naturalwidth_control(void){ 486 | unsigned long field; 487 | u64 value; 488 | 489 | field = VMX_CR0_MASK; 490 | value = 0; 491 | do_vmwrite64(field,value); 492 | field = VMX_CR4_MASK; 493 | value = 0; 494 | do_vmwrite64(field,value); 495 | 496 | field = VMX_CR0_READ_SHADOW; 497 | value = 0; 498 | do_vmwrite64(field,value); 499 | 500 | field = VMX_CR4_READ_SHADOW; 501 | value = 0; 502 | do_vmwrite64(field,value); 503 | 504 | field = VMX_CR3_TARGET_0; 505 | value = 0; 506 | do_vmwrite64(field,value); 507 | 508 | field = VMX_CR3_TARGET_1; 509 | value = 0; 510 | do_vmwrite64(field,value); 511 | 512 | field = VMX_CR3_TARGET_2; 513 | value = 0; 514 | do_vmwrite64(field,value); 515 | 516 | field = VMX_CR3_TARGET_3; 517 | value = 0; 518 | do_vmwrite64(field,value); 519 | } 520 | 521 | static void initialize_naturalwidth_host_guest_state(void) { 522 | unsigned long field,field1; 523 | u64 value; 524 | int fs_low; 525 | int gs_low; 526 | 527 | field = VMX_HOST_CR0; 528 | field1 = VMX_GUEST_CR0; 529 | asm ("movq %%cr0, %%rax\n" 530 | :"=a"(value) 531 | ); 532 | do_vmwrite64(field,value); 533 | do_vmwrite64(field1,value); 534 | 535 | field = VMX_HOST_CR3; 536 | field1 = VMX_GUEST_CR3; 537 | asm ("movq %%cr3, %%rax\n" 538 | :"=a"(value) 539 | ); 540 | do_vmwrite64(field,value); 541 | do_vmwrite64(field1,value); 542 | 543 | field = VMX_HOST_CR4; 544 | field1 = VMX_GUEST_CR4; 545 | asm ("movq %%cr4, %%rax\n" 546 | :"=a"(value) 547 | ); 548 | do_vmwrite64(field,value); 549 | do_vmwrite64(field1,value); 550 | 551 | value=0; 552 | field1 = VMX_GUEST_ES_BASE; 553 | do_vmwrite64(field1,value); 554 | field1 = VMX_GUEST_CS_BASE; 555 | do_vmwrite64(field1,value); 556 | field1 = VMX_GUEST_SS_BASE; 557 | do_vmwrite64(field1,value); 558 | field1 = VMX_GUEST_DS_BASE; 559 | do_vmwrite64(field1,value); 560 | field1 = VMX_GUEST_LDTR_BASE; 561 | do_vmwrite64(field1,value); 562 | 563 | value = 0; 564 | field = VMX_HOST_FS_BASE; 565 | field1 = VMX_GUEST_FS_BASE; 566 | asm volatile("mov $0xc0000100, %rcx\n"); 567 | asm volatile("rdmsr\n" :"=a"(fs_low) : :"%rdx"); 568 | //asm volatile ("mov %%rax, %0\n" : :"m"(fs_low) :"memory"); 569 | asm volatile ("shl $32, %%rdx\n" :"=d"(value)); 570 | value|=fs_low; 571 | do_vmwrite64(field1,value); 572 | do_vmwrite64(field,value); 573 | 574 | value = 0; 575 | field = VMX_HOST_GS_BASE; 576 | field1 = VMX_GUEST_GS_BASE; 577 | asm volatile("mov $0xc0000101, %rcx\n"); 578 | asm volatile("rdmsr\n" :"=a"(gs_low) : :"%rdx"); 579 | //asm volatile ("mov %%rax, %0\n" : :"m"(gs_low) :"memory"); 580 | asm volatile ("shl $32, %%rdx\n" :"=d"(value)); 581 | value|=gs_low; 582 | do_vmwrite64(field1,value); 583 | do_vmwrite64(field,value); 584 | 585 | 586 | 587 | field1 = VMX_GUEST_DR7; 588 | value = 0x400; 589 | do_vmwrite64(field1,value); 590 | 591 | field = VMX_HOST_RSP; 592 | field1 = VMX_GUEST_RSP; 593 | asm ("movq %%rsp, %%rax\n" 594 | :"=a"(value) 595 | ); 596 | do_vmwrite64(field1,value); 597 | do_vmwrite64(field,value); 598 | 599 | /* 600 | field1 = VMX_GUEST_RIP; 601 | value = (u64) guest_entry_code; 602 | do_vmwrite64(field1,value); 603 | 604 | field1 = VMX_HOST_RIP; 605 | value = (u64) handle_vmexit; 606 | do_vmwrite64(field1,value); */ 607 | 608 | 609 | field1 = VMX_GUEST_RFLAGS; 610 | asm volatile("pushfq\n"); 611 | asm volatile("popq %0\n" :"=m"(value)::"memory"); 612 | do_vmwrite64(field1,value); 613 | 614 | field1 = VMX_GUEST_PENDING_DEBUG_EXCEPT; 615 | value = 0x0; 616 | do_vmwrite64(field1,value); 617 | 618 | field1 = VMX_GUEST_IA32_SYSENTER_ESP; 619 | field = VMX_HOST_IA32_SYSENTER_ESP; 620 | asm volatile("mov $0x176, %rcx\n"); 621 | asm("rdmsr\n"); 622 | asm("mov %%rax, %0\n" : :"m"(value):"memory"); 623 | asm("or %0, %%rdx\n" : :"m"(value):"memory"); 624 | do_vmwrite64(field1,value); 625 | do_vmwrite64(field,value); 626 | 627 | field1 = VMX_GUEST_IA32_SYSENTER_EIP; 628 | field = VMX_HOST_IA32_SYSENTER_EIP; 629 | asm volatile("mov $0x175, %rcx\n"); 630 | asm("rdmsr\n"); 631 | asm("mov %%rax, %0\n" : :"m"(value):"memory"); 632 | asm("or %0, %%rdx\n" : :"m"(value):"memory"); 633 | do_vmwrite64(field1,value); 634 | do_vmwrite64(field,value); 635 | 636 | } 637 | 638 | 639 | 640 | static void initialize_guest_vmcs(void){ 641 | initialize_16bit_host_guest_state(); 642 | initialize_64bit_control(); 643 | initialize_64bit_host_guest_state(); 644 | initialize_32bit_control(); 645 | initialize_naturalwidth_control(); 646 | initialize_32bit_host_guest_state(); 647 | initialize_naturalwidth_host_guest_state(); 648 | } 649 | 650 | 651 | /* Allocate a 4K region for vmxon */ 652 | static void allocate_vmxon_region(void) { 653 | vmxon_region = kmalloc(MYPAGE_SIZE,GFP_KERNEL); 654 | } 655 | 656 | /* Allocate a 4K vmcs region for the guest */ 657 | static void allocate_vmcs_region(void) { 658 | vmcs_guest_region = kmalloc(MYPAGE_SIZE,GFP_KERNEL); 659 | io_bitmap_a_region = kmalloc(MYPAGE_SIZE,GFP_KERNEL); 660 | io_bitmap_b_region = kmalloc(MYPAGE_SIZE,GFP_KERNEL); 661 | msr_bitmap_region = kmalloc(MYPAGE_SIZE,GFP_KERNEL); 662 | virtual_apic_page = kmalloc(MYPAGE_SIZE,GFP_KERNEL); 663 | //Initialize data structures 664 | memset(vmcs_guest_region, 0, MYPAGE_SIZE); 665 | memset(io_bitmap_a_region, 0, MYPAGE_SIZE); 666 | memset(io_bitmap_b_region, 0, MYPAGE_SIZE); 667 | memset(msr_bitmap_region, 0, MYPAGE_SIZE); 668 | memset(virtual_apic_page, 0, MYPAGE_SIZE); 669 | 670 | } 671 | 672 | /* Dealloc vmxon region*/ 673 | static void deallocate_vmxon_region(void) { 674 | if(vmxon_region){ 675 | printk("<1> freeing allocated vmxon region!\n"); 676 | kfree(vmxon_region); 677 | } 678 | } 679 | 680 | /* Dealloc vmcs guest region*/ 681 | static void deallocate_vmcs_region(void) { 682 | if(vmcs_guest_region){ 683 | printk("<1> freeing allocated vmcs region!\n"); 684 | kfree(vmcs_guest_region); 685 | } 686 | if(io_bitmap_a_region){ 687 | printk("<1> freeing allocated io bitmapA region!\n"); 688 | kfree(io_bitmap_a_region); 689 | } 690 | if(io_bitmap_b_region){ 691 | printk("<1> freeing allocated io bitmapB region!\n"); 692 | kfree(io_bitmap_b_region); 693 | } 694 | if(msr_bitmap_region){ 695 | printk("<1> freeing allocated msr bitmap region!\n"); 696 | kfree(msr_bitmap_region); 697 | } 698 | if(virtual_apic_page){ 699 | printk("<1> freeing allocated virtual apic page region!\n"); 700 | kfree(virtual_apic_page); 701 | } 702 | } 703 | 704 | static void save_registers(void){ 705 | asm volatile("pushq %rcx\n" 706 | "pushq %rdx\n" 707 | "pushq %rax\n" 708 | "pushq %rbx\n" 709 | ); 710 | 711 | } 712 | 713 | static void restore_registers(void){ 714 | asm volatile("popq %rbx\n" 715 | "popq %rax\n" 716 | "popq %rdx\n" 717 | "popq %rcx\n"); 718 | 719 | } 720 | 721 | /*initialize revision id*/ 722 | static void vmxon_setup_revid(void){ 723 | asm volatile ("mov %0, %%rcx\n" 724 | : 725 | : "m"(vmx_msr_addr) 726 | : "memory"); 727 | 728 | asm volatile("rdmsr\n"); 729 | 730 | asm volatile ("mov %%rax, %0\n" 731 | : 732 | :"m"(vmx_rev_id) 733 | :"memory"); 734 | } 735 | 736 | /*turn on vmxe*/ 737 | static void turn_on_vmxe(void) { 738 | asm volatile("movq %cr4, %rax\n" 739 | "bts $13, %rax\n" 740 | "movq %rax, %cr4\n" 741 | ); 742 | printk("<1> turned on cr4.vmxe\n"); 743 | } 744 | 745 | /*turn off vmxe*/ 746 | static void turn_off_vmxe(void) { 747 | asm volatile("movq %cr4, %rax\n" 748 | "btr $13, %rax\n" 749 | "movq %rax, %cr4\n" 750 | ); 751 | printk("<1> turned off cr4.vmxe\n"); 752 | } 753 | 754 | 755 | /*do vmptrld*/ 756 | static void do_vmptrld(void) { 757 | asm volatile (MY_VMX_VMPTRLD_RAX 758 | : : "a"(&vmcs_phy_region), "m"(vmcs_phy_region) 759 | : "cc", "memory"); 760 | asm volatile("jbe vmptrld_fail\n"); 761 | vmptrld_success = 1; 762 | asm volatile("jmp vmptrld_finish\n" 763 | "vmptrld_fail:\n" 764 | "pushfq\n" 765 | ); 766 | asm volatile ("popq %0\n" 767 | : 768 | :"m"(rflags_value) 769 | :"memory" 770 | ); 771 | vmptrld_success = 0; 772 | printk("<1> vmptrld has failed!\n"); 773 | asm volatile("vmptrld_finish:\n"); 774 | 775 | } 776 | 777 | /*do vmclear*/ 778 | static void do_vmclear(void) { 779 | asm volatile (MY_VMX_VMCLEAR_RAX 780 | : : "a"(&vmcs_phy_region), "m"(vmcs_phy_region) 781 | : "cc", "memory"); 782 | asm volatile("jbe vmclear_fail"); 783 | vmclear_success = 1; 784 | asm volatile("jmp vmclear_finish\n" 785 | "vmclear_fail:\n" 786 | "pushfq\n" 787 | ); 788 | asm volatile ("popq %0\n" 789 | : 790 | :"m"(rflags_value) 791 | :"memory" 792 | ); 793 | vmclear_success = 0; 794 | //printk("<1> rflags after vmclear: 0x%lx\n",rflags_value); 795 | //printk("<1> vmclear has failed!\n"); 796 | asm volatile("vmclear_finish:\n"); 797 | printk("<1> vmclear done!\n"); 798 | } 799 | 800 | 801 | 802 | /*do vmxon*/ 803 | static void do_vmxon(void) { 804 | asm volatile (MY_VMX_VMXON_RAX 805 | : : "a"(&vmxon_phy_region), "m"(vmxon_phy_region) 806 | : "memory", "cc"); 807 | asm volatile("jbe vmxon_fail\n"); 808 | vmxon_success = 1; 809 | asm volatile("jmp vmxon_finish\n" 810 | "vmxon_fail:\n" 811 | "pushfq\n" 812 | ); 813 | asm volatile ("popq %0\n" 814 | : 815 | :"m"(rflags_value) 816 | :"memory" 817 | ); 818 | vmxon_success = 0; 819 | printk("<1> vmxon has failed!\n"); 820 | asm volatile("vmxon_finish:\n"); 821 | } 822 | 823 | /*do vmxoff*/ 824 | static void do_vmxoff(void) { 825 | asm volatile ("vmxoff\n" : : : "cc"); 826 | asm volatile("jbe vmxoff_fail\n"); 827 | vmxoff_success = 1; 828 | asm volatile("jmp vmxoff_finish\n"); 829 | asm volatile("vmxoff_fail:\n"); 830 | vmxoff_success = 0; 831 | printk("<1> vmxoff has failed!\n"); 832 | asm volatile("vmxoff_finish:\n"); 833 | printk("<1> vmxoff complete\n"); 834 | } 835 | 836 | 837 | static void vmxon_exit(void) { 838 | if(vmxon_success==1) { 839 | printk("<1> Machine in vmxon: Attempting vmxoff\n"); 840 | do_vmxoff(); 841 | vmxon_success = 0; 842 | } 843 | turn_off_vmxe(); 844 | deallocate_vmcs_region(); 845 | deallocate_vmxon_region(); 846 | } 847 | 848 | 849 | 850 | static int vmxon_init(void) { 851 | unsigned long field_1; 852 | u32 value_1 =0; 853 | int cpuid_leaf =1; 854 | int cpuid_ecx =0; 855 | int msr3a_value = 0; 856 | 857 | printk("<1> In vmxon\n"); 858 | save_registers(); 859 | 860 | asm volatile("cpuid\n\t" 861 | :"=c"(cpuid_ecx) 862 | :"a"(cpuid_leaf) 863 | :"%rbx","%rdx"); 864 | 865 | if((cpuid_ecx>>CPUID_VMX_BIT)&1){ 866 | printk("<1> VMX supported CPU.\n"); 867 | } else { 868 | printk("<1> VMX not supported by CPU. Not doing anything\n"); 869 | goto finish_here; 870 | } 871 | 872 | /* 873 | asm volatile ("mov %0, %%rcx\n" 874 | : 875 | : "m"(feature_control_msr_addr) 876 | : "memory"); */ 877 | 878 | asm volatile("rdmsr\n" 879 | :"=a"(msr3a_value) 880 | :"c"(feature_control_msr_addr) 881 | :"%rdx" 882 | ); 883 | 884 | if(msr3a_value&1){ 885 | if((msr3a_value>>2)&1){ 886 | printk("MSR 0x3A:Lock bit is on.VMXON bit is on.OK\n"); 887 | } else { 888 | printk("MSR 0x3A:Lock bit is on.VMXONbit is off.Cannot do vmxon\n"); 889 | goto finish_here; 890 | } 891 | } else { 892 | printk("MSR 0x3A: Lock bit is not on. Not doing anything\n"); 893 | goto finish_here; 894 | } 895 | 896 | allocate_vmxon_region(); 897 | 898 | if(vmxon_region==NULL){ 899 | printk("<1> Error allocating vmxon region\n"); 900 | vmxon_exit(); 901 | vmxon_success = -ENOMEM; 902 | return vmxon_success; 903 | } 904 | 905 | vmxon_phy_region = __pa(vmxon_region); 906 | vmxon_setup_revid(); 907 | memcpy(vmxon_region, &vmx_rev_id, 4); //copy revision id to vmxon region 908 | turn_on_vmxe(); 909 | do_vmxon(); 910 | allocate_vmcs_region(); 911 | 912 | alloc_failure = (vmcs_guest_region==NULL) || (io_bitmap_a_region==NULL) || (io_bitmap_b_region==NULL) || (msr_bitmap_region==NULL) || (virtual_apic_page==NULL); 913 | 914 | if(alloc_failure){ 915 | printk("<1> Error allocating vmcs guest region\n"); 916 | vmxon_exit(); 917 | vmptrld_success = -ENOMEM; 918 | return vmptrld_success; 919 | } 920 | vmcs_phy_region = __pa(vmcs_guest_region); 921 | memcpy(vmcs_guest_region, &vmx_rev_id, 4); //copy revision id to vmcs region 922 | do_vmptrld(); 923 | initialize_guest_vmcs(); 924 | 925 | // do_vmlaunch(); 926 | //host rip 927 | asm ("movq $0x6c16, %rdx"); 928 | asm ("movq $vmexit_handler, %rax"); 929 | asm ("vmwrite %rax, %rdx"); 930 | 931 | //guest rip 932 | asm ("movq $0x681e, %rdx"); 933 | asm ("movq $guest_entry_point, %rax"); 934 | asm ("vmwrite %rax, %rdx"); 935 | 936 | printk("<1> Doing vmlaunch now..\n"); 937 | asm volatile (MY_VMX_VMLAUNCH); 938 | asm volatile("jbe vmexit_handler\n"); 939 | asm volatile("nop\n"); //will never get here 940 | asm volatile("guest_entry_point:"); 941 | asm volatile(MY_VMX_VMCALL); 942 | asm volatile("ud2\n"); //will never get here 943 | asm volatile("vmexit_handler:\n"); 944 | 945 | printk("<1> After vmexit\n"); 946 | 947 | field_1 = VMX_EXIT_REASON; 948 | value_1 = do_vmread(field_1); 949 | printk("<1> Guest VMexit reason: 0x%x\n",value_1); 950 | 951 | vmxon_exit(); //do vmxoff 952 | printk("<1> Enable Interrupts\n"); 953 | asm volatile("sti\n"); 954 | finish_here: 955 | printk("<1> Done\n"); 956 | restore_registers(); 957 | return 0; 958 | } 959 | 960 | 961 | static void vmxon_exit_dummy(void) { 962 | 963 | 964 | 965 | } 966 | 967 | module_init(vmxon_init); 968 | module_exit(vmxon_exit_dummy); 969 | -------------------------------------------------------------------------------- /vmxon_simple.h: -------------------------------------------------------------------------------- 1 | #define VMX_GUEST_ES_SEL 0x00000800 2 | #define VMX_GUEST_CS_SEL 0x00000802 3 | #define VMX_GUEST_SS_SEL 0x00000804 4 | #define VMX_GUEST_DS_SEL 0x00000806 5 | #define VMX_GUEST_FS_SEL 0x00000808 6 | #define VMX_GUEST_GS_SEL 0x0000080a 7 | #define VMX_GUEST_LDTR_SEL 0x0000080c 8 | #define VMX_GUEST_TR_SEL 0x0000080e 9 | #define VMX_VPID 0x00000000 10 | #define VMX_HOST_ES_SEL 0x00000c00 11 | #define VMX_HOST_CS_SEL 0x00000c02 12 | #define VMX_HOST_SS_SEL 0x00000c04 13 | #define VMX_HOST_DS_SEL 0x00000c06 14 | #define VMX_HOST_FS_SEL 0x00000c08 15 | #define VMX_HOST_GS_SEL 0x00000c0a 16 | #define VMX_HOST_TR_SEL 0x00000c0c 17 | #define VMX_IO_BITMAP_A_FULL 0x00002000 18 | #define VMX_IO_BITMAP_A_HIGH 0x00002001 19 | #define VMX_IO_BITMAP_B_FULL 0x00002002 20 | #define VMX_IO_BITMAP_B_HIGH 0x00002003 21 | #define VMX_MSR_BITMAP_FULL 0x00002004 22 | #define VMX_MSR_BITMAP_HIGH 0x00002005 23 | #define VMX_EXIT_MSR_STORE_ADDR_FULL 0x00002006 24 | #define VMX_EXIT_MSR_STORE_ADDR_HIGH 0x00002007 25 | #define VMX_EXIT_MSR_LOAD_ADDR_FULL 0x00002008 26 | #define VMX_EXIT_MSR_LOAD_ADDR_HIGH 0x00002009 27 | #define VMX_ENTRY_MSR_LOAD_ADDR_FULL 0x0000200a 28 | #define VMX_ENTRY_MSR_LOAD_ADDR_HIGH 0x0000200b 29 | #define VMX_EXECUTIVE_VMCS_PTR_FULL 0x0000200c 30 | #define VMX_EXECUTIVE_VMCS_PTR_HIGH 0x0000200d 31 | #define VMX_TSC_OFFSET_FULL 0x00002010 32 | #define VMX_TSC_OFFSET_HIGH 0x00002011 33 | #define VMX_VIRTUAL_APIC_PAGE_ADDR_FULL 0x00002012 34 | #define VMX_VIRTUAL_APIC_PAGE_ADDR_HIGH 0x00002013 35 | #define VMX_APIC_ACCESS_ADDR_FULL 0x00002014 36 | #define VMX_APIC_ACCESS_ADDR_HIGH 0x00002015 37 | #define VMX_EPT_POINTER_FULL 0x0000201A 38 | #define VMX_EPT_POINTER_HIGH 0x0000201B 39 | #define VMX_VMS_LINK_PTR_FULL 0x00002800 40 | #define VMX_VMS_LINK_PTR_HIGH 0x00002801 41 | #define VMX_GUEST_IA32_DEBUGCTL_FULL 0x00002802 42 | #define VMX_GUEST_IA32_DEBUGCTL_HIGH 0x00002803 43 | #define VMX_GUEST_IA32_PAT_FULL 0x00002804 44 | #define VMX_GUEST_IA32_PAT_HIGH 0x00002805 45 | #define VMX_GUEST_IA32_EFER_FULL 0x00002806 46 | #define VMX_GUEST_IA32_EFER_HIGH 0x00002807 47 | #define VMX_GUEST_IA32_PERF_CTL_FULL 0x00002808 48 | #define VMX_GUEST_IA32_PERF_CTL_HIGH 0x00002809 49 | #define VMX_GUEST_PDPTE0_FULL 0x0000280A 50 | #define VMX_GUEST_PDPTE0_HIGH 0x0000280B 51 | #define VMX_GUEST_PDPTE1_FULL 0x0000280C 52 | #define VMX_GUEST_PDPTE1_HIGH 0x0000280D 53 | #define VMX_GUEST_PDPTE2_FULL 0x0000280E 54 | #define VMX_GUEST_PDPTE2_HIGH 0x0000280F 55 | #define VMX_GUEST_PDPTE3_FULL 0x00002810 56 | #define VMX_GUEST_PDPTE3_HIGH 0x00002811 57 | #define VMX_HOST_IA32_PAT_FULL 0x00002C00 58 | #define VMX_HOST_IA32_PAT_HIGH 0x00002C01 59 | #define VMX_HOST_IA32_EFER_FULL 0x00002C02 60 | #define VMX_HOST_IA32_EFER_HIGH 0x00002C03 61 | #define VMX_HOST_IA32_PERF_CTL_FULL 0x00002C04 62 | #define VMX_HOST_IA32_PERF_CTL_HIGH 0x00002C05 63 | #define VMX_PIN_VM_EXEC_CONTROLS 0x00004000 64 | #define VMX_PROC_VM_EXEC_CONTROLS 0x00004002 65 | #define VMX_EXCEPTION_BITMAP 0x00004004 66 | #define VMX_PF_EC_MASK 0x00004006 67 | #define VMX_PF_EC_MATCH 0x00004008 68 | #define VMX_CR3_TARGET_COUNT 0x0000400a 69 | #define VMX_EXIT_CONTROLS 0x0000400c 70 | #define VMX_EXIT_MSR_STORE_COUNT 0x0000400e 71 | #define VMX_EXIT_MSR_LOAD_COUNT 0x00004010 72 | #define VMX_ENTRY_CONTROLS 0x00004012 73 | #define VMX_ENTRY_MSR_LOAD_COUNT 0x00004014 74 | #define VMX_ENTRY_INT_INFO_FIELD 0x00004016 75 | #define VMX_ENTRY_EXCEPTION_EC 0x00004018 76 | #define VMX_ENTRY_INSTR_LENGTH 0x0000401a 77 | #define VMX_TPR_THRESHOLD 0x0000401c 78 | #define VMX_PROC_VM_EXEC_CONTROLS2 0x0000401E 79 | #define VMX_PLE_GAP 0x00004020 80 | #define VMX_PLE_WINDOW 0x00004022 81 | #define VMX_INSTR_ERROR 0x00004400 82 | #define VMX_EXIT_REASON 0x00004402 83 | #define VMX_EXIT_INT_INFO 0x00004404 84 | #define VMX_EXIT_INT_EC 0x00004406 85 | #define VMX_IDT_VEC_INFO_FIELD 0x00004408 86 | #define VMX_IDT_VEC_EC 0x0000440a 87 | #define VMX_EXIT_INSTR_LEN 0x0000440c 88 | #define VMX_INSTR_INFO 0x0000440e 89 | #define VMX_GUEST_ES_LIMIT 0x00004800 90 | #define VMX_GUEST_CS_LIMIT 0x00004802 91 | #define VMX_GUEST_SS_LIMIT 0x00004804 92 | #define VMX_GUEST_DS_LIMIT 0x00004806 93 | #define VMX_GUEST_FS_LIMIT 0x00004808 94 | #define VMX_GUEST_GS_LIMIT 0x0000480a 95 | #define VMX_GUEST_LDTR_LIMIT 0x0000480c 96 | #define VMX_GUEST_TR_LIMIT 0x0000480e 97 | #define VMX_GUEST_GDTR_LIMIT 0x00004810 98 | #define VMX_GUEST_IDTR_LIMIT 0x00004812 99 | #define VMX_GUEST_ES_ATTR 0x00004814 100 | #define VMX_GUEST_CS_ATTR 0x00004816 101 | #define VMX_GUEST_SS_ATTR 0x00004818 102 | #define VMX_GUEST_DS_ATTR 0x0000481a 103 | #define VMX_GUEST_FS_ATTR 0x0000481c 104 | #define VMX_GUEST_GS_ATTR 0x0000481e 105 | #define VMX_GUEST_LDTR_ATTR 0x00004820 106 | #define VMX_GUEST_TR_ATTR 0x00004822 107 | #define VMX_GUEST_INTERRUPTIBILITY_INFO 0x00004824 108 | #define VMX_GUEST_ACTIVITY_STATE 0x00004826 109 | #define VMX_GUEST_SMBASE 0x00004828 110 | #define VMX_GUEST_IA32_SYSENTER_CS 0x0000482a 111 | #define VMX_GUEST_TIMER 0x0000482E 112 | #define VMX_HOST_IA32_SYSENTER_CS 0x00004c00 113 | #define VMX_CR0_MASK 0x00006000 114 | #define VMX_CR4_MASK 0x00006002 115 | #define VMX_CR0_READ_SHADOW 0x00006004 116 | #define VMX_CR4_READ_SHADOW 0x00006006 117 | #define VMX_CR3_TARGET_0 0x00006008 118 | #define VMX_CR3_TARGET_1 0x0000600a 119 | #define VMX_CR3_TARGET_2 0x0000600c 120 | #define VMX_CR3_TARGET_3 0x0000600e 121 | #define VMX_EXIT_QUALIFICATION 0x00006400 122 | #define VMX_IO_RCX 0x00006402 123 | #define VMX_IO_RDI 0x00006406 124 | #define VMX_GUEST_LINEAR_ADDR 0x0000640a 125 | #define VMX_GUEST_PHYSICAL_ADDR_FULL 0x00002400 126 | #define VMX_GUEST_PHYSICAL_ADDR_HIGH 0x00002401 127 | #define VMX_GUEST_CR0 0x00006800 128 | #define VMX_GUEST_CR3 0x00006802 129 | #define VMX_GUEST_CR4 0x00006804 130 | #define VMX_GUEST_ES_BASE 0x00006806 131 | #define VMX_GUEST_CS_BASE 0x00006808 132 | #define VMX_GUEST_SS_BASE 0x0000680a 133 | #define VMX_GUEST_DS_BASE 0x0000680c 134 | #define VMX_GUEST_FS_BASE 0x0000680e 135 | #define VMX_GUEST_GS_BASE 0x00006810 136 | #define VMX_GUEST_LDTR_BASE 0x00006812 137 | #define VMX_GUEST_TR_BASE 0x00006814 138 | #define VMX_GUEST_GDTR_BASE 0x00006816 139 | #define VMX_GUEST_IDTR_BASE 0x00006818 140 | #define VMX_GUEST_DR7 0x0000681a 141 | #define VMX_GUEST_RSP 0x0000681c 142 | #define VMX_GUEST_RIP 0x0000681e 143 | #define VMX_GUEST_RFLAGS 0x00006820 144 | #define VMX_GUEST_PENDING_DEBUG_EXCEPT 0x00006822 145 | #define VMX_GUEST_IA32_SYSENTER_ESP 0x00006824 146 | #define VMX_GUEST_IA32_SYSENTER_EIP 0x00006826 147 | #define VMX_HOST_CR0 0x00006c00 148 | #define VMX_HOST_CR3 0x00006c02 149 | #define VMX_HOST_CR4 0x00006c04 150 | #define VMX_HOST_FS_BASE 0x00006c06 151 | #define VMX_HOST_GS_BASE 0x00006c08 152 | #define VMX_HOST_TR_BASE 0x00006c0a 153 | #define VMX_HOST_GDTR_BASE 0x00006c0c 154 | #define VMX_HOST_IDTR_BASE 0x00006c0e 155 | #define VMX_HOST_IA32_SYSENTER_ESP 0x00006c10 156 | #define VMX_HOST_IA32_SYSENTER_EIP 0x00006c12 157 | #define VMX_HOST_RSP 0x00006c14 158 | #define VMX_HOST_RIP 0x00006c16 159 | --------------------------------------------------------------------------------