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
15 15
16#define RDRAND_RETRY_LOOPS 1016#define RDRAND_RETRY_LOOPS 10
17 17
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
28/* Unconditional execution of RDRAND and RDSEED */18/* Unconditional execution of RDRAND and RDSEED */
29 19
30static inline bool __must_check rdrand_long(unsigned long *v)20static 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
32 bool ok;22 bool ok;
33 unsigned int retry = RDRAND_RETRY_LOOPS;23 unsigned int retry = RDRAND_RETRY_LOOPS;
34 do {24 do {
35 asm volatile(RDRAND_LONG25 asm volatile("rdrand %[out]"
36 CC_SET(c)26 CC_SET(c)
37 : CC_OUT(c) (ok), "=a" (*v));27 : CC_OUT(c) (ok), [out] "=r" (*v));
38 if (ok)28 if (ok)
39 return true;29 return true;
40 } while (--retry);30 } while (--retry);
@@ -46,9 +36,9 @@ static inline bool __must_check rdrand_int(unsigned int *v) · 5 unmodified lines
46 bool ok;36 bool ok;
47 unsigned int retry = RDRAND_RETRY_LOOPS;37 unsigned int retry = RDRAND_RETRY_LOOPS;
48 do {38 do {
49 asm volatile(RDRAND_INT39 asm volatile("rdrand %[out]"
50 CC_SET(c)40 CC_SET(c)
51 : CC_OUT(c) (ok), "=a" (*v));41 : CC_OUT(c) (ok), [out] "=r" (*v));
52 if (ok)42 if (ok)
53 return true;43 return true;
54 } while (--retry);44 } while (--retry);
@@ -58,18 +48,18 @@ static inline bool __must_check rdrand_int(unsigned int *v) · 3 unmodified lines
58static inline bool __must_check rdseed_long(unsigned long *v)48static inline bool __must_check rdseed_long(unsigned long *v)
59{49{
60 bool ok;50 bool ok;
61 asm volatile(RDSEED_LONG51 asm volatile("rdseed %[out]"
62 CC_SET(c)52 CC_SET(c)
63 : CC_OUT(c) (ok), "=a" (*v));53 : CC_OUT(c) (ok), [out] "=r" (*v));
64 return ok;54 return ok;
65}55}
66 56
67static inline bool __must_check rdseed_int(unsigned int *v)57static inline bool __must_check rdseed_int(unsigned int *v)
68{58{
69 bool ok;59 bool ok;
70 asm volatile(RDSEED_INT60 asm volatile("rdseed %[out]"
71 CC_SET(c)61 CC_SET(c)
72 : CC_OUT(c) (ok), "=a" (*v));62 : CC_OUT(c) (ok), [out] "=r" (*v));
73 return ok;63 return ok;
74}64}
75 65
arch/x86/include/asm/cpu_device_id.h+28−3
@@ -20,12 +20,14 @@ · 19 unmodified lines
20#define X86_CENTAUR_FAM6_C7_D 0xd20#define X86_CENTAUR_FAM6_C7_D 0xd
21#define X86_CENTAUR_FAM6_NANO 0xf21#define X86_CENTAUR_FAM6_NANO 0xf
22 22
23#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins)
23/**24/**
24 * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Base macro for CPU matching25 * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
25 * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY26 * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
26 * The name is expanded to X86_VENDOR_@_vendor27 * The name is expanded to X86_VENDOR_@_vendor
27 * @_family: The family number or X86_FAMILY_ANY28 * @_family: The family number or X86_FAMILY_ANY
28 * @_model: The model number, model constant or X86_MODEL_ANY29 * @_model: The model number, model constant or X86_MODEL_ANY
30 * @_steppings: Bitmask for steppings, stepping constant or X86_STEPPING_ANY
29 * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY31 * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY
30 * @_data: Driver specific data or NULL. The internal storage32 * @_data: Driver specific data or NULL. The internal storage
31 * format is unsigned long. The supplied value, pointer33 * format is unsigned long. The supplied value, pointer
@@ -37,15 +39,34 @@ · 5 unmodified lines
37 * into another macro at the usage site for good reasons, then please39 * into another macro at the usage site for good reasons, then please
38 * start this local macro with X86_MATCH to allow easy grepping.40 * start this local macro with X86_MATCH to allow easy grepping.
39 */41 */
40#define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(_vendor, _family, _model, \42#define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \
41 _feature, _data) { \43 _steppings, _feature, _data) { \
42 .vendor = X86_VENDOR_##_vendor, \44 .vendor = X86_VENDOR_##_vendor, \
43 .family = _family, \45 .family = _family, \
44 .model = _model, \46 .model = _model, \
47 .steppings = _steppings, \
45 .feature = _feature, \48 .feature = _feature, \
46 .driver_data = (unsigned long) _data \49 .driver_data = (unsigned long) _data \
47}50}
48 51
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
49/**70/**
50 * X86_MATCH_VENDOR_FAM_FEATURE - Macro for matching vendor, family and CPU feature71 * X86_MATCH_VENDOR_FAM_FEATURE - Macro for matching vendor, family and CPU feature
51 * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY72 * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
@@ -139,6 +160,10 @@ · 87 unmodified lines
139#define X86_MATCH_INTEL_FAM6_MODEL(model, data) \160#define X86_MATCH_INTEL_FAM6_MODEL(model, data) \
140 X86_MATCH_VENDOR_FAM_MODEL(INTEL, 6, INTEL_FAM6_##model, data)161 X86_MATCH_VENDOR_FAM_MODEL(INTEL, 6, INTEL_FAM6_##model, data)
141 162
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
142/*167/*
143 * Match specific microcode revisions.168 * Match specific microcode revisions.
144 *169 *
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
12 * stale TLB entries and, especially if we're flushing global12 * stale TLB entries and, especially if we're flushing global
13 * mappings, we don't want the compiler to reorder any subsequent13 * mappings, we don't want the compiler to reorder any subsequent
14 * memory accesses before the TLB flush.14 * 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.
18 */15 */
19 asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01"16 asm volatile("invpcid %[desc], %[type]"
20 : : "m" (desc), "a" (type), "c" (&desc) : "memory");17 :: [desc] "m" (desc), [type] "r" (type) : "memory");
21}18}
22 19
23#define INVPCID_TYPE_INDIV_ADDR 020#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
544};544};
545static DEFINE_PER_CPU(struct clock_event_device, lapic_events);545static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
546 546
547static __init u32 hsx_deadline_rev(void)547static const struct x86_cpu_id deadline_match[] __initconst = {
548{548 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x2, 0x2), 0x3a), /* EP */
549 switch (boot_cpu_data.x86_stepping) {549 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x4, 0x4), 0x0f), /* EX */
550 case 0x02: return 0x3a; /* EP */
551 case 0x04: return 0x0f; /* EX */
552 }
553
554 return ~0U;
555}
556
557static __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
569static __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 }
575 550
576 if (boot_cpu_data.x86_stepping > 4)551 X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
577 return 0;
578 552
579 return ~0U;553 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x2, 0x2), 0x00000011),
580}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),
581 557
582static const struct x86_cpu_id deadline_match[] __initconst = {558 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x3, 0x3), 0x01000136),
583 X86_MATCH_INTEL_FAM6_MODEL( HASWELL_X, &hsx_deadline_rev),559 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x4, 0x4), 0x02000014),
584 X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),560 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x5, 0xf), 0),
585 X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_D, &bdx_deadline_rev),
586 X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE_X, &skx_deadline_rev),
587 561
588 X86_MATCH_INTEL_FAM6_MODEL( HASWELL, 0x22),562 X86_MATCH_INTEL_FAM6_MODEL( HASWELL, 0x22),
589 X86_MATCH_INTEL_FAM6_MODEL( HASWELL_L, 0x20),563 X86_MATCH_INTEL_FAM6_MODEL( HASWELL_L, 0x20),
@@ -615,14 +589,7 @@ static __init bool apic_validate_deadline_timer(void) · 25 unmodified lines
615 if (!m)589 if (!m)
616 return true;590 return true;
617 591
618 /*592 rev = (u32)m->driver_data;
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;
626 593
627 if (boot_cpu_data.microcode >= rev)594 if (boot_cpu_data.microcode >= rev)
628 return true;595 return true;
arch/x86/kernel/cpu/amd.c+1−2
@@ -1145,8 +1145,7 @@ static const int amd_erratum_383[] = · 1144 unmodified lines
1145 1145
1146/* #1054: Instructions Retired Performance Counter May Be Inaccurate */1146/* #1054: Instructions Retired Performance Counter May Be Inaccurate */
1147static const int amd_erratum_1054[] =1147static const int amd_erratum_1054[] =
1148 AMD_OSVW_ERRATUM(0, AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));1148 AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf));
1149
1150 1149
1151static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)1150static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
1152{1151{
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
39 const struct x86_cpu_id *m;39 const struct x86_cpu_id *m;
40 struct cpuinfo_x86 *c = &boot_cpu_data;40 struct cpuinfo_x86 *c = &boot_cpu_data;
41 41
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++) {
43 if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)45 if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
44 continue;46 continue;
45 if (m->family != X86_FAMILY_ANY && c->x86 != m->family)47 if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
46 continue;48 continue;
47 if (m->model != X86_MODEL_ANY && c->x86_model != m->model)49 if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
48 continue;50 continue;
51 if (m->steppings != X86_STEPPING_ANY &&
52 !(BIT(c->x86_stepping) & m->steppings))
53 continue;
49 if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))54 if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
50 continue;55 continue;
51 return m;56 return m;
include/linux/mod_devicetable.h+2−0
@@ -663,6 +663,7 @@ struct x86_cpu_id { · 662 unmodified lines
663 __u16 vendor;663 __u16 vendor;
664 __u16 family;664 __u16 family;
665 __u16 model;665 __u16 model;
666 __u16 steppings;
666 __u16 feature; /* bit index */667 __u16 feature; /* bit index */
667 kernel_ulong_t driver_data;668 kernel_ulong_t driver_data;
668};669};
@@ -671,6 +672,7 @@ struct x86_cpu_id { · 2 unmodified lines
671#define X86_VENDOR_ANY 0xffff672#define X86_VENDOR_ANY 0xffff
672#define X86_FAMILY_ANY 0673#define X86_FAMILY_ANY 0
673#define X86_MODEL_ANY 0674#define X86_MODEL_ANY 0
675#define X86_STEPPING_ANY 0
674#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */676#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
675 677
676/*678/*

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