This function returns true if the virtual irqchip of the a CPU has any interrupt pending for cell injection. Will be needed to emulate the PSCI service CPU_SUSPEND.
CC: Ralf Ramsauer <[email protected]> CC: Mark Rutland <[email protected]> Signed-off-by: Jan Kiszka <[email protected]> --- hypervisor/arch/arm-common/gic-v2.c | 12 ++++++++++++ hypervisor/arch/arm-common/include/asm/irqchip.h | 3 +++ hypervisor/arch/arm-common/irqchip.c | 5 +++++ hypervisor/arch/arm/gic-v3.c | 12 ++++++++++++ 4 files changed, 32 insertions(+) diff --git a/hypervisor/arch/arm-common/gic-v2.c b/hypervisor/arch/arm-common/gic-v2.c index 0cfae76..200ea5e 100644 --- a/hypervisor/arch/arm-common/gic-v2.c +++ b/hypervisor/arch/arm-common/gic-v2.c @@ -281,6 +281,17 @@ static void gic_enable_maint_irq(bool enable) mmio_write32(gich_base + GICH_HCR, hcr); } +static bool gic_has_pending_irqs(void) +{ + unsigned int n; + + for (n = 0; n < gic_num_lr; n++) + if (gic_read_lr(n) & GICH_LR_PENDING_BIT) + return true; + + return false; +} + enum mmio_result gic_handle_irq_route(struct mmio_access *mmio, unsigned int irq) { @@ -305,5 +316,6 @@ struct irqchip_ops irqchip = { .handle_irq = gic_handle_irq, .inject_irq = gic_inject_irq, .enable_maint_irq = gic_enable_maint_irq, + .has_pending_irqs = gic_has_pending_irqs, .eoi_irq = gic_eoi_irq, }; diff --git a/hypervisor/arch/arm-common/include/asm/irqchip.h b/hypervisor/arch/arm-common/include/asm/irqchip.h index bbe4ef3..afb5eee 100644 --- a/hypervisor/arch/arm-common/include/asm/irqchip.h +++ b/hypervisor/arch/arm-common/include/asm/irqchip.h @@ -52,6 +52,7 @@ struct irqchip_ops { void (*eoi_irq)(u32 irqn, bool deactivate); int (*inject_irq)(struct per_cpu *cpu_data, u16 irq_id); void (*enable_maint_irq)(bool enable); + bool (*has_pending_irqs)(void); int (*mmio_access)(struct mmio_access *access); }; @@ -72,6 +73,8 @@ int irqchip_send_sgi(struct sgi *sgi); void irqchip_handle_irq(struct per_cpu *cpu_data); void irqchip_eoi_irq(u32 irqn, bool deactivate); +bool irqchip_has_pending_irqs(void); + void irqchip_inject_pending(struct per_cpu *cpu_data); void irqchip_set_pending(struct per_cpu *cpu_data, u16 irq_id); diff --git a/hypervisor/arch/arm-common/irqchip.c b/hypervisor/arch/arm-common/irqchip.c index ed471e3..0b6f36c 100644 --- a/hypervisor/arch/arm-common/irqchip.c +++ b/hypervisor/arch/arm-common/irqchip.c @@ -50,6 +50,11 @@ bool irqchip_irq_in_cell(struct cell *cell, unsigned int irq_id) return (cell->arch.irq_bitmap[irq_id / 32] & (1 << (irq_id % 32))) != 0; } +bool irqchip_has_pending_irqs(void) +{ + return irqchip.has_pending_irqs(); +} + void irqchip_set_pending(struct per_cpu *cpu_data, u16 irq_id) { bool local_injection = (this_cpu_data() == cpu_data); diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c index b2e7311..2a42deb 100644 --- a/hypervisor/arch/arm/gic-v3.c +++ b/hypervisor/arch/arm/gic-v3.c @@ -423,6 +423,17 @@ static void gicv3_enable_maint_irq(bool enable) arm_write_sysreg(ICH_HCR_EL2, hcr); } +static bool gicv3_has_pending_irqs(void) +{ + unsigned int n; + + for (n = 0; n < gic_num_lr; n++) + if (gic_read_lr(n) & ICH_LR_PENDING) + return true; + + return false; +} + unsigned int irqchip_mmio_count_regions(struct cell *cell) { return 2; @@ -438,5 +449,6 @@ struct irqchip_ops irqchip = { .handle_irq = gic_handle_irq, .inject_irq = gic_inject_irq, .enable_maint_irq = gicv3_enable_maint_irq, + .has_pending_irqs = gicv3_has_pending_irqs, .eoi_irq = gic_eoi_irq, }; -- 2.1.4 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
