ss value not constant in taskmanager/scheduler
ss value not constant in taskmanager/scheduler
I narrowed down the problem of my taskmanager to ss: Sometimes the value for ss I give a process changes to 0x10 and then triggers a page fault. Actually, I give new processes the value for ss of 0x10 but found that this value changed automatically to something else. The pagefault is only triggered when ss is 0x10.
Is this unexpected behaviour due to some properties of ss I'm not aware of or due to buggy code of mine?
Candamir
Is this unexpected behaviour due to some properties of ss I'm not aware of or due to buggy code of mine?
Candamir
- Combuster
- 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:ss value not constant in taskmanager/scheduler
SS is generally not constant in a task/thread - that is because ring 3 and ring 0 require different values for SS.
in common circumstances (gdt contains: null, code 0, data 0, code 3, data 3, more) if i end up getting taskswitched from inside kernel code, SS equals 0x10, if the scheduler is called when executing in userland, SS equals 0x20
So a taskswitcher should handle SS just as another register that needs to be saved (IRET will do)
On another note, SS accesses might differ from DS accesses due to different privileges
Given the other thread, it looks like SS ends up where it shouldnt be
in common circumstances (gdt contains: null, code 0, data 0, code 3, data 3, more) if i end up getting taskswitched from inside kernel code, SS equals 0x10, if the scheduler is called when executing in userland, SS equals 0x20
So a taskswitcher should handle SS just as another register that needs to be saved (IRET will do)
On another note, SS accesses might differ from DS accesses due to different privileges
Given the other thread, it looks like SS ends up where it shouldnt be
Re:ss value not constant in taskmanager/scheduler
I'm sure it has nothing to do with rin 3 or ring 0 changes because I only handle kernel threads, so everything's in ring 0.SS is generally not constant in a task/thread - that is because ring 3 and ring 0 require different values for SS.
Well, further research proved that ss probably isn't the main cause of trouble, but I'm still wondering why, if I set ss in my task structure to 0x10 it turns up being something else when I FIRST read this value again ??? Because this is also strange because the kernel threads actually /work/ with this strange ss value ???
Here part of the Bochs snapshot: The first time the scheduler switches to task 1:
Code: Select all
Switching to task 1
CS: 0x8, DS: 0x10, ES: 0x10, FS: 0x10, GS: 0x10, SS: 0xD0008114
EAX: 0x0, EBX: 0x0, ECX: 0x0, EDX: 0x0, ESP: 0x0, EBP: 0x0, EDI: 0x0, ESI: 0x0
EFLAGS: 0x202, USERESP: 0xD00040B8, EIP: 0xC01025B8
Candamir
Edit: I'm sure the problem is about some weird segregs...
Re:ss value not constant in taskmanager/scheduler
SS is a 16bit register, doesn't seem like SS read correctly here.Candamir wrote:SS: 0xD0008114
Re:ss value not constant in taskmanager/scheduler
This problem makes me wanting to scream!!! I've now tried anything I know, but the problem's just always the same: Page fault with some weird address that won't appear anywhere... I attached everything related to my taskmanager in one file (parts are separated with ==============), if anyone has interest in helping me.
When a Page Fault occurs, I retrieve the address of the address that has been tried to access from CR2, but can't I also retrieve the address that actually accessed this address?
Candamir
Edit: Not does only ss change, but also useresp and eflags! It drives me crazy!
When a Page Fault occurs, I retrieve the address of the address that has been tried to access from CR2, but can't I also retrieve the address that actually accessed this address?
Candamir
Edit: Not does only ss change, but also useresp and eflags! It drives me crazy!
Re:ss value not constant in taskmanager/scheduler
because a ring change doesnt take place, ss isnt pushed into the stack, so r->ss isnt actually the value of ss, rather a value on the stack before the interrupt occured, same for user-esp
Peace
Peace
Re:ss value not constant in taskmanager/scheduler
But if user-esp isn't pushed on the stack during ring0->ring0 interrupts, I guess it isn't popped during iret. So, how can I then define a stack for a kernel thread? With r->esp and r->ebp?
Candamir
Candamir
Re:ss value not constant in taskmanager/scheduler
to me, it looks like there's a problem in your scheduler.
you'll end up having a problem when the scheduler reaches the end of the run queue (when current->next == NULL).
Code: Select all
if (current == NULL)
{
if (first != NULL)
{
scheduler_retrieve(first,r);
current = first;
}
}
else
{
task_t *next = (task_t *)current->next;
if (current == next)
{
// Nothing to schedule
}
else
{
scheduler_store(current,r);
scheduler_retrieve(next,r);
current = next;
printk("\n\tSwitching to task %d\n",current->task_id);
printk("CS: %x, DS: %x, ES: %x, FS: %x, GS: %x, SS: %x\n", current->cs, current->ds, current->es, current->fs, current->ss);
printk("EAX: %x, EBX: %x, ECX: %x, EDX: %x, ESP: %x, EBP: %x, EDI: %x, ESI: %x\n",current->eax, current->ebx, current->ecx, current->edx, current->esp, current->ebp, current->edi, current->esi);
printk("EFLAGS: %x, USERESP: %x, EIP: %x\n",current->eflags,current->useresp,current->eip);
}
}
Re:ss value not constant in taskmanager/scheduler
You could change the esp value while the interrupt stub is running e.g.Candamir wrote: But if user-esp isn't pushed on the stack during ring0->ring0 interrupts, I guess it isn't popped during iret. So, how can I then define a stack for a kernel thread? With r->esp and r->ebp?
Code: Select all
...
movl %esp, %ebx
pushl %ebx
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
call taskHandler <- changes the value passed to it in the stack to the new esp
popl %ebx
movl %ebx, %esp
...
Re:ss value not constant in taskmanager/scheduler
I think I know what my problem is: My taskmanager (if anyone has checked out the code will know) changes all the values on the stack, but doesn't change the stack itself. And my code also changes the values for ss and useresp, but these values are never pushed on the stack. This leads to the scheduler changing values on the stack it has no idea what they really are and this wrong values on the stack later on somehow cause a page fault. Could that be right?
Candamir
Edit: @deadmutex: There's no problem with my scheduler, as the linked list is implemented in a circular form. So the next element of the last element is the first element... If you're interested, look at insert_task and remove_task, these are the other parts of my linked list implementation.
Candamir
Edit: @deadmutex: There's no problem with my scheduler, as the linked list is implemented in a circular form. So the next element of the last element is the first element... If you're interested, look at insert_task and remove_task, these are the other parts of my linked list implementation.