From patchwork Thu Apr 18 17:26:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 162509 Delivered-To: patch@linaro.org Received: by 2002:a02:c6d8:0:0:0:0:0 with SMTP id r24csp1013532jan; Thu, 18 Apr 2019 10:26:29 -0700 (PDT) X-Google-Smtp-Source: APXvYqys5xfowAZ6TGDMDGUseNTG3DZTOaDjK/D+FyV0/ypWdYFNAA+63JRXUVG/0p5mo4PbPRgw X-Received: by 2002:a62:b61a:: with SMTP id j26mr97909698pff.203.1555608388960; Thu, 18 Apr 2019 10:26:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555608388; cv=none; d=google.com; s=arc-20160816; b=oLTeiNhNWjm6JyOQEXctV5+NFB1COghNwjG28DqAMunruVc8fFDav0DIZOlgPhpDb2 CUYDiPeSd0nJoukEc5cTRKbWAbff+wZeA1FKhpXPEByvuE6F8dpR+jno9sQdsDybVfrg raV1oUmWHvinRmJe2+tcwESdsxFvect3E3ZD/YTWIK5UEUIQkV9F8SXqtCI0rOEBp1mo d8N8xgj3cC6ynz7KKcZL32PwFhCg6FVFie9262vxFTbbjskbHKVUW+3fJYcZfLZl9sPF 3K5tXcuYn/1leMZxclzuJaz7NgLap5EvTqvruf8/Pdb70gwWiCjfJCIDw4TsIsMl2B4q PGxg== 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=6z5OFNWMVoTovjZFN7dseM8GRxtjj9LcOV5SqDcxRKg=; b=yNDBaXrh/hmKJQVsBhNLLgxa2Z4BPZou54p4VOONApHxd9va48U34U85em7so5dLFb EY4oUFz6+vThJr7f0U4N/GSFKdnfU3anHYjsSNlDQwFeyhDFfdwia7SuWGPZGqrFyWIy 0ZRc2kjkE62bINXcja/ZjU5+XVQuRhxSGq5wSStKyEESdKolkBz29lKnvm7gosce6rFT 2iG+6y75e3zZG+y4qjLzkHVgQCozxmcuv3tvMwF5FltORvxCzsIZYPdQ8cYevXXKmuEr KUSshRYltyDvGTaQj2P1gCiFUnIKYoLypEP9H+O7LGrOKA6dVspZyaMArghPttIrnzwT 2ztw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-rt-users-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-rt-users-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 d8si2566052plo.157.2019.04.18.10.26.28; Thu, 18 Apr 2019 10:26:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-rt-users-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-rt-users-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-rt-users-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389831AbfDRR01 (ORCPT + 3 others); Thu, 18 Apr 2019 13:26:27 -0400 Received: from foss.arm.com ([217.140.101.70]:38064 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389826AbfDRR00 (ORCPT ); Thu, 18 Apr 2019 13:26:26 -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 19C9E169E; Thu, 18 Apr 2019 10:26:26 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.196.50]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D61FA3F557; Thu, 18 Apr 2019 10:26:23 -0700 (PDT) From: Julien Grall To: linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org Cc: logang@deltatee.com, douliyangs@gmail.com, miquel.raynal@bootlin.com, marc.zyngier@arm.com, jason@lakedaemon.net, tglx@linutronix.de, joro@8bytes.org, robin.murphy@arm.com, bigeasy@linutronix.de, linux-rt-users@vger.kernel.org, Julien Grall Subject: [PATCH 2/7] iommu/dma-iommu: Split iommu_dma_map_msi_msg in two parts Date: Thu, 18 Apr 2019 18:26:06 +0100 Message-Id: <20190418172611.21561-3-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190418172611.21561-1-julien.grall@arm.com> References: <20190418172611.21561-1-julien.grall@arm.com> Sender: linux-rt-users-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rt-users@vger.kernel.org On RT, the function iommu_dma_map_msi_msg may be called from non-preemptible context. This will lead to a splat with CONFIG_DEBUG_ATOMIC_SLEEP as the function is using spin_lock (they can sleep on RT). The function iommu_dma_map_msi_msg is used to map the MSI page in the IOMMU PT and update the MSI message with the IOVA. Only the part to lookup for the MSI page requires to be called in preemptible context. As the MSI page cannot change over the lifecycle of the MSI interrupt, the lookup can be cached and re-used later on. This patch split the function iommu_dma_map_msi_msg in two new functions: - iommu_dma_prepare_msi: This function will prepare the mapping in the IOMMU and store the cookie in the structure msi_desc. This function should be called in preemptible context. - iommu_dma_compose_msi_msg: This function will update the MSI message with the IOVA when the device is behind an IOMMU. Signed-off-by: Julien Grall --- drivers/iommu/dma-iommu.c | 43 ++++++++++++++++++++++++++++++++----------- include/linux/dma-iommu.h | 21 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 11 deletions(-) -- 2.11.0 diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 77aabe637a60..f5c1f1685095 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -888,17 +888,17 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, return NULL; } -void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) +int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) { - struct device *dev = msi_desc_to_dev(irq_get_msi_desc(irq)); + struct device *dev = msi_desc_to_dev(desc); struct iommu_domain *domain = iommu_get_domain_for_dev(dev); struct iommu_dma_cookie *cookie; - struct iommu_dma_msi_page *msi_page; - phys_addr_t msi_addr = (u64)msg->address_hi << 32 | msg->address_lo; unsigned long flags; - if (!domain || !domain->iova_cookie) - return; + if (!domain || !domain->iova_cookie) { + desc->iommu_cookie = NULL; + return 0; + } cookie = domain->iova_cookie; @@ -908,10 +908,33 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) * of an MSI from within an IPI handler. */ spin_lock_irqsave(&cookie->msi_lock, flags); - msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain); + desc->iommu_cookie = iommu_dma_get_msi_page(dev, msi_addr, domain); spin_unlock_irqrestore(&cookie->msi_lock, flags); - if (WARN_ON(!msi_page)) { + return (desc->iommu_cookie) ? 0 : -ENOMEM; +} + +void iommu_dma_compose_msi_msg(int irq, struct msi_msg *msg) +{ + struct msi_desc *desc = irq_get_msi_desc(irq); + struct device *dev = msi_desc_to_dev(desc); + const struct iommu_domain *domain = iommu_get_domain_for_dev(dev); + const struct iommu_dma_msi_page *msi_page = desc->iommu_cookie; + + if (!domain || !domain->iova_cookie || WARN_ON(!msi_page)) + return; + + msg->address_hi = upper_32_bits(msi_page->iova); + msg->address_lo &= cookie_msi_granule(domain->iova_cookie) - 1; + msg->address_lo += lower_32_bits(msi_page->iova); +} + +void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) +{ + struct msi_desc *desc = irq_get_msi_desc(irq); + phys_addr_t msi_addr = (u64)msg->address_hi << 32 | msg->address_lo; + + if (WARN_ON(iommu_dma_prepare_msi(desc, msi_addr))) { /* * We're called from a void callback, so the best we can do is * 'fail' by filling the message with obviously bogus values. @@ -922,8 +945,6 @@ void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) msg->address_lo = ~0U; msg->data = ~0U; } else { - msg->address_hi = upper_32_bits(msi_page->iova); - msg->address_lo &= cookie_msi_granule(cookie) - 1; - msg->address_lo += lower_32_bits(msi_page->iova); + iommu_dma_compose_msi_msg(irq, msg); } } diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h index e760dc5d1fa8..2f4b2c2cc859 100644 --- a/include/linux/dma-iommu.h +++ b/include/linux/dma-iommu.h @@ -71,12 +71,23 @@ void iommu_dma_unmap_resource(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, unsigned long attrs); /* The DMA API isn't _quite_ the whole story, though... */ +/* + * Map the MSI page in the IOMMU device and store it in @desc + * + * Return 0 if succeeded other an error if the preparation has failed. + */ +int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr); + +/* Update the MSI message if required. */ +void iommu_dma_compose_msi_msg(int irq, struct msi_msg *msg); + void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg); void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list); #else struct iommu_domain; +struct msi_desc; struct msi_msg; struct device; @@ -99,6 +110,16 @@ static inline void iommu_put_dma_cookie(struct iommu_domain *domain) { } +static inline int iommu_dma_prepare_msi(struct msi_desc *desc, + phys_addr_t msi_addr) +{ + return 0; +} + +static inline void iommu_dma_compose_msi_msg(int irq, struct msi_msg *msg) +{ +} + static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) { } From patchwork Thu Apr 18 17:26:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 162512 Delivered-To: patch@linaro.org Received: by 2002:a02:c6d8:0:0:0:0:0 with SMTP id r24csp1013676jan; Thu, 18 Apr 2019 10:26:36 -0700 (PDT) X-Google-Smtp-Source: APXvYqz6QsdZ2zljcBCQ2mlhbXg7uHj2P4voL6Jx1lvOg93+VkWJP2OBRODNuApRqjtaQ/DuVr+V X-Received: by 2002:aa7:8518:: with SMTP id v24mr97625707pfn.219.1555608396344; Thu, 18 Apr 2019 10:26:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555608396; cv=none; d=google.com; s=arc-20160816; b=m0HoVbfB+V9RO0Zog1YcKFzHLq+r1aqrMdyv7iMPJSx5f3XQMQr+x2YSsYxEfZ4Yc4 41xtzQyUXaIdKQln6tu1sIHbjCSo8ghS/xelIJoHmWV9fOvdU6kemcbxdPt2KABWHaAR OQJVwH/yTiLCorfh5EkxsYj//oTV1oX2KIkz360S4rWO3LQEpcSJwb4WELuG3q34Gw91 gSbDklK9XUvp4OQ7RWgcUYTxoeQ0of7oyFKLlmOwJTllJs4AszbjeM/YIIf+J7eIzV2N qAH9MvSKuDvu0iZOQsQckqvcKCZ1jYd35D5Uwtpqdo7rnSDxpo7S4HFNdMxHQYgUiisj Vafg== 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=UDZmQ6iP/tnTw03Zb49yqFPwqX8HpgNWDsR4uz+K9Os=; b=eaRe5a6dK5zrp0YaGUGr97/ZyMHS/ZeNr8xyMIE+IcF0GaqCGKnZr4CtaqoDNFUzI9 6bVDzmdsqIobU8gWYsE7qAZf2yyf2R95Lwwu5ZGS5ItqdZq4W46DUEnJcE7euNro0YEd H5TSI37HXxwwNvr1V069JCzgR7DL1L+PSrDmPpwlXK8jT+h8gMxKYP3YnWkSCblvtdCN xb0mhniNKFkr2uKLAnqlYO6yL7ga1Zd6llTyrtvWzVI2SrhcuOCYBRY3iYkfmkFby324 noymKJvVRWZtH50AnTzRwMssB4cj2jfLF20UHJJ3Nl7wc9Hr0XC/yBdY8/Nej7B8cTJ4 FFKQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-rt-users-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-rt-users-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 i37si2416807pgb.436.2019.04.18.10.26.36; Thu, 18 Apr 2019 10:26:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-rt-users-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-rt-users-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-rt-users-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389873AbfDRR0f (ORCPT + 3 others); Thu, 18 Apr 2019 13:26:35 -0400 Received: from foss.arm.com ([217.140.101.70]:38120 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389850AbfDRR0e (ORCPT ); Thu, 18 Apr 2019 13:26:34 -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 885651688; Thu, 18 Apr 2019 10:26:33 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.196.50]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 50D883F557; Thu, 18 Apr 2019 10:26:31 -0700 (PDT) From: Julien Grall To: linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org Cc: logang@deltatee.com, douliyangs@gmail.com, miquel.raynal@bootlin.com, marc.zyngier@arm.com, jason@lakedaemon.net, tglx@linutronix.de, joro@8bytes.org, robin.murphy@arm.com, bigeasy@linutronix.de, linux-rt-users@vger.kernel.org, Julien Grall Subject: [PATCH 5/7] irqchip/ls-scfg-msi: Don't map the MSI page in ls_scfg_msi_compose_msg Date: Thu, 18 Apr 2019 18:26:09 +0100 Message-Id: <20190418172611.21561-6-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190418172611.21561-1-julien.grall@arm.com> References: <20190418172611.21561-1-julien.grall@arm.com> Sender: linux-rt-users-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rt-users@vger.kernel.org The function ls_scfg_msi_compose_msg may be called from non-preemptible context. However, on RT, iommu_dma_map_msi_msg requires to be called from a preemptible context. A recent patch split the function iommu_dma_map_msi_msg in 2 functions: one that should be called in preemptible context, the other does not have any requirement. This patch reworks the FreeScale SCFG MSI driver to avoid executing preemptible code in non-preemptible context by preparing the MSI mapping when allocating the MSI interrupt. Signed-off-by: Julien Grall --- drivers/irqchip/irq-ls-scfg-msi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) -- 2.11.0 diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c index c671b3212010..8099c5b1fcb5 100644 --- a/drivers/irqchip/irq-ls-scfg-msi.c +++ b/drivers/irqchip/irq-ls-scfg-msi.c @@ -100,7 +100,7 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) msg->data |= cpumask_first(mask); } - iommu_dma_map_msi_msg(data->irq, msg); + iommu_dma_compose_msi_msg(data->irq, msg); } static int ls_scfg_msi_set_affinity(struct irq_data *irq_data, @@ -141,6 +141,7 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain, unsigned int nr_irqs, void *args) { + msi_alloc_info_t *info = args; struct ls_scfg_msi *msi_data = domain->host_data; int pos, err = 0; @@ -157,6 +158,10 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain, if (err) return err; + err = iommu_dma_prepare_msi(info->desc, msi_data->msiir_addr); + if (err) + return err; + irq_domain_set_info(domain, virq, pos, &ls_scfg_msi_parent_chip, msi_data, handle_simple_irq, NULL, NULL);