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


Groups > linux.kernel > #1311015 > unrolled thread

[PATCH] x86: static_cpu_has_safe: discard dynamic check after init

Started byBrian Gerst <brgerst@gmail.com>
First post2016-01-16 20:30 +0100
Last post2016-01-20 17:20 +0100
Articles 20 on this page of 42 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Brian Gerst <brgerst@gmail.com> - 2016-01-16 20:30 +0100
    Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-16 20:40 +0100
      Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Brian Gerst <brgerst@gmail.com> - 2016-01-16 21:00 +0100
        Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-17 11:40 +0100
          Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Brian Gerst <brgerst@gmail.com> - 2016-01-18 18:00 +0100
            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Andy Lutomirski <luto@amacapital.net> - 2016-01-18 18:50 +0100
            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-18 19:20 +0100
              Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Andy Lutomirski <luto@amacapital.net> - 2016-01-18 19:30 +0100
                Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-18 19:40 +0100
                  Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-18 20:50 +0100
                    Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-19 00:10 +0100
                      Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-19 00:20 +0100
                        Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-19 00:30 +0100
                          Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-19 15:00 +0100
                            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-19 17:30 +0100
                            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-20 00:20 +0100
                              Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Andy Lutomirski <luto@amacapital.net> - 2016-01-20 00:30 +0100
                                Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Boris Petkov <bp@suse.de> - 2016-01-20 01:00 +0100
                            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 05:10 +0100
                              Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-20 11:40 +0100
                                Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 11:50 +0100
                                  Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-21 23:20 +0100
                                    Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-21 23:30 +0100
                                      Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-22 00:00 +0100
                                        Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-22 00:40 +0100
                                        Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-22 00:40 +0100
                                          Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-22 11:40 +0100
              Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-18 20:00 +0100
                Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-19 02:20 +0100
                  Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-19 02:40 +0100
                    Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-19 10:30 +0100
                      Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 05:10 +0100
                        Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Brian Gerst <brgerst@gmail.com> - 2016-01-20 05:40 +0100
                          Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 05:50 +0100
                            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 12:00 +0100
                              Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-20 12:10 +0100
                                Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 15:50 +0100
                            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-20 12:00 +0100
                        Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-20 16:10 +0100
                          Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 16:20 +0100
                            Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init Borislav Petkov <bp@suse.de> - 2016-01-20 17:10 +0100
                              Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after  init "H. Peter Anvin" <hpa@zytor.com> - 2016-01-20 17:20 +0100

Page 1 of 3  [1] 2 3  Next page →


#1311015 — [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBrian Gerst <brgerst@gmail.com>
Date2016-01-16 20:30 +0100
Subject[PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qREHU-i0-3@gated-at.bofh.it>
Move the code to do the dynamic check to the init text section so that it
is discarded after alternatives have run and a static branch has been
chosen.

A new section is defined to avoid warnings with modpost due to references
to init text from main text, which in this case is legitimate.  All such
references are patched out before init mem is discarded.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
---
 arch/x86/include/asm/cpufeature.h | 33 ++++++++++++++++++++++-----------
 arch/x86/kernel/cpu/common.c      |  6 ------
 arch/x86/kernel/vmlinux.lds.S     |  6 ++++++
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 7ad8c94..2efbd83 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -412,7 +412,6 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
 
 #if __GNUC__ >= 4 && defined(CONFIG_X86_FAST_FEATURE_TESTS)
 extern void warn_pre_alternatives(void);
-extern bool __static_cpu_has_safe(u16 bit);
 
 /*
  * Static testing of CPU features.  Used the same as boot_cpu_has().
@@ -502,10 +501,10 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
 		boot_cpu_has(bit)				\
 )
 
-static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
+static __always_inline __pure bool _static_cpu_has_safe(u16 bit, __u32 *caps)
 {
 #ifdef CC_HAVE_ASM_GOTO
-		asm_volatile_goto("1: jmp %l[t_dynamic]\n"
+		asm_volatile_goto("1: jmp 6f\n"
 			 "2:\n"
 			 ".skip -(((5f-4f) - (2b-1b)) > 0) * "
 			         "((5f-4f) - (2b-1b)),0x90\n"
@@ -530,17 +529,22 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 			 " .byte 0\n"			/* repl len */
 			 " .byte 0\n"			/* pad len */
 			 ".previous\n"
-			 : : "i" (bit), "i" (X86_FEATURE_ALWAYS)
-			 : : t_dynamic, t_no);
+			 ".section .static_cpu_has,\"ax\"\n"
+			 "6: testl %2,%3\n"
+			 "   jnz %l[t_yes]\n"
+			 "   jmp %l[t_no]\n"
+			 ".previous\n"
+			 : : "i" (bit), "i" (X86_FEATURE_ALWAYS),
+			     "i" (1 << (bit & 31)), "m" (caps[bit/32])
+			 : : t_yes, t_no);
+	t_yes:
 		return true;
 	t_no:
 		return false;
-	t_dynamic:
-		return __static_cpu_has_safe(bit);
 #else
 		u8 flag;
 		/* Open-coded due to __stringify() in ALTERNATIVE() */
-		asm volatile("1: movb $2,%0\n"
+		asm volatile("1: jmp 7f\n"
 			     "2:\n"
 			     ".section .altinstructions,\"a\"\n"
 			     " .long 1b - .\n"		/* src offset */
@@ -572,9 +576,15 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 			     "5: movb $1,%0\n"
 			     "6:\n"
 			     ".previous\n"
+			     ".section .static_cpu_has,\"ax\"\n"
+			     "7: testl %3,%4\n"
+			     "   setnz %0\n"
+			     "   jmp 2b\n"
+			     ".previous\n"
 			     : "=qm" (flag)
-			     : "i" (bit), "i" (X86_FEATURE_ALWAYS));
-		return (flag == 2 ? __static_cpu_has_safe(bit) : flag);
+			     : "i" (bit), "i" (X86_FEATURE_ALWAYS),
+			       "i" (1 << (bit & 31)), "m" (caps[bit/32]));
+		return (flag != 0);
 #endif /* CC_HAVE_ASM_GOTO */
 }
 
@@ -582,7 +592,8 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 (								\
 	__builtin_constant_p(boot_cpu_has(bit)) ?		\
 		boot_cpu_has(bit) :				\
-		_static_cpu_has_safe(bit)			\
+		_static_cpu_has_safe(bit,			\
+			 &boot_cpu_data.x86_capability[0])	\
 )
 #else
 /*
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 37830de..897c65b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1483,12 +1483,6 @@ void warn_pre_alternatives(void)
 EXPORT_SYMBOL_GPL(warn_pre_alternatives);
 #endif
 
-inline bool __static_cpu_has_safe(u16 bit)
-{
-	return boot_cpu_has(bit);
-}
-EXPORT_SYMBOL_GPL(__static_cpu_has_safe);
-
 static void bsp_resume(void)
 {
 	if (this_cpu->c_bsp_resume)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 4f19942..4df1467 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -195,6 +195,12 @@ SECTIONS
 	:init
 #endif
 
+	.static_cpu_has : AT(ADDR(.static_cpu_has) - LOAD_OFFSET) {
+		__static_cpu_has_start = .;
+		*(.static_cpu_has)
+		__static_cpu_has_end = .;
+	}
+
 	INIT_DATA_SECTION(16)
 
 	.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
-- 
2.5.0

[toc] | [next] | [standalone]


#1311016 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-16 20:40 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qRERA-mf-1@gated-at.bofh.it>
In reply to#1311015
On Sat, Jan 16, 2016 at 02:22:04PM -0500, Brian Gerst wrote:
> Move the code to do the dynamic check to the init text section so that it
> is discarded after alternatives have run and a static branch has been
> chosen.
> 
> A new section is defined to avoid warnings with modpost due to references
> to init text from main text, which in this case is legitimate.  All such
> references are patched out before init mem is discarded.

And we're doing this because...? Space savings? How much are we talkin'?

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1311022

FromBrian Gerst <brgerst@gmail.com>
Date2016-01-16 21:00 +0100
Message-ID<qRFaV-v0-1@gated-at.bofh.it>
In reply to#1311016
On Sat, Jan 16, 2016 at 2:36 PM, Borislav Petkov <bp@suse.de> wrote:
> On Sat, Jan 16, 2016 at 02:22:04PM -0500, Brian Gerst wrote:
>> Move the code to do the dynamic check to the init text section so that it
>> is discarded after alternatives have run and a static branch has been
>> chosen.
>>
>> A new section is defined to avoid warnings with modpost due to references
>> to init text from main text, which in this case is legitimate.  All such
>> references are patched out before init mem is discarded.
>
> And we're doing this because...? Space savings? How much are we talkin'?

It saves space.  The only thing left in main text is one jump
instruction (5 bytes).

The old t_dynamic branch looked something like this (26 bytes in
.text, not discarded):
     553:       bf 7d 00 00 00          mov    $0x7d,%edi
     558:       48 89 4d c8             mov    %rcx,-0x38(%rbp)
     55c:       e8 00 00 00 00          callq  561 <__switch_to+0xf1>
                        55d: R_X86_64_PC32      __static_cpu_has_safe-0x4
     561:       84 c0                   test   %al,%al
     563:       48 8b 4d c8             mov    -0x38(%rbp),%rcx
     567:       0f 85 77 01 00 00       jne    6e4 <__switch_to+0x274>

New (21 bytes, discarded after init):
   0:   f7 05 00 00 00 00 00    testl  $0x20000000,0x0(%rip)        #
a <.static_cpu_has+0xa>
   7:   00 00 20
                        2: R_X86_64_PC32        boot_cpu_data+0x18
   a:   0f 85 00 00 00 00       jne    10 <.static_cpu_has+0x10>
                        c: R_X86_64_PC32        .text+0x4b9
  10:   e9 00 00 00 00          jmpq   15 <.static_cpu_has+0x15>
                        11: R_X86_64_PC32       .text+0x529

--
Brian Gerst

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


#1311127 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-17 11:40 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qRSUx-1gy-15@gated-at.bofh.it>
In reply to#1311022
On Sat, Jan 16, 2016 at 02:58:21PM -0500, Brian Gerst wrote:
> It saves space.  The only thing left in main text is one jump
> instruction (5 bytes).

How do I measure this?

Because with my tailored config here, the only thing I'm seeing is a growth of
text by 730 bytes:

before:
   text    data     bss     dec     hex filename
10926552        3598944 16642048        31167544        1db9438 vmlinux

[    0.056552] Freeing SMP alternatives memory: 24K (ffffffff81dd7000 - ffffffff81ddd000)
[    2.883728] Freeing unused kernel memory: 2904K (ffffffff81b01000 - ffffffff81dd7000)


after:
   text    data     bss     dec     hex filename
10927282        3598944 16642048        31168274        1db9712 vmlinux

[    0.052559] Freeing SMP alternatives memory: 24K (ffffffff81dd7000 - ffffffff81ddd000)
[    3.225318] Freeing unused kernel memory: 2904K (ffffffff81b01000 - ffffffff81dd7000)

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1311672

FromBrian Gerst <brgerst@gmail.com>
Date2016-01-18 18:00 +0100
Message-ID<qSljR-3pb-13@gated-at.bofh.it>
In reply to#1311127
On Sun, Jan 17, 2016 at 5:33 AM, Borislav Petkov <bp@suse.de> wrote:
> On Sat, Jan 16, 2016 at 02:58:21PM -0500, Brian Gerst wrote:
>> It saves space.  The only thing left in main text is one jump
>> instruction (5 bytes).
>
> How do I measure this?
>
> Because with my tailored config here, the only thing I'm seeing is a growth of
> text by 730 bytes:
>
> before:
>    text    data     bss     dec     hex filename
> 10926552        3598944 16642048        31167544        1db9438 vmlinux
>
> [    0.056552] Freeing SMP alternatives memory: 24K (ffffffff81dd7000 - ffffffff81ddd000)
> [    2.883728] Freeing unused kernel memory: 2904K (ffffffff81b01000 - ffffffff81dd7000)
>
>
> after:
>    text    data     bss     dec     hex filename
> 10927282        3598944 16642048        31168274        1db9712 vmlinux
>
> [    0.052559] Freeing SMP alternatives memory: 24K (ffffffff81dd7000 - ffffffff81ddd000)
> [    3.225318] Freeing unused kernel memory: 2904K (ffffffff81b01000 - ffffffff81dd7000)

It is due to page alignment padding.  It was not enough to lose a
whole page from .text in your case.

The size command includes any section that is marked executable in the
text count, including init text.  If you use readelf -S vmlinux.o
instead you will notice that .text is the same size or smaller, and
.static_cpu_has (which is freed after boot) is the difference.

--
Brian Gerst

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


#1311719

FromAndy Lutomirski <luto@amacapital.net>
Date2016-01-18 18:50 +0100
Message-ID<qSm6e-3ZZ-35@gated-at.bofh.it>
In reply to#1311672
On Mon, Jan 18, 2016 at 8:52 AM, Brian Gerst <brgerst@gmail.com> wrote:
> On Sun, Jan 17, 2016 at 5:33 AM, Borislav Petkov <bp@suse.de> wrote:
>> On Sat, Jan 16, 2016 at 02:58:21PM -0500, Brian Gerst wrote:
>>> It saves space.  The only thing left in main text is one jump
>>> instruction (5 bytes).
>>
>> How do I measure this?
>>
>> Because with my tailored config here, the only thing I'm seeing is a growth of
>> text by 730 bytes:
>>
>> before:
>>    text    data     bss     dec     hex filename
>> 10926552        3598944 16642048        31167544        1db9438 vmlinux
>>
>> [    0.056552] Freeing SMP alternatives memory: 24K (ffffffff81dd7000 - ffffffff81ddd000)
>> [    2.883728] Freeing unused kernel memory: 2904K (ffffffff81b01000 - ffffffff81dd7000)
>>
>>
>> after:
>>    text    data     bss     dec     hex filename
>> 10927282        3598944 16642048        31168274        1db9712 vmlinux
>>
>> [    0.052559] Freeing SMP alternatives memory: 24K (ffffffff81dd7000 - ffffffff81ddd000)
>> [    3.225318] Freeing unused kernel memory: 2904K (ffffffff81b01000 - ffffffff81dd7000)
>
> It is due to page alignment padding.  It was not enough to lose a
> whole page from .text in your case.
>
> The size command includes any section that is marked executable in the
> text count, including init text.  If you use readelf -S vmlinux.o
> instead you will notice that .text is the same size or smaller, and
> .static_cpu_has (which is freed after boot) is the difference.
>

If I'm understanding this correctly, the total non-init overhead from
static_cpu_has_safe with your patch is five bytes.  I'd imagine that
the short jmp optimization in regular static_cpu_has essentially never
works, which means it will also use five bytes of text, which makes me
wonder whether we should just make static_cpu_has safe and remove the
distinction.

Also, someone should write a little script to measure kernel size
minus .init stuff.

--Andy

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


#1311734 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-18 19:20 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSmzg-4r1-13@gated-at.bofh.it>
In reply to#1311672
On Mon, Jan 18, 2016 at 11:52:34AM -0500, Brian Gerst wrote:
> It is due to page alignment padding.  It was not enough to lose a
> whole page from .text in your case.

So nothing more got freed.

> The size command includes any section that is marked executable in the
> text count, including init text.  If you use readelf -S vmlinux.o
> instead you will notice that .text is the same size or smaller, and
> .static_cpu_has (which is freed after boot) is the difference.

So we're talking about less than a page here?

  [19] .static_cpu_has   PROGBITS         ffffffff81d335d3  011335d3
       00000000000002df  0000000000000000  AX       0     0     1

That's 479 bytes. Meh, it doesn't look like it is worth the trouble.

Maybe I should build an allyesconfig.

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1311737

FromAndy Lutomirski <luto@amacapital.net>
Date2016-01-18 19:30 +0100
Message-ID<qSmIW-4vc-15@gated-at.bofh.it>
In reply to#1311734
On Mon, Jan 18, 2016 at 10:14 AM, Borislav Petkov <bp@suse.de> wrote:
> On Mon, Jan 18, 2016 at 11:52:34AM -0500, Brian Gerst wrote:
>> It is due to page alignment padding.  It was not enough to lose a
>> whole page from .text in your case.
>
> So nothing more got freed.
>
>> The size command includes any section that is marked executable in the
>> text count, including init text.  If you use readelf -S vmlinux.o
>> instead you will notice that .text is the same size or smaller, and
>> .static_cpu_has (which is freed after boot) is the difference.
>
> So we're talking about less than a page here?
>
>   [19] .static_cpu_has   PROGBITS         ffffffff81d335d3  011335d3
>        00000000000002df  0000000000000000  AX       0     0     1
>
> That's 479 bytes. Meh, it doesn't look like it is worth the trouble.
>

I think that, if we can make static_cpu_has be unconditionally safe as
a result and get rid of warn_pre_alternatives, then it is worth the
trouble.

--Andy

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


#1311742 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-18 19:40 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSmSD-4zc-25@gated-at.bofh.it>
In reply to#1311737
On Mon, Jan 18, 2016 at 10:29:24AM -0800, Andy Lutomirski wrote:
> I think that, if we can make static_cpu_has be unconditionally safe as
> a result

Problem with this is the additional .altinstructions entry for
X86_FEATURE_ALWAYS. And sometimes you don't really need to use the _safe
variant when you know you're safe.

> and get rid of warn_pre_alternatives,

That's off by default, behind CONFIG_X86_DEBUG_STATIC_CPU_HAS.

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1311774 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

From"H. Peter Anvin" <hpa@zytor.com>
Date2016-01-18 20:50 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSnYl-5eq-9@gated-at.bofh.it>
In reply to#1311742
On 01/18/16 10:39, Borislav Petkov wrote:
> On Mon, Jan 18, 2016 at 10:29:24AM -0800, Andy Lutomirski wrote:
>> I think that, if we can make static_cpu_has be unconditionally safe as
>> a result
> 
> Problem with this is the additional .altinstructions entry for
> X86_FEATURE_ALWAYS. And sometimes you don't really need to use the _safe
> variant when you know you're safe.
> 

I think the two-byte optimization is the real issue if there is one at
all.  I don't care about the inittext, and unless I'm misremembering
completely altinstructions also get ejected.

So I don't personally object to killing off the unsafe variant.

	-hpa

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


#1311842 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-19 00:10 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSr5T-7Dj-7@gated-at.bofh.it>
In reply to#1311774
On Mon, Jan 18, 2016 at 11:45:18AM -0800, H. Peter Anvin wrote:
> I think the two-byte optimization is the real issue if there is one at
> all.

Well, we do optimize the jumps for a couple releases now, see
recompute_jump(). So we would always get the short JMP, if made possible
by how gcc lays out the code so that the target is not far away. If the
JMP to the dynamic branch doesn't get nopped out anyway, that is.

We have "debug-alternative" to dump exactly what happens during
patching.

> I don't care about the inittext, and unless I'm misremembering
> completely altinstructions also get ejected.

Ah yes, they do.

> So I don't personally object to killing off the unsafe variant.

Ok.

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1311844

From"H. Peter Anvin" <hpa@zytor.com>
Date2016-01-19 00:20 +0100
Message-ID<qSrfA-7GJ-17@gated-at.bofh.it>
In reply to#1311842
On January 18, 2016 3:05:54 PM PST, Borislav Petkov <bp@suse.de> wrote:
>On Mon, Jan 18, 2016 at 11:45:18AM -0800, H. Peter Anvin wrote:
>> I think the two-byte optimization is the real issue if there is one
>at
>> all.
>
>Well, we do optimize the jumps for a couple releases now, see
>recompute_jump(). So we would always get the short JMP, if made
>possible
>by how gcc lays out the code so that the target is not far away. If the
>JMP to the dynamic branch doesn't get nopped out anyway, that is.
>
>We have "debug-alternative" to dump exactly what happens during
>patching.
>
>> I don't care about the inittext, and unless I'm misremembering
>> completely altinstructions also get ejected.
>
>Ah yes, they do.
>
>> So I don't personally object to killing off the unsafe variant.
>
>Ok.

The optimization has always been there, the question is how often it actually kicks in.
-- 
Sent from my Android device with K-9 Mail. Please excuse brevity and formatting.

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


#1311847 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-19 00:30 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSrpg-7KW-15@gated-at.bofh.it>
In reply to#1311844
On Mon, Jan 18, 2016 at 03:13:00PM -0800, H. Peter Anvin wrote:
> The optimization has always been there, the question is how often it
> actually kicks in.

Luckily, I have this disassembler tool which dumps the alternatives
sections in a more readable format. I can dump all the static_cpu_has()
call sites tomorrow and we can see what gcc generates.

;-}

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1312262 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-19 15:00 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSEZb-bz-5@gated-at.bofh.it>
In reply to#1311847
On Tue, Jan 19, 2016 at 12:25:47AM +0100, Borislav Petkov wrote:
> Luckily, I have this disassembler tool which dumps the alternatives
> sections in a more readable format. I can dump all the static_cpu_has()
> call sites tomorrow and we can see what gcc generates.

Ok, below is the list of all 12(!) places where static_cpu_has() has
generated a 2-byte JMP. Which has saved us a whopping 36 bytes! On an
x86_64 allyesconfig!

Patch removing it below. I better look at a 32-bit allyesconfig too
first, though.

old insn VA: 0xffffffff8146b5ac, CPU feat: X86_FEATURE_PCOMMIT, size: 2, padlen: 0
wmb_pmem:
 ffffffff8146b5ac:      eb 02                   jmp ffffffff8146b5b0
repl insn: 0xffffffff8ca7c651, size: 0

old insn VA: 0xffffffff8200dcd6, CPU feat: X86_FEATURE_PCOMMIT, size: 2, padlen: 0
arch_has_wmb_pmem:
 ffffffff8200dcd6:      eb 02                   jmp ffffffff8200dcda
repl insn: 0xffffffff8ca7ebd8, size: 0

old insn VA: 0xffffffff828afe51, CPU feat: X86_FEATURE_PCOMMIT, size: 2, padlen: 0
arch_has_wmb_pmem:
 ffffffff828afe51:      eb 02                   jmp ffffffff828afe55
repl insn: 0xffffffff8ca80f98, size: 0

old insn VA: 0xffffffff81072f77, CPU feat: X86_FEATURE_NRIPS, size: 2, padlen: 0
rdpmc_interception:
 ffffffff81072f77:      eb 4d                   jmp ffffffff81072fc6
repl insn: 0xffffffff8ca79f6b, size: 0

old insn VA: 0xffffffff8107437d, CPU feat: X86_FEATURE_NRIPS, size: 2, padlen: 0
svm_queue_exception:
 ffffffff8107437d:      eb 6f                   jmp ffffffff810743ee
repl insn: 0xffffffff8ca79f9f, size: 0

old insn VA: 0xffffffff8107741b, CPU feat: X86_FEATURE_NRIPS, size: 2, padlen: 0
svm_check_intercept:
 ffffffff8107741b:      eb 67                   jmp ffffffff81077484
repl insn: 0xffffffff8ca79fed, size: 0

old insn VA: 0xffffffff8107741b, CPU feat: X86_FEATURE_NRIPS, size: 2, padlen: 0
svm_check_intercept:
 ffffffff8107741b:      eb 67                   jmp ffffffff81077484
repl insn: 0xffffffff8ca79fed, size: 0

old insn VA: 0xffffffff81075c4f, CPU feat: X86_FEATURE_TSCRATEMSR, size: 2, padlen: 0
svm_hardware_enable:
 ffffffff81075c4f:      eb 57                   jmp ffffffff81075ca8
repl insn: 0xffffffff8ca79fb9, size: 0

old insn VA: 0xffffffff81072c00, CPU feat: X86_FEATURE_DECODEASSISTS, size: 2, padlen: 0
invlpg_interception:
 ffffffff81072c00:      eb 55                   jmp ffffffff81072c57
repl insn: 0xffffffff8ca79f51, size: 0

old insn VA: 0xffffffff8107097c, CPU feat: X86_FEATURE_FLUSHBYASID, size: 2, padlen: 0
svm_flush_tlb:
 ffffffff8107097c:      eb 35                   jmp ffffffff810709b3
repl insn: 0xffffffff8ca79ee9, size: 0

old insn VA: 0xffffffff8108c0d0, CPU feat: X86_BUG_SYSRET_SS_ATTRS, size: 2, padlen: 0
__switch_to:
 ffffffff8108c0d0:      eb 70                   jmp ffffffff8108c142
repl insn: 0xffffffff8ca7a1a7, size: 0

old insn VA: 0xffffffff81075d90, CPU feat: X86_BUG_AMD_TLB_MMATCH, size: 2, padlen: 0
svm_hardware_enable:
 ffffffff81075d90:      eb 7c                   jmp ffffffff81075e0e
repl insn: 0xffffffff8ca79fd3, size: 0

---
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 9b18ed9..68a2d1f 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -350,16 +350,6 @@ config DEBUG_IMR_SELFTEST
 
 	  If unsure say N here.
 
-config X86_DEBUG_STATIC_CPU_HAS
-	bool "Debug alternatives"
-	depends on DEBUG_KERNEL
-	---help---
-	  This option causes additional code to be generated which
-	  fails if static_cpu_has() is used before alternatives have
-	  run.
-
-	  If unsure, say N.
-
 config X86_DEBUG_FPU
 	bool "Debug the x86 FPU code"
 	depends on DEBUG_KERNEL
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 0366374..c2d7a97 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -477,7 +477,7 @@ __visible long do_fast_syscall_32(struct pt_regs *regs)
 	 * We don't allow syscalls at all from VM86 mode, but we still
 	 * need to check VM, because we might be returning from sys_vm86.
 	 */
