代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/qemu 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 59957a4caee59e0c82b8d02ed1c1820db523ae64 Mon Sep 17 00:00:00 2001
From: Cindy Lu <lulu@redhat.com>
Date: Thu, 22 Dec 2022 15:04:48 +0800
Subject: [PATCH] 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 <lulu@redhat.com>
Message-Id: <20221222070451.936503-8-lulu@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
hw/virtio/vhost.c | 78 ++++++++++++++++++++++++++++++++++++++-
include/hw/virtio/vhost.h | 4 ++
2 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 19ea9aef69..490c97424b 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1627,7 +1627,68 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
if (r < 0) {
- VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed");
+ error_report("vhost_set_vring_call failed %d", -r);
+ }
+}
+
+bool vhost_config_pending(struct vhost_dev *hdev)
+{
+ assert(hdev->vhost_ops);
+ if ((hdev->started == false) ||
+ (hdev->vhost_ops->vhost_set_config_call == NULL)) {
+ return false;
+ }
+
+ EventNotifier *notifier =
+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
+ return event_notifier_test_and_clear(notifier);
+}
+
+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask)
+{
+ int fd;
+ int r;
+ EventNotifier *notifier =
+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
+ EventNotifier *config_notifier = &vdev->config_notifier;
+ assert(hdev->vhost_ops);
+
+ if ((hdev->started == false) ||
+ (hdev->vhost_ops->vhost_set_config_call == NULL)) {
+ return;
+ }
+ if (mask) {
+ assert(vdev->use_guest_notifier_mask);
+ fd = event_notifier_get_fd(notifier);
+ } else {
+ fd = event_notifier_get_fd(config_notifier);
+ }
+ r = hdev->vhost_ops->vhost_set_config_call(hdev, fd);
+ if (r < 0) {
+ error_report("vhost_set_config_call failed %d", -r);
+ }
+}
+
+static void vhost_stop_config_intr(struct vhost_dev *dev)
+{
+ int fd = -1;
+ assert(dev->vhost_ops);
+ if (dev->vhost_ops->vhost_set_config_call) {
+ dev->vhost_ops->vhost_set_config_call(dev, fd);
+ }
+}
+
+static void vhost_start_config_intr(struct vhost_dev *dev)
+{
+ int r;
+
+ assert(dev->vhost_ops);
+ int fd = event_notifier_get_fd(&dev->vdev->config_notifier);
+ if (dev->vhost_ops->vhost_set_config_call) {
+ r = dev->vhost_ops->vhost_set_config_call(dev, fd);
+ if (!r) {
+ event_notifier_set(&dev->vdev->config_notifier);
+ }
}
}
@@ -1867,6 +1928,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
}
}
+ r = event_notifier_init(
+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0);
+ if (r < 0) {
+ return r;
+ }
+ event_notifier_test_and_clear(
+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
+ if (!vdev->use_guest_notifier_mask) {
+ vhost_config_mask(hdev, vdev, true);
+ }
if (hdev->log_enabled) {
uint64_t log_base;
@@ -1905,6 +1976,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
vhost_device_iotlb_miss(hdev, vq->used_phys, true);
}
}
+ vhost_start_config_intr(hdev);
return 0;
fail_start:
if (vrings) {
@@ -1934,6 +2006,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
/* should only be called after backend is connected */
assert(hdev->vhost_ops);
+ event_notifier_test_and_clear(
+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
+ event_notifier_test_and_clear(&vdev->config_notifier);
trace_vhost_dev_stop(hdev, vdev->name, vrings);
@@ -1956,6 +2031,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
}
memory_listener_unregister(&hdev->iommu_listener);
}
+ vhost_stop_config_intr(hdev);
vhost_log_put(hdev, true);
hdev->started = false;
vdev->vhost_started = false;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 662e0f4370..420f93e5cd 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -32,6 +32,7 @@ struct vhost_virtqueue {
unsigned long long used_phys;
unsigned used_size;
EventNotifier masked_notifier;
+ EventNotifier masked_config_notifier;
struct vhost_dev *dev;
};
@@ -40,6 +41,7 @@ typedef unsigned long vhost_log_chunk_t;
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
#define VHOST_INVALID_FEATURE_BIT (0xff)
+#define VHOST_QUEUE_NUM_CONFIG_INR 0
struct vhost_log {
unsigned long long size;
@@ -163,6 +165,8 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
* Disable direct notifications to vhost device.
*/
void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+bool vhost_config_pending(struct vhost_dev *hdev);
+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask);
/**
* vhost_dev_start() - start the vhost device
--
2.27.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。