@samitouri / QOSamiQemu / commits / fa4a759fc1

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>

Cédric Le Goater committed Mar 22, 2026 at 22:57 UTC fa4a759fc1e19b2185becfadb00c6d8e57462849
1 file changed +8 -2
hw/net/ftgmac100.c
+8 -2
@@ -624,7 +624,10 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint64_t tx_ring,
624 bd.des0 &= ~FTGMAC100_TXDES0_TXDMA_OWN;
625
626 /* Write back the modified descriptor. */
627 - ftgmac100_write_bd(&bd, addr);
627 + if (ftgmac100_write_bd(&bd, addr)) {
628 + s->isr |= FTGMAC100_INT_AHB_ERR;
629 + break;
630 + }
631 /* Advance to the next descriptor. */
632 if (bd.des0 & s->txdes0_edotr) {
633 addr = tx_ring;
@@ -1134,7 +1137,10 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
1137 bd.des0 |= flags | FTGMAC100_RXDES0_LRS;
1138 s->isr |= FTGMAC100_INT_RPKT_BUF;
1139 }
1137 - ftgmac100_write_bd(&bd, addr);
1140 + if (ftgmac100_write_bd(&bd, addr)) {
1141 + s->isr |= FTGMAC100_INT_AHB_ERR;
1142 + break;
1143 + }
1144 if (bd.des0 & s->rxdes0_edorr) {
1145 addr = s->rx_ring;
1146 } else {