From patchwork Wed Jul 13 16:18:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 9227955 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BDF0C6088F for ; Wed, 13 Jul 2016 16:21:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AFA7527FA2 for ; Wed, 13 Jul 2016 16:21:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A433327FA7; Wed, 13 Jul 2016 16:21:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 205C226E69 for ; Wed, 13 Jul 2016 16:21:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751284AbcGMQTL (ORCPT ); Wed, 13 Jul 2016 12:19:11 -0400 Received: from foss.arm.com ([217.140.101.70]:37769 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750883AbcGMQTK (ORCPT ); Wed, 13 Jul 2016 12:19:10 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3DDA02F; Wed, 13 Jul 2016 09:19:44 -0700 (PDT) Received: from approximate.cambridge.arm.com (approximate.cambridge.arm.com [10.1.209.129]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 816443F25F; Wed, 13 Jul 2016 09:18:38 -0700 (PDT) From: Marc Zyngier To: Bjorn Helgaas , Thomas Gleixner Cc: Bharat Kumar Gogada , , Subject: [PATCH] genirq/msi: Make sure PCI MSIs are activated early Date: Wed, 13 Jul 2016 17:18:33 +0100 Message-Id: <1468426713-31431-1-git-send-email-marc.zyngier@arm.com> X-Mailer: git-send-email 2.1.4 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Bharat Kumar Gogada reported issues with the generic MSI code, where the end-point ended up with garbage in its MSI configuration (both for the vector and the message). It turns out that the two MSI paths in the kernel are doing slightly different things: generic MSI: disable MSI -> allocate MSI -> enable MSI -> setup EP PCI MSI: disable MSI -> allocate MSI -> setup EP -> enable MSI and it turns out that end-points are allowed to latch the content of the MSI configuration registers as soon as MSIs are enabled. In Bharat's case, the end-point ends up using whatever was there already, which is not what you want. In order to make things converge, we introduce a new MSI domain flag (MSI_FLAG_ACTIVATE_EARLY) that is unconditionally set for PCI/MSI. When set, this flag forces the programming of the end-point as soon as the MSIs are allocated. A consequence of this is that we have an extra activate in irq_startup, but that should be without much consequence. Reported-by: Bharat Kumar Gogada Tested-by: Bharat Kumar Gogada Signed-off-by: Marc Zyngier Acked-by: Bjorn Helgaas --- drivers/pci/msi.c | 2 ++ include/linux/msi.h | 2 ++ kernel/irq/msi.c | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a080f44..565e2a4 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -1277,6 +1277,8 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) pci_msi_domain_update_chip_ops(info); + info->flags |= MSI_FLAG_ACTIVATE_EARLY; + domain = msi_create_irq_domain(fwnode, info, parent); if (!domain) return NULL; diff --git a/include/linux/msi.h b/include/linux/msi.h index 8b425c6..513b7c7 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -270,6 +270,8 @@ enum { MSI_FLAG_MULTI_PCI_MSI = (1 << 3), /* Support PCI MSIX interrupts */ MSI_FLAG_PCI_MSIX = (1 << 4), + /* Needs early activate, required for PCI */ + MSI_FLAG_ACTIVATE_EARLY = (1 << 5), }; int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask, diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 38e89ce..4ed2cca 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -361,6 +361,13 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, else dev_dbg(dev, "irq [%d-%d] for MSI\n", virq, virq + desc->nvec_used - 1); + + if (info->flags & MSI_FLAG_ACTIVATE_EARLY) { + struct irq_data *irq_data; + + irq_data = irq_domain_get_irq_data(domain, desc->irq); + irq_domain_activate_irq(irq_data); + } } return 0;