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. In runtime, 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. Curently TEE mediator is enabled only for Dom0. Signed-off-by: Volodymyr Babchuk <volodymyr_babc...@epam.com> --- 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 | 9 +++++ xen/arch/arm/Makefile | 1 + xen/arch/arm/domain.c | 4 ++ xen/arch/arm/domain_build.c | 4 ++ xen/arch/arm/setup.c | 1 + xen/arch/arm/shutdown.c | 1 + xen/arch/arm/tee/Kconfig | 0 xen/arch/arm/tee/Makefile | 1 + xen/arch/arm/tee/tee.c | 69 ++++++++++++++++++++++++++++++++ xen/arch/arm/vsmc.c | 5 +++ xen/arch/arm/xen.lds.S | 7 ++++ xen/include/asm-arm/tee/tee.h | 91 +++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 199 insertions(+) create mode 100644 xen/arch/arm/tee/Kconfig 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 1970100..605e6bd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -376,6 +376,12 @@ F: config/Stubdom.mk.in F: m4/stubdom.m4 F: stubdom/ +TEE MEDIATORS +M: Volodymyr Babchuk <volodymyr_babc...@epam.com> +S: Supported +F: xen/arch/arm/tee/ +F: xen/include/asm-arm/tee + TOOLSTACK M: Ian Jackson <ian.jack...@eu.citrix.com> M: Wei Liu <wei.l...@citrix.com> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index 586bc62..0968378 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -102,6 +102,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" @@ -227,3 +234,5 @@ source "arch/arm/platforms/Kconfig" source "common/Kconfig" source "drivers/Kconfig" + +source "arch/arm/tee/Kconfig" diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 37fa826..630d816 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -3,6 +3,7 @@ subdir-$(CONFIG_ARM_64) += arm64 subdir-y += platforms subdir-$(CONFIG_ARM_64) += efi subdir-$(CONFIG_ACPI) += acpi +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 4baecc2..db5f5ef 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> @@ -902,6 +903,9 @@ int domain_relinquish_resources(struct domain *d) */ domain_vpl011_deinit(d); + /* Free TEE mediator resources */ + tee_domain_destroy(d); + d->arch.relmem = RELMEM_xen; /* Fallthrough */ diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index e1c79b2..d208ec7 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -20,6 +20,7 @@ #include <asm/psci.h> #include <asm/setup.h> #include <asm/cpufeature.h> +#include <asm/tee/tee.h> #include <xen/irq.h> #include <xen/grant_table.h> @@ -2193,6 +2194,9 @@ int __init construct_dom0(struct domain *d) set_current(saved_current); p2m_restore_state(saved_current); + /* Enable TEE */ + tee_enable(d); + discard_initial_modules(); memset(regs, 0, sizeof(*regs)); diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 45f3841..680356f 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -47,6 +47,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> diff --git a/xen/arch/arm/shutdown.c b/xen/arch/arm/shutdown.c index b32f07e..30c6950 100644 --- a/xen/arch/arm/shutdown.c +++ b/xen/arch/arm/shutdown.c @@ -5,6 +5,7 @@ #include <xen/smp.h> #include <asm/platform.h> #include <asm/psci.h> +#include <asm/tee/tee.h> static void noreturn halt_this_cpu(void *arg) { diff --git a/xen/arch/arm/tee/Kconfig b/xen/arch/arm/tee/Kconfig new file mode 100644 index 0000000..e69de29 diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile new file mode 100644 index 0000000..c54d479 --- /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 0000000..7fd0148 --- /dev/null +++ b/xen/arch/arm/tee/tee.c @@ -0,0 +1,69 @@ +/* + * xen/arch/arm/tee/tee.c + * + * Generic part of TEE mediator subsystem + * + * Volodymyr Babchuk <volodymyr_babc...@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. + */ + +#include <xen/init.h> +#include <xen/errno.h> +#include <xen/types.h> +#include <asm/tee/tee.h> + +extern const struct tee_mediator_desc _steemediator[], _eteemediator[]; +static const struct tee_mediator_ops *mediator_ops; + +bool tee_handle_call(struct cpu_user_regs *regs) +{ + if ( !mediator_ops ) + return false; + + return mediator_ops->handle_call(regs); +} + +int tee_enable(struct domain *d) +{ + if ( !mediator_ops ) + return -ENODEV; + + return mediator_ops->enable(d); +} + +void tee_domain_destroy(struct domain *d) +{ + if ( !mediator_ops ) + return; + + return mediator_ops->domain_destroy(d); +} + +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); + mediator_ops = desc->ops; + 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 c4ccae6..d0199c7 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> @@ -272,6 +273,10 @@ static bool vsmccc_handle_call(struct cpu_user_regs *regs) case ARM_SMCCC_OWNER_STANDARD: handled = handle_sssc(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 245a0e0..e4a2d6e 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -133,6 +133,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/tee/tee.h b/xen/include/asm-arm/tee/tee.h new file mode 100644 index 0000000..0e8b576 --- /dev/null +++ b/xen/include/asm-arm/tee/tee.h @@ -0,0 +1,91 @@ +/* + * xen/include/asm-arm/tee/tee.h + * + * Generic part of TEE mediator subsystem + * + * Volodymyr Babchuk <volodymyr_babc...@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 (*enable)(struct domain *d); + + /* + * Called during domain destruction to inform TEE that guest is now dead + * and to destroy all resources allocated for the domain being destroyed. + */ + void (*domain_destroy)(struct domain *d); + + /* Handle SMCCC call for current domain. */ + bool (*handle_call)(struct cpu_user_regs *regs); +}; + +struct tee_mediator_desc { + /* Name of the TEE. Just for debugging purposes. */ + const char *name; + + /* Mediator callbacks as described above. */ + const struct tee_mediator_ops *ops; +}; + +bool tee_handle_call(struct cpu_user_regs *regs); +int tee_enable(struct domain *d); +void tee_domain_destroy(struct domain *d); + +#define REGISTER_TEE_MEDIATOR(_name, _namestr, _ops) \ +static const struct tee_mediator_desc __tee_desc_##_name __used \ +__section(".teemediator.info") = { \ + .name = _namestr, \ + .ops = _ops \ +} + +#else + +static inline bool tee_handle_call(struct cpu_user_regs *regs) +{ + return false; +} + +static inline int tee_enable(struct domain *d) +{ + return -ENODEV; +} + +static inline void tee_domain_destroy(struct domain *d) {} + +#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: + */ -- 2.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel