Skip to content

Instantly share code, notes, and snippets.

@kode54
Last active May 30, 2023 15:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kode54/fc41a6bf5ebba00e3ab52e70b93dfd6a to your computer and use it in GitHub Desktop.
Save kode54/fc41a6bf5ebba00e3ab52e70b93dfd6a to your computer and use it in GitHub Desktop.
Xe KMD uAPI adjustments

These are minimal adjustments to the current uAPI, as inspired by Maarten Lankhorst and his process of running the headers through pahole. But instead, I adjusted them manually, making minimal changes so that the 64-bit uarch would result in the same alignment, so existing userspace software with the previous header will still work. The only difference is that 32-bit userspace software needs the new header, to continue working with the kernel.

I've split it into two patches, like was suggested to @mlankhorst, one with the uAPI header, and one with the validation code.

Edited 2023-05-12 20:42 PDT: Updated against latest rebase.

diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index b0b80aae3ee8..d5fc54b5be74 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -91,7 +91,7 @@ struct xe_user_extension {
*/
__u32 name;
/**
- * @flags: MBZ
+ * @pad: MBZ
*
* All undefined bits must be zero.
*/
@@ -291,6 +291,9 @@ struct drm_xe_gem_create {
*/
__u32 handle;
+ /** @pad: MBZ */
+ __u32 pad;
+
/** @reserved: Reserved */
__u64 reserved[2];
};
@@ -335,6 +338,9 @@ struct drm_xe_ext_vm_set_property {
#define XE_VM_PROPERTY_BIND_OP_ERROR_CAPTURE_ADDRESS 0
__u32 property;
+ /** @pad: MBZ */
+ __u32 pad;
+
/** @value: property value */
__u64 value;
@@ -379,6 +385,9 @@ struct drm_xe_vm_bind_op {
*/
__u32 obj;
+ /** @pad: MBZ */
+ __u32 pad;
+
union {
/**
* @obj_offset: Offset into the object, MBZ for CLEAR_RANGE,
@@ -469,6 +478,9 @@ struct drm_xe_vm_bind {
/** @num_binds: number of binds in this IOCTL */
__u32 num_binds;
+ /** @pad: MBZ */
+ __u32 pad;
+
union {
/** @bind: used if num_binds == 1 */
struct drm_xe_vm_bind_op bind;
@@ -482,6 +494,9 @@ struct drm_xe_vm_bind {
/** @num_syncs: amount of syncs to wait on */
__u32 num_syncs;
+ /** @pad2: MBZ */
+ __u32 pad2;
+
/** @syncs: pointer to struct drm_xe_sync array */
__u64 syncs;
@@ -497,6 +512,9 @@ struct drm_xe_ext_engine_set_property {
/** @property: property to set */
__u32 property;
+ /** @pad: MBZ */
+ __u32 pad;
+
/** @value: property value */
__u64 value;
};
@@ -612,6 +630,9 @@ struct drm_xe_sync {
#define DRM_XE_SYNC_USER_FENCE 0x3
#define DRM_XE_SYNC_SIGNAL 0x10
+ /** @pad: MBZ */
+ __u32 pad;
+
union {
__u32 handle;
/**
@@ -656,6 +677,9 @@ struct drm_xe_exec {
*/
__u16 num_batch_buffer;
+ /** @pad: MBZ */
+ __u16 pad[3];
+
/** @reserved: Reserved */
__u64 reserved[2];
};
@@ -718,6 +742,8 @@ struct drm_xe_wait_user_fence {
#define DRM_XE_UFENCE_WAIT_ABSTIME (1 << 1)
#define DRM_XE_UFENCE_WAIT_VM_ERROR (1 << 2)
__u16 flags;
+ /** @pad: MBZ */
+ __u32 pad;
/** @value: compare value */
__u64 value;
/** @mask: comparison mask */
@@ -750,6 +776,9 @@ struct drm_xe_vm_madvise {
/** @vm_id: The ID VM in which the VMA exists */
__u32 vm_id;
+ /** @pad: MBZ */
+ __u32 pad;
+
/** @range: Number of bytes in the VMA */
__u64 range;
@@ -794,6 +823,9 @@ struct drm_xe_vm_madvise {
/** @property: property to set */
__u32 property;
+ /** @pad2: MBZ */
+ __u32 pad2;
+
/** @value: property value */
__u64 value;
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index c82e995df779..de713348ccc1 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -1644,7 +1644,8 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
u32 handle;
int err;
- if (XE_IOCTL_ERR(xe, args->extensions))
+ if (XE_IOCTL_ERR(xe, args->extensions) || XE_IOCTL_ERR(xe, args->pad) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
if (XE_IOCTL_ERR(xe, args->flags &
@@ -1714,7 +1715,8 @@ int xe_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
struct drm_xe_gem_mmap_offset *args = data;
struct drm_gem_object *gem_obj;
- if (XE_IOCTL_ERR(xe, args->extensions))
+ if (XE_IOCTL_ERR(xe, args->extensions) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
if (XE_IOCTL_ERR(xe, args->flags))
diff --git a/drivers/gpu/drm/xe/xe_engine.c b/drivers/gpu/drm/xe/xe_engine.c
index 094ec17d3004..8c3a722d91c6 100644
--- a/drivers/gpu/drm/xe/xe_engine.c
+++ b/drivers/gpu/drm/xe/xe_engine.c
@@ -348,7 +348,8 @@ static int engine_user_ext_set_property(struct xe_device *xe,
return -EFAULT;
if (XE_IOCTL_ERR(xe, ext.property >=
- ARRAY_SIZE(engine_set_property_funcs)))
+ ARRAY_SIZE(engine_set_property_funcs)) ||
+ XE_IOCTL_ERR(xe, ext.pad))
return -EINVAL;
idx = array_index_nospec(ext.property, ARRAY_SIZE(engine_set_property_funcs));
@@ -380,7 +381,8 @@ static int engine_user_extensions(struct xe_device *xe, struct xe_engine *e,
if (XE_IOCTL_ERR(xe, err))
return -EFAULT;
- if (XE_IOCTL_ERR(xe, ext.name >=
+ if (XE_IOCTL_ERR(xe, ext.pad) ||
+ XE_IOCTL_ERR(xe, ext.name >=
ARRAY_SIZE(engine_user_extension_funcs)))
return -EINVAL;
@@ -523,7 +525,8 @@ int xe_engine_create_ioctl(struct drm_device *dev, void *data,
int len;
int err;
- if (XE_IOCTL_ERR(xe, args->flags))
+ if (XE_IOCTL_ERR(xe, args->flags) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
len = args->width * args->num_placements;
@@ -639,6 +642,10 @@ int xe_engine_get_property_ioctl(struct drm_device *dev, void *data,
struct drm_xe_engine_get_property *args = data;
struct xe_engine *e;
+ if (XE_IOCTL_ERR(xe, args->extensions) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
+ return -EINVAL;
+
mutex_lock(&xef->engine.lock);
e = xa_load(&xef->engine.xa, args->engine_id);
mutex_unlock(&xef->engine.lock);
@@ -718,7 +725,8 @@ int xe_engine_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_xe_engine_destroy *args = data;
struct xe_engine *e;
- if (XE_IOCTL_ERR(xe, args->pad))
+ if (XE_IOCTL_ERR(xe, args->pad) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
mutex_lock(&xef->engine.lock);
@@ -748,6 +756,9 @@ int xe_engine_set_property_ioctl(struct drm_device *dev, void *data,
int ret;
u32 idx;
+ if (XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
+ return -EINVAL;
+
e = xe_engine_lookup(xef, args->engine_id);
if (XE_IOCTL_ERR(xe, !e))
return -ENOENT;
diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c
index 3db1b159586e..e44076ee2e11 100644
--- a/drivers/gpu/drm/xe/xe_exec.c
+++ b/drivers/gpu/drm/xe/xe_exec.c
@@ -181,7 +181,9 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
bool write_locked;
int err = 0;
- if (XE_IOCTL_ERR(xe, args->extensions))
+ if (XE_IOCTL_ERR(xe, args->extensions) ||
+ XE_IOCTL_ERR(xe, args->pad[0] || args->pad[1] || args->pad[2]) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
engine = xe_engine_lookup(xef, args->engine_id);
diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
index c7fbb1cc1f64..9d583f11e290 100644
--- a/drivers/gpu/drm/xe/xe_mmio.c
+++ b/drivers/gpu/drm/xe/xe_mmio.c
@@ -407,7 +407,8 @@ int xe_mmio_ioctl(struct drm_device *dev, void *data,
bool allowed;
int ret = 0;
- if (XE_IOCTL_ERR(xe, args->extensions))
+ if (XE_IOCTL_ERR(xe, args->extensions) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
if (XE_IOCTL_ERR(xe, args->flags & ~VALID_MMIO_FLAGS))
diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c
index dd64ff0d2a57..97742d003c8a 100644
--- a/drivers/gpu/drm/xe/xe_query.c
+++ b/drivers/gpu/drm/xe/xe_query.c
@@ -374,7 +374,8 @@ int xe_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
struct drm_xe_device_query *query = data;
u32 idx;
- if (XE_IOCTL_ERR(xe, query->extensions != 0))
+ if (XE_IOCTL_ERR(xe, query->extensions ||
+ XE_IOCTL_ERR(xe, query->reserved[0] || query->reserved[1])))
return -EINVAL;
if (XE_IOCTL_ERR(xe, query->query > ARRAY_SIZE(xe_query_funcs)))
diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
index 99f1ed87196d..3c9ac74970c5 100644
--- a/drivers/gpu/drm/xe/xe_sync.c
+++ b/drivers/gpu/drm/xe/xe_sync.c
@@ -110,7 +110,9 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
return -EFAULT;
if (XE_IOCTL_ERR(xe, sync_in.flags &
- ~(SYNC_FLAGS_TYPE_MASK | DRM_XE_SYNC_SIGNAL)))
+ ~(SYNC_FLAGS_TYPE_MASK | DRM_XE_SYNC_SIGNAL)) ||
+ XE_IOCTL_ERR(xe, sync_in.pad) ||
+ XE_IOCTL_ERR(xe, sync_in.reserved[0] || sync_in.reserved[1]))
return -EINVAL;
switch (sync_in.flags & SYNC_FLAGS_TYPE_MASK) {
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 0a4becdf4675..d383e3eeadb3 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -1796,7 +1796,9 @@ static int vm_user_ext_set_property(struct xe_device *xe, struct xe_vm *vm,
return -EFAULT;
if (XE_IOCTL_ERR(xe, ext.property >=
- ARRAY_SIZE(vm_set_property_funcs)))
+ ARRAY_SIZE(vm_set_property_funcs)) ||
+ XE_IOCTL_ERR(xe, ext.pad) ||
+ XE_IOCTL_ERR(xe, ext.reserved[0] || ext.reserved[1]))
return -EINVAL;
return vm_set_property_funcs[ext.property](xe, vm, ext.value);
@@ -1824,7 +1826,8 @@ static int vm_user_extensions(struct xe_device *xe, struct xe_vm *vm,
if (XE_IOCTL_ERR(xe, err))
return -EFAULT;
- if (XE_IOCTL_ERR(xe, ext.name >=
+ if (XE_IOCTL_ERR(xe, ext.pad) ||
+ XE_IOCTL_ERR(xe, ext.name >=
ARRAY_SIZE(vm_user_extension_funcs)))
return -EINVAL;
@@ -1855,6 +1858,9 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,
int err;
u32 flags = 0;
+ if (XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
+ return -EINVAL;
+
if (XE_IOCTL_ERR(xe, args->flags & ~ALL_DRM_XE_VM_CREATE_FLAGS))
return -EINVAL;
@@ -1938,7 +1944,8 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_xe_vm_destroy *args = data;
struct xe_vm *vm;
- if (XE_IOCTL_ERR(xe, args->pad))
+ if (XE_IOCTL_ERR(xe, args->pad) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
vm = xe_vm_lookup(xef, args->vm_id);
@@ -2888,6 +2895,8 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe,
int i;
if (XE_IOCTL_ERR(xe, args->extensions) ||
+ XE_IOCTL_ERR(xe, args->pad || args->pad2) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]) ||
XE_IOCTL_ERR(xe, !args->num_binds) ||
XE_IOCTL_ERR(xe, args->num_binds > MAX_BINDS))
return -EINVAL;
@@ -2920,6 +2929,13 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe,
u64 obj_offset = (*bind_ops)[i].obj_offset;
u32 region = (*bind_ops)[i].region;
+ if (XE_IOCTL_ERR(xe, (*bind_ops)[i].pad) ||
+ XE_IOCTL_ERR(xe, (*bind_ops)[i].reserved[0] ||
+ (*bind_ops)[i].reserved[1])) {
+ err = -EINVAL;
+ goto free_bind_ops;
+ }
+
if (i == 0) {
*async = !!(op & XE_VM_BIND_FLAG_ASYNC);
} else if (XE_IOCTL_ERR(xe, !*async) ||
diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c
index 29815852985a..0f5eef337037 100644
--- a/drivers/gpu/drm/xe/xe_vm_madvise.c
+++ b/drivers/gpu/drm/xe/xe_vm_madvise.c
@@ -301,7 +301,9 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data,
struct xe_vma **vmas = NULL;
int num_vmas = 0, err = 0, idx;
- if (XE_IOCTL_ERR(xe, args->extensions))
+ if (XE_IOCTL_ERR(xe, args->extensions) ||
+ XE_IOCTL_ERR(xe, args->pad || args->pad2) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
if (XE_IOCTL_ERR(xe, args->property > ARRAY_SIZE(madvise_funcs)))
diff --git a/drivers/gpu/drm/xe/xe_wait_user_fence.c b/drivers/gpu/drm/xe/xe_wait_user_fence.c
index 15c2e5aa08d2..6c8a60c60087 100644
--- a/drivers/gpu/drm/xe/xe_wait_user_fence.c
+++ b/drivers/gpu/drm/xe/xe_wait_user_fence.c
@@ -100,7 +100,8 @@ int xe_wait_user_fence_ioctl(struct drm_device *dev, void *data,
args->flags & DRM_XE_UFENCE_WAIT_VM_ERROR;
unsigned long timeout = args->timeout;
- if (XE_IOCTL_ERR(xe, args->extensions))
+ if (XE_IOCTL_ERR(xe, args->extensions) || XE_IOCTL_ERR(xe, args->pad) ||
+ XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1]))
return -EINVAL;
if (XE_IOCTL_ERR(xe, args->flags & ~VALID_FLAGS))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment