]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
arm: Rework return to EL1 path
authorJan Kiszka <jan.kiszka@siemens.com>
Tue, 25 Nov 2014 08:06:42 +0000 (09:06 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 8 Jan 2015 12:01:23 +0000 (13:01 +0100)
Refactor cpu_return_el1 to cpu_prepare_return_el1, moving the differing
parts depending on the return mode to the caller site. Ensure that we
return to Linux passing the proper error code - it's now available to
arch_cpu_restore.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/arm/include/asm/setup.h
hypervisor/arch/arm/setup.c

index 013def7d6c58d6c3fa23215306790c6ef20ce31e..041a0e4a26e1ca22cb66e24394f080f0fdec545a 100644 (file)
 #include <jailhouse/string.h>
 
 static inline void __attribute__((always_inline))
-cpu_return_el1(struct per_cpu *cpu_data, bool panic)
+cpu_prepare_return_el1(struct per_cpu *cpu_data, int return_code)
 {
-       /*
-        * Return value
-        * FIXME: there is no way, currently, to communicate the precise error
-        * number from the core. A `EDISASTER' would be appropriate here.
-        */
-       cpu_data->linux_reg[0] = (panic ? -EIO : 0);
+       cpu_data->linux_reg[0] = return_code;
 
        asm volatile (
        "msr    sp_svc, %0\n"
@@ -38,28 +33,6 @@ cpu_return_el1(struct per_cpu *cpu_data, bool panic)
        : "r" (cpu_data->linux_sp + (NUM_ENTRY_REGS * sizeof(unsigned long))),
          "r" (cpu_data->linux_ret),
          "r" (cpu_data->linux_flags));
-
-       if (panic) {
-               /* A panicking return needs to shutdown EL2 before the ERET. */
-               struct registers *ctx = guest_regs(cpu_data);
-               memcpy(&ctx->usr, &cpu_data->linux_reg,
-                      NUM_ENTRY_REGS * sizeof(unsigned long));
-               return;
-       }
-
-       asm volatile(
-       /* Reset the hypervisor stack */
-       "mov    sp, %0\n"
-       /*
-        * We don't care about clobbering the other registers from now on. Must
-        * be in sync with arch_entry.
-        */
-       "ldm    %1, {r0 - r12}\n"
-       /* After this, the kernel won't be able to access the hypervisor code */
-       "eret\n"
-       :
-       : "r" (cpu_data->stack + PERCPU_STACK_END),
-         "r" (cpu_data->linux_reg));
 }
 
 int switch_exception_level(struct per_cpu *cpu_data);
index 6352965c6ec0b80d50d21a7d4410700a66069f3c..f47f2ab79d598dbad6ad7afa51f855e541a571d4 100644 (file)
@@ -111,9 +111,23 @@ int arch_init_late(void)
 void arch_cpu_activate_vmm(struct per_cpu *cpu_data)
 {
        /* Return to the kernel */
-       cpu_return_el1(cpu_data, false);
+       cpu_prepare_return_el1(cpu_data, 0);
 
-       while (1);
+       asm volatile(
+       /* Reset the hypervisor stack */
+       "mov    sp, %0\n"
+       /*
+        * We don't care about clobbering the other registers from now on. Must
+        * be in sync with arch_entry.
+        */
+       "ldm    %1, {r0 - r12}\n"
+       /* After this, the kernel won't be able to access the hypervisor code */
+       "eret\n"
+       :
+       : "r" (cpu_data->stack + PERCPU_STACK_END),
+         "r" (cpu_data->linux_reg));
+
+       __builtin_unreachable();
 }
 
 void arch_shutdown_self(struct per_cpu *cpu_data)
@@ -138,6 +152,8 @@ void arch_shutdown_self(struct per_cpu *cpu_data)
 
 void arch_cpu_restore(struct per_cpu *cpu_data, int return_code)
 {
+       struct registers *ctx = guest_regs(cpu_data);
+
        /*
         * If we haven't reached switch_exception_level yet, there is nothing to
         * clean up.
@@ -148,10 +164,13 @@ void arch_cpu_restore(struct per_cpu *cpu_data, int return_code)
        /*
         * Otherwise, attempt do disable the MMU and return to EL1 using the
         * arch_shutdown path. cpu_return will fill the banked registers and the
-        * guest regs structure (stored at the begginning of the stack) to
+        * guest regs structure (stored at the beginning of the stack) to
         * prepare the ERET.
         */
-       cpu_return_el1(cpu_data, true);
+       cpu_prepare_return_el1(cpu_data, return_code);
+
+       memcpy(&ctx->usr, &cpu_data->linux_reg,
+              NUM_ENTRY_REGS * sizeof(unsigned long));
 
        arch_shutdown_self(cpu_data);
 }