Messages in this thread Patch in this message | | | From | Cindy Lu <> | Subject | [PATCH v4 4/5] vduse: Add file operation for mmap | Date | Wed, 7 Feb 2024 13:43:31 +0800 |
| |
Add the operation for mmap, This function will be used by the user space application to map the pages to the user space.
Signed-off-by: Cindy Lu <lulu@redhat.com> --- drivers/vdpa/vdpa_user/vduse_dev.c | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index 2da659d5f4a8..083fe0047677 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1465,6 +1465,61 @@ static struct vduse_dev *vduse_dev_get_from_minor(int minor) return dev; } +static vm_fault_t vduse_vm_fault(struct vm_fault *vmf) +{ + struct vduse_dev *dev = vmf->vma->vm_file->private_data; + struct vm_area_struct *vma = vmf->vma; + u16 index = vma->vm_pgoff; + struct vduse_virtqueue *vq; + unsigned long vaddr; + + /* index 1+vq_number page reserved for virtqueue state*/ + vq = dev->vqs[index]; + vaddr = vq->vdpa_reconnect_vaddr; + if (remap_pfn_range(vma, vmf->address & PAGE_MASK, + PFN_DOWN(virt_to_phys((void *)vaddr)), PAGE_SIZE, + vma->vm_page_prot)) + return VM_FAULT_SIGBUS; + return VM_FAULT_NOPAGE; +} + +static const struct vm_operations_struct vduse_vm_ops = { + .fault = vduse_vm_fault, +}; + +static int vduse_dev_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct vduse_dev *dev = file->private_data; + unsigned long vaddr = 0; + unsigned long index = vma->vm_pgoff; + struct vduse_virtqueue *vq; + + if (vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EINVAL; + if ((vma->vm_flags & VM_SHARED) == 0) + return -EINVAL; + + if (index > dev->vq_num) + return -EINVAL; + + vq = dev->vqs[index]; + vaddr = vq->vdpa_reconnect_vaddr; + if (vaddr == 0) + return -EOPNOTSUPP; + + if (virt_to_phys((void *)vaddr) & (PAGE_SIZE - 1)) + return -EINVAL; + + /* Check if the Userspace App mapped the correct size */ + if (vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EOPNOTSUPP; + + vm_flags_set(vma, VM_DONTEXPAND); + vma->vm_ops = &vduse_vm_ops; + + return 0; +} + static int vduse_dev_open(struct inode *inode, struct file *file) { int ret; @@ -1497,6 +1552,8 @@ static const struct file_operations vduse_dev_fops = { .unlocked_ioctl = vduse_dev_ioctl, .compat_ioctl = compat_ptr_ioctl, .llseek = noop_llseek, + .mmap = vduse_dev_mmap, + }; static ssize_t irq_cb_affinity_show(struct vduse_virtqueue *vq, char *buf) -- 2.43.0
| |