VirtualBox

Changeset 78772 in vbox for trunk/src


Ignore:
Timestamp:
May 27, 2019 5:22:48 AM (6 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 Added a separate LMSW VM-exit handler after decoding phase is done. VM-exit exception handler helpers should return rcStrict rather than int. Renamed VMX_EXIT_QUAL_CRX_LMSW_OP to VMX_EXIT_QUAL_CRX_LMSW_OP_MEM to reflect 1 is memory operand.

File:
1 edited

Legend:

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

    r78720 r78772  
    413413 * @{
    414414 */
    415 static int hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
    416 static int hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
    417 static int hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
    418 static int hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
    419 static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
    420 static int hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
    421 static int hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     415static VBOXSTRICTRC hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     416static VBOXSTRICTRC hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     417static VBOXSTRICTRC hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     418static VBOXSTRICTRC hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     419static VBOXSTRICTRC hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     420static VBOXSTRICTRC hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     421static VBOXSTRICTRC hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient);
     422static VBOXSTRICTRC hmR0VmxExitLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uMsw, RTGCPTR GCPtrEffDst);
    422423/** @} */
    423424
     
    1284312844                case VMX_EXIT_QUAL_CRX_ACCESS_WRITE:
    1284412845                case VMX_EXIT_QUAL_CRX_ACCESS_READ:
    12845                 case VMX_EXIT_QUAL_CRX_ACCESS_CLTS:
    1284612846                {
    1284712847                    /** @todo NSTVMX: Implement me. */
     
    1284912849                }
    1285012850
     12851                case VMX_EXIT_QUAL_CRX_ACCESS_CLTS:
     12852                {
     12853                    PCVMXVVMCS pVmcsNstGst = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     12854                    Assert(pVmcsNstGst);
     12855
     12856                    uint64_t const uGstHostMask = pVmcsNstGst->u64Cr0Mask.u;
     12857                    uint64_t const uReadShadow  = pVmcsNstGst->u64Cr0ReadShadow.u;
     12858                    if (   (uGstHostMask & X86_CR0_TS)
     12859                        && (uReadShadow  & X86_CR0_TS))
     12860                    {
     12861                        /** @todo NSTVMX: continue with VM-exit.   */
     12862                    }
     12863                    break;
     12864                }
     12865
    1285112866                case VMX_EXIT_QUAL_CRX_ACCESS_LMSW:        /* LMSW (Load Machine-Status Word into CR0) */
    1285212867                {
    12853                     uint16_t const uNewMsw = VMX_EXIT_QUAL_CRX_LMSW_DATA(pVmxTransient->uExitQual);
     12868                    RTGCPTR        GCPtrEffDst;
     12869                    uint16_t const uNewMsw     = VMX_EXIT_QUAL_CRX_LMSW_DATA(pVmxTransient->uExitQual);
     12870                    bool const     fMemOperand = VMX_EXIT_QUAL_CRX_LMSW_OP_MEM(pVmxTransient->uExitQual);
     12871
     12872                    rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
     12873                    if (fMemOperand)
     12874                    {
     12875                        rc |= hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient);
     12876                        GCPtrEffDst = pVmxTransient->uGuestLinearAddr;
     12877                    }
     12878                    else
     12879                        GCPtrEffDst = NIL_RTGCPTR;
     12880                    AssertRCReturn(rc, rc);
     12881
    1285412882                    if (CPUMIsGuestVmxLmswInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, uNewMsw))
    1285512883                    {
    12856                         rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
    12857                         AssertRCReturn(rc, rc);
    12858 
    12859                         RTGCPTR    GCPtrEffDst;
    12860                         bool const fMemOperand = VMX_EXIT_QUAL_CRX_LMSW_OP(pVmxTransient->uExitQual);
    12861                         if (fMemOperand)
    12862                         {
    12863                             rc = hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient);
    12864                             AssertRCReturn(rc, rc);
    12865                             GCPtrEffDst = pVmxTransient->uGuestLinearAddr;
    12866                         }
    12867                         else
    12868                             GCPtrEffDst = NIL_RTGCPTR;
    12869 
    1287012884                        VMXVEXITINFO ExitInfo;
    1287112885                        RT_ZERO(ExitInfo);
     
    1287712891                    }
    1287812892                    else
    12879                         rcStrict = hmR0VmxExitMovCRx(pVCpu, pVmxTransient);
     12893                        rcStrict = hmR0VmxExitLmsw(pVCpu, pVmxTransient->cbInstr, uNewMsw, GCPtrEffDst);
    1288012894                    break;
    1288112895                }
     
    1337413388
    1337513389    /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */
    13376     VBOXSTRICTRC rcStrictRc1 = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pVmxTransient);
    13377     if (RT_UNLIKELY(rcStrictRc1 == VINF_SUCCESS))
     13390    VBOXSTRICTRC rcStrict = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pVmxTransient);
     13391    if (RT_UNLIKELY(rcStrict == VINF_SUCCESS))
    1337813392    { /* likely */ }
    1337913393    else
    1338013394    {
    13381         if (rcStrictRc1 == VINF_HM_DOUBLE_FAULT)
    13382             rcStrictRc1 = VINF_SUCCESS;
     13395        if (rcStrict == VINF_HM_DOUBLE_FAULT)
     13396            rcStrict = VINF_SUCCESS;
    1338313397        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
    13384         return rcStrictRc1;
     13398        return rcStrict;
    1338513399    }
    1338613400
     
    1340713421            else if (uVector != X86_XCPT_PF)
    1340813422            {
    13409                 rc = VINF_SUCCESS;
     13423                rcStrict = VINF_SUCCESS;
    1341013424                break;
    1341113425            }
     
    1341313427            switch (uVector)
    1341413428            {
    13415                 case X86_XCPT_PF: rc = hmR0VmxExitXcptPF(pVCpu, pVmxTransient);      break;
    13416                 case X86_XCPT_GP: rc = hmR0VmxExitXcptGP(pVCpu, pVmxTransient);      break;
    13417                 case X86_XCPT_MF: rc = hmR0VmxExitXcptMF(pVCpu, pVmxTransient);      break;
    13418                 case X86_XCPT_DB: rc = hmR0VmxExitXcptDB(pVCpu, pVmxTransient);      break;
    13419                 case X86_XCPT_BP: rc = hmR0VmxExitXcptBP(pVCpu, pVmxTransient);      break;
    13420                 case X86_XCPT_AC: rc = hmR0VmxExitXcptAC(pVCpu, pVmxTransient);      break;
     13429                case X86_XCPT_PF: rcStrict = hmR0VmxExitXcptPF(pVCpu, pVmxTransient);      break;
     13430                case X86_XCPT_GP: rcStrict = hmR0VmxExitXcptGP(pVCpu, pVmxTransient);      break;
     13431                case X86_XCPT_MF: rcStrict = hmR0VmxExitXcptMF(pVCpu, pVmxTransient);      break;
     13432                case X86_XCPT_DB: rcStrict = hmR0VmxExitXcptDB(pVCpu, pVmxTransient);      break;
     13433                case X86_XCPT_BP: rcStrict = hmR0VmxExitXcptBP(pVCpu, pVmxTransient);      break;
     13434                case X86_XCPT_AC: rcStrict = hmR0VmxExitXcptAC(pVCpu, pVmxTransient);      break;
    1342113435
    1342213436                case X86_XCPT_NM: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM);
    13423                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13437                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1342413438                case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXF);
    13425                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13439                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1342613440                case X86_XCPT_DE: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE);
    13427                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13441                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1342813442                case X86_XCPT_UD: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestUD);
    13429                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13443                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1343013444                case X86_XCPT_SS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS);
    13431                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13445                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1343213446                case X86_XCPT_NP: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP);
    13433                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13447                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1343413448                case X86_XCPT_TS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestTS);
    13435                                   rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     13449                                  rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    1343613450                default:
    1343713451                {
     
    1345013464                                               pVmxTransient->cbInstr, pVmxTransient->uExitIntErrorCode,
    1345113465                                               0 /* GCPtrFaultAddress */);
     13466                        rcStrict = VINF_SUCCESS;
    1345213467                    }
    1345313468                    else
     
    1345513470                        AssertMsgFailed(("Unexpected VM-exit caused by exception %#x\n", uVector));
    1345613471                        pVCpu->hm.s.u32HMError = uVector;
    13457                         rc = VERR_VMX_UNEXPECTED_EXCEPTION;
     13472                        rcStrict = VERR_VMX_UNEXPECTED_EXCEPTION;
    1345813473                    }
    1345913474                    break;
     
    1346613481        {
    1346713482            pVCpu->hm.s.u32HMError = uExitIntInfo;
    13468             rc = VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE;
     13483            rcStrict = VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE;
    1346913484            AssertMsgFailed(("Unexpected interruption info %#x\n", VMX_EXIT_INT_INFO_TYPE(uExitIntInfo)));
    1347013485            break;
     
    1347213487    }
    1347313488    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
    13474     return rc;
     13489    return rcStrict;
    1347513490}
    1347613491
     
    1449414509        case VMX_EXIT_QUAL_CRX_ACCESS_LMSW:        /* LMSW (Load Machine-Status Word into CR0) */
    1449514510        {
    14496             /* Note! LMSW cannot clear CR0.PE, so no fRealOnV86Active kludge needed here. */
    14497             rc = hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient);
    14498             AssertRCReturn(rc, rc);
    14499             rcStrict = IEMExecDecodedLmsw(pVCpu, pVmxTransient->cbInstr, VMX_EXIT_QUAL_CRX_LMSW_DATA(uExitQual),
    14500                                           pVmxTransient->uGuestLinearAddr);
    14501             AssertMsg(   rcStrict == VINF_SUCCESS
    14502                       || rcStrict == VINF_IEM_RAISED_XCPT
    14503                       , ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    14504 
    14505             ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS | HM_CHANGED_GUEST_CR0);
    14506             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLmsw);
    14507             Log4Func(("LMSW rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict)));
     14511            /*
     14512             * LMSW cannot clear CR0.PE, so no fRealOnV86Active kludge needed here.
     14513             */
     14514            RTGCPTR        GCPtrEffDst;
     14515            uint8_t const  cbInstr     = pVmxTransient->cbInstr;
     14516            uint16_t const uMsw        = VMX_EXIT_QUAL_CRX_LMSW_DATA(uExitQual);
     14517            bool const     fMemOperand = VMX_EXIT_QUAL_CRX_LMSW_OP_MEM(uExitQual);
     14518            if (fMemOperand)
     14519            {
     14520                rc = hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient);
     14521                AssertRCReturn(rc, rc);
     14522                GCPtrEffDst = pVmxTransient->uGuestLinearAddr;
     14523            }
     14524            else
     14525                GCPtrEffDst = NIL_RTGCPTR;
     14526
     14527            rcStrict = hmR0VmxExitLmsw(pVCpu, cbInstr, uMsw, GCPtrEffDst);
    1450814528            break;
    1450914529        }
     
    1517215192 * VM-exit exception handler for \#MF (Math Fault: floating point exception).
    1517315193 */
    15174 static int hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15194static VBOXSTRICTRC hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1517515195{
    1517615196    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1520215222 * VM-exit exception handler for \#BP (Breakpoint exception).
    1520315223 */
    15204 static int hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15224static VBOXSTRICTRC hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1520515225{
    1520615226    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1523115251 * VM-exit exception handler for \#AC (alignment check exception).
    1523215252 */
    15233 static int hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15253static VBOXSTRICTRC hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1523415254{
    1523515255    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1525215272 * VM-exit exception handler for \#DB (Debug exception).
    1525315273 */
    15254 static int hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15274static VBOXSTRICTRC hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1525515275{
    1525615276    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1540615426 * @remarks Requires pVmxTransient->uExitIntInfo to be up-to-date.
    1540715427 */
    15408 static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15428static VBOXSTRICTRC hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1540915429{
    1541015430    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1548415504 *          up-to-date.
    1548515505 */
    15486 static int hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15506static VBOXSTRICTRC hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1548715507{
    1548815508    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1551715537 * VM-exit exception handler for \#PF (Page-fault exception).
    1551815538 */
    15519 static int hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15539static VBOXSTRICTRC hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1552015540{
    1552115541    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     
    1560915629}
    1561015630
     15631
     15632/**
     15633 * VM-exit exception handler for LMSW.
     15634 */
     15635static VBOXSTRICTRC hmR0VmxExitLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uMsw, RTGCPTR GCPtrEffDst)
     15636{
     15637    VBOXSTRICTRC rcStrict = IEMExecDecodedLmsw(pVCpu, cbInstr, uMsw, GCPtrEffDst);
     15638    AssertMsg(   rcStrict == VINF_SUCCESS
     15639              || rcStrict == VINF_IEM_RAISED_XCPT
     15640              , ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     15641    Log4Func(("rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict)));
     15642
     15643    ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS | HM_CHANGED_GUEST_CR0);
     15644    if (rcStrict == VINF_IEM_RAISED_XCPT)
     15645    {
     15646        ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_RAISED_XCPT_MASK);
     15647        rcStrict = VINF_SUCCESS;
     15648    }
     15649    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLmsw);
     15650    return rcStrict;
     15651}
     15652
     15653
    1561115654#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    1561215655/** @name VMX instruction handlers.
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