Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04c661c4 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mink: fixing issues in local obj handling"

parents 5dd0ceaf 83f8f704
Loading
Loading
Loading
Loading
+34 −41
Original line number Diff line number Diff line
/*
 * SMC Invoke driver
 *
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -134,6 +134,10 @@
#define FILE_IS_REMOTE_OBJ(f) ((f)->f_op && (f)->f_op == &g_smcinvoke_fops)

static DEFINE_MUTEX(g_smcinvoke_lock);
#define NO_LOCK 0
#define TAKE_LOCK 1
#define MUTEX_LOCK(x) { if (x) mutex_lock(&g_smcinvoke_lock); }
#define MUTEX_UNLOCK(x) { if (x) mutex_unlock(&g_smcinvoke_lock); }
static DEFINE_HASHTABLE(g_cb_servers, 8);
static LIST_HEAD(g_mem_objs);
static uint16_t g_last_cb_server_id = CBOBJ_SERVER_ID_START;
@@ -143,6 +147,7 @@ static size_t g_max_cb_buf_size = SMCINVOKE_TZ_MIN_BUF_SIZE;
static long smcinvoke_ioctl(struct file *, unsigned int, unsigned long);
static int smcinvoke_open(struct inode *, struct file *);
static int smcinvoke_release(struct inode *, struct file *);
static int destroy_cb_server(uint16_t);

static const struct file_operations g_smcinvoke_fops = {
	.owner		= THIS_MODULE,
@@ -280,10 +285,8 @@ static struct smcinvoke_mem_obj *find_mem_obj_locked(uint16_t mem_obj_id,
{
	struct smcinvoke_mem_obj *mem_obj = NULL;

	if (list_empty(&g_mem_objs)) {
		pr_err("%s: mem obj %d not found\n", __func__, mem_obj_id);
	if (list_empty(&g_mem_objs))
		return NULL;
	}

	list_for_each_entry(mem_obj, &g_mem_objs, list) {
		if ((is_mem_rgn_obj &&
@@ -379,9 +382,11 @@ static void free_pending_cbobj_locked(struct kref *kref)
	server = obj->server;
	kfree(obj);
	if ((server->state == SMCINVOKE_SERVER_STATE_DEFUNCT) &&
				list_empty(&server->pending_cbobjs))
				list_empty(&server->pending_cbobjs)) {
		hash_del(&server->hash);
		kfree(server);
	}
}

static int get_pending_cbobj_locked(uint16_t srvr_id, int16_t obj_id)
{
@@ -618,10 +623,6 @@ static int get_tzhandle_from_uhandle(int32_t uhandle, int32_t server_fd,
		}
	}
out:
	if (ret && *filp) {
		fput(*filp);
		*filp = NULL;
	}
	return ret;
}

@@ -669,7 +670,7 @@ static int get_fd_for_obj(uint32_t obj_type, uint32_t obj, int64_t *fd)
}

static int get_uhandle_from_tzhandle(int32_t tzhandle, int32_t srvr_id,
						int64_t *uhandle)
				int64_t *uhandle, bool lock)
{
	int ret = -1;

@@ -680,14 +681,14 @@ static int get_uhandle_from_tzhandle(int32_t tzhandle, int32_t srvr_id,
		if (srvr_id != TZHANDLE_GET_SERVER(tzhandle))
			goto out;
		*uhandle = UHANDLE_MAKE_CB_OBJ(TZHANDLE_GET_OBJID(tzhandle));
		mutex_lock(&g_smcinvoke_lock);
		ret = get_pending_cbobj_locked(srvr_id,
		MUTEX_LOCK(lock)
		ret = get_pending_cbobj_locked(TZHANDLE_GET_SERVER(tzhandle),
						TZHANDLE_GET_OBJID(tzhandle));
		mutex_unlock(&g_smcinvoke_lock);
		MUTEX_UNLOCK(lock)
	} else if (TZHANDLE_IS_MEM_RGN_OBJ(tzhandle)) {
		struct smcinvoke_mem_obj *mem_obj =  NULL;

		mutex_lock(&g_smcinvoke_lock);
		MUTEX_LOCK(lock)
		mem_obj = find_mem_obj_locked(TZHANDLE_GET_OBJID(tzhandle),
						SMCINVOKE_MEM_RGN_OBJ);

@@ -705,7 +706,7 @@ static int get_uhandle_from_tzhandle(int32_t tzhandle, int32_t srvr_id,
			ret = 0;
		}
exit_lock:
		mutex_unlock(&g_smcinvoke_lock);
		MUTEX_UNLOCK(lock)
	} else if (TZHANDLE_IS_REMOTE(tzhandle)) {
		/* if execution comes here => tzhandle is an unsigned int */
		ret = get_fd_for_obj(SMCINVOKE_OBJ_TYPE_TZ_OBJ,
@@ -882,9 +883,7 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp)
		    srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT &&
		    OBJECT_OP_METHODID(cb_req->hdr.op) == OBJECT_OP_RELEASE) {
			mutex_lock(&g_smcinvoke_lock);
			put_pending_cbobj_locked(
				TZHANDLE_GET_SERVER(cb_req->hdr.tzhandle),
				TZHANDLE_GET_OBJID(cb_req->hdr.tzhandle));
			release_tzhandle_locked(cb_req->hdr.tzhandle);
			mutex_unlock(&g_smcinvoke_lock);
		}
	}
