From patchwork Fri Sep 13 15:35:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksandr Tyshchenko X-Patchwork-Id: 11144955 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 645CD14E5 for ; Fri, 13 Sep 2019 15:38:23 +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 3F36520717 for ; Fri, 13 Sep 2019 15:38:23 +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="LKXwVWnI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3F36520717 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 1i8ncj-0002EH-9I; Fri, 13 Sep 2019 15:36:37 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i8nch-0002DY-Ji for xen-devel@lists.xenproject.org; Fri, 13 Sep 2019 15:36:35 +0000 X-Inumbo-ID: 335054c0-d63c-11e9-a337-bc764e2007e4 Received: from mail-lj1-x243.google.com (unknown [2a00:1450:4864:20::243]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 335054c0-d63c-11e9-a337-bc764e2007e4; Fri, 13 Sep 2019 15:36:06 +0000 (UTC) Received: by mail-lj1-x243.google.com with SMTP id a22so27561507ljd.0 for ; Fri, 13 Sep 2019 08:36:06 -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=kUwXANjjQ0oshSNB7xTGiXsMWgK6tjSVAQHLjbkxKQ0=; b=LKXwVWnIaMYGS2astBw09NUlQ4i00JkJQlUAH6xwBIQEHn2YlcEXIrQmfEGHWwvMjf KNdtolZLJvT2+ew0PHxn395PuVsqCgbJJ38NFYvEBcesVVdVTPGeTCznfm0GX6sC9Cvy QilLC6uaaOhZeVgCfMZv6qNgue3S8bR3crdJ7xArJmGOjlj1VXCyIU52sa18MtXMaXG4 3GYb8q5NR0kxW7nyF6xx3Vok2OlqpYGE+gX0TWpgiFHMrXaNi9MLHMtZCEl3+5LyGSBY y64bASAyC7Eiow+j/jhUxfqikDUdd/jjX1m9m0rt/GqjG2vBJECwjQwodN+7MNC2pxiU 8kbg== 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=kUwXANjjQ0oshSNB7xTGiXsMWgK6tjSVAQHLjbkxKQ0=; b=VkJFRGauLs9F0KRbvkQqCuQdA/lOvmOn92Hfag44p6UOWWsy7l/HyHc/LQNuzI3e7/ yvN//EzL8+lurGkfnYwv/7wvIJOji0PjjfzVBIyV/EDosyXrLb7gbN+8c3q+V9zIgPnV b6rj5uXb+ZxjLqQnNJEjHaVthNSWUEl8DWjw6t+ykrxAt1A2ZVrCaCfg/Cxnk8Y6FVbu dF+oQzgV9EZveHDStpLMQEwOSZOvt//CircDOQiG4srVnOvOaU1zUunKVf/vK//uBdU4 L5kdc73Ji7TnZWvaQOtuY1dPsZUmAiudIyxrj1i2ITME5JK7VttWMgJNXH/r5X5JnGS6 Zzdg== X-Gm-Message-State: APjAAAV26SChVeVXKsyd7NehbqI/agkR5HYyTuHOU1ZVv0XptQHwIlmw DViPTeAIwePC2aPKKuhTkP2XdVSHLaw= X-Google-Smtp-Source: APXvYqxPdaghq00tfzK43hcmOqIB2gwvomZ07YbczXoUZC4IthoJAai3//JAUeHcuoLgcBJxGt4xJA== X-Received: by 2002:a2e:7801:: with SMTP id t1mr16306376ljc.140.1568388965327; Fri, 13 Sep 2019 08:36:05 -0700 (PDT) Received: from otyshchenko.kyiv.epam.com (ll-74.141.223.85.sovam.net.ua. [85.223.141.74]) by smtp.gmail.com with ESMTPSA id c16sm6969765lfj.8.2019.09.13.08.36.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 13 Sep 2019 08:36:04 -0700 (PDT) From: Oleksandr Tyshchenko To: xen-devel@lists.xenproject.org Date: Fri, 13 Sep 2019 18:35:16 +0300 Message-Id: <1568388917-7287-8-git-send-email-olekstysh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1568388917-7287-1-git-send-email-olekstysh@gmail.com> References: <1568388917-7287-1-git-send-email-olekstysh@gmail.com> Subject: [Xen-devel] [PATCH V4 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, Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Oleksandr Tyshchenko The main puprose of this patch is to add a way to register DT device (which is behind the IOMMU) using the generic IOMMU DT bindings [1] before assigning that device to a domain. So, this patch adds new "iommu_add_dt_device" API for adding DT device to the IOMMU using generic IOMMU DT bindings and previously added "iommu_fwspec" support. It is called when constructing Dom0 since "iommu_assign_dt_device" can be called for Dom0 also. Besides that, this patch adds new "dt_xlate" callback (borrowed from Linux "of_xlate") for providing the driver with DT IOMMU specifier which describes the IOMMU master interfaces of that device (device IDs, etc). According to the generic IOMMU DT bindings the context of required properties for IOMMU device/master node (#iommu-cells, iommus) depends on many factors and is really driver depended thing. Please note, all IOMMU drivers which support generic IOMMU DT bindings should use "dt_xlate" and "add_device" callbacks. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/iommu/iommu.txt Signed-off-by: Oleksandr Tyshchenko CC: Julien Grall CC: Jan Beulich --- Changes V3 -> V4: - squashed with "iommu: Add of_xlate callback" patch - renamed "of_xlate" to "dt_xlate" - reworked patch description - clarified comments in code, removed confusing word "initialize device", etc - updated debug message in handle_device() - modified to check ops->of_xlate and ops->add_device only if "iommus" property is exists 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 | 12 +++++++ xen/drivers/passthrough/arm/iommu.c | 63 +++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/iommu.h | 11 +++++++ xen/include/xen/iommu.h | 10 ++++++ 4 files changed, 96 insertions(+) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index a0fee1e..0d79182 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,17 @@ 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("Check if %s is behind the IOMMU and add it\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 5a3d1d5..dea79ed 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 @@ -141,3 +142,65 @@ 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 ) + return -EINVAL; + + if ( dev_iommu_fwspec_get(dev) ) + return -EEXIST; + + /* + * According to the Documentation/devicetree/bindings/iommu/iommu.txt + * from Linux. + */ + while ( !dt_parse_phandle_with_args(np, "iommus", "#iommu-cells", + index, &iommu_spec) ) + { + /* + * The driver which supports generic IOMMU DT bindings must have + * these callback implemented. + */ + if ( !ops->add_device || !ops->dt_xlate ) + return -EINVAL; + + 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 is responsible to decide how to interpret them. + */ + rc = ops->dt_xlate(dev, &iommu_spec); + if ( rc ) + break; + + index++; + } + + /* + * Add master device to the IOMMU if latter is present and available. + * The driver is responsible to 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 11dedba..04f21a2 100644 --- a/xen/include/asm-arm/iommu.h +++ b/xen/include/asm-arm/iommu.h @@ -27,6 +27,17 @@ 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); + +/* * The mapping helpers below should only be used if P2M Table is shared * between the CPU and the IOMMU. */ diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index ab258b8..59a2cee 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -239,6 +239,16 @@ struct iommu_ops { int __must_check (*iotlb_flush_all)(struct domain *d); int (*get_reserved_device_memory)(iommu_grdm_t *, void *); void (*dump_p2m_table)(struct domain *d); + +#ifdef CONFIG_HAS_DEVICE_TREE + /* + * All IOMMU drivers which support generic IOMMU DT bindings should use + * this callback. This is a way for the framework to provide the driver + * with DT IOMMU specifier which describes the IOMMU master interfaces of + * that device (device IDs, etc). + */ + int (*dt_xlate)(device_t *dev, struct dt_phandle_args *args); +#endif }; #include