Page 1 of 1
#GP when returning from a 64-bit mode interrupt handler
Posted: Wed Jul 08, 2015 1:29 pm
by songziming
I created a 64-bit mode IDT and interrupts is ok. Problems arise when I want to return from interrupt handlers.
the code of the No.32 interrupt entry is:
and in my code, I invoke that interrupt using inline assembly:
However, I got a #GP exception with errcode=0. And return RIP shows that it is "iretq" instruction caused the exception.
I did all the thing in ring0, so there won't be any privilege changes. But I'm still getting this exception. Am I missing anything to implement 64-bit mode interrupt? How did you achieve interrupts under 64-bit mode?
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Wed Jul 08, 2015 1:36 pm
by xenos
Are you running your code in Bochs? If yes, what does the log say?
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Wed Jul 08, 2015 1:57 pm
by songziming
I use QEMU to run my OS. Because my OS use GRUB to boot, and GRUB uses INT 15 AX=00c0, BX=0000, which Bochs does not support.
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Wed Jul 08, 2015 2:01 pm
by stlw
songziming wrote:I use QEMU to run my OS. Because my OS use GRUB to boot, and GRUB uses INT 15 AX=00c0, BX=0000, which Bochs does not support.
What do you mean 'doesn't support' ?
QEMU uses SeaBIOS which works perfectly with Bochs as well.
BTW, you claim that Bochs BIOS doesn't have that function while SeaBIOS has and GRUB fails because of that - so it is imply enough to write a request to port INT 15 AX=00c0, BX=0000 from SeaBIOS to Bochs BIOS, if you like.
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Wed Jul 08, 2015 2:01 pm
by kzinti
songziming wrote:I use QEMU to run my OS. Because my OS use GRUB to boot, and GRUB uses INT 15 AX=00c0, BX=0000, which Bochs does not support.
I assure you, GRUB works perfectly fine in Bochs.
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Thu Jul 09, 2015 6:39 am
by songziming
When I run my OS from Bochs, it crashes on the instruction "lgdt [gdt_ptr]". But QEMU can execute this instruction just fine
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Thu Jul 09, 2015 7:17 am
by stlw
songziming wrote:When I run my OS from Bochs, it crashes on the instruction "lgdt [gdt_ptr]". But QEMU can execute this instruction just fine
I guess you didn't run your OS doesn't run on real hardware yet ?
What is the Bochs error message printed ?
Might be QEMU doesn't emulate lgdt correctly enough
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Thu Jul 09, 2015 11:05 am
by kzinti
This means there is a problem with your GDT / GDT_PTR.
Bochs validates a lot of things. QEMU doesn't. I have run into many many bugs in my code running it through Bochs, even though QEMU was happy with it.
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Sat Jul 11, 2015 10:10 pm
by songziming
Finally, I found out that bochs will not work if I use 2MB or 1GB pages. If I use 4KB pages only, bochs works just fine.
Now I know the reason for #GP is CS-selector being null.
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Sun Jul 12, 2015 5:26 am
by stlw
songziming wrote:Finally, I found out that bochs will not work if I use 2MB or 1GB pages. If I use 4KB pages only, bochs works just fine.
Now I know the reason for #GP is CS-selector being null.
Again, you most likely doing smth wrong with 2M or 1G pages.
Bochs works well with 2M pages in many scenarios, if you believe your is different - you always could write into Bochs mailing list or post on forum.
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Sun Jul 12, 2015 9:49 am
by Roman
stlw wrote:songziming wrote:Finally, I found out that bochs will not work if I use 2MB or 1GB pages. If I use 4KB pages only, bochs works just fine.
Now I know the reason for #GP is CS-selector being null.
Again, you most likely doing smth wrong with 2M or 1G pages.
Bochs works well with 2M pages in many scenarios, if you believe your is different - you always could write into Bochs mailing list or post on forum.
Maybe his Bochs build was just not configured to support 2 MiB pages?
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Mon Jul 13, 2015 1:22 am
by songziming
Now the problem returned to the 64-bit interrupt.
I've checked the stack content of the interrupt routine, and all the addresses and selectors seem valid. I also checked GDT, also no problem found. But Bochs still says return CS selector null, I don't understand why.
My Bochs session is (at the time just before iretq instruction):
Code: Select all
(0) Breakpoint 1, 0x0000000000100b1b in ?? ()
Next at t=61530965
(0) [0x000000100b1b] 0008:0000000000100b1b (unk. ctxt): iret ; cf
<bochs:3> r
CPU0:
rax: 00000000_00000040 rcx: 00000000_00000040
rdx: 00000000_00000007 rbx: 00000000_00200003
rsp: 00000000_00105f58 rbp: 00000000_00105ff0
rsi: 00000000_0010a7f8 rdi: 40000000_00000000
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: 00000000_00100b1b
eflags 0x00000002: id vip vif ac vm rf nt IOPL=0 of df if tf sf zf af pf cf
<bochs:4> xp /40bx 0x105f58
[bochs]:
0x0000000000105f58 <bogus+ 0>: 0x7d 0x05 0x10 0x00 0x00 0x00 0x00 0x00
0x0000000000105f60 <bogus+ 8>: 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x0000000000105f68 <bogus+ 16>: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x0000000000105f70 <bogus+ 24>: 0x80 0x5f 0x10 0x00 0x00 0x00 0x00 0x00
0x0000000000105f78 <bogus+ 32>: 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00
<bochs:5>
Re: #GP when returning from a 64-bit mode interrupt handler
Posted: Mon Jul 13, 2015 1:29 am
by thepowersgang
You need to explicitly use 'iretq' in 64-bit mode (which encodes to '48 cf'), otherwise only 32-bit state will be popped from the stack.