在用户空间和内核空间之间切换线程的fs段寄存器

5

fs段寄存器如何指向TEB和KPCR。这些数据结构是否保存在线程的用户栈和内核栈上?所以当一个线程从用户态切换到内核态时,包含指向TEB指针的fs段寄存器被保存到线程的用户栈中,然后将指向KPCR的内核fs段寄存器加载回fs段寄存器,这是fs段寄存器指向TEB和KPCR的方式吗?


1
你有什么实际的编程问题吗?这听起来像是无聊的好奇心。 - Raymond Chen
2
这正是它的含义。我正在阅读一篇文章,它指出fs段寄存器指向KPCR和TEB。 - user2153720
2个回答

4
FS寄存器与LDTGDT(本地/全局段描述符表)中的段基址相关联。 FS实际上是描述符表中的索引,并选择其中一个定义在表中的段。
当您通过FS(使用指令中的FS段重写前缀)访问内存时,您将访问虚拟地址等于指令中的地址加上段基址。
该段基址必须与特定线程控制数据结构的位置相一致。因此,当创建具有其特定控制数据结构的线程时,基址被设置为指向该数据。
这些位置对于同一进程中的不同线程是不同的,因为它们共享内存,不应该踩到彼此的结构上。上下文切换要么只更新FS以指向不同的段,要么更新描述符表中段的基址,然后重新加载FS,以便CPU观察到更改。
当线程从用户模式转换到内核模式时,内核视FS及其所指向的内容为不可信。我期望内核重新加载FS,并使用指向内核端的线程特定数据结构的值来重新加载。在返回时,应恢复用户模式FS。实际上,事情可能会更加复杂,但这应该可以给您一个想法。
在64位模式下,甚至有SWAPGS指令来快速交换GS寄存器的内容,其作用类似于32位模式中的FS

谢谢Alexey,所以我推测这些值在切换不同特权级时会从线程的用户栈和内核栈中弹出和推入。由于KPCR保存了最近、当前和下一个调度的线程的详细信息,我本以为它会有自己的永久段寄存器而不会改变。 - user2153720

0

因此,fs段寄存器肯定指向kpcr。在windbg中查看并发出“dt nt!_kpcr”后,kpcr中的第一个结构是NtTib或TEB中的第一个结构,因此当人们说fs指向KPCR和TEB时,实际上fs指向KPCR,而TIB / TEB是KPCR中的第一个数据结构。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接