]> git.ipfire.org Git - people/ms/linux.git/blobdiff - drivers/vhost/vhost.c
vhost: support ASID in IOTLB API
[people/ms/linux.git] / drivers / vhost / vhost.c
index d02173fb290c39146634e0d08e14ea123ae174f5..d1e58f976f6ef08dab950eab6dbda0800de5415e 100644 (file)
@@ -468,7 +468,7 @@ void vhost_dev_init(struct vhost_dev *dev,
                    struct vhost_virtqueue **vqs, int nvqs,
                    int iov_limit, int weight, int byte_weight,
                    bool use_worker,
-                   int (*msg_handler)(struct vhost_dev *dev,
+                   int (*msg_handler)(struct vhost_dev *dev, u32 asid,
                                       struct vhost_iotlb_msg *msg))
 {
        struct vhost_virtqueue *vq;
@@ -1090,11 +1090,14 @@ static bool umem_access_ok(u64 uaddr, u64 size, int access)
        return true;
 }
 
-static int vhost_process_iotlb_msg(struct vhost_dev *dev,
+static int vhost_process_iotlb_msg(struct vhost_dev *dev, u32 asid,
                                   struct vhost_iotlb_msg *msg)
 {
        int ret = 0;
 
+       if (asid != 0)
+               return -EINVAL;
+
        mutex_lock(&dev->mutex);
        vhost_dev_lock_vqs(dev);
        switch (msg->type) {
@@ -1141,6 +1144,7 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
        struct vhost_iotlb_msg msg;
        size_t offset;
        int type, ret;
+       u32 asid = 0;
 
        ret = copy_from_iter(&type, sizeof(type), from);
        if (ret != sizeof(type)) {
@@ -1156,7 +1160,16 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
                offset = offsetof(struct vhost_msg, iotlb) - sizeof(int);
                break;
        case VHOST_IOTLB_MSG_V2:
-               offset = sizeof(__u32);
+               if (vhost_backend_has_feature(dev->vqs[0],
+                                             VHOST_BACKEND_F_IOTLB_ASID)) {
+                       ret = copy_from_iter(&asid, sizeof(asid), from);
+                       if (ret != sizeof(asid)) {
+                               ret = -EINVAL;
+                               goto done;
+                       }
+                       offset = sizeof(__u16);
+               } else
+                       offset = sizeof(__u32);
                break;
        default:
                ret = -EINVAL;
@@ -1178,9 +1191,9 @@ ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
        }
 
        if (dev->msg_handler)
-               ret = dev->msg_handler(dev, &msg);
+               ret = dev->msg_handler(dev, asid, &msg);
        else
-               ret = vhost_process_iotlb_msg(dev, &msg);
+               ret = vhost_process_iotlb_msg(dev, asid, &msg);
        if (ret) {
                ret = -EFAULT;
                goto done;