Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

misc: fastrpc: Safekeep mmaps on interrupted invoke

If the userspace daemon is killed in the middle of an invoke (e.g.
audiopd listerner invoke), we need to skip the unmapping on device
release, otherwise the DSP will crash. So lets safekeep all the maps
only if there is in invoke interrupted, by attaching them to the channel
context (which is resident until RPMSG driver is removed), and free them
on RPMSG driver remove.

Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20221125071405.148786-9-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Abel Vesa and committed by
Greg Kroah-Hartman
76e8e4ac 08715610

+15
+15
drivers/misc/fastrpc.c
··· 275 275 struct fastrpc_device *secure_fdevice; 276 276 struct fastrpc_device *fdevice; 277 277 struct fastrpc_buf *remote_heap; 278 + struct list_head invoke_interrupted_mmaps; 278 279 bool secure; 279 280 bool unsigned_support; 280 281 }; ··· 1110 1109 struct fastrpc_invoke_args *args) 1111 1110 { 1112 1111 struct fastrpc_invoke_ctx *ctx = NULL; 1112 + struct fastrpc_buf *buf, *b; 1113 + 1113 1114 int err = 0; 1114 1115 1115 1116 if (!fl->sctx) ··· 1173 1170 list_del(&ctx->node); 1174 1171 spin_unlock(&fl->lock); 1175 1172 fastrpc_context_put(ctx); 1173 + } 1174 + 1175 + if (err == -ERESTARTSYS) { 1176 + list_for_each_entry_safe(buf, b, &fl->mmaps, node) { 1177 + list_del(&buf->node); 1178 + list_add_tail(&buf->node, &fl->cctx->invoke_interrupted_mmaps); 1179 + } 1176 1180 } 1177 1181 1178 1182 if (err) ··· 2288 2278 dev_set_drvdata(&rpdev->dev, data); 2289 2279 dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); 2290 2280 INIT_LIST_HEAD(&data->users); 2281 + INIT_LIST_HEAD(&data->invoke_interrupted_mmaps); 2291 2282 spin_lock_init(&data->lock); 2292 2283 idr_init(&data->ctx_idr); 2293 2284 data->domain_id = domain_id; ··· 2313 2302 static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) 2314 2303 { 2315 2304 struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev); 2305 + struct fastrpc_buf *buf, *b; 2316 2306 struct fastrpc_user *user; 2317 2307 unsigned long flags; 2318 2308 ··· 2327 2315 2328 2316 if (cctx->secure_fdevice) 2329 2317 misc_deregister(&cctx->secure_fdevice->miscdev); 2318 + 2319 + list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node) 2320 + list_del(&buf->node); 2330 2321 2331 2322 if (cctx->remote_heap) 2332 2323 fastrpc_buf_free(cctx->remote_heap);