VirtualBox

Changeset 53212 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 4, 2014 6:22:21 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96760
Message:

HostDrivers/Support: Add infrastructure for delta-adjusted TSC reads from all contexts.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r53209 r53212  
    158158static int                  supdrvIOCtl_MsrProber(PSUPDRVDEVEXT pDevExt, PSUPMSRPROBER pReq);
    159159static int                  supdrvIOCtl_TscDeltaMeasure(PSUPDRVDEVEXT pDevExt, PSUPTSCDELTAMEASURE pReq);
     160static int                  supdrvIOCtl_TscRead(PSUPDRVDEVEXT pDevExt, PSUPTSCREAD pReq);
    160161static int                  supdrvGipCreate(PSUPDRVDEVEXT pDevExt);
    161162static void                 supdrvGipDestroy(PSUPDRVDEVEXT pDevExt);
     
    22562257        }
    22572258
     2259        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_TSC_READ):
     2260        {
     2261            /* validate */
     2262            PSUPTSCREAD pReq = (PSUPTSCREAD)pReqHdr;
     2263            REQ_CHECK_SIZES(SUP_IOCTL_TSC_READ);
     2264
     2265            pReqHdr->rc = supdrvIOCtl_TscRead(pDevExt, pReq);
     2266            return 0;
     2267        }
     2268
    22582269        default:
    22592270            Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
     
    59105921
    59115922
     5923#if 0
    59125924/**
    59135925 * Measures the nominal TSC frequency.
     
    60246036    return VERR_SUPDRV_TSC_FREQ_MEASUREMENT_FAILED;
    60256037}
     6038#endif
    60266039
    60276040
     
    73457358        u32UpdateIntervalTSC >>= 1;
    73467359
    7347         /* Value chosen for a 2GHz Athlon64 running linux 2.6.10/11, . */
     7360        /* Value chosen for a 2GHz Athlon64 running linux 2.6.10/11. */
    73487361        u32UpdateIntervalTSCSlack = u32UpdateIntervalTSC >> 14;
    73497362    }
     
    76037616}
    76047617
     7618
     7619/**
     7620 * Reads the TSC and TSC-delta atomically, applies the TSC delta.
     7621 *
     7622 * @returns VBox status code.
     7623 * @param   pDevExt         Pointer to the device instance data.
     7624 * @param   pReq            Pointer to the TSC-read request.
     7625 */
     7626static int supdrvIOCtl_TscRead(PSUPDRVDEVEXT pDevExt, PSUPTSCREAD pReq)
     7627{
     7628    uint64_t uTsc;
     7629    uint16_t idApic;
     7630    int16_t cTries;
     7631    PSUPGLOBALINFOPAGE pGip;
     7632    int rc;
     7633
     7634    /*
     7635     * Validate.
     7636     */
     7637    AssertReturn(pDevExt, VERR_INVALID_PARAMETER);
     7638    AssertReturn(pReq, VERR_INVALID_PARAMETER);
     7639    AssertReturn(pDevExt->pGip, VERR_INVALID_PARAMETER);
     7640    pGip = pDevExt->pGip;
     7641
     7642    cTries = 4;
     7643    while (cTries-- > 0)
     7644    {
     7645        rc = SUPReadTsc(&uTsc, &idApic);
     7646        if (RT_SUCCESS(rc))
     7647        {
     7648            pReq->u.Out.u64AdjustedTsc = uTsc;
     7649            pReq->u.Out.idApic = idApic;
     7650            return VINF_SUCCESS;
     7651        }
     7652        else
     7653        {
     7654            int rc2;
     7655
     7656            /* If we failed to have a delta, measurement the delta and retry. */
     7657            AssertReturn(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId), VERR_INVALID_CPU_ID);
     7658            uint16_t iCpu = pGip->aiCpuFromApicId[idApic];
     7659            AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_WRONG_ORDER);
     7660
     7661            rc2 = supdrvMeasureTscDeltaOne(pDevExt, iCpu);
     7662            if (RT_SUCCESS(rc2))
     7663                AssertReturn(pGip->aCPUs[iCpu].i64TSCDelta != INT64_MAX, VERR_INTERNAL_ERROR_2);
     7664        }
     7665    }
     7666
     7667    return rc;
     7668}
     7669
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r53173 r53212  
    215215 *          - (none).
    216216 */
    217 #define SUPDRV_IOC_VERSION                              0x001c0000
     217#define SUPDRV_IOC_VERSION                              0x001c0001
    218218
    219219/** SUP_IOCTL_COOKIE. */
     
    15081508/** @} */
    15091509
     1510/** @name SUP_IOCTL_TSC_READ
     1511 * Reads the TSC and TSC-delta atomically and returns the delta-adjusted TSC
     1512 * value.
     1513 *
     1514 * @{
     1515 */
     1516#define SUP_IOCTL_TSC_READ                              SUP_CTL_CODE_SIZE(37, SUP_IOCTL_TSC_READ_SIZE)
     1517#define SUP_IOCTL_TSC_READ_SIZE                         sizeof(SUPTSCREAD)
     1518#define SUP_IOCTL_TSC_READ_SIZE_IN                      sizeof(SUPTSCREAD)
     1519#define SUP_IOCTL_TSC_READ_SIZE_OUT                     sizeof(SUPREQHDR)
     1520typedef struct SUPTSCREAD
     1521{
     1522    /** The header. */
     1523    SUPREQHDR               Hdr;
     1524
     1525    /** Input/output union. */
     1526    union
     1527    {
     1528        struct
     1529        {
     1530            /** The TSC after applying the relevant delta. */
     1531            uint64_t        u64AdjustedTsc;
     1532            /** The APIC Id of the CPU where the TSC was read. */
     1533            uint16_t        idApic;
     1534            /** Padding for future. */
     1535            uint64_t        auPadding[3];
     1536        } Out;
     1537    } u;
     1538} SUPTSCREAD, *PSUPTSCREAD;
     1539AssertCompileMemberAlignment(SUPTSCREAD, u, 8);
     1540/** @} */
    15101541
    15111542#pragma pack()                          /* paranoia */
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r53063 r53212  
    279279        strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
    280280        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    281         const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001b0000
    282                                    ? 0x001b0001
     281        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001c0000
     282                                   ? 0x001c0001
    283283                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    284284        CookieReq.u.In.u32MinVersion = uMinVersion;
     
    21992199}
    22002200
     2201
     2202SUPR3DECL(int) SUPR3ReadTsc(uint64_t *puTsc, uint16_t *pidApic)
     2203{
     2204    AssertReturn(puTsc, VERR_INVALID_PARAMETER);
     2205
     2206    SUPTSCREAD Req;
     2207    Req.Hdr.u32Cookie        = g_u32Cookie;
     2208    Req.Hdr.u32SessionCookie = g_u32SessionCookie;
     2209    Req.Hdr.cbIn             = SUP_IOCTL_TSC_READ_SIZE_IN;
     2210    Req.Hdr.cbOut            = SUP_IOCTL_TSC_READ_SIZE_OUT;
     2211    Req.Hdr.fFlags           = SUPREQHDR_FLAGS_DEFAULT;
     2212    Req.Hdr.rc               = VERR_INTERNAL_ERROR;
     2213
     2214    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_TSC_DELTA_MEASURE, &Req, SUP_IOCTL_TSC_DELTA_MEASURE_SIZE);
     2215    if (RT_SUCCESS(rc))
     2216    {
     2217        rc = Req.Hdr.rc;
     2218        *puTsc = Req.u.Out.u64AdjustedTsc;
     2219        if (pidApic)
     2220            *pidApic = Req.u.Out.idApic;
     2221    }
     2222    return rc;
     2223}
     2224
Note: See TracChangeset for help on using the changeset viewer.

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