]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
et131x: Add missing check after DMA map
authorThomas Fourier <fourier.thomas@gmail.com>
Wed, 16 Jul 2025 09:47:30 +0000 (11:47 +0200)
committerJakub Kicinski <kuba@kernel.org>
Fri, 18 Jul 2025 02:02:55 +0000 (19:02 -0700)
The DMA map functions can fail and should be tested for errors.
If the mapping fails, unmap and return an error.

Signed-off-by: Thomas Fourier <fourier.thomas@gmail.com>
Acked-by: Mark Einon <mark.einon@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250716094733.28734-2-fourier.thomas@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/agere/et131x.c

index 678eddb3617294511c2246f992a2dc71e73fc1d9..5c8217638ddafe199a260dcf31a9ed62b289690f 100644 (file)
@@ -2459,6 +2459,10 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
                                                          skb->data,
                                                          skb_headlen(skb),
                                                          DMA_TO_DEVICE);
+                               if (dma_mapping_error(&adapter->pdev->dev,
+                                                     dma_addr))
+                                       return -ENOMEM;
+
                                desc[frag].addr_lo = lower_32_bits(dma_addr);
                                desc[frag].addr_hi = upper_32_bits(dma_addr);
                                frag++;
@@ -2468,6 +2472,10 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
                                                          skb->data,
                                                          skb_headlen(skb) / 2,
                                                          DMA_TO_DEVICE);
+                               if (dma_mapping_error(&adapter->pdev->dev,
+                                                     dma_addr))
+                                       return -ENOMEM;
+
                                desc[frag].addr_lo = lower_32_bits(dma_addr);
                                desc[frag].addr_hi = upper_32_bits(dma_addr);
                                frag++;
@@ -2478,6 +2486,10 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
                                                          skb_headlen(skb) / 2,
                                                          skb_headlen(skb) / 2,
                                                          DMA_TO_DEVICE);
+                               if (dma_mapping_error(&adapter->pdev->dev,
+                                                     dma_addr))
+                                       goto unmap_first_out;
+
                                desc[frag].addr_lo = lower_32_bits(dma_addr);
                                desc[frag].addr_hi = upper_32_bits(dma_addr);
                                frag++;
@@ -2489,6 +2501,9 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
                                                    0,
                                                    desc[frag].len_vlan,
                                                    DMA_TO_DEVICE);
+                       if (dma_mapping_error(&adapter->pdev->dev, dma_addr))
+                               goto unmap_out;
+
                        desc[frag].addr_lo = lower_32_bits(dma_addr);
                        desc[frag].addr_hi = upper_32_bits(dma_addr);
                        frag++;
@@ -2578,6 +2593,27 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb)
                       &adapter->regs->global.watchdog_timer);
        }
        return 0;
+
+unmap_out:
+       // Unmap the body of the packet with map_page
+       while (--i) {
+               frag--;
+               dma_addr = desc[frag].addr_lo;
+               dma_addr |= (u64)desc[frag].addr_hi << 32;
+               dma_unmap_page(&adapter->pdev->dev, dma_addr,
+                              desc[frag].len_vlan, DMA_TO_DEVICE);
+       }
+
+unmap_first_out:
+       // Unmap the header with map_single
+       while (frag--) {
+               dma_addr = desc[frag].addr_lo;
+               dma_addr |= (u64)desc[frag].addr_hi << 32;
+               dma_unmap_single(&adapter->pdev->dev, dma_addr,
+                                desc[frag].len_vlan, DMA_TO_DEVICE);
+       }
+
+       return -ENOMEM;
 }
 
 static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter)