diff options
author | Sasha Levin <sashal@kernel.org> | 2025-08-05 08:58:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-08-06 04:57:14 +0300 |
commit | 7881cd6886a89eda848192d3f5759ce08672e084 (patch) | |
tree | 3b767e95e64923f5ddb9d7100a36bf1852b2fae5 | |
parent | adf12a394c8eb4b857b8f70cc6594a9ab25e3fc6 (diff) |
media: venus: Fix OPP table error handling
The venus driver fails to check if dev_pm_opp_find_freq_{ceil,floor}()
returns an error pointer before calling dev_pm_opp_put(). This causes
a crash when OPP tables are not present in device tree.
Unable to handle kernel access to user memory outside uaccess routines
at virtual address 000000000000002e
...
pc : dev_pm_opp_put+0x1c/0x4c
lr : core_clks_enable+0x4c/0x16c [venus_core]
Add IS_ERR() checks before calling dev_pm_opp_put() to avoid
dereferencing error pointers.
Fixes: b179234b5e59 ("media: venus: pm_helpers: use opp-table for the frequency")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/media/platform/qcom/venus/pm_helpers.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c index 8dd5a9b0d060..e32f8862a9f9 100644 --- a/drivers/media/platform/qcom/venus/pm_helpers.c +++ b/drivers/media/platform/qcom/venus/pm_helpers.c @@ -48,7 +48,8 @@ static int core_clks_enable(struct venus_core *core) int ret; opp = dev_pm_opp_find_freq_ceil(dev, &freq); - dev_pm_opp_put(opp); + if (!IS_ERR(opp)) + dev_pm_opp_put(opp); for (i = 0; i < res->clks_num; i++) { if (IS_V6(core)) { @@ -660,7 +661,8 @@ static int decide_core(struct venus_inst *inst) /*TODO : divide this inst->load by work_route */ opp = dev_pm_opp_find_freq_floor(dev, &max_freq); - dev_pm_opp_put(opp); + if (!IS_ERR(opp)) + dev_pm_opp_put(opp); min_loaded_core(inst, &min_coreid, &min_load, false); min_loaded_core(inst, &min_lp_coreid, &min_lp_load, true); @@ -1121,7 +1123,8 @@ static int load_scale_v4(struct venus_inst *inst) freq = max(freq_core1, freq_core2); opp = dev_pm_opp_find_freq_floor(dev, &max_freq); - dev_pm_opp_put(opp); + if (!IS_ERR(opp)) + dev_pm_opp_put(opp); if (freq > max_freq) { dev_dbg(dev, VDBGL "requested clock rate: %lu scaling clock rate : %lu\n", @@ -1131,7 +1134,8 @@ static int load_scale_v4(struct venus_inst *inst) } opp = dev_pm_opp_find_freq_ceil(dev, &freq); - dev_pm_opp_put(opp); + if (!IS_ERR(opp)) + dev_pm_opp_put(opp); set_freq: |