summaryrefslogtreecommitdiff
path: root/mach-defpager/wiring.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2010-07-17 16:24:39 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2011-04-03 15:47:34 +0000
commita8744157214a302d84c8959b1ae99abe3ae2d7d2 (patch)
tree1cfebbd27e311beee3a6a1660ff7d08624ca20d8 /mach-defpager/wiring.c
parentbebc64a9a0f064a0e5f8a3549aa01aa9ac79a2e9 (diff)
Remove `serverboot'; fix "make dist" in `mach-defpager'.
* serverboot/default_pager.c, serverboot/kalloc.c, serverboot/queue.h, serverboot/wiring.c, serverboot/wiring.h: Move to `mach-defpager/'. * serverboot/Makefile, serverboot/assert.h, serverboot/bootstrap.c, serverboot/bunzip2.c, serverboot/def_pager_setup.c, serverboot/defs.h, serverboot/dir.h, serverboot/disk_inode.h, serverboot/disk_inode_ffs.h, serverboot/elf-load.c, serverboot/exec.c, serverboot/ext2_file_io.c, serverboot/ffs_compat.c, serverboot/ffs_compat.h, serverboot/ffs_file_io.c, serverboot/file_io.c, serverboot/file_io.h, serverboot/fs.h, serverboot/gets.c, serverboot/gunzip.c, serverboot/load.c, serverboot/mach-exec.h, serverboot/minix_ffs_compat.c, serverboot/minix_ffs_compat.h, serverboot/minix_file_io.c, serverboot/minix_fs.h, serverboot/minix_super.h, serverboot/panic.c, serverboot/strfcns.c: Remove. * mach-defpager/Makefile (LCLHDRS): New variable. (vpath): Remove. (CPPFLAGS): Remove `-I$(srcdir)/../serverboot'. * mach-defpager/setup.c (page_aligned): Make public.
Diffstat (limited to 'mach-defpager/wiring.c')
-rw-r--r--mach-defpager/wiring.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/mach-defpager/wiring.c b/mach-defpager/wiring.c
new file mode 100644
index 00000000..585a3075
--- /dev/null
+++ b/mach-defpager/wiring.c
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+/*
+ * Package to wire current task's memory.
+ */
+#include <mach.h>
+#include <mach_init.h>
+#include <mach/machine/vm_param.h>
+
+mach_port_t this_task; /* our task */
+mach_port_t priv_host_port = MACH_PORT_NULL;
+ /* the privileged host port */
+
+void
+wire_setup(host_priv)
+ mach_port_t host_priv;
+{
+ priv_host_port = host_priv;
+ this_task = mach_task_self();
+}
+
+void
+wire_memory(start, size, prot)
+ vm_address_t start;
+ vm_size_t size;
+ vm_prot_t prot;
+{
+ kern_return_t kr;
+
+ if (priv_host_port == MACH_PORT_NULL)
+ return;
+
+ kr = vm_wire(priv_host_port,
+ this_task,
+ start, size, prot);
+ if (kr != KERN_SUCCESS)
+ panic("mem_wire: %d", kr);
+}
+
+void
+wire_thread()
+{
+ kern_return_t kr;
+
+ if (priv_host_port == MACH_PORT_NULL)
+ return;
+
+ kr = thread_wire(priv_host_port,
+ mach_thread_self(),
+ TRUE);
+ if (kr != KERN_SUCCESS)
+ panic("wire_thread: %d", kr);
+}
+
+void
+wire_all_memory()
+{
+ register kern_return_t kr;
+ vm_offset_t address;
+ vm_size_t size;
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ boolean_t is_shared;
+ memory_object_name_t object;
+ vm_offset_t offset;
+
+ if (priv_host_port == MACH_PORT_NULL)
+ return;
+
+ /* iterate thru all regions, wiring */
+ address = 0;
+ while (
+ (kr = vm_region(this_task, &address,
+ &size,
+ &protection,
+ &max_protection,
+ &inheritance,
+ &is_shared,
+ &object,
+ &offset))
+ == KERN_SUCCESS)
+ {
+ if (MACH_PORT_VALID(object))
+ (void) mach_port_deallocate(this_task, object);
+ if (protection != VM_PROT_NONE)
+ {
+ /* 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;
+ }
+}
+
+/*
+ * Alias for vm_allocate to return wired memory.
+ */
+kern_return_t
+vm_allocate(task, address, size, anywhere)
+ task_t task;
+ vm_address_t *address;
+ vm_size_t size;
+ boolean_t anywhere;
+{
+ kern_return_t kr;
+
+ if (anywhere)
+ *address = VM_MIN_ADDRESS;
+ kr = vm_map(task,
+ address, size, (vm_offset_t) 0, anywhere,
+ MEMORY_OBJECT_NULL, (vm_offset_t)0, FALSE,
+ VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
+ if (kr != KERN_SUCCESS)
+ return kr;
+
+ if (task == this_task)
+ (void) vm_wire(priv_host_port, task, *address, size,
+ VM_PROT_DEFAULT);
+ return KERN_SUCCESS;
+}
+
+/* Other versions of this function in libc... */
+kern_return_t
+__vm_allocate (task, address, size, anywhere)
+ task_t task;
+ vm_address_t *address;
+ vm_size_t size;
+ boolean_t anywhere;
+{
+ return vm_allocate (task, address, size, anywhere);
+}