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

Unverified Commit cb23bc8b authored by Kamal Agrawal's avatar Kamal Agrawal
Browse files

msm: kgsl: Fix possible NULL pointer dereference



Return value of alloc_workqueue is not checked and as a result,
a possible NULL pointer dereference could occur.

Change-Id: I608d12601227f125625a97c1d0da37e3386cf306
Signed-off-by: default avatarKamal Agrawal <kamaagra@codeaurora.org>
parent 455a57bb
Loading
Loading
Loading
Loading
+35 −4
Original line number Diff line number Diff line
@@ -4387,6 +4387,15 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
	idr_init(&device->timelines);
	spin_lock_init(&device->timelines_lock);

	device->events_wq = alloc_workqueue("kgsl-events",
		WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS | WQ_HIGHPRI, 0);

	if (!device->events_wq) {
		dev_err(device->dev, "Failed to allocate events workqueue\n");
		status = -ENOMEM;
		goto error_pwrctrl_close;
	}

	kgsl_device_debugfs_init(device);

	dma_set_coherent_mask(&pdev->dev, KGSL_DMA_BIT_MASK);
@@ -4394,9 +4403,6 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
	/* Set up the GPU events for the device */
	kgsl_device_events_probe(device);

	device->events_wq = alloc_workqueue("kgsl-events",
		WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS | WQ_HIGHPRI, 0);

	/* Initialize common sysfs entries */
	kgsl_pwrctrl_init_sysfs(device);

@@ -4411,7 +4417,10 @@ int kgsl_device_platform_probe(struct kgsl_device *device)

void kgsl_device_platform_remove(struct kgsl_device *device)
{
	if (device->events_wq) {
		destroy_workqueue(device->events_wq);
		device->events_wq = NULL;
	}

	kgsl_device_snapshot_close(device);

@@ -4441,6 +4450,16 @@ void kgsl_core_exit(void)
{
	kgsl_exit_page_pools();

	if (kgsl_driver.workqueue) {
		destroy_workqueue(kgsl_driver.workqueue);
		kgsl_driver.workqueue = NULL;
	}

	if (kgsl_driver.mem_workqueue) {
		destroy_workqueue(kgsl_driver.mem_workqueue);
		kgsl_driver.mem_workqueue = NULL;
	}

	kgsl_events_exit();
	kgsl_core_debugfs_close();

@@ -4540,9 +4559,21 @@ int __init kgsl_core_init(void)
	kgsl_driver.workqueue = alloc_workqueue("kgsl-workqueue",
		WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0);

	if (!kgsl_driver.workqueue) {
		pr_err("kgsl: Failed to allocate kgsl workqueue\n");
		result = -ENOMEM;
		goto err;
	}

	kgsl_driver.mem_workqueue = alloc_workqueue("kgsl-mementry",
		WQ_UNBOUND | WQ_MEM_RECLAIM, 0);

	if (!kgsl_driver.mem_workqueue) {
		pr_err("kgsl: Failed to allocate mem workqueue\n");
		result = -ENOMEM;
		goto err;
	}

	kthread_init_worker(&kgsl_driver.worker);

	kgsl_driver.worker_thread = kthread_run(kthread_worker_fn,
+12 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2010-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/devfreq_cooling.h>
@@ -855,6 +855,10 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
			adreno_tz_data.bus.floating = false;
	}

	pwrscale->devfreq_wq = create_freezable_workqueue("kgsl_devfreq_wq");
	if (!pwrscale->devfreq_wq)
		return -ENOMEM;

	devfreq = devfreq_add_device(&pdev->dev, &gpu_profile->profile,
			governor, &adreno_tz_data);
	if (IS_ERR(devfreq)) {
@@ -876,7 +880,6 @@ int kgsl_pwrscale_init(struct kgsl_device *device, struct platform_device *pdev,
	ret = sysfs_create_link(&device->dev->kobj,
			&devfreq->dev.kobj, "devfreq");

	pwrscale->devfreq_wq = create_freezable_workqueue("kgsl_devfreq_wq");
	INIT_WORK(&pwrscale->devfreq_suspend_ws, do_devfreq_suspend);
	INIT_WORK(&pwrscale->devfreq_resume_ws, do_devfreq_resume);
	INIT_WORK(&pwrscale->devfreq_notify_ws, do_devfreq_notify);
@@ -923,8 +926,13 @@ void kgsl_pwrscale_close(struct kgsl_device *device)
		devfreq_cooling_unregister(pwrscale->cooling_dev);

	kgsl_pwrscale_midframe_timer_cancel(device);

	if (pwrscale->devfreq_wq) {
		flush_workqueue(pwrscale->devfreq_wq);
		destroy_workqueue(pwrscale->devfreq_wq);
		pwrscale->devfreq_wq = NULL;
	}

	devfreq_remove_device(device->pwrscale.devfreqptr);
	kfree(kgsl_midframe);
	kgsl_midframe = NULL;