History

Merge tag 'x86-cpu-2020-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 cpu updates from Ingo Molnar: "Misc updates: - Extend the x86 family/model macros with a steppings dimension, because x86 life isn't complex enough and Intel uses steppings to differentiate between different CPUs. :-/ - Convert the TSC deadline timer quirks to the steppings macros. - Clean up asm mnemonics. - Fix the handling of an AMD erratum, or in other words, fix a kernel erratum" * tag 'x86-cpu-2020-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/cpu: Use RDRAND and RDSEED mnemonics in archrandom.h x86/cpu: Use INVPCID mnemonic in invpcid.h x86/cpu/amd: Make erratum #1054 a legacy erratum x86/apic: Convert the TSC deadline timer matching to steppings macro x86/cpu: Add a X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS() macro x86/cpu: Add a steppings field to struct x86_cpu_id

Linus Torvalds committed 6 years ago

Commit eff5dda2 parents 17e0a7c 3d81b3d7 files · +59 −74Browse files

Unified · Split

7 files
  1. arch/x86/include/asm/archrandom.h +8 −18
  2. arch/x86/include/asm/cpu_device_id.h +28 −3
  3. arch/x86/include/asm/invpcid.h +2 −5
  4. arch/x86/kernel/apic/apic.c +12 −45
  5. arch/x86/kernel/cpu/amd.c +1 −2
  6. arch/x86/kernel/cpu/match.c +6 −1
  7. include/linux/mod_devicetable.h +2 −0
