From 035472170a2a21fc62d8258883a9f566943058b7 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 17 Aug 2023 16:58:50 -0700 Subject: dmaengine: stm32-mdma: Annotate struct stm32_mdma_desc with __counted_by Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). As found with Coccinelle[1], add __counted_by for struct stm32_mdma_desc. Additionally, since the element count member must be set before accessing the annotated flexible array member, move its initialization earlier. [1] https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci Cc: Vinod Koul Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: dmaengine@vger.kernel.org Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Kees Cook Reviewed-by: "Gustavo A. R. Silva" Link: https://lore.kernel.org/r/20230817235859.49846-13-keescook@chromium.org Signed-off-by: Vinod Koul --- drivers/dma/stm32-mdma.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/dma/stm32-mdma.c') diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index 0de234022c6d..926d6ecf1274 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -224,7 +224,7 @@ struct stm32_mdma_desc { u32 ccr; bool cyclic; u32 count; - struct stm32_mdma_desc_node node[]; + struct stm32_mdma_desc_node node[] __counted_by(count); }; struct stm32_mdma_dma_config { @@ -321,6 +321,7 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc( desc = kzalloc(struct_size(desc, node, count), GFP_NOWAIT); if (!desc) return NULL; + desc->count = count; for (i = 0; i < count; i++) { desc->node[i].hwdesc = @@ -330,8 +331,6 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc( goto err; } - desc->count = count; - return desc; err: -- cgit v1.2.3 From 7ba0035dc02ce0c877004dc4052c6d5f873539db Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 17 Aug 2023 16:58:51 -0700 Subject: dmaengine: stm32-mdma: Annotate struct stm32_mdma_device with __counted_by Prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time checking via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). As found with Coccinelle[1], add __counted_by for struct stm32_mdma_device. Additionally, since the element count member must be set before accessing the annotated flexible array member, move its initialization earlier. [1] https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci Cc: Vinod Koul Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: dmaengine@vger.kernel.org Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Kees Cook Reviewed-by: "Gustavo A. R. Silva" Link: https://lore.kernel.org/r/20230817235859.49846-14-keescook@chromium.org Signed-off-by: Vinod Koul --- drivers/dma/stm32-mdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma/stm32-mdma.c') diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index 926d6ecf1274..0c7d2295856e 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -256,7 +256,7 @@ struct stm32_mdma_device { u32 nr_ahb_addr_masks; u32 chan_reserved; struct stm32_mdma_chan chan[STM32_MDMA_MAX_CHANNELS]; - u32 ahb_addr_masks[]; + u32 ahb_addr_masks[] __counted_by(nr_ahb_addr_masks); }; static struct stm32_mdma_device *stm32_mdma_get_dev( @@ -1611,13 +1611,13 @@ static int stm32_mdma_probe(struct platform_device *pdev) GFP_KERNEL); if (!dmadev) return -ENOMEM; + dmadev->nr_ahb_addr_masks = count; dmadev->nr_channels = nr_channels; dmadev->nr_requests = nr_requests; device_property_read_u32_array(&pdev->dev, "st,ahb-addr-masks", dmadev->ahb_addr_masks, count); - dmadev->nr_ahb_addr_masks = count; dmadev->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dmadev->base)) -- cgit v1.2.3 From 03f25d53b145bc2f7ccc82fc04e4482ed734f524 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 9 Oct 2023 10:24:50 +0200 Subject: dmaengine: stm32-mdma: correct desc prep when channel running In case of the prep descriptor while the channel is already running, the CCR register value stored into the channel could already have its EN bit set. This would lead to a bad transfer since, at start transfer time, enabling the channel while other registers aren't yet properly set. To avoid this, ensure to mask the CCR_EN bit when storing the ccr value into the mdma channel structure. Fixes: a4ffb13c8946 ("dmaengine: Add STM32 MDMA driver") Signed-off-by: Alain Volmat Signed-off-by: Amelie Delaunay Cc: stable@vger.kernel.org Tested-by: Alain Volmat Link: https://lore.kernel.org/r/20231009082450.452877-1-amelie.delaunay@foss.st.com Signed-off-by: Vinod Koul --- drivers/dma/stm32-mdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma/stm32-mdma.c') diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index 0c7d2295856e..264abfb54a8e 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -488,7 +488,7 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, src_maxburst = chan->dma_config.src_maxburst; dst_maxburst = chan->dma_config.dst_maxburst; - ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); + ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); @@ -966,7 +966,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src, if (!desc) return NULL; - ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); + ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); -- cgit v1.2.3