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