VirtualBox

Changeset 67821 in vbox


Ignore:
Timestamp:
Jul 6, 2017 1:38:26 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116750
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
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r67136 r67821  
    18171817SUPR3DECL(int) SUPR3GipSetFlags(uint32_t fOrMask, uint32_t fAndMask);
    18181818
     1819/**
     1820 * Return processor microcode revision, if applicable.
     1821 *
     1822 * @returns VINF_SUCCESS if supported, error code indicating why if not.
     1823 * @param   puMicrocodeRev  Pointer to microcode revision dword (out).
     1824 */
     1825SUPR3DECL(int) SUPR3QueryMicrocodeRev(uint32_t *puMicrocodeRev);
     1826
    18191827/** @} */
    18201828#endif /* IN_RING3 */
     
    18991907SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps);
    19001908SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession);
     1909SUPR0DECL(int) SUPR0QueryUcodeRev(PSUPDRVSESSION pSession, uint32_t *puMicrocodeRev);
    19011910SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void);
    19021911SUPR0DECL(RTCCUINTREG) SUPR0ChangeCR4(RTCCUINTREG fOrMask, RTCCUINTREG fAndMask);
  • 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{
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r67071 r67821  
    2828#include <VBox/vmm/vm.h>
    2929#include <VBox/vmm/mm.h>
     30#include <VBox/sup.h>
    3031
    3132#include <VBox/err.h>
     
    26612662#endif
    26622663
    2663     /* Mask out the VME capability on certain CPUs, unless overridden by fForceVme. */
     2664    uint32_t uMicrocodeRev;
     2665    int rc = SUPR3QueryMicrocodeRev(&uMicrocodeRev);
     2666    rc = SUPR3QueryVTCaps(&uMicrocodeRev);
     2667    if (RT_SUCCESS(rc))
     2668    {
     2669        LogRel(("CPUM: Microcode revision 0x%08X\n", uMicrocodeRev));
     2670    }
     2671    else
     2672    {
     2673        uMicrocodeRev = 0;
     2674        LogRel(("CPUM: Failed to query microcode revision. rc=%Rrc\n", rc));
     2675    }
     2676
     2677    /* Mask out the VME capability on certain CPUs, unless overridden by fForceVme.
     2678     * VME bug was fixed in AGESA 1.0.0.6, microcode patch level 8001126.
     2679     */
    26642680    if ( (pVM->cpum.s.GuestFeatures.enmMicroarch == kCpumMicroarch_AMD_Zen_Ryzen)
     2681        && uMicrocodeRev < 0x8001126
    26652682        && !pConfig->fForceVme)
    26662683    {
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