From: Jean Delvare Date: Thu, 13 Aug 2015 12:48:40 +0000 (+0200) Subject: x86/dmi_scan: only honor end-of-table for 64-bit tables X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~2624^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b001c41cf2da767127ed5ebb7d906d4a284afad7;p=xen.git x86/dmi_scan: only honor end-of-table for 64-bit tables A 32-bit entry point to a DMI table says how many structures the table contains. The SMBIOS specification explicitly says that end-of-table markers should be ignored if they are not actually at the end of the DMI table. So only honor the end-of-table marker for tables accessed through 64-bit entry points, as they do not specify a structure count. Signed-off-by: Jean Delvare [Linux commit 17cd5bd5391e6e7b363d66335e1bc6760ae969b9] Signed-off-by: Jan Beulich Acked-by: Andrew Cooper Release-acked-by: Wei Liu --- diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c index 269168cc53..8e07f8d546 100644 --- a/xen/arch/x86/dmi_scan.c +++ b/xen/arch/x86/dmi_scan.c @@ -148,10 +148,11 @@ static int __init dmi_table(paddr_t base, u32 len, int num, data = buf; /* - * Stop when we see all the items the table claimed to have - * OR we run off the end of the table (also happens) - */ - + * Stop when we have seen all the items the table claimed to have + * (SMBIOS < 3.0 only) OR we reach an end-of-table marker (SMBIOS + * >= 3.0 only) OR we run off the end of the table (should never + * happen but sometimes does on bogus implementations.) + */ while((num < 0 || i < num) && data-buf+sizeof(struct dmi_header)<=len) { dm=(struct dmi_header *)data; @@ -165,8 +166,16 @@ static int __init dmi_table(paddr_t base, u32 len, int num, data++; if(data-buftype == DMI_ENTRY_END_OF_TABLE) - break; + /* + * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0] + * For tables behind a 64-bit entry point, we have no item + * count and no exact table length, so stop on end-of-table + * marker. For tables behind a 32-bit entry point, we have + * seen OEM structures behind the end-of-table marker on + * some systems, so don't trust it. + */ + if (num < 0 && dm->type == DMI_ENTRY_END_OF_TABLE) + break; data+=2; i++; }