In set_mcontext(), take into account that kse_switchin(2) will

eventually be passed an async. context as well as a syscall
context.
While here, fix a serious bug in that if the trapframe is a
syscall frame, but we're restoring an async context, we need
to clear the FRAME_SYSCALL flag so that we leave the kernel
via exception_restore.
This commit is contained in:
marcel 2003-12-14 01:59:31 +00:00
parent 2e9029791b
commit 6b2a4c99ba

View File

@ -1118,13 +1118,18 @@ set_mcontext(struct thread *td, const mcontext_t *mc)
if (mc->mc_flags & _MC_FLAGS_ASYNC_CONTEXT) {
/*
* We can get an async context passed to us while we
* entered the kernel through a syscall: sigreturn(2).
* entered the kernel through a syscall: sigreturn(2)
* and kse_switchin(2) both take contexts that could
* previously be the result of a trap or interrupt.
* Hence, we cannot assert that the trapframe is not
* a syscall frame, but we can assert that if it is
* the syscall is sigreturn(2).
* a syscall frame, but we can assert that it's at
* least an expected syscall.
*/
if (tf->tf_flags & FRAME_SYSCALL)
KASSERT(tf->tf_scratch.gr15 == SYS_sigreturn, ("foo"));
if (tf->tf_flags & FRAME_SYSCALL) {
KASSERT(tf->tf_scratch.gr15 == SYS_sigreturn ||
tf->tf_scratch.gr15 == SYS_kse_switchin, ("foo"));
tf->tf_flags &= ~FRAME_SYSCALL;
}
tf->tf_scratch = mc->mc_scratch;
tf->tf_scratch_fp = mc->mc_scratch_fp;
if (mc->mc_flags & _MC_FLAGS_HIGHFP_VALID)