mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	powerpc: convert interrupt handlers to use wrappers
Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210130130852.2952424-29-npiggin@gmail.com
This commit is contained in:
		
							parent
							
								
									fd3f1e0f13
								
							
						
					
					
						commit
						3a96570ffc
					
				
					 24 changed files with 170 additions and 102 deletions
				
			
		|  | @ -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, | ||||
|  |  | |||
|  | @ -456,7 +456,6 @@ static inline unsigned long hpt_hash(unsigned long vpn, | |||
| 
 | ||||
| long hpte_insert_repeating(unsigned long hash, unsigned long vpn, unsigned long pa, | ||||
| 			   unsigned long rlags, unsigned long vflags, int psize, int ssize); | ||||
| 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); | ||||
|  |  | |||
|  | @ -50,9 +50,6 @@ bool ppc_breakpoint_available(void); | |||
| #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||||
| extern void do_send_trap(struct pt_regs *regs, unsigned long address, | ||||
| 			 unsigned long error_code, int brkpt); | ||||
| #else | ||||
| 
 | ||||
| void do_break(struct pt_regs *regs); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _ASM_POWERPC_DEBUG_H */ | ||||
|  |  | |||
|  | @ -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 performance_monitor_exception(struct pt_regs *regs); | ||||
| extern void WatchdogException(struct pt_regs *regs); | ||||
| extern void unknown_exception(struct pt_regs *regs); | ||||
| void unknown_async_exception(struct pt_regs *regs); | ||||
| 
 | ||||
| #ifdef CONFIG_PPC64 | ||||
| #include <asm/paca.h> | ||||
| 
 | ||||
|  |  | |||
|  | @ -232,4 +232,70 @@ __visible noinstr long func(struct pt_regs *regs)			\ | |||
| 									\ | ||||
| static __always_inline long ____##func(struct pt_regs *regs) | ||||
| 
 | ||||
| 
 | ||||
