Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm mmap(2): If we fail with a hint, try again without it.
details: https://anonhg.NetBSD.org/src/rev/12f1e6818059
branches: trunk
changeset: 366648:12f1e6818059
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Jun 04 20:54:03 2022 +0000
description:
mmap(2): If we fail with a hint, try again without it.
`Hint' here means nonzero addr, but no MAP_FIXED or MAP_TRYFIXED.
This is suboptimal -- we could teach uvm_mmap to do a fancier search
using the address as a hint. But this should do for now.
Candidate fix for PR kern/55533.
diffstat:
sys/uvm/uvm_mmap.c | 41 +++++++++++++++++++++++++++++++++++------
1 files changed, 35 insertions(+), 6 deletions(-)
diffs (88 lines):
diff -r fa1f6123531c -r 12f1e6818059 sys/uvm/uvm_mmap.c
--- a/sys/uvm/uvm_mmap.c Sat Jun 04 20:32:49 2022 +0000
+++ b/sys/uvm/uvm_mmap.c Sat Jun 04 20:54:03 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_mmap.c,v 1.179 2022/04/19 22:53:34 riastradh Exp $ */
+/* $NetBSD: uvm_mmap.c,v 1.180 2022/06/04 20:54:03 riastradh Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.179 2022/04/19 22:53:34 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.180 2022/06/04 20:54:03 riastradh Exp $");
#include "opt_compat_netbsd.h"
#include "opt_pax.h"
@@ -277,7 +277,8 @@
vsize_t size, pageoff, newsize;
vm_prot_t prot, maxprot, extraprot;
int flags, fd, advice;
- vaddr_t defaddr;
+ vaddr_t defaddr = 0; /* XXXGCC */
+ bool addrhint = false;
struct file *fp = NULL;
struct uvm_object *uobj;
int error;
@@ -349,6 +350,12 @@
addr = MAX(addr, defaddr);
else
addr = MIN(addr, defaddr);
+
+ /*
+ * If addr is nonzero and not the default, then the
+ * address is a hint.
+ */
+ addrhint = (addr != 0 && addr != defaddr);
}
/*
@@ -399,11 +406,30 @@
pax_aslr_mmap(l, &addr, orig_addr, flags);
/*
- * now let kernel internal function uvm_mmap do the work.
+ * Now let kernel internal function uvm_mmap do the work.
+ *
+ * If the user provided a hint, take a reference to uobj in
+ * case the first attempt to satisfy the hint fails, so we can
+ * try again with the default address.
*/
-
+ if (addrhint) {
+ if (uobj)
+ (*uobj->pgops->pgo_reference)(uobj);
+ }
error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
flags, advice, uobj, pos, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
+ if (addrhint) {
+ if (error) {
+ addr = defaddr;
+ pax_aslr_mmap(l, &addr, orig_addr, flags);
+ error = uvm_mmap(&p->p_vmspace->vm_map, &addr, size,
+ prot, maxprot, flags, advice, uobj, pos,
+ p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
+ } else if (uobj) {
+ /* Release the exta reference we took. */
+ (*uobj->pgops->pgo_detach)(uobj);
+ }
+ }
/* remember to add offset */
*retval = (register_t)(addr + pageoff);
@@ -818,9 +844,12 @@
* - used by sys_mmap and various framebuffers
* - uobj is a struct uvm_object pointer or NULL for MAP_ANON
* - caller must page-align the file offset
+ *
+ * XXX This appears to leak the uobj in various error branches? Need
+ * to clean up the contract around uobj reference.
*/
-int
+static int
uvm_mmap(struct vm_map *map, vaddr_t *addr, vsize_t size, vm_prot_t prot,
vm_prot_t maxprot, int flags, int advice, struct uvm_object *uobj,
voff_t foff, vsize_t locklimit)
Home |
Main Index |
Thread Index |
Old Index