Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Jul 2020 11:23:37 +0000 (UTC)
From:      "Alfredo Dal'Ava Junior" <alfredo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r363646 - head/sys/dev/virtio/pci
Message-ID:  <202007281123.06SBNb0E053882@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alfredo
Date: Tue Jul 28 11:23:37 2020
New Revision: 363646
URL: https://svnweb.freebsd.org/changeset/base/363646

Log:
  virtio: fix mips regression introduced by r357596
  
  PowerPC support was fixed in r357596 by changing PCI bustag to BE as
  part of the solution, but this caused regression on mips. This change
  implements byte swapping of virtio PCI config area in the driver,
  leaving lower layer untouched.
  
  Submittnd by:	Fernando Valle <fernando.valle@eldorado.org.br>
  Reported by:	arichardson
  Reviewed by:	alfredo, arichardson
  Sponsored by:	Eldorado Research Institute (eldorado.org.br)
  Differential Revision:	https://reviews.freebsd.org/D25416

Modified:
  head/sys/dev/virtio/pci/virtio_pci.c

Modified: head/sys/dev/virtio/pci/virtio_pci.c
==============================================================================
--- head/sys/dev/virtio/pci/virtio_pci.c	Tue Jul 28 11:13:37 2020	(r363645)
+++ head/sys/dev/virtio/pci/virtio_pci.c	Tue Jul 28 11:23:37 2020	(r363646)
@@ -179,23 +179,25 @@ static void	vtpci_config_intr(void *);
  * I/O port read/write wrappers.
  */
 #define vtpci_read_config_1(sc, o)	bus_read_1((sc)->vtpci_res, (o))
-#define vtpci_read_config_2(sc, o)	bus_read_2((sc)->vtpci_res, (o))
-#define vtpci_read_config_4(sc, o)	bus_read_4((sc)->vtpci_res, (o))
 #define vtpci_write_config_1(sc, o, v)	bus_write_1((sc)->vtpci_res, (o), (v))
-#define vtpci_write_config_2(sc, o, v)	bus_write_2((sc)->vtpci_res, (o), (v))
-#define vtpci_write_config_4(sc, o, v)	bus_write_4((sc)->vtpci_res, (o), (v))
 
 /*
- * Legacy VirtIO header is always PCI endianness (little), so if we
- * are in a BE machine we need to swap bytes from LE to BE when reading
- * and from BE to LE when writing.
- * If we are in a LE machine, there will be no swaps.
+ * Virtio-pci specifies that PCI Configuration area is guest endian. However,
+ * since PCI devices are inherently little-endian, on BE systems the bus layer
+ * transparently converts it to BE. For virtio-legacy, this conversion is
+ * undesired, so an extra byte swap is required to fix it.
  */
-#define vtpci_read_header_2(sc, o)	le16toh(vtpci_read_config_2(sc, o))
-#define vtpci_read_header_4(sc, o)	le32toh(vtpci_read_config_4(sc, o))
-#define vtpci_write_header_2(sc, o, v)  vtpci_write_config_2(sc, o, (htole16(v)))
-#define vtpci_write_header_4(sc, o, v)  vtpci_write_config_4(sc, o, (htole32(v)))
+#define vtpci_read_config_2(sc, o)      le16toh(bus_read_2((sc)->vtpci_res, (o)))
+#define vtpci_read_config_4(sc, o)      le32toh(bus_read_4((sc)->vtpci_res, (o)))
+#define vtpci_write_config_2(sc, o, v)  bus_write_2((sc)->vtpci_res, (o), (htole16(v)))
+#define vtpci_write_config_4(sc, o, v)  bus_write_4((sc)->vtpci_res, (o), (htole32(v)))
 
+/* PCI Header LE. On BE systems the bus layer takes care of byte swapping */
+#define vtpci_read_header_2(sc, o)      (bus_read_2((sc)->vtpci_res, (o)))
+#define vtpci_read_header_4(sc, o)      (bus_read_4((sc)->vtpci_res, (o)))
+#define vtpci_write_header_2(sc, o, v)  bus_write_2((sc)->vtpci_res, (o), (v))
+#define vtpci_write_header_4(sc, o, v)  bus_write_4((sc)->vtpci_res, (o), (v))
+
 /* Tunables. */
 static int vtpci_disable_msix = 0;
 TUNABLE_INT("hw.virtio.pci.disable_msix", &vtpci_disable_msix);
@@ -289,17 +291,6 @@ vtpci_attach(device_t dev)
 		device_printf(dev, "cannot map I/O space\n");
 		return (ENXIO);
 	}
-
-/*
- * For legacy VirtIO, the device-specific configuration is guest
- * endian, while the common configuration header is always
- * PCI (little) endian and will be handled specifically in
- * other parts of this file via functions
- * 'vtpci_[read|write]_header_[2|4]'
- */
-#if _BYTE_ORDER == _BIG_ENDIAN
-	rman_set_bustag(sc->vtpci_res, &bs_be_tag);
-#endif
 
 	if (pci_find_cap(dev, PCIY_MSI, NULL) != 0)
 		sc->vtpci_flags |= VTPCI_FLAG_NO_MSI;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007281123.06SBNb0E053882>