summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorJakub Byczkowski <jakub.byczkowski@intel.com>2017-10-02 20:04:03 +0200
committerDoug Ledford <dledford@redhat.com>2017-10-04 21:39:44 +0200
commit9773afb97fc30d22db14a425fea519f4a658dc4e (patch)
treec2cb4da1245279027b5e8cf0f9c38c63b9b19f6b /drivers/infiniband/hw
parenti40iw: Do not allow posting WR after QP is flushed (diff)
downloadlinux-9773afb97fc30d22db14a425fea519f4a658dc4e.tar.xz
linux-9773afb97fc30d22db14a425fea519f4a658dc4e.zip
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 <jan.sokolowski@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@intel.com> Signed-off-by: Jakub Byczkowski <jakub.byczkowski@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/hfi1/firmware.c24
1 files 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;