When idle instruction is emulation, kvm will check whether there is pending interrupts including timer interrupt. HW timer event checking is used now, so it is not necessary to switch to sw timer during vcpu block checking flow, since hw timer pending interrupt can be set directly with CSR staus register. This patch adds preemption disabling during checking hw CSR status register, and removes SW timer mode switching in idle instruction emulation function. Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx> --- arch/loongarch/kvm/exit.c | 11 +---------- arch/loongarch/kvm/vcpu.c | 9 ++++++++- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c index ce8de3fa472c..d2a38cd47032 100644 --- a/arch/loongarch/kvm/exit.c +++ b/arch/loongarch/kvm/exit.c @@ -200,17 +200,8 @@ int kvm_emu_idle(struct kvm_vcpu *vcpu) ++vcpu->stat.idle_exits; trace_kvm_exit_idle(vcpu, KVM_TRACE_EXIT_IDLE); - if (!kvm_arch_vcpu_runnable(vcpu)) { - /* - * Switch to the software timer before halt-polling/blocking as - * the guest's timer may be a break event for the vCPU, and the - * hypervisor timer runs only when the CPU is in guest mode. - * Switch before halt-polling so that KVM recognizes an expired - * timer before blocking. - */ - kvm_save_timer(vcpu); + if (!kvm_arch_vcpu_runnable(vcpu)) kvm_vcpu_block(vcpu); - } return EMULATE_DONE; } diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 73d0c2b9c1a5..42663a345bd1 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -187,8 +187,15 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) { - return kvm_pending_timer(vcpu) || + int ret; + + /* protect from TOD sync and vcpu_load/put */ + preempt_disable(); + ret = kvm_pending_timer(vcpu) || kvm_read_hw_gcsr(LOONGARCH_CSR_ESTAT) & (1 << INT_TI); + preempt_enable(); + + return ret; } int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu) -- 2.39.3