[PATCH] dmi: dmi_decode: make advice more relevant to data handled by the kernel

IvanHu ivan.hu at canonical.com
Wed Jul 18 08:19:53 UTC 2012


On 07/18/2012 04:30 AM, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>   src/dmi/dmi_decode/dmi_decode.c |  154 ++++++++++++++++++++++++++++++++-------
>   1 file changed, 127 insertions(+), 27 deletions(-)
>
> diff --git a/src/dmi/dmi_decode/dmi_decode.c b/src/dmi/dmi_decode/dmi_decode.c
> index d266bea..f80f1a9 100644
> --- a/src/dmi/dmi_decode/dmi_decode.c
> +++ b/src/dmi/dmi_decode/dmi_decode.c
> @@ -78,6 +78,11 @@ typedef struct {
>   	uint8_t   mapped;
>   } fwts_chassis_type_map;
>
> +typedef struct {
> +	uint8_t	type;
> +	uint8_t	offset;
> +} fwts_dmi_used_by_kernel;
> +
>   static const fwts_dmi_pattern dmi_patterns[] = {
>   	{ "DMISerialNumber",	"Serial Number", 	"0123456789" },
>   	{ "DMIAssetTag",	"Asset Tag",		"1234567890" },
> @@ -143,6 +148,62 @@ static const fwts_dmi_version dmi_versions[] = {
>   	{ 0, 0 }
>   };
>
> +#define FIELD_ANY	0xff
> +#define TYPE_EOD	0xff
> +
> +/*
> + *  DMI decoded fields used by the kernel, i.e. fields
> + *  we care that work,
> + *	see drivers/firmware/dmi_scan.c, dmi_decode()
> + */
> +static fwts_dmi_used_by_kernel dmi_used_by_kernel_table[] = {
> +	/* Type 0 BIOS Information fields */
> +	{ 0, 4 },
> +	{ 0, 5 },
> +	{ 0, 8 },
> +	/* Type 1, System Information */
> +	{ 1, 4 },
> +	{ 1, 5 },
> +	{ 1, 6 },
> +	{ 1, 7 },
> +	{ 1, 8 },
> +	/* Type 2, Base Board Information */
> +	{ 2, 4 },
> +	{ 2, 5 },
> +	{ 2, 6 },
> +	{ 2, 7 },
> +	{ 2, 8 },
> +	/* Type 3, Chassis Information */
> +	{ 3, 4 },
> +	{ 3, 5 },
> +	{ 3, 6 },
> +	{ 3, 7 },
> +	{ 3, 8 },
> +	/* Type 10, Onboard Devices Information */
> +	{ 10, FIELD_ANY },
> +	/* Type 11, OEM Strings */
> +	{ 11, FIELD_ANY },
> +	/* Type 38, IPMI Device Information */
> +	{ 38, FIELD_ANY },
> +	/* Type 41, Onboard Devices Extended Information */
> +	{ 41, FIELD_ANY },
> +	/* End */
> +	{ TYPE_EOD, 0xff },
> +};
> +
> +static bool dmi_used_by_kernel(uint8_t type, uint8_t offset)
> +{
> +	int i;
> +
> +	for (i = 0; dmi_used_by_kernel_table[i].type != TYPE_EOD; i++) {
> +		if (dmi_used_by_kernel_table[i].type == type)
> +			if ((dmi_used_by_kernel_table[i].offset == FIELD_ANY) ||
> +			    (dmi_used_by_kernel_table[i].offset == offset))
> +				return true;
> +	}
> +	return false;
> +}
> +
>   static uint16_t dmi_remap_version(fwts_framework *fw, uint16_t old)
>   {
>   	int i;
> @@ -162,15 +223,21 @@ static uint16_t dmi_remap_version(fwts_framework *fw, uint16_t old)
>   	return old;
>   }
>
> -static void dmi_out_of_range_advice(fwts_framework *fw)
> +static void dmi_out_of_range_advice(fwts_framework *fw, uint8_t type, uint8_t offset)
>   {
> -	fwts_advice(fw,
> -		"A value that is out of range is incorrect and not conforming to "
> -		"the SMBIOS specification.  It is possible that it "
> -		"won't be handled correctly by the operating system or by tools "
> -		"like dmidecode. For some fields this out of range setings "
> -		"could lead to the operating system to ignore or misunderstand this "
> -		"particular SMBIOS configuration.");
> +	if (dmi_used_by_kernel(type, offset))
> +		fwts_advice(fw,
> +			"A value that is out of range is incorrect and not conforming to "
> +			"the SMBIOS specification.  The Linux kernel extracts and uses "
> +			"this particular data item, so it is recommended that this SMBIOS "
> +			"configuration is corrected even if the impact on the system "
> +			"is most probably not critical.");
> +	else
> +		fwts_advice(fw,
> +			"A value that is out of range is incorrect and not conforming to "
> +			"the SMBIOS specification.  This field is not currently used by "
> +			"the Linux kernel, so this firmware bug shouldn't cause any "
> +			"problems.");
>   }
>
>   static void dmi_min_max_uint8_check(fwts_framework *fw,
> @@ -189,7 +256,7 @@ static void dmi_min_max_uint8_check(fwts_framework *fw,
>   			"Out of range value 0x%2.2x (range allowed 0x%2.2x..0x%2.2x) "
>   			"while accessing entry '%s' @ 0x%8.8x, field '%s', offset 0x%2.2x",
>   			val, min, max, table, addr, field, offset);
> -		dmi_out_of_range_advice(fw);
> +		dmi_out_of_range_advice(fw, hdr->type, offset);
>   	}
>   }
>
> @@ -211,7 +278,7 @@ static void dmi_min_max_mask_uint8_check(fwts_framework *fw,
>   			"Out of range value 0x%2.2x (range allowed 0x%2.2x..0x%2.2x) "
>   			"while accessing entry '%s' @ 0x%8.8x, field '%s', offset 0x%2.2x",
>   			val, min, max, table, addr, field, offset);
> -		dmi_out_of_range_advice(fw);
> +		dmi_out_of_range_advice(fw, hdr->type, offset);
>   	}
>   }
>
> @@ -237,15 +304,29 @@ static void dmi_str_check_index(fwts_framework *fw,
>   		}
>   		/* Sanity checks */
>   		if (*data == '\0') {
> +			/* This entry is clearly broken so flag it as a corrupt entry */
>   			fwts_failed(fw, LOG_LEVEL_HIGH, DMI_STRING_INDEX_OUT_OF_RANGE,
>   				"Out of range string index 0x%2.2x while accessing entry '%s' "
>   				"@ 0x%8.8x, field '%s', offset 0x%2.2x",
>   				index, table, addr, field, offset);
> -			fwts_advice(fw,
> -				"DMI strings are stored in a manner that uses a special "
> -				"index to fetch the Nth string from the data. For this "
> -				"particular DMI string the index given is not in range "
> -				"which means this particular entry is broken.");
> +			if (dmi_used_by_kernel(hdr->type, offset))
> +				fwts_advice(fw,
> +					"DMI strings are stored in a manner that uses a special "
> +					"index to fetch the Nth string from the data. For this "
> +					"particular DMI string the index given is not in range "
> +					"which means this particular entry is broken. The Linux "
> +					"kernel uses this string - hence this string should be "
> +					"fixed to ensure sane data is passed to the kernel. "
> +					"Note that this probably won't cause any critical system "
> +					"errors.");
> +			else
> +				fwts_advice(fw,
> +					"DMI strings are stored in a manner that uses a special "
> +					"index to fetch the Nth string from the data. For this "
> +					"particular DMI string the index given is not in range "
> +					"which means this particular entry is broken. The Linux "
> +					"kernel does not use this string, so this error will not "
> +					"cause any system errors.");
>   			return;
>   		}
>
> @@ -262,18 +343,37 @@ static void dmi_str_check_index(fwts_framework *fw,
>   			}
>   		}
>   		if (failed != -1) {
> -			fwts_failed(fw, LOG_LEVEL_LOW, dmi_patterns[j].label,
> -				"String index 0x%2.2x in table entry '%s' @ 0x%8.8x, field '%s', "
> -				"offset 0x%2.2x has a default value '%s' and probably has "
> -				"not been updated by the BIOS vendor.",
> -				index, table, addr, field, offset, data);
> -			fwts_advice(fw,
> -				"The DMI table contains data which is clearly been "
> -				"left in a default setting and not been configured "
> -				"for this machine.  While this is not critical it does "
> -				"mean that somebody has probably forgotten to define this "
> -				"field and it basically means this field is effectively "
> -				"useless.");
> +			if (dmi_used_by_kernel(hdr->type, offset)) {
> +				fwts_failed(fw, LOG_LEVEL_MEDIUM, dmi_patterns[j].label,
> +					"String index 0x%2.2x in table entry '%s' @ 0x%8.8x, field '%s', "
> +					"offset 0x%2.2x has a default value '%s' and probably has "
> +					"not been updated by the BIOS vendor.",
> +					index, table, addr, field, offset, data);
> +				fwts_advice(fw,
> +					"The DMI table contains data which is clearly been "
> +					"left in a default setting and not been configured "
> +					"for this machine. "
> +					"Somebody has probably forgotten to define this "
> +					"field and it basically means this field is effectively "
> +					"useless. Note that the kernel uses this field so "
> +					"it probably should be corrected to ensure the kernel "
> +					"is using sane values.");
> +			} else {
> +				/* This string is broken, but we don't care about it too much */
> +				fwts_failed(fw, LOG_LEVEL_LOW, dmi_patterns[j].label,
> +					"String index 0x%2.2x in table entry '%s' @ 0x%8.8x, field '%s', "
> +					"offset 0x%2.2x has a default value '%s' and probably has "
> +					"not been updated by the BIOS vendor.",
> +					index, table, addr, field, offset, data);
> +				fwts_advice(fw,
> +					"The DMI table contains data which is clearly been "
> +					"left in a default setting and not been configured "
> +					"for this machine. "
> +					"Somebody has probably forgotten to define this "
> +					"field and it basically means this field is effectively "
> +					"useless, however the kernel does not use this data "
> +					"so the issue is fairly low.");
> +			}
>   		}
>   	}
>   }
>
Acked-by: Ivan Hu<ivan.hu at canonical.com>




More information about the fwts-devel mailing list