@@ -92,6 +92,12 @@ static void dmi_table(u8 *buf, int len, int num,
9292 while ((i < num ) && (data - buf + sizeof (struct dmi_header )) <= len ) {
9393 const struct dmi_header * dm = (const struct dmi_header * )data ;
9494
95+ /*
96+ * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0]
97+ */
98+ if (dm -> type == DMI_ENTRY_END_OF_TABLE )
99+ break ;
100+
95101 /*
96102 * We want to know the total length (formatted area and
97103 * strings) before decoding to make sure we won't run off the
@@ -107,7 +113,7 @@ static void dmi_table(u8 *buf, int len, int num,
107113 }
108114}
109115
110- static u32 dmi_base ;
116+ static phys_addr_t dmi_base ;
111117static u16 dmi_len ;
112118static u16 dmi_num ;
113119
@@ -467,7 +473,7 @@ static int __init dmi_present(const u8 *buf)
467473
468474 if (memcmp (buf , "_SM_" , 4 ) == 0 &&
469475 buf [5 ] < 32 && dmi_checksum (buf , buf [5 ])) {
470- smbios_ver = (buf [ 6 ] << 8 ) + buf [ 7 ] ;
476+ smbios_ver = get_unaligned_be16 (buf + 6 ) ;
471477
472478 /* Some BIOS report weird SMBIOS version, fix that up */
473479 switch (smbios_ver ) {
@@ -489,10 +495,9 @@ static int __init dmi_present(const u8 *buf)
489495 buf += 16 ;
490496
491497 if (memcmp (buf , "_DMI_" , 5 ) == 0 && dmi_checksum (buf , 15 )) {
492- dmi_num = (buf [13 ] << 8 ) | buf [12 ];
493- dmi_len = (buf [7 ] << 8 ) | buf [6 ];
494- dmi_base = (buf [11 ] << 24 ) | (buf [10 ] << 16 ) |
495- (buf [9 ] << 8 ) | buf [8 ];
498+ dmi_num = get_unaligned_le16 (buf + 12 );
499+ dmi_len = get_unaligned_le16 (buf + 6 );
500+ dmi_base = get_unaligned_le32 (buf + 8 );
496501
497502 if (dmi_walk_early (dmi_decode ) == 0 ) {
498503 if (smbios_ver ) {
@@ -514,12 +519,72 @@ static int __init dmi_present(const u8 *buf)
514519 return 1 ;
515520}
516521
522+ /*
523+ * Check for the SMBIOS 3.0 64-bit entry point signature. Unlike the legacy
524+ * 32-bit entry point, there is no embedded DMI header (_DMI_) in here.
525+ */
526+ static int __init dmi_smbios3_present (const u8 * buf )
527+ {
528+ if (memcmp (buf , "_SM3_" , 5 ) == 0 &&
529+ buf [6 ] < 32 && dmi_checksum (buf , buf [6 ])) {
530+ dmi_ver = get_unaligned_be16 (buf + 7 );
531+ dmi_len = get_unaligned_le32 (buf + 12 );
532+ dmi_base = get_unaligned_le64 (buf + 16 );
533+
534+ /*
535+ * The 64-bit SMBIOS 3.0 entry point no longer has a field
536+ * containing the number of structures present in the table.
537+ * Instead, it defines the table size as a maximum size, and
538+ * relies on the end-of-table structure type (#127) to be used
539+ * to signal the end of the table.
540+ * So let's define dmi_num as an upper bound as well: each
541+ * structure has a 4 byte header, so dmi_len / 4 is an upper
542+ * bound for the number of structures in the table.
543+ */
544+ dmi_num = dmi_len / 4 ;
545+
546+ if (dmi_walk_early (dmi_decode ) == 0 ) {
547+ pr_info ("SMBIOS %d.%d present.\n" ,
548+ dmi_ver >> 8 , dmi_ver & 0xFF );
549+ dmi_format_ids (dmi_ids_string , sizeof (dmi_ids_string ));
550+ pr_debug ("DMI: %s\n" , dmi_ids_string );
551+ return 0 ;
552+ }
553+ }
554+ return 1 ;
555+ }
556+
517557void __init dmi_scan_machine (void )
518558{
519559 char __iomem * p , * q ;
520560 char buf [32 ];
521561
522562 if (efi_enabled (EFI_CONFIG_TABLES )) {
563+ /*
564+ * According to the DMTF SMBIOS reference spec v3.0.0, it is
565+ * allowed to define both the 64-bit entry point (smbios3) and
566+ * the 32-bit entry point (smbios), in which case they should
567+ * either both point to the same SMBIOS structure table, or the
568+ * table pointed to by the 64-bit entry point should contain a
569+ * superset of the table contents pointed to by the 32-bit entry
570+ * point (section 5.2)
571+ * This implies that the 64-bit entry point should have
572+ * precedence if it is defined and supported by the OS. If we
573+ * have the 64-bit entry point, but fail to decode it, fall
574+ * back to the legacy one (if available)
575+ */
576+ if (efi .smbios3 != EFI_INVALID_TABLE_ADDR ) {
577+ p = dmi_early_remap (efi .smbios3 , 32 );
578+ if (p == NULL )
579+ goto error ;
580+ memcpy_fromio (buf , p , 32 );
581+ dmi_early_unmap (p , 32 );
582+
583+ if (!dmi_smbios3_present (buf )) {
584+ dmi_available = 1 ;
585+ goto out ;
586+ }
587+ }
523588 if (efi .smbios == EFI_INVALID_TABLE_ADDR )
524589 goto error ;
525590
@@ -552,7 +617,7 @@ void __init dmi_scan_machine(void)
552617 memset (buf , 0 , 16 );
553618 for (q = p ; q < p + 0x10000 ; q += 16 ) {
554619 memcpy_fromio (buf + 16 , q , 16 );
555- if (!dmi_present (buf )) {
620+ if (!dmi_smbios3_present ( buf ) || ! dmi_present (buf )) {
556621 dmi_available = 1 ;
557622 dmi_early_unmap (p , 0x10000 );
558623 goto out ;
0 commit comments