old error back again

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Poseidon

old error back again

Post by Poseidon »

A long time ago, I had problems with a page fault... something creates a page fault, and when the page fault irets, I get a triple fault... can't remember how I fixed it, but I just discovered the error was back again :(

Anyone ideas what the error could cause?

Here is the code that calls the pagefaulthandler:

Code: Select all

isr14:   cli
   
   pushl %eax
   pushl %ebx
   pushl %ecx
   pushl %edx
   
   call mm_page_fault_handler
   
   popl %edx
   popl %ecx
   popl %ebx
   popl %eax
   
   iret
Thanks :)
Zorro

Re:old error back again

Post by Zorro »

Hello Poseidon!

I think this will solve your problems:

Code: Select all

isr14:   cli
   
   pushl %eax
   pushl %ebx
   pushl %ecx
   pushl %edx
   mov %esp %ebp
   
   call mm_page_fault_handler
   
   mov %ebp %esp
   popl %edx
   popl %ecx
   popl %ebx
   popl %eax
   
   addl %esp, $4
   iret
Poseidon

Re:old error back again

Post by Poseidon »

i edited it a bit, and now it works... thanks :)
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:old error back again

Post by Neo »

Edited which? The code that "Zorro" posted?
Only Human
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:old error back again

Post by Brendan »

Hi,

Code: Select all

isr14:
   cli
This is a (subtle) bug :).

If the CPU receives an IRQ after starting the page fault handler but before the "CLI" is executed, then a second page fault (that occurs while the IRQ is being handled) will overwrite CR2.

To avoid this use an "interrupt gate" rather than a "trap gate", so that the CPU automatically disables interrupts while starting the page fault handler.

You may also need to pass the error code from the exception to the C handler (for e.g. so you can handle things differently if the kernel caused the page fault, or check if it was a "page not present" or an "access denied").

Further, eventually the page fault handler may need to read data from disk (e.g. from the swap). This means that interrupts will need to be enabled at some point during the execution of the page fault handler. For the sake of reduced interrupt latency you might as well do it as soon as you can.

Combining all of the above results in using an "interrupt gate" that looks something like:

Code: Select all

isr14:
   pushl %eax
   movl %cr2,%eax       ;eax = accessed address
   pushl %ebx
   movl 8(%esp),%ebx    ;ebx = error code
   sti                  ;re-enable interrupts
   pushl %ecx
   pushl %edx

   pushl %eax          ;put address on stack (parameter 1)
   pushl %ebx          ;put error code on stack (parameter 2)

   call mm_page_fault_handler
   sub $8,%esp        ;remove both parameters from the stack

   popl %edx
   popl %ecx
   popl %ebx
   popl %eax

   addl %esp, $4     ;remove CPU's error code from stack
   iret
I'm not too sure what order C uses for parameters, but the C function would be:

void mm_page_fault_handler(unsigned int error_code, void *address);

Or:

void mm_page_fault_handler(void *address, unsigned int error_code);

I'm also not too good with AT&T syntax either, but I think the "8(%esp)" is right (in Intel syntax it's "[esp+8]"). Hopefully it's enough to give you the general idea....


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:old error back again

Post by Colonel Kernel »

According to most C calling conventions I know of, parameters are pushed from right to left, so it's your first prototype.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
Poseidon

Re:old error back again

Post by Poseidon »

Thanks all :)
Post Reply