diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2016-10-19 18:15:44 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2016-10-19 18:15:44 +0000 |
commit | cb318718671f023ab6151ec0dbac4073a68376a3 (patch) | |
tree | 493d4f23b424851c3b48183854c40686048931d5 /sys/dev | |
parent | 801b39194a8ed84c38a91a90d8f2419236460c70 (diff) | |
download | src-cb318718671f023ab6151ec0dbac4073a68376a3.tar.gz src-cb318718671f023ab6151ec0dbac4073a68376a3.zip |
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
Notes
Notes:
svn path=/head/; revision=307649
Diffstat (limited to 'sys/dev')
-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 95909aa7b55b..537ccbe5ff11 100644 --- a/sys/dev/e1000/if_lem.c +++ b/sys/dev/e1000/if_lem.c @@ -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)) { |