Skip to content

[PW_SID:1096100] KVM: riscv: Speed up dirty logging write faults#1957

Closed
linux-riscv-bot wants to merge 6 commits into
workflow__riscv__fixesfrom
pw1096100
Closed

[PW_SID:1096100] KVM: riscv: Speed up dirty logging write faults#1957
linux-riscv-bot wants to merge 6 commits into
workflow__riscv__fixesfrom
pw1096100

Conversation

@linux-riscv-bot
Copy link
Copy Markdown

PR for series 1096100 applied to workflow__riscv__fixes

Name: KVM: riscv: Speed up dirty logging write faults
URL: https://patchwork.kernel.org/project/linux-riscv/list/?series=1096100
Version: 1

Linux RISC-V bot and others added 6 commits May 14, 2026 08:49
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
with lockdep_assert_held_write() like x86.

Signed-off-by: Jinyu Tang <tjytimi@163.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
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 <tjytimi@163.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
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 <tjytimi@163.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
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 <tjytimi@163.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
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 <tjytimi@163.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 139.11 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1042.15 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1428.92 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 28.06 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 26.40 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 0.77 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 86.47 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.25 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
kdoc
Desc: Detects for kdoc errors
Duration: 0.91 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
module-param
Desc: Detect module_param changes
Duration: 0.27 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.25 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[1/5] KVM: riscv: Rely on common MMU notifier locking"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.33 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 138.27 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1067.83 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1446.45 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 26.03 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 27.06 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 1.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 86.09 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.32 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
kdoc
Desc: Detects for kdoc errors
Duration: 0.86 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
module-param
Desc: Detect module_param changes
Duration: 0.27 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.24 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[2/5] KVM: riscv: Use an rwlock for mmu_lock"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.30 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[3/5] KVM: riscv: Add a G-stage PTE cmpxchg helper"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[3/5] KVM: riscv: Add a G-stage PTE cmpxchg helper"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.31 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 139.89 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1044.18 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1429.76 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 25.58 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 26.93 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 0.78 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 86.75 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.24 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
kdoc
Desc: Detects for kdoc errors
Duration: 0.84 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
module-param
Desc: Detect module_param changes
Duration: 0.26 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 4: "[4/5] KVM: riscv: Update G-stage PTE permissions atomically"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.31 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 139.02 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1040.04 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1425.83 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 25.37 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 27.05 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 0.79 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 85.93 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.25 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
kdoc
Desc: Detects for kdoc errors
Duration: 0.85 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
module-param
Desc: Detect module_param changes
Duration: 0.25 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 5: "[5/5] KVM: riscv: Fast-path dirty logging write faults"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.31 seconds
Result: PASS

@linux-riscv-bot linux-riscv-bot force-pushed the workflow__riscv__fixes branch 2 times, most recently from a1231b7 to c03cdce Compare May 23, 2026 03:29
@linux-riscv-bot linux-riscv-bot deleted the pw1096100 branch May 25, 2026 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants