LoongArch: KVM: Sync pending interrupt when getting ESTAT from user mode

commit e306e514906c ("LoongArch: KVM: Sync pending interrupt when getting")
Conflict: none
Backport-reason: Synchronize upstream linux loongarch kvm
patch to support loongarch virtualization.
Checkpatch: no, to be consistent with upstream commit.

Currently interrupts are posted and cleared with the asynchronous mode,
meanwhile they are saved in SW state vcpu::arch::irq_pending and vcpu::
arch::irq_clear. When vcpu is ready to run, pending interrupt is written
back to CSR.ESTAT register from SW state vcpu::arch::irq_pending at the
guest entrance.

During VM migration stage, vcpu is put into stopped state, however
pending interrupts are not synced to CSR.ESTAT register. So there will
be interrupt lost when VCPU is migrated to another host machines.

Here in this patch when ESTAT CSR register is read from VMM user mode,
pending interrupts are synchronized to ESTAT also. So that VMM can get
correct pending interrupts.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
This commit is contained in:
Bibo Mao 2024-07-09 16:25:50 +08:00 committed by Xianglai Li
parent 8f9e3139c1
commit 81ff3da831
1 changed files with 11 additions and 0 deletions

View File

@ -508,6 +508,17 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val)
return -EINVAL;
if (id == LOONGARCH_CSR_ESTAT) {
preempt_disable();
vcpu_load(vcpu);
/*
* Sync pending interrupts into ESTAT so that interrupt
* remains during VM migration stage
*/
kvm_deliver_intr(vcpu);
vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST;
vcpu_put(vcpu);
preempt_enable();
/* ESTAT IP0~IP7 get from GINTC */
gintc = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_GINTC) & 0xff;
*val = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT) | (gintc << 2);