git: 1b0a4974c500 - main - thread_create(): call cpu_copy_thread() after td_pflags is zeroed

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 08 Aug 2022 16:44:38 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1b0a4974c5004216daf4a2ac4375074ce56bc55b

commit 1b0a4974c5004216daf4a2ac4375074ce56bc55b
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-08-07 17:00:02 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-08-08 16:44:17 +0000

    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);