@@ -937,7 +936,8 @@ static int marshal_out_invoke_req(const uint8_t *buf, uint32_t buf_size,
		 * to server who serves it and that info comes from USpace.
		 */
		ret = get_uhandle_from_tzhandle(tz_args->handle,
			args_buf[i].o.cb_server_fd, &(args_buf[i].o.fd));
					TZHANDLE_GET_SERVER(tz_args->handle),
					&(args_buf[i].o.fd), NO_LOCK);
		if (ret)
			goto out;
		tz_args++;
@@ -1152,7 +1152,7 @@ static int marshal_in_tzcb_req(const struct smcinvoke_cb_txn *cb_txn,

	user_req->txn_id = cb_txn->txn_id;
	if (get_uhandle_from_tzhandle(tzcb_req->hdr.tzhandle, srvr_id,
					(int64_t *)&user_req->cbobj_id)) {
				(int64_t *)&user_req->cbobj_id, TAKE_LOCK)) {
		ret = -EINVAL;
		goto out;
	}
@@ -1214,7 +1214,7 @@ static int marshal_in_tzcb_req(const struct smcinvoke_cb_txn *cb_txn,
		 * context
		 */
		ret = get_uhandle_from_tzhandle(tz_args[i].handle, srvr_id,
							&(tmp_arg.o.fd));
						&(tmp_arg.o.fd), TAKE_LOCK);
		if (ret) {
			ret = -EINVAL;
			goto out;
@@ -1238,10 +1238,8 @@ static int marshal_out_tzcb_req(const struct smcinvoke_accept *user_req,
	int32_t tzhandles_to_release[OBJECT_COUNTS_MAX_OO] = {0};
	struct smcinvoke_tzcb_req *tzcb_req = cb_txn->cb_req;
	union smcinvoke_tz_args *tz_args = tzcb_req->args;
	put_pending_cbobj_locked(
			TZHANDLE_GET_SERVER(cb_txn->cb_req->hdr.tzhandle),
			TZHANDLE_GET_OBJID(cb_txn->cb_req->hdr.tzhandle));

	release_tzhandles(&cb_txn->cb_req->hdr.tzhandle, 1);
	tzcb_req->result = user_req->result;
	FOR_ARGS(i, tzcb_req->hdr.counts, BO) {
		union smcinvoke_arg tmp_arg;
@@ -1271,18 +1269,16 @@ static int marshal_out_tzcb_req(const struct smcinvoke_accept *user_req,
			ret = -EFAULT;
			goto out;
		}
		ret = get_tzhandle_from_uhandle(tmp_arg.o.fd, 0, &arr_filp[i],
		ret = get_tzhandle_from_uhandle(tmp_arg.o.fd,
				tmp_arg.o.cb_server_fd, &arr_filp[i],
						&(tz_args[i].handle));
		if (ret)
			goto out;
		tzhandles_to_release[i] = tz_args[i].handle;
	}
	FOR_ARGS(i, tzcb_req->hdr.counts, OI) {
		if (TZHANDLE_IS_CB_OBJ(tz_args[i].handle)) {
			put_pending_cbobj_locked(
				TZHANDLE_GET_SERVER(tz_args[i].handle),
				TZHANDLE_GET_OBJID(tz_args[i].handle));
		}
		if (TZHANDLE_IS_CB_OBJ(tz_args[i].handle))
			release_tzhandles(&tz_args[i].handle, 1);
	}
	ret = 0;
out:
@@ -1375,12 +1371,9 @@ static long process_server_req(struct file *filp, unsigned int cmd,
	ret = get_fd_for_obj(SMCINVOKE_OBJ_TYPE_SERVER,
				server_info->server_id, &server_fd);

	if (ret) {
		mutex_lock(&g_smcinvoke_lock);
		hash_del(&server_info->hash);
		mutex_unlock(&g_smcinvoke_lock);
		kfree(server_info);
	}
	if (ret)
		destroy_cb_server(server_info->server_id);

	return server_fd;
}

@@ -1435,9 +1428,7 @@ static long process_accept_req(struct file *filp, unsigned int cmd,
			cb_txn->cb_req->result = OBJECT_ERROR_UNAVAIL;

		if (OBJECT_OP_METHODID(user_args.op) == OBJECT_OP_RELEASE)
			put_pending_cbobj_locked(
			    TZHANDLE_GET_SERVER(cb_txn->cb_req->hdr.tzhandle),
			    TZHANDLE_GET_OBJID(cb_txn->cb_req->hdr.tzhandle));
			release_tzhandles(&cb_txn->cb_req->hdr.tzhandle, 1);

		cb_txn->state = SMCINVOKE_REQ_PROCESSED;
		wake_up(&server_info->rsp_wait_q);
@@ -1455,8 +1446,10 @@ static long process_accept_req(struct file *filp, unsigned int cmd,
	do {
		ret = wait_event_interruptible(server_info->req_wait_q,
				!hash_empty(server_info->reqs_table));
		if (ret)
		if (ret) {
			destroy_cb_server(server_obj->server_id);
			goto out;
		}

		mutex_lock(&g_smcinvoke_lock);
		cb_txn = find_cbtxn_locked(server_info,