X86 基于软件的TSS上下文切换是如何工作的?

X86 基于软件的TSS上下文切换是如何工作的?,x86,operating-system,X86,Operating System,我想知道一个关于TSS(任务状态段)的简单解释,以及如何使用它进行基于软件的上下文切换 首先,TSS是一个历史遗留问题。曾几何时(又称20世纪80年代初),英特尔的人们认为硬件上下文切换而不是软件上下文切换是个好主意。他们大错特错了。硬件上下文切换有几个明显的缺点,而且,由于它从未被适当地实现,所以性能很差。由于所有这些原因,甚至没有一个理智的操作系统实现它,加上它的可移植性甚至不如分段。有关详细信息,请参阅 现在,关于任务状态段。如果有任何操作系统实现了硬件上下文切换,那么它的目的就是表示一个

我想知道一个关于TSS(任务状态段)的简单解释,以及如何使用它进行基于软件的上下文切换

首先,TSS是一个历史遗留问题。曾几何时(又称20世纪80年代初),英特尔的人们认为硬件上下文切换而不是软件上下文切换是个好主意。他们大错特错了。硬件上下文切换有几个明显的缺点,而且,由于它从未被适当地实现,所以性能很差。由于所有这些原因,甚至没有一个理智的操作系统实现它,加上它的可移植性甚至不如分段。有关详细信息,请参阅

现在,关于任务状态段。如果有任何操作系统实现了硬件上下文切换,那么它的目的就是表示一个“任务”。可以将线程和进程都表示为“任务”,但通常情况下,在使用硬件上下文切换的少数代码中,它表示一个简单的进程。TSS将保存诸如任务的通用寄存器内容、控制寄存器(CR0、CR2、CR3和CR4;没有CR1)、CPU标志和指令指针等内容

然而,在软件执行所有上下文切换的现实世界中,我们只剩下一个104字节长的结构,这(几乎)是无用的。然而,正如我们所说的英特尔,它从未被弃用/删除,操作系统必须处理它

问题其实很简单。假设您正在典型的用户模式进程中运行典型的
foo()
函数。突然,您,即用户,按Windows/Meta/Super/不管您如何称呼它,都可以启动邮件客户端。结果,中断请求(IRQ)从键盘发送到中断控制器(8259A PIC或IOAPIC)。然后,中断控制器安排事情以触发CPU中断。CPU进入特权级别0,寄存器和中断号一起被推送,内核模式代码被调用以处理这种情况。等待推东西?哪里当然是在堆栈上!但是,为了定义“堆栈”,堆栈指针从何处获取

如果您碰巧使用了用户模式堆栈指针,则会发生不好的事情,并且会出现巨大的安全漏洞。如果堆栈指针指向无效地址,会发生什么情况?这是可能发生的。毕竟,严格地说,堆栈指针只是另一个通用寄存器,而众所周知,汇编程序员出于核心的考虑,会以这种方式使用它

尝试在那里推送东西会产生CPU异常,很好!而且,由于双重故障(在试图处理中断时发生的异常)将再次试图推过无效指针,操作系统最糟糕的噩梦变成了现实:三重故障。你有没有见过你的电脑在没有事先通知的情况下突然重启?这是一个三重故障(或电源故障)。操作系统没有改变来处理三重故障,它只是重新启动所有东西

太好了,系统已经重启了。但是,更糟糕的事情可能发生了。如果攻击者故意写入一个关键内核变量(!)的地址,并将其希望写入的值按正确的顺序放入其中,那么随着获得超级用户权限变得比以往任何时候都容易,让最大的权限提升漏洞发挥作用吧!GDB、内核的配置(位于
/proc/config.gz
中)以及编译内核时使用的GCC版本都足以做到这一点

现在,回到TSS,前面提到的结构恰好包含堆栈指针和堆栈段寄存器的值,这些值在特权级别3(用户模式)的中断时加载。内核将其设置为指向内核区域中的安全堆栈。因此,有一个“内核堆栈”每个线程在系统中,每个逻辑CPU在系统中都有一个TSS。在线程切换时,内核只是在正确的TSS中更改这两个变量。不,每个逻辑CPU不能有一个内核堆栈,因为内核本身可能被抢占(大部分时间)


我希望这能让你有所了解!

为什么我问的问题不清楚?我的意思是答案非常准确。这就是我所要求的。