本文将深入解析Intel iret instruction。

1. Prerequisite

建议读者阅读下浅谈栈浅谈tss

2. Materials

最权威的资料,值得读者细品。

  • Intel SDM Vol1 CHAPTER 6 PROCEDURE CALLS, INTERRUPTS, AND EXCEPTIONS
  • Intel SDM Vol2 INSTRUCTION SET REFERENCE

3. Theory

4. Example in kvm unit test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
asm volatile (
/* Prepare kernel SP for exception handlers */
"mov %%rsp, %[rsp0]\n\t"
/* Load user_ds to DS and ES */
"mov %[user_ds], %%ax\n\t"
"mov %%ax, %%ds\n\t"
"mov %%ax, %%es\n\t"
/* IRET into user mode */
"pushq %[user_ds]\n\t"
"pushq %[user_stack_top]\n\t"
"pushfq\n\t"
"pushq %[user_cs]\n\t"
"pushq $user_mode\n\t"
"iretq\n"

"user_mode:\n\t"
/* Back up registers before invoking func */
"push %%rbx\n\t"
"push %%rcx\n\t"
"push %%rdx\n\t"
"push %%r8\n\t"
"push %%r9\n\t"
"push %%r10\n\t"
"push %%r11\n\t"
"push %%rdi\n\t"
"push %%rsi\n\t"
/* Call user mode function */
"mov %[arg1], %%rdi\n\t"
"mov %[arg2], %%rsi\n\t"
"mov %[arg3], %%rdx\n\t"
"mov %[arg4], %%rcx\n\t"
"call *%[func]\n\t"
/* Restore registers */
"pop %%rsi\n\t"
"pop %%rdi\n\t"
"pop %%r11\n\t"
"pop %%r10\n\t"
"pop %%r9\n\t"
"pop %%r8\n\t"
"pop %%rdx\n\t"
"pop %%rcx\n\t"
"pop %%rbx\n\t"
/* Return to kernel via system call */
"int %[kernel_entry_vector]\n\t"
/* Kernel Mode */
"ret_to_kernel:\n\t"
"mov %[rsp0], %%rsp\n\t"
:
"+a"(rax),
[rsp0]"=m"(tss[0].rsp0)
:
[arg1]"m"(arg1),
[arg2]"m"(arg2),
[arg3]"m"(arg3),
[arg4]"m"(arg4),
[func]"m"(func),
[user_ds]"i"(USER_DS),
[user_cs]"i"(USER_CS),
[user_stack_top]"r"(user_stack +
sizeof(user_stack)),
[kernel_entry_vector]"i"(RET_TO_KERNEL_IRQ)
:
"rsi", "rdi", "rcx", "rdx");

为了能进入user mode,在内核态,进行了如下操作:

1
2
3
4
5
6
7
8
9
10
11
/* Load user_ds to DS and ES */
"mov %[user_ds], %%ax\n\t"
"mov %%ax, %%ds\n\t"
"mov %%ax, %%es\n\t"
/* IRET into user mode */
"pushq %[user_ds]\n\t"
"pushq %[user_stack_top]\n\t"
"pushfq\n\t"
"pushq %[user_cs]\n\t"
"pushq $user_mode\n\t"
"iretq\n"

5. 总结

掌握住iret instruction的Operation即可!
详情当然是参考Intel SDM Vol2 INSTRUCTION SET REFERENCE!

建议详细阅读下Switching to User-mode using iret


参考资料:

  1. Switching to User-mode using iret
  2. CPU Switches from Kernel mode to User Mode on X86 : When and How?
  3. jamesmolloy.co.uk User mode