From: Dylan.Wu Date: Wed, 1 Jul 2026 07:52:39 +0000 (-0400) Subject: riscv: kvm: Skip TLB flush when G-stage PTE becomes valid with Svvptc X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1cc935ec2d87673e3c52ba04f943ab1276c0635b;p=thirdparty%2Fkernel%2Flinux.git riscv: kvm: Skip TLB flush when G-stage PTE becomes valid with Svvptc The gstage_tlb_flush() in the kvm_riscv_gstage_set_pte() is not needed when an invalid G-stage PTE becomes valid and Svvptc extension is available because new valid PTEs become visible to the page-table walker within a bounded time. Assisted-by: YuanSheng: deepseek-v4-pro Co-developed-by: Quan Zhou Signed-off-by: Quan Zhou Signed-off-by: Dylan.Wu Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260701075239.95542-1-fredwudi0305@gmail.com Signed-off-by: Anup Patel --- diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index c4c3b79567f1..b0474fcf065a 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -5,11 +5,13 @@ */ #include +#include #include #include #include #include #include +#include #ifdef CONFIG_64BIT unsigned long kvm_riscv_gstage_max_pgd_levels __ro_after_init = 3; @@ -171,8 +173,10 @@ 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); }