ARM: fix CPSR corruption after exception handling
It seems to be caused by the corrupted or wrong CPSR restored on return
from exception. NuttX restores the context using code like this:
msr spsr, r1
GCC translates this to:
msr spsr_fc, r1
As a result, not all SPSR fields are updated on exception return. This
should be:
msr spsr_fsxc, r1
This bug has been fixed by Heesub Shin in:
343243c7c0
Change-Id: Ibc64db7bceecd0fb6ef39284fb5bc467f5603e2e
This commit is contained in:
parent
e968240855
commit
aac0db368c
@ -87,7 +87,7 @@ arm_fullcontextrestore:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
||||||
msr spsr, r1 /* Set the SPSR */
|
msr spsr_cxsf, r1 /* Set the SPSR */
|
||||||
|
|
||||||
/* Now recover r0-r1, pc and cpsr, destroying the stack frame */
|
/* Now recover r0-r1, pc and cpsr, destroying the stack frame */
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ arm_vectorirq:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r0 /* Set the return mode SPSR */
|
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||||
@ -180,7 +180,7 @@ arm_vectorsvc:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r0 /* Set the return mode SPSR */
|
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
.size arm_vectorsvc, . - arm_vectorsvc
|
.size arm_vectorsvc, . - arm_vectorsvc
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ arm_vectordata:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r0 /* Set the return mode SPSR */
|
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
.size arm_vectordata, . - arm_vectordata
|
.size arm_vectordata, . - arm_vectordata
|
||||||
|
|
||||||
@ -324,7 +324,7 @@ arm_vectorprefetch:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r0 /* Set the return mode SPSR */
|
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ arm_vectorundefinsn:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r0 /* Set the return mode SPSR */
|
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ arm_fullcontextrestore:
|
|||||||
* disabled.
|
* disabled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
msr spsr, r2 /* Set the SPSR */
|
msr spsr_cxsf, r2 /* Set the SPSR */
|
||||||
|
|
||||||
/* Now recover r0-r2, pc and cpsr, destroying the stack frame */
|
/* Now recover r0-r2, pc and cpsr, destroying the stack frame */
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ arm_vectorirq:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_KERNEL
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -356,7 +356,7 @@ arm_vectorsvc:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_KERNEL
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -498,7 +498,7 @@ arm_vectordata:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_KERNEL
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -640,7 +640,7 @@ arm_vectorprefetch:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_KERNEL
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -778,7 +778,7 @@ arm_vectorundefinsn:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_KERNEL
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -925,7 +925,7 @@ arm_vectorfiq:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_KERNEL
|
#ifdef CONFIG_BUILD_KERNEL
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
|
@ -138,7 +138,7 @@ arm_fullcontextrestore:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
||||||
msr spsr, r1 /* Set the SPSR */
|
msr spsr_cxsf, r1 /* Set the SPSR */
|
||||||
|
|
||||||
/* Now recover r0-r1, pc and cpsr, destroying the stack frame */
|
/* Now recover r0-r1, pc and cpsr, destroying the stack frame */
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ arm_vectorirq:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -310,7 +310,7 @@ arm_vectorsvc:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -452,7 +452,7 @@ arm_vectordata:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -594,7 +594,7 @@ arm_vectorprefetch:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -732,7 +732,7 @@ arm_vectorundefinsn:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
@ -879,7 +879,7 @@ arm_vectorfiq:
|
|||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||||
msr spsr, r1 /* Set the return mode SPSR */
|
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||||
|
|
||||||
#ifdef CONFIG_BUILD_PROTECTED
|
#ifdef CONFIG_BUILD_PROTECTED
|
||||||
/* Are we leaving in user mode? If so then we need to restore the
|
/* Are we leaving in user mode? If so then we need to restore the
|
||||||
|
@ -156,7 +156,7 @@ arm_vectorirq:
|
|||||||
/* Restore the CPSR, SVC modr registers and return */
|
/* Restore the CPSR, SVC modr registers and return */
|
||||||
.Lnoirqset:
|
.Lnoirqset:
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
msr spsr, r0
|
msr spsr_cxsf, r0
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
.Lirqtmp:
|
.Lirqtmp:
|
||||||
@ -215,7 +215,7 @@ arm_vectorsvc:
|
|||||||
/* Restore the CPSR, SVC modr registers and return */
|
/* Restore the CPSR, SVC modr registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
msr spsr, r0
|
msr spsr_cxsf, r0
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
@ -280,7 +280,7 @@ arm_vectordata:
|
|||||||
/* Restore the CPSR, SVC modr registers and return */
|
/* Restore the CPSR, SVC modr registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
msr spsr, r0
|
msr spsr_cxsf, r0
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
.Ldaborttmp:
|
.Ldaborttmp:
|
||||||
@ -346,7 +346,7 @@ arm_vectorprefetch:
|
|||||||
/* Restore the CPSR, SVC modr registers and return */
|
/* Restore the CPSR, SVC modr registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
msr spsr, r0
|
msr spsr_cxsf, r0
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
.Lpaborttmp:
|
.Lpaborttmp:
|
||||||
@ -412,7 +412,7 @@ arm_vectorundefinsn:
|
|||||||
/* Restore the CPSR, SVC modr registers and return */
|
/* Restore the CPSR, SVC modr registers and return */
|
||||||
|
|
||||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
msr spsr, r0
|
msr spsr_cxsf, r0
|
||||||
ldmia sp, {r0-r15}^ /* Return */
|
ldmia sp, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
.Lundeftmp:
|
.Lundeftmp:
|
||||||
|
Loading…
Reference in New Issue
Block a user