diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 7e43691..f5ff69b 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -663,6 +663,7 @@ void arch_domain_destroy(struct domain *d) /* IOMMU page table is shared with P2M, always call * iommu_domain_destroy() before p2m_teardown(). */ + WRITE_SYSREG32(0, CNTP_CTL_EL0); iommu_domain_destroy(d); p2m_teardown(d); domain_vgic_free(d); diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index a5348f2..5c8b621 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -47,7 +47,7 @@ static DEFINE_PER_CPU(uint64_t, lr_mask); static void gic_update_one_lr(struct vcpu *v, int i); -static const struct gic_hw_operations *gic_hw_ops; +const struct gic_hw_operations *gic_hw_ops; void register_gic_ops(const struct gic_hw_operations *ops) { diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index dd62ba6..9a4e50d 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -184,6 +184,7 @@ int request_irq(unsigned int irq, unsigned int irqflags, } /* Dispatch an interrupt */ +extern const struct gic_hw_operations *gic_hw_ops; void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) { struct irq_desc *desc = irq_to_desc(irq); @@ -202,6 +203,12 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) irq_enter(); spin_lock(&desc->lock); + + if (irq == 30) { + set_bit(_IRQ_GUEST, &desc->status); + desc->handler = gic_hw_ops->gic_guest_irq_type; + } + desc->handler->ack(desc); if ( !desc->action ) @@ -224,7 +231,23 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) * The irq cannot be a PPI, we only support delivery of SPIs to * guests. */ - vgic_vcpu_inject_spi(info->d, info->virq); + if (irq != 30) + vgic_vcpu_inject_spi(info->d, info->virq); + else { + struct domain *d; + + for_each_domain ( d ) + { + struct pending_irq *p; + + if (d->domain_id == 0 || is_idle_domain(d)) + continue; + p = irq_to_pending(d->vcpu[0], 30); + p->desc = desc; + vgic_vcpu_inject_irq(d->vcpu[0], 30); + break; + } + } goto out_no_end; } diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c index 7dae28b..0249631 100644 --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -297,9 +300,9 @@ void init_timer_interrupt(void) /* Sensible defaults */ WRITE_SYSREG64(0, CNTVOFF_EL2); /* No VM-specific offset */ /* Do not let the VMs program the physical timer, only read the physical counter */ - WRITE_SYSREG32(CNTHCTL_EL2_EL1PCTEN, CNTHCTL_EL2); WRITE_SYSREG32(0, CNTP_CTL_EL0); /* Physical timer disabled */ WRITE_SYSREG32(0, CNTHP_CTL_EL2); /* Hypervisor's timer disabled */ + WRITE_SYSREG32(CNTHCTL_EL2_EL1PCTEN|CNTHCTL_EL2_EL1PCEN, CNTHCTL_EL2); isb(); request_irq(timer_irq[TIMER_HYP_PPI], 0, timer_interrupt,