44 *
55 * Written by Jacob Shin - AMD, Inc.
66 * Maintained by: Borislav Petkov <bp@alien8.de>
7- *
8- * All MC4_MISCi registers are shared between cores on a node.
97 */
108#include <linux/interrupt.h>
119#include <linux/notifier.h>
2018#include <linux/smp.h>
2119#include <linux/string.h>
2220
23- #include <asm/amd_nb.h>
2421#include <asm/traps.h>
2522#include <asm/apic.h>
2623#include <asm/mce.h>
@@ -221,6 +218,32 @@ static const struct smca_hwid smca_hwid_mcatypes[] = {
221218#define MAX_MCATYPE_NAME_LEN 30
222219static char buf_mcatype [MAX_MCATYPE_NAME_LEN ];
223220
221+ struct threshold_block {
222+ /* This block's number within its bank. */
223+ unsigned int block ;
224+ /* MCA bank number that contains this block. */
225+ unsigned int bank ;
226+ /* CPU which controls this block's MCA bank. */
227+ unsigned int cpu ;
228+ /* MCA_MISC MSR address for this block. */
229+ u32 address ;
230+ /* Enable/Disable APIC interrupt. */
231+ bool interrupt_enable ;
232+ /* Bank can generate an interrupt. */
233+ bool interrupt_capable ;
234+ /* Value upon which threshold interrupt is generated. */
235+ u16 threshold_limit ;
236+ /* sysfs object */
237+ struct kobject kobj ;
238+ /* List of threshold blocks within this block's MCA bank. */
239+ struct list_head miscj ;
240+ };
241+
242+ struct threshold_bank {
243+ struct kobject * kobj ;
244+ struct threshold_block * blocks ;
245+ };
246+
224247static DEFINE_PER_CPU (struct threshold_bank * * , threshold_banks ) ;
225248
226249/*
@@ -333,19 +356,6 @@ struct thresh_restart {
333356 u16 old_limit ;
334357};
335358
336- static inline bool is_shared_bank (int bank )
337- {
338- /*
339- * Scalable MCA provides for only one core to have access to the MSRs of
340- * a shared bank.
341- */
342- if (mce_flags .smca )
343- return false;
344-
345- /* Bank 4 is for northbridge reporting and is thus shared */
346- return (bank == 4 );
347- }
348-
349359static const char * bank4_names (const struct threshold_block * b )
350360{
351361 switch (b -> address ) {
@@ -1194,62 +1204,17 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
11941204 return err ;
11951205}
11961206
1197- static int __threshold_add_blocks (struct threshold_bank * b )
1198- {
1199- struct list_head * head = & b -> blocks -> miscj ;
1200- struct threshold_block * pos = NULL ;
1201- struct threshold_block * tmp = NULL ;
1202- int err = 0 ;
1203-
1204- err = kobject_add (& b -> blocks -> kobj , b -> kobj , b -> blocks -> kobj .name );
1205- if (err )
1206- return err ;
1207-
1208- list_for_each_entry_safe (pos , tmp , head , miscj ) {
1209-
1210- err = kobject_add (& pos -> kobj , b -> kobj , pos -> kobj .name );
1211- if (err ) {
1212- list_for_each_entry_safe_reverse (pos , tmp , head , miscj )
1213- kobject_del (& pos -> kobj );
1214-
1215- return err ;
1216- }
1217- }
1218- return err ;
1219- }
1220-
12211207static int threshold_create_bank (struct threshold_bank * * bp , unsigned int cpu ,
12221208 unsigned int bank )
12231209{
12241210 struct device * dev = this_cpu_read (mce_device );
1225- struct amd_northbridge * nb = NULL ;
12261211 struct threshold_bank * b = NULL ;
12271212 const char * name = get_name (cpu , bank , NULL );
12281213 int err = 0 ;
12291214
12301215 if (!dev )
12311216 return - ENODEV ;
12321217
1233- if (is_shared_bank (bank )) {
1234- nb = node_to_amd_nb (topology_amd_node_id (cpu ));
1235-
1236- /* threshold descriptor already initialized on this node? */
1237- if (nb && nb -> bank4 ) {
1238- /* yes, use it */
1239- b = nb -> bank4 ;
1240- err = kobject_add (b -> kobj , & dev -> kobj , name );
1241- if (err )
1242- goto out ;
1243-
1244- bp [bank ] = b ;
1245- refcount_inc (& b -> cpus );
1246-
1247- err = __threshold_add_blocks (b );
1248-
1249- goto out ;
1250- }
1251- }
1252-
12531218 b = kzalloc (sizeof (struct threshold_bank ), GFP_KERNEL );
12541219 if (!b ) {
12551220 err = - ENOMEM ;
@@ -1263,17 +1228,6 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
12631228 goto out_free ;
12641229 }
12651230
1266- if (is_shared_bank (bank )) {
1267- b -> shared = 1 ;
1268- refcount_set (& b -> cpus , 1 );
1269-
1270- /* nb is already initialized, see above */
1271- if (nb ) {
1272- WARN_ON (nb -> bank4 );
1273- nb -> bank4 = b ;
1274- }
1275- }
1276-
12771231 err = allocate_threshold_blocks (cpu , b , bank , 0 , mca_msr_reg (bank , MCA_MISC ));
12781232 if (err )
12791233 goto out_kobj ;
@@ -1306,40 +1260,11 @@ static void deallocate_threshold_blocks(struct threshold_bank *bank)
13061260 kobject_put (& bank -> blocks -> kobj );
13071261}
13081262
1309- static void __threshold_remove_blocks (struct threshold_bank * b )
1310- {
1311- struct threshold_block * pos = NULL ;
1312- struct threshold_block * tmp = NULL ;
1313-
1314- kobject_put (b -> kobj );
1315-
1316- list_for_each_entry_safe (pos , tmp , & b -> blocks -> miscj , miscj )
1317- kobject_put (b -> kobj );
1318- }
1319-
13201263static void threshold_remove_bank (struct threshold_bank * bank )
13211264{
1322- struct amd_northbridge * nb ;
1323-
13241265 if (!bank -> blocks )
13251266 goto out_free ;
13261267
1327- if (!bank -> shared )
1328- goto out_dealloc ;
1329-
1330- if (!refcount_dec_and_test (& bank -> cpus )) {
1331- __threshold_remove_blocks (bank );
1332- return ;
1333- } else {
1334- /*
1335- * The last CPU on this node using the shared bank is going
1336- * away, remove that bank now.
1337- */
1338- nb = node_to_amd_nb (topology_amd_node_id (smp_processor_id ()));
1339- nb -> bank4 = NULL ;
1340- }
1341-
1342- out_dealloc :
13431268 deallocate_threshold_blocks (bank );
13441269
13451270out_free :
0 commit comments