From: Bibo Mao Date: Thu, 11 Jun 2026 12:46:42 +0000 (+0800) Subject: LoongArch: KVM: Add valid bit check when set CSR.ESTAT register X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42985883613cb316d9a1520365ff6c1e07ef5c11;p=thirdparty%2Fkernel%2Flinux.git LoongArch: KVM: Add valid bit check when set CSR.ESTAT register When set CSR.ESTAT 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 Signed-off-by: Huacai Chen --- diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index cb42f43afcc8..89aa49df276a 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -593,7 +593,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 estat, gintc; struct loongarch_csrs *csr = vcpu->arch.csr; if (get_gcsr_flag(id) & INVALID_GCSR) @@ -612,8 +612,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_EXTI_MASK; + *val = estat | (gintc << VIP_DELTA); return 0; } @@ -628,7 +629,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 estat, gintc; struct loongarch_csrs *csr = vcpu->arch.csr; if (get_gcsr_flag(id) & INVALID_GCSR) @@ -639,11 +641,16 @@ 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; - kvm_set_sw_gcsr(csr, LOONGARCH_CSR_GINTC, gintc); - - gintc = val & ~(0xffUL << 2); - kvm_set_sw_gcsr(csr, LOONGARCH_CSR_ESTAT, gintc); + gintc = (val >> VIP_DELTA) & KVM_GINTC_IRQ_MASK; + gintc |= kvm_read_sw_gcsr(csr, LOONGARCH_CSR_GINTC) & ~KVM_GINTC_IRQ_MASK; + kvm_write_sw_gcsr(csr, LOONGARCH_CSR_GINTC, gintc); + + /* Only set valid ESTAT bits */ + estat = val & ~KVM_ESTAT_EXTI_MASK; + estat &= CSR_ESTAT_IS | CSR_ESTAT_EXC | CSR_ESTAT_ESUBCODE; + if (!kvm_guest_has_msgint(&vcpu->arch)) + estat &= ~CPU_AVEC; + kvm_write_sw_gcsr(csr, LOONGARCH_CSR_ESTAT, estat); return ret; }