From patchwork Tue Apr 16 10:51:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vidya Sagar X-Patchwork-Id: 10902693 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3B4A91390 for ; Tue, 16 Apr 2019 10:51:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1C152289C5 for ; Tue, 16 Apr 2019 10:51:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 10998289CA; Tue, 16 Apr 2019 10:51:54 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,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 96573289C7 for ; Tue, 16 Apr 2019 10:51:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727942AbfDPKvw (ORCPT ); Tue, 16 Apr 2019 06:51:52 -0400 Received: from hqemgate14.nvidia.com ([216.228.121.143]:1055 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726241AbfDPKvw (ORCPT ); Tue, 16 Apr 2019 06:51:52 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 16 Apr 2019 03:51:56 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Tue, 16 Apr 2019 03:51:51 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Tue, 16 Apr 2019 03:51:51 -0700 Received: from HQMAIL108.nvidia.com (172.18.146.13) by HQMAIL103.nvidia.com (172.20.187.11) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 16 Apr 2019 10:51:51 +0000 Received: from hqnvemgw01.nvidia.com (172.20.150.20) by HQMAIL108.nvidia.com (172.18.146.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 16 Apr 2019 10:51:51 +0000 Received: from vidyas-desktop.nvidia.com (Not Verified[10.24.37.38]) by hqnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Tue, 16 Apr 2019 03:51:50 -0700 From: Vidya Sagar To: , , , , , , CC: , , , , , , Subject: [PATCH V3] PCI: tegra: Use the DMA-API to get the MSI address Date: Tue, 16 Apr 2019 16:21:44 +0530 Message-ID: <20190416105144.29315-1-vidyas@nvidia.com> X-Mailer: git-send-email 2.17.1 X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1555411916; bh=oSkj/DQHILk3vHn4yW11cN2bpcEYHic/AJ8BlZAt92s=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: X-NVConfidentiality:MIME-Version:Content-Type; b=YtLY4kdrOihxCTu8vDG/rqqUmDwxJlmwEikCYd24ZDrKI7wTCDjRslnGm36UCurnG Rs+syMM5siG0ybQ93FXIdBDUqPgCu2MycHZjDijU7VqjCxSbqlsS+8cFG+xXy0kgBx 6nkw5YHG2LeCLifRGZoToP90XLZW7XsryqNrmiIqRy43T7hl3czua+SnjrH/6/hQKI w4MTsAbD3ZgIlc4vrej4ROMIXit8h0+RM+rD1VW4ls2pBX88PSrV6reb0gSjb2KhKh upxYkIFpfZ+6vfj9Ee+z4QXuXj3EFl3GLAF+XUXbKBHJ6DSEsdC/trUa23jsQLCiwT X41+mEFaDiQMA== 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 Since the upstream MSI memory writes are generated by downstream devices, it is logically correct to have MSI target memory coming from the DMA pool reserved for PCIe than from the general memory pool reserved for CPU access. This avoids PCIe DMA addresses coinciding with MSI target address thereby raising unwanted MSI interrupts. This patch also enforces to limit the MSI target address to 32-bits to make it work for PCIe endponits that support only 32-bit MSI target address and those endpoints that support 64-bit MSI target address anyway work with 32-bit MSI target address. Signed-off-by: Vidya Sagar Reviewed-by: Thierry Reding Acked-by: Thierry Reding Reviewed-by: Robin Murphy --- v3: * replaced dma_alloc_coherent(), dma_free_coherent() APIs with dma_alloc_attrs(), dma_free_attrs() APIs along with DMA_ATTR_NO_KERNEL_MAPPING flag to indicate that there is no need to create kernel mapping for it. v2: * changed 'phys' type to 'dma_addr_t' from 'u64' * added a comment on why DMA mask is set to 32-bit * replaced 'dma' with 'DMA' drivers/pci/controller/pci-tegra.c | 37 ++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index f4f53d092e00..464ba2538d52 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -231,9 +231,9 @@ struct tegra_msi { struct msi_controller chip; DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; - unsigned long pages; struct mutex lock; - u64 phys; + void *virt; + dma_addr_t phys; int irq; }; @@ -1536,7 +1536,7 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) err = platform_get_irq_byname(pdev, "msi"); if (err < 0) { dev_err(dev, "failed to get IRQ: %d\n", err); - goto err; + goto free_irq_domain; } msi->irq = err; @@ -1545,17 +1545,35 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) tegra_msi_irq_chip.name, pcie); if (err < 0) { dev_err(dev, "failed to request IRQ: %d\n", err); - goto err; + goto free_irq_domain; + } + + /* Though the PCIe controller can address >32-bit address space, to + * facilitate endpoints that support only 32-bit MSI target address, + * the mask is set to 32-bit to make sure that MSI target address is + * always a 32-bit address + */ + err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + if (err < 0) { + dev_err(dev, "failed to set DMA coherent mask: %d\n", err); + goto free_irq; + } + + msi->virt = dma_alloc_attrs(dev, PAGE_SIZE, &msi->phys, GFP_KERNEL, + DMA_ATTR_NO_KERNEL_MAPPING); + if (!msi->virt) { + dev_err(dev, "failed to allocate DMA memory for MSI\n"); + err = -ENOMEM; + goto free_irq; } - /* setup AFI/FPCI range */ - msi->pages = __get_free_pages(GFP_KERNEL, 0); - msi->phys = virt_to_phys((void *)msi->pages); host->msi = &msi->chip; return 0; -err: +free_irq: + free_irq(msi->irq, pcie); +free_irq_domain: irq_domain_remove(msi->domain); return err; } @@ -1592,7 +1610,8 @@ static void tegra_pcie_msi_teardown(struct tegra_pcie *pcie) struct tegra_msi *msi = &pcie->msi; unsigned int i, irq; - free_pages(msi->pages, 0); + dma_free_attrs(pcie->dev, PAGE_SIZE, msi->virt, msi->phys, + DMA_ATTR_NO_KERNEL_MAPPING); if (msi->irq > 0) free_irq(msi->irq, pcie);