Changeset 86121 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Sep 14, 2020 4:56:09 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
r83372 r86121 230 230 { 231 231 NOREF(pRange); 232 PVMCC pVM = pVCpu->CTX_SUFF(pVM);233 PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu;234 235 232 switch (idMsr) 236 233 { … … 238 235 case MSR_GIM_KVM_SYSTEM_TIME_OLD: 239 236 { 240 bool fEnable = RT_BOOL(uRawValue & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT);241 237 #ifndef IN_RING3 242 gimR0KvmUpdateSystemTime(pVM, pVCpu); 243 if ( fEnable 244 && MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pKvmCpu->u64SystemTimeMsr) 245 && MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue) == pKvmCpu->GCPhysSystemTime) 246 { 247 /* 248 * Guest is asking for an update of the system-time struct. We only 249 * need to update the TSC and system time fields, the rest stays unchanged. 250 * We have to write the version twice in case another VCPU is reading the 251 * system-time struct concurrently. Making the version number odd indicates 252 * that the data is being updated. 253 */ 254 GIMKVMSYSTEMTIME SystemTime; 255 SystemTime.u32Version = ++pKvmCpu->u32SystemTimeVersion; 256 SystemTime.u32Padding0 = 0; 257 SystemTime.u64NanoTS = pKvmCpu->uVirtNanoTS; 258 SystemTime.u64Tsc = pKvmCpu->uTsc; 259 AssertCompile(RT_UOFFSETOF(GIMKVMSYSTEMTIME, u32TscScale) == 3 * sizeof(uint64_t)); 260 int rc2 = PGMPhysSimpleWriteGCPhys(pVM, pKvmCpu->GCPhysSystemTime, &SystemTime, RT_UOFFSETOF(GIMKVMSYSTEMTIME, u32TscScale)); 261 if (RT_FAILURE(rc2)) 262 return rc2; 263 264 /* Make the version number even again to indicate the data is consistent. */ 265 ++pKvmCpu->u32SystemTimeVersion; 266 rc2 = PGMPhysSimpleWriteGCPhys(pVM, pKvmCpu->GCPhysSystemTime, &pKvmCpu->u32SystemTimeVersion, sizeof(pKvmCpu->u32SystemTimeVersion)); 267 if (RT_FAILURE(rc2)) 268 return rc2; 269 return VINF_SUCCESS; 270 } 238 RT_NOREF2(pVCpu, uRawValue); 239 return VINF_CPUM_R3_MSR_WRITE; 240 #else 241 PVMCC pVM = pVCpu->CTX_SUFF(pVM); 242 PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu; 243 if (uRawValue & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT) 244 gimR3KvmEnableSystemTime(pVM, pVCpu, uRawValue); 271 245 else 272 return VINF_CPUM_R3_MSR_WRITE;273 #else /* IN_RING3 */274 if (!fEnable)275 {276 246 gimR3KvmDisableSystemTime(pVM); 277 pKvmCpu->u64SystemTimeMsr = uRawValue; 278 return VINF_SUCCESS; 279 } 280 281 /* We ASSUME that ring-0/raw-mode have updated these. */ 282 /** @todo Get logically atomic NanoTS/TSC pairs in ring-3. */ 283 Assert(pKvmCpu->uTsc); 284 Assert(pKvmCpu->uVirtNanoTS); 285 286 /* Enable and populate the system-time struct. */ 287 pKvmCpu->u64SystemTimeMsr = uRawValue; 288 pKvmCpu->GCPhysSystemTime = MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue); 289 pKvmCpu->u32SystemTimeVersion += 2; 290 int rc = gimR3KvmEnableSystemTime(pVM, pVCpu); 291 if (RT_FAILURE(rc)) 292 { 293 pKvmCpu->u64SystemTimeMsr = 0; 294 /* We shouldn't throw a #GP(0) here for buggy guests (neither does KVM apparently), see @bugref{8627}. */ 295 } 247 248 pKvmCpu->u64SystemTimeMsr = uRawValue; 296 249 return VINF_SUCCESS; 297 250 #endif /* IN_RING3 */ … … 302 255 { 303 256 #ifndef IN_RING3 257 RT_NOREF2(pVCpu, uRawValue); 304 258 return VINF_CPUM_R3_MSR_WRITE; 305 259 #else … … 308 262 if (RT_LIKELY(RT_ALIGN_64(GCPhysWallClock, 4) == GCPhysWallClock)) 309 263 { 264 PVMCC pVM = pVCpu->CTX_SUFF(pVM); 310 265 int rc = gimR3KvmEnableWallClock(pVM, GCPhysWallClock); 311 266 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.