Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+51 -20
+10 -2
arch/x86/hyperv/hv_init.c
··· 73 73 struct page *pg; 74 74 75 75 input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); 76 - pg = alloc_page(GFP_KERNEL); 76 + /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ 77 + pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); 77 78 if (unlikely(!pg)) 78 79 return -ENOMEM; 79 80 *input_arg = page_address(pg); ··· 255 254 static int hv_suspend(void) 256 255 { 257 256 union hv_x64_msr_hypercall_contents hypercall_msr; 257 + int ret; 258 258 259 259 /* 260 260 * Reset the hypercall page as it is going to be invalidated ··· 272 270 hypercall_msr.enable = 0; 273 271 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); 274 272 275 - return 0; 273 + ret = hv_cpu_die(0); 274 + return ret; 276 275 } 277 276 278 277 static void hv_resume(void) 279 278 { 280 279 union hv_x64_msr_hypercall_contents hypercall_msr; 280 + int ret; 281 + 282 + ret = hv_cpu_init(0); 283 + WARN_ON(ret); 281 284 282 285 /* Re-enable the hypercall page */ 283 286 rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); ··· 295 288 hv_hypercall_pg_saved = NULL; 296 289 } 297 290 291 + /* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ 298 292 static struct syscore_ops hv_syscore_ops = { 299 293 .suspend = hv_suspend, 300 294 .resume = hv_resume,
+2
arch/x86/include/asm/mshyperv.h
··· 35 35 rdmsrl(HV_X64_MSR_SINT0 + int_num, val) 36 36 #define hv_set_synint_state(int_num, val) \ 37 37 wrmsrl(HV_X64_MSR_SINT0 + int_num, val) 38 + #define hv_recommend_using_aeoi() \ 39 + (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)) 38 40 39 41 #define hv_get_crash_ctl(val) \ 40 42 rdmsrl(HV_X64_MSR_CRASH_CTL, val)
+1 -5
drivers/hv/hv.c
··· 184 184 185 185 shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; 186 186 shared_sint.masked = false; 187 - if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED) 188 - shared_sint.auto_eoi = false; 189 - else 190 - shared_sint.auto_eoi = true; 191 - 187 + shared_sint.auto_eoi = hv_recommend_using_aeoi(); 192 188 hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); 193 189 194 190 /* Enable the global synic bit */
+2 -2
drivers/hv/hv_trace.h
··· 286 286 __field(int, ret) 287 287 ), 288 288 TP_fast_assign( 289 - memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16); 290 - memcpy(__entry->host_id, &msg->host_service_id.b, 16); 289 + export_guid(__entry->guest_id, &msg->guest_endpoint_id); 290 + export_guid(__entry->host_id, &msg->host_service_id); 291 291 __entry->ret = ret; 292 292 ), 293 293 TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, "
+34 -9
drivers/hv/vmbus_drv.c
··· 978 978 979 979 return drv->resume(dev); 980 980 } 981 + #else 982 + #define vmbus_suspend NULL 983 + #define vmbus_resume NULL 981 984 #endif /* CONFIG_PM_SLEEP */ 982 985 983 986 /* ··· 1000 997 } 1001 998 1002 999 /* 1003 - * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than 1004 - * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm. 1000 + * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm. 1001 + * 1002 + * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we 1003 + * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there 1004 + * is no way to wake up a Generation-2 VM. 1005 + * 1006 + * The other 4 ops are for hibernation. 1005 1007 */ 1008 + 1006 1009 static const struct dev_pm_ops vmbus_pm = { 1007 - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume) 1010 + .suspend_noirq = NULL, 1011 + .resume_noirq = NULL, 1012 + .freeze_noirq = vmbus_suspend, 1013 + .thaw_noirq = vmbus_resume, 1014 + .poweroff_noirq = vmbus_suspend, 1015 + .restore_noirq = vmbus_resume, 1008 1016 }; 1009 1017 1010 1018 /* The one and only one */ ··· 2295 2281 2296 2282 return 0; 2297 2283 } 2284 + #else 2285 + #define vmbus_bus_suspend NULL 2286 + #define vmbus_bus_resume NULL 2298 2287 #endif /* CONFIG_PM_SLEEP */ 2299 2288 2300 2289 static const struct acpi_device_id vmbus_acpi_device_ids[] = { ··· 2308 2291 MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); 2309 2292 2310 2293 /* 2311 - * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than 2312 - * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the 2313 - * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the 2314 - * pci "noirq" restore callback runs before "non-noirq" callbacks (see 2294 + * Note: we must use the "no_irq" ops, otherwise hibernation can not work with 2295 + * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in 2296 + * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see 2315 2297 * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> 2316 2298 * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's 2317 - * resume callback must also run via the "noirq" callbacks. 2299 + * resume callback must also run via the "noirq" ops. 2300 + * 2301 + * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment 2302 + * earlier in this file before vmbus_pm. 2318 2303 */ 2304 + 2319 2305 static const struct dev_pm_ops vmbus_bus_pm = { 2320 - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume) 2306 + .suspend_noirq = NULL, 2307 + .resume_noirq = NULL, 2308 + .freeze_noirq = vmbus_bus_suspend, 2309 + .thaw_noirq = vmbus_bus_resume, 2310 + .poweroff_noirq = vmbus_bus_suspend, 2311 + .restore_noirq = vmbus_bus_resume 2321 2312 }; 2322 2313 2323 2314 static struct acpi_driver vmbus_acpi_driver = {
+2 -2
include/uapi/linux/hyperv.h
··· 119 119 120 120 struct hv_fcopy_hdr { 121 121 __u32 operation; 122 - uuid_le service_id0; /* currently unused */ 123 - uuid_le service_id1; /* currently unused */ 122 + __u8 service_id0[16]; /* currently unused */ 123 + __u8 service_id1[16]; /* currently unused */ 124 124 } __attribute__((packed)); 125 125 126 126 #define OVER_WRITE 0x1