From a5eb7f55b9c1dc179deb7da5fa31c6889c73c8ca Mon Sep 17 00:00:00 2001 From: patrick Date: Sat, 3 Apr 2021 15:59:08 +0000 Subject: [PATCH] Add a guard page between I/O virtual address space allocations. The idea is that IOVA allocations always have a gap in-between which produces a fault on access. If a transfer to a given allocation runs further than expected we should be able to see it. We pre-allocate IOVA on bus DMA map creation, and as long as we don't allocate a PTE descriptor, this comes with no cost. We have plenty of address space anyway, so adding a page-sized gap does not hurt at all and can only have positive effects. Idea from kettenis@ --- sys/arch/arm64/dev/smmu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/arch/arm64/dev/smmu.c b/sys/arch/arm64/dev/smmu.c index 565e9df3a9f..082248440f7 100644 --- a/sys/arch/arm64/dev/smmu.c +++ b/sys/arch/arm64/dev/smmu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smmu.c,v 1.12 2021/04/03 15:10:58 patrick Exp $ */ +/* $OpenBSD: smmu.c,v 1.13 2021/04/03 15:59:08 patrick Exp $ */ /* * Copyright (c) 2008-2009,2014-2016 Dale Rahn * Copyright (c) 2021 Patrick Wildt @@ -1294,8 +1294,9 @@ smmu_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, /* Approximation of maximum pages needed. */ len = round_page(size) + nsegments * PAGE_SIZE; + /* Allocate IOVA, and a guard page at the end. */ mtx_enter(&dom->sd_iova_mtx); - error = extent_alloc_with_descr(dom->sd_iovamap, len, + error = extent_alloc_with_descr(dom->sd_iovamap, len + PAGE_SIZE, PAGE_SIZE, 0, 0, EX_NOWAIT, &sms->sms_er, &dva); mtx_leave(&dom->sd_iova_mtx); if (error) { @@ -1343,7 +1344,7 @@ smmu_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map) mtx_enter(&dom->sd_iova_mtx); error = extent_free(dom->sd_iovamap, sms->sms_dva, - sms->sms_len, EX_NOWAIT); + sms->sms_len + PAGE_SIZE, EX_NOWAIT); mtx_leave(&dom->sd_iova_mtx); KASSERT(error == 0); -- 2.20.1