[xtensa-cvscommit] linux/arch/xtensa/kernel signal.c,1.7,1.8
Brought to you by:
zankel
|
From: <joe...@us...> - 2003-04-29 18:30:38
|
Update of /cvsroot/xtensa/linux/arch/xtensa/kernel In directory sc8-pr-cvs1:/tmp/cvs-serv27015/arch/xtensa/kernel Modified Files: signal.c Log Message: Clear all CP and EXTRA state before transfering control to a signal handler. Index: signal.c =================================================================== RCS file: /cvsroot/xtensa/linux/arch/xtensa/kernel/signal.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** signal.c 23 Apr 2003 23:19:55 -0000 1.7 --- signal.c 29 Apr 2003 18:30:33 -0000 1.8 *************** *** 303,309 **** xthal_validate_cp(i); xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i); xthal_invalidate_cp(i); ! /* I think this is unnecessary; we're not switching owners. */ ! /* coproc_owners[i] = 0; */ } } --- 303,313 ---- xthal_validate_cp(i); xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i); + + /* Invalidate and "disown" the cp to allow + * callers the chance to reset cp state in the + * task_struct. */ + xthal_invalidate_cp(i); ! coproc_owners[i] = 0; } } *************** *** 323,338 **** /* XTFIXME: If a task has never used a coprocessor, there is ! no need to save and restore anything. Tracking this ! information would allow us to optimize this section. ! Perhaps we can use current->used_math or (current->flags & ! PF_USEDFPU) or define a new field in the thread ! structure. */ struct task_struct *tsk = current; flush_my_cpstate(tsk); /* Note that we just copy everything: 'extra' and 'cp' state together. */ ! if (__copy_to_user(buf, tsk->thread.cpextra, TOTAL_CPEXTRA_SIZE)) ! return -1; ! return 1; #endif } --- 327,358 ---- /* XTFIXME: If a task has never used a coprocessor, there is ! * no need to save and restore anything. Tracking this ! * information would allow us to optimize this section. ! * Perhaps we can use current->used_math or (current->flags & ! * PF_USEDFPU) or define a new field in the thread ! * structure. */ ! ! /* We flush any live, task-owned cp state to the task_struct, ! * then copy it all to the sigframe. Then we clear all ! * cp/extra state in the task_struct, effectively ! * clearing/resetting all cp/extra state for the signal ! * handler (cp-exception handling will load these new values ! * into the cp/extra registers.) This step is important for ! * things like a floating-point cp, where the OS must reset ! * the FCR to the default rounding mode. */ + int err = 0; struct task_struct *tsk = current; + flush_my_cpstate(tsk); /* Note that we just copy everything: 'extra' and 'cp' state together. */ ! err |= __copy_to_user(buf, tsk->thread.cpextra, TOTAL_CPEXTRA_SIZE); ! memset(tsk->thread.cpextra, 0, TOTAL_CPEXTRA_SIZE); ! ! #if (TOTAL_CPEXTRA_SIZE == 0) ! #error Sanity check on memset above, cpextra_size should not be zero. ! #endif ! ! return err ? -1 : 1; #endif } |