From: "H. Peter Anvin (Intel)" <h...@zytor.com>

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) <h...@zytor.com>
Co-developed-by: Xin Li <xin3...@intel.com>
Tested-by: Shan Kang <shan.k...@intel.com>
Signed-off-by: Xin Li <xin3...@intel.com>
---

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


Reply via email to