Page MenuHomeFreeBSD

D23401.id67419.diff
No OneTemporary

D23401.id67419.diff

Index: sys/dev/virtio/pci/virtio_pci.c
===================================================================
--- sys/dev/virtio/pci/virtio_pci.c
+++ sys/dev/virtio/pci/virtio_pci.c
@@ -37,6 +37,7 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
+#include <sys/endian.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -184,6 +185,15 @@
#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 VirtioIO header is always PCI endianness (little), so if we
+ * are in a BE machine we need to swap bytes to LE.
+ */
+#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) bus_write_2((sc)->vtpci_res, (o), (le16toh(v)))
+#define vtpci_write_header_4(sc, o, v) bus_write_4((sc)->vtpci_res, (o), (le32toh(v)))
+
/* Tunables. */
static int vtpci_disable_msix = 0;
TUNABLE_INT("hw.virtio.pci.disable_msix", &vtpci_disable_msix);
@@ -278,6 +288,17 @@
return (ENXIO);
}
+ /*
+ * For VirtIO legacy drivers, the configurarion area endianness
+ * is guest endianness, except the header that is always PCI
+ * endianness (little), 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;
@@ -447,7 +468,8 @@
sc = device_get_softc(dev);
- host_features = vtpci_read_config_4(sc, VIRTIO_PCI_HOST_FEATURES);
+ host_features = vtpci_read_header_4(sc, VIRTIO_PCI_HOST_FEATURES);
+
vtpci_describe_features(sc, "host", host_features);
/*
@@ -459,7 +481,7 @@
sc->vtpci_features = features;
vtpci_describe_features(sc, "negotiated", features);
- vtpci_write_config_4(sc, VIRTIO_PCI_GUEST_FEATURES, features);
+ vtpci_write_header_4(sc, VIRTIO_PCI_GUEST_FEATURES, features);
return (features);
}
@@ -502,7 +524,7 @@
info = &vq_info[idx];
vtpci_select_virtqueue(sc, idx);
- size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
+ size = vtpci_read_header_2(sc, VIRTIO_PCI_QUEUE_NUM);
error = virtqueue_alloc(dev, idx, size, VIRTIO_PCI_VRING_ALIGN,
~(vm_paddr_t)0, info, &vq);
@@ -512,7 +534,7 @@
break;
}
- vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN,
+ vtpci_write_header_4(sc, VIRTIO_PCI_QUEUE_PFN,
virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
vqx->vtv_vq = *info->vqai_vq = vq;
@@ -646,7 +668,7 @@
sc = device_get_softc(dev);
- vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_NOTIFY, queue);
+ vtpci_write_header_2(sc, VIRTIO_PCI_QUEUE_NOTIFY, queue);
}
static uint8_t
@@ -1046,10 +1068,10 @@
} else
vector = VIRTIO_MSI_NO_VECTOR;
- vtpci_write_config_2(sc, offset, vector);
+ vtpci_write_header_2(sc, offset, vector);
/* Read vector to determine if the host had sufficient resources. */
- if (vtpci_read_config_2(sc, offset) != vector) {
+ if (vtpci_read_header_2(sc, offset) != vector) {
device_printf(dev,
"insufficient host resources for MSIX interrupts\n");
return (ENODEV);
@@ -1112,13 +1134,13 @@
KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx));
vtpci_select_virtqueue(sc, idx);
- size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
+ size = vtpci_read_header_2(sc, VIRTIO_PCI_QUEUE_NUM);
error = virtqueue_reinit(vq, size);
if (error)
return (error);
- vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN,
+ vtpci_write_header_4(sc, VIRTIO_PCI_QUEUE_PFN,
virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
return (0);
@@ -1182,7 +1204,7 @@
vqx = &sc->vtpci_vqs[idx];
vtpci_select_virtqueue(sc, idx);
- vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN, 0);
+ vtpci_write_header_4(sc, VIRTIO_PCI_QUEUE_PFN, 0);
virtqueue_free(vqx->vtv_vq);
vqx->vtv_vq = NULL;
@@ -1207,12 +1229,12 @@
int idx;
if (sc->vtpci_flags & VTPCI_FLAG_MSIX) {
- vtpci_write_config_2(sc, VIRTIO_MSI_CONFIG_VECTOR,
+ vtpci_write_header_2(sc, VIRTIO_MSI_CONFIG_VECTOR,
VIRTIO_MSI_NO_VECTOR);
for (idx = 0; idx < sc->vtpci_nvqs; idx++) {
vtpci_select_virtqueue(sc, idx);
- vtpci_write_config_2(sc, VIRTIO_MSI_QUEUE_VECTOR,
+ vtpci_write_header_2(sc, VIRTIO_MSI_QUEUE_VECTOR,
VIRTIO_MSI_NO_VECTOR);
}
}
@@ -1235,7 +1257,7 @@
vtpci_select_virtqueue(struct vtpci_softc *sc, int idx)
{
- vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_SEL, idx);
+ vtpci_write_header_2(sc, VIRTIO_PCI_QUEUE_SEL, idx);
}
static void

File Metadata

Mime Type
text/plain
Expires
Sat, May 23, 6:08 AM (21 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33430857
Default Alt Text
D23401.id67419.diff (4 KB)

Event Timeline