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

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

Merge "msm: adsprpc: Verify mini-dump region is added and removed"

parents 7d6f957e 3b468992
Loading
Loading
Loading
Loading
+120 −25
Original line number Diff line number Diff line
@@ -196,7 +196,13 @@

#define PERF_CAPABILITY   (1 << 1)

/* Fastrpc remote process attributes */
/*Max number of region supported  */
#define MAX_UNIQUE_ID 5

/*Unique index flag used for mini dump*/

static int md_unique_index_flag[MAX_UNIQUE_ID] = { 0, 0, 0, 0, 0 };

enum fastrpc_proc_attr {
	/* Macro for Debug attr */
	FASTRPC_MODE_DEBUG				= 1 << 0,
@@ -536,6 +542,7 @@ struct fastrpc_apps {
	uint32_t max_size_limit;
	void *ramdump_handle;
	bool enable_ramdump;
	struct mutex mut_uid;
};

struct fastrpc_mmap {
@@ -556,6 +563,8 @@ struct fastrpc_mmap {
	uintptr_t raddr;
	int uncached;
	int secure;
	/* Minidump unique index */
	int frpc_md_index;
	uintptr_t attr;
	struct timespec64 map_start_time;
	struct timespec64 map_end_time;
@@ -854,6 +863,99 @@ static inline void fastrpc_update_rxmsg_buf(struct fastrpc_channel_ctx *chan,
	spin_unlock_irqrestore(&chan->gmsg_log.lock, flags);
}


static inline int get_unique_index(void)
{
	int index = -1;

	mutex_lock(&gfa.mut_uid);
	for (index = 0; index < MAX_UNIQUE_ID; index++) {
		if (md_unique_index_flag[index] == 0) {
			md_unique_index_flag[index] = 1;
			mutex_unlock(&gfa.mut_uid);
			return index;
		}
	}
	mutex_unlock(&gfa.mut_uid);
	return index;
}

static inline void reset_unique_index(int index)
{
	mutex_lock(&gfa.mut_uid);
	if (index > -1 && index < MAX_UNIQUE_ID)
		md_unique_index_flag[index] = 0;
	mutex_unlock(&gfa.mut_uid);
}


/**
 * fastrpc_minidump_add_region - Add mini dump region
 * @fastrpc_mmap       : Input structure mmap
 *
 * Returns int
 */
static int fastrpc_minidump_add_region(struct fastrpc_mmap *map)
{
	int err = -1, md_index = 0;
	struct md_region md_entry;

	md_index = get_unique_index();
	if (md_index > -1 && md_index < MAX_UNIQUE_ID) {
		scnprintf(md_entry.name, MAX_NAME_LENGTH, "FRPC_%d", md_index);
		md_entry.virt_addr = map->va;
		md_entry.phys_addr = map->phys;
		md_entry.size = map->size;
		err = msm_minidump_add_region(&md_entry);
		if (err < 0) {
			ADSPRPC_ERR(
			"Failed to add/update CMA to Minidump for phys: 0x%llx, size: %zu, md_index %d, md_entry.name %s\n",
			map->phys,
			map->size, md_index,
			md_entry.name);
			reset_unique_index(md_index);
		} else {
			map->frpc_md_index = md_index;
		}
	} else {
		ADSPRPC_ERR("failed to generate valid unique id for mini dump : %d\n", md_index);
	}
	return err;
}

/**
 * fastrpc_minidump_remove_region - Remove mini dump region if added
 * @fastrpc_mmap       : Input structure mmap
 *
 * Returns int
 */
static int fastrpc_minidump_remove_region(struct fastrpc_mmap *map)
{
	int err = -1;
	struct md_region md_entry;

	if (map->frpc_md_index > -1 && map->frpc_md_index < MAX_UNIQUE_ID) {
		scnprintf(md_entry.name, MAX_NAME_LENGTH, "FRPC_%d",
					map->frpc_md_index);
		md_entry.virt_addr = map->va;
		md_entry.phys_addr = map->phys;
		md_entry.size = map->size;
		err = msm_minidump_remove_region(&md_entry);
		if (err < 0) {
			ADSPRPC_ERR(
				"Failed to remove CMA from Minidump for phys: 0x%llx, size: %zu index = %d\n",
				 map->phys, map->size, map->frpc_md_index);
		} else {
			reset_unique_index(map->frpc_md_index);
			map->frpc_md_index = -1;
		}
	} else {
		ADSPRPC_ERR("mini-dump enabled with invalid unique id: %d\n", map->frpc_md_index);
	}
	return err;
}


static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
{
	struct fastrpc_file *fl = buf == NULL ? NULL : buf->fl;
@@ -1104,7 +1206,6 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
	struct fastrpc_file *fl;
	int vmid, cid = -1, err = 0;
	struct fastrpc_session_ctx *sess;
	struct md_region md_entry;

	if (!map)
		return;
@@ -1148,16 +1249,9 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
				"failed to free remote heap allocation, device is not initialized\n");
			return;
		}

