737 lines · 18.4 KB · C
RawDownload
#include <linux/mm.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/compiler.h>#include <linux/export.h>#include <linux/err.h>#include <linux/sched.h>#include <linux/sched/mm.h>#include <linux/sched/task_stack.h>#include <linux/security.h>#include <linux/swap.h>#include <linux/swapops.h>#include <linux/mman.h>#include <linux/hugetlb.h>#include <linux/vmalloc.h>#include <linux/userfaultfd_k.h> #include <asm/sections.h>#include <linux/uaccess.h> #include "internal.h" static inline int is_kernel_rodata(unsigned long addr){	return addr >= (unsigned long)__start_rodata &&		addr < (unsigned long)__end_rodata;} /** * kfree_const - conditionally free memory * @x: pointer to the memory * * Function calls kfree only if @x is not in .rodata section. */void kfree_const(const void *x){	if (!is_kernel_rodata((unsigned long)x))		kfree(x);}EXPORT_SYMBOL(kfree_const); /** * kstrdup - allocate space for and copy an existing string * @s: the string to duplicate * @gfp: the GFP mask used in the kmalloc() call when allocating memory */char *kstrdup(const char *s, gfp_t gfp){	size_t len;	char *buf; 	if (!s)		return NULL; 	len = strlen(s) + 1;	buf = kmalloc_track_caller(len, gfp);	if (buf)		memcpy(buf, s, len);	return buf;}EXPORT_SYMBOL(kstrdup); /** * kstrdup_const - conditionally duplicate an existing const string * @s: the string to duplicate * @gfp: the GFP mask used in the kmalloc() call when allocating memory * * Function returns source string if it is in .rodata section otherwise it * fallbacks to kstrdup. * Strings allocated by kstrdup_const should be freed by kfree_const. */const char *kstrdup_const(const char *s, gfp_t gfp){	if (is_kernel_rodata((unsigned long)s))		return s; 	return kstrdup(s, gfp);}EXPORT_SYMBOL(kstrdup_const); /** * kstrndup - allocate space for and copy an existing string * @s: the string to duplicate * @max: read at most @max chars from @s * @gfp: the GFP mask used in the kmalloc() call when allocating memory * * Note: Use kmemdup_nul() instead if the size is known exactly. */char *kstrndup(const char *s, size_t max, gfp_t gfp){	size_t len;	char *buf; 	if (!s)		return NULL; 	len = strnlen(s, max);	buf = kmalloc_track_caller(len+1, gfp);	if (buf) {		memcpy(buf, s, len);		buf[len] = '\0';	}	return buf;}EXPORT_SYMBOL(kstrndup); /** * kmemdup - duplicate region of memory * * @src: memory region to duplicate * @len: memory region length * @gfp: GFP mask to use */void *kmemdup(const void *src, size_t len, gfp_t gfp){	void *p; 	p = kmalloc_track_caller(len, gfp);	if (p)		memcpy(p, src, len);	return p;}EXPORT_SYMBOL(kmemdup); /** * kmemdup_nul - Create a NUL-terminated string from unterminated data * @s: The data to stringify * @len: The size of the data * @gfp: the GFP mask used in the kmalloc() call when allocating memory */char *kmemdup_nul(const char *s, size_t len, gfp_t gfp){	char *buf; 	if (!s)		return NULL; 	buf = kmalloc_track_caller(len + 1, gfp);	if (buf) {		memcpy(buf, s, len);		buf[len] = '\0';	}	return buf;}EXPORT_SYMBOL(kmemdup_nul); /** * memdup_user - duplicate memory region from user space * * @src: source address in user space * @len: number of bytes to copy * * Returns an ERR_PTR() on failure. */void *memdup_user(const void __user *src, size_t len){	void *p; 	/*	 * Always use GFP_KERNEL, since copy_from_user() can sleep and	 * cause pagefault, which makes it pointless to use GFP_NOFS	 * or GFP_ATOMIC.	 */	p = kmalloc_track_caller(len, GFP_KERNEL);	if (!p)		return ERR_PTR(-ENOMEM); 	if (copy_from_user(p, src, len)) {		kfree(p);		return ERR_PTR(-EFAULT);	} 	return p;}EXPORT_SYMBOL(memdup_user); /* * strndup_user - duplicate an existing string from user space * @s: The string to duplicate * @n: Maximum number of bytes to copy, including the trailing NUL. */char *strndup_user(const char __user *s, long n){	char *p;	long length; 	length = strnlen_user(s, n); 	if (!length)		return ERR_PTR(-EFAULT); 	if (length > n)		return ERR_PTR(-EINVAL); 	p = memdup_user(s, length); 	if (IS_ERR(p))		return p; 	p[length - 1] = '\0'; 	return p;}EXPORT_SYMBOL(strndup_user); /** * memdup_user_nul - duplicate memory region from user space and NUL-terminate * * @src: source address in user space * @len: number of bytes to copy * * Returns an ERR_PTR() on failure. */void *memdup_user_nul(const void __user *src, size_t len){	char *p; 	/*	 * Always use GFP_KERNEL, since copy_from_user() can sleep and	 * cause pagefault, which makes it pointless to use GFP_NOFS	 * or GFP_ATOMIC.	 */	p = kmalloc_track_caller(len + 1, GFP_KERNEL);	if (!p)		return ERR_PTR(-ENOMEM); 	if (copy_from_user(p, src, len)) {		kfree(p);		return ERR_PTR(-EFAULT);	}	p[len] = '\0'; 	return p;}EXPORT_SYMBOL(memdup_user_nul); void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,		struct vm_area_struct *prev, struct rb_node *rb_parent){	struct vm_area_struct *next; 	vma->vm_prev = prev;	if (prev) {		next = prev->vm_next;		prev->vm_next = vma;	} else {		mm->mmap = vma;		if (rb_parent)			next = rb_entry(rb_parent,					struct vm_area_struct, vm_rb);		else			next = NULL;	}	vma->vm_next = next;	if (next)		next->vm_prev = vma;} /* Check if the vma is being used as a stack by this task */int vma_is_stack_for_current(struct vm_area_struct *vma){	struct task_struct * __maybe_unused t = current; 	return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));} #if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)void arch_pick_mmap_layout(struct mm_struct *mm){	mm->mmap_base = TASK_UNMAPPED_BASE;	mm->get_unmapped_area = arch_get_unmapped_area;}#endif /* * Like get_user_pages_fast() except its IRQ-safe in that it won't fall * back to the regular GUP. * If the architecture not support this function, simply return with no * page pinned */int __weak __get_user_pages_fast(unsigned long start,				 int nr_pages, int write, struct page **pages){	return 0;}EXPORT_SYMBOL_GPL(__get_user_pages_fast); /** * get_user_pages_fast() - pin user pages in memory * @start:	starting user address * @nr_pages:	number of pages from start to pin * @write:	whether pages will be written to * @pages:	array that receives pointers to the pages pinned. *		Should be at least nr_pages long. * * Returns number of pages pinned. This may be fewer than the number * requested. If nr_pages is 0 or negative, returns 0. If no pages * were pinned, returns -errno. * * get_user_pages_fast provides equivalent functionality to get_user_pages, * operating on current and current->mm, with force=0 and vma=NULL. However * unlike get_user_pages, it must be called without mmap_sem held. * * get_user_pages_fast may take mmap_sem and page table locks, so no * assumptions can be made about lack of locking. get_user_pages_fast is to be * implemented in a way that is advantageous (vs get_user_pages()) when the * user memory area is already faulted in and present in ptes. However if the * pages have to be faulted in, it may turn out to be slightly slower so * callers need to carefully consider what to use. On many architectures, * get_user_pages_fast simply falls back to get_user_pages. */int __weak get_user_pages_fast(unsigned long start,				int nr_pages, int write, struct page **pages){	return get_user_pages_unlocked(start, nr_pages, pages,				       write ? FOLL_WRITE : 0);}EXPORT_SYMBOL_GPL(get_user_pages_fast); unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,	unsigned long len, unsigned long prot,	unsigned long flag, unsigned long pgoff){	unsigned long ret;	struct mm_struct *mm = current->mm;	unsigned long populate;	LIST_HEAD(uf); 	ret = security_mmap_file(file, prot, flag);	if (!ret) {		if (down_write_killable(&mm->mmap_sem))			return -EINTR;		ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff,				    &populate, &uf);		up_write(&mm->mmap_sem);		userfaultfd_unmap_complete(mm, &uf);		if (populate)			mm_populate(ret, populate);	}	return ret;} 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); /** * kvmalloc_node - attempt to allocate physically contiguous memory, but upon * failure, fall back to non-contiguous (vmalloc) allocation. * @size: size of the request. * @flags: gfp mask for the allocation - must be compatible (superset) with GFP_KERNEL. * @node: numa node to allocate from * * Uses kmalloc to get the memory but if the allocation fails then falls back * to the vmalloc allocator. Use kvfree for freeing the memory. * * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is * preferable to the vmalloc fallback, due to visible performance drawbacks. * * Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people. */void *kvmalloc_node(size_t size, gfp_t flags, int node){	gfp_t kmalloc_flags = flags;	void *ret; 	/*	 * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)	 * so the given set of flags has to be compatible.	 */	WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL); 	/*	 * We want to attempt a large physically contiguous block first because	 * it is less likely to fragment multiple larger blocks and therefore	 * contribute to a long term fragmentation less than vmalloc fallback.	 * However make sure that larger requests are not too disruptive - no	 * OOM killer and no allocation failure warnings as we have a fallback.	 */	if (size > PAGE_SIZE) {		kmalloc_flags |= __GFP_NOWARN; 		if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL))			kmalloc_flags |= __GFP_NORETRY;	} 	ret = kmalloc_node(size, kmalloc_flags, node); 	/*	 * It doesn't really make sense to fallback to vmalloc for sub page	 * requests	 */	if (ret || size <= PAGE_SIZE)		return ret; 	return __vmalloc_node_flags_caller(size, node, flags,			__builtin_return_address(0));}EXPORT_SYMBOL(kvmalloc_node); void kvfree(const void *addr){	if (is_vmalloc_addr(addr))		vfree(addr);	else		kfree(addr);}EXPORT_SYMBOL(kvfree); static inline void *__page_rmapping(struct page *page){	unsigned long mapping; 	mapping = (unsigned long)page->mapping;	mapping &= ~PAGE_MAPPING_FLAGS; 	return (void *)mapping;} /* Neutral page->mapping pointer to address_space or anon_vma or other */void *page_rmapping(struct page *page){	page = compound_head(page);	return __page_rmapping(page);} /* * Return true if this page is mapped into pagetables. * For compound page it returns true if any subpage of compound page is mapped. */bool page_mapped(struct page *page){	int i; 	if (likely(!PageCompound(page)))		return atomic_read(&page->_mapcount) >= 0;	page = compound_head(page);	if (atomic_read(compound_mapcount_ptr(page)) >= 0)		return true;	if (PageHuge(page))		return false;	for (i = 0; i < hpage_nr_pages(page); i++) {		if (atomic_read(&page[i]._mapcount) >= 0)			return true;	}	return false;}EXPORT_SYMBOL(page_mapped); struct anon_vma *page_anon_vma(struct page *page){	unsigned long mapping; 	page = compound_head(page);	mapping = (unsigned long)page->mapping;	if ((mapping & PAGE_MAPPING_FLAGS) != PAGE_MAPPING_ANON)		return NULL;	return __page_rmapping(page);} struct address_space *page_mapping(struct page *page){	struct address_space *mapping; 	page = compound_head(page); 	/* This happens if someone calls flush_dcache_page on slab page */	if (unlikely(PageSlab(page)))		return NULL; 	if (unlikely(PageSwapCache(page))) {		swp_entry_t entry; 		entry.val = page_private(page);		return swap_address_space(entry);	} 	mapping = page->mapping;	if ((unsigned long)mapping & PAGE_MAPPING_ANON)		return NULL; 	return (void *)((unsigned long)mapping & ~PAGE_MAPPING_FLAGS);}EXPORT_SYMBOL(page_mapping); /* Slow path of page_mapcount() for compound pages */int __page_mapcount(struct page *page){	int ret; 

Lines 1–500 of 737.