[PATCH RESEND v9 27/36] x86/traps: Add external_interrupt() to dispatch external interrupts

From: Xin Li
Date: Tue Aug 01 2023 - 05:08:44 EST


From: "H. Peter Anvin (Intel)" <hpa@xxxxxxxxx>

external_interrupt() dispatches all external interrupts: it checks if an
external interrupt is a system interrupt, if yes it dipatches it through
the system_interrupt_handlers table, otherwise to
dispatch_common_interrupt().

Signed-off-by: H. Peter Anvin (Intel) <hpa@xxxxxxxxx>
Co-developed-by: Xin Li <xin3.li@xxxxxxxxx>
Tested-by: Shan Kang <shan.kang@xxxxxxxxx>
Signed-off-by: Xin Li <xin3.li@xxxxxxxxx>
---

Changes since v8:
* Reword the patch description, which was confusing (Thomas Gleixner).

Changes since v5:
* Initialize system_interrupt_handlers with dispatch_table_spurious_interrupt()
instead of NULL to get rid of a branch (Peter Zijlstra).
---
arch/x86/include/asm/traps.h | 2 ++
arch/x86/kernel/traps.c | 18 ++++++++++++++++++
2 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index cba3e4dfc329..48daa78ee88c 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -66,4 +66,6 @@ static inline void sysvec_setup_fred(unsigned int vector, system_interrupt_handl
alloc_intr_gate(vector, asm_##func); \
}

+int external_interrupt(struct pt_regs *regs);
+
#endif /* _ASM_X86_TRAPS_H */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 9040c7f01c93..90fdfcccee7a 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -1542,6 +1542,24 @@ void set_sysvec_handler(unsigned int i, system_interrupt_handler func)
system_interrupt_handlers[i] = func;
}

+int external_interrupt(struct pt_regs *regs)
+{
+ unsigned int vector = regs->vector;
+ unsigned int sysvec = vector - FIRST_SYSTEM_VECTOR;
+
+ if (unlikely(vector < FIRST_EXTERNAL_VECTOR)) {
+ pr_err("invalid external interrupt vector %d\n", vector);
+ return -EINVAL;
+ }
+
+ if (sysvec < NR_SYSTEM_VECTORS)
+ system_interrupt_handlers[sysvec](regs);
+ else
+ dispatch_common_interrupt(regs, vector);
+
+ return 0;
+}
+
#endif /* CONFIG_X86_64 */

void __init trap_init(void)
--
2.34.1