Linux-HyperV Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v5 0/3] Enhance Hyper-V for hibernation
@ 2019-09-05 22:47 Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 1/3] x86/hyper-v: Suspend/resume the hypercall page " Dexuan Cui
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Dexuan Cui @ 2019-09-05 22:47 UTC (permalink / raw)
  To: arnd, bp, daniel.lezcano, Haiyang Zhang, hpa, KY Srinivasan,
	linux-hyperv, linux-kernel, mingo, sashal, Stephen Hemminger,
	tglx, x86, Michael Kelley, Sasha Levin
  Cc: linux-arch, Dexuan Cui

This patchset (consisting of 3 patches) was part of the v4 patchset (consisting
of 12 patches):
    https://lkml.org/lkml/2019/9/2/894

I realized these 3 patches must go through the tip.git tree, because I have
to rebase 2 of the 3 patches due to recent changes from others in the tip
tree.

All the 3 patches are now rebased to the tip tree's timers/core branch:
https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/log/?h=timers/core
, and all the 3 patches have Michael Kelley's Signed-off-by's.

Please review.

Thanks!
Dexuan

Dexuan Cui (3):
  x86/hyper-v: Suspend/resume the hypercall page for hibernation
  x86/hyper-v: Implement hv_is_hibernation_supported()
  clocksource/drivers: Suspend/resume Hyper-V clocksource for
    hibernation

 arch/x86/hyperv/hv_init.c          | 40 ++++++++++++++++++++++++++++++++++++++
 drivers/clocksource/hyperv_timer.c | 25 ++++++++++++++++++++++++
 include/asm-generic/mshyperv.h     |  2 ++
 3 files changed, 67 insertions(+)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v5 1/3] x86/hyper-v: Suspend/resume the hypercall page for hibernation
  2019-09-05 22:47 [PATCH v5 0/3] Enhance Hyper-V for hibernation Dexuan Cui
@ 2019-09-05 22:47 ` " Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 2/3] x86/hyper-v: Implement hv_is_hibernation_supported() Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 3/3] clocksource/drivers: Suspend/resume Hyper-V clocksource for hibernation Dexuan Cui
  2 siblings, 0 replies; 4+ messages in thread
From: Dexuan Cui @ 2019-09-05 22:47 UTC (permalink / raw)
  To: arnd, bp, daniel.lezcano, Haiyang Zhang, hpa, KY Srinivasan,
	linux-hyperv, linux-kernel, mingo, sashal, Stephen Hemminger,
	tglx, x86, Michael Kelley, Sasha Levin
  Cc: linux-arch, Dexuan Cui

This is needed for hibernation, e.g. when we resume the old kernel, we need
to disable the "current" kernel's hypercall page and then resume the old
kernel's.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/x86/hyperv/hv_init.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 866dfb3..037b0f3 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -20,6 +20,7 @@
 #include <linux/hyperv.h>
 #include <linux/slab.h>
 #include <linux/cpuhotplug.h>
+#include <linux/syscore_ops.h>
 #include <clocksource/hyperv_timer.h>
 
 void *hv_hypercall_pg;
@@ -223,6 +224,34 @@ static int __init hv_pci_init(void)
 	return 1;
 }
 
+static int hv_suspend(void)
+{
+	union hv_x64_msr_hypercall_contents hypercall_msr;
+
+	/* Reset the hypercall page */
+	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+	hypercall_msr.enable = 0;
+	wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
+	return 0;
+}
+
+static void hv_resume(void)
+{
+	union hv_x64_msr_hypercall_contents hypercall_msr;
+
+	/* Re-enable the hypercall page */
+	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+	hypercall_msr.enable = 1;
+	hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
+	wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+}
+
+static struct syscore_ops hv_syscore_ops = {
+	.suspend = hv_suspend,
+	.resume = hv_resume,
+};
+
 /*
  * This function is to be invoked early in the boot sequence after the
  * hypervisor has been detected.
@@ -301,6 +330,8 @@ void __init hyperv_init(void)
 
 	x86_init.pci.arch_init = hv_pci_init;
 
+	register_syscore_ops(&hv_syscore_ops);
+
 	return;
 
 remove_cpuhp_state:
@@ -320,6 +351,8 @@ void hyperv_cleanup(void)
 {
 	union hv_x64_msr_hypercall_contents hypercall_msr;
 
+	unregister_syscore_ops(&hv_syscore_ops);
+
 	/* Reset our OS id */
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v5 2/3] x86/hyper-v: Implement hv_is_hibernation_supported()
  2019-09-05 22:47 [PATCH v5 0/3] Enhance Hyper-V for hibernation Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 1/3] x86/hyper-v: Suspend/resume the hypercall page " Dexuan Cui
@ 2019-09-05 22:47 ` Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 3/3] clocksource/drivers: Suspend/resume Hyper-V clocksource for hibernation Dexuan Cui
  2 siblings, 0 replies; 4+ messages in thread
