VirtualBox

Changeset 78527 in vbox


Ignore:
Timestamp:
May 15, 2019 4:59:02 AM (6 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 invvpid support. Also fixes redundant checks in hmR0VmxDecodeMemOperand with comments.

File:
1 edited

Legend:

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

    r78493 r78527  
    386386static FNVMXEXITHANDLER            hmR0VmxExitVmxoff;
    387387static FNVMXEXITHANDLER            hmR0VmxExitVmxon;
     388static FNVMXEXITHANDLER            hmR0VmxExitInvvpid;
    388389#endif
    389390static FNVMXEXITHANDLER            hmR0VmxExitRdtsc;
     
    556557 /* 51  VMX_EXIT_RDTSCP                  */  hmR0VmxExitRdtscp,
    557558 /* 52  VMX_EXIT_PREEMPT_TIMER           */  hmR0VmxExitPreemptTimer,
     559#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     560 /* 53  VMX_EXIT_INVVPID                 */  hmR0VmxExitInvvpid,
     561#else
    558562 /* 53  VMX_EXIT_INVVPID                 */  hmR0VmxExitSetPendingXcptUD,
     563#endif
    559564 /* 54  VMX_EXIT_WBINVD                  */  hmR0VmxExitWbinvd,
    560565 /* 55  VMX_EXIT_XSETBV                  */  hmR0VmxExitXsetbv,
     
    67856790 *                          RIP-relative addressing pass RIP + displacement here.
    67866791 * @param   pGCPtrMem       Where to store the effective destination memory address.
     6792 *
     6793 * @remarks Warning! This function ASSUMES the instruction cannot be used in real or
     6794 *          virtual-8086 mode hence skips those checks while verifying if the
     6795 *          segment is valid.
    67876796 */
    67886797static VBOXSTRICTRC hmR0VmxDecodeMemOperand(PVMCPU pVCpu, uint32_t uExitInstrInfo, RTGCPTR GCPtrDisp, VMXMEMACCESS enmMemAccess,
     
    69776986                              | CPUMCTX_EXTRN_CS  | CPUMCTX_EXTRN_EFER);
    69786987
    6979     if (   CPUMIsGuestInRealOrV86ModeEx(&pVCpu->cpum.GstCtx)
    6980         || (    CPUMIsGuestInLongModeEx(&pVCpu->cpum.GstCtx)
    6981             && !CPUMIsGuestIn64BitCodeEx(&pVCpu->cpum.GstCtx)))
    6982     {
    6983         Log4Func(("In real/v86-mode or long-mode outside 64-bit code segment -> #UD\n"));
    6984         hmR0VmxSetPendingXcptUD(pVCpu);
    6985         return VINF_HM_PENDING_XCPT;
    6986     }
     6988    /*
     6989     * The physical CPU would have already checked the CPU mode/code segment.
     6990     * We shall just assert here for paranoia.
     6991     * See Intel spec. 25.1.1 "Relative Priority of Faults and VM Exits".
     6992     */
     6993    Assert(!CPUMIsGuestInRealOrV86ModeEx(&pVCpu->cpum.GstCtx));
     6994    Assert(   !CPUMIsGuestInLongModeEx(&pVCpu->cpum.GstCtx)
     6995           ||  CPUMIsGuestIn64BitCodeEx(&pVCpu->cpum.GstCtx));
    69876996
    69886997    if (uExitReason == VMX_EXIT_VMXON)
     
    70147023    }
    70157024
    7016     if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx))
    7017     {
    7018         /*
    7019          * The nested-guest attempted to execute a VMX instruction, cause a VM-exit and let
    7020          * the guest hypervisor deal with it.
    7021          */
    7022         /** @todo NSTVMX: Trigger a VM-exit */
    7023     }
    7024 
    7025     /*
    7026      * VMX instructions require CPL 0 except in VMX non-root mode where the VM-exit intercept
    7027      * (above) takes preceedence over the CPL check.
    7028      */
    7029     if (CPUMGetGuestCPL(pVCpu) > 0)
    7030     {
    7031         Log4Func(("CPL > 0 -> #GP(0)\n"));
    7032         hmR0VmxSetPendingXcptGP(pVCpu, 0);
    7033         return VINF_HM_PENDING_XCPT;
    7034     }
    7035 
     7025    /* All other checks (including VM-exit intercepts) are handled by IEM instruction emulation. */
    70367026    return VINF_SUCCESS;
    70377027}
     
    1246512455        case VMX_EXIT_VMXOFF:                  VMEXIT_CALL_RET(0, hmR0VmxExitVmxoff(pVCpu, pVmxTransient));
    1246612456        case VMX_EXIT_VMXON:                   VMEXIT_CALL_RET(0, hmR0VmxExitVmxon(pVCpu, pVmxTransient));
     12457        case VMX_EXIT_INVVPID:                 VMEXIT_CALL_RET(0, hmR0VmxExitInvvpid(pVCpu, pVmxTransient));
    1246712458#else
    1246812459        case VMX_EXIT_VMCLEAR:
     
    1247512466        case VMX_EXIT_VMXOFF:
    1247612467        case VMX_EXIT_VMXON:
     12468        case VMX_EXIT_INVVPID:
    1247712469            return hmR0VmxExitSetPendingXcptUD(pVCpu, pVmxTransient);
    1247812470#endif
     
    1248912481
    1249012482        case VMX_EXIT_INVEPT:
    12491         case VMX_EXIT_INVVPID:
    1249212483        case VMX_EXIT_VMFUNC:
    1249312484        case VMX_EXIT_XSAVES:
     
    1255612547        }
    1255712548
    12558         case VMX_EXIT_CPUID:
    12559         {
    12560             int rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
    12561             AssertRCReturn(rc, rc);
    12562             rcStrict = IEMExecVmxVmexitInstr(pVCpu, uExitReason, pVmxTransient->cbInstr);
    12563             break;
    12564         }
    12565 
    1256612549        case VMX_EXIT_RDTSC:
    1256712550        {
     
    1258312566            else
    1258412567                rcStrict = hmR0VmxExitRdtsc(pVCpu, pVmxTransient);
     12568            break;
     12569        }
     12570
     12571        /* Instructions that cause VM-exits unconditionally (and provide only the instruction length). */
     12572        case VMX_EXIT_CPUID:
     12573        case VMX_EXIT_VMCALL:
     12574        case VMX_EXIT_GETSEC:
     12575        case VMX_EXIT_INVD:
     12576        case VMX_EXIT_XSETBV:
     12577        {
     12578            int rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
     12579            AssertRCReturn(rc, rc);
     12580            rcStrict = IEMExecVmxVmexitInstr(pVCpu, uExitReason, pVmxTransient->cbInstr);
    1258512581            break;
    1258612582        }
     
    1263512631        }
    1263612632
    12637         case VMX_EXIT_VMCALL:
    1263812633        case VMX_EXIT_MOV_DRX:
    1263912634        case VMX_EXIT_HLT:
    12640         case VMX_EXIT_INVD:
    1264112635        case VMX_EXIT_INVLPG:
    1264212636        case VMX_EXIT_RSM:
     
    1264612640        case VMX_EXIT_LDTR_TR_ACCESS:
    1264712641        case VMX_EXIT_WBINVD:
    12648         case VMX_EXIT_XSETBV:
    1264912642        case VMX_EXIT_RDRAND:
    1265012643        case VMX_EXIT_INVPCID:
    12651         case VMX_EXIT_GETSEC:
    1265212644        case VMX_EXIT_RDPMC:
    1265312645        case VMX_EXIT_VMCLEAR:
     
    1267112663
    1267212664        case VMX_EXIT_INVEPT:
    12673         case VMX_EXIT_INVVPID:
     12665        case VMX_EXIT_INVVPID:  /** @todo NSTVMX: Do this next. */
    1267412666        case VMX_EXIT_VMFUNC:
    1267512667        case VMX_EXIT_XSAVES:
     
    1562615618}
    1562715619
     15620
     15621/**
     15622 * VM-exit handler for INVVPID (VMX_EXIT_INVVPID). Unconditional VM-exit.
     15623 */
     15624HMVMX_EXIT_DECL hmR0VmxExitInvvpid(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15625{
     15626    HMVMX_VALIDATE_EXIT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     15627
     15628    int rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
     15629    rc    |= hmR0VmxImportGuestState(pVCpu, pVmxTransient->pVmcsInfo, CPUMCTX_EXTRN_RSP | CPUMCTX_EXTRN_SREG_MASK
     15630                                                                    | IEM_CPUMCTX_EXTRN_EXEC_DECODED_MEM_MASK);
     15631    rc    |= hmR0VmxReadExitInstrInfoVmcs(pVmxTransient);
     15632    rc    |= hmR0VmxReadExitQualVmcs(pVCpu, pVmxTransient);
     15633    AssertRCReturn(rc, rc);
     15634
     15635    HMVMX_CHECK_EXIT_DUE_TO_VMX_INSTR(pVCpu, pVmxTransient->uExitReason);
     15636
     15637    VMXVEXITINFO ExitInfo;
     15638    RT_ZERO(ExitInfo);
     15639    ExitInfo.uReason     = pVmxTransient->uExitReason;
     15640    ExitInfo.u64Qual     = pVmxTransient->uExitQual;
     15641    ExitInfo.InstrInfo.u = pVmxTransient->ExitInstrInfo.u;
     15642    ExitInfo.cbInstr     = pVmxTransient->cbInstr;
     15643    HMVMX_DECODE_MEM_OPERAND(pVCpu, ExitInfo.InstrInfo.u, ExitInfo.u64Qual, VMXMEMACCESS_READ, &ExitInfo.GCPtrEffAddr);
     15644
     15645    VBOXSTRICTRC rcStrict = IEMExecDecodedInvvpid(pVCpu, &ExitInfo);
     15646    if (RT_LIKELY(rcStrict == VINF_SUCCESS))
     15647        ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS);
     15648    else if (rcStrict == VINF_IEM_RAISED_XCPT)
     15649    {
     15650        ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_RAISED_XCPT_MASK);
     15651        rcStrict = VINF_SUCCESS;
     15652    }
     15653    return rcStrict;
     15654}
     15655
    1562815656/** @} */
    1562915657#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
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