From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753181AbcFCW2G (ORCPT ); Fri, 3 Jun 2016 18:28:06 -0400 Received: from p3plsmtps2ded02.prod.phx3.secureserver.net ([208.109.80.59]:48981 "EHLO p3plsmtps2ded02.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753138AbcFCW2C (ORCPT ); Fri, 3 Jun 2016 18:28:02 -0400 x-originating-ip: 72.167.245.219 From: "K. Y. Srinivasan" To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, jasowang@redhat.com, leann.ogasawara@canonical.com Cc: "K. Y. Srinivasan" Subject: [PATCH 1/3] Drivers: hv: avoid vfree() on crash Date: Fri, 3 Jun 2016 17:09:22 -0700 Message-Id: <1464998964-24901-1-git-send-email-kys@microsoft.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1464998940-24860-1-git-send-email-kys@microsoft.com> References: <1464998940-24860-1-git-send-email-kys@microsoft.com> X-CMAE-Envelope: MS4wfNW9TYzQSF93PMkxoLy6TXv86/TrYDXhEq2gr121ehbshu2ttVAqUq15f9BnaLpfzJYuxlvq9hmf/Auta0JSnX26IkUFG/cZLQ6mDFXyt3yreYEM9hJM mEfF6B5VDPKoQUid+h5qj8KMrAioxjg+cQSC6xTE6B3YElPX5bj+Ap7gQlbf13lv0TBEsDXDjJrMqS1XqEFvmx7CF/sAwLVvsgul/zsXqtteB36aZe8hFk8o RqdCQC+P8no3fPxMt3pPKYdP/lGMlJTljrHDy/8lySJtEgNouSbWxJ2Z5Y/+r1WloM8VuOuXzfvQ3SkNjxnMuRCh0ZQmlHvfi/WPSNAz6GsCWdnyvdS0X1LJ MEcRPHX3d5r8VU0nwxxrQpCGhuu+LLvFnB5auT/987vQvU2MN4ihKkZqoQL2XImbvUEa8Ku0R+3eI7xVvIWXZgqMP4mwjw2nEVH5GyRvWW5BTy6nnBc= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vitaly Kuznetsov 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. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c | 8 +++++--- drivers/hv/hyperv_vmbus.h | 2 +- drivers/hv/vmbus_drv.c | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c 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_msr_hypercall_contents hypercall_msr; @@ -288,7 +288,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; } @@ -308,7 +309,8 @@ void hv_cleanup(void) hypercall_msr.as_uint64 = 0; wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64); - vfree(hv_context.tsc_page); + if (!crash) + vfree(hv_context.tsc_page); hv_context.tsc_page = NULL; } #endif diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 718b5c7..dfa9fac 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -495,7 +495,7 @@ struct hv_ring_buffer_debug_info { 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 952f20f..d11690e 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -871,7 +871,7 @@ err_alloc: bus_unregister(&hv_bus); err_cleanup: - hv_cleanup(); + hv_cleanup(false); return ret; } @@ -1323,7 +1323,7 @@ static void hv_kexec_handler(void) vmbus_initiate_unload(false); for_each_online_cpu(cpu) smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); - hv_cleanup(); + hv_cleanup(false); }; static void hv_crash_handler(struct pt_regs *regs) @@ -1335,7 +1335,7 @@ static void hv_crash_handler(struct pt_regs *regs) * for kdump. */ hv_synic_cleanup(NULL); - hv_cleanup(); + hv_cleanup(true); }; static int __init hv_acpi_init(void) @@ -1395,7 +1395,7 @@ static void __exit vmbus_exit(void) &hyperv_panic_block); } bus_unregister(&hv_bus); - hv_cleanup(); + hv_cleanup(false); for_each_online_cpu(cpu) { tasklet_kill(hv_context.event_dpc[cpu]); smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); -- 1.7.4.1