diff options
-rw-r--r-- | serverboot/wiring.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/serverboot/wiring.c b/serverboot/wiring.c index ddcbd373..585a3075 100644 --- a/serverboot/wiring.c +++ b/serverboot/wiring.c @@ -1,25 +1,25 @@ -/* +/* * Mach Operating System * Copyright (c) 1991 Carnegie Mellon University * All Rights Reserved. - * + * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * + * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to - * + * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 - * + * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ @@ -107,7 +107,31 @@ wire_all_memory() if (MACH_PORT_VALID(object)) (void) mach_port_deallocate(this_task, object); if (protection != VM_PROT_NONE) - wire_memory(address, size, protection); + { + /* The VM system cannot cope with a COW fault on another + unrelated virtual copy happening later when we have + wired down the original page. So we must touch all our + pages before wiring to make sure that only we will ever + use them. */ + void *page; + if (!(protection & VM_PROT_WRITE)) + { + kr = vm_protect(this_task, address, size, + 0, max_protection); + } + for (page = (void *) address; + page < (void *) (address + size); + page += vm_page_size) + *(volatile int *) page = *(int *) page; + + wire_memory(address, size, protection); + + if (!(protection & VM_PROT_WRITE)) + { + kr = vm_protect(this_task, address, size, + 0, protection); + } + } address += size; } } @@ -149,4 +173,3 @@ __vm_allocate (task, address, size, anywhere) { return vm_allocate (task, address, size, anywhere); } - |