Re: [tip:x86/mm] x86/mm: Break out user address space handling
* Eric W. Biederman wrote: > tip-bot for Dave Hansen writes: > > > Commit-ID: aa37c51b9421d66f7931c5fdcb9ce80c450974be > > Gitweb: > > https://git.kernel.org/tip/aa37c51b9421d66f7931c5fdcb9ce80c450974be > > Author: Dave Hansen > > AuthorDate: Fri, 28 Sep 2018 09:02:23 -0700 > > Committer: Peter Zijlstra > > CommitDate: Tue, 9 Oct 2018 16:51:15 +0200 > > > > x86/mm: Break out user address space handling > > > > The last patch broke out kernel address space handing into its own > > helper. Now, do the same for user address space handling. > > > > Cc: x...@kernel.org > > Cc: Jann Horn > > Cc: Sean Christopherson > > Cc: Thomas Gleixner > > Cc: Andy Lutomirski > > Signed-off-by: Dave Hansen > > Signed-off-by: Peter Zijlstra (Intel) > > Link: http://lkml.kernel.org/r/20180928160223.9c4f6...@viggo.jf.intel.com > > --- > > arch/x86/mm/fault.c | 47 --- > > 1 file changed, 28 insertions(+), 19 deletions(-) > > > > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > > index c7e32f453852..0d1f5d39fc63 100644 > > --- a/arch/x86/mm/fault.c > > +++ b/arch/x86/mm/fault.c > > @@ -966,6 +966,7 @@ bad_area_access_error(struct pt_regs *regs, unsigned > > long error_code, > > __bad_area(regs, error_code, address, vma, SEGV_ACCERR); > > } > > > > +/* Handle faults in the kernel portion of the address space */ >^^ > I believe you mean the __user__ portion of the address space. > Given that the call chain is: > > do_user_addr_fault >handle_mm_fault > do_sigbus It's both: /* Handle faults in the kernel portion of the address space */ static void do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, u32 *pkey, unsigned int fault) { struct task_struct *tsk = current; int code = BUS_ADRERR; /* Kernel mode? Handle exceptions or die: */ if (!(error_code & X86_PF_USER)) { no_context(regs, error_code, address, SIGBUS, BUS_ADRERR); return; } /* User-space => ok to do another page fault: */ if (is_prefetch(regs, error_code, address)) return; tsk->thread.cr2 = address; tsk->thread.error_code = error_code; tsk->thread.trap_nr = X86_TRAP_PF; Note the X86_PF_USER check: that's what determines whether the fault was for user or system mappings. I agree that the comment is misleading and should be clarified. Thanks, Ingo
Re: [tip:x86/mm] x86/mm: Break out user address space handling
tip-bot for Dave Hansen writes: > Commit-ID: aa37c51b9421d66f7931c5fdcb9ce80c450974be > Gitweb: > https://git.kernel.org/tip/aa37c51b9421d66f7931c5fdcb9ce80c450974be > Author: Dave Hansen > AuthorDate: Fri, 28 Sep 2018 09:02:23 -0700 > Committer: Peter Zijlstra > CommitDate: Tue, 9 Oct 2018 16:51:15 +0200 > > x86/mm: Break out user address space handling > > The last patch broke out kernel address space handing into its own > helper. Now, do the same for user address space handling. > > Cc: x...@kernel.org > Cc: Jann Horn > Cc: Sean Christopherson > Cc: Thomas Gleixner > Cc: Andy Lutomirski > Signed-off-by: Dave Hansen > Signed-off-by: Peter Zijlstra (Intel) > Link: http://lkml.kernel.org/r/20180928160223.9c4f6...@viggo.jf.intel.com > --- > arch/x86/mm/fault.c | 47 --- > 1 file changed, 28 insertions(+), 19 deletions(-) > > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > index c7e32f453852..0d1f5d39fc63 100644 > --- a/arch/x86/mm/fault.c > +++ b/arch/x86/mm/fault.c > @@ -966,6 +966,7 @@ bad_area_access_error(struct pt_regs *regs, unsigned long > error_code, > __bad_area(regs, error_code, address, vma, SEGV_ACCERR); > } > > +/* Handle faults in the kernel portion of the address space */ ^^ I believe you mean the __user__ portion of the address space. Given that the call chain is: do_user_addr_fault handle_mm_fault do_sigbus > static void > do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long > address, > u32 *pkey, unsigned int fault) > @@ -1254,14 +1255,11 @@ do_kern_addr_fault(struct pt_regs *regs, unsigned > long hw_error_code, > } > NOKPROBE_SYMBOL(do_kern_addr_fault); > > -/* > - * This routine handles page faults. It determines the address, > - * and the problem, and then passes it off to one of the appropriate > - * routines. > - */ > -static noinline void > -__do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, > - unsigned long address) > +/* Handle faults in the user portion of the address space */ > +static inline > +void do_user_addr_fault(struct pt_regs *regs, > + unsigned long hw_error_code, > + unsigned long address) > { > unsigned long sw_error_code; > struct vm_area_struct *vma; > @@ -1274,17 +1272,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long > hw_error_code, > tsk = current; > mm = tsk->mm; > > - prefetchw(&mm->mmap_sem); > - > - if (unlikely(kmmio_fault(regs, address))) > - return; > - > - /* Was the fault on kernel-controlled part of the address space? */ > - if (unlikely(fault_in_kernel_space(address))) { > - do_kern_addr_fault(regs, hw_error_code, address); > - return; > - } > - > /* kprobes don't want to hook the spurious faults: */ > if (unlikely(kprobes_fault(regs))) > return; > @@ -1488,6 +1475,28 @@ good_area: > > check_v8086_mode(regs, address, tsk); > } > +NOKPROBE_SYMBOL(do_user_addr_fault); > + > +/* > + * This routine handles page faults. It determines the address, > + * and the problem, and then passes it off to one of the appropriate > + * routines. > + */ > +static noinline void > +__do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, > + unsigned long address) > +{ > + prefetchw(¤t->mm->mmap_sem); > + > + if (unlikely(kmmio_fault(regs, address))) > + return; > + > + /* Was the fault on kernel-controlled part of the address space? */ > + if (unlikely(fault_in_kernel_space(address))) > + do_kern_addr_fault(regs, hw_error_code, address); > + else > + do_user_addr_fault(regs, hw_error_code, address); > +} > NOKPROBE_SYMBOL(__do_page_fault); > > static nokprobe_inline void Eric
[tip:x86/mm] x86/mm: Break out user address space handling
Commit-ID: aa37c51b9421d66f7931c5fdcb9ce80c450974be Gitweb: https://git.kernel.org/tip/aa37c51b9421d66f7931c5fdcb9ce80c450974be Author: Dave Hansen AuthorDate: Fri, 28 Sep 2018 09:02:23 -0700 Committer: Peter Zijlstra CommitDate: Tue, 9 Oct 2018 16:51:15 +0200 x86/mm: Break out user address space handling The last patch broke out kernel address space handing into its own helper. Now, do the same for user address space handling. Cc: x...@kernel.org Cc: Jann Horn Cc: Sean Christopherson Cc: Thomas Gleixner Cc: Andy Lutomirski Signed-off-by: Dave Hansen Signed-off-by: Peter Zijlstra (Intel) Link: http://lkml.kernel.org/r/20180928160223.9c4f6...@viggo.jf.intel.com --- arch/x86/mm/fault.c | 47 --- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index c7e32f453852..0d1f5d39fc63 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -966,6 +966,7 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code, __bad_area(regs, error_code, address, vma, SEGV_ACCERR); } +/* Handle faults in the kernel portion of the address space */ static void do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, u32 *pkey, unsigned int fault) @@ -1254,14 +1255,11 @@ do_kern_addr_fault(struct pt_regs *regs, unsigned long hw_error_code, } NOKPROBE_SYMBOL(do_kern_addr_fault); -/* - * This routine handles page faults. It determines the address, - * and the problem, and then passes it off to one of the appropriate - * routines. - */ -static noinline void -__do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, - unsigned long address) +/* Handle faults in the user portion of the address space */ +static inline +void do_user_addr_fault(struct pt_regs *regs, + unsigned long hw_error_code, + unsigned long address) { unsigned long sw_error_code; struct vm_area_struct *vma; @@ -1274,17 +1272,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, tsk = current; mm = tsk->mm; - prefetchw(&mm->mmap_sem); - - if (unlikely(kmmio_fault(regs, address))) - return; - - /* Was the fault on kernel-controlled part of the address space? */ - if (unlikely(fault_in_kernel_space(address))) { - do_kern_addr_fault(regs, hw_error_code, address); - return; - } - /* kprobes don't want to hook the spurious faults: */ if (unlikely(kprobes_fault(regs))) return; @@ -1488,6 +1475,28 @@ good_area: check_v8086_mode(regs, address, tsk); } +NOKPROBE_SYMBOL(do_user_addr_fault); + +/* + * This routine handles page faults. It determines the address, + * and the problem, and then passes it off to one of the appropriate + * routines. + */ +static noinline void +__do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, + unsigned long address) +{ + prefetchw(¤t->mm->mmap_sem); + + if (unlikely(kmmio_fault(regs, address))) + return; + + /* Was the fault on kernel-controlled part of the address space? */ + if (unlikely(fault_in_kernel_space(address))) + do_kern_addr_fault(regs, hw_error_code, address); + else + do_user_addr_fault(regs, hw_error_code, address); +} NOKPROBE_SYMBOL(__do_page_fault); static nokprobe_inline void