Page 1 of 1

General Protection Fault after loading IDT and executing sti

Posted: Sun Mar 24, 2013 2:03 am
by vivache30
Greetings!

First, My english is not good. i can not write english good.
but i can reading english. so very very sorry.

not enable interrupt:
Image

enable interrupt:
Image

I am somehow generating General Protection Fault and interrupt 32 as soon as I invoke "sti" after setting up the IDT, ISR, and IRQ.

source is http://dev.enbcode.com/los/
if want to zip file? http://dev.enbcode.com/los/los.rar

/kernel/main.c - main
/kernel/tables.c - set gdt & tss & idt
/kernel/interrupt.c - interrupt handler
/kernel/isr.S - set ISR

set gdt & idt and executing sti!!! so interrupt error..
please feedback and Thank you so much!

Re: General Protection Fault after loading IDT and executing

Posted: Sun Mar 24, 2013 3:38 am
by Brendan
Hi,
vivache30 wrote:please feedback and Thank you so much!
For 32-bit code (with 32-bit interrupt gates or 32-bit trap gates), when an interrupt occurs the CPU pushes 12 bytes of data (EIP, EFLAGS and CS zero extended to 32-bit), plus an error code for some exceptions.

The "IRETW" instruction is intended for 16-bit code. For "IRETW" the CPU only loads 6 bytes from the stack (IP, FLAGS and CS).

Now imagine some CPL=0 code at 0x00012345 is running and an IRQ occurs. The CPU does the right thing and pushes 12 bytes of data on the stack, then the "IRETW" pops 16-bits into IP (causing the CPU to return to the wrong address - 0x2345 and not 0x00012345), and pops dodgy data into FLAGS (0x00001 left over from the other half of EIP), and loads dodgy data into CS (the first 16 bits of data from EFLAGS); and if this isn't enough only 6 bytes are taken from the stack (not 12) so the stack ends up broken too. With the stack broken, CS wrong, IP wrong and FLAGS wrong, there's 4 different ways the CPU can crash - most likely is that you'll get a General Protection Fault from IRETW itself.

You need to use "IRETD" (or just "IRET") instead of "IRETW".

Also note that there's no reason to do "pushfd" and "popfd" yourself, as the CPU already saves EFLAGS when it starts the interrupt and loads EFLAGS during IRET.

Finally, for some exceptions (page fault, general protection fault, etc) the CPU pushes an extra error code on the stack which needs to be manually removed by you (e.g. "add esp,4" just before IRET).


Cheers,

Brendan