@@ -71,6 +71,22 @@ static const char * const smca_umc_block_names[] = {
71
71
"misc_umc"
72
72
};
73
73
74
+ #define HWID_MCATYPE (hwid , mcatype ) (((hwid) << 16) | (mcatype))
75
+
76
+ struct smca_hwid {
77
+ unsigned int bank_type ; /* Use with smca_bank_types for easy indexing. */
78
+ u32 hwid_mcatype ; /* (hwid,mcatype) tuple */
79
+ };
80
+
81
+ struct smca_bank {
82
+ const struct smca_hwid * hwid ;
83
+ u32 id ; /* Value of MCA_IPID[InstanceId]. */
84
+ u8 sysfs_id ; /* Value used for sysfs name. */
85
+ };
86
+
87
+ static DEFINE_PER_CPU_READ_MOSTLY (struct smca_bank [MAX_NR_BANKS ], smca_banks ) ;
88
+ static DEFINE_PER_CPU_READ_MOSTLY (u8 [N_SMCA_BANK_TYPES ], smca_bank_counts ) ;
89
+
74
90
struct smca_bank_name {
75
91
const char * name ; /* Short name for sysfs */
76
92
const char * long_name ; /* Long name for pretty-printing */
@@ -126,22 +142,22 @@ const char *smca_get_long_name(enum smca_bank_types t)
126
142
}
127
143
EXPORT_SYMBOL_GPL (smca_get_long_name );
128
144
129
- enum smca_bank_types smca_get_bank_type (unsigned int bank )
145
+ enum smca_bank_types smca_get_bank_type (unsigned int cpu , unsigned int bank )
130
146
{
131
147
struct smca_bank * b ;
132
148
133
149
if (bank >= MAX_NR_BANKS )
134
150
return N_SMCA_BANK_TYPES ;
135
151
136
- b = & smca_banks [bank ];
152
+ b = & per_cpu ( smca_banks , cpu ) [bank ];
137
153
if (!b -> hwid )
138
154
return N_SMCA_BANK_TYPES ;
139
155
140
156
return b -> hwid -> bank_type ;
141
157
}
142
158
EXPORT_SYMBOL_GPL (smca_get_bank_type );
143
159
144
- static struct smca_hwid smca_hwid_mcatypes [] = {
160
+ static const struct smca_hwid smca_hwid_mcatypes [] = {
145
161
/* { bank_type, hwid_mcatype } */
146
162
147
163
/* Reserved type */
@@ -202,9 +218,6 @@ static struct smca_hwid smca_hwid_mcatypes[] = {
202
218
{ SMCA_GMI_PHY , HWID_MCATYPE (0x269 , 0x0 ) },
203
219
};
204
220
205
- struct smca_bank smca_banks [MAX_NR_BANKS ];
206
- EXPORT_SYMBOL_GPL (smca_banks );
207
-
208
221
/*
209
222
* In SMCA enabled processors, we can have multiple banks for a given IP type.
210
223
* So to define a unique name for each bank, we use a temp c-string to append
@@ -260,8 +273,9 @@ static void smca_set_misc_banks_map(unsigned int bank, unsigned int cpu)
260
273
261
274
static void smca_configure (unsigned int bank , unsigned int cpu )
262
275
{
276
+ u8 * bank_counts = this_cpu_ptr (smca_bank_counts );
277
+ const struct smca_hwid * s_hwid ;
263
278
unsigned int i , hwid_mcatype ;
264
- struct smca_hwid * s_hwid ;
265
279
u32 high , low ;
266
280
u32 smca_config = MSR_AMD64_SMCA_MCx_CONFIG (bank );
267
281
@@ -297,10 +311,6 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
297
311
298
312
smca_set_misc_banks_map (bank , cpu );
299
313
300
- /* Return early if this bank was already initialized. */
301
- if (smca_banks [bank ].hwid && smca_banks [bank ].hwid -> hwid_mcatype != 0 )
302
- return ;
303
-
304
314
if (rdmsr_safe (MSR_AMD64_SMCA_MCx_IPID (bank ), & low , & high )) {
305
315
pr_warn ("Failed to read MCA_IPID for bank %d\n" , bank );
306
316
return ;
@@ -311,10 +321,11 @@ static void smca_configure(unsigned int bank, unsigned int cpu)
311
321
312
322
for (i = 0 ; i < ARRAY_SIZE (smca_hwid_mcatypes ); i ++ ) {
313
323
s_hwid = & smca_hwid_mcatypes [i ];
324
+
314
325
if (hwid_mcatype == s_hwid -> hwid_mcatype ) {
315
- smca_banks [bank ].hwid = s_hwid ;
316
- smca_banks [bank ].id = low ;
317
- smca_banks [bank ].sysfs_id = s_hwid -> count ++ ;
326
+ this_cpu_ptr ( smca_banks ) [bank ].hwid = s_hwid ;
327
+ this_cpu_ptr ( smca_banks ) [bank ].id = low ;
328
+ this_cpu_ptr ( smca_banks ) [bank ].sysfs_id = bank_counts [ s_hwid -> bank_type ] ++ ;
318
329
break ;
319
330
}
320
331
}
@@ -600,7 +611,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
600
611
601
612
bool amd_filter_mce (struct mce * m )
602
613
{
603
- enum smca_bank_types bank_type = smca_get_bank_type (m -> bank );
614
+ enum smca_bank_types bank_type = smca_get_bank_type (m -> extcpu , m -> bank );
604
615
struct cpuinfo_x86 * c = & boot_cpu_data ;
605
616
606
617
/* See Family 17h Models 10h-2Fh Erratum #1114. */
@@ -638,7 +649,7 @@ static void disable_err_thresholding(struct cpuinfo_x86 *c, unsigned int bank)
638
649
} else if (c -> x86 == 0x17 &&
639
650
(c -> x86_model >= 0x10 && c -> x86_model <= 0x2F )) {
640
651
641
- if (smca_get_bank_type (bank ) != SMCA_IF )
652
+ if (smca_get_bank_type (smp_processor_id (), bank ) != SMCA_IF )
642
653
return ;
643
654
644
655
msrs [0 ] = MSR_AMD64_SMCA_MCx_MISC (bank );
@@ -706,7 +717,7 @@ bool amd_mce_is_memory_error(struct mce *m)
706
717
u8 xec = (m -> status >> 16 ) & 0x1f ;
707
718
708
719
if (mce_flags .smca )
709
- return smca_get_bank_type (m -> bank ) == SMCA_UMC && xec == 0x0 ;
720
+ return smca_get_bank_type (m -> extcpu , m -> bank ) == SMCA_UMC && xec == 0x0 ;
710
721
711
722
return m -> bank == 4 && xec == 0x8 ;
712
723
}
@@ -1022,7 +1033,7 @@ static struct kobj_type threshold_ktype = {
1022
1033
.release = threshold_block_release ,
1023
1034
};
1024
1035
1025
- static const char * get_name (unsigned int bank , struct threshold_block * b )
1036
+ static const char * get_name (unsigned int cpu , unsigned int bank , struct threshold_block * b )
1026
1037
{
1027
1038
enum smca_bank_types bank_type ;
1028
1039
@@ -1033,7 +1044,7 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
1033
1044
return th_names [bank ];
1034
1045
}
1035
1046
1036
- bank_type = smca_get_bank_type (bank );
1047
+ bank_type = smca_get_bank_type (cpu , bank );
1037
1048
if (bank_type >= N_SMCA_BANK_TYPES )
1038
1049
return NULL ;
1039
1050
@@ -1043,12 +1054,12 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
1043
1054
return NULL ;
1044
1055
}
1045
1056
1046
- if (smca_banks [ bank ]. hwid -> count == 1 )
1057
+ if (per_cpu ( smca_bank_counts , cpu )[ bank_type ] == 1 )
1047
1058
return smca_get_name (bank_type );
1048
1059
1049
1060
snprintf (buf_mcatype , MAX_MCATYPE_NAME_LEN ,
1050
- "%s_%x " , smca_get_name (bank_type ),
1051
- smca_banks [bank ].sysfs_id );
1061
+ "%s_%u " , smca_get_name (bank_type ),
1062
+ per_cpu ( smca_banks , cpu ) [bank ].sysfs_id );
1052
1063
return buf_mcatype ;
1053
1064
}
1054
1065
@@ -1104,7 +1115,7 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
1104
1115
else
1105
1116
tb -> blocks = b ;
1106
1117
1107
- err = kobject_init_and_add (& b -> kobj , & threshold_ktype , tb -> kobj , get_name (bank , b ));
1118
+ err = kobject_init_and_add (& b -> kobj , & threshold_ktype , tb -> kobj , get_name (cpu , bank , b ));
1108
1119
if (err )
1109
1120
goto out_free ;
1110
1121
recurse :
@@ -1159,7 +1170,7 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
1159
1170
struct device * dev = this_cpu_read (mce_device );
1160
1171
struct amd_northbridge * nb = NULL ;
1161
1172
struct threshold_bank * b = NULL ;
1162
- const char * name = get_name (bank , NULL );
1173
+ const char * name = get_name (cpu , bank , NULL );
1163
1174
int err = 0 ;
1164
1175
1165
1176
if (!dev )
0 commit comments