]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
target/loongarch/kvm: fix uninitialized val and unchecked GET in cpucfg2 check
authorTao Cui <cuitao@kylinos.cn>
Fri, 26 Jun 2026 05:27:39 +0000 (13:27 +0800)
committerSong Gao <gaosong@loongson.cn>
Tue, 7 Jul 2026 12:41:15 +0000 (08:41 -0400)
kvm_check_cpucfg2() discards the return value of KVM_GET_DEVICE_ATTR and
uses the local val (the host cpucfg2 mask) without checking whether the
read succeeded. val is also declared without an initializer, so on a GET
failure env->cpucfg[2] &= val reads an uninitialized value.

The &= mask is best-effort feature negotiation: if KVM_HAS_DEVICE_ATTR
succeeds, a GET failure is most likely a copy_{from,to}_user issue, not a
reason to fail the whole register sync. Check the GET return value, warn and
skip the mask on failure (the guest keeps the cpucfg2 it already has), and
initialize val to 0.

Signed-off-by: Tao Cui <cuitao@kylinos.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20260626052742.810726-2-cui.tao@linux.dev>
Signed-off-by: Song Gao <gaosong@loongson.cn>
target/loongarch/kvm/kvm.c

index 48cdb78a4ca9d8bbb37739c15285651d97b7e500..0b72883ec90ec0d82e35dc3643a08f5e1d197a1a 100644 (file)
@@ -725,7 +725,7 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
 static int kvm_check_cpucfg2(CPUState *cs)
 {
     int ret;
-    uint64_t val;
+    uint64_t val = 0;
     struct kvm_device_attr attr = {
         .group = KVM_LOONGARCH_VCPU_CPUCFG,
         .attr = 2,
@@ -736,8 +736,17 @@ static int kvm_check_cpucfg2(CPUState *cs)
     ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
 
     if (!ret) {
-        kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
-        env->cpucfg[2] &= val;
+        /*
+         * The &= mask is best-effort feature negotiation. If HAS succeeded,
+         * a GET failure is most likely a copy_{from,to}_user issue; warn and
+         * keep the cpucfg2 the guest already has rather than failing the sync.
+         */
+        int r = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
+        if (r) {
+            warn_report("CPUCFG2: KVM_GET_DEVICE_ATTR: %s", strerror(errno));
+        } else {
+            env->cpucfg[2] &= val;
+        }
 
         if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) {
             /* The FP minimal version is 1. */