Index: sys/dev/hyperv/utilities/hv_heartbeat.c =================================================================== --- sys/dev/hyperv/utilities/hv_heartbeat.c +++ sys/dev/hyperv/utilities/hv_heartbeat.c @@ -80,7 +80,7 @@ */ switch (hdr->ic_type) { case VMBUS_ICMSG_TYPE_NEGOTIATE: - error = vmbus_ic_negomsg(sc, data, dlen); + error = vmbus_ic_negomsg(sc, data, &dlen); if (error) return; break; Index: sys/dev/hyperv/utilities/hv_shutdown.c =================================================================== --- sys/dev/hyperv/utilities/hv_shutdown.c +++ sys/dev/hyperv/utilities/hv_shutdown.c @@ -87,7 +87,7 @@ if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { int error; - error = vmbus_ic_negomsg(softc, buf, recv_len); + error = vmbus_ic_negomsg(softc, buf, &recv_len); if (error) return; } else { Index: sys/dev/hyperv/utilities/hv_timesync.c =================================================================== --- sys/dev/hyperv/utilities/hv_timesync.c +++ sys/dev/hyperv/utilities/hv_timesync.c @@ -162,7 +162,7 @@ if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { int error; - error = vmbus_ic_negomsg(&softc->util_sc, time_buf, recvlen); + error = vmbus_ic_negomsg(&softc->util_sc, time_buf, &recvlen); if (error) return; } else { Index: sys/dev/hyperv/utilities/hv_util.h =================================================================== --- sys/dev/hyperv/utilities/hv_util.h +++ sys/dev/hyperv/utilities/hv_util.h @@ -54,6 +54,6 @@ int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); int hv_util_detach(device_t dev); int vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]); -int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int dlen); +int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int *dlen); #endif Index: sys/dev/hyperv/utilities/hv_util.c =================================================================== --- sys/dev/hyperv/utilities/hv_util.c +++ sys/dev/hyperv/utilities/hv_util.c @@ -48,13 +48,16 @@ #define VMBUS_IC_BRSIZE (4 * PAGE_SIZE) -CTASSERT(sizeof(struct vmbus_icmsg_negotiate) < VMBUS_IC_BRSIZE); +#define VMBUS_IC_VERCNT 2 +#define VMBUS_IC_NEGOSZ \ + __offsetof(struct vmbus_icmsg_negotiate, ic_ver[VMBUS_IC_VERCNT]) +CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE); int -vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int dlen) +vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0) { struct vmbus_icmsg_negotiate *nego; - int cnt, major; + int cnt, major, dlen = *dlen0; /* * Preliminary message size verification @@ -87,9 +90,13 @@ nego->ic_msgver_cnt = 1; nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0); - /* Data contains two versions */ - nego->ic_hdr.ic_dsize = __offsetof(struct vmbus_icmsg_negotiate, - ic_ver[2]) - sizeof(struct vmbus_icmsg_hdr); + /* Update data size */ + nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ - + sizeof(struct vmbus_icmsg_hdr); + + /* Update total size, if necessary */ + if (dlen < VMBUS_IC_NEGOSZ) + *dlen0 = VMBUS_IC_NEGOSZ; return 0; }