hyperv/ic: Fix version4 timesync message format.

It is not compat w/ the old timesync message format, which the message
type stays the same as the old timesync message.

MFC after:	1 week
Sponsored by:	Microsoft
This commit is contained in:
Sepherosa Ziehau 2016-12-23 08:41:28 +00:00
parent 650eded917
commit 69b12e53db
2 changed files with 34 additions and 9 deletions

View File

@ -114,8 +114,17 @@ struct vmbus_icmsg_timesync {
struct vmbus_icmsg_hdr ic_hdr;
uint64_t ic_hvtime;
uint64_t ic_vmtime;
uint64_t ic_rtt;
uint8_t ic_tsflags; /* VMBUS_ICMSG_TS_FLAG_ */
} __packed;
/* VMBUS_ICMSG_TYPE_TIMESYNC, MSGVER4 */
struct vmbus_icmsg_timesync4 {
struct vmbus_icmsg_hdr ic_hdr;
uint64_t ic_hvtime;
uint64_t ic_sent_tc;
uint8_t ic_tsflags; /* VMBUS_ICMSG_TS_FLAG_ */
uint8_t ic_rsvd[5];
} __packed;
#define VMBUS_ICMSG_TS_FLAG_SYNC 0x01

View File

@ -48,8 +48,11 @@ __FBSDID("$FreeBSD$");
#define VMBUS_TIMESYNC_MSGVER \
VMBUS_IC_VERSION(VMBUS_TIMESYNC_MSGVER_MAJOR, 0)
#define VMBUS_TIMESYNC_MSGVER4(sc) \
VMBUS_ICVER_LE(VMBUS_IC_VERSION(4, 0), (sc)->ic_msgver)
#define VMBUS_TIMESYNC_DORTT(sc) \
((sc)->ic_msgver >= VMBUS_IC_VERSION(4, 0) && \
(VMBUS_TIMESYNC_MSGVER4((sc)) &&\
(hyperv_features & CPUID_HV_MSR_TIME_REFCNT))
static int vmbus_timesync_probe(device_t);
@ -174,7 +177,6 @@ vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc)
{
struct vmbus_ic_softc *sc = xsc;
struct vmbus_icmsg_hdr *hdr;
const struct vmbus_icmsg_timesync *msg;
int dlen, error;
uint64_t xactid;
void *data;
@ -209,14 +211,28 @@ vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc)
break;
case VMBUS_ICMSG_TYPE_TIMESYNC:
if (dlen < sizeof(*msg)) {
device_printf(sc->ic_dev, "invalid timesync len %d\n",
dlen);
return;
if (VMBUS_TIMESYNC_MSGVER4(sc)) {
const struct vmbus_icmsg_timesync4 *msg4;
if (dlen < sizeof(*msg4)) {
device_printf(sc->ic_dev, "invalid timesync4 "
"len %d\n", dlen);
return;
}
msg4 = data;
vmbus_timesync(sc, msg4->ic_hvtime, msg4->ic_sent_tc,
msg4->ic_tsflags);
} else {
const struct vmbus_icmsg_timesync *msg;
if (dlen < sizeof(*msg)) {
device_printf(sc->ic_dev, "invalid timesync "
"len %d\n", dlen);
return;
}
msg = data;
vmbus_timesync(sc, msg->ic_hvtime, 0, msg->ic_tsflags);
}
msg = data;
vmbus_timesync(sc, msg->ic_hvtime, msg->ic_sent_tc,
msg->ic_tsflags);
break;
default: