Index: head/sys/dev/e1000/if_lem.c =================================================================== --- head/sys/dev/e1000/if_lem.c +++ head/sys/dev/e1000/if_lem.c @@ -543,8 +543,16 @@ */ 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 @@ 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)) {