virtchnl: fix fake 1-elem arrays in structures allocated as `nents + 1`
[linux-block.git] / include / linux / avf / virtchnl.h
index 3ab207c148095338f1661c6be34b7c1bb1b522f7..c1a20b533fc0d14809a8c97666787e7623681169 100644 (file)
@@ -268,10 +268,11 @@ struct virtchnl_vf_resource {
        u32 rss_key_size;
        u32 rss_lut_size;
 
-       struct virtchnl_vsi_resource vsi_res[1];
+       struct virtchnl_vsi_resource vsi_res[];
 };
 
-VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource);
+VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_vf_resource);
+#define virtchnl_vf_resource_LEGACY_SIZEOF     36
 
 /* VIRTCHNL_OP_CONFIG_TX_QUEUE
  * VF sends this message to set up parameters for one TX queue.
@@ -340,10 +341,11 @@ struct virtchnl_vsi_queue_config_info {
        u16 vsi_id;
        u16 num_queue_pairs;
        u32 pad;
-       struct virtchnl_queue_pair_info qpair[1];
+       struct virtchnl_queue_pair_info qpair[];
 };
 
-VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);
+VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_vsi_queue_config_info);
+#define virtchnl_vsi_queue_config_info_LEGACY_SIZEOF   72
 
 /* VIRTCHNL_OP_REQUEST_QUEUES
  * VF sends this message to request the PF to allocate additional queues to
@@ -385,10 +387,11 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map);
 
 struct virtchnl_irq_map_info {
        u16 num_vectors;
-       struct virtchnl_vector_map vecmap[1];
+       struct virtchnl_vector_map vecmap[];
 };
 
-VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info);
+VIRTCHNL_CHECK_STRUCT_LEN(2, virtchnl_irq_map_info);
+#define virtchnl_irq_map_info_LEGACY_SIZEOF    14
 
 /* VIRTCHNL_OP_ENABLE_QUEUES
  * VIRTCHNL_OP_DISABLE_QUEUES
@@ -459,10 +462,11 @@ VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr);
 struct virtchnl_ether_addr_list {
        u16 vsi_id;
        u16 num_elements;
-       struct virtchnl_ether_addr list[1];
+       struct virtchnl_ether_addr list[];
 };
 
-VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);
+VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_ether_addr_list);
+#define virtchnl_ether_addr_list_LEGACY_SIZEOF 12
 
 /* VIRTCHNL_OP_ADD_VLAN
  * VF sends this message to add one or more VLAN tag filters for receives.
@@ -481,10 +485,11 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);
 struct virtchnl_vlan_filter_list {
        u16 vsi_id;
        u16 num_elements;
-       u16 vlan_id[1];
+       u16 vlan_id[];
 };
 
-VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list);
+VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_vlan_filter_list);
+#define virtchnl_vlan_filter_list_LEGACY_SIZEOF        6
 
 /* This enum is used for all of the VIRTCHNL_VF_OFFLOAD_VLAN_V2_CAPS related
  * structures and opcodes.
@@ -1372,11 +1377,19 @@ VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_fdir_del);
 #define __vss_byone(p, member, count, old)                                   \
        (struct_size(p, member, count) + (old - 1 - struct_size(p, member, 0)))
 
+#define __vss_full(p, member, count, old)                                    \
+       (struct_size(p, member, count) + (old - struct_size(p, member, 0)))
+
 #define __vss(type, func, p, member, count)            \
        struct type: func(p, member, count, type##_LEGACY_SIZEOF)
 
 #define virtchnl_struct_size(p, m, c)                                        \
        _Generic(*p,                                                          \
+                __vss(virtchnl_vf_resource, __vss_full, p, m, c),            \
+                __vss(virtchnl_vsi_queue_config_info, __vss_full, p, m, c),  \
+                __vss(virtchnl_irq_map_info, __vss_full, p, m, c),           \
+                __vss(virtchnl_ether_addr_list, __vss_full, p, m, c),        \
+                __vss(virtchnl_vlan_filter_list, __vss_full, p, m, c),       \
                 __vss(virtchnl_rss_key, __vss_byone, p, m, c),               \
                 __vss(virtchnl_rss_lut, __vss_byone, p, m, c))
 
@@ -1414,24 +1427,23 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
                valid_len = sizeof(struct virtchnl_rxq_info);
                break;
        case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
-               valid_len = sizeof(struct virtchnl_vsi_queue_config_info);
+               valid_len = virtchnl_vsi_queue_config_info_LEGACY_SIZEOF;
                if (msglen >= valid_len) {
                        struct virtchnl_vsi_queue_config_info *vqc =
                            (struct virtchnl_vsi_queue_config_info *)msg;
-                       valid_len += (vqc->num_queue_pairs *
-                                     sizeof(struct
-                                            virtchnl_queue_pair_info));
+                       valid_len = virtchnl_struct_size(vqc, qpair,
+                                                        vqc->num_queue_pairs);
                        if (vqc->num_queue_pairs == 0)
                                err_msg_format = true;
                }
                break;
        case VIRTCHNL_OP_CONFIG_IRQ_MAP:
-               valid_len = sizeof(struct virtchnl_irq_map_info);
+               valid_len = virtchnl_irq_map_info_LEGACY_SIZEOF;
                if (msglen >= valid_len) {
                        struct virtchnl_irq_map_info *vimi =
                            (struct virtchnl_irq_map_info *)msg;
-                       valid_len += (vimi->num_vectors *
-                                     sizeof(struct virtchnl_vector_map));
+                       valid_len = virtchnl_struct_size(vimi, vecmap,
+                                                        vimi->num_vectors);
                        if (vimi->num_vectors == 0)
                                err_msg_format = true;
                }
@@ -1442,23 +1454,24 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
                break;
        case VIRTCHNL_OP_ADD_ETH_ADDR:
        case VIRTCHNL_OP_DEL_ETH_ADDR:
-               valid_len = sizeof(struct virtchnl_ether_addr_list);
+               valid_len = virtchnl_ether_addr_list_LEGACY_SIZEOF;
                if (msglen >= valid_len) {
                        struct virtchnl_ether_addr_list *veal =
                            (struct virtchnl_ether_addr_list *)msg;
-                       valid_len += veal->num_elements *
-                           sizeof(struct virtchnl_ether_addr);
+                       valid_len = virtchnl_struct_size(veal, list,
+                                                        veal->num_elements);
                        if (veal->num_elements == 0)
                                err_msg_format = true;
                }
                break;
        case VIRTCHNL_OP_ADD_VLAN:
        case VIRTCHNL_OP_DEL_VLAN:
-               valid_len = sizeof(struct virtchnl_vlan_filter_list);
+               valid_len = virtchnl_vlan_filter_list_LEGACY_SIZEOF;
                if (msglen >= valid_len) {
                        struct virtchnl_vlan_filter_list *vfl =
                            (struct virtchnl_vlan_filter_list *)msg;
-                       valid_len += vfl->num_elements * sizeof(u16);
+                       valid_len = virtchnl_struct_size(vfl, vlan_id,
+                                                        vfl->num_elements);
                        if (vfl->num_elements == 0)
                                err_msg_format = true;
                }