pmu__generate_fdt_nodes() checks if the host has support for PMU in a guest and prints a warning if that's not the case. However, this check is too late because the function is called after the VCPU has been created, and VCPU creation fails if KVM_CAP_ARM_PMU_V3 is not available with a rather unhelpful error: $ ./vm run -c1 -m64 -f selftest.flat --pmu # lkvm run --firmware selftest.flat -m 64 -c 1 --name guest-1039 Info: Placing fdt at 0x80200000 - 0x80210000 Fatal: Unable to initialise vcpu Move the check for KVM_CAP_ARM_PMU_V3 to kvm_cpu__arch_init() before the VCPU is created so the user can get a more useful error message. This also matches the behaviour of KVM_CAP_ARM_EL1_32BIT. Signed-off-by: Alexandru Elisei <alexandru.elisei@xxxxxxx> --- arm/kvm-cpu.c | 4 ++++ arm/pmu.c | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c index 2acecaecb696..6a2408c632df 100644 --- a/arm/kvm-cpu.c +++ b/arm/kvm-cpu.c @@ -50,6 +50,10 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) !kvm__supports_extension(kvm, KVM_CAP_ARM_EL1_32BIT)) die("32bit guests are not supported\n"); + if (kvm->cfg.arch.has_pmuv3 && + !kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3)) + die("PMUv3 is not supported"); + vcpu = calloc(1, sizeof(struct kvm_cpu)); if (!vcpu) return NULL; diff --git a/arm/pmu.c b/arm/pmu.c index ffd152e27447..5b058eabb49d 100644 --- a/arm/pmu.c +++ b/arm/pmu.c @@ -43,11 +43,6 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) if (!kvm->cfg.arch.has_pmuv3) return; - if (!kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3)) { - pr_info("PMU unsupported\n"); - return; - } - for (i = 0; i < kvm->nrcpus; i++) { struct kvm_device_attr pmu_attr; -- 2.31.1