Page 1 of 1
Interruptable kernel syscalls
Posted: Fri Aug 31, 2007 3:02 pm
by mutex
Hello again.
Its some time since i worked on my kernel last time, but im trying to get past the problem i broke down on last time:)
This is the case:
I have a kernel with a software task switcher. Task switching and kalling syscalls works very well. But when i try to have interrupts enabled during special syscalls that should be interruptable, then the problem starts.
Actually the kernel works very well with the interruptable system calls, but the problem appears when im exiting the syscall and resuming to ring3. Then it GPF's and i have no real good idea why. The LOAD / SAVE on every ISR might need some adjustments to work.
If i dont do anything stackwork in the syscall that is interruptable, the cpu does not do a GPF, but it seems to loop over an dover again on the exit from that function so it actually never exits. Other tasks continue to run as they should.
It might be something regarding the context saving on LOAD / STORE in ring0<->ring0 calls. Im not sure.
Anyone had similar problems? I have tried to draw callflow, stackflow etc on paper and think about it, but cant figure it out..
cheers
Thomas
Posted: Fri Aug 31, 2007 6:18 pm
by jerryleecooper
Im not an expert, but isn't that when an interrupt happen when the code is interrupted, it is a double fault?
Also, from what I understand, it's probably your interrupt code, you expect it to be called only once, but it's called twice. I have the same kind of code and wouldn't do syscalls whilst already interrupted.
The problem probably arise when the tss gets its esp0, it get its value, the interrupt gets, and gets its same value, and the values of the old interrupt gets lost. But without code to see, I cant be sure about that.
Posted: Fri Aug 31, 2007 7:59 pm
by frank
Do you have a separate kernel task for each process? If you plan on having an interruptible kernel then this is a must! Also are you patching the TSS on each task switch like you should?
Posted: Sat Sep 01, 2007 2:18 am
by JamesM
Remember that when a task is interrupted in a syscall, there is no stack switch, so no ESP/SS combo is pushed. Make sure you're not relying on that in some way.
Posted: Sat Sep 01, 2007 2:24 am
by bluecode
I have another question that popped up, when I read the initial post: Does a kernel for SMP/NUMA need to be interruptible? Since there are these TLB (and perhaps other synchs too...) synchronizations which are implemented through Interprocessor-Interrupts?
But then again not everything can be implemented interruptable/reentrant...
Lets see...
Posted: Sat Sep 01, 2007 5:50 am
by mutex
Code: Select all
%macro SAVE 0
cld
pushad
push ds
push es
push fs
push gs
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov eax,[_currenttask]
mov [eax],esp
%end macro
%macro LOAD 0
mov eax,[_currenttask]
mov esp,[eax]
mov ebx,[eax+8]
mov [_tss+4],ebx
mov al,0x20
out 0x20,al
pop gs
pop fs
pop es
pop ds
popad
iretd
%end macro
[extern _Syscall]
[global _syscall]
_syscall:
SAVE
call _Syscall
LOAD
[extern _Timer]
[global _timer]
_timer:
SAVE
call _Timer
LOAD
void Syscall()
{
int *n = (int*)currenttask->esp;
switch(n)
{
case 0:
ExitCallingProcess();
break;
case 1:
Scheduler();
break;
case 2:
__asm("sti");
t = cycles + 5000;
while(cycles < t);
__asm("cli");
break;
default:
// Bogus syscall.. for now we just do nothing..
}
}
void Timer()
{
cycles++;
Scheduler();
}
Maby this helps... This is a stripped down version of a few things but it should give a picture on the most important things. The scheduler just changes currenttask pointer and the syscall entry also have a method of copying in data if needed. While writing this now i think maby i know about one thing i havent thought about while coding.... but lets see if someone else is thinking the same.. It has something to do with the stack after the SAVE
Hmm....
Posted: Mon Sep 03, 2007 3:15 pm
by mutex
Anyone got any ideas?
Posted: Tue Sep 04, 2007 2:43 am
by JamesM
Code: Select all
%macro LOAD 0
mov eax,[_currenttask]
mov esp,[eax]
mov ebx,[eax+8]
mov [_tss+4],ebx
mov al,0x20
out 0x20,al
pop gs
pop fs
pop es
pop ds
popad
iretd
%end macro
why are you sending an EOI after every syscall? this should be sent only after IRQs.
EOI
Posted: Wed Sep 05, 2007 9:04 am
by mutex
In most cases this LOAD is used by the timer_isr which needs to EOI before return. On the syscall this does not do anything... Im i wrong?
I think i know what the problem might be though, but nobody else have noticed it.. I might be wrong, but i think the issue is related the kstack of each task... but i cant figure out why. But it seems anyway that if i dont touch the stack inside the syscall everything is ok...
Hmm. No one have a clue??
Posted: Fri Sep 07, 2007 10:34 pm
by mutex
Anyone have interruptable isr's or syscalls working that can give me a hint on differences from their to my code??
It seems to me to be stack related, but i cant really figure out why.. I also see that the GPF is triggered on same point every time.
Maby i should extend my bluescreen function to give a more extended output, so i can try to get the view of the error from there.