Hi Thomas, On Thu, May 21, 2020 at 10:05:43PM +0200, Thomas Gleixner wrote: > From: Thomas Gleixner > > Convert various hypervisor vectors to IDTENTRY_SYSVEC > - Implement the C entry point with DEFINE_IDTENTRY_SYSVEC > - Emit the ASM stub with DECLARE_IDTENTRY_SYSVEC > - Remove the ASM idtentries in 64bit > - Remove the BUILD_INTERRUPT entries in 32bit > - Remove the old prototypes > > No functional change. > > Signed-off-by: Thomas Gleixner > Acked-by: Andy Lutomirski I hit the following while trying to test the whole patchset on a Hyper-V guest, and git bisect told me this patch introduced the problem, the config file is in the attachment. Regards, Boqun [ 3.366637] BUG: kernel NULL pointer dereference, address: 0000000000000010 [ 3.369959] #PF: supervisor instruction fetch in kernel mode [ 3.369959] #PF: error_code(0x0010) - not-present page [ 3.369959] PGD 0 P4D 0 [ 3.369959] Oops: 0010 [#1] PREEMPT SMP PTI [ 3.369959] CPU: 27 PID: 0 Comm: swapper/27 Not tainted 5.7.0-rc5-00374-ge2d215d23d72 #23 [ 3.369959] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.0 05/16/2019 [ 3.369959] RIP: 0010:0x10 [ 3.369959] Code: Bad RIP value. [ 3.369959] RSP: 0000:ffffbf444018beb8 EFLAGS: 00010086 [ 3.369959] RAX: 000000000000001b RBX: ffffa04620900000 RCX: 00000000c8aab6dc [ 3.369959] RDX: 0000000000000001 RSI: ffffffffb390feaf RDI: ffffffffb3919e60 [ 3.369959] RBP: 000000000000001b R08: 0000000000000000 R09: 0000000000000101 [ 3.369959] R10: 0000000000dda899 R11: 0000000001d417ad R12: 0000000000000000 [ 3.369959] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 3.369959] FS: 0000000000000000(0000) GS:ffffa04627ac0000(0000) knlGS:0000000000000000 [ 3.369959] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3.369959] CR2: ffffffffffffffe6 CR3: 000000101bcba002 CR4: 00000000003606e0 [ 3.369959] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 3.369959] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 3.369959] Call Trace: [ 3.369959] ? default_idle+0x1c/0x190 [ 3.369959] ? do_idle+0x1cd/0x230 [ 3.369959] ? cpu_startup_entry+0x19/0x20 [ 3.369959] ? secondary_startup_64+0xa4/0xb0 [ 3.369959] Modules linked in: crc32c_intel hv_vmbus(+) [ 3.369959] CR2: 0000000000000010 [ 3.369959] ---[ end trace 58ded6105ec75719 ]--- [ 3.369959] RIP: 0010:0x10 [ 3.369959] Code: Bad RIP value. [ 3.369959] RSP: 0000:ffffbf444018beb8 EFLAGS: 00010086 [ 3.369959] RAX: 000000000000001b RBX: ffffa04620900000 RCX: 00000000c8aab6dc [ 3.369959] RDX: 0000000000000001 RSI: ffffffffb390feaf RDI: ffffffffb3919e60 [ 3.369959] RBP: 000000000000001b R08: 0000000000000000 R09: 0000000000000101 [ 3.369959] R10: 0000000000dda899 R11: 0000000001d417ad R12: 0000000000000000 [ 3.369959] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 3.369959] FS: 0000000000000000(0000) GS:ffffa04627ac0000(0000) knlGS:0000000000000000 [ 3.369959] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3.369959] CR2: ffffffffffffffe6 CR3: 000000101bcba002 CR4: 00000000003606e0 [ 3.369959] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 3.369959] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 3.369959] Kernel panic - not syncing: Attempted to kill the idle task! [ 3.369959] Kernel Offset: 0x31800000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 3.369959] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]--- > --- > arch/x86/entry/entry_32.S | 14 -------------- > arch/x86/entry/entry_64.S | 17 ----------------- > arch/x86/hyperv/hv_init.c | 9 +++------ > arch/x86/include/asm/acrn.h | 11 ----------- > arch/x86/include/asm/apic.h | 20 -------------------- > arch/x86/include/asm/idtentry.h | 10 ++++++++++ > arch/x86/include/asm/mshyperv.h | 13 ------------- > arch/x86/kernel/cpu/acrn.c | 9 ++++----- > arch/x86/kernel/cpu/mshyperv.c | 22 ++++++++++------------ > 9 files changed, 27 insertions(+), 98 deletions(-) > > --- a/arch/x86/entry/entry_32.S > +++ b/arch/x86/entry/entry_32.S > @@ -1342,20 +1342,6 @@ BUILD_INTERRUPT3(xen_hvm_callback_vector > xen_evtchn_do_upcall) > #endif > > - > -#if IS_ENABLED(CONFIG_HYPERV) > - > -BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, > - hyperv_vector_handler) > - > -BUILD_INTERRUPT3(hyperv_reenlightenment_vector, HYPERV_REENLIGHTENMENT_VECTOR, > - hyperv_reenlightenment_intr) > - > -BUILD_INTERRUPT3(hv_stimer0_callback_vector, HYPERV_STIMER0_VECTOR, > - hv_stimer0_vector_handler) > - > -#endif /* CONFIG_HYPERV */ > - > SYM_CODE_START_LOCAL_NOALIGN(handle_exception) > /* the function address is in %gs's slot on the stack */ > SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1 > --- a/arch/x86/entry/entry_64.S > +++ b/arch/x86/entry/entry_64.S > @@ -1116,23 +1116,6 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTO > xen_hvm_callback_vector xen_evtchn_do_upcall > #endif > > - > -#if IS_ENABLED(CONFIG_HYPERV) > -apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ > - hyperv_callback_vector hyperv_vector_handler > - > -apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \ > - hyperv_reenlightenment_vector hyperv_reenlightenment_intr > - > -apicinterrupt3 HYPERV_STIMER0_VECTOR \ > - hv_stimer0_callback_vector hv_stimer0_vector_handler > -#endif /* CONFIG_HYPERV */ > - > -#if IS_ENABLED(CONFIG_ACRN_GUEST) > -apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ > - acrn_hv_callback_vector acrn_hv_vector_handler > -#endif > - > /* > * Save all registers in pt_regs, and switch gs if needed. > * Use slow, but surefire "are we in kernel?" check. > --- a/arch/x86/hyperv/hv_init.c > +++ b/arch/x86/hyperv/hv_init.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -153,15 +154,11 @@ static inline bool hv_reenlightenment_av > ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT; > } > > -__visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs) > +DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_reenlightenment) > { > - entering_ack_irq(); > - > + ack_APIC_irq(); > inc_irq_stat(irq_hv_reenlightenment_count); > - > schedule_delayed_work(&hv_reenlightenment_work, HZ/10); > - > - exiting_irq(); > } > > void set_hv_tscchange_cb(void (*cb)(void)) > --- a/arch/x86/include/asm/acrn.h > +++ /dev/null > @@ -1,11 +0,0 @@ > -/* SPDX-License-Identifier: GPL-2.0 */ > -#ifndef _ASM_X86_ACRN_H > -#define _ASM_X86_ACRN_H > - > -extern void acrn_hv_callback_vector(void); > -#ifdef CONFIG_TRACING > -#define trace_acrn_hv_callback_vector acrn_hv_callback_vector > -#endif > - > -extern void acrn_hv_vector_handler(struct pt_regs *regs); > -#endif /* _ASM_X86_ACRN_H */ > --- a/arch/x86/include/asm/apic.h > +++ b/arch/x86/include/asm/apic.h > @@ -519,26 +519,6 @@ static inline bool apic_id_is_primary_th > static inline void apic_smt_update(void) { } > #endif > > -extern void irq_enter(void); > -extern void irq_exit(void); > - > -static inline void entering_irq(void) > -{ > - irq_enter(); > - kvm_set_cpu_l1tf_flush_l1d(); > -} > - > -static inline void entering_ack_irq(void) > -{ > - entering_irq(); > - ack_APIC_irq(); > -} > - > -static inline void exiting_irq(void) > -{ > - irq_exit(); > -} > - > extern void ioapic_zap_locks(void); > > #endif /* _ASM_X86_APIC_H */ > --- a/arch/x86/include/asm/idtentry.h > +++ b/arch/x86/include/asm/idtentry.h > @@ -608,6 +608,16 @@ DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKE > DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested_ipi); > #endif > > +#if IS_ENABLED(CONFIG_HYPERV) > +DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback); > +DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment); > +DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_STIMER0_VECTOR, sysvec_hyperv_stimer0); > +#endif > + > +#if IS_ENABLED(CONFIG_ACRN_GUEST) > +DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_acrn_hv_callback); > +#endif > + > #undef X86_TRAP_OTHER > > #endif > --- a/arch/x86/include/asm/mshyperv.h > +++ b/arch/x86/include/asm/mshyperv.h > @@ -54,20 +54,8 @@ typedef int (*hyperv_fill_flush_list_fun > vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK); > #define hv_get_raw_timer() rdtsc_ordered() > > -void hyperv_callback_vector(void); > -void hyperv_reenlightenment_vector(void); > -#ifdef CONFIG_TRACING > -#define trace_hyperv_callback_vector hyperv_callback_vector > -#endif > void hyperv_vector_handler(struct pt_regs *regs); > > -/* > - * Routines for stimer0 Direct Mode handling. > - * On x86/x64, there are no percpu actions to take. > - */ > -void hv_stimer0_vector_handler(struct pt_regs *regs); > -void hv_stimer0_callback_vector(void); > - > static inline void hv_enable_stimer0_percpu_irq(int irq) {} > static inline void hv_disable_stimer0_percpu_irq(int irq) {} > > @@ -226,7 +214,6 @@ void hyperv_setup_mmu_ops(void); > void *hv_alloc_hyperv_page(void); > void *hv_alloc_hyperv_zeroed_page(void); > void hv_free_hyperv_page(unsigned long addr); > -void hyperv_reenlightenment_intr(struct pt_regs *regs); > void set_hv_tscchange_cb(void (*cb)(void)); > void clear_hv_tscchange_cb(void); > void hyperv_stop_tsc_emulation(void); > --- a/arch/x86/kernel/cpu/acrn.c > +++ b/arch/x86/kernel/cpu/acrn.c > @@ -10,10 +10,10 @@ > */ > > #include > -#include > #include > #include > #include > +#include > #include > > static uint32_t __init acrn_detect(void) > @@ -24,7 +24,7 @@ static uint32_t __init acrn_detect(void) > static void __init acrn_init_platform(void) > { > /* Setup the IDT for ACRN hypervisor callback */ > - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, acrn_hv_callback_vector); > + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_acrn_hv_callback); > } > > static bool acrn_x2apic_available(void) > @@ -39,7 +39,7 @@ static bool acrn_x2apic_available(void) > > static void (*acrn_intr_handler)(void); > > -__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs) > +DEFINE_IDTENTRY_SYSVEC(sysvec_acrn_hv_callback) > { > struct pt_regs *old_regs = set_irq_regs(regs); > > @@ -50,13 +50,12 @@ static void (*acrn_intr_handler)(void); > * will block the interrupt whose vector is lower than > * HYPERVISOR_CALLBACK_VECTOR. > */ > - entering_ack_irq(); > + ack_APIC_irq(); > inc_irq_stat(irq_hv_callback_count); > > if (acrn_intr_handler) > acrn_intr_handler(); > > - exiting_irq(); > set_irq_regs(old_regs); > } > > --- a/arch/x86/kernel/cpu/mshyperv.c > +++ b/arch/x86/kernel/cpu/mshyperv.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -40,11 +41,10 @@ static void (*hv_stimer0_handler)(void); > static void (*hv_kexec_handler)(void); > static void (*hv_crash_handler)(struct pt_regs *regs); > > -__visible void __irq_entry hyperv_vector_handler(struct pt_regs *regs) > +DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback) > { > struct pt_regs *old_regs = set_irq_regs(regs); > > - entering_irq(); > inc_irq_stat(irq_hv_callback_count); > if (vmbus_handler) > vmbus_handler(); > @@ -52,7 +52,6 @@ static void (*hv_crash_handler)(struct p > if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED) > ack_APIC_irq(); > > - exiting_irq(); > set_irq_regs(old_regs); > } > > @@ -73,19 +72,16 @@ EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq); > * Routines to do per-architecture handling of stimer0 > * interrupts when in Direct Mode > */ > - > -__visible void __irq_entry hv_stimer0_vector_handler(struct pt_regs *regs) > +DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_stimer0) > { > struct pt_regs *old_regs = set_irq_regs(regs); > > - entering_irq(); > inc_irq_stat(hyperv_stimer0_count); > if (hv_stimer0_handler) > hv_stimer0_handler(); > add_interrupt_randomness(HYPERV_STIMER0_VECTOR, 0); > ack_APIC_irq(); > > - exiting_irq(); > set_irq_regs(old_regs); > } > > @@ -331,17 +327,19 @@ static void __init ms_hyperv_init_platfo > x86_platform.apic_post_init = hyperv_init; > hyperv_setup_mmu_ops(); > /* Setup the IDT for hypervisor callback */ > - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); > + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback); > > /* Setup the IDT for reenlightenment notifications */ > - if (ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT) > + if (ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT) { > alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR, > - hyperv_reenlightenment_vector); > + asm_sysvec_hyperv_reenlightenment); > + } > > /* Setup the IDT for stimer0 */ > - if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) > + if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) { > alloc_intr_gate(HYPERV_STIMER0_VECTOR, > - hv_stimer0_callback_vector); > + asm_sysvec_hyperv_stimer0); > + } > > # ifdef CONFIG_SMP > smp_ops.smp_prepare_boot_cpu = hv_smp_prepare_boot_cpu; >