From: Nikolay Borisov nik.borisov@suse.com
suse inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I7RQ67
Reference: https://github.com/SUSE/kernel/commit/9aee1654a4063ca19b8f4bda22b157b465bf9b...
--------------------------------
suse-commit: fc75ce0587a9184fc130351acb6474d84203ca3e
Signed-off-by: Nikolay Borisov nik.borisov@suse.com
Conflicts: arch/x86/include/asm/cpufeature.h arch/x86/include/asm/cpufeatures.h tools/arch/x86/include/asm/cpufeatures.h
Signed-off-by: Jialin Zhang zhangjialin11@huawei.com --- arch/x86/include/asm/cpufeature.h | 23 +++++++++++++++++++---- arch/x86/include/asm/cpufeatures.h | 4 ++-- arch/x86/include/asm/processor.h | 5 ++++- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/cpu/common.c | 7 ++++++- arch/x86/kernel/cpu/mkcapflags.sh | 2 +- arch/x86/kernel/cpu/proc.c | 2 +- tools/arch/x86/include/asm/cpufeatures.h | 2 +- 8 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index f4cbc01c0bc4..39cbea8f06da 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -47,10 +47,14 @@ extern const char * const x86_power_flags[32]; * In order to save room, we index into this array by doing * X86_BUG_<name> - NCAPINTS*32. */ -extern const char * const x86_bug_flags[NBUGINTS*32]; +extern const char * const x86_bug_flags[(NBUGINTS+NEXTBUGINTS)*32]; + +#define IS_EXT_BUGBIT(bit) ((bit>>5) >= (NCAPINTS+NBUGINTS))
#define test_cpu_cap(c, bit) \ - arch_test_bit(bit, (unsigned long *)((c)->x86_capability)) + (IS_EXT_BUGBIT(bit) ? arch_test_bit((bit) - ((NCAPINTS+NBUGINTS)*32), \ + (unsigned long *)((c)->x86_ext_capability)) : \ + arch_test_bit(bit, (unsigned long *)((c)->x86_capability)))
/* * There are 32 bits/features in each mask word. The high bits @@ -137,14 +141,25 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
-#define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability)) +#define set_cpu_cap(c, bit) do { \ + if (IS_EXT_BUGBIT(bit)) \ + set_bit(bit - ((NCAPINTS+NBUGINTS))*32, \ + (unsigned long *)((c)->x86_ext_capability)); \ + else \ + set_bit(bit, (unsigned long *)((c)->x86_capability)); \ +} while (0) +
extern void setup_clear_cpu_cap(unsigned int bit); extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
#define setup_force_cpu_cap(bit) do { \ set_cpu_cap(&boot_cpu_data, bit); \ - set_bit(bit, (unsigned long *)cpu_caps_set); \ + if (IS_EXT_BUGBIT(bit)) \ + set_bit(bit - ((NCAPINTS+NBUGINTS))*32, \ + (unsigned long *)&cpu_caps_set[NCAPINTS+NBUGINTS]); \ + else \ + set_bit(bit, (unsigned long *)cpu_caps_set); \ } while (0)
#define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 60102962999c..d156d639570f 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -14,8 +14,8 @@ * Defines x86 CPU feature bits */ #define NCAPINTS 19 /* N 32-bit words worth of info */ -#define NBUGINTS 2 /* N 32-bit bug flags */ - +#define NBUGINTS 1 /* N 32-bit bug flags */ +#define NEXTBUGINTS 1 /* N 32-bit extended bug flags */ /* * 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 "", diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 8b3f8b406dbf..33cf8d30e19e 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -141,6 +141,9 @@ struct cpuinfo_x86 { /* Address space bits used by the cache internally */ u8 x86_cache_bits; unsigned initialized : 1; +#ifndef __GENKSYMS__ + __u32 x86_ext_capability[NEXTBUGINTS]; +#endif } __randomize_layout;
struct extra_cpuinfo_x86 { @@ -182,7 +185,7 @@ extern struct cpuinfo_x86 new_cpu_data; extern struct extra_cpuinfo_x86 extra_boot_cpu_data;
extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS]; -extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS]; +extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS + NEXTBUGINTS];
#ifdef CONFIG_SMP DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 82e9fd11b364..293c8d4a4328 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -441,7 +441,7 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start, instr = (u8 *)&a->instr_offset + a->instr_offset; replacement = (u8 *)&a->repl_offset + a->repl_offset; BUG_ON(a->instrlen > sizeof(insn_buff)); - BUG_ON(feature >= (NCAPINTS + NBUGINTS) * 32); + BUG_ON(feature >= (NCAPINTS + NBUGINTS + NEXTBUGINTS) * 32);
/* * Patch if either: diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index ba3d7c3c0eaf..9608633f49ff 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -592,7 +592,7 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)
/* Aligned to unsigned long to avoid split lock in atomic bitmap ops */ __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long)); -__u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long)); +__u32 cpu_caps_set[NCAPINTS + NBUGINTS + NEXTBUGINTS] __aligned(sizeof(unsigned long));
void load_percpu_segment(int cpu) { @@ -855,6 +855,11 @@ static void apply_forced_caps(struct cpuinfo_x86 *c) c->x86_capability[i] &= ~cpu_caps_cleared[i]; c->x86_capability[i] |= cpu_caps_set[i]; } + + for (i = 0; i < NEXTBUGINTS; i++) { + c->x86_ext_capability[i] |= cpu_caps_set[NCAPINTS+NBUGINTS + i]; + } + }
static void init_speculation_control(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh index b030882d2f6f..a07865f0e622 100644 --- a/arch/x86/kernel/cpu/mkcapflags.sh +++ b/arch/x86/kernel/cpu/mkcapflags.sh @@ -60,7 +60,7 @@ trap 'rm "$OUT"' EXIT dump_array "x86_cap_flags" "NCAPINTS*32" "X86_FEATURE_" "" $2 echo ""
- dump_array "x86_bug_flags" "NBUGINTS*32" "X86_BUG_" "NCAPINTS*32" $2 + dump_array "x86_bug_flags" "(NBUGINTS+NEXTBUGINTS)*32" "X86_BUG_" "NCAPINTS*32" $2 echo ""
echo "#ifdef CONFIG_X86_VMX_FEATURE_NAMES" diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 7810c75abdd4..daa078c9e208 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -126,7 +126,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) #endif
seq_puts(m, "\nbugs\t\t:"); - for (i = 0; i < 32*NBUGINTS; i++) { + for (i = 0; i < 32*(NBUGINTS+NEXTBUGINTS); i++) { unsigned int bug_bit = 32*NCAPINTS + i;
if (cpu_has_bug(c, bug_bit) && x86_bug_flags[i]) diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 6186aebff9c0..238287abee0c 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -14,7 +14,7 @@ * Defines x86 CPU feature bits */ #define NCAPINTS 19 /* N 32-bit words worth of info */ -#define NBUGINTS 2 /* N 32-bit bug flags */ +#define NBUGINTS 1 /* N 32-bit bug flags */
/* * Note: If the comment begins with a quoted string, that string is used