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>
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"
ifneq ($(CONFIG_NO_PLAT),y)
subdir-y += platforms
endif
+subdir-$(CONFIG_TEE) += tee
obj-$(CONFIG_HAS_ALTERNATIVE) += alternative.o
obj-y += bootfdt.init.o
#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>
return -EINVAL;
}
+ if ( config->arch.tee_type != XEN_DOMCTL_CONFIG_TEE_NONE )
+ {
+ dprintk(XENLOG_INFO, "Unsupported TEE type\n");
+ return -EINVAL;
+ }
+
return 0;
}
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);
/*
*/
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 */
#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>
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);
--- /dev/null
+obj-y += tee.o
--- /dev/null
+/*
+ * 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:
+ */
#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>
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;
}
}
_aedevice = .;
} :text
+ . = ALIGN(8);
+ .teemediator.info : {
+ _steemediator = .;
+ *(.teemediator.info)
+ _eteemediator = .;
+ } :text
+
. = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
.init.text : {
/* Continuable domain_relinquish_resources(). */
enum {
RELMEM_not_started,
+ RELMEM_tee,
RELMEM_xen,
RELMEM_page,
RELMEM_mapping,
--- /dev/null
+/*
+ * 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:
+ */
#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