diff options
Diffstat (limited to 'target/arm/kvm64.c')
-rw-r--r-- | target/arm/kvm64.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index a16abc8d12..6554c30007 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -381,46 +381,56 @@ static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr) return NULL; } -static bool kvm_arm_pmu_support_ctrl(CPUState *cs, struct kvm_device_attr *attr) +static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr) { - return kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr) == 0; + int err; + + err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); + if (err != 0) { + error_report("PMU: KVM_HAS_DEVICE_ATTR: %s", strerror(-err)); + return false; + } + + err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); + if (err != 0) { + error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err)); + return false; + } + + return true; } -int kvm_arm_pmu_create(CPUState *cs, int irq) +void kvm_arm_pmu_init(CPUState *cs) { - int err; - struct kvm_device_attr attr = { .group = KVM_ARM_VCPU_PMU_V3_CTRL, - .addr = (intptr_t)&irq, - .attr = KVM_ARM_VCPU_PMU_V3_IRQ, - .flags = 0, + .attr = KVM_ARM_VCPU_PMU_V3_INIT, }; - if (!kvm_arm_pmu_support_ctrl(cs, &attr)) { - return 0; + if (!ARM_CPU(cs)->has_pmu) { + return; } - - err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr); - if (err < 0) { - fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n", - strerror(-err)); + if (!kvm_arm_pmu_set_attr(cs, &attr)) { + error_report("failed to init PMU"); abort(); } +} - attr.group = KVM_ARM_VCPU_PMU_V3_CTRL; - attr.attr = KVM_ARM_VCPU_PMU_V3_INIT; - attr.addr = 0; - attr.flags = 0; +void kvm_arm_pmu_set_irq(CPUState *cs, int irq) +{ + struct kvm_device_attr attr = { + .group = KVM_ARM_VCPU_PMU_V3_CTRL, + .addr = (intptr_t)&irq, + .attr = KVM_ARM_VCPU_PMU_V3_IRQ, + }; - err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr); - if (err < 0) { - fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n", - strerror(-err)); + if (!ARM_CPU(cs)->has_pmu) { + return; + } + if (!kvm_arm_pmu_set_attr(cs, &attr)) { + error_report("failed to set irq for PMU"); abort(); } - - return 1; } static inline void set_feature(uint64_t *features, int feature) @@ -508,8 +518,7 @@ int kvm_arch_init_vcpu(CPUState *cs) if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT; } - if (!kvm_irqchip_in_kernel() || - !kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) { + if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) { cpu->has_pmu = false; } if (cpu->has_pmu) { |