Author: kib
Date: Wed Oct 19 18:15:44 2016
New Revision: 307649
URL: https://svnweb.freebsd.org/changeset/base/307649

Log:
  Partial workaround for Intel PCI adapters reading past the end of the
  host-programmed DMA regions.  This change seemingly fixes the
  descriptor fetches, but the packet memory accesses are left
  problematic.
  
  Reviewed by:  emaste, erj, sbruno
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks
  Differential revision:        https://reviews.freebsd.org/D8282

Modified:
  head/sys/dev/e1000/if_lem.c

Modified: head/sys/dev/e1000/if_lem.c
==============================================================================
--- head/sys/dev/e1000/if_lem.c Wed Oct 19 17:42:45 2016        (r307648)
+++ head/sys/dev/e1000/if_lem.c Wed Oct 19 18:15:44 2016        (r307649)
@@ -543,8 +543,16 @@ lem_attach(device_t dev)
         */
        adapter->hw.mac.report_tx_early = 1;
 
-       tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
-           EM_DBA_ALIGN);
+       /*
+        * It seems that the descriptor DMA engine on some PCI cards
+        * fetches memory past the end of the last descriptor in the
+        * ring.  These reads are problematic when VT-d (DMAR) busdma
+        * is used.  Allocate the scratch space to avoid getting
+        * faults from DMAR, by requesting scratch memory for one more
+        * descriptor.
+        */
+       tsize = roundup2((adapter->num_tx_desc + 1) *
+           sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
 
        /* Allocate Transmit Descriptor ring */
        if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
@@ -555,8 +563,11 @@ lem_attach(device_t dev)
        adapter->tx_desc_base = 
            (struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
 
-       rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
-           EM_DBA_ALIGN);
+       /*
+        * See comment above txdma allocation for rationale behind +1.
+        */
+       rsize = roundup2((adapter->num_rx_desc + 1) *
+           sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
 
        /* Allocate Receive Descriptor ring */
        if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to