--- v8
+++ v11
@@ -1,143 +1,89 @@
-The upcoming patch is going to support VA mapping/unmapping.
-So let's factor out the logic of PA mapping/unmapping firstly
-to make the code more readable.
+Add an opaque pointer for vhost IOTLB. And introduce
+vhost_iotlb_add_range_ctx() to accept it.
Suggested-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
- drivers/vhost/vdpa.c | 53 +++++++++++++++++++++++++++++++++-------------------
- 1 file changed, 34 insertions(+), 19 deletions(-)
+ drivers/vhost/iotlb.c | 20 ++++++++++++++++----
+ include/linux/vhost_iotlb.h | 3 +++
+ 2 files changed, 19 insertions(+), 4 deletions(-)
-diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
-index 1d5c5c6b6d5d..c5ec45b920f8 100644
---- a/drivers/vhost/vdpa.c
-+++ b/drivers/vhost/vdpa.c
-@@ -498,7 +498,7 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
- return r;
+diff --git a/drivers/vhost/iotlb.c b/drivers/vhost/iotlb.c
+index 0582079e4bcc..670d56c879e5 100644
+--- a/drivers/vhost/iotlb.c
++++ b/drivers/vhost/iotlb.c
+@@ -36,19 +36,21 @@ void vhost_iotlb_map_free(struct vhost_iotlb *iotlb,
+ EXPORT_SYMBOL_GPL(vhost_iotlb_map_free);
+
+ /**
+- * vhost_iotlb_add_range - add a new range to vhost IOTLB
++ * vhost_iotlb_add_range_ctx - add a new range to vhost IOTLB
+ * @iotlb: the IOTLB
+ * @start: start of the IOVA range
+ * @last: last of IOVA range
+ * @addr: the address that is mapped to @start
+ * @perm: access permission of this range
++ * @opaque: the opaque pointer for the new mapping
+ *
+ * Returns an error last is smaller than start or memory allocation
+ * fails
+ */
+-int vhost_iotlb_add_range(struct vhost_iotlb *iotlb,
+- u64 start, u64 last,
+- u64 addr, unsigned int perm)
++int vhost_iotlb_add_range_ctx(struct vhost_iotlb *iotlb,
++ u64 start, u64 last,
++ u64 addr, unsigned int perm,
++ void *opaque)
+ {
+ struct vhost_iotlb_map *map;
+
+@@ -71,6 +73,7 @@ int vhost_iotlb_add_range(struct vhost_iotlb *iotlb,
+ map->last = last;
+ map->addr = addr;
+ map->perm = perm;
++ map->opaque = opaque;
+
+ iotlb->nmaps++;
+ vhost_iotlb_itree_insert(map, &iotlb->root);
+@@ -80,6 +83,15 @@ int vhost_iotlb_add_range(struct vhost_iotlb *iotlb,
+
+ return 0;
}
++EXPORT_SYMBOL_GPL(vhost_iotlb_add_range_ctx);
++
++int vhost_iotlb_add_range(struct vhost_iotlb *iotlb,
++ u64 start, u64 last,
++ u64 addr, unsigned int perm)
++{
++ return vhost_iotlb_add_range_ctx(iotlb, start, last,
++ addr, perm, NULL);
++}
+ EXPORT_SYMBOL_GPL(vhost_iotlb_add_range);
--static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, u64 start, u64 last)
-+static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
- {
- struct vhost_dev *dev = &v->vdev;
- struct vhost_iotlb *iotlb = dev->iotlb;
-@@ -520,6 +520,11 @@ static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, u64 start, u64 last)
- }
- }
+ /**
+diff --git a/include/linux/vhost_iotlb.h b/include/linux/vhost_iotlb.h
+index 6b09b786a762..2d0e2f52f938 100644
+--- a/include/linux/vhost_iotlb.h
++++ b/include/linux/vhost_iotlb.h
+@@ -17,6 +17,7 @@ struct vhost_iotlb_map {
+ u32 perm;
+ u32 flags_padding;
+ u64 __subtree_last;
++ void *opaque;
+ };
-+static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, u64 start, u64 last)
-+{
-+ return vhost_vdpa_pa_unmap(v, start, last);
-+}
-+
- static void vhost_vdpa_iotlb_free(struct vhost_vdpa *v)
- {
- struct vhost_dev *dev = &v->vdev;
-@@ -600,37 +605,28 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v, u64 iova, u64 size)
- }
- }
+ #define VHOST_IOTLB_FLAG_RETIRE 0x1
+@@ -29,6 +30,8 @@ struct vhost_iotlb {
+ unsigned int flags;
+ };
--static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
-- struct vhost_iotlb_msg *msg)
-+static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
-+ u64 iova, u64 size, u64 uaddr, u32 perm)
- {
- struct vhost_dev *dev = &v->vdev;
-- struct vhost_iotlb *iotlb = dev->iotlb;
- struct page **page_list;
- unsigned long list_size = PAGE_SIZE / sizeof(struct page *);
- unsigned int gup_flags = FOLL_LONGTERM;
- unsigned long npages, cur_base, map_pfn, last_pfn = 0;
- unsigned long lock_limit, sz2pin, nchunks, i;
-- u64 iova = msg->iova;
-+ u64 start = iova;
- long pinned;
- int ret = 0;
-
-- if (msg->iova < v->range.first ||
-- msg->iova + msg->size - 1 > v->range.last)
-- return -EINVAL;
--
-- if (vhost_iotlb_itree_first(iotlb, msg->iova,
-- msg->iova + msg->size - 1))
-- return -EEXIST;
--
- /* Limit the use of memory for bookkeeping */
- page_list = (struct page **) __get_free_page(GFP_KERNEL);
- if (!page_list)
- return -ENOMEM;
-
-- if (msg->perm & VHOST_ACCESS_WO)
-+ if (perm & VHOST_ACCESS_WO)
- gup_flags |= FOLL_WRITE;
-
-- npages = PAGE_ALIGN(msg->size + (iova & ~PAGE_MASK)) >> PAGE_SHIFT;
-+ npages = PAGE_ALIGN(size + (iova & ~PAGE_MASK)) >> PAGE_SHIFT;
- if (!npages) {
- ret = -EINVAL;
- goto free;
-@@ -644,7 +640,7 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
- goto unlock;
- }
-
-- cur_base = msg->uaddr & PAGE_MASK;
-+ cur_base = uaddr & PAGE_MASK;
- iova &= PAGE_MASK;
- nchunks = 0;
-
-@@ -675,7 +671,7 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
- csize = (last_pfn - map_pfn + 1) << PAGE_SHIFT;
- ret = vhost_vdpa_map(v, iova, csize,
- map_pfn << PAGE_SHIFT,
-- msg->perm);
-+ perm);
- if (ret) {
- /*
- * Unpin the pages that are left unmapped
-@@ -704,7 +700,7 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
-
- /* Pin the rest chunk */
- ret = vhost_vdpa_map(v, iova, (last_pfn - map_pfn + 1) << PAGE_SHIFT,
-- map_pfn << PAGE_SHIFT, msg->perm);
-+ map_pfn << PAGE_SHIFT, perm);
- out:
- if (ret) {
- if (nchunks) {
-@@ -723,13 +719,32 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
- for (pfn = map_pfn; pfn <= last_pfn; pfn++)
- unpin_user_page(pfn_to_page(pfn));
- }
-- vhost_vdpa_unmap(v, msg->iova, msg->size);
-+ vhost_vdpa_unmap(v, start, size);
- }
- unlock:
- mmap_read_unlock(dev->mm);
- free:
- free_page((unsigned long)page_list);
- return ret;
-+
-+}
-+
-+static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
-+ struct vhost_iotlb_msg *msg)
-+{
-+ struct vhost_dev *dev = &v->vdev;
-+ struct vhost_iotlb *iotlb = dev->iotlb;
-+
-+ if (msg->iova < v->range.first ||
-+ msg->iova + msg->size - 1 > v->range.last)
-+ return -EINVAL;
-+
-+ if (vhost_iotlb_itree_first(iotlb, msg->iova,
-+ msg->iova + msg->size - 1))
-+ return -EEXIST;
-+
-+ return vhost_vdpa_pa_map(v, msg->iova, msg->size, msg->uaddr,
-+ msg->perm);
- }
-
- static int vhost_vdpa_process_iotlb_msg(struct vhost_dev *dev,
++int vhost_iotlb_add_range_ctx(struct vhost_iotlb *iotlb, u64 start, u64 last,
++ u64 addr, unsigned int perm, void *opaque);
+ int vhost_iotlb_add_range(struct vhost_iotlb *iotlb, u64 start, u64 last,
+ u64 addr, unsigned int perm);
+ void vhost_iotlb_del_range(struct vhost_iotlb *iotlb, u64 start, u64 last);
--
2.11.0