]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/msm: Add a way to override processes comm/cmdline
authorRob Clark <robdclark@chromium.org>
Thu, 17 Mar 2022 16:51:40 +0000 (09:51 -0700)
committerRob Clark <robdclark@chromium.org>
Thu, 21 Apr 2022 22:01:09 +0000 (15:01 -0700)
In the cause of using the GPU via virtgpu, the host side process is
really a sort of proxy, and not terribly interesting from the PoV of
crash/fault logging.  Add a way to override these per process so that
we can see the guest process's name.

v2: Handle kmalloc failure, add comment to explain kstrdup returns
    NULL if passed NULL [Dan Carpenter]

Signed-off-by: Rob Clark <robdclark@chromium.org>
Link: https://lore.kernel.org/r/20220317165144.222101-4-robdclark@gmail.com
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_gpu.h
drivers/gpu/drm/msm/msm_submitqueue.c
include/uapi/drm/msm_drm.h

index 3d307b34854d2731e69249568e3a9d5d772e1ba5..45f2c6084aa7df0a62d31076c23ffb4eb9188751 100644 (file)
@@ -290,11 +290,48 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
 int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
                     uint32_t param, uint64_t value, uint32_t len)
 {
-       /* No pointer params yet */
-       if (len != 0)
-               return -EINVAL;
+       switch (param) {
+       case MSM_PARAM_COMM:
+       case MSM_PARAM_CMDLINE:
+               /* kstrdup_quotable_cmdline() limits to PAGE_SIZE, so
+                * that should be a reasonable upper bound
+                */
+               if (len > PAGE_SIZE)
+                       return -EINVAL;
+               break;
+       default:
+               if (len != 0)
+                       return -EINVAL;
+       }
 
        switch (param) {
+       case MSM_PARAM_COMM:
+       case MSM_PARAM_CMDLINE: {
+               char *str, **paramp;
+
+               str = kmalloc(len + 1, GFP_KERNEL);
+               if (!str)
+                       return -ENOMEM;
+
+               if (copy_from_user(str, u64_to_user_ptr(value), len)) {
+                       kfree(str);
+                       return -EFAULT;
+               }
+
+               /* Ensure string is null terminated: */
+               str[len] = '\0';
+
+               if (param == MSM_PARAM_COMM) {
+                       paramp = &ctx->comm;
+               } else {
+                       paramp = &ctx->cmdline;
+               }
+
+               kfree(*paramp);
+               *paramp = str;
+
+               return 0;
+       }
        case MSM_PARAM_SYSPROF:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
index 7a88dd6568c0f5be8f092a2597d1834766e003c1..f292b70c1e6d6eaa0f4057cca7927fbcfe62611a 100644 (file)
@@ -353,14 +353,22 @@ static void retire_submits(struct msm_gpu *gpu);
 
 static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char **cmd)
 {
+       struct msm_file_private *ctx = submit->queue->ctx;
        struct task_struct *task;
 
+       /* Note that kstrdup will return NULL if argument is NULL: */
+       *comm = kstrdup(ctx->comm, GFP_KERNEL);
+       *cmd  = kstrdup(ctx->cmdline, GFP_KERNEL);
+
        task = get_pid_task(submit->pid, PIDTYPE_PID);
        if (!task)
                return;
 
-       *comm = kstrdup(task->comm, GFP_KERNEL);
-       *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
+       if (!*comm)
+               *comm = kstrdup(task->comm, GFP_KERNEL);
+
+       if (!*cmd)
+               *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
 
        put_task_struct(task);
 }
index ab5d31f5df813faf956e66fa58798bc17163751b..321e41de6d42369e7763ead585997ca3512f5560 100644 (file)
@@ -355,6 +355,12 @@ struct msm_file_private {
         */
        int sysprof;
 
+       /** comm: Overridden task comm, see MSM_PARAM_COMM */
+       char *comm;
+
+       /** cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE */
+       char *cmdline;
+
        /**
         * entities:
         *
index 79b6ccd6ce64f93a7456c9057a66fa7f4fbc982f..f486a3cd4e5508995c0edd23474d6a445fe705ae 100644 (file)
@@ -61,6 +61,8 @@ void __msm_file_private_destroy(struct kref *kref)
        }
 
        msm_gem_address_space_put(ctx->aspace);
+       kfree(ctx->comm);
+       kfree(ctx->cmdline);
        kfree(ctx);
 }
 
index 0aa1a8cb4e0df9bd0a82f1a11ef45e1127f3a1f2..794ad1948497391061a6460faf0de91e5e89a007 100644 (file)
@@ -82,6 +82,8 @@ struct drm_msm_timespec {
 #define MSM_PARAM_FAULTS     0x09  /* RO */
 #define MSM_PARAM_SUSPENDS   0x0a  /* RO */
 #define MSM_PARAM_SYSPROF    0x0b  /* WO: 1 preserves perfcntrs, 2 also disables suspend */
+#define MSM_PARAM_COMM       0x0c  /* WO: override for task->comm */
+#define MSM_PARAM_CMDLINE    0x0d  /* WO: override for task cmdline */
 
 /* For backwards compat.  The original support for preemption was based on
  * a single ring per priority level so # of priority levels equals the #