From: Antonios Motakis <[email protected]>

We plug the irqchip handling code, and the GICv2 implementation from
AArch32.

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.

Signed-off-by: Antonios Motakis <[email protected]>
---
 hypervisor/arch/arm64/Makefile             |  2 ++
 hypervisor/arch/arm64/control.c            | 57 ++++++++++++++++++++++++++++++
 hypervisor/arch/arm64/include/asm/cell.h   |  2 ++
 hypervisor/arch/arm64/include/asm/percpu.h | 27 ++++++++++++++
 hypervisor/arch/arm64/mmio.c               |  4 +--
 hypervisor/arch/arm64/setup.c              | 24 +++++++++++--
 hypervisor/arch/arm64/traps.c              |  5 +++
 7 files changed, 117 insertions(+), 4 deletions(-)

diff --git a/hypervisor/arch/arm64/Makefile b/hypervisor/arch/arm64/Makefile
index 603056e..540f7e3 100644
--- a/hypervisor/arch/arm64/Makefile
+++ b/hypervisor/arch/arm64/Makefile
@@ -19,5 +19,7 @@ always := built-in.o
 obj-y := entry.o setup.o control.o mmio.o caches.o
 obj-y += ../arm/mmu_cell.o ../arm/paging.o ../arm/dbg-write.o ../arm/lib.o
 obj-y += exception.o traps.o
+obj-y += ../arm/irqchip.o ../arm/gic-common.o
 
 obj-$(CONFIG_SERIAL_AMBA_PL011) += ../arm/dbg-write-pl011.o
+obj-$(CONFIG_ARM_GIC) += ../arm/gic-v2.o
diff --git a/hypervisor/arch/arm64/control.c b/hypervisor/arch/arm64/control.c
index a1c4774..f141e45 100644
--- a/hypervisor/arch/arm64/control.c
+++ b/hypervisor/arch/arm64/control.c
@@ -12,6 +12,10 @@
 
 #include <jailhouse/control.h>
 #include <jailhouse/printk.h>
+#include <asm/control.h>
+#include <asm/irqchip.h>
+#include <asm/platform.h>
+#include <asm/traps.h>
 
 int arch_cell_create(struct cell *cell)
 {
@@ -81,3 +85,56 @@ void arch_panic_park(void)
        trace_error(-EINVAL);
        while (1);
 }
+
+void arch_handle_sgi(struct per_cpu *cpu_data, u32 irqn)
+{
+       cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MANAGEMENT]++;
+
+       switch (irqn) {
+       case SGI_INJECT:
+               irqchip_inject_pending(cpu_data);
+               break;
+       default:
+               printk("WARN: unknown SGI received %d\n", irqn);
+       }
+}
+
+/*
+ * Handle the maintenance interrupt, the rest is injected into the cell.
+ * Return true when the IRQ has been handled by the hyp.
+ */
+bool arch_handle_phys_irq(struct per_cpu *cpu_data, u32 irqn)
+{
+       if (irqn == MAINTENANCE_IRQ) {
+               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE]++;
+
+               irqchip_inject_pending(cpu_data);
+               return true;
+       }
+
+       cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_VIRQ]++;
+
+       irqchip_set_pending(cpu_data, irqn);
+
+       return false;
+}
+
+/*
+ * 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 4ba8224..9a9689e 100644
--- a/hypervisor/arch/arm64/include/asm/cell.h
+++ b/hypervisor/arch/arm64/include/asm/cell.h
@@ -26,6 +26,8 @@ struct arch_cell {
        struct paging_structures mm;
        spinlock_t caches_lock;
        bool needs_flush;
+
+       u64 spis;
 };
 
 extern struct cell root_cell;
diff --git a/hypervisor/arch/arm64/include/asm/percpu.h 
b/hypervisor/arch/arm64/include/asm/percpu.h
index 9d1b6ec..e9fa99b 100644
--- a/hypervisor/arch/arm64/include/asm/percpu.h
+++ b/hypervisor/arch/arm64/include/asm/percpu.h
@@ -23,9 +23,13 @@
 
 #ifndef __ASSEMBLY__
 
+#include <jailhouse/printk.h>
 #include <asm/cell.h>
+#include <asm/irqchip.h>
 #include <asm/spinlock.h>
 
+struct pending_irq;
+
 struct per_cpu {
        u8 stack[PAGE_SIZE];
        unsigned long saved_vectors;
@@ -37,6 +41,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)));
@@ -72,6 +85,20 @@ static inline struct registers *guest_regs(struct per_cpu 
*cpu_data)
                        - 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);
+
 /* Validate defines */
 #define CHECK_ASSUMPTION(assume)       ((void)sizeof(char[1 - 2*!(assume)]))
 
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 13e6387..838c541 100644
--- a/hypervisor/arch/arm64/setup.c
+++ b/hypervisor/arch/arm64/setup.c
@@ -13,23 +13,43 @@
 #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)
 {
-       return arch_mmu_cell_init(&root_cell);
+       int err = 0;
+
+       err = arch_mmu_cell_init(&root_cell);
+       if (err)
+               return err;
+
+       return irqchip_init();
 }
 
 int arch_cpu_init(struct per_cpu *cpu_data)
 {
+       int err = 0;
+
        /* switch to the permanent page tables */
        enable_mmu_el2(hv_paging_structs.root_table);
 
-       return arch_mmu_cpu_cell_init(cpu_data);
+       err = arch_mmu_cpu_cell_init(cpu_data);
+       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 cc6fe6c..fec057d 100644
--- a/hypervisor/arch/arm64/traps.c
+++ b/hypervisor/arch/arm64/traps.c
@@ -21,6 +21,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.8.0.rc3


-- 
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.

Reply via email to