aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2017-12-13 15:12:57 -0500
committerRob Clark <robdclark@gmail.com>2018-02-20 10:41:20 -0500
commit6a8bd08d0465b2b8d214007c58598e2c15312296 (patch)
tree2f776c4b220a2885a4de8f10182a63bbd1c9d5b7
parent331dc0bc195bb77fcbe60b4513464b406a6d20cb (diff)
drm/msm: add sudo flag to submit ioctl
This flags cause cmdstream to be executed from the ringbuffer (RB) instead of IB1. Normally not something you'd ever want to do, but it is super useful for firmware debugging. Hidden behind CAP_SYS_RAWIO and a default=n kconfig option which depends on EXPERT (and has a suitably scary warning), to prevent it from being used on accident. Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--drivers/gpu/drm/msm/Kconfig13
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c65
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h1
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c9
-rw-r--r--include/uapi/drm/msm_drm.h2
5 files changed, 90 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 99d39b2aefa6..3065cb290aa8 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -28,6 +28,19 @@ config DRM_MSM_REGISTER_LOGGING
28 that can be parsed by envytools demsm tool. If enabled, register 28 that can be parsed by envytools demsm tool. If enabled, register
29 logging can be switched on via msm.reglog=y module param. 29 logging can be switched on via msm.reglog=y module param.
30 30
31config DRM_MSM_GPU_SUDO
32 bool "Enable SUDO flag on submits"
33 depends on DRM_MSM && EXPERT
34 default n
35 help
36 Enable userspace that has CAP_SYS_RAWIO to submit GPU commands
37 that are run from RB instead of IB1. This essentially gives
38 userspace kernel level access, but is useful for firmware
39 debugging.
40
41 Only use this if you are a driver developer. This should *not*
42 be enabled for production kernels. If unsure, say N.
43
31config DRM_MSM_HDMI_HDCP 44config DRM_MSM_HDMI_HDCP
32 bool "Enable HDMI HDCP support in MSM DRM driver" 45 bool "Enable HDMI HDCP support in MSM DRM driver"
33 depends on DRM_MSM && QCOM_SCM 46 depends on DRM_MSM && QCOM_SCM
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 579c28c8c994..fa08b4897a56 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -140,6 +140,65 @@ static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
140 gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr); 140 gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr);
141} 141}
142 142
143static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit,
144 struct msm_file_private *ctx)
145{
146 struct msm_drm_private *priv = gpu->dev->dev_private;
147 struct msm_ringbuffer *ring = submit->ring;
148 struct msm_gem_object *obj;
149 uint32_t *ptr, dwords;
150 unsigned int i;
151
152 for (i = 0; i < submit->nr_cmds; i++) {
153 switch (submit->cmd[i].type) {
154 case MSM_SUBMIT_CMD_IB_TARGET_BUF:
155 break;
156 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
157 if (priv->lastctx == ctx)
158 break;
159 case MSM_SUBMIT_CMD_BUF:
160 /* copy commands into RB: */
161 obj = submit->bos[submit->cmd[i].idx].obj;
162 dwords = submit->cmd[i].size;
163
164 ptr = msm_gem_get_vaddr(&obj->base);
165
166 /* _get_vaddr() shouldn't fail at this point,
167 * since we've already mapped it once in
168 * submit_reloc()
169 */
170 if (WARN_ON(!ptr))
171 return;
172
173 for (i = 0; i < dwords; i++) {
174 /* normally the OUT_PKTn() would wait
175 * for space for the packet. But since
176 * we just OUT_RING() the whole thing,
177 * need to call adreno_wait_ring()
178 * ourself:
179 */
180 adreno_wait_ring(ring, 1);
181 OUT_RING(ring, ptr[i]);
182 }
183
184 msm_gem_put_vaddr(&obj->base);
185
186 break;
187 }
188 }
189
190 a5xx_flush(gpu, ring);
191 a5xx_preempt_trigger(gpu);
192
193 /* we might not necessarily have a cmd from userspace to
194 * trigger an event to know that submit has completed, so
195 * do this manually:
196 */
197 a5xx_idle(gpu, ring);
198 ring->memptrs->fence = submit->seqno;
199 msm_gpu_retire(gpu);
200}
201
143static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, 202static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
144 struct msm_file_private *ctx) 203 struct msm_file_private *ctx)
145{ 204{
@@ -149,6 +208,12 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
149 struct msm_ringbuffer *ring = submit->ring; 208 struct msm_ringbuffer *ring = submit->ring;
150 unsigned int i, ibs = 0; 209 unsigned int i, ibs = 0;
151 210
211 if (IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) && submit->in_rb) {
212 priv->lastctx = NULL;
213 a5xx_submit_in_rb(gpu, submit, ctx);
214 return;
215 }
216
152 OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); 217 OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
153 OUT_RING(ring, 0x02); 218 OUT_RING(ring, 0x02);
154 219
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 9320e184b48d..c5d9bd3e47a8 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -146,6 +146,7 @@ struct msm_gem_submit {
146 struct msm_gpu_submitqueue *queue; 146 struct msm_gpu_submitqueue *queue;
147 struct pid *pid; /* submitting process */ 147 struct pid *pid; /* submitting process */
148 bool valid; /* true if no cmdstream patching needed */ 148 bool valid; /* true if no cmdstream patching needed */
149 bool in_rb; /* "sudo" mode, copy cmds into RB */
149 struct msm_ringbuffer *ring; 150 struct msm_ringbuffer *ring;
150 unsigned int nr_cmds; 151 unsigned int nr_cmds;
151 unsigned int nr_bos; 152 unsigned int nr_bos;
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index b8dc8f96caf2..7bd83e0afa97 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -430,6 +430,12 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
430 if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS) 430 if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS)
431 return -EINVAL; 431 return -EINVAL;
432 432
433 if (args->flags & MSM_SUBMIT_SUDO) {
434 if (!IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) ||
435 !capable(CAP_SYS_RAWIO))
436 return -EINVAL;
437 }
438
433 queue = msm_submitqueue_get(ctx, args->queueid); 439 queue = msm_submitqueue_get(ctx, args->queueid);
434 if (!queue) 440 if (!queue)
435 return -ENOENT; 441 return -ENOENT;
@@ -471,6 +477,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
471 goto out_unlock; 477 goto out_unlock;
472 } 478 }
473 479
480 if (args->flags & MSM_SUBMIT_SUDO)
481 submit->in_rb = true;
482
474 ret = submit_lookup_objects(submit, args, file); 483 ret = submit_lookup_objects(submit, args, file);
475 if (ret) 484 if (ret)
476 goto out; 485 goto out;
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index bbbaffad772d..c06d0a5bdd80 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -201,10 +201,12 @@ struct drm_msm_gem_submit_bo {
201#define MSM_SUBMIT_NO_IMPLICIT 0x80000000 /* disable implicit sync */ 201#define MSM_SUBMIT_NO_IMPLICIT 0x80000000 /* disable implicit sync */
202#define MSM_SUBMIT_FENCE_FD_IN 0x40000000 /* enable input fence_fd */ 202#define MSM_SUBMIT_FENCE_FD_IN 0x40000000 /* enable input fence_fd */
203#define MSM_SUBMIT_FENCE_FD_OUT 0x20000000 /* enable output fence_fd */ 203#define MSM_SUBMIT_FENCE_FD_OUT 0x20000000 /* enable output fence_fd */
204#define MSM_SUBMIT_SUDO 0x10000000 /* run submitted cmds from RB */
204#define MSM_SUBMIT_FLAGS ( \ 205#define MSM_SUBMIT_FLAGS ( \
205 MSM_SUBMIT_NO_IMPLICIT | \ 206 MSM_SUBMIT_NO_IMPLICIT | \
206 MSM_SUBMIT_FENCE_FD_IN | \ 207 MSM_SUBMIT_FENCE_FD_IN | \
207 MSM_SUBMIT_FENCE_FD_OUT | \ 208 MSM_SUBMIT_FENCE_FD_OUT | \
209 MSM_SUBMIT_SUDO | \
208 0) 210 0)
209 211
210/* Each cmdstream submit consists of a table of buffers involved, and 212/* Each cmdstream submit consists of a table of buffers involved, and