src/sys/kern/uipc_shm.c
/*
 * Helper routines to allow the backing object of a shared memory file
 * descriptor to be mapped in the kernel.
 */
Helper routines to allow the backing object of a shared memory file
descriptor to be mapped in the kernel.
Helper routines to allow the backing object of a shared memory file descriptor to be mapped in the kernel .
int
shm_map(struct file *fp, size_t size, off_t offset, void **memp)
{
	struct shmfd *shmfd;
	vm_offset_t kva, ofs;
	vm_object_t obj;
	int rv;
	if (fp->f_type != DTYPE_SHM)
		return (EINVAL);
	shmfd = fp->f_data;
	obj = shmfd->shm_object;
	VM_OBJECT_WLOCK(obj);
	if (offset >= shmfd->shm_size ||
	    offset + size > round_page(shmfd->shm_size)) {
		VM_OBJECT_WUNLOCK(obj);
		return (EINVAL);
	}
	shmfd->shm_kmappings++;
	vm_object_reference_locked(obj);
	VM_OBJECT_WUNLOCK(obj);
	kva = vm_map_min(kernel_map);
	ofs = offset & PAGE_MASK;
	offset = trunc_page(offset);
	size = round_page(size + ofs);
	rv = vm_map_find(kernel_map, obj, offset, &kva, size, 0,
	    VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE,
	    VM_PROT_READ | VM_PROT_WRITE, 0);
	if (rv == KERN_SUCCESS) {
		rv = vm_map_wire(kernel_map, kva, kva + size,
		    VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
		if (rv == KERN_SUCCESS) {
			*memp = (void *)(kva + ofs);
			return (0);
		}
		vm_map_remove(kernel_map, kva, kva + size);
	} else
		vm_object_deallocate(obj);
	VM_OBJECT_WLOCK(obj);
	shmfd->shm_kmappings--;
	VM_OBJECT_WUNLOCK(obj);
	return (vm_mmap_to_errno(rv));
}
int shm_map ( struct file * fp , size_t size , off_t offset , void * * memp ) { struct shmfd * shmfd ; vm_offset_t kva , ofs ; vm_object_t obj ; int rv ; if ( fp -> f_type != DTYPE_SHM ) return ( EINVAL ) ; shmfd = fp -> f_data ; obj = shmfd -> shm_object ; VM_OBJECT_WLOCK ( obj ) ; if ( offset >= shmfd -> shm_size || offset + size > round_page ( shmfd -> shm_size ) ) { VM_OBJECT_WUNLOCK ( obj ) ; return ( EINVAL ) ; } shmfd -> shm_kmappings ++ ; vm_object_reference_locked ( obj ) ; VM_OBJECT_WUNLOCK ( obj ) ; kva = vm_map_min ( kernel_map ) ; ofs = offset & PAGE_MASK ; offset = trunc_page ( offset ) ; size = round_page ( size + ofs ) ; rv = vm_map_find ( kernel_map , obj , offset , & kva , size , 0 , VMFS_OPTIMAL_SPACE , VM_PROT_READ | VM_PROT_WRITE , VM_PROT_READ | VM_PROT_WRITE , 0 ) ; if ( rv == KERN_SUCCESS ) { rv = vm_map_wire ( kernel_map , kva , kva + size , VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES ) ; if ( rv == KERN_SUCCESS ) { * memp = ( void * ) ( kva + ofs ) ; return ( 0 ) ; } vm_map_remove ( kernel_map , kva , kva + size ) ; } else vm_object_deallocate ( obj ) ; VM_OBJECT_WLOCK ( obj ) ; shmfd -> shm_kmappings -- ; VM_OBJECT_WUNLOCK ( obj ) ; return ( vm_mmap_to_errno ( rv ) ) ; }
Helper routines to allow the backing object of a shared memory file
 descriptor to be mapped in the kernel.
Helper routines to allow the backing object of a shared memory file descriptor to be mapped in the kernel .
/*
	 * XXXRW: This validation is probably insufficient, and subject to
	 * sign errors.  It should be fixed.
	 */ /* Map the object into the kernel_map and wire it. */ /* On failure, drop our mapping reference. */