VirtualBox

Changeset 44076 in vbox


Ignore:
Timestamp:
Dec 10, 2012 12:36:48 PM (12 years ago)
Author:
vboxsync
Message:

VMM: don't pass certain CPUID features to the guest if the feature is not supported on some host cores

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.h

    r43852 r44076  
    415415VMMR3DECL(int)          CPUMR3Init(PVM pVM);
    416416VMMR3DECL(int)          CPUMR3InitCompleted(PVM pVM);
     417VMMR3DECL(int)          CPUMR3LogCpuIds(PVM pVM);
    417418VMMR3DECL(void)         CPUMR3Relocate(PVM pVM);
    418419VMMR3DECL(int)          CPUMR3Term(PVM pVM);
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r43387 r44076  
    105105#endif
    106106    return VINF_SUCCESS;
     107}
     108
     109
     110/**
     111 * Check the CPUID features of this particular CPU and disable relevant features
     112 * for the guest which do not exist on this CPU. We have seen systems where the
     113 * X86_CPUID_FEATURE_ECX_MONITOR feature flag is only set on some host CPUs, see
     114 * @{bugref 5436}.
     115 *
     116 * @param   idCpu       The identifier for the CPU the function is called on.
     117 * @param   pvUser1     Pointer to the VM structure.
     118 * @param   pvUser2     Ignored.
     119 */
     120static DECLCALLBACK(void) cpumR0CheckCpuid(RTCPUID idCpu, void *pvUser1, void *pvUser2)
     121{
     122    struct
     123    {
     124        uint32_t uLeave; /* leave to check */
     125        uint32_t ecx;    /* which bits in ecx to unify between CPUs */
     126        uint32_t edx;    /* which bits in edx to unify between CPUs */
     127    } aCpuidUnify[]
     128    =
     129    {
     130        { 0x00000001, X86_CPUID_FEATURE_ECX_CX16
     131                    | X86_CPUID_FEATURE_ECX_MONITOR,
     132                      X86_CPUID_FEATURE_EDX_CX8 }
     133    };
     134    PVM pVM = (PVM)pvUser1;
     135    PCPUM pCPUM = &pVM->cpum.s;
     136    for (uint32_t i = 0; i < RT_ELEMENTS(aCpuidUnify); i++)
     137    {
     138        uint32_t uLeave = aCpuidUnify[i].uLeave;
     139        uint32_t eax, ebx, ecx, edx;
     140
     141        ASMCpuId_Idx_ECX(uLeave, 0, &eax, &ebx, &ecx, &edx);
     142        PCPUMCPUID paLeaves;
     143        uint32_t idx;
     144        if (uLeave < 0x80000000)
     145            paLeaves = &pCPUM->aGuestCpuIdStd[uLeave - 0x00000000];
     146        else if (uLeave < 0xc0000000)
     147            paLeaves = &pCPUM->aGuestCpuIdExt[uLeave - 0x80000000];
     148        else
     149            paLeaves = &pCPUM->aGuestCpuIdCentaur[uLeave - 0xc0000000];
     150        /* unify important bits */
     151        paLeaves->ecx & (ecx | ~aCpuidUnify[i].ecx);
     152        paLeaves->edx & (edx | ~aCpuidUnify[i].edx);
     153    }
    107154}
    108155
     
    205252            }
    206253        }
     254
     255        RTMpOnAll(cpumR0CheckCpuid, pVM, NULL);
    207256    }
    208257
     
    676725 * Worker for cpumR0MapLocalApics. Check each CPU for a present Local APIC.
    677726 * Play safe and treat each CPU separate.
     727 *
     728 * @param   idCpu       The identifier for the CPU the function is called on.
     729 * @param   pvUser1     Ignored.
     730 * @param   pvUser2     Ignored.
    678731 */
    679732static DECLCALLBACK(void) cpumR0MapLocalApicWorker(RTCPUID idCpu, void *pvUser1, void *pvUser2)
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r44027 r44076  
    13941394    if (fEnable)
    13951395        CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);
    1396     /*
    1397      * Log the cpuid and we're good.
    1398      */
    1399     bool fOldBuffered = RTLogRelSetBuffering(true /*fBuffered*/);
    1400     RTCPUSET OnlineSet;
    1401     LogRel(("Logical host processors: %u present, %u max, %u online, online mask: %016RX64\n",
    1402             (unsigned)RTMpGetPresentCount(), (unsigned)RTMpGetCount(), (unsigned)RTMpGetOnlineCount(),
    1403             RTCpuSetToU64(RTMpGetOnlineSet(&OnlineSet)) ));
    1404     LogRel(("************************* CPUID dump ************************\n"));
    1405     DBGFR3Info(pVM, "cpuid", "verbose", DBGFR3InfoLogRelHlp());
    1406     LogRel(("\n"));
    1407     DBGFR3InfoLog(pVM, "cpuid", "verbose"); /* macro */
    1408     RTLogRelSetBuffering(fOldBuffered);
    1409     LogRel(("******************** End of CPUID dump **********************\n"));
    14101396
    14111397#undef PORTABLE_DISABLE_FEATURE_BIT
     
    44054391}
    44064392
     4393/**
     4394 * Called when the ring-0 init phases comleted.
     4395 *
     4396 * @returns VBox status code.
     4397 * @param   pVM                 Pointer to the VM.
     4398 */
     4399VMMR3DECL(int) CPUMR3LogCpuIds(PVM pVM)
     4400{
     4401    /*
     4402     * Log the cpuid.
     4403     */
     4404    bool fOldBuffered = RTLogRelSetBuffering(true /*fBuffered*/);
     4405    RTCPUSET OnlineSet;
     4406    LogRel(("Logical host processors: %u present, %u max, %u online, online mask: %016RX64\n",
     4407                (unsigned)RTMpGetPresentCount(), (unsigned)RTMpGetCount(), (unsigned)RTMpGetOnlineCount(),
     4408                RTCpuSetToU64(RTMpGetOnlineSet(&OnlineSet)) ));
     4409    LogRel(("************************* CPUID dump ************************\n"));
     4410    DBGFR3Info(pVM, "cpuid", "verbose", DBGFR3InfoLogRelHlp());
     4411    LogRel(("\n"));
     4412    DBGFR3InfoLog(pVM, "cpuid", "verbose"); /* macro */
     4413    RTLogRelSetBuffering(fOldBuffered);
     4414    LogRel(("******************** End of CPUID dump **********************\n"));
     4415    return VINF_SUCCESS;
     4416}
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r43667 r44076  
    690690                pVM->vmm.s.fUsePeriodicPreemptionTimers = false;
    691691            LogRel(("VMM: fUsePeriodicPreemptionTimers=%RTbool\n", pVM->vmm.s.fUsePeriodicPreemptionTimers));
     692
     693            /*
     694             * CPUM's post-initialization (print CPUIDs).
     695             */
     696            rc = CPUMR3LogCpuIds(pVM);
     697            AssertRCReturn(rc, rc);
     698
    692699            break;
    693700        }
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