VirtualBox

Changeset 82667 in vbox


Ignore:
Timestamp:
Jan 8, 2020 10:13:47 AM (5 years ago)
Author:
vboxsync
Message:

Devices/Storage/VBoxSCSI: Prevent multiple vCPUs from accessing the VBoxSCSI state at the same time @bugref{9632}

Location:
trunk/src/VBox/Devices/Storage
Files:
4 edited

Legend:

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

    r82179 r82667  
    11741174        buslogicR3RegisterISARange(pDevIns, pThis, pThis->uDefaultISABaseCode);
    11751175    buslogicR3InitializeLocalRam(pThis);
    1176     vboxscsiInitialize(&pThisCC->VBoxSCSI);
     1176    vboxscsiHwReset(&pThisCC->VBoxSCSI);
    11771177
    11781178    return VINF_SUCCESS;
     
    40814081    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    40824082    PBUSLOGIC pThis = PDMDEVINS_2_DATA(pDevIns, PBUSLOGIC);
     4083    PBUSLOGICCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PBUSLOGICCC);
    40834084
    40844085    PDMDevHlpCritSectDelete(pDevIns, &pThis->CritSectIntr);
     
    40894090        pThis->hEvtProcess = NIL_SUPSEMEVENT;
    40904091    }
     4092
     4093    vboxscsiDestroy(&pThisCC->VBoxSCSI);
    40914094
    40924095    return VINF_SUCCESS;
     
    42074210        AssertRCReturn(rc, rc);
    42084211    }
     4212
     4213    /* Initialize the SCSI emulation for the BIOS. */
     4214    rc = vboxscsiInitialize(&pThisCC->VBoxSCSI);
     4215    if (RT_FAILURE(rc))
     4216        return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic failed to initialize BIOS SCSI interface"));
    42094217
    42104218    if (fBootable)
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r82456 r82667  
    50805080    AssertRC(rc);
    50815081
    5082     vboxscsiInitialize(&pThisCC->VBoxSCSI);
     5082    vboxscsiHwReset(&pThisCC->VBoxSCSI);
    50835083}
    50845084
     
    51505150    lsilogicR3ConfigurationPagesFree(pThis, pThisCC);
    51515151    lsilogicR3MemRegionsFree(pThisCC);
     5152    vboxscsiDestroy(&pThisCC->VBoxSCSI);
    51525153
    51535154    return VINF_SUCCESS;
     
    54855486    /* Initialize the SCSI emulation for the BIOS. */
    54865487    rc = vboxscsiInitialize(&pThisCC->VBoxSCSI);
    5487     AssertRC(rc);
     5488    if (RT_FAILURE(rc))
     5489        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic failed to initialize BIOS SCSI interface"));
    54885490
    54895491    /*
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp

    r81773 r82667  
    7070int vboxscsiInitialize(PVBOXSCSI pVBoxSCSI)
    7171{
    72     pVBoxSCSI->pbBuf = NULL;
     72    int rc = RTCritSectInit(&pVBoxSCSI->CritSect);
     73    if (RT_SUCCESS(rc))
     74    {
     75        pVBoxSCSI->pbBuf = NULL;
     76        vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
     77    }
     78
     79    return rc;
     80}
     81
     82/**
     83 * Frees all allocated resources.
     84 *
     85 * @returns nothing.
     86 * @param   pVBoxSCSI    Pointer to the SCSI state,
     87 */
     88void vboxscsiDestroy(PVBOXSCSI pVBoxSCSI)
     89{
     90    if (RTCritSectIsInitialized(&pVBoxSCSI->CritSect))
     91        RTCritSectDelete(&pVBoxSCSI->CritSect);
     92}
     93
     94/**
     95 * Performs a hardware reset.
     96 *
     97 * @returns nothing.
     98 * @param   pVBoxSCSI    Pointer to the SCSI state,
     99 */
     100void vboxscsiHwReset(PVBOXSCSI pVBoxSCSI)
     101{
    73102    vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
    74 
    75     return VINF_SUCCESS;
    76103}
    77104
     
    88115    uint8_t uVal = 0;
    89116
     117    RTCritSectEnter(&pVBoxSCSI->CritSect);
    90118    switch (iRegister)
    91119    {
     
    138166
    139167    *pu32Value = uVal;
     168    RTCritSectLeave(&pVBoxSCSI->CritSect);
    140169
    141170    return VINF_SUCCESS;
     
    156185    int rc = VINF_SUCCESS;
    157186
     187    RTCritSectEnter(&pVBoxSCSI->CritSect);
    158188    switch (iRegister)
    159189    {
     
    270300    }
    271301
     302    RTCritSectLeave(&pVBoxSCSI->CritSect);
    272303    return rc;
    273304}
     
    291322    LogFlowFunc(("pVBoxSCSI=%#p puTargetDevice=%#p\n", pVBoxSCSI, puTargetDevice));
    292323
     324    RTCritSectEnter(&pVBoxSCSI->CritSect);
    293325    AssertMsg(pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY, ("Invalid state %u\n", pVBoxSCSI->enmState));
    294326
     
    311343    *pcbBuf = pVBoxSCSI->cbBuf;
    312344    *puTargetDevice = pVBoxSCSI->uTargetDevice;
     345    RTCritSectLeave(&pVBoxSCSI->CritSect);
    313346
    314347    return rc;
     
    323356    LogFlowFunc(("pVBoxSCSI=%#p\n", pVBoxSCSI));
    324357
     358    RTCritSectEnter(&pVBoxSCSI->CritSect);
    325359    if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE)
    326360        vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
     
    329363
    330364    ASMAtomicXchgBool(&pVBoxSCSI->fBusy, false);
     365    RTCritSectLeave(&pVBoxSCSI->CritSect);
    331366
    332367    return VINF_SUCCESS;
     
    338373    AssertReturn(cbSkip + cbCopy <= pVBoxSCSI->cbBuf, 0);
    339374
     375    RTCritSectEnter(&pVBoxSCSI->CritSect);
    340376    void *pvBuf = pVBoxSCSI->pbBuf + cbSkip;
    341     return RTSgBufCopyToBuf(pSgBuf, pvBuf, cbCopy);
     377    size_t cbCopied = RTSgBufCopyToBuf(pSgBuf, pvBuf, cbCopy);
     378    RTCritSectLeave(&pVBoxSCSI->CritSect);
     379
     380    return cbCopied;
    342381}
    343382
     
    347386    AssertReturn(cbSkip + cbCopy <= pVBoxSCSI->cbBuf, 0);
    348387
     388    RTCritSectEnter(&pVBoxSCSI->CritSect);
    349389    void *pvBuf = pVBoxSCSI->pbBuf + cbSkip;
    350     return RTSgBufCopyFromBuf(pSgBuf, pvBuf, cbCopy);
     390    size_t cbCopied = RTSgBufCopyFromBuf(pSgBuf, pvBuf, cbCopy);
     391    RTCritSectLeave(&pVBoxSCSI->CritSect);
     392
     393    return cbCopied;
    351394}
    352395
     
    376419    Assert(!pVBoxSCSI->fBusy);
    377420
     421    RTCritSectEnter(&pVBoxSCSI->CritSect);
    378422    /*
    379423     * Also ignore attempts to read more data than is available.
     
    407451    }
    408452    *pcTransfers = 0;
     453    RTCritSectLeave(&pVBoxSCSI->CritSect);
    409454
    410455    return VINF_SUCCESS;
     
    434479    AssertReturn(pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE, VINF_SUCCESS);
    435480
     481    RTCritSectEnter(&pVBoxSCSI->CritSect);
    436482    /*
    437483     * Ignore excess data (not supposed to happen).
     
    457503        AssertFailed();
    458504    *pcTransfers = 0;
     505    RTCritSectLeave(&pVBoxSCSI->CritSect);
    459506
    460507    return rc;
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.h

    r81765 r82667  
    7373*******************************************************************************/
    7474//#define DEBUG
     75#include <iprt/semaphore.h>
    7576#include <VBox/vmm/pdmdev.h>
    7677#include <VBox/vmm/pdmstorageifs.h>
     
    129130    /** The state we are in when fetching a command from the BIOS. */
    130131    VBOXSCSISTATE        enmState;
     132    /** Critical section protecting the device state. */
     133    RTCRITSECT           CritSect;
    131134} VBOXSCSI, *PVBOXSCSI;
    132135
     
    137140RT_C_DECLS_BEGIN
    138141int vboxscsiInitialize(PVBOXSCSI pVBoxSCSI);
     142void vboxscsiDestroy(PVBOXSCSI pVBoxSCSI);
     143void vboxscsiHwReset(PVBOXSCSI pVBoxSCSI);
    139144int vboxscsiReadRegister(PVBOXSCSI pVBoxSCSI, uint8_t iRegister, uint32_t *pu32Value);
    140145int vboxscsiWriteRegister(PVBOXSCSI pVBoxSCSI, uint8_t iRegister, uint8_t uVal);
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