[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v3 04/11] optee: add OP-TEE mediator skeleton



Hi Volodymyr,

On 12/18/18 9:11 PM, Volodymyr Babchuk wrote:
> From: Volodymyr Babchuk <vlad.babchuk@xxxxxxxxx>
> 
> Add very basic OP-TEE mediator. It can probe for OP-TEE presence,
> tell it about domain creation/destruction and forward all known
> calls.
> 
> This is all what is needed for Dom0 to work with OP-TEE as long
> as Dom0 shares 1:1 mapped pages with OP-TEE. Any attempt to call
> OP-TEE from DomU will fail and can lead to spectacular results. Also,
> problems can arise if Dom0 uses pages mapped from other domains.
> So, this patch should not be merged without next patches in the series.

The last sentence is not necessary in the commit message. You can add it 
after "---". So it is stripped down when the patch is committed, yet we 
know it should not be merged :).

> 
> This code issues two non-preemptible calls to OP-TEE: to create and
> to destroy client context. They can't block in OP-TEE, but OP-TEE can
> wait on a splinlocks, so there is no maximal execution time
> guaranteed.

This paragraph is worrying. From the discussion we had on the previous 
version and some discussions at Linaro Connect with OP-TEE folks, I 
gathered this call should not take a long time.

In general spinlock should have no contention or wait should be limited. 
In particular, in the context of OP-TEE I would expect something is 
really wrong if you wait on a spinlock for a really long time as you 
block the normal world. So maybe this is just a misunderstanding of the 
commit message?

> 
> Signed-off-by: Volodymyr Babchuk <vlad.babchuk@xxxxxxxxx>
> ---
> 
>   Changes from v2:
>    - Fixed coding style
>    - Introduced tee/Kconfig
>    - Fixed error messages
> 
>   xen/arch/arm/Kconfig                |   2 +
>   xen/arch/arm/tee/Kconfig            |   4 +
>   xen/arch/arm/tee/Makefile           |   1 +
>   xen/arch/arm/tee/optee.c            | 151 ++++++++++++++++++++++++++++
>   xen/include/asm-arm/tee/optee_smc.h |  50 +++++++++
>   5 files changed, 208 insertions(+)
>   create mode 100644 xen/arch/arm/tee/Kconfig
>   create mode 100644 xen/arch/arm/tee/optee.c
> 
> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
> index e527b2f885..99e6f0ebb2 100644
> --- a/xen/arch/arm/Kconfig
> +++ b/xen/arch/arm/Kconfig
> @@ -237,3 +237,5 @@ source "arch/arm/platforms/Kconfig"
>   source "common/Kconfig"
>   
>   source "drivers/Kconfig"
> +
> +source "arch/arm/tee/Kconfig"
> diff --git a/xen/arch/arm/tee/Kconfig b/xen/arch/arm/tee/Kconfig
> new file mode 100644
> index 0000000000..5b829db2e9
> --- /dev/null
> +++ b/xen/arch/arm/tee/Kconfig
> @@ -0,0 +1,4 @@
> +config OPTEE
> +     bool "Enable OP-TEE mediator"
> +     default n
> +     depends on TEE
> diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile
> index c54d4796ff..982c879684 100644
> --- a/xen/arch/arm/tee/Makefile
> +++ b/xen/arch/arm/tee/Makefile
> @@ -1 +1,2 @@
>   obj-y += tee.o
> +obj-$(CONFIG_OPTEE) += optee.o
> diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c
> new file mode 100644
> index 0000000000..73ad25ee0b
> --- /dev/null
> +++ b/xen/arch/arm/tee/optee.c
> @@ -0,0 +1,151 @@
> +/*
> + * xen/arch/arm/tee/optee.c
> + *
> + * OP-TEE mediator
> + *
> + * 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/device_tree.h>
> +#include <xen/sched.h>
> +#include <asm/smccc.h>
> +#include <asm/tee/tee.h>
> +
> +#include <asm/tee/optee_msg.h>
> +#include <asm/tee/optee_smc.h>
> +
> +/* Client ID 0 is reserved for hypervisor itself */
> +#define OPTEE_CLIENT_ID(domain) (domain->domain_id + 1)

