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.
FIX:Crash when far return from ring 0 to ring 3, bochs 2.6.2
FIX:Crash when far return from ring 0 to ring 3, bochs 2.6.2
Last edited by garyv on Sun Mar 02, 2014 1:19 am, edited 3 times in total.
- Combuster
- 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
"Lots of errors" equals just one?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)
Also, I can't see the "107" anywhere in the code so it must come from parts you haven't shown to us.
Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2
post all of your debug output. otherwise it's just a guessing game for us.
Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2
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)
Re: Crash when far return from ring 0 to ring 3, bochs 2.6.2
I think this method is using interrupt context for switching, I'll try it later.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've append crash info to my original post.
Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2
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".
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".
Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2
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: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.
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.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".
Regards,
John.
Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2
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.jnc100 wrote: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: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.
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.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".
Regards,
John.
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"?
Re: FIX:Crash when far return from ring 0 to ring 3, bochs 2
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.
Regards,
John.