arch/x86/include/asm/archrandom.h+8−18
@@ -15,16 +15,6 @@ · 14 unmodified lines
1515
1616 #define RDRAND_RETRY_LOOPS 10
1717
18−#define RDRAND_INT ".byte 0x0f,0xc7,0xf0"
19−#define RDSEED_INT ".byte 0x0f,0xc7,0xf8"
20−#ifdef CONFIG_X86_64
21−# define RDRAND_LONG ".byte 0x48,0x0f,0xc7,0xf0"
22−# define RDSEED_LONG ".byte 0x48,0x0f,0xc7,0xf8"
23−#else
24−# define RDRAND_LONG RDRAND_INT
25−# define RDSEED_LONG RDSEED_INT
26−#endif
27−
2818 /* Unconditional execution of RDRAND and RDSEED */
2919
3020 static inline bool __must_check rdrand_long(unsigned long *v)
@@ -32,9 +22,9 @@ static inline bool __must_check rdrand_long(unsigned long *v) · 1 unmodified line
3222 bool ok;
3323 unsigned int retry = RDRAND_RETRY_LOOPS;
3424 do {
35− asm volatile(RDRAND_LONG
25+ asm volatile("rdrand %[out]"
3626 CC_SET(c)
37− : CC_OUT(c) (ok), "=a" (*v));
27+ : CC_OUT(c) (ok), [out] "=r" (*v));
3828 if (ok)
3929 return true;
4030 } while (--retry);
@@ -46,9 +36,9 @@ static inline bool __must_check rdrand_int(unsigned int *v) · 5 unmodified lines
4636 bool ok;
4737 unsigned int retry = RDRAND_RETRY_LOOPS;
4838 do {
49− asm volatile(RDRAND_INT
39+ asm volatile("rdrand %[out]"
5040 CC_SET(c)
51− : CC_OUT(c) (ok), "=a" (*v));
41+ : CC_OUT(c) (ok), [out] "=r" (*v));
5242 if (ok)
5343 return true;
5444 } while (--retry);
@@ -58,18 +48,18 @@ static inline bool __must_check rdrand_int(unsigned int *v) · 3 unmodified lines
5848 static inline bool __must_check rdseed_long(unsigned long *v)
5949 {
6050 bool ok;
61− asm volatile(RDSEED_LONG
51+ asm volatile("rdseed %[out]"
6252 CC_SET(c)
63− : CC_OUT(c) (ok), "=a" (*v));
53+ : CC_OUT(c) (ok), [out] "=r" (*v));
6454 return ok;
6555 }
6656
6757 static inline bool __must_check rdseed_int(unsigned int *v)
6858 {
6959 bool ok;
70− asm volatile(RDSEED_INT
60+ asm volatile("rdseed %[out]"
7161 CC_SET(c)
72− : CC_OUT(c) (ok), "=a" (*v));
62+ : CC_OUT(c) (ok), [out] "=r" (*v));
7363 return ok;
7464 }
7565
arch/x86/include/asm/cpu_device_id.h+28−3
@@ -20,12 +20,14 @@ · 19 unmodified lines
2020 #define X86_CENTAUR_FAM6_C7_D 0xd
2121 #define X86_CENTAUR_FAM6_NANO 0xf
2222
23+#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins)
2324 /**
24− * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Base macro for CPU matching
25+ * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
2526 * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
2627 * The name is expanded to X86_VENDOR_@_vendor
2728 * @_family: The family number or X86_FAMILY_ANY
2829 * @_model: The model number, model constant or X86_MODEL_ANY
30+ * @_steppings: Bitmask for steppings, stepping constant or X86_STEPPING_ANY
2931 * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY
3032 * @_data: Driver specific data or NULL. The internal storage
3133 * format is unsigned long. The supplied value, pointer
@@ -37,15 +39,34 @@ · 5 unmodified lines
3739 * into another macro at the usage site for good reasons, then please
3840 * start this local macro with X86_MATCH to allow easy grepping.
3941 */
40−#define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(_vendor, _family, _model, \
41− _feature, _data) { \
42+#define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \
43+ _steppings, _feature, _data) { \
4244 .vendor = X86_VENDOR_##_vendor, \
4345 .family = _family, \
4446 .model = _model, \
47+ .steppings = _steppings, \
4548 .feature = _feature, \
4649 .driver_data = (unsigned long) _data \
4750 }
4851
52+/**
53+ * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Macro for CPU matching
54+ * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
55+ * The name is expanded to X86_VENDOR_@_vendor
56+ * @_family: The family number or X86_FAMILY_ANY
57+ * @_model: The model number, model constant or X86_MODEL_ANY
58+ * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY
59+ * @_data: Driver specific data or NULL. The internal storage
60+ * format is unsigned long. The supplied value, pointer
61+ * etc. is casted to unsigned long internally.
62+ *
63+ * The steppings arguments of X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE() is
64+ * set to wildcards.
65+ */
66+#define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, model, feature, data) \
67+ X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(vendor, family, model, \
68+ X86_STEPPING_ANY, feature, data)
69+
4970 /**
5071 * X86_MATCH_VENDOR_FAM_FEATURE - Macro for matching vendor, family and CPU feature
5172 * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
@@ -139,6 +160,10 @@ · 87 unmodified lines
139160 #define X86_MATCH_INTEL_FAM6_MODEL(model, data) \
140161 X86_MATCH_VENDOR_FAM_MODEL(INTEL, 6, INTEL_FAM6_##model, data)
141162
163+#define X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(model, steppings, data) \
164+ X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
165+ steppings, X86_FEATURE_ANY, data)
166+
142167 /*
143168 * Match specific microcode revisions.
144169 *
arch/x86/include/asm/invpcid.h+2−5
@@ -12,12 +12,9 @@ static inline void __invpcid(unsigned long pcid, unsigned long addr, · 11 unmodified lines
1212 * stale TLB entries and, especially if we're flushing global
1313 * mappings, we don't want the compiler to reorder any subsequent
1414 * memory accesses before the TLB flush.
15− *
16− * The hex opcode is invpcid (%ecx), %eax in 32-bit mode and
17− * invpcid (%rcx), %rax in long mode.
1815 */
19− asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01"
20− : : "m" (desc), "a" (type), "c" (&desc) : "memory");
16+ asm volatile("invpcid %[desc], %[type]"
17+ :: [desc] "m" (desc), [type] "r" (type) : "memory");
2118 }
2219
2320 #define INVPCID_TYPE_INDIV_ADDR 0
arch/x86/kernel/apic/apic.c+12−45
@@ -544,46 +544,20 @@ static struct clock_event_device lapic_clockevent = { · 543 unmodified lines
544544 };
545545 static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
546546
547−static __init u32 hsx_deadline_rev(void)
548−{
549− switch (boot_cpu_data.x86_stepping) {
550− case 0x02: return 0x3a; /* EP */
551− case 0x04: return 0x0f; /* EX */
552− }
553−
554− return ~0U;
555−}
556−
557−static __init u32 bdx_deadline_rev(void)
558−{
559− switch (boot_cpu_data.x86_stepping) {
560− case 0x02: return 0x00000011;
561− case 0x03: return 0x0700000e;
562− case 0x04: return 0x0f00000c;
563− case 0x05: return 0x0e000003;
564− }
565−
566− return ~0U;
567−}
568−
569−static __init u32 skx_deadline_rev(void)
570−{
571− switch (boot_cpu_data.x86_stepping) {
572− case 0x03: return 0x01000136;
573− case 0x04: return 0x02000014;
574− }
547+static const struct x86_cpu_id deadline_match[] __initconst = {
548+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x2, 0x2), 0x3a), /* EP */
549+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x4, 0x4), 0x0f), /* EX */
575550
576− if (boot_cpu_data.x86_stepping > 4)
577− return 0;
551+ X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
578552
579− return ~0U;
580−}
553+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x2, 0x2), 0x00000011),
554+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x3, 0x3), 0x0700000e),
555+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x4, 0x4), 0x0f00000c),
556+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x5, 0x5), 0x0e000003),
581557
582−static const struct x86_cpu_id deadline_match[] __initconst = {
583− X86_MATCH_INTEL_FAM6_MODEL( HASWELL_X, &hsx_deadline_rev),
584− X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
585− X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_D, &bdx_deadline_rev),
586− X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE_X, &skx_deadline_rev),
558+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x3, 0x3), 0x01000136),
559+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x4, 0x4), 0x02000014),
560+ X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x5, 0xf), 0),
587561
588562 X86_MATCH_INTEL_FAM6_MODEL( HASWELL, 0x22),
589563 X86_MATCH_INTEL_FAM6_MODEL( HASWELL_L, 0x20),
@@ -615,14 +589,7 @@ static __init bool apic_validate_deadline_timer(void) · 25 unmodified lines
615589 if (!m)
616590 return true;
617591
618− /*
619− * Function pointers will have the MSB set due to address layout,
620− * immediate revisions will not.
621− */
622− if ((long)m->driver_data < 0)
623− rev = ((u32 (*)(void))(m->driver_data))();
624− else
625− rev = (u32)m->driver_data;
592+ rev = (u32)m->driver_data;
626593
627594 if (boot_cpu_data.microcode >= rev)
628595 return true;
arch/x86/kernel/cpu/amd.c+1−2
@@ -1145,8 +1145,7 @@ static const int amd_erratum_383[] = · 1144 unmodified lines
11451145
11461146 /* #1054: Instructions Retired Performance Counter May Be Inaccurate */
11471147 static const int amd_erratum_1054[] =
1148− AMD_OSVW_ERRATUM(0, AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
1149−
1148+ AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
11501149
11511150 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
11521151 {
arch/x86/kernel/cpu/match.c+6−1
@@ -39,13 +39,18 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) · 38 unmodified lines
3939 const struct x86_cpu_id *m;
4040 struct cpuinfo_x86 *c = &boot_cpu_data;
4141
42− for (m = match; m->vendor | m->family | m->model | m->feature; m++) {
42+ for (m = match;
43+ m->vendor | m->family | m->model | m->steppings | m->feature;
44+ m++) {
4345 if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
4446 continue;
4547 if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
4648 continue;
4749 if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
4850 continue;
51+ if (m->steppings != X86_STEPPING_ANY &&
52+ !(BIT(c->x86_stepping) & m->steppings))
53+ continue;
4954 if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
5055 continue;
5156 return m;
include/linux/mod_devicetable.h+2−0
@@ -663,6 +663,7 @@ struct x86_cpu_id { · 662 unmodified lines
663663 __u16 vendor;
664664 __u16 family;
665665 __u16 model;
666+ __u16 steppings;
666667 __u16 feature; /* bit index */
667668 kernel_ulong_t driver_data;
668669 };
@@ -671,6 +672,7 @@ struct x86_cpu_id { · 2 unmodified lines
671672 #define X86_VENDOR_ANY 0xffff
672673 #define X86_FAMILY_ANY 0
673674 #define X86_MODEL_ANY 0
675+#define X86_STEPPING_ANY 0
674676 #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
675677
676678 /*

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t