From: Dexuan Cui @ 2019-09-05 22:47 UTC (permalink / raw)
  To: arnd, bp, daniel.lezcano, Haiyang Zhang, hpa, KY Srinivasan,
	linux-hyperv, linux-kernel, mingo, sashal, Stephen Hemminger,
	tglx, x86, Michael Kelley, Sasha Levin
  Cc: linux-arch, Dexuan Cui

The API will be used by the hv_balloon and hv_vmbus drivers.

Balloon up/down and hot-add of memory must not be active if the user
wants the Linux VM to support hibernation, because they are incompatible
with hibernation according to Hyper-V team, e.g. upon suspend the
balloon VSP doesn't save any info about the ballooned-out pages (if any);
so, after Linux resumes, Linux balloon VSC expects that the VSP will
return the pages if Linux is under memory pressure, but the VSP will
never do that, since the VSP thinks it never stole the pages from the VM.

So, if the user wants Linux VM to support hibernation, Linux must forbid
balloon up/down and hot-add, and the only functionality of the balloon VSC
driver is reporting the VM's memory pressure to the host.

Ideally, when Linux detects that the user wants it to support hibernation,
the balloon VSC should tell the VSP that it does not support ballooning
and hot-add. However, the current version of the VSP requires the VSC
should support these capabilities, otherwise the capability negotiation
fails and the VSC can not load at all, so with the later changes to the
VSC driver, Linux VM still reports to the VSP that the VSC supports these
capabilities, but the VSC ignores the VSP's requests of balloon up/down
and hot add, and reports an error to the VSP, when applicable. BTW, in
the future the balloon VSP driver will allow the VSC to not support the
capabilities of balloon up/down and hot add.

The ACPI S4 state is not a must for hibernation to work, because Linux is
able to hibernate as long as the system can shut down. However in practice
we decide to artificially use the presence of the virtual ACPI S4 state as
an indicator of the user's intent of using hibernation, because Linux VM
must find a way to know if the user wants to use the hibernation feature
or not.

By default, Hyper-V does not enable the virtual ACPI S4 state; on recent
Hyper-V hosts (e.g. RS5, 19H1), the administrator is able to enable the
state for a VM by WMI commands.

Once all the vmbus and VSC patches for the hibernation feature are
accepted, an extra patch will be submitted to forbid hibernation if the
virtual ACPI S4 state is absent, i.e. hv_is_hibernation_supported() is
false.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/x86/hyperv/hv_init.c      | 7 +++++++
 include/asm-generic/mshyperv.h | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 037b0f3..9a26071 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -7,6 +7,7 @@
  * Author : K. Y. Srinivasan <kys@microsoft.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/types.h>
 #include <asm/apic.h>
@@ -450,3 +451,9 @@ bool hv_is_hyperv_initialized(void)
 	return hypercall_msr.enable;
 }
 EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
+
+bool hv_is_hibernation_supported(void)
+{
+	return acpi_sleep_state_supported(ACPI_STATE_S4);
+}
+EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 18d8e2d..b3f1082 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -166,10 +166,12 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 void hyperv_report_panic(struct pt_regs *regs, long err);
 void hyperv_report_panic_msg(phys_addr_t pa, size_t size);
 bool hv_is_hyperv_initialized(void);
+bool hv_is_hibernation_supported(void);
 void hyperv_cleanup(void);
 void hv_setup_sched_clock(void *sched_clock);
 #else /* CONFIG_HYPERV */
 static inline bool hv_is_hyperv_initialized(void) { return false; }
+static inline bool hv_is_hibernation_supported(void) { return false; }
 static inline void hyperv_cleanup(void) {}
 #endif /* CONFIG_HYPERV */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v5 3/3] clocksource/drivers: Suspend/resume Hyper-V clocksource for hibernation
  2019-09-05 22:47 [PATCH v5 0/3] Enhance Hyper-V for hibernation Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 1/3] x86/hyper-v: Suspend/resume the hypercall page " Dexuan Cui
  2019-09-05 22:47 ` [PATCH v5 2/3] x86/hyper-v: Implement hv_is_hibernation_supported() Dexuan Cui
@ 2019-09-05 22:47 ` Dexuan Cui
  2 siblings, 0 replies; 4+ messages in thread
From: Dexuan Cui @ 2019-09-05 22:47 UTC (permalink / raw)
  To: arnd, bp, daniel.lezcano, Haiyang Zhang, hpa, KY Srinivasan,
	linux-hyperv, linux-kernel, mingo, sashal, Stephen Hemminger,
	tglx, x86, Michael Kelley, Sasha Levin
  Cc: linux-arch, Dexuan Cui

This is needed for hibernation, e.g. when we resume the old kernel, we need
to disable the "current" kernel's TSC page and then resume the old kernel's.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
---
 drivers/clocksource/hyperv_timer.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 726a65e..07f4747 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -237,12 +237,37 @@ static u64 read_hv_sched_clock_tsc(void)
 	return read_hv_clock_tsc(NULL) - hv_sched_clock_offset;
 }
 
+static void suspend_hv_clock_tsc(struct clocksource *arg)
+{
+	u64 tsc_msr;
+
+	/* Disable the TSC page */
+	hv_get_reference_tsc(tsc_msr);
+	tsc_msr &= ~BIT_ULL(0);
+	hv_set_reference_tsc(tsc_msr);
+}
+
+
+static void resume_hv_clock_tsc(struct clocksource *arg)
+{
+	phys_addr_t phys_addr = virt_to_phys(&tsc_pg);
+	u64 tsc_msr;
+
+	/* Re-enable the TSC page */
+	hv_get_reference_tsc(tsc_msr);
+	tsc_msr &= GENMASK_ULL(11, 0);
+	tsc_msr |= BIT_ULL(0) | (u64)phys_addr;
+	hv_set_reference_tsc(tsc_msr);
+}
+
 static struct clocksource hyperv_cs_tsc = {
 	.name	= "hyperv_clocksource_tsc_page",
 	.rating	= 400,
 	.read	= read_hv_clock_tsc,
 	.mask	= CLOCKSOURCE_MASK(64),
 	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+	.suspend= suspend_hv_clock_tsc,
+	.resume	= resume_hv_clock_tsc,
 };
 
 static u64 notrace read_hv_clock_msr(struct clocksource *arg)
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-05 22:47 [PATCH v5 0/3] Enhance Hyper-V for hibernation Dexuan Cui
2019-09-05 22:47 ` [PATCH v5 1/3] x86/hyper-v: Suspend/resume the hypercall page " Dexuan Cui
2019-09-05 22:47 ` [PATCH v5 2/3] x86/hyper-v: Implement hv_is_hibernation_supported() Dexuan Cui
2019-09-05 22:47 ` [PATCH v5 3/3] clocksource/drivers: Suspend/resume Hyper-V clocksource for hibernation Dexuan Cui

Linux-HyperV Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-hyperv/0 linux-hyperv/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-hyperv linux-hyperv/ https://lore.kernel.org/linux-hyperv \
		linux-hyperv@vger.kernel.org linux-hyperv@archiver.kernel.org
	public-inbox-index linux-hyperv


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-hyperv


AGPL code for this site: git clone https://public-inbox.org/ public-inbox