@@ -3,6 +3,8 @@
* Copyright © 2025 Intel Corporation
*/
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
#include <linux/slab.h>
#include <drm/drm_pagemap.h>
@@ -123,3 +125,79 @@ int drm_pagemap_acquire_owner(struct drm_pagemap_peer *peer,
return 0;
}
EXPORT_SYMBOL(drm_pagemap_acquire_owner);
+
+static int drm_pagemap_file_release(struct inode *inode, struct file *file)
+{
+ drm_pagemap_put(file->private_data);
+
+ return 0;
+}
+
+static const struct file_operations drm_pagemap_fops = {
+ .owner = THIS_MODULE,
+ .release = drm_pagemap_file_release,
+};
+
+/**
+ * drm_pagemap_fd() - Obtain an fd that can be used to reference a drm_pagemap.
+ * @dpagemap: The drm_pagemap for which to obtain an fd.
+ *
+ * Obtain an fd that can be used to reference a drm_pagemap using the function
+ * drm_pagemap_from_fd(). The fd has a reference count on the drm_pagemap, and
+ * on this module. When the fd is closed and the underlying struct file is
+ * released, the references are dropped.
+ */
+int drm_pagemap_fd(struct drm_pagemap *dpagemap)
+{
+ struct file *file;
+ int fd;
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ file = anon_inode_getfile("drm_pagemap_file",
+ &drm_pagemap_fops,
+ dpagemap, 0);
+ if (IS_ERR(file)) {
+ put_unused_fd(fd);
+ return PTR_ERR(file);
+ }
+
+ drm_pagemap_get(dpagemap);
+ fd_install(fd, file);
+
+ return fd;
+}
+EXPORT_SYMBOL(drm_pagemap_fd);
+
+/**
+ * drm_pagemap_from_fd() - Get a drm_pagemap from a file descriptor
+ * @fd: The file descriptor
+ *
+ * Return a reference-counted pointer to a drm_pagemap from
+ * a file-descriptor, typically obtained from drm_pagemap_fd().
+ * The pagemap pointer should be put using drm_pagemap_put() when
+ * no longer in use.
+ *
+ * Return: A valid drm_pagemap pointer on success. Error pointer on failure.
+ */
+struct drm_pagemap *drm_pagemap_from_fd(unsigned int fd)
+{
+ struct file *file = fget(fd);
+ struct drm_pagemap *dpagemap;
+
+ if (!file)
+ return ERR_PTR(-ENOENT);
+
+ if (file->f_op != &drm_pagemap_fops) {
+ fput(file);
+ return ERR_PTR(-ENOENT);
+ }
+
+ dpagemap = drm_pagemap_get(file->private_data);
+ fput(file);
+
+ return dpagemap;
+}
+EXPORT_SYMBOL(drm_pagemap_from_fd);
@@ -52,4 +52,8 @@ int drm_pagemap_acquire_owner(struct drm_pagemap_peer *peer,
struct drm_pagemap_owner_list *owner_list,
bool (*has_interconnect)(struct drm_pagemap_peer *peer1,
struct drm_pagemap_peer *peer2));
+
+int drm_pagemap_fd(struct drm_pagemap *dpagemap);
+
+struct drm_pagemap *drm_pagemap_from_fd(unsigned int fd);
#endif
Falicitate implementing uapi representing a struct drm_pagemap as a file descriptor. A drm_pagemap file descriptor holds, while open, a reference to the struct drm_pagemap and to the drm_pagemap_helper module. Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> --- drivers/gpu/drm/drm_pagemap_util.c | 78 ++++++++++++++++++++++++++++++ include/drm/drm_pagemap_util.h | 4 ++ 2 files changed, 82 insertions(+)