All of lore.kernel.org
 help / color / mirror / Atom feed
From: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
To: Julien Grall <julien.grall@arm.com>,
	Jens Wiklander <jens.wiklander@linaro.org>
Cc: Volodymyr Babchuk <vlad.babchuk@gmail.com>,
	"xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>,
	"tee-dev@lists.linaro.org" <tee-dev@lists.linaro.org>
Subject: Re: [PATCH v3 06/11] optee: add std call handling
Date: Thu, 17 Jan 2019 15:21:10 +0000	[thread overview]
Message-ID: <87va2ntimz.fsf@epam.com> (raw)
In-Reply-To: <f4b2976d-c776-1984-c9b6-ae371aa05217@arm.com>


Hello Julien,

Julien Grall writes:

> Hi Volodymyr,
>
> On 18/12/2018 21:11, Volodymyr Babchuk wrote:
>> From: Volodymyr Babchuk <vlad.babchuk@gmail.com>
>>
>> The main way to communicate with OP-TEE is to issue standard SMCCC
>> call. "Standard" is a SMCCC term and it means that call can be
>> interrupted and OP-TEE can return control to NW before completing
>> the call.
>>
>> In contrast with fast calls, where arguments and return values
>> are passed in registers, standard calls use shared memory. Register
>> pair a1,a2 holds 64-bit PA of command buffer, where all arguments
>> are stored and which is used to return data. OP-TEE internally
>> copies contents of this buffer into own secure memory before accessing
>> and validating any data in command buffer. This is done to make sure
>> that NW will not change contents of the validated parameters.
>>
>> Mediator needs to do the same for number of reasons:
>>
>> 1. To make sure that guest will not change data after validation.
>> 2. To translate IPAs to PAs in the command buffer (this is not done
>>     in this patch).
>> 3. To hide translated address from guest, so it will not be able
>>     to do IPA->PA translation by misusing mediator.
>>
>> During standard call OP-TEE can issue multiple "RPC returns", asking
>> NW to do some work for OP-TEE. NW then issues special call
>> OPTEE_SMC_CALL_RETURN_FROM_RPC to resume handling of the original call.
>> Thus, mediator needs to maintain context for original standard call
>> during multiple SMCCC calls.
>>
>> Standard call is considered complete, when returned value is
>> not a RPC request.
>>
>> Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
>> ---
>>
>>   Changes from v2:
>>    - renamed struct domain_ctx to struct optee_domain
>>    - fixed coding style
>>    - Now I use access_guest_memory_by_ipa() instead of mappings
>>      to read command buffer
>>    - Added tracking for in flight calls, so guest can't resume
>>      the same call from two CPUs simultaniously
>>
>>   xen/arch/arm/tee/optee.c     | 319 ++++++++++++++++++++++++++++++++++-
>>   xen/include/asm-arm/domain.h |   3 +
>>   2 files changed, 320 insertions(+), 2 deletions(-)
>>
>> diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c
>> index 584241b03a..dc90e2ed8e 100644
>> --- a/xen/arch/arm/tee/optee.c
>> +++ b/xen/arch/arm/tee/optee.c
>> @@ -12,6 +12,8 @@
>>    */
>>     #include <xen/device_tree.h>
>> +#include <xen/domain_page.h>
>> +#include <xen/guest_access.h>
>>   #include <xen/sched.h>
>>   #include <asm/smccc.h>
>>   #include <asm/tee/tee.h>
>> @@ -22,11 +24,38 @@
>>   /* Client ID 0 is reserved for hypervisor itself */
>>   #define OPTEE_CLIENT_ID(domain) (domain->domain_id + 1)
>>   +/*
>> + * Maximal number of concurrent standard calls from one guest. This
>> + * corresponds to OPTEE configuration option CFG_NUM_THREADS, because
>> + * OP-TEE spawns a thread for every standard call.
>
> Looking at OP-TEE, CFG_NUM_THREADS will vary depending on the
> platform. Is there any way to probe that number of threads from Xen?
Yes, this is per-platform configuration.
Easiest way is to add Fast SMC to OP-TEE that will report this
parameter.
Jens, what do you think about adding additional call?

> In any case, I think we should update the comment to reflect that this
> seems to be the maximum CFG_NUM_THREADS supported by any upstream
> platform.

Actually, OP-TEE protocol have possibility to handle limited number of
threads correctly. OP-TEE can report that all threads are busy and
client will wait for a free one. XEN can do the same, although this is not
implemented in this patch series. But I can add this.

Basically this means that all can work correctly even with
MAX_STD_CALLS==1. It just will be not so efficient.

>> + */
>> +#define MAX_STD_CALLS   16
>> +
>>   #define OPTEE_KNOWN_NSEC_CAPS OPTEE_SMC_NSEC_CAP_UNIPROCESSOR
>>   #define OPTEE_KNOWN_SEC_CAPS (OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM | \
>>                                 OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM |  \
>>                                 OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
>>   +/*
>> + * Call context. OP-TEE can issue multiple RPC returns during one call.
>> + * We need to preserve context during them.
>> + */
>> +struct optee_std_call {
>> +    struct list_head list;
>> +    struct optee_msg_arg *xen_arg;
>> +    paddr_t guest_arg_ipa;
>> +    int optee_thread_id;
>> +    int rpc_op;
>> +    bool in_flight;
>> +};
>> +
>> +/* Domain context */
>> +struct optee_domain {
>> +    struct list_head call_list;
>> +    atomic_t call_count;
>> +    spinlock_t lock;
>> +};
>> +
>>   static bool optee_probe(void)
>>   {
>>       struct dt_device_node *node;
>> @@ -52,6 +81,11 @@ static bool optee_probe(void)
>>   static int optee_enable(struct domain *d)
>>   {
>>       struct arm_smccc_res resp;
>> +    struct optee_domain *ctx;
>> +
>> +    ctx = xzalloc(struct optee_domain);
>> +    if ( !ctx )
>> +        return -ENOMEM;
>>         /*
>>        * Inform OP-TEE about a new guest.
>> @@ -69,9 +103,16 @@ static int optee_enable(struct domain *d)
>>       {
>>           gprintk(XENLOG_WARNING, "Unable to create OPTEE client: rc = 0x%X\n",
>>                   (uint32_t)resp.a0);
>> +        xfree(ctx);
>>           return -ENODEV;
>>       }
>>   +    INIT_LIST_HEAD(&ctx->call_list);
>> +    atomic_set(&ctx->call_count, 0);
>> +    spin_lock_init(&ctx->lock);
>> +
>> +    d->arch.tee = ctx;
>> +
>>       return 0;
>>   }
>>   @@ -111,9 +152,86 @@ static void set_return(struct cpu_user_regs
>> *regs, uint32_t ret)
>>       set_user_reg(regs, 7, 0);
>>   }
>>   +static struct optee_std_call *allocate_std_call(struct
>> optee_domain *ctx)
>> +{
>> +    struct optee_std_call *call;
>> +    int count;
>> +
>> +    /* Make sure that guest does not execute more than MAX_STD_CALLS */
>> +    count = atomic_add_unless(&ctx->call_count, 1, MAX_STD_CALLS);
>> +    if ( count == MAX_STD_CALLS )
>> +        return NULL;
>> +
>> +    call = xzalloc(struct optee_std_call);
>> +    if ( !call )
>> +    {
>> +        atomic_dec(&ctx->call_count);
>> +        return NULL;
>> +    }
>> +
>> +    call->optee_thread_id = -1;
>> +    call->in_flight = true;
>> +
>> +    spin_lock(&ctx->lock);
>> +    list_add_tail(&call->list, &ctx->call_list);
>> +    spin_unlock(&ctx->lock);
>> +
>> +    return call;
>> +}
>> +
>> +static void free_std_call(struct optee_domain *ctx,
>> +                          struct optee_std_call *call)
>> +{
>> +    atomic_dec(&ctx->call_count);
>> +
>> +    spin_lock(&ctx->lock);
>> +    list_del(&call->list);
>> +    spin_unlock(&ctx->lock);
>> +
>> +    ASSERT(!call->in_flight);
>> +    xfree(call->xen_arg);
>> +    xfree(call);
>> +}
>> +
>> +static struct optee_std_call *get_std_call(struct optee_domain *ctx,
>> +                                           int thread_id)
>> +{
>> +    struct optee_std_call *call;
>> +
>> +    spin_lock(&ctx->lock);
>> +    list_for_each_entry( call, &ctx->call_list, list )
>> +    {
>> +        if ( call->optee_thread_id == thread_id )
>> +        {
>> +            if ( call->in_flight )
>> +            {
>> +                gprintk(XENLOG_WARNING, "Guest tries to execute call which is already in flight");
>> +                goto out;
>> +            }
>> +            call->in_flight = true;
>> +            spin_unlock(&ctx->lock);
>> +            return call;
>> +        }
>> +    }
>> +out:
>> +    spin_unlock(&ctx->lock);
>> +
>> +    return NULL;
>> +}
>> +
>> +static void put_std_call(struct optee_domain *ctx, struct optee_std_call *call)
>> +{
>> +    spin_lock(&ctx->lock);
>> +    ASSERT(call->in_flight);
>> +    call->in_flight = false;
>> +    spin_unlock(&ctx->lock);
>> +}
>> +
>>   static void optee_domain_destroy(struct domain *d)
>>   {
>>       struct arm_smccc_res resp;
>> +    struct optee_std_call *call, *call_tmp;
>> +    struct optee_domain *ctx = d->arch.tee;
>>
>>       /* At this time all domain VCPUs should be stopped */
>>   @@ -124,6 +242,199 @@ static void optee_domain_destroy(struct
>> domain *d)
>>        */
>>       arm_smccc_smc(OPTEE_SMC_VM_DESTROYED, OPTEE_CLIENT_ID(d), 0, 0, 0, 0, 0, 0,
>>                     &resp);
>
> This function can be called without enable and should be
> idempotent. So I woudld check d->arch.tee before and...
Nothing bad will happen if it called without call to enable.

But yes, I need to check for ctx != NULL.

>> +    ASSERT(!spin_is_locked(&ctx->lock));
>> +
>> +    list_for_each_entry_safe( call, call_tmp, &ctx->call_list, list )
>> +        free_std_call(ctx, call);
>> +
>> +    ASSERT(!atomic_read(&ctx->call_count));
>> +
>> +    xfree(d->arch.tee);
>
> use XFREE here.
Oh, looks like I missed this macro introduction. Thank you for pointing
out.

>> +}
>> +
>> +/*
>> + * Copy command buffer into xen memory to:
>> + * 1) Hide translated addresses from guest
>> + * 2) Make sure that guest wouldn't change data in command buffer during call
>> + */
>> +static bool copy_std_request(struct cpu_user_regs *regs,
>> +                             struct optee_std_call *call)
>> +{
>> +    paddr_t xen_addr;
>> +
>> +    call->guest_arg_ipa = (paddr_t)get_user_reg(regs, 1) << 32 |
>> +                            get_user_reg(regs, 2);
>
> NIT: The indentation looks weird here.
>
>> +
>> +    /*
>> +     * Command buffer should start at page boundary.
>> +     * This is OP-TEE ABI requirement.
>> +     */
>> +    if ( call->guest_arg_ipa & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1) )
>> +        return false;
>> +
>> +    call->xen_arg = _xmalloc(OPTEE_MSG_NONCONTIG_PAGE_SIZE,
>> +                             OPTEE_MSG_NONCONTIG_PAGE_SIZE);
>> +    if ( !call->xen_arg )
>> +        return false;
>> +
>> +    BUILD_BUG_ON(OPTEE_MSG_NONCONTIG_PAGE_SIZE > PAGE_SIZE);
>
> As you use _xmalloc, you should not need this. This is only necessary
> if you use alloc_xenheap_page.
>
Yes, right. This is leftover from time when I mapped guest page into
XEN. I'll move it down, to place where I map that page.

> I am wondering whether it is wise to allocate the memory from xenheap
> and not domheap. While on Arm64 (for now) xenheap and domheap are the
> same, on Arm32 they are different. The xenheap is at most 1GB, so
> pretty limited.
Honestly, I have no opinion there. What are limitations of domheap in
this case?


> Furthermore, using domheap would have the advantage to allow in the
> future accounting the allocation to the guest and add more safety
> (there are discussion to make domheap per domain).
>
>> +
>> +    access_guest_memory_by_ipa(current->domain, call->guest_arg_ipa,
>> +                               call->xen_arg, OPTEE_MSG_NONCONTIG_PAGE_SIZE,
>> +                               false);
>
> You need to check the return of access_guest_memory_by_ipa as this
> function can fail.
Will do.

>> +
>> +    xen_addr = virt_to_maddr(call->xen_arg);
>> +
>> +    set_user_reg(regs, 1, xen_addr >> 32);
>> +    set_user_reg(regs, 2, xen_addr & 0xFFFFFFFF);
>> +
>> +    return true;
>> +}
>> +
>> +static void copy_std_request_back(struct optee_domain *ctx,
>> +                                  struct cpu_user_regs *regs,
>> +                                  struct optee_std_call *call)
>
> Can you add a comment on top of the function explaining what it does?
Yes, sure.

"Copy OP-TEE response back into guest's request buffer" will be sufficient?

>> +{
>> +    struct optee_msg_arg *guest_arg;
>> +    struct page_info *page;
>> +    unsigned int i;
>> +    uint32_t attr;
>> +
>> +    /* copy_std_request() validated IPA for us */
>
> Not really, the guest is free to modify the stage-2 mapping on another
> vCPU while this is happening. I agree that the guest will shoot
> himself, but we at least need to not have weird behavior happening.
>
> In that case, I would check that the type is p2m_ram_rw as you don't
> want to write in read-only or foreign mapping.
How I can do this atomically? I.e. what if guest will mangle p2m right
after the check?

> Also, as copy_std_request() and copy_std_request_back may not be
> called in the same "thread" it would be useful if you specify a bit
> more the interaction.
I not sure what do you mean there.

>
>> +    page = get_page_from_gfn(current->domain, paddr_to_pfn(call->guest_arg_ipa),
>
> Please use gfn_x(gaddr_to_gfn(...)) to clarify this is a gfn. The
> gfn_x will be unnecessary soon with a cleanup that is currently under
> review.
So there are chances, that it will be removed when time will come to
merge this patch series? :)

>
>> +                             NULL, P2M_ALLOC);
>> +    if ( !page )
>> +        return;
>> +
>> +    guest_arg = map_domain_page(page_to_mfn(page));
>
> So here you assume that PAGE_SIZE ==
> OPTEE_MSG_NONCONTIG_PAGE_SIZE. Can you add a BUILD_BUG_ON just above
> (with a comment) so we don't get some nasty surprise with 64K support.
Yes, sure.

> Also, you should be able to use __map_domain_page(page) here.
Oh, thank you for pointing to this macro. Not the best descriptive name,
I must say.

>
>> +
>> +    guest_arg->ret = call->xen_arg->ret;
>> +    guest_arg->ret_origin = call->xen_arg->ret_origin;
>> +    guest_arg->session = call->xen_arg->session;
>
> NIT: newline here please.
>
>> +    for ( i = 0; i < call->xen_arg->num_params; i++ )
>> +    {
>> +        attr = call->xen_arg->params[i].attr;
>> +
>> +        switch ( attr & OPTEE_MSG_ATTR_TYPE_MASK )
>> +        {
>> +        case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
>> +        case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
>> +            guest_arg->params[i].u.tmem.size =
>> +                call->xen_arg->params[i].u.tmem.size;
>> +            continue;
>> +        case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
>> +        case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
>> +            guest_arg->params[i].u.value.a =
>> +                call->xen_arg->params[i].u.value.a;
>> +            guest_arg->params[i].u.value.b =
>> +                call->xen_arg->params[i].u.value.b;
>> +            continue;
>> +        case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
>> +        case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
>> +            guest_arg->params[i].u.rmem.size =
>> +                call->xen_arg->params[i].u.rmem.size;
>> +            continue;
>> +        case OPTEE_MSG_ATTR_TYPE_NONE:
>> +        case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
>> +        case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
>> +            continue;
>> +        }
>> +    }
>> +
>> +    unmap_domain_page(guest_arg);
>> +    put_page(page);
>> +}
>> +
>> +static void execute_std_call(struct optee_domain *ctx,
>> +                             struct cpu_user_regs *regs,
>> +                             struct optee_std_call *call)
>> +{
>> +    register_t optee_ret;
>> +
>> +    forward_call(regs);
>> +
>> +    optee_ret = get_user_reg(regs, 0);
>> +    if ( OPTEE_SMC_RETURN_IS_RPC(optee_ret) )
>> +    {
>> +        call->optee_thread_id = get_user_reg(regs, 3);
>> +        call->rpc_op = OPTEE_SMC_RETURN_GET_RPC_FUNC(optee_ret);
>> +        put_std_call(ctx, call);
>> +        return;
>> +    }
>> +
>> +    copy_std_request_back(ctx, regs, call);
>> +
>> +    put_std_call(ctx, call);
>> +    free_std_call(ctx, call);
>> +}
>
> Most of the code in this patch is self-explaining, which is quite nice
> :). However, I think this function would require explaining a bit the
> logic. For instance in which case the call will be freed.
Thank you :)
Yes, this depends on if call was completed or it was interrupted due to
RPC, in which case it will be resumed later. I'll add comment.

