VirtualBox

Changeset 86121 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Sep 14, 2020 4:56:09 PM (4 years ago)
Author:
vboxsync
Message:

VMM/GIM: Fix handling KVM system-time struct. to work from both ring-0 and ring-3 (earlier it relied on MSR writes being handled in ring-0).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp

    r83372 r86121  
    230230{
    231231    NOREF(pRange);
    232     PVMCC      pVM  = pVCpu->CTX_SUFF(pVM);
    233     PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu;
    234 
    235232    switch (idMsr)
    236233    {
     
    238235        case MSR_GIM_KVM_SYSTEM_TIME_OLD:
    239236        {
    240             bool fEnable = RT_BOOL(uRawValue & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT);
    241237#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);
    271245            else
    272                 return VINF_CPUM_R3_MSR_WRITE;
    273 #else /* IN_RING3 */
    274             if (!fEnable)
    275             {
    276246                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;
    296249            return VINF_SUCCESS;
    297250#endif /* IN_RING3 */
     
    302255        {
    303256#ifndef IN_RING3
     257            RT_NOREF2(pVCpu, uRawValue);
    304258            return VINF_CPUM_R3_MSR_WRITE;
    305259#else
     
    308262            if (RT_LIKELY(RT_ALIGN_64(GCPhysWallClock, 4) == GCPhysWallClock))
    309263            {
     264                PVMCC pVM = pVCpu->CTX_SUFF(pVM);
    310265                int rc = gimR3KvmEnableWallClock(pVM, GCPhysWallClock);
    311266                if (RT_SUCCESS(rc))
Note: See TracChangeset for help on using the changeset viewer.

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