The SBI NACL interface requires software to write Page_Number and
Page_Count before publishing an HFENCE entry with Config.Pending set.
__kvm_riscv_nacl_hfence() currently stores the pending configuration first.
Write the payload first and order those stores before publishing the
configuration word with WRITE_ONCE(). Use a write barrier that also
applies to UP kernels, since the consumer is outside the Linux SMP
domain.
Keep nacl_hfence_mkconfig() unchanged: setting Pending in a local value
does not publish the entry. The shared-memory store is the publication
point.
The issue was found by our static-analysis tool and manually reviewed.
Fixes: d466c19cead5 ("RISC-V: KVM: Add common nested acceleration support")
Assisted-by: GPT-5
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
---
diff --git a/arch/riscv/kvm/nacl.c b/arch/riscv/kvm/nacl.c
index 9aff03c4..c5c4907a 100644
--- a/arch/riscv/kvm/nacl.c
+++ b/arch/riscv/kvm/nacl.c
@@ -5,6 +5,7 @@
#include <linux/kvm_host.h>
#include <linux/vmalloc.h>
+#include <asm/barrier.h>
#include <asm/kvm_nacl.h>
DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_available);
@@ -42,12 +43,15 @@ again:
}
}
- entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
- *entp = cpu_to_lelong(control);
entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PNUM(i);
*entp = cpu_to_lelong(page_num);
entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PCOUNT(i);
*entp = cpu_to_lelong(page_count);
+
+ /* Publish the payload before setting Config.Pending. */
+ wmb();
+ entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
+ WRITE_ONCE(*entp, cpu_to_lelong(control));
}
int kvm_riscv_nacl_enable(void)
base-commit: 4d7d9486c04d917265f64c55bd23b2cc4fe7749c
On Sun, Sep 6, 2026 at 1:37 PM Pengpeng Hou <hppiscas@163.com> wrote:
>
> The SBI NACL interface requires software to write Page_Number and
> Page_Count before publishing an HFENCE entry with Config.Pending set.
> __kvm_riscv_nacl_hfence() currently stores the pending configuration first.
>
> Write the payload first and order those stores before publishing the
> configuration word with WRITE_ONCE(). Use a write barrier that also
> applies to UP kernels, since the consumer is outside the Linux SMP
> domain.
>
> Keep nacl_hfence_mkconfig() unchanged: setting Pending in a local value
> does not publish the entry. The shared-memory store is the publication
> point.
>
> The issue was found by our static-analysis tool and manually reviewed.
>
> Fixes: d466c19cead5 ("RISC-V: KVM: Add common nested acceleration support")
> Assisted-by: GPT-5
> Signed-off-by: Pengpeng Hou <hppiscas@163.com>
There was another patch from Zongmin Zhou which is relatively
more complete hence I have merged that one.
Regards,
Anup
> ---
>
> diff --git a/arch/riscv/kvm/nacl.c b/arch/riscv/kvm/nacl.c
> index 9aff03c4..c5c4907a 100644
> --- a/arch/riscv/kvm/nacl.c
> +++ b/arch/riscv/kvm/nacl.c
> @@ -5,6 +5,7 @@
>
> #include <linux/kvm_host.h>
> #include <linux/vmalloc.h>
> +#include <asm/barrier.h>
> #include <asm/kvm_nacl.h>
>
> DEFINE_STATIC_KEY_FALSE(kvm_riscv_nacl_available);
> @@ -42,12 +43,15 @@ again:
> }
> }
>
> - entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
> - *entp = cpu_to_lelong(control);
> entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PNUM(i);
> *entp = cpu_to_lelong(page_num);
> entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_PCOUNT(i);
> *entp = cpu_to_lelong(page_count);
> +
> + /* Publish the payload before setting Config.Pending. */
> + wmb();
> + entp = shmem + SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG(i);
> + WRITE_ONCE(*entp, cpu_to_lelong(control));
> }
>
> int kvm_riscv_nacl_enable(void)
>
> base-commit: 4d7d9486c04d917265f64c55bd23b2cc4fe7749c
>
© 2016 - 2026 Red Hat, Inc.