VirtualBox

Changeset 14411 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 20, 2008 1:26:47 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
39642
Message:

RDTSCP support added. Enabled only for AMD-V guests.

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

Legend:

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

    r14091 r14411  
    6868*******************************************************************************/
    6969/** The saved state version. */
    70 #define CPUM_SAVED_STATE_VERSION            9
     70#define CPUM_SAVED_STATE_VERSION                10
     71/** The saved state version for the 2.1 trunk before the MSR changes. */
     72#define CPUM_SAVED_STATE_VERSION_VER2_1_NOMSR   9
    7173/** The saved state version of 2.0, used for backwards compatibility. */
    72 #define CPUM_SAVED_STATE_VERSION_VER2_0     8
     74#define CPUM_SAVED_STATE_VERSION_VER2_0         8
    7375/** The saved state version of 1.6, used for backwards compatability. */
    74 #define CPUM_SAVED_STATE_VERSION_VER1_6     6
     76#define CPUM_SAVED_STATE_VERSION_VER1_6         6
    7577
    7678
     
    350352                                       | X86_CPUID_AMD_FEATURE_EDX_FFXSR
    351353                                       //| X86_CPUID_AMD_FEATURE_EDX_PAGE1GB
    352                                        //| X86_CPUID_AMD_FEATURE_EDX_RDTSCP
    353                                        //| X86_CPUID_AMD_FEATURE_EDX_LONG_MODE - not yet.
     354                                       //| X86_CPUID_AMD_FEATURE_EDX_RDTSCP - AMD only; turned on when necessary
     355                                       //| X86_CPUID_AMD_FEATURE_EDX_LONG_MODE - turned on when necessary
    354356                                       | X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX
    355357                                       | X86_CPUID_AMD_FEATURE_EDX_3DNOW
     
    782784        SSMR3PutU32(pSSM, pVM->aCpus[i].cpum.s.fUseFlags);
    783785        SSMR3PutU32(pSSM, pVM->aCpus[i].cpum.s.fChanged);
     786        SSMR3PutMem(pSSM, &pVM->aCpus[i].cpum.s.GuestMsr, sizeof(pVM->aCpus[i].cpum.s.GuestMsr));
    784787    }
    785788
     
    912915     */
    913916    if (    u32Version != CPUM_SAVED_STATE_VERSION
     917        &&  u32Version != CPUM_SAVED_STATE_VERSION_VER2_1_NOMSR
    914918        &&  u32Version != CPUM_SAVED_STATE_VERSION_VER2_0
    915919        &&  u32Version != CPUM_SAVED_STATE_VERSION_VER1_6)
     
    947951    else
    948952    {
    949         if (u32Version == CPUM_SAVED_STATE_VERSION)
     953        if (u32Version >= CPUM_SAVED_STATE_VERSION_VER2_1_NOMSR)
    950954        {
    951955            int rc = SSMR3GetU32(pSSM, &pVM->cCPUs);
     
    967971            SSMR3GetU32(pSSM, &pVM->aCpus[i].cpum.s.fUseFlags);
    968972            SSMR3GetU32(pSSM, &pVM->aCpus[i].cpum.s.fChanged);
     973            if (u32Version == CPUM_SAVED_STATE_VERSION)
     974                SSMR3GetMem(pSSM, &pVM->aCpus[i].cpum.s.GuestMsr, sizeof(pVM->aCpus[i].cpum.s.GuestMsr));
    969975        }
    970976    }
  • trunk/src/VBox/VMM/CPUMInternal.h

    r13960 r14411  
    340340    CPUMCTX                 Guest;
    341341
     342    /**
     343     * Guest context - misc MSRs
     344     * Aligned on a 64-byte boundrary.
     345     */
     346    CPUMCTXMSR              GuestMsr;
     347
    342348    /** Use flags.
    343349     * These flags indicates both what is to be used and what has been used.
  • trunk/src/VBox/VMM/CPUMInternal.mac

    r13960 r14411  
    402402    .Guest.trHid.Attr         resd    1
    403403
     404    .GuestMsr.au64            resq    64
     405
    404406    .fUseFlags            resd    1
    405407    .fChanged             resd    1
  • trunk/src/VBox/VMM/HWACCM.cpp

    r14109 r14411  
    764764                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
    765765                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL);
     766                CPUMSetGuestCpuidFeature(pVM, CPUMCPUIDFEATURE_RDTSCP);
    766767#ifdef VBOX_ENABLE_64_BITS_GUESTS
    767768                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r13975 r14411  
    839839            break;
    840840
     841        case MSR_K8_TSC_AUX:
     842            u64 = pCpumCpu->GuestMsr.msr.tscAux;
     843            break;
     844
    841845        /* fs & gs base skipped on purpose as the current context might not be up-to-date. */
    842846        default:
     
    847851}
    848852
     853VMMDECL(void) CPUMSetGuestMsr(PVM pVM, unsigned idMsr, uint64_t valMsr)
     854{
     855    PCPUMCPU pCpumCpu = cpumGetCpumCpu(pVM);
     856
     857    /* On purpose only a limited number of MSRs; use the emulation function to update the others. */
     858    switch (idMsr)
     859    {
     860        case MSR_K8_TSC_AUX:
     861            pCpumCpu->GuestMsr.msr.tscAux = valMsr;
     862            break;
     863
     864        default:
     865            AssertFailed();
     866            break;
     867    }
     868}
    849869
    850870VMMDECL(RTGCPTR) CPUMGetGuestIDTR(PVM pVM, uint16_t *pcbLimit)
     
    14311451        }
    14321452
     1453        case CPUMCPUIDFEATURE_RDTSCP:
     1454        {
     1455            if (    pVM->cpum.s.aGuestCpuIdExt[0].eax < 0x80000001
     1456                ||  !(ASMCpuId_EDX(0x80000001) & X86_CPUID_AMD_FEATURE_EDX_RDTSCP))
     1457            {
     1458                LogRel(("WARNING: Can't turn on RDTSCP when the host doesn't support it!!\n"));
     1459                return;
     1460            }
     1461
     1462            /* Valid for AMD only (for now). */
     1463            pVM->cpum.s.aGuestCpuIdExt[1].edx |= X86_CPUID_AMD_FEATURE_EDX_RDTSCP;
     1464            LogRel(("CPUMSetGuestCpuIdFeature: Enabled RDTSCP.\n"));
     1465            break;
     1466        }
     1467
    14331468        default:
    14341469            AssertMsgFailed(("enmFeature=%d\n", enmFeature));
     
    14561491            if (pVM->cpum.s.aGuestCpuIdStd[0].eax >= 1)
    14571492                return !!(pVM->cpum.s.aGuestCpuIdStd[1].edx & X86_CPUID_FEATURE_EDX_PAE);
     1493            break;
     1494        }
     1495
     1496        case CPUMCPUIDFEATURE_RDTSCP:
     1497        {
     1498            if (pVM->cpum.s.aGuestCpuIdExt[0].eax >= 0x80000001)
     1499                return !!(pVM->cpum.s.aGuestCpuIdExt[1].edx & X86_CPUID_AMD_FEATURE_EDX_RDTSCP);
    14581500            break;
    14591501        }
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r14257 r14411  
    24522452}
    24532453
     2454VMMDECL(int) EMInterpretRdtscp(PVM pVM, PCPUMCTX pCtx)
     2455{
     2456    unsigned uCR4 = CPUMGetGuestCR4(pVM);
     2457
     2458    if (!CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP))
     2459    {
     2460        AssertFailed();
     2461        return VERR_EM_INTERPRETER; /* genuine #UD */
     2462    }
     2463
     2464    if (uCR4 & X86_CR4_TSD)
     2465        return VERR_EM_INTERPRETER; /* genuine #GP */
     2466
     2467    uint64_t uTicks = TMCpuTickGet(pVM);
     2468
     2469    /* Same behaviour in 32 & 64 bits mode */
     2470    pCtx->rax = (uint32_t)uTicks;
     2471    pCtx->rdx = (uTicks >> 32ULL);
     2472    /* Low dword of the TSC_AUX msr only. */
     2473    pCtx->rcx = (uint32_t)CPUMGetGuestMsr(pVM, MSR_K8_TSC_AUX);
     2474
     2475    return VINF_SUCCESS;
     2476}
    24542477
    24552478/**
     
    25432566        return "MSR_K8_KERNEL_GS_BASE";
    25442567    case MSR_K8_TSC_AUX:
    2545         return "Unsupported MSR_K8_TSC_AUX";
     2568        return "MSR_K8_TSC_AUX";
    25462569    case MSR_IA32_BIOS_SIGN_ID:
    25472570        return "Unsupported MSR_IA32_BIOS_SIGN_ID";
     
    26632686        break;
    26642687
     2688    case MSR_K8_TSC_AUX:
     2689        val = CPUMGetGuestMsr(pVM, MSR_K8_TSC_AUX);
     2690        break;
     2691
    26652692#if 0 /*def IN_RING0 */
    26662693    case MSR_IA32_PLATFORM_ID:
     
    28212848    case MSR_K8_KERNEL_GS_BASE:
    28222849        pCtx->msrKERNELGSBASE = val;
     2850        break;
     2851
     2852    case MSR_K8_TSC_AUX:
     2853        CPUMSetGuestMsr(pVM, MSR_K8_TSC_AUX, val);
    28232854        break;
    28242855
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r14366 r14411  
    327327                                        | SVM_CTRL2_INTERCEPT_CLGI
    328328                                        | SVM_CTRL2_INTERCEPT_SKINIT
    329                                         | SVM_CTRL2_INTERCEPT_RDTSCP        /* AMD only; we don't support this one */
    330329                                        | SVM_CTRL2_INTERCEPT_WBINVD
    331330                                        | SVM_CTRL2_INTERCEPT_MWAIT_UNCOND; /* don't execute mwait or else we'll idle inside the guest (host thinks the cpu load is high) */
     
    781780    if (TMCpuTickCanUseRealTSC(pVM, &pVMCB->ctrl.u64TSCOffset))
    782781    {
    783         pVMCB->ctrl.u32InterceptCtrl1 &= ~SVM_CTRL1_INTERCEPT_RDTSC;
     782        pVMCB->ctrl.u32InterceptCtrl1 &= ~(SVM_CTRL1_INTERCEPT_RDTSC | SVM_CTRL2_INTERCEPT_RDTSCP);
    784783        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
    785784    }
    786785    else
    787786    {
    788         pVMCB->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_RDTSC;
     787        pVMCB->ctrl.u32InterceptCtrl1 |= (SVM_CTRL1_INTERCEPT_RDTSC | SVM_CTRL2_INTERCEPT_RDTSCP);
    789788        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCIntercept);
    790789    }
     
    10371036                                             | SVM_CTRL2_INTERCEPT_CLGI
    10381037                                             | SVM_CTRL2_INTERCEPT_SKINIT
    1039                                              | SVM_CTRL2_INTERCEPT_RDTSCP        /* AMD only; we don't support this one */
    10401038                                             | SVM_CTRL2_INTERCEPT_WBINVD
    10411039                                             | SVM_CTRL2_INTERCEPT_MWAIT_UNCOND  /* don't execute mwait or else we'll idle inside the guest (host thinks the cpu load is high) */
     
    16271625    }
    16281626
     1627    case SVM_EXIT_RDTSCP:                /* Guest software attempted to execute RDTSCP. */
     1628    {
     1629        Log2(("SVM: Rdtscp\n"));
     1630        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdtsc);
     1631        rc = EMInterpretRdtscp(pVM, pCtx);
     1632        if (rc == VINF_SUCCESS)
     1633        {
     1634            /* Update EIP and continue execution. */
     1635            pCtx->rip += 3;             /* Note! hardcoded opcode size! */
     1636            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit, x);
     1637            goto ResumeExecution;
     1638        }
     1639        AssertMsgFailed(("EMU: rdtscp failed with %Rrc\n", rc));
     1640        rc = VINF_EM_RAW_EMULATE_INSTR;
     1641        break;
     1642    }
     1643
    16291644    case SVM_EXIT_INVLPG:               /* Guest software attempted to execute INVPG. */
    16301645    {
     
    19771992    case SVM_EXIT_CLGI:
    19781993    case SVM_EXIT_SKINIT:
    1979     case SVM_EXIT_RDTSCP:
    19801994    {
    19811995        /* Unsupported instructions. */
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r14155 r14411  
    8282    GEN_CHECK_SIZE(CPUMHOSTCTX);
    8383    GEN_CHECK_SIZE(CPUMCTX);
     84    GEN_CHECK_SIZE(CPUMCTXMSR);
    8485    GEN_CHECK_SIZE(CPUMCTXCORE);
    8586    GEN_CHECK_SIZE(STAMRATIOU32);
  • trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp

    r13961 r14411  
    234234    CHECK_SIZE_ALIGNMENT(CPUMCTX, 64);
    235235    CHECK_SIZE_ALIGNMENT(CPUMHOSTCTX, 64);
     236    CHECK_SIZE_ALIGNMENT(CPUMCTXMSR, 64);
    236237
    237238    /* pdm */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette