From f6ccd325fccc6128aca6fdf764aa70161b30c66b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 10 Jul 2019 22:23:59 +0000 Subject: [PATCH] Enforce a 4GB DMA boundary on isci(4) This device cannot cross a 4GB boundary with DMA. Removing the boundary in r346386 resulted in low frequency memory corruption on machines with isci(4) controllers. Submitted by: gallatin@ Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D20910 --- sys/dev/isci/isci.c | 3 ++- sys/dev/isci/isci.h | 3 +++ sys/dev/isci/isci_controller.c | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/dev/isci/isci.c b/sys/dev/isci/isci.c index d9f210ea6eed..cb6bac483d26 100644 --- a/sys/dev/isci/isci.c +++ b/sys/dev/isci/isci.c @@ -414,7 +414,8 @@ isci_allocate_dma_buffer(device_t device, struct ISCI_CONTROLLER *controller, uint32_t status; status = bus_dma_tag_create(bus_get_dma_tag(device), - 0x40 /* cacheline alignment */, 0x0, BUS_SPACE_MAXADDR, + 0x40 /* cacheline alignment */, + ISCI_DMA_BOUNDARY, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, memory->size, 0x1 /* we want physically contiguous */, memory->size, 0, busdma_lock_mutex, &controller->lock, diff --git a/sys/dev/isci/isci.h b/sys/dev/isci/isci.h index 33b5869e257b..ac46a6f48a5d 100644 --- a/sys/dev/isci/isci.h +++ b/sys/dev/isci/isci.h @@ -75,6 +75,9 @@ #define ISCI_NUM_PCI_BARS 2 #define ISCI_MAX_LUN 8 +/* This device cannot DMA across a 4GB boundary */ +#define ISCI_DMA_BOUNDARY ((bus_addr_t)((uint64_t)1 << 32)) + MALLOC_DECLARE(M_ISCI); struct ISCI_TIMER { diff --git a/sys/dev/isci/isci_controller.c b/sys/dev/isci/isci_controller.c index 8e3f992f24b7..7e8319b3e5e4 100644 --- a/sys/dev/isci/isci_controller.c +++ b/sys/dev/isci/isci_controller.c @@ -477,9 +477,9 @@ int isci_controller_allocate_memory(struct ISCI_CONTROLLER *controller) * will enable better performance than creating the DMA maps every time we get * an I/O. */ - status = bus_dma_tag_create(bus_get_dma_tag(device), 0x1, 0x0, - BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, - isci_io_request_get_max_io_size(), + status = bus_dma_tag_create(bus_get_dma_tag(device), 0x1, + ISCI_DMA_BOUNDARY, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, + NULL, NULL, isci_io_request_get_max_io_size(), SCI_MAX_SCATTER_GATHER_ELEMENTS, max_segment_size, 0, busdma_lock_mutex, &controller->lock, &controller->buffer_dma_tag);