diff options
author | kib <kib@FreeBSD.org> | 2016-11-02 08:41:01 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-11-02 08:41:01 +0000 |
commit | b81fe3e75de30ac5b7fe710ca1919a9b8d0c296e (patch) | |
tree | fb83bba87d31700242e3504065fc0454b5372398 | |
parent | e82e3bc2af43d79504472922cf08e777238426d7 (diff) | |
download | FreeBSD-src-b81fe3e75de30ac5b7fe710ca1919a9b8d0c296e.zip FreeBSD-src-b81fe3e75de30ac5b7fe710ca1919a9b8d0c296e.tar.gz |
MFC r307649:
Partial workaround for Intel PCI adapters reading past the end of the
host-programmed DMA regions.
-rw-r--r-- | sys/dev/e1000/if_lem.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c index 55b8310..717ff2a 100644 --- a/sys/dev/e1000/if_lem.c +++ b/sys/dev/e1000/if_lem.c @@ -591,8 +591,16 @@ lem_attach(device_t dev) } #endif /* NIC_PARAVIRT */ - 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)) { @@ -603,8 +611,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)) { |