diff mbox series

[v3,7/7] LoongArch: KVM: Sync pending interrupt when getting ESTAT from user mode

Message ID 20240624071422.3473789-8-maobibo@loongson.cn (mailing list archive)
State New
Headers show
Series LoongArch: KVM: VM migration enhancement | expand

Commit Message

maobibo June 24, 2024, 7:14 a.m. UTC
Currently interrupt is posted and cleared with asynchronous mode, and it
is 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 ESTAT
CSR register from SW state vcpu::arch::irq_pending at guest entrance.

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

Here when ESTAT CSR register is read from VMM user mode, pending
interrupt is synchronized to ESTAT also. So that vcpu can get correct
pending interrupt.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/vcpu.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
diff mbox series

Patch

diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index b747bd8bc037..6b612b8390f7 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -371,6 +371,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 interrupt into estat so that interrupt
+		 * remains during 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);