Skip to content

Commit 3d35390

Browse files
Souptick Joardertorvalds
authored andcommitted
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. [[email protected]: 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 <[email protected]> Reviewed-by: William Kucharski <[email protected]> Reviewed-by: Mike Rapoport <[email protected]> Reviewed-by: Matthew Wilcox <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Dan Williams <[email protected]> Cc: Kirill A. Shutemov <[email protected]> Cc: Rik van Riel <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c2938ee commit 3d35390

File tree

3 files changed

+73
-48
lines changed

3 files changed

+73
-48
lines changed

arch/x86/mm/fault.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
10311031

10321032
static void
10331033
do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
1034-
unsigned int fault)
1034+
vm_fault_t fault)
10351035
{
10361036
struct task_struct *tsk = current;
10371037

include/linux/mm.h

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,52 +1322,6 @@ static inline void clear_page_pfmemalloc(struct page *page)
13221322
page->index = 0;
13231323
}
13241324

1325-
/*
1326-
* Different kinds of faults, as returned by handle_mm_fault().
1327-
* Used to decide whether a process gets delivered SIGBUS or
1328-
* just gets major/minor fault counters bumped up.
1329-
*/
1330-
1331-
#define VM_FAULT_OOM 0x0001
1332-
#define VM_FAULT_SIGBUS 0x0002
1333-
#define VM_FAULT_MAJOR 0x0004
1334-
#define VM_FAULT_WRITE 0x0008 /* Special case for get_user_pages */
1335-
#define VM_FAULT_HWPOISON 0x0010 /* Hit poisoned small page */
1336-
#define VM_FAULT_HWPOISON_LARGE 0x0020 /* Hit poisoned large page. Index encoded in upper bits */
1337-
#define VM_FAULT_SIGSEGV 0x0040
1338-
1339-
#define VM_FAULT_NOPAGE 0x0100 /* ->fault installed the pte, not return page */
1340-
#define VM_FAULT_LOCKED 0x0200 /* ->fault locked the returned page */
1341-
#define VM_FAULT_RETRY 0x0400 /* ->fault blocked, must retry */
1342-
#define VM_FAULT_FALLBACK 0x0800 /* huge page fault failed, fall back to small */
1343-
#define VM_FAULT_DONE_COW 0x1000 /* ->fault has fully handled COW */
1344-
#define VM_FAULT_NEEDDSYNC 0x2000 /* ->fault did not modify page tables
1345-
* and needs fsync() to complete (for
1346-
* synchronous page faults in DAX) */
1347-
1348-
#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | \
1349-
VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE | \
1350-
VM_FAULT_FALLBACK)
1351-
1352-
#define VM_FAULT_RESULT_TRACE \
1353-
{ VM_FAULT_OOM, "OOM" }, \
1354-
{ VM_FAULT_SIGBUS, "SIGBUS" }, \
1355-
{ VM_FAULT_MAJOR, "MAJOR" }, \
1356-
{ VM_FAULT_WRITE, "WRITE" }, \
1357-
{ VM_FAULT_HWPOISON, "HWPOISON" }, \
1358-
{ VM_FAULT_HWPOISON_LARGE, "HWPOISON_LARGE" }, \
1359-
{ VM_FAULT_SIGSEGV, "SIGSEGV" }, \
1360-
{ VM_FAULT_NOPAGE, "NOPAGE" }, \
1361-
{ VM_FAULT_LOCKED, "LOCKED" }, \
1362-
{ VM_FAULT_RETRY, "RETRY" }, \
1363-
{ VM_FAULT_FALLBACK, "FALLBACK" }, \
1364-
{ VM_FAULT_DONE_COW, "DONE_COW" }, \
1365-
{ VM_FAULT_NEEDDSYNC, "NEEDDSYNC" }
1366-
1367-
/* Encode hstate index for a hwpoisoned large page */
1368-
#define VM_FAULT_SET_HINDEX(x) ((x) << 12)
1369-
#define VM_FAULT_GET_HINDEX(x) (((x) >> 12) & 0xf)
1370-
13711325
/*
13721326
* Can be called by the pagefault handler when it gets a VM_FAULT_OOM.
13731327
*/

include/linux/mm_types.h

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#endif
2323
#define AT_VECTOR_SIZE (2*(AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))
2424

25-
typedef int vm_fault_t;
2625

2726
struct address_space;
2827
struct mem_cgroup;
@@ -621,6 +620,78 @@ static inline bool mm_tlb_flush_nested(struct mm_struct *mm)
621620

622621
struct vm_fault;
623622

