[v8,04/33] x86/traps: add install_system_interrupt_handler()
Commit Message
Some kernel components install system interrupt handlers into the IDT,
and we need to do the same for system_interrupt_handlers. A new function
install_system_interrupt_handler() is added to install a system interrupt
handler into both the IDT and system_interrupt_handlers.
Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
---
arch/x86/include/asm/traps.h | 2 ++
arch/x86/kernel/cpu/acrn.c | 7 +++++--
arch/x86/kernel/cpu/mshyperv.c | 22 ++++++++++++++--------
arch/x86/kernel/kvm.c | 4 +++-
arch/x86/kernel/traps.c | 10 ++++++++++
drivers/xen/events/events_base.c | 5 ++++-
6 files changed, 38 insertions(+), 12 deletions(-)
Comments
On Mon, Apr 10 2023 at 01:14, Xin Li wrote:
> Some kernel components install system interrupt handlers into the IDT,
> and we need to do the same for system_interrupt_handlers.
We need to the same? This sentence does not make any sense at all.
https://www.kernel.org/doc/html/latest/process/maintainer-tip.html
> +void install_system_interrupt_handler(unsigned int n, const void *asm_addr, const void *addr);
Why is this void *?
>
> +void __init install_system_interrupt_handler(unsigned int n, const void *asm_addr, const void *addr)
> +{
> + BUG_ON(n < FIRST_SYSTEM_VECTOR);
> +
> +#ifdef CONFIG_X86_64
> + system_interrupt_handlers[n - FIRST_SYSTEM_VECTOR] = (system_interrupt_handler)addr;
Just that you can add a silly typecast here, right?
Oh well.
> - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_xen_hvm_callback);
> + install_system_interrupt_handler(HYPERVISOR_CALLBACK_VECTOR,
> + asm_sysvec_xen_hvm_callback,
> + sysvec_xen_hvm_callback);
Can we please make this less convoluted?
#ifdef CONFIG_X86_64
static inline void sysvec_setup_fred(unsigned int vector, void (*func)(struct pt_regs*))
{
...
}
#else
static inline void sysvec_setup_fred(unsigned int vector, void (*func)(struct pt_regs*))
{
}
#endif
#define sysvec_install(vector, func) { \
sysvec_setup_fred(vector, func); \
alloc_intr_gate(vector, asm_##func); \
}
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_xen_hvm_callback);
+ sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_xen_hvm_callback);
No?
Thanks,
tglx
> #ifdef CONFIG_X86_64
> static inline void sysvec_setup_fred(unsigned int vector, void (*func)(struct
> pt_regs*)) {
> ...
> }
> #else
> static inline void sysvec_setup_fred(unsigned int vector, void (*func)(struct
> pt_regs*)) { } #endif
>
> #define sysvec_install(vector, func) { \
> sysvec_setup_fred(vector, func); \
> alloc_intr_gate(vector, asm_##func); \
> }
>
> - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
> asm_sysvec_xen_hvm_callback);
> + sysvec_install(HYPERVISOR_CALLBACK_VECTOR,
> sysvec_xen_hvm_callback);
This is a better way, and I will do so in the next iteration.
Thanks!
Xin
@@ -41,6 +41,8 @@ void math_emulate(struct math_emu_info *);
bool fault_in_kernel_space(unsigned long address);
+void install_system_interrupt_handler(unsigned int n, const void *asm_addr, const void *addr);
+
#ifdef CONFIG_VMAP_STACK
void __noreturn handle_stack_overflow(struct pt_regs *regs,
unsigned long fault_address,
@@ -18,6 +18,7 @@
#include <asm/hypervisor.h>
#include <asm/idtentry.h>
#include <asm/irq_regs.h>
+#include <asm/traps.h>
static u32 __init acrn_detect(void)
{
@@ -26,8 +27,10 @@ static u32 __init acrn_detect(void)
static void __init acrn_init_platform(void)
{
- /* Setup the IDT for ACRN hypervisor callback */
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_acrn_hv_callback);
+ /* Install system interrupt handler for ACRN hypervisor callback */
+ install_system_interrupt_handler(HYPERVISOR_CALLBACK_VECTOR,
+ asm_sysvec_acrn_hv_callback,
+ sysvec_acrn_hv_callback);
x86_platform.calibrate_tsc = acrn_get_tsc_khz;
x86_platform.calibrate_cpu = acrn_get_tsc_khz;
@@ -29,6 +29,7 @@
#include <asm/i8259.h>
#include <asm/apic.h>
#include <asm/timer.h>
+#include <asm/traps.h>
#include <asm/reboot.h>
#include <asm/nmi.h>
#include <clocksource/hyperv_timer.h>
@@ -491,19 +492,24 @@ static void __init ms_hyperv_init_platform(void)
*/
x86_platform.apic_post_init = hyperv_init;
hyperv_setup_mmu_ops();
- /* Setup the IDT for hypervisor callback */
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_hyperv_callback);
- /* Setup the IDT for reenlightenment notifications */
+ /* Install system interrupt handler for hypervisor callback */
+ install_system_interrupt_handler(HYPERVISOR_CALLBACK_VECTOR,
+ asm_sysvec_hyperv_callback,
+ sysvec_hyperv_callback);
+
+ /* Install system interrupt handler for reenlightenment notifications */
if (ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT) {
- alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
- asm_sysvec_hyperv_reenlightenment);
+ install_system_interrupt_handler(HYPERV_REENLIGHTENMENT_VECTOR,
+ asm_sysvec_hyperv_reenlightenment,
+ sysvec_hyperv_reenlightenment);
}
- /* Setup the IDT for stimer0 */
+ /* Install system interrupt handler for stimer0 */
if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) {
- alloc_intr_gate(HYPERV_STIMER0_VECTOR,
- asm_sysvec_hyperv_stimer0);
+ install_system_interrupt_handler(HYPERV_STIMER0_VECTOR,
+ asm_sysvec_hyperv_stimer0,
+ sysvec_hyperv_stimer0);
}
# ifdef CONFIG_SMP
@@ -829,7 +829,9 @@ static void __init kvm_guest_init(void)
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF_INT) && kvmapf) {
static_branch_enable(&kvm_async_pf_enabled);
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_kvm_asyncpf_interrupt);
+ install_system_interrupt_handler(HYPERVISOR_CALLBACK_VECTOR,
+ asm_sysvec_kvm_asyncpf_interrupt,
+ sysvec_kvm_asyncpf_interrupt);
}
#ifdef CONFIG_SMP
@@ -1513,6 +1513,16 @@ static system_interrupt_handler system_interrupt_handlers[NR_SYSTEM_VECTORS] = {
#endif /* CONFIG_X86_64 */
+void __init install_system_interrupt_handler(unsigned int n, const void *asm_addr, const void *addr)
+{
+ BUG_ON(n < FIRST_SYSTEM_VECTOR);
+
+#ifdef CONFIG_X86_64
+ system_interrupt_handlers[n - FIRST_SYSTEM_VECTOR] = (system_interrupt_handler)addr;
+#endif
+ alloc_intr_gate(n, asm_addr);
+}
+
void __init trap_init(void)
{
/* Init cpu_entry_area before IST entries are set up */
@@ -45,6 +45,7 @@
#include <asm/irq.h>
#include <asm/io_apic.h>
#include <asm/i8259.h>
+#include <asm/traps.h>
#include <asm/xen/cpuid.h>
#include <asm/xen/pci.h>
#endif
@@ -2249,7 +2250,9 @@ static __init void xen_alloc_callback_vector(void)
return;
pr_info("Xen HVM callback vector for event delivery is enabled\n");
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_xen_hvm_callback);
+ install_system_interrupt_handler(HYPERVISOR_CALLBACK_VECTOR,
+ asm_sysvec_xen_hvm_callback,
+ sysvec_xen_hvm_callback);
}
#else
void xen_setup_callback_vector(void) {}