From: Borislav Petkov <bp@suse.de>
To: "H. Peter Anvin" <hpa@zytor.com>
Cc: Brian Gerst <brgerst@gmail.com>,
the arch/x86 maintainers <x86@kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Ingo Molnar <mingo@kernel.org>,
Denys Vlasenko <dvlasenk@redhat.com>,
Andy Lutomirski <luto@amacapital.net>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: [PATCH] x86: static_cpu_has_safe: discard dynamic check after init
Date: Wed, 20 Jan 2016 17:04:51 +0100 [thread overview]
Message-ID: <20160120160451.GG23350@pd.tnic> (raw)
In-Reply-To: <569FA333.7020401@zytor.com>
On Wed, Jan 20, 2016 at 07:09:39AM -0800, H. Peter Anvin wrote:
> But then you're using testl and get long immediates.
>
> (And the parentheses around boot_cpu_data->x86_capability are redundant.)
Right.
Ok, below is what builds here. So no SOBs etc.
All this include hell wankery is so that we can use boot_cpu_data in
cpufeature.h. And that's not simple because boot/mkcpustr.c includes it
too so if I carve out struct cpuinfo_x86 to a separate asm/cpuinfo.h
header, it complains because it doesn't see it.
Thus this _ASM_BOOT_MKCPUSTR_ yucky marker to stop arch/x86/boot from
including it.
I'm very open to better ideas. :-)
Other than that, we do:
+ "6: testb %[bitnum],%[cap_word]\n"
+ " jnz %l[t_yes]\n"
+ " jmp %l[t_no]\n"
+ ".previous\n"
+ : : "i" (bit), "i" (X86_FEATURE_ALWAYS),
+ [bitnum] "i" (1 << (bit & 7)),
+ [cap_word] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
and that has the TESTB.
Thoughts?
---
arch/x86/boot/mkcpustr.c | 5 +++
arch/x86/include/asm/cpufeature.h | 34 +++++++++++++-----
arch/x86/include/asm/cpuinfo.h | 73 +++++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/processor.h | 65 ----------------------------------
arch/x86/kernel/cpu/common.c | 6 ----
arch/x86/kernel/vmlinux.lds.S | 9 +++--
6 files changed, 110 insertions(+), 82 deletions(-)
create mode 100644 arch/x86/include/asm/cpuinfo.h
diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c
index 637097e66a62..c32113a0e3d4 100644
--- a/arch/x86/boot/mkcpustr.c
+++ b/arch/x86/boot/mkcpustr.c
@@ -17,6 +17,11 @@
#include "../include/asm/required-features.h"
#include "../include/asm/disabled-features.h"
+
+/*
+ * Stop cpufeature.h from including cpuinfo.h in kernel proper.
+ */
+#define _ASM_BOOT_MKCPUSTR_
#include "../include/asm/cpufeature.h"
#include "../kernel/cpu/capflags.c"
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 7ad8c9464297..a16cee2376c4 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -15,6 +15,10 @@
#define NCAPINTS 16 /* N 32-bit words worth of info */
#define NBUGINTS 1 /* N 32-bit bug flags */
+#ifndef _ASM_BOOT_MKCPUSTR_
+#include <asm/cpuinfo.h>
+#endif
+
/*
* Note: If the comment begins with a quoted string, that string is used
* in /proc/cpuinfo instead of the macro name. If the string is "",
@@ -412,7 +416,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().
@@ -505,7 +508,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
{
#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 +533,23 @@ 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 .altinstr_aux,\"ax\"\n"
+ "6: testb %[bitnum],%[cap_word]\n"
+ " jnz %l[t_yes]\n"
+ " jmp %l[t_no]\n"
+ ".previous\n"
+ : : "i" (bit), "i" (X86_FEATURE_ALWAYS),
+ [bitnum] "i" (1 << (bit & 7)),
+ [cap_word] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
+ : : 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 +581,16 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
"5: movb $1,%0\n"
"6:\n"
".previous\n"
+ ".section .altinstr_aux,\"ax\"\n"
+ "7: testb %[bitnum],%[cap_word]\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),
+ [bitnum] "i" (1 << (bit & 7)),
+ [cap_word] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]));
+ return (flag != 0);
#endif /* CC_HAVE_ASM_GOTO */
}
diff --git a/arch/x86/include/asm/cpuinfo.h b/arch/x86/include/asm/cpuinfo.h
new file mode 100644
index 000000000000..f906b538fdb4
--- /dev/null
+++ b/arch/x86/include/asm/cpuinfo.h
@@ -0,0 +1,73 @@
+#ifndef _ASM_X86_CPUINFO_H
+#define _ASM_X86_CPUINFO_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+/*
+ * CPU type and hardware bug flags. Kept separately for each CPU.
+ * Members of this structure are referenced in head.S, so think twice
+ * before touching them. [mj]
+ */
+
+struct cpuinfo_x86 {
+ __u8 x86; /* CPU family */
+ __u8 x86_vendor; /* CPU vendor */
+ __u8 x86_model;
+ __u8 x86_mask;
+#ifdef CONFIG_X86_32
+ char wp_works_ok; /* It doesn't on 386's */
+
+ /* Problems on some 486Dx4's and old 386's: */
+ char rfu;
+ char pad0;
+ char pad1;
+#else
+ /* Number of 4K pages in DTLB/ITLB combined(in pages): */
+ int x86_tlbsize;
+#endif
+ __u8 x86_virt_bits;
+ __u8 x86_phys_bits;
+ /* CPUID returned core id bits: */
+ __u8 x86_coreid_bits;
+ /* Max extended CPUID function supported: */
+ __u32 extended_cpuid_level;
+ /* Maximum supported CPUID level, -1=no CPUID: */
+ int cpuid_level;
+ __u32 x86_capability[NCAPINTS + NBUGINTS];
+ char x86_vendor_id[16];
+ char x86_model_id[64];
+ /* in KB - valid for CPUS which support this call: */
+ int x86_cache_size;
+ int x86_cache_alignment; /* In bytes */
+ /* Cache QoS architectural values: */
+ int x86_cache_max_rmid; /* max index */
+ int x86_cache_occ_scale; /* scale to bytes */
+ int x86_power;
+ unsigned long loops_per_jiffy;
+ /* cpuid returned max cores value: */
+ u16 x86_max_cores;
+ u16 apicid;
+ u16 initial_apicid;
+ u16 x86_clflush_size;
+ /* number of cores as seen by the OS: */
+ u16 booted_cores;
+ /* Physical processor id: */
+ u16 phys_proc_id;
+ /* Core id: */
+ u16 cpu_core_id;
+ /* Compute unit id */
+ u8 compute_unit_id;
+ /* Index into per_cpu list: */
+ u16 cpu_index;
+ u32 microcode;
+};
+
+/*
+ * capabilities of CPUs
+ */
+extern struct cpuinfo_x86 boot_cpu_data;
+extern struct cpuinfo_x86 new_cpu_data;
+#endif
+
+#endif /* _ASM_X86_CPUINFO_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2d5a50cb61a2..240d8f8d8c1b 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -79,65 +79,6 @@ extern u16 __read_mostly tlb_lld_2m[NR_INFO];
extern u16 __read_mostly tlb_lld_4m[NR_INFO];
extern u16 __read_mostly tlb_lld_1g[NR_INFO];
-/*
- * CPU type and hardware bug flags. Kept separately for each CPU.
- * Members of this structure are referenced in head.S, so think twice
- * before touching them. [mj]
- */
-
-struct cpuinfo_x86 {
- __u8 x86; /* CPU family */
- __u8 x86_vendor; /* CPU vendor */
- __u8 x86_model;
- __u8 x86_mask;
-#ifdef CONFIG_X86_32
- char wp_works_ok; /* It doesn't on 386's */
-
- /* Problems on some 486Dx4's and old 386's: */
- char rfu;
- char pad0;
- char pad1;
-#else
- /* Number of 4K pages in DTLB/ITLB combined(in pages): */
- int x86_tlbsize;
-#endif
- __u8 x86_virt_bits;
- __u8 x86_phys_bits;
- /* CPUID returned core id bits: */
- __u8 x86_coreid_bits;
- /* Max extended CPUID function supported: */
- __u32 extended_cpuid_level;
- /* Maximum supported CPUID level, -1=no CPUID: */
- int cpuid_level;
- __u32 x86_capability[NCAPINTS + NBUGINTS];
- char x86_vendor_id[16];
- char x86_model_id[64];
- /* in KB - valid for CPUS which support this call: */
- int x86_cache_size;
- int x86_cache_alignment; /* In bytes */
- /* Cache QoS architectural values: */
- int x86_cache_max_rmid; /* max index */
- int x86_cache_occ_scale; /* scale to bytes */
- int x86_power;
- unsigned long loops_per_jiffy;
- /* cpuid returned max cores value: */
- u16 x86_max_cores;
- u16 apicid;
- u16 initial_apicid;
- u16 x86_clflush_size;
- /* number of cores as seen by the OS: */
- u16 booted_cores;
- /* Physical processor id: */
- u16 phys_proc_id;
- /* Core id: */
- u16 cpu_core_id;
- /* Compute unit id */
- u8 compute_unit_id;
- /* Index into per_cpu list: */
- u16 cpu_index;
- u32 microcode;
-};
-
#define X86_VENDOR_INTEL 0
#define X86_VENDOR_CYRIX 1
#define X86_VENDOR_AMD 2
@@ -149,12 +90,6 @@ struct cpuinfo_x86 {
#define X86_VENDOR_UNKNOWN 0xff
-/*
- * capabilities of CPUs
- */
-extern struct cpuinfo_x86 boot_cpu_data;
-extern struct cpuinfo_x86 new_cpu_data;
-
extern struct tss_struct doublefault_tss;
extern __u32 cpu_caps_cleared[NCAPINTS];
extern __u32 cpu_caps_set[NCAPINTS];
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 37830de8f60a..897c65bd3faa 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 35868bf529b9..486dc0e60599 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -244,9 +244,14 @@ SECTIONS
*/
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
*(.altinstr_replacement)
+
/*
- * Auxiliary section for misc instruction patching tasks. See
- * static_cpu_has(), for an example.
+ * Section for code used exclusively before alternatives are
+ * run. All references to such code must be patched out by
+ * alternatives, normally by using a patch with
+ * X86_FEATURE_ALWAYS.
+ *
+ * See static_cpu_has() for an example.
*/
*(.altinstr_aux)
}
--
2.3.5
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
--
next prev parent reply other threads:[~2016-01-20 16:05 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-16 19:22 [PATCH] x86: static_cpu_has_safe: discard dynamic check after init Brian Gerst
2016-01-16 19:36 ` Borislav Petkov
2016-01-16 19:58 ` Brian Gerst
2016-01-17 10:33 ` Borislav Petkov
2016-01-18 16:52 ` Brian Gerst
2016-01-18 17:49 ` Andy Lutomirski
2016-01-18 18:14 ` Borislav Petkov
2016-01-18 18:29 ` Andy Lutomirski
2016-01-18 18:39 ` Borislav Petkov
2016-01-18 19:45 ` H. Peter Anvin
2016-01-18 23:05 ` Borislav Petkov
2016-01-18 23:13 ` H. Peter Anvin
2016-01-18 23:25 ` Borislav Petkov
2016-01-19 13:57 ` Borislav Petkov
2016-01-19 16:23 ` Borislav Petkov
2016-01-19 23:10 ` Borislav Petkov
2016-01-19 23:26 ` Andy Lutomirski
2016-01-19 23:49 ` Boris Petkov
2016-01-20 4:03 ` H. Peter Anvin
2016-01-20 10:33 ` Borislav Petkov
2016-01-20 10:41 ` H. Peter Anvin
2016-01-21 22:14 ` Borislav Petkov
2016-01-21 22:22 ` H. Peter Anvin
2016-01-21 22:56 ` Borislav Petkov
2016-01-21 23:36 ` H. Peter Anvin
2016-01-21 23:37 ` H. Peter Anvin
2016-01-22 10:32 ` Borislav Petkov
2016-01-18 18:51 ` Borislav Petkov
2016-01-19 1:10 ` Borislav Petkov
2016-01-19 1:33 ` H. Peter Anvin
2016-01-19 9:22 ` Borislav Petkov
2016-01-20 4:02 ` H. Peter Anvin
2016-01-20 4:39 ` Brian Gerst
2016-01-20 4:42 ` H. Peter Anvin
2016-01-20 10:50 ` Borislav Petkov
2016-01-20 10:55 ` H. Peter Anvin
2016-01-20 11:05 ` Borislav Petkov
2016-01-20 14:48 ` H. Peter Anvin
2016-01-20 15:01 ` Borislav Petkov
2016-01-20 15:09 ` H. Peter Anvin
2016-01-20 16:04 ` Borislav Petkov [this message]
2016-01-20 16:16 ` H. Peter Anvin
-- strict thread matches above, loose matches on Subject: below --
2016-01-23 6:50 [PATCH] x86/head_64.S: do not use temporary register to check alignment Alexander Kuleshov
2016-01-26 9:31 ` Borislav Petkov
2016-01-26 21:12 [PATCH 00/10] tip-queue 2016-01-26, rest Borislav Petkov
2016-01-26 21:12 ` [PATCH 01/10] x86/asm: Add condition codes clobber to memory barrier macros Borislav Petkov
2016-01-26 21:12 ` [PATCH 02/10] x86/asm: Drop a comment left over from X86_OOSTORE Borislav Petkov
2016-01-26 21:12 ` [PATCH 03/10] x86/asm: Tweak the comment about wmb() use for IO Borislav Petkov
2016-01-26 21:12 ` [PATCH 04/10] x86/cpufeature: Carve out X86_FEATURE_* Borislav Petkov
2016-01-30 13:18 ` [tip:x86/asm] " tip-bot for Borislav Petkov
2016-01-26 21:12 ` [PATCH 05/10] x86/cpufeature: Replace the old static_cpu_has() with safe variant Borislav Petkov
2016-01-30 13:19 ` [tip:x86/asm] " tip-bot for Borislav Petkov
2016-01-26 21:12 ` [PATCH 06/10] x86/cpufeature: Get rid of the non-asm goto variant Borislav Petkov
2016-01-27 3:36 ` Brian Gerst
2016-01-27 8:41 ` Borislav Petkov
2016-01-27 8:43 ` [PATCH -v1.1 " Borislav Petkov
2016-01-30 13:19 ` [tip:x86/asm] " tip-bot for Borislav Petkov
2016-01-27 8:45 ` [PATCH -v1.1 8/10] x86/alternatives: Discard dynamic check after init Borislav Petkov
2016-01-30 13:20 ` [tip:x86/asm] " tip-bot for Brian Gerst
2016-01-26 21:12 ` [PATCH 07/10] x86/alternatives: Add an auxilary section Borislav Petkov
2016-01-30 13:19 ` [tip:x86/asm] " tip-bot for Borislav Petkov
2016-01-26 21:12 ` [PATCH 08/10] x86/alternatives: Discard dynamic check after init Borislav Petkov
2016-01-26 21:12 ` [PATCH 09/10] x86/vdso: Use static_cpu_has() Borislav Petkov
2016-01-30 13:20 ` [tip:x86/asm] " tip-bot for Borislav Petkov
2016-01-26 21:12 ` [PATCH 10/10] x86/head_64: Simplify kernel load address alignment check Borislav Petkov
2016-01-30 13:20 ` [tip:x86/boot] x86/boot: " tip-bot for Alexander Kuleshov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160120160451.GG23350@pd.tnic \
--to=bp@suse.de \
--cc=brgerst@gmail.com \
--cc=dvlasenk@redhat.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=mingo@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.