Page MenuHomeFreeBSD

D8280.id21528.diff
No OneTemporary

D8280.id21528.diff

Index: sys/dev/hyperv/utilities/hv_heartbeat.c
===================================================================
--- sys/dev/hyperv/utilities/hv_heartbeat.c
+++ sys/dev/hyperv/utilities/hv_heartbeat.c
@@ -39,6 +39,12 @@
#include <dev/hyperv/utilities/vmbus_icreg.h>
#include "vmbus_if.h"
+#define HB_MAJOR 3
+#define HB_MINOR 0
+#define HB_VERSION VMBUS_IC_VERSION(HB_MAJOR, HB_MINOR)
+
+#define HB_WS2008_MAJOR 1
+#define HB_WS2008_VERSION VMBUS_IC_VERSION(HB_WS2008_MAJOR, HB_MINOR)
static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = {
{
@@ -58,7 +64,9 @@
int dlen, error;
uint64_t xactid;
void *data;
+ uint32_t vmbus_version, fw_ver, msg_ver;
+ vmbus_version = VMBUS_GET_VERSION(device_get_parent(sc->ic_dev), sc->ic_dev);
/*
* Receive request.
*/
@@ -80,7 +88,16 @@
*/
switch (hdr->ic_type) {
case VMBUS_ICMSG_TYPE_NEGOTIATE:
- error = vmbus_ic_negomsg(sc, data, &dlen);
+ switch(vmbus_version) {
+ case VMBUS_VERSION_WS2008:
+ fw_ver = UTIL_WS2008_FW_VERSION;
+ msg_ver = HB_WS2008_VERSION;
+ break;
+ default:
+ fw_ver = UTIL_FW_VERSION;
+ msg_ver = HB_VERSION;
+ }
+ error = vmbus_ic_negomsg(sc->ic_dev, data, &dlen, fw_ver, msg_ver);
if (error)
return;
break;
Index: sys/dev/hyperv/utilities/hv_kvp.h
===================================================================
--- sys/dev/hyperv/utilities/hv_kvp.h
+++ sys/dev/hyperv/utilities/hv_kvp.h
@@ -28,7 +28,7 @@
#ifndef _KVP_H
#define _KVP_H
-
+#include "vmbus_icreg.h"
/*
* An implementation of HyperV key value pair (KVP) functionality for FreeBSD
*
@@ -178,9 +178,10 @@
}__attribute__((packed));
struct hv_kvp_hdr {
- uint8_t operation;
- uint8_t pool;
- uint16_t pad;
+ struct vmbus_icmsg_hdr ic_hdr;
+ uint8_t operation;
+ uint8_t pool;
+ uint16_t pad;
} __attribute__((packed));
struct hv_kvp_exchg_msg_value {
Index: sys/dev/hyperv/utilities/hv_kvp.c
===================================================================
--- sys/dev/hyperv/utilities/hv_kvp.c
+++ sys/dev/hyperv/utilities/hv_kvp.c
@@ -61,7 +61,9 @@
#include <sys/mutex.h>
#include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/utilities/hv_utilreg.h>
+#include <dev/hyperv/utilities/vmbus_icreg.h>
#include "hv_util.h"
#include "unicode.h"
@@ -74,6 +76,18 @@
#define KVP_ERROR 1
#define kvp_hdr hdr.kvp_hdr
+#define KVP_WS2008_MAJOR 1
+#define KVP_WS2008_MINOR 0
+#define KVP_WS2008_VERSION VMBUS_IC_VERSION(KVP_WS2008_MAJOR, KVP_WS2008_MINOR)
+
+#define KVP_WIN7_MAJOR 3
+#define KVP_WIN7_MINOR 0
+#define KVP_WIN7_VERSION VMBUS_IC_VERSION(KVP_WIN7_MAJOR, KVP_WIN7_MINOR)
+
+#define KVP_WIN8_MAJOR 4
+#define KVP_WIN8_MINOR 0
+#define KVP_WIN8_VERSION VMBUS_IC_VERSION(KVP_WIN8_MAJOR, KVP_WIN8_MINOR)
+
/* hv_kvp debug control */
static int hv_kvp_log = 0;
@@ -207,53 +221,9 @@
sc->host_msg_len = rcv_len;
sc->host_msg_id = request_id;
sc->rcv_buf = rcv_buf;
- sc->host_kvp_msg = (struct hv_kvp_msg *)&rcv_buf[
- sizeof(struct hv_vmbus_pipe_hdr) +
- sizeof(struct hv_vmbus_icmsg_hdr)];
-}
-
-
-/*
- * hv_kvp - version neogtiation function
- */
-static void
-hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf)
-{
- struct hv_vmbus_icmsg_negotiate *negop;
- int icframe_vercnt;
- int icmsg_vercnt;
-
- icmsghdrp->icmsgsize = 0x10;
-
- negop = (struct hv_vmbus_icmsg_negotiate *)&buf[
- sizeof(struct hv_vmbus_pipe_hdr) +
- sizeof(struct hv_vmbus_icmsg_hdr)];
- icframe_vercnt = negop->icframe_vercnt;
- icmsg_vercnt = negop->icmsg_vercnt;
-
- /*
- * Select the framework version number we will support
- */
- if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) {
- icframe_vercnt = 3;
- if (icmsg_vercnt > 2)
- icmsg_vercnt = 4;
- else
- icmsg_vercnt = 3;
- } else {
- icframe_vercnt = 1;
- icmsg_vercnt = 1;
- }
-
- negop->icframe_vercnt = 1;
- negop->icmsg_vercnt = 1;
- negop->icversion_data[0].major = icframe_vercnt;
- negop->icversion_data[0].minor = 0;
- negop->icversion_data[1].major = icmsg_vercnt;
- negop->icversion_data[1].minor = 0;
+ sc->host_kvp_msg = (struct hv_kvp_msg *)rcv_buf;
}
-
/*
* Convert ip related info in umsg from utf8 to utf16 and store in hmsg
*/
@@ -569,16 +539,16 @@
static void
hv_kvp_respond_host(hv_kvp_sc *sc, int error)
{
- struct hv_vmbus_icmsg_hdr *hv_icmsg_hdrp;
+ struct vmbus_icmsg_hdr *hv_icmsg_hdrp;
- hv_icmsg_hdrp = (struct hv_vmbus_icmsg_hdr *)
- &sc->rcv_buf[sizeof(struct hv_vmbus_pipe_hdr)];
+ hv_icmsg_hdrp = (struct vmbus_icmsg_hdr *)sc->rcv_buf;
if (error)
error = HV_KVP_E_FAIL;
- hv_icmsg_hdrp->status = error;
- hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE;
+ hv_icmsg_hdrp->ic_status = error;
+ hv_icmsg_hdrp->ic_flags = HV_ICMSGHDRFLAG_TRANSACTION |
+ HV_ICMSGHDRFLAG_RESPONSE;
error = vmbus_chan_send(vmbus_get_channel(sc->dev),
VMBUS_CHANPKT_TYPE_INBAND, 0, sc->rcv_buf, sc->host_msg_len,
@@ -621,15 +591,17 @@
struct vmbus_channel *channel;
uint32_t recvlen = 0;
uint64_t requestid;
- struct hv_vmbus_icmsg_hdr *icmsghdrp;
- int ret = 0;
- hv_kvp_sc *sc;
+ struct vmbus_icmsg_hdr *icmsghdrp;
+ int ret = 0, error;
+ hv_kvp_sc *sc;
+ uint32_t vmbus_version, fw_ver, msg_ver;
hv_kvp_log_info("%s: entering hv_kvp_process_request\n", __func__);
sc = (hv_kvp_sc*)context;
kvp_buf = sc->util_sc.receive_buffer;
channel = vmbus_get_channel(sc->dev);
+ vmbus_version = VMBUS_GET_VERSION(device_get_parent(sc->dev), sc->dev);
recvlen = sc->util_sc.ic_buflen;
ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid);
@@ -637,14 +609,25 @@
/* XXX check recvlen to make sure that it contains enough data */
while ((ret == 0) && (recvlen > 0)) {
-
- icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
- &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)];
+ icmsghdrp = (struct vmbus_icmsg_hdr *)kvp_buf;
hv_kvp_transaction_init(sc, recvlen, requestid, kvp_buf);
- if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
- hv_kvp_negotiate_version(icmsghdrp, kvp_buf);
- hv_kvp_respond_host(sc, ret);
+ if (icmsghdrp->ic_type == HV_ICMSGTYPE_NEGOTIATE) {
+ switch(vmbus_version) {
+ case VMBUS_VERSION_WS2008:
+ fw_ver = UTIL_WS2008_FW_VERSION;
+ msg_ver = KVP_WS2008_VERSION;
+ break;
+ case VMBUS_VERSION_WIN7:
+ fw_ver = UTIL_FW_VERSION;
+ msg_ver = KVP_WIN7_VERSION;
+ default:
+ fw_ver = UTIL_FW_VERSION;
+ msg_ver = KVP_WIN8_VERSION;
+ }
+ error = vmbus_ic_negomsg(sc->dev, kvp_buf, &recvlen,
+ fw_ver, msg_ver);
+ hv_kvp_respond_host(sc, error);
/*
* It is ok to not acquire the mutex before setting
Index: sys/dev/hyperv/utilities/hv_shutdown.c
===================================================================
--- sys/dev/hyperv/utilities/hv_shutdown.c
+++ sys/dev/hyperv/utilities/hv_shutdown.c
@@ -41,6 +41,13 @@
#include "vmbus_if.h"
+#define SD_MAJOR 3
+#define SD_MINOR 0
+#define SD_VERSION VMBUS_IC_VERSION(SD_MAJOR, SD_MINOR)
+
+#define SD_WS2008_MAJOR 1
+#define SD_WS2008_VERSION VMBUS_IC_VERSION(SD_WS2008_MAJOR, SD_MINOR)
+
static const struct vmbus_ic_desc vmbus_shutdown_descs[] = {
{
.ic_guid = { .hv_guid = {
@@ -60,7 +67,9 @@
int dlen, error, do_shutdown = 0;
uint64_t xactid;
void *data;
+ uint32_t vmbus_version, fw_ver, msg_ver;
+ vmbus_version = VMBUS_GET_VERSION(device_get_parent(sc->ic_dev), sc->ic_dev);
/*
* Receive request.
*/
@@ -82,7 +91,16 @@
*/
switch (hdr->ic_type) {
case VMBUS_ICMSG_TYPE_NEGOTIATE:
- error = vmbus_ic_negomsg(sc, data, &dlen);
+ switch(vmbus_version) {
+ case VMBUS_VERSION_WS2008:
+ fw_ver = UTIL_WS2008_FW_VERSION;
+ msg_ver = SD_WS2008_VERSION;
+ break;
+ default:
+ fw_ver = UTIL_FW_VERSION;
+ msg_ver = SD_VERSION;
+ }
+ error = vmbus_ic_negomsg(sc->ic_dev, data, &dlen, fw_ver, msg_ver);
if (error)
return;
break;
Index: sys/dev/hyperv/utilities/hv_timesync.c
===================================================================
--- sys/dev/hyperv/utilities/hv_timesync.c
+++ sys/dev/hyperv/utilities/hv_timesync.c
@@ -42,6 +42,13 @@
#include "vmbus_if.h"
+#define TS_MAJOR 3
+#define TS_MINOR 0
+#define TS_VERSION VMBUS_IC_VERSION(TS_MAJOR, TS_MINOR)
+
+#define TS_WS2008_MAJOR 1
+#define TS_WS2008_VERSION VMBUS_IC_VERSION(TS_WS2008_MAJOR, TS_MINOR)
+
static const struct vmbus_ic_desc vmbus_timesync_descs[] = {
{
.ic_guid = { .hv_guid = {
@@ -140,6 +147,9 @@
int dlen, error;
uint64_t xactid;
void *data;
+ uint32_t vmbus_version, fw_ver, msg_ver;
+
+ vmbus_version = VMBUS_GET_VERSION(device_get_parent(sc->ic_dev), sc->ic_dev);
/*
* Receive request.
@@ -162,7 +172,16 @@
*/
switch (hdr->ic_type) {
case VMBUS_ICMSG_TYPE_NEGOTIATE:
- error = vmbus_ic_negomsg(sc, data, &dlen);
+ switch(vmbus_version) {
+ case VMBUS_VERSION_WS2008:
+ fw_ver = UTIL_WS2008_FW_VERSION;
+ msg_ver = TS_WS2008_VERSION;
+ break;
+ default:
+ fw_ver = UTIL_FW_VERSION;
+ msg_ver = TS_VERSION;
+ }
+ error = vmbus_ic_negomsg(sc->ic_dev, data, &dlen, fw_ver, msg_ver);
if (error)
return;
break;
Index: sys/dev/hyperv/utilities/hv_util.h
===================================================================
--- sys/dev/hyperv/utilities/hv_util.h
+++ sys/dev/hyperv/utilities/hv_util.h
@@ -51,9 +51,20 @@
#define VMBUS_IC_DESC_END { .ic_desc = NULL }
-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 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(device_t dev, void *data, int *dlen0,
+ uint32_t fw_ver, uint32_t msg_ver);
+/*
+ * Framework version for util services.
+ */
+#define UTIL_FW_MINOR 0
+
+#define UTIL_WS2008_FW_MAJOR 1
+#define UTIL_WS2008_FW_VERSION VMBUS_IC_VERSION(UTIL_WS2008_FW_MAJOR, UTIL_FW_MINOR)
+
+#define UTIL_FW_MAJOR 3
+#define UTIL_FW_VERSION VMBUS_IC_VERSION(UTIL_FW_MAJOR, UTIL_FW_MINOR)
#endif
Index: sys/dev/hyperv/utilities/hv_util.c
===================================================================
--- sys/dev/hyperv/utilities/hv_util.c
+++ sys/dev/hyperv/utilities/hv_util.c
@@ -54,42 +54,23 @@
CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE);
int
-vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0)
+vmbus_ic_negomsg(device_t dev, void *data, int *dlen0,
+ uint32_t fw_ver, uint32_t msg_ver)
{
struct vmbus_icmsg_negotiate *nego;
- int cnt, major, dlen = *dlen0;
+ int i, cnt, dlen = *dlen0;
+ uint32_t sel_fw_ver, sel_msg_ver;
+ boolean_t found = FALSE;
+ nego = data;
/*
* Preliminary message size verification
*/
if (dlen < sizeof(*nego)) {
- device_printf(sc->ic_dev, "truncated ic negotiate, len %d\n",
- dlen);
- return EINVAL;
- }
- nego = data;
-
- cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt;
- if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) {
- device_printf(sc->ic_dev, "ic negotiate does not contain "
- "versions %d\n", dlen);
+ device_printf(dev, "truncated ic negotiate, len %d\n", dlen);
return EINVAL;
}
- /* Select major version; XXX looks wrong. */
- if (nego->ic_fwver_cnt >= 2 && VMBUS_ICVER_MAJOR(nego->ic_ver[1]) == 3)
- major = 3;
- else
- major = 1;
-
- /* One framework version */
- nego->ic_fwver_cnt = 1;
- nego->ic_ver[0] = VMBUS_IC_VERSION(major, 0);
-
- /* One message version */
- nego->ic_msgver_cnt = 1;
- nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0);
-
/* Update data size */
nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ -
sizeof(struct vmbus_icmsg_hdr);
@@ -98,7 +79,69 @@
if (dlen < VMBUS_IC_NEGOSZ)
*dlen0 = VMBUS_IC_NEGOSZ;
- return 0;
+ cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt;
+ if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) {
+ device_printf(dev, "ic negotiate does not contain versions %d\n",
+ dlen);
+ return EINVAL;
+ }
+
+ /*
+ * Select the framework version number we will support.
+ */
+ for (i = 0; i < nego->ic_fwver_cnt; i++) {
+ if (nego->ic_ver[i] == fw_ver) {
+ sel_fw_ver = nego->ic_ver[i];
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ goto handle_error;
+ found = FALSE;
+
+ /*
+ * Select the message version number we will support.
+ */
+ for (i = nego->ic_fwver_cnt;
+ i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; i++) {
+ if (nego->ic_ver[i] == msg_ver) {
+ sel_msg_ver = nego->ic_ver[i];
+ found = TRUE;
+ break;
+ }
+ }
+
+handle_error:
+ if (bootverbose) {
+ device_printf(dev, "selected framework ver: [%d:%d]\n",
+ VMBUS_ICVER_MAJOR(sel_fw_ver), VMBUS_ICVER_MINOR(sel_fw_ver));
+ for (i = 0; i < nego->ic_fwver_cnt; i++) {
+ device_printf(dev, "host provided framework ver: [%d:%d]\n",
+ VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
+ VMBUS_ICVER_MINOR(nego->ic_ver[i]));
+ }
+ device_printf(dev, "selected message ver: [%d:%d]\n",
+ VMBUS_ICVER_MAJOR(sel_msg_ver), VMBUS_ICVER_MINOR(sel_msg_ver));
+ for (i = nego->ic_fwver_cnt;
+ i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; i++) {
+ device_printf(dev, "host provided message ver: [%d:%d]\n",
+ VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
+ VMBUS_ICVER_MINOR(nego->ic_ver[i]));
+ }
+ }
+ if (!found) {
+ nego->ic_fwver_cnt = 0;
+ nego->ic_msgver_cnt = 0;
+ } else {
+ nego->ic_fwver_cnt = 1;
+ nego->ic_msgver_cnt = 1;
+ }
+
+ nego->ic_ver[0] = sel_fw_ver;
+ nego->ic_ver[1] = sel_msg_ver;
+ return found ? 0 : 1;
}
int
Index: sys/dev/hyperv/utilities/hv_utilreg.h
===================================================================
--- sys/dev/hyperv/utilities/hv_utilreg.h
+++ sys/dev/hyperv/utilities/hv_utilreg.h
@@ -48,44 +48,4 @@
#define HV_ICMSGHDRFLAG_REQUEST 2
#define HV_ICMSGHDRFLAG_RESPONSE 4
-typedef struct hv_vmbus_pipe_hdr {
- uint32_t flags;
- uint32_t msgsize;
-} __packed hv_vmbus_pipe_hdr;
-
-typedef struct hv_vmbus_ic_version {
- uint16_t major;
- uint16_t minor;
-} __packed hv_vmbus_ic_version;
-
-typedef struct hv_vmbus_icmsg_hdr {
- hv_vmbus_ic_version icverframe;
- uint16_t icmsgtype;
- hv_vmbus_ic_version icvermsg;
- uint16_t icmsgsize;
- uint32_t status;
- uint8_t ictransaction_id;
- uint8_t icflags;
- uint8_t reserved[2];
-} __packed hv_vmbus_icmsg_hdr;
-
-typedef struct hv_vmbus_icmsg_negotiate {
- uint16_t icframe_vercnt;
- uint16_t icmsg_vercnt;
- uint32_t reserved;
- hv_vmbus_ic_version icversion_data[1]; /* any size array */
-} __packed hv_vmbus_icmsg_negotiate;
-
-typedef struct hv_vmbus_shutdown_msg_data {
- uint32_t reason_code;
- uint32_t timeout_seconds;
- uint32_t flags;
- uint8_t display_message[2048];
-} __packed hv_vmbus_shutdown_msg_data;
-
-typedef struct hv_vmbus_heartbeat_msg_data {
- uint64_t seq_num;
- uint32_t reserved[8];
-} __packed hv_vmbus_heartbeat_msg_data;
-
#endif /* !_HV_UTILREG_H_ */
Index: sys/dev/hyperv/utilities/vmbus_icreg.h
===================================================================
--- sys/dev/hyperv/utilities/vmbus_icreg.h
+++ sys/dev/hyperv/utilities/vmbus_icreg.h
@@ -39,6 +39,11 @@
#define VMBUS_ICMSG_STATUS_OK 0x00000000
#define VMBUS_ICMSG_STATUS_FAIL 0x80004005
+/*
+ * Version for both framework and message is
+ * 32 bits long with major on higher 16 bits
+ * and minor on lower 16 bits.
+ */
#define VMBUS_IC_VERSION(major, minor) ((major) | (((uint32_t)(minor)) << 16))
#define VMBUS_ICVER_MAJOR(ver) ((ver) & 0xffff)
#define VMBUS_ICVER_MINOR(ver) (((ver) & 0xffff0000) >> 16)

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 15, 7:35 PM (9 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
9091912
Default Alt Text
D8280.id21528.diff (15 KB)

Event Timeline