From: sashiko-bot@kernel.org
To: "Andrew Jones" <andrew.jones@linux.dev>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v2] RISC-V: KVM: Convert IMSIC vsfile_lock to a raw spinlock
Date: Mon, 19 Oct 2026 13:57:48 +0000 [thread overview]
Message-ID: <sashiko-outbox-177242@kernel.org> (raw)
In-Reply-To: <20261019134709.2610129-1-andrew.jones@linux.dev>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] RISC-V: KVM: ABBA deadlock on vsfile_lock in kvm_riscv_vcpu_aia_imsic_put()
--
commit 87fb1e91c477214da3458429ee5e7b7ff86ac173
Author: Andrew Jones <andrew.jones@linux.dev>
RISC-V: KVM: Convert IMSIC vsfile_lock to a raw spinlock
This commit converts imsic->vsfile_lock from rwlock_t to raw_spinlock_t
so that kvm_riscv_vcpu_aia_imsic_put() does not sleep while holding the
scheduler runqueue lock on PREEMPT_RT.
> diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
> index f17dc559a7092..bad0ce20edc11 100644
> --- a/arch/riscv/kvm/aia_imsic.c
> +++ b/arch/riscv/kvm/aia_imsic.c
[ ... ]
> @@ -727,10 +727,10 @@ void kvm_riscv_vcpu_aia_imsic_put(struct kvm_vcpu *vcpu)
> if (!kvm_vcpu_is_blocking(vcpu))
> return;
>
> - read_lock_irqsave(&imsic->vsfile_lock, flags);
> + raw_spin_lock_irqsave(&imsic->vsfile_lock, flags);
> if (imsic->vsfile_cpu > -1)
> csr_set(CSR_HGEIE, BIT(imsic->vsfile_hgei));
> - read_unlock_irqrestore(&imsic->vsfile_lock, flags);
> + raw_spin_unlock_irqrestore(&imsic->vsfile_lock, flags);
> }
[ ... ]
> @@ -975,7 +975,7 @@ int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type,
> }
> isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
>
> - read_lock_irqsave(&imsic->vsfile_lock, flags);
> + raw_spin_lock_irqsave(&imsic->vsfile_lock, flags);
>
> rc = 0;
> vsfile_hgei = imsic->vsfile_hgei;
> @@ -990,7 +990,7 @@ int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type,
> isel, val, 0, 0);
> }
>
> - read_unlock_irqrestore(&imsic->vsfile_lock, flags);
> + raw_spin_unlock_irqrestore(&imsic->vsfile_lock, flags);
>
> if (!rc && vsfile_cpu >= 0)
> rc = imsic_vsfile_rw(vsfile_hgei, vsfile_cpu, imsic->nr_eix,
> @@ -1052,7 +1052,7 @@ int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
> if (imsic->nr_msis <= iid)
> return -EINVAL;
>
> - read_lock_irqsave(&imsic->vsfile_lock, flags);
> + raw_spin_lock_irqsave(&imsic->vsfile_lock, flags);
>
> if (imsic->vsfile_cpu >= 0) {
> writel(iid, imsic->vsfile_va + IMSIC_MMIO_SETIPNUM_LE);
> @@ -1062,7 +1062,7 @@ int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
> imsic_swfile_extirq_update(vcpu);
> }
>
> - read_unlock_irqrestore(&imsic->vsfile_lock, flags);
> + raw_spin_unlock_irqrestore(&imsic->vsfile_lock, flags);
>
> return 0;
> }
[Severity: High]
Can converting vsfile_lock from rwlock_t to an exclusive raw_spinlock_t
cause an ABBA deadlock between rq->__lock and imsic->vsfile_lock when
imsic->vsfile_cpu < 0 (such as in KVM_DEV_RISCV_AIA_MODE_EMUL, in
KVM_DEV_RISCV_AIA_MODE_AUTO when HGEI lines are exhausted, or after
kvm_riscv_vcpu_aia_imsic_release())?
When a vCPU blocks in kvm_vcpu_block(), prepare_to_rcuwait() sets the
rcuwait task before schedule() is called, making kvm_vcpu_is_blocking()
return true. During the context switch out on CPU 0, rq->__lock is held
and prev->on_cpu is still 1 when the preempt notifier runs:
CPU 0:
__schedule() [holds rq->__lock, prev->on_cpu == 1]
-> context_switch()
-> prepare_task_switch()
-> fire_sched_out_preempt_notifiers()
-> kvm_sched_out()
-> kvm_arch_vcpu_put()
-> kvm_riscv_vcpu_aia_put()
-> kvm_riscv_vcpu_aia_imsic_put()
-> raw_spin_lock_irqsave(&imsic->vsfile_lock, flags)
This establishes the lock ordering rq->__lock -> imsic->vsfile_lock.
Concurrently on CPU 1, kvm_riscv_vcpu_aia_imsic_inject() or
kvm_riscv_aia_imsic_rw_attr() acquires imsic->vsfile_lock and, when
imsic->vsfile_cpu < 0, calls imsic_swfile_extirq_update() while still
holding imsic->vsfile_lock:
CPU 1:
kvm_riscv_vcpu_aia_imsic_inject() / kvm_riscv_aia_imsic_rw_attr()
-> raw_spin_lock_irqsave(&imsic->vsfile_lock, flags)
-> imsic_swfile_extirq_update()
-> kvm_riscv_vcpu_set_interrupt()
-> kvm_vcpu_kick()
-> kvm_vcpu_wake_up()
-> rcuwait_wake_up()
-> wake_up_process()
-> try_to_wake_up()
Inside try_to_wake_up(), CPU 1 acquires p->pi_lock and either spins
waiting for CPU 0's rq->__lock (for example in ttwu_runnable() when
delayed dequeue keeps p->on_rq set, or if preempted after
prepare_to_rcuwait()) or spins in smp_cond_load_acquire(&p->on_cpu, !VAL)
waiting for CPU 0 to finish switching out the vCPU task. Meanwhile, CPU 0
is spinning on imsic->vsfile_lock in prepare_task_switch() before
finish_task() can clear p->on_cpu or release rq->__lock.
Previously, both paths took read_lock_irqsave(&imsic->vsfile_lock, flags)
and did not block each other unless a writer was active (and writers run
with vcpu->mutex held outside schedule()). With raw_spinlock_t, these two
paths now serialize against each other and can deadlock.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261019134709.2610129-1-andrew.jones@linux.dev?part=1
next prev parent reply other threads:[~2026-10-19 13:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-19 13:47 [PATCH v2] RISC-V: KVM: Convert IMSIC vsfile_lock to a raw spinlock Andrew Jones
2026-10-19 13:57 ` sashiko-bot [this message]
2026-10-19 17:16 ` Andrew Jones
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=sashiko-outbox-177242@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=andrew.jones@linux.dev \
--cc=kvm@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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