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

misc: fastrpc: Add support to secure memory map

This patch adds support to secure memory allocations for DSP.
It repurposes the reserved field in struct fastrpc_invoke_args
to add attributes to invoke request, for example to setup a secure memory
map for dsp. Secure memory is assigned to DSP Virtual Machine IDs using
Qualcomm SCM calls.

Signed-off-by: Vamsi Krishna Gattupalli <quic_vgattupa@quicinc.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20220214161002.6831-9-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Vamsi Krishna Gattupalli and committed by
Greg Kroah-Hartman
e90d9119 87ccc14e

+61 -10
+1
drivers/misc/Kconfig
··· 259 259 depends on ARCH_QCOM || COMPILE_TEST 260 260 depends on RPMSG 261 261 select DMA_SHARED_BUFFER 262 + select QCOM_SCM 262 263 help 263 264 Provides a communication mechanism that allows for clients to 264 265 make remote method invocations across processor boundary to
+56 -9
drivers/misc/fastrpc.c
··· 17 17 #include <linux/rpmsg.h> 18 18 #include <linux/scatterlist.h> 19 19 #include <linux/slab.h> 20 + #include <linux/qcom_scm.h> 20 21 #include <uapi/misc/fastrpc.h> 21 22 22 23 #define ADSP_DOMAIN_ID (0) ··· 26 25 #define CDSP_DOMAIN_ID (3) 27 26 #define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/ 28 27 #define FASTRPC_MAX_SESSIONS 13 /*12 compute, 1 cpz*/ 28 + #define FASTRPC_MAX_VMIDS 16 29 29 #define FASTRPC_ALIGN 128 30 30 #define FASTRPC_MAX_FDLIST 16 31 31 #define FASTRPC_MAX_CRCLIST 64 ··· 197 195 void *va; 198 196 u64 len; 199 197 u64 raddr; 198 + u32 attr; 200 199 struct kref refcount; 201 200 }; 202 201 ··· 235 232 struct fastrpc_channel_ctx { 236 233 int domain_id; 237 234 int sesscount; 235 + int vmcount; 236 + u32 perms; 237 + struct qcom_scm_vmperm vmperms[FASTRPC_MAX_VMIDS]; 238 238 struct rpmsg_device *rpdev; 239 239 struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS]; 240 240 spinlock_t lock; ··· 285 279 map = container_of(ref, struct fastrpc_map, refcount); 286 280 287 281 if (map->table) { 282 + if (map->attr & FASTRPC_ATTR_SECUREMAP) { 283 + struct qcom_scm_vmperm perm; 284 + int err = 0; 285 + 286 + perm.vmid = QCOM_SCM_VMID_HLOS; 287 + perm.perm = QCOM_SCM_PERM_RWX; 288 + err = qcom_scm_assign_mem(map->phys, map->size, 289 + &(map->fl->cctx->vmperms[0].vmid), &perm, 1); 290 + if (err) { 291 + dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", 292 + map->phys, map->size, err); 293 + return; 294 + } 295 + } 288 296 dma_buf_unmap_attachment(map->attach, map->table, 289 297 DMA_BIDIRECTIONAL); 290 298 dma_buf_detach(map->buf, map->attach); ··· 675 655 }; 676 656 677 657 static int fastrpc_map_create(struct fastrpc_user *fl, int fd, 678 - u64 len, struct fastrpc_map **ppmap) 658 + u64 len, u32 attr, struct fastrpc_map **ppmap) 679 659 { 680 660 struct fastrpc_session_ctx *sess = fl->sctx; 681 661 struct fastrpc_map *map = NULL; ··· 717 697 map->len = len; 718 698 kref_init(&map->refcount); 719 699 700 + if (attr & FASTRPC_ATTR_SECUREMAP) { 701 + /* 702 + * If subsystem VMIDs are defined in DTSI, then do 703 + * hyp_assign from HLOS to those VM(s) 704 + */ 705 + unsigned int perms = BIT(QCOM_SCM_VMID_HLOS); 706 + 707 + map->attr = attr; 708 + err = qcom_scm_assign_mem(map->phys, (u64)map->size, &perms, 709 + fl->cctx->vmperms, fl->cctx->vmcount); 710 + if (err) { 711 + dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", 712 + map->phys, map->size, err); 713 + goto map_err; 714 + } 715 + } 720 716 spin_lock(&fl->lock); 721 717 list_add_tail(&map->node, &fl->maps); 722 718 spin_unlock(&fl->lock); ··· 817 781 int i, err; 818 782 819 783 for (i = 0; i < ctx->nscalars; ++i) { 820 - /* Make sure reserved field is set to 0 */ 821 - if (ctx->args[i].reserved) 822 - return -EINVAL; 823 784 824 785 if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 || 825 786 ctx->args[i].length == 0) 826 787 continue; 827 788 828 789 err = fastrpc_map_create(ctx->fl, ctx->args[i].fd, 829 - ctx->args[i].length, &ctx->maps[i]); 790 + ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]); 830 791 if (err) { 831 792 dev_err(dev, "Error Creating map %d\n", err); 832 793 return -EINVAL; ··· 1157 1124 fl->pd = USER_PD; 1158 1125 1159 1126 if (init.filelen && init.filefd) { 1160 - err = fastrpc_map_create(fl, init.filefd, init.filelen, &map); 1127 + err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map); 1161 1128 if (err) 1162 1129 goto err; 1163 1130 } ··· 1266 1233 args[0].ptr = (u64)(uintptr_t) &tgid; 1267 1234 args[0].length = sizeof(tgid); 1268 1235 args[0].fd = -1; 1269 - args[0].reserved = 0; 1270 1236 sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0); 1271 1237 1272 1238 return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, ··· 1413 1381 args[0].ptr = (u64)(uintptr_t) &tgid; 1414 1382 args[0].length = sizeof(tgid); 1415 1383 args[0].fd = -1; 1416 - args[0].reserved = 0; 1417 1384 sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0); 1418 1385 fl->pd = pd; 1419 1386 ··· 1985 1954 { 1986 1955 struct device *rdev = &rpdev->dev; 1987 1956 struct fastrpc_channel_ctx *data; 1988 - int i, err, domain_id = -1; 1957 + int i, err, domain_id = -1, vmcount; 1989 1958 const char *domain; 1990 1959 bool secure_dsp; 1960 + unsigned int vmids[FASTRPC_MAX_VMIDS]; 1991 1961 1992 1962 err = of_property_read_string(rdev->of_node, "label", &domain); 1993 1963 if (err) { ··· 2008 1976 return -EINVAL; 2009 1977 } 2010 1978 1979 + vmcount = of_property_read_variable_u32_array(rdev->of_node, 1980 + "qcom,vmids", &vmids[0], 0, FASTRPC_MAX_VMIDS); 1981 + if (vmcount < 0) 1982 + vmcount = 0; 1983 + else if (!qcom_scm_is_available()) 1984 + return -EPROBE_DEFER; 1985 + 2011 1986 data = kzalloc(sizeof(*data), GFP_KERNEL); 2012 1987 if (!data) 2013 1988 return -ENOMEM; 2014 1989 1990 + if (vmcount) { 1991 + data->vmcount = vmcount; 1992 + data->perms = BIT(QCOM_SCM_VMID_HLOS); 1993 + for (i = 0; i < data->vmcount; i++) { 1994 + data->vmperms[i].vmid = vmids[i]; 1995 + data->vmperms[i].perm = QCOM_SCM_PERM_RWX; 1996 + } 1997 + } 2015 1998 2016 1999 secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain")); 2017 2000 data->secure = secure_dsp;
+4 -1
include/uapi/misc/fastrpc.h
··· 63 63 FASTRPC_MODE_PRIVILEGED = (1 << 6), 64 64 }; 65 65 66 + /* Fastrpc attribute for memory protection of buffers */ 67 + #define FASTRPC_ATTR_SECUREMAP (1) 68 + 66 69 struct fastrpc_invoke_args { 67 70 __u64 ptr; 68 71 __u64 length; 69 72 __s32 fd; 70 - __u32 reserved; 73 + __u32 attr; 71 74 }; 72 75 73 76 struct fastrpc_invoke {