VirtualBox

Changeset 64808 in vbox


Ignore:
Timestamp:
Dec 8, 2016 12:08:01 PM (8 years ago)
Author:
vboxsync
Message:

LsiLogic: Protect the request queue and writes to the reply free queue against concurrent access from the guest when using multiple vCPUs, should fix task aborts observed with Linux kernels starting from at least 3.18 (maybe even earlier, last known godd kernel is 3.14)

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r64766 r64808  
    287287    /** Critical section protecting the reply free queue. */
    288288    PDMCRITSECT           ReplyFreeQueueCritSect;
     289    /** Critical section protecting the request queue against
     290     * concurrent access from the guest. */
     291    PDMCRITSECT           RequestQueueCritSect;
     292    /** Critical section protecting the reply free queue against
     293     * concurrent write access from the guest. */
     294    PDMCRITSECT           ReplyFreeQueueWriteCritSect;
    289295
    290296    /** Pointer to the start of the reply free queue - R3. */
     
    12761282        case LSILOGIC_REG_REPLY_QUEUE:
    12771283        {
     1284            int rc = PDMCritSectEnter(&pThis->ReplyFreeQueueWriteCritSect, VINF_IOM_R3_MMIO_WRITE);
     1285            if (rc != VINF_SUCCESS)
     1286                return rc;
    12781287            /* Add the entry to the reply free queue. */
    12791288            ASMAtomicWriteU32(&pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextEntryFreeWrite], u32);
    12801289            pThis->uReplyFreeQueueNextEntryFreeWrite++;
    12811290            pThis->uReplyFreeQueueNextEntryFreeWrite %= pThis->cReplyQueueEntries;
     1291            PDMCritSectLeave(&pThis->ReplyFreeQueueWriteCritSect);
    12821292            break;
    12831293        }
    12841294        case LSILOGIC_REG_REQUEST_QUEUE:
    12851295        {
     1296            int rc = PDMCritSectEnter(&pThis->RequestQueueCritSect, VINF_IOM_R3_MMIO_WRITE);
     1297            if (rc != VINF_SUCCESS)
     1298                return rc;
     1299
    12861300            uint32_t uNextWrite = ASMAtomicReadU32(&pThis->uRequestQueueNextEntryFreeWrite);
    12871301
     
    12971311            uNextWrite %= pThis->cRequestQueueEntries;
    12981312            ASMAtomicWriteU32(&pThis->uRequestQueueNextEntryFreeWrite, uNextWrite);
     1313            PDMCritSectLeave(&pThis->RequestQueueCritSect);
    12991314
    13001315            /* Send notification to R3 if there is not one sent already. Do this
     
    13101325#else
    13111326                    LogFlowFunc(("Signal event semaphore\n"));
    1312                     int rc = SUPSemEventSignal(pThis->pSupDrvSession, pThis->hEvtProcess);
     1327                    rc = SUPSemEventSignal(pThis->pSupDrvSession, pThis->hEvtProcess);
    13131328                    AssertRC(rc);
    13141329#endif
     
    53055320    PDMR3CritSectDelete(&pThis->ReplyFreeQueueCritSect);
    53065321    PDMR3CritSectDelete(&pThis->ReplyPostQueueCritSect);
     5322    PDMR3CritSectDelete(&pThis->RequestQueueCritSect);
     5323    PDMR3CritSectDelete(&pThis->ReplyFreeQueueWriteCritSect);
    53075324
    53085325    RTMemFree(pThis->paDeviceStates);
     
    54705487    if (RT_FAILURE(rc))
    54715488        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for reply post queue"));
     5489
     5490    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->RequestQueueCritSect, RT_SRC_POS, "%sRQ", szDevTag);
     5491    if (RT_FAILURE(rc))
     5492        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for request queue"));
     5493
     5494    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->ReplyFreeQueueWriteCritSect, RT_SRC_POS, "%sRFQW", szDevTag);
     5495    if (RT_FAILURE(rc))
     5496        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for reply free queue write access"));
    54725497
    54735498    /*
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r64800 r64808  
    17451745    GEN_CHECK_OFF(LSILOGICSCSI, ReplyPostQueueCritSect);
    17461746    GEN_CHECK_OFF(LSILOGICSCSI, ReplyFreeQueueCritSect);
     1747    GEN_CHECK_OFF(LSILOGICSCSI, RequestQueueCritSect);
     1748    GEN_CHECK_OFF(LSILOGICSCSI, ReplyFreeQueueWriteCritSect);
    17471749    GEN_CHECK_OFF(LSILOGICSCSI, pReplyFreeQueueBaseR3);
    17481750    GEN_CHECK_OFF(LSILOGICSCSI, pReplyPostQueueBaseR3);
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