#GP when returning from a 64-bit mode interrupt handler

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
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

#GP when returning from a 64-bit mode interrupt handler

Post 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:

Code: Select all

hwint32:
    inc     byte [0xb8000]
    iretq
and in my code, I invoke that interrupt using inline assembly:

Code: Select all

__asm__ volatile ("int $32");
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?
Reinventing the Wheel, code: https://github.com/songziming/wheel
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post by xenos »

Are you running your code in Bochs? If yes, what does the log say?
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
Reinventing the Wheel, code: https://github.com/songziming/wheel
stlw
Member
Member
Posts: 357
Joined: Fri Apr 04, 2008 6:43 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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
Reinventing the Wheel, code: https://github.com/songziming/wheel
stlw
Member
Member
Posts: 357
Joined: Fri Apr 04, 2008 6:43 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
Reinventing the Wheel, code: https://github.com/songziming/wheel
stlw
Member
Member
Posts: 357
Joined: Fri Apr 04, 2008 6:43 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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?
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
songziming
Member
Member
Posts: 71
Joined: Fri Jun 28, 2013 1:48 am
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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> 
Reinventing the Wheel, code: https://github.com/songziming/wheel
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: #GP when returning from a 64-bit mode interrupt handler

Post 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.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Post Reply