VirtualBox

Changeset 8876 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
May 16, 2008 9:59:07 AM (17 years ago)
Author:
vboxsync
Message:

ASID based TLB flushing

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/HWACCM.cpp

    r8873 r8876  
    156156    STAM_REG(pVM, &pVM->hwaccm.s.StatFlushTLBWorldSwitch,   STAMTYPE_COUNTER, "/HWACCM/Flush/TLB/Switch",  STAMUNIT_OCCURENCES,    "Nr of occurances");
    157157    STAM_REG(pVM, &pVM->hwaccm.s.StatNoFlushTLBWorldSwitch, STAMTYPE_COUNTER, "/HWACCM/Flush/TLB/Skipped", STAMUNIT_OCCURENCES,    "Nr of occurances");
     158    STAM_REG(pVM, &pVM->hwaccm.s.StatFlushASID,             STAMTYPE_COUNTER, "/HWACCM/Flush/TLB/ASID",    STAMUNIT_OCCURENCES,    "Nr of occurances");
    158159
    159160    pVM->hwaccm.s.pStatExitReason = 0;
  • trunk/src/VBox/VMM/HWACCMInternal.h

    r8873 r8876  
    3131#include <VBox/pgm.h>
    3232#include <iprt/memobj.h>
     33#include <iprt/cpuset.h>
     34#include <iprt/mp.h>
    3335
    3436__BEGIN_DECLS
     
    317319    STAMCOUNTER             StatNoFlushTLBWorldSwitch;
    318320    STAMCOUNTER             StatFlushTLBCRxChange;
     321    STAMCOUNTER             StatFlushASID;
    319322
    320323    STAMCOUNTER             StatSwitchGuestIrq;
     
    327330typedef HWACCM *PHWACCM;
    328331
     332static struct
     333{
     334    struct
     335    {
     336        RTR0MEMOBJ  pMemObj;
     337        bool        fVMXConfigured;
     338        bool        fSVMConfigured;
     339    } aCpuInfo[RTCPUSET_MAX_CPUS];
     340
     341    struct
     342    {
     343        /** Set by the ring-0 driver to indicate VMX is supported by the CPU. */
     344        bool                        fSupported;
     345
     346        /** Host CR4 value (set by ring-0 VMX init) */
     347        uint64_t                    hostCR4;
     348
     349        /** VMX MSR values */
     350        struct
     351        {
     352            uint64_t                feature_ctrl;
     353            uint64_t                vmx_basic_info;
     354            uint64_t                vmx_pin_ctls;
     355            uint64_t                vmx_proc_ctls;
     356            uint64_t                vmx_exit;
     357            uint64_t                vmx_entry;
     358            uint64_t                vmx_misc;
     359            uint64_t                vmx_cr0_fixed0;
     360            uint64_t                vmx_cr0_fixed1;
     361            uint64_t                vmx_cr4_fixed0;
     362            uint64_t                vmx_cr4_fixed1;
     363            uint64_t                vmx_vmcs_enum;
     364        } msr;
     365        /* Last instruction error */
     366        uint32_t                    ulLastInstrError;
     367    } vmx;
     368    struct
     369    {
     370        /** Set by the ring-0 driver to indicate SVM is supported by the CPU. */
     371        bool                        fSupported;
     372
     373        /** SVM revision. */
     374        uint32_t                    u32Rev;
     375
     376        /** Maximum ASID allowed. */
     377        uint32_t                    u32MaxASID;
     378
     379        /** SVM feature bits from cpuid 0x8000000a */
     380        uint32_t                    u32Features;
     381    } svm;
     382    /** Saved error from detection */
     383    int32_t         lLastError;
     384
     385    struct
     386    {
     387        uint32_t                    u32AMDFeatureECX;
     388        uint32_t                    u32AMDFeatureEDX;
     389    } cpuid;
     390
     391    HWACCMSTATE     enmHwAccmState;
     392} HWACCMR0GLOBALS;
     393
     394typedef struct
     395{
     396    RTCPUID     idCpu;
     397
     398    RTR0MEMOBJ  pMemObj;
     399    /* Current ASID (AMD-V only) */
     400    uint32_t    uCurrentASID;
     401
     402    bool        fVMXConfigured;
     403    bool        fSVMConfigured;
     404} HWACCM_CPUINFO;
     405typedef HWACCM_CPUINFO *PHWACCM_CPUINFO;
    329406
    330407#ifdef IN_RING0
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r8873 r8876  
    5757*   Local Variables                                                            *
    5858*******************************************************************************/
     59
    5960static struct
    6061{
    61     struct
    62     {
    63         RTR0MEMOBJ  pMemObj;
    64         bool        fVMXConfigured;
    65         bool        fSVMConfigured;
    66     } aCpuInfo[RTCPUSET_MAX_CPUS];
     62    HWACCM_CPUINFO aCpuInfo[RTCPUSET_MAX_CPUS];
    6763
    6864    struct
     
    536532    if (pVM->hwaccm.s.vmx.fSupported)
    537533    {
    538         paRc[idCpu] = VMXR0EnableCpu(idCpu, pVM, pvPageCpu, pPageCpuPhys);
     534        paRc[idCpu] = VMXR0EnableCpu(&HWACCMR0Globals.aCpuInfo[idCpu], pVM, pvPageCpu, pPageCpuPhys);
    539535        AssertRC(paRc[idCpu]);
    540536        if (VBOX_SUCCESS(paRc[idCpu]))
     
    544540    if (pVM->hwaccm.s.svm.fSupported)
    545541    {
    546         paRc[idCpu] = SVMR0EnableCpu(idCpu, pVM, pvPageCpu, pPageCpuPhys);
     542        paRc[idCpu] = SVMR0EnableCpu(&HWACCMR0Globals.aCpuInfo[idCpu], pVM, pvPageCpu, pPageCpuPhys);
    547543        AssertRC(paRc[idCpu]);
    548544        if (VBOX_SUCCESS(paRc[idCpu]))
     
    577573    if (HWACCMR0Globals.aCpuInfo[idCpu].fVMXConfigured)
    578574    {
    579         paRc[idCpu] = VMXR0DisableCpu(idCpu, pvPageCpu, pPageCpuPhys);
     575        paRc[idCpu] = VMXR0DisableCpu(&HWACCMR0Globals.aCpuInfo[idCpu], pvPageCpu, pPageCpuPhys);
    580576        AssertRC(paRc[idCpu]);
    581577        HWACCMR0Globals.aCpuInfo[idCpu].fVMXConfigured = false;
     
    584580    if (HWACCMR0Globals.aCpuInfo[idCpu].fSVMConfigured)
    585581    {
    586         paRc[idCpu] = SVMR0DisableCpu(idCpu, pvPageCpu, pPageCpuPhys);
     582        paRc[idCpu] = SVMR0DisableCpu(&HWACCMR0Globals.aCpuInfo[idCpu], pvPageCpu, pPageCpuPhys);
    587583        AssertRC(paRc[idCpu]);
    588584        HWACCMR0Globals.aCpuInfo[idCpu].fSVMConfigured = false;
     
    797793    CPUMCTX *pCtx;
    798794    int      rc;
     795    RTCPUID  idCpu = RTMpCpuId();
    799796
    800797    rc = CPUMQueryGuestCtxPtr(pVM, &pCtx);
     
    804801    if (pVM->hwaccm.s.vmx.fSupported)
    805802    {
    806         return VMXR0RunGuestCode(pVM, pCtx);
     803        return VMXR0RunGuestCode(pVM, pCtx, &HWACCMR0Globals.aCpuInfo[idCpu]);
    807804    }
    808805    else
    809806    {
    810807        Assert(pVM->hwaccm.s.svm.fSupported);
    811         return SVMR0RunGuestCode(pVM, pCtx);
     808        return SVMR0RunGuestCode(pVM, pCtx, &HWACCMR0Globals.aCpuInfo[idCpu]);
    812809    }
    813810}
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r8871 r8876  
    4242#include <iprt/assert.h>
    4343#include <iprt/asm.h>
     44#include <iprt/cpuset.h>
     45#include <iprt/mp.h>
    4446#include "HWSVMR0.h"
    4547
     
    5052 *
    5153 * @returns VBox status code.
    52  * @param   idCpu           The identifier for the CPU the function is called on.
     54 * @param   pCpu            CPU info struct
    5355 * @param   pVM             The VM to operate on.
    5456 * @param   pvPageCpu       Pointer to the global cpu page
    5557 * @param   pPageCpuPhys    Physical address of the global cpu page
    5658 */
    57 HWACCMR0DECL(int) SVMR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
     59HWACCMR0DECL(int) SVMR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
    5860{
    5961    AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
     
    6365    /* We must turn on AMD-V and setup the host state physical address, as those MSRs are per-cpu/core. */
    6466
     67#ifdef LOG_ENABLED
     68    SUPR0Printf("SVMR0EnableCpu cpu %d page (%x) %x\n", pCpu->idCpu, pvPageCpu, (uint32_t)pPageCpuPhys);
     69#endif
     70
    6571    /* Turn on AMD-V in the EFER MSR. */
    6672    uint64_t val = ASMRdMsr(MSR_K6_EFER);
     
    7076    /* Write the physical page address where the CPU will store the host state while executing the VM. */
    7177    ASMWrMsr(MSR_K8_VM_HSAVE_PA, pPageCpuPhys);
     78
     79    pCpu->uCurrentASID = 0;   /* we'll aways increment this the first time (host uses ASID 0) */
    7280    return VINF_SUCCESS;
    7381}
     
    7785 *
    7886 * @returns VBox status code.
    79  * @param   idCpu           The identifier for the CPU the function is called on.
     87 * @param   pCpu            CPU info struct
    8088 * @param   pvPageCpu       Pointer to the global cpu page
    8189 * @param   pPageCpuPhys    Physical address of the global cpu page
    8290 */
    83 HWACCMR0DECL(int) SVMR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
     91HWACCMR0DECL(int) SVMR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
    8492{
    8593    AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
    8694    AssertReturn(pvPageCpu, VERR_INVALID_PARAMETER);
    8795
     96#ifdef LOG_ENABLED
     97    SUPR0Printf("SVMR0DisableCpu cpu %d\n", pCpu->idCpu);
     98#endif
     99
    88100    /* Turn off AMD-V in the EFER MSR. */
    89101    uint64_t val = ASMRdMsr(MSR_K6_EFER);
     
    92104    /* Invalidate host state physical address. */
    93105    ASMWrMsr(MSR_K8_VM_HSAVE_PA, 0);
     106    pCpu->uCurrentASID = 0;
     107
    94108    return VINF_SUCCESS;
    95109}
     
    301315    pVMCB->ctrl.u64LBRVirt      = 0;
    302316
     317    /** The ASID must start at 1; the host uses 0. */
     318    pVMCB->ctrl.TLBCtrl.n.u32ASID = 1;
     319
    303320    return rc;
    304321}
     
    638655    pVMCB->guest.u64EFER   = MSR_K6_EFER_SVME;
    639656
    640     /** @note We can do more complex things with tagged TLBs. */
    641     pVMCB->ctrl.TLBCtrl.n.u32ASID = 1;
    642 
    643657    /** TSC offset. */
    644658    if (TMCpuTickCanUseRealTSC(pVM, &pVMCB->ctrl.u64TSCOffset))
     
    678692 * @param   pVM         The VM to operate on.
    679693 * @param   pCtx        Guest context
     694 * @param   pCpu        CPU info struct
    680695 */
    681 HWACCMR0DECL(int) SVMR0RunGuestCode(PVM pVM, CPUMCTX *pCtx)
     696HWACCMR0DECL(int) SVMR0RunGuestCode(PVM pVM, CPUMCTX *pCtx, PHWACCM_CPUINFO pCpu)
    682697{
    683698    int         rc = VINF_SUCCESS;
     
    688703
    689704    STAM_PROFILE_ADV_START(&pVM->hwaccm.s.StatEntry, x);
     705
     706    AssertReturn(pCpu->fSVMConfigured, VERR_EM_INTERNAL_ERROR);
    690707
    691708    pVMCB = (SVM_VMCB *)pVM->hwaccm.s.svm.pVMCB;
     
    771788
    772789    /* Make sure we flush the TLB when required. */
    773     pVMCB->ctrl.TLBCtrl.n.u1TLBFlush = pVM->hwaccm.s.svm.fForceTLBFlush;
     790    if (    pVM->hwaccm.s.svm.fForceTLBFlush
     791        && !pVM->hwaccm.s.svm.fAlwaysFlushTLB)
     792    {
     793        if (++pCpu->uCurrentASID >= pVM->hwaccm.s.svm.u32MaxASID)
     794        {
     795            pCpu->uCurrentASID               = 1;       /* start at 1; host uses 0 */
     796            pVMCB->ctrl.TLBCtrl.n.u1TLBFlush = 1;       /* wrap around; flush TLB */
     797        }
     798        else
     799            STAM_COUNTER_INC(&pVM->hwaccm.s.StatFlushASID);
     800    }
     801    else
     802    {
     803        Assert(pVM->hwaccm.s.svm.fForceTLBFlush == pVM->hwaccm.s.svm.fAlwaysFlushTLB);
     804        pVMCB->ctrl.TLBCtrl.n.u1TLBFlush = pVM->hwaccm.s.svm.fForceTLBFlush;
     805    }
     806
     807    Assert(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.svm.u32MaxASID);
     808    pVMCB->ctrl.TLBCtrl.n.u32ASID = pCpu->uCurrentASID;
     809
    774810#ifdef VBOX_WITH_STATISTICS
    775811    if (pVMCB->ctrl.TLBCtrl.n.u1TLBFlush)
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.h

    r8853 r8876  
    6262 *
    6363 * @returns VBox status code.
    64  * @param   idCpu           The identifier for the CPU the function is called on.
     64 * @param   pCpu            CPU info struct
    6565 * @param   pVM             The VM to operate on.
    6666 * @param   pvPageCpu       Pointer to the global cpu page
    6767 * @param   pPageCpuPhys    Physical address of the global cpu page
    6868 */
    69 HWACCMR0DECL(int) SVMR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
     69HWACCMR0DECL(int) SVMR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
    7070
    7171/**
     
    7373 *
    7474 * @returns VBox status code.
    75  * @param   idCpu           The identifier for the CPU the function is called on.
     75 * @param   pCpu            CPU info struct
    7676 * @param   pvPageCpu       Pointer to the global cpu page
    7777 * @param   pPageCpuPhys    Physical address of the global cpu page
    7878 */
    79 HWACCMR0DECL(int) SVMR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
     79HWACCMR0DECL(int) SVMR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
    8080
    8181/**
     
    112112 * @param   pVM         The VM to operate on.
    113113 * @param   pCtx        Guest context
     114 * @param   pCpu        CPU info struct
    114115 */
    115 HWACCMR0DECL(int) SVMR0RunGuestCode(PVM pVM, CPUMCTX *pCtx);
     116HWACCMR0DECL(int) SVMR0RunGuestCode(PVM pVM, CPUMCTX *pCtx, PHWACCM_CPUINFO pCpu);
    116117
    117118
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r8659 r8876  
    6363 *
    6464 * @returns VBox status code.
    65  * @param   idCpu           The identifier for the CPU the function is called on.
     65 * @param   pCpu            CPU info struct
    6666 * @param   pVM             The VM to operate on.
    6767 * @param   pvPageCpu       Pointer to the global cpu page
    6868 * @param   pPageCpuPhys    Physical address of the global cpu page
    6969 */
    70 HWACCMR0DECL(int) VMXR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
     70HWACCMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
    7171{
    7272    AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
     
    7878
    7979#ifdef LOG_ENABLED
    80     SUPR0Printf("VMXR0EnableCpu cpu %d page (%x) %x\n", idCpu, pvPageCpu, (uint32_t)pPageCpuPhys);
     80    SUPR0Printf("VMXR0EnableCpu cpu %d page (%x) %x\n", pCpu->idCpu, pvPageCpu, (uint32_t)pPageCpuPhys);
    8181#endif
    8282    /* Set revision dword at the beginning of the VMXON structure. */
     
    105105 *
    106106 * @returns VBox status code.
    107  * @param   idCpu           The identifier for the CPU the function is called on.
     107 * @param   pCpu            CPU info struct
    108108 * @param   pvPageCpu       Pointer to the global cpu page
    109109 * @param   pPageCpuPhys    Physical address of the global cpu page
    110110 */
    111 HWACCMR0DECL(int) VMXR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
     111HWACCMR0DECL(int) VMXR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys)
    112112{
    113113    AssertReturn(pPageCpuPhys, VERR_INVALID_PARAMETER);
     
    121121
    122122#ifdef LOG_ENABLED
    123     SUPR0Printf("VMXR0DisableCpu cpu %d\n", idCpu);
     123    SUPR0Printf("VMXR0DisableCpu cpu %d\n", pCpu->idCpu);
    124124#endif
    125125    return VINF_SUCCESS;
     
    963963
    964964/**
    965  * Runs guest code in a VMX VM.
     965 * Runs guest code in a VT-x VM.
    966966 *
    967967 * @note NEVER EVER turn on interrupts here. Due to our illegal entry into the kernel, it might mess things up. (XP kernel traps have been frequently observed)
     
    970970 * @param   pVM         The VM to operate on.
    971971 * @param   pCtx        Guest context
     972 * @param   pCpu        CPU info struct
    972973 */
    973 HWACCMR0DECL(int) VMXR0RunGuestCode(PVM pVM, CPUMCTX *pCtx)
     974HWACCMR0DECL(int) VMXR0RunGuestCode(PVM pVM, CPUMCTX *pCtx, PHWACCM_CPUINFO pCpu)
    974975{
    975976    int         rc = VINF_SUCCESS;
     
    983984
    984985    Log2(("\nE"));
     986
     987    AssertReturn(pCpu->fVMXConfigured, VERR_EM_INTERNAL_ERROR);
    985988
    986989    STAM_PROFILE_ADV_START(&pVM->hwaccm.s.StatEntry, x);
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.h

    r8155 r8876  
    6363 *
    6464 * @returns VBox status code.
    65  * @param   idCpu           The identifier for the CPU the function is called on.
     65 * @param   pCpu            CPU info struct
    6666 * @param   pVM             The VM to operate on.
    6767 * @param   pvPageCpu       Pointer to the global cpu page
    6868 * @param   pPageCpuPhys    Physical address of the global cpu page
    6969 */
    70 HWACCMR0DECL(int) VMXR0EnableCpu(RTCPUID idCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
     70HWACCMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
    7171
    7272/**
     
    7474 *
    7575 * @returns VBox status code.
    76  * @param   idCpu           The identifier for the CPU the function is called on.
     76 * @param   pCpu            CPU info struct
    7777 * @param   pvPageCpu       Pointer to the global cpu page
    7878 * @param   pPageCpuPhys    Physical address of the global cpu page
    7979 */
    80 HWACCMR0DECL(int) VMXR0DisableCpu(RTCPUID idCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
     80HWACCMR0DECL(int) VMXR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
    8181
    8282/**
     
    131131 * @param   pVM         The VM to operate on.
    132132 * @param   pCtx        Guest context
     133 * @param   pCpu        CPU info struct
    133134 */
    134 HWACCMR0DECL(int) VMXR0RunGuestCode(PVM pVM, CPUMCTX *pCtx);
     135HWACCMR0DECL(int) VMXR0RunGuestCode(PVM pVM, CPUMCTX *pCtx, PHWACCM_CPUINFO pCpu);
    135136
    136137
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