The dev_type validation can allow values whose derived event group has no
matching physical channel pair. d40_allocate_channel() then indexes
phy_res with j + event_group * 2, and __d40_set_prio_rt() uses the same
group to select priority and realtime registers.

Reject dev_type values outside the hardware event-group range, and stop
the physical-channel search before a partial final channel group can index
past phy_res.

Reported-by: [email protected]
Closes: 
https://lore.kernel.org/dmaengine/[email protected]/
Assisted-by: Codex:gpt-5-5
Signed-off-by: Linus Walleij <[email protected]>
---
 drivers/dma/ste_dma40.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 7c777e410c10..e0c694a1fc8b 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1739,6 +1739,10 @@ static int d40_validate_conf(struct d40_chan *d40c,
        bool is_log = conf->mode == STEDMA40_MODE_LOGICAL;
        bool invalid_dev_type = conf->dev_type < 0;
 
+       if (!invalid_dev_type &&
+           D40_TYPE_TO_GROUP(conf->dev_type) >= D40_GROUP_SIZE / 2)
+               invalid_dev_type = true;
+
        if (!conf->dir) {
                chan_err(d40c, "Invalid direction.\n");
                res = -EINVAL;
@@ -1921,8 +1925,12 @@ static int d40_allocate_channel(struct d40_chan *d40c, 
bool *first_phy_user)
                                }
                        }
                } else
-                       for (j = 0; j < d40c->base->num_phy_chans; j += 8) {
+                       for (j = 0; j < d40c->base->num_phy_chans;
+                            j += D40_GROUP_SIZE) {
                                int phy_num = j  + event_group * 2;
+                               if (phy_num + 1 >= num_phy_chans)
+                                       break;
+
                                for (i = phy_num; i < phy_num + 2; i++) {
                                        if (d40_alloc_mask_set(&phys[i],
                                                               is_src,
@@ -1942,8 +1950,10 @@ static int d40_allocate_channel(struct d40_chan *d40c, 
bool *first_phy_user)
                return -EINVAL;
 
        /* Find logical channel */
-       for (j = 0; j < d40c->base->num_phy_chans; j += 8) {
+       for (j = 0; j < d40c->base->num_phy_chans; j += D40_GROUP_SIZE) {
                int phy_num = j + event_group * 2;
+               if (phy_num + 1 >= num_phy_chans)
+                       break;
 
                if (d40c->dma_cfg.use_fixed_channel) {
                        i = d40c->dma_cfg.phy_channel;

-- 
2.55.0


Reply via email to