Page 1 of 1

ireting trouble

Posted: Sat Aug 09, 2008 4:50 pm
by sancho1980
Hi

I have set up a clock interrupt that can switch between different tasks.
It goes like this:

you create a process by calling:

createProcess(privilege,quantum,initial_eip,cs_base,ds_base,es_base,fs_base,gs_base,ss_base,cs_size,ds_size,es_size,fs_size,gs_size,ss_size);

this creates one tss for the process and 6 segment descriptors for cs,ds,es,fs,gs,ss. the tss, the selectors and the descriptors written all reflect the privilege level asked for in this call. you can then enqueue the process with

enqueue(pointer_to_tss, scheduling_queue, FRONT);

this works fine AS LONG AS i use privilege 0 in the createProcess call. when i use a lower (numerically higher) privilege level, bochs gives me: "iret: TSS selector points to bad TSS"

the iret is very probably the one i use in the timer interrupt to "beam me" into the new process after previously fiddling with the backlink of the timer tss (yes i use hw task switches!)

does any of you have a clue why i get the above error?

i have checked and the createProcess call *really* sets up the process correctly. is there any problem with ireting into a ring3 task from my ring0 timer task?

thanks

martin

Re: ireting trouble

Posted: Sat Aug 09, 2008 7:28 pm
by bewing
There is no theoretical problem with it, no. AFAIK, there is no other way to switch from ring0 to 3.

The bochs error message seems to be specifically saying that there is some kind of formatting error in the TSS itself. I would think that you should examine every single byte of the tss entry, and verify it against the intel manuals.

Re: ireting trouble

Posted: Sun Aug 10, 2008 3:22 am
by sancho1980
yes i have checked that
an my tss really looks fine
i was just wondering: when an iret occurs from ring0 to ring3, is there any kind of stack switch involved?
the reason im asking is the following: the tss data structure provides fields for ss/esp0-2 and another two fields for the programs stack segment and stack pointer registers.
i only use these last two fields, i.e. the fields for storing the esp and ss, because my os doesnt use call gates
i "misuse" the ss/esp0-2 for other purposes, because i use the tss data structure as my process data structure, so i store stuff like the process' quantum and so on in there
is there any problem with that?

Re: ireting trouble

Posted: Sun Aug 10, 2008 9:01 am
by ru2aqare
sancho1980 wrote:yes i have checked that
an my tss really looks fine
i was just wondering: when an iret occurs from ring0 to ring3, is there any kind of stack switch involved?
the reason im asking is the following: the tss data structure provides fields for ss/esp0-2 and another two fields for the programs stack segment and stack pointer registers.
i only use these last two fields, i.e. the fields for storing the esp and ss, because my os doesnt use call gates
i "misuse" the ss/esp0-2 for other purposes, because i use the tss data structure as my process data structure, so i store stuff like the process' quantum and so on in there
is there any problem with that?
You should not misuse the ss/esp0-2 fields for other purposes. Especially not the ss/esp0 fields, as those contain the selector and initial esp value loaded into ss and esp respectively, when the processor switches to ring zero. If you need to store additional data in the TSS, place it after the end of the TSS structure (after offset 0x68).

Re: ireting trouble

Posted: Sun Aug 10, 2008 2:31 pm
by sancho1980
hi
i think this CANNOT be the reason why it doesnt work
the way my process model works is as follows:
everything is a task. EVERYTHING. full stop.
i want to create a process - i set up a tss in the process table and write a descriptor for that tss in the gdt
i want to hook an interrupt - i set up a tss for the interrupt routine and write a descriptor for that tss in the idt

stack switching really shouldn't be an issue because this way stack switches should never occur

all works fine as long as i use only ring0 tasks, but as soon as i hook a ring3 tasks it crashes

the ONLY kind of task switches that i have are:

-interrupt tasks kick in
-interrupt tasks perform iret (possibly after previously rewriting their own backlink field)


there really shouldnt be any stack switches involved in here, should there?

Re: ireting trouble

Posted: Sun Aug 10, 2008 3:55 pm
by bewing
Um. I may not have understood you correctly. Of course there is a stack switch on an IRET.
When you are switching priv levels with an interrupt, there are an extra 2 dwords stored on the kernel stack -- SS and ESP for the Ring3 process. The IRET pops and uses those values when restarting the Ring3 process, after it pops all the other registers and CS.
The SS and ESP values in the TSS are only used on the interrupt, in your case. Not on the IRET.

Re: ireting trouble

Posted: Mon Aug 11, 2008 2:14 pm
by -m32
sancho1980 wrote: stack switching really shouldn't be an issue because this way stack switches should never occur

You're going to have an awfully rough time doing multi-tasking without changing stacks on a privilege change.... :roll:

Re: ireting trouble

