Changeset 94969 in vbox for trunk/src/VBox/Devices/VirtIO
- Timestamp:
- May 9, 2022 5:06:17 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 151379
- Location:
- trunk/src/VBox/Devices/VirtIO
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VirtIO/VirtioCore.cpp
r94287 r94969 620 620 uint16_t uUsedIdxShadow = pVirtq->uUsedIdxShadow; 621 621 622 #ifdef VIRTIO_VBUF_ON_STACK 623 VIRTQBUF_T VirtqBuf; 624 PVIRTQBUF pVirtqBuf = &VirtqBuf; 625 #else /* !VIRTIO_VBUF_ON_STACK */ 622 626 PVIRTQBUF pVirtqBuf = NULL; 627 #endif /* !VIRTIO_VBUF_ON_STACK */ 623 628 624 629 bool fEmpty = IS_VIRTQ_EMPTY(pDevIns, pVirtio, pVirtq); … … 629 634 if (!fEmpty) 630 635 { 636 #ifdef VIRTIO_VBUF_ON_STACK 637 virtioCoreR3VirtqAvailBufPeek(pDevIns, pVirtio, uVirtq, pVirtqBuf); 638 #else /* !VIRTIO_VBUF_ON_STACK */ 631 639 virtioCoreR3VirtqAvailBufPeek(pDevIns, pVirtio, uVirtq, &pVirtqBuf); 640 #endif /* !VIRTIO_VBUF_ON_STACK */ 632 641 cSendSegs = pVirtqBuf->pSgPhysSend ? pVirtqBuf->pSgPhysSend->cSegs : 0; 633 642 cReturnSegs = pVirtqBuf->pSgPhysReturn ? pVirtqBuf->pSgPhysReturn->cSegs : 0; … … 680 689 } 681 690 691 #ifdef VIRTIO_VBUF_ON_STACK 692 /** API Function: See header file */ 693 PVIRTQBUF virtioCoreR3VirtqBufAlloc(void) 694 { 695 PVIRTQBUF pVirtqBuf = (PVIRTQBUF)RTMemAllocZ(sizeof(VIRTQBUF_T)); 696 AssertReturn(pVirtqBuf, NULL); 697 pVirtqBuf->u32Magic = VIRTQBUF_MAGIC; 698 pVirtqBuf->cRefs = 1; 699 return pVirtqBuf; 700 } 701 #endif /* VIRTIO_VBUF_ON_STACK */ 702 682 703 /** API Function: See header file */ 683 704 uint32_t virtioCoreR3VirtqBufRetain(PVIRTQBUF pVirtqBuf) … … 752 773 753 774 /** API function: See Header file */ 775 #ifdef VIRTIO_VBUF_ON_STACK 776 int virtioCoreR3VirtqAvailBufPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, PVIRTQBUF pVirtqBuf) 777 { 778 return virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, pVirtqBuf, false); 779 } 780 #else /* !VIRTIO_VBUF_ON_STACK */ 754 781 int virtioCoreR3VirtqAvailBufPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, 755 782 PPVIRTQBUF ppVirtqBuf) … … 757 784 return virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, ppVirtqBuf, false); 758 785 } 786 #endif /* !VIRTIO_VBUF_ON_STACK */ 759 787 760 788 /** API function: See Header file */ … … 778 806 779 807 /** API Function: See header file */ 808 #ifdef VIRTIO_VBUF_ON_STACK 809 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, 810 uint16_t uHeadIdx, PVIRTQBUF pVirtqBuf) 811 #else /* !VIRTIO_VBUF_ON_STACK */ 780 812 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, 781 813 uint16_t uHeadIdx, PPVIRTQBUF ppVirtqBuf) 782 { 814 #endif /* !VIRTIO_VBUF_ON_STACK */ 815 { 816 #ifndef VIRTIO_VBUF_ON_STACK 783 817 AssertReturn(ppVirtqBuf, VERR_INVALID_POINTER); 784 818 *ppVirtqBuf = NULL; 819 #endif /* !VIRTIO_VBUF_ON_STACK */ 785 820 786 821 AssertMsgReturn(uVirtq < RT_ELEMENTS(pVirtio->aVirtqueues), … … 800 835 * Allocate and initialize the descriptor chain structure. 801 836 */ 837 #ifndef VIRTIO_VBUF_ON_STACK 802 838 PVIRTQBUF pVirtqBuf = (PVIRTQBUF)RTMemAllocZ(sizeof(VIRTQBUF_T)); 803 839 AssertReturn(pVirtqBuf, VERR_NO_MEMORY); 804 840 pVirtqBuf->u32Magic = VIRTQBUF_MAGIC; 805 841 pVirtqBuf->cRefs = 1; 842 #endif /* !VIRTIO_VBUF_ON_STACK */ 806 843 pVirtqBuf->uHeadIdx = uHeadIdx; 807 844 pVirtqBuf->uVirtq = uVirtq; 845 #ifndef VIRTIO_VBUF_ON_STACK 808 846 *ppVirtqBuf = pVirtqBuf; 847 #endif /* !VIRTIO_VBUF_ON_STACK */ 809 848 810 849 /* … … 904 943 905 944 /** API function: See Header file */ 945 #ifdef VIRTIO_VBUF_ON_STACK 946 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, 947 PVIRTQBUF pVirtqBuf, bool fRemove) 948 #else /* !VIRTIO_VBUF_ON_STACK */ 906 949 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtq, 907 950 PPVIRTQBUF ppVirtqBuf, bool fRemove) 951 #endif /* !VIRTIO_VBUF_ON_STACK */ 908 952 { 909 953 Assert(uVirtq < RT_ELEMENTS(pVirtio->aVirtqueues)); … … 921 965 pVirtq->uAvailIdxShadow++; 922 966 967 #ifdef VIRTIO_VBUF_ON_STACK 968 int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, uHeadIdx, pVirtqBuf); 969 #else /* !VIRTIO_VBUF_ON_STACK */ 923 970 int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, pVirtio, uVirtq, uHeadIdx, ppVirtqBuf); 971 #endif /* !VIRTIO_VBUF_ON_STACK */ 924 972 return rc; 925 973 } -
trunk/src/VBox/Devices/VirtIO/VirtioCore.h
r94275 r94969 22 22 # pragma once 23 23 #endif 24 25 /* Do not allocate VIRTQBUF from the heap when possible */ 26 #define VIRTIO_VBUF_ON_STACK 1 24 27 25 28 #include <iprt/ctype.h> … … 676 679 uint16_t virtioCoreVirtqAvailBufCount(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr); 677 680 681 #ifdef VIRTIO_VBUF_ON_STACK 682 /** 683 * This function is identical to virtioCoreR3VirtqAvailBufGet(), *except* it doesn't consume 684 * peeked buffer from avail ring of the virtq. The function *becomes* identical to the 685 * virtioCoreR3VirtqAvailBufGet() only if virtioCoreR3VirtqAvailRingNext() is invoked to 686 * consume buf from the queue's avail ring, followed by invocation of virtioCoreR3VirtqUsedBufPut(), 687 * to hand host-processed buffer back to guest, which completes guest-initiated virtq buffer circuit. 688 * 689 * @param pDevIns The device instance. 690 * @param pVirtio Pointer to the shared virtio state. 691 * @param uVirtqNbr Virtq number 692 * @param pVirtqBuf Pointer to descriptor chain that contains the 693 * pre-processed transaction information pulled from the virtq. 694 * 695 * @returns VBox status code: 696 * @retval VINF_SUCCESS Success 697 * @retval VERR_INVALID_STATE VirtIO not in ready state (asserted). 698 * @retval VERR_NOT_AVAILABLE If the queue is empty. 699 */ 700 int virtioCoreR3VirtqAvailBufPeek(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr, 701 PVIRTQBUF pVirtqBuf); 702 703 /** 704 * This function fetches the next buffer (descriptor chain) from the VirtIO "avail" ring of 705 * indicated queue, separating the buf's s/g vectors into OUT (e.g. guest-to-host) 706 * components and and IN (host-to-guest) components. 707 * 708 * Caller is responsible for GCPhys to host virtual memory conversions. If the 709 * virtq buffer being peeked at is "consumed", virtioCoreR3VirtqAvailRingNext() must 710 * be called, and after that virtioCoreR3VirtqUsedBufPut() must be called to 711 * complete the buffer transfer cycle with the guest. 712 * 713 * @param pDevIns The device instance. 714 * @param pVirtio Pointer to the shared virtio state. 715 * @param uVirtqNbr Virtq number 716 * @param pVirtqBuf Pointer to descriptor chain that contains the 717 * pre-processed transaction information pulled from the virtq. 718 * @param fRemove flags whether to remove desc chain from queue (false = peek) 719 * 720 * @returns VBox status code: 721 * @retval VINF_SUCCESS Success 722 * @retval VERR_INVALID_STATE VirtIO not in ready state (asserted). 723 * @retval VERR_NOT_AVAILABLE If the queue is empty. 724 */ 725 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr, 726 PVIRTQBUF pVirtqBuf, bool fRemove); 727 728 /** 729 * Fetches a specific descriptor chain using avail ring of indicated queue and converts the 730 * descriptor chain into its OUT (to device) and IN (to guest) components. 731 * 732 * The caller is responsible for GCPhys to host virtual memory conversions and *must* 733 * return the virtq buffer using virtioCoreR3VirtqUsedBufPut() to complete the roundtrip 734 * virtq transaction. 735 * * 736 * @param pDevIns The device instance. 737 * @param pVirtio Pointer to the shared virtio state. 738 * @param uVirtqNbr Virtq number 739 * @param pVirtqBuf Pointer to descriptor chain that contains the 740 * pre-processed transaction information pulled from the virtq. 741 * @param fRemove flags whether to remove desc chain from queue (false = peek) 742 * 743 * @returns VBox status code: 744 * @retval VINF_SUCCESS Success 745 * @retval VERR_INVALID_STATE VirtIO not in ready state (asserted). 746 * @retval VERR_NOT_AVAILABLE If the queue is empty. 747 */ 748 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr, 749 uint16_t uHeadIdx, PVIRTQBUF pVirtqBuf); 750 #else /* !VIRTIO_VBUF_ON_STACK */ 678 751 /** 679 752 * This function is identical to virtioCoreR3VirtqAvailBufGet(), *except* it doesn't consume … … 748 821 int virtioCoreR3VirtqAvailBufGet(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr, 749 822 uint16_t uHeadIdx, PPVIRTQBUF ppVirtqBuf); 823 #endif /* !VIRTIO_VBUF_ON_STACK */ 750 824 751 825 /** … … 1092 1166 int virtioCoreVirtqUsedRingSync(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_t uVirtqNbr); 1093 1167 1168 #ifdef VIRTIO_VBUF_ON_STACK 1169 /** 1170 * Allocates a descriptor chain object with the reference count of one. Copying the reference 1171 * to this object requires a call to virtioCoreR3VirtqBufRetain. All references must be later 1172 * released with virtioCoreR3VirtqBufRelease. Just to be clear, one alloc plus one retain will 1173 * require two releases. 1174 * 1175 * @returns A descriptor chain object. 1176 * 1177 * @retval NULL if out of memory. 1178 * 1179 * NOTE: VIRTQBUF_T objects allocated on the stack will have garbage in the u32Magic field, 1180 * triggering an assertion if virtioCoreR3VirtqBufRelease is called on them. 1181 */ 1182 PVIRTQBUF virtioCoreR3VirtqBufAlloc(void); 1183 #endif /* VIRTIO_VBUF_ON_STACK */ 1184 1094 1185 /** 1095 1186 * Retains a reference to the given descriptor chain.
Note:
See TracChangeset
for help on using the changeset viewer.