@@ -593,6 +593,17 @@ void arch_evtchn_inject(struct vcpu *v)
vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq);
}
+bool vgic_evtchn_irq_pending(struct vcpu *v)
+{
+ struct pending_irq *p;
+
+ p = irq_to_pending(v, v->domain->arch.evtchn_irq);
+ /* Does not work for LPIs. */
+ ASSERT(!is_lpi(v->domain->arch.evtchn_irq));
+
+ return list_empty(&p->inflight);
+}
+
bool vgic_emulate(struct cpu_user_regs *regs, union hsr hsr)
{
struct vcpu *v = current;
@@ -16,12 +16,6 @@ static inline int vcpu_event_delivery_is_enabled(struct vcpu *v)
static inline int local_events_need_delivery_nomask(void)
{
- struct pending_irq *p = irq_to_pending(current,
- current->domain->arch.evtchn_irq);
-
- /* Does not work for LPIs. */
- ASSERT(!is_lpi(current->domain->arch.evtchn_irq));
-
/* XXX: if the first interrupt has already been delivered, we should
* check whether any other interrupts with priority higher than the
* one in GICV_IAR are in the lr_pending queue or in the LR
@@ -33,11 +27,10 @@ static inline int local_events_need_delivery_nomask(void)
if ( gic_events_need_delivery() )
return 1;
- if ( vcpu_info(current, evtchn_upcall_pending) &&
- list_empty(&p->inflight) )
- return 1;
+ if ( !vcpu_info(current, evtchn_upcall_pending) )
+ return 0;
- return 0;
+ return vgic_evtchn_irq_pending(current);
}
static inline int local_events_need_delivery(void)
@@ -218,6 +218,8 @@ extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops);
int vgic_v2_init(struct domain *d, int *mmio_count);
int vgic_v3_init(struct domain *d, int *mmio_count);
+bool vgic_evtchn_irq_pending(struct vcpu *v);
+
extern int domain_vgic_register(struct domain *d, int *mmio_count);
extern int vcpu_vgic_free(struct vcpu *v);
extern bool vgic_to_sgi(struct vcpu *v, register_t sgir,