[PATCH v3 10/13] arm: move the handle_irq_route function to the GICv3 module

3 views
Skip to first unread message

antonios...@huawei.com

unread,
Jun 17, 2016, 3:11:25 PM6/17/16
to jailho...@googlegroups.com, Antonios Motakis, jan.k...@siemens.com, claudio...@huawei.com, jani.k...@huawei.com, dmitry...@huawei.com, veacesla...@huawei.com, jean-phili...@arm.com, marc.z...@arm.com, edgar.i...@xilinx.com, wuqi...@huawei.com, mazda....@amd.com
From: Antonios Motakis <antonios...@huawei.com>

The handle_irq_route function is not needed with the GICv2.

On the ARMv8 port we will not assign a virt_id to each CPU,
opting to use the MPIDR as much as we can from the start.
GICv3 will need heavier refactoring for this purpose; by moving
this function we can reuse the GICv2 code on ARMv8.

Signed-off-by: Antonios Motakis <antonios...@huawei.com>
---
hypervisor/arch/arm/gic-common.c | 43 ++--------------------------
hypervisor/arch/arm/gic-v3.c | 40 ++++++++++++++++++++++++++
hypervisor/arch/arm/include/asm/gic_common.h | 1 -
hypervisor/arch/arm/include/asm/gic_v3.h | 3 ++
4 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/hypervisor/arch/arm/gic-common.c b/hypervisor/arch/arm/gic-common.c
index ff32114..83aa363 100644
--- a/hypervisor/arch/arm/gic-common.c
+++ b/hypervisor/arch/arm/gic-common.c
@@ -110,46 +110,6 @@ restrict_bitmask_access(struct mmio_access *mmio, unsigned int reg_index,
}

/*
- * GICv3 uses a 64bit register IROUTER for each IRQ
- */
-static enum mmio_result handle_irq_route(struct mmio_access *mmio,
- unsigned int irq)
-{
- struct cell *cell = this_cell();
- unsigned int cpu;
-
- /* Ignore aff3 on AArch32 (return 0) */
- if (mmio->size == 4 && (mmio->address % 8))
- return MMIO_HANDLED;
-
- /* SGIs and PPIs are res0 */
- if (!is_spi(irq))
- return MMIO_HANDLED;
-
- /*
- * Ignore accesses to SPIs that do not belong to the cell. This isn't
- * forbidden, because the guest driver may simply iterate over all
- * registers at initialisation
- */
- if (!spi_in_cell(cell, irq - 32))
- return MMIO_HANDLED;
-
- /* Translate the virtual cpu id into the physical one */
- if (mmio->is_write) {
- mmio->value = arm_cpu_virt2phys(cell, mmio->value);
- if (mmio->value == -1) {
- printk("Attempt to route IRQ%d outside of cell\n", irq);
- return MMIO_ERROR;
- }
- mmio_perform_access(gicd_base, mmio);
- } else {
- cpu = mmio_read32(gicd_base + GICD_IROUTER + 8 * irq);
- mmio->value = arm_cpu_phys2virt(cpu);
- }
- return MMIO_HANDLED;
-}
-
-/*
* GICv2 uses 8bit values for each IRQ in the ITARGETRs registers
*/
static enum mmio_result handle_irq_target(struct mmio_access *mmio,
@@ -312,10 +272,11 @@ enum mmio_result gic_handle_dist_access(void *arg, struct mmio_access *mmio)
enum mmio_result ret;

switch (reg) {
+#ifdef CONFIG_ARM_GIC_V3
case REG_RANGE(GICD_IROUTER, 1024, 8):
ret = handle_irq_route(mmio, (reg - GICD_IROUTER) / 8);
break;
-
+#endif
case REG_RANGE(GICD_ITARGETSR, 1024, 1):
ret = handle_irq_target(mmio, reg - GICD_ITARGETSR);
break;
diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c
index b422200..6e5cd26 100644
--- a/hypervisor/arch/arm/gic-v3.c
+++ b/hypervisor/arch/arm/gic-v3.c
@@ -338,6 +338,46 @@ void gicv3_handle_sgir_write(u64 sgir)
gic_handle_sgir_write(&sgi, true);
}

+/*
+ * GICv3 uses a 64bit register IROUTER for each IRQ
+ */
+enum mmio_result handle_irq_route(struct mmio_access *mmio,
+ unsigned int irq)
+{
+ struct cell *cell = this_cell();
+ unsigned int cpu;
+
+ /* Ignore aff3 on AArch32 (return 0) */
+ if (mmio->size == 4 && (mmio->address % 8))
+ return MMIO_HANDLED;
+
+ /* SGIs and PPIs are res0 */
+ if (!is_spi(irq))
+ return MMIO_HANDLED;
+
+ /*
+ * Ignore accesses to SPIs that do not belong to the cell. This isn't
+ * forbidden, because the guest driver may simply iterate over all
+ * registers at initialisation
+ */
+ if (!spi_in_cell(cell, irq - 32))
+ return MMIO_HANDLED;
+
+ /* Translate the virtual cpu id into the physical one */
+ if (mmio->is_write) {
+ mmio->value = arm_cpu_virt2phys(cell, mmio->value);
+ if (mmio->value == -1) {
+ printk("Attempt to route IRQ%d outside of cell\n", irq);
+ return MMIO_ERROR;
+ }
+ mmio_perform_access(gicd_base, mmio);
+ } else {
+ cpu = mmio_read32(gicd_base + GICD_IROUTER + 8 * irq);
+ mmio->value = arm_cpu_phys2virt(cpu);
+ }
+ return MMIO_HANDLED;
+}
+
static void gic_eoi_irq(u32 irq_id, bool deactivate)
{
arm_write_sysreg(ICC_EOIR1_EL1, irq_id);
diff --git a/hypervisor/arch/arm/include/asm/gic_common.h b/hypervisor/arch/arm/include/asm/gic_common.h
index 0381194..853ac3d 100644
--- a/hypervisor/arch/arm/include/asm/gic_common.h
+++ b/hypervisor/arch/arm/include/asm/gic_common.h
@@ -33,7 +33,6 @@
#define GICD_SGIR 0x0f00
#define GICD_CPENDSGIR 0x0f10
#define GICD_SPENDSGIR 0x0f20
-#define GICD_IROUTER 0x6000

#define GICD_PIDR2_ARCH(pidr) (((pidr) & 0xf0) >> 4)

diff --git a/hypervisor/arch/arm/include/asm/gic_v3.h b/hypervisor/arch/arm/include/asm/gic_v3.h
index 4bf2bba..db96fad 100644
--- a/hypervisor/arch/arm/include/asm/gic_v3.h
+++ b/hypervisor/arch/arm/include/asm/gic_v3.h
@@ -15,6 +15,8 @@

#include <asm/sysregs.h>

+#define GICD_IROUTER 0x6000
+
#define GICD_CIDR0 0xfff0
#define GICD_CIDR1 0xfff4
#define GICD_CIDR2 0xfff8
@@ -261,6 +263,7 @@ static inline u32 gic_read_iar(void)
}

void gicv3_handle_sgir_write(u64 sgir);
+enum mmio_result handle_irq_route(struct mmio_access *mmio, unsigned int irq);

#endif /* __ASSEMBLY__ */
#endif /* _JAILHOUSE_ASM_GIC_V3_H */
--
2.8.0.rc3


Jan Kiszka

unread,
Jun 23, 2016, 4:14:28 AM6/23/16
to antonios...@huawei.com, jailho...@googlegroups.com, claudio...@huawei.com, jani.k...@huawei.com, dmitry...@huawei.com, veacesla...@huawei.com, jean-phili...@arm.com, marc.z...@arm.com, edgar.i...@xilinx.com, wuqi...@huawei.com, mazda....@amd.com
On 2016-06-17 21:10, antonios...@huawei.com wrote:
> From: Antonios Motakis <antonios...@huawei.com>
>
> The handle_irq_route function is not needed with the GICv2.
>
> On the ARMv8 port we will not assign a virt_id to each CPU,
> opting to use the MPIDR as much as we can from the start.
> GICv3 will need heavier refactoring for this purpose; by moving
> this function we can reuse the GICv2 code on ARMv8.
>
> Signed-off-by: Antonios Motakis <antonios...@huawei.com>

I just merged this variant to next instead, please cross-check:


From: Antonios Motakis <antonios...@huawei.com>

The handle_irq_route function is not needed with the GICv2.

On the ARMv8 port we will not assign a virt_id to each CPU,
opting to use the MPIDR as much as we can from the start.
GICv3 will need heavier refactoring for this purpose; by moving
this function we can reuse the GICv2 code on ARMv8.

Signed-off-by: Antonios Motakis <antonios...@huawei.com>
[Jan: implement stub in v2 to reduce #ifdefs]
Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
hypervisor/arch/arm/gic-common.c | 42 +---------------------------
hypervisor/arch/arm/gic-v2.c | 7 +++++
hypervisor/arch/arm/gic-v3.c | 40 ++++++++++++++++++++++++++
hypervisor/arch/arm/include/asm/gic_common.h | 2 ++
4 files changed, 50 insertions(+), 41 deletions(-)

diff --git a/hypervisor/arch/arm/gic-common.c b/hypervisor/arch/arm/gic-common.c
index b8dd99a..4a4d186 100644
@@ -313,7 +273,7 @@ enum mmio_result gic_handle_dist_access(void *arg, struct mmio_access *mmio)

switch (reg) {
case REG_RANGE(GICD_IROUTER, 1024, 8):
- ret = handle_irq_route(mmio, (reg - GICD_IROUTER) / 8);
+ ret = gic_handle_irq_route(mmio, (reg - GICD_IROUTER) / 8);
break;

case REG_RANGE(GICD_ITARGETSR, 1024, 1):
diff --git a/hypervisor/arch/arm/gic-v2.c b/hypervisor/arch/arm/gic-v2.c
index ff0036b..c53e58a 100644
--- a/hypervisor/arch/arm/gic-v2.c
+++ b/hypervisor/arch/arm/gic-v2.c
@@ -288,6 +288,13 @@ static void gic_enable_maint_irq(bool enable)
mmio_write32(gich_base + GICH_HCR, hcr);
}

+enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
+ unsigned int irq)
+{
+ /* doesn't exist in v2 - ignore access */
+ return MMIO_HANDLED;
+}
+
unsigned int irqchip_mmio_count_regions(struct cell *cell)
{
return 1;
diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c
index b422200..e7d5e66 100644
--- a/hypervisor/arch/arm/gic-v3.c
+++ b/hypervisor/arch/arm/gic-v3.c
@@ -338,6 +338,46 @@ void gicv3_handle_sgir_write(u64 sgir)
gic_handle_sgir_write(&sgi, true);
}

+/*
+ * GICv3 uses a 64bit register IROUTER for each IRQ
+ */
+enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
index 0381194..4c58933 100644
--- a/hypervisor/arch/arm/include/asm/gic_common.h
+++ b/hypervisor/arch/arm/include/asm/gic_common.h
@@ -50,6 +50,8 @@ struct sgi;

int gic_probe_cpu_id(unsigned int cpu);
enum mmio_result gic_handle_dist_access(void *arg, struct mmio_access *mmio);
+enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
+ unsigned int irq);
void gic_handle_sgir_write(struct sgi *sgi, bool virt_input);
void gic_handle_irq(struct per_cpu *cpu_data);
void gic_target_spis(struct cell *config_cell, struct cell *dest_cell);
--
2.1.4

Antonios Motakis

unread,
Jun 27, 2016, 9:22:16 AM6/27/16
to Jan Kiszka, jailho...@googlegroups.com, claudio...@huawei.com, jani.k...@huawei.com, dmitry...@huawei.com, veacesla...@huawei.com, jean-phili...@arm.com, marc.z...@arm.com, edgar.i...@xilinx.com, wuqi...@huawei.com, mazda....@amd.com


On 23-Jun-16 10:14, Jan Kiszka wrote:
> On 2016-06-17 21:10, antonios...@huawei.com wrote:
>> From: Antonios Motakis <antonios...@huawei.com>
>>
>> The handle_irq_route function is not needed with the GICv2.
>>
>> On the ARMv8 port we will not assign a virt_id to each CPU,
>> opting to use the MPIDR as much as we can from the start.
>> GICv3 will need heavier refactoring for this purpose; by moving
>> this function we can reuse the GICv2 code on ARMv8.
>>
>> Signed-off-by: Antonios Motakis <antonios...@huawei.com>
>
> I just merged this variant to next instead, please cross-check:
>

Looks OK!

Cheers,
Tony
Antonios Motakis
Virtualization Engineer
Huawei Technologies Duesseldorf GmbH
European Research Center
Riesstrasse 25, 80992 München

Reply all
Reply to author
Forward
0 new messages