When the hypervisor is no longer identity mapped, shutdown_el2 will require the physical address of the to-be-restored register state. Reorder its memory accesses to allow passing in a physical cpu_data adddress.
It's caller, arch_shutdown_self, then has to flush more of cpu_data because it will be accesses after MMU disabling. It's easiest to simply flush it completely. Finally, shutdown_el2 and cpu_data address have to be converted to physical ones before being used from arch_shutdown_self. Signed-off-by: Jan Kiszka <[email protected]> --- hypervisor/arch/arm64/entry.S | 17 ++++++++--------- hypervisor/arch/arm64/setup.c | 8 +++++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/hypervisor/arch/arm64/entry.S b/hypervisor/arch/arm64/entry.S index 107e054..727d50d 100644 --- a/hypervisor/arch/arm64/entry.S +++ b/hypervisor/arch/arm64/entry.S @@ -126,19 +126,13 @@ el2_entry: .globl shutdown_el2 shutdown_el2: /* x0: struct percpu* */ - mov x19, x0 /* + * Disable the hypervisor MMU. + * * Note: no data accesses must be done after turning MMU off unless the * target region has been flushed out of D-cache. */ - - /* 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 @@ -152,8 +146,13 @@ shutdown_el2: msr tpidr_el2, xzr + /* hand over control of EL2 back to Linux */ + add x1, x0, #PERCPU_SAVED_VECTORS + ldr x2, [x1] + msr vbar_el2, x2 + /* Call vmreturn(guest_registers) */ - add x0, x19, #(PERCPU_STACK_END - 32 * 8) + add x0, x0, #(PERCPU_STACK_END - 32 * 8) b vmreturn diff --git a/hypervisor/arch/arm64/setup.c b/hypervisor/arch/arm64/setup.c index 595a25b..d796ed0 100644 --- a/hypervisor/arch/arm64/setup.c +++ b/hypervisor/arch/arm64/setup.c @@ -95,6 +95,9 @@ void __attribute__((noreturn)) arch_cpu_activate_vmm(struct per_cpu *cpu_data) /* disable the hypervisor on the current CPU */ void arch_shutdown_self(struct per_cpu *cpu_data) { + void (*shutdown_func)(struct per_cpu *) = + (void (*)(struct per_cpu *))paging_hvirt2phys(shutdown_el2); + irqchip_cpu_shutdown(cpu_data); /* Free the guest */ @@ -110,12 +113,11 @@ void arch_shutdown_self(struct per_cpu *cpu_data) /* we will restore the root cell state with the MMU turned off, * so we need to make sure it has been committed to memory */ - arch_paging_flush_cpu_caches(guest_regs(cpu_data), - sizeof(struct registers)); + arch_paging_flush_cpu_caches(cpu_data, sizeof(*cpu_data)); dsb(ish); /* Return to EL1 */ - shutdown_el2(cpu_data); + shutdown_func((struct per_cpu *)paging_hvirt2phys(cpu_data)); } void arch_cpu_restore(struct per_cpu *cpu_data, int return_code) -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
