target/arm/kvm: pmu: split init and set-irq stages

When adding a PMU with a userspace irqchip we skip the set-irq
stage of device creation. Split the 'create' function into two
functions 'init' and 'set-irq' so they may be called separately.

Signed-off-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Message-id: 1500471597-2517-3-git-send-email-drjones@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Andrew Jones 2017-09-04 15:21:54 +01:00 committed by Peter Maydell
parent 07f48730bc
commit 3f07cb2aab
4 changed files with 53 additions and 36 deletions

View file

@ -381,46 +381,44 @@ 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)
{
return kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr) == 0;
}
int kvm_arm_pmu_create(CPUState *cs, int irq)
static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr)
{
int err;
err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
if (err != 0) {
return false;
}
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
if (err < 0) {
fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
strerror(-err));
abort();
}
return true;
}
int kvm_arm_pmu_init(CPUState *cs)
{
struct kvm_device_attr attr = {
.group = KVM_ARM_VCPU_PMU_V3_CTRL,
.attr = KVM_ARM_VCPU_PMU_V3_INIT,
};
return kvm_arm_pmu_set_attr(cs, &attr);
}
int 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,
.flags = 0,
};
if (!kvm_arm_pmu_support_ctrl(cs, &attr)) {
return 0;
}
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
if (err < 0) {
fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
strerror(-err));
abort();
}
attr.group = KVM_ARM_VCPU_PMU_V3_CTRL;
attr.attr = KVM_ARM_VCPU_PMU_V3_INIT;
attr.addr = 0;
attr.flags = 0;
err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, &attr);
if (err < 0) {
fprintf(stderr, "KVM_SET_DEVICE_ATTR failed: %s\n",
strerror(-err));
abort();
}
return 1;
return kvm_arm_pmu_set_attr(cs, &attr);
}
static inline void set_feature(uint64_t *features, int feature)