Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159126171
D20703.id58812.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D20703.id58812.diff
View Options
Index: sys/dev/virtio/mmio/virtio_mmio.c
===================================================================
--- sys/dev/virtio/mmio/virtio_mmio.c
+++ sys/dev/virtio/mmio/virtio_mmio.c
@@ -88,6 +88,7 @@
static void vtmmio_set_status(device_t, uint8_t);
static void vtmmio_read_dev_config(device_t, bus_size_t, void *, int);
static void vtmmio_write_dev_config(device_t, bus_size_t, void *, int);
+static uint32_t vtmmio_virtqueue_size(device_t dev, int idx);
static void vtmmio_describe_features(struct vtmmio_softc *, const char *,
uint64_t);
static void vtmmio_probe_and_attach_child(struct vtmmio_softc *);
@@ -161,6 +162,7 @@
DEVMETHOD(virtio_bus_notify_vq, vtmmio_notify_virtqueue),
DEVMETHOD(virtio_bus_read_device_config, vtmmio_read_dev_config),
DEVMETHOD(virtio_bus_write_device_config, vtmmio_write_dev_config),
+ DEVMETHOD(virtio_bus_virtqueue_size, vtmmio_virtqueue_size),
DEVMETHOD_END
};
@@ -404,6 +406,19 @@
return ((sc->vtmmio_features & feature) != 0);
}
+static uint32_t
+vtmmio_virtqueue_size(device_t dev, int idx)
+{
+ struct vtmmio_softc *sc;
+ uint32_t size;
+
+ sc = device_get_softc(dev);
+ vtmmio_select_virtqueue(sc, idx);
+ size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX);
+
+ return (size);
+}
+
static int
vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs,
struct vq_alloc_info *vq_info)
Index: sys/dev/virtio/pci/virtio_pci.c
===================================================================
--- sys/dev/virtio/pci/virtio_pci.c
+++ sys/dev/virtio/pci/virtio_pci.c
@@ -113,6 +113,7 @@
static uint64_t vtpci_negotiate_features(device_t, uint64_t);
static int vtpci_with_feature(device_t, uint64_t);
+static uint32_t vtpci_virtqueue_size(device_t dev, int idx);
static int vtpci_alloc_virtqueues(device_t, int, int,
struct vq_alloc_info *);
static int vtpci_setup_intr(device_t, enum intr_type);
@@ -215,6 +216,7 @@
DEVMETHOD(virtio_bus_notify_vq, vtpci_notify_virtqueue),
DEVMETHOD(virtio_bus_read_device_config, vtpci_read_dev_config),
DEVMETHOD(virtio_bus_write_device_config, vtpci_write_dev_config),
+ DEVMETHOD(virtio_bus_virtqueue_size, vtpci_virtqueue_size),
DEVMETHOD_END
};
@@ -474,6 +476,19 @@
return ((sc->vtpci_features & feature) != 0);
}
+static uint32_t
+vtpci_virtqueue_size(device_t dev, int idx)
+{
+ struct vtpci_softc *sc;
+ uint32_t size;
+
+ sc = device_get_softc(dev);
+ vtpci_select_virtqueue(sc, idx);
+ size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
+
+ return (size);
+}
+
static int
vtpci_alloc_virtqueues(device_t dev, int flags, int nvqs,
struct vq_alloc_info *vq_info)
Index: sys/dev/virtio/scsi/virtio_scsi.c
===================================================================
--- sys/dev/virtio/scsi/virtio_scsi.c
+++ sys/dev/virtio/scsi/virtio_scsi.c
@@ -68,6 +68,8 @@
#include "virtio_if.h"
+#define VTSCSI_FIRST_REQUEST_QUEUE 2
+
static int vtscsi_modevent(module_t, int, void *);
static int vtscsi_probe(device_t);
@@ -79,7 +81,8 @@
static void vtscsi_negotiate_features(struct vtscsi_softc *);
static void vtscsi_read_config(struct vtscsi_softc *,
struct virtio_scsi_config *);
-static int vtscsi_maximum_segments(struct vtscsi_softc *, int);
+static uint32_t vtscsi_minimum_request_queue_size(struct vtscsi_softc *, int);
+static int vtscsi_maximum_segments(struct vtscsi_softc *, int, int);
static int vtscsi_alloc_virtqueues(struct vtscsi_softc *);
static void vtscsi_write_device_config(struct vtscsi_softc *);
static int vtscsi_reinit(struct vtscsi_softc *);
@@ -297,7 +300,8 @@
vtscsi_write_device_config(sc);
- sc->vtscsi_max_nsegs = vtscsi_maximum_segments(sc, scsicfg.seg_max);
+ sc->vtscsi_max_nsegs = vtscsi_maximum_segments(sc, scsicfg.seg_max,
+ scsicfg.num_queues);
sc->vtscsi_sglist = sglist_alloc(sc->vtscsi_max_nsegs, M_NOWAIT);
if (sc->vtscsi_sglist == NULL) {
error = ENOMEM;
@@ -437,8 +441,27 @@
#undef VTSCSI_GET_CONFIG
+static uint32_t
+vtscsi_minimum_request_queue_size(struct vtscsi_softc *sc, int num_queues)
+{
+ device_t dev;
+ uint32_t size, s;
+ int i;
+
+ dev = sc->vtscsi_dev;
+ size = 0;
+ for (i = 0; i < num_queues; ++i) {
+ s = virtio_virtqueue_size(dev, i + VTSCSI_FIRST_REQUEST_QUEUE);
+ if (s != 0 && (size == 0 || s < size)) {
+ size = s;
+ }
+ }
+
+ return (size);
+}
+
static int
-vtscsi_maximum_segments(struct vtscsi_softc *sc, int seg_max)
+vtscsi_maximum_segments(struct vtscsi_softc *sc, int seg_max, int num_queues)
{
int nsegs;
@@ -448,6 +471,12 @@
nsegs += MIN(seg_max, MAXPHYS / PAGE_SIZE + 1);
if (sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT)
nsegs = MIN(nsegs, VIRTIO_MAX_INDIRECT);
+ /*
+ * Ensure the assertions in virtqueue_enqueue(),
+ * even if the hypervisor reports a bad seg_max.
+ */
+ nsegs = MIN(nsegs,
+ vtscsi_minimum_request_queue_size(sc, num_queues));
} else
nsegs += 1;
Index: sys/dev/virtio/virtio.h
===================================================================
--- sys/dev/virtio/virtio.h
+++ sys/dev/virtio/virtio.h
@@ -96,6 +96,7 @@
int virtio_config_generation(device_t dev);
int virtio_reinit(device_t dev, uint64_t features);
void virtio_reinit_complete(device_t dev);
+uint32_t virtio_virtqueue_size(device_t dev, int idx);
int virtio_child_pnpinfo_str(device_t busdev, device_t child, char *buf,
size_t buflen);
Index: sys/dev/virtio/virtio.c
===================================================================
--- sys/dev/virtio/virtio.c
+++ sys/dev/virtio/virtio.c
@@ -287,6 +287,13 @@
return (0);
}
+uint32_t
+virtio_virtqueue_size(device_t dev, int idx)
+{
+
+ return (VIRTIO_BUS_VIRTQUEUE_SIZE(device_get_parent(dev), idx));
+}
+
static int
virtio_modevent(module_t mod, int type, void *unused)
{
Index: sys/dev/virtio/virtio_bus_if.m
===================================================================
--- sys/dev/virtio/virtio_bus_if.m
+++ sys/dev/virtio/virtio_bus_if.m
@@ -104,3 +104,7 @@
device_t dev;
};
+METHOD uint32_t virtqueue_size {
+ device_t dev;
+ int idx;
+};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jun 11, 9:55 AM (11 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33875314
Default Alt Text
D20703.id58812.diff (5 KB)
Attached To
Mode
D20703: VirtIO SCSI: validate seg_max from hypervisor
Attached
Detach File
Event Timeline
Log In to Comment