When set ESTAT CSR register in function _kvm_setcsr(), valid bit check is added here. Also interrupt CPU_AVEC is checked by msgint feature. Signed-off-by: Bibo Mao --- arch/loongarch/kvm/vcpu.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index c6bcad1dd9e2..8864e55c33ac 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -602,7 +602,7 @@ struct kvm_vcpu *kvm_get_vcpu_by_cpuid(struct kvm *kvm, int cpuid) static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val) { - unsigned long gintc; + unsigned long gintc, estat; struct loongarch_csrs *csr = vcpu->arch.csr; if (get_gcsr_flag(id) & INVALID_GCSR) @@ -621,8 +621,9 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val) 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); + gintc = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_GINTC) & KVM_GINTC_IRQ_MASK; + estat = kvm_read_sw_gcsr(csr, LOONGARCH_CSR_ESTAT) & ~KVM_ESTAT_HWI_MASK; + *val = estat | (gintc << 2); return 0; } @@ -637,7 +638,8 @@ static int _kvm_getcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 *val) static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val) { - int ret = 0, gintc; + int ret = 0; + unsigned long gintc, estat; struct loongarch_csrs *csr = vcpu->arch.csr; if (get_gcsr_flag(id) & INVALID_GCSR) @@ -648,11 +650,15 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val) if (id == LOONGARCH_CSR_ESTAT) { /* ESTAT IP0~IP7 inject through GINTC */ - gintc = (val >> 2) & 0xff; + gintc = (val >> 2) & KVM_GINTC_IRQ_MASK; kvm_set_sw_gcsr(csr, LOONGARCH_CSR_GINTC, gintc); - gintc = val & ~(0xffUL << 2); - kvm_set_sw_gcsr(csr, LOONGARCH_CSR_ESTAT, gintc); + /* only set valid ESTAT bits */ + estat = val & ~KVM_ESTAT_HWI_MASK; + estat &= CSR_ESTAT_IS | CSR_ESTAT_EXC | CSR_ESTAT_ESUBCODE; + if (!kvm_guest_has_msgint(&vcpu->arch)) + estat &= ~CPU_AVEC; + kvm_set_sw_gcsr(csr, LOONGARCH_CSR_ESTAT, estat); return ret; } -- 2.39.3