diff --git a/target/linux/apm821xx/patches-6.18/700-net-ibm-emac-Clear-MAL-descriptors-without-memset.patch b/target/linux/apm821xx/patches-6.18/700-net-ibm-emac-Clear-MAL-descriptors-without-memset.patch new file mode 100644 index 0000000000..9e494bba18 --- /dev/null +++ b/target/linux/apm821xx/patches-6.18/700-net-ibm-emac-Clear-MAL-descriptors-without-memset.patch @@ -0,0 +1,49 @@ +From f992336a598ce4508b75e25dff755715f38b9b8e Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sat, 16 May 2026 16:31:09 -0700 +Subject: [PATCH] net: ibm: emac: Clear MAL descriptors without memset + +Clear MAL descriptor rings with explicit field stores instead of +memset(). The descriptor rings are carved from MAL coherent DMA memory, +which may be mapped uncached on 32-bit powerpc. The optimized memset() +path can use dcbz there and trigger an alignment warning. + +The skb tracking arrays remain ordinary CPU memory and still use memset(). + +Assisted-by: Codex:GPT-5.5 +Signed-off-by: Rosen Penev +--- + drivers/net/ethernet/ibm/emac/core.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/ibm/emac/core.c ++++ b/drivers/net/ethernet/ibm/emac/core.c +@@ -1161,6 +1161,17 @@ static void emac_clean_rx_ring(struct em + } + } + ++static void emac_clear_mal_desc(struct mal_descriptor *desc, int count) ++{ ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ desc[i].ctrl = 0; ++ desc[i].data_len = 0; ++ desc[i].data_ptr = 0; ++ } ++} ++ + static int + __emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot) + { +@@ -3086,8 +3097,8 @@ static int emac_probe(struct platform_de + DBG(dev, "rx_desc %p" NL, dev->rx_desc); + + /* Clean rings */ +- memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor)); +- memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor)); ++ emac_clear_mal_desc(dev->tx_desc, NUM_TX_BUFF); ++ emac_clear_mal_desc(dev->rx_desc, NUM_RX_BUFF); + memset(dev->tx_skb, 0, NUM_TX_BUFF * sizeof(struct sk_buff *)); + memset(dev->rx_skb, 0, NUM_RX_BUFF * sizeof(struct sk_buff *)); + diff --git a/target/linux/apm821xx/patches-6.18/910-dma-direct-Clear-pages-before-coherent-remap.patch b/target/linux/apm821xx/patches-6.18/910-dma-direct-Clear-pages-before-coherent-remap.patch new file mode 100644 index 0000000000..642ee61ed5 --- /dev/null +++ b/target/linux/apm821xx/patches-6.18/910-dma-direct-Clear-pages-before-coherent-remap.patch @@ -0,0 +1,72 @@ +From 78bddfc01439de243624b1e60a7f599ec11b55b7 Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Sat, 16 May 2026 16:08:49 -0700 +Subject: [PATCH] dma-direct: Clear pages before coherent remap + +Clear pages through their page mapping before creating a coherent +remap for dma-direct allocations. Some architectures implement the +coherent remap as uncached memory, where the generic memset() path may +use cache-only zeroing instructions that are not valid for the returned +CPU mapping. + +Keep the existing memset() for non-remapped allocations, but avoid +normal memset() on the remapped coherent allocation path. + +Assisted-by: Codex:GPT-5.5 +Signed-off-by: Rosen Penev +--- + kernel/dma/direct.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- a/kernel/dma/direct.c ++++ b/kernel/dma/direct.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -104,6 +105,15 @@ static void __dma_direct_free_pages(stru + dma_free_contiguous(dev, page, size); + } + ++static void dma_direct_zero_pages(struct page *page, size_t size) ++{ ++ unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; ++ unsigned long i; ++ ++ for (i = 0; i < count; i++) ++ clear_highpage(page + i); ++} ++ + static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size) + { + struct page *page = swiotlb_alloc(dev, size); +@@ -268,6 +278,13 @@ void *dma_direct_alloc(struct device *de + if (remap) { + pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs); + ++ /* ++ * Zero via the page mapping before creating a potentially ++ * uncached remap. Some architectures cannot safely run normal ++ * memset on uncached memory. ++ */ ++ dma_direct_zero_pages(page, size); ++ + if (force_dma_unencrypted(dev)) + prot = pgprot_decrypted(prot); + +@@ -283,10 +300,9 @@ void *dma_direct_alloc(struct device *de + ret = page_address(page); + if (dma_set_decrypted(dev, ret, size)) + goto out_leak_pages; ++ memset(ret, 0, size); + } + +- memset(ret, 0, size); +- + if (set_uncached) { + arch_dma_prep_coherent(page, size); + ret = arch_dma_set_uncached(ret, size);