powerpc: Hande page faults for bad paste and bad AMO
PATCH 1/1 powerpc: Hande page faults for bad paste and bad AMO
On POWER9 and bad paste instruction (targeting the wrong memory type) or an invalid opcode in an AMO (atomic memory operation) will result in specific DSISR bits to be set.
We currently don't understand those bits and thus just "hang" the process taking constant page faults.
Additionally in the case of paste, it appears that we don't always get a valid DAR value when the error is a wrong memory type.
So we need to test those errors early in do_page_fault(), I chose to generate a SIGBUS which is more correct than a SIGSEGV.
---
arch/powerpc/mm/fault.c +15 -0
@@ -337,6 +337,21 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, }#endif /* CONFIG_PPC_ICSWX */ +#ifdef CONFIG_PPC_STD_MMU_64 +/* +* These faults indicate a copy/paste on an invalid memory type +* or an incorrect AMO operation. They have been observed as not +* properly updating the DAR, so handle them early +*/ +if (error_code & (DSISR_BAD_COPYPASTE |DSISR_BAD_AMO )) { +if (user_mode (regs)) +_exception (SIGBUS , regs,BUS_OBJERR , address); +else + rc =SIGBUS ; + goto bail; + } +#endif /* CONFIG_PPC_STD_MMU_64 */ +if (notify_page_fault (regs)) goto bail;
arch/powerpc/include/asm/reg.h +2 -0
@@ -282,6 +282,8 @@#define DSISR_UNSUPP_MMU 0x00080000/* Unsupported MMU config */ #define DSISR_SET_RC 0x00040000/* Failed setting of R/C bits */ #define DSISR_PGDIRFAULT 0x00020000/* Fault on page directory */ +#define DSISR_BAD_COPYPASTE 0x00000008/* Copy/Paste on wrong mem type */ +#define DSISR_BAD_AMO 0x00000004/* Incorrect AMO opcode */ #define SPRN_TBRL 0x10C/* Time Base Read Lower Register (user, R/O) */ #define SPRN_TBRU 0x10D/* Time Base Read Upper Register (user, R/O) */ #define SPRN_CIR 0x11B/* Chip Information Register (hyper, R/0) */
Quoted 7 lines · Benjamin Herrenschmidt
On POWER9 and bad paste instruction (targeting the wrong memory type) or an invalid opcode in an AMO (atomic memory operation) will result in specific DSISR bits to be set.
We currently don't understand those bits and thus just "hang" the process taking constant page faults.
Quoted 6 lines
Additionally in the case of paste, it appears that we don't always get a valid DAR value when the error is a wrong memory type.
So we need to test those errors early in
do_page_fault(), I chose to generate a SIGBUS which is more correct than a SIGSEGV.
This is true even for hash right ? If so do we want to update do_hash_page:
#ifdef CONFIG_PPC_STD_MMU_64 andis. r0,r4,0xa450 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */
that 0xa450 such that we add these errors and call hand_page_fault in case of these DSISR values ?
Quoted 35 lines
Signed-off-by Benjamin Herrenschmidt <[email protected]>---
arch/powerpc/mm/fault.c +15
-0@@ -337,6 +337,21 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, }#endif /* CONFIG_PPC_ICSWX */ +#ifdef CONFIG_PPC_STD_MMU_64 +/* +* These faults indicate a copy/paste on an invalid memory type +* or an incorrect AMO operation. They have been observed as not +* properly updating the DAR, so handle them early +*/ +if (error_code & (DSISR_BAD_COPYPASTE |DSISR_BAD_AMO )) { +if (user_mode (regs)) +_exception (SIGBUS , regs,BUS_OBJERR , address); +else + rc =SIGBUS ; + goto bail; + } +#endif /* CONFIG_PPC_STD_MMU_64 */ +if (notify_page_fault (regs)) goto bail;arch/powerpc/include/asm/reg.h +0
-0
arch/powerpc/include/asm/reg.h line 289
Quoted 8 lines
arch/powerpc/include/asm/reg.h +2
-0@@ -282,6 +282,8 @@#define DSISR_UNSUPP_MMU 0x00080000/* Unsupported MMU config */ #define DSISR_SET_RC 0x00040000/* Failed setting of R/C bits */ #define DSISR_PGDIRFAULT 0x00020000/* Fault on page directory */ +#define DSISR_BAD_COPYPASTE 0x00000008/* Copy/Paste on wrong mem type */ +#define DSISR_BAD_AMO 0x00000004/* Incorrect AMO opcode */ #define SPRN_TBRL 0x10C/* Time Base Read Lower Register (user, R/O) */ #define SPRN_TBRU 0x10D/* Time Base Read Upper Register (user, R/O) */ #define SPRN_CIR 0x11B/* Chip Information Register (hyper, R/0) */
-aneesh
Quoted 11 lines · Aneesh Kumar K.V
Quoted 2 lines
So we need to test those errors early in
do_page_fault(), I chose to generate a SIGBUS which is more correct than a SIGSEGV.This is true even for hash right ? If so do we want to update
do_hash_page:
#ifdefCONFIG_PPC_STD_MMU_64
andis. r0,r4,0xa450 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */that
0xa450such that we add these errors and callhand_page_faultin case of these DSISR values ?
Correct, I forgot about that one. I'll respin.
Cheers,
Ben.