犯了一个错误,总结一下对核心栈的认识。
有tss_struct 和thread_struct 两个结构涉及核心栈指针。
struct tss_struct {
/*
* The hardware state:
*/
struct x86_hw_tss x86_tss;
} ____cacheline_aligned;
struct x86_hw_tss {
unsigned short back_link, __blh;
unsigned long sp0;
unsigned short ss0, __ss0h;
unsigned long sp1;
/* ss1 caches MSR_IA32_SYSENTER_CS: */
unsigned short ss1, __ss1h;
…..
}
thread_struct 位于task_struct中
struct thread_struct {
/* Cached TLS descriptors: */
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
unsigned long sp0;
unsigned long sp;
…..
}
1 在创建进程时copy_thread中初始化
p->thread.sp = (unsigned long) childregs;
p->thread.sp0 = (unsigned long) (childregs+1);
2 在进程切换时,switch_to(prev, next, last) 会切换 thread_struct中的sp0,同时要修改tss中的esp0(因为每个cpu才一个TSS,只要调整esp0即可),见__switch_to函数
__notrace_funcgraph struct task_struct *
__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
/*
* Reload esp0.
*/
load_sp0(tss, next);
}
实际就是用thread_struct 的sp0初始化TSS中的sp0
static inline void
native_load_sp0(struct tss_struct *tss, struct thread_struct *thread)
{
tss->x86_tss.sp0 = thread->sp0;
}
3 TSS真正被使用的域就是SS0和sp0,用于从用户态切换到核心态。在用户态kernel stack 总是为空,所以从核心态返回用户态不需要保存核心栈指针(肯定是栈顶,tss_struct中已经准备好了)
阅读(1521) | 评论(0) | 转发(0) |