aboutsummaryrefslogtreecommitdiff
path: root/hw/net
diff options
context:
space:
mode:
Diffstat (limited to 'hw/net')
-rw-r--r--hw/net/vhost_net.c45
-rw-r--r--hw/net/vmxnet3.c2
2 files changed, 44 insertions, 3 deletions
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 6e1032fc18..50f4dcd655 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -120,6 +120,11 @@ uint64_t vhost_net_get_max_queues(VHostNetState *net)
return net->dev.max_queues;
}
+uint64_t vhost_net_get_acked_features(VHostNetState *net)
+{
+ return net->dev.acked_features;
+}
+
static int vhost_net_get_fd(NetClientState *backend)
{
switch (backend->info->type) {
@@ -136,6 +141,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
int r;
bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL;
struct vhost_net *net = g_malloc(sizeof *net);
+ uint64_t features = 0;
if (!options->net_backend) {
fprintf(stderr, "vhost-net requires net backend to be setup\n");
@@ -183,8 +189,21 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
goto fail;
}
}
+
/* Set sane init value. Override when guest acks. */
- vhost_net_ack_features(net, 0);
+ if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
+ features = vhost_user_get_acked_features(net->nc);
+ if (~net->dev.features & features) {
+ fprintf(stderr, "vhost lacks feature mask %" PRIu64
+ " for backend\n",
+ (uint64_t)(~net->dev.features & features));
+ vhost_dev_cleanup(&net->dev);
+ goto fail;
+ }
+ }
+
+ vhost_net_ack_features(net, features);
+
return net;
fail:
g_free(net);
@@ -310,6 +329,15 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
if (r < 0) {
goto err_start;
}
+
+ if (ncs[i].peer->vring_enable) {
+ /* restore vring enable state */
+ r = vhost_set_vring_enable(ncs[i].peer, ncs[i].peer->vring_enable);
+
+ if (r < 0) {
+ goto err_start;
+ }
+ }
}
return 0;
@@ -401,8 +429,15 @@ VHostNetState *get_vhost_net(NetClientState *nc)
int vhost_set_vring_enable(NetClientState *nc, int enable)
{
VHostNetState *net = get_vhost_net(nc);
- const VhostOps *vhost_ops = net->dev.vhost_ops;
+ const VhostOps *vhost_ops;
+ nc->vring_enable = enable;
+
+ if (!net) {
+ return 0;
+ }
+
+ vhost_ops = net->dev.vhost_ops;
if (vhost_ops->vhost_set_vring_enable) {
return vhost_ops->vhost_set_vring_enable(&net->dev, enable);
}
@@ -442,10 +477,16 @@ uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
{
return features;
}
+
void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
{
}
+uint64_t vhost_net_get_acked_features(VHostNetState *net)
+{
+ return 0;
+}
+
bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
{
return false;
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 16645e6c23..d97897670d 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -348,7 +348,7 @@ typedef struct {
/* Interrupt management */
/*
- *This function returns sign whether interrupt line is in asserted state
+ * This function returns sign whether interrupt line is in asserted state
* This depends on the type of interrupt used. For INTX interrupt line will
* be asserted until explicit deassertion, for MSI(X) interrupt line will
* be deasserted automatically due to notification semantics of the MSI(X)