brintos

brintos / linux-shallow public Read only

0
0
Text · 21.6 KiB · d35b60c Raw
825 lines · c
1/*2 * An implementation of key value pair (KVP) functionality for Linux.3 *4 *5 * Copyright (C) 2010, Novell, Inc.6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>7 *8 * This program is free software; you can redistribute it and/or modify it9 * under the terms of the GNU General Public License version 2 as published10 * by the Free Software Foundation.11 *12 * This program is distributed in the hope that it will be useful, but13 * WITHOUT ANY WARRANTY; without even the implied warranty of14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or15 * NON INFRINGEMENT.  See the GNU General Public License for more16 * details.17 *18 * You should have received a copy of the GNU General Public License19 * along with this program; if not, write to the Free Software20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.21 *22 */23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt24 25#include <linux/net.h>26#include <linux/nls.h>27#include <linux/connector.h>28#include <linux/workqueue.h>29#include <linux/hyperv.h>30#include <asm/hyperv-tlfs.h>31 32#include "hyperv_vmbus.h"33#include "hv_utils_transport.h"34 35/*36 * Pre win8 version numbers used in ws2008 and ws 2008 r2 (win7)37 */38#define WS2008_SRV_MAJOR	139#define WS2008_SRV_MINOR	040#define WS2008_SRV_VERSION     (WS2008_SRV_MAJOR << 16 | WS2008_SRV_MINOR)41 42#define WIN7_SRV_MAJOR   343#define WIN7_SRV_MINOR   044#define WIN7_SRV_VERSION     (WIN7_SRV_MAJOR << 16 | WIN7_SRV_MINOR)45 46#define WIN8_SRV_MAJOR   447#define WIN8_SRV_MINOR   048#define WIN8_SRV_VERSION     (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)49 50#define KVP_VER_COUNT 351static const int kvp_versions[] = {52	WIN8_SRV_VERSION,53	WIN7_SRV_VERSION,54	WS2008_SRV_VERSION55};56 57#define FW_VER_COUNT 258static const int fw_versions[] = {59	UTIL_FW_VERSION,60	UTIL_WS2K8_FW_VERSION61};62 63/*64 * Global state maintained for transaction that is being processed. For a class65 * of integration services, including the "KVP service", the specified protocol66 * is a "request/response" protocol which means that there can only be single67 * outstanding transaction from the host at any given point in time. We use68 * this to simplify memory management in this driver - we cache and process69 * only one message at a time.70 *71 * While the request/response protocol is guaranteed by the host, we further72 * ensure this by serializing packet processing in this driver - we do not73 * read additional packets from the VMBUS until the current packet is fully74 * handled.75 */76 77static struct {78	int state;   /* hvutil_device_state */79	int recv_len; /* number of bytes received. */80	struct hv_kvp_msg  *kvp_msg; /* current message */81	struct vmbus_channel *recv_channel; /* chn we got the request */82	u64 recv_req_id; /* request ID. */83} kvp_transaction;84 85/*86 * This state maintains the version number registered by the daemon.87 */88static int dm_reg_value;89 90static void kvp_send_key(struct work_struct *dummy);91 92 93static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);94static void kvp_timeout_func(struct work_struct *dummy);95static void kvp_host_handshake_func(struct work_struct *dummy);96static void kvp_register(int);97 98static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func);99static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func);100static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);101 102static const char kvp_devname[] = "vmbus/hv_kvp";103static u8 *recv_buffer;104static struct hvutil_transport *hvt;105/*106 * Register the kernel component with the user-level daemon.107 * As part of this registration, pass the LIC version number.108 * This number has no meaning, it satisfies the registration protocol.109 */110#define HV_DRV_VERSION           "3.1"111 112static void kvp_poll_wrapper(void *channel)113{114	/* Transaction is finished, reset the state here to avoid races. */115	kvp_transaction.state = HVUTIL_READY;116	tasklet_schedule(&((struct vmbus_channel *)channel)->callback_event);117}118 119static void kvp_register_done(void)120{121	/*122	 * If we're still negotiating with the host cancel the timeout123	 * work to not poll the channel twice.124	 */125	pr_debug("KVP: userspace daemon registered\n");126	cancel_delayed_work_sync(&kvp_host_handshake_work);127	hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);128}129 130static void131kvp_register(int reg_value)132{133 134	struct hv_kvp_msg *kvp_msg;135	char *version;136 137	kvp_msg = kzalloc(sizeof(*kvp_msg), GFP_KERNEL);138 139	if (kvp_msg) {140		version = kvp_msg->body.kvp_register.version;141		kvp_msg->kvp_hdr.operation = reg_value;142		strcpy(version, HV_DRV_VERSION);143 144		hvutil_transport_send(hvt, kvp_msg, sizeof(*kvp_msg),145				      kvp_register_done);146		kfree(kvp_msg);147	}148}149 150static void kvp_timeout_func(struct work_struct *dummy)151{152	/*153	 * If the timer fires, the user-mode component has not responded;154	 * process the pending transaction.155	 */156	kvp_respond_to_host(NULL, HV_E_FAIL);157 158	hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);159}160 161static void kvp_host_handshake_func(struct work_struct *dummy)162{163	tasklet_schedule(&kvp_transaction.recv_channel->callback_event);164}165 166static int kvp_handle_handshake(struct hv_kvp_msg *msg)167{168	switch (msg->kvp_hdr.operation) {169	case KVP_OP_REGISTER:170		dm_reg_value = KVP_OP_REGISTER;171		pr_info("KVP: IP injection functionality not available\n");172		pr_info("KVP: Upgrade the KVP daemon\n");173		break;174	case KVP_OP_REGISTER1:175		dm_reg_value = KVP_OP_REGISTER1;176		break;177	default:178		pr_info("KVP: incompatible daemon\n");179		pr_info("KVP: KVP version: %d, Daemon version: %d\n",180			KVP_OP_REGISTER1, msg->kvp_hdr.operation);181		return -EINVAL;182	}183 184	/*185	 * We have a compatible daemon; complete the handshake.186	 */187	pr_debug("KVP: userspace daemon ver. %d connected\n",188		 msg->kvp_hdr.operation);189	kvp_register(dm_reg_value);190 191	return 0;192}193 194 195/*196 * Callback when data is received from user mode.197 */198 199static int kvp_on_msg(void *msg, int len)200{201	struct hv_kvp_msg *message = (struct hv_kvp_msg *)msg;202	struct hv_kvp_msg_enumerate *data;203	int	error = 0;204 205	if (len < sizeof(*message))206		return -EINVAL;207 208	/*209	 * If we are negotiating the version information210	 * with the daemon; handle that first.211	 */212 213	if (kvp_transaction.state < HVUTIL_READY) {214		return kvp_handle_handshake(message);215	}216 217	/* We didn't send anything to userspace so the reply is spurious */218	if (kvp_transaction.state < HVUTIL_USERSPACE_REQ)219		return -EINVAL;220 221	kvp_transaction.state = HVUTIL_USERSPACE_RECV;222 223	/*224	 * Based on the version of the daemon, we propagate errors from the225	 * daemon differently.226	 */227 228	data = &message->body.kvp_enum_data;229 230	switch (dm_reg_value) {231	case KVP_OP_REGISTER:232		/*233		 * Null string is used to pass back error condition.234		 */235		if (data->data.key[0] == 0)236			error = HV_S_CONT;237		break;238 239	case KVP_OP_REGISTER1:240		/*241		 * We use the message header information from242		 * the user level daemon to transmit errors.243		 */244		error = message->error;245		break;246	}247 248	/*249	 * Complete the transaction by forwarding the key value250	 * to the host. But first, cancel the timeout.251	 */252	if (cancel_delayed_work_sync(&kvp_timeout_work)) {253		kvp_respond_to_host(message, error);254		hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);255	}256 257	return 0;258}259 260 261static int process_ob_ipinfo(void *in_msg, void *out_msg, int op)262{263	struct hv_kvp_msg *in = in_msg;264	struct hv_kvp_ip_msg *out = out_msg;265	int len;266 267	switch (op) {268	case KVP_OP_GET_IP_INFO:269		/*270		 * Transform all parameters into utf16 encoding.271		 */272		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr,273				strlen((char *)in->body.kvp_ip_val.ip_addr),274				UTF16_HOST_ENDIAN,275				(wchar_t *)out->kvp_ip_val.ip_addr,276				MAX_IP_ADDR_SIZE);277		if (len < 0)278			return len;279 280		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net,281				strlen((char *)in->body.kvp_ip_val.sub_net),282				UTF16_HOST_ENDIAN,283				(wchar_t *)out->kvp_ip_val.sub_net,284				MAX_IP_ADDR_SIZE);285		if (len < 0)286			return len;287 288		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way,289				strlen((char *)in->body.kvp_ip_val.gate_way),290				UTF16_HOST_ENDIAN,291				(wchar_t *)out->kvp_ip_val.gate_way,292				MAX_GATEWAY_SIZE);293		if (len < 0)294			return len;295 296		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr,297				strlen((char *)in->body.kvp_ip_val.dns_addr),298				UTF16_HOST_ENDIAN,299				(wchar_t *)out->kvp_ip_val.dns_addr,300				MAX_IP_ADDR_SIZE);301		if (len < 0)302			return len;303 304		len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id,305				strlen((char *)in->body.kvp_ip_val.adapter_id),306				UTF16_HOST_ENDIAN,307				(wchar_t *)out->kvp_ip_val.adapter_id,308				MAX_ADAPTER_ID_SIZE);309		if (len < 0)310			return len;311 312		out->kvp_ip_val.dhcp_enabled =313			in->body.kvp_ip_val.dhcp_enabled;314		out->kvp_ip_val.addr_family =315			in->body.kvp_ip_val.addr_family;316	}317 318	return 0;319}320 321static void process_ib_ipinfo(void *in_msg, void *out_msg, int op)322{323	struct hv_kvp_ip_msg *in = in_msg;324	struct hv_kvp_msg *out = out_msg;325 326	switch (op) {327	case KVP_OP_SET_IP_INFO:328		/*329		 * Transform all parameters into utf8 encoding.330		 */331		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.ip_addr,332				MAX_IP_ADDR_SIZE,333				UTF16_LITTLE_ENDIAN,334				(__u8 *)out->body.kvp_ip_val.ip_addr,335				MAX_IP_ADDR_SIZE);336 337		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.sub_net,338				MAX_IP_ADDR_SIZE,339				UTF16_LITTLE_ENDIAN,340				(__u8 *)out->body.kvp_ip_val.sub_net,341				MAX_IP_ADDR_SIZE);342 343		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.gate_way,344				MAX_GATEWAY_SIZE,345				UTF16_LITTLE_ENDIAN,346				(__u8 *)out->body.kvp_ip_val.gate_way,347				MAX_GATEWAY_SIZE);348 349		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.dns_addr,350				MAX_IP_ADDR_SIZE,351				UTF16_LITTLE_ENDIAN,352				(__u8 *)out->body.kvp_ip_val.dns_addr,353				MAX_IP_ADDR_SIZE);354 355		out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled;356 357		fallthrough;358 359	case KVP_OP_GET_IP_INFO:360		utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,361				MAX_ADAPTER_ID_SIZE,362				UTF16_LITTLE_ENDIAN,363				(__u8 *)out->body.kvp_ip_val.adapter_id,364				MAX_ADAPTER_ID_SIZE);365 366		out->body.kvp_ip_val.addr_family = in->kvp_ip_val.addr_family;367	}368}369 370 371 372 373static void374kvp_send_key(struct work_struct *dummy)375{376	struct hv_kvp_msg *message;377	struct hv_kvp_msg *in_msg;378	__u8 operation = kvp_transaction.kvp_msg->kvp_hdr.operation;379	__u8 pool = kvp_transaction.kvp_msg->kvp_hdr.pool;380	__u32 val32;381	__u64 val64;382	int rc;383 384	/* The transaction state is wrong. */385	if (kvp_transaction.state != HVUTIL_HOSTMSG_RECEIVED)386		return;387 388	message = kzalloc(sizeof(*message), GFP_KERNEL);389	if (!message)390		return;391 392	message->kvp_hdr.operation = operation;393	message->kvp_hdr.pool = pool;394	in_msg = kvp_transaction.kvp_msg;395 396	/*397	 * The key/value strings sent from the host are encoded398	 * in utf16; convert it to utf8 strings.399	 * The host assures us that the utf16 strings will not exceed400	 * the max lengths specified. We will however, reserve room401	 * for the string terminating character - in the utf16s_utf8s()402	 * function we limit the size of the buffer where the converted403	 * string is placed to HV_KVP_EXCHANGE_MAX_*_SIZE -1 to guarantee404	 * that the strings can be properly terminated!405	 */406 407	switch (message->kvp_hdr.operation) {408	case KVP_OP_SET_IP_INFO:409		process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);410		break;411	case KVP_OP_GET_IP_INFO:412		/*413		 * We only need to pass on the info of operation, adapter_id414		 * and addr_family to the userland kvp daemon.415		 */416		process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);417		break;418	case KVP_OP_SET:419		switch (in_msg->body.kvp_set.data.value_type) {420		case REG_SZ:421			/*422			 * The value is a string - utf16 encoding.423			 */424			message->body.kvp_set.data.value_size =425				utf16s_to_utf8s(426				(wchar_t *)in_msg->body.kvp_set.data.value,427				in_msg->body.kvp_set.data.value_size,428				UTF16_LITTLE_ENDIAN,429				message->body.kvp_set.data.value,430				HV_KVP_EXCHANGE_MAX_VALUE_SIZE - 1) + 1;431			break;432 433		case REG_U32:434			/*435			 * The value is a 32 bit scalar.436			 * We save this as a utf8 string.437			 */438			val32 = in_msg->body.kvp_set.data.value_u32;439			message->body.kvp_set.data.value_size =440				sprintf(message->body.kvp_set.data.value,441					"%u", val32) + 1;442			break;443 444		case REG_U64:445			/*446			 * The value is a 64 bit scalar.447			 * We save this as a utf8 string.448			 */449			val64 = in_msg->body.kvp_set.data.value_u64;450			message->body.kvp_set.data.value_size =451				sprintf(message->body.kvp_set.data.value,452					"%llu", val64) + 1;453			break;454 455		}456 457		/*458		 * The key is always a string - utf16 encoding.459		 */460		message->body.kvp_set.data.key_size =461			utf16s_to_utf8s(462			(wchar_t *)in_msg->body.kvp_set.data.key,463			in_msg->body.kvp_set.data.key_size,464			UTF16_LITTLE_ENDIAN,465			message->body.kvp_set.data.key,466			HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;467 468		break;469 470	case KVP_OP_GET:471		message->body.kvp_get.data.key_size =472			utf16s_to_utf8s(473			(wchar_t *)in_msg->body.kvp_get.data.key,474			in_msg->body.kvp_get.data.key_size,475			UTF16_LITTLE_ENDIAN,476			message->body.kvp_get.data.key,477			HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;478		break;479 480	case KVP_OP_DELETE:481		message->body.kvp_delete.key_size =482			utf16s_to_utf8s(483			(wchar_t *)in_msg->body.kvp_delete.key,484			in_msg->body.kvp_delete.key_size,485			UTF16_LITTLE_ENDIAN,486			message->body.kvp_delete.key,487			HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;488		break;489 490	case KVP_OP_ENUMERATE:491		message->body.kvp_enum_data.index =492			in_msg->body.kvp_enum_data.index;493		break;494	}495 496	kvp_transaction.state = HVUTIL_USERSPACE_REQ;497	rc = hvutil_transport_send(hvt, message, sizeof(*message), NULL);498	if (rc) {499		pr_debug("KVP: failed to communicate to the daemon: %d\n", rc);500		if (cancel_delayed_work_sync(&kvp_timeout_work)) {501			kvp_respond_to_host(message, HV_E_FAIL);502			kvp_transaction.state = HVUTIL_READY;503		}504	}505 506	kfree(message);507}508 509/*510 * Send a response back to the host.511 */512 513static void514kvp_respond_to_host(struct hv_kvp_msg *msg_to_host, int error)515{516	struct hv_kvp_msg  *kvp_msg;517	struct hv_kvp_exchg_msg_value  *kvp_data;518	char	*key_name;519	char	*value;520	struct icmsg_hdr *icmsghdrp;521	int	keylen = 0;522	int	valuelen = 0;523	u32	buf_len;524	struct vmbus_channel *channel;525	u64	req_id;526	int ret;527 528	/*529	 * Copy the global state for completing the transaction. Note that530	 * only one transaction can be active at a time.531	 */532 533	buf_len = kvp_transaction.recv_len;534	channel = kvp_transaction.recv_channel;535	req_id = kvp_transaction.recv_req_id;536 537	icmsghdrp = (struct icmsg_hdr *)538			&recv_buffer[sizeof(struct vmbuspipe_hdr)];539 540	if (channel->onchannel_callback == NULL)541		/*542		 * We have raced with util driver being unloaded;543		 * silently return.544		 */545		return;546 547	icmsghdrp->status = error;548 549	/*550	 * If the error parameter is set, terminate the host's enumeration551	 * on this pool.552	 */553	if (error) {554		/*555		 * Something failed or we have timed out;556		 * terminate the current host-side iteration.557		 */558		goto response_done;559	}560 561	kvp_msg = (struct hv_kvp_msg *)562			&recv_buffer[sizeof(struct vmbuspipe_hdr) +563			sizeof(struct icmsg_hdr)];564 565	switch (kvp_transaction.kvp_msg->kvp_hdr.operation) {566	case KVP_OP_GET_IP_INFO:567		ret = process_ob_ipinfo(msg_to_host,568				 (struct hv_kvp_ip_msg *)kvp_msg,569				 KVP_OP_GET_IP_INFO);570		if (ret < 0)571			icmsghdrp->status = HV_E_FAIL;572 573		goto response_done;574	case KVP_OP_SET_IP_INFO:575		goto response_done;576	case KVP_OP_GET:577		kvp_data = &kvp_msg->body.kvp_get.data;578		goto copy_value;579 580	case KVP_OP_SET:581	case KVP_OP_DELETE:582		goto response_done;583 584	default:585		break;586	}587 588	kvp_data = &kvp_msg->body.kvp_enum_data.data;589	key_name = msg_to_host->body.kvp_enum_data.data.key;590 591	/*592	 * The windows host expects the key/value pair to be encoded593	 * in utf16. Ensure that the key/value size reported to the host594	 * will be less than or equal to the MAX size (including the595	 * terminating character).596	 */597	keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN,598				(wchar_t *) kvp_data->key,599				(HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2) - 2);600	kvp_data->key_size = 2*(keylen + 1); /* utf16 encoding */601 602copy_value:603	value = msg_to_host->body.kvp_enum_data.data.value;604	valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN,605				(wchar_t *) kvp_data->value,606				(HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2) - 2);607	kvp_data->value_size = 2*(valuelen + 1); /* utf16 encoding */608 609	/*610	 * If the utf8s to utf16s conversion failed; notify host611	 * of the error.612	 */613	if ((keylen < 0) || (valuelen < 0))614		icmsghdrp->status = HV_E_FAIL;615 616	kvp_data->value_type = REG_SZ; /* all our values are strings */617 618response_done:619	icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;620 621	vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,622				VM_PKT_DATA_INBAND, 0);623}624 625/*626 * This callback is invoked when we get a KVP message from the host.627 * The host ensures that only one KVP transaction can be active at a time.628 * KVP implementation in Linux needs to forward the key to a user-mde629 * component to retrieve the corresponding value. Consequently, we cannot630 * respond to the host in the context of this callback. Since the host631 * guarantees that at most only one transaction can be active at a time,632 * we stash away the transaction state in a set of global variables.633 */634 635void hv_kvp_onchannelcallback(void *context)636{637	struct vmbus_channel *channel = context;638	u32 recvlen;639	u64 requestid;640 641	struct hv_kvp_msg *kvp_msg;642 643	struct icmsg_hdr *icmsghdrp;644	int kvp_srv_version;645	static enum {NEGO_NOT_STARTED,646		     NEGO_IN_PROGRESS,647		     NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED;648 649	if (kvp_transaction.state < HVUTIL_READY) {650		/*651		 * If userspace daemon is not connected and host is asking652		 * us to negotiate we need to delay to not lose messages.653		 * This is important for Failover IP setting.654		 */655		if (host_negotiatied == NEGO_NOT_STARTED) {656			host_negotiatied = NEGO_IN_PROGRESS;657			schedule_delayed_work(&kvp_host_handshake_work,658				      HV_UTIL_NEGO_TIMEOUT * HZ);659		}660		return;661	}662	if (kvp_transaction.state > HVUTIL_READY)663		return;664 665	if (vmbus_recvpacket(channel, recv_buffer, HV_HYP_PAGE_SIZE * 4, &recvlen, &requestid)) {666		pr_err_ratelimited("KVP request received. Could not read into recv buf\n");667		return;668	}669 670	if (!recvlen)671		return;672 673	/* Ensure recvlen is big enough to read header data */674	if (recvlen < ICMSG_HDR) {675		pr_err_ratelimited("KVP request received. Packet length too small: %d\n",676				   recvlen);677		return;678	}679 680	icmsghdrp = (struct icmsg_hdr *)&recv_buffer[sizeof(struct vmbuspipe_hdr)];681 682	if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {683		if (vmbus_prep_negotiate_resp(icmsghdrp,684				recv_buffer, recvlen,685				fw_versions, FW_VER_COUNT,686				kvp_versions, KVP_VER_COUNT,687				NULL, &kvp_srv_version)) {688			pr_info("KVP IC version %d.%d\n",689				kvp_srv_version >> 16,690				kvp_srv_version & 0xFFFF);691		}692	} else if (icmsghdrp->icmsgtype == ICMSGTYPE_KVPEXCHANGE) {693		/*694		 * recvlen is not checked against sizeof(struct kvp_msg) because kvp_msg contains695		 * a union of structs and the msg type received is not known. Code using this696		 * struct should provide validation when accessing its fields.697		 */698		kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ICMSG_HDR];699 700		/*701		 * Stash away this global state for completing the702		 * transaction; note transactions are serialized.703		 */704 705		kvp_transaction.recv_len = recvlen;706		kvp_transaction.recv_req_id = requestid;707		kvp_transaction.kvp_msg = kvp_msg;708 709		if (kvp_transaction.state < HVUTIL_READY) {710			/* Userspace is not registered yet */711			kvp_respond_to_host(NULL, HV_E_FAIL);712			return;713		}714		kvp_transaction.state = HVUTIL_HOSTMSG_RECEIVED;715 716		/*717		 * Get the information from the718		 * user-mode component.719		 * component. This transaction will be720		 * completed when we get the value from721		 * the user-mode component.722		 * Set a timeout to deal with723		 * user-mode not responding.724		 */725		schedule_work(&kvp_sendkey_work);726		schedule_delayed_work(&kvp_timeout_work,727					HV_UTIL_TIMEOUT * HZ);728 729		return;730 731	} else {732		pr_err_ratelimited("KVP request received. Invalid msg type: %d\n",733				   icmsghdrp->icmsgtype);734		return;735	}736 737	icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION738		| ICMSGHDRFLAG_RESPONSE;739 740	vmbus_sendpacket(channel, recv_buffer,741			 recvlen, requestid,742			 VM_PKT_DATA_INBAND, 0);743 744	host_negotiatied = NEGO_FINISHED;745	hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper);746}747 748static void kvp_on_reset(void)749{750	if (cancel_delayed_work_sync(&kvp_timeout_work))751		kvp_respond_to_host(NULL, HV_E_FAIL);752	kvp_transaction.state = HVUTIL_DEVICE_INIT;753}754 755int756hv_kvp_init(struct hv_util_service *srv)757{758	recv_buffer = srv->recv_buffer;759	kvp_transaction.recv_channel = srv->channel;760	kvp_transaction.recv_channel->max_pkt_size = HV_HYP_PAGE_SIZE * 4;761 762	/*763	 * When this driver loads, the user level daemon that764	 * processes the host requests may not yet be running.765	 * Defer processing channel callbacks until the daemon766	 * has registered.767	 */768	kvp_transaction.state = HVUTIL_DEVICE_INIT;769 770	hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL,771				    kvp_on_msg, kvp_on_reset);772	if (!hvt)773		return -EFAULT;774 775	return 0;776}777 778static void hv_kvp_cancel_work(void)779{780	cancel_delayed_work_sync(&kvp_host_handshake_work);781	cancel_delayed_work_sync(&kvp_timeout_work);782	cancel_work_sync(&kvp_sendkey_work);783}784 785int hv_kvp_pre_suspend(void)786{787	struct vmbus_channel *channel = kvp_transaction.recv_channel;788 789	tasklet_disable(&channel->callback_event);790 791	/*792	 * If there is a pending transtion, it's unnecessary to tell the host793	 * that the transaction will fail, because that is implied when794	 * util_suspend() calls vmbus_close() later.795	 */796	hv_kvp_cancel_work();797 798	/*799	 * Forece the state to READY to handle the ICMSGTYPE_NEGOTIATE message800	 * later. The user space daemon may go out of order and its write()801	 * may fail with EINVAL: this doesn't matter since the daemon will802	 * reset the device by closing and re-opening it.803	 */804	kvp_transaction.state = HVUTIL_READY;805	return 0;806}807 808int hv_kvp_pre_resume(void)809{810	struct vmbus_channel *channel = kvp_transaction.recv_channel;811 812	tasklet_enable(&channel->callback_event);813 814	return 0;815}816 817void hv_kvp_deinit(void)818{819	kvp_transaction.state = HVUTIL_DEVICE_DYING;820 821	hv_kvp_cancel_work();822 823	hvutil_transport_destroy(hvt);824}825