@@ -32,6 +32,15 @@ static refcount_t ghes_refcount = REFCOUNT_INIT(0);
32
32
*/
33
33
static struct ghes_pvt * ghes_pvt ;
34
34
35
+ /*
36
+ * This driver's representation of the system hardware, as collected
37
+ * from DMI.
38
+ */
39
+ struct ghes_hw_desc {
40
+ int num_dimms ;
41
+ struct dimm_info * dimms ;
42
+ } ghes_hw ;
43
+
35
44
/* GHES registration mutex */
36
45
static DEFINE_MUTEX (ghes_reg_mutex );
37
46
@@ -72,19 +81,6 @@ struct memdev_dmi_entry {
72
81
u16 conf_mem_clk_speed ;
73
82
} __attribute__((__packed__ ));
74
83
75
- struct ghes_edac_dimm_fill {
76
- struct mem_ctl_info * mci ;
77
- unsigned int count ;
78
- };
79
-
80
- static void ghes_edac_count_dimms (const struct dmi_header * dh , void * arg )
81
- {
82
- int * num_dimm = arg ;
83
-
84
- if (dh -> type == DMI_ENTRY_MEM_DEVICE )
85
- (* num_dimm )++ ;
86
- }
87
-
88
84
static struct dimm_info * find_dimm_by_handle (struct mem_ctl_info * mci , u16 handle )
89
85
{
90
86
struct dimm_info * dimm ;
@@ -108,102 +104,135 @@ static void dimm_setup_label(struct dimm_info *dimm, u16 handle)
108
104
snprintf (dimm -> label , sizeof (dimm -> label ), "%s %s" , bank , device );
109
105
}
110
106
111
- static void ghes_edac_dmidecode ( const struct dmi_header * dh , void * arg )
107
+ static void assign_dmi_dimm_info ( struct dimm_info * dimm , struct memdev_dmi_entry * entry )
112
108
{
113
- struct ghes_edac_dimm_fill * dimm_fill = arg ;
114
- struct mem_ctl_info * mci = dimm_fill -> mci ;
115
-
116
- if (dh -> type == DMI_ENTRY_MEM_DEVICE ) {
117
- struct memdev_dmi_entry * entry = (struct memdev_dmi_entry * )dh ;
118
- struct dimm_info * dimm = edac_get_dimm (mci , dimm_fill -> count , 0 , 0 );
119
- u16 rdr_mask = BIT (7 ) | BIT (13 );
120
-
121
- if (entry -> size == 0xffff ) {
122
- pr_info ("Can't get DIMM%i size\n" ,
123
- dimm_fill -> count );
124
- dimm -> nr_pages = MiB_TO_PAGES (32 );/* Unknown */
125
- } else if (entry -> size == 0x7fff ) {
126
- dimm -> nr_pages = MiB_TO_PAGES (entry -> extended_size );
127
- } else {
128
- if (entry -> size & BIT (15 ))
129
- dimm -> nr_pages = MiB_TO_PAGES ((entry -> size & 0x7fff ) << 10 );
130
- else
131
- dimm -> nr_pages = MiB_TO_PAGES (entry -> size );
132
- }
109
+ u16 rdr_mask = BIT (7 ) | BIT (13 );
133
110
134
- switch (entry -> memory_type ) {
135
- case 0x12 :
136
- if (entry -> type_detail & BIT (13 ))
137
- dimm -> mtype = MEM_RDDR ;
138
- else
139
- dimm -> mtype = MEM_DDR ;
140
- break ;
141
- case 0x13 :
142
- if (entry -> type_detail & BIT (13 ))
143
- dimm -> mtype = MEM_RDDR2 ;
144
- else
145
- dimm -> mtype = MEM_DDR2 ;
146
- break ;
147
- case 0x14 :
148
- dimm -> mtype = MEM_FB_DDR2 ;
149
- break ;
150
- case 0x18 :
151
- if (entry -> type_detail & BIT (12 ))
152
- dimm -> mtype = MEM_NVDIMM ;
153
- else if (entry -> type_detail & BIT (13 ))
154
- dimm -> mtype = MEM_RDDR3 ;
155
- else
156
- dimm -> mtype = MEM_DDR3 ;
157
- break ;
158
- case 0x1a :
159
- if (entry -> type_detail & BIT (12 ))
160
- dimm -> mtype = MEM_NVDIMM ;
161
- else if (entry -> type_detail & BIT (13 ))
162
- dimm -> mtype = MEM_RDDR4 ;
163
- else
164
- dimm -> mtype = MEM_DDR4 ;
165
- break ;
166
- default :
167
- if (entry -> type_detail & BIT (6 ))
168
- dimm -> mtype = MEM_RMBS ;
169
- else if ((entry -> type_detail & rdr_mask ) == rdr_mask )
170
- dimm -> mtype = MEM_RDR ;
171
- else if (entry -> type_detail & BIT (7 ))
172
- dimm -> mtype = MEM_SDR ;
173
- else if (entry -> type_detail & BIT (9 ))
174
- dimm -> mtype = MEM_EDO ;
175
- else
176
- dimm -> mtype = MEM_UNKNOWN ;
177
- }
111
+ if (entry -> size == 0xffff ) {
112
+ pr_info ("Can't get DIMM%i size\n" , dimm -> idx );
113
+ dimm -> nr_pages = MiB_TO_PAGES (32 );/* Unknown */
114
+ } else if (entry -> size == 0x7fff ) {
115
+ dimm -> nr_pages = MiB_TO_PAGES (entry -> extended_size );
116
+ } else {
117
+ if (entry -> size & BIT (15 ))
118
+ dimm -> nr_pages = MiB_TO_PAGES ((entry -> size & 0x7fff ) << 10 );
119
+ else
120
+ dimm -> nr_pages = MiB_TO_PAGES (entry -> size );
121
+ }
178
122
179
- /*
180
- * Actually, we can only detect if the memory has bits for
181
- * checksum or not
182
- */
183
- if (entry -> total_width == entry -> data_width )
184
- dimm -> edac_mode = EDAC_NONE ;
123
+ switch (entry -> memory_type ) {
124
+ case 0x12 :
125
+ if (entry -> type_detail & BIT (13 ))
126
+ dimm -> mtype = MEM_RDDR ;
127
+ else
128
+ dimm -> mtype = MEM_DDR ;
129
+ break ;
130
+ case 0x13 :
131
+ if (entry -> type_detail & BIT (13 ))
132
+ dimm -> mtype = MEM_RDDR2 ;
185
133
else
186
- dimm -> edac_mode = EDAC_SECDED ;
134
+ dimm -> mtype = MEM_DDR2 ;
135
+ break ;
136
+ case 0x14 :
137
+ dimm -> mtype = MEM_FB_DDR2 ;
138
+ break ;
139
+ case 0x18 :
140
+ if (entry -> type_detail & BIT (12 ))
141
+ dimm -> mtype = MEM_NVDIMM ;
142
+ else if (entry -> type_detail & BIT (13 ))
143
+ dimm -> mtype = MEM_RDDR3 ;
144
+ else
145
+ dimm -> mtype = MEM_DDR3 ;
146
+ break ;
147
+ case 0x1a :
148
+ if (entry -> type_detail & BIT (12 ))
149
+ dimm -> mtype = MEM_NVDIMM ;
150
+ else if (entry -> type_detail & BIT (13 ))
151
+ dimm -> mtype = MEM_RDDR4 ;
152
+ else
153
+ dimm -> mtype = MEM_DDR4 ;
154
+ break ;
155
+ default :
156
+ if (entry -> type_detail & BIT (6 ))
157
+ dimm -> mtype = MEM_RMBS ;
158
+ else if ((entry -> type_detail & rdr_mask ) == rdr_mask )
159
+ dimm -> mtype = MEM_RDR ;
160
+ else if (entry -> type_detail & BIT (7 ))
161
+ dimm -> mtype = MEM_SDR ;
162
+ else if (entry -> type_detail & BIT (9 ))
163
+ dimm -> mtype = MEM_EDO ;
164
+ else
165
+ dimm -> mtype = MEM_UNKNOWN ;
166
+ }
187
167
188
- dimm -> dtype = DEV_UNKNOWN ;
189
- dimm -> grain = 128 ; /* Likely, worse case */
190
-
191
- dimm_setup_label (dimm , entry -> handle );
192
-
193
- if (dimm -> nr_pages ) {
194
- edac_dbg (1 , "DIMM%i: %s size = %d MB%s\n" ,
195
- dimm_fill -> count , edac_mem_types [dimm -> mtype ],
196
- PAGES_TO_MiB (dimm -> nr_pages ),
197
- (dimm -> edac_mode != EDAC_NONE ) ? "(ECC)" : "" );
198
- edac_dbg (2 , "\ttype %d, detail 0x%02x, width %d(total %d)\n" ,
199
- entry -> memory_type , entry -> type_detail ,
200
- entry -> total_width , entry -> data_width );
201
- }
168
+ /*
169
+ * Actually, we can only detect if the memory has bits for
170
+ * checksum or not
171
+ */
172
+ if (entry -> total_width == entry -> data_width )
173
+ dimm -> edac_mode = EDAC_NONE ;
174
+ else
175
+ dimm -> edac_mode = EDAC_SECDED ;
176
+
177
+ dimm -> dtype = DEV_UNKNOWN ;
178
+ dimm -> grain = 128 ; /* Likely, worse case */
202
179
203
- dimm -> smbios_handle = entry -> handle ;
180
+ dimm_setup_label ( dimm , entry -> handle ) ;
204
181
205
- dimm_fill -> count ++ ;
182
+ if (dimm -> nr_pages ) {
183
+ edac_dbg (1 , "DIMM%i: %s size = %d MB%s\n" ,
184
+ dimm -> idx , edac_mem_types [dimm -> mtype ],
185
+ PAGES_TO_MiB (dimm -> nr_pages ),
186
+ (dimm -> edac_mode != EDAC_NONE ) ? "(ECC)" : "" );
187
+ edac_dbg (2 , "\ttype %d, detail 0x%02x, width %d(total %d)\n" ,
188
+ entry -> memory_type , entry -> type_detail ,
189
+ entry -> total_width , entry -> data_width );
206
190
}
191
+
192
+ dimm -> smbios_handle = entry -> handle ;
193
+ }
194
+
195
+ static void enumerate_dimms (const struct dmi_header * dh , void * arg )
196
+ {
197
+ struct memdev_dmi_entry * entry = (struct memdev_dmi_entry * )dh ;
198
+ struct ghes_hw_desc * hw = (struct ghes_hw_desc * )arg ;
199
+ struct dimm_info * d ;
200
+
201
+ if (dh -> type != DMI_ENTRY_MEM_DEVICE )
202
+ return ;
203
+
204
+ /* Enlarge the array with additional 16 */
205
+ if (!hw -> num_dimms || !(hw -> num_dimms % 16 )) {
206
+ struct dimm_info * new ;
207
+
208
+ new = krealloc (hw -> dimms , (hw -> num_dimms + 16 ) * sizeof (struct dimm_info ),
209
+ GFP_KERNEL );
210
+ if (!new ) {
211
+ WARN_ON_ONCE (1 );
212
+ return ;
213
+ }
214
+
215
+ hw -> dimms = new ;
216
+ }
217
+
218
+ d = & hw -> dimms [hw -> num_dimms ];
219
+ d -> idx = hw -> num_dimms ;
220
+
221
+ assign_dmi_dimm_info (d , entry );
222
+
223
+ hw -> num_dimms ++ ;
224
+ }
225
+
226
+ static void ghes_scan_system (void )
227
+ {
228
+ static bool scanned ;
229
+
230
+ if (scanned )
231
+ return ;
232
+
233
+ dmi_walk (enumerate_dimms , & ghes_hw );
234
+
235
+ scanned = true;
207
236
}
208
237
209
238
void ghes_edac_report_mem_error (int sev , struct cper_sec_mem_err * mem_err )
@@ -466,13 +495,12 @@ static struct acpi_platform_list plat_list[] = {
466
495
int ghes_edac_register (struct ghes * ghes , struct device * dev )
467
496
{
468
497
bool fake = false;
469
- int rc = 0 , num_dimm = 0 ;
470
498
struct mem_ctl_info * mci ;
471
499
struct ghes_pvt * pvt ;
472
500
struct edac_mc_layer layers [1 ];
473
- struct ghes_edac_dimm_fill dimm_fill ;
474
501
unsigned long flags ;
475
502
int idx = -1 ;
503
+ int rc = 0 ;
476
504
477
505
if (IS_ENABLED (CONFIG_X86 )) {
478
506
/* Check if safe to enable on this system */
@@ -492,17 +520,16 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
492
520
if (refcount_inc_not_zero (& ghes_refcount ))
493
521
goto unlock ;
494
522
495
- /* Get the number of DIMMs */
496
- dmi_walk (ghes_edac_count_dimms , & num_dimm );
523
+ ghes_scan_system ();
497
524
498
525
/* Check if we've got a bogus BIOS */
499
- if (num_dimm == 0 ) {
526
+ if (! ghes_hw . num_dimms ) {
500
527
fake = true;
501
- num_dimm = 1 ;
528
+ ghes_hw . num_dimms = 1 ;
502
529
}
503
530
504
531
layers [0 ].type = EDAC_MC_LAYER_ALL_MEM ;
505
- layers [0 ].size = num_dimm ;
532
+ layers [0 ].size = ghes_hw . num_dimms ;
506
533
layers [0 ].is_virt_csrow = true;
507
534
508
535
mci = edac_mc_alloc (0 , ARRAY_SIZE (layers ), layers , sizeof (struct ghes_pvt ));
@@ -533,13 +560,34 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
533
560
pr_info ("So, the end result of using this driver varies from vendor to vendor.\n" );
534
561
pr_info ("If you find incorrect reports, please contact your hardware vendor\n" );
535
562
pr_info ("to correct its BIOS.\n" );
536
- pr_info ("This system has %d DIMM sockets.\n" , num_dimm );
563
+ pr_info ("This system has %d DIMM sockets.\n" , ghes_hw . num_dimms );
537
564
}
538
565
539
566
if (!fake ) {
540
- dimm_fill .count = 0 ;
541
- dimm_fill .mci = mci ;
542
- dmi_walk (ghes_edac_dmidecode , & dimm_fill );
567
+ struct dimm_info * src , * dst ;
568
+ int i = 0 ;
569
+
570
+ mci_for_each_dimm (mci , dst ) {
571
+ src = & ghes_hw .dimms [i ];
572
+
573
+ dst -> idx = src -> idx ;
574
+ dst -> smbios_handle = src -> smbios_handle ;
575
+ dst -> nr_pages = src -> nr_pages ;
576
+ dst -> mtype = src -> mtype ;
577
+ dst -> edac_mode = src -> edac_mode ;
578
+ dst -> dtype = src -> dtype ;
579
+ dst -> grain = src -> grain ;
580
+
581
+ /*
582
+ * If no src->label, preserve default label assigned
583
+ * from EDAC core.
584
+ */
585
+ if (strlen (src -> label ))
586
+ memcpy (dst -> label , src -> label , sizeof (src -> label ));
587
+
588
+ i ++ ;
589
+ }
590
+
543
591
} else {
544
592
struct dimm_info * dimm = edac_get_dimm (mci , 0 , 0 , 0 );
545
593
@@ -552,7 +600,7 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
552
600
553
601
rc = edac_mc_add_mc (mci );
554
602
if (rc < 0 ) {
555
- pr_info ("Can't register at EDAC core\n" );
603
+ pr_info ("Can't register with the EDAC core\n" );
556
604
edac_mc_free (mci );
557
605
rc = - ENODEV ;
558
606
goto unlock ;
@@ -566,6 +614,11 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
566
614
refcount_set (& ghes_refcount , 1 );
567
615
568
616
unlock :
617
+
618
+ /* Not needed anymore */
619
+ kfree (ghes_hw .dimms );
620
+ ghes_hw .dimms = NULL ;
621
+
569
622
mutex_unlock (& ghes_reg_mutex );
570
623
571
624
return rc ;
0 commit comments