IRET hangs when switch back from kernel-space to user-space
Posted: Sat Sep 30, 2017 11:57 pm
Hi,
If possible, I would like to receive some advices because I have been stuck with this problem for a while...I have been involved with system programming for 5 months, so I know basic things related to OS theories (e.g., GDT, IDT, TSS, how interrupt works, segmentation etc.).
I am working on a project that requires me to write a simple user-space routine for an open-source hypervisor project. The hypervisor is bare-metal running in kernel mode VMX root, and it does not support linux OS on top of it, which means that this hypervisor has no concept like Linux process. My problem is that I need to execute a simple user-space routine (i.e., which probably do nothing but to store an integer into a register for testing purpose) and whenever I execute IRET, the system hangs/freezes/ or runs into infinite loop, so I am unable to get more information on the hang. Here are things what I have tried:
- Related to my kernel-space to user-space routine, I follow Linux's way to return (i.e., kernel_execve) in which an interrupt is generated (i.e., int $0x80) in kernel-space of the hypervisor, it is trapped and the hypervisor's handler prepares the context for user-space routine before executing IRET. Unlike Linux, I did not statically initialize the process context.
- The user-space routine context requires 3 main things: (1) 2 GDT entries for User Code (DPL=3) and User Data(DPL=3), (2)(optional) TSS for user-space routine to return back to kernel-space if an interrupt happens in user-space, and (3) top of the stack so that IRET can pop information.
- I have tried to enable some flag by the temporaryFlag saved on the stack (i.e., RF, TF, IF) but none of them is effective.
- My returning routine is taken from returning to user-mode by James Molloy and OSDev-Getting to Ring 3 and they works on bochs emulator. So I basically know how to return to user-mode.
- I have tried to perform IRET between segments with the same privilege, and it works as I expect it. This experiment is to prove that I setup the GDT entries and the top-of-the-stack correctly. However, if I switch between segments with different privileges, IRET hangs/freezes/ or runs into infinite loop.
- I have tried to intentionally supply wrong parameter (i.e., wrong DPL, wrong limitation, out-of-bound index) to IRET, and I get correct exceptions(e.g., #GPF, #SS, #NP)
I am currently reading how Linux OS boot-up the first user-space process PID 1, and this is complicated for me to trip down all the dependency at the moment. So I am confused what I should do to make a successful switch and what could be a possible reason that IRET fails to execute.
Thanks in advance,
Minh
If possible, I would like to receive some advices because I have been stuck with this problem for a while...I have been involved with system programming for 5 months, so I know basic things related to OS theories (e.g., GDT, IDT, TSS, how interrupt works, segmentation etc.).
I am working on a project that requires me to write a simple user-space routine for an open-source hypervisor project. The hypervisor is bare-metal running in kernel mode VMX root, and it does not support linux OS on top of it, which means that this hypervisor has no concept like Linux process. My problem is that I need to execute a simple user-space routine (i.e., which probably do nothing but to store an integer into a register for testing purpose) and whenever I execute IRET, the system hangs/freezes/ or runs into infinite loop, so I am unable to get more information on the hang. Here are things what I have tried:
- Related to my kernel-space to user-space routine, I follow Linux's way to return (i.e., kernel_execve) in which an interrupt is generated (i.e., int $0x80) in kernel-space of the hypervisor, it is trapped and the hypervisor's handler prepares the context for user-space routine before executing IRET. Unlike Linux, I did not statically initialize the process context.
- The user-space routine context requires 3 main things: (1) 2 GDT entries for User Code (DPL=3) and User Data(DPL=3), (2)(optional) TSS for user-space routine to return back to kernel-space if an interrupt happens in user-space, and (3) top of the stack so that IRET can pop information.
- I have tried to enable some flag by the temporaryFlag saved on the stack (i.e., RF, TF, IF) but none of them is effective.
- My returning routine is taken from returning to user-mode by James Molloy and OSDev-Getting to Ring 3 and they works on bochs emulator. So I basically know how to return to user-mode.
- I have tried to perform IRET between segments with the same privilege, and it works as I expect it. This experiment is to prove that I setup the GDT entries and the top-of-the-stack correctly. However, if I switch between segments with different privileges, IRET hangs/freezes/ or runs into infinite loop.
- I have tried to intentionally supply wrong parameter (i.e., wrong DPL, wrong limitation, out-of-bound index) to IRET, and I get correct exceptions(e.g., #GPF, #SS, #NP)
I am currently reading how Linux OS boot-up the first user-space process PID 1, and this is complicated for me to trip down all the dependency at the moment. So I am confused what I should do to make a successful switch and what could be a possible reason that IRET fails to execute.
Thanks in advance,
Minh