flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Stack segment after SYSRETQ

Author
Thread Post new topic Reply to topic
CandyMan



Joined: 04 Sep 2009
Posts: 414
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan 06 Nov 2012, 17:21
Why after SYSRETQ the stack segment is set to zero?

_________________
smaller is better
Post 06 Nov 2012, 17:21
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 514
Location: Czech republic, Slovak republic
Feryno 06 Nov 2012, 18:07
what do you have in MSR_STAR ?
could you show us your descriptor table ?
Post 06 Nov 2012, 18:07
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 414
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan 06 Nov 2012, 18:38
Code:
        mov     ecx,MSR_AMD_STAR        ; SYSCALL/SYSRET codes
        mov     edx,(Code64-GDT+16+3)*65536+Code64-GDT
        mov     eax,SysCalls
        wrmsr
        ....
;GDT
TSS     dw 0080h,TSS64,8900h,00h
Code64  dw $FFFF,0,9A00h,$AF    ;64B code descriptor
Data32  dw $FFFF,0,9200h,$CF    ;4GB data descriptor
Code16  dw $FFFF,0,9A00h,$8F    ;16B code descriptor
Data16  dw $FFFF,0,9200h,$8F    ;16B data descriptor
Code32  dw $FFFF,0,9A00h,$CF    ;4GB code descriptor
    

_________________
smaller is better
Post 06 Nov 2012, 18:38
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 514
Location: Czech republic, Slovak republic
Feryno 08 Nov 2012, 12:55
Hi, that explains a lot:
bits 63-48 of STAR contain Code16+11b
after SYSRETQ from 64 bit ring0 into 64 bit ring3 the following happens:
CS.Sel is loaded from this field + 16 (that is Code32 in your case)
SS.Sel is loaded from this field + 8 (that is Data16 in your case)

Personally I would contruct GDT in a way like:
Code:
GDT:
null                     dw      0,      0,      0,      0
code32_compat_ring3
data64_ring3
code64_ring3
code64_ring0
data64_ring0
task64    


and then load STAR with
Code:
mov edx,((code32_compat_ring3-GDT + 11b) shl 16) + (code64_ring0-GDT)
mov eax,SysCalls_EIP_compatibility_mode
mov ecx,MSR_AMD_STAR
wrmsr    


if you don't plane to support compatibility mode then you can delete code32 from GDT and do only
Code:
mov edx,((null + 11b) shl 16) + (code64_ring0-GDT)
xor eax,eax
mov ecx,MSR_AMD_STAR
wrmsr

GDT:
null                     dw      0,      0,      0,      0
data64_ring3
code64_ring3
code64_ring0
data64_ring0
task64    


some my thoughts:
it is bad idea to put task64 into null of GDT, some error appears after you try to load task (the LTR instruction)
also one hint: don't forget to erase busy bit of task when you load it repeatedly - it is good to do something like
Code:
and byte [task64+5],not 10b    

just before
Code:
ltr task64-GDT    


don't hesitate to post your successes/unsuccesses, everything may be solved
Post 08 Nov 2012, 12:55
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 08 Nov 2012, 18:45
Is this compatibility mode or long mode?

If long mode and interrupts are enabled, ISRs will zero SS if CPL is changed Question (not ruling out a sysret state check failure, as Feryno hinted at, but I can't find this in the manuals...)
Post 08 Nov 2012, 18:45
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 514
Location: Czech republic, Slovak republic
Feryno 09 Nov 2012, 08:44
Hi,
how I understood it from CPU manuals (both AMD and intel) and implemented it in my old abandoned project where it worked fine (only 64 bit mode was implemented, compatibility submode of long mode wasn't)

SS.Sel is loaded from field + 8 no matter whether sysretq is into compatibility submode (32 bits) of long mode or 64 bit submode of long mode
CS.Sel is loaded from field + 0 when sysret into compatibility or 32 bits
CS.Sel is loaded from field + 16 when sysretq into 64 bits
when sysret into compatiblity submode of long mode, simple sysret instruction is used (1 byte instruction)
when sysretq into 64 bits then sysretq instruction is necessary (that is 2-bytes instruction = 1 byte for prefix 48h + 1 byte for sysret)

syscall/sysret switch rings faster than interrupt because no necessity of interrupt table

CandyMan wrote about SYSRETQ so I assumed he wants to sysretq from 64 bit ring0 into 64 bit ring3
Post 09 Nov 2012, 08:44
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 414
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan 11 Nov 2012, 15:44
I implemented changes like below.
Still stack fault exception is appearing.
Code:
GDT:    dq 0
Code32  dw $FFFF,0,$FA00,$CF
        dw $FFFF,0,$F200,$CF
        dw $FFFF,0,$FA00,$AF
Code64  dw $FFFF,0,9A00h,$AF
        dw $FFFF,0,9200h,$CF
Tss64   dw $0067,0,8900h,$00
        dq 0

        mov     ecx,MSR_AMD_STAR
        mov     edx,(Code32-GDT+3)*65536+Code64-GDT
        mov     eax,SysCalls
        wrmsr
    

_________________
smaller is better
Post 11 Nov 2012, 15:44
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.