This allows to report a precise error message if any error occurs.

In arm_gic_cap_kvm_probe() call path we just pass a NULL error handle
because we don't care about the failure, reverting to emulated
versions.

Signed-off-by: Eric Auger <[email protected]>
---
 target/arm/kvm_arm.h |  3 ++-
 target/arm/kvm.c     | 27 ++++++++++++++++++---------
 2 files changed, 20 insertions(+), 10 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 fc9551411e..c6ba2cb29a 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -104,13 +104,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 +122,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 +142,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 +156,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,7 +319,8 @@ static uint32_t kvm_arm_sve_get_vls(int fd)
     return vls[0] & MAKE_64BIT_MASK(0, ARM_MAX_VQ);
 }
 
-static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
+static bool
+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
@@ -330,6 +338,7 @@ static bool 
kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
     ahcf->dtb_compatible = "arm,armv8";
 
     if (!kvm_enabled()) {
+        error_setg(errp, "KVM is not enabled");
         return false;
     }
 
@@ -371,7 +380,7 @@ static bool 
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 false;
     }
 
@@ -502,6 +511,7 @@ static bool 
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 false;
     }
 
@@ -527,15 +537,14 @@ static bool 
kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
 void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
 {
     CPUARMState *env = &cpu->env;
-    static bool probe_ok;
+    static Error *probe_err;
 
     if (!arm_host_cpu_features.dtb_compatible) {
-        probe_ok = kvm_arm_get_host_cpu_features(&arm_host_cpu_features);
+        kvm_arm_get_host_cpu_features(&arm_host_cpu_features, &probe_err);
     }
 
-    if (!probe_ok) {
-        error_setg(&cpu->host_cpu_probe_err,
-                   "failed to retrieve host CPU features");
+    if (probe_err) {
+        cpu->host_cpu_probe_err = error_copy(probe_err);
         return;
     }
 
@@ -2671,7 +2680,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


Reply via email to