From patchwork Tue Aug 20 18:09:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 11104475 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10C2A14DB for ; Tue, 20 Aug 2019 18:12:22 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E0DA020644 for ; Tue, 20 Aug 2019 18:12:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hDNWaYOg" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E0DA020644 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i08aj-0006Ic-RY; Tue, 20 Aug 2019 18:10:45 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i08ai-0006Hm-23 for xen-devel@lists.xenproject.org; Tue, 20 Aug 2019 18:10:44 +0000 X-Inumbo-ID: c24adff8-c375-11e9-92eb-bc764e2007e4 Received: from mail-lf1-x141.google.com (unknown [2a00:1450:4864:20::141]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id c24adff8-c375-11e9-92eb-bc764e2007e4; Tue, 20 Aug 2019 18:10:15 +0000 (UTC) Received: by mail-lf1-x141.google.com with SMTP id x3so4852248lfc.0 for ; Tue, 20 Aug 2019 11:10:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=S0JoSMTFvGvAzG2YzPSF+Ye3zNZcXlx2qO4IFTTEzGA=; b=hDNWaYOgiMDe2cncNhscLTQAFvZHi40XG84BHYt4ok4O+MNPZIi33ZiFqPfuYKckpq RYyXTbNwxkLRXHfVrYSPgPMBJqr2F8Vz/vaPtuck768/7JecOmZ/TkIFARIObZX+2QXW 1EzANohZcfxAGmwg8DiDgT6c513ynZtD191bPUYiTOoY59vk1C+iE8DPOyb6+DOWw93v h9M2Js4p/0wy7lc/wulzyzUGLW2uqfKs3MrfVnS54v2ieAAVtM3pRSLLFd8XxhQgrbJN 04CXUT20B7ezMSXEb5BHeS2zSBztt74arHLtVDW/Zl/0vtTymLn8/mvTPZfwpUWgjnQk KWCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=S0JoSMTFvGvAzG2YzPSF+Ye3zNZcXlx2qO4IFTTEzGA=; b=ZYkrz7ezdRlaZ34GBqDUKQhQ9kiu5A1imLjqfYF83bImwEiYrU99W4KfBInuDfvMGJ osjsGa8g4HWqojxN5a2Ktmm5Efag0qMslhNSIaJM3QBh3TV8/6aOe5CaCiolT4QIdeiy Wpwzh3Z4WrTfRkI/z23UVPGFA/TXsySou7aXg054MAQ5YIF5laoDx3XPVCKoOqWhooQ0 Yd0Mh8FdFziroTYUmMKcAc6wn+eY3P+aq2ECIE43/5RYYnnFp6erfEztDyxfKjp2KX+B nM6mxLip/txqAbMK2Ye6wWSWb8T0FSB6errZFzifA82MIjmMvNBCSdoPl3rBD97UOUi5 G42g== X-Gm-Message-State: APjAAAWSO9h2qPdvaue1k0sR7PhNqc2gYoJxQsCAXZpCraGtHBytESff n3hC5JWhmPT6R4bVdRzl8RUGQV8E X-Google-Smtp-Source: APXvYqyx+Q+1ktyHLhD77AMRg3OMJFFvLdtKC5ffthtwC5A0Q3t0JFsKEwQ8IOywc1xeFBUHffdRSA== X-Received: by 2002:ac2:4309:: with SMTP id l9mr15909979lfh.65.1566324614379; Tue, 20 Aug 2019 11:10:14 -0700 (PDT) Received: from otyshchenko.kyiv.epam.com (ll-22.209.223.85.sovam.net.ua. [85.223.209.22]) by smtp.gmail.com with ESMTPSA id f6sm2900642lja.16.2019.08.20.11.10.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 20 Aug 2019 11:10:13 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org Date: Tue, 20 Aug 2019 21:09:46 +0300 Message-Id: <1566324587-3442-8-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1566324587-3442-1-git-send-email-olekstysh@gmail.com> References: <1566324587-3442-1-git-send-email-olekstysh@gmail.com> Subject: [Xen-devel] [PATCH V3 7/8] iommu/arm: Introduce iommu_add_dt_device API X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Oleksandr Tyshchenko , julien.grall@arm.com, sstabellini@kernel.org, Volodymyr_Babchuk@epam.com MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Oleksandr Tyshchenko This patch adds new iommu_add_dt_device API for adding DT device to the IOMMU using generic IOMMU DT bindings [1] and previously added "iommu_fwspec" support and "add_device/of_xlate" callbacks. New function does the following: - Parse the DT bindings according to the specification - Provide DT IOMMU specifier which describes the IOMMU master interfaces of that device (device IDs, etc) to the driver - Add master device to the IOMMU if latter is present and available The additional benefit here is to avoid to go through the whole DT multiple times in IOMMU driver trying to locate master devices which belong to each IOMMU device being probed. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/iommu/iommu.txt Signed-off-by: Oleksandr Tyshchenko CC: Julien Grall --- Changes V2 -> V3: - clarified patch description - clarified comments in code - modified to provide DT IOMMU specifier to the driver using "of_xlate" callback - documented function usage - modified to return an error if ops is not present/implemented, - added ability to return a possitive value to indicate that device doesn't need to be protected - removed check for the "iommu" property presence in the common code - included directly --- xen/arch/arm/domain_build.c | 11 ++++++++ xen/drivers/passthrough/arm/iommu.c | 55 +++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/iommu.h | 11 ++++++++ 3 files changed, 77 insertions(+) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index e79d4e2..159ea6a 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1240,6 +1240,7 @@ static int __init map_device_children(struct domain *d, /* * For a given device node: + * - Try to call iommu_add_dt_device to protect the device by an IOMMU * - Give permission to the guest to manage IRQ and MMIO range * - Retrieve the IRQ configuration (i.e edge/level) from device tree * When the device is not marked for guest passthrough: @@ -1257,6 +1258,16 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev, u64 addr, size; bool need_mapping = !dt_device_for_passthrough(dev); + dt_dprintk("%s add to iommu\n", dt_node_full_name(dev)); + + res = iommu_add_dt_device(dev); + if ( res < 0 ) + { + printk(XENLOG_ERR "Failed to add %s to the IOMMU\n", + dt_node_full_name(dev)); + return res; + } + nirq = dt_number_of_irq(dev); naddr = dt_number_of_address(dev); diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c index 72a30e0..47e4bc6 100644 --- a/xen/drivers/passthrough/arm/iommu.c +++ b/xen/drivers/passthrough/arm/iommu.c @@ -20,6 +20,7 @@ #include #include +#include /* * Deferred probe list is used to keep track of devices for which driver @@ -139,3 +140,57 @@ int arch_iommu_populate_page_table(struct domain *d) void __hwdom_init arch_iommu_hwdom_init(struct domain *d) { } + +int __init iommu_add_dt_device(struct dt_device_node *np) +{ + const struct iommu_ops *ops = iommu_get_ops(); + struct dt_phandle_args iommu_spec; + struct device *dev = dt_to_dev(np); + int rc = 1, index = 0; + + if ( !iommu_enabled ) + return 1; + + if ( !ops || !ops->add_device || !ops->of_xlate ) + return -EINVAL; + + if ( dev_iommu_fwspec_get(dev) ) + return -EEXIST; + + /* According Documentation/devicetree/bindings/iommu/iommu.txt from Linux */ + while ( !dt_parse_phandle_with_args(np, "iommus", "#iommu-cells", + index, &iommu_spec) ) + { + if ( !dt_device_is_available(iommu_spec.np) ) + break; + + rc = iommu_fwspec_init(dev, &iommu_spec.np->dev); + if ( rc ) + break; + + /* + * Provide DT IOMMU specifier which describes the IOMMU master + * interfaces of that device (device IDs, etc) to the driver. + * The driver's responsibility is to decide how to interpret them. + * It should also initialize/verify that device. + */ + rc = ops->of_xlate(dev, &iommu_spec); + if ( rc ) + break; + + index++; + } + + /* + * Add master device to the IOMMU if latter is present and available. + * The driver's responsibility is to check whether that device + * was initialized/verified before and mark that device as protected. + */ + if ( !rc ) + rc = ops->add_device(0, dev); + + if ( rc < 0 ) + iommu_fwspec_free(dev); + + return rc; +} diff --git a/xen/include/asm-arm/iommu.h b/xen/include/asm-arm/iommu.h index 20d865e..e75359c 100644 --- a/xen/include/asm-arm/iommu.h +++ b/xen/include/asm-arm/iommu.h @@ -26,6 +26,17 @@ struct arch_iommu const struct iommu_ops *iommu_get_ops(void); void iommu_set_ops(const struct iommu_ops *ops); +/* + * Helper to add master device to the IOMMU using generic IOMMU DT bindings. + * + * Return values: + * 0 : device is protected by an IOMMU + * <0 : device is not protected by an IOMMU, but must be (error condition) + * >0 : device doesn't need to be protected by an IOMMU + * (IOMMU is not enabled/present or device is not connected to it). + */ +int iommu_add_dt_device(struct dt_device_node *np); + /* mapping helpers */ int __must_check arm_iommu_map_page(struct domain *d, dfn_t dfn, mfn_t mfn, unsigned int flags,