Commit 42ec50b5 authored by Richard Cochran's avatar Richard Cochran Committed by Ingo Molnar

arm/kvm/vgic: Convert to hotplug state machine

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.
The VGIC callback is run after KVM's main callback since it reflects the
makefile order.
Signed-off-by: default avatarRichard Cochran <rcochran@linutronix.de>
Signed-off-by: default avatarAnna-Maria Gleixner <anna-maria@linutronix.de>
Reviewed-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Radim Krcmar <rkrcmar@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: kvm@vger.kernel.org
Cc: kvmarm@lists.cs.columbia.edu
Cc: linux-arm-kernel@lists.infradead.org
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160713153336.546953286@linutronix.deSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 911a359d
...@@ -42,6 +42,7 @@ enum cpuhp_state { ...@@ -42,6 +42,7 @@ enum cpuhp_state {
CPUHP_AP_QCOM_TIMER_STARTING, CPUHP_AP_QCOM_TIMER_STARTING,
CPUHP_AP_MIPS_GIC_TIMER_STARTING, CPUHP_AP_MIPS_GIC_TIMER_STARTING,
CPUHP_AP_KVM_STARTING, CPUHP_AP_KVM_STARTING,
CPUHP_AP_KVM_ARM_VGIC_STARTING,
CPUHP_AP_LEDTRIG_STARTING, CPUHP_AP_LEDTRIG_STARTING,
CPUHP_AP_NOTIFY_STARTING, CPUHP_AP_NOTIFY_STARTING,
CPUHP_AP_ONLINE, CPUHP_AP_ONLINE,
......
...@@ -2326,32 +2326,18 @@ int vgic_has_attr_regs(const struct vgic_io_range *ranges, phys_addr_t offset) ...@@ -2326,32 +2326,18 @@ int vgic_has_attr_regs(const struct vgic_io_range *ranges, phys_addr_t offset)
return -ENXIO; return -ENXIO;
} }
static void vgic_init_maintenance_interrupt(void *info) static int vgic_starting_cpu(unsigned int cpu)
{ {
enable_percpu_irq(vgic->maint_irq, 0); enable_percpu_irq(vgic->maint_irq, 0);
return 0;
} }
static int vgic_cpu_notify(struct notifier_block *self, static int vgic_dying_cpu(unsigned int cpu)
unsigned long action, void *cpu)
{ {
switch (action) { disable_percpu_irq(vgic->maint_irq);
case CPU_STARTING: return 0;
case CPU_STARTING_FROZEN:
vgic_init_maintenance_interrupt(NULL);
break;
case CPU_DYING:
case CPU_DYING_FROZEN:
disable_percpu_irq(vgic->maint_irq);
break;
}
return NOTIFY_OK;
} }
static struct notifier_block vgic_cpu_nb = {
.notifier_call = vgic_cpu_notify,
};
static int kvm_vgic_probe(void) static int kvm_vgic_probe(void)
{ {
const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_kvm_info;
...@@ -2392,19 +2378,10 @@ int kvm_vgic_hyp_init(void) ...@@ -2392,19 +2378,10 @@ int kvm_vgic_hyp_init(void)
return ret; return ret;
} }
ret = __register_cpu_notifier(&vgic_cpu_nb); cpuhp_setup_state(CPUHP_AP_KVM_ARM_VGIC_STARTING,
if (ret) { "AP_KVM_ARM_VGIC_STARTING", vgic_starting_cpu,
kvm_err("Cannot register vgic CPU notifier\n"); vgic_dying_cpu);
goto out_free_irq;
}
on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1);
return 0; return 0;
out_free_irq:
free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus());
return ret;
} }
int kvm_irq_map_gsi(struct kvm *kvm, int kvm_irq_map_gsi(struct kvm *kvm,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment