Page MenuHomeFreeBSD

D27898.id82525.diff
No OneTemporary

D27898.id82525.diff

diff --git a/sys/dev/virtio/pci/virtio_pci.h b/sys/dev/virtio/pci/virtio_pci.h
--- a/sys/dev/virtio/pci/virtio_pci.h
+++ b/sys/dev/virtio/pci/virtio_pci.h
@@ -45,6 +45,7 @@
struct vtpci_common {
device_t vtpci_dev;
+ uint64_t vtpci_host_features;
uint64_t vtpci_features;
struct vtpci_virtqueue *vtpci_vqs;
int vtpci_nvqs;
diff --git a/sys/dev/virtio/pci/virtio_pci.c b/sys/dev/virtio/pci/virtio_pci.c
--- a/sys/dev/virtio/pci/virtio_pci.c
+++ b/sys/dev/virtio/pci/virtio_pci.c
@@ -33,6 +33,8 @@
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/sbuf.h>
+#include <sys/sysctl.h>
#include <sys/module.h>
#include <sys/malloc.h>
@@ -85,6 +87,8 @@
static void vtpci_vq_intr(void *);
static void vtpci_config_intr(void *);
+static void vtpci_setup_sysctl(struct vtpci_common *);
+
#define vtpci_setup_msi_interrupt vtpci_setup_intx_interrupt
/*
@@ -156,6 +160,8 @@
cn->vtpci_flags |= VTPCI_FLAG_NO_MSI;
if (pci_find_cap(dev, PCIY_MSIX, NULL) != 0)
cn->vtpci_flags |= VTPCI_FLAG_NO_MSIX;
+
+ vtpci_setup_sysctl(cn);
}
int
@@ -202,6 +208,7 @@
vtpci_release_child_resources(cn);
cn->vtpci_child_feat_desc = NULL;
+ cn->vtpci_host_features = 0;
cn->vtpci_features = 0;
}
@@ -246,6 +253,7 @@
{
uint64_t features;
+ cn->vtpci_host_features = host_features;
vtpci_describe_features(cn, "host", host_features);
/*
@@ -254,9 +262,9 @@
*/
features = host_features & child_features;
features = virtio_filter_transport_features(features);
- vtpci_describe_features(cn, "negotiated", features);
cn->vtpci_features = features;
+ vtpci_describe_features(cn, "negotiated", features);
return (features);
}
@@ -930,3 +938,64 @@
if (child != NULL)
VIRTIO_CONFIG_CHANGE(child);
}
+
+static int
+vtpci_feature_sysctl(struct sysctl_req *req, struct vtpci_common *cn,
+ uint64_t features)
+{
+ struct sbuf *sb;
+ int error;
+
+ sb = sbuf_new_for_sysctl(NULL, NULL, 256, req);
+ if (sb == NULL)
+ return (ENOMEM);
+
+ error = virtio_describe_sbuf(sb, features, cn->vtpci_child_feat_desc);
+ sbuf_delete(sb);
+
+ return (error);
+}
+
+static int
+vtpci_host_features_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct vtpci_common *cn;
+
+ cn = arg1;
+
+ return (vtpci_feature_sysctl(req, cn, cn->vtpci_host_features));
+}
+
+static int
+vtpci_negotiated_features_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct vtpci_common *cn;
+
+ cn = arg1;
+
+ return (vtpci_feature_sysctl(req, cn, cn->vtpci_features));
+}
+
+static void
+vtpci_setup_sysctl(struct vtpci_common *cn)
+{
+ device_t dev;
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid *tree;
+ struct sysctl_oid_list *child;
+
+ dev = cn->vtpci_dev;
+ ctx = device_get_sysctl_ctx(dev);
+ tree = device_get_sysctl_tree(dev);
+ child = SYSCTL_CHILDREN(tree);
+
+ SYSCTL_ADD_INT(ctx, child, OID_AUTO, "nvqs",
+ CTLFLAG_RD, &cn->vtpci_nvqs, 0, "Number of virtqueues");
+
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "host_features",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, cn, 0,
+ vtpci_host_features_sysctl, "A", "Features supported by the host");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "negotiated_features",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, cn, 0,
+ vtpci_negotiated_features_sysctl, "A", "Features negotiated");
+}
diff --git a/sys/dev/virtio/virtio.h b/sys/dev/virtio/virtio.h
--- a/sys/dev/virtio/virtio.h
+++ b/sys/dev/virtio/virtio.h
@@ -35,6 +35,7 @@
#include <dev/virtio/virtio_ids.h>
#include <dev/virtio/virtio_config.h>
+struct sbuf;
struct vq_alloc_info;
/*
@@ -82,7 +83,9 @@
const char *virtio_device_name(uint16_t devid);
void virtio_describe(device_t dev, const char *msg,
- uint64_t features, struct virtio_feature_desc *feature_desc);
+ uint64_t features, struct virtio_feature_desc *desc);
+int virtio_describe_sbuf(struct sbuf *sb, uint64_t features,
+ struct virtio_feature_desc *desc);
uint64_t virtio_filter_transport_features(uint64_t features);
int virtio_bus_is_modern(device_t dev);
void virtio_read_device_config_array(device_t dev, bus_size_t offset,
diff --git a/sys/dev/virtio/virtio.c b/sys/dev/virtio/virtio.c
--- a/sys/dev/virtio/virtio.c
+++ b/sys/dev/virtio/virtio.c
@@ -119,24 +119,15 @@
return (NULL);
}
-void
-virtio_describe(device_t dev, const char *msg,
- uint64_t features, struct virtio_feature_desc *desc)
+int
+virtio_describe_sbuf(struct sbuf *sb, uint64_t features,
+ struct virtio_feature_desc *desc)
{
- struct sbuf sb;
- uint64_t val;
- char *buf;
const char *name;
+ uint64_t val;
int n;
- if ((buf = malloc(1024, M_TEMP, M_NOWAIT)) == NULL) {
- device_printf(dev, "%s features: %#jx\n",
- msg, (uintmax_t) features);
- return;
- }
-
- sbuf_new(&sb, buf, 1024, SBUF_FIXEDLEN);
- sbuf_printf(&sb, "%s features: %#jx", msg, (uintmax_t) features);
+ sbuf_printf(sb, "%#jx", (uintmax_t) features);
for (n = 0, val = 1ULL << 63; val != 0; val >>= 1) {
/*
@@ -147,25 +138,51 @@
continue;
if (n++ == 0)
- sbuf_cat(&sb, " <");
+ sbuf_cat(sb, " <");
else
- sbuf_cat(&sb, ",");
+ sbuf_cat(sb, ",");
name = virtio_feature_name(val, desc);
if (name == NULL)
- sbuf_printf(&sb, "%#jx", (uintmax_t) val);
+ sbuf_printf(sb, "%#jx", (uintmax_t) val);
else
- sbuf_cat(&sb, name);
+ sbuf_cat(sb, name);
}
if (n > 0)
- sbuf_cat(&sb, ">");
+ sbuf_cat(sb, ">");
- if (sbuf_finish(&sb) == 0)
+ return (sbuf_finish(sb));
+}
+
+void
+virtio_describe(device_t dev, const char *msg, uint64_t features,
+ struct virtio_feature_desc *desc)
+{
+ struct sbuf sb;
+ char *buf;
+ int error;
+
+ if ((buf = malloc(1024, M_TEMP, M_NOWAIT)) == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+
+ sbuf_new(&sb, buf, 1024, SBUF_FIXEDLEN);
+ sbuf_printf(&sb, "%s features: ", msg);
+
+ error = virtio_describe_sbuf(&sb, features, desc);
+ if (error == 0)
device_printf(dev, "%s\n", sbuf_data(&sb));
sbuf_delete(&sb);
free(buf, M_TEMP);
+
+out:
+ if (error != 0) {
+ device_printf(dev, "%s features: %#jx\n", msg,
+ (uintmax_t) features);
+ }
}
uint64_t

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 3:04 AM (11 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31883349
Default Alt Text
D27898.id82525.diff (5 KB)

Event Timeline