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:
ligd
2021-07-19 16:00:44 +08:00
committed by Alan Carvalho de Assis
parent e968240855
commit aac0db368c
7 changed files with 25 additions and 25 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ arm_fullcontextrestore:
*/
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 */
+5 -5
View File
@@ -122,7 +122,7 @@ arm_vectorirq:
/* Restore the CPSR, SVC mode registers and return */
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 */
#if CONFIG_ARCH_INTERRUPTSTACK > 3
@@ -180,7 +180,7 @@ arm_vectorsvc:
/* Restore the CPSR, SVC mode registers and return */
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 */
.size arm_vectorsvc, . - arm_vectorsvc
@@ -254,7 +254,7 @@ arm_vectordata:
/* Restore the CPSR, SVC mode registers and return */
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 */
.size arm_vectordata, . - arm_vectordata
@@ -324,7 +324,7 @@ arm_vectorprefetch:
/* Restore the CPSR, SVC mode registers and return */
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 */
.size arm_vectorprefetch, . - arm_vectorprefetch
@@ -392,7 +392,7 @@ arm_vectorundefinsn:
/* Restore the CPSR, SVC mode registers and return */
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 */
.size arm_vectorundefinsn, . - arm_vectorundefinsn
@@ -144,7 +144,7 @@ arm_fullcontextrestore:
* 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 */
+6 -6
View File
@@ -228,7 +228,7 @@ arm_vectorirq:
/* Restore the CPSR, SVC mode registers and return */
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
/* 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 */
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
/* 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 */
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
/* 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 */
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
/* 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 */
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
/* 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 */
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
/* 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 */
msr spsr, r1 /* Set the SPSR */
msr spsr_cxsf, r1 /* Set the SPSR */
/* Now recover r0-r1, pc and cpsr, destroying the stack frame */
+6 -6
View File
@@ -182,7 +182,7 @@ arm_vectorirq:
/* Restore the CPSR, SVC mode registers and return */
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
/* 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 */
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
/* 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 */
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
/* 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 */
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
/* 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 */
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
/* 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 */
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
/* Are we leaving in user mode? If so then we need to restore the
+5 -5
View File
@@ -156,7 +156,7 @@ arm_vectorirq:
/* Restore the CPSR, SVC modr registers and return */
.Lnoirqset:
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
msr spsr, r0
msr spsr_cxsf, r0
ldmia sp, {r0-r15}^ /* Return */
.Lirqtmp:
@@ -215,7 +215,7 @@ arm_vectorsvc:
/* Restore the CPSR, SVC modr registers and return */
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
msr spsr, r0
msr spsr_cxsf, r0
ldmia sp, {r0-r15}^ /* Return */
.align 5
@@ -280,7 +280,7 @@ arm_vectordata:
/* Restore the CPSR, SVC modr registers and return */
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
msr spsr, r0
msr spsr_cxsf, r0
ldmia sp, {r0-r15}^ /* Return */
.Ldaborttmp:
@@ -346,7 +346,7 @@ arm_vectorprefetch:
/* Restore the CPSR, SVC modr registers and return */
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
msr spsr, r0
msr spsr_cxsf, r0
ldmia sp, {r0-r15}^ /* Return */
.Lpaborttmp:
@@ -412,7 +412,7 @@ arm_vectorundefinsn:
/* Restore the CPSR, SVC modr registers and return */
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
msr spsr, r0
msr spsr_cxsf, r0
ldmia sp, {r0-r15}^ /* Return */
.Lundeftmp: