VirtualBox

Changeset 37443 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 14, 2011 2:34:11 PM (14 years ago)
Author:
vboxsync
Message:

PDM: Implemented the NOP critical section.

Location:
trunk/src/VBox/VMM
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IOMAll.cpp

    r37424 r37443  
    262262VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
    263263{
     264/** @todo should initialize *pu32Value here because it can happen that some
     265 *        handle is buggy and doesn't handle all cases. */
    264266    /* Take the IOM lock before performing any device I/O. */
    265267    int rc2 = iomLock(pVM);
  • trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp

    r37419 r37443  
    487487    AssertMsg(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, ("%p %RX32\n", pCritSect, pCritSect->s.Core.u32Magic));
    488488    Assert(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC);
     489
     490    /* Check for NOP sections before asserting ownership. */
     491    if (pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)
     492        return;
     493
    489494    Assert(pCritSect->s.Core.NativeThreadOwner == pdmCritSectGetNativeSelf(pCritSect));
    490495    Assert(pCritSect->s.Core.cNestings >= 1);
    491 
    492     /*
    493      * Check for NOP sections.
    494      */
    495     if (pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NOP)
    496         return;
    497496
    498497    /*
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r36041 r37443  
    353353    AssertRelease(sizeof(pVM->pdm.s) <= sizeof(pVM->pdm.padding));
    354354    AssertCompileMemberAlignment(PDM, CritSect, sizeof(uintptr_t));
     355
    355356    /*
    356357     * Init the structure.
    357358     */
    358     pVM->pdm.s.offVM = RT_OFFSETOF(VM, pdm.s);
    359359    pVM->pdm.s.GCPhysVMMDevHeap = NIL_RTGCPHYS;
    360360
    361361    /*
    362      * Initialize sub components.
     362     * Initialize critical sections first.
    363363     */
    364364    int rc = pdmR3CritSectInitStats(pVM);
    365365    if (RT_SUCCESS(rc))
    366366        rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.CritSect, RT_SRC_POS, "PDM");
     367    if (RT_SUCCESS(rc))
     368        rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.GiantDevCritSect, RT_SRC_POS, "Giant PDM Dev");
     369    if (RT_SUCCESS(rc))
     370    {
     371        rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.NopCritSect, RT_SRC_POS, "NOP");
     372        if (RT_SUCCESS(rc))
     373            pVM->pdm.s.NopCritSect.s.Core.fFlags |= RTCRITSECT_FLAGS_NOP;
     374    }
     375
     376    /*
     377     * Initialize sub components.
     378     */
    367379    if (RT_SUCCESS(rc))
    368380        rc = pdmR3LdrInitU(pVM->pUVM);
     
    587599{
    588600    LogFlow(("PDMR3Term:\n"));
    589     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
     601    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
    590602
    591603    /*
  • trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp

    r37419 r37443  
    622622 * Leave all critical sections the calling thread owns.
    623623 *
     624 * This is only used when entering guru meditation in order to prevent other
     625 * EMTs and I/O threads from deadlocking.
     626 *
    624627 * @param   pVM         The VM handle.
    625628 */
    626 void PDMR3CritSectLeaveAll(PVM pVM)
     629VMMR3DECL(void) PDMR3CritSectLeaveAll(PVM pVM)
    627630{
    628631    RTNATIVETHREAD const hNativeSelf = RTThreadNativeSelf();
     
    641644}
    642645
     646
     647/**
     648 * Gets the address of the NOP critical section.
     649 *
     650 * The NOP critical section will not perform any thread serialization but let
     651 * all enter immediately and concurrently.
     652 *
     653 * @returns The address of the NOP critical section.
     654 * @param   pVM                 The VM handle.
     655 */
     656VMMR3DECL(PPDMCRITSECT)             PDMR3CritSectGetNop(PVM pVM)
     657{
     658    VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
     659    return &pVM->pdm.s.NopCritSect;
     660}
     661
     662
     663/**
     664 * Gets the ring-0 address of the NOP critical section.
     665 *
     666 * @returns The ring-0 address of the NOP critical section.
     667 * @param   pVM                 The VM handle.
     668 */
     669VMMR3DECL(R0PTRTYPE(PPDMCRITSECT))  PDMR3CritSectGetNopR0(PVM pVM)
     670{
     671    VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTR0PTR);
     672    return MMHyperR3ToR0(pVM, &pVM->pdm.s.NopCritSect);
     673}
     674
     675
     676/**
     677 * Gets the raw-mode context address of the NOP critical section.
     678 *
     679 * @returns The raw-mode context address of the NOP critical section.
     680 * @param   pVM                 The VM handle.
     681 */
     682VMMR3DECL(RCPTRTYPE(PPDMCRITSECT))  PDMR3CritSectGetNopRC(PVM pVM)
     683{
     684    VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTRCPTR);
     685    return MMHyperR3ToRC(pVM, &pVM->pdm.s.NopCritSect);
     686}
     687
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r37410 r37443  
    15411541    LogFlow(("pdmR3DevHlp_CritSectInit: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    15421542    return rc;
     1543}
     1544
     1545
     1546/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNop} */
     1547static DECLCALLBACK(PPDMCRITSECT) pdmR3DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
     1548{
     1549    PDMDEV_ASSERT_DEVINS(pDevIns);
     1550    PVM pVM = pDevIns->Internal.s.pVMR3;
     1551    VM_ASSERT_EMT(pVM);
     1552
     1553    PPDMCRITSECT pCritSect = PDMR3CritSectGetNop(pVM);
     1554    LogFlow(("pdmR3DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n",
     1555             pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
     1556    return pCritSect;
     1557}
     1558
     1559
     1560/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNopR0} */
     1561static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3DevHlp_CritSectGetNopR0(PPDMDEVINS pDevIns)
     1562{
     1563    PDMDEV_ASSERT_DEVINS(pDevIns);
     1564    PVM pVM = pDevIns->Internal.s.pVMR3;
     1565    VM_ASSERT_EMT(pVM);
     1566
     1567    R0PTRTYPE(PPDMCRITSECT) pCritSect = PDMR3CritSectGetNopR0(pVM);
     1568    LogFlow(("pdmR3DevHlp_CritSectGetNopR0: caller='%s'/%d: return %RHv\n",
     1569             pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
     1570    return pCritSect;
     1571}
     1572
     1573
     1574/** @interface_method_impl{PDMDEVHLPR3,pfnCritSectGetNopRC} */
     1575static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3DevHlp_CritSectGetNopRC(PPDMDEVINS pDevIns)
     1576{
     1577    PDMDEV_ASSERT_DEVINS(pDevIns);
     1578    PVM pVM = pDevIns->Internal.s.pVMR3;
     1579    VM_ASSERT_EMT(pVM);
     1580
     1581    RCPTRTYPE(PPDMCRITSECT) pCritSect = PDMR3CritSectGetNopRC(pVM);
     1582    LogFlow(("pdmR3DevHlp_CritSectGetNopRC: caller='%s'/%d: return %RRv\n",
     1583             pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
     1584    return pCritSect;
    15431585}
    15441586
     
    32183260    pdmR3DevHlp_QueueCreate,
    32193261    pdmR3DevHlp_CritSectInit,
     3262    pdmR3DevHlp_CritSectGetNop,
     3263    pdmR3DevHlp_CritSectGetNopR0,
     3264    pdmR3DevHlp_CritSectGetNopRC,
    32203265    pdmR3DevHlp_ThreadCreate,
    32213266    pdmR3DevHlp_SetAsyncNotification,
     
    34303475    pdmR3DevHlp_QueueCreate,
    34313476    pdmR3DevHlp_CritSectInit,
     3477    pdmR3DevHlp_CritSectGetNop,
     3478    pdmR3DevHlp_CritSectGetNopR0,
     3479    pdmR3DevHlp_CritSectGetNopRC,
    34323480    pdmR3DevHlp_ThreadCreate,
    34333481    pdmR3DevHlp_SetAsyncNotification,
  • trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp

    r35346 r37443  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2011 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    247247     * Validate input.
    248248     */
    249     AssertMsg(pUVM->pVM->pdm.s.offVM, ("bad init order!\n"));
     249    AssertMsg(PDMCritSectIsInitialized(&pUVM->pVM->pdm.s.CritSect), ("bad init order!\n"));
    250250    Assert(pszFilename);
    251251    size_t cchFilename = strlen(pszFilename);
     
    441441     * Validate input.
    442442     */
    443     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
     443    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
    444444    PUVM     pUVM = pVM->pUVM;
    445445    RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
     
    692692     * Validate input.
    693693     */
    694     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
     694    AssertPtr(pVM);
     695    AssertPtr(pszModule);
     696    AssertPtr(ppvValue);
     697    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
    695698
    696699    /*
     
    748751     * Validate input.
    749752     */
    750     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
     753    AssertPtr(pVM);
     754    AssertPtrNull(pszModule);
     755    AssertPtr(ppvValue);
     756    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
     757
    751758    if (!pszModule)
    752759        pszModule = "VMMR0.r0";
     
    800807
    801808#else
     809    AssertPtr(pVM);
     810    AssertPtrNull(pszModule);
     811    AssertPtr(ppvValue);
     812    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
     813
    802814    /*
    803815     * Since we're lazy, we'll only check if the module is present
    804816     * and hand it over to PDMR3LdrGetSymbolR0 when that's done.
    805817     */
    806     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
    807818    if (pszModule)
    808819    {
     
    847858     * Validate input.
    848859     */
    849     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
     860    AssertPtr(pVM);
     861    AssertPtrNull(pszModule);
     862    AssertPtr(pRCPtrValue);
     863    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
     864
    850865    if (!pszModule)
    851866        pszModule = "VMMGC.gc";
     
    907922
    908923#else
     924    AssertPtr(pVM);
     925    AssertPtrNull(pszModule);
     926    AssertPtr(pRCPtrValue);
     927    AssertMsg(PDMCritSectIsInitialized(&pVM->pdm.s.CritSect), ("bad init order!\n"));
     928
    909929    /*
    910930     * Since we're lazy, we'll only check if the module is present
    911931     * and hand it over to PDMR3LdrGetSymbolRC when that's done.
    912932     */
    913     AssertMsg(pVM->pdm.s.offVM, ("bad init order!\n"));
    914933    if (pszModule)
    915934    {
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r36818 r37443  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2011 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    940940} PDMCPU;
    941941
    942 /**
    943  * Converts a PDM pointer into a VM pointer.
    944  * @returns Pointer to the VM structure the PDM is part of.
    945  * @param   pPDM   Pointer to PDM instance data.
    946  */
    947 #define PDM2VM(pPDM)  ( (PVM)((char*)pPDM - pPDM->offVM) )
    948 
    949942
    950943/**
     
    954947typedef struct PDM
    955948{
    956     /** Offset to the VM structure.
    957      * See PDM2VM(). */
    958     RTUINT                          offVM;
    959     RTUINT                          uPadding0; /**< Alignment padding.*/
     949    /** The PDM lock.
     950     * This is used to protect everything that deals with interrupts, i.e.
     951     * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
     952    PDMCRITSECT                     CritSect;
     953
     954    /** The giant PDM device lock.
     955     * This is a temporary measure and will be removed. */
     956    PDMCRITSECT                     GiantDevCritSect;
     957
     958    /** The NOP critical section.
     959     * This is a dummy critical section that will not do any thread
     960     * serialization but instead let all threads enter immediately and
     961     * concurrently. */
     962    PDMCRITSECT                     NopCritSect;
    960963
    961964    /** List of registered devices. (FIFO) */
     
    10141017    /** @} */
    10151018
    1016     /** The PDM lock.
    1017      * This is used to protect everything that deals with interrupts, i.e.
    1018      * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
    1019     PDMCRITSECT                     CritSect;
    1020 
    10211019    /** Number of times a critical section leave request needed to be queued for ring-3 execution. */
    10221020    STAMCOUNTER                     StatQueuedCritSectLeaves;
  • trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp

    r37441 r37443  
    290290
    291291    GEN_CHECK_SIZE(PDM);
    292     GEN_CHECK_OFF(PDM, offVM);
     292    GEN_CHECK_OFF(PDM, CritSect);
     293    GEN_CHECK_OFF(PDM, GiantDevCritSect);
     294    GEN_CHECK_OFF(PDM, NopCritSect);
    293295    GEN_CHECK_OFF(PDM, pDevs);
    294296    GEN_CHECK_OFF(PDM, pDevInstances);
     
    364366    GEN_CHECK_OFF(PDM, pQueueFlushR0);
    365367    GEN_CHECK_OFF(PDM, pQueueFlushRC);
    366     GEN_CHECK_OFF(PDM, CritSect);
    367368    GEN_CHECK_OFF(PDM, StatQueuedCritSectLeaves);
    368369
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