- Timestamp:
- Jun 12, 2020 6:17:35 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Config.kmk
r84771 r84803 465 465 # Enable the Virtio SCSI device. 466 466 VBOX_WITH_VIRTIO_SCSI = 1 467 #TODO: PAUL! REMOVE THIS ! 468 VBOX_WITH_VIRTIO_NET_1_0 = 1 467 469 # HDA emulation is Intel HDA by default. 468 470 VBOX_WITH_INTEL_HDA = 1 -
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r84775 r84803 61 61 #define VIRTIONET_SAVED_STATE_VERSION UINT32_C(1) 62 62 #define VIRTIONET_MAX_QPAIRS 1 63 #define VIRTIONET_MAX_ QUEUES (VIRTIONET_MAX_QPAIRS * 2 + 1)63 #define VIRTIONET_MAX_VIRTQS (VIRTIONET_MAX_QPAIRS * 2 + 1) 64 64 #define VIRTIONET_MAX_FRAME_SIZE 65535 + 18 /**< Max IP pkt size + Ethernet header with VLAN tag */ 65 65 #define VIRTIONET_MAC_FILTER_LEN 32 … … 67 67 #define VIRTIONET_PREALLOCATE_RX_SEG_COUNT 32 68 68 69 #define VIRTQNAME(idx Queue) (pThis->aQueues[idxQueue]->szName)70 #define CBVIRTQNAME(idx Queue) RTStrNLen(VIRTQNAME(idxQueue), sizeof(VIRTQNAME(idxQueue)))69 #define VIRTQNAME(idxVirtq) (pThis->aVirtqs[idxVirtq]->szName) 70 #define CBVIRTQNAME(idxVirtq) RTStrNLen(VIRTQNAME(idxVirtq), sizeof(VIRTQNAME(idxVirtq))) 71 71 #define FEATURE_ENABLED(feature) RT_BOOL(pThis->fNegotiatedFeatures & VIRTIONET_F_##feature) 72 72 #define FEATURE_DISABLED(feature) (!FEATURE_ENABLED(feature)) 73 73 #define FEATURE_OFFERED(feature) VIRTIONET_HOST_FEATURES_OFFERED & VIRTIONET_F_##feature 74 74 75 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, idx Queue) \76 (virtioCore QueueAvailCount(pDevIns, pVirtio, idxQueue) == 0)75 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, idxVirtq) \ 76 (virtioCoreVirtqAvailCount(pDevIns, pVirtio, idxVirtq) == 0) 77 77 78 78 #define SET_LINK_UP(pState) \ … … 90 90 91 91 /* Macros to calculate queue specific index number VirtIO 1.0, 5.1.2 */ 92 #define IS_TX_ QUEUE(n) ((n) != CTRLQIDX && ((n) & 1))93 #define IS_RX_ QUEUE(n) ((n) != CTRLQIDX && !IS_TX_QUEUE(n))94 #define IS_CTRL_ QUEUE(n) ((n) == CTRLQIDX)92 #define IS_TX_VIRTQ(n) ((n) != CTRLQIDX && ((n) & 1)) 93 #define IS_RX_VIRTQ(n) ((n) != CTRLQIDX && !IS_TX_VIRTQ(n)) 94 #define IS_CTRL_VIRTQ(n) ((n) == CTRLQIDX) 95 95 #define RXQIDX(qPairIdx) (qPairIdx * 2) 96 96 #define TXQIDX(qPairIdx) (qPairIdx * 2 + 1) … … 306 306 struct VIRTIONETWORKERR3; 307 307 308 typedef struct VIRTIONET QUEUE308 typedef struct VIRTIONETVIRTQ 309 309 { 310 310 struct VIRTIONETWORKER *pWorker; /**< Pointer to R0 worker struct */ … … 312 312 uint16_t idx; /**< Index of this queue */ 313 313 uint16_t align; 314 char szName[VIRTIO_MAX_ QUEUE_NAME_SIZE]; /**< Queuename */315 bool fCtl Queue; /**< If set this queue is the control queue */314 char szName[VIRTIO_MAX_VIRTQ_NAME_SIZE]; /**< Virtq name */ 315 bool fCtlVirtq; /**< If set this queue is the control queue */ 316 316 bool fHasWorker; /**< If set this queue has an associated worker */ 317 317 bool fAttachedToVirtioCore; /**< Set if queue attached to virtio core */ 318 318 uint8_t pad; 319 } VIRTIONET QUEUE, *PVIRTIONETQUEUE;319 } VIRTIONETVIRTQ, *PVIRTIONETVIRTQ; 320 320 321 321 /** … … 325 325 { 326 326 SUPSEMEVENT hEvtProcess; /**< handle of associated sleep/wake-up semaphore */ 327 PVIRTIONET QUEUE pQueue; /**< pointer to queue */327 PVIRTIONETVIRTQ pVirtq; /**< pointer to queue */ 328 328 uint16_t idx; /**< Index of this worker */ 329 329 bool volatile fSleeping; /**< Flags whether worker thread is sleeping or not */ … … 341 341 { 342 342 R3PTRTYPE(PPDMTHREAD) pThread; /**< pointer to worker thread's handle */ 343 PVIRTIONET QUEUE pQueue; /**< pointer to queue */343 PVIRTIONETVIRTQ pVirtq; /**< pointer to queue */ 344 344 uint16_t idx; /**< Index of this worker */ 345 345 uint16_t pad; … … 362 362 363 363 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 364 VIRTIONETWORKER aWorkers[VIRTIONET_MAX_ QUEUES];364 VIRTIONETWORKER aWorkers[VIRTIONET_MAX_VIRTQS]; 365 365 366 366 /** Track which VirtIO queues we've attached to */ 367 VIRTIONET QUEUE aQueues[VIRTIONET_MAX_QUEUES];367 VIRTIONETVIRTQ aVirtqs[VIRTIONET_MAX_VIRTQS]; 368 368 369 369 /** PDM device Instance name */ … … 377 377 378 378 /** Number of virtqueues total (which includes each queue of each pair plus one control queue */ 379 uint16_t cVirt Queues;379 uint16_t cVirtVirtqs; 380 380 381 381 /** Number of worker threads (one for the control queue and one for each Tx queue) */ … … 485 485 486 486 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 487 VIRTIONETWORKERR3 aWorkers[VIRTIONET_MAX_ QUEUES];487 VIRTIONETWORKERR3 aWorkers[VIRTIONET_MAX_VIRTQS]; 488 488 489 489 /** The device instance. … … 613 613 614 614 /** 615 * @callback_method_impl{VIRTIOCORER0,pfn QueueNotified}616 */ 617 static DECLCALLBACK(void) virtioNet QueueNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue)615 * @callback_method_impl{VIRTIOCORER0,pfnVirtqNotified} 616 */ 617 static DECLCALLBACK(void) virtioNetVirtqNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 618 618 { 619 619 RT_NOREF(pVirtio); 620 620 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 621 621 622 PVIRTIONET QUEUE pQueue = &pThis->aQueues[idxQueue];623 PVIRTIONETWORKER pWorker = p Queue->pWorker;622 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[idxVirtq]; 623 PVIRTIONETWORKER pWorker = pVirtq->pWorker; 624 624 625 625 #if defined (IN_RING3) && defined (LOG_ENABLED) … … 627 627 #endif 628 628 629 if (IS_RX_ QUEUE(idxQueue))630 { 631 uint16_t cBufsAvailable = virtioCore QueueAvailCount(pDevIns, pVirtio, idxQueue);629 if (IS_RX_VIRTQ(idxVirtq)) 630 { 631 uint16_t cBufsAvailable = virtioCoreVirtqAvailCount(pDevIns, pVirtio, idxVirtq); 632 632 633 633 if (cBufsAvailable) 634 634 { 635 635 Log10Func(("%s %u empty bufs added to %s by guest (notifying leaf device)\n", 636 pThis->szInst, cBufsAvailable, p Queue->szName));636 pThis->szInst, cBufsAvailable, pVirtq->szName)); 637 637 virtioNetWakeupRxBufWaiter(pDevIns); 638 638 } 639 639 else 640 640 LogRel(("%s \n\n***WARNING: %s notified but no empty bufs added by guest! (skip notifying of leaf device)\n\n", 641 pThis->szInst, p Queue->szName));642 } 643 else if (IS_TX_ QUEUE(idxQueue) || IS_CTRL_QUEUE(idxQueue))641 pThis->szInst, pVirtq->szName)); 642 } 643 else if (IS_TX_VIRTQ(idxVirtq) || IS_CTRL_VIRTQ(idxVirtq)) 644 644 { 645 645 /* Wake queue's worker thread up if sleeping (e.g. a Tx queue, or the control queue */ … … 648 648 if (ASMAtomicReadBool(&pWorker->fSleeping)) 649 649 { 650 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, p Queue->szName));650 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName)); 651 651 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); 652 652 AssertRC(rc); … … 654 654 else 655 655 { 656 Log10Func(("%s %s has available buffers - worker already awake\n", pThis->szInst, p Queue->szName));656 Log10Func(("%s %s has available buffers - worker already awake\n", pThis->szInst, pVirtq->szName)); 657 657 } 658 658 } 659 659 else 660 660 { 661 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, p Queue->szName));661 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName)); 662 662 } 663 663 } 664 664 else 665 LogRelFunc(("%s unrecognized queue %s (idx=%d) notified\n", p Queue->szName, idxQueue));665 LogRelFunc(("%s unrecognized queue %s (idx=%d) notified\n", pVirtq->szName, idxVirtq)); 666 666 } 667 667 … … 677 677 678 678 Log10Func(("%s\n", pThis->szInst)); 679 RT_NOREF(pThis); 679 680 680 681 return PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); … … 684 685 DECLINLINE(void) virtioNetR3SetVirtqNames(PVIRTIONET pThis) 685 686 { 686 RTStrCopy(pThis->a Queues[CTRLQIDX].szName, VIRTIO_MAX_QUEUE_NAME_SIZE, "controlq");687 RTStrCopy(pThis->aVirtqs[CTRLQIDX].szName, VIRTIO_MAX_VIRTQ_NAME_SIZE, "controlq"); 687 688 for (uint16_t qPairIdx = 0; qPairIdx < pThis->cVirtqPairs; qPairIdx++) 688 689 { 689 RTStrPrintf(pThis->a Queues[RXQIDX(qPairIdx)].szName, VIRTIO_MAX_QUEUE_NAME_SIZE, "receiveq<%d>", qPairIdx);690 RTStrPrintf(pThis->a Queues[TXQIDX(qPairIdx)].szName, VIRTIO_MAX_QUEUE_NAME_SIZE, "transmitq<%d>", qPairIdx);690 RTStrPrintf(pThis->aVirtqs[RXQIDX(qPairIdx)].szName, VIRTIO_MAX_VIRTQ_NAME_SIZE, "receiveq<%d>", qPairIdx); 691 RTStrPrintf(pThis->aVirtqs[TXQIDX(qPairIdx)].szName, VIRTIO_MAX_VIRTQ_NAME_SIZE, "transmitq<%d>", qPairIdx); 691 692 } 692 693 } … … 813 814 bool fState = pszArgs && (*pszArgs == 's' || *pszArgs == 'S'); /* "state" */ 814 815 bool fPointers = pszArgs && (*pszArgs == 'p' || *pszArgs == 'P'); /* "pointers" */ 815 bool f Queues = pszArgs && (*pszArgs == 'q' || *pszArgs == 'Q'); /* "queues */816 bool fVirtqs = pszArgs && (*pszArgs == 'q' || *pszArgs == 'Q'); /* "queues */ 816 817 817 818 /* Show basic information. */ … … 836 837 837 838 /* Show queues (and associate worker info if applicable) */ 838 if (fAll || f Queues)839 { 840 pHlp->pfnPrintf(pHlp, " Queueinformation:\n\n");841 842 for (int idx Queue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)839 if (fAll || fVirtqs) 840 { 841 pHlp->pfnPrintf(pHlp, "Virtq information:\n\n"); 842 843 for (int idxVirtq = 0; idxVirtq < pThis->cVirtVirtqs; idxVirtq++) 843 844 { 844 PVIRTIONET QUEUE pQueue = &pThis->aQueues[idxQueue];845 846 if (p Queue->fHasWorker)845 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[idxVirtq]; 846 847 if (pVirtq->fHasWorker) 847 848 { 848 PVIRTIONETWORKER pWorker = p Queue->pWorker;849 PVIRTIONETWORKERR3 pWorkerR3 = p Queue->pWorkerR3;849 PVIRTIONETWORKER pWorker = pVirtq->pWorker; 850 PVIRTIONETWORKERR3 pWorkerR3 = pVirtq->pWorkerR3; 850 851 851 852 if (pWorker->fAssigned) 852 853 { 853 854 pHlp->pfnPrintf(pHlp, " %-15s (pThread: %p %s) ", 854 p Queue->szName,855 pVirtq->szName, 855 856 pWorkerR3->pThread, 856 857 virtioNetThreadStateName(pWorkerR3->pThread)); 857 if (p Queue->fAttachedToVirtioCore)858 if (pVirtq->fAttachedToVirtioCore) 858 859 { 859 860 pHlp->pfnPrintf(pHlp, "worker: "); … … 868 869 else 869 870 { 870 pHlp->pfnPrintf(pHlp, " %-15s (INetworkDown's thread) %s", p Queue->szName,871 p Queue->fAttachedToVirtioCore ? "" : "not attached to virtio core");871 pHlp->pfnPrintf(pHlp, " %-15s (INetworkDown's thread) %s", pVirtq->szName, 872 pVirtq->fAttachedToVirtioCore ? "" : "not attached to virtio core"); 872 873 } 873 874 pHlp->pfnPrintf(pHlp, "\n"); 874 virtioCoreR3 QueueInfo(pDevIns, pHlp, pszArgs, idxQueue);875 virtioCoreR3VirtqInfo(pDevIns, pHlp, pszArgs, idxVirtq); 875 876 pHlp->pfnPrintf(pHlp, " ---------------------------------------------------------------------\n"); 876 877 pHlp->pfnPrintf(pHlp, "\n"); … … 900 901 pHlp->pfnPrintf(pHlp, " uDeviceStatus ............. 0x%x\n", pThis->Virtio.uDeviceStatus); 901 902 pHlp->pfnPrintf(pHlp, " cVirtqPairs .,............. %d\n", pThis->cVirtqPairs); 902 pHlp->pfnPrintf(pHlp, " cVirt Queues .,............. %d\n", pThis->cVirtQueues);903 pHlp->pfnPrintf(pHlp, " cVirtVirtqs .,............. %d\n", pThis->cVirtVirtqs); 903 904 pHlp->pfnPrintf(pHlp, " cWorkers .................. %d\n", pThis->cWorkers); 904 905 pHlp->pfnPrintf(pHlp, " MMIO mapping name ......... %d\n", pThisCC->Virtio.pcszMmioName); … … 1135 1136 pHlp->pfnSSMGetU64( pSSM, &pThis->fNegotiatedFeatures); 1136 1137 1137 pHlp->pfnSSMGetU16( pSSM, &pThis->cVirt Queues);1138 pHlp->pfnSSMGetU16( pSSM, &pThis->cVirtVirtqs); 1138 1139 pHlp->pfnSSMGetU16( pSSM, &pThis->cWorkers); 1139 1140 1140 for (int idx Queue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)1141 pHlp->pfnSSMGetBool(pSSM, &pThis->a Queues[idxQueue].fAttachedToVirtioCore);1141 for (int idxVirtq = 0; idxVirtq < pThis->cVirtVirtqs; idxVirtq++) 1142 pHlp->pfnSSMGetBool(pSSM, &pThis->aVirtqs[idxVirtq].fAttachedToVirtioCore); 1142 1143 1143 1144 int rc; … … 1199 1200 { 1200 1201 PVIRTIONETWORKER pWorker = &pThis->aWorkers[idxWorker]; 1201 PVIRTIONET QUEUE pQueue = pWorker->pQueue;1202 if (p Queue->fAttachedToVirtioCore)1202 PVIRTIONETVIRTQ pVirtq = pWorker->pVirtq; 1203 if (pVirtq->fAttachedToVirtioCore) 1203 1204 { 1204 Log7Func(("%s Waking %s worker.\n", pThis->szInst, p Queue->szName));1205 Log7Func(("%s Waking %s worker.\n", pThis->szInst, pVirtq->szName)); 1205 1206 rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); 1206 1207 AssertRCReturn(rc, rc); … … 1224 1225 pHlp->pfnSSMPutU64( pSSM, pThis->fNegotiatedFeatures); 1225 1226 1226 pHlp->pfnSSMPutU16( pSSM, pThis->cVirt Queues);1227 pHlp->pfnSSMPutU16( pSSM, pThis->cVirtVirtqs); 1227 1228 pHlp->pfnSSMPutU16( pSSM, pThis->cWorkers); 1228 1229 1229 for (int idx Queue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)1230 pHlp->pfnSSMPutBool(pSSM, pThis->a Queues[idxQueue].fAttachedToVirtioCore);1230 for (int idxVirtq = 0; idxVirtq < pThis->cVirtVirtqs; idxVirtq++) 1231 pHlp->pfnSSMPutBool(pSSM, pThis->aVirtqs[idxVirtq].fAttachedToVirtioCore); 1231 1232 1232 1233 /* Save config area */ … … 1470 1471 * @thread RX 1471 1472 */ 1472 static int virtioNetR3CheckRxBufsAvail(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONET QUEUE pRxQueue)1473 static int virtioNetR3CheckRxBufsAvail(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETVIRTQ pRxVirtq) 1473 1474 { 1474 1475 int rc = VERR_INVALID_STATE; … … 1477 1478 Log8Func(("%s No Rx bufs available. (VirtIO core not ready)\n", pThis->szInst)); 1478 1479 1479 else if (!virtioCoreIs QueueEnabled(&pThis->Virtio, pRxQueue->idx))1480 Log8Func(("%s No Rx bufs available. (%s not enabled)\n", pThis->szInst, pRx Queue->szName));1481 1482 else if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pRx Queue->idx))1483 Log8Func(("%s No Rx bufs available. (%s empty)\n", pThis->szInst, pRx Queue->szName));1480 else if (!virtioCoreIsVirtqEnabled(&pThis->Virtio, pRxVirtq->idx)) 1481 Log8Func(("%s No Rx bufs available. (%s not enabled)\n", pThis->szInst, pRxVirtq->szName)); 1482 1483 else if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pRxVirtq->idx)) 1484 Log8Func(("%s No Rx bufs available. (%s empty)\n", pThis->szInst, pRxVirtq->szName)); 1484 1485 1485 1486 else 1486 1487 { 1487 Log8Func(("%s Empty guest buffers available in %s\n", pThis->szInst,pRx Queue->szName));1488 Log8Func(("%s Empty guest buffers available in %s\n", pThis->szInst,pRxVirtq->szName)); 1488 1489 rc = VINF_SUCCESS; 1489 1490 } 1490 virtioCore QueueNotifyEnable(&pThis->Virtio, pRxQueue->idx, rc == VERR_INVALID_STATE /* fEnable */);1491 virtioCoreVirtqNotifyEnable(&pThis->Virtio, pRxVirtq->idx, rc == VERR_INVALID_STATE /* fEnable */); 1491 1492 return rc; 1492 1493 } 1493 1494 1494 static bool virtioNetR3RxBufsAvail(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONET QUEUE *pRxQueue)1495 { 1496 for (int idx QueuePair = 0; idxQueuePair < pThis->cVirtqPairs; idxQueuePair++)1497 { 1498 PVIRTIONET QUEUE pThisRxQueue = &pThis->aQueues[RXQIDX(idxQueuePair)];1499 if (RT_SUCCESS(virtioNetR3CheckRxBufsAvail(pDevIns, pThis, pThisRx Queue)))1495 static bool virtioNetR3RxBufsAvail(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETVIRTQ *pRxVirtq) 1496 { 1497 for (int idxVirtqPair = 0; idxVirtqPair < pThis->cVirtqPairs; idxVirtqPair++) 1498 { 1499 PVIRTIONETVIRTQ pThisRxVirtq = &pThis->aVirtqs[RXQIDX(idxVirtqPair)]; 1500 if (RT_SUCCESS(virtioNetR3CheckRxBufsAvail(pDevIns, pThis, pThisRxVirtq))) 1500 1501 { 1501 if (pRx Queue)1502 *pRx Queue = pThisRxQueue;1502 if (pRxVirtq) 1503 *pRxVirtq = pThisRxVirtq; 1503 1504 return true; 1504 1505 } … … 1516 1517 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 1517 1518 1518 if (virtioNetR3RxBufsAvail(pDevIns, pThis, NULL /* pRx Queue*/))1519 if (virtioNetR3RxBufsAvail(pDevIns, pThis, NULL /* pRxVirtq */)) 1519 1520 { 1520 1521 Log10Func(("%s Rx bufs now available, releasing waiter...\n", pThis->szInst)); … … 1530 1531 1531 1532 do { 1532 if (virtioNetR3RxBufsAvail(pDevIns, pThis, NULL /* pRx Queue*/))1533 if (virtioNetR3RxBufsAvail(pDevIns, pThis, NULL /* pRxVirtq */)) 1533 1534 { 1534 1535 Log10Func(("%s Rx bufs now available, releasing waiter...\n", pThis->szInst)); … … 1730 1731 VIRTIONET_PKT_HDR_T *rxPktHdr, uint16_t cSegsAllocated, 1731 1732 PRTSGBUF pVirtSegBufToGuest, PRTSGSEG paVirtSegsToGuest, 1732 PVIRTIONET QUEUE pRxQueue)1733 PVIRTIONETVIRTQ pRxVirtq) 1733 1734 { 1734 1735 uint8_t fAddPktHdr = true; … … 1740 1741 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 1741 1742 1742 int rc = virtioCoreR3 QueueGet(pDevIns, &pThis->Virtio, pRxQueue->idx, &pDescChain, true);1743 int rc = virtioCoreR3VirtqGet(pDevIns, &pThis->Virtio, pRxVirtq->idx, &pDescChain, true); 1743 1744 AssertMsgReturn(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE, ("%Rrc\n", rc), rc); 1744 1745 … … 1801 1802 Log7Func(("Send Rx pkt to guest...\n")); 1802 1803 STAM_PROFILE_START(&pThis->StatReceiveStore, a); 1803 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, pRxQueue->idx,1804 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, pRxVirtq->idx, 1804 1805 pVirtSegBufToGuest, pDescChain, true /* fFence */); 1805 1806 STAM_PROFILE_STOP(&pThis->StatReceiveStore, a); … … 1825 1826 rc); 1826 1827 1827 virtioCore QueueSync(pDevIns, &pThis->Virtio, pRxQueue->idx);1828 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, pRxVirtq->idx); 1828 1829 1829 1830 return VINF_SUCCESS; … … 1843 1844 * @param cb Number of bytes available in the buffer. 1844 1845 * @param pGso Pointer to Global Segmentation Offload structure 1845 * @param idxRx QueueRx queue to work with1846 * @param idxRxVirtq Rx queue to work with 1846 1847 * @thread RX 1847 1848 */ 1848 1849 static int virtioNetR3HandleRxPacket(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC, 1849 const void *pvBuf, size_t cb, PCPDMNETWORKGSO pGso, PVIRTIONET QUEUE pRxQueue)1850 const void *pvBuf, size_t cb, PCPDMNETWORKGSO pGso, PVIRTIONETVIRTQ pRxVirtq) 1850 1851 { 1851 1852 RT_NOREF(pThisCC); … … 1898 1899 1899 1900 int rc = virtioNetR3CopyRxPktToGuest(pDevIns, pThis, pvBuf, cb, &rxPktHdr, cSegsAllocated, 1900 pVirtSegBufToGuest, paVirtSegsToGuest, pRx Queue);1901 pVirtSegBufToGuest, paVirtSegsToGuest, pRxVirtq); 1901 1902 1902 1903 RTMemFree(paVirtSegsToGuest); … … 1960 1961 selection algorithm feasible or even necessary to prevent starvation? */ 1961 1962 1962 for (int idx QueuePair = 0; idxQueuePair < pThis->cVirtqPairs; idxQueuePair++)1963 { 1964 1965 PVIRTIONET QUEUE pRxQueue = &pThis->aQueues[RXQIDX(idxQueuePair)];1966 if (RT_SUCCESS(!virtioNetR3CheckRxBufsAvail(pDevIns, pThis, pRx Queue)))1963 for (int idxVirtqPair = 0; idxVirtqPair < pThis->cVirtqPairs; idxVirtqPair++) 1964 { 1965 1966 PVIRTIONETVIRTQ pRxVirtq = &pThis->aVirtqs[RXQIDX(idxVirtqPair)]; 1967 if (RT_SUCCESS(!virtioNetR3CheckRxBufsAvail(pDevIns, pThis, pRxVirtq))) 1967 1968 { 1968 1969 /* Drop packets if VM is not running or cable is disconnected. */ … … 1976 1977 if (virtioNetR3AddressFilter(pThis, pvBuf, cb)) 1977 1978 { 1978 rc = virtioNetR3HandleRxPacket(pDevIns, pThis, pThisCC, pvBuf, cb, pGso, pRx Queue);1979 rc = virtioNetR3HandleRxPacket(pDevIns, pThis, pThisCC, pvBuf, cb, pGso, pRxVirtq); 1979 1980 STAM_REL_COUNTER_ADD(&pThis->StatReceiveBytes, cb); 1980 1981 } … … 2282 2283 RTSgBufInit(pReturnSegBuf, paReturnSegs, cSegs); 2283 2284 2284 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, CTRLQIDX, pReturnSegBuf, pDescChain, true /* fFence */);2285 virtioCore QueueSync(pDevIns, &pThis->Virtio, CTRLQIDX);2285 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, CTRLQIDX, pReturnSegBuf, pDescChain, true /* fFence */); 2286 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, CTRLQIDX); 2286 2287 2287 2288 for (int i = 0; i < cSegs; i++) … … 2394 2395 2395 2396 static void virtioNetR3TransmitPendingPackets(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC, 2396 PVIRTIONET QUEUE pTxQueue, bool fOnWorkerThread)2397 PVIRTIONETVIRTQ pTxVirtq, bool fOnWorkerThread) 2397 2398 { 2398 2399 … … 2432 2433 } 2433 2434 2434 int cPkts = virtioCore QueueAvailCount(pVirtio->pDevInsR3, pVirtio, pTxQueue->idx);2435 int cPkts = virtioCoreVirtqAvailCount(pVirtio->pDevInsR3, pVirtio, pTxVirtq->idx); 2435 2436 if (!cPkts) 2436 2437 { 2437 LogFunc(("%s No packets to send found on %s\n", pThis->szInst, pTx Queue->szName));2438 LogFunc(("%s No packets to send found on %s\n", pThis->szInst, pTxVirtq->szName)); 2438 2439 2439 2440 if (pDrv) … … 2449 2450 int rc; 2450 2451 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 2451 while ((rc = virtioCoreR3 QueuePeek(pVirtio->pDevInsR3, pVirtio, pTxQueue->idx, &pDescChain)) == VINF_SUCCESS)2452 { 2453 Log10Func(("%s fetched descriptor chain from %s\n", pThis->szInst, pTx Queue->szName));2452 while ((rc = virtioCoreR3VirtqPeek(pVirtio->pDevInsR3, pVirtio, pTxVirtq->idx, &pDescChain)) == VINF_SUCCESS) 2453 { 2454 Log10Func(("%s fetched descriptor chain from %s\n", pThis->szInst, pTxVirtq->szName)); 2454 2455 2455 2456 PVIRTIOSGBUF pSgPhysSend = pDescChain->pSgPhysSend; … … 2535 2536 2536 2537 /* Remove this descriptor chain from the available ring */ 2537 virtioCoreR3 QueueSkip(pVirtio, pTxQueue->idx);2538 virtioCoreR3VirtqSkip(pVirtio, pTxVirtq->idx); 2538 2539 2539 2540 /* No data to return to guest, but call is needed put elem (e.g. desc chain) on used ring */ 2540 virtioCoreR3 QueuePut(pVirtio->pDevInsR3, pVirtio, pTxQueue->idx, NULL, pDescChain, true /* fFence */);2541 virtioCoreR3VirtqPut(pVirtio->pDevInsR3, pVirtio, pTxVirtq->idx, NULL, pDescChain, true /* fFence */); 2541 2542 2542 2543 /* Update used ring idx and notify guest that we've transmitted the data it sent */ 2543 virtioCore QueueSync(pVirtio->pDevInsR3, pVirtio, pTxQueue->idx);2544 virtioCoreVirtqSync(pVirtio->pDevInsR3, pVirtio, pTxVirtq->idx); 2544 2545 } 2545 2546 … … 2564 2565 PPDMDEVINS pDevIns = pThisCC->pDevIns; 2565 2566 PVIRTIONET pThis = PDMDEVINS_2_DATA(pThisCC->pDevIns, PVIRTIONET); 2566 PVIRTIONET QUEUE pTxQueue = &pThis->aQueues[TXQIDX(0)];2567 PVIRTIONETVIRTQ pTxVirtq = &pThis->aVirtqs[TXQIDX(0)]; 2567 2568 STAM_COUNTER_INC(&pThis->StatTransmitByNetwork); 2568 2569 2569 2570 /** @todo If we ever start using more than one Rx/Tx queue pair, is a random queue 2570 2571 selection algorithm feasible or even necessary */ 2571 virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC, pTx Queue, true /*fOnWorkerThread*/);2572 virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC, pTxVirtq, true /*fOnWorkerThread*/); 2572 2573 } 2573 2574 … … 2745 2746 static int virtioNetR3CreateOneWorkerThread(PPDMDEVINS pDevIns, PVIRTIONET pThis, uint16_t idxWorker, 2746 2747 PVIRTIONETWORKER pWorker, PVIRTIONETWORKERR3 pWorkerR3, 2747 PVIRTIONET QUEUE pQueue)2748 PVIRTIONETVIRTQ pVirtq) 2748 2749 { 2749 2750 Log10Func(("%s\n", pThis->szInst)); 2751 RT_NOREF(pThis); 2750 2752 2751 2753 int rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pWorker->hEvtProcess); … … 2755 2757 N_("DevVirtioNET: Failed to create SUP event semaphore")); 2756 2758 2757 LogFunc(("creating thread for queue %s\n", p Queue->szName));2759 LogFunc(("creating thread for queue %s\n", pVirtq->szName)); 2758 2760 2759 2761 rc = PDMDevHlpThreadCreate(pDevIns, &pWorkerR3->pThread, 2760 2762 (void *)pWorker, virtioNetR3WorkerThread, 2761 virtioNetR3WakeupWorker, 0, RTTHREADTYPE_IO, p Queue->szName);2763 virtioNetR3WakeupWorker, 0, RTTHREADTYPE_IO, pVirtq->szName); 2762 2764 if (RT_FAILURE(rc)) 2763 2765 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 2764 N_("Error creating thread for Virtual Queue %s\n"), pQueue->idx);2765 2766 pWorker->p Queue = pWorkerR3->pQueue = pQueue;2767 pWorker->idx = pWorkerR3->idx = idxWorker;2768 p Queue->pWorker = pWorker;2769 p Queue->pWorkerR3 = pWorkerR3;2766 N_("Error creating thread for Virtual Virtq %s\n"), pVirtq->idx); 2767 2768 pWorker->pVirtq = pWorkerR3->pVirtq = pVirtq; 2769 pWorker->idx = pWorkerR3->idx = idxWorker; 2770 pVirtq->pWorker = pWorker; 2771 pVirtq->pWorkerR3 = pWorkerR3; 2770 2772 pWorker->fAssigned = true; 2771 2773 2772 LogFunc(("%s pThread: %p\n", p Queue->szName, pWorkerR3->pThread));2774 LogFunc(("%s pThread: %p\n", pVirtq->szName, pWorkerR3->pThread)); 2773 2775 2774 2776 return rc; … … 2782 2784 Log10Func(("%s\n", pThis->szInst)); 2783 2785 2784 PVIRTIONET QUEUE pCtlQueue = &pThis->aQueues[CTRLQIDX];2786 PVIRTIONETVIRTQ pCtlVirtq = &pThis->aVirtqs[CTRLQIDX]; 2785 2787 int rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, CTRLQIDX /* idxWorker */, 2786 &pThis->aWorkers[CTRLWIDX], &pThisCC->aWorkers[CTRLWIDX], pCtl Queue);2788 &pThis->aWorkers[CTRLWIDX], &pThisCC->aWorkers[CTRLWIDX], pCtlVirtq); 2787 2789 AssertRCReturn(rc, rc); 2788 2790 2789 pCtl Queue->fHasWorker = true;2791 pCtlVirtq->fHasWorker = true; 2790 2792 2791 2793 uint16_t idxWorker = CTRLWIDX + 1; 2792 for (uint16_t idx QueuePair = 0; idxQueuePair < pThis->cVirtqPairs; idxQueuePair++, idxWorker++)2793 { 2794 PVIRTIONET QUEUE pTxQueue = &pThis->aQueues[TXQIDX(idxQueuePair)];2795 PVIRTIONET QUEUE pRxQueue = &pThis->aQueues[RXQIDX(idxQueuePair)];2794 for (uint16_t idxVirtqPair = 0; idxVirtqPair < pThis->cVirtqPairs; idxVirtqPair++, idxWorker++) 2795 { 2796 PVIRTIONETVIRTQ pTxVirtq = &pThis->aVirtqs[TXQIDX(idxVirtqPair)]; 2797 PVIRTIONETVIRTQ pRxVirtq = &pThis->aVirtqs[RXQIDX(idxVirtqPair)]; 2796 2798 2797 2799 rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, idxWorker, &pThis->aWorkers[idxWorker], 2798 &pThisCC->aWorkers[idxWorker], pTx Queue);2800 &pThisCC->aWorkers[idxWorker], pTxVirtq); 2799 2801 AssertRCReturn(rc, rc); 2800 2802 2801 pTx Queue->fHasWorker = true;2802 pRx Queue->fHasWorker = false;2803 } 2804 pThis->cWorkers = pThis->cVirtqPairs + 1 ;2803 pTxVirtq->fHasWorker = true; 2804 pRxVirtq->fHasWorker = false; 2805 } 2806 pThis->cWorkers = pThis->cVirtqPairs + 1 /* Control virtq */; 2805 2807 return rc; 2806 2808 } … … 2814 2816 PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC); 2815 2817 PVIRTIONETWORKER pWorker = (PVIRTIONETWORKER)pThread->pvUser; 2816 PVIRTIONET QUEUE pQueue = pWorker->pQueue;2818 PVIRTIONETVIRTQ pVirtq = pWorker->pVirtq; 2817 2819 2818 2820 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 2819 2821 return VINF_SUCCESS; 2820 2822 2821 LogFunc(("%s worker thread started for %s\n", pThis->szInst, pQueue->szName)); 2822 2823 /** @todo Race w/guest enabling/disabling guest notifications cyclically. 2824 See BugRef #8651, Comment #82 */ 2825 2826 virtioCoreQueueNotifyEnable(&pThis->Virtio, pQueue->idx, true /* fEnable */); 2823 LogFunc(("%s worker thread started for %s\n", pThis->szInst, pVirtq->szName)); 2824 2825 /** @todo Race w/guest enabling/disabling guest notifications cyclically. 2826 See BugRef #8651, Comment #82 */ 2827 virtioCoreVirtqNotifyEnable(&pThis->Virtio, pVirtq->idx, true /* fEnable */); 2827 2828 2828 2829 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 2829 2830 { 2830 if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, p Queue->idx))2831 if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pVirtq->idx)) 2831 2832 { 2832 2833 /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */ … … 2835 2836 if (!fNotificationSent) 2836 2837 { 2837 Log10Func(("%s %s worker sleeping...\n\n", pThis->szInst, p Queue->szName));2838 Log10Func(("%s %s worker sleeping...\n\n", pThis->szInst, pVirtq->szName)); 2838 2839 Assert(ASMAtomicReadBool(&pWorker->fSleeping)); 2839 2840 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT); … … 2853 2854 if (!pThisCC->fQuiescing) 2854 2855 { 2855 if (p Queue->fCtlQueue)2856 if (pVirtq->fCtlVirtq) 2856 2857 { 2857 Log10Func(("%s %s worker woken. Fetching desc chain\n", pThis->szInst, p Queue->szName));2858 Log10Func(("%s %s worker woken. Fetching desc chain\n", pThis->szInst, pVirtq->szName)); 2858 2859 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 2859 int rc = virtioCoreR3 QueueGet(pDevIns, &pThis->Virtio, pQueue->idx, &pDescChain, true);2860 int rc = virtioCoreR3VirtqGet(pDevIns, &pThis->Virtio, pVirtq->idx, &pDescChain, true); 2860 2861 if (rc == VERR_NOT_AVAILABLE) 2861 2862 { 2862 Log10Func(("%s %s worker woken. Nothing found in queue/n", pThis->szInst, p Queue->szName));2863 Log10Func(("%s %s worker woken. Nothing found in queue/n", pThis->szInst, pVirtq->szName)); 2863 2864 continue; 2864 2865 } … … 2868 2869 else /* Must be Tx queue */ 2869 2870 { 2870 Log10Func(("%s %s worker woken. Queue has data to transmit\n", pThis->szInst, pQueue->szName));2871 virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC, p Queue, false /* fOnWorkerThread */);2871 Log10Func(("%s %s worker woken. Virtq has data to transmit\n", pThis->szInst, pVirtq->szName)); 2872 virtioNetR3TransmitPendingPackets(pDevIns, pThis, pThisCC, pVirtq, false /* fOnWorkerThread */); 2872 2873 } 2873 2874 2874 2875 /* Rx queues aren't handled by our worker threads. Instead, the PDM network 2875 2876 * leaf driver invokes PDMINETWORKDOWN.pfnWaitReceiveAvail() callback, 2876 * which waits until notified directly by virtioNet QueueNotified()2877 * which waits until notified directly by virtioNetVirtqNotified() 2877 2878 * that guest IN buffers have been added to receive virt queue. 2878 2879 */ 2879 2880 } 2880 2881 } 2881 Log10(("%s %s worker thread exiting\n", pThis->szInst, p Queue->szName));2882 Log10(("%s %s worker thread exiting\n", pThis->szInst, pVirtq->szName)); 2882 2883 return VINF_SUCCESS; 2883 2884 } … … 2898 2899 pThis->szInst)); 2899 2900 2900 pThis->fNegotiatedFeatures = virtioCoreGet AcceptedFeatures(pVirtio);2901 pThis->fNegotiatedFeatures = virtioCoreGetNegotiatedFeatures(pVirtio); 2901 2902 2902 2903 #ifdef LOG_ENABLED … … 2910 2911 pThisCC->fQuiescing = false; 2911 2912 2912 for (unsigned idx Queue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)2913 for (unsigned idxVirtq = 0; idxVirtq < pThis->cVirtVirtqs; idxVirtq++) 2913 2914 { 2914 PVIRTIONET QUEUE pQueue = &pThis->aQueues[idxQueue];2915 p Queue->idx = idxQueue;2916 (void) virtioCoreR3 QueueAttach(&pThis->Virtio, pQueue->idx, pQueue->szName);2917 p Queue->fAttachedToVirtioCore = true;2918 if (IS_VIRTQ_EMPTY(pThisCC->pDevIns, &pThis->Virtio, p Queue->idx))2919 virtioCore QueueNotifyEnable(&pThis->Virtio, pQueue->idx, true /* fEnable */);2915 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[idxVirtq]; 2916 pVirtq->idx = idxVirtq; 2917 (void) virtioCoreR3VirtqAttach(&pThis->Virtio, pVirtq->idx, pVirtq->szName); 2918 pVirtq->fAttachedToVirtioCore = true; 2919 if (IS_VIRTQ_EMPTY(pThisCC->pDevIns, &pThis->Virtio, pVirtq->idx)) 2920 virtioCoreVirtqNotifyEnable(&pThis->Virtio, pVirtq->idx, true /* fEnable */); 2920 2921 } 2921 2922 } … … 2943 2944 pThisCC->pDrv->pfnSetPromiscuousMode(pThisCC->pDrv, true); 2944 2945 2945 for (uint16_t idx Queue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)2946 pThis->a Queues[idxQueue].fAttachedToVirtioCore = false;2946 for (uint16_t idxVirtq = 0; idxVirtq < pThis->cVirtVirtqs; idxVirtq++) 2947 pThis->aVirtqs[idxVirtq].fAttachedToVirtioCore = false; 2947 2948 } 2948 2949 } … … 3153 3154 3154 3155 /* Initialize the generic Virtio core: */ 3155 pThisCC->Virtio.pfn QueueNotified = virtioNetQueueNotified;3156 pThisCC->Virtio.pfnVirtqNotified = virtioNetVirtqNotified; 3156 3157 pThisCC->Virtio.pfnStatusChanged = virtioNetR3StatusChanged; 3157 3158 pThisCC->Virtio.pfnDevCapRead = virtioNetR3DevCapRead; … … 3192 3193 ? pThis->virtioNetConfig.uMaxVirtqPairs : 1; 3193 3194 3194 pThis->cVirt Queues += pThis->cVirtqPairs * 2 + 1;3195 pThis->cVirtVirtqs += pThis->cVirtqPairs * 2 + 1; 3195 3196 3196 3197 /* Create Link Up Timer */ … … 3202 3203 */ 3203 3204 virtioNetR3SetVirtqNames(pThis); 3204 pThis->a Queues[CTRLQIDX].fCtlQueue= true;3205 pThis->aVirtqs[CTRLQIDX].fCtlVirtq = true; 3205 3206 3206 3207 /* … … 3290 3291 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 3291 3292 PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC); 3292 pThisCC->Virtio.pfn QueueNotified = virtioNetQueueNotified;3293 pThisCC->Virtio.pfnVirtqNotified = virtioNetVirtqNotified; 3293 3294 return virtioCoreRZInit(pDevIns, &pThis->Virtio); 3294 3295 } -
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r84786 r84803 81 81 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED VIRTIOSCSI_HOST_SCSI_FEATURES_NONE 82 82 83 #define VIRTIOSCSI_REQ_ QUEUE_CNT 4 /**< T.B.D. Consider increasing */84 #define VIRTIOSCSI_ QUEUE_CNT (VIRTIOSCSI_REQ_QUEUE_CNT + 2)83 #define VIRTIOSCSI_REQ_VIRTQ_CNT 4 /**< T.B.D. Consider increasing */ 84 #define VIRTIOSCSI_VIRTQ_CNT (VIRTIOSCSI_REQ_VIRTQ_CNT + 2) 85 85 #define VIRTIOSCSI_MAX_TARGETS 256 /**< T.B.D. Figure out a a good value for this. */ 86 86 #define VIRTIOSCSI_MAX_LUN 256 /**< VirtIO specification, section 5.6.4 */ … … 112 112 #define VIRTQ_REQ_BASE 2 /**< Spec-defined base index of request queues */ 113 113 114 #define VIRTQNAME(idx Queue) (pThis->aszVirtqNames[idxQueue]) /**< Macro to get queue name from its index */115 #define CBVIRTQNAME(idx Queue) RTStrNLen(VIRTQNAME(idxQueue), sizeof(VIRTQNAME(idxQueue)))116 117 #define IS_REQ_ QUEUE(idxQueue) (idxQueue >= VIRTQ_REQ_BASE && idxQueue < VIRTIOSCSI_QUEUE_CNT)114 #define VIRTQNAME(idxVirtq) (pThis->aszVirtqNames[idxVirtq]) /**< Macro to get queue name from its index */ 115 #define CBVIRTQNAME(idxVirtq) RTStrNLen(VIRTQNAME(idxVirtq), sizeof(VIRTQNAME(idxVirtq))) 116 117 #define IS_REQ_VIRTQ(idxVirtq) (idxVirtq >= VIRTQ_REQ_BASE && idxVirtq < VIRTIOSCSI_VIRTQ_CNT) 118 118 119 119 #define VIRTIO_IS_IN_DIRECTION(pMediaExTxDirEnumValue) \ … … 123 123 ((pMediaExTxDirEnumValue) == PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE) 124 124 125 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, idx Queue) \126 (virtioCore QueueAvailCount(pDevIns, pVirtio, idxQueue) == 0)125 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, idxVirtq) \ 126 (virtioCoreVirtqAvailCount(pDevIns, pVirtio, idxVirtq) == 0) 127 127 128 128 … … 137 137 typedef struct virtio_scsi_config 138 138 { 139 uint32_t uNum Queues; /**< num_queues \# of req q's exposed by dev */139 uint32_t uNumVirtqs; /**< num_queues \# of req q's exposed by dev */ 140 140 uint32_t uSegMax; /**< seg_max Max \# of segs allowed in cmd */ 141 141 uint32_t uMaxSectors; /**< max_sectors Hint to guest max xfer to use */ … … 427 427 428 428 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 429 VIRTIOSCSIWORKER aWorkers[VIRTIOSCSI_ QUEUE_CNT];429 VIRTIOSCSIWORKER aWorkers[VIRTIOSCSI_VIRTQ_CNT]; 430 430 431 431 /** Instance name */ … … 433 433 434 434 /** Device-specific spec-based VirtIO VIRTQNAMEs */ 435 char aszVirtqNames[VIRTIOSCSI_ QUEUE_CNT][VIRTIO_MAX_QUEUE_NAME_SIZE];435 char aszVirtqNames[VIRTIOSCSI_VIRTQ_CNT][VIRTIO_MAX_VIRTQ_NAME_SIZE]; 436 436 437 437 /** Track which VirtIO queues we've attached to */ 438 bool af QueueAttached[VIRTIOSCSI_QUEUE_CNT];438 bool afVirtqAttached[VIRTIOSCSI_VIRTQ_CNT]; 439 439 440 440 /** Set if events missed due to lack of bufs avail on eventq */ … … 488 488 489 489 /** Per device-bound virtq worker-thread contexts (eventq slot unused) */ 490 VIRTIOSCSIWORKERR3 aWorkers[VIRTIOSCSI_ QUEUE_CNT];490 VIRTIOSCSIWORKERR3 aWorkers[VIRTIOSCSI_VIRTQ_CNT]; 491 491 492 492 /** Device base interface. */ … … 503 503 R3PTRTYPE(PPDMIMEDIANOTIFY) pMediaNotify; 504 504 505 /** Queueto send tasks to R3. - HC ptr */506 R3PTRTYPE(PPDMQUEUE) pNotifier QueueR3;505 /** Virtq to send tasks to R3. - HC ptr */ 506 R3PTRTYPE(PPDMQUEUE) pNotifierVirtqR3; 507 507 508 508 /** True if in the process of quiescing I/O */ … … 557 557 PDMMEDIAEXIOREQ hIoReq; /**< Handle of I/O request */ 558 558 PVIRTIOSCSITARGET pTarget; /**< Target */ 559 uint16_t idx Queue; /**< Index of queue this request arrived on */559 uint16_t idxVirtq; /**< Index of queue this request arrived on */ 560 560 PVIRTIO_DESC_CHAIN_T pDescChain; /**< Prepared desc chain pulled from virtq avail ring */ 561 561 size_t cbDataIn; /**< size of dataout buffer */ … … 573 573 574 574 /** 575 * callback_method_impl{VIRTIOCORER0,pfn QueueNotified}575 * callback_method_impl{VIRTIOCORER0,pfnVirtqNotified} 576 576 * @todo this causes burn if I prefix with at-sign. This callback is in VIRTIOCORER0 and VIRTIOCORER3 577 577 */ 578 static DECLCALLBACK(void) virtioScsiNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)578 static DECLCALLBACK(void) virtioScsiNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 579 579 { 580 580 … … 582 582 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 583 583 584 AssertReturnVoid(idx Queue < VIRTIOSCSI_QUEUE_CNT);585 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idx Queue];584 AssertReturnVoid(idxVirtq < VIRTIOSCSI_VIRTQ_CNT); 585 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idxVirtq]; 586 586 587 587 #if defined (IN_RING3) && defined (LOG_ENABLED) … … 589 589 #endif 590 590 591 if (idx Queue == CONTROLQ_IDX || IS_REQ_QUEUE(idxQueue))592 { 593 Log6Func(("%s has available data\n", VIRTQNAME(idx Queue)));591 if (idxVirtq == CONTROLQ_IDX || IS_REQ_VIRTQ(idxVirtq)) 592 { 593 Log6Func(("%s has available data\n", VIRTQNAME(idxVirtq))); 594 594 /* Wake queue's worker thread up if sleeping */ 595 595 if (!ASMAtomicXchgBool(&pWorker->fNotified, true)) … … 597 597 if (ASMAtomicReadBool(&pWorker->fSleeping)) 598 598 { 599 Log6Func(("waking %s worker.\n", VIRTQNAME(idx Queue)));599 Log6Func(("waking %s worker.\n", VIRTQNAME(idxVirtq))); 600 600 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); 601 601 AssertRC(rc); … … 603 603 } 604 604 } 605 else if (idx Queue== EVENTQ_IDX)606 { 607 Log3Func(("Driver queued buffer(s) to %s\n", VIRTQNAME(idx Queue)));605 else if (idxVirtq == EVENTQ_IDX) 606 { 607 Log3Func(("Driver queued buffer(s) to %s\n", VIRTQNAME(idxVirtq))); 608 608 // if (ASMAtomicXchgBool(&pThis->fEventsMissed, false)) 609 609 // virtioScsiR3ReportEventsMissed(pDevIns, pThis, 0); 610 610 } 611 611 else 612 LogFunc(("Unexpected queue idx (ignoring): %d\n", idx Queue));612 LogFunc(("Unexpected queue idx (ignoring): %d\n", idxVirtq)); 613 613 } 614 614 … … 619 619 DECLINLINE(void) virtioScsiSetVirtqNames(PVIRTIOSCSI pThis) 620 620 { 621 RTStrCopy(pThis->aszVirtqNames[CONTROLQ_IDX], VIRTIO_MAX_ QUEUE_NAME_SIZE, "controlq");622 RTStrCopy(pThis->aszVirtqNames[EVENTQ_IDX], VIRTIO_MAX_ QUEUE_NAME_SIZE, "eventq");623 for (uint16_t idx Queue = VIRTQ_REQ_BASE; idxQueue < VIRTQ_REQ_BASE + VIRTIOSCSI_REQ_QUEUE_CNT; idxQueue++)624 RTStrPrintf(pThis->aszVirtqNames[idx Queue], VIRTIO_MAX_QUEUE_NAME_SIZE,625 "requestq<%d>", idx Queue- VIRTQ_REQ_BASE);621 RTStrCopy(pThis->aszVirtqNames[CONTROLQ_IDX], VIRTIO_MAX_VIRTQ_NAME_SIZE, "controlq"); 622 RTStrCopy(pThis->aszVirtqNames[EVENTQ_IDX], VIRTIO_MAX_VIRTQ_NAME_SIZE, "eventq"); 623 for (uint16_t idxVirtq = VIRTQ_REQ_BASE; idxVirtq < VIRTQ_REQ_BASE + VIRTIOSCSI_REQ_VIRTQ_CNT; idxVirtq++) 624 RTStrPrintf(pThis->aszVirtqNames[idxVirtq], VIRTIO_MAX_VIRTQ_NAME_SIZE, 625 "requestq<%d>", idxVirtq - VIRTQ_REQ_BASE); 626 626 } 627 627 … … 755 755 756 756 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 757 int rc = virtioCoreR3 QueueGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true);757 int rc = virtioCoreR3VirtqGet(pDevIns, &pThis->Virtio, EVENTQ_IDX, &pDescChain, true); 758 758 if (rc == VERR_NOT_AVAILABLE) 759 759 { … … 783 783 RTSgBufInit(&ReqSgBuf, aReqSegs, RT_ELEMENTS(aReqSegs)); 784 784 785 rc = virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pDescChain, true /*fFence*/);785 rc = virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, EVENTQ_IDX, &ReqSgBuf, pDescChain, true /*fFence*/); 786 786 if (rc == VINF_SUCCESS) 787 virtioCore QueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, false);787 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, EVENTQ_IDX, false); 788 788 else 789 789 LogRel(("Error writing control message to guest\n")); … … 811 811 * @param pThis VirtIO SCSI shared instance data. 812 812 * @param pThisCC VirtIO SCSI ring-3 instance data. 813 * @param idx Queue Queueindex813 * @param idxVirtq Virtq index 814 814 * @param pDescChain Pointer to pre-processed descriptor chain pulled from virtq 815 815 * @param pRespHdr Response header … … 819 819 * @returns VINF_SUCCESS 820 820 */ 821 static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idx Queue,821 static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idxVirtq, 822 822 PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense, 823 823 size_t cbSenseCfg) … … 853 853 pRespHdr->uResponse = VIRTIOSCSI_S_RESET; 854 854 855 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, idxQueue, &ReqSgBuf, pDescChain, true /* fFence */);856 virtioCore QueueSync(pDevIns, &pThis->Virtio, idxQueue);855 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, idxVirtq, &ReqSgBuf, pDescChain, true /* fFence */); 856 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, idxVirtq); 857 857 858 858 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing) … … 872 872 * @param pThis VirtIO SCSI shared instance data. 873 873 * @param pThisCC VirtIO SCSI ring-3 instance data. 874 * @param idx Queue Queueindex874 * @param idxVirtq Virtq index 875 875 * @param pDescChain Pointer to pre-processed descriptor chain pulled from virtq 876 876 * @param cbResidual The number of residual bytes or something like that. … … 883 883 * @returns VINF_SUCCESS 884 884 */ 885 static int virtioScsiR3ReqErr4(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idx Queue,885 static int virtioScsiR3ReqErr4(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t idxVirtq, 886 886 PVIRTIO_DESC_CHAIN_T pDescChain, size_t cbResidual, uint8_t bStatus, uint8_t bResponse, 887 887 uint8_t *pbSense, size_t cbSense, size_t cbSenseCfg) … … 894 894 RespHdr.uResponse = bResponse; 895 895 896 return virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idx Queue, pDescChain, &RespHdr, pbSense, cbSenseCfg);896 return virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, &RespHdr, pbSense, cbSenseCfg); 897 897 } 898 898 … … 1016 1016 respHdr.uResidual = pReq->cbDataIn & UINT32_MAX; 1017 1017 1018 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->idx Queue, pReq->pDescChain, &respHdr, abSense,1018 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->idxVirtq, pReq->pDescChain, &respHdr, abSense, 1019 1019 RT_MIN(pThis->virtioScsiConfig.uSenseSize, VIRTIOSCSI_SENSE_SIZE_MAX)); 1020 1020 } … … 1042 1042 VERR_BUFFER_OVERFLOW); 1043 1043 1044 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, pReq->idxQueue, &ReqSgBuf, pReq->pDescChain, true /* fFence TBD */);1045 virtioCore QueueSync(pDevIns, &pThis->Virtio, pReq->idxQueue);1044 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, pReq->idxVirtq, &ReqSgBuf, pReq->pDescChain, true /* fFence TBD */); 1045 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, pReq->idxVirtq); 1046 1046 1047 1047 Log2(("-----------------------------------------------------------------------------------------\n")); … … 1058 1058 /** 1059 1059 * @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyFromBuf} 1060 * 1060 1061 1061 * Copy virtual memory from VSCSI layer to guest physical memory 1062 1062 */ … … 1144 1144 */ 1145 1145 static int virtioScsiR3ReqSubmit(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, 1146 uint16_t idx Queue, PVIRTIO_DESC_CHAIN_T pDescChain)1146 uint16_t idxVirtq, PVIRTIO_DESC_CHAIN_T pDescChain) 1147 1147 { 1148 1148 … … 1194 1194 if (uType == 0xc1 && uTarget == 0x01) 1195 1195 { 1196 LogRel(("* * * REPORT LUNS LU ACCESSED* * * "));1196 LogRel(("* * * WARNING: REPORT LUNS LU ACCESSED. FEATURE NOT IMPLEMENTED SEE DevVirtioScsi.cpp * * * ")); 1197 1197 /* Force rejection. */ /** @todo figure out right way to handle. Note this is a very 1198 1198 * vague and confusing part of the VirtIO spec (which deviates from the SCSI standard). 1199 1199 * I have not been able to determine how to implement this properly. I've checked the 1200 * source code of Guest drivers, and so far none seem to use it. If logs show1201 * this warning, implementing it can be re-visited */1200 * source code of Guest drivers, and so far none seem to use it. If this message is logged, 1201 * meaning a guest expects this feature, implementing it can be re-visited */ 1202 1202 uScsiLun = 0xff; 1203 1203 } … … 1232 1232 { 1233 1233 Log2Func(("Error submitting request, bad LUN format\n")); 1234 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, 0 /*bStatus*/,1234 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, 0 /*bStatus*/, 1235 1235 VIRTIOSCSI_S_FAILURE, NULL /*pbSense*/, 0 /*cbSense*/, cbSenseCfg); 1236 1236 } … … 1247 1247 0, SCSI_SENSE_ILLEGAL_REQUEST, 1248 1248 0, 0, 0, 0, 10, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 0, 0 }; 1249 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION,1249 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1250 1250 VIRTIOSCSI_S_BAD_TARGET, abSense, sizeof(abSense), cbSenseCfg); 1251 1251 } … … 1258 1258 0, SCSI_SENSE_ILLEGAL_REQUEST, 1259 1259 0, 0, 0, 0, 10, SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 0, 0 }; 1260 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION,1260 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1261 1261 VIRTIOSCSI_S_OK, abSense, sizeof(abSense), cbSenseCfg); 1262 1262 } … … 1266 1266 { 1267 1267 Log2Func(("Aborting req submission because reset is in progress\n")); 1268 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_OK,1268 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_OK, 1269 1269 VIRTIOSCSI_S_RESET, NULL /*pbSense*/, 0 /*cbSense*/, cbSenseCfg); 1270 1270 } … … 1277 1277 uint8_t abSense[] = { RT_BIT(7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED, 1278 1278 0, SCSI_SENSE_ILLEGAL_REQUEST, 0, 0, 0, 0, 10, 0, 0, 0 }; 1279 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idx Queue, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION,1279 return virtioScsiR3ReqErr4(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, cbDataIn + cbDataOut, SCSI_STATUS_CHECK_CONDITION, 1280 1280 VIRTIOSCSI_S_FAILURE, abSense, sizeof(abSense), cbSenseCfg); 1281 1281 } … … 1295 1295 pReq->hIoReq = hIoReq; 1296 1296 pReq->pTarget = pTarget; 1297 pReq->idx Queue = idxQueue;1297 pReq->idxVirtq = idxVirtq; 1298 1298 pReq->cbDataIn = cbDataIn; 1299 1299 pReq->cbDataOut = cbDataOut; … … 1323 1323 */ 1324 1324 Assert(RT_FAILURE_NP(rc)); 1325 Log2Func(("Request 1325 Log2Func(("Request-submission error from lower-level driver\n")); 1326 1326 uint8_t uASC, uASCQ = 0; 1327 1327 switch (rc) … … 1342 1342 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1343 1343 respHdr.uResidual = (cbDataIn + cbDataOut) & UINT32_MAX; 1344 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idx Queue, pDescChain, &respHdr, abSense, cbSenseCfg);1344 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, idxVirtq, pDescChain, &respHdr, abSense, cbSenseCfg); 1345 1345 virtioScsiR3FreeReq(pTarget, pReq); 1346 1346 } … … 1356 1356 * @param pThis VirtIO SCSI shared instance data. 1357 1357 * @param pThisCC VirtIO SCSI ring-3 instance data. 1358 * @param idx QueueCONTROLQ_IDX1358 * @param idxVirtq CONTROLQ_IDX 1359 1359 * @param pDescChain Descriptor chain to process. 1360 1360 */ 1361 1361 static int virtioScsiR3Ctrl(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, 1362 uint16_t idx Queue, PVIRTIO_DESC_CHAIN_T pDescChain)1362 uint16_t idxVirtq, PVIRTIO_DESC_CHAIN_T pDescChain) 1363 1363 { 1364 1364 AssertReturn(pDescChain->cbPhysSend >= RT_MIN(sizeof(VIRTIOSCSI_CTRL_AN_T), … … 1401 1401 uint32_t uScsiLun = RT_MAKE_U16(ScsiCtrlUnion.Tmf.abScsiLun[3], ScsiCtrlUnion.Tmf.abScsiLun[2]) & 0x3fff; 1402 1402 Log2Func(("[%s] (Target: %d LUN: %d) Task Mgt Function: %s\n", 1403 VIRTQNAME(idx Queue), uTarget, uScsiLun, virtioGetTMFTypeText(ScsiCtrlUnion.Tmf.uSubtype)));1403 VIRTQNAME(idxVirtq), uTarget, uScsiLun, virtioGetTMFTypeText(ScsiCtrlUnion.Tmf.uSubtype))); 1404 1404 1405 1405 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) … … 1462 1462 virtioGetControlAsyncMaskText(szTypeText, sizeof(szTypeText), ScsiCtrlUnion.AsyncNotify.fEventsRequested); 1463 1463 Log2Func(("[%s] (Target: %d LUN: %d) Async. Notification Query: %s\n", 1464 VIRTQNAME(idx Queue), uTarget, uScsiLun, szTypeText));1464 VIRTQNAME(idxVirtq), uTarget, uScsiLun, szTypeText)); 1465 1465 } 1466 1466 #endif … … 1487 1487 virtioGetControlAsyncMaskText(szTypeText, sizeof(szTypeText), ScsiCtrlUnion.AsyncNotify.fEventsRequested); 1488 1488 Log2Func(("[%s] (Target: %d LUN: %d) Async. Notification Subscribe: %s\n", 1489 VIRTQNAME(idx Queue), uTarget, uScsiLun, szTypeText));1489 VIRTQNAME(idxVirtq), uTarget, uScsiLun, szTypeText)); 1490 1490 } 1491 1491 #endif … … 1508 1508 default: 1509 1509 { 1510 LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(idx Queue), ScsiCtrlUnion.Type.uType));1510 LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(idxVirtq), ScsiCtrlUnion.Type.uType)); 1511 1511 1512 1512 bResponse = VIRTIOSCSI_S_FAILURE; … … 1527 1527 RTSgBufInit(&ReqSgBuf, aReqSegs, cSegs); 1528 1528 1529 virtioCoreR3 QueuePut(pDevIns, &pThis->Virtio, idxQueue, &ReqSgBuf, pDescChain, true /*fFence*/);1530 virtioCore QueueSync(pDevIns, &pThis->Virtio, idxQueue);1529 virtioCoreR3VirtqPut(pDevIns, &pThis->Virtio, idxVirtq, &ReqSgBuf, pDescChain, true /*fFence*/); 1530 virtioCoreVirtqSync(pDevIns, &pThis->Virtio, idxVirtq); 1531 1531 1532 1532 return VINF_SUCCESS; … … 1547 1547 static DECLCALLBACK(int) virtioScsiR3WorkerThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1548 1548 { 1549 uint16_t const idx Queue= (uint16_t)(uintptr_t)pThread->pvUser;1549 uint16_t const idxVirtq = (uint16_t)(uintptr_t)pThread->pvUser; 1550 1550 PVIRTIOSCSI pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIOSCSI); 1551 1551 PVIRTIOSCSICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOSCSICC); 1552 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idx Queue];1553 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idx Queue];1552 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idxVirtq]; 1553 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idxVirtq]; 1554 1554 1555 1555 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) … … 1558 1558 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 1559 1559 { 1560 if (!pWorkerR3->cRedoDescs && IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, idx Queue))1560 if (!pWorkerR3->cRedoDescs && IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, idxVirtq)) 1561 1561 { 1562 1562 /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */ … … 1565 1565 if (!fNotificationSent) 1566 1566 { 1567 Log6Func(("%s worker sleeping...\n", VIRTQNAME(idx Queue)));1567 Log6Func(("%s worker sleeping...\n", VIRTQNAME(idxVirtq))); 1568 1568 Assert(ASMAtomicReadBool(&pWorker->fSleeping)); 1569 1569 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT); … … 1573 1573 if (rc == VERR_INTERRUPTED) 1574 1574 continue; 1575 Log6Func(("%s worker woken\n", VIRTQNAME(idx Queue)));1575 Log6Func(("%s worker woken\n", VIRTQNAME(idxVirtq))); 1576 1576 ASMAtomicWriteBool(&pWorker->fNotified, false); 1577 1577 } … … 1579 1579 } 1580 1580 1581 if (!pThis->af QueueAttached[idxQueue])1581 if (!pThis->afVirtqAttached[idxVirtq]) 1582 1582 { 1583 LogFunc(("%s queue not attached, worker aborting...\n", VIRTQNAME(idx Queue)));1583 LogFunc(("%s queue not attached, worker aborting...\n", VIRTQNAME(idxVirtq))); 1584 1584 break; 1585 1585 } … … 1590 1590 { 1591 1591 PVIRTIO_DESC_CHAIN_T pDescChain; 1592 int rc = virtioCoreR3DescChainGet(pDevIns, &pThis->Virtio, idx Queue,1592 int rc = virtioCoreR3DescChainGet(pDevIns, &pThis->Virtio, idxVirtq, 1593 1593 pWorkerR3->auRedoDescs[i], &pDescChain); 1594 1594 if (RT_FAILURE(rc)) 1595 1595 LogRel(("Error fetching desc chain to redo, %Rrc", rc)); 1596 1596 1597 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idx Queue, pDescChain);1597 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idxVirtq, pDescChain); 1598 1598 if (RT_FAILURE(rc)) 1599 1599 LogRel(("Error submitting req packet, resetting %Rrc", rc)); … … 1603 1603 pWorkerR3->cRedoDescs = 0; 1604 1604 1605 Log6Func(("fetching next descriptor chain from %s\n", VIRTQNAME(idx Queue)));1605 Log6Func(("fetching next descriptor chain from %s\n", VIRTQNAME(idxVirtq))); 1606 1606 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 1607 int rc = virtioCoreR3 QueueGet(pDevIns, &pThis->Virtio, idxQueue, &pDescChain, true);1607 int rc = virtioCoreR3VirtqGet(pDevIns, &pThis->Virtio, idxVirtq, &pDescChain, true); 1608 1608 if (rc == VERR_NOT_AVAILABLE) 1609 1609 { 1610 Log6Func(("Nothing found in %s\n", VIRTQNAME(idx Queue)));1610 Log6Func(("Nothing found in %s\n", VIRTQNAME(idxVirtq))); 1611 1611 continue; 1612 1612 } 1613 1613 1614 1614 AssertRC(rc); 1615 if (idx Queue== CONTROLQ_IDX)1616 virtioScsiR3Ctrl(pDevIns, pThis, pThisCC, idx Queue, pDescChain);1615 if (idxVirtq == CONTROLQ_IDX) 1616 virtioScsiR3Ctrl(pDevIns, pThis, pThisCC, idxVirtq, pDescChain); 1617 1617 else /* request queue index */ 1618 1618 { 1619 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idx Queue, pDescChain);1619 rc = virtioScsiR3ReqSubmit(pDevIns, pThis, pThisCC, idxVirtq, pDescChain); 1620 1620 if (RT_FAILURE(rc)) 1621 1621 LogRel(("Error submitting req packet, resetting %Rrc", rc)); … … 1703 1703 pThisCC->fQuiescing = false; 1704 1704 1705 for (unsigned i = 0; i < VIRTIOSCSI_ QUEUE_CNT; i++)1706 pThis->af QueueAttached[i] = true;1705 for (unsigned i = 0; i < VIRTIOSCSI_VIRTQ_CNT; i++) 1706 pThis->afVirtqAttached[i] = true; 1707 1707 } 1708 1708 else 1709 1709 { 1710 1710 LogFunc(("VirtIO is resetting\n")); 1711 for (unsigned i = 0; i < VIRTIOSCSI_ QUEUE_CNT; i++)1712 pThis->af QueueAttached[i] = false;1711 for (unsigned i = 0; i < VIRTIOSCSI_VIRTQ_CNT; i++) 1712 pThis->afVirtqAttached[i] = false; 1713 1713 } 1714 1714 } … … 1835 1835 AssertReturn(pv && cb <= sizeof(uint32_t), fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00); 1836 1836 1837 if (MATCH_SCSI_CONFIG(uNum Queues))1838 SCSI_CONFIG_ACCESSOR_READONLY(uNum Queues);1837 if (MATCH_SCSI_CONFIG(uNumVirtqs)) 1838 SCSI_CONFIG_ACCESSOR_READONLY(uNumVirtqs); 1839 1839 else 1840 1840 if (MATCH_SCSI_CONFIG(uSegMax)) … … 1967 1967 1968 1968 virtioScsiSetVirtqNames(pThis); 1969 for (int idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)1970 pHlp->pfnSSMGetBool(pSSM, &pThis->af QueueAttached[idxQueue]);1971 1972 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uNum Queues);1969 for (int idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 1970 pHlp->pfnSSMGetBool(pSSM, &pThis->afVirtqAttached[idxVirtq]); 1971 1972 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uNumVirtqs); 1973 1973 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uSegMax); 1974 1974 pHlp->pfnSSMGetU32(pSSM, &pThis->virtioScsiConfig.uMaxSectors); … … 2007 2007 cReqsRedo, VIRTQ_MAX_ENTRIES)); 2008 2008 2009 for (uint16_t idx Queue = VIRTQ_REQ_BASE; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2009 for (uint16_t idxVirtq = VIRTQ_REQ_BASE; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2010 2010 { 2011 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idx Queue];2011 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idxVirtq]; 2012 2012 pWorkerR3->cRedoDescs = 0; 2013 2013 } … … 2015 2015 for (int i = 0; i < cReqsRedo; i++) 2016 2016 { 2017 uint16_t idx Queue;2018 rc = pHlp->pfnSSMGetU16(pSSM, &idx Queue);2017 uint16_t idxVirtq; 2018 rc = pHlp->pfnSSMGetU16(pSSM, &idxVirtq); 2019 2019 AssertRCReturn(rc, rc); 2020 AssertReturn(idx Queue < VIRTIOSCSI_QUEUE_CNT,2020 AssertReturn(idxVirtq < VIRTIOSCSI_VIRTQ_CNT, 2021 2021 pHlp->pfnSSMSetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS, 2022 2022 N_("Bad queue index for re-do in saved state (%#x, max %#x)"), 2023 idx Queue, VIRTIOSCSI_QUEUE_CNT - 1));2023 idxVirtq, VIRTIOSCSI_VIRTQ_CNT - 1)); 2024 2024 2025 2025 uint16_t idxHead; … … 2031 2031 idxHead, VIRTQ_MAX_ENTRIES - 1)); 2032 2032 2033 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idx Queue];2033 PVIRTIOSCSIWORKERR3 pWorkerR3 = &pThisCC->aWorkers[idxVirtq]; 2034 2034 pWorkerR3->auRedoDescs[pWorkerR3->cRedoDescs++] = idxHead; 2035 2035 pWorkerR3->cRedoDescs %= VIRTQ_MAX_ENTRIES; … … 2045 2045 * Nudge request queue workers 2046 2046 */ 2047 for (int idx Queue = VIRTQ_REQ_BASE; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2048 { 2049 if (pThis->af QueueAttached[idxQueue])2047 for (int idxVirtq = VIRTQ_REQ_BASE; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2048 { 2049 if (pThis->afVirtqAttached[idxVirtq]) 2050 2050 { 2051 LogFunc(("Waking %s worker.\n", VIRTQNAME(idx Queue)));2052 int rc2 = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idx Queue].hEvtProcess);2051 LogFunc(("Waking %s worker.\n", VIRTQNAME(idxVirtq))); 2052 int rc2 = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idxVirtq].hEvtProcess); 2053 2053 AssertRCReturn(rc, rc2); 2054 2054 } … … 2069 2069 LogFunc(("SAVE EXEC!!\n")); 2070 2070 2071 for (int idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2072 pHlp->pfnSSMPutBool(pSSM, pThis->af QueueAttached[idxQueue]);2073 2074 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uNum Queues);2071 for (int idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2072 pHlp->pfnSSMPutBool(pSSM, pThis->afVirtqAttached[idxVirtq]); 2073 2074 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uNumVirtqs); 2075 2075 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uSegMax); 2076 2076 pHlp->pfnSSMPutU32(pSSM, pThis->virtioScsiConfig.uMaxSectors); … … 2117 2117 while(--cReqsRedo) 2118 2118 { 2119 pHlp->pfnSSMPutU16(pSSM, pReq->idx Queue);2119 pHlp->pfnSSMPutU16(pSSM, pReq->idxVirtq); 2120 2120 pHlp->pfnSSMPutU16(pSSM, pReq->pDescChain->uHeadIdx); 2121 2121 … … 2335 2335 * be awake due to new reqs coming in. 2336 2336 */ 2337 for (uint16_t idx Queue = 0; idxQueue < VIRTIOSCSI_REQ_QUEUE_CNT; idxQueue++)2338 { 2339 if (ASMAtomicReadBool(&pThis->aWorkers[idx Queue].fSleeping))2337 for (uint16_t idxVirtq = 0; idxVirtq < VIRTIOSCSI_REQ_VIRTQ_CNT; idxVirtq++) 2338 { 2339 if (ASMAtomicReadBool(&pThis->aWorkers[idxVirtq].fSleeping)) 2340 2340 { 2341 Log6Func(("waking %s worker.\n", VIRTQNAME(idx Queue)));2342 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idx Queue].hEvtProcess);2341 Log6Func(("waking %s worker.\n", VIRTQNAME(idxVirtq))); 2342 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pThis->aWorkers[idxVirtq].hEvtProcess); 2343 2343 AssertRC(rc); 2344 2344 } … … 2414 2414 pThisCC->pMediaNotify = NULL; 2415 2415 2416 for (unsigned idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2417 { 2418 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idx Queue];2416 for (unsigned idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2417 { 2418 PVIRTIOSCSIWORKER pWorker = &pThis->aWorkers[idxVirtq]; 2419 2419 if (pWorker->hEvtProcess != NIL_SUPSEMEVENT) 2420 2420 { … … 2423 2423 } 2424 2424 2425 if (pThisCC->aWorkers[idx Queue].pThread)2425 if (pThisCC->aWorkers[idxVirtq].pThread) 2426 2426 { 2427 2427 /* Destroy the thread. */ 2428 2428 int rcThread; 2429 int rc = PDMDevHlpThreadDestroy(pDevIns, pThisCC->aWorkers[idx Queue].pThread, &rcThread);2429 int rc = PDMDevHlpThreadDestroy(pDevIns, pThisCC->aWorkers[idxVirtq].pThread, &rcThread); 2430 2430 if (RT_FAILURE(rc) || RT_FAILURE(rcThread)) 2431 2431 AssertMsgFailed(("%s Failed to destroythread rc=%Rrc rcThread=%Rrc\n", 2432 2432 __FUNCTION__, rc, rcThread)); 2433 pThisCC->aWorkers[idx Queue].pThread = NULL;2433 pThisCC->aWorkers[idxVirtq].pThread = NULL; 2434 2434 } 2435 2435 } … … 2487 2487 2488 2488 /* Configure virtio_scsi_config that transacts via VirtIO implementation's Dev. Specific Cap callbacks */ 2489 pThis->virtioScsiConfig.uNum Queues = VIRTIOSCSI_REQ_QUEUE_CNT;2489 pThis->virtioScsiConfig.uNumVirtqs = VIRTIOSCSI_REQ_VIRTQ_CNT; 2490 2490 pThis->virtioScsiConfig.uSegMax = VIRTIOSCSI_MAX_SEG_COUNT; 2491 2491 pThis->virtioScsiConfig.uMaxSectors = VIRTIOSCSI_MAX_SECTORS_HINT; … … 2499 2499 2500 2500 /* Initialize the generic Virtio core: */ 2501 pThisCC->Virtio.pfn QueueNotified = virtioScsiNotified;2501 pThisCC->Virtio.pfnVirtqNotified = virtioScsiNotified; 2502 2502 pThisCC->Virtio.pfnStatusChanged = virtioScsiR3StatusChanged; 2503 2503 pThisCC->Virtio.pfnDevCapRead = virtioScsiR3DevCapRead; … … 2526 2526 2527 2527 /* Attach the queues and create worker threads for them: */ 2528 for (uint16_t idx Queue = 0; idxQueue < VIRTIOSCSI_QUEUE_CNT; idxQueue++)2529 { 2530 rc = virtioCoreR3 QueueAttach(&pThis->Virtio, idxQueue, VIRTQNAME(idxQueue));2528 for (uint16_t idxVirtq = 0; idxVirtq < VIRTIOSCSI_VIRTQ_CNT; idxVirtq++) 2529 { 2530 rc = virtioCoreR3VirtqAttach(&pThis->Virtio, idxVirtq, VIRTQNAME(idxVirtq)); 2531 2531 if (RT_FAILURE(rc)) 2532 2532 continue; 2533 if (idx Queue == CONTROLQ_IDX || IS_REQ_QUEUE(idxQueue))2533 if (idxVirtq == CONTROLQ_IDX || IS_REQ_VIRTQ(idxVirtq)) 2534 2534 { 2535 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[idx Queue].pThread,2536 (void *)(uintptr_t)idx Queue, virtioScsiR3WorkerThread,2537 virtioScsiR3WorkerWakeUp, 0, RTTHREADTYPE_IO, VIRTQNAME(idx Queue));2535 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->aWorkers[idxVirtq].pThread, 2536 (void *)(uintptr_t)idxVirtq, virtioScsiR3WorkerThread, 2537 virtioScsiR3WorkerWakeUp, 0, RTTHREADTYPE_IO, VIRTQNAME(idxVirtq)); 2538 2538 if (rc != VINF_SUCCESS) 2539 2539 { 2540 LogRel(("Error creating thread for Virtual Queue %s: %Rrc\n", VIRTQNAME(idxQueue), rc));2540 LogRel(("Error creating thread for Virtual Virtq %s: %Rrc\n", VIRTQNAME(idxVirtq), rc)); 2541 2541 return rc; 2542 2542 } 2543 2543 2544 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[idx Queue].hEvtProcess);2544 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->aWorkers[idxVirtq].hEvtProcess); 2545 2545 if (RT_FAILURE(rc)) 2546 2546 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 2547 2547 N_("DevVirtioSCSI: Failed to create SUP event semaphore")); 2548 2548 } 2549 pThis->af QueueAttached[idxQueue] = true;2549 pThis->afVirtqAttached[idxVirtq] = true; 2550 2550 } 2551 2551 … … 2666 2666 2667 2667 2668 pThisCC->Virtio.pfn QueueNotified = virtioScsiNotified;2668 pThisCC->Virtio.pfnVirtqNotified = virtioScsiNotified; 2669 2669 return virtioCoreRZInit(pDevIns, &pThis->Virtio); 2670 2670 } -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r84783 r84803 42 42 *********************************************************************************************************************************/ 43 43 #define INSTANCE(a_pVirtio) ((a_pVirtio)->szInstance) 44 #define VIRTQNAME(a_pVirtio, a_idx Queue) ((a_pVirtio)->virtqState[(a_idxQueue)].szVirtqName)44 #define VIRTQNAME(a_pVirtio, a_idxVirtq) ((a_pVirtio)->aVirtqState[(a_idxVirtq)].szVirtqName) 45 45 #define IS_DRIVER_OK(a_pVirtio) ((a_pVirtio)->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK) 46 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtq ) \47 (virtioCore QueueAvailCount(pDevIns, pVirtio, pVirtq) == 0)46 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtqState) \ 47 (virtioCoreVirtqAvailCount(pDevIns, pVirtio, pVirtqState) == 0) 48 48 49 49 /** … … 135 135 /* Internal Functions */ 136 136 137 static void virtioCoreNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue);137 static void virtioCoreNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq); 138 138 static int virtioKick(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint8_t uCause, uint16_t uVec); 139 139 … … 145 145 */ 146 146 #ifdef IN_RING3 147 DECLINLINE(void) virtioReadDesc(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue,147 DECLINLINE(void) virtioReadDesc(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 148 148 uint32_t idxDesc, PVIRTQ_DESC_T pDesc) 149 149 { 150 150 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 151 uint16_t const c QueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */151 uint16_t const cVirtqItems = RT_MAX(pVirtio->uVirtqSize[idxVirtq], 1); /* Make sure to avoid div-by-zero. */ 152 152 PDMDevHlpPCIPhysRead(pDevIns, 153 pVirtio->aGCPhys QueueDesc[idxQueue] + sizeof(VIRTQ_DESC_T) * (idxDesc % cQueueItems),153 pVirtio->aGCPhysVirtqDesc[idxVirtq] + sizeof(VIRTQ_DESC_T) * (idxDesc % cVirtqItems), 154 154 pDesc, sizeof(VIRTQ_DESC_T)); 155 155 } … … 160 160 */ 161 161 #ifdef IN_RING3 162 DECLINLINE(uint16_t) virtioReadAvailDescIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue, uint32_t availIdx)162 DECLINLINE(uint16_t) virtioReadAvailDescIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, uint32_t availIdx) 163 163 { 164 164 uint16_t uDescIdx; 165 165 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 166 uint16_t const c QueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */166 uint16_t const cVirtqItems = RT_MAX(pVirtio->uVirtqSize[idxVirtq], 1); /* Make sure to avoid div-by-zero. */ 167 167 PDMDevHlpPCIPhysRead(pDevIns, 168 pVirtio->aGCPhys QueueAvail[idxQueue]169 + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[availIdx % c QueueItems]),168 pVirtio->aGCPhysVirtqAvail[idxVirtq] 169 + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[availIdx % cVirtqItems]), 170 170 &uDescIdx, sizeof(uDescIdx)); 171 171 return uDescIdx; 172 172 } 173 173 174 DECLINLINE(uint16_t) virtioReadAvailUsedEvent(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)174 DECLINLINE(uint16_t) virtioReadAvailUsedEvent(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 175 175 { 176 176 uint16_t uUsedEventIdx; … … 178 178 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 179 179 PDMDevHlpPCIPhysRead(pDevIns, 180 pVirtio->aGCPhys QueueAvail[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[pVirtio->uQueueSize[idxQueue]]),180 pVirtio->aGCPhysVirtqAvail[idxVirtq] + RT_UOFFSETOF_DYN(VIRTQ_AVAIL_T, auRing[pVirtio->uVirtqSize[idxVirtq]]), 181 181 &uUsedEventIdx, sizeof(uUsedEventIdx)); 182 182 return uUsedEventIdx; … … 184 184 #endif 185 185 186 DECLINLINE(uint16_t) virtioReadAvailRingIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)186 DECLINLINE(uint16_t) virtioReadAvailRingIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 187 187 { 188 188 uint16_t uIdx = 0; 189 189 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 190 190 PDMDevHlpPCIPhysRead(pDevIns, 191 pVirtio->aGCPhys QueueAvail[idxQueue] + RT_UOFFSETOF(VIRTQ_AVAIL_T, uIdx),191 pVirtio->aGCPhysVirtqAvail[idxVirtq] + RT_UOFFSETOF(VIRTQ_AVAIL_T, uIdx), 192 192 &uIdx, sizeof(uIdx)); 193 193 return uIdx; 194 194 } 195 195 196 DECLINLINE(uint16_t) virtioReadAvailRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)196 DECLINLINE(uint16_t) virtioReadAvailRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 197 197 { 198 198 uint16_t fFlags = 0; 199 199 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 200 200 PDMDevHlpPCIPhysRead(pDevIns, 201 pVirtio->aGCPhys QueueAvail[idxQueue] + RT_UOFFSETOF(VIRTQ_AVAIL_T, fFlags),201 pVirtio->aGCPhysVirtqAvail[idxVirtq] + RT_UOFFSETOF(VIRTQ_AVAIL_T, fFlags), 202 202 &fFlags, sizeof(fFlags)); 203 203 return fFlags; … … 211 211 212 212 #ifdef IN_RING3 213 DECLINLINE(void) virtioWriteUsedElem(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue,213 DECLINLINE(void) virtioWriteUsedElem(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 214 214 uint32_t usedIdx, uint32_t uDescIdx, uint32_t uLen) 215 215 { 216 216 VIRTQ_USED_ELEM_T elem = { uDescIdx, uLen }; 217 217 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 218 uint16_t const c QueueItems = RT_MAX(pVirtio->uQueueSize[idxQueue], 1); /* Make sure to avoid div-by-zero. */218 uint16_t const cVirtqItems = RT_MAX(pVirtio->uVirtqSize[idxVirtq], 1); /* Make sure to avoid div-by-zero. */ 219 219 PDMDevHlpPCIPhysWrite(pDevIns, 220 pVirtio->aGCPhys QueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[usedIdx % cQueueItems]),220 pVirtio->aGCPhysVirtqUsed[idxVirtq] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[usedIdx % cVirtqItems]), 221 221 &elem, sizeof(elem)); 222 222 } 223 223 224 DECLINLINE(void) virtioWriteUsedRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue, uint16_t fFlags)224 DECLINLINE(void) virtioWriteUsedRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, uint16_t fFlags) 225 225 { 226 226 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 227 227 RT_UNTRUSTED_VALIDATED_FENCE(); /* VirtIO 1.0, Section 3.2.1.4.1 */ 228 228 PDMDevHlpPCIPhysWrite(pDevIns, 229 pVirtio->aGCPhys QueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags),229 pVirtio->aGCPhysVirtqUsed[idxVirtq] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags), 230 230 &fFlags, sizeof(fFlags)); 231 231 } 232 232 #endif 233 233 234 DECLINLINE(void) virtioWriteUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue, uint16_t uIdx)234 DECLINLINE(void) virtioWriteUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, uint16_t uIdx) 235 235 { 236 236 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 237 237 PDMDevHlpPCIPhysWrite(pDevIns, 238 pVirtio->aGCPhys QueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx),238 pVirtio->aGCPhysVirtqUsed[idxVirtq] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx), 239 239 &uIdx, sizeof(uIdx)); 240 240 } … … 243 243 #ifdef IN_RING3 244 244 245 DECLINLINE(uint16_t) virtioReadUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)245 DECLINLINE(uint16_t) virtioReadUsedRingIdx(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 246 246 { 247 247 uint16_t uIdx = 0; 248 248 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 249 249 PDMDevHlpPCIPhysRead(pDevIns, 250 pVirtio->aGCPhys QueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx),250 pVirtio->aGCPhysVirtqUsed[idxVirtq] + RT_UOFFSETOF(VIRTQ_USED_T, uIdx), 251 251 &uIdx, sizeof(uIdx)); 252 252 return uIdx; 253 253 } 254 254 255 DECLINLINE(uint16_t) virtioReadUsedRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)255 DECLINLINE(uint16_t) virtioReadUsedRingFlags(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 256 256 { 257 257 uint16_t fFlags = 0; 258 258 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 259 259 PDMDevHlpPCIPhysRead(pDevIns, 260 pVirtio->aGCPhys QueueUsed[idxQueue] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags),260 pVirtio->aGCPhysVirtqUsed[idxVirtq] + RT_UOFFSETOF(VIRTQ_USED_T, fFlags), 261 261 &fFlags, sizeof(fFlags)); 262 262 return fFlags; 263 263 } 264 264 265 DECLINLINE(void) virtioWriteUsedAvailEvent(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue, uint32_t uAvailEventIdx)265 DECLINLINE(void) virtioWriteUsedAvailEvent(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, uint32_t uAvailEventIdx) 266 266 { 267 267 /** VirtIO 1.0 uAvailEventIdx (avail_event) immediately follows ring */ 268 268 AssertMsg(pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK, ("Called with guest driver not ready\n")); 269 269 PDMDevHlpPCIPhysWrite(pDevIns, 270 pVirtio->aGCPhys QueueUsed[idxQueue] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtio->uQueueSize[idxQueue]]),270 pVirtio->aGCPhysVirtqUsed[idxVirtq] + RT_UOFFSETOF_DYN(VIRTQ_USED_T, aRing[pVirtio->uVirtqSize[idxVirtq]]), 271 271 &uAvailEventIdx, sizeof(uAvailEventIdx)); 272 272 } … … 275 275 #endif 276 276 277 DECLINLINE(uint16_t) virtioCore QueueAvailCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, PVIRTQSTATE pVirtq)278 { 279 uint16_t uIdx = virtioReadAvailRingIdx(pDevIns, pVirtio, pVirtq ->idxQueue);280 uint16_t uShadow = pVirtq ->uAvailIdxShadow;277 DECLINLINE(uint16_t) virtioCoreVirtqAvailCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, PVIRTQSTATE pVirtqState) 278 { 279 uint16_t uIdx = virtioReadAvailRingIdx(pDevIns, pVirtio, pVirtqState->idxVirtq); 280 uint16_t uShadow = pVirtqState->uAvailIdxShadow; 281 281 282 282 uint16_t uDelta; … … 287 287 288 288 LogFunc(("%s has %u %s (idx=%u shadow=%u)\n", 289 VIRTQNAME(pVirtio, pVirtq ->idxQueue), uDelta, uDelta == 1 ? "entry" : "entries",289 VIRTQNAME(pVirtio, pVirtqState->idxVirtq), uDelta, uDelta == 1 ? "entry" : "entries", 290 290 uIdx, uShadow)); 291 291 … … 297 297 * @param pDevIns The device instance. 298 298 * @param pVirtio Pointer to the shared virtio state. 299 * @param idx Queue Queuenumber299 * @param idxVirtq Virtq number 300 300 * 301 301 * @returns how many entries have been added to ring as a delta of the consumer's 302 302 * avail index and the queue's guest-side current avail index. 303 303 */ 304 uint16_t virtioCore QueueAvailCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue)305 { 306 if (!IS_DRIVER_OK(pVirtio) || !pVirtio->u QueueEnable[idxQueue])304 uint16_t virtioCoreVirtqAvailCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 305 { 306 if (!IS_DRIVER_OK(pVirtio) || !pVirtio->uVirtqEnable[idxVirtq]) 307 307 { 308 308 LogRelFunc(("Driver not ready or queue not enabled\n")); 309 309 return 0; 310 310 } 311 return virtioCore QueueAvailCount(pDevIns, pVirtio, &pVirtio->virtqState[idxQueue]);311 return virtioCoreVirtqAvailCount(pDevIns, pVirtio, &pVirtio->aVirtqState[idxVirtq]); 312 312 } 313 313 … … 681 681 bool fState = pszArgs && (*pszArgs == 's' || *pszArgs == 'S'); /* "state" */ 682 682 bool fPointers = pszArgs && (*pszArgs == 'p' || *pszArgs == 'P'); /* "pointers" */ 683 bool f Queues = pszArgs && (*pszArgs == 'q' || *pszArgs == 'Q'); /* "queues */684 RT_NOREF6(fNone, fAll, fBasic, fState, fPointers, f Queues);683 bool fVirtqs = pszArgs && (*pszArgs == 'q' || *pszArgs == 'Q'); /* "queues */ 684 RT_NOREF6(fNone, fAll, fBasic, fState, fPointers, fVirtqs); 685 685 pHlp->pfnPrintf(pHlp, ""); 686 686 687 687 } 688 688 689 void virtioCoreR3 QueueInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs, int idxQueue)689 void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs, int idxVirtq) 690 690 { 691 691 RT_NOREF(pszArgs); 692 692 PVIRTIOCORE pVirtio = PDMDEVINS_2_DATA(pDevIns, PVIRTIOCORE); 693 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];693 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 694 694 695 695 // bool fDump = pszArgs && (*pszArgs == 'd' || *pszArgs == 'D'); /* "dump" (avail phys descriptor)" */ 696 696 697 uint16_t uAvailIdx = virtioReadAvailRingIdx(pDevIns, pVirtio, idx Queue);698 uint16_t uAvailIdxShadow = pVirtq ->uAvailIdxShadow;699 700 uint16_t uUsedIdx = virtioReadUsedRingIdx(pDevIns, pVirtio, idx Queue);701 uint16_t uUsedIdxShadow = pVirtq ->uUsedIdxShadow;697 uint16_t uAvailIdx = virtioReadAvailRingIdx(pDevIns, pVirtio, idxVirtq); 698 uint16_t uAvailIdxShadow = pVirtqState->uAvailIdxShadow; 699 700 uint16_t uUsedIdx = virtioReadUsedRingIdx(pDevIns, pVirtio, idxVirtq); 701 uint16_t uUsedIdxShadow = pVirtqState->uUsedIdxShadow; 702 702 703 703 PVIRTIO_DESC_CHAIN_T pDescChain = NULL; 704 704 705 bool fEmpty = IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtq );706 707 LogFunc(("%s, empty = %s\n", VIRTQNAME(pVirtio, idx Queue), fEmpty ? "true" : "false"));705 bool fEmpty = IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtqState); 706 707 LogFunc(("%s, empty = %s\n", VIRTQNAME(pVirtio, idxVirtq), fEmpty ? "true" : "false")); 708 708 709 709 int cSendSegs = 0, cReturnSegs = 0; 710 710 if (!fEmpty) 711 711 { 712 virtioCoreR3 QueuePeek(pDevIns, pVirtio, idxQueue, &pDescChain);712 virtioCoreR3VirtqPeek(pDevIns, pVirtio, idxVirtq, &pDescChain); 713 713 cSendSegs = pDescChain->pSgPhysSend ? pDescChain->pSgPhysSend->cSegs : 0; 714 714 cReturnSegs = pDescChain->pSgPhysReturn ? pDescChain->pSgPhysReturn->cSegs : 0; 715 715 } 716 716 717 bool fAvailNoInterrupt = virtioReadAvailRingFlags(pDevIns, pVirtio, idx Queue) & VIRTQ_AVAIL_F_NO_INTERRUPT;718 bool fUsedNoNotify = virtioReadUsedRingFlags(pDevIns, pVirtio, idx Queue) & VIRTQ_USED_F_NO_NOTIFY;719 720 721 pHlp->pfnPrintf(pHlp, " queue enabled: ........... %s\n", pVirtio->u QueueEnable[idxQueue] ? "true" : "false");722 pHlp->pfnPrintf(pHlp, " size: .................... %d\n", pVirtio->u QueueSize[idxQueue]);723 pHlp->pfnPrintf(pHlp, " notify offset: ........... %d\n", pVirtio->u QueueNotifyOff[idxQueue]);717 bool fAvailNoInterrupt = virtioReadAvailRingFlags(pDevIns, pVirtio, idxVirtq) & VIRTQ_AVAIL_F_NO_INTERRUPT; 718 bool fUsedNoNotify = virtioReadUsedRingFlags(pDevIns, pVirtio, idxVirtq) & VIRTQ_USED_F_NO_NOTIFY; 719 720 721 pHlp->pfnPrintf(pHlp, " queue enabled: ........... %s\n", pVirtio->uVirtqEnable[idxVirtq] ? "true" : "false"); 722 pHlp->pfnPrintf(pHlp, " size: .................... %d\n", pVirtio->uVirtqSize[idxVirtq]); 723 pHlp->pfnPrintf(pHlp, " notify offset: ........... %d\n", pVirtio->uVirtqNotifyOff[idxVirtq]); 724 724 if (pVirtio->fMsiSupport) 725 pHlp->pfnPrintf(pHlp, " MSIX vector: ....... %4.4x\n", pVirtio->u QueueMsixVector[idxQueue]);725 pHlp->pfnPrintf(pHlp, " MSIX vector: ....... %4.4x\n", pVirtio->uVirtqMsixVector[idxVirtq]); 726 726 pHlp->pfnPrintf(pHlp, "\n"); 727 727 pHlp->pfnPrintf(pHlp, " avail ring (%d entries):\n", uAvailIdx - uAvailIdxShadow); … … 747 747 { 748 748 pHlp->pfnPrintf(pHlp, " index: ............. %d\n", pDescChain->pSgPhysSend->idxSeg); 749 pHlp->pfnPrintf(pHlp, " unsent ............. %d\n", 749 pHlp->pfnPrintf(pHlp, " unsent ............. %d\n", pDescChain->pSgPhysSend->cbSegLeft); 750 750 } 751 751 pHlp->pfnPrintf(pHlp, "\n"); … … 755 755 { 756 756 pHlp->pfnPrintf(pHlp, " index: ............. %d\n", pDescChain->pSgPhysReturn->idxSeg); 757 pHlp->pfnPrintf(pHlp, " unsent ............. %d\n", 757 pHlp->pfnPrintf(pHlp, " unsent ............. %d\n", pDescChain->pSgPhysReturn->cbSegLeft); 758 758 } 759 759 } else … … 767 767 * 768 768 * @param pVirtio Pointer to the shared virtio state. 769 * @param idx Queue Queuenumber769 * @param idxVirtq Virtq number 770 770 * @param pcszName Name to give queue 771 771 * 772 772 * @returns VBox status code. 773 773 */ 774 int virtioCoreR3 QueueAttach(PVIRTIOCORE pVirtio, uint16_t idxQueue, const char *pcszName)774 int virtioCoreR3VirtqAttach(PVIRTIOCORE pVirtio, uint16_t idxVirtq, const char *pcszName) 775 775 { 776 776 LogFunc(("%s\n", pcszName)); 777 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];778 pVirtq ->idxQueue = idxQueue;779 pVirtq ->uAvailIdxShadow = 0;780 pVirtq ->uUsedIdxShadow = 0;781 pVirtq ->fVirtqRingEventThreshold = false;782 RTStrCopy(pVirtq ->szVirtqName, sizeof(pVirtq->szVirtqName), pcszName);777 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 778 pVirtqState->idxVirtq = idxVirtq; 779 pVirtqState->uAvailIdxShadow = 0; 780 pVirtqState->uUsedIdxShadow = 0; 781 pVirtqState->fVirtqRingEventThreshold = false; 782 RTStrCopy(pVirtqState->szVirtqName, sizeof(pVirtqState->szVirtqName), pcszName); 783 783 return VINF_SUCCESS; 784 784 } … … 788 788 #ifdef IN_RING3 789 789 790 int virtioCoreR3DescChainGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue,790 int virtioCoreR3DescChainGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 791 791 uint16_t uHeadIdx, PPVIRTIO_DESC_CHAIN_T ppDescChain) 792 792 { … … 794 794 *ppDescChain = NULL; 795 795 796 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));797 798 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];799 800 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->u QueueEnable[idxQueue],796 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 797 798 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 799 800 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->uVirtqEnable[idxVirtq], 801 801 ("Guest driver not in ready state.\n"), VERR_INVALID_STATE); 802 802 803 803 uint16_t uDescIdx = uHeadIdx; 804 804 805 Log6Func(("%s DESC CHAIN: (head) desc_idx=%u\n", pVirtq ->szVirtqName, uHeadIdx));806 RT_NOREF(pVirtq );805 Log6Func(("%s DESC CHAIN: (head) desc_idx=%u\n", pVirtqState->szVirtqName, uHeadIdx)); 806 RT_NOREF(pVirtqState); 807 807 808 808 /* … … 853 853 RT_UNTRUSTED_VALIDATED_FENCE(); 854 854 855 virtioReadDesc(pDevIns, pVirtio, idx Queue, uDescIdx, &desc);855 virtioReadDesc(pDevIns, pVirtio, idxVirtq, uDescIdx, &desc); 856 856 857 857 if (desc.fFlags & VIRTQ_DESC_F_WRITE) 858 858 { 859 Log6Func(("%s IN desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idx Queue), uDescIdx, cSegsIn, desc.GCPhysBuf, desc.cb));859 Log6Func(("%s IN desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxVirtq), uDescIdx, cSegsIn, desc.GCPhysBuf, desc.cb)); 860 860 cbIn += desc.cb; 861 861 pSeg = &paSegsIn[cSegsIn++]; … … 863 863 else 864 864 { 865 Log6Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idx Queue), uDescIdx, cSegsOut, desc.GCPhysBuf, desc.cb));865 Log6Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxVirtq), uDescIdx, cSegsOut, desc.GCPhysBuf, desc.cb)); 866 866 cbOut += desc.cb; 867 867 pSeg = &paSegsOut[cSegsOut++]; … … 899 899 900 900 STAM_REL_COUNTER_INC(&pVirtio->StatDescChainsAllocated); 901 Log6Func(("%s -- segs OUT: %u (%u bytes) IN: %u (%u bytes) --\n", pVirtq ->szVirtqName, cSegsOut, cbOut, cSegsIn, cbIn));901 Log6Func(("%s -- segs OUT: %u (%u bytes) IN: %u (%u bytes) --\n", pVirtqState->szVirtqName, cSegsOut, cbOut, cSegsIn, cbIn)); 902 902 903 903 return VINF_SUCCESS; … … 964 964 * 965 965 * @param pVirtio Pointer to the shared virtio state. 966 * @param idx Queue Queuenumber966 * @param idxVirtq Virtq number 967 967 * @param fEnable Selects notification mode (enabled or disabled) 968 968 */ 969 void virtioCore QueueNotifyEnable(PVIRTIOCORE pVirtio, uint16_t idxQueue, bool fEnable)969 void virtioCoreVirtqNotifyEnable(PVIRTIOCORE pVirtio, uint16_t idxVirtq, bool fEnable) 970 970 { 971 971 if (pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK) 972 972 { 973 uint16_t fFlags = virtioReadUsedRingFlags(pVirtio->pDevInsR3, pVirtio, idx Queue);973 uint16_t fFlags = virtioReadUsedRingFlags(pVirtio->pDevInsR3, pVirtio, idxVirtq); 974 974 975 975 if (fEnable) … … 978 978 fFlags |= VIRTQ_USED_F_NO_NOTIFY; 979 979 980 virtioWriteUsedRingFlags(pVirtio->pDevInsR3, pVirtio, idx Queue, fFlags);980 virtioWriteUsedRingFlags(pVirtio->pDevInsR3, pVirtio, idxVirtq, fFlags); 981 981 } 982 982 } … … 999 999 } 1000 1000 1001 1002 1003 1001 /** 1004 1002 * Fetches descriptor chain using avail ring of indicated queue and converts the descriptor 1005 1003 * chain into its OUT (to device) and IN to guest components, but does NOT remove it from 1006 * the 'avail' queue. I.e. doesn't advance the index. This can be used with virtio QueueSkip(),1004 * the 'avail' queue. I.e. doesn't advance the index. This can be used with virtioVirtqSkip(), 1007 1005 * which *does* advance the avail index. Together they facilitate a mechanism that allows 1008 1006 * work with a queue element (descriptor chain) to be aborted if necessary, by not advancing … … 1011 1009 * Additionally it converts the OUT desc chain data to a contiguous virtual 1012 1010 * memory buffer for easy consumption by the caller. The caller must return the 1013 * descriptor chain pointer via virtioCoreR3 QueuePut() and then call virtioCoreQueueSync()1011 * descriptor chain pointer via virtioCoreR3VirtqPut() and then call virtioCoreVirtqSync() 1014 1012 * at some point to return the data to the guest and complete the transaction. 1015 1013 * 1016 1014 * @param pDevIns The device instance. 1017 1015 * @param pVirtio Pointer to the shared virtio state. 1018 * @param idx Queue Queuenumber1016 * @param idxVirtq Virtq number 1019 1017 * @param ppDescChain Address to store pointer to descriptor chain that contains the 1020 1018 * pre-processed transaction information pulled from the virtq. … … 1026 1024 */ 1027 1025 1028 int virtioCoreR3 QueuePeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue,1026 int virtioCoreR3VirtqPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 1029 1027 PPVIRTIO_DESC_CHAIN_T ppDescChain) 1030 1028 { 1031 return virtioCoreR3 QueueGet(pDevIns, pVirtio, idxQueue, ppDescChain, false);1032 } 1033 1034 /** 1035 * Skip the next entry in the specified queue (typically used with virtioCoreR3 QueuePeek())1029 return virtioCoreR3VirtqGet(pDevIns, pVirtio, idxVirtq, ppDescChain, false); 1030 } 1031 1032 /** 1033 * Skip the next entry in the specified queue (typically used with virtioCoreR3VirtqPeek()) 1036 1034 * 1037 1035 * @param pVirtio Pointer to the virtio state. 1038 * @param idx QueueIndex of queue1039 */ 1040 int virtioCoreR3 QueueSkip(PVIRTIOCORE pVirtio, uint16_t idxQueue)1041 { 1042 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));1043 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];1044 1045 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->u QueueEnable[idxQueue],1036 * @param idxVirtq Index of queue 1037 */ 1038 int virtioCoreR3VirtqSkip(PVIRTIOCORE pVirtio, uint16_t idxVirtq) 1039 { 1040 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 1041 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 1042 1043 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->uVirtqEnable[idxVirtq], 1046 1044 ("Guest driver not in ready state.\n"), VERR_INVALID_STATE); 1047 1045 1048 if (IS_VIRTQ_EMPTY(pVirtio->pDevInsR3, pVirtio, pVirtq ))1046 if (IS_VIRTQ_EMPTY(pVirtio->pDevInsR3, pVirtio, pVirtqState)) 1049 1047 return VERR_NOT_AVAILABLE; 1050 1048 1051 Log6Func(("%s avail shadow idx: %u\n", pVirtq ->szVirtqName, pVirtq->uAvailIdxShadow));1052 pVirtq ->uAvailIdxShadow++;1049 Log6Func(("%s avail shadow idx: %u\n", pVirtqState->szVirtqName, pVirtqState->uAvailIdxShadow)); 1050 pVirtqState->uAvailIdxShadow++; 1053 1051 1054 1052 return VINF_SUCCESS; … … 1061 1059 * Additionally it converts the OUT desc chain data to a contiguous virtual 1062 1060 * memory buffer for easy consumption by the caller. The caller must return the 1063 * descriptor chain pointer via virtioCoreR3 QueuePut() and then call virtioCoreQueueSync()1061 * descriptor chain pointer via virtioCoreR3VirtqPut() and then call virtioCoreVirtqSync() 1064 1062 * at some point to return the data to the guest and complete the transaction. 1065 1063 * 1066 1064 * @param pDevIns The device instance. 1067 1065 * @param pVirtio Pointer to the shared virtio state. 1068 * @param idx Queue Queuenumber1066 * @param idxVirtq Virtq number 1069 1067 * @param ppDescChain Address to store pointer to descriptor chain that contains the 1070 1068 * pre-processed transaction information pulled from the virtq. … … 1078 1076 * @retval VERR_NOT_AVAILABLE If the queue is empty. 1079 1077 */ 1080 int virtioCoreR3 QueueGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue,1078 int virtioCoreR3VirtqGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 1081 1079 PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove) 1082 1080 { 1083 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];1084 1085 if (IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtq ))1081 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 1082 1083 if (IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtqState)) 1086 1084 return VERR_NOT_AVAILABLE; 1087 1085 1088 uint16_t uHeadIdx = virtioReadAvailDescIdx(pDevIns, pVirtio, idx Queue, pVirtq->uAvailIdxShadow);1086 uint16_t uHeadIdx = virtioReadAvailDescIdx(pDevIns, pVirtio, idxVirtq, pVirtqState->uAvailIdxShadow); 1089 1087 1090 1088 if (pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX) 1091 virtioWriteUsedAvailEvent(pDevIns,pVirtio, idx Queue, pVirtq->uAvailIdxShadow + 1);1089 virtioWriteUsedAvailEvent(pDevIns,pVirtio, idxVirtq, pVirtqState->uAvailIdxShadow + 1); 1092 1090 1093 1091 if (fRemove) 1094 pVirtq ->uAvailIdxShadow++;1095 1096 int rc = virtioCoreR3DescChainGet(pDevIns, pVirtio, idx Queue, uHeadIdx, ppDescChain);1092 pVirtqState->uAvailIdxShadow++; 1093 1094 int rc = virtioCoreR3DescChainGet(pDevIns, pVirtio, idxVirtq, uHeadIdx, ppDescChain); 1097 1095 return rc; 1098 1096 } 1099 1097 1100 1098 /** 1101 * Returns data to the guest to complete a transaction initiated by virt QueueGet().1099 * Returns data to the guest to complete a transaction initiated by virtVirtqGet(). 1102 1100 * 1103 1101 * The caller passes in a pointer to a scatter-gather buffer of virtual memory segments … … 1108 1106 * 1109 1107 * @note This does a write-ahead to the used ring of the guest's queue. The data 1110 * written won't be seen by the guest until the next call to virtioCore QueueSync()1108 * written won't be seen by the guest until the next call to virtioCoreVirtqSync() 1111 1109 * 1112 1110 * 1113 1111 * @param pDevIns The device instance (for reading). 1114 1112 * @param pVirtio Pointer to the shared virtio state. 1115 * @param idx Queue Queuenumber1113 * @param idxVirtq Virtq number 1116 1114 * 1117 1115 * @param pSgVirtReturn Points to scatter-gather buffer of virtual memory … … 1127 1125 * @retval VINF_SUCCESS Success 1128 1126 * @retval VERR_INVALID_STATE VirtIO not in ready state 1129 * @retval VERR_NOT_AVAILABLE Queueis empty1127 * @retval VERR_NOT_AVAILABLE Virtq is empty 1130 1128 * 1131 1129 * @note This function will not release any reference to pDescChain. The 1132 1130 * caller must take care of that. 1133 1131 */ 1134 int virtioCoreR3 QueuePut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,1132 int virtioCoreR3VirtqPut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, PRTSGBUF pSgVirtReturn, 1135 1133 PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence) 1136 1134 { 1137 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));1138 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];1135 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 1136 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 1139 1137 PVIRTIOSGBUF pSgPhysReturn = pDescChain->pSgPhysReturn; 1140 1138 … … 1145 1143 1146 1144 Log6Func(("Copying client data to %s, desc chain (head desc_idx %d)\n", 1147 VIRTQNAME(pVirtio, idx Queue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue)));1145 VIRTQNAME(pVirtio, idxVirtq), virtioReadUsedRingIdx(pDevIns, pVirtio, idxVirtq))); 1148 1146 1149 1147 /* Copy s/g buf (virtual memory) to guest phys mem (IN direction). */ … … 1175 1173 /* If this write-ahead crosses threshold where the driver wants to get an event flag it */ 1176 1174 if (pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX) 1177 if (pVirtq ->uUsedIdxShadow == virtioReadAvailUsedEvent(pDevIns, pVirtio, idxQueue))1178 pVirtq ->fVirtqRingEventThreshold = true;1175 if (pVirtqState->uUsedIdxShadow == virtioReadAvailUsedEvent(pDevIns, pVirtio, idxVirtq)) 1176 pVirtqState->fVirtqRingEventThreshold = true; 1179 1177 1180 1178 /* 1181 1179 * Place used buffer's descriptor in used ring but don't update used ring's slot index. 1182 * That will be done with a subsequent client call to virtioCore QueueSync() */1183 virtioWriteUsedElem(pDevIns, pVirtio, idx Queue, pVirtq->uUsedIdxShadow++, pDescChain->uHeadIdx, (uint32_t)cbTotal);1180 * That will be done with a subsequent client call to virtioCoreVirtqSync() */ 1181 virtioWriteUsedElem(pDevIns, pVirtio, idxVirtq, pVirtqState->uUsedIdxShadow++, pDescChain->uHeadIdx, (uint32_t)cbTotal); 1184 1182 1185 1183 if (pSgVirtReturn) … … 1188 1186 1189 1187 Log6Func(("Write ahead used_idx=%u, %s used_idx=%u\n", 1190 pVirtq ->uUsedIdxShadow, VIRTQNAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue)));1188 pVirtqState->uUsedIdxShadow, VIRTQNAME(pVirtio, idxVirtq), virtioReadUsedRingIdx(pDevIns, pVirtio, idxVirtq))); 1191 1189 1192 1190 return VINF_SUCCESS; … … 1198 1196 * Updates the indicated virtq's "used ring" descriptor index to match the 1199 1197 * current write-head index, thus exposing the data added to the used ring by all 1200 * virtioCoreR3 QueuePut() calls since the last sync. This should be called after one or1201 * more virtioCoreR3 QueuePut() calls to inform the guest driver there is data in the queue.1198 * virtioCoreR3VirtqPut() calls since the last sync. This should be called after one or 1199 * more virtioCoreR3VirtqPut() calls to inform the guest driver there is data in the queue. 1202 1200 * Explicit notifications (e.g. interrupt or MSI-X) will be sent to the guest, 1203 1201 * depending on VirtIO features negotiated and conditions, otherwise the guest … … 1206 1204 * @param pDevIns The device instance. 1207 1205 * @param pVirtio Pointer to the shared virtio state. 1208 * @param idx Queue Queuenumber1206 * @param idxVirtq Virtq number 1209 1207 * 1210 1208 * @returns VBox status code. … … 1212 1210 * @retval VERR_INVALID_STATE VirtIO not in ready state 1213 1211 */ 1214 int virtioCore QueueSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue)1215 { 1216 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));1217 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];1218 1219 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->u QueueEnable[idxQueue],1212 int virtioCoreVirtqSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 1213 { 1214 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 1215 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 1216 1217 AssertMsgReturn(IS_DRIVER_OK(pVirtio) && pVirtio->uVirtqEnable[idxVirtq], 1220 1218 ("Guest driver not in ready state.\n"), VERR_INVALID_STATE); 1221 1219 1222 1220 Log6Func(("Updating %s used_idx to %u\n", 1223 VIRTQNAME(pVirtio, idx Queue), pVirtq->uUsedIdxShadow));1224 1225 virtioWriteUsedRingIdx(pDevIns, pVirtio, idx Queue, pVirtq->uUsedIdxShadow);1226 virtioCoreNotifyGuestDriver(pDevIns, pVirtio, idx Queue);1221 VIRTQNAME(pVirtio, idxVirtq), pVirtqState->uUsedIdxShadow)); 1222 1223 virtioWriteUsedRingIdx(pDevIns, pVirtio, idxVirtq, pVirtqState->uUsedIdxShadow); 1224 virtioCoreNotifyGuestDriver(pDevIns, pVirtio, idxVirtq); 1227 1225 1228 1226 return VINF_SUCCESS; … … 1232 1230 /** 1233 1231 */ 1234 static void virtioCore QueueNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, uint16_t uNotifyIdx)1232 static void virtioCoreVirtqNotified(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, uint16_t uNotifyIdx) 1235 1233 { 1236 1234 1237 1235 PVIRTIOCORECC pVirtioCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIOCORECC); 1238 1236 1239 /* See VirtIO 1.0, section 4.1.5.2 It implies that idx Queueand uNotifyIdx should match.1237 /* See VirtIO 1.0, section 4.1.5.2 It implies that idxVirtq and uNotifyIdx should match. 1240 1238 * Disregarding this notification may cause throughput to stop, however there's no way to know 1241 1239 * which was queue was intended for wake-up if the two parameters disagree. */ 1242 1240 1243 AssertMsg(uNotifyIdx == idx Queue,1241 AssertMsg(uNotifyIdx == idxVirtq, 1244 1242 ("Guest kicked virtq %d's notify addr w/non-corresponding virtq idx %d\n", 1245 idx Queue, uNotifyIdx));1243 idxVirtq, uNotifyIdx)); 1246 1244 RT_NOREF(uNotifyIdx); 1247 1245 1248 AssertReturnVoid(idx Queue < RT_ELEMENTS(pVirtio->virtqState));1246 AssertReturnVoid(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 1249 1247 Log6Func(("%s (desc chains: %u)\n", 1250 pVirtio-> virtqState[idxQueue].szVirtqName,1251 virtioCore QueueAvailCount(pDevIns, pVirtio, idxQueue)));1248 pVirtio->aVirtqState[idxVirtq].szVirtqName, 1249 virtioCoreVirtqAvailCount(pDevIns, pVirtio, idxVirtq))); 1252 1250 1253 1251 /* Inform client */ 1254 pVirtioCC->pfn QueueNotified(pDevIns, pVirtio, idxQueue);1252 pVirtioCC->pfnVirtqNotified(pDevIns, pVirtio, idxVirtq); 1255 1253 } 1256 1254 … … 1264 1262 * @param pDevIns The device instance. 1265 1263 * @param pVirtio Pointer to the shared virtio state. 1266 * @param idx Queue Queueto check for guest interrupt handling preference1267 */ 1268 static void virtioCoreNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue)1269 { 1270 1271 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));1272 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];1264 * @param idxVirtq Virtq to check for guest interrupt handling preference 1265 */ 1266 static void virtioCoreNotifyGuestDriver(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq) 1267 { 1268 1269 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 1270 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 1273 1271 1274 1272 if (!IS_DRIVER_OK(pVirtio)) … … 1280 1278 if (pVirtio->uDriverFeatures & VIRTIO_F_EVENT_IDX) 1281 1279 { 1282 if (pVirtq ->fVirtqRingEventThreshold)1280 if (pVirtqState->fVirtqRingEventThreshold) 1283 1281 { 1284 1282 #ifdef IN_RING3 1285 1283 Log6Func(("...kicking guest %s, VIRTIO_F_EVENT_IDX set and threshold (%d) reached\n", 1286 VIRTQNAME(pVirtio, idx Queue), (uint16_t)virtioReadAvailUsedEvent(pDevIns, pVirtio, idxQueue)));1284 VIRTQNAME(pVirtio, idxVirtq), (uint16_t)virtioReadAvailUsedEvent(pDevIns, pVirtio, idxVirtq))); 1287 1285 #endif 1288 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->u QueueMsixVector[idxQueue]);1289 pVirtq ->fVirtqRingEventThreshold = false;1286 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uVirtqMsixVector[idxVirtq]); 1287 pVirtqState->fVirtqRingEventThreshold = false; 1290 1288 return; 1291 1289 } 1292 1290 #ifdef IN_RING3 1293 1291 Log6Func(("...skip interrupt %s, VIRTIO_F_EVENT_IDX set but threshold (%d) not reached (%d)\n", 1294 VIRTQNAME(pVirtio, idx Queue),(uint16_t)virtioReadAvailUsedEvent(pDevIns, pVirtio, idxQueue), pVirtq->uUsedIdxShadow));1292 VIRTQNAME(pVirtio, idxVirtq),(uint16_t)virtioReadAvailUsedEvent(pDevIns, pVirtio, idxVirtq), pVirtqState->uUsedIdxShadow)); 1295 1293 #endif 1296 1294 } … … 1298 1296 { 1299 1297 /** If guest driver hasn't suppressed interrupts, interrupt */ 1300 if (!(virtioReadAvailRingFlags(pDevIns, pVirtio, idx Queue) & VIRTQ_AVAIL_F_NO_INTERRUPT))1301 { 1302 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->u QueueMsixVector[idxQueue]);1298 if (!(virtioReadAvailRingFlags(pDevIns, pVirtio, idxVirtq) & VIRTQ_AVAIL_F_NO_INTERRUPT)) 1299 { 1300 virtioKick(pDevIns, pVirtio, VIRTIO_ISR_VIRTQ_INTERRUPT, pVirtio->uVirtqMsixVector[idxVirtq]); 1303 1301 return; 1304 1302 } 1305 1303 Log6Func(("...skipping interrupt for %s (guest set VIRTQ_AVAIL_F_NO_INTERRUPT)\n", 1306 VIRTQNAME(pVirtio, idx Queue)));1304 VIRTQNAME(pVirtio, idxVirtq))); 1307 1305 } 1308 1306 } … … 1349 1347 1350 1348 #ifdef IN_RING3 1351 static void virtioReset Queue(PVIRTIOCORE pVirtio, uint16_t idxQueue)1352 { 1353 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));1354 PVIRTQSTATE pVirtq = &pVirtio->virtqState[idxQueue];1355 pVirtq ->uAvailIdxShadow = 0;1356 pVirtq ->uUsedIdxShadow = 0;1357 pVirtq ->fVirtqRingEventThreshold = false;1358 pVirtio->u QueueEnable[idxQueue] = false;1359 pVirtio->u QueueSize[idxQueue] = VIRTQ_MAX_ENTRIES;1360 pVirtio->u QueueNotifyOff[idxQueue] = idxQueue;1361 pVirtio->u QueueMsixVector[idxQueue] = idxQueue+ 2;1349 static void virtioResetVirtq(PVIRTIOCORE pVirtio, uint16_t idxVirtq) 1350 { 1351 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 1352 PVIRTQSTATE pVirtqState = &pVirtio->aVirtqState[idxVirtq]; 1353 pVirtqState->uAvailIdxShadow = 0; 1354 pVirtqState->uUsedIdxShadow = 0; 1355 pVirtqState->fVirtqRingEventThreshold = false; 1356 pVirtio->uVirtqEnable[idxVirtq] = false; 1357 pVirtio->uVirtqSize[idxVirtq] = VIRTQ_MAX_ENTRIES; 1358 pVirtio->uVirtqNotifyOff[idxVirtq] = idxVirtq; 1359 pVirtio->uVirtqMsixVector[idxVirtq] = idxVirtq + 2; 1362 1360 if (!pVirtio->fMsiSupport) /* VirtIO 1.0, 4.1.4.3 and 4.1.5.1.2 */ 1363 pVirtio->u QueueMsixVector[idxQueue] = VIRTIO_MSI_NO_VECTOR;1364 1365 virtioLowerInterrupt(pVirtio->pDevInsR3, pVirtio->u QueueMsixVector[idxQueue]);1361 pVirtio->uVirtqMsixVector[idxVirtq] = VIRTIO_MSI_NO_VECTOR; 1362 1363 virtioLowerInterrupt(pVirtio->pDevInsR3, pVirtio->uVirtqMsixVector[idxVirtq]); 1366 1364 } 1367 1365 … … 1382 1380 for (int i = 0; i < VIRTQ_MAX_CNT; i++) 1383 1381 { 1384 virtioLowerInterrupt(pDevIns, pVirtio->u QueueMsixVector[i]);1385 pVirtio->u QueueMsixVector[i];1382 virtioLowerInterrupt(pDevIns, pVirtio->uVirtqMsixVector[i]); 1383 pVirtio->uVirtqMsixVector[i]; 1386 1384 } 1387 1385 } … … 1390 1388 pVirtio->uMsixConfig = VIRTIO_MSI_NO_VECTOR; 1391 1389 1392 for (uint16_t idx Queue = 0; idxQueue < VIRTQ_MAX_CNT; idxQueue++)1393 virtioReset Queue(pVirtio, idxQueue);1390 for (uint16_t idxVirtq = 0; idxVirtq < VIRTQ_MAX_CNT; idxVirtq++) 1391 virtioResetVirtq(pVirtio, idxVirtq); 1394 1392 } 1395 1393 … … 1579 1577 } 1580 1578 } 1581 else if (MATCH_COMMON_CFG(uNum Queues))1579 else if (MATCH_COMMON_CFG(uNumVirtqs)) 1582 1580 { 1583 1581 if (fWrite) … … 1589 1587 { 1590 1588 *(uint16_t *)pv = VIRTQ_MAX_CNT; 1591 LOG_COMMON_CFG_ACCESS(uNum Queues, 0);1589 LOG_COMMON_CFG_ACCESS(uNumVirtqs, 0); 1592 1590 } 1593 1591 } … … 1651 1649 COMMON_CFG_ACCESSOR_READONLY(uConfigGeneration); 1652 1650 else 1653 if (MATCH_COMMON_CFG(u QueueSelect))1654 COMMON_CFG_ACCESSOR(u QueueSelect);1655 else 1656 if (MATCH_COMMON_CFG(u QueueSize))1657 COMMON_CFG_ACCESSOR_INDEXED(u QueueSize, pVirtio->uQueueSelect);1658 else 1659 if (MATCH_COMMON_CFG(u QueueMsixVector))1660 COMMON_CFG_ACCESSOR_INDEXED(u QueueMsixVector, pVirtio->uQueueSelect);1661 else 1662 if (MATCH_COMMON_CFG(u QueueEnable))1663 COMMON_CFG_ACCESSOR_INDEXED(u QueueEnable, pVirtio->uQueueSelect);1664 else 1665 if (MATCH_COMMON_CFG(u QueueNotifyOff))1666 COMMON_CFG_ACCESSOR_INDEXED_READONLY(u QueueNotifyOff, pVirtio->uQueueSelect);1667 else 1668 if (MATCH_COMMON_CFG(aGCPhys QueueDesc))1669 COMMON_CFG_ACCESSOR_INDEXED(aGCPhys QueueDesc, pVirtio->uQueueSelect);1670 else 1671 if (MATCH_COMMON_CFG(aGCPhys QueueAvail))1672 COMMON_CFG_ACCESSOR_INDEXED(aGCPhys QueueAvail, pVirtio->uQueueSelect);1673 else 1674 if (MATCH_COMMON_CFG(aGCPhys QueueUsed))1675 COMMON_CFG_ACCESSOR_INDEXED(aGCPhys QueueUsed, pVirtio->uQueueSelect);1651 if (MATCH_COMMON_CFG(uVirtqSelect)) 1652 COMMON_CFG_ACCESSOR(uVirtqSelect); 1653 else 1654 if (MATCH_COMMON_CFG(uVirtqSize)) 1655 COMMON_CFG_ACCESSOR_INDEXED(uVirtqSize, pVirtio->uVirtqSelect); 1656 else 1657 if (MATCH_COMMON_CFG(uVirtqMsixVector)) 1658 COMMON_CFG_ACCESSOR_INDEXED(uVirtqMsixVector, pVirtio->uVirtqSelect); 1659 else 1660 if (MATCH_COMMON_CFG(uVirtqEnable)) 1661 COMMON_CFG_ACCESSOR_INDEXED(uVirtqEnable, pVirtio->uVirtqSelect); 1662 else 1663 if (MATCH_COMMON_CFG(uVirtqNotifyOff)) 1664 COMMON_CFG_ACCESSOR_INDEXED_READONLY(uVirtqNotifyOff, pVirtio->uVirtqSelect); 1665 else 1666 if (MATCH_COMMON_CFG(aGCPhysVirtqDesc)) 1667 COMMON_CFG_ACCESSOR_INDEXED(aGCPhysVirtqDesc, pVirtio->uVirtqSelect); 1668 else 1669 if (MATCH_COMMON_CFG(aGCPhysVirtqAvail)) 1670 COMMON_CFG_ACCESSOR_INDEXED(aGCPhysVirtqAvail, pVirtio->uVirtqSelect); 1671 else 1672 if (MATCH_COMMON_CFG(aGCPhysVirtqUsed)) 1673 COMMON_CFG_ACCESSOR_INDEXED(aGCPhysVirtqUsed, pVirtio->uVirtqSelect); 1676 1674 else 1677 1675 { … … 1809 1807 if (MATCHES_VIRTIO_CAP_STRUCT(off, cb, uOffset, pVirtio->LocNotifyCap) && cb == sizeof(uint16_t)) 1810 1808 { 1811 virtioCore QueueNotified(pDevIns, pVirtio, uOffset / VIRTIO_NOTIFY_OFFSET_MULTIPLIER, *(uint16_t *)pv);1809 virtioCoreVirtqNotified(pDevIns, pVirtio, uOffset / VIRTIO_NOTIFY_OFFSET_MULTIPLIER, *(uint16_t *)pv); 1812 1810 return VINF_SUCCESS; 1813 1811 } … … 1918 1916 pHlp->pfnSSMPutU8(pSSM, pVirtio->uPciCfgDataOff); 1919 1917 pHlp->pfnSSMPutU8(pSSM, pVirtio->uISR); 1920 pHlp->pfnSSMPutU16(pSSM, pVirtio->u QueueSelect);1918 pHlp->pfnSSMPutU16(pSSM, pVirtio->uVirtqSelect); 1921 1919 pHlp->pfnSSMPutU32(pSSM, pVirtio->uDeviceFeaturesSelect); 1922 1920 pHlp->pfnSSMPutU32(pSSM, pVirtio->uDriverFeaturesSelect); … … 1925 1923 for (uint32_t i = 0; i < VIRTQ_MAX_CNT; i++) 1926 1924 { 1927 pHlp->pfnSSMPutGCPhys64(pSSM, pVirtio->aGCPhys QueueDesc[i]);1928 pHlp->pfnSSMPutGCPhys64(pSSM, pVirtio->aGCPhys QueueAvail[i]);1929 pHlp->pfnSSMPutGCPhys64(pSSM, pVirtio->aGCPhys QueueUsed[i]);1930 pHlp->pfnSSMPutU16(pSSM, pVirtio->u QueueNotifyOff[i]);1931 pHlp->pfnSSMPutU16(pSSM, pVirtio->u QueueMsixVector[i]);1932 pHlp->pfnSSMPutU16(pSSM, pVirtio->u QueueEnable[i]);1933 pHlp->pfnSSMPutU16(pSSM, pVirtio->u QueueSize[i]);1934 pHlp->pfnSSMPutU16(pSSM, pVirtio-> virtqState[i].uAvailIdxShadow);1935 pHlp->pfnSSMPutU16(pSSM, pVirtio-> virtqState[i].uUsedIdxShadow);1936 int rc = pHlp->pfnSSMPutMem(pSSM, pVirtio-> virtqState[i].szVirtqName, 32);1925 pHlp->pfnSSMPutGCPhys64(pSSM, pVirtio->aGCPhysVirtqDesc[i]); 1926 pHlp->pfnSSMPutGCPhys64(pSSM, pVirtio->aGCPhysVirtqAvail[i]); 1927 pHlp->pfnSSMPutGCPhys64(pSSM, pVirtio->aGCPhysVirtqUsed[i]); 1928 pHlp->pfnSSMPutU16(pSSM, pVirtio->uVirtqNotifyOff[i]); 1929 pHlp->pfnSSMPutU16(pSSM, pVirtio->uVirtqMsixVector[i]); 1930 pHlp->pfnSSMPutU16(pSSM, pVirtio->uVirtqEnable[i]); 1931 pHlp->pfnSSMPutU16(pSSM, pVirtio->uVirtqSize[i]); 1932 pHlp->pfnSSMPutU16(pSSM, pVirtio->aVirtqState[i].uAvailIdxShadow); 1933 pHlp->pfnSSMPutU16(pSSM, pVirtio->aVirtqState[i].uUsedIdxShadow); 1934 int rc = pHlp->pfnSSMPutMem(pSSM, pVirtio->aVirtqState[i].szVirtqName, 32); 1937 1935 AssertRCReturn(rc, rc); 1938 1936 } … … 1976 1974 pHlp->pfnSSMGetU8(pSSM, &pVirtio->uPciCfgDataOff); 1977 1975 pHlp->pfnSSMGetU8(pSSM, &pVirtio->uISR); 1978 pHlp->pfnSSMGetU16(pSSM, &pVirtio->u QueueSelect);1976 pHlp->pfnSSMGetU16(pSSM, &pVirtio->uVirtqSelect); 1979 1977 pHlp->pfnSSMGetU32(pSSM, &pVirtio->uDeviceFeaturesSelect); 1980 1978 pHlp->pfnSSMGetU32(pSSM, &pVirtio->uDriverFeaturesSelect); … … 1983 1981 for (uint32_t i = 0; i < VIRTQ_MAX_CNT; i++) 1984 1982 { 1985 pHlp->pfnSSMGetGCPhys64(pSSM, &pVirtio->aGCPhys QueueDesc[i]);1986 pHlp->pfnSSMGetGCPhys64(pSSM, &pVirtio->aGCPhys QueueAvail[i]);1987 pHlp->pfnSSMGetGCPhys64(pSSM, &pVirtio->aGCPhys QueueUsed[i]);1988 pHlp->pfnSSMGetU16(pSSM, &pVirtio->u QueueNotifyOff[i]);1989 pHlp->pfnSSMGetU16(pSSM, &pVirtio->u QueueMsixVector[i]);1990 pHlp->pfnSSMGetU16(pSSM, &pVirtio->u QueueEnable[i]);1991 pHlp->pfnSSMGetU16(pSSM, &pVirtio->u QueueSize[i]);1992 pHlp->pfnSSMGetU16(pSSM, &pVirtio-> virtqState[i].uAvailIdxShadow);1993 pHlp->pfnSSMGetU16(pSSM, &pVirtio-> virtqState[i].uUsedIdxShadow);1994 rc = pHlp->pfnSSMGetMem(pSSM, pVirtio-> virtqState[i].szVirtqName,1995 sizeof(pVirtio-> virtqState[i].szVirtqName));1983 pHlp->pfnSSMGetGCPhys64(pSSM, &pVirtio->aGCPhysVirtqDesc[i]); 1984 pHlp->pfnSSMGetGCPhys64(pSSM, &pVirtio->aGCPhysVirtqAvail[i]); 1985 pHlp->pfnSSMGetGCPhys64(pSSM, &pVirtio->aGCPhysVirtqUsed[i]); 1986 pHlp->pfnSSMGetU16(pSSM, &pVirtio->uVirtqNotifyOff[i]); 1987 pHlp->pfnSSMGetU16(pSSM, &pVirtio->uVirtqMsixVector[i]); 1988 pHlp->pfnSSMGetU16(pSSM, &pVirtio->uVirtqEnable[i]); 1989 pHlp->pfnSSMGetU16(pSSM, &pVirtio->uVirtqSize[i]); 1990 pHlp->pfnSSMGetU16(pSSM, &pVirtio->aVirtqState[i].uAvailIdxShadow); 1991 pHlp->pfnSSMGetU16(pSSM, &pVirtio->aVirtqState[i].uUsedIdxShadow); 1992 rc = pHlp->pfnSSMGetMem(pSSM, pVirtio->aVirtqState[i].szVirtqName, 1993 sizeof(pVirtio->aVirtqState[i].szVirtqName)); 1996 1994 AssertRCReturn(rc, rc); 1997 1995 } … … 2028 2026 break; 2029 2027 case kvirtIoVmStateChangedResume: 2030 virtioCoreNotifyGuestDriver(pVirtio->pDevInsR3, pVirtio, 0 /* idx Queue*/);2028 virtioCoreNotifyGuestDriver(pVirtio->pDevInsR3, pVirtio, 0 /* idxVirtq */); 2031 2029 break; 2032 2030 default: … … 2090 2088 */ 2091 2089 AssertReturn(pVirtioCC->pfnStatusChanged, VERR_INVALID_POINTER); 2092 AssertReturn(pVirtioCC->pfn QueueNotified, VERR_INVALID_POINTER);2090 AssertReturn(pVirtioCC->pfnVirtqNotified, VERR_INVALID_POINTER); 2093 2091 2094 2092 #if 0 /* Until pdmR3DvHlp_PCISetIrq() impl is fixed and Assert that limits vec to 0 is removed */ … … 2173 2171 /* 2174 2172 * Notify capability (VirtIO 1.0 spec, section 4.1.4.4). Note: uLength is based on the choice 2175 * of this implementation to make each queue's u QueueNotifyOff equal to (QueueSelect) ordinal2173 * of this implementation to make each queue's uVirtqNotifyOff equal to (VirtqSelect) ordinal 2176 2174 * value of the queue (different strategies are possible according to spec). 2177 2175 */ -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r84774 r84803 52 52 * TEMPORARY NOTE: Some of these values are experimental during development and will likely change. 53 53 */ 54 #define VIRTIO_MAX_ QUEUE_NAME_SIZE 32 /**< Maximum length of a queue name */54 #define VIRTIO_MAX_VIRTQ_NAME_SIZE 32 /**< Maximum length of a queue name */ 55 55 #define VIRTQ_MAX_ENTRIES 1024 /**< Max size (# desc elements) of a virtq */ 56 56 #define VIRTQ_MAX_CNT 24 /**< Max queues we allow guest to create */ … … 187 187 typedef struct VIRTQSTATE 188 188 { 189 uint16_t idx Queue; /**< Index of this queue */189 uint16_t idxVirtq; /**< Index of this queue */ 190 190 char szVirtqName[32]; /**< Dev-specific name of queue */ 191 191 uint16_t uAvailIdxShadow; /**< Consumer's position in avail ring */ … … 207 207 uint32_t uDriverFeatures; /**< RW (driver-accepted device features) */ 208 208 uint16_t uMsixConfig; /**< RW (driver sets MSI-X config vector) */ 209 uint16_t uNum Queues; /**< RO (device specifies max queues) */209 uint16_t uNumVirtqs; /**< RO (device specifies max queues) */ 210 210 uint8_t uDeviceStatus; /**< RW (driver writes device status, 0=reset) */ 211 211 uint8_t uConfigGeneration; /**< RO (device changes when changing configs) */ 212 212 213 /* Per virtqueue fields (as determined by u QueueSelect) */214 uint16_t u QueueSelect; /**< RW (selects queue focus for these fields) */215 uint16_t u QueueSize; /**< RW (queue size, 0 - 2^n) */216 uint16_t u QueueMsixVector; /**< RW (driver selects MSI-X queue vector) */217 uint16_t u QueueEnable; /**< RW (driver controls usability of queue) */218 uint16_t u QueueNotifyOff; /**< RO (offset uto virtqueue; see spec) */219 uint64_t aGCPhys QueueDesc; /**< RW (driver writes desc table phys addr) */220 uint64_t aGCPhys QueueAvail; /**< RW (driver writes avail ring phys addr) */221 uint64_t aGCPhys QueueUsed; /**< RW (driver writes used ring phys addr) */213 /* Per virtqueue fields (as determined by uVirtqSelect) */ 214 uint16_t uVirtqSelect; /**< RW (selects queue focus for these fields) */ 215 uint16_t uVirtqSize; /**< RW (queue size, 0 - 2^n) */ 216 uint16_t uVirtqMsixVector; /**< RW (driver selects MSI-X queue vector) */ 217 uint16_t uVirtqEnable; /**< RW (driver controls usability of queue) */ 218 uint16_t uVirtqNotifyOff; /**< RO (offset uto virtqueue; see spec) */ 219 uint64_t aGCPhysVirtqDesc; /**< RW (driver writes desc table phys addr) */ 220 uint64_t aGCPhysVirtqAvail; /**< RW (driver writes avail ring phys addr) */ 221 uint64_t aGCPhysVirtqUsed; /**< RW (driver writes used ring phys addr) */ 222 222 } VIRTIO_PCI_COMMON_CFG_T, *PVIRTIO_PCI_COMMON_CFG_T; 223 223 … … 253 253 PPDMDEVINS pDevInsR0; /**< Client device instance */ 254 254 PPDMDEVINS pDevInsR3; /**< Client device instance */ 255 RTGCPHYS aGCPhys QueueDesc[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q desc structs GUEST */256 RTGCPHYS aGCPhys QueueAvail[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q avail structs GUEST */257 RTGCPHYS aGCPhys QueueUsed[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q used structs GUEST */258 uint16_t u QueueNotifyOff[VIRTQ_MAX_CNT]; /**< (MMIO) per-Q notify offset HOST */259 uint16_t u QueueMsixVector[VIRTQ_MAX_CNT]; /**< (MMIO) Per-queue vector for MSI-X GUEST */260 uint16_t u QueueEnable[VIRTQ_MAX_CNT]; /**< (MMIO) Per-queue enable GUEST */261 uint16_t u QueueSize[VIRTQ_MAX_CNT]; /**< (MMIO) Per-queue size HOST/GUEST */262 uint16_t u QueueSelect; /**< (MMIO) queue selector GUEST */255 RTGCPHYS aGCPhysVirtqDesc[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q desc structs GUEST */ 256 RTGCPHYS aGCPhysVirtqAvail[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q avail structs GUEST */ 257 RTGCPHYS aGCPhysVirtqUsed[VIRTQ_MAX_CNT]; /**< (MMIO) PhysAdr per-Q used structs GUEST */ 258 uint16_t uVirtqNotifyOff[VIRTQ_MAX_CNT]; /**< (MMIO) per-Q notify offset HOST */ 259 uint16_t uVirtqMsixVector[VIRTQ_MAX_CNT]; /**< (MMIO) Per-queue vector for MSI-X GUEST */ 260 uint16_t uVirtqEnable[VIRTQ_MAX_CNT]; /**< (MMIO) Per-queue enable GUEST */ 261 uint16_t uVirtqSize[VIRTQ_MAX_CNT]; /**< (MMIO) Per-queue size HOST/GUEST */ 262 uint16_t uVirtqSelect; /**< (MMIO) queue selector GUEST */ 263 263 uint16_t padding; 264 264 uint64_t uDeviceFeatures; /**< (MMIO) Host features offered HOST */ … … 270 270 uint8_t uPrevDeviceStatus; /**< (MMIO) Prev Device Status GUEST */ 271 271 uint8_t uConfigGeneration; /**< (MMIO) Device config sequencer HOST */ 272 VIRTQSTATE virtqState[VIRTQ_MAX_CNT];/**< Local impl-specific queue context */272 VIRTQSTATE aVirtqState[VIRTQ_MAX_CNT]; /**< Local impl-specific queue context */ 273 273 274 274 /** @name The locations of the capability structures in PCI config space and the BAR. … … 348 348 * @param pVirtio Pointer to the shared virtio state. 349 349 * @param pVirtioCC Pointer to the ring-3 virtio state. 350 * @param idx QueueIndex of the notified queue350 * @param idxVirtq Index of the notified queue 351 351 */ 352 DECLCALLBACKMEMBER(void, pfn QueueNotified)(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue);352 DECLCALLBACKMEMBER(void, pfnVirtqNotified)(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq); 353 353 354 354 /** @} */ … … 381 381 * @param pVirtio Pointer to the shared virtio state. 382 382 * @param pVirtioCC Pointer to the ring-3 virtio state. 383 * @param idx QueueIndex of the notified queue383 * @param idxVirtq Index of the notified queue 384 384 */ 385 DECLCALLBACKMEMBER(void, pfn QueueNotified)(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue);385 DECLCALLBACKMEMBER(void, pfnVirtqNotified)(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq); 386 386 387 387 } VIRTIOCORER0; … … 405 405 * @{ */ 406 406 407 int virtioCore QueueSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue);408 uint16_t virtioCore QueueAvailCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue);409 void virtioCore QueueEnable(PVIRTIOCORE pVirtio, uint16_t idxQueue, bool fEnable);410 void virtioCore QueueNotifyEnable(PVIRTIOCORE pVirtio, uint16_t idxQueue, bool fEnable);407 int virtioCoreVirtqSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq); 408 uint16_t virtioCoreVirtqAvailCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq); 409 void virtioCoreVirtqEnable(PVIRTIOCORE pVirtio, uint16_t idxVirtq, bool fEnable); 410 void virtioCoreVirtqNotifyEnable(PVIRTIOCORE pVirtio, uint16_t idxVirtq, bool fEnable); 411 411 void virtioCoreNotifyConfigChanged(PVIRTIOCORE pVirtio); 412 412 void virtioCoreResetAll(PVIRTIOCORE pVirtio); … … 416 416 uint32_t virtioCoreR3DescChainRelease(PVIRTIOCORE pVirtio, PVIRTIO_DESC_CHAIN_T pDescChain); 417 417 void virtioCoreR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs); 418 void virtioCoreR3 QueueInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs, int idxQueue);419 int virtioCoreR3 QueueAttach(PVIRTIOCORE pVirtio, uint16_t idxQueue, const char *pcszName);420 421 int virtioCoreR3DescChainGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idx Queue,418 void virtioCoreR3VirtqInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs, int idxVirtq); 419 int virtioCoreR3VirtqAttach(PVIRTIOCORE pVirtio, uint16_t idxVirtq, const char *pcszName); 420 421 int virtioCoreR3DescChainGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 422 422 uint16_t uHeadIdx, PPVIRTIO_DESC_CHAIN_T ppDescChain); 423 423 424 int virtioCoreR3 QueuePeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue,424 int virtioCoreR3VirtqPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 425 425 PPVIRTIO_DESC_CHAIN_T ppDescChain); 426 426 427 int virtioCoreR3 QueueSkip(PVIRTIOCORE pVirtio, uint16_t idxQueue);428 429 int virtioCoreR3 QueueGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue,427 int virtioCoreR3VirtqSkip(PVIRTIOCORE pVirtio, uint16_t idxVirtq); 428 429 int virtioCoreR3VirtqGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, 430 430 PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove); 431 431 432 int virtioCoreR3 QueuePut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxQueue, PRTSGBUF pSgVirtReturn,432 int virtioCoreR3VirtqPut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t idxVirtq, PRTSGBUF pSgVirtReturn, 433 433 PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence); 434 434 … … 438 438 * 439 439 * @param pVirtio Pointer to the virtio state. 440 * @param idx Queue Queuenumber.440 * @param idxVirtq Virtq number. 441 441 * @returns true or false indicating whether to enable queue or not 442 442 */ 443 DECLINLINE(bool) virtioCoreIs QueueEnabled(PVIRTIOCORE pVirtio, uint16_t idxQueue)444 { 445 Assert(idx Queue < RT_ELEMENTS(pVirtio->virtqState));446 return pVirtio->u QueueEnable[idxQueue] != 0;443 DECLINLINE(bool) virtioCoreIsVirtqEnabled(PVIRTIOCORE pVirtio, uint16_t idxVirtq) 444 { 445 Assert(idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 446 return pVirtio->uVirtqEnable[idxVirtq] != 0; 447 447 } 448 448 449 449 /** 450 * Get name of queue, by idx Queue, assigned at virtioCoreR3QueueAttach()450 * Get name of queue, by idxVirtq, assigned at virtioCoreR3VirtqAttach() 451 451 * 452 452 * @param pVirtio Pointer to the virtio state. 453 * @param idx Queue Queuenumber.453 * @param idxVirtq Virtq number. 454 454 * 455 455 * @returns Pointer to read-only queue name. 456 456 */ 457 DECLINLINE(const char *) virtioCore QueueGetName(PVIRTIOCORE pVirtio, uint16_t idxQueue)458 { 459 Assert((size_t)idx Queue < RT_ELEMENTS(pVirtio->virtqState));460 return pVirtio-> virtqState[idxQueue].szVirtqName;457 DECLINLINE(const char *) virtioCoreVirtqGetName(PVIRTIOCORE pVirtio, uint16_t idxVirtq) 458 { 459 Assert((size_t)idxVirtq < RT_ELEMENTS(pVirtio->aVirtqState)); 460 return pVirtio->aVirtqState[idxVirtq].szVirtqName; 461 461 } 462 462 … … 467 467 */ 468 468 DECLINLINE(uint64_t) virtioCoreGetNegotiatedFeatures(PVIRTIOCORE pVirtio) 469 {470 return pVirtio->uDriverFeatures;471 }472 473 /**474 * Get VirtIO accepted host-side features475 *476 * @returns feature bits selected or 0 if selector out of range.477 *478 * @param pState Virtio state479 */480 DECLINLINE(uint64_t) virtioCoreGetAcceptedFeatures(PVIRTIOCORE pVirtio)481 469 { 482 470 return pVirtio->uDriverFeatures;
Note:
See TracChangeset
for help on using the changeset viewer.