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.
A consideration:
From: Vitaly Kuznetsov <email address hidden>
When we crash from NMI context (e.g. after NMI injection from host when unknown_ nmi_panic= 1' is set) we hit
'sysctl -w kernel.
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.
Signed-off-by: Vitaly Kuznetsov <email address hidden> hv/hyperv_ vmbus.h | 2 +- hv/vmbus_ drv.c | 8 ++++----
Signed-off-by: K. Y. Srinivasan <email address hidden>
---
drivers/hv/hv.c | 8 +++++---
drivers/
drivers/
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c msr_hypercall_ contents hypercall_msr;
index a1c086b..60dbd6c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -278,7 +278,7 @@ cleanup:
*
* This routine is called normally during driver unloading or exiting.
*/
-void hv_cleanup(void)
+void hv_cleanup(bool crash)
{
union hv_x64_
@@ -288,7 +288,8 @@ void hv_cleanup(void) hypercall_ page) {
hypercall_ msr.as_ uint64 = 0;
wrmsrl( HV_X64_ MSR_HYPERCALL, hypercall_ msr.as_ uint64) ; context. hypercall_ page); context. hypercall_ page);
hv_context. hypercall_ page = NULL;
if (hv_context.
- vfree(hv_
+ if (!crash)
+ vfree(hv_
}
@@ -308,7 +309,8 @@ void hv_cleanup(void)
- vfree(hv_
+ if (!crash)
+ vfree(hv_
}
#endif
diff --git a/drivers/
index 718b5c7..dfa9fac 100644
--- a/drivers/
+++ b/drivers/
@@ -495,7 +495,7 @@ struct hv_ring_
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, hv/vmbus_ drv.c b/drivers/ hv/vmbus_ drv.c hv/vmbus_ drv.c hv/vmbus_ drv.c
bus_unregister (&hv_bus) ;
diff --git a/drivers/
index 952f20f..d11690e 100644
--- a/drivers/
+++ b/drivers/
@@ -871,7 +871,7 @@ err_alloc:
err_cleanup:
- hv_cleanup();
+ hv_cleanup(false);
return ret; handler( void)
vmbus_ initiate_ unload( false);
for_each_ online_ cpu(cpu)
smp_call_ function_ single( cpu, hv_synic_cleanup, NULL, 1);
}
@@ -1323,7 +1323,7 @@ static void hv_kexec_
- hv_cleanup();
+ hv_cleanup(false);
};
static void hv_crash_ handler( struct pt_regs *regs) handler( struct pt_regs *regs)
hv_synic_ cleanup( NULL);
@@ -1335,7 +1335,7 @@ static void hv_crash_
* for kdump.
*/
- hv_cleanup();
+ hv_cleanup(true);
};
static int __init hv_acpi_init(void)
&hyperv_ panic_block) ;
bus_unregister (&hv_bus) ;
for_each_ online_ cpu(cpu) {
tasklet_ kill(hv_ context. event_dpc[ cpu]);
smp_call_ function_ single( cpu, hv_synic_cleanup, NULL, 1);
@@ -1395,7 +1395,7 @@ static void __exit vmbus_exit(void)
}
- hv_cleanup();
+ hv_cleanup(false);
--
1.7.4.1