Page 1 of 1

syscall from ring 0 to ring 0

Posted: Mon Dec 31, 2012 7:09 am
by summersong
x64
I would like to do syscall (syscall-sysret) from ring 0 to ring 0. Is it possible?

I try to change GDT to:

dq 0
dw 0ffffh,0,09b00h,0afh ; code R, ring 0
dw 0ffffh,0,09300h,0afh ; data RW, ring 0
dw 0ffffh,0,09300h,0afh ; data RW, ring 0
dw 0ffffh,0,09b00h,0afh ; code R, ring 0
dq 0e90000003001h + ((tss and 0xFFFFFF) shl 16) + ((tss and 0xFF000000) shl 32),tss shr 32 ; app tss

GPF, Bochs log: "check_cs(0x0023): non-conforming code seg descriptor dpl != cpl, dpl=0, cpl=3"

I try to change GDT to:
dq 0
dw 0ffffh,0,09b00h,0afh ; code R, ring 0
dw 0ffffh,0,09300h,0afh ; data RW, ring 0
dw 0ffffh,0,0f200h,0afh ; data RW, ring 3
dw 0ffffh,0,0fa00h,0afh ; code R, ring 3
dq 0e90000003001h + ((tss and 0xFFFFFF) shl 16) + ((tss and 0xFF000000) shl 32),tss shr 32 ; app tss

Bochs - OK
QEmu - restart (tripple fault??)

Re: syscall from ring 0 to ring 0

Posted: Mon Dec 31, 2012 7:21 am
by rdos
It shouldn't work. The documentation on syscall/sysret states that the destination selectors for sysret should be in ring 3. Other than that, it seems pretty meaningless to use syscall/sysret within ring 0.

BTW, did you setup the corresponding MSRs prior to your test? Did you use 0x48 prefix for sysret?

Re: syscall from ring 0 to ring 0

Posted: Mon Dec 31, 2012 7:53 am
by summersong
Yes, I did.

Re: syscall from ring 0 to ring 0

Posted: Mon Dec 31, 2012 12:29 pm
by gerryg400
You should be able to syscall from any ring, however sysret will always try to return to ring 3. My memory manager runs in ring 1 and it uses syscall but the kernel uses iret to return to it

Re: syscall from ring 0 to ring 0

Posted: Mon Dec 31, 2012 1:14 pm
by bluemoon
If you are going from ring0 to ring0, you should refactor your code and do direct function call - this is much quicker.

Code: Select all

syscall_stub:
...
call qword [syscall_handler+rax*8]
...
sysret

syscall_handler_1:
  xxxx
  ret

syscall_handler_2:
  ...
  call syscall_handler_1
  ...
  ret

Re: syscall from ring 0 to ring 0

Posted: Wed Jan 02, 2013 5:34 am
by cyr1x
The GDT layout should be code/data/code/data as CS := selector_base and SS := selector_base + 8

Re: syscall from ring 0 to ring 0

Posted: Mon Jan 07, 2013 1:26 pm
by summersong
AMD reference volume 2 & 3:
The processor assumes (but does not check) that the SYSCALL target CS has CPL=0 and the SYSRET target CS has CPL=3.

SYSCALL sets the CPL to 0, regardless of the values of bits 33–32 of the STAR register.

SYSRET sets the CPL to 3, regardless of the values of bits 49–48 of the star register. SYSRET can only be executed at CPL 0.
Sorry for disturbing.

cyr1x: thank's, my fault.

bluemoon: I was thinking about ring 0 only OS for app & kernel. Only as idea. It's quite interesting: no protection, cooperative multitasking, and so on = fast speed. Probably :). Far call is fast, but fixed offset... I don't want to do so... Didn't want :).

Re: syscall from ring 0 to ring 0

Posted: Mon Jan 07, 2013 3:00 pm
by bluemoon
summersong wrote:Far call is fast, but fixed offset... I don't want to do so... Didn't want :).
I was talking about near call, but anyway this does not necessary be fixed offset, you can do relocation, run time linking or "query near-call interface" with slower method like INT.