| /* Interrupt handlers */ | ||||
| /* kernel/traps.c */ | ||||
| DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception); | ||||
| #ifdef CONFIG_PPC_BOOK3S_64 | ||||
| DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception); | ||||
| #else | ||||
| DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); | ||||
| #endif | ||||
| DECLARE_INTERRUPT_HANDLER(SMIException); | ||||
| DECLARE_INTERRUPT_HANDLER(handle_hmi_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(unknown_exception); | ||||
| DECLARE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(instruction_breakpoint_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(RunModeException); | ||||
| DECLARE_INTERRUPT_HANDLER(single_step_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(program_check_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(emulation_assist_interrupt); | ||||
| DECLARE_INTERRUPT_HANDLER(alignment_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(StackOverflow); | ||||
| DECLARE_INTERRUPT_HANDLER(stack_overflow_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(altivec_unavailable_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(vsx_unavailable_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(facility_unavailable_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(fp_unavailable_tm); | ||||
| DECLARE_INTERRUPT_HANDLER(altivec_unavailable_tm); | ||||
| DECLARE_INTERRUPT_HANDLER(vsx_unavailable_tm); | ||||
| DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi); | ||||
| DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async); | ||||
| DECLARE_INTERRUPT_HANDLER_RAW(performance_monitor_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(DebugException); | ||||
| DECLARE_INTERRUPT_HANDLER(altivec_assist_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(CacheLockingException); | ||||
| DECLARE_INTERRUPT_HANDLER(SPEFloatingPointException); | ||||
| DECLARE_INTERRUPT_HANDLER(SPEFloatingPointRoundException); | ||||
| DECLARE_INTERRUPT_HANDLER(unrecoverable_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(WatchdogException); | ||||
| DECLARE_INTERRUPT_HANDLER(kernel_bad_stack); | ||||
| 
 | ||||
| /* slb.c */ | ||||
| DECLARE_INTERRUPT_HANDLER_RAW(do_slb_fault); | ||||
| DECLARE_INTERRUPT_HANDLER(do_bad_slb_fault); | ||||
| 
 | ||||
| /* hash_utils.c */ | ||||
| DECLARE_INTERRUPT_HANDLER_RAW(do_hash_fault); | ||||
| 
 | ||||
| /* fault.c */ | ||||
| DECLARE_INTERRUPT_HANDLER_RET(do_page_fault); | ||||
| DECLARE_INTERRUPT_HANDLER(do_bad_page_fault_segv); | ||||
| 
 | ||||
| /* process.c */ | ||||
| DECLARE_INTERRUPT_HANDLER(do_break); | ||||
| 
 | ||||
| /* time.c */ | ||||
| DECLARE_INTERRUPT_HANDLER_ASYNC(timer_interrupt); | ||||
| 
 | ||||
| /* mce.c */ | ||||
| DECLARE_INTERRUPT_HANDLER_NMI(machine_check_early); | ||||
| DECLARE_INTERRUPT_HANDLER_NMI(hmi_exception_realmode); | ||||
| 
 | ||||
| DECLARE_INTERRUPT_HANDLER_ASYNC(TAUException); | ||||
| 
 | ||||
| void replay_system_reset(void); | ||||
| void replay_soft_interrupts(void); | ||||
| 
 | ||||
| #endif /* _ASM_POWERPC_INTERRUPT_H */ | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 
 | ||||
| #ifdef CONFIG_PPC_WATCHDOG | ||||
| extern void arch_touch_nmi_watchdog(void); | ||||
| void soft_nmi_interrupt(struct pt_regs *regs); | ||||
| long soft_nmi_interrupt(struct pt_regs *regs); | ||||
| #else | ||||
| static inline void arch_touch_nmi_watchdog(void) {} | ||||
| #endif | ||||
|  |  | |||
|  | @ -12,13 +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) | ||||
| { | ||||
| 	struct pt_regs *old_regs = set_irq_regs(regs); | ||||
| 
 | ||||
|  | @ -39,9 +40,8 @@ void doorbell_exception(struct pt_regs *regs) | |||
| 	set_irq_regs(old_regs); | ||||
| } | ||||
| #else /* CONFIG_SMP */ | ||||
| void doorbell_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception) | ||||
| { | ||||
| 	printk(KERN_WARNING "Received doorbell on non-smp system\n"); | ||||
| } | ||||
| #endif /* CONFIG_SMP */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| #include <linux/ftrace.h> | ||||
| #include <linux/memblock.h> | ||||
| 
 | ||||
| #include <asm/interrupt.h> | ||||
| #include <asm/machdep.h> | ||||
| #include <asm/mce.h> | ||||
| #include <asm/nmi.h> | ||||
|  | @ -583,7 +584,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(); | ||||
|  | @ -717,7 +718,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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ | |||
| #include <linux/pkeys.h> | ||||
| #include <linux/seq_buf.h> | ||||
| 
 | ||||
| #include <asm/interrupt.h> | ||||
| #include <asm/io.h> | ||||
| #include <asm/processor.h> | ||||
| #include <asm/mmu.h> | ||||
|  | @ -659,7 +660,7 @@ static void do_break_handler(struct pt_regs *regs) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void do_break(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(do_break) | ||||
| { | ||||
| 	current->thread.trap_nr = TRAP_HWBKPT; | ||||
| 	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, regs->dsisr, | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <asm/kup.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> | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ | |||
| #include <linux/delay.h> | ||||
| #include <linux/workqueue.h> | ||||
| 
 | ||||
| #include <asm/interrupt.h> | ||||
| #include <asm/io.h> | ||||
| #include <asm/reg.h> | ||||
| #include <asm/nvram.h> | ||||
|  | @ -100,7 +101,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(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -57,6 +57,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> | ||||
|  | @ -571,7 +572,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); | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ | |||
| #include <asm/emulated_ops.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <asm/debugfs.h> | ||||
| #include <asm/interrupt.h> | ||||
| #include <asm/io.h> | ||||
| #include <asm/machdep.h> | ||||
| #include <asm/rtas.h> | ||||
|  | @ -430,8 +431,7 @@ void hv_nmi_check_nonrecoverable(struct pt_regs *regs) | |||
| 	regs->msr &= ~MSR_RI; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void system_reset_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception) | ||||
| { | ||||
| 	unsigned long hsrr0, hsrr1; | ||||
| 	bool saved_hsrrs = false; | ||||
|  | @ -519,6 +519,8 @@ void system_reset_exception(struct pt_regs *regs) | |||
| 	this_cpu_set_ftrace_enabled(ftrace_enabled); | ||||
| 
 | ||||
| 	/* What should we do here? We could issue a shutdown or hard reset. */ | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| NOKPROBE_SYMBOL(system_reset_exception); | ||||
| 
 | ||||
|  | @ -805,7 +807,11 @@ void die_mce(const char *str, struct pt_regs *regs, long err) | |||
| } | ||||
| NOKPROBE_SYMBOL(die_mce); | ||||
| 
 | ||||
| void machine_check_exception(struct pt_regs *regs) | ||||
| #ifdef CONFIG_PPC_BOOK3S_64 | ||||
| DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception) | ||||
| #else | ||||
| DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception) | ||||
| #endif | ||||
| { | ||||
| 	int recover = 0; | ||||
| 
 | ||||
|  | @ -855,10 +861,16 @@ void machine_check_exception(struct pt_regs *regs) | |||
| 		die_mce("Unrecoverable Machine check", regs, SIGBUS); | ||||
| 
 | ||||
| 	if (nmi) nmi_exit(); | ||||
| 
 | ||||
| #ifdef CONFIG_PPC_BOOK3S_64 | ||||
| 	return; | ||||
| #else | ||||
| 	return 0; | ||||
| #endif | ||||
| } | ||||
| NOKPROBE_SYMBOL(machine_check_exception); | ||||
| 
 | ||||
| void SMIException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */ | ||||
| { | ||||
| 	die("System Management Interrupt", regs, SIGABRT); | ||||
| } | ||||
|  | @ -1044,7 +1056,7 @@ static void p9_hmi_special_emu(struct pt_regs *regs) | |||
| } | ||||
| #endif /* CONFIG_VSX */ | ||||
| 
 | ||||
| void handle_hmi_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER_ASYNC(handle_hmi_exception) | ||||
| { | ||||
| 	struct pt_regs *old_regs; | ||||
| 
 | ||||
|  | @ -1073,7 +1085,7 @@ void handle_hmi_exception(struct pt_regs *regs) | |||
| 	set_irq_regs(old_regs); | ||||
| } | ||||
| 
 | ||||
| void unknown_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(unknown_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1085,7 +1097,7 @@ void unknown_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void unknown_async_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER_ASYNC(unknown_async_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1097,7 +1109,7 @@ void unknown_async_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void instruction_breakpoint_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(instruction_breakpoint_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1112,12 +1124,12 @@ void instruction_breakpoint_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void RunModeException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(RunModeException) | ||||
| { | ||||
| 	_exception(SIGTRAP, regs, TRAP_UNK, 0); | ||||
| } | ||||
| 
 | ||||
| void single_step_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(single_step_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1579,7 +1591,7 @@ static void do_program_check(struct pt_regs *regs) | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| void program_check_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(program_check_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1593,7 +1605,7 @@ NOKPROBE_SYMBOL(program_check_exception); | |||
|  * This occurs when running in hypervisor mode on POWER6 or later | ||||
|  * and an illegal instruction is encountered. | ||||
|  */ | ||||
| void emulation_assist_interrupt(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(emulation_assist_interrupt) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1604,7 +1616,7 @@ void emulation_assist_interrupt(struct pt_regs *regs) | |||
| } | ||||
| NOKPROBE_SYMBOL(emulation_assist_interrupt); | ||||
| 
 | ||||
| void alignment_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(alignment_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 	int sig, code, fixed = 0; | ||||
|  | @ -1654,7 +1666,7 @@ void alignment_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void StackOverflow(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(StackOverflow) | ||||
| { | ||||
| 	pr_crit("Kernel stack overflow in process %s[%d], r1=%lx\n", | ||||
| 		current->comm, task_pid_nr(current), regs->gpr[1]); | ||||
|  | @ -1663,7 +1675,7 @@ void StackOverflow(struct pt_regs *regs) | |||
| 	panic("kernel stack overflow"); | ||||
| } | ||||
| 
 | ||||
| void stack_overflow_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(stack_overflow_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1672,7 +1684,7 @@ void stack_overflow_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void kernel_fp_unavailable_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(kernel_fp_unavailable_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1683,7 +1695,7 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void altivec_unavailable_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(altivec_unavailable_exception) | ||||
| { | ||||
| 	enum ctx_state prev_state = exception_enter(); | ||||
| 
 | ||||
|  | @ -1702,7 +1714,7 @@ void altivec_unavailable_exception(struct pt_regs *regs) | |||
| 	exception_exit(prev_state); | ||||
| } | ||||
| 
 | ||||
| void vsx_unavailable_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(vsx_unavailable_exception) | ||||
| { | ||||
| 	if (user_mode(regs)) { | ||||
| 		/* A user program has executed an vsx instruction,
 | ||||
|  | @ -1733,7 +1745,7 @@ static void tm_unavailable(struct pt_regs *regs) | |||
| 	die("Unrecoverable TM Unavailable Exception", regs, SIGABRT); | ||||
| } | ||||
| 
 | ||||
| void facility_unavailable_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception) | ||||
| { | ||||
| 	static char *facility_strings[] = { | ||||
| 		[FSCR_FP_LG] = "FPU", | ||||
|  | @ -1853,7 +1865,7 @@ void facility_unavailable_exception(struct pt_regs *regs) | |||
| 
 | ||||
| #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||||
| 
 | ||||
| void fp_unavailable_tm(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(fp_unavailable_tm) | ||||
| { | ||||
| 	/* Note:  This does not handle any kind of FP laziness. */ | ||||
| 
 | ||||
|  | @ -1886,7 +1898,7 @@ void fp_unavailable_tm(struct pt_regs *regs) | |||
| 	tm_recheckpoint(¤t->thread); | ||||
| } | ||||
| 
 | ||||
| void altivec_unavailable_tm(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(altivec_unavailable_tm) | ||||
| { | ||||
| 	/* See the comments in fp_unavailable_tm().  This function operates
 | ||||
| 	 * the same way. | ||||
|  | @ -1901,7 +1913,7 @@ void altivec_unavailable_tm(struct pt_regs *regs) | |||
| 	current->thread.used_vr = 1; | ||||
| } | ||||
| 
 | ||||
| void vsx_unavailable_tm(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm) | ||||
| { | ||||
| 	/* See the comments in fp_unavailable_tm().  This works similarly,
 | ||||
| 	 * though we're loading both FP and VEC registers in here. | ||||
|  | @ -1926,7 +1938,9 @@ void vsx_unavailable_tm(struct pt_regs *regs) | |||
| } | ||||
| #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ | ||||
| 
 | ||||
| static void performance_monitor_exception_nmi(struct pt_regs *regs) | ||||
| #ifdef CONFIG_PPC64 | ||||
| DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi); | ||||
| DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi) | ||||
| { | ||||
| 	nmi_enter(); | ||||
| 
 | ||||
|  | @ -1935,9 +1949,13 @@ static void performance_monitor_exception_nmi(struct pt_regs *regs) | |||
| 	perf_irq(regs); | ||||
| 
 | ||||
| 	nmi_exit(); | ||||
| } | ||||
| 
 | ||||
| static void performance_monitor_exception_async(struct pt_regs *regs) | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async); | ||||
| DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async) | ||||
| { | ||||
| 	irq_enter(); | ||||
| 
 | ||||
|  | @ -1948,7 +1966,7 @@ static void performance_monitor_exception_async(struct pt_regs *regs) | |||
| 	irq_exit(); | ||||
| } | ||||
| 
 | ||||
| void performance_monitor_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER_RAW(performance_monitor_exception) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * On 64-bit, if perf interrupts hit in a local_irq_disable | ||||
|  | @ -1960,6 +1978,8 @@ void performance_monitor_exception(struct pt_regs *regs) | |||
| 		performance_monitor_exception_nmi(regs); | ||||
| 	else | ||||
| 		performance_monitor_exception_async(regs); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_PPC_ADV_DEBUG_REGS | ||||
|  | @ -2022,7 +2042,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) | |||
| 		mtspr(SPRN_DBCR0, current->thread.debug.dbcr0); | ||||
| } | ||||
| 
 | ||||
| void DebugException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(DebugException) | ||||
| { | ||||
| 	unsigned long debug_status = regs->dsisr; | ||||
| 
 | ||||
|  | @ -2095,7 +2115,7 @@ NOKPROBE_SYMBOL(DebugException); | |||
| #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | ||||
| 
 | ||||
| #ifdef CONFIG_ALTIVEC | ||||
| void altivec_assist_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(altivec_assist_exception) | ||||
| { | ||||
| 	int err; | ||||
| 
 | ||||
|  | @ -2129,7 +2149,7 @@ void altivec_assist_exception(struct pt_regs *regs) | |||
| #endif /* CONFIG_ALTIVEC */ | ||||
| 
 | ||||
| #ifdef CONFIG_FSL_BOOKE | ||||
| void CacheLockingException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(CacheLockingException) | ||||
| { | ||||
| 	unsigned long error_code = regs->dsisr; | ||||
| 
 | ||||
|  | @ -2144,7 +2164,7 @@ void CacheLockingException(struct pt_regs *regs) | |||
| #endif /* CONFIG_FSL_BOOKE */ | ||||
| 
 | ||||
| #ifdef CONFIG_SPE | ||||
| void SPEFloatingPointException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(SPEFloatingPointException) | ||||
| { | ||||
| 	extern int do_spe_mathemu(struct pt_regs *regs); | ||||
| 	unsigned long spefscr; | ||||
|  | @ -2196,7 +2216,7 @@ void SPEFloatingPointException(struct pt_regs *regs) | |||
| 	return; | ||||
| } | ||||
| 
 | ||||
| void SPEFloatingPointRoundException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(SPEFloatingPointRoundException) | ||||
| { | ||||
| 	extern int speround_handler(struct pt_regs *regs); | ||||
| 	int err; | ||||
|  | @ -2238,7 +2258,7 @@ void SPEFloatingPointRoundException(struct pt_regs *regs) | |||
|  * in the MSR is 0.  This indicates that SRR0/1 are live, and that | ||||
|  * we therefore lost state by taking this exception. | ||||
|  */ | ||||
| void unrecoverable_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(unrecoverable_exception) | ||||
| { | ||||
| 	pr_emerg("Unrecoverable exception %lx at %lx (msr=%lx)\n", | ||||
| 		 regs->trap, regs->nip, regs->msr); | ||||
|  | @ -2258,7 +2278,7 @@ void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs) | |||
| 	return; | ||||
| } | ||||
| 
 | ||||
| void WatchdogException(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(WatchdogException) /* XXX NMI? async? */ | ||||
| { | ||||
| 	printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n"); | ||||
| 	WatchdogHandler(regs); | ||||
|  | @ -2269,7 +2289,7 @@ void WatchdogException(struct pt_regs *regs) | |||
|  * We enter here if we discover during exception entry that we are | ||||
|  * running in supervisor mode with a userspace value in the stack pointer. | ||||
|  */ | ||||
| void kernel_bad_stack(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(kernel_bad_stack) | ||||
| { | ||||
| 	printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n", | ||||
| 	       regs->gpr[1], regs->nip); | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| #include <linux/delay.h> | ||||
| #include <linux/smp.h> | ||||
| 
 | ||||
| #include <asm/interrupt.h> | ||||
| #include <asm/paca.h> | ||||
| #include <asm/nmi.h> | ||||
| 
 | ||||
|  | @ -248,14 +249,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(); | ||||
| 
 | ||||
|  | @ -292,6 +293,8 @@ void soft_nmi_interrupt(struct pt_regs *regs) | |||
| 
 | ||||
| out: | ||||
| 	nmi_exit(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| 
 | ||||
| #include <asm/cputable.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <asm/interrupt.h> | ||||
| #include <asm/kvm_ppc.h> | ||||
| #include <asm/cacheflush.h> | ||||
| #include <asm/dbell.h> | ||||
|  |  | |||
|  | @ -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> | ||||
|  | @ -1512,7 +1513,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap, | |||
| } | ||||
| EXPORT_SYMBOL_GPL(hash_page); | ||||
| 
 | ||||
| static long __do_hash_fault(struct pt_regs *regs) | ||||
| DECLARE_INTERRUPT_HANDLER_RET(__do_hash_fault); | ||||
| DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) | ||||
| { | ||||
| 	unsigned long ea = regs->dar; | ||||
| 	unsigned long dsisr = regs->dsisr; | ||||
|  | @ -1565,7 +1567,11 @@ static long __do_hash_fault(struct pt_regs *regs) | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| long do_hash_fault(struct pt_regs *regs) | ||||
| /*
 | ||||
|  * The _RAW interrupt entry checks for the in_nmi() case before | ||||
|  * running the full handler. | ||||
|  */ | ||||
| DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault) | ||||
| { | ||||
| 	unsigned long dsisr = regs->dsisr; | ||||
| 	long err; | ||||
|  | @ -1587,7 +1593,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, SIGSEGV); | ||||
| 		do_bad_page_fault_segv(regs); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -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> | ||||
|  | @ -813,7 +814,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); | ||||
|  | @ -833,7 +834,7 @@ long do_slb_fault(struct pt_regs *regs) | |||
| 	 */ | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The interrupt state is not reconciled, for performance, so that | ||||
| 	 * This is a raw interrupt handler, for performance, so that | ||||
| 	 * fast_interrupt_return can be used. The handler must not touch local | ||||
| 	 * irq state, or schedule. We could test for usermode and upgrade to a | ||||
| 	 * normal process context (synchronous) interrupt for those, which | ||||
|  | @ -868,7 +869,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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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> | ||||
|  | @ -540,7 +541,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) | ||||
| { | ||||
| 	const struct exception_table_entry *entry; | ||||
| 	enum ctx_state prev_state; | ||||
|  | @ -624,7 +625,7 @@ void bad_page_fault(struct pt_regs *regs, int sig) | |||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_PPC_BOOK3S_64 | ||||
| void do_bad_page_fault_segv(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(do_bad_page_fault_segv) | ||||
| { | ||||
| 	bad_page_fault(regs, SIGSEGV); | ||||
| } | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ static void dump_fir(int cpu) | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| void cbe_system_error_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(cbe_system_error_exception) | ||||
| { | ||||
| 	int cpu = smp_processor_id(); | ||||
| 
 | ||||
|  | @ -58,7 +58,7 @@ void cbe_system_error_exception(struct pt_regs *regs) | |||
| 	dump_stack(); | ||||
| } | ||||
| 
 | ||||
| void cbe_maintenance_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(cbe_maintenance_exception) | ||||
| { | ||||
| 	int cpu = smp_processor_id(); | ||||
| 
 | ||||
|  | @ -70,7 +70,7 @@ void cbe_maintenance_exception(struct pt_regs *regs) | |||
| 	dump_stack(); | ||||
| } | ||||
| 
 | ||||
| void cbe_thermal_exception(struct pt_regs *regs) | ||||
| DEFINE_INTERRUPT_HANDLER(cbe_thermal_exception) | ||||
| { | ||||
| 	int cpu = smp_processor_id(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,9 +2,12 @@ | |||
| #ifndef RAS_H | ||||
| #define RAS_H | ||||
| 
 | ||||
| extern void cbe_system_error_exception(struct pt_regs *regs); | ||||
| extern void cbe_maintenance_exception(struct pt_regs *regs); | ||||
| extern void cbe_thermal_exception(struct pt_regs *regs); | ||||
| #include <asm/interrupt.h> | ||||
| 
 | ||||
| DECLARE_INTERRUPT_HANDLER(cbe_system_error_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(cbe_maintenance_exception); | ||||
| DECLARE_INTERRUPT_HANDLER(cbe_thermal_exception); | ||||
| 
 | ||||
| extern void cbe_ras_init(void); | ||||
| 
 | ||||
| #endif /* RAS_H */ | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Nicholas Piggin
						Nicholas Piggin