Commit fa4a759fc1 for qemu.org

commit fa4a759fc1e19b2185becfadb00c6d8e57462849
Author: Cédric Le Goater <clg@redhat.com>
Date:   Sun Mar 22 22:57:31 2026 +0100

    hw/net/ftgmac100: Improve DMA error handling

    Currently, DMA memory operation errors in the ftgmac100 model are not
    all tested and this can lead to a guest-triggerable denial of service
    as described in https://gitlab.com/qemu-project/qemu/-/work_items/3335.

    To fix this, check the return value of ftgmac100_write_bd() in the TX
    path and exit the TX loop on error to prevent further processing. In
    the event of a DMA error, also set FTGMAC100_INT_AHB_ERR interrupt
    flag as appropriate.

    The FTGMAC100_INT_AHB_ERR interrupt status bit only applies to the
    AST2400 SoC; on newer Aspeed SoCs, it is a reserved bit.
    Nevertheless, since it is supported by the Linux driver and it should
    be safe to use in the QEMU implementation across all SoCs.

    Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3335
    Signed-off-by: Cédric Le Goater <clg@redhat.com>
    Reviewed-by: Jamin Lin <jamin_lin@aspeedtech.com>
    Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
    Message-ID: <20260322215732.387383-3-clg@redhat.com>
    Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index d29f7dcd17..2f05bba11d 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -624,7 +624,10 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint64_t tx_ring,
         bd.des0 &= ~FTGMAC100_TXDES0_TXDMA_OWN;

         /* Write back the modified descriptor.  */
-        ftgmac100_write_bd(&bd, addr);
+        if (ftgmac100_write_bd(&bd, addr)) {
+            s->isr |= FTGMAC100_INT_AHB_ERR;
+            break;
+        }
         /* Advance to the next descriptor.  */
         if (bd.des0 & s->txdes0_edotr) {
             addr = tx_ring;
@@ -1134,7 +1137,10 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
             bd.des0 |= flags | FTGMAC100_RXDES0_LRS;
             s->isr |= FTGMAC100_INT_RPKT_BUF;
         }
-        ftgmac100_write_bd(&bd, addr);
+        if (ftgmac100_write_bd(&bd, addr)) {
+            s->isr |= FTGMAC100_INT_AHB_ERR;
+            break;
+        }
         if (bd.des0 & s->rxdes0_edorr) {
             addr = s->rx_ring;
         } else {