- Timestamp:
- Mar 23, 2020 2:52:24 PM (5 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
r82968 r83372 240 240 bool fEnable = RT_BOOL(uRawValue & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT); 241 241 #ifndef IN_RING3 242 NOREF(fEnable); NOREF(pKvmCpu);243 242 gimR0KvmUpdateSystemTime(pVM, pVCpu); 244 return VINF_CPUM_R3_MSR_WRITE; 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 } 271 else 272 return VINF_CPUM_R3_MSR_WRITE; 245 273 #else /* IN_RING3 */ 246 274 if (!fEnable) … … 249 277 pKvmCpu->u64SystemTimeMsr = uRawValue; 250 278 return VINF_SUCCESS; 251 }252 253 /* Is the system-time struct. already enabled? If so, get flags that need preserving. */254 GIMKVMSYSTEMTIME SystemTime;255 RT_ZERO(SystemTime);256 if ( MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pKvmCpu->u64SystemTimeMsr)257 && MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue) == pKvmCpu->GCPhysSystemTime)258 {259 int rc2 = PGMPhysSimpleReadGCPhys(pVM, &SystemTime, pKvmCpu->GCPhysSystemTime, sizeof(GIMKVMSYSTEMTIME));260 if (RT_SUCCESS(rc2))261 pKvmCpu->fSystemTimeFlags = (SystemTime.fFlags & GIM_KVM_SYSTEM_TIME_FLAGS_GUEST_PAUSED);262 279 } 263 280 -
trunk/src/VBox/VMM/VMMR0/GIMR0Kvm.cpp
r82968 r83372 56 56 uint64_t uVirtNanoTS; 57 57 RTCCUINTREG fEFlags = ASMIntDisableFlags(); 58 uTsc = TMCpuTickGetNoCheck(pVCpu) | UINT64_C(1);59 uVirtNanoTS = TMVirtualGetNoCheck(pVM) | UINT64_C(1);58 uTsc = TMCpuTickGetNoCheck(pVCpu); 59 uVirtNanoTS = TMVirtualGetNoCheck(pVM); 60 60 ASMSetFlags(fEFlags); 61 61 … … 68 68 { 69 69 PGIMKVMCPU pKvmCpu = &VMCC_GET_CPU(pVM, idCpu)->gim.s.u.KvmCpu; 70 if ( !pKvmCpu->uTsc 71 && !pKvmCpu->uVirtNanoTS) 72 { 73 pKvmCpu->uTsc = uTsc; 74 pKvmCpu->uVirtNanoTS = uVirtNanoTS; 75 } 70 pKvmCpu->uTsc = uTsc; 71 pKvmCpu->uVirtNanoTS = uVirtNanoTS; 76 72 } 77 73 RTSpinlockRelease(pKvm->hSpinlockR0); -
trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp
r82968 r83372 416 416 417 417 /* 418 * Update guest memory with the system-time struct. 418 * Update guest memory with the system-time struct. Technically we are cheating 419 * by only writing the struct once with the version incremented by two; in reality, 420 * the system-time struct is enabled once by the boot CPU and not concurrently read 421 * by other VCPUs at the same time. 419 422 */ 420 423 Assert(!(SystemTime.u32Version & UINT32_C(1)));
Note:
See TracChangeset
for help on using the changeset viewer.