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]
Unified · Split
| @@ -290,11 +290,48 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, · 289 unmodified lines | |||
| 290 | int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, | 290 | int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, |
| 291 | uint32_t param, uint64_t value, uint32_t len) | 291 | uint32_t param, uint64_t value, uint32_t len) |
| 292 | { | 292 | { |
| 293 | /* No pointer params yet */ | 293 | switch (param) { |
| 294 | if (len != 0) | 294 | case MSM_PARAM_COMM: |
| 295 | return -EINVAL; | 295 | case MSM_PARAM_CMDLINE: |
| 296 | /* kstrdup_quotable_cmdline() limits to PAGE_SIZE, so | ||
| 297 | * that should be a reasonable upper bound | ||
| 298 | */ | ||
| 299 | if (len > PAGE_SIZE) | ||
| 300 | return -EINVAL; | ||
| 301 | break; | ||
| 302 | default: | ||
| 303 | if (len != 0) | ||
| 304 | return -EINVAL; | ||
| 305 | } | ||
| 296 | 306 | ||
| 297 | switch (param) { | 307 | switch (param) { |
| 308 | case MSM_PARAM_COMM: | ||
| 309 | case MSM_PARAM_CMDLINE: { | ||
| 310 | char *str, **paramp; | ||
| 311 | |||
| 312 | str = kmalloc(len + 1, GFP_KERNEL); | ||
| 313 | if (!str) | ||
| 314 | return -ENOMEM; | ||
| 315 | |||
| 316 | if (copy_from_user(str, u64_to_user_ptr(value), len)) { | ||
| 317 | kfree(str); | ||
| 318 | return -EFAULT; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* Ensure string is null terminated: */ | ||
| 322 | str[len] = '\0'; | ||
| 323 | |||
| 324 | if (param == MSM_PARAM_COMM) { | ||
| 325 | paramp = &ctx->comm; | ||
| 326 | } else { | ||
| 327 | paramp = &ctx->cmdline; | ||
| 328 | } | ||
| 329 | |||
| 330 | kfree(*paramp); | ||
| 331 | *paramp = str; | ||
| 332 | |||
| 333 | return 0; | ||
| 334 | } | ||
| 298 | case MSM_PARAM_SYSPROF: | 335 | case MSM_PARAM_SYSPROF: |
| 299 | if (!capable(CAP_SYS_ADMIN)) | 336 | if (!capable(CAP_SYS_ADMIN)) |
| 300 | return -EPERM; | 337 | return -EPERM; |
| @@ -353,14 +353,22 @@ static void retire_submits(struct msm_gpu *gpu); · 352 unmodified lines | |||
| 353 | 353 | ||
| 354 | static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char **cmd) | 354 | static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char **cmd) |
| 355 | { | 355 | { |
| 356 | struct msm_file_private *ctx = submit->queue->ctx; | ||
| 356 | struct task_struct *task; | 357 | struct task_struct *task; |
| 357 | 358 | ||
| 359 | /* Note that kstrdup will return NULL if argument is NULL: */ | ||
| 360 | *comm = kstrdup(ctx->comm, GFP_KERNEL); | ||
| 361 | *cmd = kstrdup(ctx->cmdline, GFP_KERNEL); | ||
| 362 | |||
| 358 | task = get_pid_task(submit->pid, PIDTYPE_PID); | 363 | task = get_pid_task(submit->pid, PIDTYPE_PID); |
| 359 | if (!task) | 364 | if (!task) |
| 360 | return; | 365 | return; |
| 361 | 366 | ||
| 362 | *comm = kstrdup(task->comm, GFP_KERNEL); | 367 | if (!*comm) |
| 363 | *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); | 368 | *comm = kstrdup(task->comm, GFP_KERNEL); |
| 369 | |||
| 370 | if (!*cmd) | ||
| 371 | *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); | ||
| 364 | 372 | ||
| 365 | put_task_struct(task); | 373 | put_task_struct(task); |
| 366 | } | 374 | } |
| @@ -355,6 +355,12 @@ struct msm_file_private { · 354 unmodified lines | |||
| 355 | */ | 355 | */ |
| 356 | int sysprof; | 356 | int sysprof; |
| 357 | 357 | ||
| 358 | /** comm: Overridden task comm, see MSM_PARAM_COMM */ | ||
| 359 | char *comm; | ||
| 360 | |||
| 361 | /** cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE */ | ||
| 362 | char *cmdline; | ||
| 363 | |||
| 358 | /** | 364 | /** |
| 359 | * entities: | 365 | * entities: |
| 360 | * | 366 | * |
| @@ -61,6 +61,8 @@ void __msm_file_private_destroy(struct kref *kref) · 60 unmodified lines | |||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | msm_gem_address_space_put(ctx->aspace); | 63 | msm_gem_address_space_put(ctx->aspace); |
| 64 | kfree(ctx->comm); | ||
| 65 | kfree(ctx->cmdline); | ||
| 64 | kfree(ctx); | 66 | kfree(ctx); |
| 65 | } | 67 | } |
| 66 | 68 | ||
| @@ -82,6 +82,8 @@ struct drm_msm_timespec { · 81 unmodified lines | |||
| 82 | #define MSM_PARAM_FAULTS 0x09 /* RO */ | 82 | #define MSM_PARAM_FAULTS 0x09 /* RO */ |
| 83 | #define MSM_PARAM_SUSPENDS 0x0a /* RO */ | 83 | #define MSM_PARAM_SUSPENDS 0x0a /* RO */ |
| 84 | #define MSM_PARAM_SYSPROF 0x0b /* WO: 1 preserves perfcntrs, 2 also disables suspend */ | 84 | #define MSM_PARAM_SYSPROF 0x0b /* WO: 1 preserves perfcntrs, 2 also disables suspend */ |
| 85 | #define MSM_PARAM_COMM 0x0c /* WO: override for task->comm */ | ||
| 86 | #define MSM_PARAM_CMDLINE 0x0d /* WO: override for task cmdline */ | ||
| 85 | 87 | ||
| 86 | /* For backwards compat. The original support for preemption was based on | 88 | /* For backwards compat. The original support for preemption was based on |
| 87 | * a single ring per priority level so # of priority levels equals the # | 89 | * a single ring per priority level so # of priority levels equals the # |