summaryrefslogtreecommitdiff
path: root/arch/loongarch/kvm/timer.c
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2023-12-19 10:48:27 +0800
committerHuacai Chen <chenhuacai@loongson.cn>2023-12-19 10:48:27 +0800
commit161267320158920a601e40d83fdac60bcaa2acb5 (patch)
treeaf655a4911e55c558a123814026ad071812feffc /arch/loongarch/kvm/timer.c
parent7ab6fb505b2a7447c4a7237a12c59e3ad0c7298c (diff)
LoongArch: KVM: Remove SW timer switch when vcpu is halt polling
With halt-polling supported, there is checking for pending events or interrupts when vcpu executes idle instruction. Pending interrupts include injected SW interrupts and passthrough HW interrupts, such as HW timer interrupts, since HW timer works still even if vcpu exists from VM mode. Since HW timer pending interrupt can be set directly with CSR status register, and pending HW timer interrupt checking is used in vcpu block checking function, it is not necessary to switch to SW timer during halt-polling. This patch adds preemption disabling in function kvm_cpu_has_pending_timer(), and removes SW timer switching in idle instruction emulation function. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch/kvm/timer.c')
-rw-r--r--arch/loongarch/kvm/timer.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/arch/loongarch/kvm/timer.c b/arch/loongarch/kvm/timer.c
index 284bf553fefe..12d58040122d 100644
--- a/arch/loongarch/kvm/timer.c
+++ b/arch/loongarch/kvm/timer.c
@@ -155,11 +155,17 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
*/
hrtimer_cancel(&vcpu->arch.swtimer);
hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
- } else
+ } else if (vcpu->stat.generic.blocking) {
/*
- * Inject timer interrupt so that hall polling can dectect and exit
+ * Inject timer interrupt so that halt polling can dectect and exit.
+ * VCPU is scheduled out already and sleeps in rcuwait queue and
+ * will not poll pending events again. kvm_queue_irq() is not enough,
+ * hrtimer swtimer should be used here.
*/
- kvm_queue_irq(vcpu, INT_TI);
+ expire = ktime_add_ns(ktime_get(), 10);
+ vcpu->arch.expire = expire;
+ hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
+ }
}
/*