/* Create a new pager in USER_PAGER with NPAGES pages, and return a mapping to the memory in *USER. */ error_t user_pager_create (struct user_pager *user_pager, unsigned int npages, struct cons_display **user) { error_t err; struct user_pager_info *upi; upi = calloc (1, sizeof (struct user_pager_info) + sizeof (vm_address_t) * npages); if (!upi) return errno; upi->memobj_npages = npages; /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */ user_pager->pager = pager_create (upi, pager_bucket, 1, MEMORY_OBJECT_COPY_DELAY, 0); if (!user_pager->pager) { free (upi); return errno; } user_pager->memobj = pager_get_port (user_pager->pager); ports_port_deref (user_pager->pager); mach_port_insert_right (mach_task_self (), user_pager->memobj, user_pager->memobj, MACH_MSG_TYPE_MAKE_SEND); *user = 0; err = vm_map (mach_task_self (), (vm_address_t *) user, (vm_size_t) npages * vm_page_size, (vm_address_t) 0, 1 /* ! (flags & MAP_FIXED) */, user_pager->memobj, 0 /* (vm_offset_t) offset */, 0 /* ! (flags & MAP_SHARED) */, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_NONE); if (err) { /* UPI will be cleaned up by libpager. */ mach_port_deallocate (mach_task_self (), user_pager->memobj); return err; } return 0; }
void diskfs_start_disk_pager (struct user_pager_info *upi, struct port_bucket *pager_bucket, int may_cache, size_t size, void **image) { error_t err; mach_port_t disk_pager_port; /* Make a thread to service paging requests. */ cthread_detach (cthread_fork ((cthread_fn_t) service_paging_requests, (any_t)pager_bucket)); /* Create the pager. */ diskfs_disk_pager = pager_create (upi, pager_bucket, may_cache, MEMORY_OBJECT_COPY_NONE); assert (diskfs_disk_pager); /* Get a port to the disk pager. */ disk_pager_port = pager_get_port (diskfs_disk_pager); mach_port_insert_right (mach_task_self (), disk_pager_port, disk_pager_port, MACH_MSG_TYPE_MAKE_SEND); /* Now map the disk image. */ err = vm_map (mach_task_self (), (vm_address_t *)image, size, 0, 1, disk_pager_port, 0, 0, VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_NONE); if (err) error (2, err, "cannot vm_map whole disk"); /* Set up the signal preemptor to catch faults on the disk image. */ preemptor.first = (vm_address_t) *image; preemptor.last = ((vm_address_t) *image + size); hurd_preempt_signals (&preemptor); /* We have the mapping; we no longer need the send right. */ mach_port_deallocate (mach_task_self (), disk_pager_port); }