Skip to content

Commit 4170a8c

Browse files
committed
Merge remote-tracking branch tech/mm/fastrpc into qcom-next
2 parents 9b7831c + 5a94c05 commit 4170a8c

1 file changed

Lines changed: 146 additions & 36 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 146 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ struct fastrpc_buf {
197197
struct dma_buf *dmabuf;
198198
struct device *dev;
199199
void *virt;
200+
/* Type of buffer */
201+
u32 flag;
200202
u64 phys;
201203
u64 size;
202204
/* Lock for dma buf attachments */
@@ -273,10 +275,12 @@ struct fastrpc_channel_ctx {
273275
struct kref refcount;
274276
/* Flag if dsp attributes are cached */
275277
bool valid_attributes;
278+
/* Flag if audio PD init mem was allocated */
279+
bool audio_init_mem;
276280
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
277281
struct fastrpc_device *secure_fdevice;
278282
struct fastrpc_device *fdevice;
279-
struct fastrpc_buf *remote_heap;
283+
struct list_head rhmaps;
280284
struct list_head invoke_interrupted_mmaps;
281285
bool secure;
282286
bool unsigned_support;
@@ -394,6 +398,9 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
394398

395399
static void fastrpc_buf_free(struct fastrpc_buf *buf)
396400
{
401+
if (!buf)
402+
return;
403+
397404
dma_free_coherent(buf->dev, buf->size, buf->virt,
398405
FASTRPC_PHYS(buf->phys));
399406
kfree(buf);
@@ -1234,12 +1241,47 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques
12341241
return false;
12351242
}
12361243

1244+
static void fastrpc_cleanup_rhmaps(struct fastrpc_channel_ctx *cctx)
1245+
{
1246+
struct fastrpc_buf *buf, *b;
1247+
struct list_head temp_list;
1248+
int err;
1249+
unsigned long flags;
1250+
1251+
INIT_LIST_HEAD(&temp_list);
1252+
1253+
spin_lock_irqsave(&cctx->lock, flags);
1254+
list_splice_init(&cctx->rhmaps, &temp_list);
1255+
spin_unlock_irqrestore(&cctx->lock, flags);
1256+
1257+
list_for_each_entry_safe(buf, b, &temp_list, node) {
1258+
if (cctx->vmcount) {
1259+
u64 src_perms = 0;
1260+
struct qcom_scm_vmperm dst_perms;
1261+
u32 i;
1262+
1263+
for (i = 0; i < cctx->vmcount; i++)
1264+
src_perms |= BIT(cctx->vmperms[i].vmid);
1265+
1266+
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
1267+
dst_perms.perm = QCOM_SCM_PERM_RWX;
1268+
err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
1269+
&src_perms, &dst_perms, 1);
1270+
if (err)
1271+
continue;
1272+
}
1273+
fastrpc_buf_free(buf);
1274+
}
1275+
}
1276+
12371277
static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
12381278
char __user *argp)
12391279
{
12401280
struct fastrpc_init_create_static init;
12411281
struct fastrpc_invoke_args *args;
12421282
struct fastrpc_phy_page pages[1];
1283+
struct fastrpc_buf *buf = NULL;
1284+
u64 phys = 0, size = 0;
12431285
char *name;
12441286
int err;
12451287
bool scm_done = false;
@@ -1249,6 +1291,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
12491291
u32 pageslen;
12501292
} inbuf;
12511293
u32 sc;
1294+
unsigned long flags;
12521295

12531296
args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
12541297
if (!args)
@@ -1270,32 +1313,37 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
12701313
goto err;
12711314
}
12721315

1273-
if (!fl->cctx->remote_heap) {
1316+
inbuf.client_id = fl->client_id;
1317+
inbuf.namelen = init.namelen;
1318+
inbuf.pageslen = 0;
1319+
if (!fl->cctx->audio_init_mem) {
12741320
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
1275-
&fl->cctx->remote_heap);
1321+
&buf);
12761322
if (err)
12771323
goto err_name;
12781324

