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

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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: