opensbi 里,_trap_handler 的实现,真的考虑了 异常里面进异常吗?

2 天前
amiwrong123  amiwrong123

看了一下 opensbi 里,_trap_handler 的实现,里面的主体就是:

_trap_handler:
	TRAP_SAVE_AND_SETUP_SP_T0

	TRAP_SAVE_MEPC_MSTATUS 0

	TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0

	TRAP_SAVE_INFO 0 0

	TRAP_CALL_C_ROUTINE

	TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0

	TRAP_RESTORE_MEPC_MSTATUS 0

	TRAP_RESTORE_A0_T0

	mret

仔细看了这些汇编的实现,尤其是 TRAP_SAVE_AND_SETUP_SP_T0 的实现,

.macro	TRAP_SAVE_AND_SETUP_SP_T0
	/* Swap TP and MSCRATCH */
	csrrw	tp, CSR_MSCRATCH, tp

	/* Save T0 in scratch space */
	REG_S	t0, SBI_SCRATCH_TMP0_OFFSET(tp)

	/*
	 * Set T0 to appropriate exception stack
	 *
	 * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1;
	 * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP))
	 *
	 * Came_From_M_Mode = 0    ==>    Exception_Stack = TP
	 * Came_From_M_Mode = -1   ==>    Exception_Stack = SP
	 */
	csrr	t0, CSR_MSTATUS
	srl	t0, t0, MSTATUS_MPP_SHIFT
	and	t0, t0, PRV_M
	slti	t0, t0, PRV_M
	add	t0, t0, -1
	xor	sp, sp, tp
	and	t0, t0, sp
	xor	sp, sp, tp
	xor	t0, tp, t0

	/* Save original SP on exception stack */
	REG_S	sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_CONTEXT_SIZE)(t0)

	/* Set SP to exception stack and make room for trap context */
	add	sp, t0, -(SBI_TRAP_CONTEXT_SIZE)

	/* Restore T0 from scratch space */
	REG_L	t0, SBI_SCRATCH_TMP0_OFFSET(tp)

	/* Save T0 on stack */
	REG_S	t0, SBI_TRAP_REGS_OFFSET(t0)(sp)

	/* Swap TP and MSCRATCH */
	csrrw	tp, CSR_MSCRATCH, tp
.endm

说白了,这段就是一个逻辑: 如果异常从 M 模式过来,那么栈就使用 tp ,也就是 scratch 空间; 如果异常从 S 模式过来,那么栈就使用 sp ,也就是 s 模式的栈空间。

但我看了这个实现,如果进入异常后(此时处于 M ),再进入异常的话,这个栈空间就没有沿着 tp 继续增长,而是覆盖了 上一次的 tp 栈空间了。 PS:其实这里不只是异常,因为源码是使用的是 direct 模式,不是 vector 模式,所以任何 trap 包括中断和异常 都是有这个问题的。

所以现在有这几个问题:

  1. TRAP_SAVE_AND_SETUP_SP_T0的实现,是不是就是没有考虑到异常里面进异常时的,栈空间的不停增长?
  2. 我这么考虑 异常里面进异常,是不是 没有什么实际意义?但考虑 中断嵌套的话,应该就有意义了吧?
  3. 为什么这个TRAP_SAVE_AND_SETUP_SP_T0的实现逻辑是,如果异常从 S 过来,就直接用 S 模式的栈,这是什么惯用做法吗?
478 次点击
所在节点   程序员  程序员
3 条回复
NealLason
NealLason
1 天前
先不纠结栈,先考虑什么场景下会出现异常里面进异常呢?
我的理解,只有 OpenSBI 自身造成的异常才会导致重复进入异常吧,OpenSBI 自身运行在最高特权级别 M 模式,如果自身没有 bug ,不应出现自身造成异常的情况
amiwrong123
amiwrong123
1 天前
@NealLason #1 #1
是的,你说的么错。只是我现在参考 OpenSBI 实现一些我自己的东西,我自己的场景,是可能出现 异常里面进异常的。

所以,我想搞清楚 它的实现,是否有这个限制
NealLason
1 天前
@amiwrong123 只要是进 trap handler 的时候就重新设置 sp ,那就肯定不能支持中断嵌套哎,不然之前中断栈里的上下文就被破坏了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1118958

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX