From: Jan Kiszka Date: Sun, 26 Jun 2016 08:14:34 +0000 (+0200) Subject: arm: Rework spi_in_cell to irqchip_irq_in_cell X-Git-Url: https://rtime.felk.cvut.cz/gitweb/jailhouse.git/commitdiff_plain/902ee9cfd32652f6926da709b259d46a68bdebf4?hp=b7857f0e03f4caea5b383a5722ce653bfd7e8ad5 arm: Rework spi_in_cell to irqchip_irq_in_cell Make use of the the fully populated irq_bitmap and enhance spi_in_cell to consider SGIs and PPIs as well. This allows to simplify restrict_bitmask_access. Signed-off-by: Jan Kiszka --- diff --git a/hypervisor/arch/arm/gic-common.c b/hypervisor/arch/arm/gic-common.c index c19d59a..ab405e5 100644 --- a/hypervisor/arch/arm/gic-common.c +++ b/hypervisor/arch/arm/gic-common.c @@ -57,14 +57,9 @@ restrict_bitmask_access(struct mmio_access *mmio, unsigned int reg_index, /* First, extract the first interrupt affected by this access */ unsigned int first_irq = reg_index * irqs_per_reg; - for (irq = first_irq; irq < first_irq + irqs_per_reg; irq++) { - unsigned int bit_nr = (irq - first_irq) * bits_per_irq; - - if ((is_spi(irq) && spi_in_cell(cell, irq - 32)) || - irq == SGI_INJECT || irq == SGI_CPU_OFF || - irq == MAINTENANCE_IRQ) - access_mask |= irq_bits << bit_nr; - } + for (irq = 0; irq < irqs_per_reg; irq++) + if (irqchip_irq_in_cell(cell, first_irq + irq)) + access_mask |= irq_bits << (irq * bits_per_irq); if (!mmio->is_write) { /* Restrict the read value */ @@ -112,7 +107,6 @@ static enum mmio_result handle_irq_target(struct mmio_access *mmio, */ struct cell *cell = this_cell(); unsigned int i, cpu; - unsigned int spi = irq - 32; unsigned int offset; u32 access_mask = 0; u8 targets; @@ -129,14 +123,14 @@ static enum mmio_result handle_irq_target(struct mmio_access *mmio, /* * The registers are byte-accessible, but we always do word accesses. */ - offset = spi % 4; + offset = irq % 4; mmio->address &= ~0x3; mmio->value <<= 8 * offset; mmio->size = 4; - spi -= offset; + irq &= ~0x3; - for (i = 0; i < 4; i++, spi++) { - if (spi_in_cell(cell, spi)) + for (i = 0; i < 4; i++, irq++) { + if (irqchip_irq_in_cell(cell, irq)) access_mask |= 0xff << (8 * i); else continue; @@ -364,7 +358,7 @@ void gic_target_spis(struct cell *config_cell, struct cell *dest_cell) itargetsr += 4 * 8; for (i = 0; i < 64; i++, shift = (shift + 8) % 32) { - if (spi_in_cell(config_cell, i)) { + if (irqchip_irq_in_cell(config_cell, 32 + i)) { mask |= (0xff << shift); bits |= (cpu_itf << shift); } diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c index e7d5e66..a231571 100644 --- a/hypervisor/arch/arm/gic-v3.c +++ b/hypervisor/arch/arm/gic-v3.c @@ -212,10 +212,9 @@ static void gic_route_spis(struct cell *config_cell, struct cell *dest_cell) for_each_cpu(first_cpu, dest_cell->cpu_set) break; - for (i = 0; i < 64; i++, irouter += 8) { - if (spi_in_cell(config_cell, i)) + for (i = 0; i < 64; i++, irouter += 8) + if (irqchip_irq_in_cell(config_cell, 32 + i)) mmio_write64(irouter, first_cpu); - } } static enum mmio_result gic_handle_redist_access(void *arg, @@ -360,7 +359,7 @@ enum mmio_result gic_handle_irq_route(struct mmio_access *mmio, * forbidden, because the guest driver may simply iterate over all * registers at initialisation */ - if (!spi_in_cell(cell, irq - 32)) + if (!irqchip_irq_in_cell(cell, irq)) return MMIO_HANDLED; /* Translate the virtual cpu id into the physical one */ diff --git a/hypervisor/arch/arm/include/asm/irqchip.h b/hypervisor/arch/arm/include/asm/irqchip.h index 42948e8..56b1b4a 100644 --- a/hypervisor/arch/arm/include/asm/irqchip.h +++ b/hypervisor/arch/arm/include/asm/irqchip.h @@ -73,7 +73,7 @@ void irqchip_eoi_irq(u32 irqn, bool deactivate); void irqchip_inject_pending(struct per_cpu *cpu_data); void irqchip_set_pending(struct per_cpu *cpu_data, u16 irq_id); -bool spi_in_cell(struct cell *cell, unsigned int spi); +bool irqchip_irq_in_cell(struct cell *cell, unsigned int irq_id); #endif /* __ASSEMBLY__ */ #endif /* _JAILHOUSE_ASM_IRQCHIP_H */ diff --git a/hypervisor/arch/arm/irqchip.c b/hypervisor/arch/arm/irqchip.c index 7dbd669..e3c813f 100644 --- a/hypervisor/arch/arm/irqchip.c +++ b/hypervisor/arch/arm/irqchip.c @@ -43,12 +43,12 @@ unsigned long gicd_size; */ static bool irqchip_is_init; -bool spi_in_cell(struct cell *cell, unsigned int spi) +bool irqchip_irq_in_cell(struct cell *cell, unsigned int irq_id) { - if (spi + 32 >= sizeof(cell->arch.irq_bitmap) * 8) + if (irq_id >= sizeof(cell->arch.irq_bitmap) * 8) return false; - return cell->arch.irq_bitmap[(spi + 32) / 32] & (1 << (spi % 32)); + return (cell->arch.irq_bitmap[irq_id / 32] & (1 << (irq_id % 32))) != 0; } void irqchip_set_pending(struct per_cpu *cpu_data, u16 irq_id)