FIX:Crash when far return from ring 0 to ring 3, bochs 2.6.2

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
garyv
Posts: 6
Joined: Wed Feb 26, 2014 4:43 am
Location: Southern China

FIX:Crash when far return from ring 0 to ring 3, bochs 2.6.2

Post by garyv »

The related ring 0 code is:

;; SS selector for ring 3, in LDT, ring 3, offset 8
mov qword ptr [rsp + 24], (8 | 4 | 3)

;; RSP for ring 3
mov rax, 0x10000400000
mov [rsp + 16], rax

;; CS selecotr for ring 3, in LDT, ring 3, offset 0
mov qword ptr [rsp + 8], (0 | 4 | 3)

;; RIP for ring 3
mov rax, 0x10000000000
mov [rsp], rax

retf 0
-------------------
GDT info:
+0 null desc
+8 64-bit code desc, non-conforming, DPL 0, for os
+16 data desc, DPL 0, for os
+24 LDT desc
+40 TSS desc

LDT info:
+0 64-bit code desc, non-conforming, DPL 3, for app
+8 data desc, DPL 3, for app

When the "retf" instruction is executed in bochs 2.6.2, processor enters an exception. If run debug command 'c', lots of errors appear and crash:
00012169062e[CPU0] fetch_raw_desciptor: GDT: index (107) 20 > limit (37)
...

I am sure the code in 0x10000000000 is correct 64-bit code, and [0x10000000000, 0x100003fffff] area is mapped successfully, because the ring 3 code had been copy to this area, followed by an instruction 'sfence'.

After debug, I found the exception vector is 0x0D, #GP fault.
rsp before execute 'retf 0': ffff8000 000221d0
rsp after execute 'retf 0': ffff8000 000221a0, exception's stack top
when enter exception, the stack info:
[rsp]: 00000000 00000100 (error code)
[rsp + 8]: ffff8000 00001b58 (old RIP)
[rsp + 10]:00000000 00000008 (old CS)
[rsp + 18]:00000000 00010082 (RFLAGS)
[rsp + 20]:ffff8000 000221d0 (old RSP)
[rsp + 28]:00000000 00000010 (old SS)

bochs 2.6.2, Windows version. Host OS is Win8.1

The last part of crash info, error.zip:
http://pan.baidu.com/s/1kT0qr4r

There are lots of "00012...[CPU0 ] fetch_raw_descriptor: GDT: index (16f) 2d > limit (37)" lines which are not show in the snapshot.
Last edited by garyv on Sun Mar 02, 2014 1:19 am, edited 3 times in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2

Post by Combuster »

When the "retf" instruction is executed in bochs 2.6.2, processor enters an exception. If run debug command 'c', lots of errors appear and crash:
00012169062e[CPU0] fetch_raw_desciptor: GDT: index (107) 20 > limit (37)
"Lots of errors" equals just one?

Also, I can't see the "107" anywhere in the code so it must come from parts you haven't shown to us.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
doxrobot
Member
Member
Posts: 30
Joined: Wed May 15, 2013 10:14 am

Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2

Post by doxrobot »

post all of your debug output. otherwise it's just a guessing game for us.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2

Post by Antti »

Would it be better to use "iretq"? Before that you must set the stack like this:

Code: Select all

        [rsp+0x20] == (SS)
        [rsp+0x18] == (RSP)
        [rsp+0x10] == (RFLAGS)
        [rsp+0x08] == (CS)
        [rsp+0x00] == (RIP)
garyv
Posts: 6
Joined: Wed Feb 26, 2014 4:43 am
Location: Southern China

Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2

Post by garyv »

Antti wrote:Would it be better to use "iretq"? Before that you must set the stack like this:

Code: Select all

        [rsp+0x20] == (SS)
        [rsp+0x18] == (RSP)
        [rsp+0x10] == (RFLAGS)
        [rsp+0x08] == (CS)
        [rsp+0x00] == (RIP)
I think this method is using interrupt context for switching, I'll try it later.

I've append crash info to my original post.
garyv
Posts: 6
Joined: Wed Feb 26, 2014 4:43 am
Location: Southern China

Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2

Post by garyv »

The bug fixed.
In 64-bit mode, I should use "rex.w retf", otherwise processor will do the same thing as return from a 32-bit call-gate.

I am using x86-64 gcc 4.6.3, gas 2.22. Do you know the exact instruction format for 64-bit call gate's "retf"? I mean that no need manually add "rex.w".
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2

Post by jnc100 »

garyv wrote:The bug fixed.
In 64-bit mode, I should use "rex.w retf", otherwise processor will do the same thing as return from a 32-bit call-gate.
This should not be necessary, unless your call gate is running in a 32-bit segment rather than a 64-bit one (you may wish to check this by examining the gdt/ldt in bochs debugger).
garyv wrote:Do you know the exact instruction format for 64-bit call gate's "retf"? I mean that no need manually add "rex.w".
lretq (little L at the beginning) should do this, but as stated above unless you're doing a return from 32-bit to 64-bit code should not be necessary.

Regards,
John.
garyv
Posts: 6
Joined: Wed Feb 26, 2014 4:43 am
Location: Southern China

Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2

Post by garyv »

jnc100 wrote:
garyv wrote:The bug fixed.
In 64-bit mode, I should use "rex.w retf", otherwise processor will do the same thing as return from a 32-bit call-gate.
This should not be necessary, unless your call gate is running in a 32-bit segment rather than a 64-bit one (you may wish to check this by examining the gdt/ldt in bochs debugger).
garyv wrote:Do you know the exact instruction format for 64-bit call gate's "retf"? I mean that no need manually add "rex.w".
lretq (little L at the beginning) should do this, but as stated above unless you're doing a return from 32-bit to 64-bit code should not be necessary.

Regards,
John.
There is NO WAY to return from 32-bit code to 64-bit code via a call gate! x86 doesn't support this kind of switching. And 32-bit call gate does not exist in 64-bit OS.

I am sure that the call gate is a 64-bit call gate! And the code spcified by the call gate is 64-bit mode code, in ring 0.

I've tested 'lretq', it's OK. Is there abrev form for "rex.w lcall"?
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2

Post by jnc100 »

Apologies if I wasn't clear. I meant make sure your call gate is not pointing at a 32-bit code segment (i.e. ensure the 'L' flat is set on the code segment it is referring to).

Regards,
John.
Post Reply