Skip to content

Commit f9a09ca

Browse files
lulu-github-namemstsirkin
authored andcommitted
vhost: add support for configure interrupt
Add functions to support configure interrupt. The configure interrupt process will start in vhost_dev_start and stop in vhost_dev_stop. Also add the functions to support vhost_config_pending and vhost_config_mask. Signed-off-by: Cindy Lu <[email protected]> Message-Id: <[email protected]> Acked-by: Jason Wang <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 7d847d0 commit f9a09ca

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

hw/virtio/vhost.c

+77-1
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,68 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
16401640
file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
16411641
r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
16421642
if (r < 0) {
1643-
VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed");
1643+
error_report("vhost_set_vring_call failed %d", -r);
1644+
}
1645+
}
1646+
1647+
bool vhost_config_pending(struct vhost_dev *hdev)
1648+
{
1649+
assert(hdev->vhost_ops);
1650+
if ((hdev->started == false) ||
1651+
(hdev->vhost_ops->vhost_set_config_call == NULL)) {
1652+
return false;
1653+
}
1654+
1655+
EventNotifier *notifier =
1656+
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
1657+
return event_notifier_test_and_clear(notifier);
1658+
}
1659+
1660+
void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask)
1661+
{
1662+
int fd;
1663+
int r;
1664+
EventNotifier *notifier =
1665+
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
1666+
EventNotifier *config_notifier = &vdev->config_notifier;
1667+
assert(hdev->vhost_ops);
1668+
1669+
if ((hdev->started == false) ||
1670+
(hdev->vhost_ops->vhost_set_config_call == NULL)) {
1671+
return;
1672+
}
1673+
if (mask) {
1674+
assert(vdev->use_guest_notifier_mask);
1675+
fd = event_notifier_get_fd(notifier);
1676+
} else {
1677+
fd = event_notifier_get_fd(config_notifier);
1678+
}
1679+
r = hdev->vhost_ops->vhost_set_config_call(hdev, fd);
1680+
if (r < 0) {
1681+
error_report("vhost_set_config_call failed %d", -r);
1682+
}
1683+
}
1684+
1685+
static void vhost_stop_config_intr(struct vhost_dev *dev)
1686+
{
1687+
int fd = -1;
1688+
assert(dev->vhost_ops);
1689+
if (dev->vhost_ops->vhost_set_config_call) {
1690+
dev->vhost_ops->vhost_set_config_call(dev, fd);
1691+
}
1692+
}
1693+
1694+
static void vhost_start_config_intr(struct vhost_dev *dev)
1695+
{
1696+
int r;
1697+
1698+
assert(dev->vhost_ops);
1699+
int fd = event_notifier_get_fd(&dev->vdev->config_notifier);
1700+
if (dev->vhost_ops->vhost_set_config_call) {
1701+
r = dev->vhost_ops->vhost_set_config_call(dev, fd);
1702+
if (!r) {
1703+
event_notifier_set(&dev->vdev->config_notifier);
1704+
}
16441705
}
16451706
}
16461707

@@ -1880,6 +1941,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
18801941
}
18811942
}
18821943

1944+
r = event_notifier_init(
1945+
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0);
1946+
if (r < 0) {
1947+
return r;
1948+
}
1949+
event_notifier_test_and_clear(
1950+
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
1951+
if (!vdev->use_guest_notifier_mask) {
1952+
vhost_config_mask(hdev, vdev, true);
1953+
}
18831954
if (hdev->log_enabled) {
18841955
uint64_t log_base;
18851956

@@ -1918,6 +1989,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
19181989
vhost_device_iotlb_miss(hdev, vq->used_phys, true);
19191990
}
19201991
}
1992+
vhost_start_config_intr(hdev);
19211993
return 0;
19221994
fail_start:
19231995
if (vrings) {
@@ -1947,6 +2019,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
19472019

19482020
/* should only be called after backend is connected */
19492021
assert(hdev->vhost_ops);
2022+
event_notifier_test_and_clear(
2023+
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
2024+
event_notifier_test_and_clear(&vdev->config_notifier);
19502025

19512026
trace_vhost_dev_stop(hdev, vdev->name, vrings);
19522027

@@ -1969,6 +2044,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
19692044
}
19702045
memory_listener_unregister(&hdev->iommu_listener);
19712046
}
2047+
vhost_stop_config_intr(hdev);
19722048
vhost_log_put(hdev, true);
19732049
hdev->started = false;
19742050
vdev->vhost_started = false;

include/hw/virtio/vhost.h

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct vhost_virtqueue {
3333
unsigned used_size;
3434
EventNotifier masked_notifier;
3535
EventNotifier error_notifier;
36+
EventNotifier masked_config_notifier;
3637
struct vhost_dev *dev;
3738
};
3839

@@ -41,6 +42,7 @@ typedef unsigned long vhost_log_chunk_t;
4142
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
4243
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
4344
#define VHOST_INVALID_FEATURE_BIT (0xff)
45+
#define VHOST_QUEUE_NUM_CONFIG_INR 0
4446

4547
struct vhost_log {
4648
unsigned long long size;
@@ -187,6 +189,8 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
187189
* Disable direct notifications to vhost device.
188190
*/
189191
void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
192+
bool vhost_config_pending(struct vhost_dev *hdev);
193+
void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask);
190194

191195
/**
192196
* vhost_dev_is_started() - report status of vhost device

0 commit comments

Comments
 (0)