1 /* 2 * Copyright (c) 2010, Microsoft Corporation. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 15 * Place - Suite 330, Boston, MA 02111-1307 USA. 16 * 17 * Authors: 18 * Haiyang Zhang <haiyangz@microsoft.com> 19 * Hank Janssen <hjanssen@microsoft.com> 20 */ 21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 23 #include <linux/kernel.h> 24 #include <linux/init.h> 25 #include <linux/module.h> 26 #include <linux/slab.h> 27 #include <linux/sysctl.h> 28 #include <linux/reboot.h> 29 #include <linux/hyperv.h> 30 31 static void shutdown_onchannelcallback(void *context); 32 static struct hv_util_service util_shutdown = { 33 .util_cb = shutdown_onchannelcallback, 34 }; 35 36 static void timesync_onchannelcallback(void *context); 37 static struct hv_util_service util_timesynch = { 38 .util_cb = timesync_onchannelcallback, 39 }; 40 41 static void heartbeat_onchannelcallback(void *context); 42 static struct hv_util_service util_heartbeat = { 43 .util_cb = heartbeat_onchannelcallback, 44 }; 45 46 static struct hv_util_service util_kvp = { 47 .util_cb = hv_kvp_onchannelcallback, 48 .util_init = hv_kvp_init, 49 .util_deinit = hv_kvp_deinit, 50 }; 51 52 static struct hv_util_service util_vss = { 53 .util_cb = hv_vss_onchannelcallback, 54 .util_init = hv_vss_init, 55 .util_deinit = hv_vss_deinit, 56 }; 57 58 static void perform_shutdown(struct work_struct *dummy) 59 { 60 orderly_poweroff(true); 61 } 62 63 /* 64 * Perform the shutdown operation in a thread context. 65 */ 66 static DECLARE_WORK(shutdown_work, perform_shutdown); 67 68 static void shutdown_onchannelcallback(void *context) 69 { 70 struct vmbus_channel *channel = context; 71 u32 recvlen; 72 u64 requestid; 73 u8 execute_shutdown = false; 74 u8 *shut_txf_buf = util_shutdown.recv_buffer; 75 76 struct shutdown_msg_data *shutdown_msg; 77 78 struct icmsg_hdr *icmsghdrp; 79 struct icmsg_negotiate *negop = NULL; 80 81 vmbus_recvpacket(channel, shut_txf_buf, 82 PAGE_SIZE, &recvlen, &requestid); 83 84 if (recvlen > 0) { 85 icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[ 86 sizeof(struct vmbuspipe_hdr)]; 87 88 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 89 vmbus_prep_negotiate_resp(icmsghdrp, negop, 90 shut_txf_buf, MAX_SRV_VER, MAX_SRV_VER); 91 } else { 92 shutdown_msg = 93 (struct shutdown_msg_data *)&shut_txf_buf[ 94 sizeof(struct vmbuspipe_hdr) + 95 sizeof(struct icmsg_hdr)]; 96 97 switch (shutdown_msg->flags) { 98 case 0: 99 case 1: 100 icmsghdrp->status = HV_S_OK; 101 execute_shutdown = true; 102 103 pr_info("Shutdown request received -" 104 " graceful shutdown initiated\n"); 105 break; 106 default: 107 icmsghdrp->status = HV_E_FAIL; 108 execute_shutdown = false; 109 110 pr_info("Shutdown request received -" 111 " Invalid request\n"); 112 break; 113 } 114 } 115 116 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 117 | ICMSGHDRFLAG_RESPONSE; 118 119 vmbus_sendpacket(channel, shut_txf_buf, 120 recvlen, requestid, 121 VM_PKT_DATA_INBAND, 0); 122 } 123 124 if (execute_shutdown == true) 125 schedule_work(&shutdown_work); 126 } 127 128 /* 129 * Set guest time to host UTC time. 130 */ 131 static inline void do_adj_guesttime(u64 hosttime) 132 { 133 s64 host_tns; 134 struct timespec host_ts; 135 136 host_tns = (hosttime - WLTIMEDELTA) * 100; 137 host_ts = ns_to_timespec(host_tns); 138 139 do_settimeofday(&host_ts); 140 } 141 142 /* 143 * Set the host time in a process context. 144 */ 145 146 struct adj_time_work { 147 struct work_struct work; 148 u64 host_time; 149 }; 150 151 static void hv_set_host_time(struct work_struct *work) 152 { 153 struct adj_time_work *wrk; 154 155 wrk = container_of(work, struct adj_time_work, work); 156 do_adj_guesttime(wrk->host_time); 157 kfree(wrk); 158 } 159 160 /* 161 * Synchronize time with host after reboot, restore, etc. 162 * 163 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. 164 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time 165 * message after the timesync channel is opened. Since the hv_utils module is 166 * loaded after hv_vmbus, the first message is usually missed. The other 167 * thing is, systime is automatically set to emulated hardware clock which may 168 * not be UTC time or in the same time zone. So, to override these effects, we 169 * use the first 50 time samples for initial system time setting. 170 */ 171 static inline void adj_guesttime(u64 hosttime, u8 flags) 172 { 173 struct adj_time_work *wrk; 174 static s32 scnt = 50; 175 176 wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC); 177 if (wrk == NULL) 178 return; 179 180 wrk->host_time = hosttime; 181 if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { 182 INIT_WORK(&wrk->work, hv_set_host_time); 183 schedule_work(&wrk->work); 184 return; 185 } 186 187 if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { 188 scnt--; 189 INIT_WORK(&wrk->work, hv_set_host_time); 190 schedule_work(&wrk->work); 191 } else 192 kfree(wrk); 193 } 194 195 /* 196 * Time Sync Channel message handler. 197 */ 198 static void timesync_onchannelcallback(void *context) 199 { 200 struct vmbus_channel *channel = context; 201 u32 recvlen; 202 u64 requestid; 203 struct icmsg_hdr *icmsghdrp; 204 struct ictimesync_data *timedatap; 205 u8 *time_txf_buf = util_timesynch.recv_buffer; 206 207 vmbus_recvpacket(channel, time_txf_buf, 208 PAGE_SIZE, &recvlen, &requestid); 209 210 if (recvlen > 0) { 211 icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ 212 sizeof(struct vmbuspipe_hdr)]; 213 214 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 215 vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf, 216 MAX_SRV_VER, MAX_SRV_VER); 217 } else { 218 timedatap = (struct ictimesync_data *)&time_txf_buf[ 219 sizeof(struct vmbuspipe_hdr) + 220 sizeof(struct icmsg_hdr)]; 221 adj_guesttime(timedatap->parenttime, timedatap->flags); 222 } 223 224 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 225 | ICMSGHDRFLAG_RESPONSE; 226 227 vmbus_sendpacket(channel, time_txf_buf, 228 recvlen, requestid, 229 VM_PKT_DATA_INBAND, 0); 230 } 231 } 232 233 /* 234 * Heartbeat functionality. 235 * Every two seconds, Hyper-V send us a heartbeat request message. 236 * we respond to this message, and Hyper-V knows we are alive. 237 */ 238 static void heartbeat_onchannelcallback(void *context) 239 { 240 struct vmbus_channel *channel = context; 241 u32 recvlen; 242 u64 requestid; 243 struct icmsg_hdr *icmsghdrp; 244 struct heartbeat_msg_data *heartbeat_msg; 245 u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; 246 247 vmbus_recvpacket(channel, hbeat_txf_buf, 248 PAGE_SIZE, &recvlen, &requestid); 249 250 if (recvlen > 0) { 251 icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ 252 sizeof(struct vmbuspipe_hdr)]; 253 254 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 255 vmbus_prep_negotiate_resp(icmsghdrp, NULL, 256 hbeat_txf_buf, MAX_SRV_VER, MAX_SRV_VER); 257 } else { 258 heartbeat_msg = 259 (struct heartbeat_msg_data *)&hbeat_txf_buf[ 260 sizeof(struct vmbuspipe_hdr) + 261 sizeof(struct icmsg_hdr)]; 262 263 heartbeat_msg->seq_num += 1; 264 } 265 266 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 267 | ICMSGHDRFLAG_RESPONSE; 268 269 vmbus_sendpacket(channel, hbeat_txf_buf, 270 recvlen, requestid, 271 VM_PKT_DATA_INBAND, 0); 272 } 273 } 274 275 static int util_probe(struct hv_device *dev, 276 const struct hv_vmbus_device_id *dev_id) 277 { 278 struct hv_util_service *srv = 279 (struct hv_util_service *)dev_id->driver_data; 280 int ret; 281 282 srv->recv_buffer = kmalloc(PAGE_SIZE * 2, GFP_KERNEL); 283 if (!srv->recv_buffer) 284 return -ENOMEM; 285 if (srv->util_init) { 286 ret = srv->util_init(srv); 287 if (ret) { 288 ret = -ENODEV; 289 goto error1; 290 } 291 } 292 293 /* 294 * The set of services managed by the util driver are not performance 295 * critical and do not need batched reading. Furthermore, some services 296 * such as KVP can only handle one message from the host at a time. 297 * Turn off batched reading for all util drivers before we open the 298 * channel. 299 */ 300 301 set_channel_read_state(dev->channel, false); 302 303 ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0, 304 srv->util_cb, dev->channel); 305 if (ret) 306 goto error; 307 308 hv_set_drvdata(dev, srv); 309 return 0; 310 311 error: 312 if (srv->util_deinit) 313 srv->util_deinit(); 314 error1: 315 kfree(srv->recv_buffer); 316 return ret; 317 } 318 319 static int util_remove(struct hv_device *dev) 320 { 321 struct hv_util_service *srv = hv_get_drvdata(dev); 322 323 vmbus_close(dev->channel); 324 if (srv->util_deinit) 325 srv->util_deinit(); 326 kfree(srv->recv_buffer); 327 328 return 0; 329 } 330 331 static const struct hv_vmbus_device_id id_table[] = { 332 /* Shutdown guid */ 333 { HV_SHUTDOWN_GUID, 334 .driver_data = (unsigned long)&util_shutdown 335 }, 336 /* Time synch guid */ 337 { HV_TS_GUID, 338 .driver_data = (unsigned long)&util_timesynch 339 }, 340 /* Heartbeat guid */ 341 { HV_HEART_BEAT_GUID, 342 .driver_data = (unsigned long)&util_heartbeat 343 }, 344 /* KVP guid */ 345 { HV_KVP_GUID, 346 .driver_data = (unsigned long)&util_kvp 347 }, 348 /* VSS GUID */ 349 { HV_VSS_GUID, 350 .driver_data = (unsigned long)&util_vss 351 }, 352 { }, 353 }; 354 355 MODULE_DEVICE_TABLE(vmbus, id_table); 356 357 /* The one and only one */ 358 static struct hv_driver util_drv = { 359 .name = "hv_util", 360 .id_table = id_table, 361 .probe = util_probe, 362 .remove = util_remove, 363 }; 364 365 static int __init init_hyperv_utils(void) 366 { 367 pr_info("Registering HyperV Utility Driver\n"); 368 369 return vmbus_driver_register(&util_drv); 370 } 371 372 static void exit_hyperv_utils(void) 373 { 374 pr_info("De-Registered HyperV Utility Driver\n"); 375 376 vmbus_driver_unregister(&util_drv); 377 } 378 379 module_init(init_hyperv_utils); 380 module_exit(exit_hyperv_utils); 381 382 MODULE_DESCRIPTION("Hyper-V Utilities"); 383 MODULE_VERSION(HV_DRV_VERSION); 384 MODULE_LICENSE("GPL"); 385