VirtualBox

儲存庫 vbox 的更動 55510


忽略:
時間撮記:
2015-4-29 上午10:13:15 (10 年 以前)
作者:
vboxsync
訊息:

VMM/GIM: EMT Rendezvous while updating global wall-clock struct.

位置:
trunk/src/VBox/VMM
檔案:
修改 3 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp

    r55129 r55510  
    255255
    256256            /* Enable and populate the system-time struct. */
    257             pKvmCpu->u64SystemTimeMsr     = uRawValue;
    258             pKvmCpu->GCPhysSystemTime     = MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue);
    259             pKvmCpu->u32SystemTimeVersion = pKvmCpu->u32SystemTimeVersion + 2;
     257            pKvmCpu->u64SystemTimeMsr      = uRawValue;
     258            pKvmCpu->GCPhysSystemTime      = MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue);
     259            pKvmCpu->u32SystemTimeVersion += 2;
    260260            int rc = gimR3KvmEnableSystemTime(pVM, pVCpu, pKvmCpu, fFlags);
    261261            if (RT_FAILURE(rc))
     
    279279            if (RT_LIKELY(RT_ALIGN_64(GCPhysWallClock, 4) == GCPhysWallClock))
    280280            {
    281                 uint32_t uVersion = 2;
    282                 int rc = gimR3KvmEnableWallClock(pVM, GCPhysWallClock, uVersion);
     281                int rc = gimR3KvmEnableWallClock(pVM, GCPhysWallClock);
    283282                if (RT_SUCCESS(rc))
    284283                {
  • trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp

    r55455 r55510  
    4747#define GIM_KVM_SAVED_STATE_VERSION         UINT32_C(1)
    4848
     49/**
     50 * VBox internal struct. to passback to EMT rendezvous callback while enabling
     51 * the KVM wall-clock.
     52 */
     53typedef struct KVMWALLCLOCKINFO
     54{
     55    /** Guest physical address of the wall-clock struct.  */
     56    RTGCPHYS GCPhysWallClock;
     57} KVMWALLCLOCKINFO;
     58/** Pointer to the wall-clock info. struct. */
     59typedef KVMWALLCLOCKINFO *PKVMWALLCLOCKINFO;
    4960
    5061/*******************************************************************************
     
    438449
    439450/**
     451 * @callback_method_impl{PFNVMMEMTRENDEZVOUS,
     452 *      Worker for gimR3KvmEnableWallClock}
     453 */
     454static DECLCALLBACK(VBOXSTRICTRC) gimR3KvmEnableWallClockCallback(PVM pVM, PVMCPU pVCpu, void *pvData)
     455{
     456    Assert(pvData);
     457    PKVMWALLCLOCKINFO pWallClockInfo  = (PKVMWALLCLOCKINFO)pvData;
     458    RTGCPHYS          GCPhysWallClock = pWallClockInfo->GCPhysWallClock;
     459
     460    /*
     461     * Read the wall-clock version (sequence) from the guest.
     462     */
     463    uint32_t uVersion;
     464    Assert(PGMPhysIsGCPhysNormal(pVM, GCPhysWallClock));
     465    int rc = PGMPhysSimpleReadGCPhys(pVM, &uVersion, GCPhysWallClock, sizeof(uVersion));
     466    if (RT_FAILURE(rc))
     467    {
     468        LogRel(("GIM: KVM: Failed to read wall-clock struct. version at %#RGp. rc=%Rrc\n", GCPhysWallClock, rc));
     469        return rc;
     470    }
     471
     472    /*
     473     * Ensure the version is incrementally even.
     474     */
     475    if (!(uVersion & 1))
     476        ++uVersion;
     477    ++uVersion;
     478
     479    /*
     480     * Update wall-clock guest struct. with UTC information.
     481     */
     482    RTTIMESPEC TimeSpec;
     483    int32_t    iSec;
     484    int32_t    iNano;
     485    TMR3UtcNow(pVM, &TimeSpec);
     486    RTTimeSpecGetSecondsAndNano(&TimeSpec, &iSec, &iNano);
     487
     488    GIMKVMWALLCLOCK WallClock;
     489    RT_ZERO(WallClock);
     490    AssertCompile(sizeof(uVersion) == sizeof(WallClock.u32Version));
     491    WallClock.u32Version = uVersion;
     492    WallClock.u32Sec     = iSec;
     493    WallClock.u32Nano    = iNano;
     494
     495    /*
     496     * Write out the wall-clock struct. to guest memory.
     497     */
     498    Assert(!(WallClock.u32Version & 1));
     499    rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysWallClock, &WallClock, sizeof(GIMKVMWALLCLOCK));
     500    if (RT_SUCCESS(rc))
     501    {
     502        LogRel(("GIM: KVM: Enabled wall-clock struct. at %#RGp - u32Sec=%u u32Nano=%u uVersion=%#RU32\n", GCPhysWallClock,
     503                WallClock.u32Sec, WallClock.u32Nano, WallClock.u32Version));
     504    }
     505    else
     506        LogRel(("GIM: KVM: Failed to write wall-clock struct. at %#RGp. rc=%Rrc\n", GCPhysWallClock, rc));
     507    return rc;
     508}
     509
     510
     511/**
    440512 * Enables the KVM wall-clock structure.
     513 *
     514 * Since the wall-clock can be read by any VCPU but it is a global struct. in
     515 * guest-memory, we do an EMT rendezvous here to be on the safe side. The
     516 * alternative is to use an MMIO2 region and use the WallClock.u32Version field
     517 * for transactional update. However, this MSR is rarely written to (typically
     518 * once during bootup) it's currently not a performance issue.
    441519 *
    442520 * @returns VBox status code.
     
    448526 *          guest R0 code.
    449527 */
    450 VMMR3_INT_DECL(int) gimR3KvmEnableWallClock(PVM pVM, RTGCPHYS GCPhysWallClock, uint32_t uVersion)
    451 {
    452     RTTIMESPEC TimeSpec;
    453     int32_t    iSec;
    454     int32_t    iNano;
    455 
    456     TMR3UtcNow(pVM, &TimeSpec);
    457     RTTimeSpecGetSecondsAndNano(&TimeSpec, &iSec, &iNano);
    458 
    459     GIMKVMWALLCLOCK WallClock;
    460     RT_ZERO(WallClock);
    461     WallClock.u32Version = uVersion;
    462     WallClock.u32Sec     = iSec;
    463     WallClock.u32Nano    = iNano;
    464 
    465     Assert(PGMPhysIsGCPhysNormal(pVM, GCPhysWallClock));
    466     Assert(!(WallClock.u32Version & UINT32_C(1)));
    467     int rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysWallClock, &WallClock, sizeof(GIMKVMWALLCLOCK));
    468     if (RT_SUCCESS(rc))
    469     {
    470         LogRel(("GIM: KVM: Enabled wall-clock struct. at %#RGp - u32Sec=%u u32Nano=%u uVersion=%#RU32\n", GCPhysWallClock,
    471                 WallClock.u32Sec, WallClock.u32Nano, WallClock.u32Version));
    472     }
    473     else
    474         LogRel(("GIM: KVM: Failed to write wall-clock struct. at %#RGp. rc=%Rrc\n", GCPhysWallClock, rc));
    475 
    476     return rc;
    477 }
    478 
     528VMMR3_INT_DECL(int) gimR3KvmEnableWallClock(PVM pVM, RTGCPHYS GCPhysWallClock)
     529{
     530    KVMWALLCLOCKINFO WallClockInfo;
     531    WallClockInfo.GCPhysWallClock = GCPhysWallClock;
     532    return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, gimR3KvmEnableWallClockCallback, &WallClockInfo);
     533}
     534
  • trunk/src/VBox/VMM/include/GIMKvmInternal.h

    r55129 r55510  
    253253VMMR3_INT_DECL(int)             gimR3KvmDisableSystemTime(PVM pVM);
    254254VMMR3_INT_DECL(int)             gimR3KvmEnableSystemTime(PVM pVM, PVMCPU pVCpu, PGIMKVMCPU pKvmCpu, uint8_t fFlags);
    255 VMMR3_INT_DECL(int)             gimR3KvmEnableWallClock(PVM pVM, RTGCPHYS GCPhysSysTime, uint32_t uVersion);
     255VMMR3_INT_DECL(int)             gimR3KvmEnableWallClock(PVM pVM, RTGCPHYS GCPhysSysTime);
    256256#endif /* IN_RING3 */
    257257
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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