@@ -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;
}
@@ -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)
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@loongson.cn> --- arch/loongarch/kvm/exit.c | 11 +---------- arch/loongarch/kvm/vcpu.c | 9 ++++++++- 2 files changed, 9 insertions(+), 11 deletions(-)