From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: linuxppc-dev@lists.ozlabs.org
Cc: aneesh.kumar@linux.vnet.ibm.com,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [PATCH 13/24] powerpc/mm: Make bad_area* helper functions
Date: Wed, 19 Jul 2017 14:49:35 +1000 [thread overview]
Message-ID: <20170719044946.22030-13-benh@kernel.crashing.org> (raw)
In-Reply-To: <20170719044946.22030-1-benh@kernel.crashing.org>
Instead of goto labels, instead call those functions and return.
This gets us closer to x86 and allows us to shring do_page_fault()
even more.
The main difference with x86 is that those function return a value
which we then return from do_page_fault(). That value is our
return value from do_page_fault() which we use to generate
kernel faults.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/mm/fault.c | 78 +++++++++++++++++++++++++++++++------------------
1 file changed, 50 insertions(+), 28 deletions(-)
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index aead07cf8a5b..3903b55fccf8 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -108,6 +108,45 @@ static int store_updates_sp(struct pt_regs *regs)
* do_page_fault error handling helpers
*/
+static int
+__bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code)
+{
+ /*
+ * If we are in kernel mode, bail out with a SEGV, this will
+ * be caught by the assembly which will restore the non-volatile
+ * registers before calling bad_page_fault()
+ */
+ if (!user_mode(regs))
+ return SIGSEGV;
+
+ _exception(SIGSEGV, regs, si_code, address);
+
+ return 0;
+}
+
+static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address)
+{
+ return __bad_area_nosemaphore(regs, address, SEGV_MAPERR);
+}
+
+static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code)
+{
+ struct mm_struct *mm = current->mm;
+
+ /*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+ up_read(&mm->mmap_sem);
+
+ return __bad_area_nosemaphore(regs, address, si_code);
+}
+
+static noinline int bad_area(struct pt_regs *regs, unsigned long address)
+{
+ return __bad_area(regs, address, SEGV_MAPERR);
+}
+
#define MM_FAULT_RETURN 0
#define MM_FAULT_CONTINUE -1
#define MM_FAULT_ERR(sig) (sig)
@@ -231,7 +270,6 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
- int code = SEGV_MAPERR;
int is_exec = TRAP(regs) == 0x400;
int is_user = user_mode(regs);
int is_write = page_fault_is_write(error_code);
@@ -317,7 +355,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
*/
if (!down_read_trylock(&mm->mmap_sem)) {
if (!is_user && !search_exception_tables(regs->nip))
- goto bad_area_nosemaphore;
+ return bad_area_nosemaphore(regs, address);
retry:
down_read(&mm->mmap_sem);
@@ -332,11 +370,11 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
vma = find_vma(mm, address);
if (!vma)
- goto bad_area;
+ return bad_area(regs, address);
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
- goto bad_area;
+ return bad_area(regs, address);
/*
* N.B. The POWER/Open ABI allows programs to access up to
@@ -351,7 +389,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
/* get user regs even if this fault is in kernel mode */
struct pt_regs *uregs = current->thread.regs;
if (uregs == NULL)
- goto bad_area;
+ return bad_area(regs, address);
/*
* A user-mode access to an address a long way below
@@ -366,14 +404,12 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
* expand the stack rather than segfaulting.
*/
if (address + 2048 < uregs->gpr[1] && !store_update_sp)
- goto bad_area;
+ return bad_area(regs, address);
}
if (expand_stack(vma, address))
- goto bad_area;
+ return bad_area(regs, address);
good_area:
- code = SEGV_ACCERR;
-
if (is_exec) {
/*
* Allow execution from readable areas if the MMU does not
@@ -388,16 +424,16 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
if (!(vma->vm_flags & VM_EXEC) &&
(cpu_has_feature(CPU_FTR_NOEXECUTE) ||
!(vma->vm_flags & (VM_READ | VM_WRITE))))
- goto bad_area;
+ return bad_area(regs, address);
/* a write */
} else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
+ return bad_area(regs, address);
flags |= FAULT_FLAG_WRITE;
/* a read */
} else {
if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
- goto bad_area;
+ return bad_area(regs, address);
}
#ifdef CONFIG_PPC_STD_MMU
/*
@@ -462,11 +498,10 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
if (fault & VM_FAULT_SIGSEGV)
- goto bad_area_nosemaphore;
+ return bad_area_nosemaphore(regs, address);
rc = mm_fault_error(regs, address, fault);
if (rc >= MM_FAULT_RETURN)
return rc;
- rc = 0;
}
/*
@@ -492,20 +527,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
regs, address);
}
-
- return rc;
-
-bad_area:
- up_read(&mm->mmap_sem);
-
-bad_area_nosemaphore:
- /* User mode accesses cause a SIGSEGV */
- if (is_user) {
- _exception(SIGSEGV, regs, code, address);
- return 0;
- }
-
- return SIGSEGV;
+ return 0;
}
NOKPROBE_SYMBOL(__do_page_fault);
--
2.13.3
next prev parent reply other threads:[~2017-07-19 4:57 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-19 4:49 [PATCH 01/24] powerpc/mm: Move exception_enter/exit to a do_page_fault wrapper Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 02/24] powerpc/mm: Pre-filter SRR1 bits before do_page_fault() Benjamin Herrenschmidt
2017-07-22 16:43 ` LEROY Christophe
2017-07-23 1:10 ` Benjamin Herrenschmidt
2017-07-24 13:48 ` Michael Ellerman
2017-07-19 4:49 ` [PATCH 03/24] powerpc/6xx: Handle DABR match before calling do_page_fault Benjamin Herrenschmidt
2017-08-03 0:19 ` Michael Ellerman
2017-08-03 1:00 ` Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 04/24] powerpc/mm: Update definitions of DSISR bits Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 05/24] powerpc/mm: Update bits used to skip hash_page Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 06/24] powerpc/mm: Use symbolic constants for filtering SRR1 bits on ISIs Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 07/24] powerpc/mm: Move out definition of CPU specific is_write bits Benjamin Herrenschmidt
2017-07-22 16:40 ` LEROY Christophe
2017-07-23 1:06 ` Benjamin Herrenschmidt
2017-07-24 11:58 ` Michael Ellerman
2017-07-19 4:49 ` [PATCH 08/24] powerpc/mm: Move error_code checks for bad faults earlier Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 09/24] powerpc/mm: Overhaul handling of bad page faults Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 10/24] powerpc/mm: Move debugger check to notify_page_fault() Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 11/24] powerpc/mm: Simplify returns from __do_page_fault Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 12/24] powerpc/mm: Fix reporting of kernel execute faults Benjamin Herrenschmidt
2018-11-07 8:35 ` Christophe LEROY
2018-11-07 10:39 ` Benjamin Herrenschmidt
[not found] ` <87zhtr5d1v.fsf@linux.ibm.com>
2018-11-30 6:08 ` Christophe LEROY
2017-07-19 4:49 ` Benjamin Herrenschmidt [this message]
2017-07-19 4:49 ` [PATCH 14/24] powerpc/mm: Rework mm_fault_error() Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 15/24] powerpc/mm: Move CMO accounting out of do_page_fault into a helper Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 16/24] powerpc/mm: Cosmetic fix to page fault accounting Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 17/24] powerpc/mm: Move the DSISR_PROTFAULT sanity check Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 18/24] powerpc/mm: Move/simplify faulthandler_disabled() and !mm check Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 19/24] powerpc/mm: Add a bunch of (un)likely annotations to do_page_fault Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 20/24] powerpc/mm: Set fault flags earlier Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 21/24] powerpc/mm: Move page fault VMA access checks to a helper Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 22/24] powerpc/mm: Don't lose "major" fault indication on retry Benjamin Herrenschmidt
2017-07-19 4:49 ` [PATCH 23/24] powerpc/mm: Cleanup check for stack expansion Benjamin Herrenschmidt
2017-07-21 16:59 ` LEROY Christophe
2017-07-24 10:47 ` Michael Ellerman
2017-07-24 17:34 ` LEROY Christophe
2017-07-25 11:19 ` Michael Ellerman
2017-07-31 11:37 ` Christophe LEROY
2017-07-19 4:49 ` [PATCH 24/24] powerpc: Remove old unused icswx based coprocessor support Benjamin Herrenschmidt
2017-08-07 10:41 ` [01/24] powerpc/mm: Move exception_enter/exit to a do_page_fault wrapper Michael Ellerman
2017-08-07 16:37 ` Christophe LEROY
2017-08-08 2:16 ` Michael Ellerman
2017-08-08 6:45 ` Christophe LEROY
2017-08-08 10:00 ` Michael Ellerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170719044946.22030-13-benh@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.