VirtualBox

Changeset 68938 in vbox


Ignore:
Timestamp:
Sep 29, 2017 4:13:26 PM (7 years ago)
Author:
vboxsync
Message:

Main,VBoxManage: Changed the CPUID override methods on IMachine to take sub-leaves into account. Currently we do not support non-zero sub-leaves due to VMM, but that can be fixed later.

Location:
trunk
Files:
8 edited

Legend:

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

    r68485 r68938  
    694694    bool operator==(const CpuIdLeaf &c) const;
    695695
    696     uint32_t                ulId;
    697     uint32_t                ulEax;
    698     uint32_t                ulEbx;
    699     uint32_t                ulEcx;
    700     uint32_t                ulEdx;
     696    uint32_t                idx;
     697    uint32_t                idxSub;
     698    uint32_t                uEax;
     699    uint32_t                uEbx;
     700    uint32_t                uEcx;
     701    uint32_t                uEdx;
    701702};
    702703
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r68514 r68938  
    630630    if (details != VMINFO_MACHINEREADABLE)
    631631        RTPrintf("CPUID overrides: ");
    632     ULONG cFound = 0;
    633     static uint32_t const s_auCpuIdRanges[] =
    634     {
    635         UINT32_C(0x00000000), UINT32_C(0x0000000a),
    636         UINT32_C(0x80000000), UINT32_C(0x8000000a)
    637     };
    638     for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2)
    639         for (uint32_t uLeaf = s_auCpuIdRanges[i]; uLeaf < s_auCpuIdRanges[i + 1]; uLeaf++)
    640         {
    641             ULONG uEAX, uEBX, uECX, uEDX;
    642             rc = machine->GetCPUIDLeaf(uLeaf, &uEAX, &uEBX, &uECX, &uEDX);
    643             if (SUCCEEDED(rc))
    644             {
    645                 if (details == VMINFO_MACHINEREADABLE)
    646                     RTPrintf("cpuid=%08x,%08x,%08x,%08x,%08x", uLeaf, uEAX, uEBX, uECX, uEDX);
    647                 else
    648                 {
    649                     if (!cFound)
    650                         RTPrintf("Leaf no.  EAX      EBX      ECX      EDX\n");
    651                     RTPrintf("                 %08x  %08x %08x %08x %08x\n", uLeaf, uEAX, uEBX, uECX, uEDX);
    652                 }
    653                 cFound++;
    654             }
    655         }
    656     if (!cFound && details != VMINFO_MACHINEREADABLE)
     632    ULONG uOrdinal = 0;
     633    for (uOrdinal = 0; uOrdinal < _4K; uOrdinal++)
     634    {
     635        ULONG uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX;
     636        rc = machine->GetCPUIDLeafByOrdinal(uOrdinal, &uLeaf, &uSubLeaf, &uEAX, &uEBX, &uECX, &uEDX);
     637        if (SUCCEEDED(rc))
     638        {
     639            if (details == VMINFO_MACHINEREADABLE)
     640                RTPrintf("cpuid=%08x,%08x,%08x,%08x,%08x,%08x", uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX);
     641            else
     642            {
     643                if (!uOrdinal)
     644                    RTPrintf("Leaf no.       EAX      EBX      ECX      EDX\n");
     645                RTPrintf("                 %08x/%03x  %08x %08x %08x %08x\n", uLeaf, uSubLeaf, uEAX, uEBX, uECX, uEDX);
     646            }
     647        }
     648        else
     649        {
     650            if (rc != E_INVALIDARG)
     651                com::GlueHandleComError(machine, "GetCPUIDLeaf", rc, __FILE__, __LINE__);
     652            break;
     653        }
     654    }
     655
     656    if (!uOrdinal && details != VMINFO_MACHINEREADABLE)
    657657        RTPrintf("None\n");
    658658
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp

    r68485 r68938  
    8181    MODIFYVM_UNPLUGCPU,
    8282    MODIFYVM_SETCPUID,
     83    MODIFYVM_SETCPUID_OLD,
    8384    MODIFYVM_DELCPUID,
     85    MODIFYVM_DELCPUID_OLD,
    8486    MODIFYVM_DELALLCPUID,
    8587    MODIFYVM_GRAPHICSCONTROLLER,
     
    253255    { "--vtxvpid",                  MODIFYVM_VTXVPID,                   RTGETOPT_REQ_BOOL_ONOFF },
    254256    { "--vtxux",                    MODIFYVM_VTXUX,                     RTGETOPT_REQ_BOOL_ONOFF },
    255     { "--cpuidset",                 MODIFYVM_SETCPUID,                  RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX},
    256     { "--cpuidremove",              MODIFYVM_DELCPUID,                  RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX},
     257    { "--cpuid-set",                MODIFYVM_SETCPUID,                  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX },
     258    { "--cpuid-remove",             MODIFYVM_DELCPUID,                  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX },
     259    { "--cpuidset",                 MODIFYVM_SETCPUID_OLD,              RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX },
     260    { "--cpuidremove",              MODIFYVM_DELCPUID_OLD,              RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX },
    257261    { "--cpuidremoveall",           MODIFYVM_DELALLCPUID,               RTGETOPT_REQ_NOTHING},
    258262    { "--cpus",                     MODIFYVM_CPUS,                      RTGETOPT_REQ_UINT32 },
     
    735739
    736740            case MODIFYVM_SETCPUID:
    737             {
    738                 uint32_t id = ValueUnion.u32;
     741            case MODIFYVM_SETCPUID_OLD:
     742            {
     743                uint32_t const idx    = c == MODIFYVM_SETCPUID ?  ValueUnion.PairU32.uFirst  : ValueUnion.u32;
     744                uint32_t const idxSub = c == MODIFYVM_SETCPUID ?  ValueUnion.PairU32.uSecond : UINT32_MAX;
    739745                uint32_t aValue[4];
    740 
    741746                for (unsigned i = 0; i < 4; i++)
    742747                {
    743748                    int vrc = RTGetOptFetchValue(&GetOptState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX);
    744749                    if (RT_FAILURE(vrc))
    745                         return errorSyntax(USAGE_MODIFYVM,
    746                                            "Missing or Invalid argument to '%s'",
    747                                            GetOptState.pDef->pszLong);
     750                        return errorSyntax(USAGE_MODIFYVM, "Missing or Invalid argument to '%s'", GetOptState.pDef->pszLong);
    748751                    aValue[i] = ValueUnion.u32;
    749752                }
    750                 CHECK_ERROR(sessionMachine, SetCPUIDLeaf(id, aValue[0], aValue[1], aValue[2], aValue[3]));
     753                CHECK_ERROR(sessionMachine, SetCPUIDLeaf(idx, idxSub, aValue[0], aValue[1], aValue[2], aValue[3]));
    751754                break;
    752755            }
    753756
    754757            case MODIFYVM_DELCPUID:
    755             {
    756                 CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32));
    757                 break;
    758             }
     758                CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond));
     759                break;
     760
     761            case MODIFYVM_DELCPUID_OLD:
     762                CHECK_ERROR(sessionMachine, RemoveCPUIDLeaf(ValueUnion.u32, UINT32_MAX));
     763                break;
    759764
    760765            case MODIFYVM_DELALLCPUID:
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r68534 r68938  
    47764776  <interface
    47774777    name="IMachine" extends="$unknown"
    4778     uuid="f50b24f0-0956-453c-d14c-8c27c683c295"
     4778    uuid="85cd948e-a71f-4289-281e-0ca7ad48cd89"
    47794779    wsmap="managed"
    47804780    wrap-hint-server-addinterfaces="IInternalMachineControl"
    47814781    wrap-hint-server="manualaddinterfaces"
    4782     reservedMethods="7" reservedAttributes="9"
     4782    reservedMethods="6" reservedAttributes="9"
    47834783    >
    47844784    <!-- Note! This interface is not compatible between 5.0 and 5.1 as it had too many
     
    69326932    </method>
    69336933
     6934    <method name="getCPUIDLeafByOrdinal" const="yes">
     6935      <desc>
     6936        Used to enumerate CPUID information override values.
     6937
     6938        <result name="E_INVALIDARG">
     6939          Invalid ordinal number is out of range.
     6940        </result>
     6941      </desc>
     6942      <param name="ordinal" type="unsigned long" dir="in">
     6943        <desc>
     6944          The ordinal number of the leaf to get.
     6945        </desc>
     6946      </param>
     6947      <param name="idx" type="unsigned long" dir="out">
     6948        <desc>
     6949          CPUID leaf index.
     6950        </desc>
     6951      </param>
     6952      <param name="idxSub" type="unsigned long" dir="out">
     6953        <desc>
     6954          CPUID leaf sub-index.
     6955        </desc>
     6956      </param>
     6957      <param name="valEax" type="unsigned long" dir="out">
     6958        <desc>
     6959          CPUID leaf value for register eax.
     6960        </desc>
     6961      </param>
     6962      <param name="valEbx" type="unsigned long" dir="out">
     6963        <desc>
     6964          CPUID leaf value for register ebx.
     6965        </desc>
     6966      </param>
     6967      <param name="valEcx" type="unsigned long" dir="out">
     6968        <desc>
     6969          CPUID leaf value for register ecx.
     6970        </desc>
     6971      </param>
     6972      <param name="valEdx" type="unsigned long" dir="out">
     6973        <desc>
     6974          CPUID leaf value for register edx.
     6975        </desc>
     6976      </param>
     6977    </method>
     6978
    69346979    <method name="getCPUIDLeaf" const="yes">
    69356980      <desc>
     
    69376982
    69386983        Currently supported index values for cpuid:
    6939         Standard CPUID leafs: 0 - 0xA
    6940         Extended CPUID leafs: 0x80000000 - 0x8000000A
    6941 
    6942         See the Intel and AMD programmer's manuals for detailed information
    6943         about the cpuid instruction and its leafs.
     6984        Standard CPUID leaves: 0 - 0x1f
     6985        Extended CPUID leaves: 0x80000000 - 0x8000001f
     6986        VIA CPUID leaves:      0xc0000000 - 0xc000000f
     6987
     6988        See the Intel, AMD and VIA programmer's manuals for detailed information
     6989        about the CPUID instruction and its leaves.
    69446990        <result name="E_INVALIDARG">
    6945           Invalid id.
    6946         </result>
    6947 
    6948       </desc>
    6949       <param name="id" type="unsigned long" dir="in">
     6991          Invalid index.
     6992        </result>
     6993
     6994      </desc>
     6995      <param name="idx" type="unsigned long" dir="in">
    69506996        <desc>
    69516997          CPUID leaf index.
     6998        </desc>
     6999      </param>
     7000      <param name="idxSub" type="unsigned long" dir="in">
     7001        <desc>
     7002          CPUID leaf sub-index (ECX).  Set to 0xffffffff (or 0) if not applicable.
    69527003        </desc>
    69537004      </param>
     
    69807031
    69817032        Currently supported index values for cpuid:
    6982         Standard CPUID leafs: 0 - 0xA
    6983         Extended CPUID leafs: 0x80000000 - 0x8000000A
    6984 
    6985         See the Intel and AMD programmer's manuals for detailed information
    6986         about the cpuid instruction and its leafs.
     7033        Standard CPUID leaves: 0 - 0x1f
     7034        Extended CPUID leaves: 0x80000000 - 0x8000001f
     7035        VIA CPUID leaves:      0xc0000000 - 0xc000000f
     7036
     7037        The subleaf index is only applicable to certain leaves (see manuals as this is
     7038        subject to change).
     7039
     7040        See the Intel, AMD and VIA programmer's manuals for detailed information
     7041        about the cpuid instruction and its leaves.
    69877042
    69887043        Do not use this method unless you know exactly what you're doing. Misuse can lead to
    69897044        random crashes inside VMs.
    69907045        <result name="E_INVALIDARG">
    6991           Invalid id.
    6992         </result>
    6993 
    6994       </desc>
    6995       <param name="id" type="unsigned long" dir="in">
     7046          Invalid index.
     7047        </result>
     7048
     7049      </desc>
     7050      <param name="idx" type="unsigned long" dir="in">
    69967051        <desc>
    69977052          CPUID leaf index.
    69987053        </desc>
    69997054      </param>
     7055      <param name="idxSub" type="unsigned long" dir="in">
     7056        <desc>
     7057          CPUID leaf sub-index (ECX).  Set to 0xffffffff (or 0) if not applicable.
     7058          The 0xffffffff causes it to remove all other subleaves before adding one
     7059          with sub-index 0.
     7060        </desc>
     7061      </param>
    70007062      <param name="valEax" type="unsigned long" dir="in">
    70017063        <desc>
     
    70257087
    70267088        <result name="E_INVALIDARG">
    7027           Invalid id.
    7028         </result>
    7029 
    7030       </desc>
    7031       <param name="id" type="unsigned long" dir="in">
     7089          Invalid index.
     7090        </result>
     7091
     7092      </desc>
     7093      <param name="idx" type="unsigned long" dir="in">
    70327094        <desc>
    70337095          CPUID leaf index.
     7096        </desc>
     7097      </param>
     7098      <param name="idxSub" type="unsigned long" dir="in">
     7099        <desc>
     7100          CPUID leaf sub-index (ECX).  Set to 0xffffffff (or 0) if not applicable.
     7101          The 0xffffffff value works like a wildcard.
    70347102        </desc>
    70357103      </param>
  • trunk/src/VBox/Main/include/MachineImpl.h

    r68485 r68938  
    298298        BOOL                mCPUAttached[SchemaDefs::MaxCPUCount];
    299299
    300         settings::CpuIdLeaf mCpuIdStdLeafs[11];
    301         settings::CpuIdLeaf mCpuIdExtLeafs[11];
     300        std::list<settings::CpuIdLeaf> mCpuIdLeafList;
    302301
    303302        DeviceType_T        mBootOrder[SchemaDefs::MaxBootPosition];
     
    10901089    HRESULT setCPUProperty(CPUPropertyType_T aProperty,
    10911090                           BOOL aValue);
    1092     HRESULT getCPUIDLeaf(ULONG aId,
     1091    HRESULT getCPUIDLeafByOrdinal(ULONG aOrdinal,
     1092                                  ULONG *aIdx,
     1093                                  ULONG *aSubIdx,
     1094                                  ULONG *aValEax,
     1095                                  ULONG *aValEbx,
     1096                                  ULONG *aValEcx,
     1097                                  ULONG *aValEdx);
     1098    HRESULT getCPUIDLeaf(ULONG aIdx, ULONG aSubIdx,
    10931099                         ULONG *aValEax,
    10941100                         ULONG *aValEbx,
    10951101                         ULONG *aValEcx,
    10961102                         ULONG *aValEdx);
    1097     HRESULT setCPUIDLeaf(ULONG aId,
     1103    HRESULT setCPUIDLeaf(ULONG aIdx, ULONG aSubIdx,
    10981104                         ULONG aValEax,
    10991105                         ULONG aValEbx,
    11001106                         ULONG aValEcx,
    11011107                         ULONG aValEdx);
    1102     HRESULT removeCPUIDLeaf(ULONG aId);
     1108    HRESULT removeCPUIDLeaf(ULONG aIdx, ULONG aSubIdx);
    11031109    HRESULT removeAllCPUIDLeaves();
    11041110    HRESULT getHWVirtExProperty(HWVirtExPropertyType_T aProperty,
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r68870 r68938  
    922922        InsertConfigNode(pRoot, "CPUM", &pCPUM);
    923923
    924         /* cpuid leaf overrides. */
    925         static uint32_t const s_auCpuIdRanges[] =
    926         {
    927             UINT32_C(0x00000000), UINT32_C(0x0000000a),
    928             UINT32_C(0x80000000), UINT32_C(0x8000000a)
    929         };
    930         for (unsigned i = 0; i < RT_ELEMENTS(s_auCpuIdRanges); i += 2)
    931             for (uint32_t uLeaf = s_auCpuIdRanges[i]; uLeaf < s_auCpuIdRanges[i + 1]; uLeaf++)
    932             {
    933                 ULONG ulEax, ulEbx, ulEcx, ulEdx;
    934                 hrc = pMachine->GetCPUIDLeaf(uLeaf, &ulEax, &ulEbx, &ulEcx, &ulEdx);
    935                 if (SUCCEEDED(hrc))
    936                 {
    937                     PCFGMNODE pLeaf;
    938                     InsertConfigNode(pCPUM, Utf8StrFmt("HostCPUID/%RX32", uLeaf).c_str(), &pLeaf);
    939 
    940                     InsertConfigInteger(pLeaf, "eax", ulEax);
    941                     InsertConfigInteger(pLeaf, "ebx", ulEbx);
    942                     InsertConfigInteger(pLeaf, "ecx", ulEcx);
    943                     InsertConfigInteger(pLeaf, "edx", ulEdx);
    944                 }
    945                 else if (hrc != E_INVALIDARG)                                               H();
    946             }
     924        /* Host CPUID leaf overrides. */
     925        for (uint32_t iOrdinal = 0; iOrdinal < _4K; iOrdinal++)
     926        {
     927            ULONG uLeaf, uSubLeaf, uEax, uEbx, uEcx, uEdx;
     928            hrc = pMachine->GetCPUIDLeafByOrdinal(iOrdinal, &uLeaf, &uSubLeaf, &uEax, &uEbx, &uEcx, &uEdx);
     929            if (hrc == E_INVALIDARG)
     930                break;
     931            H();
     932            PCFGMNODE pLeaf;
     933            InsertConfigNode(pCPUM, Utf8StrFmt("HostCPUID/%RX32", uLeaf).c_str(), &pLeaf);
     934            /** @todo Figure out how to tell the VMM about uSubLeaf   */
     935            InsertConfigInteger(pLeaf, "eax", uEax);
     936            InsertConfigInteger(pLeaf, "ebx", uEbx);
     937            InsertConfigInteger(pLeaf, "ecx", uEcx);
     938            InsertConfigInteger(pLeaf, "edx", uEdx);
     939        }
    947940
    948941        /* We must limit CPUID count for Windows NT 4, as otherwise it stops
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r68485 r68938  
    23102310}
    23112311
    2312 HRESULT Machine::getCPUIDLeaf(ULONG aId, ULONG *aValEax, ULONG *aValEbx, ULONG *aValEcx, ULONG *aValEdx)
     2312HRESULT Machine::getCPUIDLeafByOrdinal(ULONG aOrdinal, ULONG *aIdx, ULONG *aSubIdx, ULONG *aValEax, ULONG *aValEbx,
     2313                                       ULONG *aValEcx, ULONG *aValEdx)
    23132314{
    23142315    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    2315 
    2316     switch(aId)
    2317     {
    2318         case 0x0:
    2319         case 0x1:
    2320         case 0x2:
    2321         case 0x3:
    2322         case 0x4:
    2323         case 0x5:
    2324         case 0x6:
    2325         case 0x7:
    2326         case 0x8:
    2327         case 0x9:
    2328         case 0xA:
    2329             if (mHWData->mCpuIdStdLeafs[aId].ulId != aId)
    2330                 return E_INVALIDARG;
    2331 
    2332             *aValEax = mHWData->mCpuIdStdLeafs[aId].ulEax;
    2333             *aValEbx = mHWData->mCpuIdStdLeafs[aId].ulEbx;
    2334             *aValEcx = mHWData->mCpuIdStdLeafs[aId].ulEcx;
    2335             *aValEdx = mHWData->mCpuIdStdLeafs[aId].ulEdx;
    2336             break;
    2337 
    2338         case 0x80000000:
    2339         case 0x80000001:
    2340         case 0x80000002:
    2341         case 0x80000003:
    2342         case 0x80000004:
    2343         case 0x80000005:
    2344         case 0x80000006:
    2345         case 0x80000007:
    2346         case 0x80000008:
    2347         case 0x80000009:
    2348         case 0x8000000A:
    2349             if (mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulId != aId)
    2350                 return E_INVALIDARG;
    2351 
    2352             *aValEax = mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEax;
    2353             *aValEbx = mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEbx;
    2354             *aValEcx = mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEcx;
    2355             *aValEdx = mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEdx;
    2356             break;
    2357 
    2358         default:
    2359             return setError(E_INVALIDARG, tr("CpuId override leaf %#x is out of range"), aId);
    2360     }
    2361     return S_OK;
    2362 }
    2363 
    2364 
    2365 HRESULT Machine::setCPUIDLeaf(ULONG aId, ULONG aValEax, ULONG aValEbx, ULONG aValEcx, ULONG aValEdx)
    2366 {
     2316    if (aOrdinal < mHWData->mCpuIdLeafList.size())
     2317    {
     2318        for (settings::CpuIdLeafsList::const_iterator it = mHWData->mCpuIdLeafList.begin();
     2319             it != mHWData->mCpuIdLeafList.end();
     2320             ++it)
     2321        {
     2322            if (aOrdinal == 0)
     2323            {
     2324                const settings::CpuIdLeaf &rLeaf= *it;
     2325                *aIdx    = rLeaf.idx;
     2326                *aSubIdx = rLeaf.idxSub;
     2327                *aValEax = rLeaf.uEax;
     2328                *aValEbx = rLeaf.uEbx;
     2329                *aValEcx = rLeaf.uEcx;
     2330                *aValEdx = rLeaf.uEdx;
     2331                return S_OK;
     2332            }
     2333            aOrdinal--;
     2334        }
     2335    }
     2336    return E_INVALIDARG;
     2337}
     2338
     2339HRESULT Machine::getCPUIDLeaf(ULONG aIdx, ULONG aSubIdx, ULONG *aValEax, ULONG *aValEbx, ULONG *aValEcx, ULONG *aValEdx)
     2340{
     2341    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     2342
     2343    /*
     2344     * Search the list.
     2345     */
     2346    for (settings::CpuIdLeafsList::const_iterator it = mHWData->mCpuIdLeafList.begin(); it != mHWData->mCpuIdLeafList.end(); ++it)
     2347    {
     2348        const settings::CpuIdLeaf &rLeaf= *it;
     2349        if (   rLeaf.idx == aIdx
     2350            && (   aSubIdx == UINT32_MAX
     2351                || rLeaf.idxSub == aSubIdx) )
     2352        {
     2353            *aValEax = rLeaf.uEax;
     2354            *aValEbx = rLeaf.uEbx;
     2355            *aValEcx = rLeaf.uEcx;
     2356            *aValEdx = rLeaf.uEdx;
     2357            return S_OK;
     2358        }
     2359    }
     2360
     2361    return E_INVALIDARG;
     2362}
     2363
     2364
     2365HRESULT Machine::setCPUIDLeaf(ULONG aIdx, ULONG aSubIdx, ULONG aValEax, ULONG aValEbx, ULONG aValEcx, ULONG aValEdx)
     2366{
     2367    /*
     2368     * Validate input before taking locks and checking state.
     2369     */
     2370    if (aSubIdx != 0 && aSubIdx != UINT32_MAX)
     2371        return setError(E_INVALIDARG, tr("Currently only aSubIdx values 0 and 0xffffffff are supported: %#x"), aSubIdx);
     2372    if (   aIdx >= UINT32_C(0x20)
     2373        && aIdx - UINT32_C(0x80000000) >= UINT32_C(0x20)
     2374        && aIdx - UINT32_C(0xc0000000) >= UINT32_C(0x10) )
     2375        return setError(E_INVALIDARG, tr("CpuId override leaf %#x is out of range"), aIdx);
     2376
    23672377    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    2368 
    23692378    HRESULT rc = i_checkStateDependency(MutableStateDep);
    23702379    if (FAILED(rc)) return rc;
    23712380
    2372     switch(aId)
    2373     {
    2374         case 0x0:
    2375         case 0x1:
    2376         case 0x2:
    2377         case 0x3:
    2378         case 0x4:
    2379         case 0x5:
    2380         case 0x6:
    2381         case 0x7:
    2382         case 0x8:
    2383         case 0x9:
    2384         case 0xA:
    2385             AssertCompile(RT_ELEMENTS(mHWData->mCpuIdStdLeafs) == 0xB);
    2386             AssertRelease(aId < RT_ELEMENTS(mHWData->mCpuIdStdLeafs));
    2387             i_setModified(IsModified_MachineData);
    2388             mHWData.backup();
    2389             mHWData->mCpuIdStdLeafs[aId].ulId  = aId;
    2390             mHWData->mCpuIdStdLeafs[aId].ulEax = aValEax;
    2391             mHWData->mCpuIdStdLeafs[aId].ulEbx = aValEbx;
    2392             mHWData->mCpuIdStdLeafs[aId].ulEcx = aValEcx;
    2393             mHWData->mCpuIdStdLeafs[aId].ulEdx = aValEdx;
    2394             break;
    2395 
    2396         case 0x80000000:
    2397         case 0x80000001:
    2398         case 0x80000002:
    2399         case 0x80000003:
    2400         case 0x80000004:
    2401         case 0x80000005:
    2402         case 0x80000006:
    2403         case 0x80000007:
    2404         case 0x80000008:
    2405         case 0x80000009:
    2406         case 0x8000000A:
    2407             AssertCompile(RT_ELEMENTS(mHWData->mCpuIdExtLeafs) == 0xB);
    2408             AssertRelease(aId - 0x80000000 < RT_ELEMENTS(mHWData->mCpuIdExtLeafs));
    2409             i_setModified(IsModified_MachineData);
    2410             mHWData.backup();
    2411             mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulId  = aId;
    2412             mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEax = aValEax;
    2413             mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEbx = aValEbx;
    2414             mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEcx = aValEcx;
    2415             mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulEdx = aValEdx;
    2416             break;
    2417 
    2418         default:
    2419             return setError(E_INVALIDARG, tr("CpuId override leaf %#x is out of range"), aId);
    2420     }
    2421     return S_OK;
    2422 }
    2423 
    2424 HRESULT Machine::removeCPUIDLeaf(ULONG aId)
     2381    /*
     2382     * Impose a maximum number of leaves.
     2383     */
     2384    if (mHWData->mCpuIdLeafList.size() > 256)
     2385        return setError(E_FAIL, tr("Max of 256 CPUID override leaves reached"));
     2386
     2387    /*
     2388     * Updating the list is a bit more complicated.  So, let's do a remove first followed by an insert.
     2389     */
     2390    i_setModified(IsModified_MachineData);
     2391    mHWData.backup();
     2392
     2393    for (settings::CpuIdLeafsList::iterator it = mHWData->mCpuIdLeafList.begin(); it != mHWData->mCpuIdLeafList.end(); )
     2394    {
     2395        settings::CpuIdLeaf &rLeaf= *it;
     2396        if (   rLeaf.idx == aIdx
     2397            && (   aSubIdx == UINT32_MAX
     2398                || rLeaf.idxSub == aSubIdx) )
     2399            it = mHWData->mCpuIdLeafList.erase(it);
     2400        else
     2401            ++it;
     2402    }
     2403
     2404    settings::CpuIdLeaf NewLeaf;
     2405    NewLeaf.idx    = aIdx;
     2406    NewLeaf.idxSub = aSubIdx == UINT32_MAX ? 0 : aSubIdx;
     2407    NewLeaf.uEax   = aValEax;
     2408    NewLeaf.uEbx   = aValEbx;
     2409    NewLeaf.uEcx   = aValEcx;
     2410    NewLeaf.uEdx   = aValEdx;
     2411    mHWData->mCpuIdLeafList.push_back(NewLeaf);
     2412    return S_OK;
     2413}
     2414
     2415HRESULT Machine::removeCPUIDLeaf(ULONG aIdx, ULONG aSubIdx)
    24252416{
    24262417    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    24292420    if (FAILED(rc)) return rc;
    24302421
    2431     switch(aId)
    2432     {
    2433         case 0x0:
    2434         case 0x1:
    2435         case 0x2:
    2436         case 0x3:
    2437         case 0x4:
    2438         case 0x5:
    2439         case 0x6:
    2440         case 0x7:
    2441         case 0x8:
    2442         case 0x9:
    2443         case 0xA:
    2444             AssertCompile(RT_ELEMENTS(mHWData->mCpuIdStdLeafs) == 0xB);
    2445             AssertRelease(aId < RT_ELEMENTS(mHWData->mCpuIdStdLeafs));
    2446             i_setModified(IsModified_MachineData);
    2447             mHWData.backup();
    2448             /* Invalidate leaf. */
    2449             mHWData->mCpuIdStdLeafs[aId].ulId = UINT32_MAX;
    2450             break;
    2451 
    2452         case 0x80000000:
    2453         case 0x80000001:
    2454         case 0x80000002:
    2455         case 0x80000003:
    2456         case 0x80000004:
    2457         case 0x80000005:
    2458         case 0x80000006:
    2459         case 0x80000007:
    2460         case 0x80000008:
    2461         case 0x80000009:
    2462         case 0x8000000A:
    2463             AssertCompile(RT_ELEMENTS(mHWData->mCpuIdExtLeafs) == 0xB);
    2464             AssertRelease(aId - 0x80000000 < RT_ELEMENTS(mHWData->mCpuIdExtLeafs));
    2465             i_setModified(IsModified_MachineData);
    2466             mHWData.backup();
    2467             /* Invalidate leaf. */
    2468             mHWData->mCpuIdExtLeafs[aId - 0x80000000].ulId = UINT32_MAX;
    2469             break;
    2470 
    2471         default:
    2472             return setError(E_INVALIDARG, tr("CpuId override leaf %#x is out of range"), aId);
    2473     }
     2422    /*
     2423     * Do the removal.
     2424     */
     2425    bool fModified = false;
     2426    for (settings::CpuIdLeafsList::iterator it = mHWData->mCpuIdLeafList.begin(); it != mHWData->mCpuIdLeafList.end(); )
     2427    {
     2428        settings::CpuIdLeaf &rLeaf= *it;
     2429        if (   rLeaf.idx == aIdx
     2430            && (   aSubIdx == UINT32_MAX
     2431                || rLeaf.idxSub == aSubIdx) )
     2432        {
     2433            if (!fModified)
     2434            {
     2435                fModified = true;
     2436                i_setModified(IsModified_MachineData);
     2437                mHWData.backup();
     2438            }
     2439            it = mHWData->mCpuIdLeafList.erase(it);
     2440        }
     2441        else
     2442            ++it;
     2443    }
     2444
    24742445    return S_OK;
    24752446}
     
    24822453    if (FAILED(rc)) return rc;
    24832454
    2484     i_setModified(IsModified_MachineData);
    2485     mHWData.backup();
    2486 
    2487     /* Invalidate all standard leafs. */
    2488     for (unsigned i = 0; i < RT_ELEMENTS(mHWData->mCpuIdStdLeafs); ++i)
    2489         mHWData->mCpuIdStdLeafs[i].ulId = UINT32_MAX;
    2490 
    2491     /* Invalidate all extended leafs. */
    2492     for (unsigned i = 0; i < RT_ELEMENTS(mHWData->mCpuIdExtLeafs); ++i)
    2493         mHWData->mCpuIdExtLeafs[i].ulId = UINT32_MAX;
     2455    if (mHWData->mCpuIdLeafList.size() > 0)
     2456    {
     2457        i_setModified(IsModified_MachineData);
     2458        mHWData.backup();
     2459
     2460        mHWData->mCpuIdLeafList.clear();
     2461    }
    24942462
    24952463    return S_OK;
     
    89578925             ++it)
    89588926        {
    8959             const settings::CpuIdLeaf &leaf = *it;
    8960 
    8961             switch (leaf.ulId)
    8962             {
    8963             case 0x0:
    8964             case 0x1:
    8965             case 0x2:
    8966             case 0x3:
    8967             case 0x4:
    8968             case 0x5:
    8969             case 0x6:
    8970             case 0x7:
    8971             case 0x8:
    8972             case 0x9:
    8973             case 0xA:
    8974                 mHWData->mCpuIdStdLeafs[leaf.ulId] = leaf;
    8975                 break;
    8976 
    8977             case 0x80000000:
    8978             case 0x80000001:
    8979             case 0x80000002:
    8980             case 0x80000003:
    8981             case 0x80000004:
    8982             case 0x80000005:
    8983             case 0x80000006:
    8984             case 0x80000007:
    8985             case 0x80000008:
    8986             case 0x80000009:
    8987             case 0x8000000A:
    8988                 mHWData->mCpuIdExtLeafs[leaf.ulId - 0x80000000] = leaf;
    8989                 break;
    8990 
    8991             default:
    8992                 /* just ignore */
    8993                 break;
    8994             }
     8927            const settings::CpuIdLeaf &rLeaf= *it;
     8928            if (   rLeaf.idx < UINT32_C(0x20)
     8929                || rLeaf.idx - UINT32_C(0x80000000) < UINT32_C(0x20)
     8930                || rLeaf.idx - UINT32_C(0xc0000000) < UINT32_C(0x10) )
     8931                mHWData->mCpuIdLeafList.push_back(rLeaf);
     8932            /* else: just ignore */
    89958933        }
    89968934
     
    1030510243        /* Standard and Extended CPUID leafs. */
    1030610244        data.llCpuIdLeafs.clear();
    10307         for (unsigned idx = 0; idx < RT_ELEMENTS(mHWData->mCpuIdStdLeafs); ++idx)
    10308             if (mHWData->mCpuIdStdLeafs[idx].ulId != UINT32_MAX)
    10309                 data.llCpuIdLeafs.push_back(mHWData->mCpuIdStdLeafs[idx]);
    10310         for (unsigned idx = 0; idx < RT_ELEMENTS(mHWData->mCpuIdExtLeafs); ++idx)
    10311             if (mHWData->mCpuIdExtLeafs[idx].ulId != UINT32_MAX)
    10312                 data.llCpuIdLeafs.push_back(mHWData->mCpuIdExtLeafs[idx]);
     10245        data.llCpuIdLeafs = mHWData->mCpuIdLeafList;
    1031310246
    1031410247        // memory
  • trunk/src/VBox/Main/xml/Settings.cpp

    r68905 r68938  
    26352635 */
    26362636CpuIdLeaf::CpuIdLeaf() :
    2637     ulId(UINT32_MAX),
    2638     ulEax(0),
    2639     ulEbx(0),
    2640     ulEcx(0),
    2641     ulEdx(0)
     2637    idx(UINT32_MAX),
     2638    idxSub(0),
     2639    uEax(0),
     2640    uEbx(0),
     2641    uEcx(0),
     2642    uEdx(0)
    26422643{
    26432644}
     
    26512652{
    26522653    return (this == &c)
    2653         || (   ulId      == c.ulId
    2654             && ulEax     == c.ulEax
    2655             && ulEbx     == c.ulEbx
    2656             && ulEcx     == c.ulEcx
    2657             && ulEdx     == c.ulEdx);
     2654        || (   idx      == c.idx
     2655            && idxSub   == c.idxSub
     2656            && uEax     == c.uEax
     2657            && uEbx     == c.uEbx
     2658            && uEcx     == c.uEcx
     2659            && uEdx     == c.uEdx);
    26582660}
    26592661
     
    33483350        CpuIdLeaf leaf;
    33493351
    3350         if (!pelmCpuIdLeaf->getAttributeValue("id", leaf.ulId))
     3352        if (!pelmCpuIdLeaf->getAttributeValue("id", leaf.idx))
    33513353            throw ConfigFileError(this, pelmCpuIdLeaf, N_("Required CpuId/@id attribute is missing"));
    33523354
    3353         pelmCpuIdLeaf->getAttributeValue("eax", leaf.ulEax);
    3354         pelmCpuIdLeaf->getAttributeValue("ebx", leaf.ulEbx);
    3355         pelmCpuIdLeaf->getAttributeValue("ecx", leaf.ulEcx);
    3356         pelmCpuIdLeaf->getAttributeValue("edx", leaf.ulEdx);
     3355        if (!pelmCpuIdLeaf->getAttributeValue("subleaf", leaf.idxSub))
     3356            leaf.idxSub = 0;
     3357        pelmCpuIdLeaf->getAttributeValue("eax", leaf.uEax);
     3358        pelmCpuIdLeaf->getAttributeValue("ebx", leaf.uEbx);
     3359        pelmCpuIdLeaf->getAttributeValue("ecx", leaf.uEcx);
     3360        pelmCpuIdLeaf->getAttributeValue("edx", leaf.uEdx);
    33573361
    33583362        ll.push_back(leaf);
     
    53175321
    53185322        xml::ElementNode *pelmCpuIdLeaf = pelmCpuIdTree->createChild("CpuIdLeaf");
    5319         pelmCpuIdLeaf->setAttribute("id",  leaf.ulId);
    5320         pelmCpuIdLeaf->setAttribute("eax", leaf.ulEax);
    5321         pelmCpuIdLeaf->setAttribute("ebx", leaf.ulEbx);
    5322         pelmCpuIdLeaf->setAttribute("ecx", leaf.ulEcx);
    5323         pelmCpuIdLeaf->setAttribute("edx", leaf.ulEdx);
     5323        pelmCpuIdLeaf->setAttribute("id",  leaf.idx);
     5324        if (leaf.idxSub != 0)
     5325            pelmCpuIdLeaf->setAttribute("subleaf",  leaf.idxSub);
     5326        pelmCpuIdLeaf->setAttribute("eax", leaf.uEax);
     5327        pelmCpuIdLeaf->setAttribute("ebx", leaf.uEbx);
     5328        pelmCpuIdLeaf->setAttribute("ecx", leaf.uEcx);
     5329        pelmCpuIdLeaf->setAttribute("edx", leaf.uEdx);
    53245330    }
    53255331
     
    69376943            }
    69386944        }
     6945
     6946        for (CpuIdLeafsList::const_iterator it = hardwareMachine.llCpuIdLeafs.begin();
     6947             it != hardwareMachine.llCpuIdLeafs.end();
     6948             ++it)
     6949            if (it->idxSub != 0)
     6950            {
     6951                m->sv = SettingsVersion_v1_16;
     6952                return;
     6953            }
    69396954    }
    69406955
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