static void generic_virt_irq_inject(struct vmm_vcpu *vcpu, struct generic_timer_context *cntx) { int rc; u32 virq; virq = cntx->virt_timer_irq; if (virq == 0) { vmm_printf("%s: Virtual timer irq not available (VCPU=%s)\n", __func__, vcpu->name); return; } rc = vmm_devemu_emulate_percpu_irq(vcpu->guest, virq, vcpu->subid, 0); if (rc) { vmm_printf("%s: Emulate VCPU=%s irq=%d level=0 failed\n", __func__, vcpu->name, virq); } rc = vmm_devemu_emulate_percpu_irq(vcpu->guest, virq, vcpu->subid, 1); if (rc) { vmm_printf("%s: Emulate VCPU=%s irq=%d level=1 failed\n", __func__, vcpu->name, virq); } }
static vmm_irq_return_t generic_virt_timer_handler(int irq, void *dev) { int rc; u32 ctl, virq; struct vmm_vcpu *vcpu; ctl = generic_timer_reg_read(GENERIC_TIMER_REG_VIRT_CTRL); if (!(ctl & GENERIC_TIMER_CTRL_IT_STAT)) { /* We got interrupt without status bit set. * Looks like we are running on buggy hardware. */ vmm_printf("%s: suprious interrupt\n", __func__); return VMM_IRQ_NONE; } ctl |= GENERIC_TIMER_CTRL_IT_MASK; generic_timer_reg_write(GENERIC_TIMER_REG_VIRT_CTRL, ctl); vcpu = vmm_scheduler_current_vcpu(); if (!vcpu->is_normal) { /* We accidently got an interrupt meant for normal VCPU * that was previously running on this host CPU. */ vmm_printf("%s: In orphan context (current VCPU=%s)\n", __func__, vcpu->name); return VMM_IRQ_NONE; } virq = arm_gentimer_context(vcpu)->virt_timer_irq; if (virq == 0) { return VMM_IRQ_NONE; } rc = vmm_devemu_emulate_percpu_irq(vcpu->guest, virq, vcpu->subid, 0); if (rc) { vmm_printf("%s: Emulate VCPU=%s irq=%d level=0 failed\n", __func__, vcpu->name, virq); } rc = vmm_devemu_emulate_percpu_irq(vcpu->guest, virq, vcpu->subid, 1); if (rc) { vmm_printf("%s: Emulate VCPU=%s irq=%d level=1 failed\n", __func__, vcpu->name, virq); } return VMM_IRQ_HANDLED; }