[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200527014616.GA123239@debian-boqun.qqnc3lrjykvubdpftowmye0fmh.lx.internal.cloudapp.net>
Date: Wed, 27 May 2020 09:46:16 +0800
From: Boqun Feng <boqun.feng@...il.com>
To: Thomas Gleixner <tglx@...utronix.de>
Cc: LKML <linux-kernel@...r.kernel.org>,
Andy Lutomirski <luto@...nel.org>,
Andrew Cooper <andrew.cooper3@...rix.com>,
X86 ML <x86@...nel.org>,
"Paul E. McKenney" <paulmck@...nel.org>,
Alexandre Chartre <alexandre.chartre@...cle.com>,
Frederic Weisbecker <frederic@...nel.org>,
Paolo Bonzini <pbonzini@...hat.com>,
Sean Christopherson <sean.j.christopherson@...el.com>,
Masami Hiramatsu <mhiramat@...nel.org>,
Petr Mladek <pmladek@...e.com>,
Steven Rostedt <rostedt@...dmis.org>,
Joel Fernandes <joel@...lfernandes.org>,
Boris Ostrovsky <boris.ostrovsky@...cle.com>,
Juergen Gross <jgross@...e.com>,
Brian Gerst <brgerst@...il.com>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Josh Poimboeuf <jpoimboe@...hat.com>,
Will Deacon <will@...nel.org>,
Tom Lendacky <thomas.lendacky@....com>,
Wei Liu <wei.liu@...nel.org>,
Michael Kelley <mikelley@...rosoft.com>,
Jason Chen CJ <jason.cj.chen@...el.com>,
Zhao Yakui <yakui.zhao@...el.com>,
"Peter Zijlstra (Intel)" <peterz@...radead.org>
Subject: Re: [patch V9 30/39] x86/entry: Convert various hypervisor vectors
to IDTENTRY_SYSVEC
Hi Thomas,
On Thu, May 21, 2020 at 10:05:43PM +0200, Thomas Gleixner wrote:
> From: Thomas Gleixner <tglx@...utronix.de>
>
> 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 <tglx@...utronix.de>
> Acked-by: Andy Lutomirski <luto@...nel.org>
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 <asm/hypervisor.h>
> #include <asm/hyperv-tlfs.h>
> #include <asm/mshyperv.h>
> +#include <asm/idtentry.h>
> #include <linux/version.h>
> #include <linux/vmalloc.h>
> #include <linux/mm.h>
> @@ -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 <linux/interrupt.h>
> -#include <asm/acrn.h>
> #include <asm/apic.h>
> #include <asm/desc.h>
> #include <asm/hypervisor.h>
> +#include <asm/idtentry.h>
> #include <asm/irq_regs.h>
>
> 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 <asm/hyperv-tlfs.h>
> #include <asm/mshyperv.h>
> #include <asm/desc.h>
> +#include <asm/idtentry.h>
> #include <asm/irq_regs.h>
> #include <asm/i8259.h>
> #include <asm/apic.h>
> @@ -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;
>
View attachment "hyperv-config" of type "text/plain" (249046 bytes)
Powered by blists - more mailing lists