Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1311015 > unrolled thread
| Started by | Brian Gerst <brgerst@gmail.com> |
|---|---|
| First post | 2016-01-16 20:30 +0100 |
| Last post | 2016-01-20 17:20 +0100 |
| Articles | 20 on this page of 42 — 5 participants |
Back to article view | Back to linux.kernel
[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 →
| From | Brian Gerst <brgerst@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-16 20:40 +0100 |
| Subject | Re: [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]
| From | Brian Gerst <brgerst@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-17 11:40 +0100 |
| Subject | Re: [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]
| From | Brian Gerst <brgerst@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-18 19:20 +0100 |
| Subject | Re: [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]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-18 19:40 +0100 |
| Subject | Re: [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]
| From | "H. Peter Anvin" <hpa@zytor.com> |
|---|---|
| Date | 2016-01-18 20:50 +0100 |
| Subject | Re: [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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-19 00:10 +0100 |
| Subject | Re: [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]
| From | "H. Peter Anvin" <hpa@zytor.com> |
|---|---|
| Date | 2016-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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-19 00:30 +0100 |
| Subject | Re: [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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-19 15:00 +0100 |
| Subject | Re: [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 *)¤t_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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-19 17:30 +0100 |
| Subject | Re: [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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-20 00:20 +0100 |
| Subject | Re: [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]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-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]
| From | Boris Petkov <bp@suse.de> |
|---|---|
| Date | 2016-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]
| From | "H. Peter Anvin" <hpa@zytor.com> |
|---|---|
| Date | 2016-01-20 05:10 +0100 |
| Subject | Re: [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]
| From | Borislav Petkov <bp@suse.de> |
|---|---|
| Date | 2016-01-20 11:40 +0100 |
| Subject | Re: [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