Commit 869997be authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull Hyper-V fixes from Wei Liu:

 - Two patches from Dexuan fixing suspension bugs

 - Three cleanup patches from Andy and Michael

* tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  hyper-v: Remove internal types from UAPI header
  hyper-v: Use UUID API for exporting the GUID
  x86/hyperv: Suspend/resume the VP assist page for hibernation
  Drivers: hv: Move AEOI determination to architecture dependent code
  Drivers: hv: vmbus: Fix Suspend-to-Idle for Generation-2 VM
parents 6a8b55ed f081bbb3
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu)
	struct page *pg;

	input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
	pg = alloc_page(GFP_KERNEL);
	/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
	pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
	if (unlikely(!pg))
		return -ENOMEM;
	*input_arg = page_address(pg);
@@ -254,6 +255,7 @@ static int __init hv_pci_init(void)
static int hv_suspend(void)
{
	union hv_x64_msr_hypercall_contents hypercall_msr;
	int ret;

	/*
	 * Reset the hypercall page as it is going to be invalidated
@@ -270,12 +272,17 @@ static int hv_suspend(void)
	hypercall_msr.enable = 0;
	wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);

	return 0;
	ret = hv_cpu_die(0);
	return ret;
}

static void hv_resume(void)
{
	union hv_x64_msr_hypercall_contents hypercall_msr;
	int ret;

	ret = hv_cpu_init(0);
	WARN_ON(ret);

	/* Re-enable the hypercall page */
	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -288,6 +295,7 @@ static void hv_resume(void)
	hv_hypercall_pg_saved = NULL;
}

/* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */
static struct syscore_ops hv_syscore_ops = {
	.suspend	= hv_suspend,
	.resume		= hv_resume,
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)(
	rdmsrl(HV_X64_MSR_SINT0 + int_num, val)
#define hv_set_synint_state(int_num, val) \
	wrmsrl(HV_X64_MSR_SINT0 + int_num, val)
#define hv_recommend_using_aeoi() \
	(!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED))

#define hv_get_crash_ctl(val) \
	rdmsrl(HV_X64_MSR_CRASH_CTL, val)
+1 −5
Original line number Diff line number Diff line
@@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu)

	shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
	shared_sint.masked = false;
	if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)
		shared_sint.auto_eoi = false;
	else
		shared_sint.auto_eoi = true;

	shared_sint.auto_eoi = hv_recommend_using_aeoi();
	hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);

	/* Enable the global synic bit */
+2 −2
Original line number Diff line number Diff line
@@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request,
		    __field(int, ret)
		    ),
	    TP_fast_assign(
		    memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16);
		    memcpy(__entry->host_id, &msg->host_service_id.b, 16);
		    export_guid(__entry->guest_id, &msg->guest_endpoint_id);
		    export_guid(__entry->host_id, &msg->host_service_id);
		    __entry->ret = ret;
		    ),
	    TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, "
+34 −9
Original line number Diff line number Diff line
@@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device)

	return drv->resume(dev);
}
#else
#define vmbus_suspend NULL
#define vmbus_resume NULL
#endif /* CONFIG_PM_SLEEP */

/*
@@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device)
}

/*
 * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
 * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm.
 * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm.
 *
 * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we
 * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there
 * is no way to wake up a Generation-2 VM.
 *
 * The other 4 ops are for hibernation.
 */

static const struct dev_pm_ops vmbus_pm = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume)
	.suspend_noirq	= NULL,
	.resume_noirq	= NULL,
	.freeze_noirq	= vmbus_suspend,
	.thaw_noirq	= vmbus_resume,
	.poweroff_noirq	= vmbus_suspend,
	.restore_noirq	= vmbus_resume,
};

/* The one and only one */
@@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev)

	return 0;
}
#else
#define vmbus_bus_suspend NULL
#define vmbus_bus_resume NULL
#endif /* CONFIG_PM_SLEEP */

static const struct acpi_device_id vmbus_acpi_device_ids[] = {
@@ -2291,16 +2308,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = {
MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);

/*
 * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
 * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the
 * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the
 * pci "noirq" restore callback runs before "non-noirq" callbacks (see
 * Note: we must use the "no_irq" ops, otherwise hibernation can not work with
 * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in
 * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see
 * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() ->
 * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's
 * resume callback must also run via the "noirq" callbacks.
 * resume callback must also run via the "noirq" ops.
 *
 * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment
 * earlier in this file before vmbus_pm.
 */

static const struct dev_pm_ops vmbus_bus_pm = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume)
	.suspend_noirq	= NULL,
	.resume_noirq	= NULL,
	.freeze_noirq	= vmbus_bus_suspend,
	.thaw_noirq	= vmbus_bus_resume,
	.poweroff_noirq	= vmbus_bus_suspend,
	.restore_noirq	= vmbus_bus_resume
};

static struct acpi_driver vmbus_acpi_driver = {
Loading