1325+
phys = buf->phys;
1326+
size = buf->size;
12791327
/* Map if we have any heap VMIDs associated with this ADSP Static Process. */
12801328
if (fl->cctx->vmcount) {
12811329
u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
12821330

1283-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
1284-
(u64)fl->cctx->remote_heap->size,
1285-
&src_perms,
1286-
fl->cctx->vmperms, fl->cctx->vmcount);
1331+
err = qcom_scm_assign_mem(phys, size, &src_perms,
1332+
fl->cctx->vmperms, fl->cctx->vmcount);
12871333
if (err) {
12881334
dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
1289-
fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
1335+
phys, size, err);
12901336
goto err_map;
12911337
}
12921338
scm_done = true;
1339+
spin_lock_irqsave(&fl->cctx->lock, flags);
1340+
list_add_tail(&buf->node, &fl->cctx->rhmaps);
1341+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
1342+
fl->cctx->audio_init_mem = true;
1343+
inbuf.pageslen = 1;
12931344
}
12941345
}
12951346

1296-
inbuf.client_id = fl->client_id;
1297-
inbuf.namelen = init.namelen;
1298-
inbuf.pageslen = 0;
12991347
fl->pd = USER_PD;
13001348

13011349
args[0].ptr = (u64)(uintptr_t)&inbuf;
@@ -1306,8 +1354,8 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13061354
args[1].length = inbuf.namelen;
13071355
args[1].fd = -1;
13081356

1309-
pages[0].addr = fl->cctx->remote_heap->phys;
1310-
pages[0].size = fl->cctx->remote_heap->size;
1357+
pages[0].addr = phys;
1358+
pages[0].size = size;
13111359

13121360
args[2].ptr = (u64)(uintptr_t) pages;
13131361
args[2].length = sizeof(*pages);
@@ -1325,6 +1373,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13251373

13261374
return 0;
13271375
err_invoke:
1376+
if (buf) {
1377+
spin_lock_irqsave(&fl->cctx->lock, flags);
1378+
list_del(&buf->node);
1379+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
1380+
}
13281381
if (fl->cctx->vmcount && scm_done) {
13291382
u64 src_perms = 0;
13301383
struct qcom_scm_vmperm dst_perms;
@@ -1335,15 +1388,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13351388

13361389
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
13371390
dst_perms.perm = QCOM_SCM_PERM_RWX;
1338-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
1339-
(u64)fl->cctx->remote_heap->size,
1340-
&src_perms, &dst_perms, 1);
1391+
err = qcom_scm_assign_mem(phys, size, &src_perms,
1392+
&dst_perms, 1);
13411393
if (err)
13421394
dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
1343-
fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
1395+
phys, size, err);
13441396
}
13451397
err_map:
1346-
fastrpc_buf_free(fl->cctx->remote_heap);
1398+
fl->cctx->audio_init_mem = false;
1399+
fastrpc_buf_free(buf);
13471400
err_name:
13481401
kfree(name);
13491402
err:
@@ -1816,11 +1869,26 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
18161869
err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc,
18171870
&args[0]);
18181871
if (!err) {
1819-
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
1820-
spin_lock(&fl->lock);
1821-
list_del(&buf->node);
1822-
spin_unlock(&fl->lock);
1872+
if (buf->flag == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {
1873+
u64 src_perms = 0;
1874+
struct qcom_scm_vmperm dst_perms;
1875+
u32 i;
1876+
1877+
for (i = 0; i < fl->cctx->vmcount; i++)
1878+
src_perms |= BIT(fl->cctx->vmperms[i].vmid);
1879+
1880+
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
1881+
dst_perms.perm = QCOM_SCM_PERM_RWX;
1882+
err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
1883+
&src_perms, &dst_perms, 1);
1884+
if (err) {
1885+
dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
1886+
buf->phys, buf->size, err);
1887+
return err;
1888+
}
1889+
}
18231890
fastrpc_buf_free(buf);
1891+
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
18241892
} else {
18251893
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
18261894
}
@@ -1833,26 +1901,54 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
18331901
struct fastrpc_buf *buf = NULL, *iter, *b;
18341902
struct fastrpc_req_munmap req;
18351903
struct device *dev = fl->sctx->dev;
1904+
int err;
1905+
unsigned long flags;
18361906

18371907
if (copy_from_user(&req, argp, sizeof(req)))
18381908
return -EFAULT;
18391909

18401910
spin_lock(&fl->lock);
18411911
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
1842-
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
1912+
if (iter->raddr == req.vaddrout && iter->size == req.size) {
1913+
list_del(&iter->node);
18431914
buf = iter;
18441915
break;
18451916
}
18461917
}
18471918
spin_unlock(&fl->lock);
18481919

