Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d35d5ad9 authored by Archana Sriram's avatar Archana Sriram
Browse files

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: default avatarArchana Sriram <apsrir@codeaurora.org>
parent ccbf3863
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -262,7 +262,7 @@ static int ctx_print(struct seq_file *s, void *unused)
		   kgsl_context_type(drawctxt->type),
		   kgsl_context_type(drawctxt->type),
		   drawctxt->base.priority,
		   drawctxt->base.priority,
		   drawctxt->base.proc_priv->comm,
		   drawctxt->base.proc_priv->comm,
		   drawctxt->base.proc_priv->pid,
		   pid_nr(drawctxt->base.proc_priv->pid),
		   drawctxt->base.tid);
		   drawctxt->base.tid);


	seq_puts(s, "flags: ");
	seq_puts(s, "flags: ");
+5 −5
Original line number Original line Diff line number Diff line
@@ -300,7 +300,7 @@ static void _retire_timestamp(struct kgsl_drawobj *drawobj)
	info.timestamp = drawobj->timestamp;
	info.timestamp = drawobj->timestamp;


	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_RETIRED,
	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_RETIRED,
				context->proc_priv->pid,
				pid_nr(context->proc_priv->pid),
				context->id, drawobj->timestamp);
				context->id, drawobj->timestamp);


	/*
	/*
@@ -696,7 +696,7 @@ static int sendcmd(struct adreno_device *adreno_dev,
	info.gmu_dispatch_queue = -1;
	info.gmu_dispatch_queue = -1;


	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_SUBMIT,
	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_SUBMIT,
			       context->proc_priv->pid,
			       pid_nr(context->proc_priv->pid),
			       context->id, drawobj->timestamp);
			       context->id, drawobj->timestamp);


	trace_adreno_cmdbatch_submitted(drawobj, &info,
	trace_adreno_cmdbatch_submitted(drawobj, &info,
@@ -1219,7 +1219,7 @@ static void _queue_drawobj(struct adreno_context *drawctxt,
			ADRENO_CONTEXT_DRAWQUEUE_SIZE;
			ADRENO_CONTEXT_DRAWQUEUE_SIZE;
	drawctxt->queued++;
	drawctxt->queued++;
	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_QUEUE,
	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_QUEUE,
				context->proc_priv->pid,
				pid_nr(context->proc_priv->pid),
				context->id, drawobj->timestamp);
				context->id, drawobj->timestamp);
	trace_adreno_cmdbatch_queued(drawobj, drawctxt->queued);
	trace_adreno_cmdbatch_queued(drawobj, drawctxt->queued);
}
}
@@ -1643,7 +1643,7 @@ static inline const char *_kgsl_context_comm(struct kgsl_context *context)
#define pr_fault(_d, _c, fmt, args...) \
#define pr_fault(_d, _c, fmt, args...) \
		dev_err((_d)->dev, "%s[%d]: " fmt, \
		dev_err((_d)->dev, "%s[%d]: " fmt, \
		_kgsl_context_comm((_c)->context), \
		_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,
static void adreno_fault_header(struct kgsl_device *device,
@@ -2321,7 +2321,7 @@ static void retire_cmdobj(struct adreno_device *adreno_dev,
	info.eop = end;
	info.eop = end;


	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_RETIRED,
	msm_perf_events_update(MSM_PERF_GFX, MSM_PERF_RETIRED,
			       context->proc_priv->pid,
			       pid_nr(context->proc_priv->pid),
			       context->id, drawobj->timestamp);
			       context->id, drawobj->timestamp);


	/*
	/*
+1 −1
Original line number Original line Diff line number Diff line
@@ -131,7 +131,7 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev,
	ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
	ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
			drawctxt->base.id, &data_offset);
			drawctxt->base.id, &data_offset);
	ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + 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,
	ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
			drawctxt->base.tid, &data_offset);
			drawctxt->base.tid, &data_offset);
	ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
	ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset,
+16 −12
Original line number Original line Diff line number Diff line
@@ -572,7 +572,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
	if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) {
	if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) {
		dev_err(device->dev,
		dev_err(device->dev,
			     "Per process context limit reached for pid %u\n",
			     "Per process context limit reached for pid %u\n",
			     dev_priv->process_priv->pid);
			     pid_nr(dev_priv->process_priv->pid));
		spin_unlock(&proc_priv->ctxt_count_lock);
		spin_unlock(&proc_priv->ctxt_count_lock);
		return -ENOSPC;
		return -ENOSPC;
	}
	}
@@ -792,6 +792,7 @@ static void kgsl_destroy_process_private(struct kref *kref)
	struct kgsl_process_private *private = container_of(kref,
	struct kgsl_process_private *private = container_of(kref,
			struct kgsl_process_private, refcount);
			struct kgsl_process_private, refcount);


	put_pid(private->pid);
	idr_destroy(&private->mem_idr);
	idr_destroy(&private->mem_idr);
	idr_destroy(&private->syncsource_idr);
	idr_destroy(&private->syncsource_idr);


@@ -821,7 +822,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid)


	spin_lock(&kgsl_driver.proclist_lock);
	spin_lock(&kgsl_driver.proclist_lock);
	list_for_each_entry(p, &kgsl_driver.process_list, list) {
	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))
			if (kgsl_process_private_get(p))
				private = p;
				private = p;
			break;
			break;
@@ -836,13 +837,15 @@ static struct kgsl_process_private *kgsl_process_private_new(
		struct kgsl_device *device)
		struct kgsl_device *device)
{
{
	struct kgsl_process_private *private;
	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 */
	/* Search in the process list */
	list_for_each_entry(private, &kgsl_driver.process_list, list) {
	list_for_each_entry(private, &kgsl_driver.process_list, list) {
		if (private->pid == tgid) {
		if (private->pid == cur_pid) {
			if (!kgsl_process_private_get(private))
			if (!kgsl_process_private_get(private)) {
				put_pid(cur_pid);
				private = ERR_PTR(-EINVAL);
				private = ERR_PTR(-EINVAL);
			}
			return private;
			return private;
		}
		}
	}
	}
@@ -854,7 +857,7 @@ static struct kgsl_process_private *kgsl_process_private_new(


	kref_init(&private->refcount);
	kref_init(&private->refcount);


	private->pid = tgid;
	private->pid = cur_pid;
	get_task_comm(private->comm, current->group_leader);
	get_task_comm(private->comm, current->group_leader);


	spin_lock_init(&private->mem_lock);
	spin_lock_init(&private->mem_lock);
@@ -865,12 +868,13 @@ static struct kgsl_process_private *kgsl_process_private_new(
	idr_init(&private->syncsource_idr);
	idr_init(&private->syncsource_idr);


	/* Allocate a pagetable for the new process object */
	/* 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)) {
	if (IS_ERR(private->pagetable)) {
		int err = PTR_ERR(private->pagetable);
		int err = PTR_ERR(private->pagetable);


		idr_destroy(&private->mem_idr);
		idr_destroy(&private->mem_idr);
		idr_destroy(&private->syncsource_idr);
		idr_destroy(&private->syncsource_idr);
		put_pid(private->pid);


		kfree(private);
		kfree(private);
		private = ERR_PTR(err);
		private = ERR_PTR(err);
@@ -2065,7 +2069,7 @@ long gpumem_free_entry(struct kgsl_mem_entry *entry)
		return -EBUSY;
		return -EBUSY;


	trace_kgsl_mem_free(entry);
	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 ?
				entry->memdesc.pagetable->name : 0,
				entry->memdesc.pagetable->name : 0,
			entry->memdesc.gpuaddr, entry->memdesc.size,
			entry->memdesc.gpuaddr, entry->memdesc.size,
@@ -2088,7 +2092,7 @@ static void gpumem_free_func(struct kgsl_device *device,
	/* Free the memory for all event types */
	/* Free the memory for all event types */
	trace_kgsl_mem_timestamp_free(device, entry, KGSL_CONTEXT_ID(context),
	trace_kgsl_mem_timestamp_free(device, entry, KGSL_CONTEXT_ID(context),
		timestamp, 0);
		timestamp, 0);
	kgsl_memfree_add(entry->priv->pid,
	kgsl_memfree_add(pid_nr(entry->priv->pid),
			entry->memdesc.pagetable ?
			entry->memdesc.pagetable ?
				entry->memdesc.pagetable->name : 0,
				entry->memdesc.pagetable->name : 0,
			entry->memdesc.gpuaddr, entry->memdesc.size,
			entry->memdesc.gpuaddr, entry->memdesc.size,
@@ -2188,7 +2192,7 @@ static bool gpuobj_free_fence_func(void *priv)
	struct kgsl_mem_entry *entry = priv;
	struct kgsl_mem_entry *entry = priv;


	trace_kgsl_mem_free(entry);
	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 ?
				entry->memdesc.pagetable->name : 0,
				entry->memdesc.pagetable->name : 0,
			entry->memdesc.gpuaddr, entry->memdesc.size,
			entry->memdesc.gpuaddr, entry->memdesc.size,
@@ -3933,14 +3937,14 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr,
		if (IS_ERR_VALUE(val))
		if (IS_ERR_VALUE(val))
			dev_err_ratelimited(device->dev,
			dev_err_ratelimited(device->dev,
					       "get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
					       "get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
					       private->pid, addr, pgoff, len,
					       pid_nr(private->pid), addr, pgoff, len,
					       (int) val);
					       (int) val);
	} else {
	} else {
		val = get_svm_unmapped_area(file, entry, addr, len, flags);
		val = get_svm_unmapped_area(file, entry, addr, len, flags);
		if (IS_ERR_VALUE(val))
		if (IS_ERR_VALUE(val))
			dev_err_ratelimited(device->dev,
			dev_err_ratelimited(device->dev,
					       "_get_svm_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
					       "_get_svm_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
					       private->pid, addr, pgoff, len,
					       pid_nr(private->pid), addr, pgoff, len,
					       (int) val);
					       (int) val);
	}
	}


+2 −2
Original line number Original line Diff line number Diff line
@@ -339,7 +339,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private)
	unsigned char name[16];
	unsigned char name[16];
	struct dentry *dentry;
	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);
	private->debug_root = debugfs_create_dir(name, proc_d_debugfs);


@@ -359,7 +359,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private)
	}
	}


	dentry = debugfs_create_file("mem", 0444, private->debug_root,
	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))
	if (IS_ERR_OR_NULL(dentry))
		WARN((dentry == NULL),
		WARN((dentry == NULL),
Loading