diff options
author | 2011-05-24 15:27:36 +0000 | |
---|---|---|
committer | 2011-05-24 15:27:36 +0000 | |
commit | 4e3da9ea5c5c5f4e31e57e65a6f97720cfa2a93f (patch) | |
tree | d9bb5c2f86c9031ede4e5ba19468f965cd1ce33e /sys/kern/exec_elf.c | |
parent | Merge pf_scrub_ip() and pf_scrub_ip6() into a single function. Call (diff) | |
download | wireguard-openbsd-4e3da9ea5c5c5f4e31e57e65a6f97720cfa2a93f.tar.xz wireguard-openbsd-4e3da9ea5c5c5f4e31e57e65a6f97720cfa2a93f.zip |
Reimplement uvm/uvm_map.
vmmap is designed to perform address space randomized allocations,
without letting fragmentation of the address space go through the roof.
Some highlights:
- kernel address space randomization
- proper implementation of guardpages
- roughly 10% system time reduction during kernel build
Tested by alot of people on tech@ and developers.
Theo's machines are still happy.
Diffstat (limited to 'sys/kern/exec_elf.c')
-rw-r--r-- | sys/kern/exec_elf.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c index 980f49431ed..d4bdfd1ba7e 100644 --- a/sys/kern/exec_elf.c +++ b/sys/kern/exec_elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_elf.c,v 1.81 2011/04/18 21:44:56 guenther Exp $ */ +/* $OpenBSD: exec_elf.c,v 1.82 2011/05/24 15:27:36 ariane Exp $ */ /* * Copyright (c) 1996 Per Fogelstrom @@ -333,6 +333,7 @@ ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, int nload, idx = 0; Elf_Addr pos = *last; int file_align; + int loop; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); if ((error = namei(&nd)) != 0) { @@ -389,6 +390,7 @@ ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, pos = ELF_ROUND(pos, file_align); *last = epp->ep_interp_pos = pos; + loop = 0; for (i = 0; i < nload;/**/) { vaddr_t addr; struct uvm_object *uobj; @@ -416,17 +418,17 @@ ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, addr = round_page((vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ); - vm_map_lock(&p->p_vmspace->vm_map); - if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size, - &addr, uobj, uoff, 0, UVM_FLAG_FIXED) == NULL) { - if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size, - &addr, uobj, uoff, 0, 0) == NULL) { - error = ENOMEM; /* XXX */ - vm_map_unlock(&p->p_vmspace->vm_map); - goto bad1; + if (uvm_map_mquery(&p->p_vmspace->vm_map, &addr, size, + (i == 0 ? uoff : UVM_UNKNOWN_OFFSET), 0) != 0) { + if (loop == 0) { + loop = 1; + i = 0; + *last = epp->ep_interp_pos = pos = 0; + continue; } - } - vm_map_unlock(&p->p_vmspace->vm_map); + error = ENOMEM; + goto bad1; + } if (addr != pos + loadmap[i].vaddr) { /* base changed. */ pos = addr - trunc_page(loadmap[i].vaddr); |