~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/kernel/irq.c

Version: ~ [ linux-5.15-rc5 ] ~ [ linux-5.14.11 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.72 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.152 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.210 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.250 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.286 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.288 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Based on arch/arm/kernel/irq.c
  4  *
  5  * Copyright (C) 1992 Linus Torvalds
  6  * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
  7  * Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation.
  8  * Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and
  9  * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
 10  * Copyright (C) 2012 ARM Ltd.
 11  */
 12 
 13 #include <linux/irq.h>
 14 #include <linux/memory.h>
 15 #include <linux/smp.h>
 16 #include <linux/hardirq.h>
 17 #include <linux/init.h>
 18 #include <linux/irqchip.h>
 19 #include <linux/kprobes.h>
 20 #include <linux/scs.h>
 21 #include <linux/seq_file.h>
 22 #include <linux/vmalloc.h>
 23 #include <asm/daifflags.h>
 24 #include <asm/vmap_stack.h>
 25 
 26 /* Only access this in an NMI enter/exit */
 27 DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts);
 28 
 29 DEFINE_PER_CPU(unsigned long *, irq_stack_ptr);
 30 
 31 
 32 DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
 33 
 34 #ifdef CONFIG_SHADOW_CALL_STACK
 35 DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
 36 #endif
 37 
 38 static void init_irq_scs(void)
 39 {
 40         int cpu;
 41 
 42         if (!IS_ENABLED(CONFIG_SHADOW_CALL_STACK))
 43                 return;
 44 
 45         for_each_possible_cpu(cpu)
 46                 per_cpu(irq_shadow_call_stack_ptr, cpu) =
 47                         scs_alloc(cpu_to_node(cpu));
 48 }
 49 
 50 #ifdef CONFIG_VMAP_STACK
 51 static void init_irq_stacks(void)
 52 {
 53         int cpu;
 54         unsigned long *p;
 55 
 56         for_each_possible_cpu(cpu) {
 57                 p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, cpu_to_node(cpu));
 58                 per_cpu(irq_stack_ptr, cpu) = p;
 59         }
 60 }
 61 #else
 62 /* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */
 63 DEFINE_PER_CPU_ALIGNED(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
 64 
 65 static void init_irq_stacks(void)
 66 {
 67         int cpu;
 68 
 69         for_each_possible_cpu(cpu)
 70                 per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu);
 71 }
 72 #endif
 73 
 74 static void default_handle_irq(struct pt_regs *regs)
 75 {
 76         panic("IRQ taken without a root IRQ handler\n");
 77 }
 78 
 79 static void default_handle_fiq(struct pt_regs *regs)
 80 {
 81         panic("FIQ taken without a root FIQ handler\n");
 82 }
 83 
 84 void (*handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq;
 85 void (*handle_arch_fiq)(struct pt_regs *) __ro_after_init = default_handle_fiq;
 86 
 87 int __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
 88 {
 89         if (handle_arch_irq != default_handle_irq)
 90                 return -EBUSY;
 91 
 92         handle_arch_irq = handle_irq;
 93         pr_info("Root IRQ handler: %ps\n", handle_irq);
 94         return 0;
 95 }
 96 
 97 int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *))
 98 {
 99         if (handle_arch_fiq != default_handle_fiq)
100                 return -EBUSY;
101 
102         handle_arch_fiq = handle_fiq;
103         pr_info("Root FIQ handler: %ps\n", handle_fiq);
104         return 0;
105 }
106 
107 void __init init_IRQ(void)
108 {
109         init_irq_stacks();
110         init_irq_scs();
111         irqchip_init();
112 
113         if (system_uses_irq_prio_masking()) {
114                 /*
115                  * Now that we have a stack for our IRQ handler, set
116                  * the PMR/PSR pair to a consistent state.
117                  */
118                 WARN_ON(read_sysreg(daif) & PSR_A_BIT);
119                 local_daif_restore(DAIF_PROCCTX_NOIRQ);
120         }
121 }
122 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp