From patchwork Fri Feb 7 17:43:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 24309 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f199.google.com (mail-ve0-f199.google.com [209.85.128.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 52ABA2096A for ; Fri, 7 Feb 2014 17:43:46 +0000 (UTC) Received: by mail-ve0-f199.google.com with SMTP id oy12sf9145432veb.2 for ; Fri, 07 Feb 2014 09:43:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=Ylf5wCQqy+iagUcUn2Lzjj7+gUCArC0HlLCDwzCYQis=; b=IOyVZZ8auml8ujovNg352ZF1ulwVVwhkBrEOI/XwA1s7Pwy2vvmI99pmXaiwBSeVE/ t53Ykb7Ib5hMCTpI1qJTrpbgi3PpmYyIFLkreFvptEsfGQLHOiHSRON2kzqBORnLasDT QbW94Kf6t8ZtPGR+0K8m3dHTxvxTdHXrXR1WYmydUisxl+vwf5BwIqMDVg53LsDbAned TY5bAWbLUk+Dc30h5jKKjZkVGHtQ9+dllXddidDECqslZ24UY34mIxH9Zd2egODfOSWD qzEzZBAjOf32Eqv7okeSQA5tJUtCOyrXnoBmRY2FjDnOQfrZ0sYY5E8eKgGdLuIhYI00 XnwQ== X-Gm-Message-State: ALoCoQnJsTGvwYeB9BfvJJ7UOqiZn8jIoIHhvij8ukNsOz545LkVO84WNMn3PNeNdtv/4rVyTeXq X-Received: by 10.58.221.74 with SMTP id qc10mr4688988vec.35.1391795025096; Fri, 07 Feb 2014 09:43:45 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.30.8 with SMTP id c8ls1231069qgc.56.gmail; Fri, 07 Feb 2014 09:43:45 -0800 (PST) X-Received: by 10.220.139.136 with SMTP id e8mr1078009vcu.34.1391795025022; Fri, 07 Feb 2014 09:43:45 -0800 (PST) Received: from mail-vb0-f43.google.com (mail-vb0-f43.google.com [209.85.212.43]) by mx.google.com with ESMTPS id uw4si1541186vdc.92.2014.02.07.09.43.45 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 07 Feb 2014 09:43:45 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.43 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.43; Received: by mail-vb0-f43.google.com with SMTP id p5so2837392vbn.2 for ; Fri, 07 Feb 2014 09:43:44 -0800 (PST) X-Received: by 10.220.109.1 with SMTP id h1mr11434099vcp.20.1391795024921; Fri, 07 Feb 2014 09:43:44 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp123611vcz; Fri, 7 Feb 2014 09:43:43 -0800 (PST) X-Received: by 10.14.176.133 with SMTP id b5mr425267eem.105.1391795019142; Fri, 07 Feb 2014 09:43:39 -0800 (PST) Received: from mail-ee0-f42.google.com (mail-ee0-f42.google.com [74.125.83.42]) by mx.google.com with ESMTPS id v48si9571098eeo.125.2014.02.07.09.43.38 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 07 Feb 2014 09:43:39 -0800 (PST) Received-SPF: neutral (google.com: 74.125.83.42 is neither permitted nor denied by best guess record for domain of julien.grall@linaro.org) client-ip=74.125.83.42; Received: by mail-ee0-f42.google.com with SMTP id b15so1695908eek.1 for ; Fri, 07 Feb 2014 09:43:38 -0800 (PST) X-Received: by 10.14.29.6 with SMTP id h6mr5739299eea.84.1391795018524; Fri, 07 Feb 2014 09:43:38 -0800 (PST) Received: from belegaer.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id 8sm18849063eef.1.2014.02.07.09.43.37 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Feb 2014 09:43:37 -0800 (PST) From: Julien Grall To: xen-devel@lists.xenproject.org Cc: patches@linaro.org, ian.campbell@citrix.com, tim@xen.org, stefano.stabellini@citrix.com, Julien Grall , Xiantao Zhang , Jan Beulich Subject: [RFC for-4.5 10/12] xen/passthrough: Introduce IOMMU ARM architure Date: Fri, 7 Feb 2014 17:43:09 +0000 Message-Id: <1391794991-5919-11-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1391794991-5919-1-git-send-email-julien.grall@linaro.org> References: <1391794991-5919-1-git-send-email-julien.grall@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.43 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch contains the architecture to use IOMMU on ARM. There is no IOMMU drivers on this patch. The code will run through the device tree and will initialize every IOMMUs. It's possible to have multiple IOMMUs on the same platform, but they should be handled with the same drivers. For now, there is no support for using multiple iommu drivers at runtime. Each new IOMMU drivers should contain: static const char * const myiommu_dt_compat[] __initcontst = { /* list of device compatible with the drivers. Will be matched with * the "compatible" property on the device tree */ NULL, }; DT_DEVICE_START(myiommu, "MY IOMMU", DEVICE_IOMMU) .compatible = myiommu_compatible, .init = myiommu_init, DT_DEVICE_END Signed-off-by: Julien Grall Cc: Xiantao Zhang Cc: Jan Beulich --- xen/arch/arm/Rules.mk | 1 + xen/arch/arm/domain.c | 7 ++++ xen/arch/arm/domain_build.c | 2 ++ xen/arch/arm/p2m.c | 4 +++ xen/arch/arm/setup.c | 2 ++ xen/drivers/passthrough/Makefile | 1 + xen/drivers/passthrough/arm/Makefile | 1 + xen/drivers/passthrough/arm/iommu.c | 65 ++++++++++++++++++++++++++++++++++ xen/include/asm-arm/device.h | 3 +- xen/include/asm-arm/domain.h | 2 ++ xen/include/asm-arm/hvm/iommu.h | 10 ++++++ xen/include/asm-arm/iommu.h | 36 +++++++++++++++++++ 12 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 xen/drivers/passthrough/arm/Makefile create mode 100644 xen/drivers/passthrough/arm/iommu.c create mode 100644 xen/include/asm-arm/hvm/iommu.h create mode 100644 xen/include/asm-arm/iommu.h diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk index 57f2eb1..1703551 100644 --- a/xen/arch/arm/Rules.mk +++ b/xen/arch/arm/Rules.mk @@ -9,6 +9,7 @@ HAS_DEVICE_TREE := y HAS_VIDEO := y HAS_ARM_HDLCD := y +HAS_PASSTHROUGH := y CFLAGS += -I$(BASEDIR)/include diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index c279a27..b3c0dda 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -557,6 +557,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags) if ( (d->domain_id == 0) && (rc = domain_vuart_init(d)) ) goto fail; + if ( (rc = iommu_domain_init(d)) != 0 ) + goto fail; + return 0; fail: @@ -568,6 +571,10 @@ fail: void arch_domain_destroy(struct domain *d) { + /* IOMMU page table is shared with P2M, always call + * iommu_domain_destroy() before p2m_teardown(). + */ + iommu_domain_destroy(d); p2m_teardown(d); domain_vgic_free(d); domain_vuart_free(d); diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 6d9a801..1f845d7 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1091,6 +1091,8 @@ int construct_dom0(struct domain *d) } } + iommu_dom0_init(d); + return 0; } diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 85ca330..57304d0 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -401,12 +401,16 @@ static int create_p2m_entries(struct domain *d, if ( flush ) { + unsigned long sgfn = paddr_to_pfn(start_gpaddr); + unsigned long egfn = paddr_to_pfn(end_gpaddr); + /* At the beginning of the function, Xen is updating VTTBR * with the domain where the mappings are created. In this * case it's only necessary to flush TLBs on every CPUs with * the current VMID (our domain). */ flush_tlb(); + iommu_iotlb_flush(d, sgfn, egfn - sgfn); } if ( op == ALLOCATE || op == INSERT ) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 1f6d713..5a687d1 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -725,6 +725,8 @@ void __init start_xen(unsigned long boot_phys_offset, local_irq_enable(); local_abort_enable(); + iommu_setup(); /* setup iommu if available */ + smp_prepare_cpus(cpus); initialize_keytable(); diff --git a/xen/drivers/passthrough/Makefile b/xen/drivers/passthrough/Makefile index 51e0a0d..aded1ea 100644 --- a/xen/drivers/passthrough/Makefile +++ b/xen/drivers/passthrough/Makefile @@ -1,6 +1,7 @@ subdir-$(x86) += vtd subdir-$(x86) += amd subdir-$(x86_64) += x86 +subdir-$(arm) += arm obj-y += iommu.o obj-$(x86) += iommu_x86.o diff --git a/xen/drivers/passthrough/arm/Makefile b/xen/drivers/passthrough/arm/Makefile new file mode 100644 index 0000000..0484b79 --- /dev/null +++ b/xen/drivers/passthrough/arm/Makefile @@ -0,0 +1 @@ +obj-y += iommu.o diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c new file mode 100644 index 0000000..7cf36cd --- /dev/null +++ b/xen/drivers/passthrough/arm/iommu.c @@ -0,0 +1,65 @@ +/* + * xen/drivers/passthrough/arm/iommu.c + * + * Generic IOMMU framework via the device tree + * + * Julien Grall + * Copyright (c) 2013 Linaro Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +static const struct iommu_ops *iommu_ops; + +const struct iommu_ops *iommu_get_ops(void) +{ + return iommu_ops; +} + +void __init iommu_set_ops(const struct iommu_ops *ops) +{ + BUG_ON(ops == NULL); + + if ( iommu_ops && iommu_ops != ops ) + printk("WARNING: IOMMU ops already set to a different value\n"); + + iommu_ops = ops; +} + +int __init iommu_hardware_setup(void) +{ + struct dt_device_node *np; + int rc; + unsigned int num_iommus = 0; + + dt_for_each_device_node(dt_host, np) + { + rc = device_init(np, DEVICE_IOMMU, NULL); + if ( !rc ) + num_iommus++; + } + + return ( num_iommus > 0 ) ? 0 : -ENODEV; +} + +int arch_iommu_domain_init(struct domain *d) +{ + return 0; +} + +void arch_iommu_domain_destroy(struct domain *d) +{ +} diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h index 9e47ca6..ed04344 100644 --- a/xen/include/asm-arm/device.h +++ b/xen/include/asm-arm/device.h @@ -6,7 +6,8 @@ enum device_type { - DEVICE_SERIAL + DEVICE_SERIAL, + DEVICE_IOMMU, }; struct device_desc { diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index af8c64b..15d814a 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -9,6 +9,7 @@ #include #include #include +#include /* Represents state corresponding to a block of 32 interrupts */ struct vgic_irq_rank { @@ -72,6 +73,7 @@ struct pending_irq struct hvm_domain { uint64_t params[HVM_NR_PARAMS]; + struct hvm_iommu hvm_iommu; } __cacheline_aligned; #ifdef CONFIG_ARM_64 diff --git a/xen/include/asm-arm/hvm/iommu.h b/xen/include/asm-arm/hvm/iommu.h new file mode 100644 index 0000000..461c8cf --- /dev/null +++ b/xen/include/asm-arm/hvm/iommu.h @@ -0,0 +1,10 @@ +#ifndef __ASM_ARM_HVM_IOMMU_H_ +#define __ASM_ARM_HVM_IOMMU_H_ + +struct arch_hvm_iommu +{ + /* Private information for the IOMMU drivers */ + void *priv; +}; + +#endif /* __ASM_ARM_HVM_IOMMU_H_ */ diff --git a/xen/include/asm-arm/iommu.h b/xen/include/asm-arm/iommu.h new file mode 100644 index 0000000..81eec83 --- /dev/null +++ b/xen/include/asm-arm/iommu.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. +*/ +#ifndef __ARCH_ARM_IOMMU_H__ +#define __ARCH_ARM_IOMMU_H__ + +/* Always share P2M Table between the CPU and the IOMMU */ +#define iommu_use_hap_pt(d) (1) +#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu) + +const struct iommu_ops *iommu_get_ops(void); +void __init iommu_set_ops(const struct iommu_ops *ops); + +int __init iommu_hardware_setup(void); + +#endif /* __ARCH_ARM_IOMMU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */