#define CREATE_TRACE_POINTS
#include "trace.h"
+static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_former_vcpu);
+
const struct kvm_stats_desc kvm_vcpu_stats_desc[] = {
KVM_GENERIC_VCPU_STATS(),
STATS_DESC_COUNTER(VCPU, ecall_exit_stat),
vcpu->arch.cfg.hedeleg |= BIT(EXC_BREAKPOINT);
}
+ vcpu->arch.csr_dirty = true;
+
return 0;
}
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
struct kvm_vcpu_config *cfg = &vcpu->arch.cfg;
+ /*
+ * If VCPU is being reloaded on the same physical CPU and no
+ * other KVM VCPU has run on this CPU since it was last put,
+ * we can skip the expensive CSR and HGATP writes.
+ *
+ * Note: If a new CSR is added to this fast-path skip block,
+ * make sure that 'csr_dirty' is set to true in any
+ * ioctl (e.g., KVM_SET_ONE_REG) that modifies it.
+ */
+ if (vcpu != __this_cpu_read(kvm_former_vcpu))
+ __this_cpu_write(kvm_former_vcpu, vcpu);
+ else if (vcpu->arch.last_exit_cpu == cpu && !vcpu->arch.csr_dirty)
+ goto csr_restore_done;
+
+ vcpu->arch.csr_dirty = false;
if (kvm_riscv_nacl_sync_csr_available()) {
nsh = nacl_shmem();
nacl_csr_write(nsh, CSR_VSSTATUS, csr->vsstatus);
kvm_riscv_mmu_update_hgatp(vcpu);
+ kvm_riscv_vcpu_aia_load(vcpu, cpu);
+
+csr_restore_done:
kvm_riscv_vcpu_timer_restore(vcpu);
kvm_riscv_vcpu_host_fp_save(&vcpu->arch.host_context);
kvm_riscv_vcpu_guest_vector_restore(&vcpu->arch.guest_context,
vcpu->arch.isa);
- kvm_riscv_vcpu_aia_load(vcpu, cpu);
-
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
vcpu->cpu = cpu;