Skip to content

Commit 1ab9c60

Browse files
bibo-maochenhuacai
authored andcommitted
LoongArch: KVM: Remove kvm_acquire_timer() before entering guest
Timer emulation method in VM is switch to SW timer, there are two places where timer emulation is needed. One is during vcpu thread context switch, the other is halt-polling with idle instruction emulation. SW timer switching is removed during halt-polling mode, so it is not necessary to disable SW timer before entering to guest. This patch removes SW timer handling before entering guest mode, and put it in HW timer restoring flow when vcpu thread is sched-in. With this patch, vm timer emulation is simpler, there is SW/HW timer switch only in vcpu thread context switch scenario. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 0d2abe6 commit 1ab9c60

3 files changed

Lines changed: 6 additions & 46 deletions

File tree

arch/loongarch/include/asm/kvm_vcpu.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ void kvm_save_fpu(struct loongarch_fpu *fpu);
5555
void kvm_restore_fpu(struct loongarch_fpu *fpu);
5656
void kvm_restore_fcsr(struct loongarch_fpu *fpu);
5757

58-
void kvm_acquire_timer(struct kvm_vcpu *vcpu);
5958
void kvm_init_timer(struct kvm_vcpu *vcpu, unsigned long hz);
6059
void kvm_reset_timer(struct kvm_vcpu *vcpu);
6160
void kvm_save_timer(struct kvm_vcpu *vcpu);

arch/loongarch/kvm/timer.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,6 @@ void kvm_init_timer(struct kvm_vcpu *vcpu, unsigned long timer_hz)
6464
kvm_write_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_TVAL, 0);
6565
}
6666

67-
/*
68-
* Restore hard timer state and enable guest to access timer registers
69-
* without trap, should be called with irq disabled
70-
*/
71-
void kvm_acquire_timer(struct kvm_vcpu *vcpu)
72-
{
73-
/*
74-
* Freeze the soft-timer and sync the guest stable timer with it. We do
75-
* this with interrupts disabled to avoid latency.
76-
*/
77-
hrtimer_cancel(&vcpu->arch.swtimer);
78-
}
79-
8067
/*
8168
* Restore soft timer state from saved context.
8269
*/
@@ -98,6 +85,11 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
9885
return;
9986
}
10087

88+
/*
89+
* Freeze the soft-timer and sync the guest stable timer with it.
90+
*/
91+
hrtimer_cancel(&vcpu->arch.swtimer);
92+
10193
/*
10294
* Set remainder tick value if not expired
10395
*/
@@ -115,7 +107,7 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
115107
/*
116108
* Inject timer here though sw timer should inject timer
117109
* interrupt async already, since sw timer may be cancelled
118-
* during injecting intr async in function kvm_acquire_timer
110+
* during injecting intr async
119111
*/
120112
kvm_queue_irq(vcpu, INT_TI);
121113
}
@@ -140,11 +132,9 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
140132
vcpu->arch.expire = expire;
141133
if (ticks) {
142134
/*
143-
* Update hrtimer to use new timeout
144135
* HRTIMER_MODE_PINNED is suggested since vcpu may run in
145136
* the same physical cpu in next time
146137
*/
147-
hrtimer_cancel(&vcpu->arch.swtimer);
148138
hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
149139
} else if (vcpu->stat.generic.blocking) {
150140
/*

arch/loongarch/kvm/vcpu.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu)
9595
* check vmid before vcpu enter guest
9696
*/
9797
local_irq_disable();
98-
kvm_acquire_timer(vcpu);
9998
kvm_deliver_intr(vcpu);
10099
kvm_deliver_exception(vcpu);
101100
/* Make sure the vcpu mode has been written */
@@ -251,23 +250,6 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
251250
return -EINVAL;
252251
}
253252

254-
/**
255-
* kvm_migrate_count() - Migrate timer.
256-
* @vcpu: Virtual CPU.
257-
*
258-
* Migrate hrtimer to the current CPU by cancelling and restarting it
259-
* if the hrtimer is active.
260-
*
261-
* Must be called when the vCPU is migrated to a different CPU, so that
262-
* the timer can interrupt the guest at the new CPU, and the timer irq can
263-
* be delivered to the vCPU.
264-
*/
265-
static void kvm_migrate_count(struct kvm_vcpu *vcpu)
266-
{
267-
if (hrtimer_cancel(&vcpu->arch.swtimer))
268-
hrtimer_restart(&vcpu->arch.swtimer);
269-
}
270-
271253
static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val)
272254
{
273255
unsigned long gintc;
@@ -796,17 +778,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
796778
unsigned long flags;
797779

798780
local_irq_save(flags);
799-
if (vcpu->arch.last_sched_cpu != cpu) {
800-
kvm_debug("[%d->%d]KVM vCPU[%d] switch\n",
801-
vcpu->arch.last_sched_cpu, cpu, vcpu->vcpu_id);
802-
/*
803-
* Migrate the timer interrupt to the current CPU so that it
804-
* always interrupts the guest and synchronously triggers a
805-
* guest timer interrupt.
806-
*/
807-
kvm_migrate_count(vcpu);
808-
}
809-
810781
/* Restore guest state to registers */
811782
_kvm_vcpu_load(vcpu, cpu);
812783
local_irq_restore(flags);

0 commit comments

Comments
 (0)