From 63861472ffead77b032505a3f24902c48d768c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Mon, 15 Jul 2024 13:25:32 -0700 Subject: [PATCH] iris: Add support to create protected bo and protected exec_queue in Xe KMD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Lionel Landwerlin Signed-off-by: José Roberto de Souza Part-of: --- .../drivers/iris/i915/iris_kmd_backend.c | 2 +- src/gallium/drivers/iris/iris_bufmgr.c | 15 ++++---- src/gallium/drivers/iris/iris_bufmgr.h | 5 +-- src/gallium/drivers/iris/iris_kmd_backend.h | 2 +- src/gallium/drivers/iris/iris_resource.c | 11 ++++-- src/gallium/drivers/iris/xe/iris_batch.c | 36 ++++++++++++++----- .../drivers/iris/xe/iris_kmd_backend.c | 21 +++++++---- 7 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/iris/i915/iris_kmd_backend.c b/src/gallium/drivers/iris/i915/iris_kmd_backend.c index 11c8f6c2993..e2f7936e6f0 100644 --- a/src/gallium/drivers/iris/i915/iris_kmd_backend.c +++ b/src/gallium/drivers/iris/i915/iris_kmd_backend.c @@ -415,7 +415,7 @@ i915_batch_submit(struct iris_batch *batch) } static bool -i915_gem_vm_bind(struct iris_bo *bo) +i915_gem_vm_bind(struct iris_bo *bo, unsigned flags) { /* * i915 does not support VM_BIND yet. The binding operation happens at diff --git a/src/gallium/drivers/iris/iris_bufmgr.c b/src/gallium/drivers/iris/iris_bufmgr.c index e5c8cce7a21..39d44d9e7b5 100644 --- a/src/gallium/drivers/iris/iris_bufmgr.c +++ b/src/gallium/drivers/iris/iris_bufmgr.c @@ -1266,7 +1266,7 @@ iris_bo_alloc(struct iris_bufmgr *bufmgr, if (bo->address == 0ull) goto err_free; - if (!bufmgr->kmd_backend->gem_vm_bind(bo)) + if (!bufmgr->kmd_backend->gem_vm_bind(bo, flags)) goto err_vm_alloc; } @@ -1354,7 +1354,7 @@ iris_bo_create_userptr(struct iris_bufmgr *bufmgr, const char *name, bo->real.mmap_mode = heap_to_mmap_mode(bufmgr, bo->real.heap); bo->real.prime_fd = -1; - if (!bufmgr->kmd_backend->gem_vm_bind(bo)) + if (!bufmgr->kmd_backend->gem_vm_bind(bo, 0)) goto err_vma_free; return bo; @@ -1401,7 +1401,8 @@ iris_bo_set_prime_fd(struct iris_bo *bo) */ struct iris_bo * iris_bo_gem_create_from_name(struct iris_bufmgr *bufmgr, - const char *name, unsigned int handle) + const char *name, unsigned int handle, + unsigned flags) { struct iris_bo *bo; @@ -1464,7 +1465,7 @@ iris_bo_gem_create_from_name(struct iris_bufmgr *bufmgr, if (!iris_bo_set_prime_fd(bo)) goto err_vm_alloc; - if (!bufmgr->kmd_backend->gem_vm_bind(bo)) + if (!bufmgr->kmd_backend->gem_vm_bind(bo, flags)) goto err_vm_alloc; _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo); @@ -1923,7 +1924,7 @@ iris_gem_set_tiling(struct iris_bo *bo, const struct isl_surf *surf) struct iris_bo * iris_bo_import_dmabuf(struct iris_bufmgr *bufmgr, int prime_fd, - const uint64_t modifier) + const uint64_t modifier, unsigned flags) { uint32_t handle; struct iris_bo *bo; @@ -1987,7 +1988,7 @@ iris_bo_import_dmabuf(struct iris_bufmgr *bufmgr, int prime_fd, if (bo->address == 0ull) goto err_free; - if (!bufmgr->kmd_backend->gem_vm_bind(bo)) + if (!bufmgr->kmd_backend->gem_vm_bind(bo, flags)) goto err_vm_alloc; _mesa_hash_table_insert(bufmgr->handle_table, &bo->gem_handle, bo); @@ -2235,7 +2236,7 @@ intel_aux_map_buffer_alloc(void *driver_ctx, uint32_t size) if (bo->address == 0ull) goto err_free; - if (!bufmgr->kmd_backend->gem_vm_bind(bo)) + if (!bufmgr->kmd_backend->gem_vm_bind(bo, 0)) goto err_vm_alloc; simple_mtx_unlock(&bufmgr->lock); diff --git a/src/gallium/drivers/iris/iris_bufmgr.h b/src/gallium/drivers/iris/iris_bufmgr.h index 88baae5d3a8..9e7dc5fb391 100644 --- a/src/gallium/drivers/iris/iris_bufmgr.h +++ b/src/gallium/drivers/iris/iris_bufmgr.h @@ -567,7 +567,8 @@ int iris_bufmgr_get_fd(struct iris_bufmgr *bufmgr); struct iris_bo *iris_bo_gem_create_from_name(struct iris_bufmgr *bufmgr, const char *name, - unsigned handle); + unsigned handle, + unsigned flags); void* iris_bufmgr_get_aux_map_context(struct iris_bufmgr *bufmgr); @@ -576,7 +577,7 @@ int iris_gem_set_tiling(struct iris_bo *bo, const struct isl_surf *surf); int iris_bo_export_dmabuf(struct iris_bo *bo, int *prime_fd); struct iris_bo *iris_bo_import_dmabuf(struct iris_bufmgr *bufmgr, int prime_fd, - const uint64_t modifier); + const uint64_t modifier, unsigned flags); /** * Exports a bo as a GEM handle into a given DRM file descriptor diff --git a/src/gallium/drivers/iris/iris_kmd_backend.h b/src/gallium/drivers/iris/iris_kmd_backend.h index 2f5d628a13a..283f1bd2eaa 100644 --- a/src/gallium/drivers/iris/iris_kmd_backend.h +++ b/src/gallium/drivers/iris/iris_kmd_backend.h @@ -47,7 +47,7 @@ struct iris_kmd_backend { void *(*gem_mmap)(struct iris_bufmgr *bufmgr, struct iris_bo *bo); enum pipe_reset_status (*batch_check_for_reset)(struct iris_batch *batch); int (*batch_submit)(struct iris_batch *batch); - bool (*gem_vm_bind)(struct iris_bo *bo); + bool (*gem_vm_bind)(struct iris_bo *bo, unsigned flags); bool (*gem_vm_unbind)(struct iris_bo *bo); }; diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 302afa9ae84..1660a0cf77e 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -381,8 +381,9 @@ iris_memobj_create_from_handle(struct pipe_screen *pscreen, assert(whandle->type == WINSYS_HANDLE_TYPE_FD); assert(whandle->modifier == DRM_FORMAT_MOD_INVALID); + /* There is no information if memobj is protected or not */ struct iris_bo *bo = iris_bo_import_dmabuf(screen->bufmgr, whandle->handle, - DRM_FORMAT_MOD_INVALID); + DRM_FORMAT_MOD_INVALID, 0); if (!bo) { free(memobj); return NULL; @@ -1324,6 +1325,7 @@ iris_resource_from_handle(struct pipe_screen *pscreen, struct iris_screen *screen = (struct iris_screen *)pscreen; const struct intel_device_info *devinfo = screen->devinfo; struct iris_bufmgr *bufmgr = screen->bufmgr; + unsigned flags = 0; /* The gallium dri layer creates a pipe resource for each plane specified * by the format and modifier. Once all planes are present, we will merge @@ -1334,14 +1336,17 @@ iris_resource_from_handle(struct pipe_screen *pscreen, if (!res) return NULL; + if (templ->bind & PIPE_BIND_PROTECTED) + flags |= BO_ALLOC_PROTECTED; + switch (whandle->type) { case WINSYS_HANDLE_TYPE_FD: res->bo = iris_bo_import_dmabuf(bufmgr, whandle->handle, - whandle->modifier); + whandle->modifier, flags); break; case WINSYS_HANDLE_TYPE_SHARED: res->bo = iris_bo_gem_create_from_name(bufmgr, "winsys image", - whandle->handle); + whandle->handle, flags); break; default: unreachable("invalid winsys handle type"); diff --git a/src/gallium/drivers/iris/xe/iris_batch.c b/src/gallium/drivers/iris/xe/iris_batch.c index 6adcddddf98..b10678fb1a6 100644 --- a/src/gallium/drivers/iris/xe/iris_batch.c +++ b/src/gallium/drivers/iris/xe/iris_batch.c @@ -30,6 +30,7 @@ #include "common/intel_engine.h" #include "common/xe/intel_device_query.h" #include "common/xe/intel_engine.h" +#include "common/xe/intel_gem.h" #include "common/xe/intel_queue.h" #include "drm-uapi/xe_drm.h" @@ -54,7 +55,8 @@ static bool iris_xe_init_batch(struct iris_bufmgr *bufmgr, struct intel_query_engine_info *engines_info, enum intel_engine_class engine_class, - enum iris_context_priority priority, uint32_t *exec_queue_id) + enum iris_context_priority priority, uint32_t *exec_queue_id, + bool protected) { struct drm_xe_engine_class_instance *instances; @@ -88,20 +90,37 @@ iris_xe_init_batch(struct iris_bufmgr *bufmgr, instances[count].engine_instance = engine.engine_instance; instances[count++].gt_id = engine.gt_id; } - struct drm_xe_ext_set_property ext = { - .base.name = DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY, + struct drm_xe_ext_set_property priority_ext = { .property = DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY, .value = allowed_priority, }; + struct drm_xe_ext_set_property pxp_ext = { + .property = DRM_XE_EXEC_QUEUE_SET_PROPERTY_PXP_TYPE, + .value = DRM_XE_PXP_TYPE_HWDRM, + }; struct drm_xe_exec_queue_create create = { .instances = (uintptr_t)instances, .vm_id = iris_bufmgr_get_global_vm_id(bufmgr), .width = 1, .num_placements = count, - .extensions = (uintptr_t)&ext, }; - int ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), - DRM_IOCTL_XE_EXEC_QUEUE_CREATE, &create); + intel_xe_gem_add_ext((uint64_t *)&create.extensions, + DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY, + &priority_ext.base); + if (protected) + intel_xe_gem_add_ext((uint64_t *)&create.extensions, + DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY, + &pxp_ext.base); + int ret; + bool retry; + do { + ret = intel_ioctl(iris_bufmgr_get_fd(bufmgr), + DRM_IOCTL_XE_EXEC_QUEUE_CREATE, &create); + retry = protected && ret == -1 && errno == EBUSY; + if (retry) + usleep(1000); + } while (retry); + free(instances); if (ret) goto error_create_exec_queue; @@ -145,7 +164,8 @@ void iris_xe_init_batches(struct iris_context *ice) ASSERTED bool ret; ret = iris_xe_init_batch(bufmgr, engines_info, engine_classes[name], - ice->priority, &batch->xe.exec_queue_id); + ice->priority, &batch->xe.exec_queue_id, + ice->protected); assert(ret); } @@ -225,7 +245,7 @@ bool iris_xe_replace_batch(struct iris_batch *batch) iris_xe_map_intel_engine_class(bufmgr, engines_info, engine_classes); ret = iris_xe_init_batch(bufmgr, engines_info, engine_classes[batch->name], - ice->priority, &new_exec_queue_id); + ice->priority, &new_exec_queue_id, ice->protected); if (ret) { iris_xe_destroy_exec_queue(batch); batch->xe.exec_queue_id = new_exec_queue_id; diff --git a/src/gallium/drivers/iris/xe/iris_kmd_backend.c b/src/gallium/drivers/iris/xe/iris_kmd_backend.c index 9fb147d07a4..3566d217181 100644 --- a/src/gallium/drivers/iris/xe/iris_kmd_backend.c +++ b/src/gallium/drivers/iris/xe/iris_kmd_backend.c @@ -41,9 +41,11 @@ xe_gem_create(struct iris_bufmgr *bufmgr, uint16_t regions_count, uint64_t size, enum iris_heap heap_flags, unsigned alloc_flags) { - /* Xe still don't have support for protected content */ - if (alloc_flags & BO_ALLOC_PROTECTED) - return -EINVAL; + struct drm_xe_ext_set_property pxp_ext = { + .base.name = DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY, + .property = DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE, + .value = DRM_XE_PXP_TYPE_HWDRM, + }; uint32_t vm_id = iris_bufmgr_get_global_vm_id(bufmgr); vm_id = alloc_flags & BO_ALLOC_SHARED ? 0 : vm_id; @@ -82,6 +84,9 @@ xe_gem_create(struct iris_bufmgr *bufmgr, gem_create.cpu_caching = DRM_XE_GEM_CPU_CACHING_WC; } + if (alloc_flags & BO_ALLOC_PROTECTED) + gem_create.extensions = (uintptr_t)&pxp_ext; + if (intel_ioctl(iris_bufmgr_get_fd(bufmgr), DRM_IOCTL_XE_GEM_CREATE, &gem_create)) return 0; @@ -104,7 +109,7 @@ xe_gem_mmap(struct iris_bufmgr *bufmgr, struct iris_bo *bo) } static inline int -xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op) +xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op, unsigned iris_flags) { struct iris_bufmgr *bufmgr = bo->bufmgr; struct intel_bind_timeline *bind_timeline = iris_bufmgr_get_bind_timeline(bufmgr); @@ -136,6 +141,8 @@ xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op) if (bo->real.capture) flags |= DRM_XE_VM_BIND_FLAG_DUMPABLE; + if (iris_flags & BO_ALLOC_PROTECTED) + flags |= DRM_XE_VM_BIND_FLAG_CHECK_PXP; struct drm_xe_vm_bind args = { .vm_id = iris_bufmgr_get_global_vm_id(bufmgr), @@ -162,15 +169,15 @@ xe_gem_vm_bind_op(struct iris_bo *bo, uint32_t op) } static bool -xe_gem_vm_bind(struct iris_bo *bo) +xe_gem_vm_bind(struct iris_bo *bo, unsigned flags) { - return xe_gem_vm_bind_op(bo, DRM_XE_VM_BIND_OP_MAP) == 0; + return xe_gem_vm_bind_op(bo, DRM_XE_VM_BIND_OP_MAP, flags) == 0; } static bool xe_gem_vm_unbind(struct iris_bo *bo) { - return xe_gem_vm_bind_op(bo, DRM_XE_VM_BIND_OP_UNMAP) == 0; + return xe_gem_vm_bind_op(bo, DRM_XE_VM_BIND_OP_UNMAP, 0) == 0; } static bool