int kvm_timer_hyp_init(void) { struct device_node *np; unsigned int ppi; int err; timecounter = arch_timer_get_timecounter(); if (!timecounter) return -ENODEV; np = of_find_matching_node(NULL, arch_timer_of_match); if (!np) { kvm_err("kvm_arch_timer: can't find DT node\n"); return -ENODEV; } ppi = irq_of_parse_and_map(np, 2); if (!ppi) { kvm_err("kvm_arch_timer: no virtual timer interrupt\n"); err = -EINVAL; goto out; } err = request_percpu_irq(ppi, kvm_arch_timer_handler, "kvm guest timer", kvm_get_running_vcpus()); if (err) { kvm_err("kvm_arch_timer: can't request interrupt %d (%d)\n", ppi, err); goto out; } timer_irq.irq = ppi; err = register_cpu_notifier(&kvm_timer_cpu_nb); if (err) { kvm_err("Cannot register timer CPU notifier\n"); goto out_free; } wqueue = create_singlethread_workqueue("kvm_arch_timer"); if (!wqueue) { err = -ENOMEM; goto out_free; } kvm_info("%s IRQ%d\n", np->name, ppi); on_each_cpu(kvm_timer_init_interrupt, NULL, 1); goto out; out_free: free_percpu_irq(ppi, kvm_get_running_vcpus()); out: of_node_put(np); return err; }
/** * kvm_vgic_hyp_init: populates the kvm_vgic_global_state variable * according to the host GIC model. Accordingly calls either * vgic_v2/v3_probe which registers the KVM_DEVICE that can be * instantiated by a guest later on . */ int kvm_vgic_hyp_init(void) { const struct gic_kvm_info *gic_kvm_info; int ret; gic_kvm_info = gic_get_kvm_info(); if (!gic_kvm_info) return -ENODEV; if (!gic_kvm_info->maint_irq) { kvm_err("No vgic maintenance irq\n"); return -ENXIO; } switch (gic_kvm_info->type) { case GIC_V2: ret = vgic_v2_probe(gic_kvm_info); break; case GIC_V3: ret = vgic_v3_probe(gic_kvm_info); break; default: ret = -ENODEV; }; if (ret) return ret; kvm_vgic_global_state.maint_irq = gic_kvm_info->maint_irq; ret = request_percpu_irq(kvm_vgic_global_state.maint_irq, vgic_maintenance_handler, "vgic", kvm_get_running_vcpus()); if (ret) { kvm_err("Cannot register interrupt %d\n", kvm_vgic_global_state.maint_irq); return ret; } ret = cpuhp_setup_state(CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING, "AP_KVM_ARM_VGIC_INIT_STARTING", vgic_init_cpu_starting, vgic_init_cpu_dying); if (ret) { kvm_err("Cannot register vgic CPU notifier\n"); goto out_free_irq; } kvm_info("vgic interrupt IRQ%d\n", kvm_vgic_global_state.maint_irq); return 0; out_free_irq: free_percpu_irq(kvm_vgic_global_state.maint_irq, kvm_get_running_vcpus()); return ret; }