GPF on interrupt (stub calls another entry after handler)
Posted: Thu May 13, 2021 5:53 pm
Hello everyone,
I was trying not to ask for help since breaking interrupts is a quite common issue, but I'm not having much success in tracking this bug. I apologize if this is a very basic issue, but maybe someone more experienced can give some tips.
Don't mind the code, I messed up the abstraction and have been hacking it together for testing purposes for a while. I still need to clean it up.
In https://github.com/cartTest/TestOS/blob ... l/boot.cpp, I initialize gdt, idt, and pic. Then I set irq0 in index 32 to be handled and generate the respective interrupt.
At first I was trying to make the handlers with inline asm, but since I was getting similar issues (interrupt only getting called once), I decided to try the stub implementation that appears in some tutorials. This can be found in https://github.com/cartTest/TestOS/blob ... nel/irqs.S, and the handler implementation can be found in https://github.com/cartTest/TestOS/blob ... elpers.cpp.
The interrupt setup can be found in https://github.com/cartTest/TestOS/blob ... rrupts.cpp. It basically creates and loads the idt, and sets all function to point to TEST. Newer additions will overwrite this pointer to different functions.
When running this code, the handler will get called, but when the iret instruction gets executed, the code will end up in TEST (default idt handler). Either that, or the stub forces kernel_init to be called again, leading to errors.
My guess is that either the stub assembly code is wrong, or the idt has an issue.
Qemu monitor outputs the following:
Full github code can be found in: https://github.com/cartTest/TestOS
Thank you for the help.
I was trying not to ask for help since breaking interrupts is a quite common issue, but I'm not having much success in tracking this bug. I apologize if this is a very basic issue, but maybe someone more experienced can give some tips.
Don't mind the code, I messed up the abstraction and have been hacking it together for testing purposes for a while. I still need to clean it up.
In https://github.com/cartTest/TestOS/blob ... l/boot.cpp, I initialize gdt, idt, and pic. Then I set irq0 in index 32 to be handled and generate the respective interrupt.
At first I was trying to make the handlers with inline asm, but since I was getting similar issues (interrupt only getting called once), I decided to try the stub implementation that appears in some tutorials. This can be found in https://github.com/cartTest/TestOS/blob ... nel/irqs.S, and the handler implementation can be found in https://github.com/cartTest/TestOS/blob ... elpers.cpp.
The interrupt setup can be found in https://github.com/cartTest/TestOS/blob ... rrupts.cpp. It basically creates and loads the idt, and sets all function to point to TEST. Newer additions will overwrite this pointer to different functions.
When running this code, the handler will get called, but when the iret instruction gets executed, the code will end up in TEST (default idt handler). Either that, or the stub forces kernel_init to be called again, leading to errors.
My guess is that either the stub assembly code is wrong, or the idt has an issue.
Qemu monitor outputs the following:
Code: Select all
check_exception old: 0xffffffff new 0xd
1: v=0d e=6fb8 i=0 cpl=0 IP=0008:00100094 pc=00100094 SP=0018:00106fb8 env->regs[R_EAX]=00000020
EAX=00000020 EBX=00106fb8 ECX=00000020 EDX=00000020
ESI=00000000 EDI=00000000 EBP=00107018 ESP=00106fb8
EIP=00100094 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 00107040 0000003f
IDT= 0010708e 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000010 CCD=00106fa4 CCO=ADDL
EFER=0000000000000000
Thank you for the help.