From patchwork Fri Aug 18 00:22:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "lan,Tianyu" X-Patchwork-Id: 9907675 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 791D5600CC for ; Fri, 18 Aug 2017 06:32:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6ABBE28BEC for ; Fri, 18 Aug 2017 06:32:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5F70D28C43; Fri, 18 Aug 2017 06:32:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00, DATE_IN_PAST_06_12, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8BAE828BEC for ; Fri, 18 Aug 2017 06:32:35 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1diamH-00065y-1Q; Fri, 18 Aug 2017 06:29:05 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1diamG-00065s-5n for xen-devel@lists.xen.org; Fri, 18 Aug 2017 06:29:04 +0000 Received: from [85.158.137.68] by server-11.bemta-3.messagelabs.com id DA/5F-01724-F2986995; Fri, 18 Aug 2017 06:29:03 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrFLMWRWlGSWpSXmKPExsVywNxEW1evc1q kwfpONYslHxezODB6HN39mymAMYo1My8pvyKBNWPOojnMBTs8Ko49W8DcwHjVqouRk0NIoELi wt/LrCC2hACvxJFlM6DsAInVl48xdjFyAdV0MEq03P/KApJgE1CXOLF4IiOILSIgLXHt82WwI maBU4wSP+5vYQNJCAukSfR9bWQHsVkEVCVePXgJVMTBwSvgIrF8myfEAgWJKQ/fM4PYnAKWEm 1bnjNDHGQh8bhxB/sERt4FjAyrGDWKU4vKUot0jYz0kooy0zNKchMzc3QNDYz1clOLixPTU3M Sk4r1kvNzNzECw6GegYFxB+PUE36HGCU5mJREeX/PmhIpxJeUn1KZkVicEV9UmpNafIhRhoND SYK3pn1apJBgUWp6akVaZg4wMGHSEhw8SiK8K0DSvMUFibnFmekQqVOMuhwLejZ8YRJiycvPS 5US580CKRIAKcoozYMbAYuSS4yyUsK8jAwMDEI8BalFuZklqPKvGMU5GJWEed+BTOHJzCuB2/ QK6AgmoCMMW8GOKElESEk1MBblMTQ+WeT29fSvc9OeK3i/13B+7Oa3eelPXana6u1vE2dL6Pv rlp71Eb1mNzdhbXtJCaPlL2bVDXnM7FdsNd9GM8rqnonc12bD56zmsW8f8zJVPo79rxQv5M1Y 272vdM8hhRPsghnHH7vHKp1RvvEx1pNV6ewx/g05chX/vz3Kvu1+82CZlxJLcUaioRZzUXEiA PAqKLSNAgAA X-Env-Sender: tianyu.lan@intel.com X-Msg-Ref: server-14.tower-31.messagelabs.com!1503037740!110366439!1 X-Originating-IP: [192.55.52.43] X-SpamReason: No, hits=0.8 required=7.0 tests=DATE_IN_PAST_06_12 X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 51510 invoked from network); 18 Aug 2017 06:29:02 -0000 Received: from mga05.intel.com (HELO mga05.intel.com) (192.55.52.43) by server-14.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 18 Aug 2017 06:29:02 -0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga105.fm.intel.com with ESMTP; 17 Aug 2017 23:28:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.41,391,1498546800"; d="scan'208"; a="1163881158" Received: from sky-ws.sh.intel.com (HELO localhost) ([10.239.48.141]) by orsmga001.jf.intel.com with ESMTP; 17 Aug 2017 23:28:57 -0700 From: Lan Tianyu To: xen-devel@lists.xen.org Date: Thu, 17 Aug 2017 20:22:16 -0400 Message-Id: <1503015736-22315-1-git-send-email-tianyu.lan@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <20170817111841.izmp6cxiuuzj6fns@citrix.com> References: <20170817111841.izmp6cxiuuzj6fns@citrix.com> Cc: Lan Tianyu , kevin.tian@intel.com, wei.liu2@citrix.com, andrew.cooper3@citrix.com, ian.jackson@eu.citrix.com, julien.grall@arm.com, jbeulich@suse.com, chao.gao@intel.com Subject: [Xen-devel] [PATCH V2 1/25] VIOMMU: Add vIOMMU helper functions to create, destroy and query capabilities X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch is to introduct an abstract layer for arch vIOMMU implementation to deal with requests from dom0. Arch vIOMMU code needs to provide callback to perform create, destroy and query capabilities operation. Signed-off-by: Lan Tianyu --- xen/arch/x86/Kconfig | 1 + xen/arch/x86/setup.c | 1 + xen/common/Kconfig | 3 + xen/common/Makefile | 1 + xen/common/domain.c | 3 + xen/common/viommu.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/sched.h | 2 + xen/include/xen/viommu.h | 71 ++++++++++++++++++++ 8 files changed, 247 insertions(+) create mode 100644 xen/common/viommu.c create mode 100644 xen/include/xen/viommu.h diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index 30c2769..1f1de96 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -23,6 +23,7 @@ config X86 select HAS_PDX select NUMA select VGA + select VIOMMU config ARCH_DEFCONFIG string diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index db5df69..68f1631 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1513,6 +1513,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) early_msi_init(); iommu_setup(); /* setup iommu if available */ + viommu_setup(); smp_prepare_cpus(max_cpus); diff --git a/xen/common/Kconfig b/xen/common/Kconfig index dc8e876..2ad2c8d 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -49,6 +49,9 @@ config HAS_CHECKPOLICY string option env="XEN_HAS_CHECKPOLICY" +config VIOMMU + bool + config KEXEC bool "kexec support" default y diff --git a/xen/common/Makefile b/xen/common/Makefile index 26c5a64..852553d 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -56,6 +56,7 @@ obj-y += time.o obj-y += timer.o obj-y += trace.o obj-y += version.o +obj-$(CONFIG_VIOMMU) += viommu.o obj-y += virtual_region.o obj-y += vm_event.o obj-y += vmap.o diff --git a/xen/common/domain.c b/xen/common/domain.c index b22aacc..d1f9b10 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -396,6 +396,9 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags, spin_unlock(&domlist_update_lock); } + if ( (err = viommu_init_domain(d)) != 0 ) + goto fail; + return d; fail: diff --git a/xen/common/viommu.c b/xen/common/viommu.c new file mode 100644 index 0000000..6874d9f --- /dev/null +++ b/xen/common/viommu.c @@ -0,0 +1,165 @@ +/* + * common/viommu.c + * + * Copyright (c) 2017 Intel Corporation + * Author: Lan Tianyu + * + * 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, see . + */ + +#include +#include +#include +#include + +bool __read_mostly opt_viommu; +boolean_param("viommu", opt_viommu); + +static spinlock_t type_list_lock; +static struct list_head type_list; + +struct viommu_type { + u64 type; + struct viommu_ops *ops; + struct list_head node; +}; + +int viommu_init_domain(struct domain *d) +{ + d->viommu.nr_viommu = 0; + return 0; +} + +static struct viommu_type *viommu_get_type(u64 type) +{ + struct viommu_type *viommu_type = NULL; + + spin_lock(&type_list_lock); + list_for_each_entry( viommu_type, &type_list, node ) + { + if ( viommu_type->type == type ) + { + spin_unlock(&type_list_lock); + return viommu_type; + } + } + spin_unlock(&type_list_lock); + + return NULL; +} + +int viommu_register_type(u64 type, struct viommu_ops * ops) +{ + struct viommu_type *viommu_type = NULL; + + if ( !viommu_enabled() ) + return -EINVAL; + + if ( viommu_get_type(type) ) + return -EEXIST; + + viommu_type = xzalloc(struct viommu_type); + if ( !viommu_type ) + return -ENOMEM; + + viommu_type->type = type; + viommu_type->ops = ops; + + spin_lock(&type_list_lock); + list_add_tail(&viommu_type->node, &type_list); + spin_unlock(&type_list_lock); + + return 0; +} + +static int viommu_create(struct domain *d, u64 type, u64 base_address, + u64 length, u64 caps) +{ + struct viommu_info *info = &d->viommu; + struct viommu *viommu; + struct viommu_type *viommu_type = NULL; + int rc; + + viommu_type = viommu_get_type(type); + if ( !viommu_type ) + return -EINVAL; + + if ( info->nr_viommu >= NR_VIOMMU_PER_DOMAIN + || !viommu_type->ops || !viommu_type->ops->create ) + return -EINVAL; + + viommu = xzalloc(struct viommu); + if ( !viommu ) + return -ENOMEM; + + viommu->base_address = base_address; + viommu->length = length; + viommu->caps = caps; + viommu->ops = viommu_type->ops; + viommu->viommu_id = info->nr_viommu; + + info->viommu[info->nr_viommu] = viommu; + info->nr_viommu++; + + rc = viommu->ops->create(d, viommu); + if ( rc < 0 ) + { + xfree(viommu); + info->nr_viommu--; + info->viommu[info->nr_viommu] = NULL; + return rc; + } + + return viommu->viommu_id; +} + +static int viommu_destroy(struct domain *d, u32 viommu_id) +{ + struct viommu_info *info = &d->viommu; + + if ( viommu_id >= info->nr_viommu || !info->viommu[viommu_id] ) + return -EINVAL; + + if ( info->viommu[viommu_id]->ops->destroy(info->viommu[viommu_id]) ) + return -EFAULT; + + xfree(info->viommu[viommu_id]); + info->viommu[viommu_id] = NULL; + return 0; +} + +static u64 viommu_query_caps(struct domain *d, u64 type) +{ + struct viommu_type *viommu_type = viommu_get_type(type); + + if ( !viommu_type ) + return -EINVAL; + + return viommu_type->ops->query_caps(d); +} + +int __init viommu_setup(void) +{ + INIT_LIST_HEAD(&type_list); + spin_lock_init(&type_list_lock); + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 6673b27..98a965a 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -477,6 +478,7 @@ struct domain /* vNUMA topology accesses are protected by rwlock. */ rwlock_t vnuma_rwlock; struct vnuma_info *vnuma; + struct viommu_info viommu; /* Common monitor options */ struct { diff --git a/xen/include/xen/viommu.h b/xen/include/xen/viommu.h new file mode 100644 index 0000000..506ea54 --- /dev/null +++ b/xen/include/xen/viommu.h @@ -0,0 +1,71 @@ +/* + * include/xen/viommu.h + * + * Copyright (c) 2017, Intel Corporation + * Author: Lan Tianyu + * + * 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, see . + * + */ +#ifndef __XEN_VIOMMU_H__ +#define __XEN_VIOMMU_H__ + +#define NR_VIOMMU_PER_DOMAIN 1 + +struct viommu; + +struct viommu_ops { + u64 (*query_caps)(struct domain *d); + int (*create)(struct domain *d, struct viommu *viommu); + int (*destroy)(struct viommu *viommu); +}; + +struct viommu { + u64 base_address; + u64 length; + u64 caps; + u32 viommu_id; + const struct viommu_ops *ops; + void *priv; +}; + +struct viommu_info { + u32 nr_viommu; + struct viommu *viommu[NR_VIOMMU_PER_DOMAIN]; /* viommu array*/ +}; + +#ifdef CONFIG_VIOMMU +extern bool_t opt_viommu; +static inline bool viommu_enabled(void) { return opt_viommu; } +int viommu_init_domain(struct domain *d); +int viommu_register_type(u64 type, struct viommu_ops * ops); +int viommu_setup(void); +#else +static inline int viommu_init_domain(struct domain *d) { return 0; } +static inline int viommu_register_type(u64 type, struct viommu_ops * ops) +{ return 0; } +static inline int __init viommu_setup(void) { return 0; } +static inline bool viommu_enabled(void) { return false; } +#endif + +#endif /* __XEN_VIOMMU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */