We plug the irqchip handling code, and the GICv2 implementation from
AArch32. arch_handle_sgi and arch_handle_phys_irq are only provided as
stubs because they will be replaced with the arm-common versions soon.

GICv3 is slightly trickier; it makes heavier use of the sysregs, so
we will need to review more carefully that the sysregs macros do
the right thing.

Based on patch by Antonios Motakis.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---
 hypervisor/arch/arm64/Makefile             |  2 ++
 hypervisor/arch/arm64/control.c            | 37 ++++++++++++++++++++++++++++++
 hypervisor/arch/arm64/include/asm/cell.h   |  2 ++
 hypervisor/arch/arm64/include/asm/percpu.h | 25 ++++++++++++++++++++
 hypervisor/arch/arm64/mmio.c               |  4 ++--
 hypervisor/arch/arm64/setup.c              | 16 ++++++++++++-
 hypervisor/arch/arm64/traps.c              |  5 ++++
 7 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/hypervisor/arch/arm64/Makefile b/hypervisor/arch/arm64/Makefile
index c1cbae4..e6c8e30 100644
--- a/hypervisor/arch/arm64/Makefile
+++ b/hypervisor/arch/arm64/Makefile
@@ -22,5 +22,7 @@ obj-y := entry.o setup.o control.o mmio.o caches.o
 obj-y += exception.o traps.o
 obj-y += $(COMMON)/dbg-write.o $(COMMON)/lib.o
 obj-y += $(COMMON)/mmu_cell.o $(COMMON)/paging.o
+obj-y += $(COMMON)/irqchip.o $(COMMON)/gic-common.o
 
 obj-$(CONFIG_SERIAL_AMBA_PL011) += $(COMMON)/dbg-write-pl011.o
+obj-$(CONFIG_ARM_GIC_V2) += $(COMMON)/gic-v2.o
diff --git a/hypervisor/arch/arm64/control.c b/hypervisor/arch/arm64/control.c
index ca4124e..fc0a8f3 100644
--- a/hypervisor/arch/arm64/control.c
+++ b/hypervisor/arch/arm64/control.c
@@ -12,6 +12,9 @@
 
 #include <jailhouse/control.h>
 #include <jailhouse/printk.h>
+#include <asm/control.h>
+#include <asm/irqchip.h>
+#include <asm/traps.h>
 
 int arch_cell_create(struct cell *cell)
 {
@@ -79,3 +82,37 @@ void arch_panic_park(void)
        trace_error(-EINVAL);
        while (1);
 }
+
+void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn,
+                    unsigned int count_event)
+{
+       trace_error(-EINVAL);
+       while (1);
+}
+
+bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn,
+                         unsigned int count_event)
+{
+       trace_error(-EINVAL);
+       while (1);
+}
+
+/*
+ * We get rid of the virt_id in the AArch64 implementation, since it
+ * doesn't really fit with the MPIDR CPU identification scheme on ARM.
+ *
+ * Until the GICv3 and ARMv7 code has been properly refactored to
+ * support this scheme, we stub this call so we can share the GICv2
+ * code with ARMv7.
+ *
+ * TODO: implement MPIDR support in the GICv3 code, so it can be
+ * used on AArch64.
+ * TODO: refactor out virt_id from the AArch7 port as well.
+ */
+unsigned int arm_cpu_phys2virt(unsigned int cpu_id)
+{
+       panic_printk("FATAL: we shouldn't reach here\n");
+       panic_stop();
+
+       return -EINVAL;
+}
diff --git a/hypervisor/arch/arm64/include/asm/cell.h 
b/hypervisor/arch/arm64/include/asm/cell.h
index cf9e2f4..091a983 100644
--- a/hypervisor/arch/arm64/include/asm/cell.h
+++ b/hypervisor/arch/arm64/include/asm/cell.h
@@ -19,6 +19,8 @@
 
 struct arch_cell {
        struct paging_structures mm;
+
+       u32 irq_bitmap[1024/32];
 };
 
 #endif /* !__ASSEMBLY__ */
diff --git a/hypervisor/arch/arm64/include/asm/percpu.h 
b/hypervisor/arch/arm64/include/asm/percpu.h
index a22b486..4b645d6 100644
--- a/hypervisor/arch/arm64/include/asm/percpu.h
+++ b/hypervisor/arch/arm64/include/asm/percpu.h
@@ -18,6 +18,8 @@
 #ifndef __ASSEMBLY__
 
 #include <jailhouse/cell.h>
+#include <asm/irqchip.h>
+#include <asm/spinlock.h>
 
 /* Round up sizeof(struct per_cpu) to the next power of two. */
 #define PERCPU_SIZE_SHIFT \
