condvar: Fix a user-after-free in _cv_wait() when ktrace is enabled
When a thread wakes up after sleeping on a CV, it must not dereference
the CV structure, as it may already have been freed. At least ZFS
relies on this invariant, see commit
c636f94bd2ff15be5b904939872b4bce31456c18 for example.
Thus, when logging context-switch events, copy the wmesg into a stack
buffer while it is still safe to do so, and log that after waking up.
While here, move the initial ktrcsw() call later, after assertions and
the SCHEDULER_STOPPED_TD() condition are checked.
Reported by: syzkaller
Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D43450
(cherry picked from commit a5ef95cd228e43bcc459a5c8a9911e57888ba5fd)