623+
/**
624+
* typedef vm_fault_t - Return type for page fault handlers.
625+
*
626+
* Page fault handlers return a bitmask of %VM_FAULT values.
627+
*/
628+
typedef __bitwise unsigned int vm_fault_t;
629+
630+
/**
631+
* enum vm_fault_reason - Page fault handlers return a bitmask of
632+
* these values to tell the core VM what happened when handling the
633+
* fault. Used to decide whether a process gets delivered SIGBUS or
634+
* just gets major/minor fault counters bumped up.
635+
*
636+
* @VM_FAULT_OOM: Out Of Memory
637+
* @VM_FAULT_SIGBUS: Bad access
638+
* @VM_FAULT_MAJOR: Page read from storage
639+
* @VM_FAULT_WRITE: Special case for get_user_pages
640+
* @VM_FAULT_HWPOISON: Hit poisoned small page
641+
* @VM_FAULT_HWPOISON_LARGE: Hit poisoned large page. Index encoded
642+
* in upper bits
643+
* @VM_FAULT_SIGSEGV: segmentation fault
644+
* @VM_FAULT_NOPAGE: ->fault installed the pte, not return page
645+
* @VM_FAULT_LOCKED: ->fault locked the returned page
646+
* @VM_FAULT_RETRY: ->fault blocked, must retry
647+
* @VM_FAULT_FALLBACK: huge page fault failed, fall back to small
648+
* @VM_FAULT_DONE_COW: ->fault has fully handled COW
649+
* @VM_FAULT_NEEDDSYNC: ->fault did not modify page tables and needs
650+
* fsync() to complete (for synchronous page faults
651+
* in DAX)
652+
* @VM_FAULT_HINDEX_MASK: mask HINDEX value
653+
*
654+
*/
655+
enum vm_fault_reason {
656+
VM_FAULT_OOM = (__force vm_fault_t)0x000001,
657+
VM_FAULT_SIGBUS = (__force vm_fault_t)0x000002,
658+
VM_FAULT_MAJOR = (__force vm_fault_t)0x000004,
659+
VM_FAULT_WRITE = (__force vm_fault_t)0x000008,
660+
VM_FAULT_HWPOISON = (__force vm_fault_t)0x000010,
661+
VM_FAULT_HWPOISON_LARGE = (__force vm_fault_t)0x000020,
662+
VM_FAULT_SIGSEGV = (__force vm_fault_t)0x000040,
663+
VM_FAULT_NOPAGE = (__force vm_fault_t)0x000100,
664+
VM_FAULT_LOCKED = (__force vm_fault_t)0x000200,
665+
VM_FAULT_RETRY = (__force vm_fault_t)0x000400,
666+
VM_FAULT_FALLBACK = (__force vm_fault_t)0x000800,
667+
VM_FAULT_DONE_COW = (__force vm_fault_t)0x001000,
668+
VM_FAULT_NEEDDSYNC = (__force vm_fault_t)0x002000,
669+
VM_FAULT_HINDEX_MASK = (__force vm_fault_t)0x0f0000,
670+
};
671+
672+
/* Encode hstate index for a hwpoisoned large page */
673+
#define VM_FAULT_SET_HINDEX(x) ((__force vm_fault_t)((x) << 16))
674+
#define VM_FAULT_GET_HINDEX(x) (((x) >> 16) & 0xf)
675+
676+
#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS | \
677+
VM_FAULT_SIGSEGV | VM_FAULT_HWPOISON | \
678+
VM_FAULT_HWPOISON_LARGE | VM_FAULT_FALLBACK)
679+
680+
#define VM_FAULT_RESULT_TRACE \
681+
{ VM_FAULT_OOM, "OOM" }, \
682+
{ VM_FAULT_SIGBUS, "SIGBUS" }, \
683+
{ VM_FAULT_MAJOR, "MAJOR" }, \
684+
{ VM_FAULT_WRITE, "WRITE" }, \
685+
{ VM_FAULT_HWPOISON, "HWPOISON" }, \
686+
{ VM_FAULT_HWPOISON_LARGE, "HWPOISON_LARGE" }, \
687+
{ VM_FAULT_SIGSEGV, "SIGSEGV" }, \
688+
{ VM_FAULT_NOPAGE, "NOPAGE" }, \
689+
{ VM_FAULT_LOCKED, "LOCKED" }, \
690+
{ VM_FAULT_RETRY, "RETRY" }, \
691+
{ VM_FAULT_FALLBACK, "FALLBACK" }, \
692+
{ VM_FAULT_DONE_COW, "DONE_COW" }, \
693+
{ VM_FAULT_NEEDDSYNC, "NEEDDSYNC" }
694+
624695
struct vm_special_mapping {
625696
const char *name; /* The name, e.g. "[vdso]". */
626697

0 commit comments

Comments
 (0)