From: Eric Auger <eric.auger@redhat.com>
To: eric.auger.pro@gmail.com, eric.auger@redhat.com,
qemu-devel@nongnu.org, qemu-arm@nongnu.org,
peter.maydell@linaro.org, shaju.abraham@nutanix.com,
khushit.shah@nutanix.com, richard.henderson@linaro.org,
pbonzini@redhat.com, skolothumtho@nvidia.com,
philmd@oss.qualcomm.com, 7746591750@163.com, maobibo@loongson.cn,
harshpb@linux.ibm.com, amachhiw@linux.ibm.com,
daniel.barboza@oss.qualcomm.com, milesg@linux.ibm.com,
farman@linux.ibm.com, cohuck@redhat.com,
alireza.sanaee@huawei.com
Cc: armbru@redhat.com, mbawa@redhat.com
Subject: [PATCH v4 for-11.2 10/10] target/arm/kvm: Improve error handling on scratch vcpu probe
Date: Fri, 30 Oct 2026 14:13:18 +0100 [thread overview]
Message-ID: <20261030131406.461599-11-eric.auger@redhat.com> (raw)
In-Reply-To: <20261030131406.461599-1-eric.auger@redhat.com>
Pass an error handle to both kvm_arm_create_scratch_host_vcpu()
and kvm_arm_get_host_cpu_features(). This allows to improve the
error reporting on kvm_arm_set_cpu_features_from_host().
If any, the error is stored in the new cpu->host_cpu_probe_err
field and further propagated on realize().
In arm_gic_cap_kvm_probe() call path we just pass a NULL error handle
to kvm_arm_create_scratch_host_vcpu because we don't care about the
failure nature and just want to revert to emulated versions if it
fails.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
target/arm/kvm_arm.h | 3 ++-
target/arm/kvm.c | 40 ++++++++++++++++++++++++++++------------
2 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index e7c40fb003..9c7e7f654a 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -105,6 +105,7 @@ struct kvm_vcpu_init;
* @init: filled in with the necessary values for creating a host
* vcpu. If NULL is provided, will not init the vCPU (though the cpufd
* will still be set up).
+ * @errp: Error handle
*
* Create a scratch vcpu in its own VM of the type preferred by the host
* kernel (as would be used for '-cpu host'), for purposes of probing it
@@ -114,7 +115,7 @@ struct kvm_vcpu_init;
* false on failure (and fdarray and init are not valid).
*/
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
- struct kvm_vcpu_init *init);
+ struct kvm_vcpu_init *init, Error **errp);
/**
* kvm_arm_destroy_scratch_host_vcpu:
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index f9c7577460..b66eb4f6c2 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -62,6 +62,7 @@ typedef struct ARMHostCPUFeatures {
uint32_t target;
uint32_t sve_vq_supported;
const char *dtb_compatible;
+ Error *probe_err;
} ARMHostCPUFeatures;
static ARMHostCPUFeatures arm_host_cpu_features;
@@ -104,13 +105,14 @@ static int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature)
}
bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
- struct kvm_vcpu_init *init)
+ struct kvm_vcpu_init *init, Error **errp)
{
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
int max_vm_pa_size;
kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
if (kvmfd < 0) {
+ error_setg_errno(errp, errno, "Failed to open /dev/kvm");
goto err;
}
max_vm_pa_size = ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_ARM_VM_IPA_SIZE);
@@ -121,6 +123,7 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
} while (vmfd == -1 && errno == EINTR);
if (vmfd < 0) {
+ error_setg_errno(errp, errno, "Failed to create the scratch VM");
goto err;
}
@@ -140,6 +143,7 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
if (cpufd < 0) {
+ error_setg_errno(errp, errno, "Failed to create the scratch VCPU");
goto err;
}
@@ -153,12 +157,16 @@ bool kvm_arm_create_scratch_host_vcpu(int *fdarray,
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred);
if (ret < 0) {
+ error_setg_errno(errp, errno,
+ "Failed to get the preferred KVM target");
goto err;
}
init->target = preferred.target;
}
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
if (ret < 0) {
+ error_setg_errno(errp, errno,
+ "Failed to initialize the scratch VCPU");
goto err;
}
@@ -312,13 +320,19 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
}
-static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+/**
+ * kvm_arm_get_host_cpu_features:
+ * @ahcf: host CPU feature struct to populate
+ * @errp: error handle
+ *
+ * Identify the feature bits corresponding to the host CPU by creating a
+ * scratch VM/vCPU and querying its ID registers.
+ *
+ * On failure, @ahcf->target is QEMU_KVM_ARM_TARGET_NONE and *errp is set
+ * On success, @ahcf->target is set to a valid KVM target.
+ */
+static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf, Error **errp)
{
- /* Identify the feature bits corresponding to the host CPU, and
- * fill out the ARMHostCPUClass fields accordingly. To do this
- * we have to create a scratch VM, create a single CPU inside it,
- * and then query that CPU for the relevant ID registers.
- */
int fdarray[3];
bool sve_supported;
bool el2_supported;
@@ -330,6 +344,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
ahcf->dtb_compatible = "arm,armv8";
if (!kvm_enabled()) {
+ error_setg(errp, "KVM is not enabled");
return;
}
@@ -371,7 +386,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
features |= 1ULL << ARM_FEATURE_PMU;
}
- if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init)) {
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, &init, errp)) {
return;
}
@@ -502,6 +517,7 @@ static void kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
kvm_arm_destroy_scratch_host_vcpu(fdarray);
if (err < 0) {
+ error_setg(errp, "Failed to read some host CPU ID registers");
return;
}
@@ -528,7 +544,8 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
CPUARMState *env = &cpu->env;
if (!arm_host_cpu_features.dtb_compatible) {
- kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
+ kvm_arm_get_host_cpu_features(&arm_host_cpu_features,
+ &arm_host_cpu_features.probe_err);
}
cpu->kvm_target = arm_host_cpu_features.target;
@@ -538,8 +555,7 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
* We can't report this error yet, so flag that we need to
* in arm_cpu_realizefn().
*/
- error_setg(&cpu->host_cpu_probe_err,
- "failed to retrieve host CPU features");
+ cpu->host_cpu_probe_err = error_copy(arm_host_cpu_features.probe_err);
return;
}
@@ -2674,7 +2690,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3)
{
int fdarray[3];
- if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL)) {
+ if (!kvm_arm_create_scratch_host_vcpu(fdarray, NULL, NULL)) {
return;
}
--
2.53.0
next prev parent reply other threads:[~2026-10-30 13:16 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 13:13 [PATCH v4 for-11.2 00/10] kvm/arm: Some refactoring for custom KVM host model Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 01/10] target/arm/cpu-sysregs.h.inc: Sort by name alphabetical order Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 02/10] target/arm: Move REVIDR into isar.idregs[] storage Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 03/10] target/arm: Move MIDR " Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 04/10] target/arm: Enforce MPIDR " Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 05/10] target/arm/kvm: Pass an error handle to kvm_arm_init_cpreg_list Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 06/10] target/kvm: Pass an Error handle to kvm_arch_init_vcpu Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 07/10] target/arm/kvm: Introduce kvm_arm_vcpu_prepare_init_features helper Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 08/10] hw/arm/virt: Make sure virt_get_caches() keeps on reading CLIDR_EL1 as 0 Eric Auger
2026-10-30 13:13 ` [PATCH v4 for-11.2 09/10] target/arm: Directly store cpu probe failure error Eric Auger
2026-10-30 13:24 ` Peter Maydell
2026-10-30 13:13 ` Eric Auger [this message]
2026-10-30 13:25 ` [PATCH v4 for-11.2 10/10] target/arm/kvm: Improve error handling on scratch vcpu probe Peter Maydell
2026-10-30 13:38 ` Eric Auger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261030131406.461599-11-eric.auger@redhat.com \
--to=eric.auger@redhat.com \
--cc=7746591750@163.com \
--cc=alireza.sanaee@huawei.com \
--cc=amachhiw@linux.ibm.com \
--cc=armbru@redhat.com \
--cc=cohuck@redhat.com \
--cc=daniel.barboza@oss.qualcomm.com \
--cc=eric.auger.pro@gmail.com \
--cc=farman@linux.ibm.com \
--cc=harshpb@linux.ibm.com \
--cc=khushit.shah@nutanix.com \
--cc=maobibo@loongson.cn \
--cc=mbawa@redhat.com \
--cc=milesg@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@oss.qualcomm.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=shaju.abraham@nutanix.com \
--cc=skolothumtho@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.