Changeset 51643 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 18, 2014 11:06:06 AM (11 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r51422 r51643 1749 1749 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 1750 1750 { 1751 Assert(rc == VERR_CPUM_RAISE_GP_0 );1751 Assert(rc == VERR_CPUM_RAISE_GP_0 || rc == VERR_EM_INTERPRETER); 1752 1752 Log4(("EM: Refuse RDMSR: rc=%Rrc\n", rc)); 1753 1753 return VERR_EM_INTERPRETER; -
trunk/src/VBox/VMM/VMMAll/GIMAll.cpp
r51563 r51643 45 45 46 46 /** 47 * Gets the GIM provider configured for this VM. 48 * 49 * @returns The GIM provider Id. 50 * @param pVM Pointer to the VM. 51 */ 52 VMMDECL(GIMPROVIDERID) GIMGetProvider(PVM pVM) 53 { 54 return pVM->gim.s.enmProviderId; 55 } 56 57 58 /** 47 59 * Implements a GIM hypercall with the provider configured for the VM. 48 60 * … … 67 79 } 68 80 } 69 70 71 /**72 * Updates the paravirtualized TSC supported by the GIM provider.73 *74 * @returns VBox status code.75 * @retval VINF_SUCCESS if the paravirt. TSC is setup and in use.76 * @retval VERR_GIM_NOT_ENABLED if no GIM provider is configured for this VM.77 * @retval VERR_GIM_PVTSC_NOT_AVAILABLE if the GIM provider does not support any78 * paravirt. TSC.79 * @retval VERR_GIM_PVTSC_NOT_IN_USE if the GIM provider supports paravirt. TSC80 * but the guest isn't currently using it.81 *82 * @param pVM Pointer to the VM.83 * @param u64Offset The computed TSC offset.84 *85 * @thread EMT(pVCpu)86 */87 VMMDECL(int) GIMUpdateParavirtTsc(PVM pVM, uint64_t u64Offset)88 {89 if (!pVM->gim.s.fEnabled)90 return VERR_GIM_NOT_ENABLED;91 92 switch (pVM->gim.s.enmProviderId)93 {94 case GIMPROVIDERID_HYPERV:95 return GIMHvUpdateParavirtTsc(pVM, u64Offset);96 97 default:98 break;99 }100 return VERR_GIM_PVTSC_NOT_AVAILABLE;101 }102 103 81 104 82 VMMDECL(bool) GIMIsParavirtTscEnabled(PVM pVM) -
trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
r51563 r51643 28 28 #include <VBox/vmm/vm.h> 29 29 #include <VBox/vmm/pgm.h> 30 #include <VBox/vmm/pdmdev.h> 31 32 #include <iprt/asm-amd64-x86.h> 33 #include <iprt/spinlock.h> 30 34 31 35 … … 53 57 { 54 58 return MSR_GIM_HV_REF_TSC_IS_ENABLED(pVM->gim.s.u.Hv.u64TscPageMsr); 55 }56 57 58 /**59 * Updates Hyper-V's reference TSC page.60 *61 * @returns VBox status code.62 * @param pVM Pointer to the VM.63 * @param u64Offset The computed TSC offset.64 * @thread EMT(pVCpu)65 */66 VMM_INT_DECL(int) GIMHvUpdateParavirtTsc(PVM pVM, uint64_t u64Offset)67 {68 Assert(GIMIsEnabled(pVM));69 bool fHvTscEnabled = MSR_GIM_HV_REF_TSC_IS_ENABLED(pVM->gim.s.u.Hv.u64TscPageMsr);70 if (!fHvTscEnabled)71 return VERR_GIM_PVTSC_NOT_ENABLED;72 73 PGIMHV pHv = &pVM->gim.s.u.Hv;74 PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX];75 PGIMHVREFTSC pRefTsc = (PGIMHVREFTSC)pRegion->CTX_SUFF(pvPage);76 Assert(pRefTsc);77 78 /** @todo Protect this with a spinlock! */79 pRefTsc->u64TscScale = UINT64_C(0x1000000000000000);80 pRefTsc->u64TscOffset = u64Offset;81 ASMAtomicIncU32(&pRefTsc->u32TscSequence);82 83 return VINF_SUCCESS;84 59 } 85 60 … … 104 79 case MSR_GIM_HV_TIME_REF_COUNT: 105 80 { 106 /* Hyper-V reports the time in 100 ns units. */81 /* Hyper-V reports the time in 100 ns units (10 MHz). */ 107 82 uint64_t u64Tsc = TMCpuTickGet(pVCpu); 108 83 uint64_t u64TscHz = TMCpuTicksPerSecond(pVM); … … 129 104 130 105 case MSR_GIM_HV_TSC_FREQ: 131 *puValue = TMCpuTicksPerSecond(pVM); 132 return VINF_SUCCESS; 106 #ifndef IN_RING3 107 return VERR_EM_INTERPRETER; 108 #else 109 LogRel(("GIM: MSR_GIM_HV_TSC_FREQ %u\n", TMCpuTicksPerSecond(pVM))); 110 //*puValue = TMCpuTicksPerSecond(pVM); 111 *puValue = 2690000000; 112 return VINF_SUCCESS; 113 #endif 133 114 134 115 case MSR_GIM_HV_APIC_FREQ: 135 116 /** @todo Fix this later! Get the information from DevApic. */ 136 117 *puValue = UINT32_C(1000000000); /* TMCLOCK_FREQ_VIRTUAL */ 118 return VINF_SUCCESS; 119 120 case MSR_GIM_HV_RESET: 121 *puValue = 0; 137 122 return VINF_SUCCESS; 138 123 … … 171 156 if (!uRawValue) 172 157 { 173 GIMR3 Mmio2Unmap(pVM, &pHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX]);158 GIMR3HvDisableHypercallPage(pVM); 174 159 pHv->u64HypercallMsr &= ~MSR_GIM_HV_HYPERCALL_ENABLE_BIT; 175 Log4Func(("Disabled hypercalls\n"));176 160 } 177 161 pHv->u64GuestOsIdMsr = uRawValue; … … 196 180 } 197 181 198 PPDMDEVINSR3 pDevIns = pVM->gim.s.pDevInsR3; 199 PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX]; 200 AssertPtr(pDevIns); 201 AssertPtr(pRegion); 202 203 /* 204 * Is the guest disabling the hypercall-page? Allow it regardless of the Guest-OS Id Msr. 205 */ 182 /* Is the guest disabling the hypercall-page? Allow it regardless of the Guest-OS Id Msr. */ 206 183 if (!fEnable) 207 184 { 208 GIMR3 Mmio2Unmap(pVM, pRegion);185 GIMR3HvDisableHypercallPage(pVM); 209 186 pHv->u64HypercallMsr = uRawValue; 210 Log4Func(("Disabled hypercalls\n")); 211 return VINF_SUCCESS; 212 } 213 214 /* 215 * Map the hypercall-page. 216 */ 187 return VINF_SUCCESS; 188 } 189 190 /* Enable the hypercall-page. */ 217 191 RTGCPHYS GCPhysHypercallPage = MSR_GIM_HV_HYPERCALL_GUEST_PFN(uRawValue) << PAGE_SHIFT; 218 int rc = GIMR3 Mmio2Map(pVM, pRegion, GCPhysHypercallPage, "Hyper-V Hypercall-page");192 int rc = GIMR3HvEnableHypercallPage(pVM, GCPhysHypercallPage); 219 193 if (RT_SUCCESS(rc)) 220 194 { 221 /* 222 * Patch the hypercall-page. 223 */ 224 if (HMIsEnabled(pVM)) 225 { 226 size_t cbWritten = 0; 227 rc = HMPatchHypercall(pVM, pRegion->pvPageR3, PAGE_SIZE, &cbWritten); 228 if ( RT_SUCCESS(rc) 229 && cbWritten < PAGE_SIZE - 1) 230 { 231 uint8_t *pbLast = (uint8_t *)pRegion->pvPageR3 + cbWritten; 232 *pbLast = 0xc3; /* RET */ 233 234 pHv->u64HypercallMsr = uRawValue; 235 LogRelFunc(("Enabled hypercalls at %#RGp\n", GCPhysHypercallPage)); 236 LogRelFunc(("%.*Rhxd\n", cbWritten + 1, (uint8_t *)pRegion->pvPageR3)); 237 return VINF_SUCCESS; 238 } 239 240 LogFunc(("MSR_GIM_HV_HYPERCALL: HMPatchHypercall failed. rc=%Rrc cbWritten=%u\n", rc, cbWritten)); 241 } 242 else 243 { 244 /** @todo Handle raw-mode hypercall page patching. */ 245 LogRelFunc(("MSR_GIM_HV_HYPERCALL: raw-mode not yet implemented!\n")); 246 } 247 248 GIMR3Mmio2Unmap(pVM, pRegion); 249 } 250 else 251 LogFunc(("MSR_GIM_HV_HYPERCALL: GIMR3Mmio2Map failed. rc=%Rrc -> #GP(0)\n", rc)); 195 pHv->u64HypercallMsr = uRawValue; 196 return VINF_SUCCESS; 197 } 252 198 253 199 return VERR_CPUM_RAISE_GP_0; … … 263 209 pHv->u64TscPageMsr = (uRawValue & ~MSR_GIM_HV_REF_TSC_ENABLE_BIT); 264 210 265 PPDMDEVINSR3 pDevIns = pVM->gim.s.pDevInsR3; 266 PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX]; 267 AssertPtr(pDevIns); 268 AssertPtr(pRegion); 269 270 /* 271 * Is the guest disabling the TSC-page? 272 */ 211 /* Is the guest disabling the TSC-page? */ 273 212 bool fEnable = RT_BOOL(uRawValue & MSR_GIM_HV_REF_TSC_ENABLE_BIT); 274 213 if (!fEnable) 275 214 { 276 GIMR3Mmio2Unmap(pVM, pRegion); 277 Log4Func(("Disabled TSC-page\n")); 278 return VINF_SUCCESS; 279 } 280 281 /* 282 * Map the TSC-page. 283 */ 215 GIMR3HvDisableTscPage(pVM); 216 pHv->u64TscPageMsr = uRawValue; 217 return VINF_SUCCESS; 218 } 219 220 /* Enable the TSC-page. */ 284 221 RTGCPHYS GCPhysTscPage = MSR_GIM_HV_REF_TSC_GUEST_PFN(uRawValue) << PAGE_SHIFT; 285 int rc = GIMR3 Mmio2Map(pVM, pRegion, GCPhysTscPage, "Hyper-V TSC-page");222 int rc = GIMR3HvEnableTscPage(pVM, GCPhysTscPage); 286 223 if (RT_SUCCESS(rc)) 287 224 { 288 225 pHv->u64TscPageMsr = uRawValue; 289 Log4Func(("MSR_GIM_HV_REF_TSC: Enabled Hyper-V TSC page at %#RGp\n", GCPhysTscPage)); 290 return VINF_SUCCESS; 291 } 292 else 293 LogFunc(("MSR_GIM_HV_REF_TSC: GIMR3Mmio2Map failed. rc=%Rrc -> #GP(0)\n", rc)); 226 return VINF_SUCCESS; 227 } 294 228 295 229 return VERR_CPUM_RAISE_GP_0; 230 #endif /* !IN_RING3 */ 231 } 232 233 case MSR_GIM_HV_RESET: 234 { 235 #ifndef IN_RING3 236 return VERR_EM_INTERPRETER; 237 #else 238 if (MSR_GIM_HV_RESET_IS_SET(uRawValue)) 239 { 240 LogRel(("GIM: HyperV: Reset initiated by MSR.\n")); 241 int rc = PDMDevHlpVMReset(pVM->gim.s.pDevInsR3); 242 AssertRC(rc); 243 } 244 /* else: Ignore writes to other bits. */ 245 return VINF_SUCCESS; 296 246 #endif /* !IN_RING3 */ 297 247 } -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r49640 r51643 1036 1036 uint8_t idMmio2 = PGM_MMIO2_PAGEID_GET_MMIO2_ID(PGM_PAGE_GET_PAGEID(pPage)); 1037 1037 uint32_t iPage = PGM_MMIO2_PAGEID_GET_IDX(PGM_PAGE_GET_PAGEID(pPage)); 1038 AssertLogRelReturn((uint8_t)(idMmio2 - 1U)< RT_ELEMENTS(pVM->pgm.s.CTX_SUFF(apMmio2Ranges)), 1039 VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE); 1038 AssertLogRelMsgReturn((uint8_t)(idMmio2 - 1U) < RT_ELEMENTS(pVM->pgm.s.CTX_SUFF(apMmio2Ranges)), 1039 ("idMmio2=%u size=%u type=%u GCPHys=%#RGp Id=%u State=%u", idMmio2, 1040 RT_ELEMENTS(pVM->pgm.s.CTX_SUFF(apMmio2Ranges)), PGM_PAGE_GET_TYPE(pPage), GCPhys, 1041 pPage->s.idPage, pPage->s.uStateY), 1042 VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE); 1040 1043 PPGMMMIO2RANGE pMmio2Range = pVM->pgm.s.CTX_SUFF(apMmio2Ranges)[idMmio2 - 1]; 1041 1044 AssertLogRelReturn(pMmio2Range, VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE); -
trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp
r44933 r51643 25 25 #include "TMInternal.h" 26 26 #include <VBox/vmm/vm.h> 27 #include <VBox/vmm/gim.h> 27 28 #include <VBox/sup.h> 28 29 … … 140 141 * 141 142 * @returns true/false accordingly. 142 * @param pVCpu Pointer to the VMCPU.143 * @param pVCpu Pointer to the VMCPU. 143 144 * @param poffRealTSC The offset against the TSC of the current CPU. 144 145 * Can be NULL. 145 * @thread EMT. 146 */ 147 VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC) 146 * @param pfParavirtTsc Where to store whether paravirt. TSC can be used or 147 * not. 148 * @thread EMT(pVCpu). 149 */ 150 VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC, bool *pfParavirtTsc) 148 151 { 149 152 PVM pVM = pVCpu->CTX_SUFF(pVM); 153 bool fParavirtTsc = false; 150 154 151 155 /* 152 156 * We require: 157 * 1. Use of a paravirtualized TSC is enabled by the guest. 158 * (OR) 153 159 * 1. A fixed TSC, this is checked at init time. 154 160 * 2. That the TSC is ticking (we shouldn't be here if it isn't) … … 158 164 * c) we're not using warp drive (accelerated virtual guest time). 159 165 */ 160 if ( pVM->tm.s.fMaybeUseOffsettedHostTSC161 && RT_LIKELY(pVCpu->tm.s.fTSCTicking)162 && ( pVM->tm.s.fTSCUseRealTSC163 || ( !pVM->tm.s.fVirtualSyncCatchUp164 && RT_LIKELY(pVM->tm.s.fVirtualSyncTicking)165 && !pVM->tm.s.fVirtualWarpDrive))166 )166 if ( (*pfParavirtTsc = GIMIsParavirtTscEnabled(pVM)) == true 167 || ( pVM->tm.s.fMaybeUseOffsettedHostTSC 168 && RT_LIKELY(pVCpu->tm.s.fTSCTicking) 169 && ( pVM->tm.s.fTSCUseRealTSC 170 || ( !pVM->tm.s.fVirtualSyncCatchUp 171 && RT_LIKELY(pVM->tm.s.fVirtualSyncTicking) 172 && !pVM->tm.s.fVirtualWarpDrive)))) 167 173 { 168 174 if (!pVM->tm.s.fTSCUseRealTSC) … … 233 239 * @returns The number of host CPU clock ticks to the next timer deadline. 234 240 * @param pVCpu The current CPU. 241 * @param pfParavirtTsc Where to store whether paravirt. TSC can be used or 242 * not. 235 243 * @param poffRealTSC The offset against the TSC of the current CPU. 244 * 236 245 * @thread EMT(pVCpu). 237 * @remarks Superset of TMCpuTickCanUseRealTSC. 238 */ 239 VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVMCPU pVCpu, bool *pfOffsettedTsc, uint64_t *poffRealTSC) 246 * @remarks Superset of TMCpuTickCanUseRealTSC(). 247 */ 248 VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVMCPU pVCpu, bool *pfOffsettedTsc, bool *pfParavirtTsc, 249 uint64_t *poffRealTSC) 240 250 { 241 251 PVM pVM = pVCpu->CTX_SUFF(pVM); … … 244 254 /* 245 255 * We require: 256 * 1. Use of a paravirtualized TSC is enabled by the guest. 257 * (OR) 246 258 * 1. A fixed TSC, this is checked at init time. 247 259 * 2. That the TSC is ticking (we shouldn't be here if it isn't) … … 251 263 * c) we're not using warp drive (accelerated virtual guest time). 252 264 */ 253 if ( pVM->tm.s.fMaybeUseOffsettedHostTSC254 && RT_LIKELY(pVCpu->tm.s.fTSCTicking)255 && ( pVM->tm.s.fTSCUseRealTSC256 || ( !pVM->tm.s.fVirtualSyncCatchUp257 && RT_LIKELY(pVM->tm.s.fVirtualSyncTicking)258 && !pVM->tm.s.fVirtualWarpDrive))259 )265 if ( (*pfParavirtTsc = GIMIsParavirtTscEnabled(pVM)) == true 266 || ( pVM->tm.s.fMaybeUseOffsettedHostTSC 267 && RT_LIKELY(pVCpu->tm.s.fTSCTicking) 268 && ( pVM->tm.s.fTSCUseRealTSC 269 || ( !pVM->tm.s.fVirtualSyncCatchUp 270 && RT_LIKELY(pVM->tm.s.fVirtualSyncTicking) 271 && !pVM->tm.s.fVirtualWarpDrive)))) 260 272 { 261 273 *pfOffsettedTsc = true; … … 293 305 cTicksToDeadline = tmCpuCalcTicksToDeadline(TMVirtualSyncGetNsToDeadline(pVM)); 294 306 } 307 295 308 return cTicksToDeadline; 296 309 } … … 412 425 413 426 /** 414 * Gets the last seen CPU timestamp counter .415 * 416 * @returns last seen TSC427 * Gets the last seen CPU timestamp counter of the guest. 428 * 429 * @returns the last seen TSC. 417 430 * @param pVCpu Pointer to the VMCPU. 418 431 * 419 * @thread EMT which TSC is to be set.432 * @thread EMT(pVCpu). 420 433 */ 421 434 VMM_INT_DECL(uint64_t) TMCpuTickGetLastSeen(PVMCPU pVCpu)
Note:
See TracChangeset
for help on using the changeset viewer.