summaryrefslogtreecommitdiffstats
path: root/target/arm/kvm64.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/kvm64.c')
-rw-r--r--target/arm/kvm64.c63
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) {