|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v2] arm: dom0less: add TEE support
Extend TEE mediator interface with two functions :
- tee_get_type_from_dts() returns TEE type based on input string
- tee_make_dtb_node() creates a DTB entry for the selected
TEE mediator
Use those new functions to parse "xen,tee" DTS property for dom0less
guests and enable appropriate TEE mediator.
Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>
---
This is still RFC because I am not happy how I decide if
tee_make_dtb_node() needs to be called.
TEE type is stored in d_cfg, but d_cfg is not passed to
construct_domU()->prepare_dtb_domU(). So right now I am relying on
fact that every TEE mediator initilizes d->arch.tee.
Also I am sorry about previous completely botched version of this
patch. I really messed it up, including absence of [RFC] tag :(
---
docs/misc/arm/device-tree/booting.txt | 17 +++++++++++++
xen/arch/arm/dom0less-build.c | 19 +++++++++++++++
xen/arch/arm/include/asm/tee/tee.h | 13 ++++++++++
xen/arch/arm/tee/ffa.c | 8 ++++++
xen/arch/arm/tee/optee.c | 35 +++++++++++++++++++++++++++
xen/arch/arm/tee/tee.c | 21 ++++++++++++++++
6 files changed, 113 insertions(+)
diff --git a/docs/misc/arm/device-tree/booting.txt
b/docs/misc/arm/device-tree/booting.txt
index bbd955e9c2..711a6080b5 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -231,6 +231,23 @@ with the following properties:
In the future other possible property values might be added to
enable only selected interfaces.
+- xen,tee
+
+ A string property that describes what TEE mediator should be enabled
+ for the domain. Possible property values are:
+
+ - "none" (or missing property value)
+ No TEE will be available in the VM.
+
+ - "OP-TEE"
+ VM will have access to the OP-TEE using classic OP-TEE SMC interface.
+
+ - "FF-A"
+ VM will have access to a TEE using generic FF-A interface.
+
+ In the future other TEE mediators may be added, extending possible
+ values for this property.
+
- xen,domain-p2m-mem-mb
Optional. A 32-bit integer specifying the amount of megabytes of RAM
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index fb63ec6fd1..13fdd44eef 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -15,6 +15,7 @@
#include <asm/domain_build.h>
#include <asm/static-memory.h>
#include <asm/static-shmem.h>
+#include <asm/tee/tee.h>
bool __init is_dom0less_mode(void)
{
@@ -650,6 +651,10 @@ static int __init prepare_dtb_domU(struct domain *d,
struct kernel_info *kinfo)
if ( ret )
goto err;
+ /* We are making assumption that every mediator sets d->arch.tee */
+ if ( d->arch.tee )
+ tee_make_dtb_node(kinfo->fdt);
+
/*
* domain_handle_dtb_bootmodule has to be called before the rest of
* the device tree is generated because it depends on the value of
@@ -871,6 +876,7 @@ void __init create_domUs(void)
unsigned int flags = 0U;
uint32_t val;
int rc;
+ const char *tee_name;
if ( !dt_device_is_compatible(node, "xen,domain") )
continue;
@@ -881,6 +887,19 @@ void __init create_domUs(void)
if ( dt_find_property(node, "xen,static-mem", NULL) )
flags |= CDF_staticmem;
+ tee_name = dt_get_property(node, "xen,tee", NULL);
+ if ( tee_name )
+ {
+ rc = tee_get_type_from_dts(tee_name);
+ if ( rc < 0)
+ panic("Can't enable requested TEE for domain: %d\n", rc);
+ d_cfg.arch.tee_type = rc;
+ }
+ else
+ {
+ d_cfg.arch.tee_type = XEN_DOMCTL_CONFIG_TEE_NONE;
+ }
+
if ( dt_property_read_bool(node, "direct-map") )
{
if ( !(flags & CDF_staticmem) )
diff --git a/xen/arch/arm/include/asm/tee/tee.h
b/xen/arch/arm/include/asm/tee/tee.h
index da324467e1..9626667545 100644
--- a/xen/arch/arm/include/asm/tee/tee.h
+++ b/xen/arch/arm/include/asm/tee/tee.h
@@ -36,6 +36,9 @@ struct tee_mediator_ops {
int (*domain_init)(struct domain *d);
int (*domain_teardown)(struct domain *d);
+ /* Make DTB node that describes TEE. Used when creating a dom0less domain
*/
+ int (*make_dtb_node)(void *fdt);
+
/*
* Called during domain destruction to relinquish resources used
* by mediator itself. This function can return -ERESTART to indicate
@@ -65,7 +68,9 @@ bool tee_handle_call(struct cpu_user_regs *regs);
int tee_domain_init(struct domain *d, uint16_t tee_type);
int tee_domain_teardown(struct domain *d);
int tee_relinquish_resources(struct domain *d);
+int tee_make_dtb_node(void *fdt);
uint16_t tee_get_type(void);
+int tee_get_type_from_dts(const char* prop_value);
#define REGISTER_TEE_MEDIATOR(_name, _namestr, _type, _ops) \
static const struct tee_mediator_desc __tee_desc_##_name __used \
@@ -105,6 +110,14 @@ static inline uint16_t tee_get_type(void)
return XEN_DOMCTL_CONFIG_TEE_NONE;
}
+static inline int tee_get_type_from_dts(const char* prop_value)
+{
+ if ( !strcmp(prop_value, "none") )
+ return XEN_DOMCTL_CONFIG_TEE_NONE;
+
+ return -ENODEV;
+}
+
#endif /* CONFIG_TEE */
#endif /* __ARCH_ARM_TEE_TEE_H__ */
diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
index 0793c1c758..f315d6eef6 100644
--- a/xen/arch/arm/tee/ffa.c
+++ b/xen/arch/arm/tee/ffa.c
@@ -1752,6 +1752,13 @@ err_free_ffa_rx:
return false;
}
+static int ffa_make_dtb_node(void *fdt)
+{
+ /* FF-A is not configured via dtb */
+
+ return 0;
+}
+
static const struct tee_mediator_ops ffa_ops =
{
.probe = ffa_probe,
@@ -1759,6 +1766,7 @@ static const struct tee_mediator_ops ffa_ops =
.domain_teardown = ffa_domain_teardown,
.relinquish_resources = ffa_relinquish_resources,
.handle_call = ffa_handle_call,
+ .make_dtb_node = ffa_make_dtb_node,
};
REGISTER_TEE_MEDIATOR(ffa, "FF-A", XEN_DOMCTL_CONFIG_TEE_FFA, &ffa_ops);
diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c
index 5151bd90ed..5eb5d01813 100644
--- a/xen/arch/arm/tee/optee.c
+++ b/xen/arch/arm/tee/optee.c
@@ -28,6 +28,7 @@
#include <xen/domain_page.h>
#include <xen/err.h>
#include <xen/guest_access.h>
+#include <xen/libfdt/libfdt.h>
#include <xen/mm.h>
#include <xen/sched.h>
@@ -1722,6 +1723,39 @@ static bool optee_handle_call(struct cpu_user_regs *regs)
}
}
+static int __init optee_make_dtb_node(void *fdt)
+{
+ int res;
+
+ res = fdt_begin_node(fdt, "firmware");
+ if ( res )
+ return res;
+
+ res = fdt_begin_node(fdt, "optee");
+ if ( res )
+ return res;
+
+ res = fdt_property_string(fdt, "compatible", "linaro,optee-tz");
+ if ( res )
+ return res;
+
+ res = fdt_property_string(fdt, "method", "hvc");
+ if ( res )
+ return res;
+
+ /* end of "optee" */
+ res = fdt_end_node(fdt);
+ if ( res )
+ return res;
+
+ /* end of "firmware" */
+ res = fdt_end_node(fdt);
+ if ( res )
+ return res;
+
+ return 0;
+}
+
static const struct tee_mediator_ops optee_ops =
{
.probe = optee_probe,
@@ -1729,6 +1763,7 @@ static const struct tee_mediator_ops optee_ops =
.domain_teardown = optee_domain_teardown,
.relinquish_resources = optee_relinquish_resources,
.handle_call = optee_handle_call,
+ .make_dtb_node = optee_make_dtb_node,
};
REGISTER_TEE_MEDIATOR(optee, "OP-TEE", XEN_DOMCTL_CONFIG_TEE_OPTEE,
&optee_ops);
diff --git a/xen/arch/arm/tee/tee.c b/xen/arch/arm/tee/tee.c
index ddd17506a9..6388166e17 100644
--- a/xen/arch/arm/tee/tee.c
+++ b/xen/arch/arm/tee/tee.c
@@ -68,6 +68,14 @@ int tee_relinquish_resources(struct domain *d)
return cur_mediator->ops->relinquish_resources(d);
}
+int tee_make_dtb_node(void *fdt)
+{
+ if ( !cur_mediator )
+ return -ENODEV;
+
+ return cur_mediator->ops->make_dtb_node(fdt);
+}
+
uint16_t tee_get_type(void)
{
if ( !cur_mediator )
@@ -76,6 +84,19 @@ uint16_t tee_get_type(void)
return cur_mediator->tee_type;
}
+int tee_get_type_from_dts(const char* prop_value)
+{
+ if ( !strcmp(prop_value, "none") )
+ return XEN_DOMCTL_CONFIG_TEE_NONE;
+
+ if ( !cur_mediator )
+ return -ENODEV;
+
+ if ( !strcmp(prop_value, cur_mediator->name) )
+ return cur_mediator->tee_type;
+
+ return -ENODEV;
+}
static int __init tee_init(void)
{
--
2.45.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |