svn commit: r304425 - stable/10/usr.sbin/bhyve

Alexander Motin mav at FreeBSD.org
Thu Aug 18 11:56:09 UTC 2016


Author: mav
Date: Thu Aug 18 11:56:07 2016
New Revision: 304425
URL: https://svnweb.freebsd.org/changeset/base/304425

Log:
  MFC r302504, r302666, r302668, r302932, r302933:
  Add emulation for Intel e1000 (e82545) network adapter.
  
  The code was successfully tested with FreeBSD, Linux, Solaris and Windows
  guests.  This interface is predictably slower (about 2x) then virtio-net,
  but it is very helpful for guests not supporting virtio-net by default.
  
  Thanks to Jeremiah Lott and Peter Grehan for doing original heavy lifting.

Added:
  stable/10/usr.sbin/bhyve/pci_e82545.c
     - copied, changed from r302504, head/usr.sbin/bhyve/pci_e82545.c
Modified:
  stable/10/usr.sbin/bhyve/Makefile
  stable/10/usr.sbin/bhyve/bhyve.8
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/bhyve/Makefile
==============================================================================
--- stable/10/usr.sbin/bhyve/Makefile	Thu Aug 18 11:51:14 2016	(r304424)
+++ stable/10/usr.sbin/bhyve/Makefile	Thu Aug 18 11:56:07 2016	(r304425)
@@ -23,6 +23,7 @@ SRCS=	\
 	mevent.c		\
 	mptbl.c			\
 	pci_ahci.c		\
+	pci_e82545.c		\
 	pci_emul.c		\
 	pci_hostbridge.c	\
 	pci_irq.c		\
@@ -48,6 +49,10 @@ SRCS+=	vmm_instruction_emul.c
 DPADD=	${LIBVMMAPI} ${LIBMD} ${LIBUTIL} ${LIBPTHREAD}
 LDADD=	-lvmmapi -lmd -lutil -lpthread
 
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/e1000
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/mii
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/usb/controller
+
 WARNS?=	2
 
 .include <bsd.prog.mk>

Modified: stable/10/usr.sbin/bhyve/bhyve.8
==============================================================================
--- stable/10/usr.sbin/bhyve/bhyve.8	Thu Aug 18 11:51:14 2016	(r304424)
+++ stable/10/usr.sbin/bhyve/bhyve.8	Thu Aug 18 11:56:07 2016	(r304425)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 8, 2016
+.Dd July 9, 2016
 .Dt BHYVE 8
 .Os
 .Sh NAME
@@ -174,6 +174,8 @@ AHCI controller attached to arbitraty de
 AHCI controller attached to an ATAPI CD/DVD.
 .It Li ahci-hd
 AHCI controller attached to a SATA hard-drive.
+.It Li e1000
+Intel e82545 network interface.
 .It Li uart
 PCI 16550 serial device.
 .It Li lpc

Copied and modified: stable/10/usr.sbin/bhyve/pci_e82545.c (from r302504, head/usr.sbin/bhyve/pci_e82545.c)
==============================================================================
--- head/usr.sbin/bhyve/pci_e82545.c	Sat Jul  9 20:41:59 2016	(r302504, copy source)
+++ stable/10/usr.sbin/bhyve/pci_e82545.c	Thu Aug 18 11:56:07 2016	(r304425)
@@ -109,12 +109,8 @@ __FBSDID("$FreeBSD$");
 
 #define E1000_ICR_SRPD		0x00010000
 
-/*
- * XXX does this actually have a limit on the 82545 ?
- * There is a limit on the max number of bytes, but perhaps not
- * on descriptors ??
- */
-#define I82545_MAX_TXSEGS	20
+/* This is an arbitrary number.  There is no hard limit on the chip. */
+#define I82545_MAX_TXSEGS	64
 
 /* Legacy receive descriptor */
 struct e1000_rx_desc {
@@ -1050,15 +1046,18 @@ e82545_transmit_backend(struct e82545_so
 }
 
 static void
-e82545_transmit_done(struct e82545_softc *sc, union e1000_tx_udesc **txwb,
-    int nwb)
+e82545_transmit_done(struct e82545_softc *sc, uint16_t head, uint16_t tail,
+    uint16_t dsize, int *tdwb)
 {
-	int i;
+	union e1000_tx_udesc *dsc;
 
-	/* Write-back tx descriptor status */
-	for (i = 0; i < nwb; i++)
-		txwb[i]->td.upper.data |= E1000_TXD_STAT_DD;
-	/* XXX wmb() */
+	for ( ; head != tail; head = (head + 1) % dsize) {
+		dsc = &sc->esc_txdesc[head];
+		if (dsc->td.lower.data & E1000_TXD_CMD_RS) {
+			dsc->td.upper.data |= E1000_TXD_STAT_DD;
+			*tdwb = 1;
+		}
+	}
 }
 
 static int
@@ -1068,22 +1067,21 @@ e82545_transmit(struct e82545_softc *sc,
 	uint8_t *hdr, *hdrp;
 	struct iovec iovb[I82545_MAX_TXSEGS + 2];
 	struct iovec tiov[I82545_MAX_TXSEGS + 2];
-	union e1000_tx_udesc *txwb[I82545_MAX_TXSEGS];
 	struct e1000_context_desc *cd;
 	struct ck_info ckinfo[2];
 	struct iovec *iov;
 	union  e1000_tx_udesc *dsc;
-	int desc, dtype, len, ntype, nwb, iovcnt, tlen, hdrlen, vlen, tcp, tso;
+	int desc, dtype, len, ntype, iovcnt, tlen, hdrlen, vlen, tcp, tso;
 	int mss, paylen, seg, tiovcnt, left, now, nleft, nnow, pv, pvoff;
 	uint32_t tcpsum, tcpseq;
-	uint16_t ipcs, tcpcs, ipid;
+	uint16_t ipcs, tcpcs, ipid, ohead;
 
 	ckinfo[0].ck_valid = ckinfo[1].ck_valid = 0;
 	iovcnt = 0;
 	tlen = 0;
-	nwb = 0;
 	ntype = 0;
 	tso = 0;
+	ohead = head;
 
 	/* iovb[0/1] may be used for writable copy of headers. */
 	iov = &iovb[2];
@@ -1104,11 +1102,8 @@ e82545_transmit(struct e82545_softc *sc,
 				    head, dsc->td.buffer_addr,
 				    dsc->td.upper.data, dsc->td.lower.data);
 				/* Save context and return */
-				/* XXX ignore DD processing here */
 				sc->esc_txctx = dsc->cd;
-				*rhead = (head + 1) % dsize;
-				return (1);
-				break;
+				goto done;
 			case E1000_TXD_TYP_L:
 				DPRINTF("tx legacy desc idx %d: %08x%08x\r\n",
 				    head, dsc->td.upper.data, dsc->td.lower.data);
@@ -1142,16 +1137,14 @@ e82545_transmit(struct e82545_softc *sc,
 			    (dsc->td.lower.data & E1000_TXD_CMD_IFCS) == 0)
 				len -= 2;
 			tlen += len;
-			iov[iovcnt].iov_base = paddr_guest2host(sc->esc_ctx,
-			    dsc->td.buffer_addr, len);
-			iov[iovcnt].iov_len = len;
+			if (iovcnt < I82545_MAX_TXSEGS) {
+				iov[iovcnt].iov_base = paddr_guest2host(
+				    sc->esc_ctx, dsc->td.buffer_addr, len);
+				iov[iovcnt].iov_len = len;
+			}
 			iovcnt++;
 		}
 
-		/* Record the descriptor addres if write-back requested */
-		if (dsc->td.lower.data & E1000_TXD_CMD_RS)
-			txwb[nwb++] = dsc;
-
 		/*
 		 * Pull out info that is valid in the final descriptor
 		 * and exit descriptor loop.
@@ -1197,6 +1190,12 @@ e82545_transmit(struct e82545_softc *sc,
 		}
 	}
 
+	if (iovcnt > I82545_MAX_TXSEGS) {
+		WPRINTF("tx too many descriptors (%d > %d) -- dropped\r\n",
+		    iovcnt, I82545_MAX_TXSEGS);
+		goto done;
+	}
+
 	hdrlen = vlen = 0;
 	/* Estimate writable space for VLAN header insertion. */
 	if ((sc->esc_CTRL & E1000_CTRL_VME) &&
@@ -1356,12 +1355,10 @@ e82545_transmit(struct e82545_softc *sc,
 	}
 
 done:
-	/* Record if tx descs were written back */
-	e82545_transmit_done(sc, txwb, nwb);
-	if (nwb)
-		*tdwb = 1;
+	head = (head + 1) % dsize;
+	e82545_transmit_done(sc, ohead, head, dsize, tdwb);
 
-	*rhead = (head + 1) % dsize;
+	*rhead = head;
 	return (desc + 1);
 }
 
@@ -2000,6 +1997,7 @@ e82545_read_register(struct e82545_softc
 		break;
 	default:
 		DPRINTF("Unknown read register: 0x%x\r\n", offset);
+		retval = 0;
 		break;
 	}
 
@@ -2040,6 +2038,7 @@ e82545_write(struct vmctx *ctx, int vcpu
 			DPRINTF("Unknown io bar write offset:0x%lx value:0x%lx size:%d\r\n", offset, value, size);
 			break;
 		}
+		break;
 	case E82545_BAR_REGISTER:
 		if (size != 4) {
 			DPRINTF("Wrong register write size:%d offset:0x%lx value:0x%lx\r\n", size, offset, value);
@@ -2092,6 +2091,7 @@ e82545_read(struct vmctx *ctx, int vcpu,
 				offset, size);
 			break;
 		}
+		break;
 	case E82545_BAR_REGISTER:
 		if (size != 4) {
 			DPRINTF("Wrong register read size:%d offset:0x%lx\r\n",


More information about the svn-src-all mailing list