Module Name: src Committed By: riastradh Date: Wed Jul 6 01:16:36 UTC 2022
Modified Files: src/sys/uvm: uvm_device.c Log Message: mmap(2): Guarantee two's-complement wraparound for D_NEGOFFSAFE. XXX Not sure this should be allowed at all, but this way we don't change the semantics of the existing code which was written under essentially the assumption of -fwrapv. To generate a diff of this commit: cvs rdiff -u -r1.76 -r1.77 src/sys/uvm/uvm_device.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_device.c diff -u src/sys/uvm/uvm_device.c:1.76 src/sys/uvm/uvm_device.c:1.77 --- src/sys/uvm/uvm_device.c:1.76 Wed Jul 6 01:15:51 2022 +++ src/sys/uvm/uvm_device.c Wed Jul 6 01:16:36 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_device.c,v 1.76 2022/07/06 01:15:51 riastradh Exp $ */ +/* $NetBSD: uvm_device.c,v 1.77 2022/07/06 01:16:36 riastradh Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_device.c,v 1.76 2022/07/06 01:15:51 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_device.c,v 1.77 2022/07/06 01:16:36 riastradh Exp $"); #include "opt_uvmhist.h" @@ -152,13 +152,29 @@ udv_attach(dev_t device, vm_prot_t acces * XXX assumes VM_PROT_* == PROT_* * XXX clobbers off and size, but nothing else here needs them. */ - - while (size != 0) { - if (cdev_mmap(device, off, accessprot) == -1) { - return (NULL); + do { + KASSERTMSG((off % PAGE_SIZE) == 0, "off=%jd", (intmax_t)off); + KASSERTMSG(size >= PAGE_SIZE, "size=%"PRIuVSIZE, size); + if (cdev_mmap(device, off, accessprot) == -1) + return NULL; + KASSERT(off <= __type_max(voff_t) - PAGE_SIZE || + (cdev->d_flag & D_NEGOFFSAFE) != 0); + if (__predict_false(off > __type_max(voff_t) - PAGE_SIZE)) { + /* + * off += PAGE_SIZE, with two's-complement + * wraparound, or + * + * off += PAGE_SIZE - 2*(VOFF_MAX + 1). + */ + CTASSERT(PAGE_SIZE >= 2); + off -= __type_max(voff_t); + off += PAGE_SIZE - 2; + off -= __type_max(voff_t); + } else { + off += PAGE_SIZE; } - off += PAGE_SIZE; size -= PAGE_SIZE; - } + size -= PAGE_SIZE; + } while (size != 0); /* * keep looping until we get it