From 9773afb97fc30d22db14a425fea519f4a658dc4e Mon Sep 17 00:00:00 2001 From: Jakub Byczkowski Date: Mon, 2 Oct 2017 11:04:03 -0700 Subject: [PATCH] IB/hfi1: Add parsing for platform configuration format version 4 Platform configuration format version 4, that didn't use the file size field, is not parsed by the host driver. Only version 5 is supported. Add logic in parsing procedure to determine what format is being used and allow to read data from version 4 files. Reviewed-by: Jan Sokolowski Reviewed-by: Ira Weiny Reviewed-by: Andrzej Kacprowski Signed-off-by: Jakub Byczkowski Signed-off-by: Dennis Dalessandro Signed-off-by: Doug Ledford --- drivers/infiniband/hw/hfi1/firmware.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c index 5aea8f47e670..9471c4063ebe 100644 --- a/drivers/infiniband/hw/hfi1/firmware.c +++ b/drivers/infiniband/hw/hfi1/firmware.c @@ -113,6 +113,12 @@ struct css_header { #define MU_SIZE 8 #define EXPONENT_SIZE 4 +/* size of platform configuration partition */ +#define MAX_PLATFORM_CONFIG_FILE_SIZE 4096 + +/* size of file of plaform configuration encoded in format version 4 */ +#define PLATFORM_CONFIG_FORMAT_4_FILE_SIZE 528 + /* the file itself */ struct firmware_file { struct css_header css_header; @@ -1774,7 +1780,20 @@ int parse_platform_config(struct hfi1_devdata *dd) /* Field is file size in DWORDs */ file_length = (*ptr) * 4; - ptr++; + + /* + * Length can't be larger than partition size. Assume platform + * config format version 4 is being used. Interpret the file size + * field as header instead by not moving the pointer. + */ + if (file_length > MAX_PLATFORM_CONFIG_FILE_SIZE) { + dd_dev_info(dd, + "%s:File length out of bounds, using alternative format\n", + __func__); + file_length = PLATFORM_CONFIG_FORMAT_4_FILE_SIZE; + } else { + ptr++; + } if (file_length > dd->platform_config.size) { dd_dev_info(dd, "%s:File claims to be larger than read size\n", @@ -1789,7 +1808,8 @@ int parse_platform_config(struct hfi1_devdata *dd) /* * In both cases where we proceed, using the self-reported file length - * is the safer option + * is the safer option. In case of old format a predefined value is + * being used. */ while (ptr < (u32 *)(dd->platform_config.data + file_length)) { header1 = *ptr;