iommufd: Have iopt_map_file_pages convert the fd to a file

Since dmabuf only has APIs that work on an int fd and not a struct file *,
pass the fd deeper into the call chain so we can use the dmabuf APIs as
is.

Link: https://patch.msgid.link/r/7-v2-b2c110338e3f+5c2-iommufd_dmabuf_jgg@nvidia.com
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Shuai Xue <xueshuai@linux.alibaba.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Jason Gunthorpe 2025-11-21 11:51:04 -04:00
parent 74014a4b55
commit 217725f0b2
3 changed files with 13 additions and 12 deletions

View File

@ -10,6 +10,7 @@
*/ */
#include <linux/err.h> #include <linux/err.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/file.h>
#include <linux/iommu.h> #include <linux/iommu.h>
#include <linux/iommufd.h> #include <linux/iommufd.h>
#include <linux/lockdep.h> #include <linux/lockdep.h>
@ -471,21 +472,27 @@ int iopt_map_user_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt,
* @iopt: io_pagetable to act on * @iopt: io_pagetable to act on
* @iova: If IOPT_ALLOC_IOVA is set this is unused on input and contains * @iova: If IOPT_ALLOC_IOVA is set this is unused on input and contains
* the chosen iova on output. Otherwise is the iova to map to on input * the chosen iova on output. Otherwise is the iova to map to on input
* @file: file to map * @fd: fdno of a file to map
* @start: map file starting at this byte offset * @start: map file starting at this byte offset
* @length: Number of bytes to map * @length: Number of bytes to map
* @iommu_prot: Combination of IOMMU_READ/WRITE/etc bits for the mapping * @iommu_prot: Combination of IOMMU_READ/WRITE/etc bits for the mapping
* @flags: IOPT_ALLOC_IOVA or zero * @flags: IOPT_ALLOC_IOVA or zero
*/ */
int iopt_map_file_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt, int iopt_map_file_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt,
unsigned long *iova, struct file *file, unsigned long *iova, int fd, unsigned long start,
unsigned long start, unsigned long length, unsigned long length, int iommu_prot,
int iommu_prot, unsigned int flags) unsigned int flags)
{ {
struct iopt_pages *pages; struct iopt_pages *pages;
struct file *file;
file = fget(fd);
if (!file)
return -EBADF;
pages = iopt_alloc_file_pages(file, start, length, pages = iopt_alloc_file_pages(file, start, length,
iommu_prot & IOMMU_WRITE); iommu_prot & IOMMU_WRITE);
fput(file);
if (IS_ERR(pages)) if (IS_ERR(pages))
return PTR_ERR(pages); return PTR_ERR(pages);
return iopt_map_common(ictx, iopt, pages, iova, length, return iopt_map_common(ictx, iopt, pages, iova, length,

View File

@ -207,7 +207,6 @@ int iommufd_ioas_map_file(struct iommufd_ucmd *ucmd)
unsigned long iova = cmd->iova; unsigned long iova = cmd->iova;
struct iommufd_ioas *ioas; struct iommufd_ioas *ioas;
unsigned int flags = 0; unsigned int flags = 0;
struct file *file;
int rc; int rc;
if (cmd->flags & if (cmd->flags &
@ -229,11 +228,7 @@ int iommufd_ioas_map_file(struct iommufd_ucmd *ucmd)
if (!(cmd->flags & IOMMU_IOAS_MAP_FIXED_IOVA)) if (!(cmd->flags & IOMMU_IOAS_MAP_FIXED_IOVA))
flags = IOPT_ALLOC_IOVA; flags = IOPT_ALLOC_IOVA;
file = fget(cmd->fd); rc = iopt_map_file_pages(ucmd->ictx, &ioas->iopt, &iova, cmd->fd,
if (!file)
return -EBADF;
rc = iopt_map_file_pages(ucmd->ictx, &ioas->iopt, &iova, file,
cmd->start, cmd->length, cmd->start, cmd->length,
conv_iommu_prot(cmd->flags), flags); conv_iommu_prot(cmd->flags), flags);
if (rc) if (rc)
@ -243,7 +238,6 @@ int iommufd_ioas_map_file(struct iommufd_ucmd *ucmd)
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd)); rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
out_put: out_put:
iommufd_put_object(ucmd->ictx, &ioas->obj); iommufd_put_object(ucmd->ictx, &ioas->obj);
fput(file);
return rc; return rc;
} }

View File

@ -108,7 +108,7 @@ int iopt_map_user_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt,
unsigned long length, int iommu_prot, unsigned long length, int iommu_prot,
unsigned int flags); unsigned int flags);
int iopt_map_file_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt, int iopt_map_file_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt,
unsigned long *iova, struct file *file, unsigned long *iova, int fd,
unsigned long start, unsigned long length, unsigned long start, unsigned long length,
int iommu_prot, unsigned int flags); int iommu_prot, unsigned int flags);
int iopt_map_pages(struct io_pagetable *iopt, struct list_head *pages_list, int iopt_map_pages(struct io_pagetable *iopt, struct list_head *pages_list,