static int shm_seek(lua_State *L) { const char *const modes[] = { "set", "cur", "end", NULL }; lua_apr_shm *object; size_t offset; int mode; object = check_shm(L, 1); mode = luaL_checkoption(L, 2, "cur", modes); offset = luaL_optlong(L, 3, 0); if (mode == 1) { /* CUR */ offset += object->last_op->index; } else if (mode == 2) { /* END */ offset += object->last_op->limit - 1; } luaL_argcheck(L, offset >= 0, 2, "cannot seek before start of shared memory segment!"); luaL_argcheck(L, offset < object->size, 2, "cannot seek past end of shared memory segment!"); object->input.buffer.index = offset; object->output.buffer.index = offset; lua_pushinteger(L, offset); return 1; }
static int shm_destroy(lua_State *L) { lua_apr_shm *object; apr_status_t status; object = check_shm(L, 1); status = shm_destroy_real(object); return push_status(L, status); }
static int shm_detach(lua_State *L) { apr_status_t status; lua_apr_shm *object; object = check_shm(L, 1); status = apr_shm_detach(object->handle); return push_status(L, status); }
static int shm_tostring(lua_State *L) { lua_apr_shm *object; object = check_shm(L, 1); if (object->handle != NULL) lua_pushfstring(L, "%s (%p)", lua_apr_shm_type.friendlyname, object); else lua_pushfstring(L, "%s (closed)", lua_apr_shm_type.friendlyname); return 1; }
int init_info(t_info *info) { key_t key; char path[1024]; getcwd(path, sizeof(path)); key = ftok(path, 0); info->nb_team = 0; if (check_shm(key, info) < 0) return (-1); if (check_sem(key, info) < 0) return (-1); info->share = (t_share*)shmat(info->shm, NULL, 0); info->share->nb_connect++; return (0); }
static int shm_gc(lua_State *L) { shm_destroy_real(check_shm(L, 1)); return 0; }
static int shm_write(lua_State *L) { lua_apr_shm *object = check_shm(L, 1); object->last_op = &object->output.buffer; return write_buffer(L, &object->output); }
static int shm_read(lua_State *L) { lua_apr_shm *object = check_shm(L, 1); object->last_op = &object->input.buffer; return read_buffer(L, &object->input); }
static int _copy_op(struct tee_session *sess, struct tee_cmd_io *cmd_io, struct tee_cmd *cmd) { int res = -EINVAL; int idx; TEEC_Operation op; struct tee_data *param = &cmd->param; struct tee *tee; struct tee_context *ctx; BUG_ON(!sess->ctx); BUG_ON(!sess->ctx->tee); ctx = sess->ctx; tee = sess->ctx->tee; dev_dbg(_DEV(tee), "%s: > sessid=%08x\n", __func__, sess->sessid); if (tee_context_copy_from_client (sess->ctx, &op, cmd_io->op, sizeof(TEEC_Operation))) goto out; cmd->param.type_original = op.paramTypes; if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE)) { param->type = cmd->param.type_original; res = 0; goto out; } for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { int type = TEEC_PARAM_TYPE_GET(op.paramTypes, idx); switch (type) { case TEEC_NONE: break; case TEEC_VALUE_INPUT: case TEEC_VALUE_OUTPUT: case TEEC_VALUE_INOUT: param->params[idx].value = op.params[idx].value; dev_dbg(_DEV_TEE, "%s: param[%d]:type=%d,a=%08x,b=%08x (VALUE)\n", __func__, idx, type, param->params[idx].value.a, param->params[idx].value.b); break; case TEEC_MEMREF_TEMP_INPUT: case TEEC_MEMREF_TEMP_OUTPUT: case TEEC_MEMREF_TEMP_INOUT: dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p,s=%zu (TMPREF)\n", idx, type, op.params[idx].tmpref.buffer, op.params[idx].tmpref.size); param->params[idx].shm = tee_context_create_tmpref_buffer(sess->ctx, op.params[idx]. tmpref.size, op.params[idx]. tmpref.buffer, type); if (IS_ERR_OR_NULL(param->params[idx].shm)) return -ENOMEM; dev_dbg(_DEV_TEE, "< %d %p:%zu (TMPREF)\n", idx, (void *)param->params[idx].shm->paddr, param->params[idx].shm->size_req); break; case TEEC_MEMREF_WHOLE: if (sess->ctx->usr_client) { if (tee_copy_from_user(ctx, ¶m->c_shm[idx], op.params[idx].memref. parent, sizeof (TEEC_SharedMemory))) { res = TEEC_ERROR_BAD_PARAMETERS; goto out; } } else param->c_shm[idx] = *op.params[idx].memref.parent; BUG_ON(!param->c_shm[idx].buffer); BUG_ON(!param->c_shm[idx].size); if (param->c_shm[idx].flags == TEEC_MEM_INPUT) type = TEEC_MEMREF_TEMP_INPUT; else if (param->c_shm[idx].flags == TEEC_MEM_OUTPUT) type = TEEC_MEMREF_TEMP_OUTPUT; else if (param->c_shm[idx].flags == (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) type = TEEC_MEMREF_TEMP_INOUT; if (check_shm (tee, (struct tee_shm_io *)¶m->c_shm[idx])) { dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p, s=%zu (WHOLE)\n", idx, type, op.params[idx].tmpref.buffer, param->c_shm[idx].size); param->params[idx].shm = tee_context_create_tmpref_buffer(sess->ctx, param->c_shm[idx].size, param->c_shm[idx].buffer, type); if (IS_ERR_OR_NULL(param->params[idx].shm)) return -ENOMEM; dev_dbg(_DEV_TEE, "< %d %p:%zu (WHOLE)\n", idx, (void *)param->params[idx].shm->paddr, param->params[idx].shm->size_req); } else { struct tee_shm *shm; /* The buffer is already allocated by the tee * get a reference on it */ shm = tee_shm_get(sess->ctx, (struct tee_shm_io *)¶m-> c_shm[idx]); if (!shm) /* not allocated by us, * is it a use case ? */ BUG_ON(1); param->params[idx].shm = devm_kzalloc(tee->dev, sizeof(struct tee_shm), GFP_KERNEL); if (!param->params[idx].shm) return -ENOMEM; param->params[idx].shm->parent = shm; param->params[idx].shm->ctx = sess->ctx; param->params[idx].shm->tee = tee; param->params[idx].shm->dev = tee->dev; param->params[idx].shm->size_req = param->c_shm[idx].size; param->params[idx].shm->size_alloc = 0; param->params[idx].shm->kaddr = shm->kaddr; param->params[idx].shm->paddr = shm->paddr; param->params[idx].shm->flags = shm->flags | TEE_SHM_PARENT; } break; case TEEC_MEMREF_PARTIAL_INPUT: case TEEC_MEMREF_PARTIAL_OUTPUT: case TEEC_MEMREF_PARTIAL_INOUT:{ uint32_t offset = op.params[idx].memref.offset; uint32_t size = op.params[idx].memref.size; if (sess->ctx->usr_client) { if (tee_copy_from_user (ctx, ¶m->c_shm[idx], op.params[idx].memref.parent, sizeof(TEEC_SharedMemory))) { res = TEEC_ERROR_BAD_PARAMETERS; goto out; } } else param->c_shm[idx] = *op.params[idx].memref.parent; dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p, offset=%x s=%d (PARTIAL)\n", idx, type, param->c_shm[idx].buffer, offset, size); if (type == TEEC_MEMREF_PARTIAL_INPUT) type = TEEC_MEMREF_TEMP_INPUT; else if (type == TEEC_MEMREF_PARTIAL_OUTPUT) type = TEEC_MEMREF_TEMP_OUTPUT; else if (type == TEEC_MEMREF_PARTIAL_INOUT) type = TEEC_MEMREF_TEMP_INOUT; if (check_shm (tee, (struct tee_shm_io *)¶m->c_shm[idx])) { param->params[idx].shm = tee_context_create_tmpref_buffer (sess->ctx, size, param->c_shm[idx].buffer + offset, type); if (IS_ERR_OR_NULL( param->params[idx].shm)) return -ENOMEM; } else { struct tee_shm *shm; /* The buffer is already allocated by * the tee * get a reference on it */ shm = tee_shm_get(sess->ctx, (struct tee_shm_io *) ¶m->c_shm[idx]); if (!shm) /* not allocated by us, * is it a use case ? */ BUG_ON(1); param->params[idx].shm = devm_kzalloc(tee->dev, sizeof(struct tee_shm), GFP_KERNEL); if (!param->params[idx].shm) return -ENOMEM; param->params[idx].shm->parent = shm; param->params[idx].shm->ctx = sess->ctx; param->params[idx].shm->tee = tee; param->params[idx].shm->dev = tee->dev; param->params[idx].shm->size_req = size; param->params[idx].shm->size_alloc = 0; param->params[idx].shm->kaddr = shm->kaddr + offset; param->params[idx].shm->paddr = shm->paddr + offset; param->params[idx].shm->flags = shm->flags | TEE_SHM_PARENT; } dev_dbg(_DEV_TEE, "< %d %p:%zu (PARTIAL)\n", idx, (void *)param->params[idx].shm->paddr, param->params[idx].shm->size_req); break; } default: BUG_ON(1); } param->type |= (type << (idx * 4)); } res = 0; out: dev_dbg(_DEV(tee), "%s: < fd=%d\n", __func__, res); return res; }