On Thursday, December 6, 2012, Marc Zyngier wrote:
Register a CPU hotplug notifier that disables/enables the interrupt
as requested.
Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx>
---
arch/arm/kvm/vgic.c | 47 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 10 deletions(-)
diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
index 4a140da..49b594e 100644
--- a/arch/arm/kvm/vgic.c
+++ b/arch/arm/kvm/vgic.c
@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/cpu.h>
#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <linux/interrupt.h>
@@ -93,6 +94,8 @@ static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg);
static u32 vgic_nr_lr;
+static unsigned int vgic_irq;
this could mean anything in this context. I don't really have a great suggestion though, vgic_host_irq_number ?
+
static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x,
int cpuid, u32 offset)
{
@@ -1268,15 +1271,33 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
static void vgic_init_maintenance_interrupt(void *info)
{
- unsigned int *irqp = info;
+ enable_percpu_irq(vgic_irq, 0);
+}
+
+static int vgic_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *cpu)
+{
+ switch (action) {
+ case CPU_STARTING:
+ case CPU_STARTING_FROZEN:
+ vgic_init_maintenance_interrupt(NULL);
+ break;
+ case CPU_DYING:
+ case CPU_DYING_FROZEN:
+ disable_percpu_irq(vgic_irq);
+ break;
+ }
- enable_percpu_irq(*irqp, 0);
+ return NOTIFY_OK;
}
+static struct notifier_block vgic_cpu_nb = {
+ .notifier_call = vgic_cpu_notify,
+};
+
int kvm_vgic_hyp_init(void)
{
int ret;
- unsigned int irq;
struct resource vctrl_res;
struct resource vcpu_res;
@@ -1284,17 +1305,23 @@ int kvm_vgic_hyp_init(void)
if (!vgic_node)
return -ENODEV;
- irq = irq_of_parse_and_map(vgic_node, 0);
- if (!irq)
+ vgic_irq = irq_of_parse_and_map(vgic_node, 0);
+ if (!vgic_irq)
return -ENXIO;
- ret = request_percpu_irq(irq, vgic_maintenance_handler,
+ ret = request_percpu_irq(vgic_irq, vgic_maintenance_handler,
"vgic", kvm_get_running_vcpus());
if (ret) {
- kvm_err("Cannot register interrupt %d\n", irq);
+ kvm_err("Cannot register interrupt %d\n", vgic_irq);
return ret;
}
+ ret = register_cpu_notifier(&vgic_cpu_nb);
+ if (ret) {
+ kvm_err("Cannot register vgic CPU notifier\n");
+ goto out_free_irq;
+ }
+
ret = of_address_to_resource(vgic_node, 2, &vctrl_res);
if (ret) {
kvm_err("Cannot obtain VCTRL resource\n");
@@ -1319,8 +1346,8 @@ int kvm_vgic_hyp_init(void)
goto out_unmap;
}
- kvm_info("%s@%llx IRQ%d\n", vgic_node->name, vctrl_res.start, irq);
- on_each_cpu(vgic_init_maintenance_interrupt, &irq, 1);
+ kvm_info("%s@%llx IRQ%d\n", vgic_node->name, vctrl_res.start, vgic_irq);
+ on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1);
if (of_address_to_resource(vgic_node, 3, &vcpu_res)) {
kvm_err("Cannot obtain VCPU resource\n");
@@ -1334,7 +1361,7 @@ int kvm_vgic_hyp_init(void)
out_unmap:
iounmap(vgic_vctrl_base);
out_free_irq:
- free_percpu_irq(irq, kvm_get_running_vcpus());
+ free_percpu_irq(vgic_irq, kvm_get_running_vcpus());
return ret;
}
--
1.8.0.1
besides that variable name, looks good.
_______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm