Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F81970616
D8280.id21528.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D8280.id21528.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D8280: hyperv/util unify the negotitation for utils
Attached
Detach File
Event Timeline
Log In to Comment