在执行INT指令时,实际完成了以下几条操作:
1.由于INT指令发生了不同优先级之间的控制转移,所以首先从TSS(任务状态段)中获取高优先级的核心堆栈信息(SS和ESP);2.把低优先级堆栈信息(SS和ESP)保留到高优先级堆栈(即核心栈)中;
3.把EFLAGS,外层CS,EIP推入高优先级堆栈(核心栈)中。
4.通过IDT加载CS,EIP(控制转移至中断处理函数)
5.然后就进入了中断0x80的处理函数system_call了
在5的处理函数被调用时用struct pt_regs regs作参数就可以访问内核栈,进而可以获得用户态的CS、EIP、SS、ESP。然而
在 Ring3 的代码调用了 sysenter 指令之后,CPU 会做出如下的操作:
1.将 SYSENTER_CS_MSR 的值装载到 cs 寄存器
2.将 SYSENTER_EIP_MSR 的值装载到 eip 寄存器
3.将 SYSENTER_CS_MSR 的值加 8(Ring0 的堆栈段描述符)装载到 ss 寄存器。
4.将 SYSENTER_ESP_MSR 的值装载到 esp 寄存器
5.将特权级切换到 Ring0
6.如果 EFLAGS 寄存器的 VM 标志被置位,则清除该标志
7.开始执行指定的 Ring0 处理函数
1.将 SYSENTER_CS_MSR 的值加 16(Ring3 的代码段描述符)装载到 cs 寄存器
2.将寄存器 edx 的值装载到 eip 寄存器
3.将 SYSENTER_CS_MSR 的值加 24(Ring3 的堆栈段描述符)装载到 ss 寄存器
4.将寄存器 ecx 的值装载到 esp 寄存器
5.将特权级切换到 Ring3
6.继续执行 Ring3 的代码
由此可知,在调用 SYSENTER 进入 Ring0 之前,一定需要通过 wrmsr 指令设置好 Ring0 代码的相关信息,在调用 SYSEXIT 之前,还要保证寄存器edx、ecx 的正确性。
1617

被折叠的 条评论
为什么被折叠?



