From nobody Mon May 25 06:42:07 2026 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51A10361641; Sun, 17 May 2026 15:38:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032287; cv=none; b=Je0kMWrI20AZTCjEMXs1OGqik33oHZHPzS26GYmw7J7JfXi5oS/DnTQVKTeD0EKQ3aHKFHBGRNQC8hHvyju72oaZe0Vq4pRenmHymIQO2KEKGaWKIi+/X2r3FgwEM3LKlpPBgs2RwtphKRY3oVJvZMxX7z1XpMTk8ZCgCXJgoYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032287; c=relaxed/simple; bh=vqjXwYpLlPN+Svh0Oey3p87ICSbjWxqO3PUBylIq1UM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i3jfaFplz+z4wdVHBYFiooMJLIfKMMXkSyxYGeOOJYWTBBFCBCa1gqqSBEzzVqkdrVj6T1GZyvR5vgfvb65hqvKXzYWank6Xww2GPU3By3olb7TW5A3rlVSBVPLQDl2hIvLig9pPPmsW/XIMeBNrCatdSDK3FE7hTHus3CkmoVs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=Ag3HJO3k; arc=none smtp.client-ip=117.135.210.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="Ag3HJO3k" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=Js QLXeUloxPxSDxUurZ8XAjjViIbjwSl2vEzwM1rPDs=; b=Ag3HJO3k8B2qchnUoR 9HXK3xEF+q/x78VQ12mLVpxXO8uIvXu82vwdwcH84Je4028gRVJ3/vXIkH4HvaMP I1qxKZFHcNOBlOgUYLOHkfazAD6ypzCHTyDMvYT3pNapRJsdkDZISK/NYz5pWEnc /ccQVlqHy8hFx3GraoNcGFwQc= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-3 (Coremail) with SMTP id _____wA3ylwO4AlqyKW7Bw--.10227S3; Sun, 17 May 2026 23:34:41 +0800 (CST) From: Jinyu Tang To: Anup Patel , Anup Patel , Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu , Jinyu Tang Subject: [PATCH 1/5] KVM: riscv: Rely on common MMU notifier locking Date: Sun, 17 May 2026 23:34:23 +0800 Message-ID: <20260517153427.94889-2-tjytimi@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260517153427.94889-1-tjytimi@163.com> References: <20260517153427.94889-1-tjytimi@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wA3ylwO4AlqyKW7Bw--.10227S3 X-Coremail-Antispam: 1Uf129KBjvJXoW7Aw4fGw1xAFWxtw1DAF4UCFg_yoW8Arykpr WjkrZ0krWrXr4DuFyUt3WkZryj9w4vgFn7X34rJaykJrs0q3s3Ga4vqas2gF15Jrs5XFZx ZF40q3WrCry5AaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0piaFAZUUUUU= X-CM-SenderInfo: xwm13xlpl6il2tof0z/xtbC0BEZkWoJ4BGw1wAA38 Content-Type: text/plain; charset="utf-8" The common KVM invalidation paths call kvm_unmap_gfn_range() with mmu_lock already held for write. For the standard MMU notifier path, the call chain is: kvm_mmu_notifier_invalidate_range_start() kvm_handle_hva_range() kvm_unmap_gfn_range() kvm_mmu_notifier_invalidate_range_start() leaves range.lockless clear. kvm_handle_hva_range() therefore takes KVM_MMU_LOCK(kvm) before invoking the handler. The guest_memfd path has the same locking contract: __kvm_gmem_invalidate_begin() kvm_mmu_unmap_gfn_range() kvm_unmap_gfn_range() __kvm_gmem_invalidate_begin() explicitly takes KVM_MMU_LOCK(kvm) before calling kvm_mmu_unmap_gfn_range(). So remove the local trylock and make the common locking contract explicit=20 with lockdep_assert_held_write() like x86. Signed-off-by: Jinyu Tang --- arch/riscv/kvm/mmu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 2d3def024..0197e41fc 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -230,18 +230,16 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) { struct kvm_gstage gstage; - bool mmu_locked; =20 if (!kvm->arch.pgd) return false; =20 + lockdep_assert_held_write(&kvm->mmu_lock); + kvm_riscv_gstage_init(&gstage, kvm); - mmu_locked =3D spin_trylock(&kvm->mmu_lock); kvm_riscv_gstage_unmap_range(&gstage, range->start << PAGE_SHIFT, (range->end - range->start) << PAGE_SHIFT, range->may_block); - if (mmu_locked) - spin_unlock(&kvm->mmu_lock); return false; } =20 --=20 2.43.0 From nobody Mon May 25 06:42:07 2026 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8B82405C32; Sun, 17 May 2026 15:37:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032259; cv=none; b=myekS9LcKyP66w957q48fGaVdtyZB5u7gpF8io1LCN7+anBhlkU4e9xRe/3iSR2KSyOPl5wYqCeq/mgE+67+qSaeDvNotqZcT4rL2Js7ppP8eEVidjUpOevyJwx0ni+qOF8edITUJSygBBaFRE7h+HNNWtu0d0bb/+YjZJKvhqw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032259; c=relaxed/simple; bh=kjWMOo7Pn6qmPuFVc6JV4KnaXbrfUmqodz8+gUYVuFI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KUXc+Tuzula7R4PyR3EbKSx8apyL/LhueIxUUVZUDCcRWYWbVZpzjFQ8BD1nrKGP5ldW+fas7LpE4n/QbkByfBIU3QIBIuKedlwn4Uz4ffV4crd6fTYVi7w7Y3RvH2h+Iw2IeEF4f9q00EcyDB/lER06O8oM77gbYIjjYJ0WudM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=FYbpwpwg; arc=none smtp.client-ip=117.135.210.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="FYbpwpwg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=9R f9BG0sjCh68FBbnMMLHnS9NUGEPuZsSwjCC3kbcqQ=; b=FYbpwpwgIo0lGzFsbz hX6xv1NIJRlP3nRIxVATezqUzgrHq/5A4KXMmIk7VE71SuKpt/Nzxj2A7PWUlEse PEr0Mxx1WzszTftHSwhtgQ5/kl7kfwGRTuI7kppv30J+qA3REcVo7NG3BPzHKnFv WKsylKbvCCwRW7avekh618u8Y= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-3 (Coremail) with SMTP id _____wA3ylwO4AlqyKW7Bw--.10227S4; Sun, 17 May 2026 23:34:55 +0800 (CST) From: Jinyu Tang To: Anup Patel , Anup Patel , Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu , Jinyu Tang Subject: [PATCH 2/5] KVM: riscv: Use an rwlock for mmu_lock Date: Sun, 17 May 2026 23:34:24 +0800 Message-ID: <20260517153427.94889-3-tjytimi@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260517153427.94889-1-tjytimi@163.com> References: <20260517153427.94889-1-tjytimi@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wA3ylwO4AlqyKW7Bw--.10227S4 X-Coremail-Antispam: 1Uf129KBjvJXoWxXFW3uFyfuw1UWw1fXF1DZFb_yoWrZrW7pF 4q9FZxur1Sqr4kZFZrKF1DZr1DWw4vgw1fJFy5CF95AF4YyrZxZrn29342qr98Jr1xZFZ3 ZF4DJa45Ar40ywUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0ziGQ6XUUUUU= X-CM-SenderInfo: xwm13xlpl6il2tof0z/xtbC0B8clGoJ4B+ytQAA3c Content-Type: text/plain; charset="utf-8" RISC-V KVM currently uses a spinlock for mmu_lock. That serializes all G-stage MMU operations, including permission-only updates that do not allocate or free page-table pages. Use KVM's rwlock form of mmu_lock, as x86 and arm64 already do. Keep the existing map, unmap and teardown paths on the write side. This prepares RISC-V for read-side handling of G-stage permission updates. Signed-off-by: Jinyu Tang --- arch/riscv/include/asm/kvm_host.h | 2 ++ arch/riscv/kvm/gstage.c | 2 +- arch/riscv/kvm/mmu.c | 24 ++++++++++++------------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm= _host.h index 75b0a951c..60017ceec 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -48,6 +48,8 @@ =20 #define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE =20 +#define KVM_HAVE_MMU_RWLOCK + #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ KVM_DIRTY_LOG_INITIALLY_SET) =20 diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index d9fe8be2a..6f934cb4a 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -410,7 +410,7 @@ void kvm_riscv_gstage_unmap_range(struct kvm_gstage *gs= tage, * to prevent starvation and lockup detector warnings. */ if (!(gstage->flags & KVM_GSTAGE_FLAGS_LOCAL) && may_block && addr < end) - cond_resched_lock(&gstage->kvm->mmu_lock); + cond_resched_rwlock_write(&gstage->kvm->mmu_lock); } } =20 diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 0197e41fc..48f16e52f 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -26,9 +26,9 @@ static void mmu_wp_memory_region(struct kvm *kvm, int slo= t) =20 kvm_riscv_gstage_init(&gstage, kvm); =20 - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); kvm_riscv_gstage_wp_range(&gstage, start, end); - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); kvm_flush_remote_tlbs_memslot(kvm, memslot); } =20 @@ -65,9 +65,9 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phy= s_addr_t hpa, if (ret) goto out; =20 - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); ret =3D kvm_riscv_gstage_set_pte(&gstage, &pcache, &map); - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); if (ret) goto out; =20 @@ -85,9 +85,9 @@ void kvm_riscv_mmu_iounmap(struct kvm *kvm, gpa_t gpa, un= signed long size) =20 kvm_riscv_gstage_init(&gstage, kvm); =20 - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); kvm_riscv_gstage_unmap_range(&gstage, gpa, size, false); - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); } =20 void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm, @@ -131,9 +131,9 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, =20 kvm_riscv_gstage_init(&gstage, kvm); =20 - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); kvm_riscv_gstage_unmap_range(&gstage, gpa, size, false); - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); } =20 void kvm_arch_commit_memory_region(struct kvm *kvm, @@ -504,7 +504,7 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm= _memory_slot *memslot, if (logging && !is_write) writable =3D false; =20 - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); =20 if (mmu_invalidate_retry(kvm, mmu_seq)) goto out_unlock; @@ -527,7 +527,7 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm= _memory_slot *memslot, =20 out_unlock: kvm_release_faultin_page(kvm, page, ret && ret !=3D -EEXIST, writable); - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); return ret; } =20 @@ -556,7 +556,7 @@ void kvm_riscv_mmu_free_pgd(struct kvm *kvm) struct kvm_gstage gstage; void *pgd =3D NULL; =20 - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); if (kvm->arch.pgd) { kvm_riscv_gstage_init(&gstage, kvm); kvm_riscv_gstage_unmap_range(&gstage, 0UL, @@ -566,7 +566,7 @@ void kvm_riscv_mmu_free_pgd(struct kvm *kvm) kvm->arch.pgd_phys =3D 0; kvm->arch.pgd_levels =3D 0; } - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); =20 if (pgd) free_pages((unsigned long)pgd, get_order(kvm_riscv_gstage_pgd_size)); --=20 2.43.0 From nobody Mon May 25 06:42:07 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1C113BB119; Sun, 17 May 2026 15:37:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032269; cv=none; b=Gt4wx9GQqs9+EvIdoIRu10slZHQ0iGf2ocmfYVLhjymvaSCYXcX1GjJIv7/CYZOxAQkoVzRQb7pyYT2U+aO7hfBWGdvh+bzpwJoI2RZUOz4/gIAhwtzlRZKTMlGUtpJm2lrGWelsh64BueIhfv7yoxuLOTv3yeOWUiyspruuFRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032269; c=relaxed/simple; bh=MvXwo4MOq7Z9CPIBfscObm8YkRPHqvIZywS8JjwD+/A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rGr+BFbLnHqAo9nQoMs5UoyETX8EuFK1X82l9emKGXGHGkaENdYz5s+k6BXao7T+uP+UV8jh3QsM8l5iveqfMTrtdiSsStigt8suU+Z9ijv18HoJl8OrH0gytK8R8NqkBLUblgY/VLxCiOzpMvZomZcdsHg4j1MeWYOoogGYPmA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=ZMfBMTY9; arc=none smtp.client-ip=220.197.31.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="ZMfBMTY9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=yv 8yz9RXAgFGizgcfHyJDXAzm7QLNMoZ9qY4PF80Hvs=; b=ZMfBMTY9h+bhGfNVy8 LSsyccecgon5/Mc1EVL7Pyr5bDV/K5q2BsgIdXVpw4liSrzx0e1nB/difk+oW1+O ARpno5X91vLZz4Zk2VOrWk4fUQ5Rzj8AQ9kD7m9UfVSeO8d8qcfP5kKLYTkM9VGN TTbdWwYluw9myipi/e2DMatqc= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-3 (Coremail) with SMTP id _____wA3ylwO4AlqyKW7Bw--.10227S5; Sun, 17 May 2026 23:34:57 +0800 (CST) From: Jinyu Tang To: Anup Patel , Anup Patel , Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu , Jinyu Tang Subject: [PATCH 3/5] KVM: riscv: Add a G-stage PTE cmpxchg helper Date: Sun, 17 May 2026 23:34:25 +0800 Message-ID: <20260517153427.94889-4-tjytimi@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260517153427.94889-1-tjytimi@163.com> References: <20260517153427.94889-1-tjytimi@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wA3ylwO4AlqyKW7Bw--.10227S5 X-Coremail-Antispam: 1Uf129KBjvJXoW7Cr1UKF1xJF4xWFWDCF1kuFg_yoW8tr4fpF ZrCrn3Cr4rWFn3Xr1ay3yq9rn8Ca1vgr13Jr9Fvr98AF1avrW8Xryvg39Ivry5JFyrJay3 uay5Kr1UCr4vywUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0ziWE_NUUUUU= X-CM-SenderInfo: xwm13xlpl6il2tof0z/xtbC0AEdlWoJ4CGzBAAA3M Content-Type: text/plain; charset="utf-8" Permission-only G-stage PTE updates can run in parallel once they are moved to the read side of mmu_lock. Plain set_pte() is not enough for that case because another CPU may update the same PTE first. x86 handles the same class of SPTE races with cmpxchg-based updates in its fast page fault and TDP MMU paths. Add a small RISC-V helper for atomic G-stage PTE updates. The helper reports contention to the caller and flushes the target range only when the PTE value actually changes. Signed-off-by: Jinyu Tang --- arch/riscv/include/asm/kvm_gstage.h | 4 ++++ arch/riscv/kvm/gstage.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/arch/riscv/include/asm/kvm_gstage.h b/arch/riscv/include/asm/k= vm_gstage.h index 9c908432b..afe80e4bf 100644 --- a/arch/riscv/include/asm/kvm_gstage.h +++ b/arch/riscv/include/asm/kvm_gstage.h @@ -54,6 +54,10 @@ int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage, struct kvm_mmu_memory_cache *pcache, const struct kvm_gstage_mapping *map); =20 +bool kvm_riscv_gstage_try_update_pte(struct kvm_gstage *gstage, u32 level, + gpa_t addr, pte_t *ptep, + pte_t old_pte, pte_t new_pte); + int kvm_riscv_gstage_map_page(struct kvm_gstage *gstage, struct kvm_mmu_memory_cache *pcache, gpa_t gpa, phys_addr_t hpa, unsigned long page_size, diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index 6f934cb4a..d70584b9e 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -123,6 +123,20 @@ static void gstage_tlb_flush(struct kvm_gstage *gstage= , u32 level, gpa_t addr) gstage->vmid); } =20 +bool kvm_riscv_gstage_try_update_pte(struct kvm_gstage *gstage, u32 level, + gpa_t addr, pte_t *ptep, + pte_t old_pte, pte_t new_pte) +{ + if (cmpxchg(&ptep->pte, pte_val(old_pte), pte_val(new_pte)) !=3D + pte_val(old_pte)) + return false; + + if (pte_val(old_pte) !=3D pte_val(new_pte)) + gstage_tlb_flush(gstage, level, addr); + + return true; +} + int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstage, struct kvm_mmu_memory_cache *pcache, const struct kvm_gstage_mapping *map) --=20 2.43.0 From nobody Mon May 25 06:42:07 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 960A635CB81; Sun, 17 May 2026 15:37:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032265; cv=none; b=kJ18h62xc/vrb4ci+t6bK/kl0lUXr+VAfBYjFwyIWCY4g0x08WegXAYSVNscj5tzmfUYJ+ML4J6z4EQXNpD2MZOpv7AgpoxdClkx4eZ7uDzGY0yIuCIGAttUXB6zh8sYbZnubMoezAzOIdvJlvRkOg6yGraOeGhaoScxQIzfIqg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032265; c=relaxed/simple; bh=70tFVHzck9md3U6VRO1tTK/BQneNRwIcHnjlEDyjPJs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CgsJhdlBgY+Frw/CNDW54aEzg3tfqm404ovG3/9tUiu2Bo0eeJ/5rSqJsk5w8I0gJoYrAVyaabE3dr7ci2YxHy5ZKOYL3QBvECaOXDhDwkX4/REoXUSQEa16GUOa1CaeLQ/cz6S9KY+8vbSrMrsYP26geP1b9NV6KcbLP2Dzmbw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=cNdf7/9a; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="cNdf7/9a" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=GS RXubJm/GTIB2NyfMCMfFiE+Wj4O/jjRpn2yvJTgg8=; b=cNdf7/9a8wM9X4TBcT 4zZ2UCoK6d6HCiyJkAvZJ0DCDafJP/gmCKaF7iNnfv6YC308750AVGkVWWHzmoAe BWXn9vVnJ9grWVdY4hNGeIj99IcobInW/xhsxmOKfJ8bP7+PzlqhaFqwVf+4lzD8 IbpvNOsRSiDZixyxGRCZuo/C4= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-3 (Coremail) with SMTP id _____wA3ylwO4AlqyKW7Bw--.10227S6; Sun, 17 May 2026 23:34:59 +0800 (CST) From: Jinyu Tang To: Anup Patel , Anup Patel , Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu , Jinyu Tang Subject: [PATCH 4/5] KVM: riscv: Update G-stage PTE permissions atomically Date: Sun, 17 May 2026 23:34:26 +0800 Message-ID: <20260517153427.94889-5-tjytimi@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260517153427.94889-1-tjytimi@163.com> References: <20260517153427.94889-1-tjytimi@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wA3ylwO4AlqyKW7Bw--.10227S6 X-Coremail-Antispam: 1Uf129KBjvJXoW7uw4xJrykWF45Zr1kKF1DGFg_yoW8Ww43pF WDCry3ur4rKwnxCF4Sqw1vyrs8uFs7Kw4rJr9Fv34DAF15trW8Xrn093yYyr98AF97Xa4Y vrW0gF1UGr48twUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pifcTLUUUUU= X-CM-SenderInfo: xwm13xlpl6il2tof0z/xtbC8QMdlWoJ4CM3MgAA3f Content-Type: text/plain; charset="utf-8" When a fault hits an existing G-stage leaf with the same PFN, KVM only needs to update the PTE permissions. This path will be used by read-side fault handling, so it must not overwrite a concurrent PTE update. Use the cmpxchg helper when relaxing permissions on an existing leaf, following the same concurrency model used by x86 for atomic SPTE permission updates. Retry if another CPU changed the PTE first, and use cpu_relax() while spinning. Signed-off-by: Jinyu Tang --- arch/riscv/kvm/gstage.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/arch/riscv/kvm/gstage.c b/arch/riscv/kvm/gstage.c index d70584b9e..9595169da 100644 --- a/arch/riscv/kvm/gstage.c +++ b/arch/riscv/kvm/gstage.c @@ -182,17 +182,22 @@ int kvm_riscv_gstage_set_pte(struct kvm_gstage *gstag= e, static void kvm_riscv_gstage_update_pte_prot(struct kvm_gstage *gstage, u3= 2 level, gpa_t addr, pte_t *ptep, pgprot_t prot) { - pte_t new_pte; + pte_t old_pte, new_pte; =20 - if (pgprot_val(pte_pgprot(ptep_get(ptep))) =3D=3D pgprot_val(prot)) - return; + for (;;) { + old_pte =3D ptep_get(ptep); + if (pgprot_val(pte_pgprot(old_pte)) =3D=3D pgprot_val(prot)) + return; =20 - new_pte =3D pfn_pte(pte_pfn(ptep_get(ptep)), prot); - new_pte =3D pte_mkdirty(new_pte); + new_pte =3D pfn_pte(pte_pfn(old_pte), prot); + new_pte =3D pte_mkdirty(new_pte); =20 - set_pte(ptep, new_pte); + if (kvm_riscv_gstage_try_update_pte(gstage, level, addr, ptep, + old_pte, new_pte)) + return; =20 - gstage_tlb_flush(gstage, level, addr); + cpu_relax(); + } } =20 int kvm_riscv_gstage_map_page(struct kvm_gstage *gstage, --=20 2.43.0 From nobody Mon May 25 06:42:07 2026 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC01C2853E9; Sun, 17 May 2026 15:37:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=117.135.210.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032260; cv=none; b=pLv7wORvkzIuFB4gahXkA/bVRFrJafJBm/ZE26JOwJmachMZJnVLI1K5AKae10ZNg0m62gT9QbT9ZQKIViakDeKefZEUe7SgVJyeDMsH8i9rXGzcCBcHlSsAowdQVBQmfSNgMpLh6G7EB0+VThQQ0fHkN5YvNY30s0uWj5YAGR0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779032260; c=relaxed/simple; bh=Smt2GzPh5jZaZuZCiDYsUpqYPYFg1Ugjk2i2kU/2gqM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ekFa/vYLQgoAlRnlunQudrbEoBR1u18QelpdboBpd4hcpo71e/id4oUM+9rPujP03O7OoApGgRpHnuZ7CZAvO3/e9lAqnn5f3Z8dyU5oPmlk6+1zyjLfzAaJzWF9BD8SjoyJgAMeGi0SlMQB62sm2oD7Ffj33jMJdm3Qlto5huo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=XCIRvp6+; arc=none smtp.client-ip=117.135.210.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="XCIRvp6+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=Lw tr9qnrBOw3mc+mOndsjvgIabpD1HP/zVbnoBZ8j0o=; b=XCIRvp6+25uqtelPhd 08Wy2KLUDrQSxNSIHUpvOigbgi3wUDyDFiKJW51hkakkAyQJ04RJWSmC3e0+T8zb q6MvZAApfU9ESbGtt5zdIHnBQWHtX46dU98CWhsvJ6fUa83f7mE/s4eXt6nbcxbl khO7+/FtNysW2p0FwdtnQkjYM= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-3 (Coremail) with SMTP id _____wA3ylwO4AlqyKW7Bw--.10227S7; Sun, 17 May 2026 23:35:01 +0800 (CST) From: Jinyu Tang To: Anup Patel , Anup Patel , Paolo Bonzini , Sean Christopherson Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Atish Patra , Paul Walmsley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Andrew Jones , Conor Dooley , Yong-Xuan Wang , Nutty Liu , Jinyu Tang Subject: [PATCH 5/5] KVM: riscv: Fast-path dirty logging write faults Date: Sun, 17 May 2026 23:34:27 +0800 Message-ID: <20260517153427.94889-6-tjytimi@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260517153427.94889-1-tjytimi@163.com> References: <20260517153427.94889-1-tjytimi@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wA3ylwO4AlqyKW7Bw--.10227S7 X-Coremail-Antispam: 1Uf129KBjvJXoWxuF4UKw1kCF4Uuw4rZryrJFb_yoW5uF1xpF W7K3yY9rWFqF17W34ftwn2vr1Ygws7Wr17JrW3twn8Zrsrtr1Dua1kW347ZF15Jry8Zayf ZFs8KrWUCrW093DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0zEmFAXUUUUU= X-CM-SenderInfo: xwm13xlpl6il2tof0z/xtbC8gUelmoJ4CU-TgAA3o Content-Type: text/plain; charset="utf-8" With dirty logging enabled, guest writes often fault on an existing 4K G-stage leaf that was write-protected only for dirty tracking. The slow path still performs the full fault handling flow and takes mmu_lock for write, even though the page-table shape does not change. x86 handles the analogous case in its fast page fault path by atomically making a writable SPTE writable again when the fault is only a write-protection fault. Add the same style of fast path for RISC-V. If a write fault hits an existing 4K leaf in a writable dirty-log memslot, mark the page dirty and atomically set the PTE writable and dirty under the read side of mmu_lock. The dirty bitmap is updated before the PTE becomes writable again. The PTE D bit is also set so systems that trap on a clear D bit do not fall back to the slow path for a writable but clean PTE. Signed-off-by: Jinyu Tang --- arch/riscv/kvm/mmu.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 48f16e52f..980059e09 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -419,6 +419,77 @@ static unsigned long transparent_hugepage_adjust(struc= t kvm *kvm, return PAGE_SIZE; } =20 +static bool kvm_riscv_mmu_dirty_log_write_fault_fast(struct kvm *kvm, + struct kvm_memory_slot *memslot, + gpa_t gpa, + struct kvm_gstage_mapping *out_map) +{ + struct kvm_gstage gstage; + unsigned long mmu_seq; + pte_t old_pte, new_pte; + pte_t *ptep; + gfn_t gfn =3D gpa >> PAGE_SHIFT; + u32 ptep_level; + bool dirty_marked =3D false; + bool ret; + + kvm_riscv_gstage_init(&gstage, kvm); + mmu_seq =3D kvm->mmu_invalidate_seq; + + read_lock(&kvm->mmu_lock); + + if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn)) { + ret =3D false; + goto out_unlock; + } + + if (!kvm_riscv_gstage_get_leaf(&gstage, gpa, &ptep, &ptep_level) || + ptep_level) { + ret =3D false; + goto out_unlock; + } + + for (;;) { + old_pte =3D ptep_get(ptep); + if (!(pte_val(old_pte) & _PAGE_LEAF)) { + ret =3D false; + break; + } + + if (!dirty_marked) { + mark_page_dirty_in_slot(kvm, memslot, gfn); + dirty_marked =3D true; + } + + if ((pte_val(old_pte) & (_PAGE_WRITE | _PAGE_DIRTY)) =3D=3D + (_PAGE_WRITE | _PAGE_DIRTY)) { + new_pte =3D old_pte; + ret =3D true; + break; + } + + new_pte =3D pte_mkdirty(pte_mkwrite_novma(old_pte)); + + if (kvm_riscv_gstage_try_update_pte(&gstage, ptep_level, gpa, + ptep, old_pte, new_pte)) { + ret =3D true; + break; + } + cpu_relax(); + } + +out_unlock: + read_unlock(&kvm->mmu_lock); + + if (ret) { + out_map->addr =3D gpa & PAGE_MASK; + out_map->level =3D 0; + out_map->pte =3D new_pte; + } + + return ret; +} + int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memsl= ot, gpa_t gpa, unsigned long hva, bool is_write, struct kvm_gstage_mapping *out_map) @@ -442,6 +513,10 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kv= m_memory_slot *memslot, /* Setup initial state of output mapping */ memset(out_map, 0, sizeof(*out_map)); =20 + if (is_write && logging && + kvm_riscv_mmu_dirty_log_write_fault_fast(kvm, memslot, gpa, out_map)) + return 0; + /* We need minimum second+third level pages */ ret =3D kvm_mmu_topup_memory_cache(pcache, kvm->arch.pgd_levels); if (ret) { --=20 2.43.0