Linux 中断过程堆栈切换之trampoline stack

11 篇文章 1 订阅

查了一天堆栈切换的资料,发现大家都在讲user stack 、kernel stack、interrupt stack、IST,但是没有人讲一下trampoline stack,这对初入kernel的小伙伴不太友好的trampoline stack,这里分享一下心得:

进程在执行的时候,必然会使用到系统调用或者中断,按照SDM中的描述,中断发生时,硬件会自动切换堆栈到内核堆栈:

这个切换后的堆栈的地址是存放在TSS中ESP0(或RSP0)中的:

问题是RSP0中存放的到底是哪个stack?

原本RSP0中存放的是thread 的kernel stack,这样进入中断或者INT指令后,就直接切换到thread的kernel stack上了,方便简洁,估计Intel原本的design就是这样的,但是!但是!后来情况不一样了,可能是某种安全因素,kernel引入了trampoline stack,这个trampoline stack的地址存放在RSP0上,把kernel stack的地址存放在了RSP1上,所以硬件每次自动切换堆栈的时候,从RSP0上读取到的是trampoline stack的地址,也就是跳转到了trampoline stack上,这个时候handler并没有工作在kernel stack上,还需要软件切换到kernel stack,而且还需要把硬件自动保存在trampoline stack上的register的值copy到kernel stack上,如果使用IRET指令返回,还需要把register恢复到trampoline stack上,因为IRET是从RSP0指向的stack上读取返回需要的register的值的。所以中断发生时,stack的切换过程如下:

user stack==》中断==》trampoline stack==》interrupt handler==》软件切换RSP到kernel stack

增加trampoline stack 的commit:https://lore.kernel.org/patchwork/patch/855083/

此时kernel stack 的地址是存放在RSP1上的,但是!后边又有人改了,把kernel stack的地址放在了TOP_OF_INIT_STACK:

https://link.zhihu.com/?target=https%3A//github.com/torvalds/linux/commit/1591584e2e762edecefde403c44d9c26c9ff72c9%23diff-e2a566567505a4c08e2892be18d5fcadf0232e7927d9d04dc5f14c8059530ae2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值