VirtualBox

Changeset 67821 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Jul 6, 2017 1:38:26 PM (8 years ago)
Author:
vboxsync
Message:

SUP, VMM: Added interface to read CPU microcode revision, used in VMM to decide whether Ryzen VME workaround is needed or not (bugref:8852).

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

Legend:

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

    r67138 r67821  
    23032303        }
    23042304
     2305        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_UCODE_REV):
     2306        {
     2307            /* validate */
     2308            PSUPUCODEREV pReq = (PSUPUCODEREV)pReqHdr;
     2309            REQ_CHECK_SIZES(SUP_IOCTL_UCODE_REV);
     2310   
     2311            /* execute */
     2312            pReq->Hdr.rc = SUPR0QueryUcodeRev(pSession, &pReq->u.Out.MicrocodeRev);
     2313            if (RT_FAILURE(pReq->Hdr.rc))
     2314                pReq->Hdr.cbOut = sizeof(pReq->Hdr);
     2315            return 0;
     2316        }
     2317   
    23052318        default:
    23062319            Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
     
    42014214     */
    42024215    return supdrvQueryVTCapsInternal(pfCaps);
     4216}
     4217
     4218
     4219/**
     4220 * Queries the CPU microcode revision.
     4221 *
     4222 * @returns VBox status code.
     4223 * @retval  VERR_UNSUPPORTED_CPU if not identifiable as a processor with
     4224 *          readable microcode rev.
     4225 *
     4226 * @param   pSession        The session handle.
     4227 * @param   puRevisoion     Where to store the microcode revision.
     4228 */
     4229int VBOXCALL supdrvQueryUcodeRev(uint32_t *puRevision)
     4230{
     4231    int  rc = VERR_UNSUPPORTED_CPU;
     4232    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
     4233
     4234    /*
     4235     * Input validation.
     4236     */
     4237    AssertPtrReturn(puRevision, VERR_INVALID_POINTER);
     4238
     4239    *puRevision = 0;
     4240
     4241    /* Disable preemption so we make sure we don't migrate CPUs, just in case. */
     4242    /* NB: We assume that there aren't mismatched microcode revs in the system. */
     4243    RTThreadPreemptDisable(&PreemptState);
     4244
     4245    if (ASMHasCpuId())
     4246    {
     4247        uint32_t uDummy, uTFMSEAX;
     4248        uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX;
     4249
     4250        ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX);
     4251        ASMCpuId(1, &uTFMSEAX, &uDummy, &uDummy, &uDummy);
     4252
     4253        if (ASMIsValidStdRange(uMaxId))
     4254        {
     4255            uint64_t    uRevMsr;
     4256            if (ASMIsIntelCpuEx(uVendorEBX, uVendorECX, uVendorEDX))
     4257            {
     4258                /* Architectural MSR available on Pentium Pro and later. */
     4259                if (ASMGetCpuFamily(uTFMSEAX) >= 6)
     4260                {
     4261                    /* Revision is in the high dword. */
     4262                    uRevMsr = ASMRdMsr(MSR_IA32_BIOS_SIGN_ID);
     4263                    *puRevision = RT_HIDWORD(uRevMsr);
     4264                    rc = VINF_SUCCESS;
     4265                }
     4266            }
     4267            else if (ASMIsAmdCpuEx(uVendorEBX, uVendorECX, uVendorEDX))
     4268            {
     4269                /* Not well documented, but at least all AMD64 CPUs support this. */
     4270                if (ASMGetCpuFamily(uTFMSEAX) >= 15)
     4271                {
     4272                    /* Revision is in the low dword. */
     4273                    uRevMsr = ASMRdMsr(MSR_IA32_BIOS_SIGN_ID);  /* Same MSR as Intel. */
     4274                    *puRevision = RT_LODWORD(uRevMsr);
     4275                    rc = VINF_SUCCESS;
     4276                }
     4277            }
     4278        }
     4279    }
     4280
     4281    RTThreadPreemptRestore(&PreemptState);
     4282
     4283    return rc;
     4284}
     4285
     4286/**
     4287 * Queries the CPU microcode revision.
     4288 *
     4289 * @returns VBox status code.
     4290 * @retval  VERR_UNSUPPORTED_CPU if not identifiable as a processor with
     4291 *          readable microcode rev.
     4292 *
     4293 * @param   pSession        The session handle.
     4294 * @param   puRevisoion     Where to store the microcode revision.
     4295 */
     4296SUPR0DECL(int) SUPR0QueryUcodeRev(PSUPDRVSESSION pSession, uint32_t *puRevision)
     4297{
     4298    /*
     4299     * Input validation.
     4300     */
     4301    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
     4302    AssertPtrReturn(puRevision, VERR_INVALID_POINTER);
     4303
     4304    /*
     4305     * Call common worker.
     4306     */
     4307    return supdrvQueryUcodeRev(puRevision);
    42034308}
    42044309
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r67460 r67821  
    215215 *          - nothing.
    216216 */
    217 #define SUPDRV_IOC_VERSION                              0x00280001
     217#define SUPDRV_IOC_VERSION                              0x00280002
    218218
    219219/** SUP_IOCTL_COOKIE. */
     
    15971597/** @} */
    15981598
     1599
     1600/** @name SUP_IOCTL_UCODE_REV
     1601 * Get the CPU microcode revision.
     1602 *
     1603 * @{
     1604 */
     1605#define SUP_IOCTL_UCODE_REV                             SUP_CTL_CODE_SIZE(40, SUP_IOCTL_VT_CAPS_SIZE)
     1606#define SUP_IOCTL_UCODE_REV_SIZE                        sizeof(SUPUCODEREV)
     1607#define SUP_IOCTL_UCODE_REV_SIZE_IN                     sizeof(SUPREQHDR)
     1608#define SUP_IOCTL_UCODE_REV_SIZE_OUT                    sizeof(SUPUCODEREV)
     1609typedef struct SUPUCODEREV
     1610{
     1611    /** The header. */
     1612    SUPREQHDR               Hdr;
     1613    union
     1614    {
     1615        struct
     1616        {
     1617            /** The microcode revision dword. */
     1618            uint32_t        MicrocodeRev;
     1619        } Out;
     1620    } u;
     1621} SUPUCODEREV, *PSUPUCODEREV;
     1622/** @} */
     1623
     1624
    15991625#pragma pack()                          /* paranoia */
    16001626
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r67460 r67821  
    277277        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    278278        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00280000
    279                                    ? 0x00280001
     279                                   ? 0x00280002
    280280                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    281281        CookieReq.u.In.u32MinVersion = uMinVersion;
     
    17011701
    17021702
     1703SUPR3DECL(int) SUPR3QueryMicrocodeRev(uint32_t *uMicrocodeRev)
     1704{
     1705    AssertPtrReturn(uMicrocodeRev, VERR_INVALID_POINTER);
     1706
     1707    *uMicrocodeRev = 0;
     1708
     1709    /* fake */
     1710    if (RT_UNLIKELY(g_uSupFakeMode))
     1711        return VINF_SUCCESS;
     1712
     1713    /*
     1714     * Issue IOCtl to the SUPDRV kernel module.
     1715     */
     1716    SUPUCODEREV Req;
     1717    Req.Hdr.u32Cookie = g_u32Cookie;
     1718    Req.Hdr.u32SessionCookie = g_u32SessionCookie;
     1719    Req.Hdr.cbIn = SUP_IOCTL_UCODE_REV_SIZE_IN;
     1720    Req.Hdr.cbOut = SUP_IOCTL_UCODE_REV_SIZE_OUT;
     1721    Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
     1722    Req.Hdr.rc = VERR_INTERNAL_ERROR;
     1723    Req.u.Out.MicrocodeRev = 0;
     1724    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_UCODE_REV, &Req, SUP_IOCTL_UCODE_REV_SIZE);
     1725    if (RT_SUCCESS(rc))
     1726    {
     1727        rc = Req.Hdr.rc;
     1728        if (RT_SUCCESS(rc))
     1729            *uMicrocodeRev = Req.u.Out.MicrocodeRev;
     1730    }
     1731    return rc;
     1732}
     1733
     1734
    17031735SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg)
    17041736{
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