* [PATCH] riscv: kvm: Skip preventive hfence.gvma for new G-stage mappings with Svvptc
@ 2026-07-01 7:52 Dylan.Wu
2026-07-01 8:10 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Dylan.Wu @ 2026-07-01 7:52 UTC (permalink / raw)
To: anup, palmer
Cc: atish.patra, pjw, aou, alex, zhouquan, kvm, kvm-riscv,
linux-riscv, linux-kernel, Dylan.Wu
For Invalid->Valid G-stage leaf PTE updates, the flush in
kvm_riscv_gstage_set_pte() is preventive. When Svvptc is available, new
valid PTEs become visible to the page-table walker within a bounded
time, so an immediate hfence.gvma is unnecessary.
Skip gstage_tlb_flush() for that case. Permission-restricting updates
continue to use the existing flush path.
Assisted-by: YuanSheng: deepseek-v4-pro
Co-developed-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Dylan.Wu <fredwudi0305@gmail.com>
---
arch/riscv/kvm/gstage.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c
index c4c3b7956..7b805112d 100644
--- a/arch/riscv/kvm/gstage.c
+++ b/arch/riscv/kvm/gstage.c
@@ -10,6 +10,8 @@
#include <linux/module.h>
#include <linux/pgtable.h>
#include <asm/kvm_gstage.h>
+#include <asm/cpufeature.h>
+#include <asm/hwcap.h>
#ifdef CONFIG_64BIT
unsigned long kvm_riscv_gstage_max_pgd_levels __ro_after_init = 3;
@@ -171,8 +173,11 @@ int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage,
}
if (pte_val(*ptep) != pte_val(map->pte)) {
+ bool was_invalid = !pte_val(*ptep);
set_pte(ptep, map->pte);
- if (gstage_pte_leaf(ptep))
+ if (gstage_pte_leaf(ptep) &&
+ !(was_invalid &&
+ riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)))
gstage_tlb_flush(gstage, current_level, map->addr);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] riscv: kvm: Skip preventive hfence.gvma for new G-stage mappings with Svvptc
2026-07-01 7:52 [PATCH] riscv: kvm: Skip preventive hfence.gvma for new G-stage mappings with Svvptc Dylan.Wu
@ 2026-07-01 8:10 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-07-01 8:10 UTC (permalink / raw)
To: Dylan.Wu; +Cc: kvm
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing `smp_wmb()` before linking newly allocated intermediate page tables, exposing uninitialized memory to concurrent hardware page table walkers.
- [High] Non-atomic write-protection of G-stage PTEs clobbers hardware Access/Dirty bit updates.
--
commit 8c5791358f444706f77027dbaa2cea7abc95b1e0
Author: Dylan.Wu <fredwudi0305@gmail.com>
riscv: kvm: Skip preventive hfence.gvma for new G-stage mappings with Svvptc
For Invalid->Valid G-stage leaf PTE updates, the flush in
kvm_riscv_gstage_set_pte() is preventive. When Svvptc is available, new
valid PTEs become visible to the page-table walker within a bounded
time, so an immediate hfence.gvma is unnecessary. Skip gstage_tlb_flush()
for that case.
> diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c
> index c4c3b79567f10..7b805112d2829 100644
> --- a/arch/riscv/kvm/gstage.c
> +++ b/arch/riscv/kvm/gstage.c
[ ... ]
> @@ -171,8 +173,11 @@ int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage,
[Severity: High]
This isn't a bug introduced by this patch, but does
kvm_riscv_gstage_set_pte() need an smp_wmb() before linking a newly
allocated intermediate page table?
When a new page table is allocated during a guest page fault, the setup
looks like this:
next_ptep = kvm_mmu_memory_cache_alloc(pcache);
if (!next_ptep)
return -ENOMEM;
set_pte(ptep, pfn_pte(PFN_DOWN(__pa(next_ptep)),
__pgprot(_PAGE_TABLE)));
Without a memory barrier before set_pte(), the zeroing of the newly
allocated page table could be delayed past its publication in the parent
page table.
If a concurrent hardware page table walker follows the pointer to the new
page table and observes uninitialized memory, could it interpret random old
data as valid PTEs and cause wild memory accesses or guest memory
corruption?
> }
>
> if (pte_val(*ptep) != pte_val(map->pte)) {
> + bool was_invalid = !pte_val(*ptep);
> set_pte(ptep, map->pte);
> - if (gstage_pte_leaf(ptep))
> + if (gstage_pte_leaf(ptep) &&
> + !(was_invalid &&
> + riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)))
> gstage_tlb_flush(gstage, current_level, map->addr);
> }
>
[Severity: High]
This is a pre-existing issue, but can the non-atomic write-protection in
kvm_riscv_gstage_op_pte() clobber hardware Access/Dirty bit updates?
During dirty logging, GSTAGE_OP_WP uses a non-atomic read-modify-write
to clear the write bit:
else if (op == GSTAGE_OP_WP)
set_pte(ptep, __pte(pte_val(ptep_get(ptep)) & ~_PAGE_WRITE));
If the hardware page-table walker asynchronously updates the Access or
Dirty bit between ptep_get() and set_pte(), would that hardware update be
silently overwritten and lost?
Losing a Dirty bit might cause KVM to treat a modified page as clean
during dirty logging. Could this lead to silent data corruption during
live migration since the modified guest data wouldn't be transferred?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260701075239.95542-1-fredwudi0305@gmail.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-01 8:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-01 7:52 [PATCH] riscv: kvm: Skip preventive hfence.gvma for new G-stage mappings with Svvptc Dylan.Wu
2026-07-01 8:10 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox