| 431 | } |
| 432 | |
| 433 | static void |
| 434 | vmcb_init(struct svm_softc *sc, int vcpu, uint64_t iopm_base_pa, |
| 435 | uint64_t msrpm_base_pa, uint64_t np_pml4) |
| 436 | { |
| 437 | struct vmcb_ctrl *ctrl; |
| 438 | struct vmcb_state *state; |
| 439 | uint32_t mask; |
| 440 | int n; |
| 441 | |
| 442 | ctrl = svm_get_vmcb_ctrl(sc, vcpu); |
| 443 | state = svm_get_vmcb_state(sc, vcpu); |
| 444 | |
| 445 | ctrl->iopm_base_pa = iopm_base_pa; |
| 446 | ctrl->msrpm_base_pa = msrpm_base_pa; |
| 447 | |
| 448 | /* Enable nested paging */ |
| 449 | ctrl->np_enable = 1; |
| 450 | ctrl->n_cr3 = np_pml4; |
| 451 | |
| 452 | /* |
| 453 | * Intercept accesses to the control registers that are not shadowed |
| 454 | * in the VMCB - i.e. all except cr0, cr2, cr3, cr4 and cr8. |
| 455 | */ |
| 456 | for (n = 0; n < 16; n++) { |
| 457 | mask = (BIT(n) << 16) | BIT(n); |
| 458 | if (n == 0 || n == 2 || n == 3 || n == 4 || n == 8) |
| 459 | svm_disable_intercept(sc, vcpu, VMCB_CR_INTCPT, mask); |
| 460 | else |
| 461 | svm_enable_intercept(sc, vcpu, VMCB_CR_INTCPT, mask); |
| 462 | } |
| 463 | |
| 464 | /* |
| 465 | * Intercept everything when tracing guest exceptions otherwise |
| 466 | * just intercept machine check exception. |
| 467 | */ |
| 468 | if (vcpu_trace_exceptions(sc->vm, vcpu)) { |
| 469 | for (n = 0; n < 32; n++) { |
| 470 | /* |
| 471 | * Skip unimplemented vectors in the exception bitmap. |
| 472 | */ |
| 473 | if (n == 2 || n == 9) { |
| 474 | continue; |
| 475 | } |
| 476 | svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(n)); |
| 477 | } |
| 478 | } else { |
| 479 | svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(IDT_MC)); |
| 480 | } |
| 481 | |
| 482 | /* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */ |
| 483 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_IO); |
| 484 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_MSR); |
| 485 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_CPUID); |
| 486 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_INTR); |
| 487 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_INIT); |
| 488 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_NMI); |
| 489 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_SMI); |
| 490 | svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_SHUTDOWN); |
no test coverage detected