VirtualBox

Changeset 52006 in vbox for trunk


Ignore:
Timestamp:
Jul 12, 2014 12:01:19 PM (10 years ago)
Author:
vboxsync
Message:

VMM: VT-x and AMD-V support for making GIM hypercalls.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/gim.h

    r51797 r52006  
    200200VMMDECL(bool)               GIMIsEnabled(PVM pVM);
    201201VMMDECL(GIMPROVIDERID)      GIMGetProvider(PVM pVM);
    202 VMMDECL(bool)               GIMIsParavirtTscEnabled(PVM pVM);
     202VMM_INT_DECL(bool)          GIMIsParavirtTscEnabled(PVM pVM);
     203VMM_INT_DECL(bool)          GIMAreHypercallsEnabled(PVMCPU pVCpu);
    203204VMM_INT_DECL(int)           GIMHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
    204205VMM_INT_DECL(int)           GIMReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
  • trunk/src/VBox/VMM/VMMAll/GIMAll.cpp

    r51643 r52006  
    5757
    5858/**
     59 * Returns whether the guest has configured and enabled calls to the hypervisor.
     60 *
     61 * @returns true if hypercalls are enabled and usable, false otherwise.
     62 * @param   pVCpu           Pointer to the VMCPU.
     63 */
     64VMM_INT_DECL(bool) GIMAreHypercallsEnabled(PVMCPU pVCpu)
     65{
     66    PVM pVM = pVCpu->CTX_SUFF(pVM);
     67    if (!GIMIsEnabled(pVM))
     68        return false;
     69
     70    switch (pVM->gim.s.enmProviderId)
     71    {
     72        case GIMPROVIDERID_HYPERV:
     73            return GIMHvAreHypercallsEnabled(pVCpu);
     74
     75        default:
     76            return false;
     77    }
     78}
     79
     80
     81/**
    5982 * Implements a GIM hypercall with the provider configured for the VM.
    6083 *
     
    6689{
    6790    PVM pVM = pVCpu->CTX_SUFF(pVM);
    68     Assert(GIMIsEnabled(pVM));
    6991    VMCPU_ASSERT_EMT(pVCpu);
     92
     93    if (RT_UNLIKELY(!GIMIsEnabled(pVM)))
     94        return VERR_GIM_NOT_ENABLED;
    7095
    7196    switch (pVM->gim.s.enmProviderId)
     
    80105}
    81106
    82 VMMDECL(bool) GIMIsParavirtTscEnabled(PVM pVM)
     107
     108/**
     109 * Returns whether the guest has configured and setup the use of paravirtualized
     110 * TSC. Paravirtualized TSCs are per-VM and the rest of the execution engine
     111 * logic relies on that.
     112 *
     113 * @returns true if enabled and usable, false otherwise.
     114 * @param   pVM         Pointer to the VM.
     115 */
     116VMM_INT_DECL(bool) GIMIsParavirtTscEnabled(PVM pVM)
    83117{
    84118    if (!pVM->gim.s.fEnabled)
  • trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp

    r51980 r52006  
    4444VMM_INT_DECL(int) GIMHvHypercall(PVMCPU pVCpu, PCPUMCTX pCtx)
    4545{
    46     return VINF_SUCCESS;
     46    PVM pVM = pVCpu->CTX_SUFF(pVM);
     47    if (!MSR_GIM_HV_HYPERCALL_IS_ENABLED(pVM->gim.s.u.Hv.u64HypercallMsr))
     48        return VERR_GIM_HYPERCALLS_NOT_ENABLED;
     49
     50    /** @todo Handle hypercalls. Fail for now */
     51    return VERR_GIM_IPE_3;
     52}
     53
     54
     55/**
     56 * Returns whether the guest has configured and enabled the use of Hyper-V's
     57 * hypercall interface.
     58 *
     59 * @returns true if hypercalls are enabled, false otherwise.
     60 * @param   pVCpu       Pointer to the VMCPU.
     61 */
     62VMM_INT_DECL(bool) GIMHvAreHypercallsEnabled(PVMCPU pVCpu)
     63{
     64    return MSR_GIM_HV_HYPERCALL_IS_ENABLED(pVCpu->CTX_SUFF(pVM)->gim.s.u.Hv.u64HypercallMsr);
    4765}
    4866
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r51723 r52006  
    38313831 *
    38323832 * @returns VBox status code.
     3833 * @retval VINF_SUCCESS if the access was handled successfully.
     3834 * @retval VERR_NOT_FOUND if no patch record for this eip could be found.
     3835 * @retval VERR_SVM_UNEXPECTED_PATCH_TYPE if the found patch type is invalid.
     3836 *
    38333837 * @param   pVM         Pointer to the VM.
    38343838 * @param   pVCpu       Pointer to the VMCPU.
     
    38383842{
    38393843    Log4(("Emulated VMMCall TPR access replacement at RIP=%RGv\n", pCtx->rip));
     3844    bool fPatchFound = false;
    38403845    for (;;)
    38413846    {
     
    38473852            break;
    38483853
     3854        fPatchFound = true;
    38493855        switch (pPatch->enmType)
    38503856        {
     
    38883894    }
    38893895
    3890     return VINF_SUCCESS;
     3896    if (fPatchFound)
     3897        return VINF_SUCCESS;
     3898    return VERR_NOT_FOUND;
    38913899}
    38923900
     
    48964904    HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
    48974905
     4906    /* First check if this is a patched VMMCALL for mov TPR */
    48984907    int rc = hmR0SvmEmulateMovTpr(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx);
    4899     if (RT_LIKELY(rc == VINF_SUCCESS))
     4908    if (rc == VINF_SUCCESS)
    49004909        HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    4901     else
     4910    else if (rc == VERR_NOT_FOUND)
     4911    {
     4912        /* Handle GIM provider hypercalls. */
     4913        rc = VERR_NOT_SUPPORTED;
     4914        if (GIMAreHypercallsEnabled(pVCpu))
     4915            rc = GIMHypercall(pVCpu, pCtx);
     4916    }
     4917
     4918    if (rc != VINF_SUCCESS)
    49024919        hmR0SvmSetPendingXcptUD(pVCpu);
    49034920    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r51981 r52006  
    371371static FNVMXEXITHANDLER hmR0VmxExitInvlpg;
    372372static FNVMXEXITHANDLER hmR0VmxExitRdpmc;
     373static FNVMXEXITHANDLER hmR0VmxExitVmcall;
    373374static FNVMXEXITHANDLER hmR0VmxExitRdtsc;
    374375static FNVMXEXITHANDLER hmR0VmxExitRsm;
     
    440441 /* 16  VMX_EXIT_RDTSC                   */  hmR0VmxExitRdtsc,
    441442 /* 17  VMX_EXIT_RSM                     */  hmR0VmxExitRsm,
    442  /* 18  VMX_EXIT_VMCALL                  */  hmR0VmxExitSetPendingXcptUD,
     443 /* 18  VMX_EXIT_VMCALL                  */  hmR0VmxExitVmcall,
    443444 /* 19  VMX_EXIT_VMCLEAR                 */  hmR0VmxExitSetPendingXcptUD,
    444445 /* 20  VMX_EXIT_VMLAUNCH                */  hmR0VmxExitSetPendingXcptUD,
     
    89248925        case VMX_EXIT_GETSEC:                  /* SVVMCS(); */ rc = hmR0VmxExitGetsec(pVCpu, pMixedCtx, pVmxTransient);            /* LDVMCS(); */ break;
    89258926        case VMX_EXIT_RDPMC:                   /* SVVMCS(); */ rc = hmR0VmxExitRdpmc(pVCpu, pMixedCtx, pVmxTransient);             /* LDVMCS(); */ break;
     8927        case VMX_EXIT_VMCALL:                  /* SVVMCS(); */ rc = hmR0VmxExitVmcall(pVCpu, pMixedCtx, pVmxTransient);            /* LDVMCS(); */ break;
    89268928
    89278929        case VMX_EXIT_TRIPLE_FAULT:            rc = hmR0VmxExitTripleFault(pVCpu, pMixedCtx, pVmxTransient); break;
     
    89358937        case VMX_EXIT_ERR_MACHINE_CHECK:       rc = hmR0VmxExitErrMachineCheck(pVCpu, pMixedCtx, pVmxTransient); break;
    89368938
    8937         case VMX_EXIT_VMCALL:
    89388939        case VMX_EXIT_VMCLEAR:
    89398940        case VMX_EXIT_VMLAUNCH:
     
    99779978
    99789979/**
     9980 * VM-exit handler for VMCALL (VMX_EXIT_VMCALL). Unconditional VM-exit.
     9981 */
     9982HMVMX_EXIT_DECL hmR0VmxExitVmcall(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)
     9983{
     9984    HMVMX_VALIDATE_EXIT_HANDLER_PARAMS();
     9985
     9986    int rc = VERR_NOT_SUPPORTED;
     9987    if (GIMAreHypercallsEnabled(pVCpu))
     9988    {
     9989        rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
     9990        AssertRCReturn(rc, rc);
     9991
     9992        rc = GIMHypercall(pVCpu, pMixedCtx);
     9993    }
     9994    if (rc != VINF_SUCCESS)
     9995    {
     9996        hmR0VmxSetPendingXcptUD(pVCpu, pMixedCtx);
     9997        rc = VINF_SUCCESS;
     9998    }
     9999
     10000    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitVmcall);
     10001    return rc;
     10002}
     10003
     10004
     10005/**
    997910006 * VM-exit handler for INVLPG (VMX_EXIT_INVLPG). Conditional VM-exit.
    998010007 */
  • trunk/src/VBox/VMM/include/GIMHvInternal.h

    r51981 r52006  
    516516
    517517VMM_INT_DECL(bool)              GIMHvIsParavirtTscEnabled(PVM pVM);
     518VMM_INT_DECL(bool)              GIMHvAreHypercallsEnabled(PVMCPU pVCpu);
    518519VMM_INT_DECL(int)               GIMHvHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
    519520VMM_INT_DECL(int)               GIMHvReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
  • trunk/src/VBox/VMM/include/HMInternal.h

    r51643 r52006  
    857857    STAMCOUNTER             StatExitRdtscp;
    858858    STAMCOUNTER             StatExitRdpmc;
     859    STAMCOUNTER             StatExitVmcall;
    859860    STAMCOUNTER             StatExitRdrand;
    860861    STAMCOUNTER             StatExitCli;
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