diff options
author | 2017-03-21 21:43:11 +0000 | |
---|---|---|
committer | 2017-03-21 21:43:11 +0000 | |
commit | 848d34f6959d39cca8b261ed41e7e06ba4a6e25d (patch) | |
tree | 3b8e41830e04410f79c7077c561e1b451dacc3df | |
parent | Use uid_t for UID not u_int. (diff) | |
download | wireguard-openbsd-848d34f6959d39cca8b261ed41e7e06ba4a6e25d.tar.xz wireguard-openbsd-848d34f6959d39cca8b261ed41e7e06ba4a6e25d.zip |
Avoid panic in arm_sync_icache() by only flushing the parts of the address
space for which we have a userland mapping.
ok jca@
-rw-r--r-- | sys/arch/arm/arm/sys_machdep.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/sys/arch/arm/arm/sys_machdep.c b/sys/arch/arm/arm/sys_machdep.c index db168071aca..bdb1c54dddd 100644 --- a/sys/arch/arm/arm/sys_machdep.c +++ b/sys/arch/arm/arm/sys_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_machdep.c,v 1.3 2004/05/19 03:17:07 drahn Exp $ */ +/* $OpenBSD: sys_machdep.c,v 1.4 2017/03/21 21:43:11 kettenis Exp $ */ /* $NetBSD: sys_machdep.c,v 1.6 2003/07/15 00:24:42 lukem Exp $ */ /* @@ -63,12 +63,46 @@ arm32_sync_icache(p, args, retval) register_t *retval; { struct arm_sync_icache_args ua; + struct vm_map *map = &p->p_vmspace->vm_map; + struct vm_map_entry *entry; + vaddr_t va; + vsize_t sz, chunk; int error; if ((error = copyin(args, &ua, sizeof(ua))) != 0) return (error); - cpu_icache_sync_range(ua.addr, ua.len); + va = ua.addr; + sz = ua.len; + + vm_map_lock_read(map); + + if (va + sz <= vm_map_min(map) || va >= vm_map_max(map) || + va + sz < va) + goto out; + + if (va < vm_map_min(map)) { + sz -= vm_map_min(map) - va; + va = vm_map_min(map); + } else if (va + sz >= vm_map_max(map)) { + sz = vm_map_max(map) - va; + } + + chunk = PAGE_SIZE - (va & PAGE_MASK); + while (sz > 0) { + if (chunk > sz) + chunk = sz; + + if (uvm_map_lookup_entry(map, va, &entry)) + cpu_icache_sync_range(va, chunk); + + va += chunk; + sz -= chunk; + chunk = PAGE_SIZE; + } + +out: + vm_map_unlock_read(map); *retval = 0; return(0); |