Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp3567487imm; Mon, 1 Oct 2018 00:17:27 -0700 (PDT) X-Google-Smtp-Source: ACcGV61JBSdE9d2/mjfAqdzWOzBqogHuw70uid8p5tnm43ZitFpAM/uHeek92wYMtJ1YiInpid+1 X-Received: by 2002:a17:902:2:: with SMTP id 2-v6mr10591571pla.178.1538378247450; Mon, 01 Oct 2018 00:17:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538378247; cv=none; d=google.com; s=arc-20160816; b=roYBmxChPRjanUlfaOuaswHHzW/eK6joDopm8uztpbFJMTbPKZknwefca1x47U7cWm 3DdR0VpHVyhNQ377kjf7fMqGr9WcnlmsSmeJyeZt3SVsVqv/2AODKmS//ZaBfNamcVa/ GUgBW2D/bZ/PaP3Gk/ePS2sJlq69JgxqMDL4PZMWMGeLbsaOrX0NRFPDO0sGhtLEybyd 8UVLEGlIDhW8bYueFze10P2GWhAZCRWABkvqaqwGCuxU9RpRMg2eeafPXTrULVF/8GJ5 OGfKc60tmF4UTm5QixvC2MdqI79pA4H2pFVlnoCkp8Un4P6KmU4of6NJmHBg1M0qfDiO E9jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=z2+p5bcZdFctZ2E69RJRP98zJimh2nUCHNXTCZOZ/JE=; b=F8RS4ySHuN3vjPZ4FnVEk+pqOK0Z6HKq8iTaRzgh31XVZII4JFSb19PT4ZHd6eC8T8 /gKe0aoNspLCTTETABL1ZYDMciqJ71w+aHDKKEQ7BCQqJLCd51NeUduA27X48CPNozIZ 9SKgUPO0riF5iML6V0Mt3OwFCaGM3QS7i8gQP6gyBr90pKX0S1Lseivwk0Onon+Oqnsq HctTYiOAJKVClqoEhetq64le65fRORjiv1yGVjttbguWMHHnRGjqwVBdy3j9pAJTNSQ/ UcRGOeRydYH4mdfTyqXKrKI+EdSeLOrCGyTHS7PjNpvylehM38c4XCUNdGM/17+1cp2B NUvg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x85-v6si8279265pfk.54.2018.10.01.00.17.13; Mon, 01 Oct 2018 00:17:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728913AbeJANxO (ORCPT + 99 others); Mon, 1 Oct 2018 09:53:14 -0400 Received: from mx2.suse.de ([195.135.220.15]:56370 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728785AbeJANxN (ORCPT ); Mon, 1 Oct 2018 09:53:13 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id C0DB2AE15; Mon, 1 Oct 2018 07:16:53 +0000 (UTC) From: Juergen Gross To: linux-kernel@vger.kernel.org, xen-devel@lists.xenproject.org, x86@kernel.org Cc: boris.ostrovsky@oracle.com, hpa@zytor.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, Juergen Gross , stable@vger.kernel.org, Waiman.Long@hp.com, peterz@infradead.org Subject: [PATCH 2/2] xen: make xen_qlock_wait() nestable Date: Mon, 1 Oct 2018 09:16:41 +0200 Message-Id: <20181001071641.19282-3-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20181001071641.19282-1-jgross@suse.com> References: <20181001071641.19282-1-jgross@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org xen_qlock_wait() isn't safe for nested calls due to interrupts. A call of xen_qlock_kick() might be ignored in case a deeper nesting level was active right before the call of xen_poll_irq(): CPU 1: CPU 2: spin_lock(lock1) spin_lock(lock1) -> xen_qlock_wait() -> xen_clear_irq_pending() Interrupt happens spin_unlock(lock1) -> xen_qlock_kick(CPU 2) spin_lock_irqsave(lock2) spin_lock_irqsave(lock2) -> xen_qlock_wait() -> xen_clear_irq_pending() clears kick for lock1 -> xen_poll_irq() spin_unlock_irq_restore(lock2) -> xen_qlock_kick(CPU 2) wakes up spin_unlock_irq_restore(lock2) IRET resumes in xen_qlock_wait() -> xen_poll_irq() never wakes up The solution is to disable interrupts in xen_qlock_wait() and not to poll for the irq in case xen_qlock_wait() is called in nmi context. Cc: stable@vger.kernel.org Cc: Waiman.Long@hp.com Cc: peterz@infradead.org Signed-off-by: Juergen Gross --- arch/x86/xen/spinlock.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index cd210a4ba7b1..e8d880e98057 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -39,29 +39,25 @@ static void xen_qlock_kick(int cpu) */ static void xen_qlock_wait(u8 *byte, u8 val) { + unsigned long flags; int irq = __this_cpu_read(lock_kicker_irq); /* If kicker interrupts not initialized yet, just spin */ - if (irq == -1) + if (irq == -1 || in_nmi()) return; - /* If irq pending already clear it and return. */ + /* Guard against reentry. */ + local_irq_save(flags); + + /* If irq pending already clear it. */ if (xen_test_irq_pending(irq)) { xen_clear_irq_pending(irq); - return; + } else if (READ_ONCE(*byte) == val) { + /* Block until irq becomes pending (or a spurious wakeup) */ + xen_poll_irq(irq); } - if (READ_ONCE(*byte) != val) - return; - - /* - * If an interrupt happens here, it will leave the wakeup irq - * pending, which will cause xen_poll_irq() to return - * immediately. - */ - - /* Block until irq becomes pending (or perhaps a spurious wakeup) */ - xen_poll_irq(irq); + local_irq_restore(flags); } static irqreturn_t dummy_handler(int irq, void *dev_id) -- 2.16.4