From patchwork Sat Mar 25 16:18:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Semwal X-Patchwork-Id: 95981 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp532119qgd; Sat, 25 Mar 2017 09:19:09 -0700 (PDT) X-Received: by 10.98.60.20 with SMTP id j20mr16230792pfa.128.1490458749730; Sat, 25 Mar 2017 09:19:09 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r3si6723034pli.62.2017.03.25.09.19.09; Sat, 25 Mar 2017 09:19:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751319AbdCYQTJ (ORCPT + 5 others); Sat, 25 Mar 2017 12:19:09 -0400 Received: from mail-pg0-f41.google.com ([74.125.83.41]:34967 "EHLO mail-pg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751309AbdCYQTJ (ORCPT ); Sat, 25 Mar 2017 12:19:09 -0400 Received: by mail-pg0-f41.google.com with SMTP id t143so9186332pgb.2 for ; Sat, 25 Mar 2017 09:19:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zltS76OQubzWAQGYvnRjWLd918OiUgM3BKWJ0VS3VUY=; b=FlYV6Hf9KxWWsy0Hkd6r4CvslEtkvogoAYBan8Dqi9pjZ5O2j5JZxBCd7MLFh9If0f t+4qsIbcCYiQaazBFIiIC0JKGg17qWUP8KYB7F95mPZoQ6ceM81iFy1KRFos0bGfSPDu anaNaeULCJhCppY6nOq573x6IZMw04Mj9jWwk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zltS76OQubzWAQGYvnRjWLd918OiUgM3BKWJ0VS3VUY=; b=Ctk0OBFzabQyO95ZSGFBqU1ias45OqwMqIkaAqgi7ZTe0izG3g21+4c+n6tTD0lzCJ E3q7QC1ed3CXFf0RdNh6pTz35bC1nazoCJVsAUuw8vUkqISjG2W4rgpVegyP1tmAigYw r7poiQzAP9l/j6hX4OiUK0YtPpz/sDsbAF3Y6wLe7rA808qvGzdHS6lp5AMnTyGl3SeC Rc6acplL1Q8KtYmVkTq9xT9uI+hUsuiMWwtr/7DW2dwpk3Dr295wrVN32ncuKwjLi8N9 d5U3JSgzBxM32wAkU9nMwbPEoR6ajHU+MyncaCfbm1BjZdfCKX+ehuPAaGQnejtRENUu 0PmQ== X-Gm-Message-State: AFeK/H0K/XmuFpZNxXI5mBxWno5Fky6bvFTRWfUy4YRcQqrwfBPcYhqLXEkRCRY625A23Gtk X-Received: by 10.84.217.216 with SMTP id d24mr18067614plj.80.1490458747160; Sat, 25 Mar 2017 09:19:07 -0700 (PDT) Received: from phantom.lan ([106.51.225.38]) by smtp.gmail.com with ESMTPSA id q194sm11469541pfq.43.2017.03.25.09.19.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 25 Mar 2017 09:19:06 -0700 (PDT) From: Sumit Semwal To: stable@vger.kernel.org Cc: Vitaly Kuznetsov , devel@linuxdriverproject.org, Haiyang Zhang , Thomas Gleixner , Ingo Molnar , Sasha Levin , Greg Kroah-Hartman , Sumit Semwal Subject: [PATCH for-4.4 04/19] x86/hyperv: Handle unknown NMIs on one CPU when unknown_nmi_panic Date: Sat, 25 Mar 2017 21:48:04 +0530 Message-Id: <1490458699-24484-5-git-send-email-sumit.semwal@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490458699-24484-1-git-send-email-sumit.semwal@linaro.org> References: <1490458699-24484-1-git-send-email-sumit.semwal@linaro.org> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Vitaly Kuznetsov [ Upstream commit 59107e2f48831daedc46973ce4988605ab066de3 ] There is a feature in Hyper-V ('Debug-VM --InjectNonMaskableInterrupt') which injects NMI to the guest. We may want to crash the guest and do kdump on this NMI by enabling unknown_nmi_panic. To make kdump succeed we need to allow the kdump kernel to re-establish VMBus connection so it will see VMBus devices (storage, network,..). To properly unload VMBus making it possible to start over during kdump we need to do the following: - Send an 'unload' message to the hypervisor. This can be done on any CPU so we do this the crashing CPU. - Receive the 'unload finished' reply message. WS2012R2 delivers this message to the CPU which was used to establish VMBus connection during module load and this CPU may differ from the CPU sending 'unload'. Receiving a VMBus message means the following: - There is a per-CPU slot in memory for one message. This slot can in theory be accessed by any CPU. - We get an interrupt on the CPU when a message was placed into the slot. - When we read the message we need to clear the slot and signal the fact to the hypervisor. In case there are more messages to this CPU pending the hypervisor will deliver the next message. The signaling is done by writing to an MSR so this can only be done on the appropriate CPU. To avoid doing cross-CPU work on crash we have vmbus_wait_for_unload() function which checks message slots for all CPUs in a loop waiting for the 'unload finished' messages. However, there is an issue which arises when these conditions are met: - We're crashing on a CPU which is different from the one which was used to initially contact the hypervisor. - The CPU which was used for the initial contact is blocked with interrupts disabled and there is a message pending in the message slot. In this case we won't be able to read the 'unload finished' message on the crashing CPU. This is reproducible when we receive unknown NMIs on all CPUs simultaneously: the first CPU entering panic() will proceed to crash and all other CPUs will stop themselves with interrupts disabled. The suggested solution is to handle unknown NMIs for Hyper-V guests on the first CPU which gets them only. This will allow us to rely on VMBus interrupt handler being able to receive the 'unload finish' message in case it is delivered to a different CPU. The issue is not reproducible on WS2016 as Debug-VM delivers NMI to the boot CPU only, WS2012R2 and earlier Hyper-V versions are affected. Signed-off-by: Vitaly Kuznetsov Acked-by: K. Y. Srinivasan Cc: devel@linuxdriverproject.org Cc: Haiyang Zhang Link: http://lkml.kernel.org/r/20161202100720.28121-1-vkuznets@redhat.com Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sumit Semwal --- arch/x86/kernel/cpu/mshyperv.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) -- 2.7.4 diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index cfc4a96..83b5f7a 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -30,6 +30,7 @@ #include #include #include +#include struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); @@ -157,6 +158,26 @@ static unsigned char hv_get_nmi_reason(void) return 0; } +#ifdef CONFIG_X86_LOCAL_APIC +/* + * Prior to WS2016 Debug-VM sends NMIs to all CPUs which makes + * it dificult to process CHANNELMSG_UNLOAD in case of crash. Handle + * unknown NMI on the first CPU which gets it. + */ +static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs) +{ + static atomic_t nmi_cpu = ATOMIC_INIT(-1); + + if (!unknown_nmi_panic) + return NMI_DONE; + + if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1) + return NMI_HANDLED; + + return NMI_DONE; +} +#endif + static void __init ms_hyperv_init_platform(void) { /* @@ -182,6 +203,9 @@ static void __init ms_hyperv_init_platform(void) printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n", lapic_timer_frequency); } + + register_nmi_handler(NMI_UNKNOWN, hv_nmi_unknown, NMI_FLAG_FIRST, + "hv_nmi_unknown"); #endif if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)