diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/vhost.c | 10 | ||||
-rw-r--r-- | hw/vhost.h | 4 | ||||
-rw-r--r-- | hw/vhost_net.c | 24 | ||||
-rw-r--r-- | hw/vhost_net.h | 3 | ||||
-rw-r--r-- | hw/virtio-net.c | 6 | ||||
-rw-r--r-- | hw/virtio-pci.c | 7 | ||||
-rw-r--r-- | hw/virtio.h | 1 |
7 files changed, 45 insertions, 10 deletions
diff --git a/hw/vhost.c b/hw/vhost.c index 6082da287e..38cc3b365b 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -581,7 +581,7 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev, 0, virtio_queue_get_desc_size(vdev, idx)); } -int vhost_dev_init(struct vhost_dev *hdev, int devfd) +int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) { uint64_t features; int r; @@ -613,6 +613,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd) hdev->log_enabled = false; hdev->started = false; cpu_register_phys_memory_client(&hdev->client); + hdev->force = force; return 0; fail: r = -errno; @@ -627,6 +628,13 @@ void vhost_dev_cleanup(struct vhost_dev *hdev) close(hdev->control); } +bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev) +{ + return !vdev->binding->query_guest_notifiers || + vdev->binding->query_guest_notifiers(vdev->binding_opaque) || + hdev->force; +} + int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; diff --git a/hw/vhost.h b/hw/vhost.h index 86dd834dbe..c8c595a147 100644 --- a/hw/vhost.h +++ b/hw/vhost.h @@ -38,10 +38,12 @@ struct vhost_dev { bool log_enabled; vhost_log_chunk_t *log; unsigned long long log_size; + bool force; }; -int vhost_dev_init(struct vhost_dev *hdev, int devfd); +int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force); void vhost_dev_cleanup(struct vhost_dev *hdev); +bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); diff --git a/hw/vhost_net.c b/hw/vhost_net.c index c068be1f54..420e05f112 100644 --- a/hw/vhost_net.c +++ b/hw/vhost_net.c @@ -81,7 +81,8 @@ static int vhost_net_get_fd(VLANClientState *backend) } } -struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd) +struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd, + bool force) { int r; struct vhost_net *net = qemu_malloc(sizeof *net); @@ -98,7 +99,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd) (1 << VHOST_NET_F_VIRTIO_NET_HDR); net->backend = r; - r = vhost_dev_init(&net->dev, devfd); + r = vhost_dev_init(&net->dev, devfd, force); if (r < 0) { goto fail; } @@ -121,6 +122,11 @@ fail: return NULL; } +bool vhost_net_query(VHostNetState *net, VirtIODevice *dev) +{ + return vhost_dev_query(&net->dev, dev); +} + int vhost_net_start(struct vhost_net *net, VirtIODevice *dev) { @@ -188,15 +194,21 @@ void vhost_net_cleanup(struct vhost_net *net) qemu_free(net); } #else -struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd) +struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd, + bool force) +{ + return NULL; +} + +bool vhost_net_query(VHostNetState *net, VirtIODevice *dev) { - return NULL; + return false; } int vhost_net_start(struct vhost_net *net, VirtIODevice *dev) { - return -ENOSYS; + return -ENOSYS; } void vhost_net_stop(struct vhost_net *net, VirtIODevice *dev) @@ -209,7 +221,7 @@ void vhost_net_cleanup(struct vhost_net *net) unsigned vhost_net_get_features(struct vhost_net *net, unsigned features) { - return features; + return features; } void vhost_net_ack_features(struct vhost_net *net, unsigned features) { diff --git a/hw/vhost_net.h b/hw/vhost_net.h index 6c18ff7e94..91e40b195e 100644 --- a/hw/vhost_net.h +++ b/hw/vhost_net.h @@ -6,8 +6,9 @@ struct vhost_net; typedef struct vhost_net VHostNetState; -VHostNetState *vhost_net_init(VLANClientState *backend, int devfd); +VHostNetState *vhost_net_init(VLANClientState *backend, int devfd, bool force); +bool vhost_net_query(VHostNetState *net, VirtIODevice *dev); int vhost_net_start(VHostNetState *net, VirtIODevice *dev); void vhost_net_stop(VHostNetState *net, VirtIODevice *dev); diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 161f11445f..671d952921 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -119,7 +119,11 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) return; } if (!n->vhost_started) { - int r = vhost_net_start(tap_get_vhost_net(n->nic->nc.peer), &n->vdev); + int r; + if (!vhost_net_query(tap_get_vhost_net(n->nic->nc.peer), &n->vdev)) { + return; + } + r = vhost_net_start(tap_get_vhost_net(n->nic->nc.peer), &n->vdev); if (r < 0) { error_report("unable to start vhost net: %d: " "falling back on userspace virtio", -r); diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index d07ff976be..3911b09b07 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -595,6 +595,12 @@ static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign) return 0; } +static bool virtio_pci_query_guest_notifiers(void *opaque) +{ + VirtIOPCIProxy *proxy = opaque; + return msix_enabled(&proxy->pci_dev); +} + static int virtio_pci_set_guest_notifiers(void *opaque, bool assign) { VirtIOPCIProxy *proxy = opaque; @@ -658,6 +664,7 @@ static const VirtIOBindings virtio_pci_bindings = { .save_queue = virtio_pci_save_queue, .load_queue = virtio_pci_load_queue, .get_features = virtio_pci_get_features, + .query_guest_notifiers = virtio_pci_query_guest_notifiers, .set_host_notifier = virtio_pci_set_host_notifier, .set_guest_notifiers = virtio_pci_set_guest_notifiers, .vmstate_change = virtio_pci_vmstate_change, diff --git a/hw/virtio.h b/hw/virtio.h index d8546d5b30..31d16e1c31 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -93,6 +93,7 @@ typedef struct { int (*load_config)(void * opaque, QEMUFile *f); int (*load_queue)(void * opaque, int n, QEMUFile *f); unsigned (*get_features)(void * opaque); + bool (*query_guest_notifiers)(void * opaque); int (*set_guest_notifiers)(void * opaque, bool assigned); int (*set_host_notifier)(void * opaque, int n, bool assigned); void (*vmstate_change)(void * opaque, bool running); |