hv_util.c (20117B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2010, Microsoft Corporation. 4 * 5 * Authors: 6 * Haiyang Zhang <haiyangz@microsoft.com> 7 * Hank Janssen <hjanssen@microsoft.com> 8 */ 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/slab.h> 15#include <linux/sysctl.h> 16#include <linux/reboot.h> 17#include <linux/hyperv.h> 18#include <linux/clockchips.h> 19#include <linux/ptp_clock_kernel.h> 20#include <asm/mshyperv.h> 21 22#include "hyperv_vmbus.h" 23 24#define SD_MAJOR 3 25#define SD_MINOR 0 26#define SD_MINOR_1 1 27#define SD_MINOR_2 2 28#define SD_VERSION_3_1 (SD_MAJOR << 16 | SD_MINOR_1) 29#define SD_VERSION_3_2 (SD_MAJOR << 16 | SD_MINOR_2) 30#define SD_VERSION (SD_MAJOR << 16 | SD_MINOR) 31 32#define SD_MAJOR_1 1 33#define SD_VERSION_1 (SD_MAJOR_1 << 16 | SD_MINOR) 34 35#define TS_MAJOR 4 36#define TS_MINOR 0 37#define TS_VERSION (TS_MAJOR << 16 | TS_MINOR) 38 39#define TS_MAJOR_1 1 40#define TS_VERSION_1 (TS_MAJOR_1 << 16 | TS_MINOR) 41 42#define TS_MAJOR_3 3 43#define TS_VERSION_3 (TS_MAJOR_3 << 16 | TS_MINOR) 44 45#define HB_MAJOR 3 46#define HB_MINOR 0 47#define HB_VERSION (HB_MAJOR << 16 | HB_MINOR) 48 49#define HB_MAJOR_1 1 50#define HB_VERSION_1 (HB_MAJOR_1 << 16 | HB_MINOR) 51 52static int sd_srv_version; 53static int ts_srv_version; 54static int hb_srv_version; 55 56#define SD_VER_COUNT 4 57static const int sd_versions[] = { 58 SD_VERSION_3_2, 59 SD_VERSION_3_1, 60 SD_VERSION, 61 SD_VERSION_1 62}; 63 64#define TS_VER_COUNT 3 65static const int ts_versions[] = { 66 TS_VERSION, 67 TS_VERSION_3, 68 TS_VERSION_1 69}; 70 71#define HB_VER_COUNT 2 72static const int hb_versions[] = { 73 HB_VERSION, 74 HB_VERSION_1 75}; 76 77#define FW_VER_COUNT 2 78static const int fw_versions[] = { 79 UTIL_FW_VERSION, 80 UTIL_WS2K8_FW_VERSION 81}; 82 83/* 84 * Send the "hibernate" udev event in a thread context. 85 */ 86struct hibernate_work_context { 87 struct work_struct work; 88 struct hv_device *dev; 89}; 90 91static struct hibernate_work_context hibernate_context; 92static bool hibernation_supported; 93 94static void send_hibernate_uevent(struct work_struct *work) 95{ 96 char *uevent_env[2] = { "EVENT=hibernate", NULL }; 97 struct hibernate_work_context *ctx; 98 99 ctx = container_of(work, struct hibernate_work_context, work); 100 101 kobject_uevent_env(&ctx->dev->device.kobj, KOBJ_CHANGE, uevent_env); 102 103 pr_info("Sent hibernation uevent\n"); 104} 105 106static int hv_shutdown_init(struct hv_util_service *srv) 107{ 108 struct vmbus_channel *channel = srv->channel; 109 110 INIT_WORK(&hibernate_context.work, send_hibernate_uevent); 111 hibernate_context.dev = channel->device_obj; 112 113 hibernation_supported = hv_is_hibernation_supported(); 114 115 return 0; 116} 117 118static void shutdown_onchannelcallback(void *context); 119static struct hv_util_service util_shutdown = { 120 .util_cb = shutdown_onchannelcallback, 121 .util_init = hv_shutdown_init, 122}; 123 124static int hv_timesync_init(struct hv_util_service *srv); 125static int hv_timesync_pre_suspend(void); 126static void hv_timesync_deinit(void); 127 128static void timesync_onchannelcallback(void *context); 129static struct hv_util_service util_timesynch = { 130 .util_cb = timesync_onchannelcallback, 131 .util_init = hv_timesync_init, 132 .util_pre_suspend = hv_timesync_pre_suspend, 133 .util_deinit = hv_timesync_deinit, 134}; 135 136static void heartbeat_onchannelcallback(void *context); 137static struct hv_util_service util_heartbeat = { 138 .util_cb = heartbeat_onchannelcallback, 139}; 140 141static struct hv_util_service util_kvp = { 142 .util_cb = hv_kvp_onchannelcallback, 143 .util_init = hv_kvp_init, 144 .util_pre_suspend = hv_kvp_pre_suspend, 145 .util_pre_resume = hv_kvp_pre_resume, 146 .util_deinit = hv_kvp_deinit, 147}; 148 149static struct hv_util_service util_vss = { 150 .util_cb = hv_vss_onchannelcallback, 151 .util_init = hv_vss_init, 152 .util_pre_suspend = hv_vss_pre_suspend, 153 .util_pre_resume = hv_vss_pre_resume, 154 .util_deinit = hv_vss_deinit, 155}; 156 157static struct hv_util_service util_fcopy = { 158 .util_cb = hv_fcopy_onchannelcallback, 159 .util_init = hv_fcopy_init, 160 .util_pre_suspend = hv_fcopy_pre_suspend, 161 .util_pre_resume = hv_fcopy_pre_resume, 162 .util_deinit = hv_fcopy_deinit, 163}; 164 165static void perform_shutdown(struct work_struct *dummy) 166{ 167 orderly_poweroff(true); 168} 169 170static void perform_restart(struct work_struct *dummy) 171{ 172 orderly_reboot(); 173} 174 175/* 176 * Perform the shutdown operation in a thread context. 177 */ 178static DECLARE_WORK(shutdown_work, perform_shutdown); 179 180/* 181 * Perform the restart operation in a thread context. 182 */ 183static DECLARE_WORK(restart_work, perform_restart); 184 185static void shutdown_onchannelcallback(void *context) 186{ 187 struct vmbus_channel *channel = context; 188 struct work_struct *work = NULL; 189 u32 recvlen; 190 u64 requestid; 191 u8 *shut_txf_buf = util_shutdown.recv_buffer; 192 193 struct shutdown_msg_data *shutdown_msg; 194 195 struct icmsg_hdr *icmsghdrp; 196 197 if (vmbus_recvpacket(channel, shut_txf_buf, HV_HYP_PAGE_SIZE, &recvlen, &requestid)) { 198 pr_err_ratelimited("Shutdown request received. Could not read into shut txf buf\n"); 199 return; 200 } 201 202 if (!recvlen) 203 return; 204 205 /* Ensure recvlen is big enough to read header data */ 206 if (recvlen < ICMSG_HDR) { 207 pr_err_ratelimited("Shutdown request received. Packet length too small: %d\n", 208 recvlen); 209 return; 210 } 211 212 icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[sizeof(struct vmbuspipe_hdr)]; 213 214 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 215 if (vmbus_prep_negotiate_resp(icmsghdrp, 216 shut_txf_buf, recvlen, 217 fw_versions, FW_VER_COUNT, 218 sd_versions, SD_VER_COUNT, 219 NULL, &sd_srv_version)) { 220 pr_info("Shutdown IC version %d.%d\n", 221 sd_srv_version >> 16, 222 sd_srv_version & 0xFFFF); 223 } 224 } else if (icmsghdrp->icmsgtype == ICMSGTYPE_SHUTDOWN) { 225 /* Ensure recvlen is big enough to contain shutdown_msg_data struct */ 226 if (recvlen < ICMSG_HDR + sizeof(struct shutdown_msg_data)) { 227 pr_err_ratelimited("Invalid shutdown msg data. Packet length too small: %u\n", 228 recvlen); 229 return; 230 } 231 232 shutdown_msg = (struct shutdown_msg_data *)&shut_txf_buf[ICMSG_HDR]; 233 234 /* 235 * shutdown_msg->flags can be 0(shut down), 2(reboot), 236 * or 4(hibernate). It may bitwise-OR 1, which means 237 * performing the request by force. Linux always tries 238 * to perform the request by force. 239 */ 240 switch (shutdown_msg->flags) { 241 case 0: 242 case 1: 243 icmsghdrp->status = HV_S_OK; 244 work = &shutdown_work; 245 pr_info("Shutdown request received - graceful shutdown initiated\n"); 246 break; 247 case 2: 248 case 3: 249 icmsghdrp->status = HV_S_OK; 250 work = &restart_work; 251 pr_info("Restart request received - graceful restart initiated\n"); 252 break; 253 case 4: 254 case 5: 255 pr_info("Hibernation request received\n"); 256 icmsghdrp->status = hibernation_supported ? 257 HV_S_OK : HV_E_FAIL; 258 if (hibernation_supported) 259 work = &hibernate_context.work; 260 break; 261 default: 262 icmsghdrp->status = HV_E_FAIL; 263 pr_info("Shutdown request received - Invalid request\n"); 264 break; 265 } 266 } else { 267 icmsghdrp->status = HV_E_FAIL; 268 pr_err_ratelimited("Shutdown request received. Invalid msg type: %d\n", 269 icmsghdrp->icmsgtype); 270 } 271 272 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 273 | ICMSGHDRFLAG_RESPONSE; 274 275 vmbus_sendpacket(channel, shut_txf_buf, 276 recvlen, requestid, 277 VM_PKT_DATA_INBAND, 0); 278 279 if (work) 280 schedule_work(work); 281} 282 283/* 284 * Set the host time in a process context. 285 */ 286static struct work_struct adj_time_work; 287 288/* 289 * The last time sample, received from the host. PTP device responds to 290 * requests by using this data and the current partition-wide time reference 291 * count. 292 */ 293static struct { 294 u64 host_time; 295 u64 ref_time; 296 spinlock_t lock; 297} host_ts; 298 299static inline u64 reftime_to_ns(u64 reftime) 300{ 301 return (reftime - WLTIMEDELTA) * 100; 302} 303 304/* 305 * Hard coded threshold for host timesync delay: 600 seconds 306 */ 307static const u64 HOST_TIMESYNC_DELAY_THRESH = 600 * (u64)NSEC_PER_SEC; 308 309static int hv_get_adj_host_time(struct timespec64 *ts) 310{ 311 u64 newtime, reftime, timediff_adj; 312 unsigned long flags; 313 int ret = 0; 314 315 spin_lock_irqsave(&host_ts.lock, flags); 316 reftime = hv_read_reference_counter(); 317 318 /* 319 * We need to let the caller know that last update from host 320 * is older than the max allowable threshold. clock_gettime() 321 * and PTP ioctl do not have a documented error that we could 322 * return for this specific case. Use ESTALE to report this. 323 */ 324 timediff_adj = reftime - host_ts.ref_time; 325 if (timediff_adj * 100 > HOST_TIMESYNC_DELAY_THRESH) { 326 pr_warn_once("TIMESYNC IC: Stale time stamp, %llu nsecs old\n", 327 (timediff_adj * 100)); 328 ret = -ESTALE; 329 } 330 331 newtime = host_ts.host_time + timediff_adj; 332 *ts = ns_to_timespec64(reftime_to_ns(newtime)); 333 spin_unlock_irqrestore(&host_ts.lock, flags); 334 335 return ret; 336} 337 338static void hv_set_host_time(struct work_struct *work) 339{ 340 341 struct timespec64 ts; 342 343 if (!hv_get_adj_host_time(&ts)) 344 do_settimeofday64(&ts); 345} 346 347/* 348 * Synchronize time with host after reboot, restore, etc. 349 * 350 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. 351 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time 352 * message after the timesync channel is opened. Since the hv_utils module is 353 * loaded after hv_vmbus, the first message is usually missed. This bit is 354 * considered a hard request to discipline the clock. 355 * 356 * ICTIMESYNCFLAG_SAMPLE bit indicates a time sample from host. This is 357 * typically used as a hint to the guest. The guest is under no obligation 358 * to discipline the clock. 359 */ 360static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags) 361{ 362 unsigned long flags; 363 u64 cur_reftime; 364 365 /* 366 * Save the adjusted time sample from the host and the snapshot 367 * of the current system time. 368 */ 369 spin_lock_irqsave(&host_ts.lock, flags); 370 371 cur_reftime = hv_read_reference_counter(); 372 host_ts.host_time = hosttime; 373 host_ts.ref_time = cur_reftime; 374 375 /* 376 * TimeSync v4 messages contain reference time (guest's Hyper-V 377 * clocksource read when the time sample was generated), we can 378 * improve the precision by adding the delta between now and the 379 * time of generation. For older protocols we set 380 * reftime == cur_reftime on call. 381 */ 382 host_ts.host_time += (cur_reftime - reftime); 383 384 spin_unlock_irqrestore(&host_ts.lock, flags); 385 386 /* Schedule work to do do_settimeofday64() */ 387 if (adj_flags & ICTIMESYNCFLAG_SYNC) 388 schedule_work(&adj_time_work); 389} 390 391/* 392 * Time Sync Channel message handler. 393 */ 394static void timesync_onchannelcallback(void *context) 395{ 396 struct vmbus_channel *channel = context; 397 u32 recvlen; 398 u64 requestid; 399 struct icmsg_hdr *icmsghdrp; 400 struct ictimesync_data *timedatap; 401 struct ictimesync_ref_data *refdata; 402 u8 *time_txf_buf = util_timesynch.recv_buffer; 403 404 /* 405 * Drain the ring buffer and use the last packet to update 406 * host_ts 407 */ 408 while (1) { 409 int ret = vmbus_recvpacket(channel, time_txf_buf, 410 HV_HYP_PAGE_SIZE, &recvlen, 411 &requestid); 412 if (ret) { 413 pr_err_ratelimited("TimeSync IC pkt recv failed (Err: %d)\n", 414 ret); 415 break; 416 } 417 418 if (!recvlen) 419 break; 420 421 /* Ensure recvlen is big enough to read header data */ 422 if (recvlen < ICMSG_HDR) { 423 pr_err_ratelimited("Timesync request received. Packet length too small: %d\n", 424 recvlen); 425 break; 426 } 427 428 icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ 429 sizeof(struct vmbuspipe_hdr)]; 430 431 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 432 if (vmbus_prep_negotiate_resp(icmsghdrp, 433 time_txf_buf, recvlen, 434 fw_versions, FW_VER_COUNT, 435 ts_versions, TS_VER_COUNT, 436 NULL, &ts_srv_version)) { 437 pr_info("TimeSync IC version %d.%d\n", 438 ts_srv_version >> 16, 439 ts_srv_version & 0xFFFF); 440 } 441 } else if (icmsghdrp->icmsgtype == ICMSGTYPE_TIMESYNC) { 442 if (ts_srv_version > TS_VERSION_3) { 443 /* Ensure recvlen is big enough to read ictimesync_ref_data */ 444 if (recvlen < ICMSG_HDR + sizeof(struct ictimesync_ref_data)) { 445 pr_err_ratelimited("Invalid ictimesync ref data. Length too small: %u\n", 446 recvlen); 447 break; 448 } 449 refdata = (struct ictimesync_ref_data *)&time_txf_buf[ICMSG_HDR]; 450 451 adj_guesttime(refdata->parenttime, 452 refdata->vmreferencetime, 453 refdata->flags); 454 } else { 455 /* Ensure recvlen is big enough to read ictimesync_data */ 456 if (recvlen < ICMSG_HDR + sizeof(struct ictimesync_data)) { 457 pr_err_ratelimited("Invalid ictimesync data. Length too small: %u\n", 458 recvlen); 459 break; 460 } 461 timedatap = (struct ictimesync_data *)&time_txf_buf[ICMSG_HDR]; 462 463 adj_guesttime(timedatap->parenttime, 464 hv_read_reference_counter(), 465 timedatap->flags); 466 } 467 } else { 468 icmsghdrp->status = HV_E_FAIL; 469 pr_err_ratelimited("Timesync request received. Invalid msg type: %d\n", 470 icmsghdrp->icmsgtype); 471 } 472 473 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 474 | ICMSGHDRFLAG_RESPONSE; 475 476 vmbus_sendpacket(channel, time_txf_buf, 477 recvlen, requestid, 478 VM_PKT_DATA_INBAND, 0); 479 } 480} 481 482/* 483 * Heartbeat functionality. 484 * Every two seconds, Hyper-V send us a heartbeat request message. 485 * we respond to this message, and Hyper-V knows we are alive. 486 */ 487static void heartbeat_onchannelcallback(void *context) 488{ 489 struct vmbus_channel *channel = context; 490 u32 recvlen; 491 u64 requestid; 492 struct icmsg_hdr *icmsghdrp; 493 struct heartbeat_msg_data *heartbeat_msg; 494 u8 *hbeat_txf_buf = util_heartbeat.recv_buffer; 495 496 while (1) { 497 498 if (vmbus_recvpacket(channel, hbeat_txf_buf, HV_HYP_PAGE_SIZE, 499 &recvlen, &requestid)) { 500 pr_err_ratelimited("Heartbeat request received. Could not read into hbeat txf buf\n"); 501 return; 502 } 503 504 if (!recvlen) 505 break; 506 507 /* Ensure recvlen is big enough to read header data */ 508 if (recvlen < ICMSG_HDR) { 509 pr_err_ratelimited("Heartbeat request received. Packet length too small: %d\n", 510 recvlen); 511 break; 512 } 513 514 icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ 515 sizeof(struct vmbuspipe_hdr)]; 516 517 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 518 if (vmbus_prep_negotiate_resp(icmsghdrp, 519 hbeat_txf_buf, recvlen, 520 fw_versions, FW_VER_COUNT, 521 hb_versions, HB_VER_COUNT, 522 NULL, &hb_srv_version)) { 523 524 pr_info("Heartbeat IC version %d.%d\n", 525 hb_srv_version >> 16, 526 hb_srv_version & 0xFFFF); 527 } 528 } else if (icmsghdrp->icmsgtype == ICMSGTYPE_HEARTBEAT) { 529 /* 530 * Ensure recvlen is big enough to read seq_num. Reserved area is not 531 * included in the check as the host may not fill it up entirely 532 */ 533 if (recvlen < ICMSG_HDR + sizeof(u64)) { 534 pr_err_ratelimited("Invalid heartbeat msg data. Length too small: %u\n", 535 recvlen); 536 break; 537 } 538 heartbeat_msg = (struct heartbeat_msg_data *)&hbeat_txf_buf[ICMSG_HDR]; 539 540 heartbeat_msg->seq_num += 1; 541 } else { 542 icmsghdrp->status = HV_E_FAIL; 543 pr_err_ratelimited("Heartbeat request received. Invalid msg type: %d\n", 544 icmsghdrp->icmsgtype); 545 } 546 547 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 548 | ICMSGHDRFLAG_RESPONSE; 549 550 vmbus_sendpacket(channel, hbeat_txf_buf, 551 recvlen, requestid, 552 VM_PKT_DATA_INBAND, 0); 553 } 554} 555 556#define HV_UTIL_RING_SEND_SIZE VMBUS_RING_SIZE(3 * HV_HYP_PAGE_SIZE) 557#define HV_UTIL_RING_RECV_SIZE VMBUS_RING_SIZE(3 * HV_HYP_PAGE_SIZE) 558 559static int util_probe(struct hv_device *dev, 560 const struct hv_vmbus_device_id *dev_id) 561{ 562 struct hv_util_service *srv = 563 (struct hv_util_service *)dev_id->driver_data; 564 int ret; 565 566 srv->recv_buffer = kmalloc(HV_HYP_PAGE_SIZE * 4, GFP_KERNEL); 567 if (!srv->recv_buffer) 568 return -ENOMEM; 569 srv->channel = dev->channel; 570 if (srv->util_init) { 571 ret = srv->util_init(srv); 572 if (ret) { 573 ret = -ENODEV; 574 goto error1; 575 } 576 } 577 578 /* 579 * The set of services managed by the util driver are not performance 580 * critical and do not need batched reading. Furthermore, some services 581 * such as KVP can only handle one message from the host at a time. 582 * Turn off batched reading for all util drivers before we open the 583 * channel. 584 */ 585 set_channel_read_mode(dev->channel, HV_CALL_DIRECT); 586 587 hv_set_drvdata(dev, srv); 588 589 ret = vmbus_open(dev->channel, HV_UTIL_RING_SEND_SIZE, 590 HV_UTIL_RING_RECV_SIZE, NULL, 0, srv->util_cb, 591 dev->channel); 592 if (ret) 593 goto error; 594 595 return 0; 596 597error: 598 if (srv->util_deinit) 599 srv->util_deinit(); 600error1: 601 kfree(srv->recv_buffer); 602 return ret; 603} 604 605static int util_remove(struct hv_device *dev) 606{ 607 struct hv_util_service *srv = hv_get_drvdata(dev); 608 609 if (srv->util_deinit) 610 srv->util_deinit(); 611 vmbus_close(dev->channel); 612 kfree(srv->recv_buffer); 613 614 return 0; 615} 616 617/* 618 * When we're in util_suspend(), all the userspace processes have been frozen 619 * (refer to hibernate() -> freeze_processes()). The userspace is thawed only 620 * after the whole resume procedure, including util_resume(), finishes. 621 */ 622static int util_suspend(struct hv_device *dev) 623{ 624 struct hv_util_service *srv = hv_get_drvdata(dev); 625 int ret = 0; 626 627 if (srv->util_pre_suspend) { 628 ret = srv->util_pre_suspend(); 629 if (ret) 630 return ret; 631 } 632 633 vmbus_close(dev->channel); 634 635 return 0; 636} 637 638static int util_resume(struct hv_device *dev) 639{ 640 struct hv_util_service *srv = hv_get_drvdata(dev); 641 int ret = 0; 642 643 if (srv->util_pre_resume) { 644 ret = srv->util_pre_resume(); 645 if (ret) 646 return ret; 647 } 648 649 ret = vmbus_open(dev->channel, HV_UTIL_RING_SEND_SIZE, 650 HV_UTIL_RING_RECV_SIZE, NULL, 0, srv->util_cb, 651 dev->channel); 652 return ret; 653} 654 655static const struct hv_vmbus_device_id id_table[] = { 656 /* Shutdown guid */ 657 { HV_SHUTDOWN_GUID, 658 .driver_data = (unsigned long)&util_shutdown 659 }, 660 /* Time synch guid */ 661 { HV_TS_GUID, 662 .driver_data = (unsigned long)&util_timesynch 663 }, 664 /* Heartbeat guid */ 665 { HV_HEART_BEAT_GUID, 666 .driver_data = (unsigned long)&util_heartbeat 667 }, 668 /* KVP guid */ 669 { HV_KVP_GUID, 670 .driver_data = (unsigned long)&util_kvp 671 }, 672 /* VSS GUID */ 673 { HV_VSS_GUID, 674 .driver_data = (unsigned long)&util_vss 675 }, 676 /* File copy GUID */ 677 { HV_FCOPY_GUID, 678 .driver_data = (unsigned long)&util_fcopy 679 }, 680 { }, 681}; 682 683MODULE_DEVICE_TABLE(vmbus, id_table); 684 685/* The one and only one */ 686static struct hv_driver util_drv = { 687 .name = "hv_utils", 688 .id_table = id_table, 689 .probe = util_probe, 690 .remove = util_remove, 691 .suspend = util_suspend, 692 .resume = util_resume, 693 .driver = { 694 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 695 }, 696}; 697 698static int hv_ptp_enable(struct ptp_clock_info *info, 699 struct ptp_clock_request *request, int on) 700{ 701 return -EOPNOTSUPP; 702} 703 704static int hv_ptp_settime(struct ptp_clock_info *p, const struct timespec64 *ts) 705{ 706 return -EOPNOTSUPP; 707} 708 709static int hv_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta) 710{ 711 return -EOPNOTSUPP; 712} 713static int hv_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) 714{ 715 return -EOPNOTSUPP; 716} 717 718static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts) 719{ 720 return hv_get_adj_host_time(ts); 721} 722 723static struct ptp_clock_info ptp_hyperv_info = { 724 .name = "hyperv", 725 .enable = hv_ptp_enable, 726 .adjtime = hv_ptp_adjtime, 727 .adjfreq = hv_ptp_adjfreq, 728 .gettime64 = hv_ptp_gettime, 729 .settime64 = hv_ptp_settime, 730 .owner = THIS_MODULE, 731}; 732 733static struct ptp_clock *hv_ptp_clock; 734 735static int hv_timesync_init(struct hv_util_service *srv) 736{ 737 spin_lock_init(&host_ts.lock); 738 739 INIT_WORK(&adj_time_work, hv_set_host_time); 740 741 /* 742 * ptp_clock_register() returns NULL when CONFIG_PTP_1588_CLOCK is 743 * disabled but the driver is still useful without the PTP device 744 * as it still handles the ICTIMESYNCFLAG_SYNC case. 745 */ 746 hv_ptp_clock = ptp_clock_register(&ptp_hyperv_info, NULL); 747 if (IS_ERR_OR_NULL(hv_ptp_clock)) { 748 pr_err("cannot register PTP clock: %d\n", 749 PTR_ERR_OR_ZERO(hv_ptp_clock)); 750 hv_ptp_clock = NULL; 751 } 752 753 return 0; 754} 755 756static void hv_timesync_cancel_work(void) 757{ 758 cancel_work_sync(&adj_time_work); 759} 760 761static int hv_timesync_pre_suspend(void) 762{ 763 hv_timesync_cancel_work(); 764 return 0; 765} 766 767static void hv_timesync_deinit(void) 768{ 769 if (hv_ptp_clock) 770 ptp_clock_unregister(hv_ptp_clock); 771 772 hv_timesync_cancel_work(); 773} 774 775static int __init init_hyperv_utils(void) 776{ 777 pr_info("Registering HyperV Utility Driver\n"); 778 779 return vmbus_driver_register(&util_drv); 780} 781 782static void exit_hyperv_utils(void) 783{ 784 pr_info("De-Registered HyperV Utility Driver\n"); 785 786 vmbus_driver_unregister(&util_drv); 787} 788 789module_init(init_hyperv_utils); 790module_exit(exit_hyperv_utils); 791 792MODULE_DESCRIPTION("Hyper-V Utilities"); 793MODULE_LICENSE("GPL");