Any interrupt causes my qemu VM to restart

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
r0nk
Posts: 7
Joined: Tue Feb 24, 2015 8:02 pm

Any interrupt causes my qemu VM to restart

Post by r0nk »

Any interrupt I send to my OS causes qemu to reset the virtual machine. I've got gdt working and loaded the idt, and double checked it and everything looks good (as far as my noob self can tell). I've used qemu's debugging capabilities, and the only thing I see happening is It jump to some random location (0x0e05b, if that means anything) on each interrupt. I've got interrupts logged, (warning, wall of text.):

Code: Select all

SMM: enter
EAX=00000001 EBX=00000000 ECX=02000000 EDX=00000cfc
ESI=0000000b EDI=02000000 EBP=00000007 ESP=00006d74
EIP=000f16a1 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 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 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=     000f6c58 00000037
IDT=     000f6c96 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=000f1190 CCD=00000001 CCO=LOGICB  
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=00000000 ECX=02000000 EDX=00000cfc
ESI=0000000b EDI=02000000 EBP=00000007 ESP=00006d74
EIP=000f16a1 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000f6c58 00000037
IDT=     000f6c96 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=ffffff9c CCO=EFLAGS  
EFER=0000000000000000
     0: v=02 e=0000 i=1 cpl=0 IP=0008:00100353 pc=00100353 SP=0010:00107038 env->regs[R_EAX]=00000001
EAX=00000001 EBX=00009500 ECX=00000021 EDX=00101031
ESI=00000000 EDI=00109000 EBP=00107038 ESP=00107038
EIP=00100353 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 =0010 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=     00102000 00000800
IDT=     00102840 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000010 CCD=00107040 CCO=ADDL    
EFER=0000000000000000
check_exception old: 0xffffffff new 0xd
     1: v=0d e=0012 i=0 cpl=0 IP=0008:00100353 pc=00100353 SP=0010:00107038 env->regs[R_EAX]=00000001
EAX=00000001 EBX=00009500 ECX=00000021 EDX=00101031
ESI=00000000 EDI=00109000 EBP=00107038 ESP=00107038
EIP=00100353 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 =0010 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=     00102000 00000800
IDT=     00102840 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000010 CCD=00107040 CCO=ADDL    
EFER=0000000000000000
check_exception old: 0xd new 0xd
     2: v=08 e=0000 i=0 cpl=0 IP=0008:00100353 pc=00100353 SP=0010:00107038 env->regs[R_EAX]=00000001
EAX=00000001 EBX=00009500 ECX=00000021 EDX=00101031
ESI=00000000 EDI=00109000 EBP=00107038 ESP=00107038
EIP=00100353 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 =0010 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=     00102000 00000800
IDT=     00102840 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000010 CCD=00107040 CCO=ADDL    
EFER=0000000000000000
check_exception old: 0x8 new 0xd 
Unfortunately, It's not very clear to me at all what is happening here. I've tried to find the problem but I'm at my wits end. The next thing I've considered doing is taking a look at the qemu code base, but that's quite the rabbit hole and I'm pretty sure I just made some stupid mistake somewhere that I can't see. I've already looked at the related wiki pages, but nothing I've tried from there has fixed it.

Here is the source code for my os (quite a mess, I know. This Is just a attempt to get something sorta working the first time, then rewrite it all once I've learned from my mistakes.) Any help would be very much appreciated.
MDenham
Member
Member
Posts: 62
Joined: Sat Nov 10, 2012 1:16 pm

Re: Any interrupt causes my qemu VM to restart

Post by MDenham »

You're getting two GPFs followed by the obvious double fault, which (according to the community Magic 8-Ball) tells me that the VM is restarting because of a triple fault afterwards, probably because the handler for processor exceptions is - for whatever reason - triggering a GPF of its own.
User avatar
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Re: Any interrupt causes my qemu VM to restart

Post by eryjus »

After a quick review, I notice a couple of things. First, you should have a target for your interrupts written in assembly. C just cannot handle saving and restoring all the registers.

Second, the following code:

Code: Select all

void initalize_interrupts()
{
/* initalize the table contents */
initalize_idt();
idt_descr.size=(256*8);
idt_descr.address=(unsigned int)idt_table;
load_idt(&idt_descr);
}
... the size needs to be 1 less than the true size. In other words:

Code: Select all

idt_descr.size=(256*8)-1;
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
r0nk
Posts: 7
Joined: Tue Feb 24, 2015 8:02 pm

Re: Any interrupt causes my qemu VM to restart

Post by r0nk »

MDenham wrote:You're getting two GPFs followed by the obvious double fault, which (according to the community Magic 8-Ball) tells me that the VM is restarting because of a triple fault afterwards, probably because the handler for processor exceptions is - for whatever reason - triggering a GPF of its own.
It seem's that your right about the triple fault, adventures into qemu revealed the '-d cpu_reset' option, which is a bit more illuminating, as it states that the CPU Triple faulted. It appears to be an error in how I encoded the type for each gate, still working out a fix.
r0nk
Posts: 7
Joined: Tue Feb 24, 2015 8:02 pm

Re: Any interrupt causes my qemu VM to restart

Post by r0nk »

I FIXED IT! AS;LKDJFA;LKSDJF;ALKSJDF YES MWAHAHAHAHAHAH.

Ok, so here is what I did; I started by going to qemu's codebase and adding a few printfs to point me in the right direction,
The mistakes I made;
* In the IDT, I had the low and high uint32's in the wrong order
* I forgot to enable the P bit (I'm not a clever man)
* lastly, for the segment selector in the IDT, I mistakenly thought that the segment selector was an offset value, when it actually was just an index value. I put 8 where I should've put 1.

VICTORY SPEECH TIME;
DON'T GIVE UP ON YOUR DREAMS, NO MATTER HOW FAR THEY MIGHT SEEM. CHAMPIONS DON'T GIVE UP. YOU ARE A CHAMPION. YES I KNOW INTERRUPTS ARE FOR IDIOTS, BUT IT DOESN'T MATTER BECAUSE I'M A SUCCESSFUL IDIOT AND SO CAN YOU. THIS TOOK ME LIKE 4 DAYS BUT IDGAF I DID IT. WOO!
Post Reply