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