Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1109235pxb; Thu, 21 Oct 2021 16:06:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxAeDwtjRvfqAjsvsqsr1mJh7v89A1tIsyv1MI8EL1rilYVdjPKGG8vMdof4OAC9Zw9qYKI X-Received: by 2002:a17:90b:1e49:: with SMTP id pi9mr10150714pjb.144.1634857618100; Thu, 21 Oct 2021 16:06:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634857618; cv=none; d=google.com; s=arc-20160816; b=sxoyqeCsVzbZ5RSxjipGXSzbYdU/a8Zh7XBjr0/X0CVqlF0rNYYMFkJOagtSS8f3nJ KVgqWZ9XPBw/pISASwqhSBpCLJAqMOsV93w2nJSOlZdCNfX7FL0s7S5ttJ4px3bNWrfx WlF/wvVMXldhAviM+bRRGV4hn+AyC3hvMU1CLBPWPoqh1TzVWagU1eQfQBVIUGyndG27 8cu780bmCPb4FzNxnOh2VSRRV2lgIX6ZfpPR9t7ZJiDlbZBJn/8RdUvV2CSyxdJcc5zD K1pT93mbeyYSlfp8Keg5segzW47I37cgQwA5JuN2C9TW9CcbvOHCQk57FDCgz6rSTp2+ 94Qg== 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=u3u30Rh3l5Tai2DDVyNnYeqawMnMxb1VZDPQPO00lew=; b=V+nWZb648h3CBtUBx06ZDqK/ShDx6eOuCkw6Rur8U7o5rMdKJ2pz6D+cLc+H89gBHH 3p8rhY99q91x4jEixapw4/eR4tk4v7ghASyLMYN078sUcfYdJNTTYqs8pQzt73WOP0fA GuRtysrv1LRTUGJfkm66QOqaaEJoD6sB1L3pjysIQz/sT3+QZlhOcQCsXckMnqgoQxJ1 GO3IbVOvv50iutj5F4JYQ4BBH31hrUMhhNPVBCowIEH9NsrFHa/DqwCS/8zt4MATXG0x BtXQHy0HoeMQG6PxeeUYkF4y0WfIu+T/2B6Uw19wukQJYKhx34Hka6HIyH/WeT/ELfl6 i9Hg== 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 c24si11130332pgj.440.2021.10.21.16.06.45; Thu, 21 Oct 2021 16:06:58 -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 S232442AbhJUXHc (ORCPT + 99 others); Thu, 21 Oct 2021 19:07:32 -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 S232195AbhJUXHQ (ORCPT ); Thu, 21 Oct 2021 19:07:16 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10144"; a="315380040" X-IronPort-AV: E=Sophos;i="5.87,170,1631602800"; d="scan'208";a="315380040" 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="445033322" 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 09/23] x86/fpu/signal: Prepare for variable sigframe length Date: Thu, 21 Oct 2021 15:55:13 -0700 Message-Id: <20211021225527.10184-10-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 The software reserved portion of the fxsave frame in the signal frame is copied from structures which have been set up at boot time. With dynamically enabled features the content of these structures is not longer correct because the xfeatures and size can be different per task. Calculate the software reserved portion at runtime and fill in the xfeatures and size values from the tasks active fpstate. Signed-off-by: Chang S. Bae Signed-off-by: Thomas Gleixner Signed-off-by: Chang S. Bae --- arch/x86/kernel/fpu/internal.h | 3 -- arch/x86/kernel/fpu/signal.c | 62 ++++++++++++++-------------------- arch/x86/kernel/fpu/xstate.c | 1 - 3 files changed, 26 insertions(+), 40 deletions(-) diff --git a/arch/x86/kernel/fpu/internal.h b/arch/x86/kernel/fpu/internal.h index e1d8a352f12d..dbdb31f55fc7 100644 --- a/arch/x86/kernel/fpu/internal.h +++ b/arch/x86/kernel/fpu/internal.h @@ -21,9 +21,6 @@ static __always_inline __pure bool use_fxsr(void) # define WARN_ON_FPU(x) ({ (void)(x); 0; }) #endif -/* Init functions */ -extern void fpu__init_prepare_fx_sw_frame(void); - /* Used in init.c */ extern void fpstate_init_user(struct fpstate *fpstate); extern void fpstate_reset(struct fpu *fpu); diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 8554e540a871..d128eb581ffc 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -20,9 +20,6 @@ #include "legacy.h" #include "xstate.h" -static struct _fpx_sw_bytes fx_sw_reserved __ro_after_init; -static struct _fpx_sw_bytes fx_sw_reserved_ia32 __ro_after_init; - /* * Check for the presence of extended state information in the * user fpstate pointer in the sigcontext. @@ -98,23 +95,42 @@ static inline bool save_fsave_header(struct task_struct *tsk, void __user *buf) return true; } +/* + * Prepare the SW reserved portion of the fxsave memory layout, indicating + * the presence of the extended state information in the memory layout + * pointed to by the fpstate pointer in the sigcontext. + * This is saved when ever the FP and extended state context is + * saved on the user stack during the signal handler delivery to the user. + */ +static inline void save_sw_bytes(struct _fpx_sw_bytes *sw_bytes, bool ia32_frame, + struct fpstate *fpstate) +{ + sw_bytes->magic1 = FP_XSTATE_MAGIC1; + sw_bytes->extended_size = fpstate->user_size + FP_XSTATE_MAGIC2_SIZE; + sw_bytes->xfeatures = fpstate->user_xfeatures; + sw_bytes->xstate_size = fpstate->user_size; + + if (ia32_frame) + sw_bytes->extended_size += sizeof(struct fregs_state); +} + static inline bool save_xstate_epilog(void __user *buf, int ia32_frame, - unsigned int usize) + struct fpstate *fpstate) { struct xregs_state __user *x = buf; - struct _fpx_sw_bytes *sw_bytes; + struct _fpx_sw_bytes sw_bytes; u32 xfeatures; int err; /* Setup the bytes not touched by the [f]xsave and reserved for SW. */ - sw_bytes = ia32_frame ? &fx_sw_reserved_ia32 : &fx_sw_reserved; - err = __copy_to_user(&x->i387.sw_reserved, sw_bytes, sizeof(*sw_bytes)); + save_sw_bytes(&sw_bytes, ia32_frame, fpstate); + err = __copy_to_user(&x->i387.sw_reserved, &sw_bytes, sizeof(sw_bytes)); if (!use_xsave()) return !err; err |= __put_user(FP_XSTATE_MAGIC2, - (__u32 __user *)(buf + usize)); + (__u32 __user *)(buf + fpstate->user_size)); /* * Read the xfeatures which we copied (directly from the cpu or @@ -173,7 +189,7 @@ bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) { struct task_struct *tsk = current; struct fpstate *fpstate = tsk->thread.fpu.fpstate; - int ia32_fxstate = (buf != buf_fx); + bool ia32_fxstate = (buf != buf_fx); int ret; ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) || @@ -226,8 +242,7 @@ bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) if ((ia32_fxstate || !use_fxsr()) && !save_fsave_header(tsk, buf)) return false; - if (use_fxsr() && - !save_xstate_epilog(buf_fx, ia32_fxstate, fpstate->user_size)) + if (use_fxsr() && !save_xstate_epilog(buf_fx, ia32_fxstate, fpstate)) return false; return true; @@ -523,28 +538,3 @@ unsigned long __init fpu__get_fpstate_size(void) return ret; } -/* - * Prepare the SW reserved portion of the fxsave memory layout, indicating - * the presence of the extended state information in the memory layout - * pointed by the fpstate pointer in the sigcontext. - * This will be saved when ever the FP and extended state context is - * saved on the user stack during the signal handler delivery to the user. - */ -void __init fpu__init_prepare_fx_sw_frame(void) -{ - int size = fpu_user_cfg.default_size + FP_XSTATE_MAGIC2_SIZE; - - fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1; - fx_sw_reserved.extended_size = size; - fx_sw_reserved.xfeatures = fpu_user_cfg.default_features; - fx_sw_reserved.xstate_size = fpu_user_cfg.default_size; - - if (IS_ENABLED(CONFIG_IA32_EMULATION) || - IS_ENABLED(CONFIG_X86_32)) { - int fsave_header_size = sizeof(struct fregs_state); - - fx_sw_reserved_ia32 = fx_sw_reserved; - fx_sw_reserved_ia32.extended_size = size + fsave_header_size; - } -} - diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index c79ca3d430c4..c178aa91abb3 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -830,7 +830,6 @@ void __init fpu__init_system_xstate(unsigned int legacy_size) update_regset_xstate_info(fpu_user_cfg.max_size, fpu_user_cfg.max_features); - fpu__init_prepare_fx_sw_frame(); setup_init_fpu_buf(); setup_xstate_comp_offsets(); setup_supervisor_only_offsets(); -- 2.17.1