1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2010, Microsoft Corporation.
6 * Haiyang Zhang <haiyangz@microsoft.com>
7 * Hank Janssen <hjanssen@microsoft.com>
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
22 #include "hyperv_vmbus.h"
26 #define SD_VERSION (SD_MAJOR << 16 | SD_MINOR)
29 #define SD_VERSION_1 (SD_MAJOR_1 << 16 | SD_MINOR)
33 #define TS_VERSION (TS_MAJOR << 16 | TS_MINOR)
36 #define TS_VERSION_1 (TS_MAJOR_1 << 16 | TS_MINOR)
39 #define TS_VERSION_3 (TS_MAJOR_3 << 16 | TS_MINOR)
43 #define HB_VERSION (HB_MAJOR << 16 | HB_MINOR)
46 #define HB_VERSION_1 (HB_MAJOR_1 << 16 | HB_MINOR)
48 static int sd_srv_version;
49 static int ts_srv_version;
50 static int hb_srv_version;
52 #define SD_VER_COUNT 2
53 static const int sd_versions[] = {
58 #define TS_VER_COUNT 3
59 static const int ts_versions[] = {
65 #define HB_VER_COUNT 2
66 static const int hb_versions[] = {
71 #define FW_VER_COUNT 2
72 static const int fw_versions[] = {
77 static void shutdown_onchannelcallback(void *context);
78 static struct hv_util_service util_shutdown = {
79 .util_cb = shutdown_onchannelcallback,
82 static int hv_timesync_init(struct hv_util_service *srv);
83 static void hv_timesync_deinit(void);
85 static void timesync_onchannelcallback(void *context);
86 static struct hv_util_service util_timesynch = {
87 .util_cb = timesync_onchannelcallback,
88 .util_init = hv_timesync_init,
89 .util_deinit = hv_timesync_deinit,
92 static void heartbeat_onchannelcallback(void *context);
93 static struct hv_util_service util_heartbeat = {
94 .util_cb = heartbeat_onchannelcallback,
97 static struct hv_util_service util_kvp = {
98 .util_cb = hv_kvp_onchannelcallback,
99 .util_init = hv_kvp_init,
100 .util_deinit = hv_kvp_deinit,
103 static struct hv_util_service util_vss = {
104 .util_cb = hv_vss_onchannelcallback,
105 .util_init = hv_vss_init,
106 .util_deinit = hv_vss_deinit,
109 static struct hv_util_service util_fcopy = {
110 .util_cb = hv_fcopy_onchannelcallback,
111 .util_init = hv_fcopy_init,
112 .util_deinit = hv_fcopy_deinit,
115 static void perform_shutdown(struct work_struct *dummy)
117 orderly_poweroff(true);
121 * Perform the shutdown operation in a thread context.
123 static DECLARE_WORK(shutdown_work, perform_shutdown);
125 static void shutdown_onchannelcallback(void *context)
127 struct vmbus_channel *channel = context;
130 bool execute_shutdown = false;
131 u8 *shut_txf_buf = util_shutdown.recv_buffer;
133 struct shutdown_msg_data *shutdown_msg;
135 struct icmsg_hdr *icmsghdrp;
137 vmbus_recvpacket(channel, shut_txf_buf,
138 PAGE_SIZE, &recvlen, &requestid);
141 icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[
142 sizeof(struct vmbuspipe_hdr)];
144 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
145 if (vmbus_prep_negotiate_resp(icmsghdrp, shut_txf_buf,
146 fw_versions, FW_VER_COUNT,
147 sd_versions, SD_VER_COUNT,
148 NULL, &sd_srv_version)) {
149 pr_info("Shutdown IC version %d.%d\n",
150 sd_srv_version >> 16,
151 sd_srv_version & 0xFFFF);
155 (struct shutdown_msg_data *)&shut_txf_buf[
156 sizeof(struct vmbuspipe_hdr) +
157 sizeof(struct icmsg_hdr)];
159 switch (shutdown_msg->flags) {
162 icmsghdrp->status = HV_S_OK;
163 execute_shutdown = true;
165 pr_info("Shutdown request received -"
166 " graceful shutdown initiated\n");
169 icmsghdrp->status = HV_E_FAIL;
170 execute_shutdown = false;
172 pr_info("Shutdown request received -"
173 " Invalid request\n");
178 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
179 | ICMSGHDRFLAG_RESPONSE;
181 vmbus_sendpacket(channel, shut_txf_buf,
183 VM_PKT_DATA_INBAND, 0);
186 if (execute_shutdown == true)
187 schedule_work(&shutdown_work);
191 * Set the host time in a process context.
193 static struct work_struct adj_time_work;
196 * The last time sample, received from the host. PTP device responds to
197 * requests by using this data and the current partition-wide time reference
206 static struct timespec64 hv_get_adj_host_time(void)
208 struct timespec64 ts;
209 u64 newtime, reftime;
212 spin_lock_irqsave(&host_ts.lock, flags);
213 reftime = hyperv_cs->read(hyperv_cs);
214 newtime = host_ts.host_time + (reftime - host_ts.ref_time);
215 ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100);
216 spin_unlock_irqrestore(&host_ts.lock, flags);
221 static void hv_set_host_time(struct work_struct *work)
223 struct timespec64 ts = hv_get_adj_host_time();
225 do_settimeofday64(&ts);
229 * Synchronize time with host after reboot, restore, etc.
231 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM.
232 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time
233 * message after the timesync channel is opened. Since the hv_utils module is
234 * loaded after hv_vmbus, the first message is usually missed. This bit is
235 * considered a hard request to discipline the clock.
237 * ICTIMESYNCFLAG_SAMPLE bit indicates a time sample from host. This is
238 * typically used as a hint to the guest. The guest is under no obligation
239 * to discipline the clock.
241 static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags)
247 * Save the adjusted time sample from the host and the snapshot
248 * of the current system time.
250 spin_lock_irqsave(&host_ts.lock, flags);
252 cur_reftime = hyperv_cs->read(hyperv_cs);
253 host_ts.host_time = hosttime;
254 host_ts.ref_time = cur_reftime;
257 * TimeSync v4 messages contain reference time (guest's Hyper-V
258 * clocksource read when the time sample was generated), we can
259 * improve the precision by adding the delta between now and the
260 * time of generation. For older protocols we set
261 * reftime == cur_reftime on call.
263 host_ts.host_time += (cur_reftime - reftime);
265 spin_unlock_irqrestore(&host_ts.lock, flags);
267 /* Schedule work to do do_settimeofday64() */
268 if (adj_flags & ICTIMESYNCFLAG_SYNC)
269 schedule_work(&adj_time_work);
273 * Time Sync Channel message handler.
275 static void timesync_onchannelcallback(void *context)
277 struct vmbus_channel *channel = context;
280 struct icmsg_hdr *icmsghdrp;
281 struct ictimesync_data *timedatap;
282 struct ictimesync_ref_data *refdata;
283 u8 *time_txf_buf = util_timesynch.recv_buffer;
285 vmbus_recvpacket(channel, time_txf_buf,
286 PAGE_SIZE, &recvlen, &requestid);
289 icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
290 sizeof(struct vmbuspipe_hdr)];
292 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
293 if (vmbus_prep_negotiate_resp(icmsghdrp, time_txf_buf,
294 fw_versions, FW_VER_COUNT,
295 ts_versions, TS_VER_COUNT,
296 NULL, &ts_srv_version)) {
297 pr_info("TimeSync IC version %d.%d\n",
298 ts_srv_version >> 16,
299 ts_srv_version & 0xFFFF);
302 if (ts_srv_version > TS_VERSION_3) {
303 refdata = (struct ictimesync_ref_data *)
305 sizeof(struct vmbuspipe_hdr) +
306 sizeof(struct icmsg_hdr)];
308 adj_guesttime(refdata->parenttime,
309 refdata->vmreferencetime,
312 timedatap = (struct ictimesync_data *)
314 sizeof(struct vmbuspipe_hdr) +
315 sizeof(struct icmsg_hdr)];
316 adj_guesttime(timedatap->parenttime,
317 hyperv_cs->read(hyperv_cs),
322 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
323 | ICMSGHDRFLAG_RESPONSE;
325 vmbus_sendpacket(channel, time_txf_buf,
327 VM_PKT_DATA_INBAND, 0);
332 * Heartbeat functionality.
333 * Every two seconds, Hyper-V send us a heartbeat request message.
334 * we respond to this message, and Hyper-V knows we are alive.
336 static void heartbeat_onchannelcallback(void *context)
338 struct vmbus_channel *channel = context;
341 struct icmsg_hdr *icmsghdrp;
342 struct heartbeat_msg_data *heartbeat_msg;
343 u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
347 vmbus_recvpacket(channel, hbeat_txf_buf,
348 PAGE_SIZE, &recvlen, &requestid);
353 icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
354 sizeof(struct vmbuspipe_hdr)];
356 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
357 if (vmbus_prep_negotiate_resp(icmsghdrp,
359 fw_versions, FW_VER_COUNT,
360 hb_versions, HB_VER_COUNT,
361 NULL, &hb_srv_version)) {
363 pr_info("Heartbeat IC version %d.%d\n",
364 hb_srv_version >> 16,
365 hb_srv_version & 0xFFFF);
369 (struct heartbeat_msg_data *)&hbeat_txf_buf[
370 sizeof(struct vmbuspipe_hdr) +
371 sizeof(struct icmsg_hdr)];
373 heartbeat_msg->seq_num += 1;
376 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
377 | ICMSGHDRFLAG_RESPONSE;
379 vmbus_sendpacket(channel, hbeat_txf_buf,
381 VM_PKT_DATA_INBAND, 0);
385 static int util_probe(struct hv_device *dev,
386 const struct hv_vmbus_device_id *dev_id)
388 struct hv_util_service *srv =
389 (struct hv_util_service *)dev_id->driver_data;
392 srv->recv_buffer = kmalloc(PAGE_SIZE * 4, GFP_KERNEL);
393 if (!srv->recv_buffer)
395 srv->channel = dev->channel;
396 if (srv->util_init) {
397 ret = srv->util_init(srv);
405 * The set of services managed by the util driver are not performance
406 * critical and do not need batched reading. Furthermore, some services
407 * such as KVP can only handle one message from the host at a time.
408 * Turn off batched reading for all util drivers before we open the
411 set_channel_read_mode(dev->channel, HV_CALL_DIRECT);
413 hv_set_drvdata(dev, srv);
415 ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0,
416 srv->util_cb, dev->channel);
423 if (srv->util_deinit)
426 kfree(srv->recv_buffer);
430 static int util_remove(struct hv_device *dev)
432 struct hv_util_service *srv = hv_get_drvdata(dev);
434 if (srv->util_deinit)
436 vmbus_close(dev->channel);
437 kfree(srv->recv_buffer);
442 static const struct hv_vmbus_device_id id_table[] = {
445 .driver_data = (unsigned long)&util_shutdown
447 /* Time synch guid */
449 .driver_data = (unsigned long)&util_timesynch
452 { HV_HEART_BEAT_GUID,
453 .driver_data = (unsigned long)&util_heartbeat
457 .driver_data = (unsigned long)&util_kvp
461 .driver_data = (unsigned long)&util_vss
465 .driver_data = (unsigned long)&util_fcopy
470 MODULE_DEVICE_TABLE(vmbus, id_table);
472 /* The one and only one */
473 static struct hv_driver util_drv = {
475 .id_table = id_table,
477 .remove = util_remove,
479 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
483 static int hv_ptp_enable(struct ptp_clock_info *info,
484 struct ptp_clock_request *request, int on)
489 static int hv_ptp_settime(struct ptp_clock_info *p, const struct timespec64 *ts)
494 static int hv_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
498 static int hv_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
503 static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
505 *ts = hv_get_adj_host_time();
510 static struct ptp_clock_info ptp_hyperv_info = {
512 .enable = hv_ptp_enable,
513 .adjtime = hv_ptp_adjtime,
514 .adjfreq = hv_ptp_adjfreq,
515 .gettime64 = hv_ptp_gettime,
516 .settime64 = hv_ptp_settime,
517 .owner = THIS_MODULE,
520 static struct ptp_clock *hv_ptp_clock;
522 static int hv_timesync_init(struct hv_util_service *srv)
524 /* TimeSync requires Hyper-V clocksource. */
528 spin_lock_init(&host_ts.lock);
530 INIT_WORK(&adj_time_work, hv_set_host_time);
533 * ptp_clock_register() returns NULL when CONFIG_PTP_1588_CLOCK is
534 * disabled but the driver is still useful without the PTP device
535 * as it still handles the ICTIMESYNCFLAG_SYNC case.
537 hv_ptp_clock = ptp_clock_register(&ptp_hyperv_info, NULL);
538 if (IS_ERR_OR_NULL(hv_ptp_clock)) {
539 pr_err("cannot register PTP clock: %ld\n",
540 PTR_ERR(hv_ptp_clock));
547 static void hv_timesync_deinit(void)
550 ptp_clock_unregister(hv_ptp_clock);
551 cancel_work_sync(&adj_time_work);
554 static int __init init_hyperv_utils(void)
556 pr_info("Registering HyperV Utility Driver\n");
558 return vmbus_driver_register(&util_drv);
561 static void exit_hyperv_utils(void)
563 pr_info("De-Registered HyperV Utility Driver\n");
565 vmbus_driver_unregister(&util_drv);
568 module_init(init_hyperv_utils);
569 module_exit(exit_hyperv_utils);
571 MODULE_DESCRIPTION("Hyper-V Utilities");
572 MODULE_LICENSE("GPL");