Fixed a major oversight in the interrupt handling: when a user space
application got interrupted, thread_at_kernel_exit() was called - but
that expected interrupts to be enabled for signal handling.
However, only exceptions 3 (breakpoint) and 99 (syscall) are trap
gates, and thus, only those actually had interrupt enabled at that
point.
If a KILL signal was pending when a hardware interrupt interrupted a
user space thread you were entering KDL before ("acquire_sem() called
with interrupts turned off").
Thanks to mouse interrupts I finally got this often enough to find
this...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15143 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -334,6 +334,9 @@ i386_handle_trap(struct iframe frame)
|
|||||||
struct thread *thread = thread_get_current_thread();
|
struct thread *thread = thread_get_current_thread();
|
||||||
int ret = B_HANDLED_INTERRUPT;
|
int ret = B_HANDLED_INTERRUPT;
|
||||||
|
|
||||||
|
// all exceptions besides 3 (breakpoint), and 99 (syscall) enter this
|
||||||
|
// function with interrupts disabled
|
||||||
|
|
||||||
if (thread)
|
if (thread)
|
||||||
x86_push_iframe(&thread->arch_info.iframes, &frame);
|
x86_push_iframe(&thread->arch_info.iframes, &frame);
|
||||||
else
|
else
|
||||||
@@ -530,6 +533,9 @@ i386_handle_trap(struct iframe frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frame.cs == USER_CODE_SEG) {
|
if (frame.cs == USER_CODE_SEG) {
|
||||||
|
enable_interrupts();
|
||||||
|
// interrupts are not enabled at this point if we came from
|
||||||
|
// a hardware interrupt
|
||||||
thread_at_kernel_exit();
|
thread_at_kernel_exit();
|
||||||
i386_init_user_debug_at_kernel_exit(&frame);
|
i386_init_user_debug_at_kernel_exit(&frame);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,11 +169,6 @@ handle_signals(struct thread *thread)
|
|||||||
&& !notify_debugger(thread, signal, handler, true))
|
&& !notify_debugger(thread, signal, handler, true))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// ToDo: when we have more than a thread per process,
|
|
||||||
// it can likely happen (for any thread other than the first)
|
|
||||||
// that here, interrupts are still disabled.
|
|
||||||
// Just search for the cause if it still happens!
|
|
||||||
|
|
||||||
thread_exit();
|
thread_exit();
|
||||||
// won't return
|
// won't return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user