|
|
76daa3 |
From 252e1d70fd15578a8ed365ee2c0face8f12bc149 Mon Sep 17 00:00:00 2001
|
|
|
76daa3 |
From: Maxime Coquelin <maxime.coquelin@redhat.com>
|
|
|
76daa3 |
Date: Tue, 6 Jun 2017 12:05:21 +0200
|
|
|
76daa3 |
Subject: [PATCH 10/17] vhost: rework IOTLB messaging
|
|
|
76daa3 |
|
|
|
76daa3 |
RH-Author: Maxime Coquelin <maxime.coquelin@redhat.com>
|
|
|
76daa3 |
Message-id: <20170606120524.3050-3-maxime.coquelin@redhat.com>
|
|
|
76daa3 |
Patchwork-id: 75497
|
|
|
76daa3 |
O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH 2/5] vhost: rework IOTLB messaging
|
|
|
76daa3 |
Bugzilla: 1451862
|
|
|
76daa3 |
RH-Acked-by: Peter Xu <peterx@redhat.com>
|
|
|
76daa3 |
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
|
|
76daa3 |
RH-Acked-by: Jens Freimann <jfreiman@redhat.com>
|
|
|
76daa3 |
|
|
|
76daa3 |
This patch reworks IOTLB messaging to prepare for vhost-user
|
|
|
76daa3 |
device IOTLB support.
|
|
|
76daa3 |
|
|
|
76daa3 |
IOTLB messages handling is extracted from vhost-kernel backend,
|
|
|
76daa3 |
so that only the messages transport remains backend specifics.
|
|
|
76daa3 |
|
|
|
76daa3 |
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
|
|
76daa3 |
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
76daa3 |
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
76daa3 |
(cherry picked from commit 020e571b8bf90e022bbb78346e189f0f26e4675f)
|
|
|
76daa3 |
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
|
|
76daa3 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
76daa3 |
---
|
|
|
76daa3 |
hw/virtio/vhost-backend.c | 130 +++++++++++++++++++++-----------------
|
|
|
76daa3 |
hw/virtio/vhost.c | 8 +--
|
|
|
76daa3 |
include/hw/virtio/vhost-backend.h | 23 ++++---
|
|
|
76daa3 |
3 files changed, 92 insertions(+), 69 deletions(-)
|
|
|
76daa3 |
|
|
|
76daa3 |
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
|
|
|
76daa3 |
index be927b8..4e31de1 100644
|
|
|
76daa3 |
--- a/hw/virtio/vhost-backend.c
|
|
|
76daa3 |
+++ b/hw/virtio/vhost-backend.c
|
|
|
76daa3 |
@@ -192,7 +192,6 @@ static void vhost_kernel_iotlb_read(void *opaque)
|
|
|
76daa3 |
ssize_t len;
|
|
|
76daa3 |
|
|
|
76daa3 |
while ((len = read((uintptr_t)dev->opaque, &msg, sizeof msg)) > 0) {
|
|
|
76daa3 |
- struct vhost_iotlb_msg *imsg = &msg.iotlb;
|
|
|
76daa3 |
if (len < sizeof msg) {
|
|
|
76daa3 |
error_report("Wrong vhost message len: %d", (int)len);
|
|
|
76daa3 |
break;
|
|
|
76daa3 |
@@ -201,70 +200,21 @@ static void vhost_kernel_iotlb_read(void *opaque)
|
|
|
76daa3 |
error_report("Unknown vhost iotlb message type");
|
|
|
76daa3 |
break;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
- switch (imsg->type) {
|
|
|
76daa3 |
- case VHOST_IOTLB_MISS:
|
|
|
76daa3 |
- vhost_device_iotlb_miss(dev, imsg->iova,
|
|
|
76daa3 |
- imsg->perm != VHOST_ACCESS_RO);
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- case VHOST_IOTLB_UPDATE:
|
|
|
76daa3 |
- case VHOST_IOTLB_INVALIDATE:
|
|
|
76daa3 |
- error_report("Unexpected IOTLB message type");
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- case VHOST_IOTLB_ACCESS_FAIL:
|
|
|
76daa3 |
- /* FIXME: report device iotlb error */
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- default:
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
-}
|
|
|
76daa3 |
|
|
|
76daa3 |
-static int vhost_kernel_update_device_iotlb(struct vhost_dev *dev,
|
|
|
76daa3 |
- uint64_t iova, uint64_t uaddr,
|
|
|
76daa3 |
- uint64_t len,
|
|
|
76daa3 |
- IOMMUAccessFlags perm)
|
|
|
76daa3 |
-{
|
|
|
76daa3 |
- struct vhost_msg msg;
|
|
|
76daa3 |
- msg.type = VHOST_IOTLB_MSG;
|
|
|
76daa3 |
- msg.iotlb.iova = iova;
|
|
|
76daa3 |
- msg.iotlb.uaddr = uaddr;
|
|
|
76daa3 |
- msg.iotlb.size = len;
|
|
|
76daa3 |
- msg.iotlb.type = VHOST_IOTLB_UPDATE;
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- switch (perm) {
|
|
|
76daa3 |
- case IOMMU_RO:
|
|
|
76daa3 |
- msg.iotlb.perm = VHOST_ACCESS_RO;
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- case IOMMU_WO:
|
|
|
76daa3 |
- msg.iotlb.perm = VHOST_ACCESS_WO;
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- case IOMMU_RW:
|
|
|
76daa3 |
- msg.iotlb.perm = VHOST_ACCESS_RW;
|
|
|
76daa3 |
- break;
|
|
|
76daa3 |
- default:
|
|
|
76daa3 |
- g_assert_not_reached();
|
|
|
76daa3 |
- }
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
|
|
|
76daa3 |
- error_report("Fail to update device iotlb");
|
|
|
76daa3 |
- return -EFAULT;
|
|
|
76daa3 |
+ vhost_backend_handle_iotlb_msg(dev, &msg.iotlb);
|
|
|
76daa3 |
}
|
|
|
76daa3 |
-
|
|
|
76daa3 |
- return 0;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
-static int vhost_kernel_invalidate_device_iotlb(struct vhost_dev *dev,
|
|
|
76daa3 |
- uint64_t iova, uint64_t len)
|
|
|
76daa3 |
+static int vhost_kernel_send_device_iotlb_msg(struct vhost_dev *dev,
|
|
|
76daa3 |
+ struct vhost_iotlb_msg *imsg)
|
|
|
76daa3 |
{
|
|
|
76daa3 |
struct vhost_msg msg;
|
|
|
76daa3 |
|
|
|
76daa3 |
msg.type = VHOST_IOTLB_MSG;
|
|
|
76daa3 |
- msg.iotlb.iova = iova;
|
|
|
76daa3 |
- msg.iotlb.size = len;
|
|
|
76daa3 |
- msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
|
|
|
76daa3 |
+ msg.iotlb = *imsg;
|
|
|
76daa3 |
|
|
|
76daa3 |
if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
|
|
|
76daa3 |
- error_report("Fail to invalidate device iotlb");
|
|
|
76daa3 |
+ error_report("Fail to update device iotlb");
|
|
|
76daa3 |
return -EFAULT;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
|
|
|
76daa3 |
@@ -311,8 +261,7 @@ static const VhostOps kernel_ops = {
|
|
|
76daa3 |
.vhost_vsock_set_running = vhost_kernel_vsock_set_running,
|
|
|
76daa3 |
#endif /* CONFIG_VHOST_VSOCK */
|
|
|
76daa3 |
.vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
|
|
|
76daa3 |
- .vhost_update_device_iotlb = vhost_kernel_update_device_iotlb,
|
|
|
76daa3 |
- .vhost_invalidate_device_iotlb = vhost_kernel_invalidate_device_iotlb,
|
|
|
76daa3 |
+ .vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg,
|
|
|
76daa3 |
};
|
|
|
76daa3 |
|
|
|
76daa3 |
int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
|
|
|
76daa3 |
@@ -333,3 +282,70 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
|
|
|
76daa3 |
|
|
|
76daa3 |
return r;
|
|
|
76daa3 |
}
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
|
|
|
76daa3 |
+ uint64_t iova, uint64_t uaddr,
|
|
|
76daa3 |
+ uint64_t len,
|
|
|
76daa3 |
+ IOMMUAccessFlags perm)
|
|
|
76daa3 |
+{
|
|
|
76daa3 |
+ struct vhost_iotlb_msg imsg;
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ imsg.iova = iova;
|
|
|
76daa3 |
+ imsg.uaddr = uaddr;
|
|
|
76daa3 |
+ imsg.size = len;
|
|
|
76daa3 |
+ imsg.type = VHOST_IOTLB_UPDATE;
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ switch (perm) {
|
|
|
76daa3 |
+ case IOMMU_RO:
|
|
|
76daa3 |
+ imsg.perm = VHOST_ACCESS_RO;
|
|
|
76daa3 |
+ break;
|
|
|
76daa3 |
+ case IOMMU_WO:
|
|
|
76daa3 |
+ imsg.perm = VHOST_ACCESS_WO;
|
|
|
76daa3 |
+ break;
|
|
|
76daa3 |
+ case IOMMU_RW:
|
|
|
76daa3 |
+ imsg.perm = VHOST_ACCESS_RW;
|
|
|
76daa3 |
+ break;
|
|
|
76daa3 |
+ default:
|
|
|
76daa3 |
+ return -EINVAL;
|
|
|
76daa3 |
+ }
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ return dev->vhost_ops->vhost_send_device_iotlb_msg(dev, &imsg);
|
|
|
76daa3 |
+}
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,
|
|
|
76daa3 |
+ uint64_t iova, uint64_t len)
|
|
|
76daa3 |
+{
|
|
|
76daa3 |
+ struct vhost_iotlb_msg imsg;
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ imsg.iova = iova;
|
|
|
76daa3 |
+ imsg.size = len;
|
|
|
76daa3 |
+ imsg.type = VHOST_IOTLB_INVALIDATE;
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ return dev->vhost_ops->vhost_send_device_iotlb_msg(dev, &imsg);
|
|
|
76daa3 |
+}
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
|
|
|
76daa3 |
+ struct vhost_iotlb_msg *imsg)
|
|
|
76daa3 |
+{
|
|
|
76daa3 |
+ int ret = 0;
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ switch (imsg->type) {
|
|
|
76daa3 |
+ case VHOST_IOTLB_MISS:
|
|
|
76daa3 |
+ ret = vhost_device_iotlb_miss(dev, imsg->iova,
|
|
|
76daa3 |
+ imsg->perm != VHOST_ACCESS_RO);
|
|
|
76daa3 |
+ break;
|
|
|
76daa3 |
+ case VHOST_IOTLB_ACCESS_FAIL:
|
|
|
76daa3 |
+ /* FIXME: report device iotlb error */
|
|
|
76daa3 |
+ error_report("Access failure IOTLB message type not supported");
|
|
|
76daa3 |
+ ret = -ENOTSUP;
|
|
|
76daa3 |
+ break;
|
|
|
76daa3 |
+ case VHOST_IOTLB_UPDATE:
|
|
|
76daa3 |
+ case VHOST_IOTLB_INVALIDATE:
|
|
|
76daa3 |
+ default:
|
|
|
76daa3 |
+ error_report("Unexpected IOTLB message type");
|
|
|
76daa3 |
+ ret = -EINVAL;
|
|
|
76daa3 |
+ break;
|
|
|
76daa3 |
+ }
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+ return ret;
|
|
|
76daa3 |
+}
|
|
|
76daa3 |
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
|
|
|
76daa3 |
index 369373a..748e331 100644
|
|
|
76daa3 |
--- a/hw/virtio/vhost.c
|
|
|
76daa3 |
+++ b/hw/virtio/vhost.c
|
|
|
76daa3 |
@@ -724,8 +724,8 @@ static void vhost_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
|
|
|
76daa3 |
struct vhost_dev *hdev = iommu->hdev;
|
|
|
76daa3 |
hwaddr iova = iotlb->iova + iommu->iommu_offset;
|
|
|
76daa3 |
|
|
|
76daa3 |
- if (hdev->vhost_ops->vhost_invalidate_device_iotlb(hdev, iova,
|
|
|
76daa3 |
- iotlb->addr_mask + 1)) {
|
|
|
76daa3 |
+ if (vhost_backend_invalidate_device_iotlb(hdev, iova,
|
|
|
76daa3 |
+ iotlb->addr_mask + 1)) {
|
|
|
76daa3 |
error_report("Fail to invalidate device iotlb");
|
|
|
76daa3 |
}
|
|
|
76daa3 |
}
|
|
|
76daa3 |
@@ -993,8 +993,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
|
|
|
76daa3 |
len = MIN(iotlb.addr_mask + 1, len);
|
|
|
76daa3 |
iova = iova & ~iotlb.addr_mask;
|
|
|
76daa3 |
|
|
|
76daa3 |
- ret = dev->vhost_ops->vhost_update_device_iotlb(dev, iova, uaddr,
|
|
|
76daa3 |
- len, iotlb.perm);
|
|
|
76daa3 |
+ ret = vhost_backend_update_device_iotlb(dev, iova, uaddr,
|
|
|
76daa3 |
+ len, iotlb.perm);
|
|
|
76daa3 |
if (ret) {
|
|
|
76daa3 |
error_report("Fail to update device iotlb");
|
|
|
76daa3 |
goto out;
|
|
|
76daa3 |
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
|
|
|
76daa3 |
index c3cf4a7..a7a5f22 100644
|
|
|
76daa3 |
--- a/include/hw/virtio/vhost-backend.h
|
|
|
76daa3 |
+++ b/include/hw/virtio/vhost-backend.h
|
|
|
76daa3 |
@@ -27,6 +27,7 @@ struct vhost_vring_file;
|
|
|
76daa3 |
struct vhost_vring_state;
|
|
|
76daa3 |
struct vhost_vring_addr;
|
|
|
76daa3 |
struct vhost_scsi_target;
|
|
|
76daa3 |
+struct vhost_iotlb_msg;
|
|
|
76daa3 |
|
|
|
76daa3 |
typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
|
|
|
76daa3 |
typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
|
|
|
76daa3 |
@@ -81,12 +82,8 @@ typedef int (*vhost_vsock_set_guest_cid_op)(struct vhost_dev *dev,
|
|
|
76daa3 |
typedef int (*vhost_vsock_set_running_op)(struct vhost_dev *dev, int start);
|
|
|
76daa3 |
typedef void (*vhost_set_iotlb_callback_op)(struct vhost_dev *dev,
|
|
|
76daa3 |
int enabled);
|
|
|
76daa3 |
-typedef int (*vhost_update_device_iotlb_op)(struct vhost_dev *dev,
|
|
|
76daa3 |
- uint64_t iova, uint64_t uaddr,
|
|
|
76daa3 |
- uint64_t len,
|
|
|
76daa3 |
- IOMMUAccessFlags perm);
|
|
|
76daa3 |
-typedef int (*vhost_invalidate_device_iotlb_op)(struct vhost_dev *dev,
|
|
|
76daa3 |
- uint64_t iova, uint64_t len);
|
|
|
76daa3 |
+typedef int (*vhost_send_device_iotlb_msg_op)(struct vhost_dev *dev,
|
|
|
76daa3 |
+ struct vhost_iotlb_msg *imsg);
|
|
|
76daa3 |
|
|
|
76daa3 |
typedef struct VhostOps {
|
|
|
76daa3 |
VhostBackendType backend_type;
|
|
|
76daa3 |
@@ -120,8 +117,7 @@ typedef struct VhostOps {
|
|
|
76daa3 |
vhost_vsock_set_guest_cid_op vhost_vsock_set_guest_cid;
|
|
|
76daa3 |
vhost_vsock_set_running_op vhost_vsock_set_running;
|
|
|
76daa3 |
vhost_set_iotlb_callback_op vhost_set_iotlb_callback;
|
|
|
76daa3 |
- vhost_update_device_iotlb_op vhost_update_device_iotlb;
|
|
|
76daa3 |
- vhost_invalidate_device_iotlb_op vhost_invalidate_device_iotlb;
|
|
|
76daa3 |
+ vhost_send_device_iotlb_msg_op vhost_send_device_iotlb_msg;
|
|
|
76daa3 |
} VhostOps;
|
|
|
76daa3 |
|
|
|
76daa3 |
extern const VhostOps user_ops;
|
|
|
76daa3 |
@@ -129,4 +125,15 @@ extern const VhostOps user_ops;
|
|
|
76daa3 |
int vhost_set_backend_type(struct vhost_dev *dev,
|
|
|
76daa3 |
VhostBackendType backend_type);
|
|
|
76daa3 |
|
|
|
76daa3 |
+int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
|
|
|
76daa3 |
+ uint64_t iova, uint64_t uaddr,
|
|
|
76daa3 |
+ uint64_t len,
|
|
|
76daa3 |
+ IOMMUAccessFlags perm);
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,
|
|
|
76daa3 |
+ uint64_t iova, uint64_t len);
|
|
|
76daa3 |
+
|
|
|
76daa3 |
+int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
|
|
|
76daa3 |
+ struct vhost_iotlb_msg *imsg);
|
|
|
76daa3 |
+
|
|
|
76daa3 |
#endif /* VHOST_BACKEND_H */
|
|
|
76daa3 |
--
|
|
|
76daa3 |
1.8.3.1
|
|
|
76daa3 |
|