From: "K. Y. Srinivasan" <kys@microsoft.com>
To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com,
vkuznets@redhat.com, jasowang@redhat.com
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Subject: [PATCH V2 04/10] Drivers: hv: vmbus: add special kexec handler
Date: Thu, 4 Jun 2015 16:26:10 -0700 [thread overview]
Message-ID: <1433460376-9387-4-git-send-email-kys@microsoft.com> (raw)
In-Reply-To: <1433460376-9387-1-git-send-email-kys@microsoft.com>
From: Vitaly Kuznetsov <vkuznets@redhat.com>
When general-purpose kexec (not kdump) is being performed in Hyper-V guest
the newly booted kernel fails with an MCE error coming from the host. It
is the same error which was fixed in the "Drivers: hv: vmbus: Implement
the protocol for tearing down vmbus state" commit - monitor pages remain
special and when they're being written to (as the new kernel doesn't know
these pages are special) bad things happen. We need to perform some
minimalistic cleanup before booting a new kernel on kexec. To do so we
need to register a special machine_ops.shutdown handler to be executed
before the native_machine_shutdown(). Registering a shutdown notification
handler via the register_reboot_notifier() call is not sufficient as it
happens to early for our purposes. machine_ops is not being exported to
modules (and I don't think we want to export it) so let's do this in
mshyperv.c
The minimalistic cleanup consists of cleaning up clockevents, synic MSRs,
guest os id MSR, and hypercall MSR.
Kdump doesn't require all this stuff as it lives in a separate memory
space.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
arch/x86/include/asm/mshyperv.h | 2 ++
arch/x86/kernel/cpu/mshyperv.c | 30 ++++++++++++++++++++++++++++++
drivers/hv/vmbus_drv.c | 14 ++++++++++++++
3 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index c163215..d3db910 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -20,4 +20,6 @@ void hyperv_vector_handler(struct pt_regs *regs);
void hv_setup_vmbus_irq(void (*handler)(void));
void hv_remove_vmbus_irq(void);
+void hv_setup_kexec_handler(void (*handler)(void));
+void hv_remove_kexec_handler(void);
#endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 939155f..efc20a0 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -18,6 +18,9 @@
#include <linux/efi.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#ifdef CONFIG_KEXEC
+#include <linux/kexec.h>
+#endif
#include <asm/processor.h>
#include <asm/hypervisor.h>
#include <asm/hyperv.h>
@@ -28,12 +31,14 @@
#include <asm/i8259.h>
#include <asm/apic.h>
#include <asm/timer.h>
+#include <asm/reboot.h>
struct ms_hyperv_info ms_hyperv;
EXPORT_SYMBOL_GPL(ms_hyperv);
#if IS_ENABLED(CONFIG_HYPERV)
static void (*vmbus_handler)(void);
+static void (*hv_kexec_handler)(void);
void hyperv_vector_handler(struct pt_regs *regs)
{
@@ -69,6 +74,28 @@ void hv_remove_vmbus_irq(void)
}
EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
+
+void hv_setup_kexec_handler(void (*handler)(void))
+{
+ hv_kexec_handler = handler;
+}
+EXPORT_SYMBOL_GPL(hv_setup_kexec_handler);
+
+void hv_remove_kexec_handler(void)
+{
+ /* We have no way to deallocate the interrupt gate */
+ hv_kexec_handler = NULL;
+}
+EXPORT_SYMBOL_GPL(hv_remove_kexec_handler);
+
+static void hv_machine_shutdown(void)
+{
+#ifdef CONFIG_KEXEC
+ if (kexec_in_progress && hv_kexec_handler)
+ hv_kexec_handler();
+#endif
+ native_machine_shutdown();
+}
#endif
static uint32_t __init ms_hyperv_platform(void)
@@ -143,6 +170,9 @@ static void __init ms_hyperv_init_platform(void)
no_timer_check = 1;
#endif
+#if IS_ENABLED(CONFIG_HYPERV)
+ machine_ops.shutdown = hv_machine_shutdown;
+#endif
}
const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 58a9344..7de3e10 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1029,6 +1029,17 @@ static struct acpi_driver vmbus_acpi_driver = {
},
};
+static void hv_kexec_handler(void)
+{
+ int cpu;
+
+ hv_synic_clockevents_cleanup();
+ vmbus_initiate_unload();
+ for_each_online_cpu(cpu)
+ smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
+ hv_cleanup();
+};
+
static int __init hv_acpi_init(void)
{
int ret, t;
@@ -1061,6 +1072,8 @@ static int __init hv_acpi_init(void)
if (ret)
goto cleanup;
+ hv_setup_kexec_handler(hv_kexec_handler);
+
return 0;
cleanup:
@@ -1073,6 +1086,7 @@ static void __exit vmbus_exit(void)
{
int cpu;
+ hv_remove_kexec_handler();
vmbus_connection.conn_state = DISCONNECTED;
hv_synic_clockevents_cleanup();
vmbus_disconnect();
--
1.7.4.1
next prev parent reply other threads:[~2015-06-04 22:05 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-04 23:25 [PATCH V2 00/10] Drivers: hv: vmbus: Enable kexec and other misc cleanup K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 01/10] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 02/10] Drivers: hv: vmbus: use cpu_hotplug_enable/disable K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 03/10] Drivers: hv: vmbus: remove hv_synic_free_cpu() call from hv_synic_cleanup() K. Y. Srinivasan
2015-06-04 23:26 ` K. Y. Srinivasan [this message]
2015-06-23 7:57 ` [PATCH V2 04/10] Drivers: hv: vmbus: add special kexec handler Olaf Hering
2015-06-23 16:28 ` Vitaly Kuznetsov
2015-06-24 3:11 ` Greg KH
2015-06-04 23:26 ` [PATCH V2 05/10] Drivers: hv: don't do hypercalls when hypercall_page is NULL K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 06/10] Drivers: hv: vmbus: use 'die' notification chain instead of 'panic' K. Y. Srinivasan
2015-06-25 11:37 ` Vitaly Kuznetsov
2015-06-04 23:26 ` [PATCH V2 07/10] Drivers: hv: kvp: check kzalloc return value K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 08/10] Drivers: hv: fcopy: dynamically allocate smsg_out in fcopy_send_data() K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 09/10] Drivers: hv: balloon: Enable dynamic memory protocol negotiation with Windows 10 hosts K. Y. Srinivasan
2015-06-04 23:26 ` [PATCH V2 10/10] Drivers: hv: vmbus: Permit sending of packets without payload K. Y. Srinivasan
2015-06-13 0:03 ` [PATCH V2 01/10] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1433460376-9387-4-git-send-email-kys@microsoft.com \
--to=kys@microsoft.com \
--cc=apw@canonical.com \
--cc=devel@linuxdriverproject.org \
--cc=gregkh@linuxfoundation.org \
--cc=jasowang@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=olaf@aepfle.de \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox