* [PATCH v2 1/4] target/loongarch/kvm: fix uninitialized val and unchecked GET in cpucfg2 check
2026-06-26 5:27 [PATCH v2 0/4] target/loongarch/kvm: cpucfg and device attr fixes Tao Cui
@ 2026-06-26 5:27 ` Tao Cui
2026-06-26 5:27 ` [PATCH v2 2/4] target/loongarch/kvm: pass device attr by reference to kvm_vcpu_ioctl Tao Cui
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Tao Cui @ 2026-06-26 5:27 UTC (permalink / raw)
To: qemu-devel
Cc: Song Gao, Bibo Mao, Paolo Bonzini, Philippe Mathieu-Daudé,
Qiang Ma, Tao Cui
From: Tao Cui <cuitao@kylinos.cn>
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>
---
target/loongarch/kvm/kvm.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index d6539c12ac..5bd5e268b9 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -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. */
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 2/4] target/loongarch/kvm: pass device attr by reference to kvm_vcpu_ioctl
2026-06-26 5:27 [PATCH v2 0/4] target/loongarch/kvm: cpucfg and device attr fixes Tao Cui
2026-06-26 5:27 ` [PATCH v2 1/4] target/loongarch/kvm: fix uninitialized val and unchecked GET in cpucfg2 check Tao Cui
@ 2026-06-26 5:27 ` Tao Cui
2026-06-26 5:27 ` [PATCH v2 3/4] target/loongarch/kvm: remove redundant cpucfg failure traces Tao Cui
2026-06-26 5:27 ` [PATCH v2 4/4] target/loongarch/kvm: fix cpucfg sync error handling Tao Cui
3 siblings, 0 replies; 5+ messages in thread
From: Tao Cui @ 2026-06-26 5:27 UTC (permalink / raw)
To: qemu-devel
Cc: Song Gao, Bibo Mao, Paolo Bonzini, Philippe Mathieu-Daudé,
Qiang Ma, Tao Cui
From: Tao Cui <cuitao@kylinos.cn>
kvm_vcpu_ioctl() is variadic and reads its argument as a pointer, but
kvm_get_stealtime(), kvm_set_stealtime() and kvm_set_pv_features() pass
the local struct kvm_device_attr by value. It currently works because of
how the calling convention passes large structs; pass &attr so the
argument is passed as intended.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
target/loongarch/kvm/kvm.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 5bd5e268b9..4bb5be6864 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -46,12 +46,12 @@ static int kvm_get_stealtime(CPUState *cs)
.addr = (uint64_t)&env->stealtime.guest_addr,
};
- err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
if (err) {
return 0;
}
- err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, attr);
+ err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
if (err) {
error_report("PVTIME: KVM_GET_DEVICE_ATTR: %s", strerror(errno));
return err;
@@ -70,12 +70,12 @@ static int kvm_set_stealtime(CPUState *cs)
.addr = (uint64_t)&env->stealtime.guest_addr,
};
- err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
if (err) {
return 0;
}
- err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
+ err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
if (err) {
error_report("PVTIME: KVM_SET_DEVICE_ATTR %s with gpa "TARGET_FMT_lx,
strerror(errno), env->stealtime.guest_addr);
@@ -96,13 +96,13 @@ static int kvm_set_pv_features(CPUState *cs)
.addr = (uint64_t)&val,
};
- err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
if (err) {
return 0;
}
val = env->pv_features;
- err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
+ err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
if (err) {
error_report("Fail to set pv feature "TARGET_FMT_lx " with error %s",
val, strerror(errno));
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 3/4] target/loongarch/kvm: remove redundant cpucfg failure traces
2026-06-26 5:27 [PATCH v2 0/4] target/loongarch/kvm: cpucfg and device attr fixes Tao Cui
2026-06-26 5:27 ` [PATCH v2 1/4] target/loongarch/kvm: fix uninitialized val and unchecked GET in cpucfg2 check Tao Cui
2026-06-26 5:27 ` [PATCH v2 2/4] target/loongarch/kvm: pass device attr by reference to kvm_vcpu_ioctl Tao Cui
@ 2026-06-26 5:27 ` Tao Cui
2026-06-26 5:27 ` [PATCH v2 4/4] target/loongarch/kvm: fix cpucfg sync error handling Tao Cui
3 siblings, 0 replies; 5+ messages in thread
From: Tao Cui @ 2026-06-26 5:27 UTC (permalink / raw)
To: qemu-devel
Cc: Song Gao, Bibo Mao, Paolo Bonzini, Philippe Mathieu-Daudé,
Qiang Ma, Tao Cui
From: Tao Cui <cuitao@kylinos.cn>
kvm_get_one_reg() and kvm_set_one_reg() already trace on failure, so the
trace_kvm_failed_get_cpucfg()/trace_kvm_failed_put_cpucfg() calls in
kvm_loongarch_get_cpucfg() and kvm_loongarch_put_cpucfg() duplicate that.
Remove the calls and the now-unused trace events.
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
target/loongarch/kvm/kvm.c | 6 ------
target/loongarch/trace-events | 2 --
2 files changed, 8 deletions(-)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 4bb5be6864..a504cfaaf7 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -714,9 +714,6 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
for (i = 0; i < 21; i++) {
ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
- if (ret < 0) {
- trace_kvm_failed_get_cpucfg(strerror(errno));
- }
env->cpucfg[i] = (uint32_t)val;
}
return ret;
@@ -777,9 +774,6 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
}
val = env->cpucfg[i];
ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
- if (ret < 0) {
- trace_kvm_failed_put_cpucfg(strerror(errno));
- }
}
return ret;
}
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
index dea11edc0f..829d8e0f53 100644
--- a/target/loongarch/trace-events
+++ b/target/loongarch/trace-events
@@ -9,7 +9,5 @@ kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s"
kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s"
kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s"
kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s"
-kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
-kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d"
kvm_set_intr(int irq, int level) "kvm set interrupt, irq num: %d, level: %d"
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 4/4] target/loongarch/kvm: fix cpucfg sync error handling
2026-06-26 5:27 [PATCH v2 0/4] target/loongarch/kvm: cpucfg and device attr fixes Tao Cui
` (2 preceding siblings ...)
2026-06-26 5:27 ` [PATCH v2 3/4] target/loongarch/kvm: remove redundant cpucfg failure traces Tao Cui
@ 2026-06-26 5:27 ` Tao Cui
3 siblings, 0 replies; 5+ messages in thread
From: Tao Cui @ 2026-06-26 5:27 UTC (permalink / raw)
To: qemu-devel
Cc: Song Gao, Bibo Mao, Paolo Bonzini, Philippe Mathieu-Daudé,
Qiang Ma, Tao Cui
From: Tao Cui <cuitao@kylinos.cn>
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>
---
target/loongarch/kvm/kvm.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index a504cfaaf7..9f1ee41ef6 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -713,8 +713,11 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs)
CPULoongArchState *env = cpu_env(cs);
for (i = 0; i < 21; i++) {
- ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
- env->cpucfg[i] = (uint32_t)val;
+ int r = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
+ ret |= r;
+ if (!r) {
+ env->cpucfg[i] = (uint32_t)val;
+ }
}
return ret;
}
@@ -767,13 +770,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
for (i = 0; i < 21; i++) {
if (i == 2) {
- ret = kvm_check_cpucfg2(cs);
- if (ret) {
- return ret;
+ int r = kvm_check_cpucfg2(cs);
+ if (r) {
+ return r;
}
}
val = env->cpucfg[i];
- ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
}
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread