Commit 37cb0c76 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hyperv-fixes-signed-20241217' of...

Merge tag 'hyperv-fixes-signed-20241217' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv fixes from Wei Liu:

 - Various fixes to Hyper-V tools in the kernel tree (Dexuan Cui, Olaf
   Hering, Vitaly Kuznetsov)

 - Fix a bug in the Hyper-V TSC page based sched_clock() (Naman Jain)

 - Two bug fixes in the Hyper-V utility functions (Michael Kelley)

 - Convert open-coded timeouts to secs_to_jiffies() in Hyper-V drivers
   (Easwar Hariharan)

* tag 'hyperv-fixes-signed-20241217' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  tools/hv: reduce resource usage in hv_kvp_daemon
  tools/hv: add a .gitignore file
  tools/hv: reduce resouce usage in hv_get_dns_info helper
  hv/hv_kvp_daemon: Pass NIC name to hv_get_dns_info as well
  Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet
  Drivers: hv: util: Don't force error code to ENODEV in util_probe()
  tools/hv: terminate fcopy daemon if read from uio fails
  drivers: hv: Convert open-coded timeouts to secs_to_jiffies()
  tools: hv: change permissions of NetworkManager configuration file
  x86/hyperv: Fix hv tsc page based sched_clock for hibernation
  tools: hv: Fix a complier warning in the fcopy uio daemon
parents 349f0086 175c71c2
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -223,6 +223,63 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
	hyperv_cleanup();
}
#endif /* CONFIG_CRASH_DUMP */

static u64 hv_ref_counter_at_suspend;
static void (*old_save_sched_clock_state)(void);
static void (*old_restore_sched_clock_state)(void);

/*
 * Hyper-V clock counter resets during hibernation. Save and restore clock
 * offset during suspend/resume, while also considering the time passed
 * before suspend. This is to make sure that sched_clock using hv tsc page
 * based clocksource, proceeds from where it left off during suspend and
 * it shows correct time for the timestamps of kernel messages after resume.
 */
static void save_hv_clock_tsc_state(void)
{
	hv_ref_counter_at_suspend = hv_read_reference_counter();
}

static void restore_hv_clock_tsc_state(void)
{
	/*
	 * Adjust the offsets used by hv tsc clocksource to
	 * account for the time spent before hibernation.
	 * adjusted value = reference counter (time) at suspend
	 *                - reference counter (time) now.
	 */
	hv_adj_sched_clock_offset(hv_ref_counter_at_suspend - hv_read_reference_counter());
}

/*
 * Functions to override save_sched_clock_state and restore_sched_clock_state
 * functions of x86_platform. The Hyper-V clock counter is reset during
 * suspend-resume and the offset used to measure time needs to be
 * corrected, post resume.
 */
static void hv_save_sched_clock_state(void)
{
	old_save_sched_clock_state();
	save_hv_clock_tsc_state();
}

static void hv_restore_sched_clock_state(void)
{
	restore_hv_clock_tsc_state();
	old_restore_sched_clock_state();
}

static void __init x86_setup_ops_for_tsc_pg_clock(void)
{
	if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
		return;

	old_save_sched_clock_state = x86_platform.save_sched_clock_state;
	x86_platform.save_sched_clock_state = hv_save_sched_clock_state;

	old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
	x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
}
#endif /* CONFIG_HYPERV */

static uint32_t  __init ms_hyperv_platform(void)
@@ -579,6 +636,7 @@ static void __init ms_hyperv_init_platform(void)

	/* Register Hyper-V specific clocksource */
	hv_init_clocksource();
	x86_setup_ops_for_tsc_pg_clock();
	hv_vtl_init_platform();
#endif
	/*
+13 −1
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@
#include <asm/mshyperv.h>

static struct clock_event_device __percpu *hv_clock_event;
static u64 hv_sched_clock_offset __ro_after_init;
/* Note: offset can hold negative values after hibernation. */
static u64 hv_sched_clock_offset __read_mostly;

/*
 * If false, we're using the old mechanism for stimer0 interrupts
@@ -470,6 +471,17 @@ static void resume_hv_clock_tsc(struct clocksource *arg)
	hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
}

/*
 * Called during resume from hibernation, from overridden
 * x86_platform.restore_sched_clock_state routine. This is to adjust offsets
 * used to calculate time for hv tsc page based sched_clock, to account for
 * time spent before hibernation.
 */
void hv_adj_sched_clock_offset(u64 offset)
{
	hv_sched_clock_offset -= offset;
}

#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
static int hv_cs_enable(struct clocksource *cs)
{
+5 −4
Original line number Diff line number Diff line
@@ -756,7 +756,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size,
		 * adding succeeded, it is ok to proceed even if the memory was
		 * not onlined in time.
		 */
		wait_for_completion_timeout(&dm_device.ol_waitevent, 5 * HZ);
		wait_for_completion_timeout(&dm_device.ol_waitevent, secs_to_jiffies(5));
		post_status(&dm_device);
	}
}
@@ -1373,7 +1373,8 @@ static int dm_thread_func(void *dm_dev)
	struct hv_dynmem_device *dm = dm_dev;

	while (!kthread_should_stop()) {
		wait_for_completion_interruptible_timeout(&dm_device.config_event, 1 * HZ);
		wait_for_completion_interruptible_timeout(&dm_device.config_event,
								secs_to_jiffies(1));
		/*
		 * The host expects us to post information on the memory
		 * pressure every second.
@@ -1748,7 +1749,7 @@ static int balloon_connect_vsp(struct hv_device *dev)
	if (ret)
		goto out;

	t = wait_for_completion_timeout(&dm_device.host_event, 5 * HZ);
	t = wait_for_completion_timeout(&dm_device.host_event, secs_to_jiffies(5));
	if (t == 0) {
		ret = -ETIMEDOUT;
		goto out;
@@ -1806,7 +1807,7 @@ static int balloon_connect_vsp(struct hv_device *dev)
	if (ret)
		goto out;

	t = wait_for_completion_timeout(&dm_device.host_event, 5 * HZ);
	t = wait_for_completion_timeout(&dm_device.host_event, secs_to_jiffies(5));
	if (t == 0) {
		ret = -ETIMEDOUT;
		goto out;
+8 −2
Original line number Diff line number Diff line
@@ -655,7 +655,7 @@ void hv_kvp_onchannelcallback(void *context)
		if (host_negotiatied == NEGO_NOT_STARTED) {
			host_negotiatied = NEGO_IN_PROGRESS;
			schedule_delayed_work(&kvp_host_handshake_work,
				      HV_UTIL_NEGO_TIMEOUT * HZ);
						secs_to_jiffies(HV_UTIL_NEGO_TIMEOUT));
		}
		return;
	}
@@ -724,7 +724,7 @@ void hv_kvp_onchannelcallback(void *context)
		 */
		schedule_work(&kvp_sendkey_work);
		schedule_delayed_work(&kvp_timeout_work,
					HV_UTIL_TIMEOUT * HZ);
				      secs_to_jiffies(HV_UTIL_TIMEOUT));

		return;

@@ -767,6 +767,12 @@ hv_kvp_init(struct hv_util_service *srv)
	 */
	kvp_transaction.state = HVUTIL_DEVICE_INIT;

	return 0;
}

int
hv_kvp_init_transport(void)
{
	hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL,
				    kvp_on_msg, kvp_on_reset);
	if (!hvt)
+8 −1
Original line number Diff line number Diff line
@@ -193,7 +193,8 @@ static void vss_send_op(void)
	vss_transaction.state = HVUTIL_USERSPACE_REQ;

	schedule_delayed_work(&vss_timeout_work, op == VSS_OP_FREEZE ?
			VSS_FREEZE_TIMEOUT * HZ : HV_UTIL_TIMEOUT * HZ);
				secs_to_jiffies(VSS_FREEZE_TIMEOUT) :
				secs_to_jiffies(HV_UTIL_TIMEOUT));

	rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg), NULL);
	if (rc) {
@@ -388,6 +389,12 @@ hv_vss_init(struct hv_util_service *srv)
	 */
	vss_transaction.state = HVUTIL_DEVICE_INIT;

	return 0;
}

int
hv_vss_init_transport(void)
{
	hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
				    vss_on_msg, vss_on_reset);
	if (!hvt) {
Loading