@@ -195,6 +195,7 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
DRM_IOCTL_DEF_DRV(XE_WAIT_USER_FENCE, xe_wait_user_fence_ioctl,
DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(XE_DEVMEM_OPEN, xe_devmem_open_ioctl, DRM_RENDER_ALLOW),
};
static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -6,6 +6,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_managed.h>
#include <drm/drm_pagemap.h>
+#include <drm/drm_pagemap_util.h>
#include "xe_bo.h"
#include "xe_gt_tlb_invalidation.h"
@@ -1272,6 +1273,55 @@ xe_pagemap_find_or_create(struct xe_device *xe, struct xe_pagemap_cache *cache,
return xpagemap;
}
+/**
+ * xe_devmem_open_ioctl() - IOCTL callback implementing the devmem_open functionality
+ * @dev: The struct drm_device.
+ * @data: The ioctl argurment.
+ * @file: The drm file.
+ *
+ * For the given xe device and memory region, open a pagemap and return a
+ * file descriptor that can be used to reference the pagemap. First,
+ * attempt to look up an already used or cached pagemap. If that fails,
+ * create a new one.
+ *
+ * Return: %0 on success. Negative error code on failure.
+ */
+int xe_devmem_open_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct xe_device *xe = to_xe_device(dev);
+ struct drm_xe_devmem_open *args = data;
+ struct drm_pagemap *dpagemap;
+ struct xe_pagemap *xpagemap;
+ struct xe_vram_region *vr;
+ u32 tile_id;
+ int fd;
+
+ if (XE_IOCTL_DBG(xe, args->extensions) ||
+ XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))
+ return -EINVAL;
+
+ tile_id = (u32)args->region_instance - 1;
+ if (XE_IOCTL_DBG(xe, tile_id >= xe->info.tile_count))
+ return -ENOENT;
+
+ if (XE_IOCTL_DBG(xe, !((BIT(tile_id) << 1) & xe->info.mem_region_mask)))
+ return -ENOENT;
+
+ vr = &xe->tiles[tile_id].mem.vram;
+ xpagemap = xe_pagemap_find_or_create(xe, &vr->pagemap_cache, vr);
+ if (XE_IOCTL_DBG(xe, IS_ERR(xpagemap)))
+ return -ENOENT;
+
+ dpagemap = &xpagemap->dpagemap;
+ fd = drm_pagemap_fd(dpagemap);
+ xe_pagemap_put(xpagemap);
+ if (XE_IOCTL_DBG(xe, fd < 0))
+ return fd;
+
+ args->pagemap_fd = fd;
+
+ return 0;
+}
#endif
/**
@@ -149,6 +149,8 @@ static inline void xe_svm_vma_assign_dpagemap(struct xe_svm_vma *svma,
#else
#include <linux/interval_tree.h>
+struct drm_device;
+struct drm_file;
struct drm_pagemap_device_addr;
struct xe_bo;
struct xe_device;
@@ -243,6 +245,8 @@ int xe_pagemap_cache_init(struct drm_device *drm, struct xe_pagemap_cache *cache
void xe_pagemaps_remove(struct xe_device *xe);
+int xe_devmem_open_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+
#else
#define xe_pagemap_cache_init(...) 0
@@ -251,6 +255,10 @@ static inline void xe_pagemaps_remove(struct xe_device *xe)
{
}
+static inline int xe_devmem_open_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ return -EOPNOTSUPP;
+}
#endif
#endif
@@ -102,6 +102,7 @@ extern "C" {
#define DRM_XE_EXEC 0x09
#define DRM_XE_WAIT_USER_FENCE 0x0a
#define DRM_XE_OBSERVATION 0x0b
+#define DRM_XE_DEVMEM_OPEN 0x0c
/* Must be kept compact -- no holes */
@@ -117,6 +118,7 @@ extern "C" {
#define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec)
#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
+#define DRM_IOCTL_XE_DEVMEM_OPEN DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVMEM_OPEN, struct drm_xe_devmem_open)
/**
* DOC: Xe IOCTL Extensions
@@ -1961,6 +1963,33 @@ struct drm_xe_query_eu_stall {
__u64 sampling_rates[];
};
+/**
+ * struct drm_xe_devmem_open - Get a file-descriptor representing
+ * device memory on a specific tile on a specific device.
+ */
+struct drm_xe_devmem_open {
+ /** @extensions: Pointer to the first extension struct, if any */
+ __u64 extensions;
+
+ /** @region_instance: The memory region describing the device memory to open. */
+ __u16 region_instance;
+
+ /** @pad: MBZ */
+ __u16 pad;
+
+ /**
+ * @pagemap_fd: On successful return, a file descriptor
+ * representing the device memory to open.
+ * Should be close()d when no longer in use. The file
+ * descriptor can be used to represent the device memory in
+ * gpu madvise ioctl and the devmem_allow ioctl.
+ */
+ __u32 pagemap_fd;
+
+ /** @reserved: Reserved */
+ __u64 reserved[2];
+};
+
#if defined(__cplusplus)
}
#endif
Add an IOCTL to get a file descriptor referencing a memory region for SVM. Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> --- drivers/gpu/drm/xe/xe_device.c | 1 + drivers/gpu/drm/xe/xe_svm.c | 50 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_svm.h | 8 ++++++ include/uapi/drm/xe_drm.h | 29 ++++++++++++++++++++ 4 files changed, 88 insertions(+)