1*b0104773SPascal Brand /* 2*b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 3*b0104773SPascal Brand * All rights reserved. 4*b0104773SPascal Brand * 5*b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 6*b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 7*b0104773SPascal Brand * 8*b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 9*b0104773SPascal Brand * this list of conditions and the following disclaimer. 10*b0104773SPascal Brand * 11*b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 12*b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 13*b0104773SPascal Brand * and/or other materials provided with the distribution. 14*b0104773SPascal Brand * 15*b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16*b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19*b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 26*b0104773SPascal Brand */ 27*b0104773SPascal Brand #include <kernel/tee_common_otp.h> 28*b0104773SPascal Brand #include <kernel/tee_common.h> 29*b0104773SPascal Brand #include <kernel/tee_compat.h> 30*b0104773SPascal Brand #include <tee_api_types.h> 31*b0104773SPascal Brand #include <kernel/tee_ta_manager.h> 32*b0104773SPascal Brand #include <utee_types.h> 33*b0104773SPascal Brand #include <tee/tee_svc.h> 34*b0104773SPascal Brand #include <mm/tee_mmu.h> 35*b0104773SPascal Brand #include <mm/tee_mm.h> 36*b0104773SPascal Brand #include <kernel/tee_rpc.h> 37*b0104773SPascal Brand #include <kernel/tee_rpc_types.h> 38*b0104773SPascal Brand #include <kernel/tee_time.h> 39*b0104773SPascal Brand 40*b0104773SPascal Brand #include <user_ta_header.h> 41*b0104773SPascal Brand #include <kernel/tee_core_trace.h> 42*b0104773SPascal Brand #include <kernel/tee_kta_trace.h> 43*b0104773SPascal Brand #include <kernel/chip_services.h> 44*b0104773SPascal Brand #include <tee/tee_hash.h> 45*b0104773SPascal Brand #include <tee_ltc_wrapper.h> 46*b0104773SPascal Brand 47*b0104773SPascal Brand 48*b0104773SPascal Brand void tee_svc_sys_log(const void *buf, size_t len) 49*b0104773SPascal Brand { 50*b0104773SPascal Brand char *kbuf; 51*b0104773SPascal Brand 52*b0104773SPascal Brand if (len == 0) 53*b0104773SPascal Brand return; 54*b0104773SPascal Brand 55*b0104773SPascal Brand kbuf = malloc(len); 56*b0104773SPascal Brand if (kbuf == NULL) 57*b0104773SPascal Brand return; 58*b0104773SPascal Brand 59*b0104773SPascal Brand /* log as Info/Raw traces */ 60*b0104773SPascal Brand if (tee_svc_copy_from_user(NULL, kbuf, buf, len) == TEE_SUCCESS) 61*b0104773SPascal Brand ATAMSG_RAW("%s", kbuf); 62*b0104773SPascal Brand 63*b0104773SPascal Brand free(kbuf); 64*b0104773SPascal Brand } 65*b0104773SPascal Brand 66*b0104773SPascal Brand void tee_svc_sys_panic(uint32_t code) 67*b0104773SPascal Brand { 68*b0104773SPascal Brand struct tee_ta_session *sess; 69*b0104773SPascal Brand 70*b0104773SPascal Brand if (tee_ta_get_current_session(&sess) == TEE_SUCCESS) { 71*b0104773SPascal Brand EMSG("Set session 0x%x to panicked", sess); 72*b0104773SPascal Brand sess->ctx->panicked = 1; 73*b0104773SPascal Brand sess->ctx->panic_code = code; 74*b0104773SPascal Brand 75*b0104773SPascal Brand { 76*b0104773SPascal Brand /* 77*b0104773SPascal Brand * Force panicking. This memory error will be trapped by 78*b0104773SPascal Brand * the error exception handler myErrorHandler() 79*b0104773SPascal Brand */ 80*b0104773SPascal Brand EMSG("Following 'DTLB exception in bundle'"); 81*b0104773SPascal Brand EMSG(" is generated with code %d", code); 82*b0104773SPascal Brand int *p = 0; 83*b0104773SPascal Brand *p = 1; 84*b0104773SPascal Brand } 85*b0104773SPascal Brand } else { 86*b0104773SPascal Brand DMSG("Panic called from unknown TA"); 87*b0104773SPascal Brand } 88*b0104773SPascal Brand } 89*b0104773SPascal Brand 90*b0104773SPascal Brand uint32_t tee_svc_sys_dummy(uint32_t *a) 91*b0104773SPascal Brand { 92*b0104773SPascal Brand DMSG("tee_svc_sys_dummy: a 0x%x", (unsigned int)a); 93*b0104773SPascal Brand return 0; 94*b0104773SPascal Brand } 95*b0104773SPascal Brand 96*b0104773SPascal Brand uint32_t tee_svc_sys_dummy_7args(uint32_t a1, uint32_t a2, uint32_t a3, 97*b0104773SPascal Brand uint32_t a4, uint32_t a5, uint32_t a6, 98*b0104773SPascal Brand uint32_t a7) 99*b0104773SPascal Brand { 100*b0104773SPascal Brand DMSG("tee_svc_sys_dummy_7args: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, %x, %x\n", 101*b0104773SPascal Brand a1, a2, a3, a4, a5, a6, a7); 102*b0104773SPascal Brand return 0; 103*b0104773SPascal Brand } 104*b0104773SPascal Brand 105*b0104773SPascal Brand uint32_t tee_svc_sys_nocall(void) 106*b0104773SPascal Brand { 107*b0104773SPascal Brand DMSG("No syscall"); 108*b0104773SPascal Brand return 0x1; 109*b0104773SPascal Brand } 110*b0104773SPascal Brand 111*b0104773SPascal Brand TEE_Result tee_svc_sys_get_property(uint32_t prop, tee_uaddr_t buf, size_t blen) 112*b0104773SPascal Brand { 113*b0104773SPascal Brand static const char api_vers[] = "1.0"; 114*b0104773SPascal Brand static const char descr[] = "Version N.N"; 115*b0104773SPascal Brand /* 116*b0104773SPascal Brand * Value 100 means: 117*b0104773SPascal Brand * System time based on REE-controlled timers. Can be tampered by the 118*b0104773SPascal Brand * REE. The implementation must still guarantee that the system time 119*b0104773SPascal Brand * is monotonous, i.e., successive calls to TEE_GetSystemTime must 120*b0104773SPascal Brand * return increasing values of the system time. 121*b0104773SPascal Brand */ 122*b0104773SPascal Brand static const uint32_t sys_time_prot_lvl = 100; 123*b0104773SPascal Brand static const uint32_t ta_time_prot_lvl = 100; 124*b0104773SPascal Brand struct tee_ta_session *sess; 125*b0104773SPascal Brand TEE_Result res; 126*b0104773SPascal Brand 127*b0104773SPascal Brand res = tee_ta_get_current_session(&sess); 128*b0104773SPascal Brand if (res != TEE_SUCCESS) 129*b0104773SPascal Brand return res; 130*b0104773SPascal Brand 131*b0104773SPascal Brand switch (prop) { 132*b0104773SPascal Brand case UTEE_PROP_TEE_API_VERSION: 133*b0104773SPascal Brand if (blen < sizeof(api_vers)) 134*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 135*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, api_vers, 136*b0104773SPascal Brand sizeof(api_vers)); 137*b0104773SPascal Brand 138*b0104773SPascal Brand case UTEE_PROP_TEE_DESCR: 139*b0104773SPascal Brand if (blen < sizeof(descr)) 140*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 141*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, descr, 142*b0104773SPascal Brand sizeof(descr)); 143*b0104773SPascal Brand 144*b0104773SPascal Brand case UTEE_PROP_TEE_DEV_ID: 145*b0104773SPascal Brand { 146*b0104773SPascal Brand TEE_UUID uuid; 147*b0104773SPascal Brand const size_t nslen = 4; 148*b0104773SPascal Brand uint8_t data[4 + 149*b0104773SPascal Brand FVR_DIE_ID_NUM_REGS * sizeof(uint32_t)] = { 150*b0104773SPascal Brand 'S', 'T', 'E', 'E' }; 151*b0104773SPascal Brand 152*b0104773SPascal Brand if (blen < sizeof(uuid)) 153*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 154*b0104773SPascal Brand 155*b0104773SPascal Brand if (tee_otp_get_die_id 156*b0104773SPascal Brand (data + nslen, sizeof(data) - nslen)) 157*b0104773SPascal Brand return TEE_ERROR_BAD_STATE; 158*b0104773SPascal Brand 159*b0104773SPascal Brand res = tee_hash_createdigest( 160*b0104773SPascal Brand TEE_ALG_SHA256, 161*b0104773SPascal Brand data, sizeof(data), 162*b0104773SPascal Brand (uint8_t *)&uuid, sizeof(uuid)); 163*b0104773SPascal Brand if (res != TEE_SUCCESS) 164*b0104773SPascal Brand return TEE_ERROR_BAD_STATE; 165*b0104773SPascal Brand 166*b0104773SPascal Brand /* 167*b0104773SPascal Brand * Changes the random value into and UUID as specifiec 168*b0104773SPascal Brand * in RFC 4122. The magic values are from the example 169*b0104773SPascal Brand * code in the RFC. 170*b0104773SPascal Brand * 171*b0104773SPascal Brand * TEE_UUID is defined slightly different from the RFC, 172*b0104773SPascal Brand * but close enough for our purpose. 173*b0104773SPascal Brand */ 174*b0104773SPascal Brand 175*b0104773SPascal Brand uuid.timeHiAndVersion &= 0x0fff; 176*b0104773SPascal Brand uuid.timeHiAndVersion |= 5 << 12; 177*b0104773SPascal Brand 178*b0104773SPascal Brand /* uuid.clock_seq_hi_and_reserved in the RFC */ 179*b0104773SPascal Brand uuid.clockSeqAndNode[0] &= 0x3f; 180*b0104773SPascal Brand uuid.clockSeqAndNode[0] |= 0x80; 181*b0104773SPascal Brand 182*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, &uuid, 183*b0104773SPascal Brand sizeof(TEE_UUID)); 184*b0104773SPascal Brand } 185*b0104773SPascal Brand 186*b0104773SPascal Brand case UTEE_PROP_TEE_SYS_TIME_PROT_LEVEL: 187*b0104773SPascal Brand if (blen < sizeof(sys_time_prot_lvl)) 188*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 189*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, 190*b0104773SPascal Brand &sys_time_prot_lvl, 191*b0104773SPascal Brand sizeof(sys_time_prot_lvl)); 192*b0104773SPascal Brand 193*b0104773SPascal Brand case UTEE_PROP_TEE_TA_TIME_PROT_LEVEL: 194*b0104773SPascal Brand if (blen < sizeof(ta_time_prot_lvl)) 195*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 196*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, 197*b0104773SPascal Brand &ta_time_prot_lvl, 198*b0104773SPascal Brand sizeof(ta_time_prot_lvl)); 199*b0104773SPascal Brand 200*b0104773SPascal Brand case UTEE_PROP_TEE_ARITH_MAX_BIG_INT_SIZE: 201*b0104773SPascal Brand { 202*b0104773SPascal Brand uint32_t v = LTC_MAX_BITS_PER_VARIABLE / 2; 203*b0104773SPascal Brand 204*b0104773SPascal Brand if (blen < sizeof(v)) 205*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 206*b0104773SPascal Brand 207*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, &v, 208*b0104773SPascal Brand sizeof(v)); 209*b0104773SPascal Brand } 210*b0104773SPascal Brand 211*b0104773SPascal Brand case UTEE_PROP_CLIENT_ID: 212*b0104773SPascal Brand { 213*b0104773SPascal Brand if (blen < sizeof(TEE_Identity)) 214*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 215*b0104773SPascal Brand 216*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, 217*b0104773SPascal Brand &sess->clnt_id, 218*b0104773SPascal Brand sizeof(TEE_Identity)); 219*b0104773SPascal Brand } 220*b0104773SPascal Brand case UTEE_PROP_TA_APP_ID: 221*b0104773SPascal Brand { 222*b0104773SPascal Brand if (blen < sizeof(TEE_UUID)) 223*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 224*b0104773SPascal Brand 225*b0104773SPascal Brand return tee_svc_copy_to_user(sess, (void *)buf, 226*b0104773SPascal Brand &sess->ctx->head->uuid, 227*b0104773SPascal Brand sizeof(TEE_UUID)); 228*b0104773SPascal Brand } 229*b0104773SPascal Brand 230*b0104773SPascal Brand default: 231*b0104773SPascal Brand break; 232*b0104773SPascal Brand } 233*b0104773SPascal Brand return TEE_ERROR_NOT_IMPLEMENTED; 234*b0104773SPascal Brand } 235*b0104773SPascal Brand 236*b0104773SPascal Brand /* 237*b0104773SPascal Brand * TA invokes some TA with parameter. 238*b0104773SPascal Brand * If some parameters are memory references: 239*b0104773SPascal Brand * - either the memref is inside TA private RAM: TA is not allowed to expose 240*b0104773SPascal Brand * its private RAM: use a temporary memory buffer and copy the data. 241*b0104773SPascal Brand * - or the memref is not in the TA private RAM: 242*b0104773SPascal Brand * - if the memref was mapped to the TA, TA is allowed to expose it. 243*b0104773SPascal Brand * - if so, converts memref virtual address into a physical address. 244*b0104773SPascal Brand */ 245*b0104773SPascal Brand static TEE_Result tee_svc_copy_param(struct tee_ta_session *sess, 246*b0104773SPascal Brand struct tee_ta_session *called_sess, 247*b0104773SPascal Brand uint32_t param_types, 248*b0104773SPascal Brand TEE_Param params[TEE_NUM_PARAMS], 249*b0104773SPascal Brand struct tee_ta_param *param, 250*b0104773SPascal Brand tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS], 251*b0104773SPascal Brand tee_mm_entry_t **mm) 252*b0104773SPascal Brand { 253*b0104773SPascal Brand size_t n; 254*b0104773SPascal Brand TEE_Result res; 255*b0104773SPascal Brand size_t req_mem = 0; 256*b0104773SPascal Brand size_t s; 257*b0104773SPascal Brand uint8_t *dst = 0; 258*b0104773SPascal Brand tee_paddr_t dst_pa, src_pa = 0; 259*b0104773SPascal Brand bool ta_private_memref[TEE_NUM_PARAMS]; 260*b0104773SPascal Brand 261*b0104773SPascal Brand param->types = param_types; 262*b0104773SPascal Brand if (params == NULL) { 263*b0104773SPascal Brand if (param->types != 0) 264*b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 265*b0104773SPascal Brand memset(param->params, 0, sizeof(param->params)); 266*b0104773SPascal Brand } else { 267*b0104773SPascal Brand tee_svc_copy_from_user(sess, param->params, params, 268*b0104773SPascal Brand sizeof(param->params)); 269*b0104773SPascal Brand } 270*b0104773SPascal Brand 271*b0104773SPascal Brand if ((called_sess != NULL) && 272*b0104773SPascal Brand (called_sess->ctx->static_ta == NULL) && 273*b0104773SPascal Brand (called_sess->ctx->flags & TA_FLAG_USER_MODE) == 0) { 274*b0104773SPascal Brand /* 275*b0104773SPascal Brand * kernel TA, borrow the mapping of the calling 276*b0104773SPascal Brand * during this call. 277*b0104773SPascal Brand */ 278*b0104773SPascal Brand called_sess->calling_sess = sess; 279*b0104773SPascal Brand return TEE_SUCCESS; 280*b0104773SPascal Brand } 281*b0104773SPascal Brand 282*b0104773SPascal Brand for (n = 0; n < TEE_NUM_PARAMS; n++) { 283*b0104773SPascal Brand 284*b0104773SPascal Brand ta_private_memref[n] = false; 285*b0104773SPascal Brand 286*b0104773SPascal Brand switch (TEE_PARAM_TYPE_GET(param->types, n)) { 287*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_INPUT: 288*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_OUTPUT: 289*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_INOUT: 290*b0104773SPascal Brand if (param->params[n].memref.buffer == NULL) { 291*b0104773SPascal Brand if (param->params[n].memref.size != 0) 292*b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 293*b0104773SPascal Brand break; 294*b0104773SPascal Brand } 295*b0104773SPascal Brand /* uTA cannot expose its private memory */ 296*b0104773SPascal Brand if (tee_mmu_is_vbuf_inside_ta_private(sess->ctx, 297*b0104773SPascal Brand (uintptr_t)param->params[n].memref.buffer, 298*b0104773SPascal Brand param->params[n].memref.size)) { 299*b0104773SPascal Brand 300*b0104773SPascal Brand s = TEE_ROUNDUP(param->params[n].memref.size, 301*b0104773SPascal Brand sizeof(uint32_t)); 302*b0104773SPascal Brand /* Check overflow */ 303*b0104773SPascal Brand if (req_mem + s < req_mem) 304*b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 305*b0104773SPascal Brand req_mem += s; 306*b0104773SPascal Brand ta_private_memref[n] = true; 307*b0104773SPascal Brand break; 308*b0104773SPascal Brand } 309*b0104773SPascal Brand if (!tee_mmu_is_vbuf_outside_ta_private(sess->ctx, 310*b0104773SPascal Brand (uintptr_t)param->params[n].memref.buffer, 311*b0104773SPascal Brand param->params[n].memref.size)) 312*b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 313*b0104773SPascal Brand 314*b0104773SPascal Brand if (tee_mmu_user_va2pa(sess->ctx, 315*b0104773SPascal Brand (void *)param->params[n].memref.buffer, 316*b0104773SPascal Brand (void **)&src_pa) != TEE_SUCCESS) 317*b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 318*b0104773SPascal Brand 319*b0104773SPascal Brand param->param_attr[n] = tee_mmu_user_get_cache_attr( 320*b0104773SPascal Brand sess->ctx, 321*b0104773SPascal Brand (void *)param->params[n].memref.buffer); 322*b0104773SPascal Brand 323*b0104773SPascal Brand param->params[n].memref.buffer = (void *)src_pa; 324*b0104773SPascal Brand break; 325*b0104773SPascal Brand 326*b0104773SPascal Brand default: 327*b0104773SPascal Brand break; 328*b0104773SPascal Brand } 329*b0104773SPascal Brand } 330*b0104773SPascal Brand 331*b0104773SPascal Brand if (req_mem == 0) 332*b0104773SPascal Brand return TEE_SUCCESS; 333*b0104773SPascal Brand 334*b0104773SPascal Brand /* Allocate section in secure DDR */ 335*b0104773SPascal Brand *mm = tee_mm_alloc(&tee_mm_sec_ddr, req_mem); 336*b0104773SPascal Brand if (*mm == NULL) { 337*b0104773SPascal Brand DMSG("tee_mm_alloc TEE_ERROR_GENERIC"); 338*b0104773SPascal Brand return TEE_ERROR_GENERIC; 339*b0104773SPascal Brand } 340*b0104773SPascal Brand 341*b0104773SPascal Brand /* Get the virtual address for the section in secure DDR */ 342*b0104773SPascal Brand res = tee_mmu_kmap(tee_mm_get_smem(*mm), req_mem, &dst); 343*b0104773SPascal Brand if (res != TEE_SUCCESS) 344*b0104773SPascal Brand return res; 345*b0104773SPascal Brand dst_pa = tee_mm_get_smem(*mm); 346*b0104773SPascal Brand 347*b0104773SPascal Brand for (n = 0; n < 4; n++) { 348*b0104773SPascal Brand 349*b0104773SPascal Brand if (ta_private_memref[n] == false) 350*b0104773SPascal Brand continue; 351*b0104773SPascal Brand 352*b0104773SPascal Brand s = TEE_ROUNDUP(param->params[n].memref.size, sizeof(uint32_t)); 353*b0104773SPascal Brand 354*b0104773SPascal Brand switch (TEE_PARAM_TYPE_GET(param->types, n)) { 355*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_INPUT: 356*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_INOUT: 357*b0104773SPascal Brand if (param->params[n].memref.buffer != NULL) { 358*b0104773SPascal Brand res = tee_svc_copy_from_user(sess, dst, 359*b0104773SPascal Brand param->params[n]. 360*b0104773SPascal Brand memref.buffer, 361*b0104773SPascal Brand param->params[n]. 362*b0104773SPascal Brand memref.size); 363*b0104773SPascal Brand if (res != TEE_SUCCESS) 364*b0104773SPascal Brand return res; 365*b0104773SPascal Brand 366*b0104773SPascal Brand param->param_attr[n] = 367*b0104773SPascal Brand tee_mmu_kmap_get_cache_attr(dst); 368*b0104773SPascal Brand param->params[n].memref.buffer = (void *)dst_pa; 369*b0104773SPascal Brand tmp_buf_pa[n] = dst_pa; 370*b0104773SPascal Brand dst += s; 371*b0104773SPascal Brand dst_pa += s; 372*b0104773SPascal Brand } 373*b0104773SPascal Brand break; 374*b0104773SPascal Brand 375*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_OUTPUT: 376*b0104773SPascal Brand if (param->params[n].memref.buffer != NULL) { 377*b0104773SPascal Brand param->param_attr[n] = 378*b0104773SPascal Brand tee_mmu_kmap_get_cache_attr(dst); 379*b0104773SPascal Brand param->params[n].memref.buffer = (void *)dst_pa; 380*b0104773SPascal Brand tmp_buf_pa[n] = dst_pa; 381*b0104773SPascal Brand dst += s; 382*b0104773SPascal Brand dst_pa += s; 383*b0104773SPascal Brand } 384*b0104773SPascal Brand break; 385*b0104773SPascal Brand 386*b0104773SPascal Brand default: 387*b0104773SPascal Brand continue; 388*b0104773SPascal Brand } 389*b0104773SPascal Brand } 390*b0104773SPascal Brand 391*b0104773SPascal Brand tee_mmu_kunmap(dst, req_mem); 392*b0104773SPascal Brand 393*b0104773SPascal Brand return TEE_SUCCESS; 394*b0104773SPascal Brand } 395*b0104773SPascal Brand 396*b0104773SPascal Brand /* 397*b0104773SPascal Brand * Back from execution of service: update parameters passed from TA: 398*b0104773SPascal Brand * If some parameters were memory references: 399*b0104773SPascal Brand * - either the memref was temporary: copy back data and update size 400*b0104773SPascal Brand * - or it was the original TA memref: update only the size value. 401*b0104773SPascal Brand */ 402*b0104773SPascal Brand static TEE_Result tee_svc_update_out_param( 403*b0104773SPascal Brand struct tee_ta_session *sess, 404*b0104773SPascal Brand struct tee_ta_session *called_sess, 405*b0104773SPascal Brand struct tee_ta_param *param, 406*b0104773SPascal Brand tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS], 407*b0104773SPascal Brand TEE_Param params[TEE_NUM_PARAMS]) 408*b0104773SPascal Brand { 409*b0104773SPascal Brand size_t n; 410*b0104773SPascal Brand bool have_private_mem_map = (called_sess == NULL) || 411*b0104773SPascal Brand (called_sess->ctx->static_ta != NULL) || 412*b0104773SPascal Brand ((called_sess->ctx->flags & TA_FLAG_USER_MODE) != 0); 413*b0104773SPascal Brand 414*b0104773SPascal Brand tee_ta_set_current_session(sess); 415*b0104773SPascal Brand 416*b0104773SPascal Brand for (n = 0; n < TEE_NUM_PARAMS; n++) { 417*b0104773SPascal Brand switch (TEE_PARAM_TYPE_GET(param->types, n)) { 418*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_OUTPUT: 419*b0104773SPascal Brand case TEE_PARAM_TYPE_MEMREF_INOUT: 420*b0104773SPascal Brand 421*b0104773SPascal Brand /* outside TA private => memref is valid, update size */ 422*b0104773SPascal Brand if (!tee_mmu_is_vbuf_inside_ta_private(sess->ctx, 423*b0104773SPascal Brand (uintptr_t)params[n].memref.buffer, 424*b0104773SPascal Brand param->params[n].memref.size)) { 425*b0104773SPascal Brand params[n].memref.size = 426*b0104773SPascal Brand param->params[n].memref.size; 427*b0104773SPascal Brand break; 428*b0104773SPascal Brand } 429*b0104773SPascal Brand 430*b0104773SPascal Brand /* 431*b0104773SPascal Brand * If we called a kernel TA the parameters are in shared 432*b0104773SPascal Brand * memory and no copy is needed. 433*b0104773SPascal Brand */ 434*b0104773SPascal Brand if (have_private_mem_map && 435*b0104773SPascal Brand param->params[n].memref.size <= 436*b0104773SPascal Brand params[n].memref.size) { 437*b0104773SPascal Brand uint8_t *src = 0; 438*b0104773SPascal Brand TEE_Result res; 439*b0104773SPascal Brand 440*b0104773SPascal Brand /* FIXME: TA_RAM is already mapped ! */ 441*b0104773SPascal Brand res = tee_mmu_kmap(tmp_buf_pa[n], 442*b0104773SPascal Brand param->params[n].memref.size, &src); 443*b0104773SPascal Brand if (res != TEE_SUCCESS) 444*b0104773SPascal Brand return TEE_ERROR_GENERIC; 445*b0104773SPascal Brand 446*b0104773SPascal Brand res = tee_svc_copy_to_user(sess, 447*b0104773SPascal Brand params[n].memref. 448*b0104773SPascal Brand buffer, src, 449*b0104773SPascal Brand param->params[n]. 450*b0104773SPascal Brand memref.size); 451*b0104773SPascal Brand if (res != TEE_SUCCESS) 452*b0104773SPascal Brand return res; 453*b0104773SPascal Brand tee_mmu_kunmap(src, 454*b0104773SPascal Brand param->params[n].memref.size); 455*b0104773SPascal Brand 456*b0104773SPascal Brand } 457*b0104773SPascal Brand params[n].memref.size = param->params[n].memref.size; 458*b0104773SPascal Brand break; 459*b0104773SPascal Brand 460*b0104773SPascal Brand case TEE_PARAM_TYPE_VALUE_OUTPUT: 461*b0104773SPascal Brand case TEE_PARAM_TYPE_VALUE_INOUT: 462*b0104773SPascal Brand params[n].value = param->params[n].value; 463*b0104773SPascal Brand break; 464*b0104773SPascal Brand 465*b0104773SPascal Brand default: 466*b0104773SPascal Brand continue; 467*b0104773SPascal Brand } 468*b0104773SPascal Brand } 469*b0104773SPascal Brand 470*b0104773SPascal Brand return TEE_SUCCESS; 471*b0104773SPascal Brand } 472*b0104773SPascal Brand 473*b0104773SPascal Brand /* Called when a TA calls an OpenSession on another TA */ 474*b0104773SPascal Brand TEE_Result tee_svc_open_ta_session(const TEE_UUID *dest, 475*b0104773SPascal Brand uint32_t cancel_req_to, uint32_t param_types, 476*b0104773SPascal Brand TEE_Param params[4], 477*b0104773SPascal Brand TEE_TASessionHandle *ta_sess, 478*b0104773SPascal Brand uint32_t *ret_orig) 479*b0104773SPascal Brand { 480*b0104773SPascal Brand TEE_Result res; 481*b0104773SPascal Brand uint32_t ret_o = TEE_ORIGIN_TEE; 482*b0104773SPascal Brand struct tee_ta_session *s = NULL; 483*b0104773SPascal Brand struct tee_ta_session *sess; 484*b0104773SPascal Brand tee_mm_entry_t *mm_param = NULL; 485*b0104773SPascal Brand 486*b0104773SPascal Brand TEE_UUID *uuid = malloc(sizeof(TEE_UUID)); 487*b0104773SPascal Brand struct tee_ta_param *param = malloc(sizeof(struct tee_ta_param)); 488*b0104773SPascal Brand TEE_Identity *clnt_id = malloc(sizeof(TEE_Identity)); 489*b0104773SPascal Brand tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS]; 490*b0104773SPascal Brand 491*b0104773SPascal Brand if (uuid == NULL || param == NULL || clnt_id == NULL) { 492*b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 493*b0104773SPascal Brand goto out_free_only; 494*b0104773SPascal Brand } 495*b0104773SPascal Brand 496*b0104773SPascal Brand memset(param, 0, sizeof(struct tee_ta_param)); 497*b0104773SPascal Brand 498*b0104773SPascal Brand res = tee_ta_get_current_session(&sess); 499*b0104773SPascal Brand if (res != TEE_SUCCESS) 500*b0104773SPascal Brand goto out_free_only; 501*b0104773SPascal Brand 502*b0104773SPascal Brand res = tee_svc_copy_from_user(sess, uuid, dest, sizeof(TEE_UUID)); 503*b0104773SPascal Brand if (res != TEE_SUCCESS) 504*b0104773SPascal Brand goto function_exit; 505*b0104773SPascal Brand 506*b0104773SPascal Brand clnt_id->login = TEE_LOGIN_TRUSTED_APP; 507*b0104773SPascal Brand memcpy(&clnt_id->uuid, &sess->ctx->head->uuid, sizeof(TEE_UUID)); 508*b0104773SPascal Brand 509*b0104773SPascal Brand res = tee_svc_copy_param(sess, NULL, param_types, params, param, 510*b0104773SPascal Brand tmp_buf_pa, &mm_param); 511*b0104773SPascal Brand if (res != TEE_SUCCESS) 512*b0104773SPascal Brand goto function_exit; 513*b0104773SPascal Brand 514*b0104773SPascal Brand /* 515*b0104773SPascal Brand * Find session of a multi session TA or a static TA 516*b0104773SPascal Brand * In such a case, there is no need to ask the supplicant for the TA 517*b0104773SPascal Brand * code 518*b0104773SPascal Brand */ 519*b0104773SPascal Brand res = tee_ta_open_session(&ret_o, &s, &sess->ctx->open_sessions, uuid, 520*b0104773SPascal Brand NULL, clnt_id, cancel_req_to, param); 521*b0104773SPascal Brand 522*b0104773SPascal Brand if (ret_o != TEE_ORIGIN_TEE || res != TEE_ERROR_ITEM_NOT_FOUND) 523*b0104773SPascal Brand goto function_exit; 524*b0104773SPascal Brand 525*b0104773SPascal Brand if (ret_o == TEE_ORIGIN_TEE && res == TEE_ERROR_ITEM_NOT_FOUND) { 526*b0104773SPascal Brand kta_signed_header_t *ta = NULL; 527*b0104773SPascal Brand struct tee_ta_nwumap lp; 528*b0104773SPascal Brand 529*b0104773SPascal Brand tee_mmu_set_ctx(NULL); 530*b0104773SPascal Brand 531*b0104773SPascal Brand /* Load TA */ 532*b0104773SPascal Brand res = tee_ta_rpc_load(uuid, &ta, &lp, &ret_o); 533*b0104773SPascal Brand if (res != TEE_SUCCESS) { 534*b0104773SPascal Brand tee_mmu_set_ctx(sess->ctx); 535*b0104773SPascal Brand goto function_exit; 536*b0104773SPascal Brand } 537*b0104773SPascal Brand 538*b0104773SPascal Brand res = tee_ta_open_session(&ret_o, &s, &sess->ctx->open_sessions, 539*b0104773SPascal Brand uuid, ta, clnt_id, cancel_req_to, 540*b0104773SPascal Brand param); 541*b0104773SPascal Brand tee_mmu_set_ctx(sess->ctx); 542*b0104773SPascal Brand if (res != TEE_SUCCESS) 543*b0104773SPascal Brand goto function_exit; 544*b0104773SPascal Brand 545*b0104773SPascal Brand s->ctx->nwumap = lp; 546*b0104773SPascal Brand } 547*b0104773SPascal Brand 548*b0104773SPascal Brand res = tee_svc_update_out_param(sess, NULL, param, tmp_buf_pa, params); 549*b0104773SPascal Brand if (res != TEE_SUCCESS) 550*b0104773SPascal Brand goto function_exit; 551*b0104773SPascal Brand 552*b0104773SPascal Brand function_exit: 553*b0104773SPascal Brand tee_ta_set_current_session(sess); 554*b0104773SPascal Brand 555*b0104773SPascal Brand if (mm_param != NULL) { 556*b0104773SPascal Brand TEE_Result res2; 557*b0104773SPascal Brand void *va = 0; 558*b0104773SPascal Brand 559*b0104773SPascal Brand res2 = 560*b0104773SPascal Brand tee_mmu_kmap_pa2va((void *)tee_mm_get_smem(mm_param), &va); 561*b0104773SPascal Brand if (res2 == TEE_SUCCESS) 562*b0104773SPascal Brand tee_mmu_kunmap(va, tee_mm_get_bytes(mm_param)); 563*b0104773SPascal Brand } 564*b0104773SPascal Brand tee_mm_free(mm_param); 565*b0104773SPascal Brand tee_svc_copy_to_user(sess, ta_sess, &s, sizeof(s)); 566*b0104773SPascal Brand tee_svc_copy_to_user(sess, ret_orig, &ret_o, sizeof(ret_o)); 567*b0104773SPascal Brand 568*b0104773SPascal Brand out_free_only: 569*b0104773SPascal Brand free(param); 570*b0104773SPascal Brand free(uuid); 571*b0104773SPascal Brand free(clnt_id); 572*b0104773SPascal Brand return res; 573*b0104773SPascal Brand } 574*b0104773SPascal Brand 575*b0104773SPascal Brand TEE_Result tee_svc_close_ta_session(TEE_TASessionHandle ta_sess) 576*b0104773SPascal Brand { 577*b0104773SPascal Brand TEE_Result res; 578*b0104773SPascal Brand struct tee_ta_session *sess; 579*b0104773SPascal Brand 580*b0104773SPascal Brand res = tee_ta_get_current_session(&sess); 581*b0104773SPascal Brand if (res != TEE_SUCCESS) 582*b0104773SPascal Brand return res; 583*b0104773SPascal Brand 584*b0104773SPascal Brand tee_ta_set_current_session(NULL); 585*b0104773SPascal Brand 586*b0104773SPascal Brand res = 587*b0104773SPascal Brand tee_ta_close_session((uint32_t)ta_sess, &sess->ctx->open_sessions); 588*b0104773SPascal Brand tee_ta_set_current_session(sess); 589*b0104773SPascal Brand return res; 590*b0104773SPascal Brand } 591*b0104773SPascal Brand 592*b0104773SPascal Brand TEE_Result tee_svc_invoke_ta_command(TEE_TASessionHandle ta_sess, 593*b0104773SPascal Brand uint32_t cancel_req_to, uint32_t cmd_id, 594*b0104773SPascal Brand uint32_t param_types, TEE_Param params[4], 595*b0104773SPascal Brand uint32_t *ret_orig) 596*b0104773SPascal Brand { 597*b0104773SPascal Brand TEE_Result res; 598*b0104773SPascal Brand uint32_t ret_o = TEE_ORIGIN_TEE; 599*b0104773SPascal Brand struct tee_ta_param param = { 0 }; 600*b0104773SPascal Brand TEE_Identity clnt_id; 601*b0104773SPascal Brand struct tee_ta_session *sess; 602*b0104773SPascal Brand struct tee_ta_session *called_sess = (struct tee_ta_session *)ta_sess; 603*b0104773SPascal Brand tee_mm_entry_t *mm_param = NULL; 604*b0104773SPascal Brand tee_paddr_t tmp_buf_pa[TEE_NUM_PARAMS]; 605*b0104773SPascal Brand 606*b0104773SPascal Brand res = tee_ta_get_current_session(&sess); 607*b0104773SPascal Brand if (res != TEE_SUCCESS) 608*b0104773SPascal Brand return res; 609*b0104773SPascal Brand 610*b0104773SPascal Brand res = 611*b0104773SPascal Brand tee_ta_verify_session_pointer(called_sess, 612*b0104773SPascal Brand &sess->ctx->open_sessions); 613*b0104773SPascal Brand if (res != TEE_SUCCESS) 614*b0104773SPascal Brand return res; 615*b0104773SPascal Brand 616*b0104773SPascal Brand res = tee_svc_copy_param(sess, called_sess, param_types, params, 617*b0104773SPascal Brand ¶m, tmp_buf_pa, &mm_param); 618*b0104773SPascal Brand if (res != TEE_SUCCESS) 619*b0104773SPascal Brand goto function_exit; 620*b0104773SPascal Brand 621*b0104773SPascal Brand res = 622*b0104773SPascal Brand tee_ta_invoke_command(&ret_o, called_sess, &clnt_id, cancel_req_to, 623*b0104773SPascal Brand cmd_id, ¶m); 624*b0104773SPascal Brand if (res != TEE_SUCCESS) 625*b0104773SPascal Brand goto function_exit; 626*b0104773SPascal Brand 627*b0104773SPascal Brand res = tee_svc_update_out_param(sess, called_sess, ¶m, tmp_buf_pa, 628*b0104773SPascal Brand params); 629*b0104773SPascal Brand if (res != TEE_SUCCESS) 630*b0104773SPascal Brand goto function_exit; 631*b0104773SPascal Brand 632*b0104773SPascal Brand function_exit: 633*b0104773SPascal Brand tee_ta_set_current_session(sess); 634*b0104773SPascal Brand called_sess->calling_sess = NULL; /* clear eventual borrowed mapping */ 635*b0104773SPascal Brand 636*b0104773SPascal Brand if (mm_param != NULL) { 637*b0104773SPascal Brand TEE_Result res2; 638*b0104773SPascal Brand void *va = 0; 639*b0104773SPascal Brand 640*b0104773SPascal Brand res2 = 641*b0104773SPascal Brand tee_mmu_kmap_pa2va((void *)tee_mm_get_smem(mm_param), &va); 642*b0104773SPascal Brand if (res2 == TEE_SUCCESS) 643*b0104773SPascal Brand tee_mmu_kunmap(va, tee_mm_get_bytes(mm_param)); 644*b0104773SPascal Brand } 645*b0104773SPascal Brand tee_mm_free(mm_param); 646*b0104773SPascal Brand if (ret_orig) 647*b0104773SPascal Brand tee_svc_copy_to_user(sess, ret_orig, &ret_o, sizeof(ret_o)); 648*b0104773SPascal Brand return res; 649*b0104773SPascal Brand } 650*b0104773SPascal Brand 651*b0104773SPascal Brand TEE_Result tee_svc_check_access_rights(uint32_t flags, const void *buf, 652*b0104773SPascal Brand size_t len) 653*b0104773SPascal Brand { 654*b0104773SPascal Brand TEE_Result res; 655*b0104773SPascal Brand struct tee_ta_session *s; 656*b0104773SPascal Brand 657*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 658*b0104773SPascal Brand if (res != TEE_SUCCESS) 659*b0104773SPascal Brand return res; 660*b0104773SPascal Brand 661*b0104773SPascal Brand return tee_mmu_check_access_rights(s->ctx, flags, (tee_uaddr_t)buf, 662*b0104773SPascal Brand len); 663*b0104773SPascal Brand } 664*b0104773SPascal Brand 665*b0104773SPascal Brand TEE_Result tee_svc_copy_from_user(struct tee_ta_session *sess, void *kaddr, 666*b0104773SPascal Brand const void *uaddr, size_t len) 667*b0104773SPascal Brand { 668*b0104773SPascal Brand TEE_Result res; 669*b0104773SPascal Brand struct tee_ta_session *s; 670*b0104773SPascal Brand 671*b0104773SPascal Brand if (sess == NULL) { 672*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 673*b0104773SPascal Brand if (res != TEE_SUCCESS) 674*b0104773SPascal Brand return res; 675*b0104773SPascal Brand } else { 676*b0104773SPascal Brand s = sess; 677*b0104773SPascal Brand tee_ta_set_current_session(s); 678*b0104773SPascal Brand } 679*b0104773SPascal Brand res = 680*b0104773SPascal Brand tee_mmu_check_access_rights(s->ctx, 681*b0104773SPascal Brand TEE_MEMORY_ACCESS_READ | 682*b0104773SPascal Brand TEE_MEMORY_ACCESS_ANY_OWNER, 683*b0104773SPascal Brand (tee_uaddr_t)uaddr, len); 684*b0104773SPascal Brand if (res != TEE_SUCCESS) 685*b0104773SPascal Brand return res; 686*b0104773SPascal Brand 687*b0104773SPascal Brand memcpy(kaddr, uaddr, len); 688*b0104773SPascal Brand return TEE_SUCCESS; 689*b0104773SPascal Brand } 690*b0104773SPascal Brand 691*b0104773SPascal Brand TEE_Result tee_svc_copy_to_user(struct tee_ta_session *sess, void *uaddr, 692*b0104773SPascal Brand const void *kaddr, size_t len) 693*b0104773SPascal Brand { 694*b0104773SPascal Brand TEE_Result res; 695*b0104773SPascal Brand struct tee_ta_session *s; 696*b0104773SPascal Brand 697*b0104773SPascal Brand if (sess == NULL) { 698*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 699*b0104773SPascal Brand if (res != TEE_SUCCESS) 700*b0104773SPascal Brand return res; 701*b0104773SPascal Brand } else { 702*b0104773SPascal Brand s = sess; 703*b0104773SPascal Brand tee_ta_set_current_session(s); 704*b0104773SPascal Brand } 705*b0104773SPascal Brand 706*b0104773SPascal Brand res = 707*b0104773SPascal Brand tee_mmu_check_access_rights(s->ctx, 708*b0104773SPascal Brand TEE_MEMORY_ACCESS_WRITE | 709*b0104773SPascal Brand TEE_MEMORY_ACCESS_ANY_OWNER, 710*b0104773SPascal Brand (tee_uaddr_t)uaddr, len); 711*b0104773SPascal Brand if (res != TEE_SUCCESS) 712*b0104773SPascal Brand return res; 713*b0104773SPascal Brand 714*b0104773SPascal Brand memcpy(uaddr, kaddr, len); 715*b0104773SPascal Brand return TEE_SUCCESS; 716*b0104773SPascal Brand } 717*b0104773SPascal Brand 718*b0104773SPascal Brand static bool session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time) 719*b0104773SPascal Brand { 720*b0104773SPascal Brand TEE_Time current_time; 721*b0104773SPascal Brand 722*b0104773SPascal Brand if (s->cancel_mask) 723*b0104773SPascal Brand return false; 724*b0104773SPascal Brand 725*b0104773SPascal Brand if (s->cancel) 726*b0104773SPascal Brand return true; 727*b0104773SPascal Brand 728*b0104773SPascal Brand if (s->cancel_time.seconds == UINT32_MAX) 729*b0104773SPascal Brand return false; 730*b0104773SPascal Brand 731*b0104773SPascal Brand if (curr_time != NULL) 732*b0104773SPascal Brand current_time = *curr_time; 733*b0104773SPascal Brand else if (tee_time_get_sys_time(¤t_time) != TEE_SUCCESS) 734*b0104773SPascal Brand return false; 735*b0104773SPascal Brand 736*b0104773SPascal Brand if (current_time.seconds > s->cancel_time.seconds || 737*b0104773SPascal Brand (current_time.seconds == s->cancel_time.seconds && 738*b0104773SPascal Brand current_time.millis >= s->cancel_time.millis)) { 739*b0104773SPascal Brand return true; 740*b0104773SPascal Brand } 741*b0104773SPascal Brand 742*b0104773SPascal Brand return false; 743*b0104773SPascal Brand } 744*b0104773SPascal Brand 745*b0104773SPascal Brand TEE_Result tee_svc_get_cancellation_flag(bool *cancel) 746*b0104773SPascal Brand { 747*b0104773SPascal Brand TEE_Result res; 748*b0104773SPascal Brand struct tee_ta_session *s = NULL; 749*b0104773SPascal Brand bool c; 750*b0104773SPascal Brand 751*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 752*b0104773SPascal Brand if (res != TEE_SUCCESS) 753*b0104773SPascal Brand return res; 754*b0104773SPascal Brand 755*b0104773SPascal Brand c = session_is_cancelled(s, NULL); 756*b0104773SPascal Brand 757*b0104773SPascal Brand return tee_svc_copy_to_user(s, cancel, &c, sizeof(c)); 758*b0104773SPascal Brand } 759*b0104773SPascal Brand 760*b0104773SPascal Brand TEE_Result tee_svc_unmask_cancellation(bool *old_mask) 761*b0104773SPascal Brand { 762*b0104773SPascal Brand TEE_Result res; 763*b0104773SPascal Brand struct tee_ta_session *s = NULL; 764*b0104773SPascal Brand bool m; 765*b0104773SPascal Brand 766*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 767*b0104773SPascal Brand if (res != TEE_SUCCESS) 768*b0104773SPascal Brand return res; 769*b0104773SPascal Brand 770*b0104773SPascal Brand m = s->cancel_mask; 771*b0104773SPascal Brand s->cancel_mask = false; 772*b0104773SPascal Brand return tee_svc_copy_to_user(s, old_mask, &m, sizeof(m)); 773*b0104773SPascal Brand } 774*b0104773SPascal Brand 775*b0104773SPascal Brand TEE_Result tee_svc_mask_cancellation(bool *old_mask) 776*b0104773SPascal Brand { 777*b0104773SPascal Brand TEE_Result res; 778*b0104773SPascal Brand struct tee_ta_session *s = NULL; 779*b0104773SPascal Brand bool m; 780*b0104773SPascal Brand 781*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 782*b0104773SPascal Brand if (res != TEE_SUCCESS) 783*b0104773SPascal Brand return res; 784*b0104773SPascal Brand 785*b0104773SPascal Brand m = s->cancel_mask; 786*b0104773SPascal Brand s->cancel_mask = true; 787*b0104773SPascal Brand return tee_svc_copy_to_user(s, old_mask, &m, sizeof(m)); 788*b0104773SPascal Brand } 789*b0104773SPascal Brand 790*b0104773SPascal Brand TEE_Result tee_svc_wait(uint32_t timeout) 791*b0104773SPascal Brand { 792*b0104773SPascal Brand TEE_Result res = TEE_SUCCESS; 793*b0104773SPascal Brand uint32_t mytime = 0; 794*b0104773SPascal Brand struct tee_ta_session *s; 795*b0104773SPascal Brand TEE_Time base_time; 796*b0104773SPascal Brand TEE_Time current_time; 797*b0104773SPascal Brand 798*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 799*b0104773SPascal Brand if (res != TEE_SUCCESS) 800*b0104773SPascal Brand return res; 801*b0104773SPascal Brand 802*b0104773SPascal Brand res = tee_time_get_sys_time(&base_time); 803*b0104773SPascal Brand if (res != TEE_SUCCESS) 804*b0104773SPascal Brand return res; 805*b0104773SPascal Brand 806*b0104773SPascal Brand while (true) { 807*b0104773SPascal Brand res = tee_time_get_sys_time(¤t_time); 808*b0104773SPascal Brand if (res != TEE_SUCCESS) 809*b0104773SPascal Brand return res; 810*b0104773SPascal Brand 811*b0104773SPascal Brand if (session_is_cancelled(s, ¤t_time)) 812*b0104773SPascal Brand return TEE_ERROR_CANCEL; 813*b0104773SPascal Brand 814*b0104773SPascal Brand mytime = (current_time.seconds - base_time.seconds) * 1000 + 815*b0104773SPascal Brand (int)current_time.millis - (int)base_time.millis; 816*b0104773SPascal Brand if (mytime >= timeout) 817*b0104773SPascal Brand return TEE_SUCCESS; 818*b0104773SPascal Brand 819*b0104773SPascal Brand tee_wait_specific(timeout - mytime); 820*b0104773SPascal Brand } 821*b0104773SPascal Brand 822*b0104773SPascal Brand return res; 823*b0104773SPascal Brand } 824*b0104773SPascal Brand 825*b0104773SPascal Brand TEE_Result tee_svc_get_time(enum utee_time_category cat, TEE_Time *mytime) 826*b0104773SPascal Brand { 827*b0104773SPascal Brand TEE_Result res, res2; 828*b0104773SPascal Brand struct tee_ta_session *s = NULL; 829*b0104773SPascal Brand TEE_Time t; 830*b0104773SPascal Brand 831*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 832*b0104773SPascal Brand if (res != TEE_SUCCESS) 833*b0104773SPascal Brand return res; 834*b0104773SPascal Brand 835*b0104773SPascal Brand switch (cat) { 836*b0104773SPascal Brand case UTEE_TIME_CAT_SYSTEM: 837*b0104773SPascal Brand res = tee_time_get_sys_time(&t); 838*b0104773SPascal Brand break; 839*b0104773SPascal Brand case UTEE_TIME_CAT_TA_PERSISTENT: 840*b0104773SPascal Brand res = 841*b0104773SPascal Brand tee_time_get_ta_time((const void *)&s->ctx->head->uuid, &t); 842*b0104773SPascal Brand break; 843*b0104773SPascal Brand case UTEE_TIME_CAT_REE: 844*b0104773SPascal Brand res = tee_time_get_ree_time(&t); 845*b0104773SPascal Brand break; 846*b0104773SPascal Brand default: 847*b0104773SPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 848*b0104773SPascal Brand break; 849*b0104773SPascal Brand } 850*b0104773SPascal Brand 851*b0104773SPascal Brand if (res == TEE_SUCCESS || res == TEE_ERROR_OVERFLOW) { 852*b0104773SPascal Brand res2 = tee_svc_copy_to_user(s, mytime, &t, sizeof(t)); 853*b0104773SPascal Brand if (res2 != TEE_SUCCESS) 854*b0104773SPascal Brand res = res2; 855*b0104773SPascal Brand } 856*b0104773SPascal Brand 857*b0104773SPascal Brand return res; 858*b0104773SPascal Brand } 859*b0104773SPascal Brand 860*b0104773SPascal Brand TEE_Result tee_svc_set_ta_time(const TEE_Time *mytime) 861*b0104773SPascal Brand { 862*b0104773SPascal Brand TEE_Result res; 863*b0104773SPascal Brand struct tee_ta_session *s = NULL; 864*b0104773SPascal Brand TEE_Time t; 865*b0104773SPascal Brand 866*b0104773SPascal Brand res = tee_ta_get_current_session(&s); 867*b0104773SPascal Brand if (res != TEE_SUCCESS) 868*b0104773SPascal Brand return res; 869*b0104773SPascal Brand 870*b0104773SPascal Brand res = tee_svc_copy_from_user(s, &t, mytime, sizeof(t)); 871*b0104773SPascal Brand if (res != TEE_SUCCESS) 872*b0104773SPascal Brand return res; 873*b0104773SPascal Brand 874*b0104773SPascal Brand return tee_time_set_ta_time((const void *)&s->ctx->head->uuid, &t); 875*b0104773SPascal Brand } 876