【MIPS CPU 体系结构概述2】连载13:

异常返回时,把控制转移到用户代码和把模式从内核态改为用户态要同时完成 如果前者先完成,用户态指令有机会以内核态运行导致安全漏洞;
反之则会由于用户态下不能修改状态而导致异常
r3000以前使用rfe(restore from exception)指令,这个指令把status寄存器
状态位修改回异常发生前的状态(利用硬件的一个小堆栈),但不做跳转.我们使用一个 技巧来完成要求:在一个跳转指令的delay slot中放rte.因为delay slot的指令
是一定会做的,跳转完成时,status也恢复了.
MIPS III(r4000)以上的指令集则增加了eret指令来完成整个工作: 它清除 status寄存器的EXL位并跳转到epc指定的位置.
*/

.set pop

#else

#define RESTORE_SOME \
.set push; \
.set reorder; \
mfc0 t0, CP0_STATUS; \
.set pop; \
ori t0, 0x1f; \
xori t0, 0x1f; \
mtc0 t0, CP0_STATUS; \
li v1, 0xff00; \
and t0, v1; \
lw v0, PT_STATUS(sp); \
nor v1, $0, v1; \
and v0, v1; \
or v0, t0; \
mtc0 v0, CP0_STATUS; \

lw v1, PT_EPC(sp); \
mtc0 v1, CP0_EPC; \
lw $31, PT_R31(sp); \
lw $28, PT_R28(sp); \
lw $25, PT_R25(sp); \
lw $7, PT_R7(sp); \
lw $6, PT_R6(sp); \
lw $5, PT_R5(sp); \
lw $4, PT_R4(sp); \
lw $3, PT_R3(sp); \
lw $2, PT_R2(sp)

#define RESTORE_SP_AND_RET \
lw sp, PT_R29(sp); \
.set mips3; \
eret; \
.set mips0

#endif

#define RESTORE_SP \
lw sp, PT_R29(sp); \

#define RESTORE_ALL \
RESTORE_SOME; \
RESTORE_AT; \
RESTORE_TEMP; \
RESTORE_STATIC; \
RESTORE_SP

#define RESTORE_ALL_AND_RET \
RESTORE_SOME; \
RESTORE_AT; \
RESTORE_TEMP; \
RESTORE_STATIC; \
RESTORE_SP_AND_RET

/*
* Move to kernel mode and disable interrupts.
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
#define CLI \
mfc0 t0,CP0_STATUS; \
li t1,ST0_CU0|0x1f; \
or t0,t1; \
xori t0,0x1f; \
mtc0 t0,CP0_STATUS

/*
* Move to kernel mode and enable interrupts.
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
#define STI \
mfc0 t0,CP0_STATUS; \
li t1,ST0_CU0|0x1f; \
or t0,t1; \
xori t0,0x1e; \
mtc0 t0,CP0_STATUS

/*
* Just move to kernel mode and leave interrupts as they are.
* Set cp0 enable bit as sign that we're running on the kernel stack
*/
#define KMODE \
mfc0 t0,CP0_STATUS; \
li t1,ST0_CU0|0x1e; \
or t0,t1; \
xori t0,0x1e; \
mtc0 t0,CP0_STATUS

#endif /* __ASM_STACKFRAME_H */

--电子创新网--
粤ICP备12070055号