net: atlantic: add alignment checks in hw_atl2_utils_fw.c
authorMark Starovoytov <mstarovoitov@marvell.com>
Fri, 26 Jun 2020 18:40:37 +0000 (21:40 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Jun 2020 23:32:51 +0000 (16:32 -0700)
This patch adds alignment checks in all the helper macros in
hw_atl2_utils_fw.c
These alignment checks are compile-time, so runtime is not affected.

All these helper macros assume the length to be aligned (multiple of 4).
If it's not aligned, then there might be issues, e.g. stack corruption.

Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c

index 3a9352190816c17edb2c9255ada4fc1cc47a52a2..a8ce9a2c1c51b85c9919fb90864602827d273faf 100644 (file)
 #define AQ_A2_FW_READ_TRY_MAX 1000
 
 #define hw_atl2_shared_buffer_write(HW, ITEM, VARIABLE) \
+{\
+       BUILD_BUG_ON_MSG((offsetof(struct fw_interface_in, ITEM) % \
+                        sizeof(u32)) != 0,\
+                        "Unaligned write " # ITEM);\
+       BUILD_BUG_ON_MSG((sizeof(VARIABLE) %  sizeof(u32)) != 0,\
+                        "Unaligned write length " # ITEM);\
        hw_atl2_mif_shared_buf_write(HW,\
                (offsetof(struct fw_interface_in, ITEM) / sizeof(u32)),\
-               (u32 *)&(VARIABLE), sizeof(VARIABLE) / sizeof(u32))
+               (u32 *)&(VARIABLE), sizeof(VARIABLE) / sizeof(u32));\
+}
 
 #define hw_atl2_shared_buffer_get(HW, ITEM, VARIABLE) \
+{\
+       BUILD_BUG_ON_MSG((offsetof(struct fw_interface_in, ITEM) % \
+                        sizeof(u32)) != 0,\
+                        "Unaligned get " # ITEM);\
+       BUILD_BUG_ON_MSG((sizeof(VARIABLE) %  sizeof(u32)) != 0,\
+                        "Unaligned get length " # ITEM);\
        hw_atl2_mif_shared_buf_get(HW, \
                (offsetof(struct fw_interface_in, ITEM) / sizeof(u32)),\
                (u32 *)&(VARIABLE), \
-               sizeof(VARIABLE) / sizeof(u32))
+               sizeof(VARIABLE) / sizeof(u32));\
+}
 
 /* This should never be used on non atomic fields,
  * treat any > u32 read as non atomic.
@@ -33,7 +47,9 @@
 {\
        BUILD_BUG_ON_MSG((offsetof(struct fw_interface_out, ITEM) % \
                         sizeof(u32)) != 0,\
-                        "Non aligned read " # ITEM);\
+                        "Unaligned read " # ITEM);\
+       BUILD_BUG_ON_MSG((sizeof(VARIABLE) %  sizeof(u32)) != 0,\
+                        "Unaligned read length " # ITEM);\
        BUILD_BUG_ON_MSG(sizeof(VARIABLE) > sizeof(u32),\
                         "Non atomic read " # ITEM);\
        hw_atl2_mif_shared_buf_read(HW, \
 }
 
 #define hw_atl2_shared_buffer_read_safe(HW, ITEM, DATA) \
+({\
+       BUILD_BUG_ON_MSG((offsetof(struct fw_interface_out, ITEM) % \
+                        sizeof(u32)) != 0,\
+                        "Unaligned read_safe " # ITEM);\
+       BUILD_BUG_ON_MSG((sizeof(((struct fw_interface_out *)0)->ITEM) % \
+                        sizeof(u32)) != 0,\
+                        "Unaligned read_safe length " # ITEM);\
        hw_atl2_shared_buffer_read_block((HW), \
                (offsetof(struct fw_interface_out, ITEM) / sizeof(u32)),\
                sizeof(((struct fw_interface_out *)0)->ITEM) / sizeof(u32),\
-               (DATA))
+               (DATA));\
+})
 
 static int hw_atl2_shared_buffer_read_block(struct aq_hw_s *self,
                                            u32 offset, u32 dwords, void *data)