Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756735AbcCUQQQ (ORCPT ); Mon, 21 Mar 2016 12:16:16 -0400 Received: from mga11.intel.com ([192.55.52.93]:42805 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751332AbcCUQQO (ORCPT ); Mon, 21 Mar 2016 12:16:14 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,372,1455004800"; d="scan'208";a="915706559" From: Andi Kleen To: x86@kernel.org Cc: luto@amacapital.net, linux-kernel@vger.kernel.org, Andi Kleen Subject: [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Date: Mon, 21 Mar 2016 09:16:04 -0700 Message-Id: <1458576969-13309-5-git-send-email-andi@firstfloor.org> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1458576969-13309-1-git-send-email-andi@firstfloor.org> References: <1458576969-13309-1-git-send-email-andi@firstfloor.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3232 Lines: 97 From: Andi Kleen The kernel needs to explicitely enable RD/WRFSBASE to handle context switch correctly. So the application needs to know if it can safely use these instruction. Just looking at the CPUID bit is not enough because it may be running in a kernel that does not enable the instructions. One way for the application would be to just try and catch the SIGILL. But that is difficult to do in libraries which may not want to overwrite the signal handlers of the main application. So we need to provide a way for the application to discover the kernel capability. I used AT_HWCAP2 in the ELF aux vector which is already used by PPC for similar things. We define a new Linux defined bitmap returned in AT_HWCAP. Currently it has only one bit set, for kernel is FSGSBASE capable. The application can then access it manually or using the getauxval() function in newer glibc. v2: Rename things. Signed-off-by: Andi Kleen --- arch/x86/include/asm/elf.h | 7 +++++++ arch/x86/include/uapi/asm/hwcap.h | 7 +++++++ arch/x86/kernel/cpu/common.c | 7 ++++++- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/uapi/asm/hwcap.h diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 15340e3..0df9c95 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -258,6 +258,13 @@ extern int force_personality32; #define ELF_HWCAP (boot_cpu_data.x86_capability[CPUID_1_EDX]) +extern unsigned elf_hwcap2; + +/* HWCAP2 supplies kernel enabled CPU feature, so that the application + can know that it can safely use them. The bits are defined in + uapi/asm/hwcap.h. */ +#define ELF_HWCAP2 elf_hwcap2 + /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in intent than poking at uname or /proc/cpuinfo. diff --git a/arch/x86/include/uapi/asm/hwcap.h b/arch/x86/include/uapi/asm/hwcap.h new file mode 100644 index 0000000..d9c54f8 --- /dev/null +++ b/arch/x86/include/uapi/asm/hwcap.h @@ -0,0 +1,7 @@ +#ifndef _ASM_HWCAP_H +#define _ASM_HWCAP_H 1 + +#define HWCAP2_FSGSBASE (1 << 0) /* Kernel enabled RD/WR FS/GS BASE */ +/* upto bit 31 free */ + +#endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f581cd1..b022f31 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,8 @@ #include "cpu.h" +unsigned elf_hwcap2 __read_mostly; + /* all of these masks are initialized in setup_cpu_local_masks() */ cpumask_var_t cpu_initialized_mask; cpumask_var_t cpu_callout_mask; @@ -1019,8 +1022,10 @@ static void identify_cpu(struct cpuinfo_x86 *c) /* The boot/hotplug time assigment got cleared, restore it */ c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id); - if (cpu_has(c, X86_FEATURE_FSGSBASE)) + if (cpu_has(c, X86_FEATURE_FSGSBASE)) { + elf_hwcap2 |= HWCAP2_FSGSBASE; cr4_set_bits(X86_CR4_FSGSBASE); + } } /* -- 2.5.5