Skip to content

Commit dcdd6b8

Browse files
committed
drm/xe/pxp: Allocate PXP execution resources
PXP requires submissions to the HW for the following operations 1) Key invalidation, done via the VCS engine 2) Communication with the GSC FW for session management, done via the GSCCS. Key invalidation submissions are serialized (only 1 termination can be serviced at a given time) and done via GGTT, so we can allocate a simple BO and a kernel queue for it. Submissions for session management are tied to a PXP client (identified by a unique host_session_id); from the GSC POV this is a user-accessible construct, so all related submission must be done via PPGTT. The driver does not currently support PPGTT submission from within the kernel, so to add this support, the following changes have been included: - a new type of kernel-owned VM (marked as GSC), required to ensure we don't use fault mode on the engine and to mark the different lock usage with lockdep. - a new function to map a BO into a VM from within the kernel. v2: improve comments and function name, remove unneeded include (John) v3: fix variable/function names in documentation Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.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-3-daniele.ceraolospurio@intel.com
1 parent ff48e05 commit dcdd6b8

File tree

10 files changed

+410
-11
lines changed

10 files changed

+410
-11
lines changed

drivers/gpu/drm/xe/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ xe-y += xe_bb.o \
8888
xe_pt.o \
8989
xe_pt_walk.o \
9090
xe_pxp.o \
91+
xe_pxp_submit.o \
9192
xe_query.o \
9293
xe_range_fence.o \
9394
xe_reg_sr.o \

drivers/gpu/drm/xe/abi/gsc_pxp_commands_abi.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
#ifndef _ABI_GSC_PXP_COMMANDS_ABI_H
77
#define _ABI_GSC_PXP_COMMANDS_ABI_H
88

9+
#include <linux/sizes.h>
910
#include <linux/types.h>
1011

1112
/* Heci client ID for PXP commands */
1213
#define HECI_MEADDRESS_PXP 17
1314

1415
#define PXP_APIVER(x, y) (((x) & 0xFFFF) << 16 | ((y) & 0xFFFF))
1516

17+
/*
18+
* A PXP sub-section in an HECI packet can be up to 64K big in each direction.
19+
* This does not include the top-level GSC header.
20+
*/
21+
#define PXP_MAX_PACKET_SIZE SZ_64K
22+
1623
/*
1724
* there are a lot of status codes for PXP, but we only define the cross-API
1825
* common ones that we actually can handle in the kernel driver. Other failure

drivers/gpu/drm/xe/xe_exec_queue.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *v
153153
struct xe_exec_queue *q;
154154
int err;
155155

156+
/* VMs for GSCCS queues (and only those) must have the XE_VM_FLAG_GSC flag */
157+
xe_assert(xe, !vm || (!!(vm->flags & XE_VM_FLAG_GSC) == !!(hwe->engine_id == XE_HW_ENGINE_GSCCS0)));
158+
156159
q = __xe_exec_queue_alloc(xe, vm, logical_mask, width, hwe, flags,
157160
extensions);
158161
if (IS_ERR(q))

drivers/gpu/drm/xe/xe_pxp.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "xe_gt.h"
1313
#include "xe_gt_types.h"
1414
#include "xe_mmio.h"
15+
#include "xe_pxp_submit.h"
1516
#include "xe_pxp_types.h"
1617
#include "xe_uc_fw.h"
1718
#include "regs/xe_pxp_regs.h"
@@ -50,6 +51,20 @@ static int kcr_pxp_enable(const struct xe_pxp *pxp)
5051
return kcr_pxp_set_status(pxp, true);
5152
}
5253

