drm/msm: additions for firmware debugging
Subsystems (5)
cover drm/msm: additions for firmware debugging
A couple patches aimed in particular at simplifying firmware debugging.
The first patch adds some debugfs to dump out state, as well as a debugfs file that can be written to trigger GPU reset and firmware reloading.
The second patch adds a new SUBMIT ioctl flag to allow userspace to submit cmdstream that is executed from the ringbuffer (RB) instead of from IB1. *Normally* this isn't something you want to allow userspace to do, so it is (a) restricted to CAP_SYS_ADMIN and (b) hidden behind an additional kconfig option. But it *is* quite useful for debugging since it allows you to execute a single command and then dump out the PFP and/or ME microcontroller registers/state, without having that state overwritten by handling of the return-from-CP_INDIRECT_BUFFER or other commands that the kernel normally writes into RB as part of handling of a SUBMIT.
Compared to hacking up the kernel to submit different commands and dumping state, these two patches avoid much kernel rebuilding and rebooting. Also it makes it much easier to debug commands that have pointers to other GPU buffers, since it re-uses all the existing SUBMIT reloc logic.
Maybe I should also add a module_param() to unlock the "sudo" flag on SUBMIT, or some other mechanism to prevent accidental use? Suggestions welcome.
So far, the "sudo" flag is only supported on a5xx.. a4xx and before had different instruction sets for PFP and ME (which seem to closely match the PFP and ME instruction sets for r600), and I haven't tried to write an assembler/disassembler for those yet (and therefore haven't needed this feature).
In case anyone else wants to play with this, see:
https://github.com/freedreno/envytools/tree/afuc/afuc
Rob Clark (2):
drm/msm: add a5xx specific debugfs
drm/msm: add sudo flag to submit ioctl
drivers/gpu/drm/msm/Kconfig | 13 ++ drivers/gpu/drm/msm/Makefile | 2 + drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 188 +++++++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 66 ++++++++++ drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 4 + drivers/gpu/drm/msm/adreno/adreno_device.c | 6 + drivers/gpu/drm/msm/msm_debugfs.c | 5 +- drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 9 ++ drivers/gpu/drm/msm/msm_gpu.h | 2 + include/uapi/drm/msm_drm.h | 2 + 11 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
Signature · 1 line
2.13.6
A message that is not in the archive (sent off-list or not yet received): 20171213201302.22001-1-robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
RFC 1/2 drm/msm: add a5xx specific debugfs
Add some debugfs to dump out PFP and ME microcontroller state, as well as some of the queues (MEQ and ROQ). Also add a debugfs file to trigger a GPU reset (and reloading the firmware on next submit).
--- drivers/gpu/drm/msm/Makefile | 2 + drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 188 +++++++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 1 + drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 4 + drivers/gpu/drm/msm/adreno/adreno_device.c | 6 + drivers/gpu/drm/msm/msm_debugfs.c | 5 +- drivers/gpu/drm/msm/msm_gpu.h | 2 + 7 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
drivers/gpu/drm/msm/Makefile +2 -0
@@ -62,6 +62,8 @@ msm-y := \ msm_ringbuffer.o \ msm_submitqueue.o +msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o + msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o
drivers/gpu/drm/msm/adreno/a5xx_debugfs.c new file +188 -0
188 lines not on this page · raw message
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +1 -0
@@ -1179,6 +1179,7 @@ static const struct adreno_gpu_funcs funcs = { .destroy = a5xx_destroy, #ifdef CONFIG_DEBUG_FS .show = a5xx_show, + .debugfs_init = a5xx_debugfs_init, #endif }, .get_timestamp = a5xx_get_timestamp,
drivers/gpu/drm/msm/adreno/a5xx_gpu.h +4 -0
@@ -49,6 +49,10 @@ struct a5xx_gpu {#define to_a5xx_gpu (x) container_of(x, struct a5xx_gpu, base) +#ifdef CONFIG_DEBUG_FS +int a5xx_debugfs_init (struct msm_gpu *gpu,struct drm_minor *minor); +#endif +/* * In order to do lockless preemption we use a simple state machine to progress * through the process.
drivers/gpu/drm/msm/adreno/adreno_device.c +6 -0
@@ -143,6 +143,12 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)return NULL ; } +if (gpu->funcs->debugfs_init) { + gpu->funcs->debugfs_init (gpu, dev->primary); + gpu->funcs->debugfs_init (gpu, dev->render); + gpu->funcs->debugfs_init (gpu, dev->control); + } +return gpu; }
drivers/gpu/drm/msm/msm_debugfs.c +4 -1
@@ -161,8 +161,11 @@ int msm_debugfs_init(struct drm_minor *minor)return ret; } -if (priv->kms->funcs->debugfs_init) +if (priv->kms->funcs->debugfs_init) { ret = priv->kms->funcs->debugfs_init (priv->kms, minor); +if (ret) +return ret; + }return ret; }
drivers/gpu/drm/msm/msm_gpu.h +2 -0
@@ -66,6 +66,8 @@ struct msm_gpu_funcs {#ifdef CONFIG_DEBUG_FS /* show GPU status in debugfs: */ void (*show)(struct msm_gpu *gpu,struct seq_file *m); +/* for generation specific debugfs: */ +int (*debugfs_init)(struct msm_gpu *gpu,struct drm_minor *minor);#endif };
Signature · 6 lines
2.13.6 _______________________________________________ Freedreno mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/freedreno
RFC 2/2 drm/msm: add sudo flag to submit ioctl
In reply to Rob ClarkThis 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_ADMIN and a default=n kconfig option, to prevent it from being used on accident.
--- drivers/gpu/drm/msm/Kconfig | 13 +++++++ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 65 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 9 +++++ include/uapi/drm/msm_drm.h | 2 ++ 5 files changed, 90 insertions(+)
drivers/gpu/drm/msm/Kconfig +13 -0
@@ -28,6 +28,19 @@ config DRM_MSM_REGISTER_LOGGING that can be parsed by envytools demsm tool. If enabled, register logging can be switched on via msm.reglog=y module param. +config DRM_MSM_GPU_SUDO + bool "Enable SUDO flag on submits" + depends on DRM_MSM && EXPERT + default n + help + Enable userspace that has CAP_SYS_ADMIN to submit GPU commands + that are run from RB instead of IB1. This essentially gives + userspace kernel level access, but is useful for firmware + debugging. + + Only use this if you really know what you are doing. This should + *not* be enabled for production kernels. If unsure, say N. + config DRM_MSM_HDMI_HDCP bool "Enable HDMI HDCP support in MSM DRM driver" depends on DRM_MSM && QCOM_SCM
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +65 -0
77 lines not on this page · raw message
drivers/gpu/drm/msm/msm_gem.h +1 -0
@@ -147,6 +147,7 @@ struct msm_gem_submit {struct pid *pid;/* submitting process */ bool valid;/* true if no cmdstream patching needed */ bool dumped;/* true if already dumped */ +bool in_rb;/* "sudo" mode, copy cmds into RB */ struct msm_ringbuffer *ring;unsigned int nr_cmds;unsigned int nr_bos;
drivers/gpu/drm/msm/msm_gem_submit.c +9 -0
@@ -431,6 +431,12 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,if (MSM_PIPE_FLAGS (args->flags) & ~MSM_SUBMIT_FLAGS )return -EINVAL ; +if (args->flags &MSM_SUBMIT_SUDO ) { +if (!IS_ENABLED (CONFIG_DRM_MSM_GPU_SUDO ) || + !capable (CAP_SYS_ADMIN )) +return -EINVAL ; + } + queue =msm_submitqueue_get (ctx, args->queueid);if (!queue)return -ENOENT ;
@@ -472,6 +478,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, goto out_unlock; } +if (args->flags &MSM_SUBMIT_SUDO ) + submit->in_rb = true; + ret =submit_lookup_objects (submit, args, file);if (ret) goto out;
include/uapi/drm/msm_drm.h +2 -0
@@ -201,10 +201,12 @@ struct drm_msm_gem_submit_bo {#define MSM_SUBMIT_NO_IMPLICIT 0x80000000/* disable implicit sync */ #define MSM_SUBMIT_FENCE_FD_IN 0x40000000/* enable input fence_fd */ #define MSM_SUBMIT_FENCE_FD_OUT 0x20000000/* enable output fence_fd */ +#define MSM_SUBMIT_SUDO 0x10000000/* run submitted cmds from RB */ #define MSM_SUBMIT_FLAGS ( \ MSM_SUBMIT_NO_IMPLICIT | \ MSM_SUBMIT_FENCE_FD_IN | \ MSM_SUBMIT_FENCE_FD_OUT | \ + MSM_SUBMIT_SUDO | \ 0)/* Each cmdstream submit consists of a table of buffers involved, and
Signature · 1 line
2.13.6