firmware: dmi_scan: Look for SMBIOS 3 entry point first
Since version 3.0.0 of the SMBIOS specification, there can be multiple entry points in memory, pointing to one or two DMI tables. If both a 32-bit ("_SM_") entry point and a 64-bit ("_SM3_") entry point are present, the specification requires that the latter points to a table which is a super-set of the table pointed to by the former. Therefore we should give preference to the 64-bit ("_SM3_") entry point. However, currently the code is picking the first valid entry point it finds. Per specification, we should look for a 64-bit ("_SM3_") entry point first, and if we can't find any, look for a 32-bit ("_SM_" or "_DMI_") entry point. Modify the code to do that. Signed-off-by: Jean Delvare <jdelvare@suse.de>
This commit is contained in:
parent
3c2993b8c6
commit
c9aba14362
|
@ -649,6 +649,21 @@ void __init dmi_scan_machine(void)
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same logic as above, look for a 64-bit entry point
|
||||||
|
* first, and if not found, fall back to 32-bit entry point.
|
||||||
|
*/
|
||||||
|
memcpy_fromio(buf, p, 16);
|
||||||
|
for (q = p + 16; q < p + 0x10000; q += 16) {
|
||||||
|
memcpy_fromio(buf + 16, q, 16);
|
||||||
|
if (!dmi_smbios3_present(buf)) {
|
||||||
|
dmi_available = 1;
|
||||||
|
dmi_early_unmap(p, 0x10000);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memcpy(buf, buf + 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate over all possible DMI header addresses q.
|
* Iterate over all possible DMI header addresses q.
|
||||||
* Maintain the 32 bytes around q in buf. On the
|
* Maintain the 32 bytes around q in buf. On the
|
||||||
|
@ -659,7 +674,7 @@ void __init dmi_scan_machine(void)
|
||||||
memset(buf, 0, 16);
|
memset(buf, 0, 16);
|
||||||
for (q = p; q < p + 0x10000; q += 16) {
|
for (q = p; q < p + 0x10000; q += 16) {
|
||||||
memcpy_fromio(buf + 16, q, 16);
|
memcpy_fromio(buf + 16, q, 16);
|
||||||
if (!dmi_smbios3_present(buf) || !dmi_present(buf)) {
|
if (!dmi_present(buf)) {
|
||||||
dmi_available = 1;
|
dmi_available = 1;
|
||||||
dmi_early_unmap(p, 0x10000);
|
dmi_early_unmap(p, 0x10000);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
Loading…
Reference in New Issue