target/loongarch/kvm: fix cpucfg sync error handling
In kvm_loongarch_get_cpucfg() and kvm_loongarch_put_cpucfg(), ret is overwritten on each iteration, so only the last register's result is returned and earlier failures are lost. On a failed read, env->cpucfg[i] is stored from a stale or uninitialized val. Accumulate errors with ret |=, matching kvm_loongarch_get_csr()/put_csr(), and only update env->cpucfg[i] on a successful read. Keep the cpucfg2 negotiation check in put_cpucfg() on a separate variable so its early return does not overwrite the accumulated result. Signed-off-by: Tao Cui <cuitao@kylinos.cn> Reviewed-by: Bibo Mao <maobibo@loongson.cn> Message-ID: <20260626052742.810726-5-cui.tao@linux.dev> Signed-off-by: Song Gao <gaosong@loongson.cn>
Tao Cui committed
Jun 26, 2026 at 13:27 UTC
87da979a96afd97d05497f80f6277962c40553d4
1 file changed
+9
-6
target/loongarch/kvm/kvm.c
+9
-6
@@ -713,8 +713,11 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
713
CPULoongArchState *env = cpu_env(cs);
714
715
for (i = 0; i < 21; i++) {
716
- ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
717
- env->cpucfg[i] = (uint32_t)val;
716
+ int r = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
717
+ ret |= r;
718
+ if (!r) {
719
+ env->cpucfg[i] = (uint32_t)val;
720
+ }
721
}
722
return ret;
723
}
@@ -767,13 +770,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
770
771
for (i = 0; i < 21; i++) {
772
if (i == 2) {
770
- ret = kvm_check_cpucfg2(cs);
771
- if (ret) {
772
- return ret;
773
+ int r = kvm_check_cpucfg2(cs);
774
+ if (r) {
775
+ return r;
776
}
777
}
778
val = env->cpucfg[i];
776
- ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
779
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
780
}
781
return ret;
782
}