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 it 9 * under the terms of the GNU General Public License version 2 as published 10 * by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 15 * NON INFRINGEMENT. See the GNU General Public License for more 16 * details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 */ 23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 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 31 #include "hv_kvp.h" 32 33 34 35 /* 36 * Global state maintained for transaction that is being processed. 37 * Note that only one transaction can be active at any point in time. 38 * 39 * This state is set when we receive a request from the host; we 40 * cleanup this state when the transaction is completed - when we respond 41 * to the host with the key value. 42 */ 43 44 static struct { 45 bool active; /* transaction status - active or not */ 46 int recv_len; /* number of bytes received. */ 47 int index; /* current index */ 48 struct vmbus_channel *recv_channel; /* chn we got the request */ 49 u64 recv_req_id; /* request ID. */ 50 } kvp_transaction; 51 52 static void kvp_send_key(struct work_struct *dummy); 53 54 #define TIMEOUT_FIRED 1 55 56 static void kvp_respond_to_host(char *key, char *value, int error); 57 static void kvp_work_func(struct work_struct *dummy); 58 static void kvp_register(void); 59 60 static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func); 61 static DECLARE_WORK(kvp_sendkey_work, kvp_send_key); 62 63 static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL }; 64 static const char kvp_name[] = "kvp_kernel_module"; 65 static u8 *recv_buffer; 66 /* 67 * Register the kernel component with the user-level daemon. 68 * As part of this registration, pass the LIC version number. 69 */ 70 71 static void 72 kvp_register(void) 73 { 74 75 struct cn_msg *msg; 76 77 msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC); 78 79 if (msg) { 80 msg->id.idx = CN_KVP_IDX; 81 msg->id.val = CN_KVP_VAL; 82 msg->seq = KVP_REGISTER; 83 strcpy(msg->data, HV_DRV_VERSION); 84 msg->len = strlen(HV_DRV_VERSION) + 1; 85 cn_netlink_send(msg, 0, GFP_ATOMIC); 86 kfree(msg); 87 } 88 } 89 static void 90 kvp_work_func(struct work_struct *dummy) 91 { 92 /* 93 * If the timer fires, the user-mode component has not responded; 94 * process the pending transaction. 95 */ 96 kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED); 97 } 98 99 /* 100 * Callback when data is received from user mode. 101 */ 102 103 static void 104 kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) 105 { 106 struct hv_ku_msg *message; 107 108 message = (struct hv_ku_msg *)msg->data; 109 if (msg->seq == KVP_REGISTER) { 110 pr_info("KVP: user-mode registering done.\n"); 111 kvp_register(); 112 } 113 114 if (msg->seq == KVP_USER_SET) { 115 /* 116 * Complete the transaction by forwarding the key value 117 * to the host. But first, cancel the timeout. 118 */ 119 if (cancel_delayed_work_sync(&kvp_work)) 120 kvp_respond_to_host(message->kvp_key, 121 message->kvp_value, 122 !strlen(message->kvp_key)); 123 } 124 } 125 126 static void 127 kvp_send_key(struct work_struct *dummy) 128 { 129 struct cn_msg *msg; 130 int index = kvp_transaction.index; 131 132 msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); 133 134 if (msg) { 135 msg->id.idx = CN_KVP_IDX; 136 msg->id.val = CN_KVP_VAL; 137 msg->seq = KVP_KERNEL_GET; 138 ((struct hv_ku_msg *)msg->data)->kvp_index = index; 139 msg->len = sizeof(struct hv_ku_msg); 140 cn_netlink_send(msg, 0, GFP_ATOMIC); 141 kfree(msg); 142 } 143 return; 144 } 145 146 /* 147 * Send a response back to the host. 148 */ 149 150 static void 151 kvp_respond_to_host(char *key, char *value, int error) 152 { 153 struct hv_kvp_msg *kvp_msg; 154 struct hv_kvp_msg_enumerate *kvp_data; 155 char *key_name; 156 struct icmsg_hdr *icmsghdrp; 157 int keylen, valuelen; 158 u32 buf_len; 159 struct vmbus_channel *channel; 160 u64 req_id; 161 162 /* 163 * If a transaction is not active; log and return. 164 */ 165 166 if (!kvp_transaction.active) { 167 /* 168 * This is a spurious call! 169 */ 170 pr_warn("KVP: Transaction not active\n"); 171 return; 172 } 173 /* 174 * Copy the global state for completing the transaction. Note that 175 * only one transaction can be active at a time. 176 */ 177 178 buf_len = kvp_transaction.recv_len; 179 channel = kvp_transaction.recv_channel; 180 req_id = kvp_transaction.recv_req_id; 181 182 kvp_transaction.active = false; 183 184 if (channel->onchannel_callback == NULL) 185 /* 186 * We have raced with util driver being unloaded; 187 * silently return. 188 */ 189 return; 190 191 icmsghdrp = (struct icmsg_hdr *) 192 &recv_buffer[sizeof(struct vmbuspipe_hdr)]; 193 kvp_msg = (struct hv_kvp_msg *) 194 &recv_buffer[sizeof(struct vmbuspipe_hdr) + 195 sizeof(struct icmsg_hdr)]; 196 kvp_data = &kvp_msg->kvp_data; 197 key_name = key; 198 199 /* 200 * If the error parameter is set, terminate the host's enumeration. 201 */ 202 if (error) { 203 /* 204 * We don't support this index or the we have timedout; 205 * terminate the host-side iteration by returning an error. 206 */ 207 icmsghdrp->status = HV_E_FAIL; 208 goto response_done; 209 } 210 211 /* 212 * The windows host expects the key/value pair to be encoded 213 * in utf16. 214 */ 215 keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN, 216 (wchar_t *) kvp_data->data.key, 217 HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2); 218 kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */ 219 valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN, 220 (wchar_t *) kvp_data->data.value, 221 HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2); 222 kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */ 223 224 kvp_data->data.value_type = REG_SZ; /* all our values are strings */ 225 icmsghdrp->status = HV_S_OK; 226 227 response_done: 228 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; 229 230 vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, 231 VM_PKT_DATA_INBAND, 0); 232 233 } 234 235 /* 236 * This callback is invoked when we get a KVP message from the host. 237 * The host ensures that only one KVP transaction can be active at a time. 238 * KVP implementation in Linux needs to forward the key to a user-mde 239 * component to retrive the corresponding value. Consequently, we cannot 240 * respond to the host in the conext of this callback. Since the host 241 * guarantees that at most only one transaction can be active at a time, 242 * we stash away the transaction state in a set of global variables. 243 */ 244 245 void hv_kvp_onchannelcallback(void *context) 246 { 247 struct vmbus_channel *channel = context; 248 u32 recvlen; 249 u64 requestid; 250 251 struct hv_kvp_msg *kvp_msg; 252 struct hv_kvp_msg_enumerate *kvp_data; 253 254 struct icmsg_hdr *icmsghdrp; 255 struct icmsg_negotiate *negop = NULL; 256 257 258 vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid); 259 260 if (recvlen > 0) { 261 icmsghdrp = (struct icmsg_hdr *)&recv_buffer[ 262 sizeof(struct vmbuspipe_hdr)]; 263 264 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 265 vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer); 266 } else { 267 kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ 268 sizeof(struct vmbuspipe_hdr) + 269 sizeof(struct icmsg_hdr)]; 270 271 kvp_data = &kvp_msg->kvp_data; 272 273 /* 274 * We only support the "get" operation on 275 * "KVP_POOL_AUTO" pool. 276 */ 277 278 if ((kvp_msg->kvp_hdr.pool != KVP_POOL_AUTO) || 279 (kvp_msg->kvp_hdr.operation != 280 KVP_OP_ENUMERATE)) { 281 icmsghdrp->status = HV_E_FAIL; 282 goto callback_done; 283 } 284 285 /* 286 * Stash away this global state for completing the 287 * transaction; note transactions are serialized. 288 */ 289 kvp_transaction.recv_len = recvlen; 290 kvp_transaction.recv_channel = channel; 291 kvp_transaction.recv_req_id = requestid; 292 kvp_transaction.active = true; 293 kvp_transaction.index = kvp_data->index; 294 295 /* 296 * Get the information from the 297 * user-mode component. 298 * component. This transaction will be 299 * completed when we get the value from 300 * the user-mode component. 301 * Set a timeout to deal with 302 * user-mode not responding. 303 */ 304 schedule_work(&kvp_sendkey_work); 305 schedule_delayed_work(&kvp_work, 5*HZ); 306 307 return; 308 309 } 310 311 callback_done: 312 313 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 314 | ICMSGHDRFLAG_RESPONSE; 315 316 vmbus_sendpacket(channel, recv_buffer, 317 recvlen, requestid, 318 VM_PKT_DATA_INBAND, 0); 319 } 320 321 } 322 323 int 324 hv_kvp_init(struct hv_util_service *srv) 325 { 326 int err; 327 328 err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback); 329 if (err) 330 return err; 331 recv_buffer = srv->recv_buffer; 332 333 return 0; 334 } 335 336 void hv_kvp_deinit(void) 337 { 338 cn_del_callback(&kvp_id); 339 cancel_delayed_work_sync(&kvp_work); 340 cancel_work_sync(&kvp_sendkey_work); 341 } 342