1 /* 2 * 3 * Copyright (c) 2009, Microsoft Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16 * Place - Suite 330, Boston, MA 02111-1307 USA. 17 * 18 * Authors: 19 * Haiyang Zhang <haiyangz@microsoft.com> 20 * Hank Janssen <hjanssen@microsoft.com> 21 * 22 */ 23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 25 #include <linux/kernel.h> 26 #include <linux/sched.h> 27 #include <linux/wait.h> 28 #include <linux/delay.h> 29 #include <linux/mm.h> 30 #include <linux/slab.h> 31 #include <linux/vmalloc.h> 32 #include <linux/hyperv.h> 33 #include <linux/export.h> 34 #include <asm/mshyperv.h> 35 36 #include "hyperv_vmbus.h" 37 38 39 struct vmbus_connection vmbus_connection = { 40 .conn_state = DISCONNECTED, 41 .next_gpadl_handle = ATOMIC_INIT(0xE1E10), 42 }; 43 EXPORT_SYMBOL_GPL(vmbus_connection); 44 45 /* 46 * Negotiated protocol version with the host. 47 */ 48 __u32 vmbus_proto_version; 49 EXPORT_SYMBOL_GPL(vmbus_proto_version); 50 51 static __u32 vmbus_get_next_version(__u32 current_version) 52 { 53 switch (current_version) { 54 case (VERSION_WIN7): 55 return VERSION_WS2008; 56 57 case (VERSION_WIN8): 58 return VERSION_WIN7; 59 60 case (VERSION_WIN8_1): 61 return VERSION_WIN8; 62 63 case (VERSION_WIN10): 64 return VERSION_WIN8_1; 65 66 case (VERSION_WS2008): 67 default: 68 return VERSION_INVAL; 69 } 70 } 71 72 static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, 73 __u32 version) 74 { 75 int ret = 0; 76 struct vmbus_channel_initiate_contact *msg; 77 unsigned long flags; 78 79 init_completion(&msginfo->waitevent); 80 81 msg = (struct vmbus_channel_initiate_contact *)msginfo->msg; 82 83 msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT; 84 msg->vmbus_version_requested = version; 85 msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); 86 msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); 87 msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); 88 /* 89 * We want all channel messages to be delivered on CPU 0. 90 * This has been the behavior pre-win8. This is not 91 * perf issue and having all channel messages delivered on CPU 0 92 * would be ok. 93 * For post win8 hosts, we support receiving channel messagges on 94 * all the CPUs. This is needed for kexec to work correctly where 95 * the CPU attempting to connect may not be CPU 0. 96 */ 97 if (version >= VERSION_WIN8_1) { 98 msg->target_vcpu = 99 hv_cpu_number_to_vp_number(smp_processor_id()); 100 vmbus_connection.connect_cpu = smp_processor_id(); 101 } else { 102 msg->target_vcpu = 0; 103 vmbus_connection.connect_cpu = 0; 104 } 105 106 /* 107 * Add to list before we send the request since we may 108 * receive the response before returning from this routine 109 */ 110 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 111 list_add_tail(&msginfo->msglistentry, 112 &vmbus_connection.chn_msg_list); 113 114 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); 115 116 ret = vmbus_post_msg(msg, 117 sizeof(struct vmbus_channel_initiate_contact), 118 true); 119 120 trace_vmbus_negotiate_version(msg, ret); 121 122 if (ret != 0) { 123 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 124 list_del(&msginfo->msglistentry); 125 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, 126 flags); 127 return ret; 128 } 129 130 /* Wait for the connection response */ 131 wait_for_completion(&msginfo->waitevent); 132 133 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 134 list_del(&msginfo->msglistentry); 135 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); 136 137 /* Check if successful */ 138 if (msginfo->response.version_response.version_supported) { 139 vmbus_connection.conn_state = CONNECTED; 140 } else { 141 return -ECONNREFUSED; 142 } 143 144 return ret; 145 } 146 147 /* 148 * vmbus_connect - Sends a connect request on the partition service connection 149 */ 150 int vmbus_connect(void) 151 { 152 int ret = 0; 153 struct vmbus_channel_msginfo *msginfo = NULL; 154 __u32 version; 155 156 /* Initialize the vmbus connection */ 157 vmbus_connection.conn_state = CONNECTING; 158 vmbus_connection.work_queue = create_workqueue("hv_vmbus_con"); 159 if (!vmbus_connection.work_queue) { 160 ret = -ENOMEM; 161 goto cleanup; 162 } 163 164 INIT_LIST_HEAD(&vmbus_connection.chn_msg_list); 165 spin_lock_init(&vmbus_connection.channelmsg_lock); 166 167 INIT_LIST_HEAD(&vmbus_connection.chn_list); 168 mutex_init(&vmbus_connection.channel_mutex); 169 170 /* 171 * Setup the vmbus event connection for channel interrupt 172 * abstraction stuff 173 */ 174 vmbus_connection.int_page = 175 (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0); 176 if (vmbus_connection.int_page == NULL) { 177 ret = -ENOMEM; 178 goto cleanup; 179 } 180 181 vmbus_connection.recv_int_page = vmbus_connection.int_page; 182 vmbus_connection.send_int_page = 183 (void *)((unsigned long)vmbus_connection.int_page + 184 (PAGE_SIZE >> 1)); 185 186 /* 187 * Setup the monitor notification facility. The 1st page for 188 * parent->child and the 2nd page for child->parent 189 */ 190 vmbus_connection.monitor_pages[0] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0); 191 vmbus_connection.monitor_pages[1] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0); 192 if ((vmbus_connection.monitor_pages[0] == NULL) || 193 (vmbus_connection.monitor_pages[1] == NULL)) { 194 ret = -ENOMEM; 195 goto cleanup; 196 } 197 198 msginfo = kzalloc(sizeof(*msginfo) + 199 sizeof(struct vmbus_channel_initiate_contact), 200 GFP_KERNEL); 201 if (msginfo == NULL) { 202 ret = -ENOMEM; 203 goto cleanup; 204 } 205 206 /* 207 * Negotiate a compatible VMBUS version number with the 208 * host. We start with the highest number we can support 209 * and work our way down until we negotiate a compatible 210 * version. 211 */ 212 213 version = VERSION_CURRENT; 214 215 do { 216 ret = vmbus_negotiate_version(msginfo, version); 217 if (ret == -ETIMEDOUT) 218 goto cleanup; 219 220 if (vmbus_connection.conn_state == CONNECTED) 221 break; 222 223 version = vmbus_get_next_version(version); 224 } while (version != VERSION_INVAL); 225 226 if (version == VERSION_INVAL) 227 goto cleanup; 228 229 vmbus_proto_version = version; 230 pr_info("Vmbus version:%d.%d\n", 231 version >> 16, version & 0xFFFF); 232 233 kfree(msginfo); 234 return 0; 235 236 cleanup: 237 pr_err("Unable to connect to host\n"); 238 239 vmbus_connection.conn_state = DISCONNECTED; 240 vmbus_disconnect(); 241 242 kfree(msginfo); 243 244 return ret; 245 } 246 247 void vmbus_disconnect(void) 248 { 249 /* 250 * First send the unload request to the host. 251 */ 252 vmbus_initiate_unload(false); 253 254 if (vmbus_connection.work_queue) { 255 drain_workqueue(vmbus_connection.work_queue); 256 destroy_workqueue(vmbus_connection.work_queue); 257 } 258 259 if (vmbus_connection.int_page) { 260 free_pages((unsigned long)vmbus_connection.int_page, 0); 261 vmbus_connection.int_page = NULL; 262 } 263 264 free_pages((unsigned long)vmbus_connection.monitor_pages[0], 0); 265 free_pages((unsigned long)vmbus_connection.monitor_pages[1], 0); 266 vmbus_connection.monitor_pages[0] = NULL; 267 vmbus_connection.monitor_pages[1] = NULL; 268 } 269 270 /* 271 * relid2channel - Get the channel object given its 272 * child relative id (ie channel id) 273 */ 274 struct vmbus_channel *relid2channel(u32 relid) 275 { 276 struct vmbus_channel *channel; 277 struct vmbus_channel *found_channel = NULL; 278 struct list_head *cur, *tmp; 279 struct vmbus_channel *cur_sc; 280 281 BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); 282 283 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { 284 if (channel->offermsg.child_relid == relid) { 285 found_channel = channel; 286 break; 287 } else if (!list_empty(&channel->sc_list)) { 288 /* 289 * Deal with sub-channels. 290 */ 291 list_for_each_safe(cur, tmp, &channel->sc_list) { 292 cur_sc = list_entry(cur, struct vmbus_channel, 293 sc_list); 294 if (cur_sc->offermsg.child_relid == relid) { 295 found_channel = cur_sc; 296 break; 297 } 298 } 299 } 300 } 301 302 return found_channel; 303 } 304 305 /* 306 * vmbus_on_event - Process a channel event notification 307 * 308 * For batched channels (default) optimize host to guest signaling 309 * by ensuring: 310 * 1. While reading the channel, we disable interrupts from host. 311 * 2. Ensure that we process all posted messages from the host 312 * before returning from this callback. 313 * 3. Once we return, enable signaling from the host. Once this 314 * state is set we check to see if additional packets are 315 * available to read. In this case we repeat the process. 316 * If this tasklet has been running for a long time 317 * then reschedule ourselves. 318 */ 319 void vmbus_on_event(unsigned long data) 320 { 321 struct vmbus_channel *channel = (void *) data; 322 unsigned long time_limit = jiffies + 2; 323 324 trace_vmbus_on_event(channel); 325 326 do { 327 void (*callback_fn)(void *); 328 329 /* A channel once created is persistent even when 330 * there is no driver handling the device. An 331 * unloading driver sets the onchannel_callback to NULL. 332 */ 333 callback_fn = READ_ONCE(channel->onchannel_callback); 334 if (unlikely(callback_fn == NULL)) 335 return; 336 337 (*callback_fn)(channel->channel_callback_context); 338 339 if (channel->callback_mode != HV_CALL_BATCHED) 340 return; 341 342 if (likely(hv_end_read(&channel->inbound) == 0)) 343 return; 344 345 hv_begin_read(&channel->inbound); 346 } while (likely(time_before(jiffies, time_limit))); 347 348 /* The time limit (2 jiffies) has been reached */ 349 tasklet_schedule(&channel->callback_event); 350 } 351 352 /* 353 * vmbus_post_msg - Send a msg on the vmbus's message connection 354 */ 355 int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep) 356 { 357 union hv_connection_id conn_id; 358 int ret = 0; 359 int retries = 0; 360 u32 usec = 1; 361 362 conn_id.asu32 = 0; 363 conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID; 364 365 /* 366 * hv_post_message() can have transient failures because of 367 * insufficient resources. Retry the operation a couple of 368 * times before giving up. 369 */ 370 while (retries < 100) { 371 ret = hv_post_message(conn_id, 1, buffer, buflen); 372 373 switch (ret) { 374 case HV_STATUS_INVALID_CONNECTION_ID: 375 /* 376 * We could get this if we send messages too 377 * frequently. 378 */ 379 ret = -EAGAIN; 380 break; 381 case HV_STATUS_INSUFFICIENT_MEMORY: 382 case HV_STATUS_INSUFFICIENT_BUFFERS: 383 ret = -ENOBUFS; 384 break; 385 case HV_STATUS_SUCCESS: 386 return ret; 387 default: 388 pr_err("hv_post_msg() failed; error code:%d\n", ret); 389 return -EINVAL; 390 } 391 392 retries++; 393 if (can_sleep && usec > 1000) 394 msleep(usec / 1000); 395 else if (usec < MAX_UDELAY_MS * 1000) 396 udelay(usec); 397 else 398 mdelay(usec / 1000); 399 400 if (retries < 22) 401 usec *= 2; 402 } 403 return ret; 404 } 405 406 /* 407 * vmbus_set_event - Send an event notification to the parent 408 */ 409 void vmbus_set_event(struct vmbus_channel *channel) 410 { 411 u32 child_relid = channel->offermsg.child_relid; 412 413 if (!channel->is_dedicated_interrupt) 414 vmbus_send_interrupt(child_relid); 415 416 ++channel->sig_events; 417 418 hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event); 419 } 420 EXPORT_SYMBOL_GPL(vmbus_set_event); 421