Interruptable kernel syscalls

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
User avatar
mutex
Member
Member
Posts: 131
Joined: Sat Jul 07, 2007 7:49 pm

Interruptable kernel syscalls

Post 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
User avatar
jerryleecooper
Member
Member
Posts: 233
Joined: Mon Aug 06, 2007 6:32 pm
Location: Canada

Post 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.
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post 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?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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.
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

Post 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...
User avatar
mutex
Member
Member
Posts: 131
Joined: Sat Jul 07, 2007 7:49 pm

Lets see...

Post 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 :)
User avatar
mutex
Member
Member
Posts: 131
Joined: Sat Jul 07, 2007 7:49 pm

Hmm....

Post by mutex »

Anyone got any ideas?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post 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.
User avatar
mutex
Member
Member
Posts: 131
Joined: Sat Jul 07, 2007 7:49 pm

EOI

Post 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...
User avatar
mutex
Member
Member
Posts: 131
Joined: Sat Jul 07, 2007 7:49 pm

Hmm. No one have a clue??

Post 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.
Post Reply