Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758017AbbEEWPb (ORCPT ); Tue, 5 May 2015 18:15:31 -0400 Received: from mga03.intel.com ([134.134.136.65]:2932 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758001AbbEEWPZ convert rfc822-to-8bit (ORCPT ); Tue, 5 May 2015 18:15:25 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,375,1427785200"; d="scan'208";a="690454991" From: "Yu, Fenghua" To: Ingo Molnar , "linux-kernel@vger.kernel.org" CC: Andy Lutomirski , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Linus Torvalds , Oleg Nesterov , Thomas Gleixner Subject: RE: [PATCH 151/208] x86/fpu: Introduce cpu_has_xfeatures(xfeatures_mask, feature_name) Thread-Topic: [PATCH 151/208] x86/fpu: Introduce cpu_has_xfeatures(xfeatures_mask, feature_name) Thread-Index: AQHQh1x9hue+JyIb70CiSALrhHy7pp1t8g+A Date: Tue, 5 May 2015 22:15:18 +0000 Message-ID: <3E5A0FA7E9CA944F9D5414FEC6C712205C8D620C@ORSMSX106.amr.corp.intel.com> References: <1430848300-27877-1-git-send-email-mingo@kernel.org> <1430848300-27877-73-git-send-email-mingo@kernel.org> In-Reply-To: <1430848300-27877-73-git-send-email-mingo@kernel.org> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.138] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4982 Lines: 146 > From: Ingo Molnar [mailto:mingo.kernel.org@gmail.com] On Behalf Of Ingo > Molnar > Sent: Tuesday, May 05, 2015 10:51 AM > To: linux-kernel@vger.kernel.org > Cc: Andy Lutomirski; Borislav Petkov; Dave Hansen; Yu, Fenghua; H. Peter > Anvin; Linus Torvalds; Oleg Nesterov; Thomas Gleixner > Subject: [PATCH 151/208] x86/fpu: Introduce > cpu_has_xfeatures(xfeatures_mask, feature_name) > > A lot of FPU using driver code is querying complex CPU features to be able to > figure out whether a given set of xstate features is supported by the CPU or > not. > > Introduce a simplified API function that can be used on any CPU type to get > this information. Also add an error string return pointer, so that the driver > can print a meaningful error message with a standardized feature name. > > Also mark xfeatures_mask as __read_only. > > Cc: Andy Lutomirski > Cc: Borislav Petkov > Cc: Dave Hansen > Cc: Fenghua Yu > Cc: H. Peter Anvin > Cc: Linus Torvalds > Cc: Oleg Nesterov > Cc: Thomas Gleixner > Signed-off-by: Ingo Molnar > --- > arch/x86/include/asm/fpu/api.h | 9 +++++++++ > arch/x86/kernel/fpu/xstate.c | 53 > ++++++++++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 61 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/fpu/api.h > b/arch/x86/include/asm/fpu/api.h index 62035cc1d961..1429a7c736db > 100644 > --- a/arch/x86/include/asm/fpu/api.h > +++ b/arch/x86/include/asm/fpu/api.h > @@ -36,4 +36,13 @@ extern bool irq_fpu_usable(void); extern int > irq_ts_save(void); extern void irq_ts_restore(int TS_state); > > +/* > + * Query the presence of one or more xfeatures. Works on any legacy CPU > as well. > + * > + * If 'feature_name' is set then put a human-readable description of > + * the feature there as well - this can be used to print error (or > +success) > + * messages. > + */ > +extern int cpu_has_xfeatures(u64 xfeatures_mask, const char > +**feature_name); > + > #endif /* _ASM_X86_FPU_API_H */ > diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c > index f549e2a44336..2e52f01f4931 100644 > --- a/arch/x86/kernel/fpu/xstate.c > +++ b/arch/x86/kernel/fpu/xstate.c > @@ -11,10 +11,23 @@ > #include > #include > > +static const char *xfeature_names[] = > +{ > + "x87 floating point registers" , > + "SSE registers" , > + "AVX registers" , > + "MPX bounds registers" , > + "MPX CSR" , > + "AVX-512 opmask" , > + "AVX-512 Hi256" , > + "AVX-512 ZMM_Hi256" , > + "unknown xstate feature" , > +}; > + > /* > * Mask of xstate features supported by the CPU and the kernel: > */ > -u64 xfeatures_mask; > +u64 xfeatures_mask __read_mostly; > > /* > * Represents init state for the supported extended state. > @@ -29,6 +42,44 @@ static unsigned int > xstate_comp_offsets[sizeof(xfeatures_mask)*8]; > static unsigned int xfeatures_nr; > > /* > + * Return whether the system supports a given xfeature. > + * > + * Also return the name of the (most advanced) feature that the caller > requested: > + */ > +int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name) > +{ > + u64 xfeatures_missing = xfeatures_needed & ~xfeatures_mask; > + > + if (unlikely(feature_name)) { > + long xfeature_idx, max_idx; > + u64 xfeatures_print; > + /* > + * So we use FLS here to be able to print the most advanced > + * feature that was requested but is missing. So if a driver > + * asks about "XSTATE_SSE | XSTATE_YMM" we'll print the > + * missing AVX feature - this is the most informative message > + * to users: > + */ > + if (xfeatures_missing) > + xfeatures_print = xfeatures_missing; If the feature is missing (xfeatures_missing!=0), the xfeature_name will point to the next feature name with the higher idx in xfeatures_mask. Is that supposed to be? I think the "if (xfeatures_missing)" and " xfeatures_print = xfeatures_missing;" are not needed, right? > + else > + xfeatures_print = xfeatures_needed; > + > + xfeature_idx = fls64(xfeatures_print)-1; > + max_idx = ARRAY_SIZE(xfeature_names)-1; > + xfeature_idx = min(xfeature_idx, max_idx); > + > + *feature_name = xfeature_names[xfeature_idx]; > + } > + > + if (xfeatures_missing) > + return 0; > + > + return 1; > +} > +EXPORT_SYMBOL_GPL(cpu_has_xfeatures); > + > +/* > * When executing XSAVEOPT (optimized XSAVE), if a processor > implementation > * detects that an FPU state component is still (or is again) in its > * initialized state, it may clear the corresponding bit in the header.xfeatures > -- > 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/