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:
		
							parent
							
								
									07f48730bc
								
							
						
					
					
						commit
						3f07cb2aab
					
				@ -492,10 +492,17 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
 | 
			
		||||
 | 
			
		||||
    CPU_FOREACH(cpu) {
 | 
			
		||||
        armcpu = ARM_CPU(cpu);
 | 
			
		||||
        if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) ||
 | 
			
		||||
            (kvm_enabled() && !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ)))) {
 | 
			
		||||
        if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (kvm_enabled()) {
 | 
			
		||||
            if (!kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ))) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (!kvm_arm_pmu_init(cpu)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (vms->gic_version == 2) {
 | 
			
		||||
 | 
			
		||||
@ -522,7 +522,13 @@ bool kvm_arm_hw_debug_active(CPUState *cs)
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int kvm_arm_pmu_create(CPUState *cs, int irq)
 | 
			
		||||
int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
 | 
			
		||||
{
 | 
			
		||||
    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int kvm_arm_pmu_init(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,8 @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu);
 | 
			
		||||
 | 
			
		||||
int kvm_arm_vgic_probe(void);
 | 
			
		||||
 | 
			
		||||
int kvm_arm_pmu_create(CPUState *cs, int irq);
 | 
			
		||||
int kvm_arm_pmu_set_irq(CPUState *cs, int irq);
 | 
			
		||||
int kvm_arm_pmu_init(CPUState *cs);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
@ -204,7 +205,12 @@ static inline int kvm_arm_vgic_probe(void)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int kvm_arm_pmu_create(CPUState *cs, int irq)
 | 
			
		||||
static inline int kvm_arm_pmu_set_irq(CPUState *cs, int irq)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int kvm_arm_pmu_init(CPUState *cs)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user