The first page of the I/O virtual address space is reserved so that
authorpatrick <patrick@openbsd.org>
Wed, 23 Jun 2021 19:46:13 +0000 (19:46 +0000)
committerpatrick <patrick@openbsd.org>
Wed, 23 Jun 2021 19:46:13 +0000 (19:46 +0000)
is easier to spot misconfiguration or wrong behaviour where NULL is
used as address.  Right now that page is not part of the IOVA at all,
so when we reserve regions, like PCI I/O space, which can cover that
page as well, extent(9) will panic.  Instead, include it in the IOVA
but reserve it right away.  This way that page can be reserved twice.

sys/arch/arm64/dev/smmu.c

index 07a5539..9cf65a6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: smmu.c,v 1.14 2021/05/16 15:10:19 deraadt Exp $ */
+/* $OpenBSD: smmu.c,v 1.15 2021/06/23 19:46:13 patrick Exp $ */
 /*
  * Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
  * Copyright (c) 2021 Patrick Wildt <patrick@blueri.se>
@@ -750,10 +750,13 @@ smmu_domain_create(struct smmu_softc *sc, uint32_t sid)
 
        snprintf(dom->sd_exname, sizeof(dom->sd_exname), "%s:%x",
            sc->sc_dev.dv_xname, sid);
-       dom->sd_iovamap = extent_create(dom->sd_exname, PAGE_SIZE,
+       dom->sd_iovamap = extent_create(dom->sd_exname, 0,
            (1LL << iovabits) - 1, M_DEVBUF, NULL, 0, EX_WAITOK |
            EX_NOCOALESCE);
 
+       /* Reserve first page (to catch NULL access) */
+       extent_alloc_region(dom->sd_iovamap, 0, PAGE_SIZE, EX_WAITOK);
+
 #if 0
        /* FIXME PCIe address space */
        {