GP on context switch

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
user mode

GP on context switch

Post by user mode »

Hello,

I'm getting general protection exception whenever I try to switch to user mode. Here is what I use:

Code: Select all

global userMode

userMode:
        mov    eax, esp     ; Save Current Stack Offset
        push    0x18        ; Push user data selector
        push    eax         ; Push Stack Offset
        pushfd                ; Push EFLAGS
        push    0x20        ; Push user code selector
        push    here        ; Push EIP
        iretd               ; Cause Switch
here:
        mov    ax, 0x18   ; user data selector
        mov    ds, ax
        mov    es, ax
        mov    fs, ax
        mov    gs, ax
and my gdt's user & code selectors:

Code: Select all


userData        equ     $-gdt      
        dw 0FFFFh
        dw 0
        db 0
        db 0F2h         ; ring 3
        db 0CFh        
        db 0

userCode        equ     $-gdt      
        dw 0FFFFh
        dw 0
        db 0
        db 0FAh        ; ring 3 
        db 0CFh         
        db 0
Can anyone please help me out? :)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:GP on context switch

Post by Pype.Clicker »

knowing which instruction raises the GPF and what the error code was could help ... i can't remember whether ds..gs are also automatically pushed when a user/supervisor stack switch occur, but i would say it's only in case of a virtual/protected mode switch ... so everything should be fine ...
userMode

Re:GP on context switch

Post by userMode »

knowing which instruction raises the GPF and what the error code was could help
The IRETD seems to be the culprit causing GPF.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:GP on context switch

Post by Pype.Clicker »

i'm not sure, but you might need to push home-made flags rather than using "pushfd". iirc, some of the bits in eflags carry things like the IO Priviledge Level, and the processor might not like you to run user-level code segment with a supervisor IOPL ...

It also seems a bad idea to reuse the supervisor stack pointer in the user code. You should better allocate a memory region and fill the user pointer with it ...
userMode

Re:GP on context switch

Post by userMode »

Is this not correct method of context switching to ring 3:

push userSS
push userESP
push userEFLAGS
push userCS
push userEIP
iretd

If anyone has better psuedo code please let me know :)
Therx

Re:GP on context switch

Post by Therx »

Somewhere in this thread is loads of disscusion on the order of pushing/poping on entering leaving ISRs/irets etc. I was really confused and after that even I understood it. ;D

Pete
shadowH3
Posts: 8
Joined: Tue Dec 15, 2009 1:04 am

Re: GP on context switch

Post by shadowH3 »

MAKE SURE you are coding straight assembler within the OS defs header file, not C or pascal..they add headers that will drive you BONKERS!

just tried a 'what if' in prt0 and VIOLA!!! Finally, after months of hell...USER MODE and proper register settings..this is close..all you need is a call to this routine(as external assembler).

I know the code is off, use the C example. This is for NASM, not GAS or AS(S).
I use FPC, but this is within the prt0 OS assembler header.

Try $23 and $1b...(have to add ring3 [+03]) and you need a TSS to get back to ring0.

----
extern UserESP ; this MUST be a seperate stack.
global switch_to_user_mode
switch_to_user_mode:
cli ;there is especial way to turn interrupts on for user mode, sti will NOT do it.
mov dword eax,$23
mov word ds,ax
mov word es,ax
mov word fs,ax
mov word gs,ax
mov eax,UserESP
push dword $23
pushf
push dword $1b
push dword eax

push dword $23 ; think this is the culprit, I GPF in usermode on switch..
iret
jmp 0x1b:user
user:
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: GP on context switch

Post by Owen »

I'm so sure user mode is has been waiting ever so patiently these 8 yearsfor an answer to his question.

(Also: A font size cap of 200%? Aww, what? I can't help but feel that sometimes you need 1000% or similar to really hammer home the point)
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: GP on context switch

Post by gerryg400 »

Code: Select all

extern UserESP ; this MUST be a seperate stack.
global switch_to_user_mode
switch_to_user_mode:
    cli ;there is especial way to turn interrupts on for user mode, sti will NOT do it.
    mov dword eax,$23
    mov word ds,ax
    mov word es,ax
    mov word fs,ax
    mov word gs,ax
    mov eax,UserESP
    push dword $23
    pushf
    push dword $1b
    push dword eax

    push dword $23 ; think this is the culprit, I GPF in usermode on switch..
    iret
    jmp 0x1b:user
user:
Strictly speaking I don't think it's 100% correct anyway. Loading DS with the ring3 data selector and then accessing a kernel-private variable (UserESP) won't work for all designs.
If a trainstation is where trains stop, what is a workstation ?
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 on context switch

Post by xenos »

IMHO it is easier to switch to user mode only in the scheduler, since you need the kernel -> user transition there anyway. In my kernel there is no "switch to user mode" in the way described here, having a sequence of instructions where some of them are executed in kernel mode, the segment registers are reloaded and the following ones are executed in user mode. Instead, when a new user thread is created, the task manager creates a PL0 stack image for the new thread, which looks exactly as if had been generated by the timer interrupt handler. This handler pushes all registers to the stack, calls the scheduler, switches to a different PL0 stack, pops the register contents and IRETs. It does not matter whether the scheduled thread was running at PL3 before or whether it was just created by the task manager. The task manager simply needs to create the new PL0 stack, put the initial register values at the right position, set the return EIP and ESP to the entry point and PL3 stack of the new thread - that's it.

(Of course one can modify this a bit. For example, instead of pushing the registers to the stack, one could save them in a "struct ThreadState" or whatever.)
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
digo_rp
Member
Member
Posts: 233
Joined: Sun Jun 05, 2005 11:00 pm

Re: GP on context switch

Post by digo_rp »

Man have you set up the tss.ss0 and tss.esp0 ? to use ring3 in context switch you need one TSS.
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 on context switch

Post by xenos »

digo_rp wrote:Man have you set up the tss.ss0 and tss.esp0 ? to use ring3 in context switch you need one TSS.
AFAIK, you always need a TSS if you want to get back from PL3 to PL0.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
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: GP on context switch

Post by Combuster »

Why are we still replying to an OP from 2003? (you don't need a TSS to get back to ring 0, but a lack of TSS in usermode is just stupid design.)
"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 ]
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 on context switch

Post by xenos »

Well, my post was not meant for the OP, but simply for the readers of this thread which has been awakened from the dead...

Just out of curiosity, let me see if I get this right: If I have no TSS, i cannot have interrupts while running in PL3 (so I need to clear the IF) and the only way to get back to PL0 is using SYSENTER (or SYSCALL in long mode) or call gates? But anyway, I agree with you, it's a stupid design.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Post Reply