Changeset 14411 in vbox
- Timestamp:
- Nov 20, 2008 1:26:47 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 39642
- Location:
- trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/cpum.h
r13975 r14411 361 361 */ 362 362 #define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->edi) 363 364 363 365 364 /** … … 543 542 } CPUMCTX_VER1_6; 544 543 #pragma pack() 544 545 /* Guest MSR state. */ 546 typedef union CPUMCTXMSR 547 { 548 struct 549 { 550 uint64_t tscAux; /* MSR_K8_TSC_AUX */ 551 } msr; 552 uint64_t au64[64]; 553 } CPUMCTXMSR; 554 /** Pointer to the guest MSR state. */ 555 typedef CPUMCTXMSR *PCPUMCTXMSR; 556 /** Pointer to the const guest MSR state. */ 557 typedef const CPUMCTXMSR *PCCPUMCTXMSR; 545 558 546 559 … … 584 597 /** The x2APIC feature bit. (Std) */ 585 598 CPUMCPUIDFEATURE_X2APIC, 599 /** The RDTSCP feature bit. (Ext) */ 600 CPUMCPUIDFEATURE_RDTSCP, 586 601 /** 32bit hackishness. */ 587 602 CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff … … 649 664 VMMDECL(uint64_t) CPUMGetGuestEFER(PVM pVM); 650 665 VMMDECL(uint64_t) CPUMGetGuestMsr(PVM pVM, unsigned idMsr); 666 VMMDECL(void) CPUMSetGuestMsr(PVM pVM, unsigned idMsr, uint64_t valMsr); 651 667 /** @} */ 652 668 -
trunk/include/VBox/cpum.mac
r13954 r14411 196 196 ; padding 197 197 ;;; .padding resd 6 198 endstruc 199 200 201 ;;/* Guest MSR state. */ 202 struc CPUMCTXMSR 203 .au64 resq 64 198 204 endstruc 199 205 -
trunk/include/VBox/em.h
r13858 r14411 126 126 VMMDECL(int) EMInterpretCpuId(PVM pVM, PCPUMCTXCORE pRegFrame); 127 127 VMMDECL(int) EMInterpretRdtsc(PVM pVM, PCPUMCTXCORE pRegFrame); 128 VMMDECL(int) EMInterpretRdtscp(PVM pVM, PCPUMCTX pCtx); 128 129 VMMDECL(int) EMInterpretInvlpg(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC); 129 130 VMMDECL(int) EMInterpretIret(PVM pVM, PCPUMCTXCORE pRegFrame); -
trunk/include/VBox/vm.h
r14244 r14411 113 113 struct CPUMCPU s; 114 114 #endif 115 char padding[2 048]; /* multiple of 64 */115 char padding[2560]; /* multiple of 64 */ 116 116 } cpum; 117 117 /** VMM part. */ -
trunk/src/VBox/VMM/CPUM.cpp
r14091 r14411 68 68 *******************************************************************************/ 69 69 /** 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 71 73 /** The saved state version of 2.0, used for backwards compatibility. */ 72 #define CPUM_SAVED_STATE_VERSION_VER2_0 874 #define CPUM_SAVED_STATE_VERSION_VER2_0 8 73 75 /** The saved state version of 1.6, used for backwards compatability. */ 74 #define CPUM_SAVED_STATE_VERSION_VER1_6 676 #define CPUM_SAVED_STATE_VERSION_VER1_6 6 75 77 76 78 … … 350 352 | X86_CPUID_AMD_FEATURE_EDX_FFXSR 351 353 //| 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 354 356 | X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX 355 357 | X86_CPUID_AMD_FEATURE_EDX_3DNOW … … 782 784 SSMR3PutU32(pSSM, pVM->aCpus[i].cpum.s.fUseFlags); 783 785 SSMR3PutU32(pSSM, pVM->aCpus[i].cpum.s.fChanged); 786 SSMR3PutMem(pSSM, &pVM->aCpus[i].cpum.s.GuestMsr, sizeof(pVM->aCpus[i].cpum.s.GuestMsr)); 784 787 } 785 788 … … 912 915 */ 913 916 if ( u32Version != CPUM_SAVED_STATE_VERSION 917 && u32Version != CPUM_SAVED_STATE_VERSION_VER2_1_NOMSR 914 918 && u32Version != CPUM_SAVED_STATE_VERSION_VER2_0 915 919 && u32Version != CPUM_SAVED_STATE_VERSION_VER1_6) … … 947 951 else 948 952 { 949 if (u32Version == CPUM_SAVED_STATE_VERSION)953 if (u32Version >= CPUM_SAVED_STATE_VERSION_VER2_1_NOMSR) 950 954 { 951 955 int rc = SSMR3GetU32(pSSM, &pVM->cCPUs); … … 967 971 SSMR3GetU32(pSSM, &pVM->aCpus[i].cpum.s.fUseFlags); 968 972 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)); 969 975 } 970 976 } -
trunk/src/VBox/VMM/CPUMInternal.h
r13960 r14411 340 340 CPUMCTX Guest; 341 341 342 /** 343 * Guest context - misc MSRs 344 * Aligned on a 64-byte boundrary. 345 */ 346 CPUMCTXMSR GuestMsr; 347 342 348 /** Use flags. 343 349 * These flags indicates both what is to be used and what has been used. -
trunk/src/VBox/VMM/CPUMInternal.mac
r13960 r14411 402 402 .Guest.trHid.Attr resd 1 403 403 404 .GuestMsr.au64 resq 64 405 404 406 .fUseFlags resd 1 405 407 .fChanged resd 1 -
trunk/src/VBox/VMM/HWACCM.cpp
r14109 r14411 764 764 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP); 765 765 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL); 766 CPUMSetGuestCpuidFeature(pVM, CPUMCPUIDFEATURE_RDTSCP); 766 767 #ifdef VBOX_ENABLE_64_BITS_GUESTS 767 768 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE); -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r13975 r14411 839 839 break; 840 840 841 case MSR_K8_TSC_AUX: 842 u64 = pCpumCpu->GuestMsr.msr.tscAux; 843 break; 844 841 845 /* fs & gs base skipped on purpose as the current context might not be up-to-date. */ 842 846 default: … … 847 851 } 848 852 853 VMMDECL(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 } 849 869 850 870 VMMDECL(RTGCPTR) CPUMGetGuestIDTR(PVM pVM, uint16_t *pcbLimit) … … 1431 1451 } 1432 1452 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 1433 1468 default: 1434 1469 AssertMsgFailed(("enmFeature=%d\n", enmFeature)); … … 1456 1491 if (pVM->cpum.s.aGuestCpuIdStd[0].eax >= 1) 1457 1492 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); 1458 1500 break; 1459 1501 } -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r14257 r14411 2452 2452 } 2453 2453 2454 VMMDECL(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 } 2454 2477 2455 2478 /** … … 2543 2566 return "MSR_K8_KERNEL_GS_BASE"; 2544 2567 case MSR_K8_TSC_AUX: 2545 return " UnsupportedMSR_K8_TSC_AUX";2568 return "MSR_K8_TSC_AUX"; 2546 2569 case MSR_IA32_BIOS_SIGN_ID: 2547 2570 return "Unsupported MSR_IA32_BIOS_SIGN_ID"; … … 2663 2686 break; 2664 2687 2688 case MSR_K8_TSC_AUX: 2689 val = CPUMGetGuestMsr(pVM, MSR_K8_TSC_AUX); 2690 break; 2691 2665 2692 #if 0 /*def IN_RING0 */ 2666 2693 case MSR_IA32_PLATFORM_ID: … … 2821 2848 case MSR_K8_KERNEL_GS_BASE: 2822 2849 pCtx->msrKERNELGSBASE = val; 2850 break; 2851 2852 case MSR_K8_TSC_AUX: 2853 CPUMSetGuestMsr(pVM, MSR_K8_TSC_AUX, val); 2823 2854 break; 2824 2855 -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r14366 r14411 327 327 | SVM_CTRL2_INTERCEPT_CLGI 328 328 | SVM_CTRL2_INTERCEPT_SKINIT 329 | SVM_CTRL2_INTERCEPT_RDTSCP /* AMD only; we don't support this one */330 329 | SVM_CTRL2_INTERCEPT_WBINVD 331 330 | SVM_CTRL2_INTERCEPT_MWAIT_UNCOND; /* don't execute mwait or else we'll idle inside the guest (host thinks the cpu load is high) */ … … 781 780 if (TMCpuTickCanUseRealTSC(pVM, &pVMCB->ctrl.u64TSCOffset)) 782 781 { 783 pVMCB->ctrl.u32InterceptCtrl1 &= ~ SVM_CTRL1_INTERCEPT_RDTSC;782 pVMCB->ctrl.u32InterceptCtrl1 &= ~(SVM_CTRL1_INTERCEPT_RDTSC | SVM_CTRL2_INTERCEPT_RDTSCP); 784 783 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset); 785 784 } 786 785 else 787 786 { 788 pVMCB->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_RDTSC;787 pVMCB->ctrl.u32InterceptCtrl1 |= (SVM_CTRL1_INTERCEPT_RDTSC | SVM_CTRL2_INTERCEPT_RDTSCP); 789 788 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCIntercept); 790 789 } … … 1037 1036 | SVM_CTRL2_INTERCEPT_CLGI 1038 1037 | SVM_CTRL2_INTERCEPT_SKINIT 1039 | SVM_CTRL2_INTERCEPT_RDTSCP /* AMD only; we don't support this one */1040 1038 | SVM_CTRL2_INTERCEPT_WBINVD 1041 1039 | SVM_CTRL2_INTERCEPT_MWAIT_UNCOND /* don't execute mwait or else we'll idle inside the guest (host thinks the cpu load is high) */ … … 1627 1625 } 1628 1626 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 1629 1644 case SVM_EXIT_INVLPG: /* Guest software attempted to execute INVPG. */ 1630 1645 { … … 1977 1992 case SVM_EXIT_CLGI: 1978 1993 case SVM_EXIT_SKINIT: 1979 case SVM_EXIT_RDTSCP:1980 1994 { 1981 1995 /* Unsupported instructions. */ -
trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
r14155 r14411 82 82 GEN_CHECK_SIZE(CPUMHOSTCTX); 83 83 GEN_CHECK_SIZE(CPUMCTX); 84 GEN_CHECK_SIZE(CPUMCTXMSR); 84 85 GEN_CHECK_SIZE(CPUMCTXCORE); 85 86 GEN_CHECK_SIZE(STAMRATIOU32); -
trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
r13961 r14411 234 234 CHECK_SIZE_ALIGNMENT(CPUMCTX, 64); 235 235 CHECK_SIZE_ALIGNMENT(CPUMHOSTCTX, 64); 236 CHECK_SIZE_ALIGNMENT(CPUMCTXMSR, 64); 236 237 237 238 /* pdm */ -
trunk/src/recompiler/VBoxREMWrapper.cpp
r13852 r14411 480 480 }; 481 481 482 /* CPUMGetGuestMsr args */ 483 static const REMPARMDESC g_aArgsCPUMGetGuestMsr[] = 484 { 485 { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL }, 486 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL }, 487 }; 488 489 /* CPUMGetGuestMsr args */ 490 static const REMPARMDESC g_aArgsCPUMSetGuestMsr[] = 491 { 492 { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL }, 493 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL }, 494 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t), NULL }, 495 }; 496 482 497 static const REMPARMDESC g_aArgsCPUMGetGuestCpuId[] = 483 498 { … … 1043 1058 { "CPUMSetChangedFlags", (void *)(uintptr_t)&CPUMSetChangedFlags, &g_aArgsCPUMSetChangedFlags[0], RT_ELEMENTS(g_aArgsCPUMSetChangedFlags), REMFNDESC_FLAGS_RET_VOID, 0, NULL }, 1044 1059 { "CPUMGetGuestCPL", (void *)(uintptr_t)&CPUMGetGuestCPL, &g_aArgsCPUMGetGuestCpl[0], RT_ELEMENTS(g_aArgsCPUMGetGuestCpl), REMFNDESC_FLAGS_RET_INT, sizeof(unsigned), NULL }, 1060 { "CPUMGetGuestMsr", (void *)(uintptr_t)&CPUMGetGuestMsr, &g_aArgsCPUMGetGuestMsr[0], RT_ELEMENTS(g_aArgsCPUMGetGuestMsr), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL }, 1061 { "CPUMSetGuestMsr", (void *)(uintptr_t)&CPUMSetGuestMsr, &g_aArgsCPUMSetGuestMsr[0], RT_ELEMENTS(g_aArgsCPUMSetGuestMsr), REMFNDESC_FLAGS_RET_VOID, 0, NULL }, 1045 1062 { "CPUMGetGuestCpuId", (void *)(uintptr_t)&CPUMGetGuestCpuId, &g_aArgsCPUMGetGuestCpuId[0], RT_ELEMENTS(g_aArgsCPUMGetGuestCpuId), REMFNDESC_FLAGS_RET_VOID, 0, NULL }, 1046 1063 { "CPUMGetGuestEAX", (void *)(uintptr_t)&CPUMGetGuestEAX, &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL }, -
trunk/src/recompiler/VBoxRecompiler.c
r13840 r14411 1773 1773 #endif 1774 1774 1775 1776 1775 /* 1777 1776 * Registers which are rarely changed and require special handling / order when changed. … … 4133 4132 LogFlow(("cpu_apic_wrmsr: rc=%Rrc\n", rc)); NOREF(rc); 4134 4133 } 4134 4135 uint64_t cpu_rdmsr(CPUX86State *env, uint32_t msr) 4136 { 4137 return CPUMGetGuestMsr(env->pVM, msr); 4138 } 4139 4140 void cpu_wrmsr(CPUX86State *env, uint32_t msr, uint64_t val) 4141 { 4142 CPUMSetGuestMsr(env->pVM, msr, val); 4143 } 4144 4135 4145 /* -+- I/O Ports -+- */ 4136 4146 -
trunk/src/recompiler/target-i386/cpu.h
r13034 r14411 857 857 void cpu_smm_update(CPUX86State *env); 858 858 859 #ifdef VBOX 860 uint64_t cpu_rdmsr(CPUX86State *env, uint32_t msr); 861 void cpu_wrmsr(CPUX86State *env, uint32_t msr, uint64_t val); 862 #endif 863 859 864 /* will be suppressed */ 860 865 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); -
trunk/src/recompiler/target-i386/exec.h
r11982 r14411 215 215 void helper_sysret(int dflag); 216 216 void helper_rdtsc(void); 217 #ifdef VBOX 218 void helper_rdtscp(void); 219 #endif 217 220 void helper_rdmsr(void); 218 221 void helper_wrmsr(void); -
trunk/src/recompiler/target-i386/helper.c
r13839 r14411 3023 3023 } 3024 3024 3025 #ifdef VBOX 3026 void helper_rdtscp(void) 3027 { 3028 uint64_t val; 3029 3030 if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { 3031 raise_exception(EXCP0D_GPF); 3032 } 3033 3034 val = cpu_get_tsc(env); 3035 EAX = (uint32_t)(val); 3036 EDX = (uint32_t)(val >> 32); 3037 ECX = cpu_rdmsr(env, MSR_K8_TSC_AUX); 3038 } 3039 #endif 3040 3025 3041 #if defined(CONFIG_USER_ONLY) 3026 3042 void helper_wrmsr(void) … … 3106 3122 break; 3107 3123 } 3124 case MSR_K8_TSC_AUX: 3125 cpu_wrmsr(env, MSR_K8_TSC_AUX, val); 3126 break; 3108 3127 #endif /* VBOX */ 3109 3128 } … … 3170 3189 break; 3171 3190 } 3191 case MSR_K8_TSC_AUX: 3192 val = cpu_rdmsr(env, MSR_K8_TSC_AUX); 3193 break; 3172 3194 #endif /* VBOX */ 3173 3195 } -
trunk/src/recompiler/target-i386/op.c
r13449 r14411 1055 1055 helper_rdtsc(); 1056 1056 } 1057 1058 #ifdef VBOX 1059 void OPPROTO op_rdtscp(void) 1060 { 1061 helper_rdtscp(); 1062 } 1063 #endif 1057 1064 1058 1065 void OPPROTO op_cpuid(void) -
trunk/src/recompiler/target-i386/translate.c
r13839 r14411 5940 5940 op = (modrm >> 3) & 7; 5941 5941 rm = modrm & 7; 5942 5943 #ifdef VBOX 5944 /* 0f 01 f9 */ 5945 if (modrm == 0xf9) 5946 { 5947 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) 5948 goto illegal_op; 5949 gen_jmp_im(pc_start - s->cs_base); 5950 gen_op_rdtscp(); 5951 break; 5952 } 5953 #endif 5954 5942 5955 switch(op) { 5943 5956 case 0: /* sgdt */
Note:
See TracChangeset
for help on using the changeset viewer.