-	return static_cpu_has(X86_FEATURE_SEP) &&
+	return static_cpu_has_safe(X86_FEATURE_SEP) &&
 		regs->cs == __USER_CS && regs->ss == __USER_DS &&
 		regs->ip == landing_pad &&
 		(regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF | X86_EFLAGS_VM)) == 0;
diff --git a/arch/x86/include/asm/archrandom.h b/arch/x86/include/asm/archrandom.h
index 69f1366..2fb511b 100644
--- a/arch/x86/include/asm/archrandom.h
+++ b/arch/x86/include/asm/archrandom.h
@@ -114,8 +114,8 @@ GET_SEED(arch_get_random_seed_int, unsigned int, RDSEED_INT, ASM_NOP4);
 
 #endif /* CONFIG_X86_64 */
 
-#define arch_has_random()	static_cpu_has(X86_FEATURE_RDRAND)
-#define arch_has_random_seed()	static_cpu_has(X86_FEATURE_RDSEED)
+#define arch_has_random()	static_cpu_has_safe(X86_FEATURE_RDRAND)
+#define arch_has_random_seed()	static_cpu_has_safe(X86_FEATURE_RDSEED)
 
 #else
 
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 7ad8c94..5fe399a 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -419,89 +419,6 @@ extern bool __static_cpu_has_safe(u16 bit);
  * These are only valid after alternatives have run, but will statically
  * patch the target code for additional performance.
  */
-static __always_inline __pure bool __static_cpu_has(u16 bit)
-{
-#ifdef CC_HAVE_ASM_GOTO
-
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
-
-		/*
-		 * Catch too early usage of this before alternatives
-		 * have run.
-		 */
-		asm_volatile_goto("1: jmp %l[t_warn]\n"
-			 "2:\n"
-			 ".section .altinstructions,\"a\"\n"
-			 " .long 1b - .\n"
-			 " .long 0\n"		/* no replacement */
-			 " .word %P0\n"		/* 1: do replace */
-			 " .byte 2b - 1b\n"	/* source len */
-			 " .byte 0\n"		/* replacement len */
-			 " .byte 0\n"		/* pad len */
-			 ".previous\n"
-			 /* skipping size check since replacement size = 0 */
-			 : : "i" (X86_FEATURE_ALWAYS) : : t_warn);
-
-#endif
-
-		asm_volatile_goto("1: jmp %l[t_no]\n"
-			 "2:\n"
-			 ".section .altinstructions,\"a\"\n"
-			 " .long 1b - .\n"
-			 " .long 0\n"		/* no replacement */
-			 " .word %P0\n"		/* feature bit */
-			 " .byte 2b - 1b\n"	/* source len */
-			 " .byte 0\n"		/* replacement len */
-			 " .byte 0\n"		/* pad len */
-			 ".previous\n"
-			 /* skipping size check since replacement size = 0 */
-			 : : "i" (bit) : : t_no);
-		return true;
-	t_no:
-		return false;
-
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
-	t_warn:
-		warn_pre_alternatives();
-		return false;
-#endif
-
-#else /* CC_HAVE_ASM_GOTO */
-
-		u8 flag;
-		/* Open-coded due to __stringify() in ALTERNATIVE() */
-		asm volatile("1: movb $0,%0\n"
-			     "2:\n"
-			     ".section .altinstructions,\"a\"\n"
-			     " .long 1b - .\n"
-			     " .long 3f - .\n"
-			     " .word %P1\n"		/* feature bit */
-			     " .byte 2b - 1b\n"		/* source len */
-			     " .byte 4f - 3f\n"		/* replacement len */
-			     " .byte 0\n"		/* pad len */
-			     ".previous\n"
-			     ".section .discard,\"aw\",@progbits\n"
-			     " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
-			     ".previous\n"
-			     ".section .altinstr_replacement,\"ax\"\n"
-			     "3: movb $1,%0\n"
-			     "4:\n"
-			     ".previous\n"
-			     : "=qm" (flag) : "i" (bit));
-		return flag;
-
-#endif /* CC_HAVE_ASM_GOTO */
-}
-
-#define static_cpu_has(bit)					\
-(								\
-	__builtin_constant_p(boot_cpu_has(bit)) ?		\
-		boot_cpu_has(bit) :				\
-	__builtin_constant_p(bit) ?				\
-		__static_cpu_has(bit) :				\
-		boot_cpu_has(bit)				\
-)
-
 static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 {
 #ifdef CC_HAVE_ASM_GOTO
@@ -588,7 +505,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 /*
  * gcc 3.x is too stupid to do the static test; fall back to dynamic.
  */
-#define static_cpu_has(bit)		boot_cpu_has(bit)
 #define static_cpu_has_safe(bit)	boot_cpu_has(bit)
 #endif
 
@@ -596,7 +512,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 #define set_cpu_bug(c, bit)		set_cpu_cap(c, (bit))
 #define clear_cpu_bug(c, bit)		clear_cpu_cap(c, (bit))
 
-#define static_cpu_has_bug(bit)		static_cpu_has((bit))
 #define static_cpu_has_bug_safe(bit)	static_cpu_has_safe((bit))
 #define boot_cpu_has_bug(bit)		cpu_has_bug(&boot_cpu_data, (bit))
 
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
index c70689b..2bd6e47 100644
--- a/arch/x86/include/asm/mwait.h
+++ b/arch/x86/include/asm/mwait.h
@@ -96,7 +96,7 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
 static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 {
 	if (!current_set_polling_and_test()) {
-		if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
+		if (static_cpu_has_bug_safe(X86_BUG_CLFLUSH_MONITOR)) {
 			mb();
 			clflush((void *)&current_thread_info()->flags);
 			mb();
diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h
index 1544fab..5d7abb4 100644
--- a/arch/x86/include/asm/pmem.h
+++ b/arch/x86/include/asm/pmem.h
@@ -142,7 +142,7 @@ static inline bool __arch_has_wmb_pmem(void)
 	 * We require that wmb() be an 'sfence', that is only guaranteed on
 	 * 64-bit builds
 	 */
-	return static_cpu_has(X86_FEATURE_PCOMMIT);
+	return static_cpu_has_safe(X86_FEATURE_PCOMMIT);
 }
 #endif /* CONFIG_ARCH_HAS_PMEM_API */
 #endif /* __ASM_X86_PMEM_H__ */
diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h
index eaba080..f456616 100644
--- a/arch/x86/include/asm/qspinlock.h
+++ b/arch/x86/include/asm/qspinlock.h
@@ -43,7 +43,7 @@ static inline void queued_spin_unlock(struct qspinlock *lock)
 #define virt_spin_lock virt_spin_lock
 static inline bool virt_spin_lock(struct qspinlock *lock)
 {
-	if (!static_cpu_has(X86_FEATURE_HYPERVISOR))
+	if (!static_cpu_has_safe(X86_FEATURE_HYPERVISOR))
 		return false;
 
 	/*
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 18ca99f..f8a6cfb 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -32,11 +32,11 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
 		   "fpu_exception\t: %s\n"
 		   "cpuid level\t: %d\n"
 		   "wp\t\t: %s\n",
-		   static_cpu_has_bug(X86_BUG_FDIV) ? "yes" : "no",
-		   static_cpu_has_bug(X86_BUG_F00F) ? "yes" : "no",
-		   static_cpu_has_bug(X86_BUG_COMA) ? "yes" : "no",
-		   static_cpu_has(X86_FEATURE_FPU) ? "yes" : "no",
-		   static_cpu_has(X86_FEATURE_FPU) ? "yes" : "no",
+		   static_cpu_has_bug_safe(X86_BUG_FDIV) ? "yes" : "no",
+		   static_cpu_has_bug_safe(X86_BUG_F00F) ? "yes" : "no",
+		   static_cpu_has_bug_safe(X86_BUG_COMA) ? "yes" : "no",
+		   static_cpu_has_safe(X86_FEATURE_FPU) ? "yes" : "no",
+		   static_cpu_has_safe(X86_FEATURE_FPU) ? "yes" : "no",
 		   c->cpuid_level,
 		   c->wp_works_ok ? "yes" : "no");
 }
diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
index 0bc3490..9b0163c 100644
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -275,7 +275,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
 
 	fpu__activate_fpstate_read(fpu);
 
-	if (!static_cpu_has(X86_FEATURE_FPU))
+	if (!static_cpu_has_safe(X86_FEATURE_FPU))
 		return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
 
 	if (!cpu_has_fxsr)
@@ -306,7 +306,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
 	fpu__activate_fpstate_write(fpu);
 	fpstate_sanitize_xstate(fpu);
 
-	if (!static_cpu_has(X86_FEATURE_FPU))
+	if (!static_cpu_has_safe(X86_FEATURE_FPU))
 		return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
 
 	if (!cpu_has_fxsr)
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 31c6a60..05b6ede 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -162,7 +162,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
 	if (!access_ok(VERIFY_WRITE, buf, size))
 		return -EACCES;
 
-	if (!static_cpu_has(X86_FEATURE_FPU))
+	if (!static_cpu_has_safe(X86_FEATURE_FPU))
 		return fpregs_soft_get(current, NULL, 0,
 			sizeof(struct user_i387_ia32_struct), NULL,
 			(struct _fpstate_32 __user *) buf) ? -1 : 1;
@@ -267,7 +267,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
 
 	fpu__activate_curr(fpu);
 
-	if (!static_cpu_has(X86_FEATURE_FPU))
+	if (!static_cpu_has_safe(X86_FEATURE_FPU))
 		return fpregs_soft_set(current, NULL,
 				       0, sizeof(struct user_i387_ia32_struct),
 				       NULL, buf) != 0;
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b9d99e0..c49a284 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -411,7 +411,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 		     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
 		__switch_to_xtra(prev_p, next_p, tss);
 
-	if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {
+	if (static_cpu_has_bug_safe(X86_BUG_SYSRET_SS_ATTRS)) {
 		/*
 		 * AMD CPUs have a misfeature: SYSRET sets the SS selector but
 		 * does not update the cached descriptor.  As a result, if we
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index c8eda14..89d5ad7 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -32,7 +32,7 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpuid_entry2 *best;
 
-	if (!static_cpu_has(X86_FEATURE_XSAVE))
+	if (!static_cpu_has_safe(X86_FEATURE_XSAVE))
 		return false;
 
 	best = kvm_find_cpuid_entry(vcpu, 1, 0);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c13a64b..1892bdd 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -516,7 +516,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	if (svm->vmcb->control.next_rip != 0) {
-		WARN_ON_ONCE(!static_cpu_has(X86_FEATURE_NRIPS));
+		WARN_ON_ONCE(!static_cpu_has_safe(X86_FEATURE_NRIPS));
 		svm->next_rip = svm->vmcb->control.next_rip;
 	}
 
@@ -548,7 +548,7 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
 	    nested_svm_check_exception(svm, nr, has_error_code, error_code))
 		return;
 
-	if (nr == BP_VECTOR && !static_cpu_has(X86_FEATURE_NRIPS)) {
+	if (nr == BP_VECTOR && !static_cpu_has_safe(X86_FEATURE_NRIPS)) {
 		unsigned long rip, old_rip = kvm_rip_read(&svm->vcpu);
 
 		/*
@@ -577,7 +577,7 @@ static void svm_init_erratum_383(void)
 	int err;
 	u64 val;
 
-	if (!static_cpu_has_bug(X86_BUG_AMD_TLB_MMATCH))
+	if (!static_cpu_has_bug_safe(X86_BUG_AMD_TLB_MMATCH))
 		return;
 
 	/* Use _safe variants to not break nested virtualization */
@@ -631,7 +631,7 @@ static int has_svm(void)
 static void svm_hardware_disable(void)
 {
 	/* Make sure we clean up behind us */
-	if (static_cpu_has(X86_FEATURE_TSCRATEMSR))
+	if (static_cpu_has_safe(X86_FEATURE_TSCRATEMSR))
 		wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT);
 
 	cpu_svm_disable();
@@ -674,7 +674,7 @@ static int svm_hardware_enable(void)
 
 	wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT);
 
-	if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+	if (static_cpu_has_safe(X86_FEATURE_TSCRATEMSR)) {
 		wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT);
 		__this_cpu_write(current_tsc_ratio, TSC_RATIO_DEFAULT);
 	}
@@ -1233,7 +1233,7 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
 		rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
 
-	if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+	if (static_cpu_has_safe(X86_FEATURE_TSCRATEMSR)) {
 		u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio;
 		if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
 			__this_cpu_write(current_tsc_ratio, tsc_ratio);
@@ -1241,7 +1241,7 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 		}
 	}
 	/* This assumes that the kernel never uses MSR_TSC_AUX */
-	if (static_cpu_has(X86_FEATURE_RDTSCP))
+	if (static_cpu_has_safe(X86_FEATURE_RDTSCP))
 		wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
 }
 
@@ -2806,7 +2806,7 @@ static int iret_interception(struct vcpu_svm *svm)
 
 static int invlpg_interception(struct vcpu_svm *svm)
 {
-	if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
+	if (!static_cpu_has_safe(X86_FEATURE_DECODEASSISTS))
 		return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 
 	kvm_mmu_invlpg(&svm->vcpu, svm->vmcb->control.exit_info_1);
@@ -2823,7 +2823,7 @@ static int rdpmc_interception(struct vcpu_svm *svm)
 {
 	int err;
 
-	if (!static_cpu_has(X86_FEATURE_NRIPS))
+	if (!static_cpu_has_safe(X86_FEATURE_NRIPS))
 		return emulate_on_interception(svm);
 
 	err = kvm_rdpmc(&svm->vcpu);
@@ -2864,7 +2864,7 @@ static int cr_interception(struct vcpu_svm *svm)
 	unsigned long val;
 	int err;
 
-	if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
+	if (!static_cpu_has_safe(X86_FEATURE_DECODEASSISTS))
 		return emulate_on_interception(svm);
 
 	if (unlikely((svm->vmcb->control.exit_info_1 & CR_VALID) == 0))
@@ -3710,7 +3710,7 @@ static void svm_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	if (static_cpu_has(X86_FEATURE_FLUSHBYASID))
+	if (static_cpu_has_safe(X86_FEATURE_FLUSHBYASID))
 		svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
 	else
 		svm->asid_generation--;
@@ -4282,7 +4282,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
 	}
 
 	/* TODO: Advertise NRIPS to guest hypervisor unconditionally */
-	if (static_cpu_has(X86_FEATURE_NRIPS))
+	if (static_cpu_has_safe(X86_FEATURE_NRIPS))
 		vmcb->control.next_rip  = info->next_rip;
 	vmcb->control.exit_code = icpt_info.exit_code;
 	vmexit = nested_svm_exit_handled(svm);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e2951b6..4bef603 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8993,7 +8993,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
 	if (cpu_has_secondary_exec_ctrls())
 		vmcs_set_secondary_exec_control(secondary_exec_ctl);
 
-	if (static_cpu_has(X86_FEATURE_PCOMMIT) && nested) {
+	if (static_cpu_has_safe(X86_FEATURE_PCOMMIT) && nested) {
 		if (guest_cpuid_has_pcommit(vcpu))
 			vmx->nested.nested_vmx_secondary_ctls_high |=
 				SECONDARY_EXEC_PCOMMIT;
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index eef44d9..711e9bc 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1033,7 +1033,7 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
 	if (!IS_ENABLED(CONFIG_X86_SMAP))
 		return false;
 
-	if (!static_cpu_has(X86_FEATURE_SMAP))
+	if (!static_cpu_has_safe(X86_FEATURE_SMAP))
 		return false;
 
 	if (error_code & PF_USER)
diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c
index 55d38cf..191650f 100644
--- a/arch/x86/ras/mce_amd_inj.c
+++ b/arch/x86/ras/mce_amd_inj.c
@@ -275,7 +275,7 @@ static void do_inject(void)
 	 * only on the node base core. Refer to D18F3x44[NbMcaToMstCpuEn] for
 	 * Fam10h and later BKDGs.
 	 */
-	if (static_cpu_has(X86_FEATURE_AMD_DCM) && b == 4) {
+	if (static_cpu_has_safe(X86_FEATURE_AMD_DCM) && b == 4) {
 		toggle_nb_mca_mst_cpu(amd_get_nb_id(cpu));
 		cpu = get_nbc_for_node(amd_get_nb_id(cpu));
 	}
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
index f6b79ab..87b0cf4 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -115,7 +115,7 @@ static int __init amd_freq_sensitivity_init(void)
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
 		return -ENODEV;
 
-	if (!static_cpu_has(X86_FEATURE_PROC_FEEDBACK))
+	if (!static_cpu_has_safe(X86_FEATURE_PROC_FEEDBACK))
 		return -ENODEV;
 
 	if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val))
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 0b5bf13..aa71612 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -1193,7 +1193,7 @@ static int powernowk8_init(void)
 	unsigned int i, supported_cpus = 0;
 	int ret;
 
-	if (static_cpu_has(X86_FEATURE_HW_PSTATE)) {
+	if (static_cpu_has_safe(X86_FEATURE_HW_PSTATE)) {
 		__request_acpi_cpufreq();
 		return -ENODEV;
 	}


-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1312368 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-19 17:30 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSHkn-1Ws-19@gated-at.bofh.it>
In reply to#1312262
On Tue, Jan 19, 2016 at 02:57:14PM +0100, Borislav Petkov wrote:
> Patch removing it below. I better look at a 32-bit allyesconfig too
> first, though.

Yap, no 2-byte jumps in the static_cpu_has()-generated code on an 32-bit
allyesconfig build.

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1312577 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-20 00:20 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSNJ7-6c7-1@gated-at.bofh.it>
In reply to#1312262
On Tue, Jan 19, 2016 at 02:57:14PM +0100, Borislav Petkov wrote:
> Patch removing it below.

Andy has a point: I should simply drop static_cpu_has and kill the "_safe"
suffix of the remaining variant:

---
 arch/x86/Kconfig.debug               | 10 ----
 arch/x86/include/asm/cpufeature.h    | 99 +++---------------------------------
 arch/x86/include/asm/fpu/internal.h  | 14 ++---
 arch/x86/kernel/apic/apic_numachip.c |  4 +-
 arch/x86/kernel/cpu/common.c         |  4 +-
 arch/x86/kernel/vm86_32.c            |  2 +-
 drivers/cpufreq/intel_pstate.c       |  2 +-
 fs/btrfs/disk-io.c                   |  2 +-
 8 files changed, 21 insertions(+), 116 deletions(-)

diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 9b18ed9..68a2d1f 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -350,16 +350,6 @@ config DEBUG_IMR_SELFTEST
 
 	  If unsure say N here.
 
-config X86_DEBUG_STATIC_CPU_HAS
-	bool "Debug alternatives"
-	depends on DEBUG_KERNEL
-	---help---
-	  This option causes additional code to be generated which
-	  fails if static_cpu_has() is used before alternatives have
-	  run.
-
-	  If unsure, say N.
-
 config X86_DEBUG_FPU
 	bool "Debug the x86 FPU code"
 	depends on DEBUG_KERNEL
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 7ad8c94..9219f00 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -406,103 +406,20 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
 #define cpu_has_osxsave		boot_cpu_has(X86_FEATURE_OSXSAVE)
 #define cpu_has_hypervisor	boot_cpu_has(X86_FEATURE_HYPERVISOR)
 /*
- * Do not add any more of those clumsy macros - use static_cpu_has_safe() for
+ * Do not add any more of those clumsy macros - use static_cpu_has() for
  * fast paths and boot_cpu_has() otherwise!
  */
 
 #if __GNUC__ >= 4 && defined(CONFIG_X86_FAST_FEATURE_TESTS)
 extern void warn_pre_alternatives(void);
-extern bool __static_cpu_has_safe(u16 bit);
+extern bool __static_cpu_has(u16 bit);
 
 /*
  * Static testing of CPU features.  Used the same as boot_cpu_has().
  * These are only valid after alternatives have run, but will statically
  * patch the target code for additional performance.
  */
-static __always_inline __pure bool __static_cpu_has(u16 bit)
-{
-#ifdef CC_HAVE_ASM_GOTO
-
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
-
-		/*
-		 * Catch too early usage of this before alternatives
-		 * have run.
-		 */
-		asm_volatile_goto("1: jmp %l[t_warn]\n"
-			 "2:\n"
-			 ".section .altinstructions,\"a\"\n"
-			 " .long 1b - .\n"
-			 " .long 0\n"		/* no replacement */
-			 " .word %P0\n"		/* 1: do replace */
-			 " .byte 2b - 1b\n"	/* source len */
-			 " .byte 0\n"		/* replacement len */
-			 " .byte 0\n"		/* pad len */
-			 ".previous\n"
-			 /* skipping size check since replacement size = 0 */
-			 : : "i" (X86_FEATURE_ALWAYS) : : t_warn);
-
-#endif
-
-		asm_volatile_goto("1: jmp %l[t_no]\n"
-			 "2:\n"
-			 ".section .altinstructions,\"a\"\n"
-			 " .long 1b - .\n"
-			 " .long 0\n"		/* no replacement */
-			 " .word %P0\n"		/* feature bit */
-			 " .byte 2b - 1b\n"	/* source len */
-			 " .byte 0\n"		/* replacement len */
-			 " .byte 0\n"		/* pad len */
-			 ".previous\n"
-			 /* skipping size check since replacement size = 0 */
-			 : : "i" (bit) : : t_no);
-		return true;
-	t_no:
-		return false;
-
-#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
-	t_warn:
-		warn_pre_alternatives();
-		return false;
-#endif
-
-#else /* CC_HAVE_ASM_GOTO */
-
-		u8 flag;
-		/* Open-coded due to __stringify() in ALTERNATIVE() */
-		asm volatile("1: movb $0,%0\n"
-			     "2:\n"
-			     ".section .altinstructions,\"a\"\n"
-			     " .long 1b - .\n"
-			     " .long 3f - .\n"
-			     " .word %P1\n"		/* feature bit */
-			     " .byte 2b - 1b\n"		/* source len */
-			     " .byte 4f - 3f\n"		/* replacement len */
-			     " .byte 0\n"		/* pad len */
-			     ".previous\n"
-			     ".section .discard,\"aw\",@progbits\n"
-			     " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
-			     ".previous\n"
-			     ".section .altinstr_replacement,\"ax\"\n"
-			     "3: movb $1,%0\n"
-			     "4:\n"
-			     ".previous\n"
-			     : "=qm" (flag) : "i" (bit));
-		return flag;
-
-#endif /* CC_HAVE_ASM_GOTO */
-}
-
-#define static_cpu_has(bit)					\
-(								\
-	__builtin_constant_p(boot_cpu_has(bit)) ?		\
-		boot_cpu_has(bit) :				\
-	__builtin_constant_p(bit) ?				\
-		__static_cpu_has(bit) :				\
-		boot_cpu_has(bit)				\
-)
-
-static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
+static __always_inline __pure bool _static_cpu_has(u16 bit)
 {
 #ifdef CC_HAVE_ASM_GOTO
 		asm_volatile_goto("1: jmp %l[t_dynamic]\n"
@@ -536,7 +453,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 	t_no:
 		return false;
 	t_dynamic:
-		return __static_cpu_has_safe(bit);
+		return __static_cpu_has(bit);
 #else
 		u8 flag;
 		/* Open-coded due to __stringify() in ALTERNATIVE() */
@@ -574,22 +491,21 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 			     ".previous\n"
 			     : "=qm" (flag)
 			     : "i" (bit), "i" (X86_FEATURE_ALWAYS));
-		return (flag == 2 ? __static_cpu_has_safe(bit) : flag);
+		return (flag == 2 ? __static_cpu_has(bit) : flag);
 #endif /* CC_HAVE_ASM_GOTO */
 }
 
-#define static_cpu_has_safe(bit)				\
+#define static_cpu_has(bit)					\
 (								\
 	__builtin_constant_p(boot_cpu_has(bit)) ?		\
 		boot_cpu_has(bit) :				\
-		_static_cpu_has_safe(bit)			\
+		_static_cpu_has(bit)				\
 )
 #else
 /*
  * gcc 3.x is too stupid to do the static test; fall back to dynamic.
  */
 #define static_cpu_has(bit)		boot_cpu_has(bit)
-#define static_cpu_has_safe(bit)	boot_cpu_has(bit)
 #endif
 
 #define cpu_has_bug(c, bit)		cpu_has(c, (bit))
@@ -597,7 +513,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
 #define clear_cpu_bug(c, bit)		clear_cpu_cap(c, (bit))
 
 #define static_cpu_has_bug(bit)		static_cpu_has((bit))
-#define static_cpu_has_bug_safe(bit)	static_cpu_has_safe((bit))
 #define boot_cpu_has_bug(bit)		cpu_has_bug(&boot_cpu_data, (bit))
 
 #define MAX_CPU_FEATURES		(NCAPINTS * 32)
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
index 0fd440d..97022dd 100644
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -58,22 +58,22 @@ extern u64 fpu__get_supported_xfeatures_mask(void);
  */
 static __always_inline __pure bool use_eager_fpu(void)
 {
-	return static_cpu_has_safe(X86_FEATURE_EAGER_FPU);
+	return static_cpu_has(X86_FEATURE_EAGER_FPU);
 }
 
 static __always_inline __pure bool use_xsaveopt(void)
 {
-	return static_cpu_has_safe(X86_FEATURE_XSAVEOPT);
+	return static_cpu_has(X86_FEATURE_XSAVEOPT);
 }
 
 static __always_inline __pure bool use_xsave(void)
 {
-	return static_cpu_has_safe(X86_FEATURE_XSAVE);
+	return static_cpu_has(X86_FEATURE_XSAVE);
 }
 
 static __always_inline __pure bool use_fxsr(void)
 {
-	return static_cpu_has_safe(X86_FEATURE_FXSR);
+	return static_cpu_has(X86_FEATURE_FXSR);
 }
 
 /*
@@ -300,7 +300,7 @@ static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate)
 
 	WARN_ON(system_state != SYSTEM_BOOTING);
 
-	if (static_cpu_has_safe(X86_FEATURE_XSAVES))
+	if (static_cpu_has(X86_FEATURE_XSAVES))
 		XSTATE_OP(XSAVES, xstate, lmask, hmask, err);
 	else
 		XSTATE_OP(XSAVE, xstate, lmask, hmask, err);
@@ -322,7 +322,7 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate)
 
 	WARN_ON(system_state != SYSTEM_BOOTING);
 
-	if (static_cpu_has_safe(X86_FEATURE_XSAVES))
+	if (static_cpu_has(X86_FEATURE_XSAVES))
 		XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
 	else
 		XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
@@ -460,7 +460,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate)
 	 * pending. Clear the x87 state here by setting it to fixed values.
 	 * "m" is a random variable that should be in L1.
 	 */
-	if (unlikely(static_cpu_has_bug_safe(X86_BUG_FXSAVE_LEAK))) {
+	if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) {
 		asm volatile(
 			"fnclex\n\t"
 			"emms\n\t"
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c
index c80c02c..ab5c2c6 100644
--- a/arch/x86/kernel/apic/apic_numachip.c
+++ b/arch/x86/kernel/apic/apic_numachip.c
@@ -30,7 +30,7 @@ static unsigned int numachip1_get_apic_id(unsigned long x)
 	unsigned long value;
 	unsigned int id = (x >> 24) & 0xff;
 
-	if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
+	if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
 		rdmsrl(MSR_FAM10H_NODE_ID, value);
 		id |= (value << 2) & 0xff00;
 	}
@@ -178,7 +178,7 @@ static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
 	this_cpu_write(cpu_llc_id, node);
 
 	/* Account for nodes per socket in multi-core-module processors */
-	if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
+	if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
 		rdmsrl(MSR_FAM10H_NODE_ID, val);
 		nodes = ((val >> 3) & 7) + 1;
 	}
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 37830de..a57ec0d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1483,11 +1483,11 @@ void warn_pre_alternatives(void)
 EXPORT_SYMBOL_GPL(warn_pre_alternatives);
 #endif
 
-inline bool __static_cpu_has_safe(u16 bit)
+inline bool __static_cpu_has(u16 bit)
 {
 	return boot_cpu_has(bit);
 }
-EXPORT_SYMBOL_GPL(__static_cpu_has_safe);
+EXPORT_SYMBOL_GPL(__static_cpu_has);
 
 static void bsp_resume(void)
 {
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index e574b85..3dce1ca 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -362,7 +362,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
 	/* make room for real-mode segments */
 	tsk->thread.sp0 += 16;
 
-	if (static_cpu_has_safe(X86_FEATURE_SEP))
+	if (static_cpu_has(X86_FEATURE_SEP))
 		tsk->thread.sysenter_cs = 0;
 
 	load_sp0(tss, &tsk->thread);
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index cd83d47..3a4b39a 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1431,7 +1431,7 @@ static int __init intel_pstate_init(void)
 	if (!all_cpu_data)
 		return -ENOMEM;
 
-	if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) {
+	if (static_cpu_has(X86_FEATURE_HWP) && !no_hwp) {
 		pr_info("intel_pstate: HWP enabled\n");
 		hwp_active++;
 	}
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e99ccd6..87ce612 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -924,7 +924,7 @@ static int check_async_write(struct inode *inode, unsigned long bio_flags)
 	if (bio_flags & EXTENT_BIO_TREE_LOG)
 		return 0;
 #ifdef CONFIG_X86
-	if (static_cpu_has_safe(X86_FEATURE_XMM4_2))
+	if (static_cpu_has(X86_FEATURE_XMM4_2))
 		return 0;
 #endif
 	return 1;
-- 
1.8.5.6

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


#1312579

FromAndy Lutomirski <luto@amacapital.net>
Date2016-01-20 00:30 +0100
Message-ID<qSNSO-6gl-15@gated-at.bofh.it>
In reply to#1312577
On Tue, Jan 19, 2016 at 3:10 PM, Borislav Petkov <bp@suse.de> wrote:
> On Tue, Jan 19, 2016 at 02:57:14PM +0100, Borislav Petkov wrote:
>> Patch removing it below.
>
> Andy has a point: I should simply drop static_cpu_has and kill the "_safe"
> suffix of the remaining variant:
>

Is this on top of Brian's patch?  I think we should do both or neither.

--Andy

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


#1312593

FromBoris Petkov <bp@suse.de>
Date2016-01-20 01:00 +0100
Message-ID<qSOlQ-6sp-5@gated-at.bofh.it>
In reply to#1312579
Andy Lutomirski <luto@amacapital.net> wrote:

>Is this on top of Brian's patch?  I think we should do both or >neither.

Of course. I'll prep a branch tomorrow for the build bot to smoke-test.


-- 
Sent from a small device: formatting sux and brevity is inevitable. 

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


#1312861 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

From"H. Peter Anvin" <hpa@zytor.com>
Date2016-01-20 05:10 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSSfM-16M-51@gated-at.bofh.it>
In reply to#1312262
On 01/19/16 05:57, Borislav Petkov wrote:
> 
> old insn VA: 0xffffffff8108c0d0, CPU feat: X86_BUG_SYSRET_SS_ATTRS, size: 2, padlen: 0
> __switch_to:
>  ffffffff8108c0d0:      eb 70                   jmp ffffffff8108c142
> repl insn: 0xffffffff8ca7a1a7, size: 0
> 

This is the only one I could possibly imagine mattering.  Would it be
possible to get the disassembly here?

	-hpa

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


#1313096 — Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init

FromBorislav Petkov <bp@suse.de>
Date2016-01-20 11:40 +0100
SubjectRe: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Message-ID<qSYld-56e-23@gated-at.bofh.it>
In reply to#1312861
On Tue, Jan 19, 2016 at 08:03:55PM -0800, H. Peter Anvin wrote:
> On 01/19/16 05:57, Borislav Petkov wrote:
> > 
> > old insn VA: 0xffffffff8108c0d0, CPU feat: X86_BUG_SYSRET_SS_ATTRS, size: 2, padlen: 0
> > __switch_to:
> >  ffffffff8108c0d0:      eb 70                   jmp ffffffff8108c142
> > repl insn: 0xffffffff8ca7a1a7, size: 0
> > 
> 
> This is the only one I could possibly imagine mattering.  Would it be
> possible to get the disassembly here?

Sure, I've kept the vmlinux, see below:

ffffffff8108c0d0:       eb 70                   jmp    ffffffff8108c142 <__switch_to+0x838>

jumps to:

ffffffff8108c142:       48 ff 05 b7 08 aa 0b    incq   0xbaa08b7(%rip)

which is something-gcov. In any case, it jumps over the SS fixup code:

        if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {

		...

                unsigned short ss_sel;
                savesegment(ss, ss_sel);
                if (ss_sel != __KERNEL_DS)
                        loadsegment(ss, __KERNEL_DS);
        }

I guess we could fix that with an alternative_call() where @oldinstr is
empty so that on !X86_BUG_SYSRET_SS_ATTRS machines we simply return and
on the others, we do a CALL fixup_ss or so.

We have to pay attention to clobbers, though, similar to the POPCNT fun
in __arch_hweight32().

ffffffff8108b90a <__switch_to>:
ffffffff8108b90a:       55                      push   %rbp
ffffffff8108b90b:       48 8d 87 c0 2d 00 00    lea    0x2dc0(%rdi),%rax
ffffffff8108b912:       48 c7 c1 80 f6 1d 00    mov    $0x1df680,%rcx
ffffffff8108b919:       48 89 e5                mov    %rsp,%rbp
ffffffff8108b91c:       41 57                   push   %r15
ffffffff8108b91e:       45 31 ff                xor    %r15d,%r15d
ffffffff8108b921:       41 56                   push   %r14

...

ffffffff8108c0c2:       48 ff 05 07 09 aa 0b    incq   0xbaa0907(%rip)        # ffffffff8cb2c9d0 <__gcov0.__switch_to+0xc0>
ffffffff8108c0c9:       48 ff 05 08 09 aa 0b    incq   0xbaa0908(%rip)        # ffffffff8cb2c9d8 <__gcov0.__switch_to+0xc8>
ffffffff8108c0d0:       eb 70                   jmp    ffffffff8108c142 <__switch_to+0x838>
ffffffff8108c0d2:       48 ff 05 07 09 aa 0b    incq   0xbaa0907(%rip)        # ffffffff8cb2c9e0 <__gcov0.__switch_to+0xd0>
ffffffff8108c0d9:       48 ff 05 08 09 aa 0b    incq   0xbaa0908(%rip)        # ffffffff8cb2c9e8 <__gcov0.__switch_to+0xd8>
ffffffff8108c0e0:       48 ff 05 11 09 aa 0b    incq   0xbaa0911(%rip)        # ffffffff8cb2c9f8 <__gcov0.__switch_to+0xe8>
ffffffff8108c0e7:       66 8c d0                mov    %ss,%ax
ffffffff8108c0ea:       66 83 f8 18             cmp    $0x18,%ax
ffffffff8108c0ee:       75 17                   jne    ffffffff8108c107 <__switch_to+0x7fd>
ffffffff8108c0f0:       eb 57                   jmp    ffffffff8108c149 <__switch_to+0x83f>
ffffffff8108c0f2:       48 ff 05 cf 08 aa 0b    incq   0xbaa08cf(%rip)        # ffffffff8cb2c9c8 <__gcov0.__switch_to+0xb8>
ffffffff8108c0f9:       e8 db b0 01 00          callq  ffffffff810a71d9 <warn_pre_alternatives>
ffffffff8108c0fe:       48 ff 05 eb 08 aa 0b    incq   0xbaa08eb(%rip)        # ffffffff8cb2c9f0 <__gcov0.__switch_to+0xe0>
ffffffff8108c105:       eb 3b                   jmp    ffffffff8108c142 <__switch_to+0x838>
ffffffff8108c107:       48 ff 05 fa 08 aa 0b    incq   0xbaa08fa(%rip)        # ffffffff8cb2ca08 <__gcov0.__switch_to+0xf8>
ffffffff8108c10e:       b8 18 00 00 00          mov    $0x18,%eax
ffffffff8108c113:       8e d0                   mov    %eax,%ss
ffffffff8108c115:       48 ff 05 f4 08 aa 0b    incq   0xbaa08f4(%rip)        # ffffffff8cb2ca10 <__gcov0.__switch_to+0x100>
ffffffff8108c11c:       eb 2b                   jmp    ffffffff8108c149 <__switch_to+0x83f>
ffffffff8108c11e:       48 ff 05 9b 02 aa 0b    incq   0xbaa029b(%rip)        # ffffffff8cb2c3c0 <__gcov0.copy_xregs_to_kernel+0x30>
ffffffff8108c125:       e9 91 f9 ff ff          jmpq   ffffffff8108babb <__switch_to+0x1b1>
ffffffff8108c12a:       48 ff 05 bf 02 aa 0b    incq   0xbaa02bf(%rip)        # ffffffff8cb2c3f0 <__gcov0.copy_kernel_to_xregs+0x20>
ffffffff8108c131:       e9 84 fe ff ff          jmpq   ffffffff8108bfba <__switch_to+0x6b0>
ffffffff8108c136:       48 ff 05 43 02 aa 0b    incq   0xbaa0243(%rip)        # ffffffff8cb2c380 <__gcov0.copy_kernel_to_fxregs+0x20>
ffffffff8108c13d:       e9 db fe ff ff          jmpq   ffffffff8108c01d <__switch_to+0x713>
ffffffff8108c142:       48 ff 05 b7 08 aa 0b    incq   0xbaa08b7(%rip)        # ffffffff8cb2ca00 <__gcov0.__switch_to+0xf0>
ffffffff8108c149:       48 83 c4 28             add    $0x28,%rsp
ffffffff8108c14d:       4c 89 e0                mov    %r12,%rax
ffffffff8108c150:       5b                      pop    %rbx
ffffffff8108c151:       41 5c                   pop    %r12
ffffffff8108c153:       41 5d                   pop    %r13
ffffffff8108c155:       41 5e                   pop    %r14
ffffffff8108c157:       41 5f                   pop    %r15
ffffffff8108c159:       5d                      pop    %rbp
ffffffff8108c15a:       c3                      retq


-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

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


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | linux.kernel


csiph-web