bool Lease::isExpired() const
{
    AssertPtrReturn(m.get(), false);

    if (!m->fBinding)
        return (ASMDivU64ByU32RetU32(RTTimeMilliTS() - m->u64TimestampLeasingStarted, 1000)
                > m->u32LeaseExpirationPeriod);
    else
        return (ASMDivU64ByU32RetU32(RTTimeMilliTS() - m->u64TimestampBindingStarted, 1000)
                > m->u32BindExpirationPeriod);
}
Esempio n. 2
0
/**
 * Enables the KVM VCPU system-time structure.
 *
 * @returns VBox status code.
 * @param   pVM                Pointer to the VM.
 * @param   pVCpu              Pointer to the VMCPU.
 *
 * @remarks Don't do any release assertions here, these can be triggered by
 *          guest R0 code.
 */
VMMR3_INT_DECL(int) gimR3KvmEnableSystemTime(PVM pVM, PVMCPU pVCpu)
{
    PGIMKVM    pKvm    = &pVM->gim.s.u.Kvm;
    PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu;

    /*
     * Validate the mapping address first.
     */
    if (!PGMPhysIsGCPhysNormal(pVM, pKvmCpu->GCPhysSystemTime))
    {
        LogRel(("GIM: KVM: VCPU%3d: Invalid physical addr requested for mapping system-time struct. GCPhysSystemTime=%#RGp\n",
               pVCpu->idCpu, pKvmCpu->GCPhysSystemTime));
        return VERR_GIM_OPERATION_FAILED;
    }

    /*
     * Construct the system-time struct.
     */
    GIMKVMSYSTEMTIME SystemTime;
    RT_ZERO(SystemTime);
    SystemTime.u32Version  = pKvmCpu->u32SystemTimeVersion;
    SystemTime.u64NanoTS   = pKvmCpu->uVirtNanoTS;
    SystemTime.u64Tsc      = pKvmCpu->uTsc;
    SystemTime.fFlags      = pKvmCpu->fSystemTimeFlags | GIM_KVM_SYSTEM_TIME_FLAGS_TSC_STABLE;

    /*
     * How the guest calculates the system time (nanoseconds):
     *
     * tsc = rdtsc - SysTime.u64Tsc
     * if (SysTime.i8TscShift >= 0)
     *     tsc <<= i8TscShift;
     * else
     *     tsc >>= -i8TscShift;
     * time = ((tsc * SysTime.u32TscScale) >> 32) + SysTime.u64NanoTS
     */
    uint64_t u64TscFreq   = pKvm->cTscTicksPerSecond;
    SystemTime.i8TscShift = 0;
    while (u64TscFreq > 2 * RT_NS_1SEC_64)
    {
        u64TscFreq >>= 1;
        SystemTime.i8TscShift--;
    }
    uint32_t uTscFreqLo = (uint32_t)u64TscFreq;
    while (uTscFreqLo <= RT_NS_1SEC)
    {
        uTscFreqLo <<= 1;
        SystemTime.i8TscShift++;
    }
    SystemTime.u32TscScale = ASMDivU64ByU32RetU32(RT_NS_1SEC_64 << 32, uTscFreqLo);

    /*
     * Update guest memory with the system-time struct.
     */
    Assert(!(SystemTime.u32Version & UINT32_C(1)));
    int rc = PGMPhysSimpleWriteGCPhys(pVM, pKvmCpu->GCPhysSystemTime, &SystemTime, sizeof(GIMKVMSYSTEMTIME));
    if (RT_SUCCESS(rc))
    {
        LogRel(("GIM: KVM: VCPU%3d: Enabled system-time struct. at %#RGp - u32TscScale=%#RX32 i8TscShift=%d uVersion=%#RU32 "
                "fFlags=%#x uTsc=%#RX64 uVirtNanoTS=%#RX64\n", pVCpu->idCpu, pKvmCpu->GCPhysSystemTime, SystemTime.u32TscScale,
                SystemTime.i8TscShift, SystemTime.u32Version, SystemTime.fFlags, pKvmCpu->uTsc, pKvmCpu->uVirtNanoTS));
        TMR3CpuTickParavirtEnable(pVM);
    }
    else
        LogRel(("GIM: KVM: VCPU%3d: Failed to write system-time struct. at %#RGp. rc=%Rrc\n",
                pVCpu->idCpu, pKvmCpu->GCPhysSystemTime, rc));

    return rc;
}