Skip to content

Commit 020e571

Browse files
mcoquelinmstsirkin
authored andcommitted
vhost: rework IOTLB messaging
This patch reworks IOTLB messaging to prepare for vhost-user device IOTLB support. IOTLB messages handling is extracted from vhost-kernel backend, so that only the messages transport remains backend specifics. Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent fc58bd0 commit 020e571

File tree

3 files changed

+92
-69
lines changed

3 files changed

+92
-69
lines changed

hw/virtio/vhost-backend.c

+73-57
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ static void vhost_kernel_iotlb_read(void *opaque)
192192
ssize_t len;
193193

194194
while ((len = read((uintptr_t)dev->opaque, &msg, sizeof msg)) > 0) {
195-
struct vhost_iotlb_msg *imsg = &msg.iotlb;
196195
if (len < sizeof msg) {
197196
error_report("Wrong vhost message len: %d", (int)len);
198197
break;
@@ -201,70 +200,21 @@ static void vhost_kernel_iotlb_read(void *opaque)
201200
error_report("Unknown vhost iotlb message type");
202201
break;
203202
}
204-
switch (imsg->type) {
205-
case VHOST_IOTLB_MISS:
206-
vhost_device_iotlb_miss(dev, imsg->iova,
207-
imsg->perm != VHOST_ACCESS_RO);
208-
break;
209-
case VHOST_IOTLB_UPDATE:
210-
case VHOST_IOTLB_INVALIDATE:
211-
error_report("Unexpected IOTLB message type");
212-
break;
213-
case VHOST_IOTLB_ACCESS_FAIL:
214-
/* FIXME: report device iotlb error */
215-
break;
216-
default:
217-
break;
218-
}
219-
}
220-
}
221203

222-
static int vhost_kernel_update_device_iotlb(struct vhost_dev *dev,
223-
uint64_t iova, uint64_t uaddr,
224-
uint64_t len,
225-
IOMMUAccessFlags perm)
226-
{
227-
struct vhost_msg msg;
228-
msg.type = VHOST_IOTLB_MSG;
229-
msg.iotlb.iova = iova;
230-
msg.iotlb.uaddr = uaddr;
231-
msg.iotlb.size = len;
232-
msg.iotlb.type = VHOST_IOTLB_UPDATE;
233-
234-
switch (perm) {
235-
case IOMMU_RO:
236-
msg.iotlb.perm = VHOST_ACCESS_RO;
237-
break;
238-
case IOMMU_WO:
239-
msg.iotlb.perm = VHOST_ACCESS_WO;
240-
break;
241-
case IOMMU_RW:
242-
msg.iotlb.perm = VHOST_ACCESS_RW;
243-
break;
244-
default:
245-
g_assert_not_reached();
246-
}
247-
248-
if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
249-
error_report("Fail to update device iotlb");
250-
return -EFAULT;
204+
vhost_backend_handle_iotlb_msg(dev, &msg.iotlb);
251205
}
252-
253-
return 0;
254206
}
255207

256-
static int vhost_kernel_invalidate_device_iotlb(struct vhost_dev *dev,
257-
uint64_t iova, uint64_t len)
208+
static int vhost_kernel_send_device_iotlb_msg(struct vhost_dev *dev,
209+
struct vhost_iotlb_msg *imsg)
258210
{
259211
struct vhost_msg msg;
260212

261213
msg.type = VHOST_IOTLB_MSG;
262-
msg.iotlb.iova = iova;
263-
msg.iotlb.size = len;
264-
msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
214+
msg.iotlb = *imsg;
265215

266216
if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
267-
error_report("Fail to invalidate device iotlb");
217+
error_report("Fail to update device iotlb");
268218
return -EFAULT;
269219
}
270220

@@ -311,8 +261,7 @@ static const VhostOps kernel_ops = {
311261
.vhost_vsock_set_running = vhost_kernel_vsock_set_running,
312262
#endif /* CONFIG_VHOST_VSOCK */
313263
.vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
314-
.vhost_update_device_iotlb = vhost_kernel_update_device_iotlb,
315-
.vhost_invalidate_device_iotlb = vhost_kernel_invalidate_device_iotlb,
264+
.vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg,
316265
};
317266

318267
int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
@@ -333,3 +282,70 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
333282

