[PATCH v7] KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core

Nutty.Liu nutty.liu at hotmail.com
Mon Mar 2 19:13:42 PST 2026


On 2/27/2026 8:10 PM, Jinyu Tang wrote:
> Currently, kvm_arch_vcpu_load() unconditionally restores guest CSRs,
> HGATP, and AIA state. However, when a VCPU is loaded back on the same
> physical CPU, and no other KVM VCPU has run on this CPU since it was
> last put, the hardware CSRs and AIA registers are still valid.
>
> This patch optimizes the vcpu_load path by skipping the expensive CSR
> and AIA writes if all the following conditions are met:
> 1. It is being reloaded on the same CPU (vcpu->arch.last_exit_cpu == cpu).
> 2. The CSRs are not dirty (!vcpu->arch.csr_dirty).
> 3. No other VCPU used this CPU (vcpu == __this_cpu_read(kvm_former_vcpu)).
>
> To ensure this fast-path doesn't break corner cases:
> - Live migration and VCPU reset are naturally safe. KVM initializes
>    last_exit_cpu to -1, which guarantees the fast-path won't trigger.
> - The 'csr_dirty' flag tracks runtime userspace interventions. If
>    userspace modifies guest configurations (e.g., hedeleg via
>    KVM_SET_GUEST_DEBUG, or CSRs including AIA via KVM_SET_ONE_REG),
>    the flag is set to skip the fast path.
>
> With the 'csr_dirty' safeguard proven effective, it is safe to
> include kvm_riscv_vcpu_aia_load() inside the skip logic now.
>
> Signed-off-by: Jinyu Tang <tjytimi at 163.com>
> ---
>   v6 -> v7:
>   - Moved kvm_riscv_vcpu_aia_load() into the fast-path skip logic, as
>     suggested by Radim Krčmář.
>   - Verified the fix for the IMSIC instability issue reported in v3.
>     Testing was conducted on QEMU 10.0.2 with explicitly enabled AIA
>     (`-machine virt,aia=aplic-imsic`). The guest boots successfully
>     using virtio-mmio devices like virtio-blk and virtio-net.
>
>   v5 -> v6:
>   As suggested by Andrew Jones, checking 'last_exit_cpu' first (most
>   likely to fail on busy hosts) and placing the expensive
>   __this_cpu_read() last, skipping __this_cpu_write() in kvm_arch_vcpu_put()
>   if kvm_former_vcpu is already set to the current VCPU.
>
>   v4 -> v5:
>   - Dropped the 'vcpu->scheduled_out' check as Andrew Jones pointed out,
>     relying on 'last_exit_cpu', 'former_vcpu', and '!csr_dirty'
>     is sufficient and safe. This expands the optimization to cover many
>     userspace exits (e.g., MMIO) as well.
>   - Added a block comment in kvm_arch_vcpu_load() to warn future
>     developers about maintaining the 'csr_dirty' dependency, as Andrew's
>     suggestion to reduce fragility.
>   - Removed unnecessary single-line comments and fixed indentation nits.
>
>   v3 -> v4:
>   - Addressed Anup Patel's review regarding hardware state inconsistency.
>   - Introduced 'csr_dirty' flag to track dynamic userspace CSR/CONFIG
>     modifications (KVM_SET_ONE_REG, KVM_SET_GUEST_DEBUG), forcing a full
>     restore when debugging or modifying states at userspace.
>   - Kept kvm_riscv_vcpu_aia_load() out of the skip block to resolve IMSIC
>     VS-file instability.
>
>   v2 -> v3:
>   v2 was missing a critical check because I generated the patch from my
>   wrong (experimental) branch. This is fixed in v3. Sorry for my trouble.
>
>   v1 -> v2:
>   Apply the logic to aia csr load. Thanks for Andrew Jones's advice.
> ---
>   arch/riscv/include/asm/kvm_host.h |  3 +++
>   arch/riscv/kvm/vcpu.c             | 24 ++++++++++++++++++++++--
>   arch/riscv/kvm/vcpu_onereg.c      |  2 ++
>   3 files changed, 27 insertions(+), 2 deletions(-)
Reviewed-by: Nutty Liu <nutty.liu at hotmail.com>

Thanks,
Nutty



More information about the linux-riscv mailing list