Changeset 85016 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Jul 1, 2020 5:28:16 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r84882 r85016 59 59 #include "VBoxDD.h" 60 60 61 #define VIRTIONET_SAVED_STATE_VERSION UINT32_C(1) 62 #define VIRTIONET_MAX_QPAIRS 1 63 #define VIRTIONET_MAX_VIRTQS (VIRTIONET_MAX_QPAIRS * 2 + 1) 64 #define VIRTIONET_MAX_FRAME_SIZE 65535 + 18 /**< Max IP pkt size + Ethernet header with VLAN tag */ 65 #define VIRTIONET_MAC_FILTER_LEN 32 66 #define VIRTIONET_MAX_VLAN_ID (1 << 12) 67 #define VIRTIONET_PREALLOCATE_RX_SEG_COUNT 32 68 69 #define VIRTQNAME(uVirtqNbr) (pThis->aVirtqs[uVirtqNbr]->szName) 70 #define CBVIRTQNAME(uVirtqNbr) RTStrNLen(VIRTQNAME(uVirtqNbr), sizeof(VIRTQNAME(uVirtqNbr))) 71 #define FEATURE_ENABLED(feature) RT_BOOL(pThis->fNegotiatedFeatures & VIRTIONET_F_##feature) 72 #define FEATURE_DISABLED(feature) (!FEATURE_ENABLED(feature)) 73 #define FEATURE_OFFERED(feature) VIRTIONET_HOST_FEATURES_OFFERED & VIRTIONET_F_##feature 74 75 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, uVirtqNbr) \ 76 (virtioCoreVirtqAvailBufCount(pDevIns, pVirtio, uVirtqNbr) == 0) 77 61 #define LUN0 0 62 63 #define VIRTIONET_SAVED_STATE_VERSION UINT32_C(1) 64 #define VIRTIONET_MAX_QPAIRS 1 65 #define VIRTIONET_MAX_VIRTQS (VIRTIONET_MAX_QPAIRS * 2 + 1) 66 #define VIRTIONET_MAX_FRAME_SIZE 65535 + 18 /**< Max IP pkt size + Eth. header w/VLAN tag */ 67 #define VIRTIONET_MAC_FILTER_LEN 32 68 #define VIRTIONET_MAX_VLAN_ID (1 << 12) 69 #define VIRTIONET_RX_SEG_COUNT 32 70 71 #define VIRTQNAME(uVirtqNbr) (pThis->aVirtqs[uVirtqNbr]->szName) 72 #define CBVIRTQNAME(uVirtqNbr) RTStrNLen(VIRTQNAME(uVirtqNbr), sizeof(VIRTQNAME(uVirtqNbr))) 73 #define FEATURE_ENABLED(feature) RT_BOOL(pThis->fNegotiatedFeatures & VIRTIONET_F_##feature) 74 #define FEATURE_DISABLED(feature) (!FEATURE_ENABLED(feature)) 75 #define FEATURE_OFFERED(feature) VIRTIONET_HOST_FEATURES_OFFERED & VIRTIONET_F_##feature 76 77 /* Macros to calculate queue specific index number VirtIO 1.0, 5.1.2 */ 78 #define IS_TX_VIRTQ(n) ((n) != CTRLQIDX && ((n) & 1)) 79 #define IS_RX_VIRTQ(n) ((n) != CTRLQIDX && !IS_TX_VIRTQ(n)) 80 #define IS_CTRL_VIRTQ(n) ((n) == CTRLQIDX) 81 #define RXQIDX(qPairIdx) (qPairIdx * 2) 82 #define TXQIDX(qPairIdx) (qPairIdx * 2 + 1) 83 #define CTRLQIDX (FEATURE_ENABLED(MQ) ? ((VIRTIONET_MAX_QPAIRS - 1) * 2 + 2) : 2) 84 85 #define IS_LINK_UP(pState) (pState->virtioNetConfig.uStatus & VIRTIONET_F_LINK_UP) 86 #define IS_LINK_DOWN(pState) !IS_LINK_UP(pState) 87 88 \ 78 89 #define SET_LINK_UP(pState) \ 79 90 LogFunc(("SET_LINK_UP\n")); \ … … 86 97 virtioCoreNotifyConfigChanged(&pThis->Virtio) 87 98 88 #define IS_LINK_UP(pState) (pState->virtioNetConfig.uStatus & VIRTIONET_F_LINK_UP) 89 #define IS_LINK_DOWN(pState) !IS_LINK_UP(pState) 90 91 /* Macros to calculate queue specific index number VirtIO 1.0, 5.1.2 */ 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 #define RXQIDX(qPairIdx) (qPairIdx * 2) 96 #define TXQIDX(qPairIdx) (qPairIdx * 2 + 1) 97 #define CTRLQIDX (FEATURE_ENABLED(MQ) ? ((VIRTIONET_MAX_QPAIRS - 1) * 2 + 2) : 2) 98 99 #define LUN0 0 99 #define IS_VIRTQ_EMPTY(pDevIns, pVirtio, uVirtqNbr) \ 100 (virtioCoreVirtqAvailBufCount(pDevIns, pVirtio, uVirtqNbr) == 0) 101 100 102 101 103 #ifdef USING_CRITICAL_SECTION … … 183 185 * Structures and Typedefs * 184 186 *********************************************************************************************************************************/ 187 185 188 /** 186 189 * Virtio Net Host Device device-specific configuration (VirtIO 1.0, 5.1.4) … … 188 191 * MMIO accesses to device-specific configuration parameters. 189 192 */ 190 191 193 #pragma pack(1) 192 typedef struct virtio_net_config 193 { 194 RTMAC uMacAddress; /**< mac */ 195 #if FEATURE_OFFERED(STATUS) 196 uint16_t uStatus; /**< status */ 194 195 typedef struct virtio_net_config 196 { 197 RTMAC uMacAddress; /**< mac */ 198 199 #if FEATURE_OFFERED(STATUS) 200 uint16_t uStatus; /**< status */ 197 201 #endif 198 #if FEATURE_OFFERED(MQ) 199 uint16_t uMaxVirtqPairs; /**< max_virtq_pairs */ 202 203 #if FEATURE_OFFERED(MQ) 204 uint16_t uMaxVirtqPairs; /**< max_virtq_pairs */ 200 205 #endif 201 } VIRTIONET_CONFIG_T, PVIRTIONET_CONFIG_T; 206 207 } VIRTIONET_CONFIG_T, PVIRTIONET_CONFIG_T; 208 202 209 #pragma pack() 203 210 … … 770 777 #ifdef LOG_ENABLED 771 778 void virtioNetDumpGcPhysRxBuf(PPDMDEVINS pDevIns, PVIRTIONETPKTHDR pRxPktHdr, 772 uint16_t c Descs, uint8_t *pvBuf, uint16_t cb, RTGCPHYS GCPhysRxBuf, uint8_t cbRxBuf)779 uint16_t cVirtqBufs, uint8_t *pvBuf, uint16_t cb, RTGCPHYS GCPhysRxBuf, uint8_t cbRxBuf) 773 780 { 774 781 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 775 pRxPktHdr->uNumBuffers = c Descs;782 pRxPktHdr->uNumBuffers = cVirtqBufs; 776 783 if (pRxPktHdr) 777 784 { … … 916 923 pHlp->pfnPrintf(pHlp, " fMsiSupport ............... %d\n", pThis->Virtio.fMsiSupport); 917 924 pHlp->pfnPrintf(pHlp, " uConfigGeneration ......... %d\n", pThis->Virtio.uConfigGeneration); 918 pHlp->pfnPrintf(pHlp, " uDeviceStatus ............. 0x%x\n", pThis->Virtio. uDeviceStatus);925 pHlp->pfnPrintf(pHlp, " uDeviceStatus ............. 0x%x\n", pThis->Virtio.fDeviceStatus); 919 926 pHlp->pfnPrintf(pHlp, " cVirtqPairs .,............. %d\n", pThis->cVirtqPairs); 920 927 pHlp->pfnPrintf(pHlp, " cVirtVirtqs .,............. %d\n", pThis->cVirtVirtqs); … … 1011 1018 } 1012 1019 1013 /** 1014 * Resolves to boolean true if uOffset matches a field offset and size exactly, 1015 * (or if 64-bit field, if it accesses either 32-bit part as a 32-bit access) 1016 * Assumption is this critereon is mandated by VirtIO 1.0, Section 4.1.3.1) 1017 * (Easily re-written to allow unaligned bounded access to a field). 1018 * 1019 * @param member - Member of VIRTIO_PCI_COMMON_CFG_T 1020 * @result - true or false 1021 */ 1022 #define MATCH_NET_CONFIG(member) \ 1023 ( ( RT_SIZEOFMEMB(VIRTIONET_CONFIG_T, member) == 8 \ 1024 && ( offConfig == RT_UOFFSETOF(VIRTIONET_CONFIG_T, member) \ 1025 || offConfig == RT_UOFFSETOF(VIRTIONET_CONFIG_T, member) + sizeof(uint32_t)) \ 1026 && cb == sizeof(uint32_t)) \ 1027 || (offConfig + cb <= RT_UOFFSETOF(VIRTIONET_CONFIG_T, member) \ 1028 + RT_SIZEOFMEMB(VIRTIONET_CONFIG_T, member)) ) 1029 1030 #ifdef LOG_ENABLED 1031 # define LOG_NET_CONFIG_ACCESSOR(member) \ 1032 virtioCoreLogMappedIoValue(__FUNCTION__, #member, RT_SIZEOFMEMB(VIRTIONET_CONFIG_T, member), \ 1033 pv, cb, offIntra, fWrite, false, 0); 1034 #else 1035 # define LOG_NET_CONFIG_ACCESSOR(member) do { } while (0) 1036 #endif 1037 1038 #define NET_CONFIG_ACCESSOR(member) \ 1039 do \ 1040 { \ 1041 uint32_t offIntra = offConfig - RT_UOFFSETOF(VIRTIONET_CONFIG_T, member); \ 1042 if (fWrite) \ 1043 memcpy((char *)&pThis->virtioNetConfig.member + offIntra, pv, cb); \ 1044 else \ 1045 memcpy(pv, (const char *)&pThis->virtioNetConfig.member + offIntra, cb); \ 1046 LOG_NET_CONFIG_ACCESSOR(member); \ 1047 } while(0) 1048 1049 #define NET_CONFIG_ACCESSOR_READONLY(member) \ 1050 do \ 1051 { \ 1052 uint32_t offIntra = offConfig - RT_UOFFSETOF(VIRTIONET_CONFIG_T, member); \ 1053 if (fWrite) \ 1054 LogFunc(("%s Guest attempted to write readonly virtio_pci_common_cfg.%s\n", pThis->szInst, #member)); \ 1055 else \ 1056 { \ 1057 memcpy(pv, (const char *)&pThis->virtioNetConfig.member + offIntra, cb); \ 1058 LOG_NET_CONFIG_ACCESSOR(member); \ 1059 } \ 1060 } while(0) 1061 1062 1063 static int virtioNetR3CfgAccessed(PVIRTIONET pThis, uint32_t offConfig, void *pv, uint32_t cb, bool fWrite) 1020 static int virtioNetR3CfgAccessed(PVIRTIONET pThis, uint32_t uOffsetOfAccess, void *pv, uint32_t cb, bool fWrite) 1064 1021 { 1065 1022 AssertReturn(pv && cb <= sizeof(uint32_t), fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00); 1066 1023 1067 if ( MATCH_NET_CONFIG(uMacAddress))1068 NET_CONFIG_ACCESSOR_READONLY(uMacAddress);1024 if (VIRTIO_DEV_CONFIG_SUBMATCH_MEMBER( uMacAddress, VIRTIONET_CONFIG_T, uOffsetOfAccess)) 1025 VIRTIO_DEV_CONFIG_ACCESS_READONLY( uMacAddress, VIRTIONET_CONFIG_T, uOffsetOfAccess, &pThis->virtioNetConfig); 1069 1026 #if FEATURE_OFFERED(STATUS) 1070 1027 else 1071 if ( MATCH_NET_CONFIG(uStatus))1072 NET_CONFIG_ACCESSOR_READONLY(uStatus);1028 if (VIRTIO_DEV_CONFIG_MATCH_MEMBER( uStatus, VIRTIONET_CONFIG_T, uOffsetOfAccess)) 1029 VIRTIO_DEV_CONFIG_ACCESS_READONLY( uStatus, VIRTIONET_CONFIG_T, uOffsetOfAccess, &pThis->virtioNetConfig); 1073 1030 #endif 1074 1031 #if FEATURE_OFFERED(MQ) 1075 1032 else 1076 if ( MATCH_NET_CONFIG(uMaxVirtqPairs))1077 NET_CONFIG_ACCESSOR_READONLY(uMaxVirtqPairs);1033 if (VIRTIO_DEV_CONFIG_MATCH_MEMBER( uMaxVirtqPairs, VIRTIONET_CONFIG_T, uOffsetOfAccess)) 1034 VIRTIO_DEV_CONFIG_ACCESS_READONLY( uMaxVirtqPairs, VIRTIONET_CONFIG_T, uOffsetOfAccess, &pThis->virtioNetConfig); 1078 1035 #endif 1079 1036 else 1080 1037 { 1081 LogFunc(("%s Bad access by guest to virtio_net_config: off=%u (%#x), cb=%u\n", pThis->szInst, offConfig, offConfig, cb)); 1038 LogFunc(("%s Bad access by guest to virtio_net_config: off=%u (%#x), cb=%u\n", 1039 pThis->szInst, uOffsetOfAccess, uOffsetOfAccess, cb)); 1082 1040 return fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00; 1083 1041 } … … 1085 1043 } 1086 1044 1087 #undef NET_CONFIG_ACCESSOR_READONLY1088 #undef NET_CONFIG_ACCESSOR1089 #undef LOG_ACCESSOR1090 #undef MATCH_NET_CONFIG1091 1092 1045 /** 1093 1046 * @callback_method_impl{VIRTIOCORER3,pfnDevCapRead} … … 1097 1050 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 1098 1051 1099 LogFunc((" %s uOffset: %d, cb: %d\n", pThis->szInst, uOffset, cb));1052 LogFunc((" %s uOffset: %d, cb: %d\n", pThis->szInst, uOffset, cb)); 1100 1053 RT_NOREF(pThis); 1101 1054 return virtioNetR3CfgAccessed(PDMDEVINS_2_DATA(pDevIns, PVIRTIONET), uOffset, pv, cb, false /*fRead*/); … … 1545 1498 if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED) 1546 1499 { 1547 LogFunc(("Waken due to %s\n", rc == VERR_TIMEOUT ? "timeout" : " interrupted"));1500 LogFunc(("Waken due to %s\n", rc == VERR_TIMEOUT ? "timeout" : "getting interrupted")); 1548 1501 continue; 1549 1502 } … … 1662 1615 pszType = (char *)"Unicast"; 1663 1616 1664 LogFunc(("%s node(%RTmac %s%s), pkt(%RTmac %s) ",1617 LogFunc(("%s node(%RTmac %s%s), pkt(%RTmac %s)\n", 1665 1618 pThis->szInst, pThis->virtioNetConfig.uMacAddress.au8, 1666 1619 pThis->fPromiscuous ? "promiscuous" : "", … … 1735 1688 PVIRTIONETVIRTQ pRxVirtq) 1736 1689 { 1737 uint8_t fAddPktHdr = true;1738 1690 RTGCPHYS GCPhysPktHdrNumBuffers = 0; 1739 uint16_t cDescs; 1740 uint64_t uOffset; 1741 for (cDescs = uOffset = 0; uOffset < cb; ) 1691 uint8_t fAddPktHdr = true; 1692 uint16_t cVirtqBufs = 0; 1693 uint64_t uOffset = 0; 1694 1695 while (uOffset < cb) 1742 1696 { 1743 1697 PVIRTQBUF pVirtqBuf = NULL; … … 1761 1715 VERR_INTERNAL_ERROR); 1762 1716 1763 size_t cb DescChainLeft= pVirtqBuf->cbPhysReturn;1717 size_t cbBufRemaining = pVirtqBuf->cbPhysReturn; 1764 1718 uint8_t cbHdr = sizeof(VIRTIONETPKTHDR); 1765 1719 1766 1720 /* Fill the Guest Rx buffer with data received from the interface */ 1767 for (uint16_t cSegs = 0; uOffset < cb && cb DescChainLeft; )1721 for (uint16_t cSegs = 0; uOffset < cb && cbBufRemaining; ) 1768 1722 { 1769 1723 if (fAddPktHdr) … … 1773 1727 paVirtSegsToGuest[0].pvSeg = RTMemAlloc(cbHdr); 1774 1728 AssertReturn(paVirtSegsToGuest[0].pvSeg, VERR_NO_MEMORY); 1775 cb DescChainLeft-= cbHdr;1729 cbBufRemaining -= cbHdr; 1776 1730 1777 1731 memcpy(paVirtSegsToGuest[0].pvSeg, rxPktHdr, cbHdr); … … 1794 1748 1795 1749 /* Append remaining Rx pkt or as much current desc chain has room for */ 1796 size_t cb Cropped = RT_MIN(cb, cbDescChainLeft);1797 paVirtSegsToGuest[cSegs].cbSeg = cb Cropped;1750 size_t cbLimited = RT_MIN(cb, cbBufRemaining); 1751 paVirtSegsToGuest[cSegs].cbSeg = cbLimited; 1798 1752 paVirtSegsToGuest[cSegs].pvSeg = ((uint8_t *)pvBuf) + uOffset; 1799 cb DescChainLeft -= cbCropped;1800 uOffset += cbCropped;1801 c Descs++;1753 cbBufRemaining -= cbLimited; 1754 uOffset += cbLimited; 1755 cVirtqBufs++; 1802 1756 cSegs++; 1803 1757 RTSgBufInit(pVirtSegBufToGuest, paVirtSegsToGuest, cSegs); … … 1805 1759 STAM_PROFILE_START(&pThis->StatReceiveStore, a); 1806 1760 virtioCoreR3VirtqUsedBufPut(pDevIns, &pThis->Virtio, pRxVirtq->idx, 1807 pVirtSegBufToGuest, pVirtqBuf, true /* fFence */);1761 pVirtSegBufToGuest, pVirtqBuf, true /* fFence */); 1808 1762 STAM_PROFILE_STOP(&pThis->StatReceiveStore, a); 1809 1763 … … 1811 1765 break; 1812 1766 } 1813 1814 1767 virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf); 1815 1768 } … … 1823 1776 /* Fix-up pkthdr (in guest phys. memory) with number buffers (descriptors) processed */ 1824 1777 1825 int rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhysPktHdrNumBuffers, &cDescs, sizeof(cDescs)); 1826 AssertMsgRCReturn(rc, 1827 ("Failure updating descriptor count in pkt hdr in guest physical memory\n"), 1828 rc); 1778 int rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhysPktHdrNumBuffers, &cVirtqBufs, sizeof(cVirtqBufs)); 1779 AssertMsgRCReturn(rc, ("Failure updating descriptor count in pkt hdr in guest physical memory\n"), rc); 1829 1780 1830 1781 virtioCoreVirtqSyncUsedRing(pDevIns, &pThis->Virtio, pRxVirtq->idx); … … 1892 1843 } 1893 1844 1894 uint16_t cSegsAllocated = VIRTIONET_ PREALLOCATE_RX_SEG_COUNT;1845 uint16_t cSegsAllocated = VIRTIONET_RX_SEG_COUNT; 1895 1846 1896 1847 PRTSGBUF pVirtSegBufToGuest = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF)); … … 1998 1949 } 1999 1950 2000 /* Read physical bytes from the out segment(s) of descriptor chain */ 2001 static void virtqNetR3PullBytesFromVirtqBuf(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTQBUF pVirtqBuf, 2002 void *pv, size_t cb) 2003 { 2004 uint8_t *pb = (uint8_t *)pv; 2005 size_t cbLim = RT_MIN(pVirtqBuf->cbPhysSend, cb); 2006 while (cbLim) 2007 { 2008 size_t cbSeg = cbLim; 2009 RTGCPHYS GCPhys = virtioCoreGCPhysChainGetNextSegment(pVirtqBuf->pSgPhysSend, &cbSeg); 2010 PDMDevHlpPCIPhysRead(pDevIns, GCPhys, pb, cbSeg); 2011 pb += cbSeg; 2012 cbLim -= cbSeg; 2013 pVirtqBuf->cbPhysSend -= cbSeg; 2014 } 2015 LogFunc(("%s Pulled %d/%d bytes from desc chain (%d bytes left)\n", 2016 pThis->szInst, cb - cbLim, cb, pVirtqBuf->cbPhysSend)); 2017 RT_NOREF(pThis); 2018 } 2019 2020 static uint8_t virtioNetR3CtrlRx(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC, 1951 1952 static uint8_t virtioNetR3CtrlRx(PVIRTIONET pThis, PVIRTIONETCC pThisCC, 2021 1953 PVIRTIONET_CTRL_HDR_T pCtrlPktHdr, PVIRTQBUF pVirtqBuf) 2022 1954 { … … 2025 1957 2026 1958 LogFunc(("%s Processing CTRL Rx command\n", pThis->szInst)); 2027 RT_NOREF(pThis);2028 1959 switch(pCtrlPktHdr->uCmd) 2029 1960 { … … 2046 1977 2047 1978 uint8_t fOn, fPromiscChanged = false; 2048 virt qNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &fOn, (size_t)RT_MIN(pVirtqBuf->cbPhysSend, sizeof(fOn)));1979 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &fOn, (size_t)RT_MIN(pVirtqBuf->cbPhysSend, sizeof(fOn))); 2049 1980 2050 1981 switch(pCtrlPktHdr->uCmd) … … 2079 2010 2080 2011 if (pThisCC->pDrv && fPromiscChanged) 2081 { 2082 if (pThis->fPromiscuous | pThis->fAllMulticast) 2083 { 2084 pThisCC->pDrv->pfnSetPromiscuousMode(pThisCC->pDrv, true); 2085 } 2086 else 2087 { 2088 pThisCC->pDrv->pfnSetPromiscuousMode(pThisCC->pDrv, false); 2089 } 2090 } 2012 pThisCC->pDrv->pfnSetPromiscuousMode(pThisCC->pDrv, (pThis->fPromiscuous || pThis->fAllMulticast)); 2091 2013 2092 2014 return VIRTIONET_OK; 2093 2015 } 2094 2016 2095 static uint8_t virtioNetR3CtrlMac(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC, 2096 PVIRTIONET_CTRL_HDR_T pCtrlPktHdr, PVIRTQBUF pVirtqBuf) 2017 static uint8_t virtioNetR3CtrlMac(PVIRTIONET pThis, PVIRTIONET_CTRL_HDR_T pCtrlPktHdr, PVIRTQBUF pVirtqBuf) 2097 2018 { 2098 2019 LogFunc(("%s Processing CTRL MAC command\n", pThis->szInst)); 2099 2100 RT_NOREF(pThisCC);2101 2102 #define ASSERT_CTRL_ADDR_SET(v) \2103 AssertMsgReturn((v), ("DESC chain too small to process CTRL_MAC_ADDR_SET cmd\n"), VIRTIONET_ERROR)2104 2105 #define ASSERT_CTRL_TABLE_SET(v) \2106 AssertMsgReturn((v), ("DESC chain too small to process CTRL_MAC_TABLE_SET cmd\n"), VIRTIONET_ERROR)2107 2020 2108 2021 AssertMsgReturn(pVirtqBuf->cbPhysSend >= sizeof(*pCtrlPktHdr), … … 2116 2029 { 2117 2030 /* Set default Rx filter MAC */ 2118 ASSERT_CTRL_ADDR_SET(cbRemaining >= sizeof(VIRTIONET_CTRL_MAC_TABLE_LEN)); 2119 virtqNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &pThis->rxFilterMacDefault, sizeof(VIRTIONET_CTRL_MAC_TABLE_LEN)); 2031 AssertMsgReturn(cbRemaining >= sizeof(pThis->rxFilterMacDefault), 2032 ("DESC chain too small to process CTRL_MAC_ADDR_SET cmd\n"), VIRTIONET_ERROR); 2033 2034 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &pThis->rxFilterMacDefault, sizeof(VIRTIONET_CTRL_MAC_TABLE_LEN)); 2120 2035 break; 2121 2036 } … … 2125 2040 2126 2041 /* Load unicast MAC filter table */ 2127 ASSERT_CTRL_TABLE_SET(cbRemaining >= sizeof(cMacs)); 2128 virtqNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &cMacs, sizeof(cMacs)); 2042 2043 AssertMsgReturn(cbRemaining >= sizeof(cMacs), 2044 ("DESC chain too small to process CTRL_MAC_TABLE_SET cmd\n"), VIRTIONET_ERROR); 2045 2046 /* Fetch count of unicast filter MACs from guest buffer */ 2047 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &cMacs, sizeof(cMacs)); 2048 2129 2049 cbRemaining -= sizeof(cMacs); 2050 2130 2051 Log7Func(("%s Guest provided %d unicast MAC Table entries\n", pThis->szInst, cMacs)); 2052 2131 2053 if (cMacs) 2132 2054 { 2133 2055 uint32_t cbMacs = cMacs * sizeof(RTMAC); 2134 ASSERT_CTRL_TABLE_SET(cbRemaining >= cbMacs); 2135 virtqNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &pThis->aMacUnicastFilter, cbMacs); 2056 2057 AssertMsgReturn(cbRemaining >= cbMacs, 2058 ("Virtq buffer too small to process CTRL_MAC_TABLE_SET cmd\n"), VIRTIONET_ERROR); 2059 2060 /* Fetch unicast table contents from guest buffer */ 2061 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &pThis->aMacUnicastFilter, cbMacs); 2062 2136 2063 cbRemaining -= cbMacs; 2137 2064 } … … 2139 2066 2140 2067 /* Load multicast MAC filter table */ 2141 ASSERT_CTRL_TABLE_SET(cbRemaining >= sizeof(cMacs)); 2142 virtqNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &cMacs, sizeof(cMacs)); 2068 AssertMsgReturn(cbRemaining >= sizeof(cMacs), 2069 ("Virtq buffer too small to process CTRL_MAC_TABLE_SET cmd\n"), VIRTIONET_ERROR); 2070 2071 /* Fetch count of multicast filter MACs from guest buffer */ 2072 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &cMacs, sizeof(cMacs)); 2073 2143 2074 cbRemaining -= sizeof(cMacs); 2075 2144 2076 Log10Func(("%s Guest provided %d multicast MAC Table entries\n", pThis->szInst, cMacs)); 2077 2078 2145 2079 if (cMacs) 2146 2080 { 2147 2081 uint32_t cbMacs = cMacs * sizeof(RTMAC); 2148 ASSERT_CTRL_TABLE_SET(cbRemaining >= cbMacs); 2149 virtqNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &pThis->aMacMulticastFilter, cbMacs); 2082 2083 AssertMsgReturn(cbRemaining >= cbMacs, 2084 ("Virtq buffer too small to process CTRL_MAC_TABLE_SET cmd\n"), VIRTIONET_ERROR); 2085 2086 /* Fetch multicast table contents from guest buffer */ 2087 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &pThis->aMacMulticastFilter, cbMacs); 2088 2150 2089 cbRemaining -= cbMacs; 2151 2090 } … … 2166 2105 } 2167 2106 2168 static uint8_t virtioNetR3CtrlVlan(PPDMDEVINS pDevIns, PVIRTIONET pThis, PVIRTIONETCC pThisCC, 2169 PVIRTIONET_CTRL_HDR_T pCtrlPktHdr, PVIRTQBUF pVirtqBuf) 2107 static uint8_t virtioNetR3CtrlVlan(PVIRTIONET pThis, PVIRTIONET_CTRL_HDR_T pCtrlPktHdr, PVIRTQBUF pVirtqBuf) 2170 2108 { 2171 2109 LogFunc(("%s Processing CTRL VLAN command\n", pThis->szInst)); 2172 2173 RT_NOREF(pThisCC);2174 2110 2175 2111 uint16_t uVlanId; 2176 2112 size_t cbRemaining = pVirtqBuf->cbPhysSend - sizeof(*pCtrlPktHdr); 2113 2177 2114 AssertMsgReturn(cbRemaining > sizeof(uVlanId), 2178 2115 ("DESC chain too small for VIRTIO_NET_CTRL_VLAN cmd processing"), VIRTIONET_ERROR); 2179 virtqNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, &uVlanId, sizeof(uVlanId)); 2116 2117 /* Fetch VLAN ID from guest buffer */ 2118 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, &uVlanId, sizeof(uVlanId)); 2119 2180 2120 AssertMsgReturn(uVlanId > VIRTIONET_MAX_VLAN_ID, 2181 2121 ("%s VLAN ID out of range (VLAN ID=%u)\n", pThis->szInst, uVlanId), VIRTIONET_ERROR); 2122 2182 2123 LogFunc(("%s uCommand=%u VLAN ID=%u\n", pThis->szInst, pCtrlPktHdr->uCmd, uVlanId)); 2124 2183 2125 switch (pCtrlPktHdr->uCmd) 2184 2126 { … … 2221 2163 ("DESC chain too small for CTRL pkt header")); 2222 2164 2223 virt qNetR3PullBytesFromVirtqBuf(pDevIns, pThis, pVirtqBuf, pCtrlPktHdr,2165 virtioCoreR3VirtqBufDrain(&pThis->Virtio, pVirtqBuf, pCtrlPktHdr, 2224 2166 RT_MIN(pVirtqBuf->cbPhysSend, sizeof(VIRTIONET_CTRL_HDR_T))); 2225 2167 … … 2230 2172 { 2231 2173 case VIRTIONET_CTRL_RX: 2232 uAck = virtioNetR3CtrlRx(p DevIns, pThis, pThisCC, pCtrlPktHdr, pVirtqBuf);2174 uAck = virtioNetR3CtrlRx(pThis, pThisCC, pCtrlPktHdr, pVirtqBuf); 2233 2175 break; 2234 2176 case VIRTIONET_CTRL_MAC: 2235 uAck = virtioNetR3CtrlMac(p DevIns, pThis, pThisCC, pCtrlPktHdr, pVirtqBuf);2177 uAck = virtioNetR3CtrlMac(pThis, pCtrlPktHdr, pVirtqBuf); 2236 2178 break; 2237 2179 case VIRTIONET_CTRL_VLAN: 2238 uAck = virtioNetR3CtrlVlan(p DevIns, pThis, pThisCC, pCtrlPktHdr, pVirtqBuf);2180 uAck = virtioNetR3CtrlVlan(pThis, pCtrlPktHdr, pVirtqBuf); 2239 2181 break; 2240 2182 case VIRTIONET_CTRL_ANNOUNCE: … … 2917 2859 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uVirtqNbr]; 2918 2860 pVirtq->idx = uVirtqNbr; 2919 (void) virtioCore R3VirtqAttach(&pThis->Virtio, pVirtq->idx, pVirtq->szName);2861 (void) virtioCoreVirtqAttach(&pThis->Virtio, pVirtq->idx, pVirtq->szName); 2920 2862 pVirtq->fAttachedToVirtioCore = true; 2921 2863 if (IS_VIRTQ_EMPTY(pThisCC->pDevIns, &pThis->Virtio, pVirtq->idx))
Note:
See TracChangeset
for help on using the changeset viewer.