[PATCH] KVM: riscv: Fix NACL hfence entry update order

Anup Patel anup at brainfault.org
Thu Sep 10 07:47:18 PDT 2026


On Wed, Aug 26, 2026 at 1:20 PM Zongmin Zhou <min_halo at 163.com> wrote:
>
> From: Zongmin Zhou <zhouzongmin at kylinos.cn>
>
> The SBI v3.0 specification (section 15.1.2) requires a nested HFENCE
> entry to be populated as follows:
> 1) find an unused entry with Config.Pending == 0
> 2) update the Page_Number and Page_Count words
> 3) update the Config word with Config.Pending set
>
> __kvm_riscv_nacl_hfence() writes the Config word first, so the SBI
> implementation (or NACL hardware) can observe a pending entry with
> pnum/pcount values left over from the previous use of that entry,
> resulting in incorrect TLB flush ranges.
>
> Write pnum and pcount first and the Config word last. Since the
> consumer is an external agent on coherent shared memory, use
> WRITE_ONCE() to stop the compiler from reordering the stores and
> smp_wmb() to make the parameter words globally visible before the
> Pending bit is set.
>
> Fixes: d466c19cead5 ("RISC-V: KVM: Add common nested acceleration support")
> Signed-off-by: Zongmin Zhou <zhouzongmin at kylinos.cn>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Queued this patch as fix for Linux-7.3-rcX

Thanks,
Anup

> ---
>  arch/riscv/kvm/nacl.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kvm/nacl.c b/arch/riscv/kvm/nacl.c
> index 9aff03c4f667..a5cda9a65156 100644
> --- a/arch/riscv/kvm/nacl.c
> +++ b/arch/riscv/kvm/nacl.c
> @@ -42,12 +42,24 @@ void __kvm_riscv_nacl_hfence(void *shmem,
>                 }
>         }
>
> -       entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
> -       *entp = cpu_to_lelong(control);
> +       /*
> +        * Per SBI v3.0 section 15.1.2, the Page_Number and Page_Count
> +        * words must be updated before the Config word with its Pending
> +        * bit set. WRITE_ONCE() stops the compiler from reordering the
> +        * stores and smp_wmb() makes the parameter words globally
> +        * visible to the SBI implementation (or NACL hardware) before
> +        * the Pending bit is set.
> +        */
>         entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PNUM(i);
> -       *entp = cpu_to_lelong(page_num);
> +       WRITE_ONCE(*entp, cpu_to_lelong(page_num));
>         entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PCOUNT(i);
> -       *entp = cpu_to_lelong(page_count);
> +       WRITE_ONCE(*entp, cpu_to_lelong(page_count));
> +
> +       /* Ensure the parameter words are visible before the Pending bit */
> +       smp_wmb();
> +
> +       entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
> +       WRITE_ONCE(*entp, cpu_to_lelong(control));
>  }
>
>  int kvm_riscv_nacl_enable(void)
> --
> 2.34.1
>
>
> No virus found
>                 Checked by Hillstone Network AntiVirus
>



More information about the linux-riscv mailing list