VirtualBox

Changeset 8876

Show
Ignore:
Timestamp:
05/16/08 11:59:07 (4 months ago)
Author:
vboxsync
Message:

ASID based TLB flushing

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy