[PATCH] RISC-V: KVM: Order IMSIC VS-file write before releasing vsfile_lock
Anup Patel
anup.patel at oss.qualcomm.com
Fri Nov 13 00:00:42 PST 2026
On Fri, Oct 23, 2026 at 7:56 PM Oleksii Kurochko
<oleksii.kurochko at gmail.com> wrote:
>
> kvm_riscv_vcpu_aia_imsic_inject() writes the interrupt identity to the
> SETIPNUM register of the vCPU's IMSIC VS-file while holding vsfile_lock
> for reading. The lock keeps the VS-file from being switched under the
> injector: kvm_riscv_vcpu_aia_imsic_update() and
> kvm_riscv_vcpu_aia_imsic_release() take it for writing to move the vCPU
> to a new VS-file or to the SW-file, then read and clear the old VS-file
> and free its HGEI line.
>
> On RISC-V, writel() is followed only by mmiowb_set_pending(). The
> trailing "fence o,w" is deferred to spin_unlock() by the mmiowb()
> tracking, and rwlocks don't take part in that tracking:
> queued_read_unlock() issues just "fence rw,w" before the AMO, which
> doesn't order device output. So the SETIPNUM write can still be in
> flight after another hart has observed vsfile_lock being released. If
> the old VS-file is read and cleared before the write lands, the
> interrupt is lost. If the HGEI line has already been handed out
> again, the interrupt ends up in another vCPU's VS-file.
>
> Add an explicit RISCV_FENCE(o, w) after the write to the VS-file, which
> is what spin_unlock() would issue via mmiowb().
>
> Fixes: db8b7e97d613 ("RISC-V: KVM: Add in-kernel virtualization of AIA IMSIC")
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko at gmail.com>
> ---
> Why RISCV_FENCE(o, w) and not mmiowb():
>
> - Since the mmiowb() rework in v5.2 (e.g. commit 60ca1e5a200c
> ("mmiowb: Hook up mmiowb helpers to spinlocks and generic I/O
> accessors")), mmiowb() is an implementation detail of the spinlock
> code. Explicit invocations were removed from drivers by commit
> fb24ea52f78e ("drivers: Remove explicit invocations of mmiowb()") and
> from the documentation by commit 915530396c78 ("Documentation: Kill
> all references to mmiowb()"), so adding a new direct caller would go
> against that.
>
> - RISCV_FENCE(o, w) states exactly the ordering needed here (device
> output before the store that releases the lock), which is fine for
> arch-specific code, and it is the same instruction mmiowb() expands to
> on RISC-V. wmb() ("fence ow,ow") would also work but is stronger than
> required.
>
> Scope: this only orders the write before the lock release. Whether a
> write that is already in global memory order is guaranteed to have
> taken effect in the old VS-file before kvm_riscv_vcpu_aia_imsic_update()
> or kvm_riscv_vcpu_aia_imsic_release() reads and clears it is a separate
> question, see https://github.com/riscv/riscv-aia/issues/172. If it
> isn't, these paths will also need to drain the old VS-file, and such a
> drain depends on the ordering added here.
> ---
> arch/riscv/kvm/aia_imsic.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c
> index f17dc559a709..807bb73a129a 100644
> --- a/arch/riscv/kvm/aia_imsic.c
> +++ b/arch/riscv/kvm/aia_imsic.c
> @@ -1056,6 +1056,13 @@ int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
>
> if (imsic->vsfile_cpu >= 0) {
> writel(iid, imsic->vsfile_va + IMSIC_MMIO_SETIPNUM_LE);
> + /*
> + * rwlocks don't participate in mmiowb() tracking, so order
> + * the write to the VS-file before releasing vsfile_lock,
> + * i.e. before the vCPU can be moved off this VS-file and
> + * the VS-file read and cleared.
> + */
> + RISCV_FENCE(o, w);
Another fence after every writel() is a big hammer in the path.
If the intention is to have correct contents when VS-file is read then
better place to add a fence is at the start of imsic_vsfile_local_read().
> } else {
> eix = &imsic->swfile->eix[iid / BITS_PER_TYPE(u64)];
> set_bit(iid & (BITS_PER_TYPE(u64) - 1), eix->eip);
>
> base-commit: 72d3fcf802c45d00b300f25b848a93c3a2bd7c7e
> --
> 2.56.0
>
>
> --
> kvm-riscv mailing list
> kvm-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
Regards,
Anup
More information about the linux-riscv
mailing list