| From 7100e8704b61247649c50551b965e71d168df30b Mon Sep 17 00:00:00 2001 |
| From: Nicholas Piggin <npiggin@gmail.com> |
| Date: Fri, 29 Mar 2019 17:42:57 +1000 |
| Subject: powerpc/64s/radix: Fix radix segment exception handling |
| |
| From: Nicholas Piggin <npiggin@gmail.com> |
| |
| commit 7100e8704b61247649c50551b965e71d168df30b upstream. |
| |
| Commit 48e7b76957 ("powerpc/64s/hash: Convert SLB miss handlers to C") |
| broke the radix-mode segment exception handler. In radix mode, this is |
| exception is not an SLB miss, rather it signals that the EA is outside |
| the range translated by any page table. |
| |
| The commit lost the radix feature alternate code patch, which can |
| cause faults to some EAs to kernel BUG at arch/powerpc/mm/slb.c:639! |
| |
| The original radix code would send faults to slb_miss_large_addr, |
| which would end up faulting due to slb_addr_limit being 0. This patch |
| sends radix directly to do_bad_slb_fault, which is a bit clearer. |
| |
| Fixes: 48e7b7695745 ("powerpc/64s/hash: Convert SLB miss handlers to C") |
| Cc: stable@vger.kernel.org # v4.20+ |
| Reported-by: Anton Blanchard <anton@samba.org> |
| Signed-off-by: Nicholas Piggin <npiggin@gmail.com> |
| Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/powerpc/kernel/exceptions-64s.S | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| --- a/arch/powerpc/kernel/exceptions-64s.S |
| +++ b/arch/powerpc/kernel/exceptions-64s.S |
| @@ -612,11 +612,17 @@ EXC_COMMON_BEGIN(data_access_slb_common) |
| ld r4,PACA_EXSLB+EX_DAR(r13) |
| std r4,_DAR(r1) |
| addi r3,r1,STACK_FRAME_OVERHEAD |
| +BEGIN_MMU_FTR_SECTION |
| + /* HPT case, do SLB fault */ |
| bl do_slb_fault |
| cmpdi r3,0 |
| bne- 1f |
| b fast_exception_return |
| 1: /* Error case */ |
| +MMU_FTR_SECTION_ELSE |
| + /* Radix case, access is outside page table range */ |
| + li r3,-EFAULT |
| +ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) |
| std r3,RESULT(r1) |
| bl save_nvgprs |
| RECONCILE_IRQ_STATE(r10, r11) |
| @@ -661,11 +667,17 @@ EXC_COMMON_BEGIN(instruction_access_slb_ |
| EXCEPTION_PROLOG_COMMON(0x480, PACA_EXSLB) |
| ld r4,_NIP(r1) |
| addi r3,r1,STACK_FRAME_OVERHEAD |
| +BEGIN_MMU_FTR_SECTION |
| + /* HPT case, do SLB fault */ |
| bl do_slb_fault |
| cmpdi r3,0 |
| bne- 1f |
| b fast_exception_return |
| 1: /* Error case */ |
| +MMU_FTR_SECTION_ELSE |
| + /* Radix case, access is outside page table range */ |
| + li r3,-EFAULT |
| +ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) |
| std r3,RESULT(r1) |
| bl save_nvgprs |
| RECONCILE_IRQ_STATE(r10, r11) |