Page 1 of 1

Returning from an abort

Posted: Mon Feb 23, 2009 9:23 pm
by Cone
Hi all, new guy here.

I guess I'll start off with a question about abortive exceptions on x86 architecture, specifically the double-fault. Normally, when a double-fault exception occurs, the faulting code section cannot be restarted because the return address pushed onto the stack is undefined (is it pushed onto the stack? I don't know specifically.) Even so, if I set up the double-fault exception handler to be called through a task gate, will the valid CS and EIP of the faulting instruction be saved in the code section's TSS? Can I retrieve those registers and "fudge" a return to the faulting code section? And even if that's possible, does an abort create some internal state in the processor that prevents a return absolutely?

If not, I think I can patch any contributory exception or page fault handlers to immediately IRET to handling code outside the context of an interrupt, so that no double faults will ever occur. I'm hoping that can work.

Now, I know that it is always a good idea to avoid any type of aborts, but the nature of my purposes necessarily involves general protection exceptions following from contributory exceptions (I'm more or less stacking two independent kernels on top of one another hierarchically, with the ring 0 kernel mediating the ring 1 kernel.) Just in case you wanted to know why I'd have to ask this question. :)

Thanks,
Cone

Re: Returning from an abort

Posted: Mon Feb 23, 2009 10:31 pm
by Brendan
Hi,
Cone wrote:I guess I'll start off with a question about abortive exceptions on x86 architecture, specifically the double-fault. Normally, when a double-fault exception occurs, the faulting code section cannot be restarted because the return address pushed onto the stack is undefined (is it pushed onto the stack? I don't know specifically.) Even so, if I set up the double-fault exception handler to be called through a task gate, will the valid CS and EIP of the faulting instruction be saved in the code section's TSS? Can I retrieve those registers and "fudge" a return to the faulting code section? And even if that's possible, does an abort create some internal state in the processor that prevents a return absolutely?
The CPU does put return information on the stack. The problem is the IRET will take you back to the original problem, and the TSS won't have reliable error information to fix the original problem.

The best it can do is fix the cause of the double fault, then return to the faulty instruction which will cause a second general protection fault, where (hopefully) the CPU will be able to start the general protection fault handler (and the general protection fault handler will be able to get the error code from the stack and reliably figure out what went wrong with the original instruction).

Also note that a double fault only occurs if the CPU can't start the exception handler (e.g. bad IVT limit, bad IVT entry, bad CS in the interrupt gate, bad SS:ESP, etc). Once the CPU has pushed return information on the stack and started the exception handler's first instruction, then any further exceptions won't cause a double fault.
Cone wrote:Now, I know that it is always a good idea to avoid any type of aborts, but the nature of my purposes necessarily involves general protection exceptions following from contributory exceptions (I'm more or less stacking two independent kernels on top of one another hierarchically, with the ring 0 kernel mediating the ring 1 kernel.) Just in case you wanted to know why I'd have to ask this question. :)
Sounds like the exception handlers themselves should be in the ring 0 kernel, and if/when necessary the ring 0 exception handlers should call handlers in the ring 1 kernel.


Cheers,

Brendan

Re: Returning from an abort

Posted: Tue Feb 24, 2009 12:25 am
by Cone
Thanks for the answer, Brendan.
Also note that a double fault only occurs if the CPU can't start the exception handler (e.g. bad IVT limit, bad IVT entry, bad CS in the interrupt gate, bad SS:ESP, etc). Once the CPU has pushed return information on the stack and started the exception handler's first instruction, then any further exceptions won't cause a double fault.
Ugh, I can't believe I missed that. Thanks, now I shouldn't have to worry about this ever happening.