From b8501b9902ccb2acc4a5ca1e9448b3e2977b2647 Mon Sep 17 00:00:00 2001 From: Archana Sriram Date: Sun, 18 Oct 2020 23:34:04 +0530 Subject: [PATCH] msm: kgsl: Compare pid pointer instead of TGID for a new process There is a possibility of sharing process_private between two unrelated processes due to PID wrapping. In kgsl_process_private_new(), instead of checking numeric TGID, compare the unique pid pointer of the current process with that of the existing processes in kgsl process list to allow sharing of process_private data judiciously. Also, in all required functions get TGID/PID of a process from its struct pid. Change-Id: I0e3d5d79275cdb3f3c304fb36322ad56b0d0b227 Signed-off-by: Archana Sriram --- drivers/gpu/msm/adreno_debugfs.c | 4 ++-- drivers/gpu/msm/adreno_dispatch.c | 4 ++-- drivers/gpu/msm/adreno_profile.c | 4 ++-- drivers/gpu/msm/kgsl.c | 31 +++++++++++++++++++------------ drivers/gpu/msm/kgsl_debugfs.c | 9 +++++---- drivers/gpu/msm/kgsl_device.h | 10 +++++----- drivers/gpu/msm/kgsl_iommu.c | 6 +++--- drivers/gpu/msm/kgsl_sharedmem.c | 2 +- drivers/gpu/msm/kgsl_trace.h | 10 +++++----- 9 files changed, 44 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index 2dd651a446b1..420078b9fee4 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -275,7 +275,7 @@ static int ctx_print(struct seq_file *s, void *unused) ctx_type_str(drawctxt->type), drawctxt->base.priority, drawctxt->base.proc_priv->comm, - drawctxt->base.proc_priv->pid, + pid_nr(drawctxt->base.proc_priv->pid), drawctxt->base.tid); seq_puts(s, "flags: "); diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 4e4be1e64cef..ee12563ea962 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1686,7 +1686,7 @@ static inline const char *_kgsl_context_comm(struct kgsl_context *context) #define pr_fault(_d, _c, fmt, args...) \ dev_err((_d)->dev, "%s[%d]: " fmt, \ _kgsl_context_comm((_c)->context), \ - (_c)->context->proc_priv->pid, ##args) + pid_nr((_c)->context->proc_priv->pid), ##args) static void adreno_fault_header(struct kgsl_device *device, diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c index 96c37aacf7dd..2c5ab243282a 100644 --- a/drivers/gpu/msm/adreno_profile.c +++ b/drivers/gpu/msm/adreno_profile.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018,2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -168,7 +168,7 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev, ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, drawctxt->base.id, &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, - drawctxt->base.proc_priv->pid, &data_offset); + pid_nr(drawctxt->base.proc_priv->pid), &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, drawctxt->base.tid, &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 4cdfd52df7c8..d4b974135c50 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -613,7 +613,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { KGSL_DRV_ERR_RATELIMIT(device, "Per process context limit reached for pid %u", - dev_priv->process_priv->pid); + pid_nr(dev_priv->process_priv->pid)); spin_unlock(&proc_priv->ctxt_count_lock); return -ENOSPC; } @@ -973,6 +973,7 @@ static void kgsl_destroy_process_private(struct kref *kref) struct kgsl_process_private *private = container_of(kref, struct kgsl_process_private, refcount); + put_pid(private->pid); idr_destroy(&private->mem_idr); idr_destroy(&private->syncsource_idr); @@ -1002,7 +1003,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid) mutex_lock(&kgsl_driver.process_mutex); list_for_each_entry(p, &kgsl_driver.process_list, list) { - if (p->pid == pid) { + if (pid_nr(p->pid) == pid) { if (kgsl_process_private_get(p)) private = p; break; @@ -1016,13 +1017,15 @@ static struct kgsl_process_private *kgsl_process_private_new( struct kgsl_device *device) { struct kgsl_process_private *private; - pid_t tgid = task_tgid_nr(current); + struct pid *cur_pid = get_task_pid(current->group_leader, PIDTYPE_PID); /* Search in the process list */ list_for_each_entry(private, &kgsl_driver.process_list, list) { - if (private->pid == tgid) { - if (!kgsl_process_private_get(private)) + if (private->pid == cur_pid) { + if (!kgsl_process_private_get(private)) { + put_pid(cur_pid); private = ERR_PTR(-EINVAL); + } return private; } } @@ -1034,7 +1037,7 @@ static struct kgsl_process_private *kgsl_process_private_new( kref_init(&private->refcount); - private->pid = tgid; + private->pid = cur_pid; get_task_comm(private->comm, current->group_leader); spin_lock_init(&private->mem_lock); @@ -1045,12 +1048,14 @@ static struct kgsl_process_private *kgsl_process_private_new( idr_init(&private->syncsource_idr); /* Allocate a pagetable for the new process object */ - private->pagetable = kgsl_mmu_getpagetable(&device->mmu, tgid); + private->pagetable = kgsl_mmu_getpagetable(&device->mmu, + pid_nr(cur_pid)); if (IS_ERR(private->pagetable)) { int err = PTR_ERR(private->pagetable); idr_destroy(&private->mem_idr); idr_destroy(&private->syncsource_idr); + put_pid(private->pid); kfree(private); private = ERR_PTR(err); @@ -2047,7 +2052,7 @@ long gpumem_free_entry(struct kgsl_mem_entry *entry) return -EBUSY; trace_kgsl_mem_free(entry); - kgsl_memfree_add(entry->priv->pid, + kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.pagetable ? entry->memdesc.pagetable->name : 0, entry->memdesc.gpuaddr, entry->memdesc.size, @@ -2070,7 +2075,7 @@ static void gpumem_free_func(struct kgsl_device *device, /* Free the memory for all event types */ trace_kgsl_mem_timestamp_free(device, entry, KGSL_CONTEXT_ID(context), timestamp, 0); - kgsl_memfree_add(entry->priv->pid, + kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.pagetable ? entry->memdesc.pagetable->name : 0, entry->memdesc.gpuaddr, entry->memdesc.size, @@ -2170,7 +2175,7 @@ static bool gpuobj_free_fence_func(void *priv) struct kgsl_mem_entry *entry = priv; trace_kgsl_mem_free(entry); - kgsl_memfree_add(entry->priv->pid, + kgsl_memfree_add(pid_nr(entry->priv->pid), entry->memdesc.pagetable ? entry->memdesc.pagetable->name : 0, entry->memdesc.gpuaddr, entry->memdesc.size, @@ -4686,13 +4691,15 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr, if (IS_ERR_VALUE(val)) KGSL_DRV_ERR_RATELIMIT(device, "get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n", - private->pid, addr, pgoff, len, (int) val); + pid_nr(private->pid), addr, + pgoff, len, (int) val); } else { val = _get_svm_area(private, entry, addr, len, flags); if (IS_ERR_VALUE(val)) KGSL_DRV_ERR_RATELIMIT(device, "_get_svm_area: pid %d mmap_base %lx addr %lx pgoff %lx len %ld failed error %d\n", - private->pid, current->mm->mmap_base, addr, + pid_nr(private->pid), + current->mm->mmap_base, addr, pgoff, len, (int) val); } diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index fbd5a44ba0fa..678fba2e04c0 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2008-2017, 2019 The Linux Foundation. All rights reserved. +/* Copyright (c) 2002, 2008-2017, 2019-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -398,7 +398,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private) unsigned char name[16]; struct dentry *dentry; - snprintf(name, sizeof(name), "%d", private->pid); + snprintf(name, sizeof(name), "%d", pid_nr(private->pid)); private->debug_root = debugfs_create_dir(name, proc_d_debugfs); @@ -418,14 +418,15 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private) } dentry = debugfs_create_file("mem", 0444, private->debug_root, - (void *) ((unsigned long) private->pid), &process_mem_fops); + (void *) ((unsigned long) pid_nr(private->pid)), + &process_mem_fops); if (IS_ERR_OR_NULL(dentry)) WARN((dentry == NULL), "Unable to create 'mem' file for %s\n", name); dentry = debugfs_create_file("sparse_mem", 0444, private->debug_root, - (void *) ((unsigned long) private->pid), + (void *) ((unsigned long) pid_nr(private->pid)), &process_sparse_mem_fops); if (IS_ERR_OR_NULL(dentry)) diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 09b4afd7005c..b3e3ea603334 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -440,13 +440,13 @@ struct kgsl_context { #define pr_context(_d, _c, fmt, args...) \ dev_err((_d)->dev, "%s[%d]: " fmt, \ _context_comm((_c)), \ - (_c)->proc_priv->pid, ##args) + pid_nr((_c)->proc_priv->pid), ##args) /** * struct kgsl_process_private - Private structure for a KGSL process (across * all devices) * @priv: Internal flags, use KGSL_PROCESS_* values - * @pid: ID for the task owner of the process + * @pid: Identification structure for the task owner of the process * @comm: task name of the process * @mem_lock: Spinlock to protect the process memory lists * @refcount: kref object for reference counting the process @@ -464,7 +464,7 @@ struct kgsl_context { */ struct kgsl_process_private { unsigned long priv; - pid_t pid; + struct pid *pid; char comm[TASK_COMM_LEN]; spinlock_t mem_lock; struct kref refcount; @@ -586,7 +586,7 @@ static inline void kgsl_process_sub_stats(struct kgsl_process_private *priv, struct mm_struct *mm; atomic64_sub(size, &priv->stats[type].cur); - pid_struct = find_get_pid(priv->pid); + pid_struct = find_get_pid(pid_nr(priv->pid)); if (pid_struct) { task = get_pid_task(pid_struct, PIDTYPE_PID); if (task) { diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index f8ef12a4640d..31a4206bbc48 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -668,7 +668,7 @@ static void _get_entries(struct kgsl_process_private *private, prev->flags = p->memdesc.flags; prev->priv = p->memdesc.priv; prev->pending_free = p->pending_free; - prev->pid = private->pid; + prev->pid = pid_nr(private->pid); __kgsl_get_memory_usage(prev); } @@ -678,7 +678,7 @@ static void _get_entries(struct kgsl_process_private *private, next->flags = n->memdesc.flags; next->priv = n->memdesc.priv; next->pending_free = n->pending_free; - next->pid = private->pid; + next->pid = pid_nr(private->pid); __kgsl_get_memory_usage(next); } } @@ -844,7 +844,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, if (!kgsl_process_private_get(private)) private = NULL; else - pid = private->pid; + pid = pid_nr(private->pid); if (kgsl_iommu_suppress_pagefault(addr, write, private)) { iommu->pagefault_suppression_count++; diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index f96baacb7842..02a038220ca2 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -275,7 +275,7 @@ void kgsl_process_init_sysfs(struct kgsl_device *device, /* Keep private valid until the sysfs enries are removed. */ kgsl_process_private_get(private); - snprintf(name, sizeof(name), "%d", private->pid); + snprintf(name, sizeof(name), "%d", pid_nr(private->pid)); if (kobject_init_and_add(&private->kobj, &ktype_mem_entry, kgsl_driver.prockobj, name)) { diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h index d4cd17f52c99..ca37cf995481 100644 --- a/drivers/gpu/msm/kgsl_trace.h +++ b/drivers/gpu/msm/kgsl_trace.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -416,7 +416,7 @@ TRACE_EVENT(kgsl_mem_alloc, TP_fast_assign( __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -509,7 +509,7 @@ TRACE_EVENT(kgsl_mem_map, __entry->size = mem_entry->memdesc.size; __entry->fd = fd; __entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -544,7 +544,7 @@ TRACE_EVENT(kgsl_mem_free, __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; __entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -579,7 +579,7 @@ TRACE_EVENT(kgsl_mem_sync_cache, __entry->gpuaddr = mem_entry->memdesc.gpuaddr; kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); __entry->id = mem_entry->id; __entry->op = op; __entry->offset = offset;