VirtualBox

Changeset 54065 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Feb 3, 2015 10:45:39 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
98006
Message:

VMM: Implemented TM TSC-mode switching with paravirtualized guests.

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

Legend:

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

    r53631 r54065  
    55
    66/*
    7  * Copyright (C) 2013-2014 Oracle Corporation
     7 * Copyright (C) 2013-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    22572257static void hmR0SvmUpdateTscOffsetting(PVMCPU pVCpu)
    22582258{
    2259     bool     fParavirtTsc = false;
     2259    bool fParavirtTsc;
     2260    bool fCanUseRealTsc;
    22602261    PSVMVMCB pVmcb = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb;
    2261     if (TMCpuTickCanUseRealTSC(pVCpu, &pVmcb->ctrl.u64TSCOffset, &fParavirtTsc))
    2262     {
    2263         uint64_t u64CurTSC   = ASMReadTSC();
    2264         uint64_t u64LastTick = TMCpuTickGetLastSeen(pVCpu);
    2265 
    2266         if (u64CurTSC + pVmcb->ctrl.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))
    2267         {
    2268             pVmcb->ctrl.u32InterceptCtrl1 &= ~SVM_CTRL1_INTERCEPT_RDTSC;
    2269             pVmcb->ctrl.u32InterceptCtrl2 &= ~SVM_CTRL2_INTERCEPT_RDTSCP;
    2270             STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffset);
    2271         }
    2272         else
    2273         {
    2274             pVmcb->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_RDTSC;
    2275             pVmcb->ctrl.u32InterceptCtrl2 |= SVM_CTRL2_INTERCEPT_RDTSCP;
    2276             STAM_COUNTER_INC(&pVCpu->hm.s.StatTscInterceptOverFlow);
    2277         }
     2262    fCanUseRealTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVmcb->ctrl.u64TSCOffset, &fParavirtTsc);
     2263    if (fCanUseRealTsc)
     2264    {
     2265        pVmcb->ctrl.u32InterceptCtrl1 &= ~SVM_CTRL1_INTERCEPT_RDTSC;
     2266        pVmcb->ctrl.u32InterceptCtrl2 &= ~SVM_CTRL2_INTERCEPT_RDTSCP;
     2267        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffset);
    22782268    }
    22792269    else
    22802270    {
    2281         Assert(!fParavirtTsc);
    22822271        pVmcb->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_RDTSC;
    22832272        pVmcb->ctrl.u32InterceptCtrl2 |= SVM_CTRL2_INTERCEPT_RDTSCP;
    22842273        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscIntercept);
    22852274    }
    2286 
     2275    pVmcb->ctrl.u64VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
     2276
     2277    /** @todo later optimize this to be done elsewhere and not before every
     2278     *        VM-entry. */
    22872279    if (fParavirtTsc)
    22882280    {
     
    22912283        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscParavirt);
    22922284    }
    2293 
    2294     pVmcb->ctrl.u64VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
    22952285}
    22962286
     
    32003190    }
    32013191
    3202     /** @todo Last-seen-tick shouldn't be necessary when TM supports invariant
    3203      *        mode. */
    32043192    if (!(pVmcb->ctrl.u32InterceptCtrl1 & SVM_CTRL1_INTERCEPT_RDTSC))
    3205         TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVmcb->ctrl.u64TSCOffset);
     3193        TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVmcb->ctrl.u64TSCOffset);     /** @todo use SUPReadTSC() eventually. */
    32063194
    32073195    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x);
     
    43574345    HMSVM_CHECK_SINGLE_STEP(pVCpu, rc);
    43584346    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt);
     4347    if (rc != VINF_SUCCESS)
     4348        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHltToR3);
    43594349    return rc;
    43604350}
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r54058 r54065  
    55
    66/*
    7  * Copyright (C) 2012-2014 Oracle Corporation
     7 * Copyright (C) 2012-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    56065606    if (pVM->hm.s.vmx.fUsePreemptTimer)
    56075607    {
    5608         uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVCpu, &fOffsettedTsc, &fParavirtTsc,
    5609                                                                      &pVCpu->hm.s.vmx.u64TSCOffset);
     5608        uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset, &fOffsettedTsc,
     5609                                                                     &fParavirtTsc);
    56105610
    56115611        /* Make sure the returned values have sane upper and lower boundaries. */
     
    56165616
    56175617        uint32_t cPreemptionTickCount = (uint32_t)RT_MIN(cTicksToDeadline, UINT32_MAX - 16);
    5618         rc = VMXWriteVmcs32(VMX_VMCS32_GUEST_PREEMPT_TIMER_VALUE, cPreemptionTickCount);            AssertRC(rc);
     5618        rc = VMXWriteVmcs32(VMX_VMCS32_GUEST_PREEMPT_TIMER_VALUE, cPreemptionTickCount);        AssertRC(rc);
    56195619    }
    56205620    else
    56215621        fOffsettedTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset, &fParavirtTsc);
    56225622
     5623    /** @todo later optimize this to be done elsewhere and not before every
     5624     *        VM-entry. */
    56235625    if (fParavirtTsc)
    56245626    {
     
    56305632    if (fOffsettedTsc)
    56315633    {
    5632         uint64_t u64CurTSC = ASMReadTSC();
    5633         if (u64CurTSC + pVCpu->hm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))
    5634         {
    5635             /* Note: VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT takes precedence over TSC_OFFSET, applies to RDTSCP too. */
    5636             rc = VMXWriteVmcs64(VMX_VMCS64_CTRL_TSC_OFFSET_FULL, pVCpu->hm.s.vmx.u64TSCOffset);     AssertRC(rc);
    5637 
    5638             pVCpu->hm.s.vmx.u32ProcCtls &= ~VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT;
    5639             rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);            AssertRC(rc);
    5640             STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffset);
    5641         }
    5642         else
    5643         {
    5644             /* VM-exit on RDTSC(P) as we would otherwise pass decreasing TSC values to the guest. */
    5645             pVCpu->hm.s.vmx.u32ProcCtls |= VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT;
    5646             rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);            AssertRC(rc);
    5647             STAM_COUNTER_INC(&pVCpu->hm.s.StatTscInterceptOverFlow);
    5648         }
     5634        /* Note: VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT takes precedence over TSC_OFFSET, applies to RDTSCP too. */
     5635        rc = VMXWriteVmcs64(VMX_VMCS64_CTRL_TSC_OFFSET_FULL, pVCpu->hm.s.vmx.u64TSCOffset);     AssertRC(rc);
     5636
     5637        pVCpu->hm.s.vmx.u32ProcCtls &= ~VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT;
     5638        rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);            AssertRC(rc);
     5639        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffset);
    56495640    }
    56505641    else
     
    56525643        /* We can't use TSC-offsetting (non-fixed TSC, warp drive active etc.), VM-exit on RDTSC(P). */
    56535644        pVCpu->hm.s.vmx.u32ProcCtls |= VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT;
    5654         rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);                AssertRC(rc);
     5645        rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_PROC_EXEC, pVCpu->hm.s.vmx.u32ProcCtls);            AssertRC(rc);
    56555646        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscIntercept);
    56565647    }
     
    87138704    pVmxTransient->fVectoringDoublePF  = false;                 /* Vectoring double page-fault needs to be determined later. */
    87148705
    8715     /** @todo Last-seen-tick shouldn't be necessary when TM supports invariant
    8716      *        mode. */
    87178706    if (!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT))
    8718         TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hm.s.vmx.u64TSCOffset);
     8707        TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hm.s.vmx.u64TSCOffset);     /** @todo use SUPReadTSC() eventually. */
    87198708
    87208709    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x);
     
    88398828        }
    88408829
    8841         /* Profiling the VM-exit. */
     8830        /* Profile the VM-exit. */
    88428831        AssertMsg(VmxTransient.uExitReason <= VMX_EXIT_MAX, ("%#x\n", VmxTransient.uExitReason));
    88438832        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitAll);
     
    89228911            return VBOXSTRICTRC_TODO(rcStrict);
    89238912        }
    8924         /* Profiling the VM-exit. */
     8913
     8914        /* Profile the VM-exit. */
    89258915        AssertMsg(VmxTransient.uExitReason <= VMX_EXIT_MAX, ("%#x\n", VmxTransient.uExitReason));
    89268916        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitAll);
     
    1046110451
    1046210452    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt);
     10453    if (rc != VINF_SUCCESS)
     10454        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHltToR3);
    1046310455    return rc;
    1046410456}
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