lkml.org 
[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 002/846] KVM: VMX: switch blocked_vcpu_on_cpu_lock to raw spinlock
    Date
    From: Marcelo Tosatti <mtosatti@redhat.com>

    commit 5f02ef741a785678930f3ff0a8b6b2b0ef1bb402 upstream.

    blocked_vcpu_on_cpu_lock is taken from hard interrupt context
    (pi_wakeup_handler), therefore it cannot sleep.

    Switch it to a raw spinlock.

    Fixes:

    [41297.066254] BUG: scheduling while atomic: CPU 0/KVM/635218/0x00010001
    [41297.066323] Preemption disabled at:
    [41297.066324] [<ffffffff902ee47f>] irq_enter_rcu+0xf/0x60
    [41297.066339] Call Trace:
    [41297.066342] <IRQ>
    [41297.066346] dump_stack_lvl+0x34/0x44
    [41297.066353] ? irq_enter_rcu+0xf/0x60
    [41297.066356] __schedule_bug.cold+0x7d/0x8b
    [41297.066361] __schedule+0x439/0x5b0
    [41297.066365] ? task_blocks_on_rt_mutex.constprop.0.isra.0+0x1b0/0x440
    [41297.066369] schedule_rtlock+0x1e/0x40
    [41297.066371] rtlock_slowlock_locked+0xf1/0x260
    [41297.066374] rt_spin_lock+0x3b/0x60
    [41297.066378] pi_wakeup_handler+0x31/0x90 [kvm_intel]
    [41297.066388] sysvec_kvm_posted_intr_wakeup_ipi+0x9d/0xd0
    [41297.066392] </IRQ>
    [41297.066392] asm_sysvec_kvm_posted_intr_wakeup_ipi+0x12/0x20
    ...

    Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/x86/kvm/vmx/posted_intr.c | 16 ++++++++--------
    1 file changed, 8 insertions(+), 8 deletions(-)

    --- a/arch/x86/kvm/vmx/posted_intr.c
    +++ b/arch/x86/kvm/vmx/posted_intr.c
    @@ -15,7 +15,7 @@
    * can find which vCPU should be waken up.
    */
    static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu);
    -static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock);
    +static DEFINE_PER_CPU(raw_spinlock_t, blocked_vcpu_on_cpu_lock);

    static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu)
    {
    @@ -121,9 +121,9 @@ static void __pi_post_block(struct kvm_v
    new.control) != old.control);

    if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) {
    - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    + raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    list_del(&vcpu->blocked_vcpu_list);
    - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    + raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    vcpu->pre_pcpu = -1;
    }
    }
    @@ -154,11 +154,11 @@ int pi_pre_block(struct kvm_vcpu *vcpu)
    local_irq_disable();
    if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) {
    vcpu->pre_pcpu = vcpu->cpu;
    - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    + raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    list_add_tail(&vcpu->blocked_vcpu_list,
    &per_cpu(blocked_vcpu_on_cpu,
    vcpu->pre_pcpu));
    - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    + raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu));
    }

    do {
    @@ -215,7 +215,7 @@ void pi_wakeup_handler(void)
    struct kvm_vcpu *vcpu;
    int cpu = smp_processor_id();

    - spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
    + raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
    list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu),
    blocked_vcpu_list) {
    struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
    @@ -223,13 +223,13 @@ void pi_wakeup_handler(void)
    if (pi_test_on(pi_desc) == 1)
    kvm_vcpu_kick(vcpu);
    }
    - spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
    + raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
    }

    void __init pi_init_cpu(int cpu)
    {
    INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu));
    - spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
    + raw_spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu));
    }

    bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu)

    \
     
     \ /
      Last update: 2022-01-24 23:09    [W:2.698 / U:0.536 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site