Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp4175147pxb; Mon, 8 Feb 2021 09:38:06 -0800 (PST) X-Google-Smtp-Source: ABdhPJy+V6Vl4N4kVNyFQ8DG2IrPBsB1vTaTX2a764yK7qHJBRbJKOjLAYQMKqTmq7DcRGo7XGDT X-Received: by 2002:a2e:97d1:: with SMTP id m17mr4924067ljj.265.1612805886252; Mon, 08 Feb 2021 09:38:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612805886; cv=none; d=google.com; s=arc-20160816; b=LrNfoPoeCUaLBDtbWxTRhLCv3RA8O5KVsLHbtfA0gsd2d7QVoqoodKJ+2tg4tASSTU UQgXWZPRhN3ZIpNST+GDUPfKHQgCwoJPTXpuVq7PAw/L1Ei+/508bsmPxupuwAgZrF9s 2odB8ly5BNl+5ksnqh21FLwvnGGGJiQNyRaj1wMGC2o113cvnQ7o5pp7BRXGrgjCOeuH QOuWudK7iBW5m/tX6cKSgyYX0wOymXjVIvottkIxQI/fu0dVbwy2kP5uQRx7VPbYGHIc 4z45sazr2q+dFOZCYeMmwYgN1g4ZZrXhMYJPH5IB/UIvqySOWgTx1yWMRHOLIT3ZuqMU f5Hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=LzT0ECpvR44Kjpjqvq877PmwlcbNqEAK4NeLoKzKxDI=; b=DODoOQ+0fAFG+6dndILAUESzVCBAOYignMb85jvyIdcJ/WV/fisBrlfb7a0nnGs1Ni o+8Ax86OGRrQbWHOre42x57FZhlOpbgLHdvqiA6kB0Tq7/fzXYohO5jKQxEdLn5ywogH g/4bvxRbdwUhDMi7DSfaAVnIU/+13PrVrSzIfFstqxkj6y51b4E8oMRYt2BhPM9NcwJj c7ualvple0azqDpMOibnpNHd++MbdeMg3+cEDEPMebmJjtL2D4wu8jMiO22Kj0Halji2 z5q/d+sCrbqEzoWoNONPHZg5At8dxitS5FgymuFi0RzsVw2OQQwV8gCZqSGIqmK/wHZs cJIA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=zJxQgWSk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r13si12816653edd.388.2021.02.08.09.37.42; Mon, 08 Feb 2021 09:38:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=zJxQgWSk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231654AbhBHRev (ORCPT + 99 others); Mon, 8 Feb 2021 12:34:51 -0500 Received: from mail.kernel.org ([198.145.29.99]:37878 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233044AbhBHP3q (ORCPT ); Mon, 8 Feb 2021 10:29:46 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id C371064F30; Mon, 8 Feb 2021 15:16:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1612797408; bh=nKEKEMpkRM4NdzLi1m2M6eBfvwlq3zXdHAI6at0QUSI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zJxQgWSk3s6atOgjGPiQFysABFoglYfS6DcoGkv1svwhEg3rIbV3j4GpkPtQ+6OdB AlEg0KqdazN+svkjktC9Vnz7JQNOgqmzz+Mq8F/347WTBZTKiFIbQ0LTEFVKq73Irh Bw/IYdrlyzZXoq9z3NRdAR+grBGlJb5NMnwC/3i0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Shameer Kolothum , Marc Zyngier , Thomas Gleixner Subject: [PATCH 5.10 067/120] genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set Date: Mon, 8 Feb 2021 16:00:54 +0100 Message-Id: <20210208145821.086356658@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210208145818.395353822@linuxfoundation.org> References: <20210208145818.395353822@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marc Zyngier commit 4c457e8cb75eda91906a4f89fc39bde3f9a43922 upstream. When MSI_FLAG_ACTIVATE_EARLY is set (which is the case for PCI), __msi_domain_alloc_irqs() performs the activation of the interrupt (which in the case of PCI results in the endpoint being programmed) as soon as the interrupt is allocated. But it appears that this is only done for the first vector, introducing an inconsistent behaviour for PCI Multi-MSI. Fix it by iterating over the number of vectors allocated to each MSI descriptor. This is easily achieved by introducing a new "for_each_msi_vector" iterator, together with a tiny bit of refactoring. Fixes: f3b0946d629c ("genirq/msi: Make sure PCI MSIs are activated early") Reported-by: Shameer Kolothum Signed-off-by: Marc Zyngier Signed-off-by: Thomas Gleixner Tested-by: Shameer Kolothum Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210123122759.1781359-1-maz@kernel.org Signed-off-by: Greg Kroah-Hartman --- include/linux/msi.h | 6 ++++++ kernel/irq/msi.c | 44 ++++++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -139,6 +139,12 @@ struct msi_desc { list_for_each_entry((desc), dev_to_msi_list((dev)), list) #define for_each_msi_entry_safe(desc, tmp, dev) \ list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list) +#define for_each_msi_vector(desc, __irq, dev) \ + for_each_msi_entry((desc), (dev)) \ + if ((desc)->irq) \ + for (__irq = (desc)->irq; \ + __irq < ((desc)->irq + (desc)->nvec_used); \ + __irq++) #ifdef CONFIG_IRQ_MSI_IOMMU static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -436,22 +436,22 @@ int __msi_domain_alloc_irqs(struct irq_d can_reserve = msi_check_reservation_mode(domain, info, dev); - for_each_msi_entry(desc, dev) { - virq = desc->irq; - if (desc->nvec_used == 1) - dev_dbg(dev, "irq %d for MSI\n", virq); - else + /* + * This flag is set by the PCI layer as we need to activate + * the MSI entries before the PCI layer enables MSI in the + * card. Otherwise the card latches a random msi message. + */ + if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY)) + goto skip_activate; + + for_each_msi_vector(desc, i, dev) { + if (desc->irq == i) { + virq = desc->irq; dev_dbg(dev, "irq [%d-%d] for MSI\n", virq, virq + desc->nvec_used - 1); - /* - * This flag is set by the PCI layer as we need to activate - * the MSI entries before the PCI layer enables MSI in the - * card. Otherwise the card latches a random msi message. - */ - if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY)) - continue; + } - irq_data = irq_domain_get_irq_data(domain, desc->irq); + irq_data = irq_domain_get_irq_data(domain, i); if (!can_reserve) { irqd_clr_can_reserve(irq_data); if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK) @@ -462,28 +462,24 @@ int __msi_domain_alloc_irqs(struct irq_d goto cleanup; } +skip_activate: /* * If these interrupts use reservation mode, clear the activated bit * so request_irq() will assign the final vector. */ if (can_reserve) { - for_each_msi_entry(desc, dev) { - irq_data = irq_domain_get_irq_data(domain, desc->irq); + for_each_msi_vector(desc, i, dev) { + irq_data = irq_domain_get_irq_data(domain, i); irqd_clr_activated(irq_data); } } return 0; cleanup: - for_each_msi_entry(desc, dev) { - struct irq_data *irqd; - - if (desc->irq == virq) - break; - - irqd = irq_domain_get_irq_data(domain, desc->irq); - if (irqd_is_activated(irqd)) - irq_domain_deactivate_irq(irqd); + for_each_msi_vector(desc, i, dev) { + irq_data = irq_domain_get_irq_data(domain, i); + if (irqd_is_activated(irq_data)) + irq_domain_deactivate_irq(irq_data); } msi_domain_free_irqs(domain, dev); return ret;