Message ID | 20190611184541.7281-2-volodymyr_babchuk@epam.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | TEE mediator (and OP-TEE) support in XEN | expand |
On Tue, 11 Jun 2019, Volodymyr Babchuk wrote: > This patch adds basic framework for TEE mediators. Guests can't talk > to TEE directly, we need some entity that will intercept request > and decide what to do with them. "TEE mediator" is a such entity. > > This is how it works: user can build XEN with multiple TEE mediators > (see the next patches, where OP-TEE mediator is introduced). > TEE mediator register self with REGISTER_TEE_MEDIATOR() macro in the > same way, as device drivers use DT_DEVICE_START()/DT_DEVICE_END() > macros. > > At run-time, during initialization, framework calls probe() function > for each available mediator driver to find which TEE is installed > on the platform. Then generic vSMC handler will call selected mediator > when it intercept SMC/HVC that belongs to TEE OS or TEE application. > > Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com> > Reviewed-by: Julien Grall <julien.grall@arm.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org> > --- > Changes from v5: > - Fixed bug, when XEN won't boot with CONFIG_TEE=n > - Fixed coding style > - Added __read_mostly attribute to *cur_mediator variable > > Changes from v4: > - Added tee_get_type() function, which returns id of currently > available TEE > - Removed "dom0_tee_enabled" command line option. Dom0 now always > uses currently available TEE. > - Added TEE type sanity check in arch_sanitise_domain_config() > - tee_domain_init() now internally checks if requested TEE type > corresponds to available TEE > - removed tee_domain_destroy() function because it is not used > by anyone > > Changes from v3: > > - tee_enable() renamed to tee_domain_init() > - Added tee_relinquish_resources() function along with > changes to domain_relinquish_resources() > - Added command-line parameter dom0_tee_enabled, which controls > if tee is enabled for Dom0. It is disabled by default > - Instead of boolean tee state (enabled/disabled) I introduced > enumeration with two values: none or native. It is possible > to add other types of tee in the future > > Changes from v2: > - Removed empty tee/Kconfig file > > Changes from v1: > - Removed tee_remove() function > - CONFIG_TEE depends on EXPERT > - tee_domain_created() converted to tee_enable() > - tee_init() is called using initcall() mechanism > - tee_handle_smc() renamed to tee_handle_call() > > Changes from "RFC" version: > - renamed CONFIG_ARM_TEE to CONFIG_TEE > - changed discovery mechanism: instead of UUID mathing, TEE-specific > probing is used > --- > MAINTAINERS | 6 ++ > xen/arch/arm/Kconfig | 7 +++ > xen/arch/arm/Makefile | 1 + > xen/arch/arm/domain.c | 18 ++++++ > xen/arch/arm/setup.c | 2 + > xen/arch/arm/tee/Makefile | 1 + > xen/arch/arm/tee/tee.c | 98 +++++++++++++++++++++++++++++ > xen/arch/arm/vsmc.c | 5 ++ > xen/arch/arm/xen.lds.S | 7 +++ > xen/include/asm-arm/domain.h | 1 + > xen/include/asm-arm/tee/tee.h | 112 ++++++++++++++++++++++++++++++++++ > xen/include/public/arch-arm.h | 5 ++ > 12 files changed, 263 insertions(+) > create mode 100644 xen/arch/arm/tee/Makefile > create mode 100644 xen/arch/arm/tee/tee.c > create mode 100644 xen/include/asm-arm/tee/tee.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 6fbdc2bdcb..ab32e7f409 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -381,6 +381,12 @@ F: config/Stubdom.mk.in > F: m4/stubdom.m4 > F: stubdom/ > > +TEE MEDIATORS > +M: Volodymyr Babchuk <volodymyr_babchuk@epam.com> > +S: Supported > +F: xen/arch/arm/tee/ > +F: xen/include/asm-arm/tee > + > TOOLSTACK > M: Ian Jackson <ian.jackson@eu.citrix.com> > M: Wei Liu <wl@xen.org> > diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig > index 585b57f023..caaf377a33 100644 > --- a/xen/arch/arm/Kconfig > +++ b/xen/arch/arm/Kconfig > @@ -106,6 +106,13 @@ config HARDEN_BRANCH_PREDICTOR > > If unsure, say Y. > > +config TEE > + bool "Enable TEE mediators support" if EXPERT = "y" > + default n > + help > + This option enables generic TEE mediators support. It allows guests > + to access real TEE via one of TEE mediators implemented in XEN. > + > endmenu > > menu "ARM errata workaround via the alternative framework" > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index cb902cb6fe..5c2aa34557 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -5,6 +5,7 @@ subdir-$(CONFIG_ACPI) += acpi > ifneq ($(CONFIG_NO_PLAT),y) > subdir-y += platforms > endif > +subdir-$(CONFIG_TEE) += tee > > obj-$(CONFIG_HAS_ALTERNATIVE) += alternative.o > obj-y += bootfdt.init.o > diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c > index ad1b106bd7..d27a137f7a 100644 > --- a/xen/arch/arm/domain.c > +++ b/xen/arch/arm/domain.c > @@ -32,6 +32,7 @@ > #include <asm/platform.h> > #include <asm/procinfo.h> > #include <asm/regs.h> > +#include <asm/tee/tee.h> > #include <asm/vfp.h> > #include <asm/vgic.h> > #include <asm/vtimer.h> > @@ -647,6 +648,12 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config) > return -EINVAL; > } > > + if ( config->arch.tee_type != XEN_DOMCTL_CONFIG_TEE_NONE ) > + { > + dprintk(XENLOG_INFO, "Unsupported TEE type\n"); > + return -EINVAL; > + } > + > return 0; > } > > @@ -704,6 +711,9 @@ int arch_domain_create(struct domain *d, > if ( (rc = domain_vtimer_init(d, &config->arch)) != 0 ) > goto fail; > > + if ( (rc = tee_domain_init(d, config->arch.tee_type)) != 0 ) > + goto fail; > + > update_domain_wallclock_time(d); > > /* > @@ -948,6 +958,14 @@ int domain_relinquish_resources(struct domain *d) > */ > domain_vpl011_deinit(d); > > + d->arch.relmem = RELMEM_tee; > + /* Fallthrough */ > + > + case RELMEM_tee: > + ret = tee_relinquish_resources(d); > + if (ret ) > + return ret; > + > d->arch.relmem = RELMEM_xen; > /* Fallthrough */ > > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index 5af49c7a08..1643f91f1c 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -49,6 +49,7 @@ > #include <asm/platform.h> > #include <asm/procinfo.h> > #include <asm/setup.h> > +#include <asm/tee/tee.h> > #include <xsm/xsm.h> > #include <asm/acpi.h> > > @@ -894,6 +895,7 @@ void __init start_xen(unsigned long boot_phys_offset, > dom0_cfg.arch.nr_spis = min(gic_number_lines(), (unsigned int) 992) - 32; > if ( gic_number_lines() > 992 ) > printk(XENLOG_WARNING "Maximum number of vGIC IRQs exceeded.\n"); > + dom0_cfg.arch.tee_type = tee_get_type(); > dom0_cfg.max_vcpus = dom0_max_vcpus(); > > dom0 = domain_create(0, &dom0_cfg, true); > diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile > new file mode 100644 > index 0000000000..c54d4796ff > --- /dev/null > +++ b/xen/arch/arm/tee/Makefile > @@ -0,0 +1 @@ > +obj-y += tee.o > diff --git a/xen/arch/arm/tee/tee.c b/xen/arch/arm/tee/tee.c > new file mode 100644 > index 0000000000..3964a8a5cd > --- /dev/null > +++ b/xen/arch/arm/tee/tee.c > @@ -0,0 +1,98 @@ > +/* > + * xen/arch/arm/tee/tee.c > + * > + * Generic part of TEE mediator subsystem > + * > + * Volodymyr Babchuk <volodymyr_babchuk@epam.com> > + * Copyright (c) 2018-2019 EPAM Systems. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * 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 <xen/errno.h> > +#include <xen/init.h> > +#include <xen/types.h> > + > +#include <asm/tee/tee.h> > + > +extern const struct tee_mediator_desc _steemediator[], _eteemediator[]; > +static const struct tee_mediator_desc __read_mostly *cur_mediator; > + > +/* > + * TODO: Add function to alter Dom0 DTB, so we can properly describe > + * present TEE. > + */ > + > +bool tee_handle_call(struct cpu_user_regs *regs) > +{ > + if ( unlikely(!cur_mediator) ) > + return false; > + > + return cur_mediator->ops->handle_call(regs); > +} > + > +int tee_domain_init(struct domain *d, uint16_t tee_type) > +{ > + if ( tee_type == XEN_DOMCTL_CONFIG_TEE_NONE ) > + return 0; > + > + if ( !cur_mediator ) > + return -ENODEV; > + > + if ( cur_mediator->tee_type != tee_type ) > + return -EINVAL; > + > + return cur_mediator->ops->domain_init(d); > +} > + > +int tee_relinquish_resources(struct domain *d) > +{ > + if ( !cur_mediator ) > + return 0; > + > + return cur_mediator->ops->relinquish_resources(d); > +} > + > +uint16_t tee_get_type(void) > +{ > + if ( !cur_mediator ) > + return XEN_DOMCTL_CONFIG_TEE_NONE; > + > + return cur_mediator->tee_type; > +} > + > + > +static int __init tee_init(void) > +{ > + const struct tee_mediator_desc *desc; > + > + for ( desc = _steemediator; desc != _eteemediator; desc++ ) > + { > + if ( desc->ops->probe() ) > + { > + printk(XENLOG_INFO "Using TEE mediator for %s\n", desc->name); > + cur_mediator = desc; > + return 0; > + } > + } > + > + return 0; > +} > + > +__initcall(tee_init); > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c > index c72b9a04ff..f8e350311d 100644 > --- a/xen/arch/arm/vsmc.c > +++ b/xen/arch/arm/vsmc.c > @@ -23,6 +23,7 @@ > #include <asm/monitor.h> > #include <asm/regs.h> > #include <asm/smccc.h> > +#include <asm/tee/tee.h> > #include <asm/traps.h> > #include <asm/vpsci.h> > #include <asm/platform.h> > @@ -276,6 +277,10 @@ static bool vsmccc_handle_call(struct cpu_user_regs *regs) > case ARM_SMCCC_OWNER_SIP: > handled = platform_smc(regs); > break; > + case ARM_SMCCC_OWNER_TRUSTED_APP ... ARM_SMCCC_OWNER_TRUSTED_APP_END: > + case ARM_SMCCC_OWNER_TRUSTED_OS ... ARM_SMCCC_OWNER_TRUSTED_OS_END: > + handled = tee_handle_call(regs); > + break; > } > } > > diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S > index 1e72906477..e664c4441a 100644 > --- a/xen/arch/arm/xen.lds.S > +++ b/xen/arch/arm/xen.lds.S > @@ -137,6 +137,13 @@ SECTIONS > _aedevice = .; > } :text > > + . = ALIGN(8); > + .teemediator.info : { > + _steemediator = .; > + *(.teemediator.info) > + _eteemediator = .; > + } :text > + > . = ALIGN(PAGE_SIZE); /* Init code and data */ > __init_begin = .; > .init.text : { > diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h > index 312fec8932..0f15372098 100644 > --- a/xen/include/asm-arm/domain.h > +++ b/xen/include/asm-arm/domain.h > @@ -58,6 +58,7 @@ struct arch_domain > /* Continuable domain_relinquish_resources(). */ > enum { > RELMEM_not_started, > + RELMEM_tee, > RELMEM_xen, > RELMEM_page, > RELMEM_mapping, > diff --git a/xen/include/asm-arm/tee/tee.h b/xen/include/asm-arm/tee/tee.h > new file mode 100644 > index 0000000000..f483986385 > --- /dev/null > +++ b/xen/include/asm-arm/tee/tee.h > @@ -0,0 +1,112 @@ > +/* > + * xen/include/asm-arm/tee/tee.h > + * > + * Generic part of TEE mediator subsystem > + * > + * Volodymyr Babchuk <volodymyr_babchuk@epam.com> > + * Copyright (c) 2018 EPAM Systems. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#ifndef __ARCH_ARM_TEE_TEE_H__ > +#define __ARCH_ARM_TEE_TEE_H__ > + > +#include <xen/lib.h> > +#include <xen/types.h> > + > +#include <asm/regs.h> > + > +#ifdef CONFIG_TEE > + > +struct tee_mediator_ops { > + /* > + * Probe for TEE. Should return true if TEE found and > + * mediator is initialized. > + */ > + bool (*probe)(void); > + > + /* > + * Called during domain construction if toolstack requests to enable > + * TEE support so mediator can inform TEE about new > + * guest and create own structures for the new domain. > + */ > + int (*domain_init)(struct domain *d); > + > + /* > + * Called during domain destruction to relinquish resources used > + * by mediator itself. This function can return -ERESTART to indicate > + * that it does not finished work and should be called again. > + */ > + int (*relinquish_resources)(struct domain *d); > + > + /* Handle SMCCC call for current domain. */ > + bool (*handle_call)(struct cpu_user_regs *regs); > +}; > + > +struct tee_mediator_desc { > + /* Printable name of the TEE. */ > + const char *name; > + > + /* Mediator callbacks as described above. */ > + const struct tee_mediator_ops *ops; > + > + /* > + * ID of TEE. Corresponds to xen_arch_domainconfig.tee_type. > + * Should be one of XEN_DOMCTL_CONFIG_TEE_xxx > + */ > + uint16_t tee_type; > +}; > + > +bool tee_handle_call(struct cpu_user_regs *regs); > +int tee_domain_init(struct domain *d, uint16_t tee_type); > +int tee_relinquish_resources(struct domain *d); > +uint16_t tee_get_type(void); > + > +#define REGISTER_TEE_MEDIATOR(_name, _namestr, _type, _ops) \ > +static const struct tee_mediator_desc __tee_desc_##_name __used \ > +__section(".teemediator.info") = { \ > + .name = _namestr, \ > + .ops = _ops, \ > + .tee_type = _type \ > +} > + > +#else > + > +static inline bool tee_handle_call(struct cpu_user_regs *regs) > +{ > + return false; > +} > + > +static inline int tee_domain_init(struct domain *d, uint16_t tee_type) > +{ > + if ( likely(tee_type == XEN_DOMCTL_CONFIG_TEE_NONE) ) > + return 0; > + > + return -ENODEV; > +} > + > +static inline int tee_relinquish_resources(struct domain *d) > +{ > + return 0; > +} > + > +static inline uint16_t tee_get_type(void) > +{ > + return XEN_DOMCTL_CONFIG_TEE_NONE; > +} > + > +#endif /* CONFIG_TEE */ > + > +#endif /* __ARCH_ARM_TEE_TEE_H__ */ > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h > index eb424e8286..bb69c380ec 100644 > --- a/xen/include/public/arch-arm.h > +++ b/xen/include/public/arch-arm.h > @@ -304,10 +304,15 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); > #define XEN_DOMCTL_CONFIG_GIC_NATIVE 0 > #define XEN_DOMCTL_CONFIG_GIC_V2 1 > #define XEN_DOMCTL_CONFIG_GIC_V3 2 > + > +#define XEN_DOMCTL_CONFIG_TEE_NONE 0 > + > struct xen_arch_domainconfig { > /* IN/OUT */ > uint8_t gic_version; > /* IN */ > + uint16_t tee_type; > + /* IN */ > uint32_t nr_spis; > /* > * OUT > -- > 2.21.0 >
diff --git a/MAINTAINERS b/MAINTAINERS index 6fbdc2bdcb..ab32e7f409 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -381,6 +381,12 @@ F: config/Stubdom.mk.in F: m4/stubdom.m4 F: stubdom/ +TEE MEDIATORS +M: Volodymyr Babchuk <volodymyr_babchuk@epam.com> +S: Supported +F: xen/arch/arm/tee/ +F: xen/include/asm-arm/tee + TOOLSTACK M: Ian Jackson <ian.jackson@eu.citrix.com> M: Wei Liu <wl@xen.org> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index 585b57f023..caaf377a33 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -106,6 +106,13 @@ config HARDEN_BRANCH_PREDICTOR If unsure, say Y. +config TEE + bool "Enable TEE mediators support" if EXPERT = "y" + default n + help + This option enables generic TEE mediators support. It allows guests + to access real TEE via one of TEE mediators implemented in XEN. + endmenu menu "ARM errata workaround via the alternative framework" diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index cb902cb6fe..5c2aa34557 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -5,6 +5,7 @@ subdir-$(CONFIG_ACPI) += acpi ifneq ($(CONFIG_NO_PLAT),y) subdir-y += platforms endif +subdir-$(CONFIG_TEE) += tee obj-$(CONFIG_HAS_ALTERNATIVE) += alternative.o obj-y += bootfdt.init.o diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index ad1b106bd7..d27a137f7a 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -32,6 +32,7 @@ #include <asm/platform.h> #include <asm/procinfo.h> #include <asm/regs.h> +#include <asm/tee/tee.h> #include <asm/vfp.h> #include <asm/vgic.h> #include <asm/vtimer.h> @@ -647,6 +648,12 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config) return -EINVAL; } + if ( config->arch.tee_type != XEN_DOMCTL_CONFIG_TEE_NONE ) + { + dprintk(XENLOG_INFO, "Unsupported TEE type\n"); + return -EINVAL; + } + return 0; } @@ -704,6 +711,9 @@ int arch_domain_create(struct domain *d, if ( (rc = domain_vtimer_init(d, &config->arch)) != 0 ) goto fail; + if ( (rc = tee_domain_init(d, config->arch.tee_type)) != 0 ) + goto fail; + update_domain_wallclock_time(d); /* @@ -948,6 +958,14 @@ int domain_relinquish_resources(struct domain *d) */ domain_vpl011_deinit(d); + d->arch.relmem = RELMEM_tee; + /* Fallthrough */ + + case RELMEM_tee: + ret = tee_relinquish_resources(d); + if (ret ) + return ret; + d->arch.relmem = RELMEM_xen; /* Fallthrough */ diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 5af49c7a08..1643f91f1c 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -49,6 +49,7 @@ #include <asm/platform.h> #include <asm/procinfo.h> #include <asm/setup.h> +#include <asm/tee/tee.h> #include <xsm/xsm.h> #include <asm/acpi.h> @@ -894,6 +895,7 @@ void __init start_xen(unsigned long boot_phys_offset, dom0_cfg.arch.nr_spis = min(gic_number_lines(), (unsigned int) 992) - 32; if ( gic_number_lines() > 992 ) printk(XENLOG_WARNING "Maximum number of vGIC IRQs exceeded.\n"); + dom0_cfg.arch.tee_type = tee_get_type(); dom0_cfg.max_vcpus = dom0_max_vcpus(); dom0 = domain_create(0, &dom0_cfg, true); diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile new file mode 100644 index 0000000000..c54d4796ff --- /dev/null +++ b/xen/arch/arm/tee/Makefile @@ -0,0 +1 @@ +obj-y += tee.o diff --git a/xen/arch/arm/tee/tee.c b/xen/arch/arm/tee/tee.c new file mode 100644 index 0000000000..3964a8a5cd --- /dev/null +++ b/xen/arch/arm/tee/tee.c @@ -0,0 +1,98 @@ +/* + * xen/arch/arm/tee/tee.c + * + * Generic part of TEE mediator subsystem + * + * Volodymyr Babchuk <volodymyr_babchuk@epam.com> + * Copyright (c) 2018-2019 EPAM Systems. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 <xen/errno.h> +#include <xen/init.h> +#include <xen/types.h> + +#include <asm/tee/tee.h> + +extern const struct tee_mediator_desc _steemediator[], _eteemediator[]; +static const struct tee_mediator_desc __read_mostly *cur_mediator; + +/* + * TODO: Add function to alter Dom0 DTB, so we can properly describe + * present TEE. + */ + +bool tee_handle_call(struct cpu_user_regs *regs) +{ + if ( unlikely(!cur_mediator) ) + return false; + + return cur_mediator->ops->handle_call(regs); +} + +int tee_domain_init(struct domain *d, uint16_t tee_type) +{ + if ( tee_type == XEN_DOMCTL_CONFIG_TEE_NONE ) + return 0; + + if ( !cur_mediator ) + return -ENODEV; + + if ( cur_mediator->tee_type != tee_type ) + return -EINVAL; + + return cur_mediator->ops->domain_init(d); +} + +int tee_relinquish_resources(struct domain *d) +{ + if ( !cur_mediator ) + return 0; + + return cur_mediator->ops->relinquish_resources(d); +} + +uint16_t tee_get_type(void) +{ + if ( !cur_mediator ) + return XEN_DOMCTL_CONFIG_TEE_NONE; + + return cur_mediator->tee_type; +} + + +static int __init tee_init(void) +{ + const struct tee_mediator_desc *desc; + + for ( desc = _steemediator; desc != _eteemediator; desc++ ) + { + if ( desc->ops->probe() ) + { + printk(XENLOG_INFO "Using TEE mediator for %s\n", desc->name); + cur_mediator = desc; + return 0; + } + } + + return 0; +} + +__initcall(tee_init); + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c index c72b9a04ff..f8e350311d 100644 --- a/xen/arch/arm/vsmc.c +++ b/xen/arch/arm/vsmc.c @@ -23,6 +23,7 @@ #include <asm/monitor.h> #include <asm/regs.h> #include <asm/smccc.h> +#include <asm/tee/tee.h> #include <asm/traps.h> #include <asm/vpsci.h> #include <asm/platform.h> @@ -276,6 +277,10 @@ static bool vsmccc_handle_call(struct cpu_user_regs *regs) case ARM_SMCCC_OWNER_SIP: handled = platform_smc(regs); break; + case ARM_SMCCC_OWNER_TRUSTED_APP ... ARM_SMCCC_OWNER_TRUSTED_APP_END: + case ARM_SMCCC_OWNER_TRUSTED_OS ... ARM_SMCCC_OWNER_TRUSTED_OS_END: + handled = tee_handle_call(regs); + break; } } diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index 1e72906477..e664c4441a 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -137,6 +137,13 @@ SECTIONS _aedevice = .; } :text + . = ALIGN(8); + .teemediator.info : { + _steemediator = .; + *(.teemediator.info) + _eteemediator = .; + } :text + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; .init.text : { diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 312fec8932..0f15372098 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -58,6 +58,7 @@ struct arch_domain /* Continuable domain_relinquish_resources(). */ enum { RELMEM_not_started, + RELMEM_tee, RELMEM_xen, RELMEM_page, RELMEM_mapping, diff --git a/xen/include/asm-arm/tee/tee.h b/xen/include/asm-arm/tee/tee.h new file mode 100644 index 0000000000..f483986385 --- /dev/null +++ b/xen/include/asm-arm/tee/tee.h @@ -0,0 +1,112 @@ +/* + * xen/include/asm-arm/tee/tee.h + * + * Generic part of TEE mediator subsystem + * + * Volodymyr Babchuk <volodymyr_babchuk@epam.com> + * Copyright (c) 2018 EPAM Systems. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_TEE_TEE_H__ +#define __ARCH_ARM_TEE_TEE_H__ + +#include <xen/lib.h> +#include <xen/types.h> + +#include <asm/regs.h> + +#ifdef CONFIG_TEE + +struct tee_mediator_ops { + /* + * Probe for TEE. Should return true if TEE found and + * mediator is initialized. + */ + bool (*probe)(void); + + /* + * Called during domain construction if toolstack requests to enable + * TEE support so mediator can inform TEE about new + * guest and create own structures for the new domain. + */ + int (*domain_init)(struct domain *d); + + /* + * Called during domain destruction to relinquish resources used + * by mediator itself. This function can return -ERESTART to indicate + * that it does not finished work and should be called again. + */ + int (*relinquish_resources)(struct domain *d); + + /* Handle SMCCC call for current domain. */ + bool (*handle_call)(struct cpu_user_regs *regs); +}; + +struct tee_mediator_desc { + /* Printable name of the TEE. */ + const char *name; + + /* Mediator callbacks as described above. */ + const struct tee_mediator_ops *ops; + + /* + * ID of TEE. Corresponds to xen_arch_domainconfig.tee_type. + * Should be one of XEN_DOMCTL_CONFIG_TEE_xxx + */ + uint16_t tee_type; +}; + +bool tee_handle_call(struct cpu_user_regs *regs); +int tee_domain_init(struct domain *d, uint16_t tee_type); +int tee_relinquish_resources(struct domain *d); +uint16_t tee_get_type(void); + +#define REGISTER_TEE_MEDIATOR(_name, _namestr, _type, _ops) \ +static const struct tee_mediator_desc __tee_desc_##_name __used \ +__section(".teemediator.info") = { \ + .name = _namestr, \ + .ops = _ops, \ + .tee_type = _type \ +} + +#else + +static inline bool tee_handle_call(struct cpu_user_regs *regs) +{ + return false; +} + +static inline int tee_domain_init(struct domain *d, uint16_t tee_type) +{ + if ( likely(tee_type == XEN_DOMCTL_CONFIG_TEE_NONE) ) + return 0; + + return -ENODEV; +} + +static inline int tee_relinquish_resources(struct domain *d) +{ + return 0; +} + +static inline uint16_t tee_get_type(void) +{ + return XEN_DOMCTL_CONFIG_TEE_NONE; +} + +#endif /* CONFIG_TEE */ + +#endif /* __ARCH_ARM_TEE_TEE_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index eb424e8286..bb69c380ec 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -304,10 +304,15 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); #define XEN_DOMCTL_CONFIG_GIC_NATIVE 0 #define XEN_DOMCTL_CONFIG_GIC_V2 1 #define XEN_DOMCTL_CONFIG_GIC_V3 2 + +#define XEN_DOMCTL_CONFIG_TEE_NONE 0 + struct xen_arch_domainconfig { /* IN/OUT */ uint8_t gic_version; /* IN */ + uint16_t tee_type; + /* IN */ uint32_t nr_spis; /* * OUT