Commit 869997be authored by Linus Torvalds's avatar Linus Torvalds

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

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
...@@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu) ...@@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu)
struct page *pg; struct page *pg;
input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); 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)) if (unlikely(!pg))
return -ENOMEM; return -ENOMEM;
*input_arg = page_address(pg); *input_arg = page_address(pg);
...@@ -254,6 +255,7 @@ static int __init hv_pci_init(void) ...@@ -254,6 +255,7 @@ static int __init hv_pci_init(void)
static int hv_suspend(void) static int hv_suspend(void)
{ {
union hv_x64_msr_hypercall_contents hypercall_msr; union hv_x64_msr_hypercall_contents hypercall_msr;
int ret;
/* /*
* Reset the hypercall page as it is going to be invalidated * Reset the hypercall page as it is going to be invalidated
...@@ -270,12 +272,17 @@ static int hv_suspend(void) ...@@ -270,12 +272,17 @@ static int hv_suspend(void)
hypercall_msr.enable = 0; hypercall_msr.enable = 0;
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
return 0; ret = hv_cpu_die(0);
return ret;
} }
static void hv_resume(void) static void hv_resume(void)
{ {
union hv_x64_msr_hypercall_contents hypercall_msr; union hv_x64_msr_hypercall_contents hypercall_msr;
int ret;
ret = hv_cpu_init(0);
WARN_ON(ret);
/* Re-enable the hypercall page */ /* Re-enable the hypercall page */
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
...@@ -288,6 +295,7 @@ static void hv_resume(void) ...@@ -288,6 +295,7 @@ static void hv_resume(void)
hv_hypercall_pg_saved = NULL; 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 = { static struct syscore_ops hv_syscore_ops = {
.suspend = hv_suspend, .suspend = hv_suspend,
.resume = hv_resume, .resume = hv_resume,
......
...@@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)( ...@@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)(
rdmsrl(HV_X64_MSR_SINT0 + int_num, val) rdmsrl(HV_X64_MSR_SINT0 + int_num, val)
#define hv_set_synint_state(int_num, val) \ #define hv_set_synint_state(int_num, val) \
wrmsrl(HV_X64_MSR_SINT0 + 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) \ #define hv_get_crash_ctl(val) \
rdmsrl(HV_X64_MSR_CRASH_CTL, val) rdmsrl(HV_X64_MSR_CRASH_CTL, val)
......
...@@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu) ...@@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu)
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
shared_sint.masked = false; shared_sint.masked = false;
if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED) shared_sint.auto_eoi = hv_recommend_using_aeoi();
shared_sint.auto_eoi = false;
else
shared_sint.auto_eoi = true;
hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
/* Enable the global synic bit */ /* Enable the global synic bit */
......
...@@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request, ...@@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request,
__field(int, ret) __field(int, ret)
), ),
TP_fast_assign( TP_fast_assign(
memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16); export_guid(__entry->guest_id, &msg->guest_endpoint_id);
memcpy(__entry->host_id, &msg->host_service_id.b, 16); export_guid(__entry->host_id, &msg->host_service_id);
__entry->ret = ret; __entry->ret = ret;
), ),
TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, " TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, "
......
...@@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device) ...@@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device)
return drv->resume(dev); return drv->resume(dev);
} }
#else
#define vmbus_suspend NULL
#define vmbus_resume NULL
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
/* /*
...@@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device) ...@@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device)
} }
/* /*
* Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm.
* SET_SYSTEM_SLEEP_PM_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 = { 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 */ /* The one and only one */
...@@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev) ...@@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev)
return 0; return 0;
} }
#else
#define vmbus_bus_suspend NULL
#define vmbus_bus_resume NULL
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
static const struct acpi_device_id vmbus_acpi_device_ids[] = { static const struct acpi_device_id vmbus_acpi_device_ids[] = {
...@@ -2291,16 +2308,24 @@ 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); MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
/* /*
* Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than * Note: we must use the "no_irq" ops, otherwise hibernation can not work with
* SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in
* "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see
* pci "noirq" restore callback runs before "non-noirq" callbacks (see
* resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() ->
* dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's * 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 = { 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 = { static struct acpi_driver vmbus_acpi_driver = {
......
...@@ -119,8 +119,8 @@ enum hv_fcopy_op { ...@@ -119,8 +119,8 @@ enum hv_fcopy_op {
struct hv_fcopy_hdr { struct hv_fcopy_hdr {
__u32 operation; __u32 operation;
uuid_le service_id0; /* currently unused */ __u8 service_id0[16]; /* currently unused */
uuid_le service_id1; /* currently unused */ __u8 service_id1[16]; /* currently unused */
} __attribute__((packed)); } __attribute__((packed));
#define OVER_WRITE 0x1 #define OVER_WRITE 0x1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment