Return to ring 0 after iret

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
friackazoid
Posts: 4
Joined: Thu Feb 25, 2010 4:31 am

Return to ring 0 after iret

Post 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?
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Return to ring 0 after iret

Post 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.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
friackazoid
Posts: 4
Joined: Thu Feb 25, 2010 4:31 am

Re: Return to ring 0 after iret

Post 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
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Return to ring 0 after iret

Post 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.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
friackazoid
Posts: 4
Joined: Thu Feb 25, 2010 4:31 am

Re: Return to ring 0 after iret

Post 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.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Return to ring 0 after iret

Post 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.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
friackazoid
Posts: 4
Joined: Thu Feb 25, 2010 4:31 am

Re: Return to ring 0 after iret

Post by friackazoid »

Thanks.

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