From 1b0a4974c5004216daf4a2ac4375074ce56bc55b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 7 Aug 2022 20:00:02 +0300 Subject: [PATCH] thread_create(): call cpu_copy_thread() after td_pflags is zeroed By calling the function too early we might still have the td_pflags value cached from the previous struct thread use. cpu_copy_thread() depends on correct value for TDP_KTHREAD at least on x86. Reported, bisected, and tested by: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D36069 --- sys/compat/linux/linux_fork.c | 4 ++-- sys/kern/kern_thr.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c index 31d8344ce032..7654e447f878 100644 --- a/sys/compat/linux/linux_fork.c +++ b/sys/compat/linux/linux_fork.c @@ -280,8 +280,6 @@ linux_clone_thread(struct thread *td, struct l_clone_args *args) if (error) goto fail; - cpu_copy_thread(newtd, td); - bzero(&newtd->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); bcopy(&td->td_startcopy, &newtd->td_startcopy, @@ -290,6 +288,8 @@ linux_clone_thread(struct thread *td, struct l_clone_args *args) newtd->td_proc = p; thread_cow_get(newtd, td); + cpu_copy_thread(newtd, td); + /* create the emuldata */ linux_proc_init(td, newtd, true); diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 2f44c5304471..4c0cfe06f1b4 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -231,8 +231,6 @@ thread_create(struct thread *td, struct rtprio *rtp, if (error) goto fail; - cpu_copy_thread(newtd, td); - bzero(&newtd->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); bcopy(&td->td_startcopy, &newtd->td_startcopy, @@ -241,6 +239,8 @@ thread_create(struct thread *td, struct rtprio *rtp, newtd->td_rb_list = newtd->td_rbp_list = newtd->td_rb_inact = 0; thread_cow_get(newtd, td); + cpu_copy_thread(newtd, td); + error = initialize_thread(newtd, thunk); if (error != 0) { thread_cow_free(newtd);