Skip to content

Commit 869997b

Browse files
committed
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
2 parents 6a8b55e + f081bbb commit 869997b

File tree

6 files changed

+51
-20
lines changed

6 files changed

+51
-20
lines changed

arch/x86/hyperv/hv_init.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu)
7373
struct page *pg;
7474

7575
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);
7778
if (unlikely(!pg))
7879
return -ENOMEM;
7980
*input_arg = page_address(pg);
@@ -254,6 +255,7 @@ static int __init hv_pci_init(void)
254255
static int hv_suspend(void)
255256
{
256257
union hv_x64_msr_hypercall_contents hypercall_msr;
258+
int ret;
257259

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

273-
return 0;
275+
ret = hv_cpu_die(0);
276+
return ret;
274277
}
275278

276279
static void hv_resume(void)
277280
{
278281
union hv_x64_msr_hypercall_contents hypercall_msr;
282+
int ret;
283+
284+
ret = hv_cpu_init(0);
285+
WARN_ON(ret);
279286

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

298+
/* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */
291299
static struct syscore_ops hv_syscore_ops = {
292300
.suspend = hv_suspend,
293301
.resume = hv_resume,

arch/x86/include/asm/mshyperv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)(
3535
rdmsrl(HV_X64_MSR_SINT0 + int_num, val)
3636
#define hv_set_synint_state(int_num, val) \
3737
wrmsrl(HV_X64_MSR_SINT0 + int_num, val)
38+
#define hv_recommend_using_aeoi() \
39+
(!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED))
3840

3941
#define hv_get_crash_ctl(val) \
4042
rdmsrl(HV_X64_MSR_CRASH_CTL, val)

drivers/hv/hv.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu)
184184

185185
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
186186
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();
192188
hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
193189

194190
/* Enable the global synic bit */

drivers/hv/hv_trace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request,
286286
__field(int, ret)
287287
),
288288
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);
291291
__entry->ret = ret;
292292
),
293293
TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, "

drivers/hv/vmbus_drv.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device)
978978

979979
return drv->resume(dev);
980980
}
981+
#else
982+
#define vmbus_suspend NULL
983+
#define vmbus_resume NULL
981984
#endif /* CONFIG_PM_SLEEP */
982985

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

9991002
/*
1000-
* Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
1001-
* SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm.
1003+
* Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm.
1004+
*
1005+
* suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we
1006+
* shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there
1007+
* is no way to wake up a Generation-2 VM.
1008+
*
1009+
* The other 4 ops are for hibernation.
10021010
*/
1011+
10031012
static const struct dev_pm_ops vmbus_pm = {
1004-
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume)
1013+
.suspend_noirq = NULL,
1014+
.resume_noirq = NULL,
1015+
.freeze_noirq = vmbus_suspend,
1016+
.thaw_noirq = vmbus_resume,
1017+
.poweroff_noirq = vmbus_suspend,
1018+
.restore_noirq = vmbus_resume,
10051019
};
10061020

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

22822296
return 0;
22832297
}
2298+
#else
2299+
#define vmbus_bus_suspend NULL
2300+
#define vmbus_bus_resume NULL
22842301
#endif /* CONFIG_PM_SLEEP */
22852302

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

22932310
/*
2294-
* Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
2295-
* SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the
2296-
* "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the
2297-
* pci "noirq" restore callback runs before "non-noirq" callbacks (see
2311+
* Note: we must use the "no_irq" ops, otherwise hibernation can not work with
2312+
* PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in
2313+
* the resume path, the pci "noirq" restore op runs before "non-noirq" op (see
22982314
* resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() ->
22992315
* dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's
2300-
* resume callback must also run via the "noirq" callbacks.
2316+
* resume callback must also run via the "noirq" ops.
2317+
*
2318+
* Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment
2319+
* earlier in this file before vmbus_pm.
23012320
*/
2321+
23022322
static const struct dev_pm_ops vmbus_bus_pm = {
2303-
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume)
2323+
.suspend_noirq = NULL,
2324+
.resume_noirq = NULL,
2325+
.freeze_noirq = vmbus_bus_suspend,
2326+
.thaw_noirq = vmbus_bus_resume,
2327+
.poweroff_noirq = vmbus_bus_suspend,
2328+
.restore_noirq = vmbus_bus_resume
23042329
};
23052330

23062331
static struct acpi_driver vmbus_acpi_driver = {

include/uapi/linux/hyperv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ enum hv_fcopy_op {
119119

120120
struct hv_fcopy_hdr {
121121
__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 */
124124
} __attribute__((packed));
125125

126126
#define OVER_WRITE 0x1

0 commit comments

Comments
 (0)