Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1109352pxb; Thu, 21 Oct 2021 16:07:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyV6MEvD1ZREMchopJLEB8MmGksshEItWExq8rveeWfnpP0nM+uB0M9ueu6CW+Ly8BjpGfh X-Received: by 2002:a05:6a00:cce:b0:44c:af88:eb00 with SMTP id b14-20020a056a000cce00b0044caf88eb00mr8422377pfv.45.1634857625351; Thu, 21 Oct 2021 16:07:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634857625; cv=none; d=google.com; s=arc-20160816; b=YqctPALIuOsfeLzrNh1byJI1Ku3T3hkA5Th8zt/2RPeYY4ZWEVYE3FIISCg0d1XFvS s7GHJ7c9V/RVbGpdQTJSX02Zb+0buNWlAjCAhX7ocVhhAcvwv788JURLpMjdjkX43AeS 9DOV62bKc7YM3siDkCOFC1Tgy/j32Qn0fHHvzxJ+QAJy95m0kacY3DHl6+qMlSJiCUeg mijSJ1QH6qSDvtrsTwkqxXtd+Luy3yS53zejHxqLK/A0e3/OBBRie/eEhc7J4QJSeKCW fcEIpyVVNpfglCcNMh9DZtbix6s5xlJ2TdHg0fGL3AmSBCh1rqhv3PEjgbW/NKfisPWZ xg5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from; bh=h5etOtOUVhA6zK4pr6kv6yc/6JFJDuZ5dxvjXFfgHPs=; b=AmC6HRZ6hmOoR/qZZbvMRt15jru0B5Q+j1jWCnNYbPMM0XdarpaCf1UzRv+qgY2VEj m3wXF8t9aIi7nCyDKDHby1WwQowRmDS37aNwuy93mVoSb28a0KI5/f1gwVhVE4KZN1qP e9/FL1C9A9OsXb7iST3iXDrpF/Y+ehgQrOUjWEH+vpcYQskTSafeq8nBu/6Q+C5qV8mL 1OQP/DEZzDpFPCZcup2wLJioj6Js8mJd6O5tci9/FPE7p83QtE1Is5htVZbvNCUojt4z WqqIiZB8wyK8K8rf8paE4/MZyyUCXbl4wFu/jKqZZ3mgVRr6rVkM44AFIB49URD65PV0 Tl1g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u6si10705204plf.76.2021.10.21.16.06.53; Thu, 21 Oct 2021 16:07:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232458AbhJUXHf (ORCPT + 99 others); Thu, 21 Oct 2021 19:07:35 -0400 Received: from mga05.intel.com ([192.55.52.43]:58072 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231206AbhJUXHR (ORCPT ); Thu, 21 Oct 2021 19:07:17 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10144"; a="315380045" X-IronPort-AV: E=Sophos;i="5.87,170,1631602800"; d="scan'208";a="315380045" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 16:02:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,170,1631602800"; d="scan'208";a="445033338" Received: from chang-linux-3.sc.intel.com ([172.25.66.175]) by orsmga006.jf.intel.com with ESMTP; 21 Oct 2021 16:02:23 -0700 From: "Chang S. Bae" To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@linutronix.de, dave.hansen@linux.intel.com, arjan@linux.intel.com, ravi.v.shankar@intel.com, chang.seok.bae@intel.com Subject: [PATCH 10/23] x86/fpu: Prepare fpu_clone() for dynamically enabled features Date: Thu, 21 Oct 2021 15:55:14 -0700 Message-Id: <20211021225527.10184-11-chang.seok.bae@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211021225527.10184-1-chang.seok.bae@intel.com> References: <20211021225527.10184-1-chang.seok.bae@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Gleixner The default portion of the parent's FPU state is saved in a child task. With dynamic features enabled, the non-default portion is not saved in a child's fpstate because these register states are defined to be caller-saved. The new task's fpstate is therefore the default buffer. Fork inherits the permission of the parent. Also, do not use memcpy() when TIF_NEED_FPU_LOAD is set because it is invalid when the parent has dynamic features. Signed-off-by: Thomas Gleixner Signed-off-by: Chang S. Bae --- Changes from the tglx tree: * Add the changelog. * Update comments. (Dave Hansen) --- arch/x86/include/asm/fpu/sched.h | 2 +- arch/x86/kernel/fpu/core.c | 35 +++++++++++++++++++++++--------- arch/x86/kernel/process.c | 2 +- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/fpu/sched.h b/arch/x86/include/asm/fpu/sched.h index cdb78d590c86..99a8820e8cc4 100644 --- a/arch/x86/include/asm/fpu/sched.h +++ b/arch/x86/include/asm/fpu/sched.h @@ -11,7 +11,7 @@ extern void save_fpregs_to_fpstate(struct fpu *fpu); extern void fpu__drop(struct fpu *fpu); -extern int fpu_clone(struct task_struct *dst); +extern int fpu_clone(struct task_struct *dst, unsigned long clone_flags); extern void fpu_flush_thread(void); /* diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index ff7d239fe961..177f27687261 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -426,8 +426,20 @@ void fpstate_reset(struct fpu *fpu) fpu->perm.__user_state_size = fpu_user_cfg.default_size; } +static inline void fpu_inherit_perms(struct fpu *dst_fpu) +{ + if (fpu_state_size_dynamic()) { + struct fpu *src_fpu = ¤t->group_leader->thread.fpu; + + spin_lock_irq(¤t->sighand->siglock); + /* Fork also inherits the permissions of the parent */ + dst_fpu->perm = src_fpu->perm; + spin_unlock_irq(¤t->sighand->siglock); + } +} + /* Clone current's FPU state on fork */ -int fpu_clone(struct task_struct *dst) +int fpu_clone(struct task_struct *dst, unsigned long clone_flags) { struct fpu *src_fpu = ¤t->thread.fpu; struct fpu *dst_fpu = &dst->thread.fpu; @@ -458,17 +470,20 @@ int fpu_clone(struct task_struct *dst) } /* - * If the FPU registers are not owned by current just memcpy() the - * state. Otherwise save the FPU registers directly into the - * child's FPU context, without any memory-to-memory copying. + * Save the default portion of the current FPU state into the + * clone. Assume all dynamic features to be defined as caller- + * saved, which enables skipping both the expansion of fpstate + * and the copying of any dynamic state. + * + * Do not use memcpy() when TIF_NEED_FPU_LOAD is set because + * copying is not valid when current uses non-default states. */ fpregs_lock(); - if (test_thread_flag(TIF_NEED_FPU_LOAD)) { - memcpy(&dst_fpu->fpstate->regs, &src_fpu->fpstate->regs, - dst_fpu->fpstate->size); - } else { - save_fpregs_to_fpstate(dst_fpu); - } + if (test_thread_flag(TIF_NEED_FPU_LOAD)) + fpregs_restore_userregs(); + save_fpregs_to_fpstate(dst_fpu); + if (!(clone_flags & CLONE_THREAD)) + fpu_inherit_perms(dst_fpu); fpregs_unlock(); trace_x86_fpu_copy_src(src_fpu); diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 97fea1649a5e..99025e32f105 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -157,7 +157,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, frame->flags = X86_EFLAGS_FIXED; #endif - fpu_clone(p); + fpu_clone(p, clone_flags); /* Kernel thread ? */ if (unlikely(p->flags & PF_KTHREAD)) { -- 2.17.1