RE: [PATCH][next] PCI: hv: Avoid multiple -Wflex-array-member-not-at-end warnings

Michael Kelley
2025-04-27T15:22:23Z

From: Gustavo A. R. Silva <gustavoars@kernel.org> Sent: Friday, April 25, 2025 9:48 AM
>
> -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]

I'm supportive of cleaning up these warnings. I've worked with the pci-hyperv.c
code a fair amount over the years, but never had looked closely at the on-stack
structs that are causing the warnings. The current code is a bit unusual and
perhaps unnecessarily obtuse.

Rather than the approach you've taken below, I tried removing the flex array
entirely from struct pci_packet. In all cases except one, it was used only to
locate the end of struct pci_packet, which is the beginning of the follow-on
message. Locating that follow-on message can easily be done by just referencing
the "buf" field in the on-stack structs, or as (pkt + 1) in the dynamically allocated
case. In both cases, there's no need for the flex array. In the one exception, a
couple of minor tweaks avoids the need for the flex array as well.

So here's an alternate approach to solving the problem. This approach is
14 insertions and 15 deletions, so it's a lot less change than your approach.
I still don't understand why the on-stack struct are declared as (for example):

struct {
struct pci_packet pkt;
char buf[sizeof(struct pci_read_block)];
} pkt;

instead of just:

struct {
struct pci_packet pkt;
struct pci_read_block msg;
} pkt;

but that's a topic for another time. Anyway, here's my proposed diff, which I've
compiled and smoke-tested in a VM in the Azure cloud:

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index e1eaa24559a2..ca5459e0dfcb 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -309,8 +309,6 @@ struct pci_packet {
void (*completion_func)(void *context, struct pci_response *resp,
int resp_packet_size);
void *compl_ctxt;
-
- struct pci_message message[];
};

/*
@@ -1438,7 +1436,7 @@ static int hv_read_config_block(struct pci_dev *pdev, void *buf,
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;
+ read_blk = (struct pci_read_block *)pkt.buf;
read_blk->message_type.type = PCI_READ_BLOCK;
read_blk->wslot.slot = devfn_to_wslot(pdev->devfn);
read_blk->block_id = block_id;
@@ -1518,7 +1516,7 @@ static int hv_write_config_block(struct pci_dev *pdev, void *buf,
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;
+ write_blk = (struct pci_write_block *)pkt.buf;
write_blk->message_type.type = PCI_WRITE_BLOCK;
write_blk->wslot.slot = devfn_to_wslot(pdev->devfn);
write_blk->block_id = block_id;
@@ -1599,7 +1597,7 @@ static void hv_int_desc_free(struct hv_pci_dev *hpdev,
return;
}
memset(&ctxt, 0, sizeof(ctxt));
- int_pkt = (struct pci_delete_interrupt *)&ctxt.pkt.message;
+ int_pkt = (struct pci_delete_interrupt *)ctxt.buffer;
int_pkt->message_type.type =
PCI_DELETE_INTERRUPT_MESSAGE;
int_pkt->wslot.slot = hpdev->desc.win_slot.slot;
@@ -2482,7 +2480,7 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus,
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;
+ res_req = (struct pci_child_message *)pkt.buffer;
res_req->message_type.type = PCI_QUERY_RESOURCE_REQUIREMENTS;
res_req->wslot.slot = desc->win_slot.slot;

@@ -2860,7 +2858,7 @@ static void hv_eject_device_work(struct work_struct *work)
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 *)ctxt.buffer;
ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE;
ejct_pkt->wslot.slot = hpdev->desc.win_slot.slot;
vmbus_sendpacket(hbus->hdev->channel, ejct_pkt,
@@ -3118,7 +3116,7 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev,
init_completion(&comp_pkt.host_event);
pkt->completion_func = hv_pci_generic_compl;
pkt->compl_ctxt = &comp_pkt;
- version_req = (struct pci_version_request *)&pkt->message;
+ version_req = (struct pci_version_request *)(pkt + 1);
version_req->message_type.type = PCI_QUERY_PROTOCOL_VERSION;

for (i = 0; i < num_version; i++) {
@@ -3340,7 +3338,7 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
init_completion(&comp_pkt.host_event);
pkt->completion_func = hv_pci_generic_compl;
pkt->compl_ctxt = &comp_pkt;
- d0_entry = (struct pci_bus_d0_entry *)&pkt->message;
+ d0_entry = (struct pci_bus_d0_entry *)(pkt + 1);
d0_entry->message_type.type = PCI_BUS_D0ENTRY;
d0_entry->mmio_base = hbus->mem_config->start;

@@ -3498,20 +3496,20 @@ static int hv_send_resources_allocated(struct hv_device *hdev)

if (hbus->protocol_version < PCI_PROTOCOL_VERSION_1_2) {
res_assigned =
- (struct pci_resources_assigned *)&pkt->message;
+ (struct pci_resources_assigned *)(pkt + 1);
res_assigned->message_type.type =
PCI_RESOURCES_ASSIGNED;
res_assigned->wslot.slot = hpdev->desc.win_slot.slot;
} else {
res_assigned2 =
- (struct pci_resources_assigned2 *)&pkt->message;
+ (struct pci_resources_assigned2 *)(pkt + 1);
res_assigned2->message_type.type =
PCI_RESOURCES_ASSIGNED2;
res_assigned2->wslot.slot = hpdev->desc.win_slot.slot;
}
put_pcichild(hpdev);

- ret = vmbus_sendpacket(hdev->channel, &pkt->message,
+ ret = vmbus_sendpacket(hdev->channel, pkt + 1,
size_res, (unsigned long)pkt,
VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -3809,6 +3807,7 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
struct pci_packet teardown_packet;
u8 buffer[sizeof(struct pci_message)];
} pkt;
+ struct pci_message *msg;
struct hv_pci_compl comp_pkt;
struct hv_pci_dev *hpdev, *tmp;
unsigned long flags;
@@ -3854,10 +3853,10 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
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;
+ msg = (struct pci_message *)pkt.buffer;
+ msg->type = PCI_BUS_D0EXIT;

- ret = vmbus_sendpacket_getid(chan, &pkt.teardown_packet.message,
- sizeof(struct pci_message),
+ ret = vmbus_sendpacket_getid(chan, msg, sizeof(*msg),
(unsigned long)&pkt.teardown_packet,
&trans_id, VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
Let me know what you think.

Michael

>
> Signed-off-by: Gustavo A. R. Silva <gustavoars@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 = &comp;
> + pkt->completion_func = hv_pci_compose_compl;
> + pkt->compl_ctxt = &comp;
>
> 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
>