		if (msm_minidump_enabled()) {
			scnprintf(md_entry.name, sizeof(md_entry.name), "CMA_%d", current->tgid);
			md_entry.virt_addr = map->va;
			md_entry.phys_addr = map->phys;
			md_entry.size = map->size;
			if (msm_minidump_remove_region(&md_entry) < 0) {
				ADSPRPC_ERR(
					"Failed to remove CMA from Minidump for tgid: %d, phys: 0x%llx, size: %zu\n",
					current->tgid, map->phys, map->size);
			}
			err = fastrpc_minidump_remove_region(map);
		}
		trace_fastrpc_dma_free(-1, map->phys, map->size);
		if (map->phys) {
@@ -1226,7 +1320,6 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
	unsigned long flags;
	int err = 0, vmid, sgl_index = 0;
	struct scatterlist *sgl = NULL;
	struct md_region md_entry;

	VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS);
	if (err) {
@@ -1249,6 +1342,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
	map->fl = fl;
	map->fd = fd;
	map->attr = attr;
	map->frpc_md_index = -1;
	ktime_get_real_ts64(&map->map_start_time);
	if (mflags == ADSP_MMAP_HEAP_ADDR ||
				mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
@@ -1264,16 +1358,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
		map->phys = (uintptr_t)region_phys;
		map->size = len;
		map->va = (uintptr_t)region_vaddr;

		if (msm_minidump_enabled()) {
			scnprintf(md_entry.name, sizeof(md_entry.name), "CMA_%d", fl->tgid);
			md_entry.virt_addr = map->va;
			md_entry.phys_addr = map->phys;
			md_entry.size = map->size;
			if (msm_minidump_add_region(&md_entry) >= 0) {
				ADSPRPC_ERR(
					"Failed to add CMA to Minidump for tgid: %d, phys: 0x%llx, size: %zu\n",
					fl->tgid, map->phys, map->size);
			}
			err = fastrpc_minidump_add_region(map);
			if (err)
				goto bail;
		}
	} else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
		VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
@@ -2789,6 +2878,7 @@ static void fastrpc_init(struct fastrpc_apps *me)
	INIT_HLIST_HEAD(&me->maps);
	spin_lock_init(&me->hlock);
	me->channel = &gcinfo[0];
	mutex_init(&me->mut_uid);
	for (i = 0; i < NUM_CHANNELS; i++) {
		init_completion(&me->channel[i].work);
		init_completion(&me->channel[i].workport);
@@ -3648,7 +3738,7 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl,
static int fastrpc_init_create_static_process(struct fastrpc_file *fl,
				struct fastrpc_ioctl_init *init)
{
	int err = 0, rh_hyp_done = 0;
	int err = 0, rh_hyp_done = 0, mem_create = 0;
	struct fastrpc_apps *me = &gfa;
	struct fastrpc_ioctl_invoke_async ioctl;
	struct smq_phy_page pages[1];
@@ -3705,6 +3795,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_file *fl,
		mutex_unlock(&fl->map_mutex);
		if (err)
			goto bail;
		mem_create = 1;
		phys = mem->phys;
		size = mem->size;
		/*
@@ -3774,10 +3865,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_file *fl,
					"rh hyp unassign failed with %d for phys 0x%llx of size %zu\n",
					hyp_err, phys, size);
		}
		if (mem_create && mem) {
			mutex_lock(&fl->map_mutex);
			fastrpc_mmap_free(mem, 0);
			mutex_unlock(&fl->map_mutex);
		}
	}
	return err;
}

@@ -6503,6 +6596,7 @@ static int fastrpc_probe(struct platform_device *pdev)
static void fastrpc_deinit(void)
{
	struct fastrpc_channel_ctx *chan = gcinfo;
	struct fastrpc_apps *me = &gfa;
	int i, j;

	for (i = 0; i < NUM_CHANNELS; i++, chan++) {
@@ -6515,6 +6609,7 @@ static void fastrpc_deinit(void)
		kfree(chan->rhvm.vmid);
		kfree(chan->rhvm.vmperm);
	}
	mutex_destroy(&me->mut_uid);
}

static struct platform_driver fastrpc_driver = {