mm/util.c

Source file repositories/reference/linux-study-clean/mm/util.c

File Facts

System
Linux kernel
Corpus path
mm/util.c
Extension
.c
Size
43913 bytes
Lines
1609
Domain
Core OS
Bucket
Memory Management
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

ret = do_mmap(file, addr, len, prot, flag, 0, pgoff, &populate,
			      &uf);
		mmap_write_unlock(mm);
		userfaultfd_unmap_complete(mm, &uf);
		if (populate)
			mm_populate(ret, populate);
	}
	return ret;
}

/*
 * Perform a userland memory mapping into the current process address space. See
 * the comment for do_mmap() for more details on this operation in general.
 *
 * This differs from do_mmap() in that:
 *
 * a. An offset parameter is provided rather than pgoff, which is both checked
 *    for overflow and page alignment.
 * b. mmap locking is performed on the caller's behalf.
 * c. Userfaultfd unmap events and memory population are handled.
 *
 * This means that this function performs essentially the same work as if
 * userland were invoking mmap (2).
 *
 * Returns either an error, or the address at which the requested mapping has
 * been performed.
 */
unsigned long vm_mmap(struct file *file, unsigned long addr,
	unsigned long len, unsigned long prot,
	unsigned long flag, unsigned long offset)
{
	if (unlikely(offset + PAGE_ALIGN(len) < offset))
		return -EINVAL;
	if (unlikely(offset_in_page(offset)))
		return -EINVAL;

	return vm_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
}
EXPORT_SYMBOL(vm_mmap);

#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK
/*
 * Perform a userland memory mapping for a shadow stack into the current
 * process address space. This is intended to be used by architectures that
 * support user shadow stacks.
 */
unsigned long vm_mmap_shadow_stack(unsigned long addr, unsigned long len,
		unsigned long flags)
{
	struct mm_struct *mm = current->mm;
	unsigned long ret, unused;
	vm_flags_t vm_flags = VM_SHADOW_STACK;

	flags |= MAP_ANONYMOUS | MAP_PRIVATE;
	if (addr)
		flags |= MAP_FIXED_NOREPLACE;

	if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
		vm_flags |= VM_NOHUGEPAGE;

	mmap_write_lock(mm);
	ret = do_mmap(NULL, addr, len, PROT_READ | PROT_WRITE, flags,
		      vm_flags, 0, &unused, NULL);
	mmap_write_unlock(mm);

	return ret;
}
#endif /* CONFIG_ARCH_HAS_USER_SHADOW_STACK */

/**
 * __vmalloc_array - allocate memory for a virtually contiguous array.
 * @n: number of elements.
 * @size: element size.
 * @flags: the type of memory to allocate (see kmalloc).
 */
void *__vmalloc_array_noprof(size_t n, size_t size, gfp_t flags)
{
	size_t bytes;

	if (unlikely(check_mul_overflow(n, size, &bytes)))
		return NULL;
	return __vmalloc_noprof(bytes, flags);
}
EXPORT_SYMBOL(__vmalloc_array_noprof);

/**
 * vmalloc_array - allocate memory for a virtually contiguous array.
 * @n: number of elements.
 * @size: element size.
 */

Annotation

Implementation Notes