forked from mirrors/linux
		
	mm: create the new vm_fault_t type
Page fault handlers are supposed to return VM_FAULT codes, but some drivers/file systems mistakenly return error numbers. Now that all drivers/file systems have been converted to use the vm_fault_t return type, change the type definition to no longer be compatible with 'int'. By making it an unsigned int, the function prototype becomes incompatible with a function which returns int. Sparse will detect any attempts to return a value which is not a VM_FAULT code. VM_FAULT_SET_HINDEX and VM_FAULT_GET_HINDEX values are changed to avoid conflict with other VM_FAULT codes. [jrdr.linux@gmail.com: fix warnings] Link: http://lkml.kernel.org/r/20190109183742.GA24326@jordon-HP-15-Notebook-PC Link: http://lkml.kernel.org/r/20190108183041.GA12137@jordon-HP-15-Notebook-PC Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com> Reviewed-by: William Kucharski <william.kucharski@oracle.com> Reviewed-by: Mike Rapoport <rppt@linux.ibm.com> Reviewed-by: Matthew Wilcox <willy@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									c2938eeb88
								
							
						
					
					
						commit
						3d3539018d
					
				
					 3 changed files with 73 additions and 48 deletions
				
			
		|  | @ -1031,7 +1031,7 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code, | |||
| 
 | ||||
| static void | ||||
| do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | ||||
| 	  unsigned int fault) | ||||
| 	  vm_fault_t fault) | ||||
| { | ||||
| 	struct task_struct *tsk = current; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1322,52 +1322,6 @@ static inline void clear_page_pfmemalloc(struct page *page) | |||
| 	page->index = 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Different kinds of faults, as returned by handle_mm_fault(). | ||||
|  * Used to decide whether a process gets delivered SIGBUS or | ||||
|  * just gets major/minor fault counters bumped up. | ||||
|  */ | ||||
| 
 | ||||
| #define VM_FAULT_OOM	0x0001 | ||||
| #define VM_FAULT_SIGBUS	0x0002 | ||||
| #define VM_FAULT_MAJOR	0x0004 | ||||
| #define VM_FAULT_WRITE	0x0008	/* Special case for get_user_pages */ | ||||
| #define VM_FAULT_HWPOISON 0x0010	/* Hit poisoned small page */ | ||||
| #define VM_FAULT_HWPOISON_LARGE 0x0020  /* Hit poisoned large page. Index encoded in upper bits */ | ||||
| #define VM_FAULT_SIGSEGV 0x0040 | ||||
| 
 | ||||
| #define VM_FAULT_NOPAGE	0x0100	/* ->fault installed the pte, not return page */ | ||||
| #define VM_FAULT_LOCKED	0x0200	/* ->fault locked the returned page */ | ||||
| #define VM_FAULT_RETRY	0x0400	/* ->fault blocked, must retry */ | ||||
| #define VM_FAULT_FALLBACK 0x0800	/* huge page fault failed, fall back to small */ | ||||
| #define VM_FAULT_DONE_COW   0x1000	/* ->fault has fully handled COW */ | ||||
| #define VM_FAULT_NEEDDSYNC  0x2000	/* ->fault did not modify page tables | ||||
| 					 * and needs fsync() to complete (for | ||||
| 					 * synchronous page faults in DAX) */ | ||||
| 
 | ||||
| #define VM_FAULT_ERROR	(VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | \ | ||||
| 			 VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE | \ | ||||
| 			 VM_FAULT_FALLBACK) | ||||
| 
 | ||||
| #define VM_FAULT_RESULT_TRACE \ | ||||
| 	{ VM_FAULT_OOM,			"OOM" }, \ | ||||
| 	{ VM_FAULT_SIGBUS,		"SIGBUS" }, \ | ||||
| 	{ VM_FAULT_MAJOR,		"MAJOR" }, \ | ||||
| 	{ VM_FAULT_WRITE,		"WRITE" }, \ | ||||
| 	{ VM_FAULT_HWPOISON,		"HWPOISON" }, \ | ||||
| 	{ VM_FAULT_HWPOISON_LARGE,	"HWPOISON_LARGE" }, \ | ||||
| 	{ VM_FAULT_SIGSEGV,		"SIGSEGV" }, \ | ||||
| 	{ VM_FAULT_NOPAGE,		"NOPAGE" }, \ | ||||
| 	{ VM_FAULT_LOCKED,		"LOCKED" }, \ | ||||
| 	{ VM_FAULT_RETRY,		"RETRY" }, \ | ||||
| 	{ VM_FAULT_FALLBACK,		"FALLBACK" }, \ | ||||
| 	{ VM_FAULT_DONE_COW,		"DONE_COW" }, \ | ||||
| 	{ VM_FAULT_NEEDDSYNC,		"NEEDDSYNC" } | ||||
| 
 | ||||
| /* Encode hstate index for a hwpoisoned large page */ | ||||
| #define VM_FAULT_SET_HINDEX(x) ((x) << 12) | ||||
| #define VM_FAULT_GET_HINDEX(x) (((x) >> 12) & 0xf) | ||||
| 
 | ||||
| /*
 | ||||
|  * Can be called by the pagefault handler when it gets a VM_FAULT_OOM. | ||||
|  */ | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ | |||
| #endif | ||||
| #define AT_VECTOR_SIZE (2*(AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1)) | ||||
| 
 | ||||
| typedef int vm_fault_t; | ||||
| 
 | ||||
| struct address_space; | ||||
| struct mem_cgroup; | ||||
|  | @ -621,6 +620,78 @@ static inline bool mm_tlb_flush_nested(struct mm_struct *mm) | |||
| 
 | ||||
| struct vm_fault; | ||||
| 
 | ||||
| /**
 | ||||
|  * typedef vm_fault_t - Return type for page fault handlers. | ||||
|  * | ||||
|  * Page fault handlers return a bitmask of %VM_FAULT values. | ||||
|  */ | ||||
| typedef __bitwise unsigned int vm_fault_t; | ||||
| 
 | ||||
| /**
 | ||||
|  * enum vm_fault_reason - Page fault handlers return a bitmask of | ||||
|  * these values to tell the core VM what happened when handling the | ||||
|  * fault. Used to decide whether a process gets delivered SIGBUS or | ||||
|  * just gets major/minor fault counters bumped up. | ||||
|  * | ||||
|  * @VM_FAULT_OOM:		Out Of Memory | ||||
|  * @VM_FAULT_SIGBUS:		Bad access | ||||
|  * @VM_FAULT_MAJOR:		Page read from storage | ||||
|  * @VM_FAULT_WRITE:		Special case for get_user_pages | ||||
|  * @VM_FAULT_HWPOISON:		Hit poisoned small page | ||||
|  * @VM_FAULT_HWPOISON_LARGE:	Hit poisoned large page. Index encoded | ||||
|  *				in upper bits | ||||
|  * @VM_FAULT_SIGSEGV:		segmentation fault | ||||
|  * @VM_FAULT_NOPAGE:		->fault installed the pte, not return page | ||||
|  * @VM_FAULT_LOCKED:		->fault locked the returned page | ||||
|  * @VM_FAULT_RETRY:		->fault blocked, must retry | ||||
|  * @VM_FAULT_FALLBACK:		huge page fault failed, fall back to small | ||||
|  * @VM_FAULT_DONE_COW:		->fault has fully handled COW | ||||
|  * @VM_FAULT_NEEDDSYNC:		->fault did not modify page tables and needs | ||||
|  *				fsync() to complete (for synchronous page faults | ||||
|  *				in DAX) | ||||
|  * @VM_FAULT_HINDEX_MASK:	mask HINDEX value | ||||
|  * | ||||
|  */ | ||||
| enum vm_fault_reason { | ||||
| 	VM_FAULT_OOM            = (__force vm_fault_t)0x000001, | ||||
| 	VM_FAULT_SIGBUS         = (__force vm_fault_t)0x000002, | ||||
| 	VM_FAULT_MAJOR          = (__force vm_fault_t)0x000004, | ||||
| 	VM_FAULT_WRITE          = (__force vm_fault_t)0x000008, | ||||
| 	VM_FAULT_HWPOISON       = (__force vm_fault_t)0x000010, | ||||
| 	VM_FAULT_HWPOISON_LARGE = (__force vm_fault_t)0x000020, | ||||
| 	VM_FAULT_SIGSEGV        = (__force vm_fault_t)0x000040, | ||||
| 	VM_FAULT_NOPAGE         = (__force vm_fault_t)0x000100, | ||||
| 	VM_FAULT_LOCKED         = (__force vm_fault_t)0x000200, | ||||
| 	VM_FAULT_RETRY          = (__force vm_fault_t)0x000400, | ||||
| 	VM_FAULT_FALLBACK       = (__force vm_fault_t)0x000800, | ||||
| 	VM_FAULT_DONE_COW       = (__force vm_fault_t)0x001000, | ||||
| 	VM_FAULT_NEEDDSYNC      = (__force vm_fault_t)0x002000, | ||||
| 	VM_FAULT_HINDEX_MASK    = (__force vm_fault_t)0x0f0000, | ||||
| }; | ||||
| 
 | ||||
| /* Encode hstate index for a hwpoisoned large page */ | ||||
| #define VM_FAULT_SET_HINDEX(x) ((__force vm_fault_t)((x) << 16)) | ||||
| #define VM_FAULT_GET_HINDEX(x) (((x) >> 16) & 0xf) | ||||
| 
 | ||||
| #define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS |	\ | ||||
| 			VM_FAULT_SIGSEGV | VM_FAULT_HWPOISON |	\ | ||||
| 			VM_FAULT_HWPOISON_LARGE | VM_FAULT_FALLBACK) | ||||
| 
 | ||||
| #define VM_FAULT_RESULT_TRACE \ | ||||
| 	{ VM_FAULT_OOM,                 "OOM" },	\ | ||||
| 	{ VM_FAULT_SIGBUS,              "SIGBUS" },	\ | ||||
| 	{ VM_FAULT_MAJOR,               "MAJOR" },	\ | ||||
| 	{ VM_FAULT_WRITE,               "WRITE" },	\ | ||||
| 	{ VM_FAULT_HWPOISON,            "HWPOISON" },	\ | ||||
| 	{ VM_FAULT_HWPOISON_LARGE,      "HWPOISON_LARGE" },	\ | ||||
| 	{ VM_FAULT_SIGSEGV,             "SIGSEGV" },	\ | ||||
| 	{ VM_FAULT_NOPAGE,              "NOPAGE" },	\ | ||||
| 	{ VM_FAULT_LOCKED,              "LOCKED" },	\ | ||||
| 	{ VM_FAULT_RETRY,               "RETRY" },	\ | ||||
| 	{ VM_FAULT_FALLBACK,            "FALLBACK" },	\ | ||||
| 	{ VM_FAULT_DONE_COW,            "DONE_COW" },	\ | ||||
| 	{ VM_FAULT_NEEDDSYNC,           "NEEDDSYNC" } | ||||
| 
 | ||||
| struct vm_special_mapping { | ||||
| 	const char *name;	/* The name, e.g. "[vdso]". */ | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Souptick Joarder
						Souptick Joarder