当RCX保存正确的返回地址时,为什么SYSRET返回地址0?

时间:2017-09-27 20:23:34

标签: kernel system-calls

我的业余爱好是x86_64 UEFI内核,其中用户代码调用系统代码,但它生成一般保护错误,错误代码0位于0x1B:0x0(0x1B是用户模式代码段选择器)。单步执行我意识到SYSRET不会返回到RCX中保存的地址,而是返回零。我使用和不带KVM的qemu-system-x86_64进行调试。附上关于这种现象的两个截图。有谁能解释一下,并告诉我,我做错了什么?

MSR 0xC0000080 = 0x0000000000000501
MSR 0xC0000081 = 0x001B00083D906D79
MSR 0xC0000082 = 0x000000003D906D79
MSR 0xC0000083 = 0x000000003D906D79
MSR 0xC0000084 = 0x0000000000000300

使用cli和Local APIC条目禁用中断。

Before the deadly step

After

GDT:

{ 0, 0, 0, 0x9A, 0x20, 0 }; // 0x08 ring 0 code
{ 0, 0, 0, 0x92, 0x00, 0 }; // 0x10 ring 0 data
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x1B ring 3 code
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x23 ring 3 data
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x2B ring 3 code
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x33 ring 3 data

typedef struct PACKED ENTRY
{
    U16 limit_0_15;
    U16 base_0_15;
    U8  base_16_23;
    U8  access;
    U8  granularity;
    U8  base_24_31;
} ENTRY, *PENTRY;

编辑:再次阅读说明书后,我注意到在长模式下返回CS将是(STAR.SYSRET_CS + 16)| 3所以我复制用户模式段描述符只是为了确定,但结果是一样的。

1 个答案:

答案 0 :(得分:0)

在SYSEXIT上,RCX ==返回RSP和RDX ==返回RIP。请参阅Intel指令集参考。