The switch to assembly of arm32 in linux is like that: you coud see there are no cpsr reigister backup, compare to others arch, like mips or riscv, which corresponding mstatus and status register are all do the backup and restore during the _switch_to, so, why there are the differences?
12948 8010d328 <__switch_to>:
12949 8010d328: e281c018 add ip, r1, #24
12950 8010d32c: e8ac6ff0 stmia ip!, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
12951 8010d330: e592405c ldr r4, [r2, #92] ; 0x5c
12952 8010d334: e5925060 ldr r5, [r2, #96] ; 0x60
12953 8010d338: ee1d7f50 mrc 15, 0, r7, cr13, cr0, {2}
12954 8010d33c: ee0d4f70 mcr 15, 0, r4, cr13, cr0, {3}
12955 8010d340: ee0d5f50 mcr 15, 0, r5, cr13, cr0, {2}
12956 8010d344: e5817060 str r7, [r1, #96] ; 0x60
12957 8010d348: e1a05000 mov r5, r0
12958 8010d34c: e2824018 add r4, r2, #24
12959 8010d350: e59f000c ldr r0, [pc, #12] ; 8010d364 <__switch_to+0x3c>
12960 8010d354: e3a01002 mov r1, #2
12961 8010d358: eb00c813 bl 8013f3ac <atomic_notifier_call_chain>
12962 8010d35c: e1a00005 mov r0, r5
12963 8010d360: e894aff0 ldm r4, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
12964 8010d364: 80b61200 .word 0x80b61200
12965 8010d368: e58d403c str r4, [sp, #60] ; 0x3c
12966 8010d36c: e1a0f009 mov pc, r9
There are a few different uses of
cpsrand it is not clear which one you are referring to.These values are stored during an exception on an ARM cpu.
See: Linux kernel ARM exception stack
This makes all 'spsr' except the svc and user mode meaningless.
Note: The ARM has banked SP, cpsr and lr. Other referenced architectures may or may not have banked registers. For certain, all need to restore the user mode status register or user CPSR on ARM.
The
switch_toassembler is used to switch kernel state for a process. Thespthat is restored is an 8k page where the lower portion is athread_infoholding a copy of the user registers. Theswitch_to()function takes a from and to thread_info held in R1 and R2.The code,
Is more like a
longjmp()to a previous call toswitch_to(); the code is not heading to the same place it was called from necessarily. The SPSR which is the return to user mode CPSR (and lr). These are saved in r1,r2 by the vector stubs. They are restored by the restore_user_regs macro. The instructionmovs pc, lrwill restore the user CPSR and return from an exception/syscall.The cpsr (SVC) active with kernel code is protected by the 'C' ABI which says the status bits are not valid after a function call. It is also assumed the any svc code uses the same 'T' bit (all kernel code is either Thumb or ARM only) and the function needs to be called with 'F' and 'I' bits in a known state.
switch_tocallers should use the stacking mask functions OR never have interrupts masked. I think it is probably the last one. If you try to mix Thumb/ARM code or use/change interrupt masking with calls toswitch_to, it would be an issue; otherwise, there is no need to save/restore this value.