Skip to content

Commit bd98ac2

Browse files
committed
drm/xe/pxp/uapi: Add a query for PXP status
PXP prerequisites (SW proxy and HuC auth via GSC) are completed asynchronously from driver load, which means that userspace can start submitting before we're ready to start a PXP session. Therefore, we need a query that userspace can use to check not only if PXP is supported but also to wait until the prerequisites are done. v2: Improve doc, do not report TYPE_NONE as supported (José) v3: Better comments, remove unneeded copy_from_user (John) Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: José Roberto de Souza <jose.souza@intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: John Harrison <John.C.Harrison@Intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250129174140.948829-10-daniele.ceraolospurio@intel.com
1 parent 72d4796 commit bd98ac2

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

drivers/gpu/drm/xe/xe_pxp.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,38 @@ static bool pxp_prerequisites_done(const struct xe_pxp *pxp)
8080
return ready;
8181
}
8282

83+
/**
84+
* xe_pxp_get_readiness_status - check whether PXP is ready for userspace use
85+
* @pxp: the xe_pxp pointer (can be NULL if PXP is disabled)
86+
*
87+
* Returns: 0 if PXP is not ready yet, 1 if it is ready, a negative errno value
88+
* if PXP is not supported/enabled or if something went wrong in the
89+
* initialization of the prerequisites. Note that the return values of this
90+
* function follow the uapi (see drm_xe_query_pxp_status), so they can be used
91+
* directly in the query ioctl.
92+
*/
93+
int xe_pxp_get_readiness_status(struct xe_pxp *pxp)
94+
{
95+
int ret = 0;
96+
97+
if (!xe_pxp_is_enabled(pxp))
98+
return -ENODEV;
99+
100+
/* if the GSC or HuC FW are in an error state, PXP will never work */
101+
if (xe_uc_fw_status_to_error(pxp->gt->uc.huc.fw.status) ||
102+
xe_uc_fw_status_to_error(pxp->gt->uc.gsc.fw.status))
103+
return -EIO;
104+
105+
xe_pm_runtime_get(pxp->xe);
106+
107+
/* PXP requires both HuC loaded and GSC proxy initialized */
108+
if (pxp_prerequisites_done(pxp))
109+
ret = 1;
110+
111+
xe_pm_runtime_put(pxp->xe);
112+
return ret;
113+
}
114+
83115
static bool pxp_session_is_in_play(struct xe_pxp *pxp, u32 id)
84116
{
85117
struct xe_gt *gt = pxp->gt;

drivers/gpu/drm/xe/xe_pxp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct xe_pxp;
1414

1515
bool xe_pxp_is_supported(const struct xe_device *xe);
1616
bool xe_pxp_is_enabled(const struct xe_pxp *pxp);
17+
int xe_pxp_get_readiness_status(struct xe_pxp *pxp);
1718

1819
int xe_pxp_init(struct xe_device *xe);
1920
void xe_pxp_irq_handler(struct xe_device *xe, u16 iir);

drivers/gpu/drm/xe/xe_query.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "xe_macros.h"
2525
#include "xe_mmio.h"
2626
#include "xe_oa.h"
27+
#include "xe_pxp.h"
2728
#include "xe_ttm_vram_mgr.h"
2829
#include "xe_wa.h"
2930

@@ -698,6 +699,33 @@ static int query_oa_units(struct xe_device *xe,
698699
return ret ? -EFAULT : 0;
699700
}
700701

702+
static int query_pxp_status(struct xe_device *xe, struct drm_xe_device_query *query)
703+
{
704+
struct drm_xe_query_pxp_status __user *query_ptr = u64_to_user_ptr(query->data);
705+
size_t size = sizeof(struct drm_xe_query_pxp_status);
706+
struct drm_xe_query_pxp_status resp = { 0 };
707+
int ret;
708+
709+
if (query->size == 0) {
710+
query->size = size;
711+
return 0;
712+
} else if (XE_IOCTL_DBG(xe, query->size != size)) {
713+
return -EINVAL;
714+
}
715+
716+
ret = xe_pxp_get_readiness_status(xe->pxp);
717+
if (ret < 0)
718+
return ret;
719+
720+
resp.status = ret;
721+
resp.supported_session_types = BIT(DRM_XE_PXP_TYPE_HWDRM);
722+
723+
if (copy_to_user(query_ptr, &resp, size))
724+
return -EFAULT;
725+
726+
return 0;
727+
}
728+
701729
static int (* const xe_query_funcs[])(struct xe_device *xe,
702730
struct drm_xe_device_query *query) = {
703731
query_engines,
@@ -709,6 +737,7 @@ static int (* const xe_query_funcs[])(struct xe_device *xe,
709737
query_engine_cycles,
710738
query_uc_fw_version,
711739
query_oa_units,
740+
query_pxp_status,
712741
};
713742

714743
int xe_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)

include/uapi/drm/xe_drm.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,39 @@ struct drm_xe_query_uc_fw_version {
629629
__u64 reserved;
630630
};
631631

632+
/**
633+
* struct drm_xe_query_pxp_status - query if PXP is ready
634+
*
635+
* If PXP is enabled and no fatal error has occurred, the status will be set to
636+
* one of the following values:
637+
* 0: PXP init still in progress
638+
* 1: PXP init complete
639+
*
640+
* If PXP is not enabled or something has gone wrong, the query will be failed
641+
* with one of the following error codes:
642+
* -ENODEV: PXP not supported or disabled;
643+
* -EIO: fatal error occurred during init, so PXP will never be enabled;
644+
* -EINVAL: incorrect value provided as part of the query;
645+
* -EFAULT: error copying the memory between kernel and userspace.
646+
*
647+
* The status can only be 0 in the first few seconds after driver load. If
648+
* everything works as expected, the status will transition to init complete in
649+
* less than 1 second, while in case of errors the driver might take longer to
650+
* start returning an error code, but it should still take less than 10 seconds.
651+
*
652+
* The supported session type bitmask is based on the values in
653+
* enum drm_xe_pxp_session_type. TYPE_NONE is always supported and therefore
654+
* is not reported in the bitmask.
655+
*
656+
*/
657+
struct drm_xe_query_pxp_status {
658+
/** @status: current PXP status */
659+
__u32 status;
660+
661+
/** @supported_session_types: bitmask of supported PXP session types */
662+
__u32 supported_session_types;
663+
};
664+
632665
/**
633666
* struct drm_xe_device_query - Input of &DRM_IOCTL_XE_DEVICE_QUERY - main
634667
* structure to query device information
@@ -648,6 +681,7 @@ struct drm_xe_query_uc_fw_version {
648681
* attributes.
649682
* - %DRM_XE_DEVICE_QUERY_GT_TOPOLOGY
650683
* - %DRM_XE_DEVICE_QUERY_ENGINE_CYCLES
684+
* - %DRM_XE_DEVICE_QUERY_PXP_STATUS
651685
*
652686
* If size is set to 0, the driver fills it with the required size for
653687
* the requested type of data to query. If size is equal to the required
@@ -700,6 +734,7 @@ struct drm_xe_device_query {
700734
#define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6
701735
#define DRM_XE_DEVICE_QUERY_UC_FW_VERSION 7
702736
#define DRM_XE_DEVICE_QUERY_OA_UNITS 8
737+
#define DRM_XE_DEVICE_QUERY_PXP_STATUS 9
703738
/** @query: The type of data to query */
704739
__u32 query;
705740

0 commit comments

Comments
 (0)