-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally.
Use the `DEFINE_RAW_FLEX()` helper for a few on-stack definitions of a flexible structure where the size of the flexible-array member is known at compile-time, and refactor the rest of the code, accordingly. So, with these changes, fix the following warnings: drivers/pci/controller/pci-hyperv.c:3809:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/pci/controller/pci-hyperv.c:2831:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/pci/controller/pci-hyperv.c:2468:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/pci/controller/pci-hyperv.c:1830:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/pci/controller/pci-hyperv.c:1593:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/pci/controller/pci-hyperv.c:1504:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/pci/controller/pci-hyperv.c:1424:35: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Signed-off-by: Gustavo A. R. Silva <gustavo...@kernel.org> --- drivers/pci/controller/pci-hyperv.c | 126 ++++++++++++---------------- 1 file changed, 55 insertions(+), 71 deletions(-) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index e1eaa24559a2..f2b5036bcf64 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -1420,10 +1420,8 @@ static int hv_read_config_block(struct pci_dev *pdev, void *buf, struct hv_pcibus_device *hbus = container_of(pdev->bus->sysdata, struct hv_pcibus_device, sysdata); - struct { - struct pci_packet pkt; - char buf[sizeof(struct pci_read_block)]; - } pkt; + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, + sizeof(struct pci_read_block)); struct hv_read_config_compl comp_pkt; struct pci_read_block *read_blk; int ret; @@ -1435,17 +1433,16 @@ static int hv_read_config_block(struct pci_dev *pdev, void *buf, comp_pkt.buf = buf; comp_pkt.len = len; - memset(&pkt, 0, sizeof(pkt)); - pkt.pkt.completion_func = hv_pci_read_config_compl; - pkt.pkt.compl_ctxt = &comp_pkt; - read_blk = (struct pci_read_block *)&pkt.pkt.message; + pkt->completion_func = hv_pci_read_config_compl; + pkt->compl_ctxt = &comp_pkt; + read_blk = (struct pci_read_block *)pkt->message; read_blk->message_type.type = PCI_READ_BLOCK; read_blk->wslot.slot = devfn_to_wslot(pdev->devfn); read_blk->block_id = block_id; read_blk->bytes_requested = len; ret = vmbus_sendpacket(hbus->hdev->channel, read_blk, - sizeof(*read_blk), (unsigned long)&pkt.pkt, + sizeof(*read_blk), (unsigned long)pkt, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) @@ -1500,11 +1497,8 @@ static int hv_write_config_block(struct pci_dev *pdev, void *buf, struct hv_pcibus_device *hbus = container_of(pdev->bus->sysdata, struct hv_pcibus_device, sysdata); - struct { - struct pci_packet pkt; - char buf[sizeof(struct pci_write_block)]; - u32 reserved; - } pkt; + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, + sizeof(struct pci_write_block) + sizeof(u32)); struct hv_pci_compl comp_pkt; struct pci_write_block *write_blk; u32 pkt_size; @@ -1515,10 +1509,9 @@ static int hv_write_config_block(struct pci_dev *pdev, void *buf, init_completion(&comp_pkt.host_event); - memset(&pkt, 0, sizeof(pkt)); - pkt.pkt.completion_func = hv_pci_write_config_compl; - pkt.pkt.compl_ctxt = &comp_pkt; - write_blk = (struct pci_write_block *)&pkt.pkt.message; + pkt->completion_func = hv_pci_write_config_compl; + pkt->compl_ctxt = &comp_pkt; + write_blk = (struct pci_write_block *)pkt->message; write_blk->message_type.type = PCI_WRITE_BLOCK; write_blk->wslot.slot = devfn_to_wslot(pdev->devfn); write_blk->block_id = block_id; @@ -1532,10 +1525,10 @@ static int hv_write_config_block(struct pci_dev *pdev, void *buf, * and new hosts, because, on them, what really matters is the length * specified in write_blk->byte_count. */ - pkt_size += sizeof(pkt.reserved); + pkt_size += sizeof(u32); ret = vmbus_sendpacket(hbus->hdev->channel, write_blk, pkt_size, - (unsigned long)&pkt.pkt, VM_PKT_DATA_INBAND, + (unsigned long)pkt, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) return ret; @@ -1589,17 +1582,14 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev, struct tran_int_desc *int_desc) { struct pci_delete_interrupt *int_pkt; - struct { - struct pci_packet pkt; - u8 buffer[sizeof(struct pci_delete_interrupt)]; - } ctxt; + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, + sizeof(struct pci_delete_interrupt)); if (!int_desc->vector_count) { kfree(int_desc); return; } - memset(&ctxt, 0, sizeof(ctxt)); - int_pkt = (struct pci_delete_interrupt *)&ctxt.pkt.message; + int_pkt = (struct pci_delete_interrupt *)pkt->message; int_pkt->message_type.type = PCI_DELETE_INTERRUPT_MESSAGE; int_pkt->wslot.slot = hpdev->desc.win_slot.slot; @@ -1798,6 +1788,12 @@ static u32 hv_compose_msi_req_v3( return sizeof(*int_pkt); } +union int_pkts { + struct pci_create_interrupt v1; + struct pci_create_interrupt2 v2; + struct pci_create_interrupt3 v3; +}; + /** * hv_compose_msi_msg() - Supplies a valid MSI address/data * @data: Everything about this MSI @@ -1811,6 +1807,13 @@ static u32 hv_compose_msi_req_v3( */ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) { + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, sizeof(union int_pkts)); + struct pci_create_interrupt *pkt_v1 = + (struct pci_create_interrupt *)pkt->message; + struct pci_create_interrupt2 *pkt_v2 = + (struct pci_create_interrupt2 *)pkt->message; + struct pci_create_interrupt3 *pkt_v3 = + (struct pci_create_interrupt3 *)pkt->message; struct hv_pcibus_device *hbus; struct vmbus_channel *channel; struct hv_pci_dev *hpdev; @@ -1826,14 +1829,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) */ u16 vector_count; u32 vector; - struct { - struct pci_packet pci_pkt; - union { - struct pci_create_interrupt v1; - struct pci_create_interrupt2 v2; - struct pci_create_interrupt3 v3; - } int_pkts; - } __packed ctxt; bool multi_msi; u64 trans_id; u32 size; @@ -1910,14 +1905,13 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) * can't exceed u8. Cast 'vector' down to u8 for v1/v2 explicitly * for better readability. */ - memset(&ctxt, 0, sizeof(ctxt)); init_completion(&comp.comp_pkt.host_event); - ctxt.pci_pkt.completion_func = hv_pci_compose_compl; - ctxt.pci_pkt.compl_ctxt = ∁ + pkt->completion_func = hv_pci_compose_compl; + pkt->compl_ctxt = ∁ switch (hbus->protocol_version) { case PCI_PROTOCOL_VERSION_1_1: - size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1, + size = hv_compose_msi_req_v1(pkt_v1, hpdev->desc.win_slot.slot, (u8)vector, vector_count); @@ -1925,7 +1919,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) case PCI_PROTOCOL_VERSION_1_2: case PCI_PROTOCOL_VERSION_1_3: - size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2, + size = hv_compose_msi_req_v2(pkt_v2, cpu, hpdev->desc.win_slot.slot, (u8)vector, @@ -1933,7 +1927,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) break; case PCI_PROTOCOL_VERSION_1_4: - size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3, + size = hv_compose_msi_req_v3(pkt_v3, cpu, hpdev->desc.win_slot.slot, vector, @@ -1950,8 +1944,8 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) goto free_int_desc; } - ret = vmbus_sendpacket_getid(hpdev->hbus->hdev->channel, &ctxt.int_pkts, - size, (unsigned long)&ctxt.pci_pkt, + ret = vmbus_sendpacket_getid(hpdev->hbus->hdev->channel, pkt->message, + size, (unsigned long)pkt, &trans_id, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) { @@ -2034,7 +2028,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) * * Cf. hv_pci_onchannelcallback(). */ - vmbus_request_addr_match(channel, trans_id, (unsigned long)&ctxt.pci_pkt); + vmbus_request_addr_match(channel, trans_id, (unsigned long)pkt); free_int_desc: kfree(int_desc); drop_reference: @@ -2464,10 +2458,8 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus, struct hv_pci_dev *hpdev; struct pci_child_message *res_req; struct q_res_req_compl comp_pkt; - struct { - struct pci_packet init_packet; - u8 buffer[sizeof(struct pci_child_message)]; - } pkt; + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, + sizeof(struct pci_child_message)); unsigned long flags; int ret; @@ -2477,18 +2469,17 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus, hpdev->hbus = hbus; - memset(&pkt, 0, sizeof(pkt)); init_completion(&comp_pkt.host_event); comp_pkt.hpdev = hpdev; - pkt.init_packet.compl_ctxt = &comp_pkt; - pkt.init_packet.completion_func = q_resource_requirements; - res_req = (struct pci_child_message *)&pkt.init_packet.message; + pkt->compl_ctxt = &comp_pkt; + pkt->completion_func = q_resource_requirements; + res_req = (struct pci_child_message *)pkt->message; res_req->message_type.type = PCI_QUERY_RESOURCE_REQUIREMENTS; res_req->wslot.slot = desc->win_slot.slot; ret = vmbus_sendpacket(hbus->hdev->channel, res_req, - sizeof(struct pci_child_message), - (unsigned long)&pkt.init_packet, + __member_size(pkt->message), + (unsigned long)pkt, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) @@ -2827,10 +2818,8 @@ static void hv_eject_device_work(struct work_struct *work) struct pci_dev *pdev; unsigned long flags; int wslot; - struct { - struct pci_packet pkt; - u8 buffer[sizeof(struct pci_eject_response)]; - } ctxt; + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, + sizeof(struct pci_eject_response)); hpdev = container_of(work, struct hv_pci_dev, wrk); hbus = hpdev->hbus; @@ -2859,8 +2848,7 @@ static void hv_eject_device_work(struct work_struct *work) if (hpdev->pci_slot) pci_destroy_slot(hpdev->pci_slot); - memset(&ctxt, 0, sizeof(ctxt)); - ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; + ejct_pkt = (struct pci_eject_response *)pkt->message; ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE; ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot; vmbus_sendpacket(hbus->hdev->channel, ejct_pkt, @@ -3805,10 +3793,7 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) { struct hv_pcibus_device *hbus = hv_get_drvdata(hdev); struct vmbus_channel *chan = hdev->channel; - struct { - struct pci_packet teardown_packet; - u8 buffer[sizeof(struct pci_message)]; - } pkt; + DEFINE_RAW_FLEX(struct pci_packet, pkt, message, 1); struct hv_pci_compl comp_pkt; struct hv_pci_dev *hpdev, *tmp; unsigned long flags; @@ -3850,15 +3835,14 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) return ret; } - memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet)); init_completion(&comp_pkt.host_event); - pkt.teardown_packet.completion_func = hv_pci_generic_compl; - pkt.teardown_packet.compl_ctxt = &comp_pkt; - pkt.teardown_packet.message[0].type = PCI_BUS_D0EXIT; + pkt->completion_func = hv_pci_generic_compl; + pkt->compl_ctxt = &comp_pkt; + pkt->message[0].type = PCI_BUS_D0EXIT; - ret = vmbus_sendpacket_getid(chan, &pkt.teardown_packet.message, - sizeof(struct pci_message), - (unsigned long)&pkt.teardown_packet, + ret = vmbus_sendpacket_getid(chan, pkt->message, + __member_size(pkt->message), + (unsigned long)pkt, &trans_id, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret) @@ -3873,7 +3857,7 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) * Cf. hv_pci_onchannelcallback(). */ vmbus_request_addr_match(chan, trans_id, - (unsigned long)&pkt.teardown_packet); + (unsigned long)pkt); return -ETIMEDOUT; } -- 2.43.0