Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1361970 > unrolled thread

[PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2

Started byAndi Kleen <andi@firstfloor.org>
First post2016-03-21 17:20 +0100
Last post2016-03-21 20:50 +0100
Articles 6 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Andi Kleen <andi@firstfloor.org> - 2016-03-21 17:20 +0100
    Re: [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Brian Gerst <brgerst@gmail.com> - 2016-03-21 20:40 +0100
      Re: [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Andi Kleen <andi@firstfloor.org> - 2016-03-21 20:50 +0100
        Re: [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Andy Lutomirski <luto@amacapital.net> - 2016-03-21 23:20 +0100
    Re: [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Andi Kleen <andi@firstfloor.org> - 2016-03-21 20:40 +0100
    Re: [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2 Brian Gerst <brgerst@gmail.com> - 2016-03-21 20:50 +0100

#1361970 — [PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2

FromAndi Kleen <andi@firstfloor.org>
Date2016-03-21 17:20 +0100
Subject[PATCH 4/9] x86: Enumerate kernel FSGS capability in AT_HWCAP2
Message-ID<rfaIG-8aj-23@gated-at.bofh.it>
From: Andi Kleen <ak@linux.intel.com>

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 <ak@linux.intel.com>
---
 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 <asm/desc.h>
 #include <asm/fpu/internal.h>
 #include <asm/mtrr.h>
+#include <asm/hwcap.h>
 #include <linux/numa.h>
 #include <asm/asm.h>
 #include <asm/cpu.h>
@@ -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

[toc] | [next] | [standalone]


#1362103

FromBrian Gerst <brgerst@gmail.com>
Date2016-03-21 20:40 +0100
Message-ID<rfdQe-1Ku-13@gated-at.bofh.it>
In reply to#1361970
On Mon, Mar 21, 2016 at 2:54 PM, Andi Kleen <andi@firstfloor.org> wrote:
> On Mon, Mar 21, 2016 at 02:49:44PM -0400, Brian Gerst wrote:
>> On Mon, Mar 21, 2016 at 12:16 PM, Andi Kleen <andi@firstfloor.org> wrote:
>> > From: Andi Kleen <ak@linux.intel.com>
>> >
>> > 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.
>>
>> How about adding a VDSO function instead?  The VDSO can use
>> alternatives, so it can use the new instructions if supported, or else
>> use the old syscall.
>
> What would be the point of that?
>
> It would be a lot more complicated, and I don't see any advantages
> over the aux vector. vdso also requires custom assembler
> stubs in the C library.
>
> -Andi

It would be less complicated actually, as normal userspace would just
continue to call arch_prctl() as it does today.  Glibc would implement
arch_prctl() just like it does with gettimeofday() -- with an ifunc
selector [1] that calls the VDSO function if it is available, or the
syscall if not.  No custom assembly needed.

[1] https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86/gettimeofday.c;h=36f7c26ffb0e818709d032c605fec8c4bd22a14e;hb=HEAD

--
Brian Gerst

[toc] | [prev] | [next] | [standalone]


#1362121

FromAndi Kleen <andi@firstfloor.org>
Date2016-03-21 20:50 +0100
Message-ID<rfdZV-1O7-23@gated-at.bofh.it>
In reply to#1362103
> It would be less complicated actually, as normal userspace would just
> continue to call arch_prctl() as it does today.  Glibc would implement

We already have that through the system call, no advantage of
putting it into a vsyscall.

Also the experience with getcpu and similar so far is that
vsyscalls are too slow for the users who want really fast paths.
So they're prefer to use the direct instructions anyways.

> arch_prctl() just like it does with gettimeofday() -- with an ifunc
> selector [1] that calls the VDSO function if it is available, or the
> syscall if not.  No custom assembly needed.

vdso always needs custom assembler, please see how glibc implements it.

-Andi

[toc] | [prev] | [next] | [standalone]


#1362176

FromAndy Lutomirski <luto@amacapital.net>
Date2016-03-21 23:20 +0100
Message-ID<rfgl4-3uK-11@gated-at.bofh.it>
In reply to#1362121
On Mar 21, 2016 12:43 PM, "Andi Kleen" <andi@firstfloor.org> wrote:
>
> > It would be less complicated actually, as normal userspace would just
> > continue to call arch_prctl() as it does today.  Glibc would implement
>
> We already have that through the system call, no advantage of
> putting it into a vsyscall.
>
> Also the experience with getcpu and similar so far is that
> vsyscalls are too slow for the users who want really fast paths.
> So they're prefer to use the direct instructions anyways.

Getcpu is mainly slow because the overcomplicated API requires
branches.  I've been tempted to add __vdso_get_cpu as an alternative
that simply returns the CPU number.

>
> > arch_prctl() just like it does with gettimeofday() -- with an ifunc
> > selector [1] that calls the VDSO function if it is available, or the
> > syscall if not.  No custom assembly needed.
>
> vdso always needs custom assembler, please see how glibc implements it.

This is simply not true.

I haven't checked the glibc implementation, and I wouldn't be remotely
surprised if it is maliciously incomprehensible, but there is no
reason whatsoever that using any vdso mechanism other than AT_SYSINFO
itself requires assembler.  AT_SYSINFO, of course, requires assembler
because the calling convention is weird.

--Andy

[toc] | [prev] | [next] | [standalone]


#1362107

FromAndi Kleen <andi@firstfloor.org>
Date2016-03-21 20:40 +0100
Message-ID<rfdQe-1Ku-17@gated-at.bofh.it>
In reply to#1361970
On Mon, Mar 21, 2016 at 02:49:44PM -0400, Brian Gerst wrote:
> On Mon, Mar 21, 2016 at 12:16 PM, Andi Kleen <andi@firstfloor.org> wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> >
> > 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.
> 
> How about adding a VDSO function instead?  The VDSO can use
> alternatives, so it can use the new instructions if supported, or else
> use the old syscall.

What would be the point of that?

It would be a lot more complicated, and I don't see any advantages
over the aux vector. vdso also requires custom assembler 
stubs in the C library.

-Andi

[toc] | [prev] | [next] | [standalone]


#1362117

FromBrian Gerst <brgerst@gmail.com>
Date2016-03-21 20:50 +0100
Message-ID<rfdQe-1Ku-15@gated-at.bofh.it>
In reply to#1361970
On Mon, Mar 21, 2016 at 12:16 PM, Andi Kleen <andi@firstfloor.org> wrote:
> From: Andi Kleen <ak@linux.intel.com>
>
> 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.

How about adding a VDSO function instead?  The VDSO can use
alternatives, so it can use the new instructions if supported, or else
use the old syscall.

--
Brian Gerst

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web