lkml.org 
[lkml]   [2017]   [Apr]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 3.12 048/142] Drivers: hv: avoid vfree() on crash
Date
From: Vitaly Kuznetsov <vkuznets@redhat.com>

3.12-stable review patch. If anyone has any objections, please let me know.

===============

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>
---
drivers/hv/hv.c | 5 +++--
drivers/hv/hyperv_vmbus.h | 2 +-
drivers/hv/vmbus_drv.c | 4 ++--
3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 9c0d458ec232..24d3ceec9d0a 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 d84918fe19ab..862004c15c41 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 d13f3dda6769..37f697fcf477 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -622,7 +622,7 @@ err_unregister:
bus_unregister(&hv_bus);

err_cleanup:
- hv_cleanup();
+ hv_cleanup(false);

return ret;
}
@@ -845,7 +845,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);
}
--
2.12.2
\
 
 \ /
  Last update: 2017-04-10 18:03    [W:0.416 / U:5.268 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site