Posted: Wed Aug 13, 2008 8:07 am
by sancho1980
hi sorry i didnt reply earlier but didnt have time:
i'm pretty sure you're wrong here; there really shouldn't be any stack switching in my os; what you need to take into account here *reallyreallyreally* is that i'm using hardware task switching; and that means (quotation from http://download.intel.com/design/proces ... 253668.pdf chapter 6.4):

When a CALL instruction, an interrupt, or an exception causes a task switch: the
processor copies the segment selector for the current TSS to the previous task link
field of the TSS for the new task; it then sets EFLAGS.NT = 1. If software uses an
IRET instruction to suspend the new task, the processor checks for EFLAGS.NT = 1;
it then uses the value in the previous task link field to return to the previous task. See
Figures 6-8.

This is what I'm doing. I am NOT doing software task switches.

Re: ireting trouble

Posted: Thu Aug 14, 2008 6:44 am
by -m32
sancho1980 wrote:hi sorry i didnt reply earlier but didnt have time:
i'm pretty sure you're wrong here; there really shouldn't be any stack switching in my os; what you need to take into account here *reallyreallyreally* is that i'm using hardware task switching; and that means (quotation from http://download.intel.com/design/proces ... 253668.pdf chapter 6.4):

When a CALL instruction, an interrupt, or an exception causes a task switch: the
processor copies the segment selector for the current TSS to the previous task link
field of the TSS for the new task; it then sets EFLAGS.NT = 1. If software uses an
IRET instruction to suspend the new task, the processor checks for EFLAGS.NT = 1;
it then uses the value in the previous task link field to return to the previous task. See
Figures 6-8.

This is what I'm doing. I am NOT doing software task switches.
Section 6.1:
If an operating system or executive uses the processor’s privilege-level protection mechanism, the task execution space also provides a separate stack for each privilege level.
Yes, stack switches occur during privilege change.

Re: ireting trouble

Posted: Thu Aug 14, 2008 7:09 am
by jtlb
Is there a simple way to set the NT flag or do i have to use an interrupt handler to edit the eflag register image on the stack?

Re: ireting trouble

Posted: Fri Aug 15, 2008 5:07 pm
by sancho1980
ok, if im really really wrong about the stack switching thing, then can someone please explain.
following situation: clock handler task is executing (privilege 0). then it performs the iret to a task of privilege level 3:
in he fields of the tss, WHICH entries are going to be used as selector and pointer for the stack of the new task: ss/esp, ss2/esp2, ss1/esp1 or ss0/esp0?
i would guess the only relevant stack in the tss of the entrant task is contained in ss/esp, no?
but that's what i'm doing!
i thought the fields ss2/esp2-ss0/esp0 are there just to be used in those cases where for example my privilege 3 task jumps into a conforming privilege 0 code segment.
i really don't get my head around this. how does stack switching happen on a task switch (which fields are used exactly and in what order)?

thanks

martin

Re: ireting trouble

Posted: Sat Aug 16, 2008 3:21 am
by jtlb
When you create a selector(at least for segment) you shall make it the following way:
uint16_t selector = (selector_index * 0x8) | RPL;
RPL being the Requested Privilege Level. I guess that in your case it is 3.
You MUST do this for EACH selector used by your task.

When doing hardware task switching(very hard in my opinion) with an iret:
Description
Returns program control from an exception or interrupt handler to a program or
procedure that was interrupted by an exception, an external interrupt, or a software-
generated interrupt. These instructions are also used to perform a return from a
nested task. (A nested task is created when a CALL instruction is used to initiate a
task switch or when an interrupt or exception causes a task switch to an interrupt or
exception handler.) See the section titled “Task Linking” in Chapter 6 of the Intel® 64
and IA-32 Architectures Software Developer’s Manual, Volume 3A.
IRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (inter-
rupt return double) is intended for use when returning from an interrupt when using
the 32-bit operand size; however, most assemblers use the IRET mnemonic inter-
changeably for both operand sizes.
In Real-Address Mode, the IRET instruction preforms a far return to the interrupted
program or procedure. During this operation, the processor pops the return instruc-
tion pointer, return code segment selector, and EFLAGS image from the stack to the
EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the inter-
rupted program or procedure.
In Protected Mode, the action of the IRET instruction depends on the settings of the
NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS
image stored on the current stack. Depending on the setting of these flags, the
processor performs the following types of interrupt returns:
• Return from virtual-8086 mode.
• Return to virtual-8086 mode.
• Intra-privilege level return.
• Inter-privilege level return.
• Return from nested task (task switch).
If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return
from the interrupt procedure, without a task switch. The code segment being
returned to must be equally or less privileged than the interrupt handler routine (as
indicated by the RPL field of the code segment selector popped from the stack).
3-530 Vol. 2A IRET/IRETD—Interrupt Return
INSTRUCTION SET REFERENCE, A-M
As with a real-address mode interrupt return, the IRET instruction pops the return
instruction pointer, return code segment selector, and EFLAGS image from the stack
to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of
the interrupted program or procedure. If the return is to another privilege level, the
IRET instruction also pops the stack pointer and SS from the stack, before resuming
program execution. If the return is to virtual-8086 mode, the processor also pops the
data segment registers from the stack.
If the NT flag is set, the IRET instruction performs a task switch (return) from a
nested task (a task called with a CALL instruction, an interrupt, or an exception) back
to the calling or interrupted task. The updated state of the task executing the IRET
instruction is saved in its TSS. If the task is re-entered later, the code that follows the
IRET instruction is executed.
This comes from the intel instruction set reference (manual 2A)

Re: ireting trouble

Posted: Sat Aug 16, 2008 8:31 am
by sancho1980
I just found out what the problem was:

I forgot to set the busy flag for the new task before doing the iret;
the problem had NOTHING at all to do with the stack..i am still misusing esp2/ss2-0 for other purposes because these fields are completely irrelevant for iret task switches, which is what i do in my os. even if im switching to a a different privilege level: these fields are completely IRRELEVANT

how could you be so sure of yourself when you were wrong?