xen/arm: Allow secondary cpus to start in THUMB
authorJulien Grall <julien.grall@linaro.org>
Thu, 25 Jul 2013 15:21:31 +0000 (16:21 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Mon, 29 Jul 2013 15:54:48 +0000 (16:54 +0100)
Unlike bx, eret will not update the instruction set (THUMB,ARM) according to
the return address. This will result to an unpredicable behaviour for the
processor if the address doesn't match the right instruction set.

When the kernel is compiled with THUMB2, THUMB bit needs to be set in CPSR
for the secondary cpus.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/psci.c

index 18feeadbfc6b97621e0535c4652eceebc5ade61a..200769c0801b3546f7b19e15bc91dd1209632eee 100644 (file)
@@ -24,6 +24,7 @@ int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point)
     struct domain *d = current->domain;
     struct vcpu_guest_context *ctxt;
     int rc;
+    int is_thumb = entry_point & 1;
 
     if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
         return PSCI_EINVAL;
@@ -31,6 +32,10 @@ int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point)
     if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
         return PSCI_EINVAL;
 
+    /* THUMB set is not allowed with 64-bit domain */
+    if ( is_pv64_domain(d) && is_thumb )
+        return PSCI_EINVAL;
+
     if ( (ctxt = alloc_vcpu_guest_context()) == NULL )
         return PSCI_DENIED;
 
@@ -43,6 +48,9 @@ int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point)
     ctxt->ttbr1 = 0;
     ctxt->ttbcr = 0; /* Defined Reset Value */
     ctxt->user_regs.cpsr = PSR_GUEST_INIT;
+    /* Start the VCPU with THUMB set if it's requested by the kernel */
+    if ( is_thumb )
+        ctxt->user_regs.cpsr |= PSR_THUMB;
     ctxt->flags = VGCF_online;
 
     domain_lock(d);