summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Kuznetsov <vkuznets@redhat.com>2017-01-28 22:37:14 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-31 13:05:58 +0300
commitd6f3609d2b4c6d0eec01f398cb685e50da3e6013 (patch)
treee4810aaa4fee18f5876d13c6a0376ed72685fc6d
parent17244623a4c0f68d3f02c9c74d9b6ae259425826 (diff)
downloadlinux-d6f3609d2b4c6d0eec01f398cb685e50da3e6013.tar.xz
Drivers: hv: restore hypervcall page cleanup before kexec
We need to cleanup the hypercall page before doing kexec/kdump or the new kernel may crash if it tries to use it. Reuse the now-empty hv_cleanup function renaming it to hyperv_cleanup and moving to the arch specific code. Fixes: 8730046c1498 ("Drivers: hv vmbus: Move Hypercall page setup out of common code") Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/hyperv/hv_init.c16
-rw-r--r--arch/x86/include/asm/mshyperv.h1
-rw-r--r--drivers/hv/hv.c10
-rw-r--r--drivers/hv/hyperv_vmbus.h2
-rw-r--r--drivers/hv/vmbus_drv.c10
5 files changed, 20 insertions, 19 deletions
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index d289bc29d282..d6b018b86c42 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -166,6 +166,22 @@ void hyperv_init(void)
}
/*
+ * This routine is called before kexec/kdump, it does the required cleanup.
+ */
+void hyperv_cleanup(void)
+{
+ union hv_x64_msr_hypercall_contents hypercall_msr;
+
+ /* Reset our OS id */
+ wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+
+ /* Reset the hypercall page */
+ hypercall_msr.as_uint64 = 0;
+ wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+}
+EXPORT_SYMBOL_GPL(hyperv_cleanup);
+
+/*
* hv_do_hypercall- Invoke the specified hypercall
*/
u64 hv_do_hypercall(u64 control, void *input, void *output)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 42505d1158d6..f8dc3700de67 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -171,5 +171,6 @@ void hv_remove_crash_handler(void);
void hyperv_init(void);
void hyperv_report_panic(struct pt_regs *regs);
bool hv_is_hypercall_page_setup(void);
+void hyperv_cleanup(void);
#endif
#endif
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 60594fa3250d..0f73237bed0a 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -71,16 +71,6 @@ int hv_init(void)
}
/*
- * hv_cleanup - Cleanup routine.
- *
- * This routine is called normally during driver unloading or exiting.
- */
-void hv_cleanup(bool crash)
-{
-
-}
-
-/*
* hv_post_message - Post a message using the hypervisor message IPC.
*
* This involves a hypercall.
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 2463ef93c1f6..86b56b677dc3 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -255,8 +255,6 @@ struct hv_ring_buffer_debug_info {
extern int hv_init(void);
-extern void hv_cleanup(bool crash);
-
extern int hv_post_message(union hv_connection_id connection_id,
enum hv_message_type message_type,
void *payload, size_t payload_size);
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 8e81346114d4..f8ebe13cf251 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -962,7 +962,7 @@ static int vmbus_bus_init(void)
ret = bus_register(&hv_bus);
if (ret)
- goto err_cleanup;
+ return ret;
hv_setup_vmbus_irq(vmbus_isr);
@@ -1004,9 +1004,6 @@ err_alloc:
bus_unregister(&hv_bus);
-err_cleanup:
- hv_cleanup(false);
-
return ret;
}
@@ -1462,7 +1459,7 @@ static void hv_kexec_handler(void)
/* Make sure conn_state is set as hv_synic_cleanup checks for it */
mb();
cpuhp_remove_state(hyperv_cpuhp_online);
- hv_cleanup(false);
+ hyperv_cleanup();
};
static void hv_crash_handler(struct pt_regs *regs)
@@ -1475,7 +1472,7 @@ static void hv_crash_handler(struct pt_regs *regs)
*/
vmbus_connection.conn_state = DISCONNECTED;
hv_synic_cleanup(smp_processor_id());
- hv_cleanup(true);
+ hyperv_cleanup();
};
static int __init hv_acpi_init(void)
@@ -1535,7 +1532,6 @@ static void __exit vmbus_exit(void)
&hyperv_panic_block);
}
bus_unregister(&hv_bus);
- hv_cleanup(false);
for_each_online_cpu(cpu) {
tasklet_kill(hv_context.event_dpc[cpu]);
}