@@ -32,6 +32,15 @@ static refcount_t ghes_refcount = REFCOUNT_INIT(0);
3232 */
3333static struct ghes_pvt * ghes_pvt ;
3434
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+
3544/* GHES registration mutex */
3645static DEFINE_MUTEX (ghes_reg_mutex );
3746
@@ -72,19 +81,6 @@ struct memdev_dmi_entry {
7281 u16 conf_mem_clk_speed ;
7382} __attribute__((__packed__ ));
7483
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-
8884static struct dimm_info * find_dimm_by_handle (struct mem_ctl_info * mci , u16 handle )
8985{
9086 struct dimm_info * dimm ;
@@ -108,102 +104,135 @@ static void dimm_setup_label(struct dimm_info *dimm, u16 handle)
108104 snprintf (dimm -> label , sizeof (dimm -> label ), "%s %s" , bank , device );
109105}
110106
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 )
112108{
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 );
133110
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+ }
178122
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 ;
185133 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+ }
187167
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 */
202179
203- dimm -> smbios_handle = entry -> handle ;
180+ dimm_setup_label ( dimm , entry -> handle ) ;
204181
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 );
206190 }
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;
207236}
208237
209238void 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[] = {
466495int ghes_edac_register (struct ghes * ghes , struct device * dev )
467496{
468497 bool fake = false;
469- int rc = 0 , num_dimm = 0 ;
470498 struct mem_ctl_info * mci ;
471499 struct ghes_pvt * pvt ;
472500 struct edac_mc_layer layers [1 ];
473- struct ghes_edac_dimm_fill dimm_fill ;
474501 unsigned long flags ;
475502 int idx = -1 ;
503+ int rc = 0 ;
476504
477505 if (IS_ENABLED (CONFIG_X86 )) {
478506 /* Check if safe to enable on this system */
@@ -492,17 +520,16 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
492520 if (refcount_inc_not_zero (& ghes_refcount ))
493521 goto unlock ;
494522
495- /* Get the number of DIMMs */
496- dmi_walk (ghes_edac_count_dimms , & num_dimm );
523+ ghes_scan_system ();
497524
498525 /* Check if we've got a bogus BIOS */
499- if (num_dimm == 0 ) {
526+ if (! ghes_hw . num_dimms ) {
500527 fake = true;
501- num_dimm = 1 ;
528+ ghes_hw . num_dimms = 1 ;
502529 }
503530
504531 layers [0 ].type = EDAC_MC_LAYER_ALL_MEM ;
505- layers [0 ].size = num_dimm ;
532+ layers [0 ].size = ghes_hw . num_dimms ;
506533 layers [0 ].is_virt_csrow = true;
507534
508535 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)
533560 pr_info ("So, the end result of using this driver varies from vendor to vendor.\n" );
534561 pr_info ("If you find incorrect reports, please contact your hardware vendor\n" );
535562 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 );
537564 }
538565
539566 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+
543591 } else {
544592 struct dimm_info * dimm = edac_get_dimm (mci , 0 , 0 , 0 );
545593
@@ -552,7 +600,7 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
552600
553601 rc = edac_mc_add_mc (mci );
554602 if (rc < 0 ) {
555- pr_info ("Can't register at EDAC core\n" );
603+ pr_info ("Can't register with the EDAC core\n" );
556604 edac_mc_free (mci );
557605 rc = - ENODEV ;
558606 goto unlock ;
@@ -566,6 +614,11 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev)
566614 refcount_set (& ghes_refcount , 1 );
567615
568616unlock :
617+
618+ /* Not needed anymore */
619+ kfree (ghes_hw .dimms );
620+ ghes_hw .dimms = NULL ;
621+
569622 mutex_unlock (& ghes_reg_mutex );
570623
571624 return rc ;
0 commit comments