334283
return r;
335284
}
285+
286+
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
287+
uint64_t iova, uint64_t uaddr,
288+
uint64_t len,
289+
IOMMUAccessFlags perm)
290+
{
291+
struct vhost_iotlb_msg imsg;
292+
293+
imsg.iova = iova;
294+
imsg.uaddr = uaddr;
295+
imsg.size = len;
296+
imsg.type = VHOST_IOTLB_UPDATE;
297+
298+
switch (perm) {
299+
case IOMMU_RO:
300+
imsg.perm = VHOST_ACCESS_RO;
301+
break;
302+
case IOMMU_WO:
303+
imsg.perm = VHOST_ACCESS_WO;
304+
break;
305+
case IOMMU_RW:
306+
imsg.perm = VHOST_ACCESS_RW;
307+
break;
308+
default:
309+
return -EINVAL;
310+
}
311+
312+
return dev->vhost_ops->vhost_send_device_iotlb_msg(dev, &imsg);
313+
}
314+
315+
int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,
316+
uint64_t iova, uint64_t len)
317+
{
318+
struct vhost_iotlb_msg imsg;
319+
320+
imsg.iova = iova;
321+
imsg.size = len;
322+
imsg.type = VHOST_IOTLB_INVALIDATE;
323+
324+
return dev->vhost_ops->vhost_send_device_iotlb_msg(dev, &imsg);
325+
}
326+
327+
int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
328+
struct vhost_iotlb_msg *imsg)
329+
{
330+
int ret = 0;
331+
332+
switch (imsg->type) {
333+
case VHOST_IOTLB_MISS:
334+
ret = vhost_device_iotlb_miss(dev, imsg->iova,
335+
imsg->perm != VHOST_ACCESS_RO);
336+
break;
337+
case VHOST_IOTLB_ACCESS_FAIL:
338+
/* FIXME: report device iotlb error */
339+
error_report("Access failure IOTLB message type not supported");
340+
ret = -ENOTSUP;
341+
break;
342+
case VHOST_IOTLB_UPDATE:
343+
case VHOST_IOTLB_INVALIDATE:
344+
default:
345+
error_report("Unexpected IOTLB message type");
346+
ret = -EINVAL;
347+
break;
348+
}
349+
350+
return ret;
351+
}

hw/virtio/vhost.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -724,8 +724,8 @@ static void vhost_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
724724
struct vhost_dev *hdev = iommu->hdev;
725725
hwaddr iova = iotlb->iova + iommu->iommu_offset;
726726

727-
if (hdev->vhost_ops->vhost_invalidate_device_iotlb(hdev, iova,
728-
iotlb->addr_mask + 1)) {
727+
if (vhost_backend_invalidate_device_iotlb(hdev, iova,
728+
iotlb->addr_mask + 1)) {
729729
error_report("Fail to invalidate device iotlb");
730730
}
731731
}
@@ -993,8 +993,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
993993
len = MIN(iotlb.addr_mask + 1, len);
994994
iova = iova & ~iotlb.addr_mask;
995995

996-
ret = dev->vhost_ops->vhost_update_device_iotlb(dev, iova, uaddr,
997-
len, iotlb.perm);
996+
ret = vhost_backend_update_device_iotlb(dev, iova, uaddr,
997+
len, iotlb.perm);
998998
if (ret) {
999999
error_report("Fail to update device iotlb");
10001000
goto out;

include/hw/virtio/vhost-backend.h

+15-8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct vhost_vring_file;
2727
struct vhost_vring_state;
2828
struct vhost_vring_addr;
2929
struct vhost_scsi_target;
30+
struct vhost_iotlb_msg;
3031

3132
typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
3233
typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
@@ -81,12 +82,8 @@ typedef int (*vhost_vsock_set_guest_cid_op)(struct vhost_dev *dev,
8182
typedef int (*vhost_vsock_set_running_op)(struct vhost_dev *dev, int start);
8283
typedef void (*vhost_set_iotlb_callback_op)(struct vhost_dev *dev,
8384
int enabled);
84-
typedef int (*vhost_update_device_iotlb_op)(struct vhost_dev *dev,
85-
uint64_t iova, uint64_t uaddr,
86-
uint64_t len,
87-
IOMMUAccessFlags perm);
88-
typedef int (*vhost_invalidate_device_iotlb_op)(struct vhost_dev *dev,
89-
uint64_t iova, uint64_t len);
85+
typedef int (*vhost_send_device_iotlb_msg_op)(struct vhost_dev *dev,
86+
struct vhost_iotlb_msg *imsg);
9087

9188
typedef struct VhostOps {
9289
VhostBackendType backend_type;
@@ -120,13 +117,23 @@ typedef struct VhostOps {
120117
vhost_vsock_set_guest_cid_op vhost_vsock_set_guest_cid;
121118
vhost_vsock_set_running_op vhost_vsock_set_running;
122119
vhost_set_iotlb_callback_op vhost_set_iotlb_callback;
123-
vhost_update_device_iotlb_op vhost_update_device_iotlb;
124-
vhost_invalidate_device_iotlb_op vhost_invalidate_device_iotlb;
120+
vhost_send_device_iotlb_msg_op vhost_send_device_iotlb_msg;
125121
} VhostOps;
126122

127123
extern const VhostOps user_ops;
128124

129125
int vhost_set_backend_type(struct vhost_dev *dev,
130126
VhostBackendType backend_type);
131127

128+
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
129+
uint64_t iova, uint64_t uaddr,
130+
uint64_t len,
131+
IOMMUAccessFlags perm);
132+
133+
int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,
134+
uint64_t iova, uint64_t len);
135+
136+
int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
137+
struct vhost_iotlb_msg *imsg);
138+
132139
#endif /* VHOST_BACKEND_H */

0 commit comments

Comments
 (0)