diff --git a/arch/loongarch/include/asm/kvm_extioi.h b/arch/loongarch/include/asm/kvm_extioi.h index d2af039a7d6f145d45d8ad74ab2cfaf86f4dfd81..c2bd295d0edcb6d0b750ba89e55fef2a4d6a1966 100644 --- a/arch/loongarch/include/asm/kvm_extioi.h +++ b/arch/loongarch/include/asm/kvm_extioi.h @@ -92,4 +92,5 @@ struct loongarch_extioi { void extioi_set_irq(struct loongarch_extioi *s, int irq, int level); int kvm_loongarch_register_extioi_device(void); +int kvm_loongarch_reset_extioi(struct kvm *kvm); #endif /* LOONGARCH_EXTIOI_H */ diff --git a/arch/loongarch/kvm/intc/extioi.c b/arch/loongarch/kvm/intc/extioi.c index 48141823aaa3aa9a413901279b9a287b531c6894..5327066f16aec95ca383f127e1aa1f048fa73a10 100644 --- a/arch/loongarch/kvm/intc/extioi.c +++ b/arch/loongarch/kvm/intc/extioi.c @@ -781,3 +781,24 @@ int kvm_loongarch_register_extioi_device(void) return kvm_register_device_ops(&kvm_loongarch_extioi_dev_ops, KVM_DEV_TYPE_LA_EXTIOI); } + +int kvm_loongarch_reset_extioi(struct kvm *kvm) +{ + struct loongarch_extioi *extioi = kvm->arch.extioi; + unsigned long flags; + u8 offset, size; + u8 *pstart; + + if (!extioi) + return -EINVAL; + + pstart = (char *)&extioi->nodetype; + offset = (char *)&extioi->nodetype - (char *)extioi; + size = sizeof(struct loongarch_extioi) - offset; + + loongarch_ext_irq_lock(extioi, flags); + memset(pstart, 0, size); + loongarch_ext_irq_unlock(extioi, flags); + + return 0; +} diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index e9b397543fdf7d9a7b2c32214ad07f8ac65fd67f..50bd40d36eb9e5eecf0c522180ff7b4b33c0cb57 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -870,6 +870,8 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu, break; case KVM_REG_LOONGARCH_VCPU_RESET: vcpu->arch.st.guest_addr = 0; + if (vcpu->vcpu_id == 0) + kvm_loongarch_reset_extioi(vcpu->kvm); memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending)); memset(&vcpu->arch.irq_clear, 0, sizeof(vcpu->arch.irq_clear)); break;