From patchwork Wed Aug 21 03:53:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 11105349 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 8087F1813 for ; Wed, 21 Aug 2019 03:55: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 5D3E422DD3 for ; Wed, 21 Aug 2019 03:55:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="YaNnl+jE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5D3E422DD3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org 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 1i0Hgm-0007d1-BA; Wed, 21 Aug 2019 03:53:36 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i0Hgl-0007cP-2g for xen-devel@lists.xen.org; Wed, 21 Aug 2019 03:53:35 +0000 X-Inumbo-ID: 374ad56e-c3c7-11e9-ac23-bc764e2007e4 Received: from mail.kernel.org (unknown [198.145.29.99]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 374ad56e-c3c7-11e9-ac23-bc764e2007e4; Wed, 21 Aug 2019 03:53:21 +0000 (UTC) Received: from localhost.localdomain (c-67-164-102-47.hsd1.ca.comcast.net [67.164.102.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C98452339F; Wed, 21 Aug 2019 03:53:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1566359600; bh=JaVbeAAX/zwCno/kZQEV2bAAyzSchQxLtpBM7P9idhc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YaNnl+jETCIzO6E3AyTTVqV0qV5lZUMOc7Np8r1Lp27Pwr91ISn1ImhSbpnjhsLu0 1EALaP965Yjcxijun/5GqUwvQpuFFkAFsL+r+vMm+L+367WM+SP6si8GYKZVhxN4K5 2JvPoRXdED/2XjUS+FQTHrs01P8tKD2IpK+wYokQ= From: Stefano Stabellini To: julien.grall@arm.com Date: Tue, 20 Aug 2019 20:53:12 -0700 Message-Id: <20190821035315.12812-5-sstabellini@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: Subject: [Xen-devel] [PATCH v4 5/8] xen/arm: assign devices to boot domains 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: Stefano Stabellini , sstabellini@kernel.org, andrii_anisov@epam.com, Achin.Gupta@arm.com, xen-devel@lists.xen.org, Volodymyr_Babchuk@epam.com MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Scan the user provided dtb fragment at boot. For each device node, map memory to guests, and route interrupts and setup the iommu. The memory region to remap is specified by the "xen,reg" property. The iommu is setup by passing the node of the device to assign on the host device tree. The path is specified in the device tree fragment as the "xen,path" string property. The interrupts are remapped based on the information from the corresponding node on the host device tree. Call handle_device_interrupts to remap interrupts. Interrupts related device tree properties are copied from the device tree fragment, same as all the other properties. Signed-off-by: Stefano Stabellini --- Changes in v4: - use unsigned - improve commit message - code style - use dt_prop_cmp - use device_tree_get_reg - don't copy over xen,reg and xen,path - don't create special interrupt properties for domU: copy them from the fragment - in-code comment Changes in v3: - improve commit message - remove superfluous cast - merge code with the copy code - add interrup-parent - demove depth > 2 check - reuse code from handle_device_interrupts - copy interrupts from host dt Changes in v2: - rename "path" to "xen,path" - grammar fix - use gaddr_to_gfn and maddr_to_mfn - remove depth <= 2 limitation in scanning the dtb fragment - introduce and parse xen,reg - code style - support more than one interrupt per device - specify only the GIC is supported --- xen/arch/arm/domain_build.c | 66 ++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index c71b9f2889..256c83462a 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1721,6 +1721,9 @@ static int __init handle_prop_pfdt(struct kernel_info *kinfo, void *fdt = kinfo->fdt; int propoff, nameoff, res; const struct fdt_property *prop; + struct dt_device_node *node; + const __be32 *cell; + unsigned int i, len; for ( propoff = fdt_first_property_offset(pfdt, nodeoff); propoff >= 0; @@ -1730,10 +1733,65 @@ static int __init handle_prop_pfdt(struct kernel_info *kinfo, return -FDT_ERR_INTERNAL; nameoff = fdt32_to_cpu(prop->nameoff); - res = fdt_property(fdt, fdt_string(pfdt, nameoff), - prop->data, fdt32_to_cpu(prop->len)); - if ( res ) - return res; + + /* xen,reg specifies where to map the MMIO region */ + if ( dt_prop_cmp("xen,reg", fdt_string(pfdt, nameoff)) == 0 ) + { + paddr_t mstart, size, gstart; + cell = (const __be32 *)prop->data; + len = fdt32_to_cpu(prop->len) / + ((address_cells * 2 + size_cells) * sizeof(uint32_t)); + + for ( i = 0; i < len; i++ ) + { + device_tree_get_reg(&cell, address_cells, size_cells, + &mstart, &size); + gstart = dt_next_cell(address_cells, &cell); + + res = guest_physmap_add_entry(kinfo->d, gaddr_to_gfn(gstart), + maddr_to_mfn(mstart), + get_order_from_bytes(size), + p2m_mmio_direct_dev); + if ( res < 0 ) + { + dprintk(XENLOG_ERR, + "Failed to map %"PRIpaddr" to the guest at%"PRIpaddr"\n", + mstart, gstart); + return -EFAULT; + } + } + } + /* + * xen,path specifies the corresponding node in the host DT. + * Both interrupt mappings and IOMMU settings are based on it, + * as they are done based on the corresponding host DT node. + */ + else if ( dt_prop_cmp("xen,path", fdt_string(pfdt, nameoff)) == 0 ) + { + node = dt_find_node_by_path(prop->data); + if ( node == NULL ) + { + dprintk(XENLOG_ERR, "Couldn't find node %s in host_dt!\n", + (char *)prop->data); + return -EINVAL; + } + + res = iommu_assign_dt_device(kinfo->d, node); + if ( res < 0 ) + return res; + + res = handle_device_interrupts(kinfo->d, node, true); + if ( res < 0 ) + return res; + } + /* copy all other properties */ + else + { + res = fdt_property(fdt, fdt_string(pfdt, nameoff), prop->data, + fdt32_to_cpu(prop->len)); + if ( res ) + return res; + } } /* FDT_ERR_NOTFOUND => There is no more properties for this node */