diff options
author | Huacai Chen <chenhuacai@loongson.cn> | 2022-11-21 14:02:57 +0300 |
---|---|---|
committer | Huacai Chen <chenhuacai@loongson.cn> | 2022-11-21 14:02:57 +0300 |
commit | e428e9613531d1ef6bd0d91352899712b29134fb (patch) | |
tree | dfa28b595a5edef206d7d2dd462f949ac7622b0e /arch/loongarch | |
parent | c56ab8e85d6de5c2c5ba37e7a5698b2eb0c80ef5 (diff) | |
download | linux-e428e9613531d1ef6bd0d91352899712b29134fb.tar.xz |
LoongArch: Clear FPU/SIMD thread info flags for kernel thread
If a kernel thread is created by a user thread, it may carry FPU/SIMD
thread info flags (TIF_USEDFPU, TIF_USEDSIMD, etc.). Then it will be
considered as a fpu owner and kernel try to save its FPU/SIMD context
and cause such errors:
[ 41.518931] do_fpu invoked from kernel context![#1]:
[ 41.523933] CPU: 1 PID: 395 Comm: iou-wrk-394 Not tainted 6.1.0-rc5+ #217
[ 41.530757] Hardware name: Loongson Loongson-3A5000-7A1000-1w-CRB/Loongson-LS3A5000-7A1000-1w-CRB, BIOS vUDK2018-LoongArch-V2.0.pre-beta8 08/18/2022
[ 41.544064] $ 0 : 0000000000000000 90000000011e9468 9000000106c7c000 9000000106c7fcf0
[ 41.552101] $ 4 : 9000000106305d40 9000000106689800 9000000106c7fd08 0000000003995818
[ 41.560138] $ 8 : 0000000000000001 90000000009a72e4 0000000000000020 fffffffffffffffc
[ 41.568174] $12 : 0000000000000000 0000000000000000 0000000000000020 00000009aab7e130
[ 41.576211] $16 : 00000000000001ff 0000000000000407 0000000000000001 0000000000000000
[ 41.584247] $20 : 0000000000000000 0000000000000001 9000000106c7fd70 90000001002f0400
[ 41.592284] $24 : 0000000000000000 900000000178f740 90000000011e9834 90000001063057c0
[ 41.600320] $28 : 0000000000000000 0000000000000001 9000000006826b40 9000000106305140
[ 41.608356] era : 9000000000228848 _save_fp+0x0/0xd8
[ 41.613542] ra : 90000000011e9468 __schedule+0x568/0x8d0
[ 41.619160] CSR crmd: 000000b0
[ 41.619163] CSR prmd: 00000000
[ 41.622359] CSR euen: 00000000
[ 41.625558] CSR ecfg: 00071c1c
[ 41.628756] CSR estat: 000f0000
[ 41.635239] ExcCode : f (SubCode 0)
[ 41.638783] PrId : 0014c010 (Loongson-64bit)
[ 41.643191] Modules linked in: acpi_ipmi vfat fat ipmi_si ipmi_devintf cfg80211 ipmi_msghandler rfkill fuse efivarfs
[ 41.653734] Process iou-wrk-394 (pid: 395, threadinfo=0000000004ebe913, task=00000000636fa1be)
[ 41.662375] Stack : 00000000ffff0875 9000000006800ec0 9000000006800ec0 90000000002d57e0
[ 41.670412] 0000000000000001 0000000000000000 9000000106535880 0000000000000001
[ 41.678450] 9000000105291800 0000000000000000 9000000105291838 900000000178e000
[ 41.686487] 9000000106c7fd90 9000000106305140 0000000000000001 90000000011e9834
[ 41.694523] 00000000ffff0875 90000000011f034c 9000000105291838 9000000105291830
[ 41.702561] 0000000000000000 9000000006801440 00000000ffff0875 90000000002d48c0
[ 41.710597] 9000000128800001 9000000106305140 9000000105291838 9000000105291838
[ 41.718634] 9000000105291830 9000000107811740 9000000105291848 90000000009bf1e0
[ 41.726672] 9000000105291830 9000000107811748 2d6b72772d756f69 0000000000343933
[ 41.734708] 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[ 41.742745] ...
[ 41.745252] Call Trace:
[ 42.197868] [<9000000000228848>] _save_fp+0x0/0xd8
[ 42.205214] [<90000000011ed468>] __schedule+0x568/0x8d0
[ 42.210485] [<90000000011ed834>] schedule+0x64/0xd4
[ 42.215411] [<90000000011f434c>] schedule_timeout+0x88/0x188
[ 42.221115] [<90000000009c36d0>] io_wqe_worker+0x184/0x350
[ 42.226645] [<9000000000221cf0>] ret_from_kernel_thread+0xc/0x9c
This can be easily triggered by ltp testcase syscalls/io_uring02 and it
can also be easily fixed by clearing the FPU/SIMD thread info flags for
kernel threads in copy_thread().
Cc: stable@vger.kernel.org
Reported-by: Qi Hu <huqi@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch/loongarch')
-rw-r--r-- | arch/loongarch/kernel/process.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c index 2526b68f1c0f..ddb8ba4eb399 100644 --- a/arch/loongarch/kernel/process.c +++ b/arch/loongarch/kernel/process.c @@ -152,7 +152,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) childregs->csr_crmd = p->thread.csr_crmd; childregs->csr_prmd = p->thread.csr_prmd; childregs->csr_ecfg = p->thread.csr_ecfg; - return 0; + goto out; } /* user thread */ @@ -171,14 +171,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) */ childregs->csr_euen = 0; + if (clone_flags & CLONE_SETTLS) + childregs->regs[2] = tls; + +out: clear_tsk_thread_flag(p, TIF_USEDFPU); clear_tsk_thread_flag(p, TIF_USEDSIMD); clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE); clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE); - if (clone_flags & CLONE_SETTLS) - childregs->regs[2] = tls; - return 0; } |