summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 22:55:52 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 22:55:52 +0000
commitcd47c2446f1a9dee96610f298989848f8986a8be (patch)
tree02c30d62a9164987d0aaba2f72c58a50053205d6 /src/VBox/Devices
parentReleasing progress-linux version 7.0.14-dfsg-4~progress7.99u1. (diff)
downloadvirtualbox-cd47c2446f1a9dee96610f298989848f8986a8be.tar.xz
virtualbox-cd47c2446f1a9dee96610f298989848f8986a8be.zip
Merging upstream version 7.0.16-dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices')
-rw-r--r--src/VBox/Devices/Audio/AudioMixer.cpp11
-rw-r--r--src/VBox/Devices/Audio/DevHdaStream.cpp60
-rw-r--r--src/VBox/Devices/Audio/DevIchAc97.cpp11
-rw-r--r--src/VBox/Devices/Audio/DevSB16.cpp159
-rw-r--r--src/VBox/Devices/Bus/DevPciIch9.cpp1
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py0
-rw-r--r--[-rwxr-xr-x]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl0
-rwxr-xr-x[-rw-r--r--]src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py0
-rw-r--r--src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fdbin4194304 -> 4194304 bytes
-rw-r--r--src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fdbin4194304 -> 4194304 bytes
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp9
-rw-r--r--src/VBox/Devices/Graphics/DevVGA.cpp36
-rw-r--r--src/VBox/Devices/Input/testcase/tstUsbMouse.cpp19
-rw-r--r--src/VBox/Devices/Network/DevPCNet.cpp2
-rw-r--r--src/VBox/Devices/Network/SrvIntNetR0.cpp25
-rw-r--r--src/VBox/Devices/Network/testcase/tstIntNetR0.cpp20
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum2
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum2
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum2
-rw-r--r--src/VBox/Devices/Serial/DevOxPcie958.cpp35
-rw-r--r--src/VBox/Devices/Storage/DevAHCI.cpp8
-rw-r--r--src/VBox/Devices/Storage/DevBusLogic.cpp13
-rw-r--r--src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp9
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp49
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h22
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp111
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp133
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp2
-rw-r--r--src/VBox/Devices/USB/DevEHCI.cpp50
-rw-r--r--src/VBox/Devices/USB/DevOHCI.cpp93
-rw-r--r--src/VBox/Devices/USB/DevXHCI.cpp103
-rw-r--r--src/VBox/Devices/USB/DrvVUSBRootHub.cpp59
-rw-r--r--src/VBox/Devices/VirtIO/VirtioCore.cpp15
52 files changed, 867 insertions, 230 deletions
diff --git a/src/VBox/Devices/Audio/AudioMixer.cpp b/src/VBox/Devices/Audio/AudioMixer.cpp
index 90d86063..899154eb 100644
--- a/src/VBox/Devices/Audio/AudioMixer.cpp
+++ b/src/VBox/Devices/Audio/AudioMixer.cpp
@@ -2011,6 +2011,9 @@ uint64_t AudioMixerSinkTransferFromCircBuf(PAUDMIXSINK pSink, PRTCIRCBUF pCircBu
Assert(pSink->enmDir == PDMAUDIODIR_OUT);
RT_NOREF(idStream);
+ int rc = RTCritSectEnter(&pSink->CritSect);
+ AssertRCReturn(rc, rc);
+
/*
* Figure how much that we can push down.
*/
@@ -2022,7 +2025,8 @@ uint64_t AudioMixerSinkTransferFromCircBuf(PAUDMIXSINK pSink, PRTCIRCBUF pCircBu
Log3Func(("idStream=%u: cbSinkWritable=%#RX32 cbCircBufReadable=%#RX32 -> cbToTransfer=%#RX32 @%#RX64\n",
idStream, cbSinkWritable, cbCircBufReadable, cbToTransfer, offStream));
- AssertMsg(!(pSink->fStatus & AUDMIXSINK_STS_DRAINING) || cbCircBufReadable == pSink->cbDmaLeftToDrain,
+ /* Note: There now can be more data in the DMA buffer than initially announced. See @bugref{10354}. */
+ AssertMsg(!(pSink->fStatus & AUDMIXSINK_STS_DRAINING) || cbCircBufReadable >= pSink->cbDmaLeftToDrain,
("cbCircBufReadable=%#x cbDmaLeftToDrain=%#x\n", cbCircBufReadable, pSink->cbDmaLeftToDrain));
/*
@@ -2080,6 +2084,11 @@ uint64_t AudioMixerSinkTransferFromCircBuf(PAUDMIXSINK pSink, PRTCIRCBUF pCircBu
else
Assert(cbToTransfer2 == 0);
+ Log3Func(("idStream=%u: cbCircBufUsed=%RX32 left\n", idStream, (uint32_t)RTCircBufUsed(pCircBuf)));
+
+ RTCritSectLeave(&pSink->CritSect);
+
+ LogFlowFuncLeave();
return offStream;
}
diff --git a/src/VBox/Devices/Audio/DevHdaStream.cpp b/src/VBox/Devices/Audio/DevHdaStream.cpp
index aa6b0535..9bb27a4a 100644
--- a/src/VBox/Devices/Audio/DevHdaStream.cpp
+++ b/src/VBox/Devices/Audio/DevHdaStream.cpp
@@ -797,18 +797,6 @@ int hdaR3StreamSetUp(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShar
* Set up internal ring buffer.
*/
- /* (Re-)Allocate the stream's internal DMA buffer,
- * based on the timing *and* PCM properties we just got above. */
- if (pStreamR3->State.pCircBuf)
- {
- RTCircBufDestroy(pStreamR3->State.pCircBuf);
- pStreamR3->State.pCircBuf = NULL;
- pStreamR3->State.StatDmaBufSize = 0;
- pStreamR3->State.StatDmaBufUsed = 0;
- }
- pStreamShared->State.offWrite = 0;
- pStreamShared->State.offRead = 0;
-
/*
* The default internal ring buffer size must be:
*
@@ -857,16 +845,37 @@ int hdaR3StreamSetUp(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShar
rc = VERR_INVALID_PARAMETER);
if (RT_SUCCESS(rc))
{
- rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBuf);
- if (RT_SUCCESS(rc))
+ /**
+ * Note: Only re-create the DMA buffer if the size actually has changed.
+ *
+ * Otherwise do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
+ if (pStreamR3->State.StatDmaBufSize != cbCircBuf)
{
- pStreamR3->State.StatDmaBufSize = cbCircBuf;
+ /* (Re-)Allocate the stream's internal DMA buffer,
+ * based on the timing *and* PCM properties we just got above. */
+ if (pStreamR3->State.pCircBuf)
+ {
+ RTCircBufDestroy(pStreamR3->State.pCircBuf);
+ pStreamR3->State.pCircBuf = NULL;
+ pStreamR3->State.StatDmaBufSize = 0;
+ pStreamR3->State.StatDmaBufUsed = 0;
+ }
+ pStreamShared->State.offWrite = 0;
+ pStreamShared->State.offRead = 0;
- /*
- * Forward the timer frequency hint to TM as well for better accuracy on
- * systems w/o preemption timers (also good for 'info timers').
- */
- PDMDevHlpTimerSetFrequencyHint(pDevIns, pStreamShared->hTimer, uTransferHz);
+ rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBuf);
+ if (RT_SUCCESS(rc))
+ {
+ pStreamR3->State.StatDmaBufSize = cbCircBuf;
+
+ /*
+ * Forward the timer frequency hint to TM as well for better accuracy on
+ * systems w/o preemption timers (also good for 'info timers').
+ */
+ PDMDevHlpTimerSetFrequencyHint(pDevIns, pStreamShared->hTimer, uTransferHz);
+ }
}
}
@@ -1003,10 +1012,9 @@ void hdaR3StreamReset(PHDASTATE pThis, PHDASTATER3 pThisCC, PHDASTREAM pStreamSh
pStreamShared->State.idxScheduleLoop = 0;
pStreamShared->State.fInputPreBuffered = false;
- if (pStreamR3->State.pCircBuf)
- RTCircBufReset(pStreamR3->State.pCircBuf);
- pStreamShared->State.offWrite = 0;
- pStreamShared->State.offRead = 0;
+ /* Note: Do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
/* Report that we're done resetting this stream. */
HDA_STREAM_REG(pThis, CTL, uSD) = 0;
@@ -1041,6 +1049,8 @@ int hdaR3StreamEnable(PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pS
PAUDMIXSINK const pSink = pStreamR3->pMixSink ? pStreamR3->pMixSink->pMixSink : NULL;
if (pSink)
{
+ AudioMixerSinkLock(pSink);
+
if (fEnable)
{
if (pStreamR3->State.pAioRegSink != pSink)
@@ -1060,6 +1070,8 @@ int hdaR3StreamEnable(PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pS
else
rc = AudioMixerSinkDrainAndStop(pSink,
pStreamR3->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf) : 0);
+
+ AudioMixerSinkUnlock(pSink);
}
if ( RT_SUCCESS(rc)
&& fEnable
diff --git a/src/VBox/Devices/Audio/DevIchAc97.cpp b/src/VBox/Devices/Audio/DevIchAc97.cpp
index 97743372..969e12db 100644
--- a/src/VBox/Devices/Audio/DevIchAc97.cpp
+++ b/src/VBox/Devices/Audio/DevIchAc97.cpp
@@ -1730,8 +1730,9 @@ static void ichac97R3StreamReset(PAC97STATE pThis, PAC97STREAM pStream, PAC97STR
LogFunc(("[SD%RU8]\n", pStream->u8SD));
- if (pStreamCC->State.pCircBuf)
- RTCircBufReset(pStreamCC->State.pCircBuf);
+ /* Note: Do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
pStream->Regs.bdbar = 0;
pStream->Regs.civ = 0;
@@ -2198,7 +2199,11 @@ static int ichac97R3StreamSetUp(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATE
*/
if ( pStreamCC->State.pCircBuf
&& RTCircBufSize(pStreamCC->State.pCircBuf) == cbCircBuf)
- RTCircBufReset(pStreamCC->State.pCircBuf);
+ {
+ /* Note: Do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
+ }
else
{
if (pStreamCC->State.pCircBuf)
diff --git a/src/VBox/Devices/Audio/DevSB16.cpp b/src/VBox/Devices/Audio/DevSB16.cpp
index a405f311..7df081e7 100644
--- a/src/VBox/Devices/Audio/DevSB16.cpp
+++ b/src/VBox/Devices/Audio/DevSB16.cpp
@@ -110,6 +110,8 @@ typedef struct SB16STATE *PSB16STATE;
*/
typedef struct SB16STREAMSTATE
{
+ /** Critical section for this stream. */
+ RTCRITSECT CritSect;
/** Flag indicating whether this stream is in enabled state or not. */
bool fEnabled;
/** Set if we've registered the asynchronous update job. */
@@ -335,6 +337,8 @@ static int sb16StreamEnable(PSB16STATE pThis, PSB16STREAM pStream, bool fEnable
static void sb16StreamReset(PSB16STATE pThis, PSB16STREAM pStream);
static int sb16StreamOpen(PPDMDEVINS pDevIns, PSB16STATE pThis, PSB16STREAM pStream);
static void sb16StreamClose(PPDMDEVINS pDevIns, PSB16STATE pThis, PSB16STREAM pStream);
+DECLINLINE(void) sb16StreamLock(PSB16STREAM pStream);
+DECLINLINE(void) sb16StreamUnlock(PSB16STREAM pStream);
DECLINLINE(PAUDMIXSINK) sb16StreamIndexToSink(PSB16STATE pThis, uint8_t uIdx);
static void sb16StreamTransferScheduleNext(PSB16STATE pThis, PSB16STREAM pStream, uint32_t cSamples);
static int sb16StreamDoDmaOutput(PSB16STATE pThis, PSB16STREAM pStream, int uDmaChan, uint32_t offDma, uint32_t cbDma, uint32_t cbToRead, uint32_t *pcbRead);
@@ -1923,6 +1927,20 @@ static void sb16RemoveDrv(PPDMDEVINS pDevIns, PSB16STATE pThis, PSB16DRIVER pDrv
* Stream handling *
*********************************************************************************************************************************/
+/**
+ * Reads DMA output data into the internal DMA buffer.
+ *
+ * @returns VBox status code.
+ * @param pThis The SB16 state.
+ * @param pStream The SB16 stream to read DMA output data from.
+ * @param uDmaChan DMA channel to read from.
+ * @param offDma DMA offset (in bytes) to start reading from.
+ * @param cbDma DMA area size in bytes.
+ * @param cbToRead How much bytes to read in total.
+ * @param pcbRead Where to return the DMA bytes read.
+ *
+ * @thread EMT
+ */
static int sb16StreamDoDmaOutput(PSB16STATE pThis, PSB16STREAM pStream, int uDmaChan, uint32_t offDma, uint32_t cbDma,
uint32_t cbToRead, uint32_t *pcbRead)
{
@@ -1930,6 +1948,8 @@ static int sb16StreamDoDmaOutput(PSB16STATE pThis, PSB16STREAM pStream, int uDma
//Assert(cbToRead <= cbFree); /** @todo Add statistics for overflows. */
cbToRead = RT_MIN(cbToRead, cbFree);
+ sb16StreamLock(pStream);
+
uint32_t cbReadTotal = 0;
while (cbToRead)
{
@@ -1948,6 +1968,8 @@ static int sb16StreamDoDmaOutput(PSB16STATE pThis, PSB16STREAM pStream, int uDma
if (cbReadTotal > 0)
break;
*pcbRead = 0;
+
+ sb16StreamUnlock(pStream);
return rc;
}
@@ -1956,8 +1978,12 @@ static int sb16StreamDoDmaOutput(PSB16STATE pThis, PSB16STREAM pStream, int uDma
else
AudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, pv, cbRead);
+ Log3Func(("Writing %#RX32 bytes to DMA buffer\n", cbRead));
+
RTCircBufReleaseWriteBlock(pStream->State.pCircBuf, cbRead);
+ Log3Func(("Now %#RX32 bytes in buffer\n", RTCircBufUsed(pStream->State.pCircBuf)));
+
Assert(cbToRead >= cbRead);
pStream->State.offWrite += cbRead;
offDma = (offDma + cbRead) % cbDma;
@@ -1970,6 +1996,9 @@ static int sb16StreamDoDmaOutput(PSB16STATE pThis, PSB16STREAM pStream, int uDma
/* Update buffer stats. */
pStream->State.StatDmaBufUsed = (uint32_t)RTCircBufUsed(pStream->State.pCircBuf);
+ Log3Func(("[SD%RU8] cbCircBufUsed=%#RX64\n", pStream->uIdx, RTCircBufUsed(pStream->State.pCircBuf)));
+
+ sb16StreamUnlock(pStream);
return VINF_SUCCESS;
}
@@ -2011,8 +2040,19 @@ static int sb16StreamEnable(PSB16STATE pThis, PSB16STREAM pStream, bool fEnable,
}
else
{
- rc = AudioMixerSinkDrainAndStop(pSink, pStream->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStream->State.pCircBuf) : 0);
+ /* We need to lock the stream here in order to synchronize the amount of bytes we have to drain
+ * here with the mixer's async I/O thread. See @bugref{10354}. */
+ sb16StreamLock(pStream);
+
+ uint32_t const cbToDrain = pStream->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStream->State.pCircBuf) : 0;
+ Log3Func(("cbToDrain=%#RX32\n", cbToDrain));
+
+ sb16StreamUnlock(pStream);
+
+ rc = AudioMixerSinkDrainAndStop(pSink, cbToDrain);
AssertRCReturn(rc, rc);
+
+
}
pStream->State.fEnabled = fEnable;
@@ -2068,6 +2108,9 @@ static int sb16StreamCreate(PSB16STATE pThis, PSB16STREAM pStream, uint8_t uIdx)
{
LogFlowFuncEnter();
+ int rc = RTCritSectInit(&pStream->State.CritSect);
+ AssertRCReturn(rc, rc);
+
pStream->Dbg.Runtime.fEnabled = pThis->Dbg.fEnabled;
if (RT_LIKELY(!pStream->Dbg.Runtime.fEnabled))
@@ -2111,6 +2154,9 @@ static int sb16StreamDestroy(PPDMDEVINS pDevIns, PSB16STATE pThis, PSB16STREAM p
pStream->State.fRegisteredAsyncUpdateJob = false;
}
+ int rc2 = RTCritSectDelete(&pStream->State.CritSect);
+ AssertRC(rc2);
+
if (pStream->State.pCircBuf)
{
RTCircBufDestroy(pStream->State.pCircBuf);
@@ -2177,6 +2223,28 @@ static void sb16StreamReset(PSB16STATE pThis, PSB16STREAM pStream)
}
/**
+ * Locks a SB16 stream for serialized access.
+ *
+ * @param pStream The SB16 stream to lock.
+ */
+DECLINLINE(void) sb16StreamLock(PSB16STREAM pStream)
+{
+ int rc2 = RTCritSectEnter(&pStream->State.CritSect);
+ AssertRC(rc2);
+}
+
+/**
+ * Unlocks a formerly locked SB16 stream.
+ *
+ * @param pStream The SB16 stream to unlock.
+ */
+DECLINLINE(void) sb16StreamUnlock(PSB16STREAM pStream)
+{
+ int rc2 = RTCritSectLeave(&pStream->State.CritSect);
+ AssertRC(rc2);
+}
+
+/**
* Opens a SB16 stream with its current mixer settings.
*
* @returns VBox status code.
@@ -2209,47 +2277,59 @@ static int sb16StreamOpen(PPDMDEVINS pDevIns, PSB16STATE pThis, PSB16STREAM pStr
PDMAudioPropsChannels(&pStream->Cfg.Props), pStream->Cfg.Props.fSigned ? "S" : "U",
PDMAudioPropsSampleBits(&pStream->Cfg.Props)));
- /* (Re-)create the stream's internal ring buffer. */
- if (pStream->State.pCircBuf)
- {
- RTCircBufDestroy(pStream->State.pCircBuf);
- pStream->State.pCircBuf = NULL;
- }
-
/** @todo r=bird: two DMA periods is probably too little. */
const uint32_t cbCircBuf = PDMAudioPropsMilliToBytes(&pStream->Cfg.Props,
(RT_MS_1SEC / pStream->uTimerHz) * 2 /* Use double buffering here */);
+ int rc = VINF_SUCCESS;
- int rc = RTCircBufCreate(&pStream->State.pCircBuf, cbCircBuf);
- AssertRCReturn(rc, rc);
- pStream->State.StatDmaBufSize = (uint32_t)RTCircBufSize(pStream->State.pCircBuf);
+ /**
+ * Note: Only re-create the DMA buffer if the size actually has changed.
+ *
+ * Otherwise do *not* reset the stream's circular buffer here, as the audio mixer still relies on
+ * previously announced DMA data (via AudioMixerSinkDrainAndStop()) and processes it asynchronously.
+ * Resetting the buffer here will cause a race condition. See @bugref{10354}. */
+ if (pStream->State.StatDmaBufSize != cbCircBuf)
+ {
+ Log3Func(("Re-creating ring buffer (%#RX32 -> %#RX32)\n", pStream->State.StatDmaBufSize, cbCircBuf));
- /* Set scheduling hint. */
- pStream->Cfg.Device.cMsSchedulingHint = RT_MS_1SEC / RT_MIN(pStream->uTimerHz, 1);
+ /* (Re-)create the stream's internal ring buffer. */
+ if (pStream->State.pCircBuf)
+ {
+ RTCircBufDestroy(pStream->State.pCircBuf);
+ pStream->State.pCircBuf = NULL;
+ }
- PAUDMIXSINK pMixerSink = sb16StreamIndexToSink(pThis, pStream->uIdx);
- AssertPtrReturn(pMixerSink, VERR_INVALID_POINTER);
+ rc = RTCircBufCreate(&pStream->State.pCircBuf, cbCircBuf);
+ AssertRCReturn(rc, rc);
+ pStream->State.StatDmaBufSize = (uint32_t)RTCircBufSize(pStream->State.pCircBuf);
- sb16RemoveDrvStreams(pDevIns, pThis,
- sb16StreamIndexToSink(pThis, pStream->uIdx), pStream->Cfg.enmDir, pStream->Cfg.enmPath);
+ /* Set scheduling hint. */
+ pStream->Cfg.Device.cMsSchedulingHint = RT_MS_1SEC / RT_MIN(pStream->uTimerHz, 1);
- rc = sb16AddDrvStreams(pDevIns, pThis, pMixerSink, &pStream->Cfg);
- if (RT_SUCCESS(rc))
- {
- if (RT_LIKELY(!pStream->Dbg.Runtime.fEnabled))
- { /* likely */ }
- else
+ PAUDMIXSINK pMixerSink = sb16StreamIndexToSink(pThis, pStream->uIdx);
+ AssertPtrReturn(pMixerSink, VERR_INVALID_POINTER);
+
+ sb16RemoveDrvStreams(pDevIns, pThis,
+ sb16StreamIndexToSink(pThis, pStream->uIdx), pStream->Cfg.enmDir, pStream->Cfg.enmPath);
+
+ rc = sb16AddDrvStreams(pDevIns, pThis, pMixerSink, &pStream->Cfg);
+ if (RT_SUCCESS(rc))
{
- /* Make sure to close + delete a former debug file, as the PCM format has changed (e.g. U8 -> S16). */
- if (AudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMA))
+ if (RT_LIKELY(!pStream->Dbg.Runtime.fEnabled))
+ { /* likely */ }
+ else
{
- AudioHlpFileClose(pStream->Dbg.Runtime.pFileDMA);
- AudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMA);
- }
+ /* Make sure to close + delete a former debug file, as the PCM format has changed (e.g. U8 -> S16). */
+ if (AudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMA))
+ {
+ AudioHlpFileClose(pStream->Dbg.Runtime.pFileDMA);
+ AudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMA);
+ }
- int rc2 = AudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMA, AUDIOHLPFILE_DEFAULT_OPEN_FLAGS,
- &pStream->Cfg.Props);
- AssertRC(rc2);
+ int rc2 = AudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMA, AUDIOHLPFILE_DEFAULT_OPEN_FLAGS,
+ &pStream->Cfg.Props);
+ AssertRC(rc2);
+ }
}
}
@@ -2302,11 +2382,18 @@ static void sb16StreamTransferScheduleNext(PSB16STATE pThis, PSB16STREAM pStream
*
* @param pStream The SB16 stream.
* @param pSink The mixer sink to push to.
+ *
+ * @thread MixAIO-n
+ *
+ * @note Takes the stream's lock.
*/
static void sb16StreamPushToMixer(PSB16STREAM pStream, PAUDMIXSINK pSink)
{
+ sb16StreamLock(pStream);
+
#ifdef LOG_ENABLED
uint64_t const offReadOld = pStream->State.offRead;
+ Log3Func(("[SD%RU8] cbCircBufUsed=%#RX64\n", pStream->uIdx, RTCircBufUsed(pStream->State.pCircBuf)));
#endif
pStream->State.offRead = AudioMixerSinkTransferFromCircBuf(pSink,
pStream->State.pCircBuf,
@@ -2315,11 +2402,13 @@ static void sb16StreamPushToMixer(PSB16STREAM pStream, PAUDMIXSINK pSink)
/** @todo pStream->Dbg.Runtime.fEnabled
? pStream->Dbg.Runtime.pFileStream :*/ NULL);
- Log3Func(("[SD%RU8] transferred=%#RX64 bytes -> @%#RX64\n", pStream->uIdx,
- pStream->State.offRead - offReadOld, pStream->State.offRead));
+ Log3Func(("[SD%RU8] transferred=%#RX64 bytes -> @%#RX64 (cbCircBufUsed=%#RX64)\n", pStream->uIdx,
+ pStream->State.offRead - offReadOld, pStream->State.offRead, RTCircBufUsed(pStream->State.pCircBuf)));
/* Update buffer stats. */
pStream->State.StatDmaBufUsed = (uint32_t)RTCircBufUsed(pStream->State.pCircBuf);
+
+ sb16StreamUnlock(pStream);
}
@@ -2327,8 +2416,10 @@ static void sb16StreamPushToMixer(PSB16STREAM pStream, PAUDMIXSINK pSink)
* @callback_method_impl{FNAUDMIXSINKUPDATE}
*
* For output streams this moves data from the internal DMA buffer (in which
- * ichac97R3StreamUpdateDma put it), thru the mixer and to the various backend
+ * sb16StreamDoDmaOutput put it), thru the mixer and to the various backend
* audio devices.
+ *
+ * @thread MixAIO-n
*/
static DECLCALLBACK(void) sb16StreamUpdateAsyncIoJob(PPDMDEVINS pDevIns, PAUDMIXSINK pSink, void *pvUser)
{
diff --git a/src/VBox/Devices/Bus/DevPciIch9.cpp b/src/VBox/Devices/Bus/DevPciIch9.cpp
index 7e2b49a7..2bd89e9b 100644
--- a/src/VBox/Devices/Bus/DevPciIch9.cpp
+++ b/src/VBox/Devices/Bus/DevPciIch9.cpp
@@ -730,6 +730,7 @@ static DECLCALLBACK(VBOXSTRICTRC) ich9pciMcfgMMIORead(PPDMDEVINS pDevIns, void *
break;
default:
ASSERT_GUEST_MSG_FAILED(("cb=%u off=%RGp\n", cb, off)); /** @todo how the heck should this work? Split it, right? */
+ rcStrict = VINF_IOM_MMIO_UNUSED_00;
break;
}
}
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py
index c23a3a10..c23a3a10 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/GetUtcDateTime.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py
index b3198d5b..b3198d5b 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/doxygen.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py
index c0a3269b..c0a3269b 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/BuildToolError.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py
index c0b5e460..c0b5e460 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/Exceptions.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py
index f4cf1989..f4cf1989 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/ToolError.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
index 7f000648..7f000648 100755..100644
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py
index 4e19e636..4e19e636 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/tests/Split/test_split.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py
index e5e20f41..e5e20f41 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CToolsTests.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py
index 29ed80b4..29ed80b4 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/CheckPythonSyntax.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py
index afe58534..afe58534 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonTest.py
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py
index a287f3a3..a287f3a3 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Tests/PythonToolsTests.py
diff --git a/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl b/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl
index 5b0749fa..5b0749fa 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl
+++ b/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/OpensslLib/process_files.pl
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py
index a71073ba..a71073ba 100644..100755
--- a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Tools/Tests/test_yaml.py
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 4e0d4b76..2c689d9b 100644
--- a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
+++ b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
Binary files differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index 07cc531c..e586a195 100644
--- a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
+++ b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
Binary files differ
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
index d805833f..0b83b579 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
@@ -8281,7 +8281,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.14 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.16 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -9212,7 +9212,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.14', 000h
+ db 'Oracle VM VirtualBox Version 7.0.16', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -9247,4 +9247,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 0e2h
+ db 000h, 0deh
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
index 2f608321..9d6aad04 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
@@ -1 +1 @@
-9431df94586df05b1873d86a27b77eb5 *VBoxVgaBios286.rom
+852353ec31d0749de1c385e91ab27511 *VBoxVgaBios286.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
index 9b6c7100..12ea3360 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
@@ -7735,7 +7735,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.14 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.16 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -8666,7 +8666,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.14', 000h
+ db 'Oracle VM VirtualBox Version 7.0.16', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -8701,4 +8701,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 057h
+ db 000h, 053h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
index d0e0691d..5bbcac9e 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
@@ -1 +1 @@
-a0e84ee6aab110901a8d59aa1451cfd2 *VBoxVgaBios386.rom
+5fd5574a01aad6139078230edb9b0545 *VBoxVgaBios386.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
index 89fd1abc..695ce11f 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
@@ -8439,7 +8439,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.14 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.16 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -9370,7 +9370,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.14', 000h
+ db 'Oracle VM VirtualBox Version 7.0.16', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -9405,4 +9405,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 021h
+ db 000h, 01dh
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
index 437a4099..d19f9c05 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
@@ -1 +1 @@
-fe9decb70cbd4b2ae6fa11107ac955ae *VBoxVgaBios8086.rom
+4d5fd4aad75f5b2295caecb11ca646b2 *VBoxVgaBios8086.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp
index 9802b570..58aa8562 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-dx-dx11.cpp
@@ -7902,7 +7902,14 @@ static DECLCALLBACK(int) vmsvga3dBackDXClearDepthStencilView(PVGASTATECC pThisCC
int rc = dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
AssertRCReturn(rc, rc);
}
- pDevice->pImmediateContext->ClearDepthStencilView(pDXView->u.pDepthStencilView, flags, depth, stencil);
+
+ UINT ClearFlags = 0;
+ if (flags & SVGA3D_CLEAR_DEPTH)
+ ClearFlags |= D3D11_CLEAR_DEPTH;
+ if (flags & SVGA3D_CLEAR_STENCIL)
+ ClearFlags |= D3D11_CLEAR_STENCIL;
+
+ pDevice->pImmediateContext->ClearDepthStencilView(pDXView->u.pDepthStencilView, ClearFlags, depth, stencil);
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/Graphics/DevVGA.cpp b/src/VBox/Devices/Graphics/DevVGA.cpp
index a2ce3b39..e1060783 100644
--- a/src/VBox/Devices/Graphics/DevVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA.cpp
@@ -387,9 +387,9 @@ DECLINLINE(bool) vgaR3IsDirty(PVGASTATE pThis, RTGCPHYS offVRAM)
*/
DECLINLINE(void) vgaR3ResetDirty(PVGASTATE pThis, RTGCPHYS offVRAMStart, RTGCPHYS offVRAMEnd)
{
- Assert(offVRAMStart < pThis->vram_size);
- Assert(offVRAMEnd <= pThis->vram_size);
- Assert(offVRAMStart < offVRAMEnd);
+ AssertReturnVoid(offVRAMStart < pThis->vram_size);
+ AssertReturnVoid(offVRAMEnd <= pThis->vram_size);
+ AssertReturnVoid(offVRAMStart < offVRAMEnd);
ASMBitClearRange(&pThis->bmDirtyBitmap[0], offVRAMStart >> GUEST_PAGE_SHIFT, offVRAMEnd >> GUEST_PAGE_SHIFT);
}
@@ -962,9 +962,9 @@ static void recalculate_data(PVGASTATE pThis)
offStart += offX >> 1;
else
offStart += offX * ((cBPP + 7) >> 3);
- offStart >>= 2;
+
pThis->vbe_line_offset = RT_MIN(cbLinePitch, pThis->vram_size);
- pThis->vbe_start_addr = RT_MIN(offStart, pThis->vram_size);
+ pThis->vbe_start_addr = RT_MIN(offStart, pThis->vram_size) >> 2;
/* The VBE_DISPI_INDEX_VIRT_HEIGHT is used to prevent setting resolution bigger than
* the VRAM size permits. It is used instead of VBE_DISPI_INDEX_YRES *only* in case
@@ -985,10 +985,14 @@ static VBOXSTRICTRC vbe_ioport_write_data(PPDMDEVINS pDevIns, PVGASTATE pThis, P
uint32_t max_bank;
RT_NOREF(pThisCC, addr);
- if (pThis->vbe_index <= VBE_DISPI_INDEX_NB) {
+ uint16_t const idxVbe = pThis->vbe_index;
+ if (idxVbe <= VBE_DISPI_INDEX_NB)
+ {
+ RT_UNTRUSTED_VALIDATED_FENCE();
+
bool fRecalculate = false;
- Log(("VBE: write index=0x%x val=0x%x\n", pThis->vbe_index, val));
- switch(pThis->vbe_index) {
+ Log(("VBE: write index=0x%x val=0x%x\n", idxVbe, val));
+ switch(idxVbe) {
case VBE_DISPI_INDEX_ID:
if (val == VBE_DISPI_ID0 ||
val == VBE_DISPI_ID1 ||
@@ -1003,27 +1007,27 @@ static VBOXSTRICTRC vbe_ioport_write_data(PPDMDEVINS pDevIns, PVGASTATE pThis, P
# endif
val == VBE_DISPI_ID_CFG)
{
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_ID] = val;
}
break;
case VBE_DISPI_INDEX_XRES:
if (val <= VBE_DISPI_MAX_XRES)
{
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_XRES] = val;
pThis->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = val;
fRecalculate = true;
}
break;
case VBE_DISPI_INDEX_YRES:
if (val <= VBE_DISPI_MAX_YRES)
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_YRES] = val;
break;
case VBE_DISPI_INDEX_BPP:
if (val == 0)
val = 8;
if (val == 4 || val == 8 || val == 15 ||
val == 16 || val == 24 || val == 32) {
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_BPP] = val;
fRecalculate = true;
}
break;
@@ -1039,7 +1043,7 @@ static VBOXSTRICTRC vbe_ioport_write_data(PPDMDEVINS pDevIns, PVGASTATE pThis, P
val &= 0xff;
if (val > max_bank)
val = max_bank;
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_BANK] = val;
pThis->bank_offset = (val << 16);
# ifndef IN_RC
@@ -1143,7 +1147,7 @@ static VBOXSTRICTRC vbe_ioport_write_data(PPDMDEVINS pDevIns, PVGASTATE pThis, P
*/
pThis->bank_offset = 0;
}
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_ENABLE] = val;
/*
* LFB video mode is either disabled or changed. Notify the display
* and reset VBVA.
@@ -1167,7 +1171,7 @@ static VBOXSTRICTRC vbe_ioport_write_data(PPDMDEVINS pDevIns, PVGASTATE pThis, P
case VBE_DISPI_INDEX_X_OFFSET:
case VBE_DISPI_INDEX_Y_OFFSET:
{
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[idxVbe] = val;
fRecalculate = true;
}
break;
@@ -1185,7 +1189,7 @@ static VBOXSTRICTRC vbe_ioport_write_data(PPDMDEVINS pDevIns, PVGASTATE pThis, P
# endif /* IN_RING3 */
break;
case VBE_DISPI_INDEX_CFG:
- pThis->vbe_regs[pThis->vbe_index] = val;
+ pThis->vbe_regs[VBE_DISPI_INDEX_CFG] = val;
break;
default:
break;
diff --git a/src/VBox/Devices/Input/testcase/tstUsbMouse.cpp b/src/VBox/Devices/Input/testcase/tstUsbMouse.cpp
index 1b411583..32ed14a8 100644
--- a/src/VBox/Devices/Input/testcase/tstUsbMouse.cpp
+++ b/src/VBox/Devices/Input/testcase/tstUsbMouse.cpp
@@ -100,6 +100,23 @@ static DECLCALLBACK(int) tstDriverAttach(PPDMUSBINS pUsbIns, RTUINT iLun, PPDMIB
}
+/** @interface_method_impl{PDMUSBHLP,pfnTimerCreate} */
+static DECLCALLBACK(int) tstTimerCreate(PPDMUSBINS pUsbIns, TMCLOCK enmClock, PFNTMTIMERUSB pfnCallback, void *pvUser,
+ uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
+{
+ RT_NOREF7(pUsbIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
+ return VINF_SUCCESS;
+}
+
+
+/** @interface_method_impl{PDMUSBHLP,pfnTimerCreate} */
+static DECLCALLBACK(int) tstTimerDestroy(PPDMUSBINS pUsbIns, TMTIMERHANDLE hTimer)
+{
+ RT_NOREF2(pUsbIns, hTimer);
+ return VINF_SUCCESS;
+}
+
+
/**
* @interface_method_impl{PDMIBASE,pfnQueryInterface}
*/
@@ -393,6 +410,8 @@ int main()
g_tstUsbHlp.u32Version = PDM_USBHLP_VERSION;
g_tstUsbHlp.pfnVMSetErrorV = tstVMSetErrorV;
g_tstUsbHlp.pfnDriverAttach = tstDriverAttach;
+ g_tstUsbHlp.pfnTimerCreate = tstTimerCreate;
+ g_tstUsbHlp.pfnTimerDestroy = tstTimerDestroy;
g_tstUsbHlp.pfnCFGMValidateConfig = CFGMR3ValidateConfig;
g_tstUsbHlp.pfnCFGMQueryStringDef = CFGMR3QueryStringDef;
g_tstUsbHlp.pfnCFGMQueryU8Def = CFGMR3QueryU8Def;
diff --git a/src/VBox/Devices/Network/DevPCNet.cpp b/src/VBox/Devices/Network/DevPCNet.cpp
index 49140775..10dbcd27 100644
--- a/src/VBox/Devices/Network/DevPCNet.cpp
+++ b/src/VBox/Devices/Network/DevPCNet.cpp
@@ -3813,7 +3813,9 @@ static DECLCALLBACK(VBOXSTRICTRC) pcnetR3MmioRead(PPDMDEVINS pDevIns, void *pvUs
case 2: rc = pcnetR3MmioReadU16(pDevIns, pThis, pThisCC, off, (uint16_t *)pv); break;
case 4: rc = pcnetR3MmioReadU32(pDevIns, pThis, pThisCC, off, (uint32_t *)pv); break;
default:
+ memset(pv, 0, cb);
rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "pcnetR3MmioRead: unsupported op size: address=%RGp cb=%u\n", off, cb);
+ break;
}
STAM_PROFILE_ADV_STOP(&pThis->CTX_SUFF_Z(StatMMIORead), a);
}
diff --git a/src/VBox/Devices/Network/SrvIntNetR0.cpp b/src/VBox/Devices/Network/SrvIntNetR0.cpp
index 1a2b055d..728cd25a 100644
--- a/src/VBox/Devices/Network/SrvIntNetR0.cpp
+++ b/src/VBox/Devices/Network/SrvIntNetR0.cpp
@@ -4104,9 +4104,16 @@ INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession)
* Process the send buffer.
*/
INTNETSWDECISION enmSwDecision = INTNETSWDECISION_BROADCAST;
- INTNETSG Sg; /** @todo this will have to be changed if we're going to use async sending
- * with buffer sharing for some OS or service. Darwin copies everything so
- * I won't bother allocating and managing SGs right now. Sorry. */
+
+ /** @todo this will have to be changed if we're going to use async sending
+ * with buffer sharing for some OS or service. Darwin copies everything so
+ * I won't bother allocating and managing SGs right now. Sorry. */
+ union
+ {
+ uint8_t abBuf[sizeof(INTNETSG) + sizeof(INTNETSEG)];
+ INTNETSG SG;
+ } u;
+
PINTNETHDR pHdr;
while ((pHdr = IntNetRingGetNextFrameToRead(&pIf->pIntBuf->Send)) != NULL)
{
@@ -4115,10 +4122,10 @@ INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession)
{
/* Send regular frame. */
void *pvCurFrame = IntNetHdrGetFramePtr(pHdr, pIf->pIntBuf);
- IntNetSgInitTemp(&Sg, pvCurFrame, pHdr->cbFrame);
+ IntNetSgInitTemp(&u.SG, pvCurFrame, pHdr->cbFrame);
if (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
- intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame, false /*fGso*/, (uint16_t *)&Sg.fFlags);
- enmSwDecision = intnetR0NetworkSend(pNetwork, pIf, 0 /*fSrc*/, &Sg, pDstTab);
+ intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame, false /*fGso*/, (uint16_t *)&u.SG.fFlags);
+ enmSwDecision = intnetR0NetworkSend(pNetwork, pIf, 0 /*fSrc*/, &u.SG, pDstTab);
}
else if (u8Type == INTNETHDR_TYPE_GSO)
{
@@ -4128,10 +4135,10 @@ INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession)
if (RT_LIKELY(PDMNetGsoIsValid(pGso, pHdr->cbFrame, cbFrame)))
{
void *pvCurFrame = pGso + 1;
- IntNetSgInitTempGso(&Sg, pvCurFrame, cbFrame, pGso);
+ IntNetSgInitTempGso(&u.SG, pvCurFrame, cbFrame, pGso);
if (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
- intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, cbFrame, true /*fGso*/, (uint16_t *)&Sg.fFlags);
- enmSwDecision = intnetR0NetworkSend(pNetwork, pIf, 0 /*fSrc*/, &Sg, pDstTab);
+ intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, cbFrame, true /*fGso*/, (uint16_t *)&u.SG.fFlags);
+ enmSwDecision = intnetR0NetworkSend(pNetwork, pIf, 0 /*fSrc*/, &u.SG, pDstTab);
}
else
{
diff --git a/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp b/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
index 5cb94894..515f2065 100644
--- a/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
+++ b/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp
@@ -203,9 +203,13 @@ INTNETR3DECL(int) SUPR0MemFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr)
static int tstIntNetSendBuf(PINTNETRINGBUF pRingBuf, INTNETIFHANDLE hIf,
PSUPDRVSESSION pSession, void const *pvBuf, size_t cbBuf)
{
- INTNETSG Sg;
- IntNetSgInitTemp(&Sg, (void *)pvBuf, (uint32_t)cbBuf);
- int rc = intnetR0RingWriteFrame(pRingBuf, &Sg, NULL);
+ union
+ {
+ uint8_t abBuf[sizeof(INTNETSG) + sizeof(INTNETSEG)];
+ INTNETSG SG;
+ } u;
+ IntNetSgInitTemp(&u.SG, (void *)pvBuf, (uint32_t)cbBuf);
+ int rc = intnetR0RingWriteFrame(pRingBuf, &u.SG, NULL);
if (RT_SUCCESS(rc))
rc = IntNetR0IfSend(hIf, pSession);
return rc;
@@ -269,9 +273,13 @@ static DECLCALLBACK(int) SendThread(RTTHREAD hThreadSelf, void *pvArg)
: iFrame % 1519 + sizeof(RTMAC) * 2 + sizeof(unsigned);
pHdr->iFrame = iFrame;
- INTNETSG Sg;
- IntNetSgInitTemp(&Sg, abBuf, cb);
- RTTEST_CHECK_RC_OK(g_hTest, rc = intnetR0RingWriteFrame(&pArgs->pBuf->Send, &Sg, NULL));
+ union
+ {
+ uint8_t abBuf[sizeof(INTNETSG) + sizeof(INTNETSEG)];
+ INTNETSG SG;
+ } u;
+ IntNetSgInitTemp(&u.SG, abBuf, cb);
+ RTTEST_CHECK_RC_OK(g_hTest, rc = intnetR0RingWriteFrame(&pArgs->pBuf->Send, &u.SG, NULL));
if (RT_SUCCESS(rc))
RTTEST_CHECK_RC_OK(g_hTest, rc = IntNetR0IfSend(pArgs->hIf, g_pSession));
if (RT_FAILURE(rc) && ++cErrors > 64)
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
index 050ae0c2..5b6da227 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
@@ -1621,7 +1621,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xcda class=DATA group=DGROUP
section CONST2 progbits vstart=0xdca align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0dca LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0dca 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0dca LB 0x12
- db 'VirtualBox 7.0.14', 000h
+ db 'VirtualBox 7.0.16', 000h
; disGetNextSymbol 0xf0ddc LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0ddc '_bios_prefix_string'
_bios_prefix_string: ; 0xf0ddc LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19429,4 +19429,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0d8h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0d6h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
index 90f623ca..556bdbe3 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
@@ -1 +1 @@
-21db2300f54bae35aef5b24839864806 *VBoxPcBios286.rom
+574c2c72048d5a5c9c079fbf47683b0f *VBoxPcBios286.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
index 2b0294cc..a3231d00 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
@@ -1566,7 +1566,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xd14 class=DATA group=DGROUP
section CONST2 progbits vstart=0xe04 align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0e04 LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0e04 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0e04 LB 0x12
- db 'VirtualBox 7.0.14', 000h
+ db 'VirtualBox 7.0.16', 000h
; disGetNextSymbol 0xf0e16 LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0e16 '_bios_prefix_string'
_bios_prefix_string: ; 0xf0e16 LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19195,4 +19195,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 036h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 034h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
index 0ff07b1e..80cc8e0a 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
@@ -1 +1 @@
-b0137ac614de33e88bea424380fe32be *VBoxPcBios386.rom
+951bc82dd1a8482863248e9157928f1b *VBoxPcBios386.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
index 263b9f5c..92665f77 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
@@ -1621,7 +1621,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xcda class=DATA group=DGROUP
section CONST2 progbits vstart=0xdca align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0dca LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0dca 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0dca LB 0x12
- db 'VirtualBox 7.0.14', 000h
+ db 'VirtualBox 7.0.16', 000h
; disGetNextSymbol 0xf0ddc LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0ddc '_bios_prefix_string'
_bios_prefix_string: ; 0xf0ddc LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19906,4 +19906,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fbh, 0bdh
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fbh, 0bbh
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
index 7746ce56..95f06271 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
@@ -1 +1 @@
-341856987bd565a025d1f9896927c8a6 *VBoxPcBios8086.rom
+0704d20fb86b2ca3eba57b2ca2f9e135 *VBoxPcBios8086.rom
diff --git a/src/VBox/Devices/Serial/DevOxPcie958.cpp b/src/VBox/Devices/Serial/DevOxPcie958.cpp
index e9cccd0b..1cfb2dd1 100644
--- a/src/VBox/Devices/Serial/DevOxPcie958.cpp
+++ b/src/VBox/Devices/Serial/DevOxPcie958.cpp
@@ -247,10 +247,23 @@ static VBOXSTRICTRC ox958UartRegRead(PPDMDEVINS pDevIns, PDEVOX958 pThis, POX958
if (offUartReg >= OX958_REG_UART_DMA_REGION_OFFSET)
{
/* Access to the DMA registers. */
- rc = VINF_SUCCESS;
+ rc = VINF_IOM_MMIO_UNUSED_00; /** @todo Misses implementation, just pretend there is nothing there yet. */
}
else /* Access UART registers. */
- rc = uartRegRead(pDevIns, &pUart->UartCore, &pUartCC->UartCore, offUartReg, (uint32_t *)pv, cb);
+ {
+ AssertReturn(cb == 1, VINF_IOM_MMIO_UNUSED_00);
+
+ uint32_t u32 = 0;
+ rc = uartRegRead(pDevIns, &pUart->UartCore, &pUartCC->UartCore, offUartReg, &u32, 1);
+ Assert(rc == VINF_SUCCESS || rc == VINF_IOM_R3_IOPORT_READ);
+
+ if (rc == VINF_SUCCESS)
+ *(uint8_t *)pv = (uint8_t)u32;
+ else if (rc == VERR_IOM_IOPORT_UNUSED)
+ rc = VINF_IOM_MMIO_UNUSED_00;
+ else if (rc == VINF_IOM_R3_IOPORT_READ)
+ rc = VINF_IOM_R3_MMIO_READ;
+ }
return rc;
}
@@ -280,7 +293,15 @@ static VBOXSTRICTRC ox958UartRegWrite(PPDMDEVINS pDevIns, PDEVOX958 pThis, POX95
rc = VINF_SUCCESS;
}
else /* Access UART registers. */
- rc = uartRegWrite(pDevIns, &pUart->UartCore, &pUartCC->UartCore, offUartReg, *(const uint32_t *)pv, cb);
+ {
+ AssertReturn(cb == 1, VINF_SUCCESS);
+
+ rc = uartRegWrite(pDevIns, &pUart->UartCore, &pUartCC->UartCore, offUartReg, *(const uint8_t *)pv, 1);
+ Assert(rc == VINF_SUCCESS || rc == VINF_IOM_R3_IOPORT_WRITE);
+
+ if (rc == VINF_IOM_R3_IOPORT_WRITE)
+ rc = VINF_IOM_R3_MMIO_WRITE;
+ }
return rc;
}
@@ -319,8 +340,8 @@ static DECLCALLBACK(VBOXSTRICTRC) ox958MmioRead(PPDMDEVINS pDevIns, void *pvUser
if (off < OX958_REG_UART_REGION_OFFSET)
{
+ AssertReturn(cb == 4, VINF_IOM_MMIO_UNUSED_00);
uint32_t *pu32 = (uint32_t *)pv;
- Assert(cb == 4);
switch ((uint32_t)off)
{
@@ -360,8 +381,6 @@ static DECLCALLBACK(VBOXSTRICTRC) ox958MmioRead(PPDMDEVINS pDevIns, void *pvUser
POX958UART pUart = &pThis->aUarts[iUart];
POX958UARTCC pUartCC = &pThisCC->aUarts[iUart];
rc = ox958UartRegRead(pDevIns, pThis, pUart, pUartCC, offUartReg, pv, cb);
- if (rc == VINF_IOM_R3_IOPORT_READ)
- rc = VINF_IOM_R3_MMIO_READ;
}
else
rc = VINF_IOM_MMIO_UNUSED_00;
@@ -383,8 +402,8 @@ static DECLCALLBACK(VBOXSTRICTRC) ox958MmioWrite(PPDMDEVINS pDevIns, void *pvUse
if (off < OX958_REG_UART_REGION_OFFSET)
{
+ AssertReturn(cb == 4, VINF_SUCCESS);
const uint32_t u32 = *(const uint32_t *)pv;
- Assert(cb == 4);
switch ((uint32_t)off)
{
@@ -420,8 +439,6 @@ static DECLCALLBACK(VBOXSTRICTRC) ox958MmioWrite(PPDMDEVINS pDevIns, void *pvUse
POX958UART pUart = &pThis->aUarts[iUart];
POX958UARTCC pUartCC = &pThisCC->aUarts[iUart];
rc = ox958UartRegWrite(pDevIns, pThis, pUart, pUartCC, offUartReg, pv, cb);
- if (rc == VINF_IOM_R3_IOPORT_WRITE)
- rc = VINF_IOM_R3_MMIO_WRITE;
}
}
diff --git a/src/VBox/Devices/Storage/DevAHCI.cpp b/src/VBox/Devices/Storage/DevAHCI.cpp
index 199dc04f..f77f5c28 100644
--- a/src/VBox/Devices/Storage/DevAHCI.cpp
+++ b/src/VBox/Devices/Storage/DevAHCI.cpp
@@ -1912,7 +1912,7 @@ static VBOXSTRICTRC PortInvalid_r(PPDMDEVINS pDevIns, PAHCI pThis, PAHCIPORT pAh
{
RT_NOREF(pDevIns, pThis, pAhciPort, iReg, pu32Value);
ahciLog(("%s: Read denied!!! iReg=%u\n", __FUNCTION__, iReg));
- return VINF_SUCCESS;
+ return VINF_IOM_MMIO_UNUSED_00;
}
/**
@@ -2356,10 +2356,10 @@ ahciLegacyFakeWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t
static DECLCALLBACK(VBOXSTRICTRC)
ahciLegacyFakeRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)
{
- /** @todo we should set *pu32 to something. */
- RT_NOREF(pDevIns, pvUser, offPort, pu32, cb);
+ *pu32 = 0;
+ RT_NOREF(pDevIns, pvUser, offPort, cb);
ASSERT_GUEST_MSG_FAILED(("Should not happen\n"));
- return VINF_SUCCESS;
+ return VERR_IOM_IOPORT_UNUSED;
}
diff --git a/src/VBox/Devices/Storage/DevBusLogic.cpp b/src/VBox/Devices/Storage/DevBusLogic.cpp
index a5cf9f9a..21f59250 100644
--- a/src/VBox/Devices/Storage/DevBusLogic.cpp
+++ b/src/VBox/Devices/Storage/DevBusLogic.cpp
@@ -979,10 +979,12 @@ typedef struct ESCMD
unsigned char uReserved2 : 3;
/** Length of the SCSI CDB. */
uint8_t cbCDB;
- /** The SCSI CDB. (A CDB can be 12 bytes long.) */
- uint8_t abCDB[12];
+ /** The SCSI CDB. (A CDB from our BIOS can be up to 16 bytes long
+ * which works with our emulation even though the original BusLogic HBA
+ * supports only 12 byte CDBs). */
+ uint8_t abCDB[16];
} ESCMD, *PESCMD;
-AssertCompileSize(ESCMD, 24);
+AssertCompileSize(ESCMD, 28);
/**
* Task state for a CCB request.
@@ -3161,7 +3163,8 @@ static int buslogicR3DeviceSCSIRequestSetup(PPDMDEVINS pDevIns, PBUSLOGIC pThis,
blPhysReadMeta(pDevIns, pThis, GCPhysAddrCCB, &CCBGuest, sizeof(CCB32));
uTargetIdCCB = pThis->fMbxIs24Bit ? CCBGuest.o.uTargetId : CCBGuest.n.uTargetId;
- if (RT_LIKELY(uTargetIdCCB < RT_ELEMENTS(pThisCC->aDeviceStates)))
+ if ( RT_LIKELY(uTargetIdCCB < RT_ELEMENTS(pThisCC->aDeviceStates))
+ && CCBGuest.c.cbCDB <= RT_ELEMENTS(CCBGuest.c.abCDB))
{
PBUSLOGICDEVICE pTgtDev = &pThisCC->aDeviceStates[uTargetIdCCB];
@@ -3378,7 +3381,7 @@ static void buslogicR3ProcessBiosReq(PPDMDEVINS pDevIns, PBUSLOGIC pThis, PBUSLO
PESCMD pCmd = (PESCMD)pThis->aCommandBuffer;
if (RT_LIKELY( pCmd->uTargetId < RT_ELEMENTS(pThisCC->aDeviceStates)
- && pCmd->cbCDB <= 16))
+ && pCmd->cbCDB <= RT_ELEMENTS(pCmd->abCDB)))
{
PBUSLOGICDEVICE pTgtDev = &pThisCC->aDeviceStates[pCmd->uTargetId];
diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
index b089f3c4..626f531d 100644
--- a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
+++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
@@ -2295,7 +2295,8 @@ static int lsilogicR3ProcessSCSIIORequest(PPDMDEVINS pDevIns, PLSILOGICSCSI pThi
{
PLSILOGICDEVICE pTgtDev = &pThisCC->paDeviceStates[pGuestReq->SCSIIO.u8TargetID];
- if (pTgtDev->pDrvBase)
+ if ( pTgtDev->pDrvBase
+ && pGuestReq->SCSIIO.u8CDBLength <= RT_ELEMENTS(pGuestReq->SCSIIO.au8CDB))
{
/* Allocate and prepare a new request. */
PDMMEDIAEXIOREQ hIoReq;
@@ -2364,12 +2365,12 @@ static int lsilogicR3ProcessSCSIIORequest(PPDMDEVINS pDevIns, PLSILOGICSCSI pThi
if (g_cLogged++ < MAX_REL_LOG_ERRORS)
{
- LogRel(("LsiLogic#%d: %d/%d (Bus/Target) doesn't exist\n", pDevIns->iInstance,
- pGuestReq->SCSIIO.u8TargetID, pGuestReq->SCSIIO.u8Bus));
+ LogRel(("LsiLogic#%d: %d/%d/%d (Bus/Target/CDBLength) doesn't exist\n", pDevIns->iInstance,
+ pGuestReq->SCSIIO.u8TargetID, pGuestReq->SCSIIO.u8Bus, pGuestReq->SCSIIO.u8CDBLength));
/* Log the CDB too */
LogRel(("LsiLogic#%d: Guest issued CDB {%#x",
pDevIns->iInstance, pGuestReq->SCSIIO.au8CDB[0]));
- for (unsigned i = 1; i < pGuestReq->SCSIIO.u8CDBLength; i++)
+ for (unsigned i = 1; i < RT_MIN(pGuestReq->SCSIIO.u8CDBLength, RT_ELEMENTS(pGuestReq->SCSIIO.au8CDB)); i++)
LogRel((", %#x", pGuestReq->SCSIIO.au8CDB[i]));
LogRel(("}\n"));
}
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
index a2864b84..2b8a9a07 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
@@ -67,6 +67,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
{
bool fProcessed = true;
+ if (!pVScsiReq->cbCDB)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ return true;
+ }
+
switch (pVScsiReq->pbCDB[0])
{
case SCSI_INQUIRY:
@@ -92,6 +99,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
}
case SCSI_REPORT_LUNS:
{
+ if (pVScsiReq->cbCDB < 10)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
/*
* If allocation length is less than 16 bytes SPC compliant devices have
* to return an error.
@@ -127,6 +141,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
}
case SCSI_REQUEST_SENSE:
{
+ if (pVScsiReq->cbCDB < 5)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
vscsiReqSetXferDir(pVScsiReq, VSCSIXFERDIR_T2I);
vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
@@ -140,6 +161,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
#if 0
case SCSI_MAINTENANCE_IN:
{
+ if (pVScsiReq->cbCDB < 8)
+ {
+ *prcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
if (pVScsiReq->pbCDB[1] == SCSI_MAINTENANCE_IN_REPORT_SUPP_OPC)
{
/*
@@ -374,7 +402,26 @@ VBOXDDU_DECL(int) VSCSIDeviceReqEnqueue(VSCSIDEVICE hVScsiDevice, VSCSIREQ hVScs
if (vscsiDeviceLunIsPresent(pVScsiDevice, pVScsiReq->iLun))
{
PVSCSILUNINT pVScsiLun = pVScsiDevice->papVScsiLun[pVScsiReq->iLun];
- rc = pVScsiLun->pVScsiLunDesc->pfnVScsiLunReqProcess(pVScsiLun, pVScsiReq);
+ PVSCSILUNDESC pVScsiLunDesc = pVScsiLun->pVScsiLunDesc;
+ uint8_t const bOpc = pVScsiReq->pbCDB[0];
+ uint8_t const cbCdbMin = pVScsiLunDesc->pacbCdbOpc[bOpc];
+
+ /* Fail if the opcode is not supported or the CDB is too short. */
+ if ( cbCdbMin != VSCSI_LUN_CDB_SZ_INVALID
+ && pVScsiReq->cbCDB >= cbCdbMin)
+ rc = pVScsiLunDesc->pfnVScsiLunReqProcess(pVScsiLun, pVScsiReq);
+ else
+ {
+ /*
+ * CDB length is smaller than what the LUN expects, respond with an
+ * ILLEGAL OPCODE error.
+ */
+ vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+
+ vscsiDeviceReqComplete(pVScsiDevice, pVScsiReq,
+ SCSI_STATUS_CHECK_CONDITION, false, VINF_SUCCESS);
+ }
}
else
{
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h b/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
index 71924d1d..b4af0cb5 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
@@ -241,6 +241,25 @@ typedef const VSCSILUNSUPOPC *PCVSCSILUNSUPOPC;
{ a_u8Opc, a_u16SvcAction, VSCSI_LUN_SUP_OPC_SVC_ACTION_REQUIRED, a_pszOpc, a_cbCdb, a_pbCdbUsage, 0, 0, 0}
/** @} */
+/** @name Helper macros to specify a range of not supported CDB opcodes for the entries pointed
+ * to by VSCSILUNDESC::pacbCdbOpc.
+ * @{ */
+#define VSCSI_LUN_CDB_SZ_INVALID 0
+#define VSCSI_LUN_CDB_SZ_INVALID_X2 \
+ VSCSI_LUN_CDB_SZ_INVALID, \
+ VSCSI_LUN_CDB_SZ_INVALID
+#define VSCSI_LUN_CDB_SZ_INVALID_X4 \
+ VSCSI_LUN_CDB_SZ_INVALID_X2, \
+ VSCSI_LUN_CDB_SZ_INVALID_X2
+#define VSCSI_LUN_CDB_SZ_INVALID_X8 \
+ VSCSI_LUN_CDB_SZ_INVALID_X4, \
+ VSCSI_LUN_CDB_SZ_INVALID_X4
+#define VSCSI_LUN_CDB_SZ_INVALID_X16 \
+ VSCSI_LUN_CDB_SZ_INVALID_X8, \
+ VSCSI_LUN_CDB_SZ_INVALID_X8
+/** @} */
+
+
/**
* Virtual SCSI LUN descriptor.
*/
@@ -252,6 +271,9 @@ typedef struct VSCSILUNDESC
const char *pcszDescName;
/** LUN type size */
size_t cbLun;
+ /** Pointer to the array holding the CDB length indexed by the opcode.
+ * A 0 entry means opcode not supported (CDB must be at least 1 byte big). */
+ const uint8_t *pacbCdbOpc;
/** Number of entries in the supported operation codes array. */
uint32_t cSupOpcInfo;
/** Pointer to the array of supported operation codes for the
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp
index 66d76e22..24fc6a33 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp
@@ -1770,6 +1770,115 @@ static DECLCALLBACK(int) vscsiLunMmcMediumRemoved(PVSCSILUNINT pVScsiLun)
}
+/**
+ * The supported operation codes for the MMC LUN type.
+ *
+ * @note This gives the minimum size required by our implementation
+ * which may be smaller than what the spec defines (for example
+ * we do not access the control byte at the end).
+ */
+static uint8_t s_acbCdbOpc[] =
+{
+ 1, /**< 0x00 TEST UNIT READY */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x01 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x02 - 0x03 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x04 - 0x07 Invalid */
+ 5, /**< 0x08 READ (6) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x09 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x0a - 0x0b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x0c - 0x0f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x10 - 0x11 Invalid */
+ 5, /**< 0x12 INQUIRY */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x13 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x14 Invalid */
+ 5, /**< 0x15 MODE SELECT (6) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x16 - 0x17 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x18 - 0x19 Invalid */
+ 5, /**< 0x1a MODE SENSE (6) */
+ 5, /**< 0x1b START STOP UNIT */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x1c - 0x1d Invalid */
+ 5, /**< 0x1e PREVENT ALLOW MEDIUM REMOVAL */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x1f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x20 - 0x23 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x24 Invalid */
+ 1, /**< 0x25 READ CAPACITY */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x26 - 0x27 Invalid */
+ 9, /**< 0x28 READ (10) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x29 - 0x2a Invalid */
+ 6, /**< 0x2b SEEK (10) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x2c - 0x2d Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x2e Invalid */
+ 5, /**< 0x2f VERIFY (10) */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x30 - 0x37 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x38 - 0x3b Invalid */
+ 8, /**< 0x3c READ BUFFER */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x3d Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x3e - 0x3f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x40 - 0x41 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x42 Invalid */
+ 9, /**< 0x43 READ TOC PMA ATIP */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x44 - 0x45 Invalid */
+ 9, /**< 0x46 GET CONFIGURATION */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x47 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x48 - 0x49 Invalid */
+ 9, /**< 0x4a GET EVENT STATUS NOTIFICATION */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x4b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x4c Invalid */
+ 9, /**< 0x4d LOG SENSE */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x4e - 0x4f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x50 Invalid */
+ 9, /**< 0x51 READ DISC INFORMATION */
+ 9, /**< 0x52 READ TRACK INFORMATION */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x53 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x54 - 0x57 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x58 - 0x59 Invalid */
+ 9, /**< 0x5a MODE SENSE (10) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x5b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x5c - 0x5f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x60 - 0x6f Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x70 - 0x7f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x80 - 0x87 Invalid */
+ 14, /**< 0x88 READ (16) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x89 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x8a - 0x8b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x8c - 0x8f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x90 - 0x97 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x98 - 0x9b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x9c - 0x9d Invalid */
+ 2, /**< 0x9e SERVICE ACTION IN (16) (at least 2). */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x9f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0xa0 - 0xa7 Invalid */
+ 10, /**< 0xa8 READ (12) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xa9 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0xaa - 0xab Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xac Invalid */
+ 10, /**< 0xad READ DVD STRUCTURE */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0xae - 0xaf Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0xb0 - 0xb7 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0xb8 - 0xbb Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xbc Invalid */
+ 10, /**< 0xbd MECHANISM STATUS */
+ 10, /**< 0xbe READ CD */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xbf Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xc0 - 0xcf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xd0 - 0xdf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xe0 - 0xef Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16 /**< 0xf0 - 0xff Invalid */
+};
+AssertCompileSize(s_acbCdbOpc, 256 * sizeof(uint8_t));
+
+
VSCSILUNDESC g_VScsiLunTypeMmc =
{
/** enmLunType */
@@ -1778,6 +1887,8 @@ VSCSILUNDESC g_VScsiLunTypeMmc =
"MMC",
/** cbLun */
sizeof(VSCSILUNMMC),
+ /** pacbCdbOpc */
+ &s_acbCdbOpc[0],
/** cSupOpcInfo */
0,
/** paSupOpcInfo */
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
index 3769c4f6..3fb5436e 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
@@ -230,30 +230,35 @@ static DECLCALLBACK(int) vscsiLunSbcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQ
SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
else
{
- SCSIINQUIRYDATA ScsiInquiryReply;
+ if (pVScsiReq->cbCDB >= 5)
+ {
+ SCSIINQUIRYDATA ScsiInquiryReply;
- vscsiReqSetXferSize(pVScsiReq, RT_MIN(sizeof(SCSIINQUIRYDATA), scsiBE2H_U16(&pVScsiReq->pbCDB[3])));
- memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
+ vscsiReqSetXferSize(pVScsiReq, RT_MIN(sizeof(SCSIINQUIRYDATA), scsiBE2H_U16(&pVScsiReq->pbCDB[3])));
+ memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
- ScsiInquiryReply.cbAdditional = 31;
- ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS;
- ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED;
- ScsiInquiryReply.u3AnsiVersion = 0x05; /* SPC-4 compliant */
- ScsiInquiryReply.fCmdQue = 1; /* Command queuing supported. */
- ScsiInquiryReply.fWBus16 = 1;
+ ScsiInquiryReply.cbAdditional = 31;
+ ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS;
+ ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED;
+ ScsiInquiryReply.u3AnsiVersion = 0x05; /* SPC-4 compliant */
+ ScsiInquiryReply.fCmdQue = 1; /* Command queuing supported. */
+ ScsiInquiryReply.fWBus16 = 1;
- const char *pszVendorId = "VBOX";
- const char *pszProductId = "HARDDISK";
- const char *pszProductLevel = "1.0";
- int rcTmp = vscsiLunQueryInqStrings(pVScsiLun, &pszVendorId, &pszProductId, &pszProductLevel);
- Assert(RT_SUCCESS(rcTmp) || rcTmp == VERR_NOT_FOUND); RT_NOREF(rcTmp);
+ const char *pszVendorId = "VBOX";
+ const char *pszProductId = "HARDDISK";
+ const char *pszProductLevel = "1.0";
+ int rcTmp = vscsiLunQueryInqStrings(pVScsiLun, &pszVendorId, &pszProductId, &pszProductLevel);
+ Assert(RT_SUCCESS(rcTmp) || rcTmp == VERR_NOT_FOUND); RT_NOREF(rcTmp);
- scsiPadStrS(ScsiInquiryReply.achVendorId, pszVendorId, 8);
- scsiPadStrS(ScsiInquiryReply.achProductId, pszProductId, 16);
- scsiPadStrS(ScsiInquiryReply.achProductLevel, pszProductLevel, 4);
+ scsiPadStrS(ScsiInquiryReply.achVendorId, pszVendorId, 8);
+ scsiPadStrS(ScsiInquiryReply.achProductId, pszProductId, 16);
+ scsiPadStrS(ScsiInquiryReply.achProductLevel, pszProductLevel, 4);
- RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
- rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
+ RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
+ rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
+ }
+ else
+ rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INVALID_MESSAGE, 0x00);
}
break;
}
@@ -419,7 +424,7 @@ static DECLCALLBACK(int) vscsiLunSbcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQ
uint8_t uDataMode = pVScsiReq->pbCDB[1] & 0x1f;
vscsiReqSetXferDir(pVScsiReq, VSCSIXFERDIR_T2I);
- vscsiReqSetXferSize(pVScsiReq, scsiBE2H_U16(&pVScsiReq->pbCDB[6]));
+ vscsiReqSetXferSize(pVScsiReq, scsiBE2H_U24(&pVScsiReq->pbCDB[6]));
switch (uDataMode)
{
@@ -627,6 +632,92 @@ static DECLCALLBACK(int) vscsiLunSbcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQ
return rc;
}
+
+/**
+ * The supported operation codes for the SBC LUN type.
+ *
+ * @note This gives the minimum size required by our implementation
+ * which may be smaller than what the spec defines (for example
+ * we do not access the control byte at the end).
+ */
+static uint8_t s_acbCdbOpc[] =
+{
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x00 - 0x07 Invalid */
+ 5, /**< 0x08 READ (6) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x09 Invalid */
+ 5, /**< 0x0a WRITE (6) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x0b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x0c - 0x0f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x10 - 0x11 Invalid */
+ 3, /**< 0x12 INQUIRY (at least 3) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x13 - 0x14 Invalid */
+ 5, /**< 0x15 MODE SELECT (6) */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x16 - 0x19 Invalid */
+ 5, /**< 0x1a MODE SENSE (6) */
+ 1, /**< 0x1b START STOP UNIT */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x1c - 0x1f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x20 - 0x23 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x24 Invalid */
+ 1, /**< 0x25 READ CAPACITY */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x26 - 0x27 Invalid */
+ 9, /**< 0x28 READ (10) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x29 Invalid */
+ 9, /**< 0x2a WRITE (10) */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x2b - 0x2e Invalid */
+ 1, /**< 0x2f VERIFY (10) */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x30 - 0x33 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x34 Invalid */
+ 1, /**< 0x35 SYNCHRONIZE CACHE */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x36 - 0x39 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x3a - 0x3b Invalid */
+ 8, /**< 0x3c READ BUFFER */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x3d Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x3e - 0x3f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x40 - 0x41 Invalid */
+ 9, /**< 0x42 UNMAP */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x43 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x44 - 0x4b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x4c Invalid */
+ 9, /**< 0x4d LOG SENSE */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x4e - 0x4f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x50 - 0x5f Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x60 - 0x6f Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x70 - 0x7f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x80 - 0x87 Invalid */
+ 14, /**< 0x88 READ (16) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x89 Invalid */
+ 14, /**< 0x8a WRITE (16) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x8b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x8c - 0x8f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x90 - 0x97 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x98 - 0x9b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x9c - 0x9d Invalid */
+ 2, /**< 0x9e SERVICE ACTION IN (16) (at least 2). */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x9f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0xa0 - 0xa7 Invalid */
+ 10, /**< 0xa8 READ (12) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xa9 Invalid */
+ 10, /**< 0xaa WRITE (12) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xab Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0xac - 0xaf Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xb0 - 0xbf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xc0 - 0xcf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xd0 - 0xdf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xe0 - 0xef Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16 /**< 0xf0 - 0xff Invalid */
+};
+AssertCompileSize(s_acbCdbOpc, 256 * sizeof(uint8_t));
+
+
VSCSILUNDESC g_VScsiLunTypeSbc =
{
/** enmLunType */
@@ -635,6 +726,8 @@ VSCSILUNDESC g_VScsiLunTypeSbc =
"SBC",
/** cbLun */
sizeof(VSCSILUNSBC),
+ /** pacbCdbOpc */
+ &s_acbCdbOpc[0],
/** cSupOpcInfo */
0,
/** paSupOpcInfo */
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp
index 4c659a2d..a190ff65 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp
@@ -450,6 +450,8 @@ VSCSILUNDESC g_VScsiLunTypeSsc =
"SSC",
/** cbLun */
sizeof(VSCSILUNSSC),
+ /** pacbCdbOpc */
+ NULL,
/** cSupOpcInfo */
0,
/** paSupOpcInfo */
diff --git a/src/VBox/Devices/USB/DevEHCI.cpp b/src/VBox/Devices/USB/DevEHCI.cpp
index ade53208..1ca85af3 100644
--- a/src/VBox/Devices/USB/DevEHCI.cpp
+++ b/src/VBox/Devices/USB/DevEHCI.cpp
@@ -1623,7 +1623,7 @@ DECLINLINE(void) ehciR3DumpQTD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLi
if (GCPhys == ((RTGCPHYS)qtd.Next.Pointer << EHCI_TD_PTR_SHIFT))
break; /* detect if list item is self-cycled. */
- GCPhys = qtd.Next.Pointer << EHCI_TD_PTR_SHIFT;
+ GCPhys = (RTGCPHYS)qtd.Next.Pointer << EHCI_TD_PTR_SHIFT;
if (GCPhys == GCPhysHead)
break;
@@ -1659,7 +1659,7 @@ DECLINLINE(void) ehciR3DumpQTD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLi
if (GCPhys == ((RTGCPHYS)qtd.AltNext.Pointer << EHCI_TD_PTR_SHIFT))
break; /* detect if list item is self-cycled. */
- GCPhys = qtd.AltNext.Pointer << EHCI_TD_PTR_SHIFT;
+ GCPhys = (RTGCPHYS)qtd.AltNext.Pointer << EHCI_TD_PTR_SHIFT;
if (GCPhys == GCPhysHead)
break;
@@ -1701,8 +1701,8 @@ DECLINLINE(void) ehciR3DumpQH(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLis
((RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT),
((RTGCPHYS)qhd.Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT), qhd.Overlay.OrgQTD.Next.Terminate,
((RTGCPHYS)qhd.Overlay.OrgQTD.AltNext.Pointer << EHCI_TD_PTR_SHIFT), qhd.Overlay.OrgQTD.AltNext.Terminate));
- ehciR3DumpSingleQTD(qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT, &qhd.Overlay.OrgQTD, "");
- ehciR3DumpQTD(pDevIns, qhd.Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT, true);
+ ehciR3DumpSingleQTD((RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT, &qhd.Overlay.OrgQTD, "");
+ ehciR3DumpQTD(pDevIns, (RTGCPHYS)qhd.Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT, true);
Assert(qhd.Next.Pointer || qhd.Next.Terminate);
if ( !fList
@@ -1727,7 +1727,7 @@ DECLINLINE(void) ehciR3DumpQH(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLis
if (GCPhys == ((RTGCPHYS)ptr.Pointer << EHCI_TD_PTR_SHIFT))
break; /* Looping on itself. Bad guest! */
- GCPhys = ptr.Pointer << EHCI_TD_PTR_SHIFT;
+ GCPhys = (RTGCPHYS)ptr.Pointer << EHCI_TD_PTR_SHIFT;
if (GCPhys == GCPhysHead)
break; /* break the loop */
@@ -1767,7 +1767,7 @@ DECLINLINE(void) ehciR3DumpITD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLi
if (pItd->Transaction[i].Active)
{
Log2(("T%d Len=%x Offset=%x PG=%d IOC=%d Buffer=%x\n", i, pItd->Transaction[i].Length, pItd->Transaction[i].Offset, pItd->Transaction[i].PG, pItd->Transaction[i].IOC,
- pItd->Buffer.Buffer[pItd->Transaction[i].PG].Pointer << EHCI_BUFFER_PTR_SHIFT));
+ (RTGCPHYS)pItd->Buffer.Buffer[pItd->Transaction[i].PG].Pointer << EHCI_BUFFER_PTR_SHIFT));
}
}
Assert(pItd->Next.Pointer || pItd->Next.Terminate);
@@ -1784,7 +1784,7 @@ DECLINLINE(void) ehciR3DumpITD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLi
}
/* next */
- GCPhys = pItd->Next.Pointer << EHCI_TD_PTR_SHIFT;
+ GCPhys = (RTGCPHYS)pItd->Next.Pointer << EHCI_TD_PTR_SHIFT;
}
}
@@ -2325,7 +2325,7 @@ static void ehciR3RhXferCompleteITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pTh
if ((pg + 1) >= EHCI_NUM_ITD_PAGES)
LogRelMax(10, ("EHCI: Crossing to undefined page %d in iTD at %RGp on completion.\n", pg + 1, pUrb->paTds[0].TdAddr));
- GCPhysBuf = pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
+ GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
ehciPhysWrite(pDevIns, GCPhysBuf, pb + cb1, cb2);
}
else
@@ -2409,7 +2409,7 @@ static void ehciR3RhXferCompleteQH(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThi
AssertMsg(pUrb->paTds[0].TdAddr == ((RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT),
("Out of order completion %RGp != %RGp Endpoint=%#x\n", pUrb->paTds[0].TdAddr,
((RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT), pUrb->EndPt));
- ehciR3ReadQTD(pDevIns, qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT, &qtd);
+ ehciR3ReadQTD(pDevIns, (RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT, &qtd);
/*
* Check that the URB hasn't been canceled and then try unlink the TDs.
@@ -2460,7 +2460,7 @@ static void ehciR3RhXferCompleteQH(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThi
RTGCPHYS GCPhysBuf;
unsigned cbCurTransfer;
- GCPhysBuf = qtd.Buffer.Buffer[i].Pointer << EHCI_BUFFER_PTR_SHIFT;
+ GCPhysBuf = (RTGCPHYS)qtd.Buffer.Buffer[i].Pointer << EHCI_BUFFER_PTR_SHIFT;
if (i == 0)
GCPhysBuf += qtd.Buffer.Offset.Offset;
@@ -2600,7 +2600,7 @@ static bool ehciR3RhXferErrorQH(PPDMDEVINS pDevIns, PEHCICC pThisCC, PVUSBURB pU
/* Read the whole QHD & QTD */
ehciR3ReadQHD(pDevIns, pUrb->pHci->EdAddr, &qhd);
Assert(pUrb->paTds[0].TdAddr == ((RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT));
- ehciR3ReadQTD(pDevIns, qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT, &qtd);
+ ehciR3ReadQTD(pDevIns, (RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT, &qtd);
/*
* Check if the TDs still are valid.
@@ -2737,7 +2737,7 @@ static bool ehciR3SubmitQTD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC, RT
RTGCPHYS GCPhysBuf;
unsigned cbCurTransfer;
- GCPhysBuf = pQtd->Buffer.Buffer[i].Pointer << EHCI_BUFFER_PTR_SHIFT;
+ GCPhysBuf = (RTGCPHYS)pQtd->Buffer.Buffer[i].Pointer << EHCI_BUFFER_PTR_SHIFT;
if (i == 0)
GCPhysBuf += pQtd->Buffer.Offset.Offset;
@@ -2862,7 +2862,7 @@ static bool ehciR3SubmitITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
{
const unsigned pg = pItd->Transaction[i].PG;
- GCPhysBuf = pItd->Buffer.Buffer[pg].Pointer << EHCI_BUFFER_PTR_SHIFT;
+ GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg].Pointer << EHCI_BUFFER_PTR_SHIFT;
GCPhysBuf += pItd->Transaction[i].Offset;
/* If the transfer would cross page boundary, use the next sequential PG pointer
@@ -2877,7 +2877,7 @@ static bool ehciR3SubmitITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
if ((pg + 1) >= EHCI_NUM_ITD_PAGES)
LogRelMax(10, ("EHCI: Crossing to undefined page %d in iTD at %RGp on submit.\n", pg + 1, pUrb->paTds[0].TdAddr));
- GCPhysBuf = pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
+ GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
ehciPhysRead(pDevIns, GCPhysBuf, &pUrb->abData[curOffset + cb1], cb2);
}
else
@@ -3024,7 +3024,7 @@ static void ehciR3QHUpdateOverlay(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThis
if (!pQhd->Overlay.OrgQTD.Next.Terminate)
{
EHCI_QTD qtdNext;
- RTGCPHYS GCPhysNextQTD = pQhd->Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT;
+ RTGCPHYS GCPhysNextQTD = (RTGCPHYS)pQhd->Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT;
if (ehciR3IsTdInFlight(pThisCC, GCPhysNextQTD))
{
@@ -3073,7 +3073,7 @@ static RTGCPHYS ehciR3ServiceQTD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisC
|| GCPhysQTD == (RTGCPHYS)pQhd->CurrQTD.Pointer << EHCI_TD_PTR_SHIFT)
ehciR3QHSetupOverlay(pDevIns, pQhd, GCPhysQHD, &qtd, GCPhysQTD);
else
- Log2Func(("transfer %RGp in progress -> don't update the overlay\n", (RTGCPHYS)(pQhd->CurrQTD.Pointer << EHCI_TD_PTR_SHIFT)));
+ Log2Func(("transfer %RGp in progress -> don't update the overlay\n", (RTGCPHYS)pQhd->CurrQTD.Pointer << EHCI_TD_PTR_SHIFT));
ehciR3SubmitQTD(pDevIns, pThis, pThisCC, GCPhysQHD, pQhd, GCPhysQTD, &qtd, iFrame);
@@ -3119,14 +3119,14 @@ static RTGCPHYS ehciR3ServiceQTD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisC
{
Assert(qtd.AltNext.Pointer);
Log2(("Taking alternate pointer %RGp\n", (RTGCPHYS)(qtd.AltNext.Pointer << EHCI_TD_PTR_SHIFT)));
- return qtd.AltNext.Pointer << EHCI_TD_PTR_SHIFT;
+ return (RTGCPHYS)qtd.AltNext.Pointer << EHCI_TD_PTR_SHIFT;
}
else
{
Assert(qtd.Next.Pointer || qtd.Next.Terminate);
if (qtd.Next.Terminate || !qtd.Next.Pointer)
return 0;
- return qtd.Next.Pointer << EHCI_TD_PTR_SHIFT;
+ return (RTGCPHYS)qtd.Next.Pointer << EHCI_TD_PTR_SHIFT;
}
}
@@ -3206,8 +3206,8 @@ static bool ehciR3ServiceQHD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
RTGCPHYS GCPhysQTD;
if (qhd.Overlay.OrgQTD.Token.Bits.Active)
{
- Assert(ehciR3IsTdInFlight(pThisCC, qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT));
- GCPhysQTD = qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT;
+ Assert(ehciR3IsTdInFlight(pThisCC, (RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT));
+ GCPhysQTD = (RTGCPHYS)qhd.CurrQTD.Pointer << EHCI_TD_PTR_SHIFT;
}
else
{
@@ -3216,8 +3216,8 @@ static bool ehciR3ServiceQHD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
&& qhd.Overlay.OrgQTD.Token.Bits.Length)
{
Assert(qhd.Overlay.OrgQTD.AltNext.Pointer);
- Log2(("Taking alternate pointer %RGp\n", (RTGCPHYS)(qhd.Overlay.OrgQTD.AltNext.Pointer << EHCI_TD_PTR_SHIFT)));
- GCPhysQTD = qhd.Overlay.OrgQTD.AltNext.Pointer << EHCI_TD_PTR_SHIFT;
+ Log2(("Taking alternate pointer %RGp\n", (RTGCPHYS)qhd.Overlay.OrgQTD.AltNext.Pointer << EHCI_TD_PTR_SHIFT));
+ GCPhysQTD = (RTGCPHYS)qhd.Overlay.OrgQTD.AltNext.Pointer << EHCI_TD_PTR_SHIFT;
}
else
{
@@ -3225,7 +3225,7 @@ static bool ehciR3ServiceQHD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
if (qhd.Overlay.OrgQTD.Next.Terminate || !qhd.Overlay.OrgQTD.Next.Pointer || qhd.Overlay.OrgQTD.Token.Bits.Halted)
GCPhysQTD = 0;
else
- GCPhysQTD = qhd.Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT;
+ GCPhysQTD = (RTGCPHYS)qhd.Overlay.OrgQTD.Next.Pointer << EHCI_TD_PTR_SHIFT;
}
}
@@ -3308,7 +3308,7 @@ static void ehciR3ServiceAsyncList(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThi
AssertMsgBreak(++cIterations < 128, ("Too many iterations, exiting\n"));
/* next */
- GCPhys = ptr.Pointer << EHCI_TD_PTR_SHIFT;
+ GCPhys = (RTGCPHYS)ptr.Pointer << EHCI_TD_PTR_SHIFT;
Assert(!(GCPhys & 0x1f));
if ( GCPhys == GCPhysHead
|| GCPhys == GCPhysLast)
@@ -3357,7 +3357,7 @@ static void ehciR3ServicePeriodicList(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC p
ehciR3ReadFrameListPtr(pDevIns, GCPhys, &FramePtr);
while (!FramePtr.Terminate && (pThis->cmd & EHCI_CMD_RUN))
{
- GCPhys = FramePtr.FrameAddr << EHCI_FRAME_LIST_NEXTPTR_SHIFT;
+ GCPhys = (RTGCPHYS)FramePtr.FrameAddr << EHCI_FRAME_LIST_NEXTPTR_SHIFT;
/* Process the descriptor based on its type. Note that on the periodic
* list, HCDs may (and do) mix iTDs and qHDs more or less freely.
*/
diff --git a/src/VBox/Devices/USB/DevOHCI.cpp b/src/VBox/Devices/USB/DevOHCI.cpp
index 75c28aaf..cd139e98 100644
--- a/src/VBox/Devices/USB/DevOHCI.cpp
+++ b/src/VBox/Devices/USB/DevOHCI.cpp
@@ -668,7 +668,7 @@ typedef struct OHCIOPREG
#define OHCI_INTR_START_OF_FRAME RT_BIT(2)
/** RD - Resume detect. */
#define OHCI_INTR_RESUME_DETECT RT_BIT(3)
-/** UE - Unrecoverable error. */
+/** UE - ",erable error. */
#define OHCI_INTR_UNRECOVERABLE_ERROR RT_BIT(4)
/** FNO - Frame number overflow. */
#define OHCI_INTR_FRAMENUMBER_OVERFLOW RT_BIT(5)
@@ -886,6 +886,7 @@ static void ohciR3PhysReadCacheInvalidate(POHCIPAGECACHE pPageCa
static DECLCALLBACK(void) ohciR3RhXferCompletion(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb);
static DECLCALLBACK(bool) ohciR3RhXferError(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb);
+static bool ohciR3IsTdInFlight(POHCICC pThisCC, uint32_t GCPhysTD);
static int ohciR3InFlightFind(POHCICC pThisCC, uint32_t GCPhysTD);
# if defined(VBOX_STRICT) || defined(LOG_ENABLED)
static int ohciR3InDoneQueueFind(POHCICC pThisCC, uint32_t GCPhysTD);
@@ -1917,6 +1918,13 @@ DECLINLINE(int) ohciR3InFlightFindFree(POHCICC pThisCC, const int iStart)
*/
static void ohciR3InFlightAdd(POHCI pThis, POHCICC pThisCC, uint32_t GCPhysTD, PVUSBURB pUrb)
{
+ if (ohciR3IsTdInFlight(pThisCC, GCPhysTD))
+ {
+ PPDMDEVINS pDevIns = pThisCC->pDevInsR3;
+ ohciR3RaiseUnrecoverableError(pDevIns, pThis, 10);
+ return;
+ }
+
int i = ohciR3InFlightFindFree(pThisCC, (GCPhysTD >> 4) % RT_ELEMENTS(pThisCC->aInFlight));
if (i >= 0)
{
@@ -1995,6 +2003,7 @@ static bool ohciR3IsTdInFlight(POHCICC pThisCC, uint32_t GCPhysTD)
return ohciR3InFlightFind(pThisCC, GCPhysTD) >= 0;
}
+#if 0
/**
* Returns a URB associated with an in-flight TD, if any.
*
@@ -2012,6 +2021,7 @@ static PVUSBURB ohciR3TdInFlightUrb(POHCICC pThisCC, uint32_t GCPhysTD)
return pThisCC->aInFlight[i].pUrb;
return NULL;
}
+#endif
/**
* Removes a in-flight TD.
@@ -3049,6 +3059,53 @@ static DECLCALLBACK(bool) ohciR3RhXferError(PVUSBIROOTHUBPORT pInterface, PVUSBU
/**
+ * Determine transfer direction from an endpoint descriptor.
+ * NB: This may fail if the direction is not valid. If it does fail,
+ * we do not raise an unrecoverable error but the caller may wish to.
+ */
+static VUSBDIRECTION ohciR3GetDirection(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC, PCOHCIED pEd)
+{
+ RT_NOREF(pThisCC);
+ RT_NOREF(pThis);
+ VUSBDIRECTION enmDir = VUSBDIRECTION_INVALID;
+
+ if (pEd->hwinfo & ED_HWINFO_ISO)
+ {
+ switch (pEd->hwinfo & ED_HWINFO_DIR)
+ {
+ case ED_HWINFO_OUT: enmDir = VUSBDIRECTION_OUT; break;
+ case ED_HWINFO_IN: enmDir = VUSBDIRECTION_IN; break;
+ default:
+ Log(("ohciR3GetDirection: Invalid direction!!!! Ed.hwinfo=%#x\n", pEd->hwinfo));
+ }
+ }
+ else
+ {
+ switch (pEd->hwinfo & ED_HWINFO_DIR)
+ {
+ case ED_HWINFO_OUT: enmDir = VUSBDIRECTION_OUT; break;
+ case ED_HWINFO_IN: enmDir = VUSBDIRECTION_IN; break;
+ default:
+ /* We must read the TD to determine direction. */
+ uint32_t TdAddr = pEd->HeadP & ED_PTR_MASK;
+ OHCITD Td;
+ ohciR3ReadTd(pDevIns, TdAddr, &Td);
+ switch (Td.hwinfo & TD_HWINFO_DIR)
+ {
+ case TD_HWINFO_OUT: enmDir = VUSBDIRECTION_OUT; break;
+ case TD_HWINFO_IN: enmDir = VUSBDIRECTION_IN; break;
+ case 0: enmDir = VUSBDIRECTION_SETUP; break;
+ default:
+ Log(("ohciR3GetDirection: Invalid direction!!!! Td.hwinfo=%#x Ed.hwinfo=%#x\n", Td.hwinfo, pEd->hwinfo));
+ }
+ }
+ }
+
+ return enmDir;
+}
+
+
+/**
* Service a general transport descriptor.
*/
static bool ohciR3ServiceTd(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC, VUSBXFERTYPE enmType,
@@ -3802,10 +3859,13 @@ static void ohciR3ServiceBulkList(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThis
/* If the ED is in 'skip' state, no transactions on it are allowed and we must
* cancel outstanding URBs, if any.
*/
- uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK;
- PVUSBURB pUrb = ohciR3TdInFlightUrb(pThisCC, TdAddr);
- if (pUrb)
- pThisCC->RootHub.pIRhConn->pfnCancelUrbsEp(pThisCC->RootHub.pIRhConn, pUrb);
+ uint8_t uAddr = Ed.hwinfo & ED_HWINFO_FUNCTION;
+ uint8_t uEndPt = (Ed.hwinfo & ED_HWINFO_ENDPOINT) >> ED_HWINFO_ENDPOINT_SHIFT;
+ VUSBDIRECTION enmDir = ohciR3GetDirection(pDevIns, pThis, pThisCC, &Ed);
+ if (enmDir != VUSBDIRECTION_INVALID)
+ {
+ pThisCC->RootHub.pIRhConn->pfnAbortEpByAddr(pThisCC->RootHub.pIRhConn, uAddr, uEndPt, enmDir);
+ }
}
}
@@ -3858,9 +3918,14 @@ static void ohciR3UndoBulkList(PPDMDEVINS pDevIns, POHCI pThis, POHCICC pThisCC)
if (ohciR3IsTdInFlight(pThisCC, TdAddr))
{
LogFlow(("ohciR3UndoBulkList: Ed=%#010RX32 Ed.TailP=%#010RX32 UNDO\n", EdAddr, Ed.TailP));
- PVUSBURB pUrb = ohciR3TdInFlightUrb(pThisCC, TdAddr);
- if (pUrb)
- pThisCC->RootHub.pIRhConn->pfnCancelUrbsEp(pThisCC->RootHub.pIRhConn, pUrb);
+ /* First we need to determine the transfer direction, which may fail(!). */
+ uint8_t uAddr = Ed.hwinfo & ED_HWINFO_FUNCTION;
+ uint8_t uEndPt = (Ed.hwinfo & ED_HWINFO_ENDPOINT) >> ED_HWINFO_ENDPOINT_SHIFT;
+ VUSBDIRECTION enmDir = ohciR3GetDirection(pDevIns, pThis, pThisCC, &Ed);
+ if (enmDir != VUSBDIRECTION_INVALID)
+ {
+ pThisCC->RootHub.pIRhConn->pfnAbortEpByAddr(pThisCC->RootHub.pIRhConn, uAddr, uEndPt, enmDir);
+ }
}
}
@@ -4022,11 +4087,15 @@ static void ohciR3ServicePeriodicList(PPDMDEVINS pDevIns, POHCI pThis, POHCICC p
Log3(("ohciR3ServicePeriodicList: Ed=%#010RX32 Ed.TailP=%#010RX32 SKIP\n", EdAddr, Ed.TailP));
/* If the ED is in 'skip' state, no transactions on it are allowed and we must
* cancel outstanding URBs, if any.
+ * First we need to determine the transfer direction, which may fail(!).
*/
- uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK;
- PVUSBURB pUrb = ohciR3TdInFlightUrb(pThisCC, TdAddr);
- if (pUrb)
- pThisCC->RootHub.pIRhConn->pfnCancelUrbsEp(pThisCC->RootHub.pIRhConn, pUrb);
+ uint8_t uAddr = Ed.hwinfo & ED_HWINFO_FUNCTION;
+ uint8_t uEndPt = (Ed.hwinfo & ED_HWINFO_ENDPOINT) >> ED_HWINFO_ENDPOINT_SHIFT;
+ VUSBDIRECTION enmDir = ohciR3GetDirection(pDevIns, pThis, pThisCC, &Ed);
+ if (enmDir != VUSBDIRECTION_INVALID)
+ {
+ pThisCC->RootHub.pIRhConn->pfnAbortEpByAddr(pThisCC->RootHub.pIRhConn, uAddr, uEndPt, enmDir);
+ }
}
}
/* Trivial loop detection. */
diff --git a/src/VBox/Devices/USB/DevXHCI.cpp b/src/VBox/Devices/USB/DevXHCI.cpp
index 5df1cc5a..c8212158 100644
--- a/src/VBox/Devices/USB/DevXHCI.cpp
+++ b/src/VBox/Devices/USB/DevXHCI.cpp
@@ -1603,8 +1603,8 @@ typedef struct XHCI
uint32_t Alignment00; /**< Force alignment. */
#endif
- /** Flag indicating a sleeping worker thread. */
- volatile bool fWrkThreadSleeping;
+ /** Flag indicating a pending worker thread notification. */
+ volatile bool fNotificationSent;
volatile bool afPadding[3];
/** The event semaphore the worker thread waits on. */
@@ -2165,7 +2165,7 @@ static void xhciKickWorker(PPDMDEVINS pDevIns, PXHCI pThis, XHCI_JOB enmJob, uin
RT_NOREF(enmJob, uWorkDesc);
/* Tell the worker thread there's something to do. */
- if (ASMAtomicReadBool(&pThis->fWrkThreadSleeping))
+ if (!ASMAtomicXchgBool(&pThis->fNotificationSent, true))
{
LogFlowFunc(("Signal event semaphore\n"));
int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtProcess);
@@ -4352,18 +4352,21 @@ static unsigned xhciR3StopEndpoint(PPDMDEVINS pDevIns, PXHCI pThis, PXHCICC pThi
uint32_t uPort;
/* Abort the endpoint, i.e. cancel any outstanding URBs. This needs to be done after
- * writing back the EP state so that the completion callback can operate.
+ * writing back the EP state so that the completion callback can operate. Note that
+ * the completion callback will not modify the TR when it sees that the EP is not in
+ * the 'running' state.
+ * NB: If a URB is canceled before it completed, we have no way to tell if any data
+ * was already (partially) transferred.
*/
if (RT_SUCCESS(xhciR3FindRhDevBySlot(pDevIns, pThis, pThisCC, uSlotID, &pRh, &uPort)))
{
/* Temporarily give up the lock so that the completion callbacks can run. */
RTCritSectLeave(&pThisCC->CritSectThrd);
Log(("Aborting DCI %u -> ep=%u d=%u\n", uDCI, uDCI / 2, uDCI & 1 ? VUSBDIRECTION_IN : VUSBDIRECTION_OUT));
- pRh->pIRhConn->pfnAbortEp(pRh->pIRhConn, uPort, uDCI / 2, uDCI & 1 ? VUSBDIRECTION_IN : VUSBDIRECTION_OUT);
+ pRh->pIRhConn->pfnAbortEpByPort(pRh->pIRhConn, uPort, uDCI / 2, uDCI & 1 ? VUSBDIRECTION_IN : VUSBDIRECTION_OUT);
RTCritSectEnter(&pThisCC->CritSectThrd);
}
- /// @todo The completion callbacks should do more work for canceled URBs.
/* Once the completion callbacks had a chance to run, we have to adjust
* the endpoint state.
* NB: The guest may just ring the doorbell to continue and not execute
@@ -4371,6 +4374,9 @@ static unsigned xhciR3StopEndpoint(PPDMDEVINS pDevIns, PXHCI pThis, PXHCICC pThi
*/
PDMDevHlpPCIPhysReadMeta(pDevIns, GCPhysEndp, &endp_ctx, sizeof(endp_ctx));
+ /* If the enqueue and dequeue pointers are different, a transfer was
+ * in progress.
+ */
bool fXferWasInProgress = endp_ctx.trep != endp_ctx.trdp;
/* Reset the TREP, but the EDTLA should be left alone. */
@@ -4557,6 +4563,8 @@ static unsigned xhciR3ConfigureDevice(PPDMDEVINS pDevIns, PXHCI pThis, uint64_t
XHCI_DEV_CTX dc_out;
unsigned uDCI;
+ RT_ZERO(dc_inp);
+
Assert(uSlotID);
LogFlowFunc(("Slot ID %u, input control context @ %RGp\n", uSlotID, GCPhysInpCtx));
@@ -4638,15 +4646,6 @@ static unsigned xhciR3ConfigureDevice(PPDMDEVINS pDevIns, PXHCI pThis, uint64_t
/// @todo Check input slot context according to 6.2.2.2
/// @todo Check input EP contexts according to 6.2.3.2
}
-/** @todo r=bird: Looks like MSC is right that dc_inp can be used uninitalized.
- *
- * However, this function is so hard to read I'm leaving the exorcism of it to
- * the author and just zeroing it in the mean time.
- *
- */
- else
- RT_ZERO(dc_inp);
-
/* Read the output Slot Context plus all Endpoint Contexts up to and
* including the one with the highest 'add' or 'drop' bit set.
*/
@@ -5252,20 +5251,17 @@ static DECLCALLBACK(int) xhciR3WorkerLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread
while (pThread->enmState == PDMTHREADSTATE_RUNNING)
{
- uint32_t u32Tasks = 0;
uint8_t uSlotID;
- ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, true);
- u32Tasks = ASMAtomicXchgU32(&pThis->u32TasksNew, 0);
- if (!u32Tasks)
+ bool fNotificationSent = ASMAtomicXchgBool(&pThis->fNotificationSent, false);
+ if (!fNotificationSent)
{
- Assert(ASMAtomicReadBool(&pThis->fWrkThreadSleeping));
rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hEvtProcess, RT_INDEFINITE_WAIT);
AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc);
if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING))
break;
LogFlowFunc(("Woken up with rc=%Rrc\n", rc));
- u32Tasks = ASMAtomicXchgU32(&pThis->u32TasksNew, 0);
+ ASMAtomicWriteBool(&pThis->fNotificationSent, false);
}
RTCritSectEnter(&pThisCC->CritSectThrd);
@@ -5305,8 +5301,6 @@ static DECLCALLBACK(int) xhciR3WorkerLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread
}
RTCritSectLeave(&pThisCC->CritSectThrd);
-
- ASMAtomicWriteBool(&pThis->fWrkThreadSleeping, false);
} /* While running */
LogFlow(("xHCI worker thread exiting.\n"));
@@ -7565,6 +7559,68 @@ static DECLCALLBACK(void) xhciR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, con
pThis->fDropUrb = true;
return;
}
+
+ if (pszArgs && strstr(pszArgs, "genintrhw"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (external)...\n");
+ int iIntr = 0;
+ PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
+ xhciSetIntr(pDevIns, pThis, pIntr);
+ return;
+ }
+
+ if (pszArgs && strstr(pszArgs, "genintrint"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (internal)...\n");
+ int iIntr = 0;
+ PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
+ xhciR3SetIntrPending(pDevIns, pThis, pIntr);
+ return;
+ }
+
+ if (pszArgs && strstr(pszArgs, "genintrhw"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (external)...\n");
+ int iIntr = 0;
+ PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
+ xhciSetIntr(pDevIns, pThis, pIntr);
+ return;
+ }
+
+ if (pszArgs && strstr(pszArgs, "genintrint"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating hardware interrupt (internal)...\n");
+ int iIntr = 0;
+ PXHCIINTRPTR pIntr = &pThis->aInterrupters[iIntr & XHCI_INTR_MASK];
+ xhciR3SetIntrPending(pDevIns, pThis, pIntr);
+ return;
+ }
+
+ if (pszArgs && strstr(pszArgs, "genportchgevt"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating port change event...\n");
+ int iPort = 0;
+ xhciR3GenPortChgEvent(pDevIns, pThis, IDX_TO_ID(iPort));
+ return;
+ }
+
+ if (pszArgs && strstr(pszArgs, "genmfiwrapevt"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating MF Index wrap event...\n");
+ XHCI_EVENT_TRB ed;
+ RT_ZERO(ed);
+ ed.mwe.cc = XHCI_TCC_SUCCESS;
+ ed.mwe.type = XHCI_TRB_MFIDX_WRAP;
+ xhciR3WriteEvent(pDevIns, pThis, &ed, XHCI_PRIMARY_INTERRUPTER, false);
+ return;
+ }
+
+ if (pszArgs && strstr(pszArgs, "gendoorbell"))
+ {
+ pHlp->pfnPrintf(pHlp, "Generating doorbell ring..\n");
+ xhciKickWorker(pDevIns, pThis, XHCI_JOB_DOORBELL, 0);
+ return;
+ }
#endif
/* Show basic information. */
@@ -7731,6 +7787,7 @@ static DECLCALLBACK(void) xhciR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, con
pcszDesc = ctxSlot.slot_state < RT_ELEMENTS(g_apszSltStates) ? g_apszSltStates[ctxSlot.slot_state] : "BAD!!!";
pHlp->pfnPrintf(pHlp, " Speed:%u Entries:%u RhPort:%u", ctxSlot.speed, ctxSlot.ctx_ent, ctxSlot.rh_port);
pHlp->pfnPrintf(pHlp, " Address:%u State:%s \n", ctxSlot.dev_addr, pcszDesc);
+ pHlp->pfnPrintf(pHlp, " Doorbells:%08X\n", pThis->aBellsRung[ID_TO_IDX(uSlotID)]);
/* Endpoint contexts. */
for (j = 1; j <= ctxSlot.ctx_ent; ++j)
diff --git a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
index 7088390c..c1d5ab9d 100644
--- a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
+++ b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
@@ -1109,17 +1109,52 @@ static DECLCALLBACK(int) vusbRhAbortEpWorker(PVUSBDEV pDev, int EndPt, VUSBDIREC
}
-/** @interface_method_impl{VUSBIROOTHUBCONNECTOR,pfnAbortEp} */
-static DECLCALLBACK(int) vusbRhAbortEp(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, int EndPt, VUSBDIRECTION enmDir)
+/** @interface_method_impl{VUSBIROOTHUBCONNECTOR,pfnAbortEpByPort} */
+static DECLCALLBACK(int) vusbRhAbortEpByPort(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, int EndPt, VUSBDIRECTION enmDir)
{
PVUSBROOTHUB pRh = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
- PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhAbortEp");
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhAbortEpByPort");
+
+ /* We expect to be called from a device like xHCI which keeps good track
+ * of device <--> port correspondence. Being called for a nonexistent
+ * device is an error.
+ */
+ AssertPtrReturn(pDev, VERR_INVALID_PARAMETER);
if (pDev->pHub != pRh)
AssertFailedReturn(VERR_INVALID_PARAMETER);
vusbDevIoThreadExecSync(pDev, (PFNRT)vusbRhAbortEpWorker, 3, pDev, EndPt, enmDir);
- vusbDevRelease(pDev, "vusbRhAbortEp");
+ vusbDevRelease(pDev, "vusbRhAbortEpByPort");
+
+ /* The reaper thread will take care of completing the URB. */
+
+ return VINF_SUCCESS;
+}
+
+
+/** @interface_method_impl{VUSBIROOTHUBCONNECTOR,pfnAbortEpByAddr} */
+static DECLCALLBACK(int) vusbRhAbortEpByAddr(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, int EndPt, VUSBDIRECTION enmDir)
+{
+ PVUSBROOTHUB pRh = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByAddrRetain(pRh, DstAddress, "vusbRhAbortEpByAddr");
+
+ /* We expect to be called from a device like OHCI which does not
+ * keep track of device <--> address correspondence and may try to
+ * cancel an address that does not correspond to a device. If there's
+ * no device, just do nothing.
+ */
+ if (!pDev)
+ return VINF_SUCCESS;
+
+ if (pDev->pHub != pRh)
+ AssertFailedReturn(VERR_INVALID_PARAMETER);
+
+ /* This method is the same as vusbRhAbortEp[ByPort], intended for old controllers
+ * which don't have a defined port <-> device relationship.
+ */
+ vusbDevIoThreadExecSync(pDev, (PFNRT)vusbRhAbortEpWorker, 3, pDev, EndPt, enmDir);
+ vusbDevRelease(pDev, "vusbRhAbortEpByAddr");
/* The reaper thread will take care of completing the URB. */
@@ -1206,7 +1241,8 @@ static DECLCALLBACK(uint32_t) vusbRhUpdateIsocFrameDelta(PVUSBIROOTHUBCONNECTOR
{
PVUSBROOTHUB pRh = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
AssertReturn(pRh, 0);
- PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhUpdateIsocFrameDelta"); AssertPtr(pDev);
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhUpdateIsocFrameDelta");
+ AssertPtrReturn(pDev, 0);
PVUSBPIPE pPipe = &pDev->aPipes[EndPt];
uint32_t *puLastFrame;
int32_t uFrameDelta;
@@ -1243,7 +1279,7 @@ static DECLCALLBACK(int) vusbR3RhDevPowerOn(PVUSBIROOTHUBCONNECTOR pInterface, u
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevPowerOn");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VERR_VUSB_DEVICE_NOT_ATTACHED);
int rc = VUSBIDevPowerOn(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevPowerOn");
@@ -1256,7 +1292,7 @@ static DECLCALLBACK(int) vusbR3RhDevPowerOff(PVUSBIROOTHUBCONNECTOR pInterface,
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevPowerOff");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VERR_VUSB_DEVICE_NOT_ATTACHED);
int rc = VUSBIDevPowerOff(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevPowerOff");
@@ -1269,7 +1305,7 @@ static DECLCALLBACK(VUSBDEVICESTATE) vusbR3RhDevGetState(PVUSBIROOTHUBCONNECTOR
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevGetState");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VUSB_DEVICE_STATE_DETACHED);
VUSBDEVICESTATE enmState = VUSBIDevGetState(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevGetState");
@@ -1282,7 +1318,7 @@ static DECLCALLBACK(bool) vusbR3RhDevIsSavedStateSupported(PVUSBIROOTHUBCONNECTO
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevIsSavedStateSupported");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, false);
bool fSavedStateSupported = VUSBIDevIsSavedStateSupported(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevIsSavedStateSupported");
@@ -1295,7 +1331,7 @@ static DECLCALLBACK(VUSBSPEED) vusbR3RhDevGetSpeed(PVUSBIROOTHUBCONNECTOR pInter
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevGetSpeed");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VUSB_SPEED_UNKNOWN);
VUSBSPEED enmSpeed = pDev->IDevice.pfnGetSpeed(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevGetSpeed");
@@ -1609,7 +1645,8 @@ static DECLCALLBACK(int) vusbRhConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
pThis->IRhConnector.pfnReapAsyncUrbs = vusbRhReapAsyncUrbs;
pThis->IRhConnector.pfnCancelUrbsEp = vusbRhCancelUrbsEp;
pThis->IRhConnector.pfnCancelAllUrbs = vusbRhCancelAllUrbs;
- pThis->IRhConnector.pfnAbortEp = vusbRhAbortEp;
+ pThis->IRhConnector.pfnAbortEpByPort = vusbRhAbortEpByPort;
+ pThis->IRhConnector.pfnAbortEpByAddr = vusbRhAbortEpByAddr;
pThis->IRhConnector.pfnSetPeriodicFrameProcessing = vusbRhSetFrameProcessing;
pThis->IRhConnector.pfnGetPeriodicFrameRate = vusbRhGetPeriodicFrameRate;
pThis->IRhConnector.pfnUpdateIsocFrameDelta = vusbRhUpdateIsocFrameDelta;
diff --git a/src/VBox/Devices/VirtIO/VirtioCore.cpp b/src/VBox/Devices/VirtIO/VirtioCore.cpp
index 3849aa7c..23ecf30c 100644
--- a/src/VBox/Devices/VirtIO/VirtioCore.cpp
+++ b/src/VBox/Devices/VirtIO/VirtioCore.cpp
@@ -897,6 +897,18 @@ int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16
}
break;
}
+ /* Check if the limit has been reached for input chain (see section 2.4.4.1 of virtio 1.0 spec). */
+ if (cSegsIn >= RT_ELEMENTS(pVirtqBuf->aSegsIn))
+ {
+ LogRelMax(64, ("Too many input descriptors (cSegsIn=%u).\n", cSegsIn));
+ break;
+ }
+ /* Check if the limit has been reached for output chain (see section 2.4.4.1 of virtio 1.0 spec). */
+ if (cSegsOut >= RT_ELEMENTS(pVirtqBuf->aSegsOut))
+ {
+ LogRelMax(64, ("Too many output descriptors (cSegsOut=%u).\n", cSegsOut));
+ break;
+ }
RT_UNTRUSTED_VALIDATED_FENCE();
virtioReadDesc(pDevIns, pVirtio, pVirtq, uDescIdx, &desc);
@@ -1936,7 +1948,7 @@ static DECLCALLBACK(VBOXSTRICTRC) virtioMmioRead(PPDMDEVINS pDevIns, void *pvUse
{
PVIRTIOCORE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOCORE);
PVIRTIOCORECC pVirtioCC = PDMINS_2_DATA_CC(pDevIns, PVIRTIOCORECC);
- AssertReturn(cb == 1 || cb == 2 || cb == 4, VERR_INVALID_PARAMETER);
+ AssertReturn(cb == 1 || cb == 2 || cb == 4, VINF_IOM_MMIO_UNUSED_FF);
Assert(pVirtio == (PVIRTIOCORE)pvUser); RT_NOREF(pvUser);
STAM_PROFILE_ADV_START(&pVirtio->CTX_SUFF(StatRead), a);
@@ -1994,6 +2006,7 @@ static DECLCALLBACK(VBOXSTRICTRC) virtioMmioRead(PPDMDEVINS pDevIns, void *pvUse
ASSERT_GUEST_MSG_FAILED(("Bad read access to mapped capabilities region: off=%RGp cb=%u\n", off, cb));
STAM_PROFILE_ADV_STOP(&pVirtio->CTX_SUFF(StatRead), a);
+ memset(pv, 0xFF, cb);
int rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS,
"virtioMmioRead: Bad MMIO access to capabilities, offset=%RTiop cb=%08x\n", off, cb);
return rc;