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

Add hypervisor disable support to the Jailhouse firmware. Handle
Jailhouse disable calls from the root cell, and also disable the
hypervisor in case of an error during initialization.

Signed-off-by: Antonios Motakis <antonios.mota...@huawei.com>
[Jan: rebase, install shutdown call in handle_hvc]
Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>
---
 hypervisor/arch/arm64/entry.S | 33 +++++++++++++++++++++++++++++++++
 hypervisor/arch/arm64/setup.c | 36 ++++++++++++++++++++++++++++++++++--
 hypervisor/arch/arm64/traps.c |  3 +++
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/hypervisor/arch/arm64/entry.S b/hypervisor/arch/arm64/entry.S
index 16d52f4..4feb1c7 100644
--- a/hypervisor/arch/arm64/entry.S
+++ b/hypervisor/arch/arm64/entry.S
@@ -118,6 +118,39 @@ el2_entry:
        bl      entry
        b       .
 
+       .globl arch_shutdown_mmu
+arch_shutdown_mmu:
+       /* x0: struct percpu* */
+       mov     x19, x0
+
+       /* Note: no memory accesses must be done after turning MMU off. There
+        * is non-zero probability that cached data can be not syncronized with
+        * system memory. CPU can access data bypassing D-cache when MMU is off.
+        */
+
+       /* hand over control of EL2 back to Linux */
+       add     x1, x19, #PERCPU_SAVED_VECTORS
+       ldr     x2, [x1]
+       msr     vbar_el2, x2
+
+       /* disable the hypervisor MMU */
+       mrs     x1, sctlr_el2
+       ldr     x2, =(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT)
+       bic     x1, x1, x2
+       msr     sctlr_el2, x1
+       isb
+
+       msr     mair_el2, xzr
+       msr     ttbr0_el2, xzr
+       msr     tcr_el2, xzr
+       isb
+
+       msr     tpidr_el2, xzr
+
+       /* Call vmreturn(guest_registers) */
+       add     x0, x19, #(PERCPU_STACK_END - 32 * 8)
+       b       vmreturn
+
        .globl enable_mmu_el2
 enable_mmu_el2:
        /*
diff --git a/hypervisor/arch/arm64/setup.c b/hypervisor/arch/arm64/setup.c
index 82685f2..8d5bd38 100644
--- a/hypervisor/arch/arm64/setup.c
+++ b/hypervisor/arch/arm64/setup.c
@@ -92,8 +92,40 @@ void __attribute__((noreturn)) arch_cpu_activate_vmm(struct 
per_cpu *cpu_data)
        vmreturn(regs);
 }
 
+/* disable the hypervisor on the current CPU */
+void arch_shutdown_self(struct per_cpu *cpu_data)
+{
+       irqchip_cpu_shutdown(cpu_data);
+
+       /* Free the guest */
+       arm_write_sysreg(HCR_EL2, HCR_RW_BIT);
+       arm_write_sysreg(VTCR_EL2, VTCR_RES1);
+
+       /* Remove stage-2 mappings */
+       arm_paging_vcpu_flush_tlbs();
+
+       /* TLB flush needs the cell's VMID */
+       isb();
+       arm_write_sysreg(VTTBR_EL2, 0);
+
+       /* we will restore the root cell state with the MMU turned off,
+        * so we need to make sure it has been commited to memory */
+       arch_paging_flush_cpu_caches(guest_regs(cpu_data),
+                                    sizeof(struct registers));
+       dsb(ish);
+
+       /* Return to EL1 */
+       arch_shutdown_mmu(cpu_data);
+}
+
 void arch_cpu_restore(struct per_cpu *cpu_data, int return_code)
 {
-       trace_error(-EINVAL);
-       while (1);
+       struct registers *regs = guest_regs(cpu_data);
+
+       /* Jailhouse initialization failed; return to the caller in EL1 */
+       arm_write_sysreg(ELR_EL2, regs->usr[30]);
+
+       regs->usr[0] = return_code;
+
+       arch_shutdown_self(cpu_data);
 }
diff --git a/hypervisor/arch/arm64/traps.c b/hypervisor/arch/arm64/traps.c
index 3523b7d..26b9228 100644
--- a/hypervisor/arch/arm64/traps.c
+++ b/hypervisor/arch/arm64/traps.c
@@ -52,6 +52,9 @@ static int handle_hvc(struct trap_context *ctx)
 
        regs[0] = hypercall(code, regs[1], regs[2]);
 
+       if (code == JAILHOUSE_HC_DISABLE && regs[0] == 0)
+               arch_shutdown_self(this_cpu_data());
+
        return TRAP_HANDLED;
 }
 
-- 
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