>> +
>> +static bool handle_std_call(struct optee_domain *ctx,
>> +                            struct cpu_user_regs *regs)
>> +{
>> +    struct optee_std_call *call = allocate_std_call(ctx);
>> +
>> +    if ( !call )
>> +        return false;
>> +
>> +    if ( !copy_std_request(regs, call) )
>> +        goto err;
>> +
>> +    /* Now we can safely examine contents of command buffer */
>> +    if ( OPTEE_MSG_GET_ARG_SIZE(call->xen_arg->num_params) >
>> +         OPTEE_MSG_NONCONTIG_PAGE_SIZE )
>> +        goto err;
>> +
>> +    switch ( call->xen_arg->cmd )
>> +    {
>> +    case OPTEE_MSG_CMD_OPEN_SESSION:
>> +    case OPTEE_MSG_CMD_CLOSE_SESSION:
>> +    case OPTEE_MSG_CMD_INVOKE_COMMAND:
>> +    case OPTEE_MSG_CMD_CANCEL:
>> +    case OPTEE_MSG_CMD_REGISTER_SHM:
>> +    case OPTEE_MSG_CMD_UNREGISTER_SHM:
>> +        break;
>> +    default:
>> +        goto err;
>> +    }
>> +
>> +    execute_std_call(ctx, regs, call);
>> +
>> +    return true;
>
> This function is a bit odd to read. I think it would be more clear if
> you move this code before the break.
Yes, you are right.

>> +
>> +err:
>> +    put_std_call(ctx, call);
>> +    free_std_call(ctx, call);
>> +
>> +    return false;
>> +}
>> +
>> +static bool handle_rpc(struct optee_domain *ctx, struct cpu_user_regs *regs)
>> +{
>> +    struct optee_std_call *call;
>> +    int optee_thread_id = get_user_reg(regs, 3);
>> +
>> +    call = get_std_call(ctx, optee_thread_id);
>> +
>> +    if ( !call )
>> +        return false;
>> +
>> +    switch ( call->rpc_op )
>> +    {
>> +    case OPTEE_SMC_RPC_FUNC_ALLOC:
>> +        /* TODO: Add handling */
>> +        break;
>> +    case OPTEE_SMC_RPC_FUNC_FREE:
>> +        /* TODO: Add handling */
>> +        break;
>> +    case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
>> +        break;
>> +    case OPTEE_SMC_RPC_FUNC_CMD:
>> +        /* TODO: Add handling */
>> +        break;
>> +    }
>> +
>> +    execute_std_call(ctx, regs, call);
>> +    return true;
>>   }
>>     static bool handle_exchange_capabilities(struct cpu_user_regs
>> *regs)
>> @@ -161,6 +472,8 @@ static bool handle_exchange_capabilities(struct cpu_user_regs *regs)
>>     static bool optee_handle_call(struct cpu_user_regs *regs)
>>   {
>> +    struct optee_domain *ctx = current->domain->arch.tee;
>> +
>>       switch ( get_user_reg(regs, 0) )
>>       {
>>       case OPTEE_SMC_CALLS_COUNT:
>> @@ -170,8 +483,6 @@ static bool optee_handle_call(struct cpu_user_regs *regs)
>>       case OPTEE_SMC_FUNCID_GET_OS_REVISION:
>>       case OPTEE_SMC_ENABLE_SHM_CACHE:
>>       case OPTEE_SMC_DISABLE_SHM_CACHE:
>> -    case OPTEE_SMC_CALL_WITH_ARG:
>> -    case OPTEE_SMC_CALL_RETURN_FROM_RPC:
>>           forward_call(regs);
>>           return true;
>>       case OPTEE_SMC_GET_SHM_CONFIG:
>> @@ -180,6 +491,10 @@ static bool optee_handle_call(struct cpu_user_regs *regs)
>>           return true;
>>       case OPTEE_SMC_EXCHANGE_CAPABILITIES:
>>           return handle_exchange_capabilities(regs);
>> +    case OPTEE_SMC_CALL_WITH_ARG:
>> +        return handle_std_call(ctx, regs);
>> +    case OPTEE_SMC_CALL_RETURN_FROM_RPC:
>> +        return handle_rpc(ctx, regs);
>>       default:
>>           return false;
>>       }
>> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
>> index 175de44927..88b48697bd 100644
>> --- a/xen/include/asm-arm/domain.h
>> +++ b/xen/include/asm-arm/domain.h
>> @@ -97,6 +97,9 @@ struct arch_domain
>>       struct vpl011 vpl011;
>>   #endif
>>   +#ifdef CONFIG_TEE
>> +    void *tee;
>> +#endif
>
> Did you look whether there are any hole in arch_domain that could be re-used?
I thought about that. But what are chances to find 64bit-wide,
64bit-aligned hole in a structure? If I remember C standard correctly,
there are no reasons for compiler to leave such holes.

I'm talking about aarch64 there, but I assume, that this is true for aarch32/armv7.

>>   }  __cacheline_aligned;
>>     struct arch_vcpu
>>
>
> Cheers,


