[PATCH v2 09/12] drm/xe/pxp: Add API to mark a BO as using PXP

John Harrison john.c.harrison at intel.com
Wed Oct 9 00:42:33 UTC 2024


On 8/16/2024 12:00, Daniele Ceraolo Spurio wrote:
> The driver needs to know if a BO is encrypted with PXP to enable the
> display decryption at flip time.
> Furthermore, we want to keep track of the status of the encryption and
> reject any operation that involves a BO that is encrypted using an old
> key. There are two points in time where such checks can kick in:
>
> 1 - at VM bind time, all operations except for unmapping will be
>      rejected if the key used to encrypt the BO is no longer valid. This
>      check is opt-in via a new VM_BIND flag, to avoid a scenario where a
>      malicious app purposely shares an invalid BO with the compositor (or
>      other app) and cause an error there.
Not following the last statement here.

>
> 2 - at job submission time, if the queue is marked as using PXP, all
>      objects bound to the VM will be checked and the submission will be
>      rejected if any of them was encrypted with a key that is no longer
>      valid.
>
> Note that there is no risk of leaking the encrypted data if a user does
> not opt-in to those checks; the only consequence is that the user will
> not realize that the encryption key is changed and that the data is no
> longer valid.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> Cc: Matthew Brost <matthew.brost at intel.com>
> Cc: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> ---
>   .../xe/compat-i915-headers/pxp/intel_pxp.h    |  10 +-
>   drivers/gpu/drm/xe/xe_bo.c                    | 100 +++++++++++++++++-
>   drivers/gpu/drm/xe/xe_bo.h                    |   5 +
>   drivers/gpu/drm/xe/xe_bo_types.h              |   3 +
>   drivers/gpu/drm/xe/xe_exec.c                  |   6 ++
>   drivers/gpu/drm/xe/xe_pxp.c                   |  74 +++++++++++++
>   drivers/gpu/drm/xe/xe_pxp.h                   |   4 +
>   drivers/gpu/drm/xe/xe_pxp_types.h             |   3 +
>   drivers/gpu/drm/xe/xe_vm.c                    |  46 +++++++-
>   drivers/gpu/drm/xe/xe_vm.h                    |   2 +
>   include/uapi/drm/xe_drm.h                     |  19 ++++
>   11 files changed, 265 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
> index 881680727452..d8682f781619 100644
> --- a/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/xe/compat-i915-headers/pxp/intel_pxp.h
> @@ -9,6 +9,9 @@
>   #include <linux/errno.h>
>   #include <linux/types.h>
>   
> +#include "xe_bo.h"
> +#include "xe_pxp.h"
> +
>   struct drm_i915_gem_object;
>   struct xe_pxp;
>   
> @@ -16,13 +19,16 @@ static inline int intel_pxp_key_check(struct xe_pxp *pxp,
>   				      struct drm_i915_gem_object *obj,
>   				      bool assign)
>   {
> -	return -ENODEV;
> +	if (assign)
> +		return -EINVAL;
What does 'assign' mean and why is it always invalid?

> +
> +	return xe_pxp_key_check(pxp, obj);
>   }
>   
>   static inline bool
>   i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>   {
> -	return false;
> +	return xe_bo_is_protected(obj);
>   }
>   
>   #endif
> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> index 56a089aa3916..0f591b7d93b1 100644
> --- a/drivers/gpu/drm/xe/xe_bo.c
> +++ b/drivers/gpu/drm/xe/xe_bo.c
> @@ -6,6 +6,7 @@
>   #include "xe_bo.h"
>   
>   #include <linux/dma-buf.h>
> +#include <linux/nospec.h>
>   
>   #include <drm/drm_drv.h>
>   #include <drm/drm_gem_ttm_helper.h>
> @@ -24,6 +25,7 @@
>   #include "xe_migrate.h"
>   #include "xe_pm.h"
>   #include "xe_preempt_fence.h"
> +#include "xe_pxp.h"
>   #include "xe_res_cursor.h"
>   #include "xe_trace_bo.h"
>   #include "xe_ttm_stolen_mgr.h"
> @@ -1949,6 +1951,95 @@ void xe_bo_vunmap(struct xe_bo *bo)
>   	__xe_bo_vunmap(bo);
>   }
>   
> +static int gem_create_set_pxp_type(struct xe_device *xe, struct xe_bo *bo, u64 value)
> +{
> +	if (value == DRM_XE_PXP_TYPE_NONE)
> +		return 0;
> +
> +	/* we only support DRM_XE_PXP_TYPE_HWDRM for now */
> +	if (XE_IOCTL_DBG(xe, value != DRM_XE_PXP_TYPE_HWDRM))
> +		return -EINVAL;
> +
> +	xe_pxp_key_assign(xe->pxp, bo);
> +
> +	return 0;
> +}
> +
> +typedef int (*xe_gem_create_set_property_fn)(struct xe_device *xe,
> +					     struct xe_bo *bo,
> +					     u64 value);
> +
> +static const xe_gem_create_set_property_fn gem_create_set_property_funcs[] = {
> +	[DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY] = gem_create_set_pxp_type,
> +};
> +
> +static int gem_create_user_ext_set_property(struct xe_device *xe,
> +					    struct xe_bo *bo,
> +					    u64 extension)
> +{
> +	u64 __user *address = u64_to_user_ptr(extension);
> +	struct drm_xe_ext_set_property ext;
> +	int err;
> +	u32 idx;
> +
> +	err = __copy_from_user(&ext, address, sizeof(ext));
> +	if (XE_IOCTL_DBG(xe, err))
> +		return -EFAULT;
> +
> +	if (XE_IOCTL_DBG(xe, ext.property >=
> +			 ARRAY_SIZE(gem_create_set_property_funcs)) ||
> +	    XE_IOCTL_DBG(xe, ext.pad) ||
> +	    XE_IOCTL_DBG(xe, ext.property != DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY))
Two overlapping checks on the same field in the same if statement seems 
unnecessary.

> +		return -EINVAL;
> +
> +	idx = array_index_nospec(ext.property, ARRAY_SIZE(gem_create_set_property_funcs));
> +	if (!gem_create_set_property_funcs[idx])
> +		return -EINVAL;
> +
> +	return gem_create_set_property_funcs[idx](xe, bo, ext.value);
> +}
> +
> +typedef int (*xe_gem_create_user_extension_fn)(struct xe_device *xe,
> +					       struct xe_bo *bo,
> +					       u64 extension);
> +
> +static const xe_gem_create_user_extension_fn gem_create_user_extension_funcs[] = {
> +	[DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY] = gem_create_user_ext_set_property,
> +};
> +
> +#define MAX_USER_EXTENSIONS	16
> +static int gem_create_user_extensions(struct xe_device *xe, struct xe_bo *bo,
> +				      u64 extensions, int ext_number)
> +{
> +	u64 __user *address = u64_to_user_ptr(extensions);
> +	struct drm_xe_user_extension ext;
> +	int err;
> +	u32 idx;
> +
> +	if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
> +		return -E2BIG;
> +
> +	err = __copy_from_user(&ext, address, sizeof(ext));
> +	if (XE_IOCTL_DBG(xe, err))
> +		return -EFAULT;
> +
> +	if (XE_IOCTL_DBG(xe, ext.pad) ||
> +	    XE_IOCTL_DBG(xe, ext.name >= ARRAY_SIZE(gem_create_user_extension_funcs)))
> +		return -EINVAL;
> +
> +	idx = array_index_nospec(ext.name,
> +				 ARRAY_SIZE(gem_create_user_extension_funcs));
> +	err = gem_create_user_extension_funcs[idx](xe, bo, extensions);
> +	if (XE_IOCTL_DBG(xe, err))
> +		return err;
> +
> +	if (ext.next_extension)
> +		return gem_create_user_extensions(xe, bo, ext.next_extension,
> +						  ++ext_number);
> +
> +	return 0;
> +}
> +
>   int xe_gem_create_ioctl(struct drm_device *dev, void *data,
>   			struct drm_file *file)
>   {
> @@ -1961,8 +2052,7 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
>   	u32 handle;
>   	int err;
>   
> -	if (XE_IOCTL_DBG(xe, args->extensions) ||
> -	    XE_IOCTL_DBG(xe, args->pad[0] || args->pad[1] || args->pad[2]) ||
> +	if (XE_IOCTL_DBG(xe, args->pad[0] || args->pad[1] || args->pad[2]) ||
>   	    XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))
>   		return -EINVAL;
>   
> @@ -2037,6 +2127,12 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
>   		goto out_vm;
>   	}
>   
> +	if (args->extensions) {
> +		err = gem_create_user_extensions(xe, bo, args->extensions, 0);
> +		if (err)
> +			goto out_bulk;
> +	}
> +
>   	err = drm_gem_handle_create(file, &bo->ttm.base, &handle);
>   	if (err)
>   		goto out_bulk;
> diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
> index 1c9dc8adaaa3..721f7dc35aac 100644
> --- a/drivers/gpu/drm/xe/xe_bo.h
> +++ b/drivers/gpu/drm/xe/xe_bo.h
> @@ -171,6 +171,11 @@ static inline bool xe_bo_is_pinned(struct xe_bo *bo)
>   	return bo->ttm.pin_count;
>   }
>   
> +static inline bool xe_bo_is_protected(const struct xe_bo *bo)
> +{
> +	return bo->pxp_key_instance;
> +}
> +
>   static inline void xe_bo_unpin_map_no_vm(struct xe_bo *bo)
>   {
>   	if (likely(bo)) {
> diff --git a/drivers/gpu/drm/xe/xe_bo_types.h b/drivers/gpu/drm/xe/xe_bo_types.h
> index ebc8abf7930a..8668e0374b18 100644
> --- a/drivers/gpu/drm/xe/xe_bo_types.h
> +++ b/drivers/gpu/drm/xe/xe_bo_types.h
> @@ -56,6 +56,9 @@ struct xe_bo {
>   	 */
>   	struct list_head client_link;
>   #endif
> +	/** @pxp_key_instance: key instance this bo was created against (if any) */
> +	u32 pxp_key_instance;
> +
>   	/** @freed: List node for delayed put. */
>   	struct llist_node freed;
>   	/** @update_index: Update index if PT BO */
> diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c
> index f36980aa26e6..aa4f2fe2e131 100644
> --- a/drivers/gpu/drm/xe/xe_exec.c
> +++ b/drivers/gpu/drm/xe/xe_exec.c
> @@ -250,6 +250,12 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
>   		goto err_exec;
>   	}
>   
> +	if (xe_exec_queue_uses_pxp(q)) {
> +		err = xe_vm_validate_protected(q->vm);
> +		if (err)
> +			goto err_exec;
> +	}
> +
>   	job = xe_sched_job_create(q, xe_exec_queue_is_parallel(q) ?
>   				  addresses : &args->address);
>   	if (IS_ERR(job)) {
> diff --git a/drivers/gpu/drm/xe/xe_pxp.c b/drivers/gpu/drm/xe/xe_pxp.c
> index ca4302af4ced..640e62d1d5d7 100644
> --- a/drivers/gpu/drm/xe/xe_pxp.c
> +++ b/drivers/gpu/drm/xe/xe_pxp.c
> @@ -8,6 +8,8 @@
>   #include <drm/drm_managed.h>
>   #include <drm/xe_drm.h>
>   
> +#include "xe_bo.h"
> +#include "xe_bo_types.h"
>   #include "xe_device_types.h"
>   #include "xe_exec_queue.h"
>   #include "xe_exec_queue_types.h"
> @@ -132,6 +134,9 @@ static void pxp_terminate(struct xe_pxp *pxp)
>   
>   	pxp_invalidate_queues(pxp);
>   
> +	if (pxp->status == XE_PXP_ACTIVE)
> +		pxp->key_instance++;
> +
>   	/*
>   	 * If we have a termination already in progress, we need to wait for
>   	 * it to complete before queueing another one. We update the state
> @@ -343,6 +348,8 @@ int xe_pxp_init(struct xe_device *xe)
>   	pxp->xe = xe;
>   	pxp->gt = gt;
>   
> +	pxp->key_instance = 1;
> +
>   	/*
>   	 * we'll use the completion to check if there is a termination pending,
>   	 * so we start it as completed and we reinit it when a termination
> @@ -574,3 +581,70 @@ static void pxp_invalidate_queues(struct xe_pxp *pxp)
>   	spin_unlock_irq(&pxp->queues.lock);
>   }
>   
> +/**
> + * xe_pxp_key_assign - mark a BO as using the current PXP key iteration
> + * @pxp: the xe->pxp pointer (it will be NULL if PXP is disabled)
> + * @bo: the BO to mark
> + *
> + * Returns: -ENODEV if PXP is disabled, 0 otherwise.
> + */
> +int xe_pxp_key_assign(struct xe_pxp *pxp, struct xe_bo *bo)
> +{
> +	if (!xe_pxp_is_enabled(pxp))
> +		return -ENODEV;
> +
> +	xe_assert(pxp->xe, !bo->pxp_key_instance);
> +
> +	/*
> +	 * Note that the PXP key handling is inherently racey, because the key
> +	 * can theoretically change at any time (although it's unlikely to do
> +	 * so without triggers), even right after we copy it. Taking a lock
> +	 * wouldn't help because the value might still change as soon as we
> +	 * release the lock.
> +	 * Userspace needs to handle the fact that their BOs can go invalid at
> +	 * any point.
> +	 */
> +	bo->pxp_key_instance = pxp->key_instance;
> +
> +	return 0;
> +}
> +
> +/**
> + * xe_pxp_key_check - check if the key used by a BO is valid
> + * @pxp: the xe->pxp pointer (it will be NULL if PXP is disabled)
> + * @bo: the BO we want to check
> + *
> + * Checks whether a BO was encrypted with the current key or an obsolete one.
> + *
> + * Returns: 0 if the key is valid, -ENODEV if PXP is disabled, -EINVAL if the
> + * BO is not using PXP,  -ENOEXEC if the key is not valid.
> + */
> +int xe_pxp_key_check(struct xe_pxp *pxp, struct xe_bo *bo)
> +{
> +	if (!xe_pxp_is_enabled(pxp))
> +		return -ENODEV;
> +
> +	if (!xe_bo_is_protected(bo))
> +		return -EINVAL;
> +
> +	xe_assert(pxp->xe, bo->pxp_key_instance);
> +
> +	/*
> +	 * Note that the PXP key handling is inherently racey, because the key
> +	 * can theoretically change at any time (although it's unlikely to do
> +	 * so without triggers), even right after we check it. Taking a lock
> +	 * wouldn't help because the value might still change as soon as we
> +	 * release the lock.
> +	 * We mitigate the risk by checking the key at multiple points (on each
> +	 * submission involving the BO and right before flipping it on the
> +	 * display), but there is still a very small chance that we could
> +	 * operate on an invalid BO for a single submission or a single frame
> +	 * flip. This is a compromise made to protect the encrypted data (which
> +	 * is what the key termination is for).
> +	 */
> +	if (bo->pxp_key_instance != pxp->key_instance)
And the possibility that the key_instance value has wrapped around and 
is valid again is considered not a problem? Using a bo with a bad key 
potentially results in garbage being displayed but nothing worse than that?

> +		return -ENOEXEC;
> +
> +	return 0;
> +}
> +
> diff --git a/drivers/gpu/drm/xe/xe_pxp.h b/drivers/gpu/drm/xe/xe_pxp.h
> index 868813cc84b9..2d22a6e6ab27 100644
> --- a/drivers/gpu/drm/xe/xe_pxp.h
> +++ b/drivers/gpu/drm/xe/xe_pxp.h
> @@ -8,6 +8,7 @@
>   
>   #include <linux/types.h>
>   
> +struct xe_bo;
>   struct xe_device;
>   struct xe_exec_queue;
>   struct xe_pxp;
> @@ -23,4 +24,7 @@ int xe_pxp_exec_queue_set_type(struct xe_pxp *pxp, struct xe_exec_queue *q, u8 t
>   int xe_pxp_exec_queue_add(struct xe_pxp *pxp, struct xe_exec_queue *q);
>   void xe_pxp_exec_queue_remove(struct xe_pxp *pxp, struct xe_exec_queue *q);
>   
> +int xe_pxp_key_assign(struct xe_pxp *pxp, struct xe_bo *bo);
> +int xe_pxp_key_check(struct xe_pxp *pxp, struct xe_bo *bo);
> +
>   #endif /* __XE_PXP_H__ */
> diff --git a/drivers/gpu/drm/xe/xe_pxp_types.h b/drivers/gpu/drm/xe/xe_pxp_types.h
> index eb6a0183320a..1bb747837f86 100644
> --- a/drivers/gpu/drm/xe/xe_pxp_types.h
> +++ b/drivers/gpu/drm/xe/xe_pxp_types.h
> @@ -108,6 +108,9 @@ struct xe_pxp {
>   		/** @queues.list: list of exec_queues that use PXP */
>   		struct list_head list;
>   	} queues;
> +
> +	/** @key_instance: keep track of the current iteration of the PXP key */
> +	u32 key_instance;
>   };
>   
>   #endif /* __XE_PXP_TYPES_H__ */
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 56f105797ae6..1011d643ebb8 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -34,6 +34,7 @@
>   #include "xe_pm.h"
>   #include "xe_preempt_fence.h"
>   #include "xe_pt.h"
> +#include "xe_pxp.h"
>   #include "xe_res_cursor.h"
>   #include "xe_sync.h"
>   #include "xe_trace_bo.h"
> @@ -2754,7 +2755,8 @@ static struct dma_fence *vm_bind_ioctl_ops_execute(struct xe_vm *vm,
>   	(DRM_XE_VM_BIND_FLAG_READONLY | \
>   	 DRM_XE_VM_BIND_FLAG_IMMEDIATE | \
>   	 DRM_XE_VM_BIND_FLAG_NULL | \
> -	 DRM_XE_VM_BIND_FLAG_DUMPABLE)
> +	 DRM_XE_VM_BIND_FLAG_DUMPABLE | \
> +	 DRM_XE_VM_BIND_FLAG_CHECK_PXP)
>   
>   #ifdef TEST_VM_OPS_ERROR
>   #define SUPPORTED_FLAGS	(SUPPORTED_FLAGS_STUB | FORCE_OP_ERROR)
> @@ -2916,7 +2918,7 @@ static void xe_vma_ops_init(struct xe_vma_ops *vops, struct xe_vm *vm,
>   
>   static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
>   					u64 addr, u64 range, u64 obj_offset,
> -					u16 pat_index)
> +					u16 pat_index, u32 op, u32 bind_flags)
>   {
>   	u16 coh_mode;
>   
> @@ -2951,6 +2953,12 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
>   		return  -EINVAL;
>   	}
>   
> +	/* If a BO is protected it must be valid to be mapped */
"is protected it can only be mapped if the key is still valid". The 
above can be read as saying the BO must be mappable, which isn't the 
same thing.

> +	if ((bind_flags & DRM_XE_VM_BIND_FLAG_CHECK_PXP) && xe_bo_is_protected(bo) &&
> +	    op != DRM_XE_VM_BIND_OP_UNMAP && op != DRM_XE_VM_BIND_OP_UNMAP_ALL)
> +		if (XE_IOCTL_DBG(xe, xe_pxp_key_check(xe->pxp, bo) != 0))
> +			return -ENOEXEC;
> +
>   	return 0;
>   }
>   
> @@ -3038,6 +3046,8 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
>   		u32 obj = bind_ops[i].obj;
>   		u64 obj_offset = bind_ops[i].obj_offset;
>   		u16 pat_index = bind_ops[i].pat_index;
> +		u32 op = bind_ops[i].op;
> +		u32 bind_flags = bind_ops[i].flags;
>   
>   		if (!obj)
>   			continue;
> @@ -3050,7 +3060,8 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
>   		bos[i] = gem_to_xe_bo(gem_obj);
>   
>   		err = xe_vm_bind_ioctl_validate_bo(xe, bos[i], addr, range,
> -						   obj_offset, pat_index);
> +						   obj_offset, pat_index, op,
> +						   bind_flags);
>   		if (err)
>   			goto put_obj;
>   	}
> @@ -3343,6 +3354,35 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
>   	return ret;
>   }
>   
> +int xe_vm_validate_protected(struct xe_vm *vm)
> +{
> +	struct drm_gpuva *gpuva;
> +	int err = 0;
> +
> +	if (!vm)
> +		return -ENODEV;
> +
> +	mutex_lock(&vm->snap_mutex);
> +
> +	drm_gpuvm_for_each_va(gpuva, &vm->gpuvm) {
> +		struct xe_vma *vma = gpuva_to_vma(gpuva);
> +		struct xe_bo *bo = vma->gpuva.gem.obj ?
> +			gem_to_xe_bo(vma->gpuva.gem.obj) : NULL;
> +
> +		if (!bo)
> +			continue;
> +
> +		if (xe_bo_is_protected(bo)) {
> +			err = xe_pxp_key_check(vm->xe->pxp, bo);
> +			if (err)
> +				break;
> +		}
> +	}
> +
> +	mutex_unlock(&vm->snap_mutex);
> +	return err;
> +}
> +
>   struct xe_vm_snapshot {
>   	unsigned long num_snaps;
>   	struct {
> diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
> index bfc19e8113c3..dd51c9790dab 100644
> --- a/drivers/gpu/drm/xe/xe_vm.h
> +++ b/drivers/gpu/drm/xe/xe_vm.h
> @@ -216,6 +216,8 @@ struct dma_fence *xe_vma_rebind(struct xe_vm *vm, struct xe_vma *vma,
>   
>   int xe_vm_invalidate_vma(struct xe_vma *vma);
>   
> +int xe_vm_validate_protected(struct xe_vm *vm);
> +
>   static inline void xe_vm_queue_rebind_worker(struct xe_vm *vm)
>   {
>   	xe_assert(vm->xe, xe_vm_in_preempt_fence_mode(vm));
> diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
> index 9972ceb3fbfb..335febe03e40 100644
> --- a/include/uapi/drm/xe_drm.h
> +++ b/include/uapi/drm/xe_drm.h
> @@ -776,8 +776,23 @@ struct drm_xe_device_query {
>    *  - %DRM_XE_GEM_CPU_CACHING_WC - Allocate the pages as write-combined. This
>    *    is uncached. Scanout surfaces should likely use this. All objects
>    *    that can be placed in VRAM must use this.
> + *
> + * This ioctl supports setting the following properties via the
> + * %DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY extension, which uses the
> + * generic @drm_xe_ext_set_property struct:
> + *
> + *  - %DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE - set the type of PXP session
> + *    this object will be used with. Valid values are listed in enum
> + *    drm_xe_pxp_session_type. %DRM_XE_PXP_TYPE_NONE is the default behavior, so
> + *    there is no need to explicitly set that. Objects used with session of type
> + *    %DRM_XE_PXP_TYPE_HWDRM will be marked as invalid if a PXP invalidation
> + *    event occurs after their creation. Attempting to flip an invalid object
> + *    will cause a black frame to be displayed instead. Submissions with invalid
> + *    objects mapped in the VM will be rejected.
Again, seems like the per type descriptions should be collected together 
in the type enum.

John.

>    */
>   struct drm_xe_gem_create {
> +#define DRM_XE_GEM_CREATE_EXTENSION_SET_PROPERTY	0
> +#define   DRM_XE_GEM_CREATE_SET_PROPERTY_PXP_TYPE	0
>   	/** @extensions: Pointer to the first extension struct, if any */
>   	__u64 extensions;
>   
> @@ -939,6 +954,9 @@ struct drm_xe_vm_destroy {
>    *    will only be valid for DRM_XE_VM_BIND_OP_MAP operations, the BO
>    *    handle MBZ, and the BO offset MBZ. This flag is intended to
>    *    implement VK sparse bindings.
> + *  - %DRM_XE_VM_BIND_FLAG_CHECK_PXP - If the object is encrypted via PXP,
> + *    reject the binding if the encryption key is no longer valid. This
> + *    flag has no effect on BOs that are not marked as using PXP.
>    */
>   struct drm_xe_vm_bind_op {
>   	/** @extensions: Pointer to the first extension struct, if any */
> @@ -1029,6 +1047,7 @@ struct drm_xe_vm_bind_op {
>   #define DRM_XE_VM_BIND_FLAG_IMMEDIATE	(1 << 1)
>   #define DRM_XE_VM_BIND_FLAG_NULL	(1 << 2)
>   #define DRM_XE_VM_BIND_FLAG_DUMPABLE	(1 << 3)
> +#define DRM_XE_VM_BIND_FLAG_CHECK_PXP	(1 << 4)
>   	/** @flags: Bind flags */
>   	__u32 flags;
>   



More information about the Intel-xe mailing list