为什么Linux内核的arm端口没有备份";cpsr";在上下文切换期间注册



切换到linux中arm32的汇编如下:与其他arch(如mips或riscv(相比,您可以看到没有cpsr-register备份,哪个相应的mstatus和状态寄存器都在_switch_to期间进行备份和恢复,那么,为什么会有差异呢?

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

cpsr有几种不同的用途,不清楚您指的是哪一种。

  1. 监控器模式cpsr
  2. 用户模式cpsr
  3. 某些异常cpsr

这些值在ARM cpu上发生异常时存储。

请参阅:Linux内核ARM异常堆栈

这使得除svc和用户模式之外的所有"spsr"都变得毫无意义。

注:ARM已存储SP、cpsr和lr。其他参考体系结构可能有也可能没有存储寄存器。当然,所有的都需要恢复ARM上的用户模式状态寄存器或用户CPSR。

switch_to汇编程序用于切换进程的内核状态。被恢复的sp是8k页,其中下部是持有用户寄存器的副本的thread_infoswitch_to()函数从R1和R2中的和thread_info获取

代码,

add     r4, r2, #24
ldm     r4, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}

更像是对switch_to()的先前呼叫的longjmp();代码不一定是从同一个地方调用的。SPSR是返回到用户模式的CPSR(和lr(。这些由矢量短截线保存在r1、r2中。它们由restore_user_regs宏恢复。指令movs pc, lr将恢复用户CPSR并从异常/syscall返回。

带有内核代码的活动cpsr(SVC(受"C"ABI保护,该ABI表示在函数调用后状态位无效。还假设任何svc代码使用相同的"T"位(所有内核代码仅为Thumb或ARM(,并且需要在已知状态下使用"F"one_answers"I"位来调用函数。switch_to调用方应该使用堆栈掩码函数,或者永远不要屏蔽中断。我想这可能是最后一个了。如果您尝试将Thumb/ARM代码与调用switch_to混合使用或使用/更改中断屏蔽,这将是一个问题;否则,无需保存/恢复此值。

相关内容

  • 没有找到相关文章

最新更新