Ring3 Tasks GPF on IRET
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Ring3 Tasks GPF on IRET
Currently I am in the process of switching all usermode processes to ring3 instead of ring0, but it's not working out too well...
If I use ring3, whenever an interrupt fires I get a GPF from the 'iret' line (at the very end of it). As soon as I switch all usermode tasks back to ring0, I have no problems at all.
This is really confusing, but I've worked at it and have found that on the GPF the error code shows that the faulting segment was 0x18, my ring3 code segment.
Any ideas? I've been reading the Intel Manuals and so far nothing has worked.
Edit: Another thing, when I OR all segment descriptors by 3, I get a page fault for an invalid privilege level access (these pages are not supervisor pages).
If I use ring3, whenever an interrupt fires I get a GPF from the 'iret' line (at the very end of it). As soon as I switch all usermode tasks back to ring0, I have no problems at all.
This is really confusing, but I've worked at it and have found that on the GPF the error code shows that the faulting segment was 0x18, my ring3 code segment.
Any ideas? I've been reading the Intel Manuals and so far nothing has worked.
Edit: Another thing, when I OR all segment descriptors by 3, I get a page fault for an invalid privilege level access (these pages are not supervisor pages).
pcmattman,
I had the same problem when I was implementing my scheduler and later I found out that the RPL of my user processes' CS/DS/ES/FS/GS and etc were not set to 3. Make sure the RPL of the segment selectors that you create for your user processes is set to 3. The RPL is the rightmost 2 bits of a segment selector.
You say that the reported error indicates that the code segment that has caused the GPF is 0x18 that is equal to 24 in decimal. 24 is divisible by 8 and thus it shows that you have not set the rightmost 2 bits of the CS of the process to 1 (all the bits). So the segment selector of 0x18 will become 0x1B after it is changed to RPL3 (0x1B 11011; note that the rightmost 2 bits are set to 1). Basically for every user process, make sure the DPL/RPL/CPL are all equal to 3.
Good luck.
I had the same problem when I was implementing my scheduler and later I found out that the RPL of my user processes' CS/DS/ES/FS/GS and etc were not set to 3. Make sure the RPL of the segment selectors that you create for your user processes is set to 3. The RPL is the rightmost 2 bits of a segment selector.
You say that the reported error indicates that the code segment that has caused the GPF is 0x18 that is equal to 24 in decimal. 24 is divisible by 8 and thus it shows that you have not set the rightmost 2 bits of the CS of the process to 1 (all the bits). So the segment selector of 0x18 will become 0x1B after it is changed to RPL3 (0x1B 11011; note that the rightmost 2 bits are set to 1). Basically for every user process, make sure the DPL/RPL/CPL are all equal to 3.
Good luck.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
Hi,
Where does the page fault occur (what is CR2)? Could it be that you are a) Trying to use data or b) Trying to use a stack which is in kernel space. I know I had stack problems when I first did this too, as I hadn't allowed for a user mode page for the stack.
Als, make sure that the u/s bit is set in all page table entries and page directory entries where your user task is accessing data/code.
A possible way to find a solution would be to make your paging mechanism set the user bit in all PDE's/PTE's on every page in operation (including in kernel space). Then, modify it so that the paging bit is not set for kernel pages - if you get a PFE again, you then know you are trying to access a kernel page you shouldn't be.
Hope this makes sense!
Adam
Where does the page fault occur (what is CR2)? Could it be that you are a) Trying to use data or b) Trying to use a stack which is in kernel space. I know I had stack problems when I first did this too, as I hadn't allowed for a user mode page for the stack.
Als, make sure that the u/s bit is set in all page table entries and page directory entries where your user task is accessing data/code.
A possible way to find a solution would be to make your paging mechanism set the user bit in all PDE's/PTE's on every page in operation (including in kernel space). Then, modify it so that the paging bit is not set for kernel pages - if you get a PFE again, you then know you are trying to access a kernel page you shouldn't be.
Hope this makes sense!
Adam
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Wait, bit 3 set? Won't that make it supervisor?AJ wrote:All PTEs and PDEs have bit 3 set
Edit: OK, I set bit 3 on all pages relating to usermode, now I'm faulting on 0xB8000 which is a kernel (ie. supervisor) mapping. This is good.
Edit 2: Here's a shot of the kernel in action:
Code: Select all
[NULL] Idle task has started.
[FAT ] Initializing FAT32 structures... Done!
Welcome to Mattise!
Version 1.1, ALPHA
I've been rudely interrupted by the processor with this message for you:
Page Fault
Crash at 0x 40001e EFLAGS: 0x 13286 Process: 1
Registers at time of crash:
------------------------------------------
PAGE FAULT, error code information:
Error because of a privilege violation
Was a read
Processor was in supervisor mode
Reserved bit violation: no
Wasn't caused by an instruction fetch
------------------------------------------
Interrupt number: 14
EAX: 0x 0 EBX: 0x 0 ECX: 0xffbff000 EDX: 0x 0
EBP: 0xffbfefe8 ESP: 0x 115f84 ESI: 0x 0 EDI: 0x 0
Segments at time of crash:
CS: 0x 1b DS: 0x 23 ES: 0x 23
FS: 0x 23 GS: 0x 23 SS: 0x 23
Control registers:
CR0: 0x80000011 CR2: 0x b8000 CR3: 0x 171000
-
- Member
- Posts: 45
- Joined: Fri Jul 20, 2007 1:39 am
OK - given your second edit above, I don't quite understand the problem (this may me be being slow ).
You now have set bit 3 of your user code which runs without a problem until you try to print something directly to video RAM. At that point, you get a PFE occurring at 0xB8000, because of a privilege level problem, but you have already stated that 0xB8000 is paged at supervisor level.
If I have summarised the problem correctly, you can only access video RAM from either your kernel (running in PL0), or by setting bit 3 of the 0xB8000 page from your kernel before switching to the user task (which I wouldn't advise).
I would suggest doing it by handling a syscall to the kernel and writing to video RAM from there.
Sorry if I have got the wrong end of the stick..
Adam
You now have set bit 3 of your user code which runs without a problem until you try to print something directly to video RAM. At that point, you get a PFE occurring at 0xB8000, because of a privilege level problem, but you have already stated that 0xB8000 is paged at supervisor level.
If I have summarised the problem correctly, you can only access video RAM from either your kernel (running in PL0), or by setting bit 3 of the 0xB8000 page from your kernel before switching to the user task (which I wouldn't advise).
I would suggest doing it by handling a syscall to the kernel and writing to video RAM from there.
Sorry if I have got the wrong end of the stick..
Adam