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

Commit fdac6893 authored by c_mtharu's avatar c_mtharu
Browse files

msm: ADSPRPC: validate context pointer with magic number



Validate context pointer using magic number instead of searching
through context list. It removes the usage of spin lock in interrupt
handler for avoiding deadlock and reducing latency.

Change-Id: I2492a7984a8d6545618a9cfb7a2d239d03ddd5a2
Acked-by: default avatarViswanatham Paduchuri <vpaduchu@qti.qualcomm.com>
Signed-off-by: default avatarTharun Kumar Merugu <mtharu@codeaurora.org>
parent 5b93637d
Loading
Loading
Loading
Loading
+14 −48
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@
#define M_FDLIST	(16)
#define M_CRCLIST	(64)
#define SESSION_ID_INDEX (30)
#define FASTRPC_CTX_MAGIC (0xbeeddeed)

#define IS_CACHE_ALIGNED(x) (((x) & ((L1_CACHE_BYTES)-1)) == 0)

@@ -176,6 +177,7 @@ struct smq_invoke_ctx {
	struct overlap **overps;
	struct smq_msg msg;
	uint32_t *crc;
	unsigned int magic;
};

struct fastrpc_ctx_lst {
@@ -864,6 +866,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
	ctx->pid = current->pid;
	ctx->tgid = fl->tgid;
	init_completion(&ctx->work);
	ctx->magic = FASTRPC_CTX_MAGIC;

	spin_lock(&fl->hlock);
	hlist_add_head(&ctx->hn, &clst->pending);
@@ -899,6 +902,7 @@ static void context_free(struct smq_invoke_ctx *ctx)
	for (i = 0; i < nbufs; ++i)
		fastrpc_mmap_free(ctx->maps[i]);
	fastrpc_buf_free(ctx->buf, 1);
	ctx->magic = 0;
	kfree(ctx);
}

@@ -1822,64 +1826,26 @@ void fastrpc_glink_notify_tx_done(void *handle, const void *priv,
{
}

static int fastrpc_search_ctx(uint64_t rctx)
{
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_file *fl;
	struct hlist_node *n, *m;
	struct smq_invoke_ctx *ictx = NULL;
	struct smq_invoke_ctx *ctx;
	int bfound = 0;
	unsigned long flags;
	unsigned long flags1;

	ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rctx));
	if (!ctx)
		return bfound;

	spin_lock_irqsave(&me->hlock, flags);
	hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
		if (ctx->fl != fl)
			continue;
		spin_lock_irqsave(&fl->hlock, flags1);
		hlist_for_each_entry_safe(ictx, m, &fl->clst.pending, hn) {
			if (ptr_to_uint64(ictx) == rctx) {
				bfound = 1;
				break;
			}
		}
		hlist_for_each_entry_safe(ictx, m, &fl->clst.interrupted, hn) {
			if (ptr_to_uint64(ictx) == rctx) {
				bfound = 1;
				break;
			}
		}
		spin_unlock_irqrestore(&fl->hlock, flags1);
		if (bfound)
			break;
	}
	spin_unlock_irqrestore(&me->hlock, flags);
	return bfound;
}

void fastrpc_glink_notify_rx(void *handle, const void *priv,
	const void *pkt_priv, const void *ptr, size_t size)
{
	struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
	int bfound = 0;
	struct smq_invoke_ctx *ctx;
	int err = 0;

	if (!rsp || (size < sizeof(*rsp)))
	VERIFY(err, (rsp && size >= sizeof(*rsp)));
	if (err)
		goto bail;

	bfound = fastrpc_search_ctx((uint64_t)(rsp->ctx & ~1));
	if (!bfound) {
		pr_err("adsprpc: invalid context %pK\n", (void *)rsp->ctx);
	ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rsp->ctx & ~1));
	VERIFY(err, (ctx && ctx->magic == FASTRPC_CTX_MAGIC));
	if (err)
		goto bail;
	}

	rsp->ctx = rsp->ctx & ~1;
	context_notify_user(uint64_to_ptr(rsp->ctx), rsp->retval);
	context_notify_user(ctx, rsp->retval);
bail:
	if (err)
		pr_err("adsprpc: invalid response or context\n");
	glink_rx_done(handle, ptr, true);
}