diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 3625797e9ee8f9..46a4c012e15f27 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -139,7 +140,8 @@ static void do_interrupt_handler(struct pt_regs *regs, set_irq_regs(old_regs); } -extern void (*handle_arch_irq)(struct pt_regs *); +extern void (*_handle_arch_irq)(struct pt_regs *); +#define handle_arch_irq runtime_const_ptr(_handle_arch_irq) extern void (*handle_arch_fiq)(struct pt_regs *); static void noinstr __panic_unhandled(struct pt_regs *regs, const char *vector, diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 15dedb385b9e4c..30629c183606b2 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -84,15 +85,17 @@ static void default_handle_fiq(struct pt_regs *regs) panic("FIQ taken without a root FIQ handler\n"); } -void (*handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq; +void (*_handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq; +#define handle_arch_irq runtime_const_ptr(_handle_arch_irq) void (*handle_arch_fiq)(struct pt_regs *) __ro_after_init = default_handle_fiq; int __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) { - if (handle_arch_irq != default_handle_irq) + if (_handle_arch_irq != default_handle_irq) return -EBUSY; - handle_arch_irq = handle_irq; + _handle_arch_irq = handle_irq; + runtime_const_init(ptr, _handle_arch_irq); pr_info("Root IRQ handler: %ps\n", handle_irq); return 0; } diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index eeb070f330bdb8..c4af2c7d0eedf7 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -973,7 +973,8 @@ RUNTIME_CONST(shift, d_hash_shift) \ RUNTIME_CONST(ptr, dentry_hashtable) \ RUNTIME_CONST(ptr, __dentry_cache) \ - RUNTIME_CONST(ptr, __names_cache) + RUNTIME_CONST(ptr, __names_cache) \ + RUNTIME_CONST(ptr, _handle_arch_irq) /* Alignment must be consistent with (kunit_suite *) in include/kunit/test.h */ #define KUNIT_TABLE() \ diff --git a/include/linux/irq.h b/include/linux/irq.h index 951acbdb9f8457..2ba4a8afb71e33 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -1274,6 +1274,7 @@ void ipi_mux_process(void); int ipi_mux_create(unsigned int nr_ipi, void (*mux_send)(unsigned int cpu)); #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER +#include /* * Registers a generic IRQ handling function as the top-level IRQ handler in * the system, which is generally the first C code called from an assembly @@ -1288,7 +1289,8 @@ int __init set_handle_irq(void (*handle_irq)(struct pt_regs *)); * Allows interrupt handlers to find the irqchip that's been registered as the * top-level IRQ handler. */ -extern void (*handle_arch_irq)(struct pt_regs *) __ro_after_init; +extern void (*_handle_arch_irq)(struct pt_regs *) __ro_after_init; +#define handle_arch_irq runtime_const_ptr(_handle_arch_irq) asmlinkage void generic_handle_arch_irq(struct pt_regs *regs); #else #ifndef set_handle_irq diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index b7d52821837bc3..aac9e7b1301e3f 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -15,13 +15,14 @@ #include #include +#include #include #include "internals.h" #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER -void (*handle_arch_irq)(struct pt_regs *) __ro_after_init; +void (*_handle_arch_irq)(struct pt_regs *) __ro_after_init; #endif /** @@ -270,10 +271,11 @@ irqreturn_t handle_irq_event(struct irq_desc *desc) #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER int __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) { - if (handle_arch_irq) + if (_handle_arch_irq) return -EBUSY; - handle_arch_irq = handle_irq; + _handle_arch_irq = handle_irq; + runtime_const_init(ptr, _handle_arch_irq); return 0; }