summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-11-02 08:41:01 +0000
committerkib <kib@FreeBSD.org>2016-11-02 08:41:01 +0000
commitb81fe3e75de30ac5b7fe710ca1919a9b8d0c296e (patch)
treefb83bba87d31700242e3504065fc0454b5372398
parente82e3bc2af43d79504472922cf08e777238426d7 (diff)
downloadFreeBSD-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.c19
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)) {
OpenPOWER on IntegriCloud