1 /*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include "opt_ddb.h" 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/pcpu.h> 37 38 #include <vm/vm.h> 39 #include <vm/pmap.h> 40 41 #include <machine/segments.h> 42 #include <machine/vmm.h> 43 #include "vmm_host.h" 44 #include "vmx_cpufunc.h" 45 #include "vmcs.h" 46 #include "ept.h" 47 #include "vmx.h" 48 49 #ifdef DDB 50 #include <ddb/ddb.h> 51 #endif 52 53 static uint64_t 54 vmcs_fix_regval(uint32_t encoding, uint64_t val) 55 { 56 57 switch (encoding) { 58 case VMCS_GUEST_CR0: 59 val = vmx_fix_cr0(val); 60 break; 61 case VMCS_GUEST_CR4: 62 val = vmx_fix_cr4(val); 63 break; 64 default: 65 break; 66 } 67 return (val); 68 } 69 70 static uint32_t 71 vmcs_field_encoding(int ident) 72 { 73 switch (ident) { 74 case VM_REG_GUEST_CR0: 75 return (VMCS_GUEST_CR0); 76 case VM_REG_GUEST_CR3: 77 return (VMCS_GUEST_CR3); 78 case VM_REG_GUEST_CR4: 79 return (VMCS_GUEST_CR4); 80 case VM_REG_GUEST_DR7: 81 return (VMCS_GUEST_DR7); 82 case VM_REG_GUEST_RSP: 83 return (VMCS_GUEST_RSP); 84 case VM_REG_GUEST_RIP: 85 return (VMCS_GUEST_RIP); 86 case VM_REG_GUEST_RFLAGS: 87 return (VMCS_GUEST_RFLAGS); 88 case VM_REG_GUEST_ES: 89 return (VMCS_GUEST_ES_SELECTOR); 90 case VM_REG_GUEST_CS: 91 return (VMCS_GUEST_CS_SELECTOR); 92 case VM_REG_GUEST_SS: 93 return (VMCS_GUEST_SS_SELECTOR); 94 case VM_REG_GUEST_DS: 95 return (VMCS_GUEST_DS_SELECTOR); 96 case VM_REG_GUEST_FS: 97 return (VMCS_GUEST_FS_SELECTOR); 98 case VM_REG_GUEST_GS: 99 return (VMCS_GUEST_GS_SELECTOR); 100 case VM_REG_GUEST_TR: 101 return (VMCS_GUEST_TR_SELECTOR); 102 case VM_REG_GUEST_LDTR: 103 return (VMCS_GUEST_LDTR_SELECTOR); 104 case VM_REG_GUEST_EFER: 105 return (VMCS_GUEST_IA32_EFER); 106 case VM_REG_GUEST_PDPTE0: 107 return (VMCS_GUEST_PDPTE0); 108 case VM_REG_GUEST_PDPTE1: 109 return (VMCS_GUEST_PDPTE1); 110 case VM_REG_GUEST_PDPTE2: 111 return (VMCS_GUEST_PDPTE2); 112 case VM_REG_GUEST_PDPTE3: 113 return (VMCS_GUEST_PDPTE3); 114 default: 115 return (-1); 116 } 117 118 } 119 120 static int 121 vmcs_seg_desc_encoding(int seg, uint32_t *base, uint32_t *lim, uint32_t *acc) 122 { 123 124 switch (seg) { 125 case VM_REG_GUEST_ES: 126 *base = VMCS_GUEST_ES_BASE; 127 *lim = VMCS_GUEST_ES_LIMIT; 128 *acc = VMCS_GUEST_ES_ACCESS_RIGHTS; 129 break; 130 case VM_REG_GUEST_CS: 131 *base = VMCS_GUEST_CS_BASE; 132 *lim = VMCS_GUEST_CS_LIMIT; 133 *acc = VMCS_GUEST_CS_ACCESS_RIGHTS; 134 break; 135 case VM_REG_GUEST_SS: 136 *base = VMCS_GUEST_SS_BASE; 137 *lim = VMCS_GUEST_SS_LIMIT; 138 *acc = VMCS_GUEST_SS_ACCESS_RIGHTS; 139 break; 140 case VM_REG_GUEST_DS: 141 *base = VMCS_GUEST_DS_BASE; 142 *lim = VMCS_GUEST_DS_LIMIT; 143 *acc = VMCS_GUEST_DS_ACCESS_RIGHTS; 144 break; 145 case VM_REG_GUEST_FS: 146 *base = VMCS_GUEST_FS_BASE; 147 *lim = VMCS_GUEST_FS_LIMIT; 148 *acc = VMCS_GUEST_FS_ACCESS_RIGHTS; 149 break; 150 case VM_REG_GUEST_GS: 151 *base = VMCS_GUEST_GS_BASE; 152 *lim = VMCS_GUEST_GS_LIMIT; 153 *acc = VMCS_GUEST_GS_ACCESS_RIGHTS; 154 break; 155 case VM_REG_GUEST_TR: 156 *base = VMCS_GUEST_TR_BASE; 157 *lim = VMCS_GUEST_TR_LIMIT; 158 *acc = VMCS_GUEST_TR_ACCESS_RIGHTS; 159 break; 160 case VM_REG_GUEST_LDTR: 161 *base = VMCS_GUEST_LDTR_BASE; 162 *lim = VMCS_GUEST_LDTR_LIMIT; 163 *acc = VMCS_GUEST_LDTR_ACCESS_RIGHTS; 164 break; 165 case VM_REG_GUEST_IDTR: 166 *base = VMCS_GUEST_IDTR_BASE; 167 *lim = VMCS_GUEST_IDTR_LIMIT; 168 *acc = VMCS_INVALID_ENCODING; 169 break; 170 case VM_REG_GUEST_GDTR: 171 *base = VMCS_GUEST_GDTR_BASE; 172 *lim = VMCS_GUEST_GDTR_LIMIT; 173 *acc = VMCS_INVALID_ENCODING; 174 break; 175 default: 176 return (EINVAL); 177 } 178 179 return (0); 180 } 181 182 int 183 vmcs_getreg(struct vmcs *vmcs, int running, int ident, uint64_t *retval) 184 { 185 int error; 186 uint32_t encoding; 187 188 /* 189 * If we need to get at vmx-specific state in the VMCS we can bypass 190 * the translation of 'ident' to 'encoding' by simply setting the 191 * sign bit. As it so happens the upper 16 bits are reserved (i.e 192 * set to 0) in the encodings for the VMCS so we are free to use the 193 * sign bit. 194 */ 195 if (ident < 0) 196 encoding = ident & 0x7fffffff; 197 else 198 encoding = vmcs_field_encoding(ident); 199 200 if (encoding == (uint32_t)-1) 201 return (EINVAL); 202 203 if (!running) 204 VMPTRLD(vmcs); 205 206 error = vmread(encoding, retval); 207 208 if (!running) 209 VMCLEAR(vmcs); 210 211 return (error); 212 } 213 214 int 215 vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val) 216 { 217 int error; 218 uint32_t encoding; 219 220 if (ident < 0) 221 encoding = ident & 0x7fffffff; 222 else 223 encoding = vmcs_field_encoding(ident); 224 225 if (encoding == (uint32_t)-1) 226 return (EINVAL); 227 228 val = vmcs_fix_regval(encoding, val); 229 230 if (!running) 231 VMPTRLD(vmcs); 232 233 error = vmwrite(encoding, val); 234 235 if (!running) 236 VMCLEAR(vmcs); 237 238 return (error); 239 } 240 241 int 242 vmcs_setdesc(struct vmcs *vmcs, int running, int seg, struct seg_desc *desc) 243 { 244 int error; 245 uint32_t base, limit, access; 246 247 error = vmcs_seg_desc_encoding(seg, &base, &limit, &access); 248 if (error != 0) 249 panic("vmcs_setdesc: invalid segment register %d", seg); 250 251 if (!running) 252 VMPTRLD(vmcs); 253 if ((error = vmwrite(base, desc->base)) != 0) 254 goto done; 255 256 if ((error = vmwrite(limit, desc->limit)) != 0) 257 goto done; 258 259 if (access != VMCS_INVALID_ENCODING) { 260 if ((error = vmwrite(access, desc->access)) != 0) 261 goto done; 262 } 263 done: 264 if (!running) 265 VMCLEAR(vmcs); 266 return (error); 267 } 268 269 int 270 vmcs_getdesc(struct vmcs *vmcs, int running, int seg, struct seg_desc *desc) 271 { 272 int error; 273 uint32_t base, limit, access; 274 uint64_t u64; 275 276 error = vmcs_seg_desc_encoding(seg, &base, &limit, &access); 277 if (error != 0) 278 panic("vmcs_getdesc: invalid segment register %d", seg); 279 280 if (!running) 281 VMPTRLD(vmcs); 282 if ((error = vmread(base, &u64)) != 0) 283 goto done; 284 desc->base = u64; 285 286 if ((error = vmread(limit, &u64)) != 0) 287 goto done; 288 desc->limit = u64; 289 290 if (access != VMCS_INVALID_ENCODING) { 291 if ((error = vmread(access, &u64)) != 0) 292 goto done; 293 desc->access = u64; 294 } 295 done: 296 if (!running) 297 VMCLEAR(vmcs); 298 return (error); 299 } 300 301 int 302 vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count) 303 { 304 int error; 305 306 VMPTRLD(vmcs); 307 308 /* 309 * Guest MSRs are saved in the VM-exit MSR-store area. 310 * Guest MSRs are loaded from the VM-entry MSR-load area. 311 * Both areas point to the same location in memory. 312 */ 313 if ((error = vmwrite(VMCS_EXIT_MSR_STORE, g_area)) != 0) 314 goto done; 315 if ((error = vmwrite(VMCS_EXIT_MSR_STORE_COUNT, g_count)) != 0) 316 goto done; 317 318 if ((error = vmwrite(VMCS_ENTRY_MSR_LOAD, g_area)) != 0) 319 goto done; 320 if ((error = vmwrite(VMCS_ENTRY_MSR_LOAD_COUNT, g_count)) != 0) 321 goto done; 322 323 error = 0; 324 done: 325 VMCLEAR(vmcs); 326 return (error); 327 } 328 329 int 330 vmcs_init(struct vmcs *vmcs) 331 { 332 int error, codesel, datasel, tsssel; 333 u_long cr0, cr4, efer; 334 uint64_t pat, fsbase, idtrbase; 335 uint32_t exc_bitmap; 336 337 codesel = vmm_get_host_codesel(); 338 datasel = vmm_get_host_datasel(); 339 tsssel = vmm_get_host_tsssel(); 340 341 /* 342 * Make sure we have a "current" VMCS to work with. 343 */ 344 VMPTRLD(vmcs); 345 346 /* Initialize guest IA32_PAT MSR with the default value */ 347 pat = PAT_VALUE(0, PAT_WRITE_BACK) | 348 PAT_VALUE(1, PAT_WRITE_THROUGH) | 349 PAT_VALUE(2, PAT_UNCACHED) | 350 PAT_VALUE(3, PAT_UNCACHEABLE) | 351 PAT_VALUE(4, PAT_WRITE_BACK) | 352 PAT_VALUE(5, PAT_WRITE_THROUGH) | 353 PAT_VALUE(6, PAT_UNCACHED) | 354 PAT_VALUE(7, PAT_UNCACHEABLE); 355 if ((error = vmwrite(VMCS_GUEST_IA32_PAT, pat)) != 0) 356 goto done; 357 358 /* Host state */ 359 360 /* Initialize host IA32_PAT MSR */ 361 pat = vmm_get_host_pat(); 362 if ((error = vmwrite(VMCS_HOST_IA32_PAT, pat)) != 0) 363 goto done; 364 365 /* Load the IA32_EFER MSR */ 366 efer = vmm_get_host_efer(); 367 if ((error = vmwrite(VMCS_HOST_IA32_EFER, efer)) != 0) 368 goto done; 369 370 /* Load the control registers */ 371 372 cr0 = vmm_get_host_cr0(); 373 if ((error = vmwrite(VMCS_HOST_CR0, cr0)) != 0) 374 goto done; 375 376 cr4 = vmm_get_host_cr4() | CR4_VMXE; 377 if ((error = vmwrite(VMCS_HOST_CR4, cr4)) != 0) 378 goto done; 379 380 /* Load the segment selectors */ 381 if ((error = vmwrite(VMCS_HOST_ES_SELECTOR, datasel)) != 0) 382 goto done; 383 384 if ((error = vmwrite(VMCS_HOST_CS_SELECTOR, codesel)) != 0) 385 goto done; 386 387 if ((error = vmwrite(VMCS_HOST_SS_SELECTOR, datasel)) != 0) 388 goto done; 389 390 if ((error = vmwrite(VMCS_HOST_DS_SELECTOR, datasel)) != 0) 391 goto done; 392 393 if ((error = vmwrite(VMCS_HOST_FS_SELECTOR, datasel)) != 0) 394 goto done; 395 396 if ((error = vmwrite(VMCS_HOST_GS_SELECTOR, datasel)) != 0) 397 goto done; 398 399 if ((error = vmwrite(VMCS_HOST_TR_SELECTOR, tsssel)) != 0) 400 goto done; 401 402 /* 403 * Load the Base-Address for %fs and idtr. 404 * 405 * Note that we exclude %gs, tss and gdtr here because their base 406 * address is pcpu specific. 407 */ 408 fsbase = vmm_get_host_fsbase(); 409 if ((error = vmwrite(VMCS_HOST_FS_BASE, fsbase)) != 0) 410 goto done; 411 412 idtrbase = vmm_get_host_idtrbase(); 413 if ((error = vmwrite(VMCS_HOST_IDTR_BASE, idtrbase)) != 0) 414 goto done; 415 416 /* instruction pointer */ 417 if ((error = vmwrite(VMCS_HOST_RIP, (u_long)vmx_exit_guest)) != 0) 418 goto done; 419 420 /* exception bitmap */ 421 exc_bitmap = 1 << IDT_MC; 422 if ((error = vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap)) != 0) 423 goto done; 424 425 /* link pointer */ 426 if ((error = vmwrite(VMCS_LINK_POINTER, ~0)) != 0) 427 goto done; 428 done: 429 VMCLEAR(vmcs); 430 return (error); 431 } 432 433 #ifdef DDB 434 extern int vmxon_enabled[]; 435 436 DB_SHOW_COMMAND(vmcs, db_show_vmcs) 437 { 438 uint64_t cur_vmcs, val; 439 uint32_t exit; 440 441 if (!vmxon_enabled[curcpu]) { 442 db_printf("VMX not enabled\n"); 443 return; 444 } 445 446 if (have_addr) { 447 db_printf("Only current VMCS supported\n"); 448 return; 449 } 450 451 vmptrst(&cur_vmcs); 452 if (cur_vmcs == VMCS_INITIAL) { 453 db_printf("No current VM context\n"); 454 return; 455 } 456 db_printf("VMCS: %jx\n", cur_vmcs); 457 db_printf("VPID: %lu\n", vmcs_read(VMCS_VPID)); 458 db_printf("Activity: "); 459 val = vmcs_read(VMCS_GUEST_ACTIVITY); 460 switch (val) { 461 case 0: 462 db_printf("Active"); 463 break; 464 case 1: 465 db_printf("HLT"); 466 break; 467 case 2: 468 db_printf("Shutdown"); 469 break; 470 case 3: 471 db_printf("Wait for SIPI"); 472 break; 473 default: 474 db_printf("Unknown: %#lx", val); 475 } 476 db_printf("\n"); 477 exit = vmcs_read(VMCS_EXIT_REASON); 478 if (exit & 0x80000000) 479 db_printf("Entry Failure Reason: %u\n", exit & 0xffff); 480 else 481 db_printf("Exit Reason: %u\n", exit & 0xffff); 482 db_printf("Qualification: %#lx\n", vmcs_exit_qualification()); 483 db_printf("Guest Linear Address: %#lx\n", 484 vmcs_read(VMCS_GUEST_LINEAR_ADDRESS)); 485 switch (exit & 0x8000ffff) { 486 case EXIT_REASON_EXCEPTION: 487 case EXIT_REASON_EXT_INTR: 488 val = vmcs_read(VMCS_EXIT_INTR_INFO); 489 db_printf("Interrupt Type: "); 490 switch (val >> 8 & 0x7) { 491 case 0: 492 db_printf("external"); 493 break; 494 case 2: 495 db_printf("NMI"); 496 break; 497 case 3: 498 db_printf("HW exception"); 499 break; 500 case 4: 501 db_printf("SW exception"); 502 break; 503 default: 504 db_printf("?? %lu", val >> 8 & 0x7); 505 break; 506 } 507 db_printf(" Vector: %lu", val & 0xff); 508 if (val & 0x800) 509 db_printf(" Error Code: %lx", 510 vmcs_read(VMCS_EXIT_INTR_ERRCODE)); 511 db_printf("\n"); 512 break; 513 case EXIT_REASON_EPT_FAULT: 514 case EXIT_REASON_EPT_MISCONFIG: 515 db_printf("Guest Physical Address: %#lx\n", 516 vmcs_read(VMCS_GUEST_PHYSICAL_ADDRESS)); 517 break; 518 } 519 db_printf("VM-instruction error: %#lx\n", vmcs_instruction_error()); 520 } 521 #endif 522