Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>
---
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_babchuk@xxxxxxxx>
+S: Supported
+F: xen/arch/arm/tee/
+F: xen/include/asm-arm/tee
+
TOOLSTACK
M: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
M: Wei Liu <wei.liu2@xxxxxxxxxx>
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_babchuk@xxxxxxxx>
+ * 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_babchuk@xxxxxxxx>
+ * 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:
+ */