From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B41CA26738C; Sat, 19 Sep 2026 22:22:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789856573; cv=none; b=a22bn/jxwbWDliAcGJF27gWEcT3KRWRifvnmerDeagwfFY520CtE2o0mhbkCejFBhHgWC5Nvb6nlNOCwssYqDjkHmuS2bNypYyEqVTWVv9MA0hWTfSmV9wHk2NRHPybhVLjRFkJ8bqYEBYdRcpV/WX7/+TBPuLhTbMgJjLKzxjg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789856573; c=relaxed/simple; bh=W90+AuIPoX6mohg8/Xc9WvVvddsqcw1cKPoyxi9gy2Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OCMST3FtDWJkeLg5Wfn4l+PeX7N6Vq7XtklCG4XnQ3UHV3tUO2kEgyWKLYlrHwKbKP4wbrD6qt8uqlLx1/4IMLdWgX0+ucuyPu1n9sO1fTuBrutwdtQ1yFpKYqweNZOFw2C8OHdM5MTtvhI9R+yfrBfH+5JJFNrS7SRnkXJXRTU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Qq7DsfZm; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Qq7DsfZm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1ADCE1F00893; Sat, 19 Sep 2026 22:22:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789856572; bh=K5YSsiE1AfSrRLqKCg+X8+o2MtRN9+cTyNniZzWYnlI=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Qq7DsfZmpgZCv/x+o5hg429sXPY8cP3kFuKEn1lTX57CE6XJhwQ7rySyxYddd0GCv 2iCsV+IzbydcDXHSlEax79NRVfx9/8/CCpYTuiFQOwX29Sjkx3Nwecd+PYltGTRL/5 LzyG6+s6Icsm2SpzLGafGPb5RZ0oM/k7UqKLWTtXzlDLDjkD26vdhWQdU4AZYtjQyR Yqv1GUizygADpKVPVznRWopc//3OiuffrU5FY+a0r/zQdz/qJgiOU0+MNwehiAh0ZW 0ilKtU9u5yRJudAcBvF+trUWX72ZSx+GgbcdhrWpUuPAKRN3R7hDg+ZDnLaUhbOJKK GHbPV/1MbxJAw== From: Linus Walleij Date: Sun, 20 Sep 2026 00:22:31 +0200 Subject: [PATCH v4 20/23] dmaengine: ste_dma40: Fix event group bounds Precedence: bulk X-Mailing-List: dmaengine@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260920-dma40-fixes-v4-20-d751b2d9c23f@kernel.org> References: <20260920-dma40-fixes-v4-0-d751b2d9c23f@kernel.org> In-Reply-To: <20260920-dma40-fixes-v4-0-d751b2d9c23f@kernel.org> To: Vinod Koul , Frank Li Cc: dmaengine@vger.kernel.org, phone-devel@vger.kernel.org, Linus Walleij , sashiko-bot@kernel.org X-Mailer: b4 0.14.3 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. The physical-mode validation also compares dev_type with the number of physical channels. However, dev_type identifies an event line: DB8500 has eight physical channels but 64 source and 64 destination event lines. The event group determines which physical channel pair can serve an event, so the physical channel count is not a valid dev_type limit. Reject dev_type values outside the hardware event-group range, remove the incorrect physical channel count limit, and stop the physical-channel search before a partial final channel group can index past phy_res. Fixes: 26955c07dcf3 ("dmaengine: ste_dma40: Amalgamate DMA source and destination channel numbers") Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/dmaengine/20260819225008.5F9651F000E9@smtp.kernel.org/ Assisted-by: LLM Signed-off-by: Linus Walleij --- drivers/dma/ste_dma40.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index fe9759787981..1738a37da682 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -79,6 +79,10 @@ struct stedma40_platform_data { #define D40_LCLA_LINK_PER_EVENT_GRP 128 #define D40_LCLA_END D40_LCLA_LINK_PER_EVENT_GRP +/* Number of event groups per hardware register layout */ +#define D40_EVENT_GROUPS_V4A 4 +#define D40_EVENT_GROUPS_V4B 5 + /* Max number of logical channels per physical channel */ #define D40_MAX_LOG_CHAN_PER_PHY 32 @@ -517,6 +521,7 @@ struct d40_chan { * @high_prio_clear: the high priority clear register * @interrupt_en: the interrupt enable register * @interrupt_clear: the interrupt clear register + * @num_event_groups: number of supported event groups * @il: the pointer to struct d40_interrupt_lookup * @il_size: the size of d40_interrupt_lookup array * @init_reg: the pointer to the struct d40_reg_val @@ -531,6 +536,7 @@ struct d40_gen_dmac { u32 high_prio_clear; u32 interrupt_en; u32 interrupt_clear; + u32 num_event_groups; struct d40_interrupt_lookup *il; u32 il_size; struct d40_reg_val *init_reg; @@ -1852,6 +1858,11 @@ 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) >= + d40c->base->gen_dmac.num_event_groups) + invalid_dev_type = true; + if (!conf->dir) { chan_err(d40c, "Invalid direction.\n"); res = -EINVAL; @@ -1868,8 +1879,7 @@ static int d40_validate_conf(struct d40_chan *d40c, invalid_dev_type = conf->dev_type >= max_dev_type; } - if (invalid_dev_type || - (!is_log && conf->dev_type > d40c->base->num_phy_chans)) { + if (invalid_dev_type) { chan_err(d40c, "Invalid device type (%d)\n", conf->dev_type); res = -EINVAL; } @@ -2034,8 +2044,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, @@ -2055,8 +2069,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; @@ -3438,6 +3454,7 @@ static int __init d40_hw_detect_init(struct platform_device *pdev, base->log_chans = &base->phy_chans[num_phy_chans]; if (base->plat_data->num_of_phy_chans == 14) { + base->gen_dmac.num_event_groups = D40_EVENT_GROUPS_V4B; base->gen_dmac.backup = d40_backup_regs_v4b; base->gen_dmac.backup_size = BACKUP_REGS_SZ_V4B; base->gen_dmac.interrupt_en = D40_DREG_CPCMIS; @@ -3451,6 +3468,7 @@ static int __init d40_hw_detect_init(struct platform_device *pdev, base->gen_dmac.init_reg = dma_init_reg_v4b; base->gen_dmac.init_reg_size = ARRAY_SIZE(dma_init_reg_v4b); } else { + base->gen_dmac.num_event_groups = D40_EVENT_GROUPS_V4A; if (base->rev >= 3) { base->gen_dmac.backup = d40_backup_regs_v4a; base->gen_dmac.backup_size = BACKUP_REGS_SZ_V4A; -- 2.55.0