VirtualBox

Changeset 45502 in vbox


Ignore:
Timestamp:
Apr 12, 2013 12:22:50 AM (12 years ago)
Author:
vboxsync
Message:

VMMR0/HMVMXR0: Redo the event injection logic to be done only on the entry side. This is cleaner and any returns the recompiler should not lose any events.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r45501 r45502  
    232232static DECLCALLBACK(int)  hmR0VmxExitRdtsc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    233233static DECLCALLBACK(int)  hmR0VmxExitRsm(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    234 static DECLCALLBACK(int)  hmR0VmxExitInjectXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
     234static DECLCALLBACK(int)  hmR0VmxExitSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    235235static DECLCALLBACK(int)  hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    236236static DECLCALLBACK(int)  hmR0VmxExitMovDRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
     
    304304 /* 16  VMX_EXIT_RDTSC                   */  hmR0VmxExitRdtsc,
    305305 /* 17  VMX_EXIT_RSM                     */  hmR0VmxExitRsm,
    306  /* 18  VMX_EXIT_VMCALL                  */  hmR0VmxExitInjectXcptUD,
    307  /* 19  VMX_EXIT_VMCLEAR                 */  hmR0VmxExitInjectXcptUD,
    308  /* 20  VMX_EXIT_VMLAUNCH                */  hmR0VmxExitInjectXcptUD,
    309  /* 21  VMX_EXIT_VMPTRLD                 */  hmR0VmxExitInjectXcptUD,
    310  /* 22  VMX_EXIT_VMPTRST                 */  hmR0VmxExitInjectXcptUD,
    311  /* 23  VMX_EXIT_VMREAD                  */  hmR0VmxExitInjectXcptUD,
    312  /* 24  VMX_EXIT_VMRESUME                */  hmR0VmxExitInjectXcptUD,
    313  /* 25  VMX_EXIT_VMWRITE                 */  hmR0VmxExitInjectXcptUD,
    314  /* 26  VMX_EXIT_VMXOFF                  */  hmR0VmxExitInjectXcptUD,
    315  /* 27  VMX_EXIT_VMXON                   */  hmR0VmxExitInjectXcptUD,
     306 /* 18  VMX_EXIT_VMCALL                  */  hmR0VmxExitSetPendingXcptUD,
     307 /* 19  VMX_EXIT_VMCLEAR                 */  hmR0VmxExitSetPendingXcptUD,
     308 /* 20  VMX_EXIT_VMLAUNCH                */  hmR0VmxExitSetPendingXcptUD,
     309 /* 21  VMX_EXIT_VMPTRLD                 */  hmR0VmxExitSetPendingXcptUD,
     310 /* 22  VMX_EXIT_VMPTRST                 */  hmR0VmxExitSetPendingXcptUD,
     311 /* 23  VMX_EXIT_VMREAD                  */  hmR0VmxExitSetPendingXcptUD,
     312 /* 24  VMX_EXIT_VMRESUME                */  hmR0VmxExitSetPendingXcptUD,
     313 /* 25  VMX_EXIT_VMWRITE                 */  hmR0VmxExitSetPendingXcptUD,
     314 /* 26  VMX_EXIT_VMXOFF                  */  hmR0VmxExitSetPendingXcptUD,
     315 /* 27  VMX_EXIT_VMXON                   */  hmR0VmxExitSetPendingXcptUD,
    316316 /* 28  VMX_EXIT_MOV_CRX                 */  hmR0VmxExitMovCRx,
    317317 /* 29  VMX_EXIT_MOV_DRX                 */  hmR0VmxExitMovDRx,
     
    336336 /* 48  VMX_EXIT_EPT_VIOLATION           */  hmR0VmxExitEptViolation,
    337337 /* 49  VMX_EXIT_EPT_MISCONFIG           */  hmR0VmxExitEptMisconfig,
    338  /* 50  VMX_EXIT_INVEPT                  */  hmR0VmxExitInjectXcptUD,
     338 /* 50  VMX_EXIT_INVEPT                  */  hmR0VmxExitSetPendingXcptUD,
    339339 /* 51  VMX_EXIT_RDTSCP                  */  hmR0VmxExitRdtscp,
    340340 /* 52  VMX_EXIT_PREEMPT_TIMER           */  hmR0VmxExitPreemptTimer,
    341  /* 53  VMX_EXIT_INVVPID                 */  hmR0VmxExitInjectXcptUD,
     341 /* 53  VMX_EXIT_INVVPID                 */  hmR0VmxExitSetPendingXcptUD,
    342342 /* 54  VMX_EXIT_WBINVD                  */  hmR0VmxExitWbinvd,
    343343 /* 55  VMX_EXIT_XSETBV                  */  hmR0VmxExitXsetbv,
     
    345345 /* 57  VMX_EXIT_RDRAND                  */  hmR0VmxExitRdrand,
    346346 /* 58  VMX_EXIT_INVPCID                 */  hmR0VmxExitInvpcid,
    347  /* 59  VMX_EXIT_VMFUNC                  */  hmR0VmxExitInjectXcptUD
     347 /* 59  VMX_EXIT_VMFUNC                  */  hmR0VmxExitSetPendingXcptUD
    348348};
    349349
     
    46374637
    46384638/**
     4639 * Sets an event as a pending event to be injected into the guest.
     4640 *
     4641 * @param   pVCpu           Pointer to the VMCPU.
     4642 * @param   u32IntrInfo     The VM-entry interruption-information field.
     4643 * @param   cbInstr         The VM-entry instruction length in bytes (for software
     4644 *                          interrupts, exceptions and privileged software
     4645 *                          exceptions).
     4646 * @param   u32ErrCode      The VM-entry exception error code.
     4647 */
     4648DECLINLINE(void) hmR0VmxSetPendingEvent(PVMCPU pVCpu, uint32_t u32IntrInfo, uint32_t cbInstr, uint32_t u32ErrCode)
     4649{
     4650    Assert(!pVCpu->hm.s.Event.fPending);
     4651    pVCpu->hm.s.Event.fPending    = true;
     4652    pVCpu->hm.s.Event.u64IntrInfo = u32IntrInfo;
     4653    pVCpu->hm.s.Event.u32ErrCode  = u32ErrCode;
     4654    pVCpu->hm.s.Event.u32InstrLen = cbInstr;
     4655}
     4656
     4657
     4658/**
    46394659 * Handle a condition that occurred while delivering an event through the guest
    46404660 * IDT.
     
    47224742            case VMXREFLECTXCPT_XCPT:
    47234743            {
    4724                 Assert(!pVCpu->hm.s.Event.fPending);
    4725                 pVCpu->hm.s.Event.fPending = true;
    4726                 pVCpu->hm.s.Event.u64IntrInfo = VMX_ENTRY_INTR_INFO_FROM_EXIT_IDT_INFO(pVmxTransient->uIdtVectoringInfo);
     4744                uint32_t u32ErrCode = 0;
    47274745                if (VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.u64IntrInfo))
    47284746                {
    47294747                    rc = hmR0VmxReadIdtVectoringErrorCodeVmcs(pVmxTransient);
    47304748                    AssertRCReturn(rc, rc);
    4731                     pVCpu->hm.s.Event.u32ErrCode = pVmxTransient->uIdtVectoringErrorCode;
     4749                    u32ErrCode = pVmxTransient->uIdtVectoringErrorCode;
    47324750                }
    4733                 else
    4734                     pVCpu->hm.s.Event.u32ErrCode = 0;
     4751                hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INTR_INFO_FROM_EXIT_IDT_INFO(pVmxTransient->uIdtVectoringInfo),
     4752                                       0 /* cbInstr */,  u32ErrCode);
     4753                rc = VINF_SUCCESS;
    47354754                Log(("Pending event %#RX64 Err=%#RX32\n", pVCpu->hm.s.Event.u64IntrInfo, pVCpu->hm.s.Event.u32ErrCode));
    47364755                break;
     
    47434762                u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
    47444763                u32IntrInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID;
    4745 
    4746                 Assert(!pVCpu->hm.s.Event.fPending);
    4747                 pVCpu->hm.s.Event.fPending     = true;
    4748                 pVCpu->hm.s.Event.u64IntrInfo  = u32IntrInfo;
    4749                 pVCpu->hm.s.Event.u32ErrCode   = 0;
     4764                hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);
    47504765                rc = VINF_VMX_DOUBLE_FAULT;
    47514766                Log(("Pending #DF %#RX64 uIdt=%#x uExit=%#x\n", pVCpu->hm.s.Event.u64IntrInfo, uIdtVector, uExitVector));
     
    47644779        }
    47654780    }
    4766     Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET || rc == VINF_VMX_DOUBLE_FAULT);
     4781    Assert(rc == VINF_SUCCESS || rc == VINF_VMX_DOUBLE_FAULT || rc == VINF_EM_RESET);
    47674782    return rc;
    47684783}
     
    55735588        pVCpu->hm.s.Event.fPending = false;
    55745589    }
    5575 
    5576     /* Clear the VT-x state bits to prevent any stale injection. This can happen when InjectEventVmcs() */
    5577     int rc2 = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0);
    5578     AssertRC(rc2);
    55795590}
    55805591
     
    58045815    if (pVCpu->hm.s.Event.fPending)
    58055816    {
    5806         Log(("Pending event\n"));
    5807         int rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, pVCpu->hm.s.Event.u64IntrInfo, 0 /* cbInstr */,
    5808                                     pVCpu->hm.s.Event.u32ErrCode);
     5817        Log(("Injecting pending event\n"));
     5818        int rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, pVCpu->hm.s.Event.u64IntrInfo, pVCpu->hm.s.Event.u32InstrLen,
     5819                                        pVCpu->hm.s.Event.u32ErrCode);
    58095820        AssertRCReturn(rc, rc);
    58105821        pVCpu->hm.s.Event.fPending = false;
     
    58825893        Assert(!TRPMHasTrap(pVCpu));
    58835894        AssertRCReturn(rc, rc);
    5884     }
     5895        return rc;
     5896    }
     5897
     5898    /* Clear the VM-entry interruption info. if we're not injecting anything; prevents any stale injection. */
     5899    rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0);
     5900    AssertRCReturn(rc, rc);
    58855901    return rc;
    58865902}
    58875903
    58885904/**
    5889  * Injects an invalid-opcode (#UD) exception into the VM.
     5905 * Sets an invalid-opcode (#UD) exception as pending-for-injection into the VM.
    58905906 *
    58915907 * @returns VBox status code (informational status code included).
     
    58955911 *                          before using them.
    58965912 */
    5897 DECLINLINE(int) hmR0VmxInjectXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     5913DECLINLINE(int) hmR0VmxSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
    58985914{
    58995915    /* Refer Intel spec. 24.8.3 "VM-entry Controls for Event Injection" for the format of u32IntrInfo. */
    59005916    uint32_t u32IntrInfo = X86_XCPT_UD | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
    59015917    STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
    5902     return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);
     5918    hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);
     5919    return VINF_SUCCESS;
     5920}
     5921
     5922
     5923/**
     5924 * Sets a double-fault (#DF) exception as pending-for-injection into the VM.
     5925 *
     5926 * @param   pVCpu           Pointer to the VMCPU.
     5927 * @param   pMixedCtx       Pointer to the guest-CPU context. The data may be
     5928 *                          out-of-sync. Make sure to update the required fields
     5929 *                          before using them.
     5930 */
     5931DECLINLINE(void) hmR0VmxSetPendingXcptDF(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     5932{
     5933    /* Inject the double-fault. */
     5934    uint32_t u32IntrInfo = X86_XCPT_DF | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
     5935    u32IntrInfo         |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
     5936    u32IntrInfo         |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID;
     5937    STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
     5938    hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo,  0 /* cbInstr */, 0 /* u32ErrCode */);
    59035939}
    59045940
     
    59205956    u32IntrInfo         |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID;
    59215957    STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
    5922     return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);
    5923 }
    5924 
    5925 
    5926 /**
    5927  * Injects a debug (#DB) exception into the VM.
     5958    return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo,  0 /* cbInstr */, 0 /* u32ErrCode */);
     5959}
     5960
     5961
     5962/**
     5963 * Sets a debug (#DB) exception as pending-for-injection into the VM.
    59285964 *
    59295965 * @returns VBox status code (informational status code included).
     
    59335969 *                          before using them.
    59345970 */
    5935 DECLINLINE(int) hmR0VmxInjectXcptDB(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     5971DECLINLINE(int) hmR0VmxSetPendingXcptDB(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
    59365972{
    59375973    /* Inject the debug-exception. */
     
    59395975    u32IntrInfo         |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
    59405976    STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
    5941     return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);
    5942 }
    5943 
    5944 
    5945 /**
    5946  * Injects a overflow (#OF) exception into the VM.
     5977    hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);
     5978    return VINF_SUCCESS;
     5979}
     5980
     5981
     5982/**
     5983 * Sets an overflow (#OF) exception as pending-for-injection into the VM.
    59475984 *
    59485985 * @returns VBox status code (informational status code included).
     
    59545991 *                          stack.
    59555992 */
    5956 DECLINLINE(int) hmR0VmxInjectXcptOF(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint32_t cbInstr)
     5993DECLINLINE(int) hmR0VmxSetPendingXcptOF(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint32_t cbInstr)
    59575994{
    59585995    /* Inject the overflow exception. */
     
    59605997    u32IntrInfo         |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
    59615998    STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
    5962     return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, cbInstr, 0 /* u32ErrCode */);
     5999    hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, cbInstr, 0 /* u32ErrCode */);
     6000    return VINF_SUCCESS;
    59636001}
    59646002
     
    60046042    u32IntrInfo         |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
    60056043    STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
    6006     return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, cbInstr, 0 /* u32ErrCode */);
     6044    hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, cbInstr, 0 /* u32ErrCode */);
     6045    return VINF_SUCCESS;
    60076046}
    60086047
     
    67486787        case VMX_EXIT_INVVPID:
    67496788        case VMX_EXIT_VMFUNC:
    6750             rc = hmR0VmxExitInjectXcptUD(pVCpu, pMixedCtx, pVmxTransient);
     6789            rc = hmR0VmxExitSetPendingXcptUD(pVCpu, pMixedCtx, pVmxTransient);
    67516790            break;
    67526791        default:
     
    68966935                        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
    68976936                        AssertRCReturn(rc, rc);
    6898                         rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    6899                                                     VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(uExitIntrInfo),
    6900                                                     pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
     6937                        hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(uExitIntrInfo),
     6938                                               pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    69016939                        AssertRCReturn(rc, rc);
    69026940                    }
     
    73017339 * VM-exit handler for instructions that result in a #UD exception delivered to the guest.
    73027340 */
    7303 static DECLCALLBACK(int) hmR0VmxExitInjectXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
     7341static DECLCALLBACK(int) hmR0VmxExitSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
    73047342{
    73057343    VMX_VALIDATE_EXIT_HANDLER_PARAMS();
    7306     return hmR0VmxInjectXcptUD(pVCpu, pMixedCtx);
     7344    hmR0VmxSetPendingXcptUD(pVCpu, pMixedCtx);
     7345    return VINF_SUCCESS;
    73077346}
    73087347
     
    78847923                        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG;
    78857924
    7886                         /* Inject #DB and get on with guest execution. */
    7887                         rc = hmR0VmxInjectXcptDB(pVCpu, pMixedCtx);
     7925                        /* Set #DB to be injected into the VM and continue guest execution. */
     7926                        rc = hmR0VmxSetPendingXcptDB(pVCpu, pMixedCtx);
    78887927                        AssertRCReturn(rc, rc);
    78897928                        break;
     
    82638302        return VERR_EM_INTERPRETER;
    82648303    }
    8265     rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8266                                  VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8267                                  pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    8268     AssertRCReturn(rc, rc);
     8304    hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8305                           pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    82698306    return rc;
    82708307}
     
    82938330        AssertRCReturn(rc, rc);
    82948331
    8295         rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8296                                     VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8297                                     pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    8298         AssertRCReturn(rc, rc);
    8299     }
    8300 
    8301     Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET || rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_EM_DBG_BREAKPOINT);
     8332        hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8333                               pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
     8334    }
     8335
     8336    Assert(rc == VINF_SUCCESS || rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_EM_DBG_BREAKPOINT);
    83028337    return rc;
    83038338}
     
    83458380        rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
    83468381        rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient);
    8347         rc |= hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8348                                      VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8349                                      pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    83508382        AssertRCReturn(rc,rc);
     8383        hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8384                               pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    83518385        return rc;
    83528386    }
     
    83878421    rc = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
    83888422    AssertRCReturn(rc, rc);
    8389     rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8390                                 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8391                                 pVmxTransient->cbInstr, 0 /* error code */);
    8392     AssertRCReturn(rc, rc);
     8423    hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8424                           pVmxTransient->cbInstr, 0 /* error code */);
    83938425    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM);
    83948426    return rc;
     
    84158447        rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
    84168448        rc |= hmR0VmxSaveGuestRip(pVCpu, pMixedCtx);
     8449        AssertRCReturn(rc, rc);
    84178450        Log(("#GP Gst: RIP %#RX64\n", pMixedCtx->rip));
    8418         rc |= hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8419                                      VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8420                                      pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    8421         AssertRCReturn(rc, rc);
     8451        hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8452                               pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    84228453        return rc;
    84238454#else
     
    86088639                if (pMixedCtx->eflags.Bits.u1OF)
    86098640                {
    8610                     rc = hmR0VmxInjectXcptOF(pVCpu, pMixedCtx, pDis->cbInstr);
     8641                    rc = hmR0VmxSetPendingXcptOF(pVCpu, pMixedCtx, pDis->cbInstr);
    86118642                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
    86128643                }
     
    86288659        rc = VERR_EM_INTERPRETER;
    86298660
    8630     AssertMsg(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT
    8631               || rc == VINF_EM_RESET /* injection caused triple fault */,
     8661    AssertMsg(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT,
    86328662              ("#GP Unexpected rc=%Rrc\n", rc));
    86338663    return rc;
     
    86488678    /* Re-inject the exception into the guest. This cannot be a double-fault condition which would have been handled in
    86498679       hmR0VmxCheckExitDueToEventDelivery(). */
    8650     int rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8651                                     VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8652                                     pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    8653     AssertRCReturn(rc, rc);
    8654     return rc;
     8680    hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8681                           pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
     8682    return VINF_SUCCESS;
    86558683}
    86568684
     
    86758703        {
    86768704            pMixedCtx->cr2 = pVmxTransient->uExitQualification;
    8677             rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8678                                         VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8679                                         pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    8680             AssertRCReturn(rc, rc);
     8705            hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8706                                   pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);
    86818707        }
    86828708        else
    86838709        {
    86848710            /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
    8685             Assert(!pVCpu->hm.s.Event.fPending);
    8686             rc = hmR0VmxInjectXcptDF(pVCpu, pMixedCtx);
     8711            rc = hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
    86878712        }
    86888713        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
     
    87578782            TRPMResetTrap(pVCpu);
    87588783            pMixedCtx->cr2 = pVmxTransient->uExitQualification;
    8759             rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,
    8760                                         VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
    8761                                         pVmxTransient->cbInstr, uGstErrorCode);
    8762             AssertRCReturn(rc, rc);
     8784            hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),
     8785                                   pVmxTransient->cbInstr, uGstErrorCode);
    87638786        }
    87648787        else
    87658788        {
    87668789            /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */
    8767             Assert(!pVCpu->hm.s.Event.fPending);
    87688790            TRPMResetTrap(pVCpu);
    8769             Log(("#PF: Injecting #DF\n"));
    8770             rc = hmR0VmxInjectXcptDF(pVCpu, pMixedCtx);
     8791            hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx);
     8792            Log(("#PF: Pending #DF injection\n"));
    87718793        }
    87728794        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
    8773         Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET);
    8774         return rc;
     8795        return VINF_SUCCESS;
    87758796    }
    87768797
  • trunk/src/VBox/VMM/include/HMInternal.h

    r45501 r45502  
    731731        uint32_t                    fPending;
    732732        uint32_t                    u32ErrCode;
     733        uint32_t                    u32InstrLen;
    733734        uint64_t                    u64IntrInfo;
    734735    } Event;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette