aboutsummaryrefslogtreecommitdiff
path: root/drivers/hv
diff options
context:
space:
mode:
authorVitaly Kuznetsov <vkuznets@redhat.com>2016-06-03 17:09:22 -0700
committerMoyster <oysterized@gmail.com>2017-06-17 16:10:27 +0200
commit81671f4d891831d6502dae4b280e34cdfe5abd29 (patch)
tree54a9e8f5852c094615b5b00147abe55042461240 /drivers/hv
parent9916ff18dbb21277e1dd7a661de77ae272f6abfd (diff)
Drivers: hv: avoid vfree() on crash
commit a9f61ca793becabdefab03b77568d6c6f8c1bc79 upstream. When we crash from NMI context (e.g. after NMI injection from host when 'sysctl -w kernel.unknown_nmi_panic=1' is set) we hit kernel BUG at mm/vmalloc.c:1530! as vfree() is denied. While the issue could be solved with in_nmi() check instead I opted for skipping vfree on all sorts of crashes to reduce the amount of work which can cause consequent crashes. We don't really need to free anything on crash. [js] no tsc and kexec in 3.12 yet Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Willy Tarreau <w@1wt.eu>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/hv.c5
-rw-r--r--drivers/hv/hyperv_vmbus.h2
-rw-r--r--drivers/hv/vmbus_drv.c4
3 files changed, 6 insertions, 5 deletions
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index ae4923756..b1039552b 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -193,7 +193,7 @@ cleanup:
*
* This routine is called normally during driver unloading or exiting.
*/
-void hv_cleanup(void)
+void hv_cleanup(bool crash)
{
union hv_x64_msr_hypercall_contents hypercall_msr;
@@ -203,7 +203,8 @@ void hv_cleanup(void)
if (hv_context.hypercall_page) {
hypercall_msr.as_uint64 = 0;
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
- vfree(hv_context.hypercall_page);
+ if (!crash)
+ vfree(hv_context.hypercall_page);
hv_context.hypercall_page = NULL;
}
}
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 12f2f9e98..11d4e6222 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -519,7 +519,7 @@ extern struct hv_context hv_context;
extern int hv_init(void);
-extern void hv_cleanup(void);
+extern void hv_cleanup(bool crash);
extern int hv_post_message(union hv_connection_id connection_id,
enum hv_message_type message_type,
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 80754e2d8..3190a1fc7 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -618,7 +618,7 @@ err_unregister:
bus_unregister(&hv_bus);
err_cleanup:
- hv_cleanup();
+ hv_cleanup(false);
return ret;
}
@@ -841,7 +841,7 @@ static void __exit vmbus_exit(void)
free_irq(irq, hv_acpi_dev);
vmbus_free_channels();
bus_unregister(&hv_bus);
- hv_cleanup();
+ hv_cleanup(false);
acpi_bus_unregister_driver(&vmbus_acpi_driver);
hv_cpu_hotplug_quirk(false);
}