--
Best regards,Volodymyr Babchuk
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2019-01-17 15:21 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-18 21:11 [PATCH v3 00/11] TEE mediator (and OP-TEE) support in XEN Volodymyr Babchuk
2018-12-18 21:11 ` [PATCH v3 01/11] arm: add generic TEE mediator framework Volodymyr Babchuk
2019-01-15 17:50   ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 03/11] arm: tee: add OP-TEE header files Volodymyr Babchuk
2018-12-18 21:11 ` [PATCH v3 02/11] arm: add tee_enabled flag to xen_arch_domainconfig Volodymyr Babchuk
2019-01-15 17:35   ` Julien Grall
2019-01-16 17:22     ` Volodymyr Babchuk
2019-01-16 17:27       ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 04/11] optee: add OP-TEE mediator skeleton Volodymyr Babchuk
2019-01-15 18:15   ` Julien Grall
2019-01-16 17:31     ` Volodymyr Babchuk
2019-01-16 17:51   ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 05/11] optee: add fast calls handling Volodymyr Babchuk
2019-01-17 18:31   ` Julien Grall
2019-01-17 19:22     ` Volodymyr Babchuk
2019-01-17 20:02       ` Julien Grall
2019-01-17 20:10         ` Volodymyr Babchuk
2019-01-18 15:29           ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 06/11] optee: add std call handling Volodymyr Babchuk
2019-01-16 18:45   ` Julien Grall
2019-01-17 15:21     ` Volodymyr Babchuk [this message]
2019-01-17 18:18       ` Julien Grall
2019-01-17 19:13         ` Volodymyr Babchuk
2019-01-17 20:00           ` Julien Grall
2019-01-17 20:14             ` Volodymyr Babchuk
2018-12-18 21:11 ` [PATCH v3 07/11] optee: add support for RPC SHM buffers Volodymyr Babchuk
2019-01-17 18:49   ` Julien Grall
2019-01-17 19:48     ` Volodymyr Babchuk
2019-01-17 20:08       ` Julien Grall
2019-01-17 21:01         ` Volodymyr Babchuk
2019-01-18 15:38           ` Julien Grall
2019-01-18 16:05             ` Volodymyr Babchuk
2019-01-18 17:51               ` Julien Grall
2019-01-18 18:29                 ` Volodymyr Babchuk
2018-12-18 21:11 ` [PATCH v3 08/11] optee: add support for arbitrary shared memory Volodymyr Babchuk
2019-01-21 11:42   ` Julien Grall
2019-02-19 15:59     ` Volodymyr Babchuk
2019-02-20 13:26       ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 09/11] optee: add support for RPC commands Volodymyr Babchuk
2019-01-21 11:58   ` Julien Grall
2019-02-19 16:14     ` Volodymyr Babchuk
2019-02-20 13:46       ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 11/11] libxl: arm: create optee firmware node in DT if tee=1 Volodymyr Babchuk
2019-01-21 12:10   ` Julien Grall
2018-12-18 21:11 ` [PATCH v3 10/11] xl: add "tee" option for xl.cfg Volodymyr Babchuk
2019-01-21 12:08   ` Julien Grall
2018-12-19 13:25 ` [PATCH v3 00/11] TEE mediator (and OP-TEE) support in XEN Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87va2ntimz.fsf@epam.com \
    --to=volodymyr_babchuk@epam.com \
    --cc=jens.wiklander@linaro.org \
    --cc=julien.grall@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=tee-dev@lists.linaro.org \
    --cc=vlad.babchuk@gmail.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.