From: Xin Li <xin3.li@intel.com>
To: linux-kernel@vger.kernel.org, x86@kernel.org, kvm@vger.kernel.org
Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, hpa@zytor.com, seanjc@google.com,
pbonzini@redhat.com, kevin.tian@intel.com
Subject: [RESEND PATCH 2/6] x86/traps: add a system interrupt table for system interrupt dispatch
Date: Wed, 9 Nov 2022 22:15:41 -0800 [thread overview]
Message-ID: <20221110061545.1531-3-xin3.li@intel.com> (raw)
In-Reply-To: <20221110061545.1531-1-xin3.li@intel.com>
Upon receiving an external interrupt, KVM VMX reinjects it through
calling the interrupt handler in its IDT descriptor on the current
kernel stack, which essentially uses the IDT as an interrupt dispatch
table.
However the IDT is one of the lowest level critical data structures
between a x86 CPU and the Linux kernel, we should avoid using it
*directly* whenever possible, espeically in a software defined manner.
On x86, external interrupts are divided into the following groups
1) system interrupts
2) external device interrupts
With the IDT, system interrupts are dispatched through the IDT
directly, while external device interrupts are all routed to the
external interrupt dispatch function common_interrupt(), which
dispatches external device interrupts through a per-CPU external
interrupt dispatch table vector_irq.
To eliminate dispatching external interrupts through the IDT, add
a system interrupt handler table for dispatching a system interrupt
to its corresponding handler directly. Thus a software based dispatch
function will be:
void external_interrupt(struct pt_regs *regs, u8 vector)
{
if (is_system_interrupt(vector))
system_interrupt_handler_table[vector_to_sysvec(vector)](regs);
else /* external device interrupt */
common_interrupt(regs, vector);
}
What's more, with the Intel FRED (Flexible Return and Event Delivery)
architecture, IDT, the hardware based event dispatch table, is gone,
and the Linux kernel needs to dispatch events to their handlers with
vector to handler mappings, the dispatch function external_interrupt()
is also needed.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
---
arch/x86/include/asm/traps.h | 8 ++++++
arch/x86/kernel/traps.c | 55 ++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 47ecfff2c83d..3dc63d753bda 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -47,4 +47,12 @@ void __noreturn handle_stack_overflow(struct pt_regs *regs,
struct stack_info *info);
#endif
+/*
+ * How system interrupt handlers are called.
+ */
+#define DECLARE_SYSTEM_INTERRUPT_HANDLER(f) \
+ void f (struct pt_regs *regs __maybe_unused, \
+ unsigned long vector __maybe_unused)
+typedef DECLARE_SYSTEM_INTERRUPT_HANDLER((*system_interrupt_handler));
+
#endif /* _ASM_X86_TRAPS_H */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 178015a820f0..95dd917ef9ad 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -1444,6 +1444,61 @@ DEFINE_IDTENTRY_SW(iret_error)
}
#endif
+#define SYSV(x,y) [(x) - FIRST_SYSTEM_VECTOR] = (system_interrupt_handler)y
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+
+/*
+ * The initializer spurious_interrupt() has two arguments of types struct
+ * pt_regs * and unsigned long, and the system interrupt handlers with
+ * prefix sysvec_ are all defined with either DEFINE_IDTENTRY_SYSVEC or
+ * DEFINE_IDTENTRY_SYSVEC_SIMPLE, both with only one argument of type
+ * struct pt_regs *. Because all handlers only declare and require a subset
+ * of the arguments provided by the full system_interrupt_handler prototype,
+ * the function type cast is safe here.
+ */
+const system_interrupt_handler system_interrupt_handler_table[NR_SYSTEM_VECTORS] = {
+ [0 ... NR_SYSTEM_VECTORS-1] = spurious_interrupt,
+#ifdef CONFIG_SMP
+ SYSV(RESCHEDULE_VECTOR, sysvec_reschedule_ipi),
+ SYSV(CALL_FUNCTION_VECTOR, sysvec_call_function),
+ SYSV(CALL_FUNCTION_SINGLE_VECTOR, sysvec_call_function_single),
+ SYSV(REBOOT_VECTOR, sysvec_reboot),
+#endif
+
+#ifdef CONFIG_X86_THERMAL_VECTOR
+ SYSV(THERMAL_APIC_VECTOR, sysvec_thermal),
+#endif
+
+#ifdef CONFIG_X86_MCE_THRESHOLD
+ SYSV(THRESHOLD_APIC_VECTOR, sysvec_threshold),
+#endif
+
+#ifdef CONFIG_X86_MCE_AMD
+ SYSV(DEFERRED_ERROR_VECTOR, sysvec_deferred_error),
+#endif
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ SYSV(LOCAL_TIMER_VECTOR, sysvec_apic_timer_interrupt),
+ SYSV(X86_PLATFORM_IPI_VECTOR, sysvec_x86_platform_ipi),
+# ifdef CONFIG_HAVE_KVM
+ SYSV(POSTED_INTR_VECTOR, sysvec_kvm_posted_intr_ipi),
+ SYSV(POSTED_INTR_WAKEUP_VECTOR, sysvec_kvm_posted_intr_wakeup_ipi),
+ SYSV(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested_ipi),
+# endif
+# ifdef CONFIG_IRQ_WORK
+ SYSV(IRQ_WORK_VECTOR, sysvec_irq_work),
+# endif
+ SYSV(SPURIOUS_APIC_VECTOR, sysvec_spurious_apic_interrupt),
+ SYSV(ERROR_APIC_VECTOR, sysvec_error_interrupt),
+#endif
+};
+
+#pragma GCC diagnostic pop
+
+#undef SYSV
+
void __init trap_init(void)
{
/* Init cpu_entry_area before IST entries are set up */
--
2.34.1
next prev parent reply other threads:[~2022-11-10 6:39 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-10 6:15 [RESEND PATCH 0/6] x86/traps,VMX: implement software based NMI/IRQ dispatch for VMX NMI/IRQ reinjection Xin Li
2022-11-10 6:15 ` [RESEND PATCH 1/6] x86/traps: let common_interrupt() handle IRQ_MOVE_CLEANUP_VECTOR Xin Li
2022-11-10 18:59 ` Ashok Raj
2022-11-10 22:09 ` Li, Xin3
2022-11-10 6:15 ` Xin Li [this message]
2022-11-10 8:56 ` [RESEND PATCH 2/6] x86/traps: add a system interrupt table for system interrupt dispatch Peter Zijlstra
2022-11-10 19:55 ` Li, Xin3
2022-11-10 20:36 ` Li, Xin3
2022-11-10 21:12 ` Nathan Chancellor
2022-11-10 23:00 ` Li, Xin3
2022-11-11 0:08 ` Nathan Chancellor
2022-11-11 3:03 ` Li, Xin3
2022-11-11 8:58 ` Peter Zijlstra
2022-11-11 1:12 ` Tian, Kevin
2022-11-11 3:54 ` Li, Xin3
2022-11-11 8:55 ` Peter Zijlstra
2022-11-11 22:07 ` H. Peter Anvin
2022-11-12 9:47 ` Peter Zijlstra
2022-11-10 6:15 ` [RESEND PATCH 3/6] x86/traps: add install_system_interrupt_handler() Xin Li
2022-11-10 6:15 ` [RESEND PATCH 4/6] x86/traps: add external_interrupt() to dispatch external interrupts Xin Li
2022-11-10 16:24 ` Sean Christopherson
2022-11-10 18:02 ` Li, Xin3
2022-11-10 20:10 ` Sean Christopherson
2022-11-10 6:15 ` [RESEND PATCH 5/6] KVM: x86/VMX: add kvm_vmx_reinject_nmi_irq() for NMI/IRQ reinjection Xin Li
2022-11-10 9:03 ` Peter Zijlstra
2022-11-10 20:53 ` Li, Xin3
2022-11-11 9:15 ` Peter Zijlstra
2022-11-11 12:04 ` Paolo Bonzini
2022-11-11 12:19 ` Peter Zijlstra
2022-11-11 12:48 ` Paolo Bonzini
2022-11-11 14:23 ` Peter Zijlstra
2022-11-11 16:35 ` Andrew Cooper
2022-11-11 22:22 ` H. Peter Anvin
2022-11-12 0:08 ` Andrew Cooper
2022-11-11 18:06 ` Li, Xin3
2022-11-11 19:33 ` Peter Zijlstra
2022-11-12 6:35 ` Li, Xin3
2022-11-14 4:39 ` Li, Xin3
2022-11-14 9:08 ` Peter Zijlstra
2022-11-15 7:50 ` Li, Xin3
2022-11-15 9:17 ` Peter Zijlstra
2022-11-17 3:37 ` Li, Xin3
2022-11-17 15:51 ` Sean Christopherson
2022-11-18 0:05 ` Li, Xin3
2022-11-22 13:00 ` Li, Xin3
2022-11-22 20:52 ` Sean Christopherson
2022-11-23 8:31 ` Li, Xin3
2022-11-23 20:42 ` Sean Christopherson
2022-11-24 3:40 ` Li, Xin3
2022-11-28 16:26 ` Sean Christopherson
2022-11-24 9:46 ` Peter Zijlstra
2022-11-28 19:05 ` Sean Christopherson
2022-11-23 9:16 ` Peter Zijlstra
2022-11-23 19:18 ` Sean Christopherson
2022-11-11 22:15 ` H. Peter Anvin
2022-11-10 6:15 ` [RESEND PATCH 6/6] x86/traps: remove unused NMI entry exc_nmi_noist() Xin Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221110061545.1531-3-xin3.li@intel.com \
--to=xin3.li@intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox