diff options
author | Vitaly Kuznetsov <vkuznets@redhat.com> | 2017-01-28 12:37:14 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-31 11:05:58 +0100 |
commit | d6f3609d2b4c6d0eec01f398cb685e50da3e6013 (patch) | |
tree | e4810aaa4fee18f5876d13c6a0376ed72685fc6d | |
parent | 17244623a4c0f68d3f02c9c74d9b6ae259425826 (diff) | |
download | linux-stable-d6f3609d2b4c6d0eec01f398cb685e50da3e6013.tar.gz linux-stable-d6f3609d2b4c6d0eec01f398cb685e50da3e6013.tar.bz2 linux-stable-d6f3609d2b4c6d0eec01f398cb685e50da3e6013.zip |
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.c | 16 | ||||
-rw-r--r-- | arch/x86/include/asm/mshyperv.h | 1 | ||||
-rw-r--r-- | drivers/hv/hv.c | 10 | ||||
-rw-r--r-- | drivers/hv/hyperv_vmbus.h | 2 | ||||
-rw-r--r-- | drivers/hv/vmbus_drv.c | 10 |
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]); } |