[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20251215-rocket-error-path-v1-2-eec3bf29dc3b@cherry.de>
Date: Mon, 15 Dec 2025 17:36:15 +0100
From: Quentin Schulz <foss+kernel@...il.net>
To: Tomeu Vizoso <tomeu@...euvizoso.net>, Oded Gabbay <ogabbay@...nel.org>,
Jeff Hugo <jeff.hugo@....qualcomm.com>
Cc: dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
linux-rockchip@...ts.infradead.org,
Quentin Schulz <quentin.schulz@...rry.de>, stable@...r.kernel.org
Subject: [PATCH 2/2] accel/rocket: fix unwinding in error path in
rocket_probe
From: Quentin Schulz <quentin.schulz@...rry.de>
When rocket_core_init() fails (as could be the case with EPROBE_DEFER),
we need to properly unwind by decrementing the counter we just
incremented and if this is the first core we failed to probe, remove the
rocket DRM device with rocket_device_fini() as well. This matches the
logic in rocket_remove(). Failing to properly unwind results in
out-of-bounds accesses.
Fixes: 0810d5ad88a1 ("accel/rocket: Add job submission IOCTL")
Cc: stable@...r.kernel.org
Signed-off-by: Quentin Schulz <quentin.schulz@...rry.de>
---
Note that this means that, technically, the first core (in HW) may not
be the first core in the kernel (if EPROBE_DEFER is returned by the
first core's probe for example). This may be a real issue if we rely on
this. E.g. I see the iommu domain is set in in rocket_open() with
rocket_iommu_domain_create(rdev->cores[0].dev) which could be expecting
the main core (but it isn't clear from the commit logs, so maybe all
cores may be totally independent). In any case, this patch is keeping
the status quo.
---
drivers/accel/rocket/rocket_drv.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index 5c0b63f0a8f00..f6ef4c7aeef11 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include "rocket_device.h"
#include "rocket_drv.h"
#include "rocket_gem.h"
#include "rocket_job.h"
@@ -158,6 +159,8 @@ static const struct drm_driver rocket_drm_driver = {
static int rocket_probe(struct platform_device *pdev)
{
+ int ret;
+
if (rdev == NULL) {
/* First core probing, initialize DRM device. */
rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
@@ -177,7 +180,17 @@ static int rocket_probe(struct platform_device *pdev)
rdev->num_cores++;
- return rocket_core_init(&rdev->cores[core]);
+ ret = rocket_core_init(&rdev->cores[core]);
+ if (ret) {
+ rdev->num_cores--;
+
+ if (rdev->num_cores == 0) {
+ rocket_device_fini(rdev);
+ rdev = NULL;
+ }
+ }
+
+ return ret;
}
static void rocket_remove(struct platform_device *pdev)
--
2.52.0
Powered by blists - more mailing lists