From: GuoHan Zhao <[email protected]>

ethosu_sram_init() returns -ENOMEM if allocation from a declared SRAM
pool fails. ethosu_init() ignores the error after recording the pool size.
Probe then registers a device with a nonzero SRAM size and a zero sramphys
address, allowing jobs to program address zero for SRAM.

Propagate the error and synchronously suspend the device before the probe
path releases the scheduler.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: [email protected]
Reported-by: Sashiko <[email protected]>
Link: 
https://sashiko.dev/#/patchset/[email protected]?part=1
Signed-off-by: GuoHan Zhao <[email protected]>
---
Sashiko report:

> This is a pre-existing issue, but was not introduced by this patch.
>
> In ethosu_sram_init(), if gen_pool_dma_alloc() fails, it returns an
> error. However, ethosu_init() ignores this return value.
>
> Because npu_info.sram_size was already set to gen_pool_size(), it remains
> non-zero while sramphys remains 0.
>
> When a user submits a job requesting sram, the size check passes, and
> ethosu_job_hw_submit() configures the hardware to use physical sram
> address 0x0.
>
> Could this result in a memory corruption regression or an IOMMU fault?

 drivers/accel/ethosu/ethosu_drv.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/accel/ethosu/ethosu_drv.c 
b/drivers/accel/ethosu/ethosu_drv.c
index d1153b15ca3e..479156f79bc1 100644
--- a/drivers/accel/ethosu/ethosu_drv.c
+++ b/drivers/accel/ethosu/ethosu_drv.c
@@ -320,7 +320,9 @@ static int ethosu_init(struct ethosu_device *ethosudev)
        ethosudev->npu_info.id = id = readl_relaxed(ethosudev->regs + 
NPU_REG_ID);
        ethosudev->npu_info.config = config = readl_relaxed(ethosudev->regs + 
NPU_REG_CONFIG);
 
-       ethosu_sram_init(ethosudev);
+       ret = ethosu_sram_init(ethosudev);
+       if (ret)
+               goto err_runtime_suspend;
 
        dev_info(ethosudev->base.dev,
                 "Ethos-U NPU, arch v%ld.%ld.%ld, rev r%ldp%ld, cmd stream 
ver%ld, %d MACs, %dKB SRAM\n",
@@ -335,6 +337,10 @@ static int ethosu_init(struct ethosu_device *ethosudev)
 
        return 0;
 
+err_runtime_suspend:
+       pm_runtime_dont_use_autosuspend(ethosudev->base.dev);
+       pm_runtime_put_sync_suspend(ethosudev->base.dev);
+       return ret;
 err_suspend:
        pm_runtime_dont_use_autosuspend(ethosudev->base.dev);
        ethosu_device_suspend(ethosudev->base.dev);
-- 
2.43.0

Reply via email to