| 1413 | } |
| 1414 | |
| 1415 | static void |
| 1416 | vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic, |
| 1417 | uint64_t guestrip) |
| 1418 | { |
| 1419 | int vector, need_nmi_exiting, extint_pending; |
| 1420 | uint64_t rflags, entryinfo; |
| 1421 | uint32_t gi, info; |
| 1422 | |
| 1423 | if (vmx->state[vcpu].nextrip != guestrip) { |
| 1424 | gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); |
| 1425 | if (gi & HWINTR_BLOCKING) { |
| 1426 | VCPU_CTR2(vmx->vm, vcpu, "Guest interrupt blocking " |
| 1427 | "cleared due to rip change: %#lx/%#lx", |
| 1428 | vmx->state[vcpu].nextrip, guestrip); |
| 1429 | gi &= ~HWINTR_BLOCKING; |
| 1430 | vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi); |
| 1431 | } |
| 1432 | } |
| 1433 | |
| 1434 | if (vm_entry_intinfo(vmx->vm, vcpu, &entryinfo)) { |
| 1435 | KASSERT((entryinfo & VMCS_INTR_VALID) != 0, ("%s: entry " |
| 1436 | "intinfo is not valid: %#lx", __func__, entryinfo)); |
| 1437 | |
| 1438 | info = vmcs_read(VMCS_ENTRY_INTR_INFO); |
| 1439 | KASSERT((info & VMCS_INTR_VALID) == 0, ("%s: cannot inject " |
| 1440 | "pending exception: %#lx/%#x", __func__, entryinfo, info)); |
| 1441 | |
| 1442 | info = entryinfo; |
| 1443 | vector = info & 0xff; |
| 1444 | if (vector == IDT_BP || vector == IDT_OF) { |
| 1445 | /* |
| 1446 | * VT-x requires #BP and #OF to be injected as software |
| 1447 | * exceptions. |
| 1448 | */ |
| 1449 | info &= ~VMCS_INTR_T_MASK; |
| 1450 | info |= VMCS_INTR_T_SWEXCEPTION; |
| 1451 | } |
| 1452 | |
| 1453 | if (info & VMCS_INTR_DEL_ERRCODE) |
| 1454 | vmcs_write(VMCS_ENTRY_EXCEPTION_ERROR, entryinfo >> 32); |
| 1455 | |
| 1456 | vmcs_write(VMCS_ENTRY_INTR_INFO, info); |
| 1457 | } |
| 1458 | |
| 1459 | if (vm_nmi_pending(vmx->vm, vcpu)) { |
| 1460 | /* |
| 1461 | * If there are no conditions blocking NMI injection then |
| 1462 | * inject it directly here otherwise enable "NMI window |
| 1463 | * exiting" to inject it as soon as we can. |
| 1464 | * |
| 1465 | * We also check for STI_BLOCKING because some implementations |
| 1466 | * don't allow NMI injection in this case. If we are running |
| 1467 | * on a processor that doesn't have this restriction it will |
| 1468 | * immediately exit and the NMI will be injected in the |
| 1469 | * "NMI window exiting" handler. |
| 1470 | */ |
| 1471 | need_nmi_exiting = 1; |
| 1472 | gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); |
no test coverage detected