@@ -34,6 +36,15 @@ struct per_cpu {
        int shutdown_state;
        bool failed;
 
+       /* synchronizes parallel insertions of SGIs into the pending ring */
+       spinlock_t pending_irqs_lock;
+       u16 pending_irqs[MAX_PENDING_IRQS];
+       unsigned int pending_irqs_head;
+       /* removal from the ring happens lockless, thus tail is volatile */
+       volatile unsigned int pending_irqs_tail;
+       /* Only GICv3: redistributor base */
+       void *gicr_base;
+
        bool flush_vcpu_caches;
        unsigned long mpidr;
 } __attribute__((aligned(PAGE_SIZE)));
@@ -68,6 +79,20 @@ static inline struct registers *guest_regs(struct per_cpu 
*cpu_data)
        return (struct registers *)(cpu_data->stack + sizeof(cpu_data->stack)
                        - sizeof(struct registers));
 }
+
+/*
+ * We get rid of the virt_id in the AArch64 implementation, since it
+ * doesn't really fit with the MPIDR CPU identification scheme on ARM.
+ *
+ * Until the GICv3 and ARMv7 code has been properly refactored to
+ * support this scheme, we stub this call so we can share the GICv2
+ * code with ARMv7.
+ *
+ * TODO: implement MPIDR support in the GICv3 code, so it can be
+ * used on AArch64.
+ * TODO: refactor out virt_id from the AArch7 port as well.
+ */
+unsigned int arm_cpu_phys2virt(unsigned int cpu_id);
 #endif /* !__ASSEMBLY__ */
 
 #endif /* !_JAILHOUSE_ASM_PERCPU_H */
diff --git a/hypervisor/arch/arm64/mmio.c b/hypervisor/arch/arm64/mmio.c
index 0c43365..8888251 100644
--- a/hypervisor/arch/arm64/mmio.c
+++ b/hypervisor/arch/arm64/mmio.c
@@ -18,6 +18,7 @@
 #include <jailhouse/mmio.h>
 #include <jailhouse/printk.h>
 #include <asm/bitops.h>
+#include <asm/irqchip.h>
 #include <asm/percpu.h>
 #include <asm/sysregs.h>
 #include <asm/traps.h>
@@ -26,8 +27,7 @@
 
 unsigned int arch_mmio_count_regions(struct cell *cell)
 {
-       /* not entirely a lie :) */
-       return 0;
+       return irqchip_mmio_count_regions(cell);
 }
 
 static void arch_inject_dabt(struct trap_context *ctx, unsigned long addr)
diff --git a/hypervisor/arch/arm64/setup.c b/hypervisor/arch/arm64/setup.c
index 616c324..8f1fc69 100644
--- a/hypervisor/arch/arm64/setup.c
+++ b/hypervisor/arch/arm64/setup.c
@@ -14,6 +14,7 @@
 #include <jailhouse/entry.h>
 #include <jailhouse/printk.h>
 #include <asm/control.h>
+#include <asm/irqchip.h>
 #include <asm/setup.h>
 
 int arch_init_early(void)
@@ -23,16 +24,29 @@ int arch_init_early(void)
 
 int arch_cpu_init(struct per_cpu *cpu_data)
 {
+       int err;
+
        /* switch to the permanent page tables */
        enable_mmu_el2(hv_paging_structs.root_table);
 
        arm_paging_vcpu_init(&root_cell.arch.mm);
 
-       return 0;
+       err = irqchip_init();
+       if (err)
+               return err;
+
+       return irqchip_cpu_init(cpu_data);
 }
 
 int arch_init_late(void)
 {
+       int err;
+
+       /* Setup the SPI bitmap */
+       err = irqchip_cell_init(&root_cell);
+       if (err)
+               return err;
+
        return map_root_memory_regions();
 }
 
diff --git a/hypervisor/arch/arm64/traps.c b/hypervisor/arch/arm64/traps.c
index 9830209..0773867 100644
--- a/hypervisor/arch/arm64/traps.c
+++ b/hypervisor/arch/arm64/traps.c
@@ -20,6 +20,7 @@
 #include <asm/sysregs.h>
 #include <asm/traps.h>
 #include <asm/processor.h>
+#include <asm/irqchip.h>
 
 void arch_skip_instruction(struct trap_context *ctx)
 {
@@ -143,6 +144,10 @@ struct registers *arch_handle_exit(struct per_cpu 
*cpu_data,
        cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_TOTAL]++;
 
        switch (regs->exit_reason) {
+       case EXIT_REASON_EL1_IRQ:
+               irqchip_handle_irq(cpu_data);
+               break;
+
        case EXIT_REASON_EL1_ABORT:
                arch_handle_trap(cpu_data, regs);
                break;
-- 
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 jailhouse-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to