1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Derived from arch/i386/kernel/irq.c 4 * Copyright (C) 1992 Linus Torvalds 5 * Adapted from arch/i386 by Gary Thomas 6 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 7 * Updated and modified by Cort Dougan <cort@fsmlabs.com> 8 * Copyright (C) 1996-2001 Cort Dougan 9 * Adapted for Power Macintosh by Paul Mackerras 10 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) 11 * 12 * This file contains the code used by various IRQ handling routines: 13 * asking for different IRQ's should be done through these routines 14 * instead of just grabbing them. Thus setups with different IRQ numbers 15 * shouldn't result in any weird surprises, and installing new handlers 16 * should be easier. 17 * 18 * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the 19 * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit 20 * mask register (of which only 16 are defined), hence the weird shifting 21 * and complement of the cached_irq_mask. I want to be able to stuff 22 * this right into the SIU SMASK register. 23 * Many of the prep/chrp functions are conditional compiled on CONFIG_PPC_8xx 24 * to reduce code space and undefined function references. 25 */ 26 27 #undef DEBUG 28 29 #include <linux/export.h> 30 #include <linux/threads.h> 31 #include <linux/kernel_stat.h> 32 #include <linux/signal.h> 33 #include <linux/sched.h> 34 #include <linux/ptrace.h> 35 #include <linux/ioport.h> 36 #include <linux/interrupt.h> 37 #include <linux/timex.h> 38 #include <linux/init.h> 39 #include <linux/slab.h> 40 #include <linux/delay.h> 41 #include <linux/irq.h> 42 #include <linux/seq_file.h> 43 #include <linux/cpumask.h> 44 #include <linux/profile.h> 45 #include <linux/bitops.h> 46 #include <linux/list.h> 47 #include <linux/radix-tree.h> 48 #include <linux/mutex.h> 49 #include <linux/pci.h> 50 #include <linux/debugfs.h> 51 #include <linux/of.h> 52 #include <linux/of_irq.h> 53 #include <linux/vmalloc.h> 54 #include <linux/pgtable.h> 55 #include <linux/static_call.h> 56 57 #include <linux/uaccess.h> 58 #include <asm/interrupt.h> 59 #include <asm/io.h> 60 #include <asm/irq.h> 61 #include <asm/cache.h> 62 #include <asm/ptrace.h> 63 #include <asm/machdep.h> 64 #include <asm/udbg.h> 65 #include <asm/smp.h> 66 #include <asm/hw_irq.h> 67 #include <asm/softirq_stack.h> 68 #include <asm/ppc_asm.h> 69 70 #define CREATE_TRACE_POINTS 71 #include <asm/trace.h> 72 #include <asm/cpu_has_feature.h> 73 74 DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); 75 EXPORT_PER_CPU_SYMBOL(irq_stat); 76 DEFINE_PER_CPU(unsigned int, __softirq_pending); 77 78 #ifdef CONFIG_PPC32 79 atomic_t ppc_n_lost_interrupts; 80 81 #ifdef CONFIG_TAU_INT 82 extern int tau_initialized; 83 u32 tau_interrupts(unsigned long cpu); 84 #endif 85 #endif /* CONFIG_PPC32 */ 86 87 struct irq_stat_info { 88 const char *symbol; 89 const char *text; 90 int optional; 91 }; 92 93 /* ISE - IRQ STAT ENABLED, ISC - IRQ STAT CONDITIONAL */ 94 #define ISE(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 0} 95 #define ISC(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 1} 96 97 98 static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = { 99 ISE(LOC_TIMER, "LOC", " Local timer interrupts for timer event device\n"), 100 ISE(BCT_TIMER, "BCT", " Broadcast timer interrupts for timer event device\n"), 101 ISE(OTHER_TIMER, "LOC", " Local timer interrupts for others\n"), 102 ISE(SPURIOUS, "SPU", " Spurious interrupts\n"), 103 ISE(PMI, "PMI", " Performance monitoring interrupts\n"), 104 ISC(MCE, "MCE", " Machine check exceptions\n"), 105 ISC(NMI_SRESET, "NMI", " System Reset interrupts\n"), 106 #ifdef CONFIG_PPC_WATCHDOG 107 ISE(WATCHDOG, "WDG", " Watchdog soft-NMI interrupts\n"), 108 #endif 109 #ifdef CONFIG_PPC_DOORBELL 110 ISE(DOORBELL, "DBL", " Doorbell interrupts\n"), 111 #endif 112 }; 113 114 /* 115 * Used for default disabled counters to increment the stats and to enable the 116 * entry for /proc/interrupts output. 117 */ 118 static DECLARE_BITMAP(irq_stat_count_show, IRQ_COUNT_MAX) __read_mostly; 119 void inc_irq_stat_and_enable(enum irq_stat_counts which) 120 { 121 __this_cpu_inc(irq_stat.counts[which]); 122 set_bit(which, irq_stat_count_show); 123 } 124 125 int arch_show_interrupts(struct seq_file *p, int prec) 126 { 127 const struct irq_stat_info *info = irq_stat_info; 128 129 for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) { 130 if (info->optional && !test_bit(i, irq_stat_count_show)) 131 continue; 132 133 seq_printf(p, "%*s:", prec, info->symbol); 134 irq_proc_emit_counts(p, &irq_stat.counts[i]); 135 seq_puts(p, info->text); 136 } 137 138 #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT) 139 if (tau_initialized) { 140 int j; 141 seq_printf(p, "%*s:", prec, "TAU"); 142 for_each_online_cpu(j) 143 seq_put_decimal_ull_width(p, " ", tau_interrupts(j), 10); 144 seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); 145 } 146 #endif /* CONFIG_PPC32 && CONFIG_TAU_INT */ 147 #ifdef CONFIG_PPC_BOOK3S_64 148 if (cpu_has_feature(CPU_FTR_HVMODE)) { 149 int j; 150 seq_printf(p, "%*s:", prec, "HMI"); 151 for_each_online_cpu(j) 152 seq_put_decimal_ull_width(p, " ", paca_ptrs[j]->hmi_irqs, 10); 153 seq_printf(p, " Hypervisor Maintenance Interrupts\n"); 154 } 155 #endif 156 return 0; 157 } 158 159 static int __init irq_init_stats(void) 160 { 161 struct irq_stat_info *info = irq_stat_info; 162 163 for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) { 164 if (info->optional == 0) 165 set_bit(i, irq_stat_count_show); 166 } 167 168 return 0; 169 } 170 late_initcall(irq_init_stats); 171 172 /* 173 * /proc/stat helpers 174 */ 175 u64 arch_irq_stat_cpu(unsigned int cpu) 176 { 177 irq_cpustat_t *p = per_cpu_ptr(&irq_stat, cpu); 178 u64 sum = 0; 179 180 for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++) 181 sum += p->counts[i]; 182 183 #ifdef CONFIG_PPC_BOOK3S_64 184 sum += paca_ptrs[cpu]->hmi_irqs; 185 #endif 186 return sum; 187 } 188 189 static inline void check_stack_overflow(unsigned long sp) 190 { 191 if (!IS_ENABLED(CONFIG_DEBUG_STACKOVERFLOW)) 192 return; 193 194 sp &= THREAD_SIZE - 1; 195 196 /* check for stack overflow: is there less than 1/4th free? */ 197 if (unlikely(sp < THREAD_SIZE / 4)) { 198 pr_err("do_IRQ: stack overflow: %ld\n", sp); 199 dump_stack(); 200 } 201 } 202 203 #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK 204 static __always_inline void call_do_softirq(const void *sp) 205 { 206 /* Temporarily switch r1 to sp, call __do_softirq() then restore r1. */ 207 asm volatile ( 208 PPC_STLU " %%r1, %[offset](%[sp]) ;" 209 "mr %%r1, %[sp] ;" 210 #ifdef CONFIG_PPC_KERNEL_PCREL 211 "bl %[callee]@notoc ;" 212 #else 213 "bl %[callee] ;" 214 #endif 215 PPC_LL " %%r1, 0(%%r1) ;" 216 : // Outputs 217 : // Inputs 218 [sp] "b" (sp), [offset] "i" (THREAD_SIZE - STACK_FRAME_MIN_SIZE), 219 [callee] "i" (__do_softirq) 220 : // Clobbers 221 "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", "cr7", "r0", 222 /* r2 may be clobbered by the callee when using PCREL mode in the ELFv2 ABI. */ 223 #ifdef CONFIG_PPC_KERNEL_PCREL 224 "r2", 225 #endif 226 "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 227 "r11", "r12" 228 ); 229 } 230 #endif 231 232 DEFINE_STATIC_CALL_RET0(ppc_get_irq, *ppc_md.get_irq); 233 234 static void __do_irq(struct pt_regs *regs, unsigned long oldsp) 235 { 236 unsigned int irq; 237 238 trace_irq_entry(regs); 239 240 check_stack_overflow(oldsp); 241 242 /* 243 * Query the platform PIC for the interrupt & ack it. 244 * 245 * This will typically lower the interrupt line to the CPU 246 */ 247 irq = static_call(ppc_get_irq)(); 248 249 /* We can hard enable interrupts now to allow perf interrupts */ 250 if (should_hard_irq_enable(regs)) 251 do_hard_irq_enable(); 252 253 /* And finally process it */ 254 if (unlikely(!irq)) 255 inc_irq_stat(SPURIOUS); 256 else 257 generic_handle_irq(irq); 258 259 trace_irq_exit(regs); 260 } 261 262 static __always_inline void call_do_irq(struct pt_regs *regs, void *sp) 263 { 264 register unsigned long r3 asm("r3") = (unsigned long)regs; 265 266 /* Temporarily switch r1 to sp, call __do_irq() then restore r1. */ 267 asm volatile ( 268 PPC_STLU " %%r1, %[offset](%[sp]) ;" 269 "mr %%r4, %%r1 ;" 270 "mr %%r1, %[sp] ;" 271 #ifdef CONFIG_PPC_KERNEL_PCREL 272 "bl %[callee]@notoc ;" 273 #else 274 "bl %[callee] ;" 275 #endif 276 PPC_LL " %%r1, 0(%%r1) ;" 277 : // Outputs 278 "+r" (r3) 279 : // Inputs 280 [sp] "b" (sp), [offset] "i" (THREAD_SIZE - STACK_FRAME_MIN_SIZE), 281 [callee] "i" (__do_irq) 282 : // Clobbers 283 "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", "cr7", "r0", 284 /* r2 may be clobbered by the callee when using PCREL mode in the ELFv2 ABI. */ 285 #ifdef CONFIG_PPC_KERNEL_PCREL 286 "r2", 287 #endif 288 "r4", "r5", "r6", "r7", "r8", "r9", "r10", 289 "r11", "r12" 290 ); 291 } 292 293 void __do_IRQ(struct pt_regs *regs) 294 { 295 struct pt_regs *old_regs = set_irq_regs(regs); 296 void *cursp, *irqsp; 297 298 /* Switch to the irq stack to handle this */ 299 cursp = (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); 300 irqsp = hardirq_ctx[raw_smp_processor_id()]; 301 302 /* Already there ? If not switch stack and call */ 303 if (unlikely(cursp == irqsp)) 304 __do_irq(regs, current_stack_pointer); 305 else 306 call_do_irq(regs, irqsp); 307 308 set_irq_regs(old_regs); 309 } 310 311 DEFINE_INTERRUPT_HANDLER_ASYNC(do_IRQ) 312 { 313 __do_IRQ(regs); 314 } 315 316 static void *__init alloc_vm_stack(void) 317 { 318 return __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, THREADINFO_GFP, 319 NUMA_NO_NODE, (void *)_RET_IP_); 320 } 321 322 static void __init vmap_irqstack_init(void) 323 { 324 int i; 325 326 for_each_possible_cpu(i) { 327 softirq_ctx[i] = alloc_vm_stack(); 328 hardirq_ctx[i] = alloc_vm_stack(); 329 } 330 } 331 332 333 void __init init_IRQ(void) 334 { 335 if (IS_ENABLED(CONFIG_VMAP_STACK)) 336 vmap_irqstack_init(); 337 338 if (ppc_md.init_IRQ) 339 ppc_md.init_IRQ(); 340 341 if (!WARN_ON(!ppc_md.get_irq)) 342 static_call_update(ppc_get_irq, ppc_md.get_irq); 343 } 344 345 #ifdef CONFIG_BOOKE 346 void *critirq_ctx[NR_CPUS] __read_mostly; 347 void *dbgirq_ctx[NR_CPUS] __read_mostly; 348 void *mcheckirq_ctx[NR_CPUS] __read_mostly; 349 #endif 350 351 void *softirq_ctx[NR_CPUS] __read_mostly; 352 void *hardirq_ctx[NR_CPUS] __read_mostly; 353 354 #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK 355 void do_softirq_own_stack(void) 356 { 357 call_do_softirq(softirq_ctx[smp_processor_id()]); 358 } 359 #endif 360 361 irq_hw_number_t virq_to_hw(unsigned int virq) 362 { 363 struct irq_data *irq_data = irq_get_irq_data(virq); 364 return WARN_ON(!irq_data) ? 0 : irq_data->hwirq; 365 } 366 EXPORT_SYMBOL_GPL(virq_to_hw); 367 368 #ifdef CONFIG_SMP 369 int irq_choose_cpu(const struct cpumask *mask) 370 { 371 int cpuid; 372 373 if (cpumask_equal(mask, cpu_online_mask)) { 374 static int irq_rover; 375 static DEFINE_RAW_SPINLOCK(irq_rover_lock); 376 unsigned long flags; 377 378 /* Round-robin distribution... */ 379 do_round_robin: 380 raw_spin_lock_irqsave(&irq_rover_lock, flags); 381 382 irq_rover = cpumask_next_wrap(irq_rover, cpu_online_mask); 383 cpuid = irq_rover; 384 385 raw_spin_unlock_irqrestore(&irq_rover_lock, flags); 386 } else { 387 cpuid = cpumask_first_and(mask, cpu_online_mask); 388 if (cpuid >= nr_cpu_ids) 389 goto do_round_robin; 390 } 391 392 return get_hard_smp_processor_id(cpuid); 393 } 394 #else 395 int irq_choose_cpu(const struct cpumask *mask) 396 { 397 return hard_smp_processor_id(); 398 } 399 #endif 400