diff mbox

[v2,2/3] xen/arm: Allow secondary cpus to start in THUMB

Message ID 1374765692-31370-3-git-send-email-julien.grall@linaro.org
State Accepted, archived
Headers show

Commit Message

Julien Grall July 25, 2013, 3:21 p.m. UTC
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>

---
    Changes in v2:
        - Return PSCI_EINVAL if an aarch64 guest tries to use THUMB set
---
 xen/arch/arm/psci.c |    8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Ian Campbell July 29, 2013, 3:57 p.m. UTC | #1
On Thu, 2013-07-25 at 16:21 +0100, Julien Grall wrote:
> 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 + applied, thanks.
>
diff mbox

Patch

diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
index 18feead..200769c 100644
--- a/xen/arch/arm/psci.c
+++ b/xen/arch/arm/psci.c
@@ -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);