VirtualBox

Changeset 36234 in vbox


Ignore:
Timestamp:
Mar 9, 2011 5:19:20 PM (14 years ago)
Author:
vboxsync
Message:

CPUMR0.cpp: Stay within the bounds of g_aLApics; safely bail out of RTR0MemObjMapKernel errors. (untested)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r35346 r36234  
    4545    RTR0MEMOBJ  hMemObj;
    4646    RTR0MEMOBJ  hMapObj;
    47     void        *pv;
     47    void       *pv;
    4848    uint32_t    fHasThermal;
    4949} CPUMHOSTLAPIC;
     
    646646static void cpumR0MapLocalApicWorker(RTCPUID idCpu, void *pvUser1, void *pvUser2)
    647647{
    648     uint32_t u32MaxIdx;
    649     uint32_t u32EBX, u32ECX, u32EDX;
    650648    int iCpu = RTMpCpuIdToSetIndex(idCpu);
    651     Assert(iCpu < RTCPUSET_MAX_CPUS);
     649    AssertReturnVoid(iCpu >= 0 && (unsigned)iCpu < RT_ELEMENTS(g_aLApics));
     650
     651    uint32_t u32MaxIdx, u32EBX, u32ECX, u32EDX;
    652652    ASMCpuId(0, &u32MaxIdx, &u32EBX, &u32ECX, &u32EDX);
    653653    if (   (   (   u32EBX == X86_CPUID_VENDOR_INTEL_EBX
     
    664664        {
    665665            uint64_t u64ApicBase = ASMRdMsr(MSR_IA32_APICBASE);
     666            uint64_t u64Mask     = UINT64_C(0x0000000ffffff000);
     667
     668            /* see Intel Manual: Local APIC Status and Location: MAXPHYADDR default is bit 36 */
    666669            uint32_t u32MaxExtIdx;
    667             /* see Intel Manual: Local APIC Status and Location: MAXPHYADDR default is bit 36 */
    668             uint64_t u64Mask = UINT64_C(0x0000000ffffff000);
    669670            ASMCpuId(0x80000000, &u32MaxExtIdx, &u32EBX, &u32ECX, &u32EDX);
    670671            if (   u32MaxExtIdx >= 0x80000008
     
    676677                u64Mask = ((UINT64_C(1) << u32PhysBits) - 1) & UINT64_C(0xfffffffffffff000);
    677678            }
     679
    678680            g_aLApics[iCpu].fEnabled = true;
    679681            g_aLApics[iCpu].PhysBase = u64ApicBase & u64Mask;
     
    688690static int cpumR0MapLocalApics(void)
    689691{
     692    /*
     693     * Check that we'll always stay within the array bounds.
     694     */
     695    if (RTMpGetArraySize() > RT_ELEMENTS(g_aLApics))
     696    {
     697        LogRel(("CPUM: Too many real CPUs - %u, max %u\n", RTMpGetArraySize(), RT_ELEMENTS(g_aLApics)));
     698        return VERR_TOO_MANY_CPUS;
     699    }
     700
     701    /*
     702     * Create mappings for all online CPUs we think have APICs.
     703     */
     704    /** @todo r=bird: This code is not adequately handling CPUs that are
     705     *        offline or unplugged at init time and later bought into action. */
    690706    int rc = RTMpOnAll(cpumR0MapLocalApicWorker, NULL, NULL);
     707
    691708    for (unsigned iCpu = 0; RT_SUCCESS(rc) && iCpu < RT_ELEMENTS(g_aLApics); iCpu++)
    692709    {
     
    696713                                     PAGE_SIZE, RTMEM_CACHE_POLICY_MMIO);
    697714            if (RT_SUCCESS(rc))
    698                 rc = RTR0MemObjMapKernel(&g_aLApics[iCpu].hMapObj, g_aLApics[iCpu].hMemObj, (void*)-1,
     715            {
     716                rc = RTR0MemObjMapKernel(&g_aLApics[iCpu].hMapObj, g_aLApics[iCpu].hMemObj, (void *)-1,
    699717                                         PAGE_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
    700             if (RT_SUCCESS(rc))
    701             {
    702                 void *pApicBase = RTR0MemObjAddress(g_aLApics[iCpu].hMapObj);
    703                 uint32_t ApicVersion = ApicRegRead(pApicBase, APIC_REG_VERSION);
    704                 /*
    705                  * 0x0X       82489 external APIC
    706                  * 0x1X       Local APIC
    707                  * 0x2X..0xFF reserved
    708                  */
    709                 if ((APIC_REG_VERSION_GET_VER(ApicVersion) & 0xF0) != 0x10)
     718                if (RT_SUCCESS(rc))
    710719                {
     720                    void *pvApicBase = RTR0MemObjAddress(g_aLApics[iCpu].hMapObj);
     721
     722                    /*
     723                     * 0x0X       82489 external APIC
     724                     * 0x1X       Local APIC
     725                     * 0x2X..0xFF reserved
     726                     */
     727                    uint32_t ApicVersion = ApicRegRead(pvApicBase, APIC_REG_VERSION);
     728                    if ((APIC_REG_VERSION_GET_VER(ApicVersion) & 0xF0) == 0x10)
     729                    {
     730                        g_aLApics[iCpu].fHasThermal = APIC_REG_VERSION_GET_MAX_LVT(ApicVersion) >= 5;
     731                        g_aLApics[iCpu].pv          = pvApicBase;
     732                        continue;
     733                    }
     734
    711735                    RTR0MemObjFree(g_aLApics[iCpu].hMapObj, true /* fFreeMappings */);
    712                     RTR0MemObjFree(g_aLApics[iCpu].hMemObj, true /* fFreeMappings */);
    713                     g_aLApics[iCpu].fEnabled = false;
    714                     continue;
    715736                }
    716                 g_aLApics[iCpu].fHasThermal = APIC_REG_VERSION_GET_MAX_LVT(ApicVersion) >= 5;
    717                 g_aLApics[iCpu].pv = pApicBase;
     737                RTR0MemObjFree(g_aLApics[iCpu].hMemObj, true /* fFreeMappings */);
    718738            }
     739            g_aLApics[iCpu].fEnabled = false;
    719740        }
    720741    }
     
    740761            RTR0MemObjFree(g_aLApics[iCpu].hMapObj, true /* fFreeMappings */);
    741762            RTR0MemObjFree(g_aLApics[iCpu].hMemObj, true /* fFreeMappings */);
     763            g_aLApics[iCpu].hMapObj  = NIL_RTR0MEMOBJ;
     764            g_aLApics[iCpu].hMemObj  = NIL_RTR0MEMOBJ;
    742765            g_aLApics[iCpu].fEnabled = false;
    743             g_aLApics[iCpu].pv = NULL;
     766            g_aLApics[iCpu].pv       = NULL;
    744767        }
    745768    }
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