powerpc: interrupt wrappers
Subsystems (3)
Nicholas Piggin
reviewerv2 cover powerpc: interrupt wrappers
This adds interrupt handler wrapper functions, similar to the generic / x86 code, and moves several common operations into them from either asm or open coded in the individual handlers.
Since v1:
- Fixed a couple of compile issues
- Fixed perf weirdness (sometimes NMI, sometimes not)
- Also move irq_enter/exit into wrappers
Thanks,
Nick
Nicholas Piggin (19):
powerpc/64s: move the last of the page fault handling logic to C
powerpc: remove arguments from fault handler functions
powerpc: bad_page_fault, do_break get registers from regs powerpc/perf: move perf irq/nmi handling details into traps.c
powerpc: interrupt handler wrapper functions
powerpc: add interrupt wrapper entry / exit stub functions
powerpc: add interrupt_cond_local_irq_enable helper powerpc/64: context tracking remove _TIF_NOHZ powerpc/64: context tracking move to interrupt wrappers powerpc/64: add context tracking to asynchronous interrupts
powerpc: handle irq_enter/irq_exit in interrupt handler wrappers powerpc/64s: move context tracking exit to interrupt exit path powerpc/64s: reconcile interrupts in C
powerpc/64: move account_stolen_time into its own function powerpc/64: entry cpu time accounting in C
powerpc: move NMI entry/exit code into wrapper powerpc/64s: move NMI soft-mask handling to C powerpc/64s: runlatch interrupt handling in C powerpc/64s: power4 nap fixup in C
arch/Kconfig | 6 - arch/powerpc/Kconfig | 1 - arch/powerpc/include/asm/asm-prototypes.h | 29 -- arch/powerpc/include/asm/bug.h | 5 +- arch/powerpc/include/asm/cputime.h | 15 + arch/powerpc/include/asm/debug.h | 3 +- arch/powerpc/include/asm/hw_irq.h | 9 - arch/powerpc/include/asm/interrupt.h | 403 +++++++++++++++++++++ arch/powerpc/include/asm/ppc_asm.h | 24 -- arch/powerpc/include/asm/processor.h | 1 + arch/powerpc/include/asm/thread_info.h | 10 +- arch/powerpc/include/asm/time.h | 2 + arch/powerpc/kernel/dbell.c | 15 +- arch/powerpc/kernel/entry_32.S | 14 +- arch/powerpc/kernel/exceptions-64e.S | 6 +- arch/powerpc/kernel/exceptions-64s.S | 307 ++-------------- arch/powerpc/kernel/head_40x.S | 10 +- arch/powerpc/kernel/head_8xx.S | 11 +- arch/powerpc/kernel/head_book3s_32.S | 12 +- arch/powerpc/kernel/head_booke.h | 4 +- arch/powerpc/kernel/idle_book3s.S | 4 + arch/powerpc/kernel/irq.c | 7 +- arch/powerpc/kernel/mce.c | 16 +- arch/powerpc/kernel/process.c | 7 +- arch/powerpc/kernel/ptrace/ptrace.c | 4 - arch/powerpc/kernel/signal.c | 4 - arch/powerpc/kernel/syscall_64.c | 30 +- arch/powerpc/kernel/tau_6xx.c | 5 +- arch/powerpc/kernel/time.c | 7 +- arch/powerpc/kernel/traps.c | 227 ++++++------ arch/powerpc/kernel/watchdog.c | 15 +- arch/powerpc/kvm/book3s_hv.c | 1 + arch/powerpc/kvm/book3s_hv_builtin.c | 1 + arch/powerpc/mm/book3s64/hash_utils.c | 82 +++-- arch/powerpc/mm/book3s64/slb.c | 12 +- arch/powerpc/mm/fault.c | 80 +++- arch/powerpc/perf/core-book3s.c | 35 +- arch/powerpc/perf/core-fsl-emb.c | 25 -- arch/powerpc/platforms/8xx/machine_check.c | 2 +- arch/powerpc/platforms/powernv/idle.c | 1 + 40 files changed, 766 insertions(+), 686 deletions(-) create mode 100644 arch/powerpc/include/asm/interrupt.h
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 1/19 powerpc/64s: move the last of the page fault handling logic to C
The page fault handling still has some complex logic particularly around hash table handling, in asm. Implement this in C instead.
--- arch/powerpc/include/asm/book3s/64/mmu-hash.h | 1 + arch/powerpc/include/asm/bug.h | 1 + arch/powerpc/kernel/exceptions-64s.S | 131 +++--------------- arch/powerpc/mm/book3s64/hash_utils.c | 77 ++++++---- arch/powerpc/mm/fault.c | 57 +++++++- 5 files changed, 127 insertions(+), 140 deletions(-)
arch/powerpc/include/asm/book3s/64/mmu-hash.h +1 -0
@@ -453,6 +453,7 @@ static inline unsigned long hpt_hash(unsigned long vpn,#define HPTE_LOCAL_UPDATE 0x1#define HPTE_NOHPTE_UPDATE 0x2 +int do_hash_fault (struct pt_regs *regs,unsigned long ea,unsigned long dsisr);extern int __hash_page_4K (unsigned long ea,unsigned long access,unsigned long vsid,pte_t *ptep,unsigned long trap,unsigned long flags,int ssize,int subpage_prot);
arch/powerpc/include/asm/bug.h +1 -0
@@ -112,6 +112,7 @@struct pt_regs ;extern int do_page_fault (struct pt_regs *,unsigned long ,unsigned long ); +int hash__do_page_fault (struct pt_regs *,unsigned long ,unsigned long );extern void bad_page_fault (struct pt_regs *,unsigned long ,int );extern void _exception (int ,struct pt_regs *,int ,unsigned long );extern void _exception_pkey (struct pt_regs *,unsigned long ,int );
arch/powerpc/kernel/exceptions-64s.S +22 -109
161 lines not on this page · raw message
arch/powerpc/mm/book3s64/hash_utils.c +49 -28
105 lines not on this page · raw message
arch/powerpc/mm/fault.c +54 -3
79 lines not on this page · raw message
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 2/19 powerpc: remove arguments from fault handler functions
In reply to Nicholas PigginMake mm fault handlers all just take the pt_regs * argument and load DAR/DSISR from that. Make those that return a value return long.
This is done to make the function signatures match other handlers, which will help with a future patch to add wrappers. Explicit arguments could be added for performance but that would require more wrapper macro variants.
--- arch/powerpc/include/asm/asm-prototypes.h | 4 ++-- arch/powerpc/include/asm/book3s/64/mmu-hash.h | 2 +- arch/powerpc/include/asm/bug.h | 4 ++-- arch/powerpc/kernel/exceptions-64e.S | 2 -- arch/powerpc/kernel/exceptions-64s.S | 14 ++------------ arch/powerpc/kernel/head_40x.S | 10 +++++----- arch/powerpc/kernel/head_8xx.S | 6 +++--- arch/powerpc/kernel/head_book3s_32.S | 6 ++---- arch/powerpc/kernel/head_booke.h | 4 +--- arch/powerpc/mm/book3s64/hash_utils.c | 8 +++++--- arch/powerpc/mm/book3s64/slb.c | 11 +++++++---- arch/powerpc/mm/fault.c | 16 +++++++++------- 12 files changed, 39 insertions(+), 48 deletions(-)
arch/powerpc/include/asm/asm-prototypes.h +2 -2
@@ -82,8 +82,8 @@ void kernel_bad_stack(struct pt_regs *regs);void system_reset_exception (struct pt_regs *regs);void machine_check_exception (struct pt_regs *regs);void emulation_assist_interrupt (struct pt_regs *regs); -long do_slb_fault (struct pt_regs *regs,unsigned long ea); -void do_bad_slb_fault (struct pt_regs *regs,unsigned long ea,long err); +long do_slb_fault (struct pt_regs *regs); +void do_bad_slb_fault (struct pt_regs *regs);/* signals, syscalls and interrupts */ long sys_swapcontext(struct ucontext __user *old_ctx,
arch/powerpc/include/asm/book3s/64/mmu-hash.h +1 -1
@@ -453,7 +453,7 @@ static inline unsigned long hpt_hash(unsigned long vpn,#define HPTE_LOCAL_UPDATE 0x1#define HPTE_NOHPTE_UPDATE 0x2 -int do_hash_fault (struct pt_regs *regs,unsigned long ea,unsigned long dsisr); +long do_hash_fault (struct pt_regs *regs);extern int __hash_page_4K (unsigned long ea,unsigned long access,unsigned long vsid,pte_t *ptep,unsigned long trap,unsigned long flags,int ssize,int subpage_prot);
arch/powerpc/include/asm/bug.h +2 -2
@@ -111,8 +111,8 @@#ifndef __ASSEMBLY__struct pt_regs ; -extern int do_page_fault (struct pt_regs *,unsigned long ,unsigned long ); -int hash__do_page_fault (struct pt_regs *,unsigned long ,unsigned long ); +long do_page_fault (struct pt_regs *); +long hash__do_page_fault (struct pt_regs *);extern void bad_page_fault (struct pt_regs *,unsigned long ,int );extern void _exception (int ,struct pt_regs *,int ,unsigned long );extern void _exception_pkey (struct pt_regs *,unsigned long ,int );
arch/powerpc/kernel/exceptions-64e.S +0 -2
@@ -1011,8 +1011,6 @@ storage_fault_common: std r14,_DAR(r1) std r15,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD - mr r4,r14 - mr r5,r15 ld r14,PACA_EXGEN+EX_R14(r13) ld r15,PACA_EXGEN+EX_R15(r13) bl do_page_fault
arch/powerpc/kernel/exceptions-64s.S +2 -12
@@ -1437,8 +1437,6 @@ EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) EXC_VIRT_END(data_access, 0x4300, 0x80) EXC_COMMON_BEGIN(data_access_common) GEN_COMMON data_access - ld r4,_DAR(r1) - ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION bl do_hash_fault
@@ -1491,10 +1489,9 @@ EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) EXC_VIRT_END(data_access_slb, 0x4380, 0x80) EXC_COMMON_BEGIN(data_access_slb_common) GEN_COMMON data_access_slb - ld r4,_DAR(r1) - addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION /* HPT case, do SLB fault */ + addi r3,r1,STACK_FRAME_OVERHEAD bl do_slb_fault cmpdi r3,0 bne- 1f
@@ -1506,8 +1503,6 @@ MMU_FTR_SECTION_ELSE ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) RECONCILE_IRQ_STATE(r10, r11) - ld r4,_DAR(r1) - ld r5,RESULT(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault b interrupt_return
@@ -1542,8 +1537,6 @@ EXC_VIRT_BEGIN(instruction_access, 0x4400, 0x80) EXC_VIRT_END(instruction_access, 0x4400, 0x80) EXC_COMMON_BEGIN(instruction_access_common) GEN_COMMON instruction_access - ld r4,_DAR(r1) - ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION bl do_hash_fault
@@ -1587,10 +1580,9 @@ EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80) EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80) EXC_COMMON_BEGIN(instruction_access_slb_common) GEN_COMMON instruction_access_slb - ld r4,_DAR(r1) - addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION /* HPT case, do SLB fault */ + addi r3,r1,STACK_FRAME_OVERHEAD bl do_slb_fault cmpdi r3,0 bne- 1f
@@ -1602,8 +1594,6 @@ MMU_FTR_SECTION_ELSE ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) RECONCILE_IRQ_STATE(r10, r11) - ld r4,_DAR(r1) - ld r5,RESULT(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault b interrupt_return
arch/powerpc/kernel/head_40x.S +5 -5
@@ -179,9 +179,9 @@ _ENTRY(saved_ksp_limit) */ START_EXCEPTION(0x0300, DataStorage) EXCEPTION_PROLOG - mfspr r5, SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + mfspr r5, SPRN_ESR /* Grab the ESR, save it */ stw r5, _ESR(r11) - mfspr r4, SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + mfspr r4, SPRN_DEAR /* Grab the DEAR, save it */ stw r4, _DEAR(r11) EXC_XFER_LITE(0x300, handle_page_fault)
@@ -191,9 +191,9 @@ _ENTRY(saved_ksp_limit) */ START_EXCEPTION(0x0400, InstructionAccess) EXCEPTION_PROLOG - mr r4,r12 /* Pass SRR0 as arg2 */ - stw r4, _DEAR(r11) - li r5,0 /* Pass zero as arg3 */ + li r5,0 + stw r5, _ESR(r11) /* Zero ESR */ + stw r12, _DEAR(r11) /* SRR0 as DEAR */ EXC_XFER_LITE(0x400, handle_page_fault) /* 0x0500 - External Interrupt Exception */
arch/powerpc/kernel/head_8xx.S +3 -3
@@ -356,14 +356,14 @@ DataStoreTLBMiss: . = 0x1300 InstructionTLBError: EXCEPTION_PROLOG - mr r4,r12 andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ andis. r10,r9,SRR1_ISI_NOPT@h beq+ .Litlbie - tlbie r4 + tlbie r12 /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */ .Litlbie: - stw r4, _DAR(r11) + stw r12, _DAR(r11) + stw r5, _DSISR(r11) EXC_XFER_LITE(0x400, handle_page_fault) /* This is the data TLB error on the MPC8xx. This could be due to
arch/powerpc/kernel/head_book3s_32.S +2 -4
@@ -369,9 +369,9 @@ BEGIN_MMU_FTR_SECTION bl hash_page END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) #endif /* CONFIG_VMAP_STACK */ -1: mr r4,r12 andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ - stw r4, _DAR(r11) + stw r5, _DSISR(r11) + stw r12, _DAR(r11) EXC_XFER_LITE(0x400, handle_page_fault) /* External interrupt */
@@ -698,8 +698,6 @@ handle_page_fault_tramp_1: #ifdef CONFIG_VMAP_STACK EXCEPTION_PROLOG_2 handle_dar_dsisr=1 #endif - lwz r4, _DAR(r11) - lwz r5, _DSISR(r11) /* fall through */ handle_page_fault_tramp_2: EXC_XFER_LITE(0x300, handle_page_fault)
arch/powerpc/kernel/head_booke.h +1 -3
@@ -477,9 +477,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)NORMAL_EXCEPTION_PROLOG (INST_STORAGE ); \mfspr r5,SPRN_ESR ;/* Grab the ESR and save it */ \stw r5,_ESR (r11 ); \ -mr r4,r12;/* Pass SRR0 as arg2 */ \ -stw r4,_DEAR (r11 ); \ - li r5,0; /* Pass zero as arg3 */ \ +stw r12,_DEAR (r11 );/* Pass SRR0 as arg2 */ \ EXC_XFER_LITE(0x0400, handle_page_fault)#define ALIGNMENT_EXCEPTION \
arch/powerpc/mm/book3s64/hash_utils.c +5 -3
@@ -1510,13 +1510,15 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap, }EXPORT_SYMBOL_GPL (hash_page); -int do_hash_fault (struct pt_regs *regs,unsigned long ea,unsigned long dsisr) +long do_hash_fault (struct pt_regs *regs) { +unsigned long ea = regs->dar; +unsigned long dsisr = regs->dsisr;unsigned long access = _PAGE_PRESENT | _PAGE_READ;unsigned long flags =0 ;struct mm_struct *mm;unsigned int region_id; -int err; +long err;if (unlikely (dsisr & (DSISR_BAD_FAULT_64S |DSISR_DABRMATCH |DSISR_KEYFAULT ))) goto _do_page_fault;
@@ -1580,7 +1582,7 @@ int do_hash_fault(struct pt_regs *regs, unsigned long ea, unsigned long dsisr) }else if (err) { _do_page_fault: - err =hash__do_page_fault (regs, ea, dsisr); + err =hash__do_page_fault (regs); }return err;
arch/powerpc/mm/book3s64/slb.c +7 -4
@@ -837,8 +837,9 @@ static long slb_allocate_user(struct mm_struct *mm, unsigned long ea)return slb_insert_entry (ea, context, flags, ssize, false); } -long do_slb_fault (struct pt_regs *regs,unsigned long ea) +long do_slb_fault (struct pt_regs *regs) { +unsigned long ea = regs->dar;unsigned long id =get_region_id (ea);/* IRQs are not reconciled here, so can't check irqs_disabled */
@@ -889,13 +890,15 @@ long do_slb_fault(struct pt_regs *regs, unsigned long ea) } } -void do_bad_slb_fault (struct pt_regs *regs,unsigned long ea,long err) +void do_bad_slb_fault (struct pt_regs *regs) { +int err = regs->result; +if (err == -EFAULT ) {if (user_mode (regs)) -_exception (SIGSEGV , regs,SEGV_BNDERR , ea); +_exception (SIGSEGV , regs,SEGV_BNDERR , regs->dar);else -bad_page_fault (regs, ea,SIGSEGV ); +bad_page_fault (regs, regs->dar,SIGSEGV ); }else if (err == -EINVAL ) {unrecoverable_exception (regs); }else {
arch/powerpc/mm/fault.c +9 -7
@@ -549,11 +549,12 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address, }NOKPROBE_SYMBOL (__do_page_fault); -int do_page_fault (struct pt_regs *regs,unsigned long address, -unsigned long error_code) +long do_page_fault (struct pt_regs *regs) {enum ctx_state prev_state =exception_enter (); -int err; +unsigned long address = regs->dar; +unsigned long error_code = regs->dsisr; +long err; err =__do_page_fault (regs, address, error_code);
@@ -580,11 +581,12 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,NOKPROBE_SYMBOL (do_page_fault);#ifdef CONFIG_PPC_BOOK3S_64 -/* Same as do_page_fault but interrupt entry has already run in do_hash_fault */ -int hash__do_page_fault (struct pt_regs *regs,unsigned long address, -unsigned long error_code) +/* Same as do_page_fault but no interrupt entry */ +long hash__do_page_fault (struct pt_regs *regs) { -int err; +unsigned long address = regs->dar; +unsigned long error_code = regs->dsisr; +long err; err =__do_page_fault (regs, address, error_code);if (unlikely (err)) {
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 3/19 powerpc: bad_page_fault, do_break get registers from regs
In reply to Nicholas PigginThis also moves the 32s DABR match to C.
Similar to the previous patch this makes interrupt handler function types more regular so they can be wrapped with the next patch.
bad_page_fault and do_break are not performance critical.
--- arch/powerpc/include/asm/bug.h | 2 +- arch/powerpc/include/asm/debug.h | 3 +-- arch/powerpc/kernel/entry_32.S | 14 ++++---------- arch/powerpc/kernel/exceptions-64e.S | 3 +-- arch/powerpc/kernel/exceptions-64s.S | 3 +-- arch/powerpc/kernel/head_8xx.S | 5 ++--- arch/powerpc/kernel/process.c | 7 +++---- arch/powerpc/kernel/traps.c | 2 +- arch/powerpc/mm/book3s64/hash_utils.c | 4 ++-- arch/powerpc/mm/book3s64/slb.c | 2 +- arch/powerpc/mm/fault.c | 14 +++++++------- arch/powerpc/platforms/8xx/machine_check.c | 2 +- 12 files changed, 25 insertions(+), 36 deletions(-)
arch/powerpc/include/asm/bug.h +1 -1
@@ -113,7 +113,7 @@struct pt_regs ;long do_page_fault (struct pt_regs *);long hash__do_page_fault (struct pt_regs *); -extern void bad_page_fault (struct pt_regs *,unsigned long ,int ); +void bad_page_fault (struct pt_regs *,int );extern void _exception (int ,struct pt_regs *,int ,unsigned long );extern void _exception_pkey (struct pt_regs *,unsigned long ,int );extern void die (const char *,struct pt_regs *,long );
arch/powerpc/include/asm/debug.h +1 -2
@@ -52,8 +52,7 @@ extern void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int brkpt);#else -extern void do_break (struct pt_regs *regs,unsigned long address, -unsigned long error_code); +void do_break (struct pt_regs *regs);#endif #endif /* _ASM_POWERPC_DEBUG_H */
arch/powerpc/kernel/entry_32.S +4 -10
@@ -657,10 +657,6 @@ ppc_swapcontext: .globl handle_page_fault handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S_32 - andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault -#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except
@@ -668,19 +664,17 @@ handle_page_fault: lwz r0,_TRAP(r1) clrrwi r0,r0,1 stw r0,_TRAP(r1) - mr r5,r3 + mr r4,r3 /* err arg for bad_page_fault */ addi r3,r1,STACK_FRAME_OVERHEAD - lwz r4,_DAR(r1) +#ifdef CONFIG_PPC_BOOK3S_32 + blt handle_dabr_fault +#endif bl bad_page_fault b ret_from_except_full #ifdef CONFIG_PPC_BOOK3S_32 /* We have a data breakpoint exception - handle it */ handle_dabr_fault: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - clrrwi r0,r0,1 - stw r0,_TRAP(r1) bl do_break b ret_from_except_full #endif
arch/powerpc/kernel/exceptions-64e.S +1 -2
@@ -1018,9 +1018,8 @@ storage_fault_common: bne- 1f b ret_from_except_lite 1: bl save_nvgprs - mr r5,r3 + mr r4,r3 addi r3,r1,STACK_FRAME_OVERHEAD - ld r4,_DAR(r1) bl bad_page_fault b ret_from_except
arch/powerpc/kernel/exceptions-64s.S +1 -2
@@ -2135,8 +2135,7 @@ EXC_COMMON_BEGIN(h_data_storage_common) GEN_COMMON h_data_storage addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION - ld r4,_DAR(r1) - li r5,SIGSEGV + li r4,SIGSEGV bl bad_page_fault MMU_FTR_SECTION_ELSE bl unknown_exception
arch/powerpc/kernel/head_8xx.S +2 -3
@@ -408,10 +408,9 @@ do_databreakpoint: addi r3,r1,STACK_FRAME_OVERHEAD mfspr r4,SPRN_BAR stw r4,_DAR(r11) -#ifdef CONFIG_VMAP_STACK - lwz r5,_DSISR(r11) -#else +#ifndef CONFIG_VMAP_STACK mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) #endif EXC_XFER_STD(0x1c00, do_break)
arch/powerpc/kernel/process.c +3 -4
@@ -660,11 +660,10 @@ static void do_break_handler(struct pt_regs *regs) } } -void do_break (struct pt_regs *regs,unsigned long address, -unsigned long error_code) +void do_break (struct pt_regs *regs) { current->thread.trap_nr =TRAP_HWBKPT ; -if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, error_code, +if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, regs->dsisr,11 ,SIGSEGV ) ==NOTIFY_STOP )return ;
@@ -682,7 +681,7 @@ void do_break (struct pt_regs *regs, unsigned long address,do_break_handler (regs);/* Deliver the signal to userspace */ - force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address); + force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)regs->dar); }#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
arch/powerpc/kernel/traps.c +1 -1
@@ -1641,7 +1641,7 @@ void alignment_exception(struct pt_regs *regs)if (user_mode (regs))_exception (sig, regs, code, regs->dar);else -bad_page_fault (regs, regs->dar, sig); +bad_page_fault (regs, sig); bail:exception_exit (prev_state);
arch/powerpc/mm/book3s64/hash_utils.c +2 -2
@@ -1537,7 +1537,7 @@ long do_hash_fault(struct pt_regs *regs)* the access, or panic if there isn't a handler. */ if (unlikely (in_nmi ())) { -bad_page_fault (regs, ea,SIGSEGV ); +bad_page_fault (regs,SIGSEGV );return 0 ; }
@@ -1576,7 +1576,7 @@ long do_hash_fault(struct pt_regs *regs)else _exception (SIGBUS , regs,BUS_ADRERR , ea); }else { -bad_page_fault (regs, ea,SIGBUS ); +bad_page_fault (regs,SIGBUS ); } err =0 ;
arch/powerpc/mm/book3s64/slb.c +1 -1
@@ -898,7 +898,7 @@ void do_bad_slb_fault(struct pt_regs *regs)if (user_mode (regs))_exception (SIGSEGV , regs,SEGV_BNDERR , regs->dar);else -bad_page_fault (regs, regs->dar,SIGSEGV ); +bad_page_fault (regs,SIGSEGV ); }else if (err == -EINVAL ) {unrecoverable_exception (regs); }else {
arch/powerpc/mm/fault.c +7 -7
@@ -375,7 +375,7 @@ static void sanity_check_fault(bool is_write, bool is_user,#elif defined(CONFIG_PPC_BOOK3E_64 )#define page_fault_is_bad (__err) ((__err) & DSISR_BAD_FAULT_64S)#else -#define page_fault_is_bad (__err) ((__err) & DSISR_BAD_FAULT_32S) +#define page_fault_is_bad (__err) ((__err) & (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH))#endif #endif
@@ -408,7 +408,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,return 0 ;if (unlikely (page_fault_is_bad (error_code))) { -if (IS_ENABLED (CONFIG_PPC_BOOK3S_64 ) && (error_code &DSISR_DABRMATCH )) +if (IS_ENABLED (CONFIG_PPC_BOOK3S ) && (error_code &DSISR_DABRMATCH ))return -1 ;if (is_user) {
@@ -562,14 +562,14 @@ long do_page_fault(struct pt_regs *regs)/* 32 and 64e handle errors in their asm code */ if (unlikely (err)) {if (err >0 ) { -bad_page_fault (regs, address, err); +bad_page_fault (regs, err); err =0 ; }else {/* * do_break() may change NV GPRS while handling the * breakpoint. Return -ve to caller to do that. */ -do_break (regs, address, error_code); +do_break (regs); } }#endif
@@ -591,14 +591,14 @@ long hash__do_page_fault(struct pt_regs *regs) err =__do_page_fault (regs, address, error_code);if (unlikely (err)) {if (err >0 ) { -bad_page_fault (regs, address, err); +bad_page_fault (regs, err); err =0 ; }else {/* * do_break() may change NV GPRS while handling the * breakpoint. Return -ve to caller to do that. */ -do_break (regs, address, error_code); +do_break (regs); } }
@@ -612,7 +612,7 @@ NOKPROBE_SYMBOL(hash__do_page_fault);* It is called from the DSI and ISI handlers in head.S and from some * of the procedures in traps.c. */ -void bad_page_fault (struct pt_regs *regs,unsigned long address,int sig) +void bad_page_fault (struct pt_regs *regs,int sig) {const struct exception_table_entry *entry;int is_write =page_fault_is_write (regs->dsisr);
arch/powerpc/platforms/8xx/machine_check.c +1 -1
@@ -26,7 +26,7 @@ int machine_check_8xx(struct pt_regs *regs)* to deal with that than having a wart in the mcheck handler. * -- BenH */ -bad_page_fault (regs, regs->dar,SIGBUS ); +bad_page_fault (regs,SIGBUS );return 1 ;#else return 0 ;
Signature · 1 line
2.23.0
Re: [PATCH v2 03/19] powerpc: bad_page_fault, do_break get registers from regs
Hi,
Quoting Nicholas Piggin <[email protected]>:
Quoted 1 line
This also moves the 32s DABR match to C.
I'm still not happy with that. What about the following instead ?
arch/powerpc/kernel/entry_32.S +0 -15
@@ -657,10 +657,6 @@ ppc_swapcontext: .globl handle_page_fault handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S_32 - andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault -#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except
@@ -674,17 +670,6 @@ handle_page_fault: bl bad_page_fault b ret_from_except_full -#ifdef CONFIG_PPC_BOOK3S_32 - /* We have a data breakpoint exception - handle it */ -handle_dabr_fault: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - clrrwi r0,r0,1 - stw r0,_TRAP(r1) - bl do_break - b ret_from_except_full -#endif - /* * This routine switches between two different tasks. The process * state of one is saved on its kernel stack. Then the state
arch/powerpc/kernel/head_book3s_32.S +3 -0
@@ -684,7 +684,10 @@ handle_page_fault_tramp_1: lwz r5, _DSISR(r11) /* fall through */ handle_page_fault_tramp_2: + andis. r0, r5, DSISR_DABRMATCH@h + bne- 1f EXC_XFER_LITE(0x300, handle_page_fault) +1: EXC_XFER_STD(0x300, do_break) #ifdef CONFIG_VMAP_STACK .macro save_regs_thread thread
---
Christophe
Quoted 294 lines
Similar to the previous patch this makes interrupt handler function types more regular so they can be wrapped with the next patch.
bad_page_faultanddo_breakare not performance critical.Signed-off-by Nicholas Piggin <[email protected]>--- arch/powerpc/include/asm/bug.h | 2 +- arch/powerpc/include/asm/debug.h | 3 +-- arch/powerpc/kernel/entry_32.S | 14 ++++---------- arch/powerpc/kernel/exceptions-64e.S | 3 +-- arch/powerpc/kernel/exceptions-64s.S | 3 +-- arch/powerpc/kernel/head_8xx.S | 5 ++--- arch/powerpc/kernel/process.c | 7 +++---- arch/powerpc/kernel/traps.c | 2 +- arch/powerpc/mm/book3s64/hash_utils.c | 4 ++-- arch/powerpc/mm/book3s64/slb.c | 2 +- arch/powerpc/mm/fault.c | 14 +++++++------- arch/powerpc/platforms/8xx/machine_check.c | 2 +- 12 files changed, 25 insertions(+), 36 deletions(-)arch/powerpc/include/asm/bug.h +1
-1@@ -113,7 +113,7 @@struct pt_regs ;long do_page_fault (struct pt_regs *);long hash__do_page_fault (struct pt_regs *); -extern void bad_page_fault (struct pt_regs *,unsigned long ,int ); +void bad_page_fault (struct pt_regs *,int );extern void _exception (int ,struct pt_regs *,int ,unsigned long );extern void _exception_pkey (struct pt_regs *,unsigned long ,int );extern void die (const char *,struct pt_regs *,long );arch/powerpc/include/asm/debug.h +1
-2@@ -52,8 +52,7 @@ extern void do_send_trap(struct pt_regs *regs,unsigned long address, unsigned long error_code, int brkpt);#else -extern void do_break (struct pt_regs *regs,unsigned long address, -unsigned long error_code); +void do_break (struct pt_regs *regs);#endif #endif /*
_ASM_POWERPC_DEBUG_H*/arch/powerpc/kernel/entry_32.S +4
-10@@ -657,10 +657,6 @@ ppc_swapcontext: .globl handle_page_fault handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S_32 - andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault -#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except@@ -668,19 +664,17 @@ handle_page_fault: lwz r0,_TRAP(r1) clrrwi r0,r0,1 stw r0,_TRAP(r1) - mr r5,r3 + mr r4,r3 /* err arg for bad_page_fault */ addi r3,r1,STACK_FRAME_OVERHEAD - lwz r4,_DAR(r1) +#ifdef CONFIG_PPC_BOOK3S_32 + blt handle_dabr_fault +#endif bl bad_page_fault b ret_from_except_full #ifdef CONFIG_PPC_BOOK3S_32 /* We have a data breakpoint exception - handle it */ handle_dabr_fault: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - clrrwi r0,r0,1 - stw r0,_TRAP(r1) bl do_break b ret_from_except_full #endifarch/powerpc/kernel/exceptions-64e.S +1
-2@@ -1018,9 +1018,8 @@ storage_fault_common: bne- 1f b ret_from_except_lite 1: bl save_nvgprs - mr r5,r3 + mr r4,r3 addi r3,r1,STACK_FRAME_OVERHEAD - ld r4,_DAR(r1) bl bad_page_fault b ret_from_exceptarch/powerpc/kernel/exceptions-64s.S +1
-2@@ -2135,8 +2135,7 @@ EXC_COMMON_BEGIN(h_data_storage_common) GEN_COMMON h_data_storage addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION - ld r4,_DAR(r1) - li r5,SIGSEGV + li r4,SIGSEGV bl bad_page_fault MMU_FTR_SECTION_ELSE bl unknown_exceptionarch/powerpc/kernel/head_8xx.S +2
-3@@ -408,10 +408,9 @@ do_databreakpoint: addi r3,r1,STACK_FRAME_OVERHEAD mfspr r4,SPRN_BAR stw r4,_DAR(r11) -#ifdef CONFIG_VMAP_STACK - lwz r5,_DSISR(r11) -#else +#ifndef CONFIG_VMAP_STACK mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) #endif EXC_XFER_STD(0x1c00, do_break)arch/powerpc/kernel/process.c +3
-4@@ -660,11 +660,10 @@ static void do_break_handler(struct pt_regs *regs) } } -void do_break (struct pt_regs *regs,unsigned long address, -unsigned long error_code) +void do_break (struct pt_regs *regs) { current->thread.trap_nr =TRAP_HWBKPT ; -if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, error_code, +if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, regs->dsisr,11 ,SIGSEGV ) ==NOTIFY_STOP )return ;@@ -682,7 +681,7 @@ void do_break (struct pt_regs *regs, unsignedlong address,do_break_handler (regs );/* Deliver the signal to userspace */ - force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address); + force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)regs->dar); }#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ arch/powerpc/kernel/traps.c +1
-1@@ -1641,7 +1641,7 @@ void alignment_exception(struct pt_regs *regs)if (user_mode (regs))_exception (sig, regs, code, regs->dar);else -bad_page_fault (regs, regs->dar, sig); +bad_page_fault (regs, sig); bail:exception_exit (prev_state);arch/powerpc/mm/book3s64/hash_utils.c +2
-2@@ -1537,7 +1537,7 @@ long do_hash_fault(struct pt_regs *regs)* the access, or panic if there isn't a handler. */ if (unlikely (in_nmi ())) { -bad_page_fault (regs, ea,SIGSEGV ); +bad_page_fault (regs,SIGSEGV );return 0 ; }@@ -1576,7 +1576,7 @@ long do_hash_fault(struct pt_regs *regs)else _exception (SIGBUS , regs,BUS_ADRERR , ea); }else { -bad_page_fault (regs, ea,SIGBUS ); +bad_page_fault (regs,SIGBUS ); } err =0 ;arch/powerpc/mm/book3s64/slb.c +1
-1@@ -898,7 +898,7 @@ void do_bad_slb_fault(struct pt_regs *regs)if (user_mode (regs))_exception (SIGSEGV , regs,SEGV_BNDERR , regs->dar);else -bad_page_fault (regs, regs->dar,SIGSEGV ); +bad_page_fault (regs,SIGSEGV ); }else if (err == -EINVAL ) {unrecoverable_exception (regs); }else {arch/powerpc/mm/fault.c +1
-1@@ -375,7 +375,7 @@ static void sanity_check_fault(bool is_write, bool is_user,#elif defined(CONFIG_PPC_BOOK3E_64 )#define page_fault_is_bad (__err) ((__err) & DSISR_BAD_FAULT_64S)#else -#define page_fault_is_bad (__err) ((__err) & DSISR_BAD_FAULT_32S) +#define page_fault_is_bad (__err) ((__err) & (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH))#endif #endif
arch/powerpc/mm/fault.c +1
-1@@ -408,7 +408,7 @@ static int __do_page_fault(struct pt_regs *regs,unsigned long address, return 0;if (unlikely (page_fault_is_bad (error_code))) { -if (IS_ENABLED (CONFIG_PPC_BOOK3S_64 ) && (error_code &DSISR_DABRMATCH )) +if (IS_ENABLED (CONFIG_PPC_BOOK3S ) && (error_code &DSISR_DABRMATCH ))return -1 ;arch/powerpc/mm/fault.c +5
-5if (is_user) {@@ -562,14 +562,14 @@ long do_page_fault(struct pt_regs *regs)/* 32 and 64e handle errors in their asm code */ if (unlikely (err)) {if (err >0 ) { -bad_page_fault (regs, address, err); +bad_page_fault (regs, err); err =0 ; }else {/* * do_break() may change NV GPRS while handling the * breakpoint. Return -ve to caller to do that. */ -do_break (regs, address, error_code); +do_break (regs); } }#endif @@ -591,14 +591,14 @@ long hash__do_page_fault(struct pt_regs *regs) err =__do_page_fault (regs, address, error_code);if (unlikely (err)) {if (err >0 ) { -bad_page_fault (regs, address, err); +bad_page_fault (regs, err); err =0 ; }else {/* * do_break() may change NV GPRS while handling the * breakpoint. Return -ve to caller to do that. */ -do_break (regs, address, error_code); +do_break (regs); } }@@ -612,7 +612,7 @@ NOKPROBE_SYMBOL(hash__do_page_fault);* It is called from the DSI and ISI handlers in head.S and from some * of the procedures in traps.c. */ -void bad_page_fault (struct pt_regs *regs,unsigned long address,int sig) +void bad_page_fault (struct pt_regs *regs,int sig) {const struct exception_table_entry *entry;int is_write =page_fault_is_write (regs->dsisr);arch/powerpc/platforms/8xx/machine_check.c +1
-2@@ -26,7 +26,7 @@ int machine_check_8xx(struct pt_regs *regs)* to deal with that than having a wart in the mcheck handler. * -- BenH */ -bad_page_fault (regs, regs->dar,SIGBUS ); +bad_page_fault (regs,SIGBUS );return 1 ;#else return 0 ; --2.23.0
Nicholas Piggin
reviewerRe: [PATCH v2 03/19] powerpc: bad_page_fault, do_break get registers from regs
Excerpts from Christophe Leroy's message of November 15, 2020 5:07 am:
Quoted 7 lines
Hi,
Quoting Nicholas Piggin <[email protected]>:
Quoted 1 line
This also moves the 32s DABR match to C.
I'm still not happy with that. What about the following instead ?
This seems quite clean. I'll pull it into the series and see how it looks.
Thanks,
Nick
Quoted 355 lines
arch/powerpc/kernel/entry_32.S +0
-15@@ -657,10 +657,6 @@ ppc_swapcontext: .globl handle_page_fault handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S_32 - andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault -#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except@@ -674,17 +670,6 @@ handle_page_fault: bl bad_page_fault b ret_from_except_full -#ifdef CONFIG_PPC_BOOK3S_32 - /* We have a data breakpoint exception - handle it */ -handle_dabr_fault: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - clrrwi r0,r0,1 - stw r0,_TRAP(r1) - bl do_break - b ret_from_except_full -#endif - /* * This routine switches between two different tasks. The process * state of one is saved on its kernel stack. Then the statearch/powerpc/kernel/head_book3s_32.S +3
-1@@ -684,7 +684,10 @@ handle_page_fault_tramp_1: lwz r5, _DSISR(r11) /* fall through */ handle_page_fault_tramp_2: + andis. r0, r5, DSISR_DABRMATCH@h + bne- 1f EXC_XFER_LITE(0x300, handle_page_fault) +1: EXC_XFER_STD(0x300, do_break) #ifdef CONFIG_VMAP_STACK .macro save_regs_thread thread ---Christophe
Quoted 299 lines
Similar to the previous patch this makes interrupt handler function types more regular so they can be wrapped with the next patch.
bad_page_faultanddo_breakare not performance critical.Signed-off-by Nicholas Piggin <[email protected]>--- arch/powerpc/include/asm/bug.h | 2 +- arch/powerpc/include/asm/debug.h | 3 +-- arch/powerpc/kernel/entry_32.S | 14 ++++---------- arch/powerpc/kernel/exceptions-64e.S | 3 +-- arch/powerpc/kernel/exceptions-64s.S | 3 +-- arch/powerpc/kernel/head_8xx.S | 5 ++--- arch/powerpc/kernel/process.c | 7 +++---- arch/powerpc/kernel/traps.c | 2 +- arch/powerpc/mm/book3s64/hash_utils.c | 4 ++-- arch/powerpc/mm/book3s64/slb.c | 2 +- arch/powerpc/mm/fault.c | 14 +++++++------- arch/powerpc/platforms/8xx/machine_check.c | 2 +- 12 files changed, 25 insertions(+), 36 deletions(-)arch/powerpc/include/asm/bug.h +1
-1@@ -113,7 +113,7 @@struct pt_regs ;long do_page_fault (struct pt_regs *);long hash__do_page_fault (struct pt_regs *); -extern void bad_page_fault (struct pt_regs *,unsigned long ,int ); +void bad_page_fault (struct pt_regs *,int );extern void _exception (int ,struct pt_regs *,int ,unsigned long );extern void _exception_pkey (struct pt_regs *,unsigned long ,int );extern void die (const char *,struct pt_regs *,long );arch/powerpc/include/asm/debug.h +1
-2@@ -52,8 +52,7 @@ extern void do_send_trap(struct pt_regs *regs,unsigned long address, unsigned long error_code, int brkpt);#else -extern void do_break (struct pt_regs *regs,unsigned long address, -unsigned long error_code); +void do_break (struct pt_regs *regs);#endif #endif /*
_ASM_POWERPC_DEBUG_H*/arch/powerpc/kernel/entry_32.S +4
-10@@ -657,10 +657,6 @@ ppc_swapcontext: .globl handle_page_fault handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S_32 - andis. r0,r5,DSISR_DABRMATCH@h - bne- handle_dabr_fault -#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except@@ -668,19 +664,17 @@ handle_page_fault: lwz r0,_TRAP(r1) clrrwi r0,r0,1 stw r0,_TRAP(r1) - mr r5,r3 + mr r4,r3 /* err arg for bad_page_fault */ addi r3,r1,STACK_FRAME_OVERHEAD - lwz r4,_DAR(r1) +#ifdef CONFIG_PPC_BOOK3S_32 + blt handle_dabr_fault +#endif bl bad_page_fault b ret_from_except_full #ifdef CONFIG_PPC_BOOK3S_32 /* We have a data breakpoint exception - handle it */ handle_dabr_fault: - SAVE_NVGPRS(r1) - lwz r0,_TRAP(r1) - clrrwi r0,r0,1 - stw r0,_TRAP(r1) bl do_break b ret_from_except_full #endifarch/powerpc/kernel/exceptions-64e.S +1
-2@@ -1018,9 +1018,8 @@ storage_fault_common: bne- 1f b ret_from_except_lite 1: bl save_nvgprs - mr r5,r3 + mr r4,r3 addi r3,r1,STACK_FRAME_OVERHEAD - ld r4,_DAR(r1) bl bad_page_fault b ret_from_exceptarch/powerpc/kernel/exceptions-64s.S +1
-2@@ -2135,8 +2135,7 @@ EXC_COMMON_BEGIN(h_data_storage_common) GEN_COMMON h_data_storage addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION - ld r4,_DAR(r1) - li r5,SIGSEGV + li r4,SIGSEGV bl bad_page_fault MMU_FTR_SECTION_ELSE bl unknown_exceptionarch/powerpc/kernel/head_8xx.S +2
-3@@ -408,10 +408,9 @@ do_databreakpoint: addi r3,r1,STACK_FRAME_OVERHEAD mfspr r4,SPRN_BAR stw r4,_DAR(r11) -#ifdef CONFIG_VMAP_STACK - lwz r5,_DSISR(r11) -#else +#ifndef CONFIG_VMAP_STACK mfspr r5,SPRN_DSISR + stw r5,_DSISR(r11) #endif EXC_XFER_STD(0x1c00, do_break)arch/powerpc/kernel/process.c +3
-4@@ -660,11 +660,10 @@ static void do_break_handler(struct pt_regs *regs) } } -void do_break (struct pt_regs *regs,unsigned long address, -unsigned long error_code) +void do_break (struct pt_regs *regs) { current->thread.trap_nr =TRAP_HWBKPT ; -if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, error_code, +if (notify_die (DIE_DABR_MATCH ,"dabr_match" , regs, regs->dsisr,11 ,SIGSEGV ) ==NOTIFY_STOP )return ;@@ -682,7 +681,7 @@ void do_break (struct pt_regs *regs, unsignedlong address,do_break_handler (regs );/* Deliver the signal to userspace */ - force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address); + force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)regs->dar); }#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ arch/powerpc/kernel/traps.c +1
-1@@ -1641,7 +1641,7 @@ void alignment_exception(struct pt_regs *regs)if (user_mode (regs))_exception (sig, regs, code, regs->dar);else -bad_page_fault (regs, regs->dar, sig); +bad_page_fault (regs, sig); bail:exception_exit (prev_state);arch/powerpc/mm/book3s64/hash_utils.c +2
-2@@ -1537,7 +1537,7 @@ long do_hash_fault(struct pt_regs *regs)* the access, or panic if there isn't a handler. */ if (unlikely (in_nmi ())) { -bad_page_fault (regs, ea,SIGSEGV ); +bad_page_fault (regs,SIGSEGV );return 0 ; }@@ -1576,7 +1576,7 @@ long do_hash_fault(struct pt_regs *regs)else _exception (SIGBUS , regs,BUS_ADRERR , ea); }else { -bad_page_fault (regs, ea,SIGBUS ); +bad_page_fault (regs,SIGBUS ); } err =0 ;arch/powerpc/mm/book3s64/slb.c +1
-1@@ -898,7 +898,7 @@ void do_bad_slb_fault(struct pt_regs *regs)if (user_mode (regs))_exception (SIGSEGV , regs,SEGV_BNDERR , regs->dar);else -bad_page_fault (regs, regs->dar,SIGSEGV ); +bad_page_fault (regs,SIGSEGV ); }else if (err == -EINVAL ) {unrecoverable_exception (regs); }else {arch/powerpc/mm/fault.c +1
-1@@ -375,7 +375,7 @@ static void sanity_check_fault(bool is_write, bool is_user,#elif defined(CONFIG_PPC_BOOK3E_64 )#define page_fault_is_bad (__err) ((__err) & DSISR_BAD_FAULT_64S)#else -#define page_fault_is_bad (__err) ((__err) & DSISR_BAD_FAULT_32S) +#define page_fault_is_bad (__err) ((__err) & (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH))#endif #endif
arch/powerpc/mm/fault.c +1
-1@@ -408,7 +408,7 @@ static int __do_page_fault(struct pt_regs *regs,unsigned long address, return 0;if (unlikely (page_fault_is_bad (error_code))) { -if (IS_ENABLED (CONFIG_PPC_BOOK3S_64 ) && (error_code &DSISR_DABRMATCH )) +if (IS_ENABLED (CONFIG_PPC_BOOK3S ) && (error_code &DSISR_DABRMATCH ))return -1 ;arch/powerpc/mm/fault.c +5
-5if (is_user) {@@ -562,14 +562,14 @@ long do_page_fault(struct pt_regs *regs)/* 32 and 64e handle errors in their asm code */ if (unlikely (err)) {if (err >0 ) { -bad_page_fault (regs, address, err); +bad_page_fault (regs, err); err =0 ; }else {/* * do_break() may change NV GPRS while handling the * breakpoint. Return -ve to caller to do that. */ -do_break (regs, address, error_code); +do_break (regs); } }#endif @@ -591,14 +591,14 @@ long hash__do_page_fault(struct pt_regs *regs) err =__do_page_fault (regs, address, error_code);if (unlikely (err)) {if (err >0 ) { -bad_page_fault (regs, address, err); +bad_page_fault (regs, err); err =0 ; }else {/* * do_break() may change NV GPRS while handling the * breakpoint. Return -ve to caller to do that. */ -do_break (regs, address, error_code); +do_break (regs); } }@@ -612,7 +612,7 @@ NOKPROBE_SYMBOL(hash__do_page_fault);* It is called from the DSI and ISI handlers in head.S and from some * of the procedures in traps.c. */ -void bad_page_fault (struct pt_regs *regs,unsigned long address,int sig) +void bad_page_fault (struct pt_regs *regs,int sig) {const struct exception_table_entry *entry;int is_write =page_fault_is_write (regs->dsisr);arch/powerpc/platforms/8xx/machine_check.c +1
-2@@ -26,7 +26,7 @@ int machine_check_8xx(struct pt_regs *regs)* to deal with that than having a wart in the mcheck handler. * -- BenH */ -bad_page_fault (regs, regs->dar,SIGBUS ); +bad_page_fault (regs,SIGBUS );return 1 ;#else return 0 ; --2.23.0
Nicholas Piggin
reviewerPATCH v2 4/19 powerpc/perf: move perf irq/nmi handling details into traps.c
In reply to Nicholas PigginThis is required in order to allow more significant differences between NMI type interrupt handlers and regular asynchronous handlers.
--- arch/powerpc/kernel/traps.c | 31 +++++++++++++++++++++++++++- arch/powerpc/perf/core-book3s.c | 35 ++------------------------------ arch/powerpc/perf/core-fsl-emb.c | 25 ----------------------- 3 files changed, 32 insertions(+), 59 deletions(-)
arch/powerpc/kernel/traps.c +30 -1
@@ -1919,11 +1919,40 @@ void vsx_unavailable_tm(struct pt_regs *regs) }#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -void performance_monitor_exception (struct pt_regs *regs) +static void performance_monitor_exception_nmi (struct pt_regs *regs) +{ +nmi_enter (); + +__this_cpu_inc (irq_stat.pmu_irqs); + +perf_irq (regs); + +nmi_exit (); +} + +static void performance_monitor_exception_async (struct pt_regs *regs) { +irq_enter (); +__this_cpu_inc (irq_stat.pmu_irqs);perf_irq (regs); + +irq_exit (); +} + +void performance_monitor_exception (struct pt_regs *regs) +{ +/* +* On 64-bit, if perf interrupts hit in a local_irq_disable +* (soft-masked) region, we consider them as NMIs. This is required to +* prevent hash faults on user addresses when reading callchains (and +* looks better from an irq tracing perspective). +*/ +if (IS_ENABLED (CONFIG_PPC64 ) &&unlikely (arch_irq_disabled_regs (regs))) +performance_monitor_exception_nmi (regs); +else +performance_monitor_exception_async (regs); }#ifdef CONFIG_PPC_ADV_DEBUG_REGS
arch/powerpc/perf/core-book3s.c +2 -33
@@ -109,10 +109,6 @@ static inline void perf_read_regs(struct pt_regs *regs) { regs->result =0 ; } -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -return 0 ; -}static inline int siar_valid (struct pt_regs *regs) {
@@ -328,15 +324,6 @@ static inline void perf_read_regs(struct pt_regs *regs) regs->result = use_siar; } -/* -* If interrupts were soft-disabled when a PMU interrupt occurs, treat -* it as an NMI. -*/ -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -return (regs->softe &IRQS_DISABLED ); -} -/* * On processors like P7+ that have the SIAR-Valid bit, marked instructions * must be sampled only if the SIAR-valid bit is set.
@@ -2224,7 +2211,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)struct perf_event *event;unsigned long val[8 ];int found, active; -int nmi;if (cpuhw->n_limited) freeze_limited_counters(cpuhw, mfspr(SPRN_PMC5),
@@ -2232,18 +2218,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)perf_read_regs (regs); -/* -* If perf interrupts hit in a local_irq_disable (soft-masked) region, -* we consider them as NMIs. This is required to prevent hash faults on -* user addresses when reading callchains. See the NMI test in -* do_hash_page. -*/ - nmi =perf_intr_is_nmi (regs); -if (nmi) -nmi_enter (); -else -irq_enter (); -/* Read all the PMCs since we'll need them a bunch of times */ for (i =0 ; i < ppmu->n_counter; ++i) val[i] =read_pmc (i +1 );
@@ -2289,8 +2263,8 @@ static void __perf_event_interrupt(struct pt_regs *regs) } } } -if (!found && !nmi &&printk_ratelimit ()) -printk (KERN_WARNING "Can't find PMC that caused IRQ\n" ); +if (unlikely (!found) && !arch_irq_disabled_regs (regs)) +printk_ratelimited (KERN_WARNING "Can't find PMC that caused IRQ\n" );/* * Reset MMCR0 to its normal value. This will set PMXE and
@@ -2300,11 +2274,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)* we get back out of this interrupt. */ write_mmcr0 (cpuhw, cpuhw->mmcr.mmcr0); - -if (nmi) -nmi_exit (); -else -irq_exit (); }static void perf_event_interrupt (struct pt_regs *regs)
arch/powerpc/perf/core-fsl-emb.c +0 -25
@@ -31,19 +31,6 @@ static atomic_t num_events;/* Used to avoid races in calling reserve/release_pmc_hardware */ static DEFINE_MUTEX (pmc_reserve_mutex); -/* -* If interrupts were soft-disabled when a PMU interrupt occurs, treat -* it as an NMI. -*/ -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -#ifdef __powerpc64__ -return (regs->softe &IRQS_DISABLED ); -#else -return 0 ; -#endif -} -static void perf_event_interrupt (struct pt_regs *regs);/*
@@ -659,13 +646,6 @@ static void perf_event_interrupt(struct pt_regs *regs)struct perf_event *event;unsigned long val;int found =0 ; -int nmi; - - nmi =perf_intr_is_nmi (regs); -if (nmi) -nmi_enter (); -else -irq_enter ();for (i =0 ; i < ppmu->n_counter; ++i) { event = cpuhw->event[i];
@@ -690,11 +670,6 @@ static void perf_event_interrupt(struct pt_regs *regs)mtmsr (mfmsr () |MSR_PMM );mtpmr (PMRN_PMGC0 ,PMGC0_PMIE |PMGC0_FCECE );isync (); - -if (nmi) -nmi_exit (); -else -irq_exit (); }void hw_perf_event_setup (int cpu)
Signature · 1 line
2.23.0
Re: [PATCH v2 04/19] powerpc/perf: move perf irq/nmi handling details into traps.c
Quoted 78 lines · Nicholas Piggin
This is required in order to allow more significant differences between NMI type interrupt handlers and regular asynchronous handlers.
Signed-off-by Nicholas Piggin <[email protected]>---
arch/powerpc/kernel/traps.c | 31 +++++++++++++++++++++++++++- arch/powerpc/perf/core-book3s.c | 35 ++------------------------------ arch/powerpc/perf/core-fsl-emb.c | 25 ----------------------- 3 files changed, 32 insertions(+), 59 deletions(-)arch/powerpc/kernel/traps.c +30
-1@@ -1919,11 +1919,40 @@ void vsx_unavailable_tm(struct pt_regs *regs) }#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ -void performance_monitor_exception (struct pt_regs *regs) +static void performance_monitor_exception_nmi (struct pt_regs *regs) +{ +nmi_enter (); + +__this_cpu_inc (irq_stat.pmu_irqs); + +perf_irq (regs); + +nmi_exit (); +} + +static void performance_monitor_exception_async (struct pt_regs *regs) { +irq_enter (); +__this_cpu_inc (irq_stat.pmu_irqs);perf_irq (regs); + +irq_exit (); +} + +void performance_monitor_exception (struct pt_regs *regs) +{ +/* +* On 64-bit, if perf interrupts hit in a local_irq_disable +* (soft-masked) region, we consider them as NMIs. This is required to +* prevent hash faults on user addresses when reading callchains (and +* looks better from an irq tracing perspective). +*/ +if (IS_ENABLED (CONFIG_PPC64 ) &&unlikely (arch_irq_disabled_regs (regs))) +performance_monitor_exception_nmi (regs); +else +performance_monitor_exception_async (regs); }#ifdef CONFIG_PPC_ADV_DEBUG_REGS arch/powerpc/perf/core-book3s.c +0
-4@@ -109,10 +109,6 @@ static inline void perf_read_regs(struct pt_regs *regs) { regs->result =0 ; } -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -return 0 ; -}static inline int siar_valid (struct pt_regs *regs) {@@ -328,15 +324,6 @@ static inline void perf_read_regs(struct pt_regs *regs) regs->result = use_siar; }
arch/powerpc/perf/core-book3s.c static inline void perf_read_regs(struct pt_regs *regs) · line 339
Quoted 10 lines
arch/powerpc/perf/core-book3s.c +0
-9-/* -* If interrupts were soft-disabled when a PMU interrupt occurs, treat -* it as an NMI. -*/ -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -return (regs->softe &IRQS_DISABLED ); -} -
Hi Nick,
arch_irq_disabled_regs checks the regs->softe value, if it has IRQS_DISABLED set. Core-book3s is also using same logic in perf_intr_is_nmi to check if it is an NMI. With the changes in this patch, if I understood correctly, we will do the irq/nmi handling in traps.c rather than doing it in the PMI interrupt handler. But can you please help to understand better on what is the perf weirdness (sometimes NMI, sometimes not) mentioned in the cover letter that we are fixing with this change ?
Thanks
Athira
Quoted 106 lines
arch/powerpc/perf/core-book3s.c +2
-20/* * On processors like P7+ that have the SIAR-Valid bit, marked instructions * must be sampled only if the SIAR-valid bit is set. @@ -2224,7 +2211,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)struct perf_event *event;unsigned long val[8 ];int found, active; -int nmi;if (cpuhw->n_limited) freeze_limited_counters(cpuhw, mfspr(SPRN_PMC5),@@ -2232,18 +2218,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)perf_read_regs (regs); -/* -* If perf interrupts hit in a local_irq_disable (soft-masked) region, -* we consider them as NMIs. This is required to prevent hash faults on -* user addresses when reading callchains. See the NMI test in -* do_hash_page. -*/ - nmi =perf_intr_is_nmi (regs); -if (nmi) -nmi_enter (); -else -irq_enter (); -/* Read all the PMCs since we'll need them a bunch of times */ for (i =0 ; i < ppmu->n_counter; ++i) val[i] =read_pmc (i +1 );@@ -2289,8 +2263,8 @@ static void __perf_event_interrupt(struct pt_regs *regs) } } } -if (!found && !nmi &&printk_ratelimit ()) -printk (KERN_WARNING "Can't find PMC that caused IRQ\n" ); +if (unlikely (!found) && !arch_irq_disabled_regs (regs)) +printk_ratelimited (KERN_WARNING "Can't find PMC that caused IRQ\n" );/* * Reset MMCR0 to its normal value. This will set PMXE and @@ -2300,11 +2274,6 @@ static void __perf_event_interrupt(struct pt_regs *regs)* we get back out of this interrupt. */ write_mmcr0 (cpuhw, cpuhw->mmcr.mmcr0); - -if (nmi) -nmi_exit (); -else -irq_exit (); }static void perf_event_interrupt (struct pt_regs *regs)arch/powerpc/perf/core-fsl-emb.c +0
-25@@ -31,19 +31,6 @@ static atomic_t num_events;/* Used to avoid races in calling reserve/release_pmc_hardware */ static DEFINE_MUTEX (pmc_reserve_mutex); -/* -* If interrupts were soft-disabled when a PMU interrupt occurs, treat -* it as an NMI. -*/ -static inline int perf_intr_is_nmi (struct pt_regs *regs) -{ -#ifdef __powerpc64__ -return (regs->softe &IRQS_DISABLED ); -#else -return 0 ; -#endif -} -static void perf_event_interrupt (struct pt_regs *regs);/* @@ -659,13 +646,6 @@ static void perf_event_interrupt(struct pt_regs *regs)struct perf_event *event;unsigned long val;int found =0 ; -int nmi; - - nmi =perf_intr_is_nmi (regs); -if (nmi) -nmi_enter (); -else -irq_enter ();for (i =0 ; i < ppmu->n_counter; ++i) { event = cpuhw->event[i];@@ -690,11 +670,6 @@ static void perf_event_interrupt(struct pt_regs *regs)mtmsr (mfmsr () |MSR_PMM );mtpmr (PMRN_PMGC0 ,PMGC0_PMIE |PMGC0_FCECE );isync (); - -if (nmi) -nmi_exit (); -else -irq_exit (); }void hw_perf_event_setup (int cpu)Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 5/19 powerpc: interrupt handler wrapper functions
In reply to Nicholas PigginAdd wrapper functions (derived from x86 macros) for interrupt handler functions. This allows interrupt entry code to be written in C.
--- arch/powerpc/include/asm/asm-prototypes.h | 29 --- arch/powerpc/include/asm/book3s/64/mmu-hash.h | 1 - arch/powerpc/include/asm/hw_irq.h | 9 - arch/powerpc/include/asm/interrupt.h | 203 ++++++++++++++++++ arch/powerpc/include/asm/time.h | 2 + arch/powerpc/kernel/dbell.c | 12 +- arch/powerpc/kernel/exceptions-64s.S | 7 +- arch/powerpc/kernel/head_book3s_32.S | 6 +- arch/powerpc/kernel/irq.c | 3 +- arch/powerpc/kernel/mce.c | 5 +- arch/powerpc/kernel/syscall_64.c | 1 + arch/powerpc/kernel/tau_6xx.c | 2 +- arch/powerpc/kernel/time.c | 3 +- arch/powerpc/kernel/traps.c | 84 +++++--- arch/powerpc/kernel/watchdog.c | 7 +- arch/powerpc/kvm/book3s_hv.c | 1 + arch/powerpc/kvm/book3s_hv_builtin.c | 1 + arch/powerpc/mm/book3s64/hash_utils.c | 3 +- arch/powerpc/mm/book3s64/slb.c | 5 +- arch/powerpc/mm/fault.c | 10 +- arch/powerpc/platforms/powernv/idle.c | 1 + 21 files changed, 303 insertions(+), 92 deletions(-) create mode 100644 arch/powerpc/include/asm/interrupt.h
arch/powerpc/include/asm/asm-prototypes.h +0 -29
@@ -56,35 +56,6 @@ int exit_vmx_usercopy(void);int enter_vmx_ops (void );void *exit_vmx_ops (void *dest); -/* Traps */ -long machine_check_early (struct pt_regs *regs); -long hmi_exception_realmode (struct pt_regs *regs); -void SMIException (struct pt_regs *regs); -void handle_hmi_exception (struct pt_regs *regs); -void instruction_breakpoint_exception (struct pt_regs *regs); -void RunModeException (struct pt_regs *regs); -void single_step_exception (struct pt_regs *regs); -void program_check_exception (struct pt_regs *regs); -void alignment_exception (struct pt_regs *regs); -void StackOverflow (struct pt_regs *regs); -void stack_overflow_exception (struct pt_regs *regs); -void kernel_fp_unavailable_exception (struct pt_regs *regs); -void altivec_unavailable_exception (struct pt_regs *regs); -void vsx_unavailable_exception (struct pt_regs *regs); -void fp_unavailable_tm (struct pt_regs *regs); -void altivec_unavailable_tm (struct pt_regs *regs); -void vsx_unavailable_tm (struct pt_regs *regs); -void facility_unavailable_exception (struct pt_regs *regs); -void TAUException (struct pt_regs *regs); -void altivec_assist_exception (struct pt_regs *regs); -void unrecoverable_exception (struct pt_regs *regs); -void kernel_bad_stack (struct pt_regs *regs); -void system_reset_exception (struct pt_regs *regs); -void machine_check_exception (struct pt_regs *regs); -void emulation_assist_interrupt (struct pt_regs *regs); -long do_slb_fault (struct pt_regs *regs); -void do_bad_slb_fault (struct pt_regs *regs); -/* signals, syscalls and interrupts */ long sys_swapcontext(struct ucontext __user *old_ctx, struct ucontext __user *new_ctx,
arch/powerpc/include/asm/book3s/64/mmu-hash.h +0 -1
@@ -453,7 +453,6 @@ static inline unsigned long hpt_hash(unsigned long vpn,#define HPTE_LOCAL_UPDATE 0x1#define HPTE_NOHPTE_UPDATE 0x2 -long do_hash_fault (struct pt_regs *regs);extern int __hash_page_4K (unsigned long ea,unsigned long access,unsigned long vsid,pte_t *ptep,unsigned long trap,unsigned long flags,int ssize,int subpage_prot);
arch/powerpc/include/asm/hw_irq.h +0 -9
@@ -50,15 +50,6 @@#ifndef __ASSEMBLY__ -extern void replay_system_reset (void ); -extern void replay_soft_interrupts (void ); - -extern void timer_interrupt (struct pt_regs *); -extern void timer_broadcast_interrupt (void ); -extern void performance_monitor_exception (struct pt_regs *regs); -extern void WatchdogException (struct pt_regs *regs); -extern void unknown_exception (struct pt_regs *regs); -#ifdef CONFIG_PPC64 #include <asm/paca.h>
arch/powerpc/include/asm/interrupt.h new file +203 -0
203 lines not on this page · raw message
arch/powerpc/include/asm/time.h +2 -0
@@ -131,6 +131,8 @@ DECLARE_PER_CPU(u64, decrementers_next_tb);/* Convert timebase ticks to nanoseconds */ unsigned long long tb_to_ns (unsigned long long tb_ticks); +void timer_broadcast_interrupt (void ); +/* SPLPAR */ void accumulate_stolen_time (void );
arch/powerpc/kernel/dbell.c +4 -8
@@ -12,14 +12,14 @@#include <linux/hardirq.h> #include <asm/dbell.h> +#include <asm/interrupt.h> #include <asm/irq_regs.h> #include <asm/kvm_ppc.h> #include <asm/trace.h> -#ifdef CONFIG_SMP - -void doorbell_exception (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC (doorbell_exception) { +#ifdef CONFIG_SMP struct pt_regs *old_regs =set_irq_regs (regs);irq_enter ();
@@ -37,11 +37,7 @@ void doorbell_exception(struct pt_regs *regs)trace_doorbell_exit (regs);irq_exit ();set_irq_regs (old_regs); -}#else /* CONFIG_SMP */ -void doorbell_exception (struct pt_regs *regs) -{printk (KERN_WARNING "Received doorbell on non-smp system\n" ); -}#endif /* CONFIG_SMP */ - +}
arch/powerpc/kernel/exceptions-64s.S +3 -4
@@ -1922,7 +1922,7 @@ EXC_COMMON_BEGIN(doorbell_super_common) #ifdef CONFIG_PPC_DOORBELL bl doorbell_exception #else - bl unknown_exception + bl unknown_async_exception #endif b interrupt_return
@@ -2135,8 +2135,7 @@ EXC_COMMON_BEGIN(h_data_storage_common) GEN_COMMON h_data_storage addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION - li r4,SIGSEGV - bl bad_page_fault + bl do_bad_page_fault MMU_FTR_SECTION_ELSE bl unknown_exception ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX)
@@ -2309,7 +2308,7 @@ EXC_COMMON_BEGIN(h_doorbell_common) #ifdef CONFIG_PPC_DOORBELL bl doorbell_exception #else - bl unknown_exception + bl unknown_async_exception #endif b interrupt_return
arch/powerpc/kernel/head_book3s_32.S +3 -3
@@ -239,8 +239,8 @@ __secondary_hold_acknowledge: /* System reset */ /* core99 pmac starts the seconary here by changing the vector, and - putting it back to what it was (unknown_exception) when done. */ - EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD) + putting it back to what it was (unknown_async_exception) when done. */ + EXCEPTION(0x100, Reset, unknown_async_exception, EXC_XFER_STD) /* Machine check */ /*
@@ -653,7 +653,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) #endif #ifndef CONFIG_TAU_INT -#define TAUException unknown_exception +#define TAUException unknown_async_exception #endif EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_STD)
arch/powerpc/kernel/irq.c +2 -1
@@ -54,6 +54,7 @@#include <linux/pgtable.h> #include <linux/uaccess.h> +#include <asm/interrupt.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/cache.h>
@@ -665,7 +666,7 @@ void __do_irq(struct pt_regs *regs)irq_exit (); } -void do_IRQ (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC (do_IRQ) {struct pt_regs *old_regs =set_irq_regs (regs);void *cursp, *irqsp, *sirqsp;
arch/powerpc/kernel/mce.c +3 -2
@@ -18,6 +18,7 @@#include <linux/extable.h> #include <linux/ftrace.h> +#include <asm/interrupt.h> #include <asm/machdep.h> #include <asm/mce.h> #include <asm/nmi.h>
@@ -588,7 +589,7 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info);* * regs->nip and regs->msr contains srr0 and ssr1. */ -long notrace machine_check_early (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI (machine_check_early) {long handled =0 ;u8 ftrace_enabled =this_cpu_get_ftrace_enabled ();
@@ -722,7 +723,7 @@ long hmi_handle_debugtrig(struct pt_regs *regs)/* * Return values: */ -long hmi_exception_realmode (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI (hmi_exception_realmode) {int ret;
arch/powerpc/kernel/syscall_64.c +1 -0
@@ -5,6 +5,7 @@#include <asm/book3s/64/kup-radix.h> #include <asm/cputime.h> #include <asm/hw_irq.h> +#include <asm/interrupt.h> #include <asm/kprobes.h> #include <asm/paca.h> #include <asm/ptrace.h>
arch/powerpc/kernel/tau_6xx.c +1 -1
@@ -100,7 +100,7 @@ static void TAUupdate(int cpu)* with interrupts disabled */ -void TAUException (struct pt_regs * regs) +DEFINE_INTERRUPT_HANDLER_ASYNC (TAUException) {int cpu =smp_processor_id ();
arch/powerpc/kernel/time.c +2 -1
@@ -56,6 +56,7 @@#include <linux/processor.h> #include <asm/trace.h> +#include <asm/interrupt.h> #include <asm/io.h> #include <asm/nvram.h> #include <asm/cache.h>
@@ -545,7 +546,7 @@ void arch_irq_work_raise(void)* timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. */ -void timer_interrupt (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_ASYNC (timer_interrupt) {struct clock_event_device *evt =this_cpu_ptr (&decrementers);u64 *next_tb =this_cpu_ptr (&decrementers_next_tb);
arch/powerpc/kernel/traps.c +57 -27
259 lines not on this page · raw message
arch/powerpc/kernel/watchdog.c +5 -2
@@ -26,6 +26,7 @@#include <linux/delay.h> #include <linux/smp.h> +#include <asm/interrupt.h> #include <asm/paca.h> /*
@@ -247,14 +248,14 @@ static void watchdog_timer_interrupt(int cpu)watchdog_smp_panic (cpu, tb); } -void soft_nmi_interrupt (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_NMI (soft_nmi_interrupt) {unsigned long flags;int cpu =raw_smp_processor_id ();u64 tb;if (!cpumask_test_cpu (cpu, &wd_cpus_enabled)) -return ; +return 0 ;nmi_enter ();
@@ -291,6 +292,8 @@ void soft_nmi_interrupt(struct pt_regs *regs) out:nmi_exit (); + +return 0 ; }static enum hrtimer_restart watchdog_timer_fn (struct hrtimer *hrtimer)
arch/powerpc/kvm/book3s_hv.c +1 -0
@@ -53,6 +53,7 @@#include <asm/cputable.h> #include <asm/cacheflush.h> #include <linux/uaccess.h> +#include <asm/interrupt.h> #include <asm/io.h> #include <asm/kvm_ppc.h> #include <asm/kvm_book3s.h>
arch/powerpc/kvm/book3s_hv_builtin.c +1 -0
@@ -17,6 +17,7 @@#include <asm/asm-prototypes.h> #include <asm/cputable.h> +#include <asm/interrupt.h> #include <asm/kvm_ppc.h> #include <asm/kvm_book3s.h> #include <asm/archrandom.h>
arch/powerpc/mm/book3s64/hash_utils.c +2 -1
@@ -38,6 +38,7 @@#include <linux/pgtable.h> #include <asm/debugfs.h> +#include <asm/interrupt.h> #include <asm/processor.h> #include <asm/mmu.h> #include <asm/mmu_context.h>
@@ -1510,7 +1511,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap, }EXPORT_SYMBOL_GPL (hash_page); -long do_hash_fault (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_RET (do_hash_fault) {unsigned long ea = regs->dar;unsigned long dsisr = regs->dsisr;
arch/powerpc/mm/book3s64/slb.c +3 -2
@@ -10,6 +10,7 @@*/ #include <asm/asm-prototypes.h> +#include <asm/interrupt.h> #include <asm/mmu.h> #include <asm/mmu_context.h> #include <asm/paca.h>
@@ -837,7 +838,7 @@ static long slb_allocate_user(struct mm_struct *mm, unsigned long ea)return slb_insert_entry (ea, context, flags, ssize, false); } -long do_slb_fault (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_RAW (do_slb_fault) {unsigned long ea = regs->dar;unsigned long id =get_region_id (ea);
@@ -890,7 +891,7 @@ long do_slb_fault(struct pt_regs *regs) } } -void do_bad_slb_fault (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER (do_bad_slb_fault) {int err = regs->result;
arch/powerpc/mm/fault.c +9 -1
@@ -34,6 +34,7 @@#include <linux/uaccess.h> #include <asm/firmware.h> +#include <asm/interrupt.h> #include <asm/page.h> #include <asm/mmu.h> #include <asm/mmu_context.h>
@@ -549,7 +550,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address, }NOKPROBE_SYMBOL (__do_page_fault); -long do_page_fault (struct pt_regs *regs) +DEFINE_INTERRUPT_HANDLER_RET (do_page_fault) {enum ctx_state prev_state =exception_enter ();unsigned long address = regs->dar;
@@ -656,3 +657,10 @@ void bad_page_fault(struct pt_regs *regs, int sig)die ("Kernel access of bad area" , regs, sig); } + +#ifdef CONFIG_PPC_BOOK3S_64 +DEFINE_INTERRUPT_HANDLER (do_bad_page_fault) +{ +bad_page_fault (regs,SIGSEGV ); +} +#endif
arch/powerpc/platforms/powernv/idle.c +1 -0
@@ -14,6 +14,7 @@#include <asm/asm-prototypes.h> #include <asm/firmware.h> +#include <asm/interrupt.h> #include <asm/machdep.h> #include <asm/opal.h> #include <asm/cputhreads.h>
Signature · 1 line
2.23.0
kernel test robot
build botRe: [PATCH v2 05/19] powerpc: interrupt handler wrapper functions
I love your patch! Yet something to improve:
Hi Nicholas,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.10-rc3 next-20201113]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-interrupt-wrappers/20201111-183954 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-randconfig-r003-20201113 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 9e0c35655b6e8186baef8840b26ba4090503b554)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# install powerpc cross compiling tool for clang build
# apt-get install binutils-powerpc-linux-gnu
# https://github.com/0day-ci/linux/commit/36805b0ebcf1760588efad86b8b5db5344329148
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-interrupt-wrappers/20201111-183954 git checkout 36805b0ebcf1760588efad86b8b5db5344329148
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
All errors (new ones prefixed by >>):
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:45:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:16:1: note: expanded from here
__do_insw
^
arch/powerpc/include/asm/io.h:542:56: note: expanded from macro '__do_insw'
#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from arch/powerpc/kvm/booke.c:15:
In file included from include/linux/kvm_host.h:7:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:47:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:18:1: note: expanded from here
__do_insl
^
arch/powerpc/include/asm/io.h:543:56: note: expanded from macro '__do_insl'
#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from arch/powerpc/kvm/booke.c:15:
In file included from include/linux/kvm_host.h:7:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:49:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:20:1: note: expanded from here
__do_outsb
^
arch/powerpc/include/asm/io.h:544:58: note: expanded from macro '__do_outsb'
#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from arch/powerpc/kvm/booke.c:15:
In file included from include/linux/kvm_host.h:7:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:51:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:22:1: note: expanded from here
__do_outsw
^
arch/powerpc/include/asm/io.h:545:58: note: expanded from macro '__do_outsw'
#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from arch/powerpc/kvm/booke.c:15:
In file included from include/linux/kvm_host.h:7:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:53:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:24:1: note: expanded from here
__do_outsl
^
arch/powerpc/include/asm/io.h:546:58: note: expanded from macro '__do_outsl'
#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
arch/powerpc/kvm/booke.c:600:6: warning: no previous prototype for function 'kvmppc_watchdog_func' [-Wmissing-prototypes]
void kvmppc_watchdog_func(struct timer_list *t)
^
arch/powerpc/kvm/booke.c:600:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void kvmppc_watchdog_func(struct timer_list *t)
^
static
>> arch/powerpc/kvm/booke.c:922:3: error: implicit declaration of function 'timer_interrupt' [-Werror,-Wimplicit-function-declaration]
timer_interrupt(®s);
^
arch/powerpc/kvm/booke.c:922:3: note: did you mean 'hrtimer_interrupt'?
include/linux/hrtimer.h:319:13: note: 'hrtimer_interrupt' declared here
extern void hrtimer_interrupt(struct clock_event_device *dev);
^
>> arch/powerpc/kvm/booke.c:935:3: error: implicit declaration of function 'performance_monitor_exception' [-Werror,-Wimplicit-function-declaration]
performance_monitor_exception(®s);
^
>> arch/powerpc/kvm/booke.c:942:3: error: implicit declaration of function 'unknown_exception' [-Werror,-Wimplicit-function-declaration]
unknown_exception(®s);
^
arch/powerpc/kvm/booke.c:984:5: warning: no previous prototype for function 'kvmppc_handle_exit' [-Wmissing-prototypes]
int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr)
^
arch/powerpc/kvm/booke.c:984:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr)
^
static
arch/powerpc/kvm/booke.c:1909:6: warning: no previous prototype for function 'kvm_guest_protect_msr' [-Wmissing-prototypes]
void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set)
^ arch/powerpc/kvm/booke.c:1909:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set)
^
static
9 warnings and 3 errors generated.
vim +/timer_interrupt +922 arch/powerpc/kvm/booke.c
4e642ccbd6a3f14 Alexander Graf 2012-02-20 903
6328e593c3df5e8 Bharat Bhushan 2012-06-20 904 /*
6328e593c3df5e8 Bharat Bhushan 2012-06-20 905 * For interrupts needed to be handled by host interrupt handlers,
6328e593c3df5e8 Bharat Bhushan 2012-06-20 906 * corresponding host handler are called from here in similar way
6328e593c3df5e8 Bharat Bhushan 2012-06-20 907 * (but not exact) as they are called from low level handler
6328e593c3df5e8 Bharat Bhushan 2012-06-20 908 * (such as from arch/powerpc/kernel/head_fsl_booke.S).
6328e593c3df5e8 Bharat Bhushan 2012-06-20 909 */
4e642ccbd6a3f14 Alexander Graf 2012-02-20 910 static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
4e642ccbd6a3f14 Alexander Graf 2012-02-20 911 unsigned int exit_nr)
4e642ccbd6a3f14 Alexander Graf 2012-02-20 912 {
4e642ccbd6a3f14 Alexander Graf 2012-02-20 913 struct pt_regs regs;
73e75b416ffcfa3 Hollis Blanchard 2008-12-02 914
d30f6e480055e5b Scott Wood 2011-12-20 915 switch (exit_nr) {
d30f6e480055e5b Scott Wood 2011-12-20 916 case BOOKE_INTERRUPT_EXTERNAL:
4e642ccbd6a3f14 Alexander Graf 2012-02-20 917 kvmppc_fill_pt_regs(®s);
4e642ccbd6a3f14 Alexander Graf 2012-02-20 918 do_IRQ(®s);
d30f6e480055e5b Scott Wood 2011-12-20 919 break;
d30f6e480055e5b Scott Wood 2011-12-20 920 case BOOKE_INTERRUPT_DECREMENTER:
4e642ccbd6a3f14 Alexander Graf 2012-02-20 921 kvmppc_fill_pt_regs(®s);
4e642ccbd6a3f14 Alexander Graf 2012-02-20 @922 timer_interrupt(®s);
d30f6e480055e5b Scott Wood 2011-12-20 923 break;
5f17ce8b954a2ff Tiejun Chen 2013-05-13 924 #if defined(CONFIG_PPC_DOORBELL)
d30f6e480055e5b Scott Wood 2011-12-20 925 case BOOKE_INTERRUPT_DOORBELL:
4e642ccbd6a3f14 Alexander Graf 2012-02-20 926 kvmppc_fill_pt_regs(®s);
4e642ccbd6a3f14 Alexander Graf 2012-02-20 927 doorbell_exception(®s);
d30f6e480055e5b Scott Wood 2011-12-20 928 break;
d30f6e480055e5b Scott Wood 2011-12-20 929 #endif
d30f6e480055e5b Scott Wood 2011-12-20 930 case BOOKE_INTERRUPT_MACHINE_CHECK:
d30f6e480055e5b Scott Wood 2011-12-20 931 /* FIXME */
d30f6e480055e5b Scott Wood 2011-12-20 932 break;
7cc1e8ee78f469e Alexander Graf 2012-02-22 933 case BOOKE_INTERRUPT_PERFORMANCE_MONITOR:
7cc1e8ee78f469e Alexander Graf 2012-02-22 934 kvmppc_fill_pt_regs(®s);
7cc1e8ee78f469e Alexander Graf 2012-02-22 @935 performance_monitor_exception(®s);
7cc1e8ee78f469e Alexander Graf 2012-02-22 936 break;
6328e593c3df5e8 Bharat Bhushan 2012-06-20 937 case BOOKE_INTERRUPT_WATCHDOG:
6328e593c3df5e8 Bharat Bhushan 2012-06-20 938 kvmppc_fill_pt_regs(®s);
6328e593c3df5e8 Bharat Bhushan 2012-06-20 939 #ifdef CONFIG_BOOKE_WDT
6328e593c3df5e8 Bharat Bhushan 2012-06-20 940 WatchdogException(®s);
6328e593c3df5e8 Bharat Bhushan 2012-06-20 941 #else
6328e593c3df5e8 Bharat Bhushan 2012-06-20 @942 unknown_exception(®s);
6328e593c3df5e8 Bharat Bhushan 2012-06-20 943 #endif
6328e593c3df5e8 Bharat Bhushan 2012-06-20 944 break;
6328e593c3df5e8 Bharat Bhushan 2012-06-20 945 case BOOKE_INTERRUPT_CRITICAL:
845ac985cf8e3d5 Tudor Laurentiu 2015-05-18 946 kvmppc_fill_pt_regs(®s);
6328e593c3df5e8 Bharat Bhushan 2012-06-20 947 unknown_exception(®s);
6328e593c3df5e8 Bharat Bhushan 2012-06-20 948 break;
ce11e48b7fdd256 Bharat Bhushan 2013-07-04 949 case BOOKE_INTERRUPT_DEBUG:
ce11e48b7fdd256 Bharat Bhushan 2013-07-04 950 /* Save DBSR before preemption is enabled */
ce11e48b7fdd256 Bharat Bhushan 2013-07-04 951 vcpu->arch.dbsr = mfspr(SPRN_DBSR);
ce11e48b7fdd256 Bharat Bhushan 2013-07-04 952 kvmppc_clear_dbsr();
ce11e48b7fdd256 Bharat Bhushan 2013-07-04 953 break;
d30f6e480055e5b Scott Wood 2011-12-20 954 }
4e642ccbd6a3f14 Alexander Graf 2012-02-20 955 }
4e642ccbd6a3f14 Alexander Graf 2012-02-20 956 ---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
kernel test robot
build botRe: [PATCH v2 05/19] powerpc: interrupt handler wrapper functions
In reply to Nicholas PigginI love your patch! Perhaps something to improve:
Hi Nicholas,
I love your patch! Perhaps something to improve:
[auto build test WARNING on powerpc/next]
[also build test WARNING on v5.10-rc3 next-20201113]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-interrupt-wrappers/20201111-183954 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-randconfig-r035-20201111 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project a719eef73ec447b2c5fc8b70f69564a2e0f78e1e)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# install powerpc cross compiling tool for clang build
# apt-get install binutils-powerpc-linux-gnu
# https://github.com/0day-ci/linux/commit/36805b0ebcf1760588efad86b8b5db5344329148
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-interrupt-wrappers/20201111-183954 git checkout 36805b0ebcf1760588efad86b8b5db5344329148
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
>> arch/powerpc/kernel/traps.c:1950:30: warning: no previous prototype for function 'performance_monitor_exception_nmi' [-Wmissing-prototypes]
DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
^
arch/powerpc/kernel/traps.c:1950:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
^
arch/powerpc/include/asm/interrupt.h:146:19: note: expanded from macro 'DEFINE_INTERRUPT_HANDLER_NMI'
__visible noinstr long func(struct pt_regs *regs) \
^
>> arch/powerpc/kernel/traps.c:1963:32: warning: no previous prototype for function 'performance_monitor_exception_async' [-Wmissing-prototypes]
DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async)
^
arch/powerpc/kernel/traps.c:1963:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async)
^
arch/powerpc/include/asm/interrupt.h:118:19: note: expanded from macro 'DEFINE_INTERRUPT_HANDLER_ASYNC'
__visible noinstr void func(struct pt_regs *regs) \
^2 warnings generated.
vim +/performance_monitor_exception_nmi +1950 arch/powerpc/kernel/traps.c
1949
> 1950 DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
1951 {
1952 nmi_enter();
1953
1954 __this_cpu_inc(irq_stat.pmu_irqs);
1955
1956 perf_irq(regs);
1957
1958 nmi_exit();
1959
1960 return 0;
1961 }
1962
> 1963 DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async) 1964 {
1965 irq_enter();
1966
1967 __this_cpu_inc(irq_stat.pmu_irqs);
1968
1969 perf_irq(regs);
1970
1971 irq_exit();
1972 }
1973
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
Nicholas Piggin
reviewerPATCH v2 6/19 powerpc: add interrupt wrapper entry / exit stub functions
In reply to Nicholas PigginThese will be used by subsequent patches.
--- arch/powerpc/include/asm/interrupt.h | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
arch/powerpc/include/asm/interrupt.h +66 -0
@@ -5,6 +5,50 @@#include <linux/context_tracking.h> #include <asm/ftrace.h> +struct interrupt_state { +}; + +static inline void interrupt_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) +{ +} + +/* +* Care should be taken to note that interrupt_exit_prepare and +* interrupt_async_exit_prepare do not necessarily return immediately to +* regs context (e.g., if regs is usermode, we don't necessarily return to +* user mode). Other interrupts might be taken between here and return, +* context switch / preemption may occur in the exit path after this, or a +* signal may be delivered, etc. +* +* The real interrupt exit code is platform specific, e.g., +* interrupt_exit_user_prepare / interrupt_exit_kernel_prepare for 64s. +* +* However interrupt_nmi_exit_prepare does return directly to regs, because +* NMIs do not do "exit work" or replay soft-masked interrupts. +*/ +static inline void interrupt_exit_prepare (struct pt_regs *regs,struct interrupt_state *state) +{ +} + +static inline void interrupt_async_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) +{ +} + +static inline void interrupt_async_exit_prepare (struct pt_regs *regs,struct interrupt_state *state) +{ +} + +struct interrupt_nmi_state { +}; + +static inline void interrupt_nmi_enter_prepare (struct pt_regs *regs,struct interrupt_nmi_state *state) +{ +} + +static inline void interrupt_nmi_exit_prepare (struct pt_regs *regs,struct interrupt_nmi_state *state) +{ +} +/** * DECLARE_INTERRUPT_HANDLER_RAW - Declare raw interrupt handler function * @func: Function name of the entry point
@@ -59,7 +103,13 @@ static __always_inline void ___##func(struct pt_regs *regs); \ \ __visible noinstr void func(struct pt_regs *regs) \ { \ +struct interrupt_state state; \ + \ +interrupt_enter_prepare (regs, &state); \ + \ ___##func (regs); \ + \ + interrupt_exit_prepare(regs, &state); \ } \ \ static __always_inline void ___##func(struct pt_regs *regs)
@@ -87,10 +137,15 @@ static __always_inline long ___##func(struct pt_regs *regs); \ \ __visible noinstr long func(struct pt_regs *regs) \ { \ +struct interrupt_state state; \long ret; \ \ +interrupt_enter_prepare (regs, &state); \ + \ ret = ___##func (regs); \ \ +interrupt_exit_prepare (regs, &state); \ + \return ret; \ } \ \
@@ -117,7 +172,13 @@ static __always_inline void ___##func(struct pt_regs *regs); \ \ __visible noinstr void func(struct pt_regs *regs) \ { \ +struct interrupt_state state; \ + \ +interrupt_async_enter_prepare (regs, &state); \ + \ ___##func (regs); \ + \ + interrupt_async_exit_prepare(regs, &state); \ } \ \ static __always_inline void ___##func(struct pt_regs *regs)
@@ -145,10 +206,15 @@ static __always_inline long ___##func(struct pt_regs *regs); \ \ __visible noinstr long func(struct pt_regs *regs) \ { \ +struct interrupt_nmi_state state; \long ret; \ \ +interrupt_nmi_enter_prepare (regs, &state); \ + \ ret = ___##func (regs); \ \ +interrupt_nmi_exit_prepare (regs, &state); \ + \return ret; \ } \ \
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 7/19 powerpc: add interrupt_cond_local_irq_enable helper
In reply to Nicholas PigginSimple helper for synchronous interrupt handlers to use to enable interrupts if they were taken in interrupt-enabled context.
--- arch/powerpc/include/asm/interrupt.h | 7 +++++++ arch/powerpc/kernel/traps.c | 24 +++++++----------------- arch/powerpc/mm/fault.c | 4 +--- 3 files changed, 15 insertions(+), 20 deletions(-)
arch/powerpc/include/asm/interrupt.h +7 -0
@@ -3,6 +3,7 @@#define _ASM_POWERPC_INTERRUPT_H#include <linux/context_tracking.h> +#include <linux/hardirq.h> #include <asm/ftrace.h> struct interrupt_state {
@@ -266,4 +267,10 @@ DECLARE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception);void replay_system_reset (void );void replay_soft_interrupts (void ); +static inline void interrupt_cond_local_irq_enable (struct pt_regs *regs) +{ +if (!arch_irq_disabled_regs (regs)) +local_irq_enable (); +} +#endif /* _ASM_POWERPC_INTERRUPT_H */
arch/powerpc/kernel/traps.c +7 -17
@@ -343,8 +343,8 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,show_signal_msg (signr, regs, code, addr); -if (arch_irqs_disabled () && !arch_irq_disabled_regs (regs)) -local_irq_enable (); +if (arch_irqs_disabled ()) +interrupt_cond_local_irq_enable (regs); current->thread.trap_nr = code;
@@ -1575,9 +1575,7 @@ DEFINE_INTERRUPT_HANDLER(program_check_exception)if (!user_mode (regs)) goto sigill; -/* We restore the interrupt state now */ -if (!arch_irq_disabled_regs (regs)) -local_irq_enable (); +interrupt_cond_local_irq_enable (regs);/* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD)
@@ -1631,9 +1629,7 @@ DEFINE_INTERRUPT_HANDLER(alignment_exception)int sig, code, fixed =0 ;unsigned long reason; -/* We restore the interrupt state now */ -if (!arch_irq_disabled_regs (regs)) -local_irq_enable (); +interrupt_cond_local_irq_enable (regs); reason =get_reason (regs);
@@ -1794,9 +1790,7 @@ DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception)die ("Unexpected facility unavailable exception" , regs,SIGABRT ); } -/* We restore the interrupt state now */ -if (!arch_irq_disabled_regs (regs)) -local_irq_enable (); +interrupt_cond_local_irq_enable (regs);if (status ==FSCR_DSCR_LG ) {/*
@@ -2172,9 +2166,7 @@ void SPEFloatingPointException(struct pt_regs *regs)int code =FPE_FLTUNK ;int err; -/* We restore the interrupt state now */ -if (!arch_irq_disabled_regs (regs)) -local_irq_enable (); +interrupt_cond_local_irq_enable (regs);flush_spe_to_thread (current);
@@ -2221,9 +2213,7 @@ void SPEFloatingPointRoundException(struct pt_regs *regs)extern int speround_handler (struct pt_regs *regs);int err; -/* We restore the interrupt state now */ -if (!arch_irq_disabled_regs (regs)) -local_irq_enable (); +interrupt_cond_local_irq_enable (regs);preempt_disable ();if (regs->msr &MSR_SPE )
arch/powerpc/mm/fault.c +1 -3
@@ -443,9 +443,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,return bad_area_nosemaphore (regs, address); } -/* We restore the interrupt state now */ -if (!arch_irq_disabled_regs (regs)) -local_irq_enable (); +interrupt_cond_local_irq_enable (regs);perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS ,1 , regs, address);
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 8/19 powerpc/64: context tracking remove _TIF_NOHZ
In reply to Nicholas PigginAdd context tracking to the system call handler explicitly, and remove _TIF_NOHZ.
This saves 35 cycles on gettid system call cost on POWER9 with a CONFIG_NOHZ_FULL kernel.
--- arch/Kconfig | 6 ------ arch/powerpc/Kconfig | 1 - arch/powerpc/include/asm/thread_info.h | 4 +--- arch/powerpc/kernel/ptrace/ptrace.c | 4 ---- arch/powerpc/kernel/signal.c | 4 ---- arch/powerpc/kernel/syscall_64.c | 10 ++++++++++ 6 files changed, 11 insertions(+), 18 deletions(-)
arch/Kconfig +0 -6
@@ -618,12 +618,6 @@ config HAVE_CONTEXT_TRACKING protected inside rcu_irq_enter/rcu_irq_exit() but preemption or signal handling on irq exit still need to be protected. -config HAVE_TIF_NOHZ - bool - help - Arch relies on TIF_NOHZ and syscall slow path to implement context - tracking calls to user_enter()/user_exit(). - config HAVE_VIRT_CPU_ACCOUNTING bool
arch/powerpc/Kconfig +0 -1
@@ -193,7 +193,6 @@ config PPC select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) select HAVE_CONTEXT_TRACKING if PPC64 - select HAVE_TIF_NOHZ if PPC64 select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_STACKOVERFLOW select HAVE_DYNAMIC_FTRACE
arch/powerpc/include/asm/thread_info.h +1 -3
@@ -95,7 +95,6 @@ void arch_setup_new_exec(void);#define TIF_PATCH_PENDING 6/* pending live patching update */ #define TIF_SYSCALL_AUDIT 7/* syscall auditing active */ #define TIF_SINGLESTEP 8/* singlestepping active */ -#define TIF_NOHZ 9/* in adaptive nohz mode */ #define TIF_SECCOMP 10/* secure computing */ #define TIF_RESTOREALL 11/* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12/* Force successful syscall return */
@@ -128,11 +127,10 @@ void arch_setup_new_exec(void);#define _TIF_UPROBE (1<<TIF_UPROBE)#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)#define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE) -#define _TIF_NOHZ (1<<TIF_NOHZ)#define _TIF_SYSCALL_EMU (1<<TIF_SYSCALL_EMU)#define _TIF_SYSCALL_DOTRACE (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \ - _TIF_NOHZ | _TIF_SYSCALL_EMU) + _TIF_SYSCALL_EMU)#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
arch/powerpc/kernel/ptrace/ptrace.c +0 -4
@@ -290,8 +290,6 @@ long do_syscall_trace_enter(struct pt_regs *regs) {u32 flags; -user_exit (); - flags =READ_ONCE (current_thread_info ()->flags) & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
@@ -368,8 +366,6 @@ void do_syscall_trace_leave(struct pt_regs *regs) step =test_thread_flag (TIF_SINGLESTEP );if (step ||test_thread_flag (TIF_SYSCALL_TRACE ))tracehook_report_syscall_exit (regs, step); - -user_enter (); }void __init pt_regs_check (void );
arch/powerpc/kernel/signal.c +0 -4
@@ -310,8 +310,6 @@ static void do_signal(struct task_struct *tsk)void do_notify_resume (struct pt_regs *regs,unsigned long thread_info_flags) { -user_exit (); -if (thread_info_flags & _TIF_UPROBE)uprobe_notify_resume (regs);
@@ -327,8 +325,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)tracehook_notify_resume (regs);rseq_handle_notify_resume (NULL , regs); } - -user_enter (); }unsigned long get_tm_stackpointer (struct task_struct *tsk)
arch/powerpc/kernel/syscall_64.c +10 -0
@@ -1,9 +1,11 @@// SPDX-License-Identifier: GPL-2.0-or-later +#include <linux/context_tracking.h> #include <linux/err.h> #include <asm/asm-prototypes.h> #include <asm/book3s/64/kup-radix.h> #include <asm/cputime.h> +#include <asm/interrupt.h> #include <asm/hw_irq.h> #include <asm/interrupt.h> #include <asm/kprobes.h>
@@ -28,6 +30,9 @@ notrace long system_call_exception(long r3, long r4, long r5,if (IS_ENABLED (CONFIG_PPC_IRQ_SOFT_MASK_DEBUG ))BUG_ON (irq_soft_mask_return () !=IRQS_ALL_DISABLED ); +CT_WARN_ON (ct_state () ==CONTEXT_KERNEL ); +user_exit_irqoff (); +trace_hardirqs_off ();/* finish reconciling */ if (IS_ENABLED (CONFIG_PPC_BOOK3S ))
@@ -158,6 +163,8 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,unsigned long ti_flags;unsigned long ret =0 ; +CT_WARN_ON (ct_state () ==CONTEXT_USER ); +kuap_check_amr (); regs->result = r3;
@@ -234,8 +241,11 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3, } } +user_enter_irqoff (); +/* scv need not set RI=0 because SRRs are not used */ if (unlikely (!prep_irq_for_enabled_exit (!scv))) { +user_exit_irqoff ();local_irq_enable (); goto again; }
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 9/19 powerpc/64: context tracking move to interrupt wrappers
In reply to Nicholas PigginThis moves exception_enter/exit calls to wrapper functions for synchronous interrupts. More interrupt handlers are covered by this than previously.
--- arch/powerpc/include/asm/interrupt.h | 9 ++++ arch/powerpc/kernel/traps.c | 74 ++++++--------------------- arch/powerpc/mm/book3s64/hash_utils.c | 2 - arch/powerpc/mm/fault.c | 3 -- 4 files changed, 26 insertions(+), 62 deletions(-)
arch/powerpc/include/asm/interrupt.h +9 -0
@@ -7,10 +7,16 @@#include <asm/ftrace.h> struct interrupt_state { +#ifdef CONFIG_PPC64 +enum ctx_state ctx_state; +#endif };static inline void interrupt_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) { +#ifdef CONFIG_PPC64 + state->ctx_state =exception_enter (); +#endif }/*
@@ -29,6 +35,9 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup*/ static inline void interrupt_exit_prepare (struct pt_regs *regs,struct interrupt_state *state) { +#ifdef CONFIG_PPC64 +exception_exit (state->ctx_state); +#endif }static inline void interrupt_async_enter_prepare (struct pt_regs *regs,struct interrupt_state *state)
arch/powerpc/kernel/traps.c +17 -57
230 lines not on this page · raw message
arch/powerpc/mm/book3s64/hash_utils.c +0 -2
@@ -1289,7 +1289,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long flags) {bool is_thp; -enum ctx_state prev_state =exception_enter ();pgd_t *pgdir;unsigned long vsid;pte_t *ptep;
@@ -1489,7 +1488,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,DBG_LOW (" -> rc=%d\n" , rc); bail: -exception_exit (prev_state);return rc; }EXPORT_SYMBOL_GPL (hash_page_mm);
arch/powerpc/mm/fault.c +0 -3
@@ -550,7 +550,6 @@ NOKPROBE_SYMBOL(__do_page_fault);DEFINE_INTERRUPT_HANDLER_RET (do_page_fault) { -enum ctx_state prev_state =exception_enter ();unsigned long address = regs->dar;unsigned long error_code = regs->dsisr;long err;
@@ -573,8 +572,6 @@ DEFINE_INTERRUPT_HANDLER_RET(do_page_fault) }#endif -exception_exit (prev_state); -return err; }NOKPROBE_SYMBOL (do_page_fault);
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 10/19 powerpc/64: add context tracking to asynchronous interrupts
In reply to Nicholas PigginPreviously context tracking was not done for asynchronous interrupts, (those that run in interrupt context), and if those would cause a reschedule when they exit, then scheduling functions (schedule_user, preempt_schedule_irq) call exception_enter/exit to fix this up and exit user context.
This is a hack we would like to get away from, so do context tracking for asynchronous interrupts too.
--- arch/powerpc/include/asm/interrupt.h | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/include/asm/interrupt.h +2 -0
@@ -42,10 +42,12 @@ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interruptstatic inline void interrupt_async_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) { +interrupt_enter_prepare (regs, state); }static inline void interrupt_async_exit_prepare (struct pt_regs *regs,struct interrupt_state *state) { +interrupt_exit_prepare (regs, state); }struct interrupt_nmi_state {
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 11/19 powerpc: handle irq_enter/irq_exit in interrupt handler wrappers
In reply to Nicholas PigginMove irq_enter/irq_exit into asynchronous interrupt handler wrappers.
--- arch/powerpc/include/asm/interrupt.h | 2 ++ arch/powerpc/kernel/dbell.c | 3 +-- arch/powerpc/kernel/irq.c | 4 ---- arch/powerpc/kernel/tau_6xx.c | 3 --- arch/powerpc/kernel/time.c | 4 ++-- arch/powerpc/kernel/traps.c | 6 ------ 6 files changed, 5 insertions(+), 17 deletions(-)
arch/powerpc/include/asm/interrupt.h +2 -0
@@ -43,10 +43,12 @@ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interruptstatic inline void interrupt_async_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) {interrupt_enter_prepare (regs, state); +irq_enter (); }static inline void interrupt_async_exit_prepare (struct pt_regs *regs,struct interrupt_state *state) { +irq_exit ();interrupt_exit_prepare (regs, state); }
arch/powerpc/kernel/dbell.c +1 -2
@@ -22,7 +22,6 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)#ifdef CONFIG_SMP struct pt_regs *old_regs =set_irq_regs (regs); -irq_enter ();trace_doorbell_entry (regs);ppc_msgsync ();
@@ -35,7 +34,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)smp_ipi_demux_relaxed ();/* already performed the barrier */ trace_doorbell_exit (regs); -irq_exit (); +set_irq_regs (old_regs);#else /* CONFIG_SMP */ printk (KERN_WARNING "Received doorbell on non-smp system\n" );
arch/powerpc/kernel/irq.c +0 -4
@@ -641,8 +641,6 @@ void __do_irq(struct pt_regs *regs) {unsigned int irq; -irq_enter (); -trace_irq_entry (regs);/*
@@ -662,8 +660,6 @@ void __do_irq(struct pt_regs *regs)generic_handle_irq (irq);trace_irq_exit (regs); - -irq_exit (); }DEFINE_INTERRUPT_HANDLER_ASYNC (do_IRQ)
arch/powerpc/kernel/tau_6xx.c +0 -3
@@ -104,12 +104,9 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(TAUException) {int cpu =smp_processor_id (); -irq_enter (); tau[cpu].interrupts++;TAUupdate (cpu); - -irq_exit (); }#endif /* CONFIG_TAU_INT */
arch/powerpc/kernel/time.c +2 -2
@@ -585,7 +585,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)#endif old_regs =set_irq_regs (regs); -irq_enter (); +trace_timer_interrupt_entry (regs);if (test_irq_work_pending ()) {
@@ -610,7 +610,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) }trace_timer_interrupt_exit (regs); -irq_exit (); +set_irq_regs (old_regs); }EXPORT_SYMBOL (timer_interrupt);
arch/powerpc/kernel/traps.c +0 -6
@@ -1082,7 +1082,6 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(handle_hmi_exception)struct pt_regs *old_regs; old_regs =set_irq_regs (regs); -irq_enter ();#ifdef CONFIG_VSX /* Real mode flagged P9 special emu is needed */
@@ -1102,7 +1101,6 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(handle_hmi_exception)if (ppc_md.handle_hmi_exception) ppc_md.handle_hmi_exception (regs); -irq_exit ();set_irq_regs (old_regs); }
@@ -1916,13 +1914,9 @@ DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)DEFINE_INTERRUPT_HANDLER_ASYNC (performance_monitor_exception_async) { -irq_enter (); -__this_cpu_inc (irq_stat.pmu_irqs);perf_irq (regs); - -irq_exit (); }void performance_monitor_exception (struct pt_regs *regs)
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 12/19 powerpc/64s: move context tracking exit to interrupt exit path
In reply to Nicholas PigginThe interrupt handler wrapper functions are not the ideal place to maintain context tracking because after they return, the low level exit code must then determine if there are interrupts to replay, or if the task should be preempted, etc. Those paths (e.g., schedule_user) include their own exception_enter/exit pairs to fix this up but it's a bit hacky (see schedule_user() comments).
Ideally context tracking will go to user mode only when there are no more interrupts or context switches or other exit processing work to handle.
64e can not do this because it does not use the C interrupt exit code.
--- arch/powerpc/include/asm/interrupt.h | 34 +++++++++++++++++++++++++--- arch/powerpc/kernel/syscall_64.c | 9 ++++++++ 2 files changed, 40 insertions(+), 3 deletions(-)
arch/powerpc/include/asm/interrupt.h +31 -3
@@ -7,16 +7,30 @@#include <asm/ftrace.h> struct interrupt_state { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3E_64 enum ctx_state ctx_state;#endif };static inline void interrupt_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3E_64 state->ctx_state =exception_enter ();#endif + +#ifdef CONFIG_PPC_BOOK3S_64 +if (user_mode (regs)) { +CT_WARN_ON (ct_state () !=CONTEXT_USER ); +user_exit_irqoff (); + }else { +/* +* CT_WARN_ON comes here via program_check_exception, +* so avoid recursion. +*/ +if (TRAP (regs) !=0x700 ) +CT_WARN_ON (ct_state () !=CONTEXT_KERNEL ); + } +#endif }/*
@@ -35,9 +49,23 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup*/ static inline void interrupt_exit_prepare (struct pt_regs *regs,struct interrupt_state *state) { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3E_64 exception_exit (state->ctx_state);#endif + +/* +* Book3S exits to user via interrupt_exit_user_prepare(), which does +* context tracking, which is a cleaner way to handle PREEMPT=y +* and avoid context entry/exit in e.g., preempt_schedule_irq()), +* which is likely to be where the core code wants to end up. +* +* The above comment explains why we can't do the +* +* if (user_mode(regs)) +* user_exit_irqoff(); +* +* sequence here. +*/ }static inline void interrupt_async_enter_prepare (struct pt_regs *regs,struct interrupt_state *state)
arch/powerpc/kernel/syscall_64.c +9 -0
@@ -275,6 +275,7 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsignedBUG_ON (!(regs->msr &MSR_PR ));BUG_ON (!FULL_REGS (regs));BUG_ON (regs->softe !=IRQS_ENABLED ); +CT_WARN_ON (ct_state () ==CONTEXT_USER );/* * We don't need to restore AMR on the way back to userspace for KUAP.
@@ -317,7 +318,9 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned } } +user_enter_irqoff ();if (unlikely (!prep_irq_for_enabled_exit (true))) { +user_exit_irqoff ();local_irq_enable ();local_irq_disable (); goto again;
@@ -358,6 +361,12 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsignunrecoverable_exception (regs);BUG_ON (regs->msr &MSR_PR );BUG_ON (!FULL_REGS (regs)); +/* +* CT_WARN_ON comes here via program_check_exception, +* so avoid recursion. +*/ +if (TRAP (regs) !=0x700 ) +CT_WARN_ON (ct_state () ==CONTEXT_USER ); amr =kuap_get_and_check_amr ();
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 13/19 powerpc/64s: reconcile interrupts in C
In reply to Nicholas PigginThere is no need for this to be in asm, use the new intrrupt entry wrapper.
--- arch/powerpc/include/asm/interrupt.h | 15 +++++++++++---- arch/powerpc/kernel/exceptions-64s.S | 26 -------------------------- 2 files changed, 11 insertions(+), 30 deletions(-)
arch/powerpc/include/asm/interrupt.h +11 -4
@@ -14,11 +14,14 @@ struct interrupt_state {static inline void interrupt_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) { -#ifdef CONFIG_PPC_BOOK3E_64 - state->ctx_state =exception_enter (); -#endif - +/* +* Book3E reconciles irq soft mask in asm +*/ #ifdef CONFIG_PPC_BOOK3S_64 +if (irq_soft_mask_set_return (IRQS_ALL_DISABLED ) ==IRQS_ENABLED ) +trace_hardirqs_off (); + local_paca->irq_happened |=PACA_IRQ_HARD_DIS ; +if (user_mode (regs)) {CT_WARN_ON (ct_state () !=CONTEXT_USER );user_exit_irqoff ();
@@ -31,6 +34,10 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup CT_WARN_ON(ct_state() != CONTEXT_KERNEL); }#endif + +#ifdef CONFIG_PPC_BOOK3E_64 + state->ctx_state =exception_enter (); +#endif }/*
arch/powerpc/kernel/exceptions-64s.S +0 -26
@@ -139,7 +139,6 @@ name: #define IKVM_VIRT .L_IKVM_VIRT_\name\() /* Virt entry tests KVM */ #define ISTACK .L_ISTACK_\name\() /* Set regular kernel stack */ #define __ISTACK(name) .L_ISTACK_ ## name -#define IRECONCILE .L_IRECONCILE_\name\() /* Do RECONCILE_IRQ_STATE */ #define IKUAP .L_IKUAP_\name\() /* Do KUAP lock */ #define INT_DEFINE_BEGIN(n) \
@@ -203,9 +202,6 @@ do_define_int n .ifndef ISTACK ISTACK=1 .endif - .ifndef IRECONCILE - IRECONCILE=1 - .endif .ifndef IKUAP IKUAP=1 .endif
@@ -653,10 +649,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) .if ISTACK ACCOUNT_STOLEN_TIME .endif - - .if IRECONCILE - RECONCILE_IRQ_STATE(r10, r11) - .endif .endm /*
@@ -935,7 +927,6 @@ INT_DEFINE_BEGIN(system_reset) */ ISET_RI=0 ISTACK=0 - IRECONCILE=0 IKVM_REAL=1 INT_DEFINE_END(system_reset)
@@ -1125,7 +1116,6 @@ INT_DEFINE_BEGIN(machine_check_early) ISTACK=0 IDAR=1 IDSISR=1 - IRECONCILE=0 IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */ INT_DEFINE_END(machine_check_early)
@@ -1473,7 +1463,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) INT_DEFINE_BEGIN(data_access_slb) IVEC=0x380 IAREA=PACA_EXSLB - IRECONCILE=0 IDAR=1 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_SKIP=1
@@ -1502,7 +1491,6 @@ MMU_FTR_SECTION_ELSE li r3,-EFAULT ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault b interrupt_return
@@ -1564,7 +1552,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) INT_DEFINE_BEGIN(instruction_access_slb) IVEC=0x480 IAREA=PACA_EXSLB - IRECONCILE=0 IISIDE=1 IDAR=1 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
@@ -1593,7 +1580,6 @@ MMU_FTR_SECTION_ELSE li r3,-EFAULT ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) std r3,RESULT(r1) - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl do_bad_slb_fault b interrupt_return
@@ -1753,7 +1739,6 @@ EXC_COMMON_BEGIN(program_check_common) */ INT_DEFINE_BEGIN(fp_unavailable) IVEC=0x800 - IRECONCILE=0 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_REAL=1 #endif
@@ -1768,7 +1753,6 @@ EXC_VIRT_END(fp_unavailable, 0x4800, 0x100) EXC_COMMON_BEGIN(fp_unavailable_common) GEN_COMMON fp_unavailable bne 1f /* if from user, just load it up */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl kernel_fp_unavailable_exception 0: trap
@@ -1787,7 +1771,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM) b fast_interrupt_return #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl fp_unavailable_tm b interrupt_return
@@ -1852,7 +1835,6 @@ INT_DEFINE_BEGIN(hdecrementer) IVEC=0x980 IHSRR=1 ISTACK=0 - IRECONCILE=0 IKVM_REAL=1 IKVM_VIRT=1 INT_DEFINE_END(hdecrementer)
@@ -2226,7 +2208,6 @@ INT_DEFINE_BEGIN(hmi_exception_early) IHSRR=1 IREALMODE_COMMON=1 ISTACK=0 - IRECONCILE=0 IKUAP=0 /* We don't touch AMR here, we never go to virtual mode */ IKVM_REAL=1 INT_DEFINE_END(hmi_exception_early)
@@ -2400,7 +2381,6 @@ EXC_COMMON_BEGIN(performance_monitor_common) */ INT_DEFINE_BEGIN(altivec_unavailable) IVEC=0xf20 - IRECONCILE=0 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_REAL=1 #endif
@@ -2430,7 +2410,6 @@ BEGIN_FTR_SECTION b fast_interrupt_return #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl altivec_unavailable_tm b interrupt_return
@@ -2438,7 +2417,6 @@ BEGIN_FTR_SECTION 1: END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl altivec_unavailable_exception b interrupt_return
@@ -2454,7 +2432,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) */ INT_DEFINE_BEGIN(vsx_unavailable) IVEC=0xf40 - IRECONCILE=0 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE IKVM_REAL=1 #endif
@@ -2483,7 +2460,6 @@ BEGIN_FTR_SECTION b load_up_vsx #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 2: /* User process was in a transaction */ - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl vsx_unavailable_tm b interrupt_return
@@ -2491,7 +2467,6 @@ BEGIN_FTR_SECTION 1: END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif - RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl vsx_unavailable_exception b interrupt_return
@@ -2826,7 +2801,6 @@ EXC_VIRT_NONE(0x5800, 0x100) INT_DEFINE_BEGIN(soft_nmi) IVEC=0x900 ISTACK=0 - IRECONCILE=0 /* Soft-NMI may fire under local_irq_disable */ INT_DEFINE_END(soft_nmi) /*
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 14/19 powerpc/64: move account_stolen_time into its own function
In reply to Nicholas PigginThis will be used by interrupt entry as well.
--- arch/powerpc/include/asm/cputime.h | 15 +++++++++++++++ arch/powerpc/kernel/syscall_64.c | 10 +--------- 2 files changed, 16 insertions(+), 9 deletions(-)
arch/powerpc/include/asm/cputime.h +15 -0
@@ -87,6 +87,18 @@ static notrace inline void account_cpu_user_exit(void) acct->starttime_user = tb; } +static notrace inline void account_stolen_time(void) +{ +#ifdef CONFIG_PPC_SPLPAR +if (IS_ENABLED (CONFIG_VIRT_CPU_ACCOUNTING_NATIVE ) && +firmware_has_feature (FW_FEATURE_SPLPAR )) { +struct lppaca *lp = local_paca->lppaca_ptr; + +if (unlikely (local_paca->dtl_ridx !=be64_to_cpu (lp->dtl_idx))) +accumulate_stolen_time (); + } +#endif +}#endif /* __KERNEL__ */ #else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
@@ -96,5 +108,8 @@ static inline void account_cpu_user_entry(void)static inline void account_cpu_user_exit (void ) { } +static notrace inline void account_stolen_time(void) +{ +}#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #endif /* __POWERPC_CPUTIME_H */
arch/powerpc/kernel/syscall_64.c +1 -9
@@ -45,15 +45,7 @@ notrace long system_call_exception(long r3, long r4, long r5,account_cpu_user_entry (); -#ifdef CONFIG_PPC_SPLPAR -if (IS_ENABLED (CONFIG_VIRT_CPU_ACCOUNTING_NATIVE ) && -firmware_has_feature (FW_FEATURE_SPLPAR )) { -struct lppaca *lp = local_paca->lppaca_ptr; - -if (unlikely (local_paca->dtl_ridx !=be64_to_cpu (lp->dtl_idx))) -accumulate_stolen_time (); - } -#endif +account_stolen_time ();/* * This is not required for the syscall exit path, but makes the
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 15/19 powerpc/64: entry cpu time accounting in C
In reply to Nicholas PigginThere is no need for this to be in asm, use the new intrrupt entry wrapper.
--- arch/powerpc/include/asm/interrupt.h | 7 +++++++ arch/powerpc/include/asm/ppc_asm.h | 24 ------------------------ arch/powerpc/kernel/exceptions-64e.S | 1 - arch/powerpc/kernel/exceptions-64s.S | 5 ----- 4 files changed, 7 insertions(+), 30 deletions(-)
arch/powerpc/include/asm/interrupt.h +7 -0
@@ -4,6 +4,7 @@#include <linux/context_tracking.h> #include <linux/hardirq.h> +#include <asm/cputime.h> #include <asm/ftrace.h> struct interrupt_state {
@@ -25,6 +26,9 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupif (user_mode (regs)) {CT_WARN_ON (ct_state () !=CONTEXT_USER );user_exit_irqoff (); + +account_cpu_user_entry (); +account_stolen_time (); }else {/* * CT_WARN_ON comes here via program_check_exception,
@@ -38,6 +42,9 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup#ifdef CONFIG_PPC_BOOK3E_64 state->ctx_state =exception_enter ();#endif + +if (!IS_ENABLED (CONFIG_PPC_BOOK3S_64 ) &&user_mode (regs)) +account_cpu_user_entry (); }/*
arch/powerpc/include/asm/ppc_asm.h +0 -24
@@ -25,7 +25,6 @@#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #define ACCOUNT_CPU_USER_ENTRY (ptr, ra, rb)#define ACCOUNT_CPU_USER_EXIT (ptr, ra, rb) -#define ACCOUNT_STOLEN_TIME #else #define ACCOUNT_CPU_USER_ENTRY (ptr, ra, rb) \ MFTB(ra);/* get timebase */ \
@@ -44,29 +43,6 @@PPC_LL ra,ACCOUNT_SYSTEM_TIME (ptr ); \add ra,ra,rb;/* add on to system time */ \ PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr) - -#ifdef CONFIG_PPC_SPLPAR -#define ACCOUNT_STOLEN_TIME \ -BEGIN_FW_FTR_SECTION; \ - beq 33f; \ -/* from user - see if there are any DTL entries to process */ \ -ld r10,PACALPPACAPTR (r13 );/* get ptr to VPA */ \ -ld r11,PACA_DTL_RIDX (r13 );/* get log read index */ \ -addi r10,r10,LPPACA_DTLIDX ; \ - LDX_BE r10,0,r10; /* get log write index */ \ -cmpd cr1,r11,r10; \ - beq+ cr1,33f ; \ -bl accumulate_stolen_time; \ -ld r12,_MSR (r1 ); \ - andi. r10,r12,MSR_PR ;/* Restore cr0 (coming from user) */ \ -33: \ -END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) - -#else /* CONFIG_PPC_SPLPAR */ -#define ACCOUNT_STOLEN_TIME - -#endif /* CONFIG_PPC_SPLPAR */ -#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ /*
arch/powerpc/kernel/exceptions-64e.S +0 -1
@@ -398,7 +398,6 @@ exc_##n##_common: \ std r10,_NIP(r1); /* save SRR0 to stackframe */ \ std r11,_MSR(r1); /* save SRR1 to stackframe */ \ beq 2f; /* if from kernel mode */ \ - ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \ 2: ld r3,excf+EX_R10(r13); /* get back r10 */ \ ld r4,excf+EX_R11(r13); /* get back r11 */ \ mfspr r5,scratch; /* get back r13 */ \
arch/powerpc/kernel/exceptions-64s.S +0 -5
@@ -577,7 +577,6 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real) kuap_save_amr_and_lock r9, r10, cr1, cr0 .endif beq 101f /* if from kernel mode */ - ACCOUNT_CPU_USER_ENTRY(r13, r9, r10) BEGIN_FTR_SECTION ld r9,IAREA+EX_PPR(r13) /* Read PPR from paca */ std r9,_PPR(r1)
@@ -645,10 +644,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) ld r11,exception_marker@toc(r2) std r10,RESULT(r1) /* clear regs->result */ std r11,STACK_FRAME_OVERHEAD-16(r1) /* mark the frame */ - - .if ISTACK - ACCOUNT_STOLEN_TIME - .endif .endm /*
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 16/19 powerpc: move NMI entry/exit code into wrapper
In reply to Nicholas PigginThis moves the common NMI entry and exit code into the interrupt handler wrappers.
This changes the behaviour of soft-NMI (watchdog) and HMI interrupts, and also MCE interrupts on 64e, by adding missing parts of the NMI entry to them. It fixes a bug with sreset on pseries HPT guests which shouldn't call nmi_enter().
--- arch/powerpc/include/asm/interrupt.h | 24 ++++++++++++++++ arch/powerpc/kernel/mce.c | 11 -------- arch/powerpc/kernel/traps.c | 42 +++++----------------------- arch/powerpc/kernel/watchdog.c | 10 +++---- 4 files changed, 35 insertions(+), 52 deletions(-)
arch/powerpc/include/asm/interrupt.h +24 -0
@@ -95,14 +95,38 @@ static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct int }struct interrupt_nmi_state { +#ifdef CONFIG_PPC64 +u8 ftrace_enabled; +#endif };static inline void interrupt_nmi_enter_prepare (struct pt_regs *regs,struct interrupt_nmi_state *state) { +#ifdef CONFIG_PPC64 + state->ftrace_enabled =this_cpu_get_ftrace_enabled (); +this_cpu_set_ftrace_enabled (0 ); +#endif + +/* +* Do not use nmi_enter() for pseries hash guest taking a real-mode +* NMI because not everything it touches is within the RMA limit. +*/ +if (!IS_ENABLED (CONFIG_PPC_BOOK3S_64 ) || + !firmware_has_feature (FW_FEATURE_LPAR ) || +radix_enabled () || (mfmsr () &MSR_DR )) +nmi_enter (); }static inline void interrupt_nmi_exit_prepare (struct pt_regs *regs,struct interrupt_nmi_state *state) { +if (!IS_ENABLED (CONFIG_PPC_BOOK3S_64 ) || + !firmware_has_feature (FW_FEATURE_LPAR ) || +radix_enabled () || (mfmsr () &MSR_DR )) +nmi_exit (); + +#ifdef CONFIG_PPC64 +this_cpu_set_ftrace_enabled (state->ftrace_enabled); +#endif }/**
arch/powerpc/kernel/mce.c +0 -11
@@ -592,12 +592,6 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info);DEFINE_INTERRUPT_HANDLER_NMI (machine_check_early) {long handled =0 ; -u8 ftrace_enabled =this_cpu_get_ftrace_enabled (); - -this_cpu_set_ftrace_enabled (0 ); -/* Do not use nmi_enter/exit for pseries hpte guest */ -if (radix_enabled () || !firmware_has_feature (FW_FEATURE_LPAR )) -nmi_enter ();hv_nmi_check_nonrecoverable (regs);
@@ -607,11 +601,6 @@ DEFINE_INTERRUPT_HANDLER_NMI(machine_check_early)if (ppc_md.machine_check_early) handled = ppc_md.machine_check_early (regs); -if (radix_enabled () || !firmware_has_feature (FW_FEATURE_LPAR )) -nmi_exit (); - -this_cpu_set_ftrace_enabled (ftrace_enabled); -return handled; }
arch/powerpc/kernel/traps.c +7 -35
92 lines not on this page · raw message
arch/powerpc/kernel/watchdog.c +4 -6
@@ -254,11 +254,12 @@ DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt)int cpu =raw_smp_processor_id ();u64 tb; +/* should only arrive from kernel, with irqs disabled */ +WARN_ON_ONCE (!arch_irq_disabled_regs (regs)); +if (!cpumask_test_cpu (cpu, &wd_cpus_enabled))return 0 ; -nmi_enter (); -__this_cpu_inc (irq_stat.soft_nmi_irqs); tb =get_tb ();
@@ -266,7 +267,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt)wd_smp_lock (&flags);if (cpumask_test_cpu (cpu, &wd_smp_cpus_stuck)) {wd_smp_unlock (&flags); - goto out; +return 0 ; }set_cpu_stuck (cpu, tb);
@@ -290,9 +291,6 @@ DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt)if (wd_panic_timeout_tb <0x7fffffff )mtspr (SPRN_DEC , wd_panic_timeout_tb); -out: -nmi_exit (); -return 0 ; }
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 17/19 powerpc/64s: move NMI soft-mask handling to C
In reply to Nicholas PigginSaving and restoring soft-mask state can now be done in C using the interrupt handler wrapper functions.
--- arch/powerpc/include/asm/interrupt.h | 26 ++++++++++++ arch/powerpc/kernel/exceptions-64s.S | 60 ---------------------------- 2 files changed, 26 insertions(+), 60 deletions(-)
arch/powerpc/include/asm/interrupt.h +26 -0
@@ -96,6 +96,10 @@ static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct intstruct interrupt_nmi_state {#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S_64 +u8 irq_soft_mask; +u8 irq_happened; +#endif u8 ftrace_enabled;#endif };
@@ -103,6 +107,21 @@ struct interrupt_nmi_state {static inline void interrupt_nmi_enter_prepare (struct pt_regs *regs,struct interrupt_nmi_state *state) {#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3S_64 + state->irq_soft_mask = local_paca->irq_soft_mask; + state->irq_happened = local_paca->irq_happened; + +/* +* Set IRQS_ALL_DISABLED unconditionally so irqs_disabled() does +* the right thing, and set IRQ_HARD_DIS. We do not want to reconcile +* because that goes through irq tracing which we don't want in NMI. +*/ + local_paca->irq_soft_mask =IRQS_ALL_DISABLED ; + local_paca->irq_happened |=PACA_IRQ_HARD_DIS ; + +/* Don't do any per-CPU operations until interrupt state is fixed */ + state->ftrace_enabled =this_cpu_get_ftrace_enabled (); +#endif state->ftrace_enabled =this_cpu_get_ftrace_enabled ();this_cpu_set_ftrace_enabled (0 );#endif
@@ -126,6 +145,13 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter#ifdef CONFIG_PPC64 this_cpu_set_ftrace_enabled (state->ftrace_enabled); + +#ifdef CONFIG_PPC_BOOK3S_64 +/* Check we didn't change the pending interrupt mask. */ +WARN_ON_ONCE ((state->irq_happened |PACA_IRQ_HARD_DIS ) != local_paca->irq_happened); + local_paca->irq_happened = state->irq_happened; + local_paca->irq_soft_mask = state->irq_soft_mask; +#endif #endif }
arch/powerpc/kernel/exceptions-64s.S +0 -60
95 lines not on this page · raw message
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 18/19 powerpc/64s: runlatch interrupt handling in C
In reply to Nicholas PigginThere is no need for this to be in asm, use the new intrrupt entry wrapper.
--- arch/powerpc/include/asm/interrupt.h | 7 +++++++ arch/powerpc/kernel/exceptions-64s.S | 18 ------------------ 2 files changed, 7 insertions(+), 18 deletions(-)
arch/powerpc/include/asm/interrupt.h +7 -0
@@ -6,6 +6,7 @@#include <linux/hardirq.h> #include <asm/cputime.h> #include <asm/ftrace.h> +#include <asm/runlatch.h> struct interrupt_state {#ifdef CONFIG_PPC_BOOK3E_64
@@ -84,6 +85,12 @@ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interruptstatic inline void interrupt_async_enter_prepare (struct pt_regs *regs,struct interrupt_state *state) { +#ifdef CONFIG_PPC_BOOK3S_64 +if (cpu_has_feature (CPU_FTR_CTRL ) && + !test_thread_local_flags (_TLF_RUNLATCH)) +__ppc64_runlatch_on (); +#endif +interrupt_enter_prepare (regs, state);irq_enter (); }
arch/powerpc/kernel/exceptions-64s.S +0 -18
@@ -692,14 +692,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) ld r1,GPR1(r1) .endm -#define RUNLATCH_ON \ -BEGIN_FTR_SECTION \ - ld r3, PACA_THREAD_INFO(r13); \ - ld r4,TI_LOCAL_FLAGS(r3); \ - andi. r0,r4,_TLF_RUNLATCH; \ - beql ppc64_runlatch_on_trampoline; \ -END_FTR_SECTION_IFSET(CPU_FTR_CTRL) - /* * When the idle code in power4_idle puts the CPU into NAP mode, * it has to do so in a loop, and relies on the external interrupt
@@ -1581,7 +1573,6 @@ EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) EXC_COMMON_BEGIN(hardware_interrupt_common) GEN_COMMON hardware_interrupt FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl do_IRQ b interrupt_return
@@ -1767,7 +1758,6 @@ EXC_VIRT_END(decrementer, 0x4900, 0x80) EXC_COMMON_BEGIN(decrementer_common) GEN_COMMON decrementer FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl timer_interrupt b interrupt_return
@@ -1853,7 +1843,6 @@ EXC_VIRT_END(doorbell_super, 0x4a00, 0x100) EXC_COMMON_BEGIN(doorbell_super_common) GEN_COMMON doorbell_super FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_DOORBELL bl doorbell_exception
@@ -2208,7 +2197,6 @@ EXC_COMMON_BEGIN(hmi_exception_early_common) EXC_COMMON_BEGIN(hmi_exception_common) GEN_COMMON hmi_exception FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl handle_hmi_exception b interrupt_return
@@ -2238,7 +2226,6 @@ EXC_VIRT_END(h_doorbell, 0x4e80, 0x20) EXC_COMMON_BEGIN(h_doorbell_common) GEN_COMMON h_doorbell FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD #ifdef CONFIG_PPC_DOORBELL bl doorbell_exception
@@ -2272,7 +2259,6 @@ EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20) EXC_COMMON_BEGIN(h_virt_irq_common) GEN_COMMON h_virt_irq FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl do_IRQ b interrupt_return
@@ -2319,7 +2305,6 @@ EXC_VIRT_END(performance_monitor, 0x4f00, 0x20) EXC_COMMON_BEGIN(performance_monitor_common) GEN_COMMON performance_monitor FINISH_NAP - RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl performance_monitor_exception b interrupt_return
@@ -3030,9 +3015,6 @@ kvmppc_skip_Hinterrupt: * come here. */ -EXC_COMMON_BEGIN(ppc64_runlatch_on_trampoline) - b __ppc64_runlatch_on - USE_FIXED_SECTION(virt_trampolines) /* * All code below __end_interrupts is treated as soft-masked. If
Signature · 1 line
2.23.0
Nicholas Piggin
reviewerPATCH v2 19/19 powerpc/64s: power4 nap fixup in C
In reply to Nicholas PigginThere is no need for this to be in asm, use the new intrrupt entry wrapper.
--- arch/powerpc/include/asm/interrupt.h | 15 +++++++++ arch/powerpc/include/asm/processor.h | 1 + arch/powerpc/include/asm/thread_info.h | 6 ++++ arch/powerpc/kernel/exceptions-64s.S | 45 -------------------------- arch/powerpc/kernel/idle_book3s.S | 4 +++ 5 files changed, 26 insertions(+), 45 deletions(-)
arch/powerpc/include/asm/interrupt.h +15 -0
@@ -8,6 +8,16 @@#include <asm/ftrace.h> #include <asm/runlatch.h> +static inline void nap_adjust_return (struct pt_regs *regs) +{ +#ifdef CONFIG_PPC_970_NAP +if (unlikely (test_thread_local_flags (_TLF_NAPPING))) { +clear_thread_local_flags (_TLF_NAPPING); + regs->nip = (unsigned long )power4_idle_nap_return; + } +#endif +} +struct interrupt_state {#ifdef CONFIG_PPC_BOOK3E_64 enum ctx_state ctx_state;
@@ -99,6 +109,9 @@ static inline void interrupt_async_exit_prepare(struct pt_regs *regs, struct int {irq_exit ();interrupt_exit_prepare (regs, state); + +/* Adjust at exit so the main handler sees the true NIA */ +nap_adjust_return (regs); }struct interrupt_nmi_state {
@@ -150,6 +163,8 @@ static inline void interrupt_nmi_exit_prepare(struct pt_regs *regs, struct inter radix_enabled() || (mfmsr() & MSR_DR))nmi_exit (); +nap_adjust_return (regs); +#ifdef CONFIG_PPC64 this_cpu_set_ftrace_enabled (state->ftrace_enabled);
arch/powerpc/include/asm/processor.h +1 -0
@@ -418,6 +418,7 @@ extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val);extern unsigned long isa206_idle_insn_mayloss (unsigned long type);#ifdef CONFIG_PPC_970_NAP extern void power4_idle_nap (void ); +void power4_idle_nap_return (void );#endif extern unsigned long cpuidle_disable;
arch/powerpc/include/asm/thread_info.h +6 -0
@@ -151,6 +151,12 @@ void arch_setup_new_exec(void);#ifndef __ASSEMBLY__ +static inline void clear_thread_local_flags (unsigned int flags) +{ +struct thread_info *ti =current_thread_info (); + ti->local_flags &= ~flags; +} +static inline bool test_thread_local_flags (unsigned int flags) {struct thread_info *ti =current_thread_info ();
arch/powerpc/kernel/exceptions-64s.S +0 -45
105 lines not on this page · raw message
arch/powerpc/kernel/idle_book3s.S +4 -0
@@ -201,4 +201,8 @@ _GLOBAL(power4_idle_nap) mtmsrd r7 isync b 1b + + .globl power4_idle_nap_return +power4_idle_nap_return: + blr #endif
Signature · 1 line
2.23.0