| 1111 | } |
| 1112 | |
| 1113 | static void |
| 1114 | clear_nmi_blocking(struct svm_softc *sc, int vcpu) |
| 1115 | { |
| 1116 | int error; |
| 1117 | |
| 1118 | KASSERT(nmi_blocked(sc, vcpu), ("vNMI already unblocked")); |
| 1119 | VCPU_CTR0(sc->vm, vcpu, "vNMI blocking cleared"); |
| 1120 | /* |
| 1121 | * When the IRET intercept is cleared the vcpu will attempt to execute |
| 1122 | * the "iret" when it runs next. However, it is possible to inject |
| 1123 | * another NMI into the vcpu before the "iret" has actually executed. |
| 1124 | * |
| 1125 | * For e.g. if the "iret" encounters a #NPF when accessing the stack |
| 1126 | * it will trap back into the hypervisor. If an NMI is pending for |
| 1127 | * the vcpu it will be injected into the guest. |
| 1128 | * |
| 1129 | * XXX this needs to be fixed |
| 1130 | */ |
| 1131 | svm_disable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_IRET); |
| 1132 | |
| 1133 | /* |
| 1134 | * Set 'intr_shadow' to prevent an NMI from being injected on the |
| 1135 | * immediate VMRUN. |
| 1136 | */ |
| 1137 | error = svm_modify_intr_shadow(sc, vcpu, 1); |
| 1138 | KASSERT(!error, ("%s: error %d setting intr_shadow", __func__, error)); |
| 1139 | } |
| 1140 | |
| 1141 | #define EFER_MBZ_BITS 0xFFFFFFFFFFFF0200UL |
| 1142 |
no test coverage detected