anv: xe: fully initialize drm_xe_sync addr/handle union

The handle and addr fields of drm_xe_sync is defined as the union:

union {
   __u32 handle;
   __u64 addr;
};

When initialized on the stack on certain implementations, setting
.handle will leave the upper bits of .addr/the overall union
uninitialized causing exec calls to fail with:

[drm:xe_sync_entry_parse [xe]] Ioctl argument check failed at drivers/gpu/drm/xe/xe_sync.c:136: upper_32_bits(sync_in.addr)

Somewhat awkward but init .addr first to 0 and then set the handle after
the struct init.

Cc: stable
Signed-off-by: Juston Li <justonli@google.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33172>
This commit is contained in:
Juston Li 2025-01-24 13:08:47 -08:00
parent f7e5daaedd
commit 9afe29153d
2 changed files with 14 additions and 7 deletions

View file

@ -43,9 +43,10 @@ vk_sync_to_drm_xe_sync(struct vk_sync *vk_sync, uint64_t value, bool signal)
.type = value ? DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ :
DRM_XE_SYNC_TYPE_SYNCOBJ,
.flags = signal ? DRM_XE_SYNC_FLAG_SIGNAL : 0,
.handle = syncobj->syncobj,
.addr = 0, /* init union to 0 before setting .handle */
.timeline_value = value,
};
drm_sync.handle = syncobj->syncobj;
return drm_sync;
}
@ -103,12 +104,14 @@ xe_exec_process_syncs(struct anv_queue *queue,
xe_syncs[count++] = vk_sync_to_drm_xe_sync(queue->sync, 0, TYPE_SIGNAL);
/* vm bind sync */
xe_syncs[count++] = (struct drm_xe_sync) {
xe_syncs[count] = (struct drm_xe_sync) {
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = 0 /* TYPE_WAIT */,
.handle = intel_bind_timeline_get_syncobj(&device->bind_timeline),
.addr = 0, /* init union to 0 before setting .handle */
.timeline_value = intel_bind_timeline_get_last_point(&device->bind_timeline),
};
xe_syncs[count++].handle =
intel_bind_timeline_get_syncobj(&device->bind_timeline);
assert(count == num_syncs);
*ret = xe_syncs;
@ -163,12 +166,14 @@ xe_queue_exec_async(struct anv_async_submit *submit,
if (queue->sync)
xe_syncs[n_syncs++] = vk_sync_to_drm_xe_sync(queue->sync, 0, TYPE_SIGNAL);
xe_syncs[n_syncs++] = (struct drm_xe_sync) {
xe_syncs[n_syncs] = (struct drm_xe_sync) {
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = 0 /* TYPE_WAIT */,
.handle = intel_bind_timeline_get_syncobj(&device->bind_timeline),
.addr = 0, /* init union to 0 before setting .handle */
.timeline_value = intel_bind_timeline_get_last_point(&device->bind_timeline),
};
xe_syncs[n_syncs++].handle =
intel_bind_timeline_get_syncobj(&device->bind_timeline);
#ifdef SUPPORT_INTEL_INTEGRATED_GPUS
if (device->physical->memory.need_flush &&

View file

@ -198,12 +198,14 @@ xe_vm_bind_op(struct anv_device *device,
true);
}
if (signal_bind_timeline) {
xe_syncs[sync_idx++] = (struct drm_xe_sync) {
xe_syncs[sync_idx] = (struct drm_xe_sync) {
.type = DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ,
.flags = DRM_XE_SYNC_FLAG_SIGNAL,
.handle = intel_bind_timeline_get_syncobj(&device->bind_timeline),
.addr = 0, /* init union to 0 before setting .handle */
/* .timeline_value will be set later. */
};
xe_syncs[sync_idx++].handle =
intel_bind_timeline_get_syncobj(&device->bind_timeline);
}
assert(sync_idx == num_syncs);