Loading drivers/soc/qcom/memshare/msm_memshare.c +28 −11 Original line number Original line Diff line number Diff line /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -324,7 +324,7 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, { { int i; int i; int ret; int ret; u32 source_vmlist[2] = {VMID_HLOS, VMID_MSS_MSA}; u32 source_vmlist[1] = {VMID_MSS_MSA}; int dest_vmids[1] = {VMID_HLOS}; int dest_vmids[1] = {VMID_HLOS}; int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; struct notif_data *notifdata = NULL; struct notif_data *notifdata = NULL; Loading @@ -335,6 +335,9 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, case SUBSYS_BEFORE_SHUTDOWN: case SUBSYS_BEFORE_SHUTDOWN: bootup_request++; bootup_request++; for (i = 0; ((i < MAX_CLIENTS) && !memblock[i].guarantee); i++) memblock[i].alloc_request = 0; break; break; case SUBSYS_RAMDUMP_NOTIFICATION: case SUBSYS_RAMDUMP_NOTIFICATION: Loading Loading @@ -374,14 +377,15 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, if (memblock[i].peripheral == if (memblock[i].peripheral == DHMS_MEM_PROC_MPSS_V01 && DHMS_MEM_PROC_MPSS_V01 && !memblock[i].guarantee && !memblock[i].guarantee && memblock[i].allotted) { memblock[i].allotted && !memblock[i].alloc_request) { pr_debug("memshare: hypervisor unmapping for client id: %d\n", pr_debug("memshare: hypervisor unmapping for client id: %d\n", memblock[i].client_id); memblock[i].client_id); ret = hyp_assign_phys( ret = hyp_assign_phys( memblock[i].phy_addr, memblock[i].phy_addr, memblock[i].size, memblock[i].size, source_vmlist, source_vmlist, 2, dest_vmids, 1, dest_vmids, dest_perms, 1); dest_perms, 1); if (ret && if (ret && memblock[i].hyp_mapping == 1) { memblock[i].hyp_mapping == 1) { Loading @@ -393,7 +397,6 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, */ */ pr_err("memshare: %s, failed to unmap the region\n", pr_err("memshare: %s, failed to unmap the region\n", __func__); __func__); memblock[i].hyp_mapping = 1; } else { } else { memblock[i].hyp_mapping = 0; memblock[i].hyp_mapping = 0; } } Loading Loading @@ -425,9 +428,8 @@ static void shared_hyp_mapping(int client_id) { { int ret; int ret; u32 source_vmlist[1] = {VMID_HLOS}; u32 source_vmlist[1] = {VMID_HLOS}; int dest_vmids[2] = {VMID_HLOS, VMID_MSS_MSA}; int dest_vmids[1] = {VMID_MSS_MSA}; int dest_perms[2] = {PERM_READ|PERM_WRITE, int dest_perms[1] = {PERM_READ|PERM_WRITE}; PERM_READ|PERM_WRITE}; if (client_id == DHMS_MEM_CLIENT_INVALID) { if (client_id == DHMS_MEM_CLIENT_INVALID) { pr_err("memshare: %s, Invalid Client\n", __func__); pr_err("memshare: %s, Invalid Client\n", __func__); Loading @@ -437,7 +439,7 @@ static void shared_hyp_mapping(int client_id) ret = hyp_assign_phys(memblock[client_id].phy_addr, ret = hyp_assign_phys(memblock[client_id].phy_addr, memblock[client_id].size, memblock[client_id].size, source_vmlist, 1, dest_vmids, source_vmlist, 1, dest_vmids, dest_perms, 2); dest_perms, 1); if (ret != 0) { if (ret != 0) { pr_err("memshare: hyp_assign_phys failed size=%u err=%d\n", pr_err("memshare: hyp_assign_phys failed size=%u err=%d\n", Loading Loading @@ -539,6 +541,7 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) memblock[client_id].allotted = 1; memblock[client_id].allotted = 1; memblock[client_id].size = alloc_req->num_bytes; memblock[client_id].size = alloc_req->num_bytes; memblock[client_id].peripheral = alloc_req->proc_id; memblock[client_id].peripheral = alloc_req->proc_id; memblock[client_id].alloc_request = 1; } } } } pr_debug("memshare: In %s, free memory count for client id: %d = %d", pr_debug("memshare: In %s, free memory count for client id: %d = %d", Loading Loading @@ -603,9 +606,11 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) { { struct mem_free_generic_req_msg_v01 *free_req; struct mem_free_generic_req_msg_v01 *free_req; struct mem_free_generic_resp_msg_v01 free_resp; struct mem_free_generic_resp_msg_v01 free_resp; int rc; int rc, flag = 0, ret = 0; int flag = 0; uint32_t client_id; uint32_t client_id; u32 source_vmlist[1] = {VMID_MSS_MSA}; int dest_vmids[1] = {VMID_HLOS}; int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; mutex_lock(&memsh_drv->mem_free); mutex_lock(&memsh_drv->mem_free); free_req = (struct mem_free_generic_req_msg_v01 *)req; free_req = (struct mem_free_generic_req_msg_v01 *)req; Loading @@ -624,6 +629,17 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) memblock[client_id].allotted) { memblock[client_id].allotted) { pr_debug("memshare: %s: size: %d", pr_debug("memshare: %s: size: %d", __func__, memblock[client_id].size); __func__, memblock[client_id].size); ret = hyp_assign_phys(memblock[client_id].phy_addr, memblock[client_id].size, source_vmlist, 1, dest_vmids, dest_perms, 1); if (ret && memblock[client_id].hyp_mapping == 1) { /* * This is an error case as hyp mapping was successful * earlier but during unmap it lead to failure. */ pr_err("memshare: %s, failed to unmap the region\n", __func__); } dma_free_attrs(memsh_drv->dev, memblock[client_id].size, dma_free_attrs(memsh_drv->dev, memblock[client_id].size, memblock[client_id].virtual_addr, memblock[client_id].virtual_addr, memblock[client_id].phy_addr, memblock[client_id].phy_addr, Loading Loading @@ -959,6 +975,7 @@ static int memshare_child_probe(struct platform_device *pdev) return rc; return rc; } } memblock[num_clients].allotted = 1; memblock[num_clients].allotted = 1; memblock[num_clients].alloc_request = 1; shared_hyp_mapping(num_clients); shared_hyp_mapping(num_clients); } } Loading drivers/soc/qcom/memshare/msm_memshare.h +3 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -39,6 +39,8 @@ struct mem_blocks { uint32_t guarantee; uint32_t guarantee; /* Memory alloted or not */ /* Memory alloted or not */ uint32_t allotted; uint32_t allotted; /* Memory allocation request received or not */ uint32_t alloc_request; /* Size required for client */ /* Size required for client */ uint32_t size; uint32_t size; /* /* Loading Loading
drivers/soc/qcom/memshare/msm_memshare.c +28 −11 Original line number Original line Diff line number Diff line /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -324,7 +324,7 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, { { int i; int i; int ret; int ret; u32 source_vmlist[2] = {VMID_HLOS, VMID_MSS_MSA}; u32 source_vmlist[1] = {VMID_MSS_MSA}; int dest_vmids[1] = {VMID_HLOS}; int dest_vmids[1] = {VMID_HLOS}; int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; struct notif_data *notifdata = NULL; struct notif_data *notifdata = NULL; Loading @@ -335,6 +335,9 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, case SUBSYS_BEFORE_SHUTDOWN: case SUBSYS_BEFORE_SHUTDOWN: bootup_request++; bootup_request++; for (i = 0; ((i < MAX_CLIENTS) && !memblock[i].guarantee); i++) memblock[i].alloc_request = 0; break; break; case SUBSYS_RAMDUMP_NOTIFICATION: case SUBSYS_RAMDUMP_NOTIFICATION: Loading Loading @@ -374,14 +377,15 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, if (memblock[i].peripheral == if (memblock[i].peripheral == DHMS_MEM_PROC_MPSS_V01 && DHMS_MEM_PROC_MPSS_V01 && !memblock[i].guarantee && !memblock[i].guarantee && memblock[i].allotted) { memblock[i].allotted && !memblock[i].alloc_request) { pr_debug("memshare: hypervisor unmapping for client id: %d\n", pr_debug("memshare: hypervisor unmapping for client id: %d\n", memblock[i].client_id); memblock[i].client_id); ret = hyp_assign_phys( ret = hyp_assign_phys( memblock[i].phy_addr, memblock[i].phy_addr, memblock[i].size, memblock[i].size, source_vmlist, source_vmlist, 2, dest_vmids, 1, dest_vmids, dest_perms, 1); dest_perms, 1); if (ret && if (ret && memblock[i].hyp_mapping == 1) { memblock[i].hyp_mapping == 1) { Loading @@ -393,7 +397,6 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code, */ */ pr_err("memshare: %s, failed to unmap the region\n", pr_err("memshare: %s, failed to unmap the region\n", __func__); __func__); memblock[i].hyp_mapping = 1; } else { } else { memblock[i].hyp_mapping = 0; memblock[i].hyp_mapping = 0; } } Loading Loading @@ -425,9 +428,8 @@ static void shared_hyp_mapping(int client_id) { { int ret; int ret; u32 source_vmlist[1] = {VMID_HLOS}; u32 source_vmlist[1] = {VMID_HLOS}; int dest_vmids[2] = {VMID_HLOS, VMID_MSS_MSA}; int dest_vmids[1] = {VMID_MSS_MSA}; int dest_perms[2] = {PERM_READ|PERM_WRITE, int dest_perms[1] = {PERM_READ|PERM_WRITE}; PERM_READ|PERM_WRITE}; if (client_id == DHMS_MEM_CLIENT_INVALID) { if (client_id == DHMS_MEM_CLIENT_INVALID) { pr_err("memshare: %s, Invalid Client\n", __func__); pr_err("memshare: %s, Invalid Client\n", __func__); Loading @@ -437,7 +439,7 @@ static void shared_hyp_mapping(int client_id) ret = hyp_assign_phys(memblock[client_id].phy_addr, ret = hyp_assign_phys(memblock[client_id].phy_addr, memblock[client_id].size, memblock[client_id].size, source_vmlist, 1, dest_vmids, source_vmlist, 1, dest_vmids, dest_perms, 2); dest_perms, 1); if (ret != 0) { if (ret != 0) { pr_err("memshare: hyp_assign_phys failed size=%u err=%d\n", pr_err("memshare: hyp_assign_phys failed size=%u err=%d\n", Loading Loading @@ -539,6 +541,7 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h) memblock[client_id].allotted = 1; memblock[client_id].allotted = 1; memblock[client_id].size = alloc_req->num_bytes; memblock[client_id].size = alloc_req->num_bytes; memblock[client_id].peripheral = alloc_req->proc_id; memblock[client_id].peripheral = alloc_req->proc_id; memblock[client_id].alloc_request = 1; } } } } pr_debug("memshare: In %s, free memory count for client id: %d = %d", pr_debug("memshare: In %s, free memory count for client id: %d = %d", Loading Loading @@ -603,9 +606,11 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) { { struct mem_free_generic_req_msg_v01 *free_req; struct mem_free_generic_req_msg_v01 *free_req; struct mem_free_generic_resp_msg_v01 free_resp; struct mem_free_generic_resp_msg_v01 free_resp; int rc; int rc, flag = 0, ret = 0; int flag = 0; uint32_t client_id; uint32_t client_id; u32 source_vmlist[1] = {VMID_MSS_MSA}; int dest_vmids[1] = {VMID_HLOS}; int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; mutex_lock(&memsh_drv->mem_free); mutex_lock(&memsh_drv->mem_free); free_req = (struct mem_free_generic_req_msg_v01 *)req; free_req = (struct mem_free_generic_req_msg_v01 *)req; Loading @@ -624,6 +629,17 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h) memblock[client_id].allotted) { memblock[client_id].allotted) { pr_debug("memshare: %s: size: %d", pr_debug("memshare: %s: size: %d", __func__, memblock[client_id].size); __func__, memblock[client_id].size); ret = hyp_assign_phys(memblock[client_id].phy_addr, memblock[client_id].size, source_vmlist, 1, dest_vmids, dest_perms, 1); if (ret && memblock[client_id].hyp_mapping == 1) { /* * This is an error case as hyp mapping was successful * earlier but during unmap it lead to failure. */ pr_err("memshare: %s, failed to unmap the region\n", __func__); } dma_free_attrs(memsh_drv->dev, memblock[client_id].size, dma_free_attrs(memsh_drv->dev, memblock[client_id].size, memblock[client_id].virtual_addr, memblock[client_id].virtual_addr, memblock[client_id].phy_addr, memblock[client_id].phy_addr, Loading Loading @@ -959,6 +975,7 @@ static int memshare_child_probe(struct platform_device *pdev) return rc; return rc; } } memblock[num_clients].allotted = 1; memblock[num_clients].allotted = 1; memblock[num_clients].alloc_request = 1; shared_hyp_mapping(num_clients); shared_hyp_mapping(num_clients); } } Loading
drivers/soc/qcom/memshare/msm_memshare.h +3 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -39,6 +39,8 @@ struct mem_blocks { uint32_t guarantee; uint32_t guarantee; /* Memory alloted or not */ /* Memory alloted or not */ uint32_t allotted; uint32_t allotted; /* Memory allocation request received or not */ uint32_t alloc_request; /* Size required for client */ /* Size required for client */ uint32_t size; uint32_t size; /* /* Loading