Page 1 of 1

Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 6:23 am
by Js2xxx
Well, although I got my system calls with syscall/sysret works(only two - block and unblock), should I set IF in IA32_FMASK when initializing?
  • If so, some system calls that takes a long time will slow down the CPU or some system calls that need to wait interrupts happen will causes an infinite loop.
  • And if not, when timer triggers and context switches and other processes on the same CPU want to call the system, the stack will be broken (I've tested before and it works as I expect - triple fault occurs and computer reboots).
Or, is there a better solution?

Re: Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 7:32 am
by Brendan
Hi,
Js2xxx wrote:Well, although I got my system calls with syscall/sysret works(only two - block and unblock), should I set IF in IA32_FMASK when initializing?
Yes, you should. If you don't an IRQ can occur after CPL switches to CPL=0 but before you've switched to a sane stack.
Js2xxx wrote:Or, is there a better solution?
You can enable IRQs again, like:

Code: Select all

syscall_handler:
    swapgs
    mov [gs:thread_stack],rsp
    mov rsp,[gs:kernel_stack_top]
    sti

    ...

    cli
    mov rsp,[gs:thread_stack]
    swapgs
    sysret

Cheers,

Brendan

Re: Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 7:04 pm
by Js2xxx
Brenden wrote:Yes, you should. If you don't an IRQ can occur after CPL switches to CPL=0 but before you've switched to a sane stack.
Js2xxx wrote:Or, is there a better solution?
You can enable IRQs again
Well, I think if so, scheduler will mess the stack up again.
So what if I mask the timer and sti and cli and then unmask the timer?

EDIT: My syscall handler works well when there's only one thread calling the system. But it reboots when two threads call the system at the same time. Bochs says there's three canonical failure. :shock: So how to solve this problem?

EDIT AGAIN: I think the three canonical failure is this: When the second thread calls the system. The swapgs instruction is executed again. My original gs base is 0 so rsp will be loaded a non-canonical value. Then a push instruction causes #SS. But it's CPL = 0 now, so rsp will not change and the push instruction in exception handler will causes a double fault. However, according to the text above, it reboots. So I think I should set IST to the exception handlers. But how do I solve the first canonical failure?

Re: Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 7:55 pm
by Brendan
Hi,
Js2xxx wrote:
Brendan wrote:You can enable IRQs again
Well, I think if so, scheduler will mess the stack up again.
So what if I mask the timer and sti and cli and then unmask the timer?
Most IRQ handlers may end up triggering a task switch for various reasons (e.g. because data that a task was blocked/waiting for arrived), so disabling the timer IRQ shouldn't help.

If the kernel is supposed to be pre-emptable; you'd want to fix the scheduler (e.g. have a special kind of lock that causes task switches to be postponed if anything triggers a task switch) so that it doesn't matter if any IRQ interrupts a syscall (even if the IRQ triggers a task switch, and even if the syscall triggers a task switch).
Js2xxx wrote:EDIT: My syscall handler works well when there's only one thread calling the system. But it reboots when two threads call the system at the same time. Bochs says there's three canonical failure. :shock: So how to solve this problem?

EDIT AGAIN: I think the three canonical failure is this: When the second thread calls the system. The swapgs instruction is executed again. My original gs base is 0 so rsp will be loaded a non-canonical value. Then a push instruction causes #SS. But it's CPL = 0 now, so rsp will not change and the push instruction in exception handler will causes a double fault. However, according to the text above, it reboots. So I think I should set IST to the exception handlers. But how do I solve the first canonical failure?
From this I'd assume that your scheduler is unstable, and syscall just exposes pre-existing bugs.


Cheers,

Brendan

Re: Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 8:07 pm
by ~
You could use a single integer flag variable to indicate the scheduler if it's OK to switch tasks, another variable to indicate if it can load new tasks, another to indicate if it cannot unload existing tasks.

You could set them manually with a kernel console module, because of events of your choice, or enable/disable them arbitrarily.

Re: Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 8:12 pm
by Js2xxx
Brendan wrote:you'd want to fix the scheduler (e.g. have a special kind of lock that causes task switches to be postponed if anything triggers a task switch)
I see. Let me try later.

And also I agree that my scheduler is unstable. It is mixed with assembly and C. What a mess! I intend to rewrite it with pure C++.

Re: Confusing about IF and SYSCALL

Posted: Thu Jun 29, 2017 8:16 pm
by Js2xxx
~ wrote:You could use a single integer flag variable to indicate the scheduler if it's OK to switch tasks, another variable to indicate if it can load new tasks, another to indicate if it cannot load existing tasks.

You could set them manually with a kernel console module, because of events of your choice, or enable/disable them arbitrarily.
Oh yes that's what I'm going to do. Thanks for your help.