From: Jan Kiszka <[email protected]> We can avoid the extra loop in gic_handle_redist_access just to map the virtual GICR address to its corresponding CPU. We just need to register one redist region per cell CPU.
Signed-off-by: Jan Kiszka <[email protected]> --- hypervisor/arch/arm/gic-v3.c | 51 +++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c index f629f9fc..9732085c 100644 --- a/hypervisor/arch/arm/gic-v3.c +++ b/hypervisor/arch/arm/gic-v3.c @@ -204,32 +204,7 @@ static void gic_adjust_irq_target(struct cell *cell, u16 irq_id) static enum mmio_result gic_handle_redist_access(void *arg, struct mmio_access *mmio) { - struct cell *cell = this_cell(); - unsigned int cpu; - unsigned int virt_id; - unsigned int redist_size = (gic_version == 4) ? 0x40000 : 0x20000; - void *phys_redist = NULL; - unsigned long offs; - - /* - * The redistributor accessed by the cell is not the one stored in these - * cpu_datas, but the one associated to its virtual id. So we first - * need to translate the redistributor address. - */ - for_each_cpu(cpu, cell->cpu_set) { - virt_id = arm_cpu_phys2virt(cpu); - offs = per_cpu(virt_id)->gicr_base - gicr_base; - if (mmio->address >= offs && - mmio->address < offs + redist_size) { - phys_redist = per_cpu(cpu)->gicr_base; - break; - } - } - - if (phys_redist == NULL) - return MMIO_ERROR; - - mmio->address -= offs; + struct per_cpu *cpu_data = arg; /* Change the ID register, all other accesses are allowed. */ if (!mmio->is_write) { @@ -245,23 +220,29 @@ static enum mmio_result gic_handle_redist_access(void *arg, /* AArch64 can use a writeq for this register */ if (mmio->size == 8) - mmio->value |= (u64)virt_id << 32; + mmio->value |= (u64)cpu_data->virt_id << 32; return MMIO_HANDLED; case GICR_TYPER + 4: /* Upper bits contain the affinity */ - mmio->value = virt_id; + mmio->value = cpu_data->virt_id; return MMIO_HANDLED; } } - mmio_perform_access(phys_redist, mmio); + mmio_perform_access(cpu_data->gicr_base, mmio); return MMIO_HANDLED; } static int gic_cell_init(struct cell *cell) { - mmio_region_register(cell, system_config->platform_info.arm.gicr_base, - GICR_SIZE, gic_handle_redist_access, NULL); + unsigned long redist_base = system_config->platform_info.arm.gicr_base; + unsigned long redist_size = gic_version == 4 ? 0x40000 : 0x20000; + unsigned int cpu; + + for_each_cpu(cpu, cell->cpu_set) + mmio_region_register(cell, + redist_base + per_cpu(cpu)->virt_id * redist_size, + redist_size, gic_handle_redist_access, per_cpu(cpu)); return 0; } @@ -441,7 +422,13 @@ static enum mmio_result gicv3_handle_irq_target(struct mmio_access *mmio, unsigned int irqchip_mmio_count_regions(struct cell *cell) { - return 2; + unsigned int cpu, regions = 1; /* GICD */ + + /* 1 GICR per CPU */ + for_each_cpu(cpu, cell->cpu_set) + regions++; + + return regions; } struct irqchip_ops irqchip = { -- 2.12.3 -- 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.