The second 'domain' should be between () to avoid macro-expansion issue.

> +
> +static bool optee_probe(void)
> +{
> +    struct dt_device_node *node;
> +    struct arm_smccc_res resp;
> +
> +    /* Check for entry in dtb  */
> +    node = dt_find_compatible_node(NULL, NULL, "linaro,optee-tz");
> +    if ( !node )
> +        return false;
> +
> +    /* Check UID */
> +    arm_smccc_smc(ARM_SMCCC_CALL_UID_FID(TRUSTED_OS_END), &resp);
> +
> +    if ( (uint32_t)resp.a0 != OPTEE_MSG_UID_0 ||
> +         (uint32_t)resp.a1 != OPTEE_MSG_UID_1 ||
> +         (uint32_t)resp.a2 != OPTEE_MSG_UID_2 ||
> +         (uint32_t)resp.a3 != OPTEE_MSG_UID_3 )
> +        return false;
> +
> +    return true;
> +}
> +
> +static int optee_enable(struct domain *d)
> +{
> +    struct arm_smccc_res resp;
> +
> +    /*
> +     * Inform OP-TEE about a new guest.
> +     * This is a "Fast" call in terms of OP-TEE. This basically
> +     * means that it can't be preempted, because there is no
> +     * thread allocated for it in OP-TEE. It is close to atomic
> +     * context in linux kernel: E.g. no blocking calls can be issued.
> +     * Also, interrupts are disabled.
> +     * Right now OP-TEE just frees allocated memory, so it should be
> +     * really fast.

The last sentence looks wrong in this context.

> +     */
> +    arm_smccc_smc(OPTEE_SMC_VM_CREATED, OPTEE_CLIENT_ID(d), 0, 0, 0, 0, 0, 0,
> +                  &resp);
> +    if ( resp.a0 != OPTEE_SMC_RETURN_OK )
> +    {
> +        gprintk(XENLOG_WARNING, "Unable to create OPTEE client: rc = 0x%X\n",
> +                (uint32_t)resp.a0);
> +        return -ENODEV;
> +    }
> +
> +    return 0;
> +}
> +
> +static void forward_call(struct cpu_user_regs *regs)
> +{
> +    struct arm_smccc_res resp;
> +
> +    arm_smccc_smc(get_user_reg(regs, 0),
> +                  get_user_reg(regs, 1),
> +                  get_user_reg(regs, 2),
> +                  get_user_reg(regs, 3),
> +                  get_user_reg(regs, 4),
> +                  get_user_reg(regs, 5),
> +                  get_user_reg(regs, 6),
> +                  OPTEE_CLIENT_ID(current->domain),
> +                  &resp);
> +
> +    set_user_reg(regs, 0, resp.a0);
> +    set_user_reg(regs, 1, resp.a1);
> +    set_user_reg(regs, 2, resp.a2);
> +    set_user_reg(regs, 3, resp.a3);
> +    set_user_reg(regs, 4, 0);
> +    set_user_reg(regs, 5, 0);
> +    set_user_reg(regs, 6, 0);
> +    set_user_reg(regs, 7, 0);
> +}
> +
> +static void optee_domain_destroy(struct domain *d)
> +{
> +    struct arm_smccc_res resp;
> +
> +    /* At this time all domain VCPUs should be stopped */
> +
> +    /*
> +     * Inform OP-TEE that domain is shutting down. This is
> +     * also a fast SMC call, like OPTEE_SMC_VM_CREATED, so
> +     * it is also non-preemptible.
> +     */
> +    arm_smccc_smc(OPTEE_SMC_VM_DESTROYED, OPTEE_CLIENT_ID(d), 0, 0, 0, 0, 0, 
> 0,
> +                  &resp);
> +}
> +
> +static bool optee_handle_call(struct cpu_user_regs *regs)
> +{
> +    switch ( get_user_reg(regs, 0) )
> +    {
> +    case OPTEE_SMC_CALLS_COUNT:
> +    case OPTEE_SMC_CALLS_UID:
> +    case OPTEE_SMC_CALLS_REVISION:
> +    case OPTEE_SMC_CALL_GET_OS_UUID:
> +    case OPTEE_SMC_FUNCID_GET_OS_REVISION:
> +    case OPTEE_SMC_ENABLE_SHM_CACHE:
> +    case OPTEE_SMC_DISABLE_SHM_CACHE:
> +    case OPTEE_SMC_GET_SHM_CONFIG:
> +    case OPTEE_SMC_EXCHANGE_CAPABILITIES:
> +    case OPTEE_SMC_CALL_WITH_ARG:
> +    case OPTEE_SMC_CALL_RETURN_FROM_RPC:
> +        forward_call(regs);
> +        return true;
> +    default:
> +        return false;
> +    }
> +}
> +
> +static const struct tee_mediator_ops optee_ops =
> +{
> +    .probe = optee_probe,
> +    .enable = optee_enable,
> +    .domain_destroy = optee_domain_destroy,
> +    .handle_call = optee_handle_call,
> +};
> +
> +REGISTER_TEE_MEDIATOR(optee, "OP-TEE", &optee_ops);
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/asm-arm/tee/optee_smc.h 
> b/xen/include/asm-arm/tee/optee_smc.h
> index 26d100e215..1c5a2479e9 100644
> --- a/xen/include/asm-arm/tee/optee_smc.h
> +++ b/xen/include/asm-arm/tee/optee_smc.h
> @@ -304,6 +304,56 @@ struct optee_smc_disable_shm_cache_result {
>   #define OPTEE_SMC_ENABLE_SHM_CACHE \
>       OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE)
>   
> +/*
> + * Inform OP-TEE about a new virtual machine
> + *
> + * Hypervisor issues this call during virtual machine (guest) creation.
> + * OP-TEE records VM_ID of new virtual machine and makes self ready
> + * to receive requests from it.
> + *
> + * Call requests usage:
> + * a0        SMC Function ID, OPTEE_SMC_VM_CREATED
> + * a1        VM_ID of newly created virtual machine
> + * a2-6 Not used
> + * a7        Hypervisor Client ID register. Must be 0, because only 
> hypervisor
> + *      can issue this call
> + *
> + * Normal return register usage:
> + * a0        OPTEE_SMC_RETURN_OK
> + * a1-7      Preserved
> + *
> + * Error return:
> + * a0        OPTEE_SMC_RETURN_ENOTAVAIL      OP-TEE has no resources for
> + *                                   another VM
> + * a1-7      Preserved
> + *
> + */
> +#define OPTEE_SMC_FUNCID_VM_CREATED  13
> +#define OPTEE_SMC_VM_CREATED \
> +     OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_VM_CREATED)
> +
> +/*
> + * Inform OP-TEE about shutdown of a virtual machine
> + *
> + * Hypervisor issues this call during virtual machine (guest) destruction.
> + * OP-TEE will clean up all resources associated with this VM.
> + *
> + * Call requests usage:
> + * a0        SMC Function ID, OPTEE_SMC_VM_DESTROYED
> + * a1        VM_ID of virtual machine being shutted down
> + * a2-6 Not used
> + * a7        Hypervisor Client ID register. Must be 0, because only 
> hypervisor
> + *      can issue this call
> + *
> + * Normal return register usage:
> + * a0        OPTEE_SMC_RETURN_OK
> + * a1-7      Preserved
> + *
> + */
> +#define OPTEE_SMC_FUNCID_VM_DESTROYED        14
> +#define OPTEE_SMC_VM_DESTROYED \
> +     OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_VM_DESTROYED)
> +
>   /*
>    * Resume from RPC (for example after processing a foreign interrupt)
>    *
> 

Cheers,

-- 
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.