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