Skip to content

Commit eff5dda

Browse files
committed
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
2 parents 17e0a7c + 3d81b3d commit eff5dda

File tree

7 files changed

+59
-74
lines changed

7 files changed

+59
-74
lines changed

arch/x86/include/asm/archrandom.h

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,16 @@
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)
3121
{
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)
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)
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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
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 @@
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 @@
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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@ static inline void __invpcid(unsigned long pcid, unsigned long addr,
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

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -544,46 +544,20 @@ static struct clock_event_device lapic_clockevent = {
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)
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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,8 +1145,7 @@ static const int amd_erratum_383[] =
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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,18 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ struct x86_cpu_id {
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 {
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
/*

0 commit comments

Comments
 (0)