On AArch64 we pretty much rely on PSCI being present for SMP
support (turning multiple cores on and off). This patch implements
the helpers needed for SMP and plugs in the PSCI code from AArch32.

On AArch64 PSCI calls can be issued via SMC64 as well, contrary to
AArch32 which uses SMC32 calls only. We add the changes necessary to
support the requests that are used by a Linux root cell. CPU hotplug now
is still working after we enable Jailhouse.

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                        |  3 +++
 .../arch/arm64/include/asm/jailhouse_hypercall.h       |  3 ++-
 hypervisor/arch/arm64/setup.c                          |  3 +++
 hypervisor/arch/arm64/traps.c                          | 18 ++++++++++++++++++
 5 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/hypervisor/arch/arm64/Makefile b/hypervisor/arch/arm64/Makefile
index 095212a..bf717cd 100644
--- a/hypervisor/arch/arm64/Makefile
+++ b/hypervisor/arch/arm64/Makefile
@@ -21,7 +21,7 @@ always := built-in.o
 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)/control.o
+obj-y += $(COMMON)/control.o $(COMMON)/psci.o
 obj-y += $(COMMON)/mmu_cell.o $(COMMON)/paging.o
 obj-y += $(COMMON)/irqchip.o $(COMMON)/gic-common.o
 
diff --git a/hypervisor/arch/arm64/control.c b/hypervisor/arch/arm64/control.c
index 289e382..63f1db9 100644
--- a/hypervisor/arch/arm64/control.c
+++ b/hypervisor/arch/arm64/control.c
@@ -72,6 +72,9 @@ void arm_cpu_reset(unsigned long pc)
 
        arm_write_sysreg(ELR_EL2, pc);
 
+       /* transfer the context that may have been passed to PSCI_CPU_ON */
+       regs->usr[1] = cpu_data->cpu_on_context;
+
        arm_paging_vcpu_init(&cpu_data->cell->arch.mm);
 
        irqchip_cpu_reset(cpu_data);
diff --git a/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h 
b/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h
index fb12d23..382e8b1 100644
--- a/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h
+++ b/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h
@@ -21,7 +21,8 @@
 #define JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE JAILHOUSE_GENERIC_CPU_STATS
 #define JAILHOUSE_CPU_STAT_VMEXITS_VIRQ                
JAILHOUSE_GENERIC_CPU_STATS + 1
 #define JAILHOUSE_CPU_STAT_VMEXITS_VSGI                
JAILHOUSE_GENERIC_CPU_STATS + 2
-#define JAILHOUSE_NUM_CPU_STATS                        
JAILHOUSE_GENERIC_CPU_STATS + 3
+#define JAILHOUSE_CPU_STAT_VMEXITS_PSCI                
JAILHOUSE_GENERIC_CPU_STATS + 3
+#define JAILHOUSE_NUM_CPU_STATS                        
JAILHOUSE_GENERIC_CPU_STATS + 4
 
 #ifndef __ASSEMBLY__
 
diff --git a/hypervisor/arch/arm64/setup.c b/hypervisor/arch/arm64/setup.c
index 78a245b..897dad6 100644
--- a/hypervisor/arch/arm64/setup.c
+++ b/hypervisor/arch/arm64/setup.c
@@ -14,6 +14,7 @@
 #include <jailhouse/entry.h>
 #include <jailhouse/paging.h>
 #include <jailhouse/printk.h>
+#include <jailhouse/processor.h>
 #include <asm/control.h>
 #include <asm/irqchip.h>
 #include <asm/setup.h>
@@ -53,6 +54,8 @@ int arch_cpu_init(struct per_cpu *cpu_data)
        /* switch to the permanent page tables */
        enable_mmu_el2(hv_paging_structs.root_table);
 
+       cpu_data->mpidr = phys_processor_id();
+
        arm_paging_vcpu_init(&root_cell.arch.mm);
 
        err = irqchip_init();
diff --git a/hypervisor/arch/arm64/traps.c b/hypervisor/arch/arm64/traps.c
index 0773867..3aaaba8 100644
--- a/hypervisor/arch/arm64/traps.c
+++ b/hypervisor/arch/arm64/traps.c
@@ -31,6 +31,20 @@ void arch_skip_instruction(struct trap_context *ctx)
        arm_write_sysreg(ELR_EL2, pc);
 }
 
+static int handle_smc(struct trap_context *ctx)
+{
+       unsigned long *regs = ctx->regs;
+
+       if (!IS_PSCI_32(regs[0]) && !IS_PSCI_64(regs[0]))
+               return TRAP_UNHANDLED;
+
+       regs[0] = psci_dispatch(ctx);
+
+       arch_skip_instruction(ctx);
+
+       return TRAP_HANDLED;
+}
+
 static void dump_regs(struct trap_context *ctx)
 {
        unsigned char i;
@@ -114,6 +128,10 @@ static void arch_handle_trap(struct per_cpu *cpu_data,
                ret = arch_handle_dabt(&ctx);
                break;
 
+       case ESR_EC_SMC64:
+               ret = handle_smc(&ctx);
+               break;
+
        default:
                ret = TRAP_UNHANDLED;
        }
-- 
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