From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757249AbbE2WfP (ORCPT ); Fri, 29 May 2015 18:35:15 -0400 Received: from mga11.intel.com ([192.55.52.93]:11878 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161137AbbE2Wem (ORCPT ); Fri, 29 May 2015 18:34:42 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,519,1427785200"; d="scan'208";a="737628370" Subject: [PATCH 02/19] x86, fpu: Wrap get_xsave_addr() to make it safer To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, tglx@linutronix.de, Dave Hansen , dave.hansen@linux.intel.com, oleg@redhat.com, bp@alien8.de, riel@redhat.com, sbsiddha@gmail.com, luto@amacapital.net, mingo@redhat.com, hpa@zytor.com, fenghua.yu@intel.com From: Dave Hansen Date: Fri, 29 May 2015 15:34:55 -0700 References: <20150529223454.564C1F9E@viggo.jf.intel.com> In-Reply-To: <20150529223454.564C1F9E@viggo.jf.intel.com> Message-Id: <20150529223455.4D7C1F7E@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Hansen The MPX code appears to be saving off the FPU in a potntially unsafe way (if eagerfpu=off). It does not disable preemption or ensure that the FPU state has been allocated. All of the preemption safety comes from the unfortunatley-named 'unlazy_fpu()'. This patch introduces a new helper which will do both of those things internally. Signed-off-by: Dave Hansen Reviewed-by: Thomas Gleixner Cc: Oleg Nesterov Cc: bp@alien8.de Cc: Rik van Riel Cc: Suresh Siddha Cc: Andy Lutomirski Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Fenghua Yu Cc: the arch/x86 maintainers --- Changes from v21: * add comments about preemption * rename helper to get_xsave_field_ptr() Changes from "v19": * remove 'tsk' argument to get_xsave_addr() since the code can only realistically work on 'current', and fix up the comment a bit to match. Changes from "v17": * fix s/xstate/xsave_field/ in the function comment * remove EXPORT_SYMBOL_GPL() --- b/arch/x86/include/asm/fpu/xstate.h | 1 + b/arch/x86/kernel/fpu/xstate.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff -puN arch/x86/include/asm/fpu/xstate.h~tsk_get_xsave_addr arch/x86/include/asm/fpu/xstate.h --- a/arch/x86/include/asm/fpu/xstate.h~tsk_get_xsave_addr 2015-05-28 08:49:45.191271502 -0700 +++ b/arch/x86/include/asm/fpu/xstate.h 2015-05-29 13:43:34.291184369 -0700 @@ -41,5 +41,6 @@ extern u64 xstate_fx_sw_bytes[USER_XSTAT extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask); void *get_xsave_addr(struct xregs_state *xsave, int xstate); +const void *get_xsave_field_ptr(int xstate_field); #endif diff -puN arch/x86/kernel/fpu/xstate.c~tsk_get_xsave_addr arch/x86/kernel/fpu/xstate.c --- a/arch/x86/kernel/fpu/xstate.c~tsk_get_xsave_addr 2015-05-28 08:49:45.192271546 -0700 +++ b/arch/x86/kernel/fpu/xstate.c 2015-05-29 12:32:47.869662576 -0700 @@ -427,3 +427,35 @@ void *get_xsave_addr(struct xregs_state return (void *)xsave + xstate_comp_offsets[feature_nr]; } EXPORT_SYMBOL_GPL(get_xsave_addr); + +/* + * This wraps up the common operations that need to occur when retrieving + * data from xsave state. It first ensures that the current task was + * using the FPU and retrieves the data in to a buffer. It then calculates + * the offset of the requested field in the buffer. + * + * This function is safe to call whether the FPU is in use or not. + * + * Note that this only works on the current task. + * + * Inputs: + * @xsave_state: state which is defined in xsave.h (e.g. XSTATE_FP, + * XSTATE_SSE, etc...) + * Output: + * address of the state in the xsave area or NULL if the state + * is not present or is in its 'init state'. + */ +const void *get_xsave_field_ptr(int xsave_state) +{ + struct fpu *fpu = ¤t->thread.fpu; + + if (!fpu->fpstate_active) + return NULL; + /* + * fpu__save() takes the CPU's xstate registers + * and saves them off to the 'fpu memory buffer. + */ + fpu__save(fpu); + + return get_xsave_addr(&fpu->xstate->xsave, xsave_state); +} _