@@ -2,9 +2,11 @@
/*
* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
*/
+#include <linux/guestmemfs.h>
#include <linux/interval_tree.h>
#include <linux/iommufd.h>
#include <linux/iommu.h>
+#include <linux/mm_types.h>
#include <uapi/linux/iommufd.h>
#include "io_pagetable.h"
@@ -217,6 +219,26 @@ int iommufd_ioas_map(struct iommufd_ucmd *ucmd)
if (IS_ERR(ioas))
return PTR_ERR(ioas);
+ pr_info("iommufd_ioas_map persistent id %lu\n",
+ ucmd->ictx->persistent_id);
+ if (ucmd->ictx->persistent_id) {
+#ifdef CONFIG_GUESTMEMFS_FS
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+
+ mmap_read_lock(mm);
+ vma = find_vma_intersection(current->mm,
+ cmd->user_va, cmd->user_va + cmd->length);
+ if (!vma || !is_guestmemfs_file(vma->vm_file)) {
+ mmap_read_unlock(mm);
+ return -EFAULT;
+ }
+ mmap_read_unlock(mm);
+#else
+ return -EFAULT;
+#endif /* CONFIG_GUESTMEMFS_FS */
+ }
+
if (!(cmd->flags & IOMMU_IOAS_MAP_FIXED_IOVA))
flags = IOPT_ALLOC_IOVA;
rc = iopt_map_user_pages(ucmd->ictx, &ioas->iopt, &iova,
@@ -104,3 +104,8 @@ const struct file_operations guestmemfs_file_fops = {
.owner = THIS_MODULE,
.mmap = mmap,
};
+
+bool is_guestmemfs_file(struct file const *file)
+{
+ return file && file->f_op == &guestmemfs_file_fops;
+}
@@ -3,14 +3,21 @@
#ifndef _LINUX_GUESTMEMFS_H
#define _LINUX_GUESTMEMFS_H
+#include <linux/fs.h>
+
/*
* Carves out chunks of memory from memblocks for guestmemfs.
* Must be called in early boot before memblocks are freed.
*/
# ifdef CONFIG_GUESTMEMFS_FS
void guestmemfs_reserve_mem(void);
+bool is_guestmemfs_file(struct file const *filp);
#else
void guestmemfs_reserve_mem(void) { }
+inline bool is_guestmemfs_file(struct file const *filp)
+{
+ return 0;
+}
#endif
#endif