3rd exception while CPL switching

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
pini

3rd exception while CPL switching

Post by pini »

I'm trying to go from a CPL0 function to a CPL3 function. I can't use a far call, because you can only call a more privileged function, so I planned to use a far return, which is in theory usable.
The stack looks like this when I execute the retf

Code: Select all

SS
ESP
CS
EIP
Where SS:ESP refers to the CPL3 stack and CS:EIP to the CPL3 function.
I set the others segments (DS, ES, FS & GS) to the correct CPL3 values.

Everything works good, until it's time to execute the first CPL3 instruction... because it crashes in an

Code: Select all

exception(): 3rd exception with no resolution
I can't figure out what the problem is...
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:3rd exception while CPL switching

Post by Pype.Clicker »

did you made sure you had segments aligned properly on stack ?

Code: Select all

mov ax,ds ; push ax
will *not* give the same result as

Code: Select all

push ds
pini

Re:3rd exception while CPL switching

Post by pini »

the code produced is the following :

Code: Select all

mov eax,0x23                       ; User CPL3 data selector
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
push byte +0x23                 ; push SS
push esp                              ; push ESP
push byte +0x1b                 ; push CS (CPL3 code selector)
push dword [0x101ea4]     ; push EIP
retf                                         ; go to CPL3 function
mystran

Re:3rd exception while CPL switching

Post by mystran »

Set bochs to print the CPU debug messages, and it will tell you which exception it was that caused the triple-fault. Once you know what the problem is, it's easier to guess where it might be.
pini

Re:3rd exception while CPL switching

Post by pini »

Here is what I got :

Code: Select all

00000671074d[CPU  ] exception(0e h)
00000671074d[CPU  ] interrupt(): vector = 14, INT = 0, EXT = 1
00000671074d[CPU  ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00000671074d[CPU  ] exception(0e h)
00000671074d[CPU  ] interrupt(): vector = 8, INT = 0, EXT = 1
00000671074d[CPU  ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
00000671074d[CPU  ] exception(0e h)
00000671074p[CPU  ] >>PANIC<< exception(): 3rd exception with no resolution
It seems to be a triple page fault.
mystran

Re:3rd exception while CPL switching

Post by mystran »

It seems to be a triple page fault.
That's actually what I expected. :)

Check that:
a) the new EIP is on page that is mapped (page present)
b) that CPL3 code can access the page (user level access)
c) that you have properly invalidated any possibly stale TLBs
d) if using C, check that relevant parts are volatile

The page fault seems to happen before CPU switches to CPL3 so also check that GDT is properly mapped. Now, you probably either don't have IDT set up, or it's also causing page fault when trying to find the page-fault handler from IDT (since you double fault) so if you do have an IDT you know that it's also broken.

I'd check that all the registers have sane values, then try to print the relevant page-table entries in hex to see if they are what they should be. That includes both the page where you are trying to return and GDT.
pini

Re:3rd exception while CPL switching

Post by pini »

mystran wrote: b) that CPL3 code can access the page (user level access)
Thanks, I didn't thought about the paging privilege level. It now works correctly.

I currently have an IDT which should (?) work :
a) I'm using IRQ 0 to compute the CPU speed, and it works well.
b) I get this with bochs :

Code: Select all

allow_io(): TR doesn't point to a valid 32bit TSS
00000999467d[CPU  ] exception(0d h)
00000999467d[CPU  ] interrupt(): vector = 13, INT = 0, EXT = 1
00000999467d[CPU  ] int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE
I get these lines until I stop my kernel, but bochs doesn't complain, so I think that my handler for this exception (which is "general protection fault") works correctly, and this means that my IDT is correct (I just didn't implement TSS support yet).

Anyway, thanks for giving me the solution to my pb ;)
mystran

Re:3rd exception while CPL switching

Post by mystran »

If you haven't set a TSS, then naturally TR (register for TSS address) is invalid. Just implement a TSS and the problem will (should) go away.
Peter_Vigren

Re:3rd exception while CPL switching

Post by Peter_Vigren »

Pype.Clicker wrote: did you made sure you had segments aligned properly on stack ?

Code: Select all

mov ax,ds ; push ax
will *not* give the same result as

Code: Select all

push ds
It won't?? Why?? *very confused*
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:3rd exception while CPL switching

Post by Pype.Clicker »

when you push a segment in a 32 bits environment, the processor automagically aligns the stack so that you actually use a 32-bits location for a 16 bits value (all the TSS and stackframes work this way), while when you push a 16bits word (including "push ax") using a 16bits override prefix, the processor assumes you know what you're doing and decreases the stack pointer by 2 only...

the correct alternative is

Code: Select all

mov ax,ds
push eax
Post Reply