Page 1 of 1

Return to ring 0 after iret

Posted: Thu Feb 25, 2010 4:36 am
by friackazoid
Hi all!

I am using x86 processor and I want to do some function in CPL1

Code: Select all

#define __STR(X) #X
#define STR(X) __STR(X)

        __asm__ __volatile__ (
                "\tcli\n"                                       //stop interupt
                "\tmov $"STR(__MASTER_CONTROL_DS)", %%ax\n"
                "\tmov %%ax, %%ds\n"
                "\tmov %%ax, %%es\n"
                "\tmov %%ax, %%fs\n"
                "\tmov %%ax, %%gs\n"
                "\tmov %%esp, %%eax"
                "\tpushl $"STR(__MASTER_CONTROL_DS)"\n"
                "\tpushl %%eax\n"
                "\tpushl %1\n"
                "\tpushl $"STR(__MASTER_CONTROL_CS)"\n"
                "\tpushl $1f\n"
                "\tiret\n"
                "\t1:\n"
                "\tcall %0\n"
                "\tnop\n"
                ::"r"(addr), "r" (flags | X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | X86_EFLAGS_NT | 0x2): "eax", "memory");
#undef STR
#undef __STR
after it I want to return in ring0. Is it possible?

Re: Return to ring 0 after iret

Posted: Thu Feb 25, 2010 5:21 am
by thepowersgang
When an IRQ fires it loads CS from the IDT, this sets the new PL, which is usually zero. Hence, once you drop to user-mode (or to rings 1 or 2), an interrupt will set the ring level to what the IDT says, allowing you to return to kernel mode to handle task switches and syscalls.

Re: Return to ring 0 after iret

Posted: Thu Feb 25, 2010 9:04 am
by friackazoid
Hi. Thanks for answer.

If I add one more iret after nop I have GP with "invalid TSS". I find some info [url]here|http://geezer.osdevbrasil.net/osd/gotchas/index.htm[/url]
f an exception switches the processor from Ring 3 (user privilege) to Ring 0 (kernel privilege), the Ring 0 stack pointer will automatically be loaded from the TSS. However, the reverse is not true: before using IRET to return from Ring 0 to Ring 3, you must save the Ring 0 stack pointer in the TSS:
If I understand right I must save ring 0 stack and after iret i return to ring0

Re: Return to ring 0 after iret

Posted: Thu Feb 25, 2010 6:02 pm
by thepowersgang
Usually you won't have to worry, because when you IRET you are normally at the top of the ring0 stack, so there is no need to change it before IRET.

Re: Return to ring 0 after iret

Posted: Fri Feb 26, 2010 8:39 am
by friackazoid
OK.

But what about Linux kernel do? If I understand rigth it use software interupt. But I'am not understand how it switch context and how it return after switch.

Re: Return to ring 0 after iret

Posted: Fri Feb 26, 2010 8:47 am
by thepowersgang
I don't really know how linux does it, only how I do it.
In my kernel, when a user mode program wants to access a kernel service (VFS, Process control) it calls a software interrupt. My IDT has CS for that interrupt set to a ring 0 descriptor (0x08). The TSS contains the kernel's SS (0x10) and the starting kernel ESP (for single threaded apps, this stays at 0xF0008000, but is usually changed on task switch to allow kernel threads)
This setup allows the processor to return to ring 0 to do privileged operations.
It returns by calling IRET in the interrupt handler (with the stack pointer being the same as when the handler first received control), hence returning to user mode.

Re: Return to ring 0 after iret

Posted: Sat Feb 27, 2010 4:59 am
by friackazoid
Thanks.

I will use gate. Linux do some strange stack magic, with only one TSS and without ldt.