Skip to content

Commit cea8896

Browse files
committed
RISC-V: KVM: Fix kvm_riscv_vcpu_timer_pending() for Sstc
The kvm_riscv_vcpu_timer_pending() checks per-VCPU next_cycles and per-VCPU software injected VS timer interrupt. This function returns incorrect value when Sstc is available because the per-VCPU next_cycles are only updated by kvm_riscv_vcpu_timer_save() called from kvm_arch_vcpu_put(). As a result, when Sstc is available the VCPU does not block properly upon WFI traps. To fix the above issue, we introduce kvm_riscv_vcpu_timer_sync() which will update per-VCPU next_cycles upon every VM exit instead of kvm_riscv_vcpu_timer_save(). Fixes: 8f5cb44 ("RISC-V: KVM: Support sstc extension") Signed-off-by: Anup Patel <[email protected]> Reviewed-by: Atish Patra <[email protected]> Signed-off-by: Anup Patel <[email protected]>
1 parent 5c20a3a commit cea8896

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

arch/riscv/include/asm/kvm_vcpu_timer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ int kvm_riscv_vcpu_timer_deinit(struct kvm_vcpu *vcpu);
4545
int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu);
4646
void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu);
4747
void kvm_riscv_guest_timer_init(struct kvm *kvm);
48+
void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu);
4849
void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu);
4950
bool kvm_riscv_vcpu_timer_pending(struct kvm_vcpu *vcpu);
5051

arch/riscv/kvm/vcpu.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,9 @@ void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu)
708708
clear_bit(IRQ_VS_SOFT, &v->irqs_pending);
709709
}
710710
}
711+
712+
/* Sync-up timer CSRs */
713+
kvm_riscv_vcpu_timer_sync(vcpu);
711714
}
712715

713716
int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)

arch/riscv/kvm/vcpu_timer.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,20 +320,33 @@ void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu)
320320
kvm_riscv_vcpu_timer_unblocking(vcpu);
321321
}
322322

323-
void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu)
323+
void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu)
324324
{
325325
struct kvm_vcpu_timer *t = &vcpu->arch.timer;
326326

327327
if (!t->sstc_enabled)
328328
return;
329329

330-
t = &vcpu->arch.timer;
331330
#if defined(CONFIG_32BIT)
332331
t->next_cycles = csr_read(CSR_VSTIMECMP);
333332
t->next_cycles |= (u64)csr_read(CSR_VSTIMECMPH) << 32;
334333
#else
335334
t->next_cycles = csr_read(CSR_VSTIMECMP);
336335
#endif
336+
}
337+
338+
void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu)
339+
{
340+
struct kvm_vcpu_timer *t = &vcpu->arch.timer;
341+
342+
if (!t->sstc_enabled)
343+
return;
344+
345+
/*
346+
* The vstimecmp CSRs are saved by kvm_riscv_vcpu_timer_sync()
347+
* upon every VM exit so no need to save here.
348+
*/
349+
337350
/* timer should be enabled for the remaining operations */
338351
if (unlikely(!t->init_done))
339352
return;

0 commit comments

Comments
 (0)