1849-
if (!buf) {
1850-
dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
1851-
req.vaddrout, req.size);
1852-
return -EINVAL;
1920+
if (buf) {
1921+
err = fastrpc_req_munmap_impl(fl, buf);
1922+
if (err) {
1923+
spin_lock(&fl->lock);
1924+
list_add_tail(&buf->node, &fl->mmaps);
1925+
spin_unlock(&fl->lock);
1926+
}
1927+
return err;
1928+
}
1929+
1930+
spin_lock_irqsave(&fl->cctx->lock, flags);
1931+
list_for_each_entry_safe(iter, b, &fl->cctx->rhmaps, node) {
1932+
if (iter->raddr == req.vaddrout && iter->size == req.size) {
1933+
list_del(&iter->node);
1934+
buf = iter;
1935+
break;
1936+
}
1937+
}
1938+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
1939+
if (buf) {
1940+
err = fastrpc_req_munmap_impl(fl, buf);
1941+
if (err) {
1942+
spin_lock_irqsave(&fl->cctx->lock, flags);
1943+
list_add_tail(&buf->node, &fl->cctx->rhmaps);
1944+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
1945+
}
1946+
return err;
18531947
}
1948+
dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
1949+
req.vaddrout, req.size);
18541950

1855-
return fastrpc_req_munmap_impl(fl, buf);
1951+
return -EINVAL;
18561952
}
18571953

18581954
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
@@ -1866,6 +1962,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
18661962
struct device *dev = fl->sctx->dev;
18671963
int err;
18681964
u32 sc;
1965+
unsigned long flags;
18691966

18701967
if (copy_from_user(&req, argp, sizeof(req)))
18711968
return -EFAULT;
@@ -1919,6 +2016,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
19192016

19202017
/* update the buffer to be able to deallocate the memory on the DSP */
19212018
buf->raddr = (uintptr_t) rsp_msg.vaddr;
2019+
buf->flag = req.flags;
19222020

19232021
/* let the client know the address to use */
19242022
req.vaddrout = rsp_msg.vaddr;
@@ -1934,22 +2032,34 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
19342032
buf->phys, buf->size, err);
19352033
goto err_assign;
19362034
}
2035+
spin_lock_irqsave(&fl->cctx->lock, flags);
2036+
list_add_tail(&buf->node, &fl->cctx->rhmaps);
2037+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
2038+
} else {
2039+
spin_lock(&fl->lock);
2040+
list_add_tail(&buf->node, &fl->mmaps);
2041+
spin_unlock(&fl->lock);
19372042
}
19382043

1939-
spin_lock(&fl->lock);
1940-
list_add_tail(&buf->node, &fl->mmaps);
1941-
spin_unlock(&fl->lock);
1942-
19432044
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
19442045
err = -EFAULT;
1945-
goto err_assign;
2046+
goto err_copy;
19462047
}
19472048

19482049
dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
19492050
buf->raddr, buf->size);
19502051

19512052
return 0;
1952-
2053+
err_copy:
2054+
if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
2055+
spin_lock_irqsave(&fl->cctx->lock, flags);
2056+
list_del(&buf->node);
2057+
spin_unlock_irqrestore(&fl->cctx->lock, flags);
2058+
} else {
2059+
spin_lock(&fl->lock);
2060+
list_del(&buf->node);
2061+
spin_unlock(&fl->lock);
2062+
}
19532063
err_assign:
19542064
fastrpc_req_munmap_impl(fl, buf);
19552065

@@ -2359,6 +2469,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
23592469
rdev->dma_mask = &data->dma_mask;
23602470
dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32));
23612471
INIT_LIST_HEAD(&data->users);
2472+
INIT_LIST_HEAD(&data->rhmaps);
23622473
INIT_LIST_HEAD(&data->invoke_interrupted_mmaps);
23632474
spin_lock_init(&data->lock);
23642475
idr_init(&data->ctx_idr);
@@ -2417,8 +2528,7 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
24172528
list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
24182529
list_del(&buf->node);
24192530

2420-
if (cctx->remote_heap)
2421-
fastrpc_buf_free(cctx->remote_heap);
2531+
fastrpc_cleanup_rhmaps(cctx);
24222532

24232533
of_platform_depopulate(&rpdev->dev);
24242534

0 commit comments

Comments
 (0)