summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2017-03-21 21:43:11 +0000
committerkettenis <kettenis@openbsd.org>2017-03-21 21:43:11 +0000
commit848d34f6959d39cca8b261ed41e7e06ba4a6e25d (patch)
tree3b8e41830e04410f79c7077c561e1b451dacc3df
parentUse uid_t for UID not u_int. (diff)
downloadwireguard-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.c38
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);