Page 1 of 1
GPF when trying to access syscalls
Posted: Mon Feb 08, 2016 8:14 pm
by lpoulain
All,
After having implemented multitasking, I added the switch to the user mode (I confirmed that I cannot access pages only accessible to kernel mode)
My challenge is now to access system calls from the user mode. No matter what way I try I get a General Protection Fault.
I tried to setup interrupt 0x80 using the same mechanism I use to handle Page Faults or IRQs (and which works fine), but I get a GPF when I try to raise int 0x80.
I tried to use SYSENTER, but just trying to call wrmsr leads to a GPF (note: I'm in 32-bit):
Code: Select all
asm __volatile__ ("wrmsr" : : "a"(0x9A), "d"(0), "c"(0x174));
Thanks
Re: GPF when trying to access syscalls
Posted: Mon Feb 08, 2016 8:18 pm
by gerryg400
Hi, make sure to set the DPL of the IDT entry for your sw int to 3 so that it is accessible from user land.
Also, I think you should be writing your ring 0 code selector to MSR 0x174. A code selector of 0x9a has a privilege level of 2. HINT: Most people have a ring 0 code selector of 0x8. IIRC, you also need your ring 0 data selector to be the next entry in the GDT.
Re: GPF when trying to access syscalls
Posted: Mon Feb 08, 2016 9:47 pm
by lpoulain
Thanks a lot for the tips.
Regarding the interruptions, indeed I did not set ring 3 in the DPL. This is fixed, but I still get a GPF. Interestingly, I get a GPF even when I stay in kernel mode, even though keyboard/mouse interrupt handling works fine. So there's something I'm doing wrong with my interruptions.
I tried changing the MSR parameter 0x174 code selector to 0x8 but still get the GPF as well. I set my GDT entries as:
- null segment
- kernel code segment
- kernel data segment
- user mode code segment
- user mode data segment
Re: GPF when trying to access syscalls
Posted: Tue Feb 09, 2016 12:47 pm
by tsdnz
lpoulain wrote:Thanks a lot for the tips.
Regarding the interruptions, indeed I did not set ring 3 in the DPL. This is fixed, but I still get a GPF. Interestingly, I get a GPF even when I stay in kernel mode, even though keyboard/mouse interrupt handling works fine. So there's something I'm doing wrong with my interruptions.
I tried changing the MSR parameter 0x174 code selector to 0x8 but still get the GPF as well. I set my GDT entries as:
- null segment
- kernel code segment
- kernel data segment
- user mode code segment
- user mode data segment
I am using 64 bit mode, my GDT looks like this, the User CS and SS are in a different order. See 24594_APM_v3.pdf, lookup sysret.
Code: Select all
Selector Group Location Value
0 Null 0x5000 0x0000000000000000
1 Kernel Code 0x5008 0x0000920000000000
2 Kernel Data 0x5010 0x0020980000000000
3 User Data 0x5018 0x0020F80000000000
4 User Code 0x5020 0x0000F20000000000
5 TSS[0] 0x5028
260 TSS[255] 0x6028
END 0x6038
Re: GPF when trying to access syscalls
Posted: Tue Feb 09, 2016 4:47 pm
by lpoulain
You seem to be using an AMD CPU. For the Intel processor and SYSENTER, it looks like ring 0 code / ring 0 data / ring 3 code / ring 3 data is the right order (
http://wiki.osdev.org/Sysenter)
Re: GPF when trying to access syscalls
Posted: Tue Feb 09, 2016 5:09 pm
by lpoulain
Also, I finally found what I did wrong in my interruption code (I forgot a step to catch interrupt 0x80). It would still be nice to be able to use SYSENTER / SYSEXIT though, but my next is anyway to create a wrapper that hides how the system call is made.
Re: GPF when trying to access syscalls
Posted: Tue Feb 09, 2016 5:18 pm
by tsdnz
lpoulain wrote:You seem to be using an AMD CPU. For the Intel processor and SYSENTER, it looks like ring 0 code / ring 0 data / ring 3 code / ring 3 data is the right order (
http://wiki.osdev.org/Sysenter)
Oops, sorry about that. I am using SYSCALL and just read yours as SYSCALL not as you typed it.
LOL