Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753253AbdFGXgR (ORCPT ); Wed, 7 Jun 2017 19:36:17 -0400 Received: from wtarreau.pck.nerim.net ([62.212.114.60]:50680 "EHLO 1wt.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753202AbdFGXFD (ORCPT ); Wed, 7 Jun 2017 19:05:03 -0400 From: Willy Tarreau To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, linux@roeck-us.net Cc: Vitaly Kuznetsov , "K . Y . Srinivasan" , Sumit Semwal , Jiri Slaby , Willy Tarreau Subject: [PATCH 3.10 232/250] Drivers: hv: avoid vfree() on crash Date: Thu, 8 Jun 2017 01:00:18 +0200 Message-Id: <1496876436-32402-233-git-send-email-w@1wt.eu> X-Mailer: git-send-email 2.8.0.rc2.1.gbe9624a In-Reply-To: <1496876436-32402-1-git-send-email-w@1wt.eu> References: <1496876436-32402-1-git-send-email-w@1wt.eu> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2581 Lines: 87 From: Vitaly Kuznetsov 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 Signed-off-by: K. Y. Srinivasan Cc: Sumit Semwal Signed-off-by: Jiri Slaby Signed-off-by: Willy Tarreau --- 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 ae49237..b103955 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 12f2f9e..11d4e62 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 80754e2..3190a1f 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); } -- 2.8.0.rc2.1.gbe9624a