54+
static int kcr_pxp_disable(const struct xe_pxp *pxp)
55+
{
56+
return kcr_pxp_set_status(pxp, false);
57+
}
58+
59+
static void pxp_fini(void *arg)
60+
{
61+
struct xe_pxp *pxp = arg;
62+
63+
xe_pxp_destroy_execution_resources(pxp);
64+
65+
/* no need to explicitly disable KCR since we're going to do an FLR */
66+
}
67+
5368
/**
5469
* xe_pxp_init - initialize PXP support
5570
* @xe: the xe_device structure
@@ -97,10 +112,16 @@ int xe_pxp_init(struct xe_device *xe)
97112
if (err)
98113
goto out_free;
99114

115+
err = xe_pxp_allocate_execution_resources(pxp);
116+
if (err)
117+
goto out_kcr_disable;
118+
100119
xe->pxp = pxp;
101120

102-
return 0;
121+
return devm_add_action_or_reset(xe->drm.dev, pxp_fini, pxp);
103122

123+
out_kcr_disable:
124+
kcr_pxp_disable(pxp);
104125
out_free:
105126
drmm_kfree(&xe->drm, pxp);
106127
return err;

drivers/gpu/drm/xe/xe_pxp_submit.c

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
// SPDX-License-Identifier: MIT
2+
/*
3+
* Copyright(c) 2024 Intel Corporation.
4+
*/
5+
6+
#include "xe_pxp_submit.h"
7+
8+
#include <uapi/drm/xe_drm.h>
9+
10+
#include "xe_device_types.h"
11+
#include "xe_bo.h"
12+
#include "xe_exec_queue.h"
13+
#include "xe_gsc_submit.h"
14+
#include "xe_gt.h"
15+
#include "xe_pxp_types.h"
16+
#include "xe_vm.h"
17+
18+
/*
19+
* The VCS is used for kernel-owned GGTT submissions to issue key termination.
20+
* Terminations are serialized, so we only need a single queue and a single
21+
* batch.
22+
*/
23+
static int allocate_vcs_execution_resources(struct xe_pxp *pxp)
24+
{
25+
struct xe_gt *gt = pxp->gt;
26+
struct xe_device *xe = pxp->xe;
27+
struct xe_tile *tile = gt_to_tile(gt);
28+
struct xe_hw_engine *hwe;
29+
struct xe_exec_queue *q;
30+
struct xe_bo *bo;
31+
int err;
32+
33+
hwe = xe_gt_hw_engine(gt, XE_ENGINE_CLASS_VIDEO_DECODE, 0, true);
34+
if (!hwe)
35+
return -ENODEV;
36+
37+
q = xe_exec_queue_create(xe, NULL, BIT(hwe->logical_instance), 1, hwe,
38+
EXEC_QUEUE_FLAG_KERNEL | EXEC_QUEUE_FLAG_PERMANENT, 0);
39+
if (IS_ERR(q))
40+
return PTR_ERR(q);
41+
42+
/*
43+
* Each termination is 16 DWORDS, so 4K is enough to contain a
44+
* termination for each sessions.
45+
*/
46+
bo = xe_bo_create_pin_map(xe, tile, 0, SZ_4K, ttm_bo_type_kernel,
47+
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_PINNED | XE_BO_FLAG_GGTT);
48+
if (IS_ERR(bo)) {
49+
err = PTR_ERR(bo);
50+
goto out_queue;
51+
}
52+
53+
pxp->vcs_exec.q = q;
54+
pxp->vcs_exec.bo = bo;
55+
56+
return 0;
57+
58+
out_queue:
59+
xe_exec_queue_put(q);
60+
return err;
61+
}
62+
63+
static void destroy_vcs_execution_resources(struct xe_pxp *pxp)
64+
{
65+
if (pxp->vcs_exec.bo)
66+
xe_bo_unpin_map_no_vm(pxp->vcs_exec.bo);
67+
68+
if (pxp->vcs_exec.q)
69+
xe_exec_queue_put(pxp->vcs_exec.q);
70+
}
71+
72+
#define PXP_BB_SIZE XE_PAGE_SIZE
73+
static int allocate_gsc_client_resources(struct xe_gt *gt,
74+
struct xe_pxp_gsc_client_resources *gsc_res,
75+
size_t inout_size)
76+
{
77+
struct xe_tile *tile = gt_to_tile(gt);
78+
struct xe_device *xe = tile_to_xe(tile);
79+
struct xe_hw_engine *hwe;
80+
struct xe_vm *vm;
81+
struct xe_bo *bo;
82+
struct xe_exec_queue *q;
83+
struct dma_fence *fence;
84+
long timeout;
85+
int err = 0;
86+
87+
hwe = xe_gt_hw_engine(gt, XE_ENGINE_CLASS_OTHER, 0, true);
88+
89+
/* we shouldn't reach here if the GSC engine is not available */
90+
xe_assert(xe, hwe);
91+
92+
/* PXP instructions must be issued from PPGTT */
93+
vm = xe_vm_create(xe, XE_VM_FLAG_GSC);
94+
if (IS_ERR(vm))
95+
return PTR_ERR(vm);
96+
97+
/* We allocate a single object for the batch and the in/out memory */
98+
xe_vm_lock(vm, false);
99+
bo = xe_bo_create_pin_map(xe, tile, vm, PXP_BB_SIZE + inout_size * 2,
100+
ttm_bo_type_kernel,
101+
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_PINNED | XE_BO_FLAG_NEEDS_UC);
102+
xe_vm_unlock(vm);
103+
if (IS_ERR(bo)) {
104+
err = PTR_ERR(bo);
105+
goto vm_out;
106+
}
107+
108+
fence = xe_vm_bind_kernel_bo(vm, bo, NULL, 0, XE_CACHE_WB);
109+
if (IS_ERR(fence)) {
110+
err = PTR_ERR(fence);
111+
goto bo_out;
112+
}
113+
114+
timeout = dma_fence_wait_timeout(fence, false, HZ);
115+
dma_fence_put(fence);
116+
if (timeout <= 0) {
117+
err = timeout ?: -ETIME;
118+
goto bo_out;
119+
}
120+
121+
q = xe_exec_queue_create(xe, vm, BIT(hwe->logical_instance), 1, hwe,
122+
EXEC_QUEUE_FLAG_KERNEL |
123+
EXEC_QUEUE_FLAG_PERMANENT, 0);
124+
if (IS_ERR(q)) {
125+
err = PTR_ERR(q);
126+
goto bo_out;
127+
}
128+
129+
gsc_res->vm = vm;
130+
gsc_res->bo = bo;
131+
gsc_res->inout_size = inout_size;
132+
gsc_res->batch = IOSYS_MAP_INIT_OFFSET(&bo->vmap, 0);
133+
gsc_res->msg_in = IOSYS_MAP_INIT_OFFSET(&bo->vmap, PXP_BB_SIZE);
134+
gsc_res->msg_out = IOSYS_MAP_INIT_OFFSET(&bo->vmap, PXP_BB_SIZE + inout_size);
135+
gsc_res->q = q;
136+
137+
/* initialize host-session-handle (for all Xe-to-gsc-firmware PXP cmds) */
138+
gsc_res->host_session_handle = xe_gsc_create_host_session_id();
139+
140+
return 0;
141+
142+
bo_out:
143+
xe_bo_unpin_map_no_vm(bo);
144+
vm_out:
145+
xe_vm_close_and_put(vm);
146+
147+
return err;
148+
}
149+
150+
static void destroy_gsc_client_resources(struct xe_pxp_gsc_client_resources *gsc_res)
151+
{
152+
if (!gsc_res->q)
153+
return;
154+
155+
xe_exec_queue_put(gsc_res->q);
156+
xe_bo_unpin_map_no_vm(gsc_res->bo);
157+
xe_vm_close_and_put(gsc_res->vm);
158+
}
159+
160+
/**
161+
* xe_pxp_allocate_execution_resources - Allocate PXP submission objects
162+
* @pxp: the xe_pxp structure
163+
*
164+
* Allocates exec_queues objects for VCS and GSCCS submission. The GSCCS
165+
* submissions are done via PPGTT, so this function allocates a VM for it and
166+
* maps the object into it.
167+
*
168+
* Returns 0 if the allocation and mapping is successful, an errno value
169+
* otherwise.
170+
*/
171+
int xe_pxp_allocate_execution_resources(struct xe_pxp *pxp)
172+
{
173+
int err;
174+
175+
err = allocate_vcs_execution_resources(pxp);
176+
if (err)
177+
return err;
178+
179+
/*
180+
* PXP commands can require a lot of BO space (see PXP_MAX_PACKET_SIZE),
181+
* but we currently only support a subset of commands that are small
182+
* (< 20 dwords), so a single page is enough for now.
183+
*/
184+
err = allocate_gsc_client_resources(pxp->gt, &pxp->gsc_res, XE_PAGE_SIZE);
185+
if (err)
186+
goto destroy_vcs_context;
187+
188+
return 0;
189+
190+
destroy_vcs_context:
191+
destroy_vcs_execution_resources(pxp);
192+
return err;
193+
}
194+
195+
void xe_pxp_destroy_execution_resources(struct xe_pxp *pxp)
196+
{
197+
destroy_gsc_client_resources(&pxp->gsc_res);
198+
destroy_vcs_execution_resources(pxp);
199+
}

drivers/gpu/drm/xe/xe_pxp_submit.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* Copyright(c) 2024, Intel Corporation. All rights reserved.
4+
*/
5+
6+
#ifndef __XE_PXP_SUBMIT_H__
7+
#define __XE_PXP_SUBMIT_H__
8+
9+
struct xe_pxp;
10+
11+
int xe_pxp_allocate_execution_resources(struct xe_pxp *pxp);
12+
void xe_pxp_destroy_execution_resources(struct xe_pxp *pxp);
13+
14+
#endif /* __XE_PXP_SUBMIT_H__ */

drivers/gpu/drm/xe/xe_pxp_types.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,45 @@
66
#ifndef __XE_PXP_TYPES_H__
77
#define __XE_PXP_TYPES_H__
88

9+
#include <linux/iosys-map.h>
10+
#include <linux/types.h>
11+
12+
struct xe_bo;
13+
struct xe_exec_queue;
914
struct xe_device;
1015
struct xe_gt;
16+
struct xe_vm;
17+
18+
/**
19+
* struct xe_pxp_gsc_client_resources - resources for GSC submission by a PXP
20+
* client. The GSC FW supports multiple GSC client active at the same time.
21+
*/
22+
struct xe_pxp_gsc_client_resources {
23+
/**
24+
* @host_session_handle: handle used to identify the client in messages
25+
* sent to the GSC firmware.
26+
*/
27+
u64 host_session_handle;
28+
/** @vm: VM used for PXP submissions to the GSCCS */
29+
struct xe_vm *vm;
30+
/** @q: GSCCS exec queue for PXP submissions */
31+
struct xe_exec_queue *q;
32+
33+
/**
34+
* @bo: BO used for submissions to the GSCCS and GSC FW. It includes
35+
* space for the GSCCS batch and the input/output buffers read/written
36+
* by the FW
37+
*/
38+
struct xe_bo *bo;
39+
/** @inout_size: size of each of the msg_in/out sections individually */
40+
u32 inout_size;
41+
/** @batch: iosys_map to the batch memory within the BO */
42+
struct iosys_map batch;
43+
/** @msg_in: iosys_map to the input memory within the BO */
44+
struct iosys_map msg_in;
45+
/** @msg_out: iosys_map to the output memory within the BO */
46+
struct iosys_map msg_out;
47+
};
1148

1249
/**
1350
* struct xe_pxp - pxp state
@@ -21,6 +58,17 @@ struct xe_pxp {
2158
* (VDBOX, KCR and GSC)
2259
*/
2360
struct xe_gt *gt;
61+
62+
/** @vcs_exec: kernel-owned objects for PXP submissions to the VCS */
63+
struct {
64+
/** @vcs_exec.q: kernel-owned VCS exec queue used for PXP terminations */
65+
struct xe_exec_queue *q;
66+
/** @vcs_exec.bo: BO used for submissions to the VCS */
67+
struct xe_bo *bo;
68+
} vcs_exec;
69+
70+
/** @gsc_res: kernel-owned objects for PXP submissions to the GSCCS */
71+
struct xe_pxp_gsc_client_resources gsc_res;
2472
};
2573

2674
#endif /* __XE_PXP_TYPES_H__ */

0 commit comments

Comments
 (0)