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

Verify mini dump region is added and removed for same region.

Change-Id: I416d9fe0fd35e9eae7a9048241cce58086a01da1
Signed-off-by: Vamsi krishna Gattupalli <vgattupa@codeaurora.org>
This commit is contained in:
Vamsi krishna Gattupalli 2021-03-15 23:09:10 +05:30 • committed by vgattupa
commit 3b468992d6

View file

@ -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)));
@ -2786,6 +2875,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);
@ -3645,7 +3735,7 @@ bail:
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];
@ -3702,6 +3792,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;
/*
@ -3771,9 +3862,11 @@ bail:
"rh hyp unassign failed with %d for phys 0x%llx of size %zu\n",
hyp_err, phys, size);
}
mutex_lock(&fl->map_mutex);
fastrpc_mmap_free(mem, 0);
mutex_unlock(&fl->map_mutex);
if (mem_create && mem) {
mutex_lock(&fl->map_mutex);
fastrpc_mmap_free(mem, 0);
mutex_unlock(&fl->map_mutex);
}
}
return err;
}
@ -6492,6 +6585,7 @@ bail:
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++) {
@ -6504,6 +6598,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 = {