In order to be able to start the adsp listener for audiopd using adsprpcd,
we need to add the corresponding ioctl for creating a static process.
On that ioctl call we need to allocate the heap. Allocating the heap needs
to be happening only once and needs to be kept between different device
open calls, so attach it to the channel context to make sure that remains
until the RPMSG driver is removed. Then, if there are any VMIDs associated
with the static ADSP process, do a call to SCM to assign it.
And then, send all the necessary info related to heap to the DSP.
Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
---
drivers/misc/fastrpc.c | 126 ++++++++++++++++++++++++++++++++++++
include/uapi/misc/fastrpc.h | 7 ++
2 files changed, 133 insertions(+)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 7c364c58e379..2c656da4ca5e 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -37,8 +37,20 @@
#define FASTRPC_DSP_UTILITIES_HANDLE 2
#define FASTRPC_CTXID_MASK (0xFF0)
#define INIT_FILELEN_MAX (2 * 1024 * 1024)
+#define INIT_FILE_NAMELEN_MAX (128)
#define FASTRPC_DEVICE_NAME "fastrpc"
+
+/* Add memory to static PD pool, protection thru XPU */
+#define ADSP_MMAP_HEAP_ADDR 4
+/* MAP static DMA buffer on DSP User PD */
+#define ADSP_MMAP_DMA_BUFFER 6
+/* Add memory to static PD pool protection thru hypervisor */
+#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
+/* Add memory to userPD pool, for user heap */
#define ADSP_MMAP_ADD_PAGES 0x1000
+/* Add memory to userPD pool, for LLC heap */
+#define ADSP_MMAP_ADD_PAGES_LLC 0x3000,
+
#define DSP_UNSUPPORTED_API (0x80000414)
/* MAX NUMBER of DSP ATTRIBUTES SUPPORTED */
#define FASTRPC_MAX_DSP_ATTRIBUTES (256)
@@ -72,6 +84,7 @@
FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0)
#define FASTRPC_CREATE_PROCESS_NARGS 6
+#define FASTRPC_CREATE_STATIC_PROCESS_NARGS 3
/* Remote Method id table */
#define FASTRPC_RMID_INIT_ATTACH 0
#define FASTRPC_RMID_INIT_RELEASE 1
@@ -261,6 +274,7 @@ struct fastrpc_channel_ctx {
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
struct fastrpc_device *secure_fdevice;
struct fastrpc_device *fdevice;
+ struct fastrpc_buf *remote_heap;
bool secure;
bool unsigned_support;
};
@@ -1167,6 +1181,7 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
spin_unlock(&fl->lock);
fastrpc_context_put(ctx);
}
+
if (err)
dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err);
@@ -1191,6 +1206,111 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques
return false;
}
+static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
+ char __user *argp)
+{
+ struct fastrpc_init_create_static init;
+ struct fastrpc_invoke_args *args;
+ struct fastrpc_phy_page pages[1];
+ char *name;
+ int err;
+ struct {
+ int pgid;
+ u32 namelen;
+ u32 pageslen;
+ } inbuf;
+ u32 sc;
+
+ args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+
+ if (copy_from_user(&init, argp, sizeof(init))) {
+ err = -EFAULT;
+ goto err;
+ }
+
+ if (init.namelen > INIT_FILE_NAMELEN_MAX) {
+ err = -EINVAL;
+ goto err;
+ }
+
+ name = kzalloc(init.namelen, GFP_KERNEL);
+ if (!name) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ if (copy_from_user(name, (void __user *)(uintptr_t)init.name, init.namelen)) {
+ err = -EFAULT;
+ goto err_name;
+ }
+
+ if (!fl->cctx->remote_heap) {
+ err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
+ &fl->cctx->remote_heap);
+ if (err)
+ goto err_name;
+
+ /* Map if we have any heap VMIDs associated with this ADSP Static Process. */
+ if (fl->cctx->vmcount) {
+ unsigned int perms = BIT(QCOM_SCM_VMID_HLOS);
+
+ dev_dbg(fl->sctx->dev, "Assinging memory with phys 0x%llx size 0x%llx perms 0x%x, vmperms %x, vmcount %x\n",
+ fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size,
+ perms, fl->cctx->vmperms, fl->cctx->vmcount);
+ err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
+ (u64)fl->cctx->remote_heap->size, &perms,
+ fl->cctx->vmperms, fl->cctx->vmcount);
+ if (err) {
+ dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",
+ fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+ goto err_map;
+ }
+ }
+ }
+
+ inbuf.pgid = fl->tgid;
+ inbuf.namelen = init.namelen;
+ inbuf.pageslen = 0;
+ fl->pd = USER_PD;
+
+ args[0].ptr = (u64)(uintptr_t)&inbuf;
+ args[0].length = sizeof(inbuf);
+ args[0].fd = -1;
+
+ args[1].ptr = (u64)(uintptr_t)name;
+ args[1].length = inbuf.namelen;
+ args[1].fd = -1;
+
+ pages[0].addr = fl->cctx->remote_heap->phys;
+ pages[0].size = fl->cctx->remote_heap->size;
+
+ args[2].ptr = (u64)(uintptr_t) pages;
+ args[2].length = sizeof(*pages);
+ args[2].fd = -1;
+
+ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0);
+
+ err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
+ sc, args);
+ if (err)
+ goto err_invoke;
+
+ kfree(args);
+
+ return 0;
+err_invoke:
+err_map:
+ fastrpc_buf_free(fl->cctx->remote_heap);
+err_name:
+ kfree(name);
+err:
+ kfree(args);
+
+ return err;
+}
+
static int fastrpc_init_create_process(struct fastrpc_user *fl,
char __user *argp)
{
@@ -1918,6 +2038,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
case FASTRPC_IOCTL_INIT_ATTACH_SNS:
err = fastrpc_init_attach(fl, SENSORS_PD);
break;
+ case FASTRPC_IOCTL_INIT_CREATE_STATIC:
+ err = fastrpc_init_create_static_process(fl, argp);
+ break;
case FASTRPC_IOCTL_INIT_CREATE:
err = fastrpc_init_create_process(fl, argp);
break;
@@ -2183,6 +2306,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
if (cctx->secure_fdevice)
misc_deregister(&cctx->secure_fdevice->miscdev);
+ if (cctx->remote_heap)
+ fastrpc_buf_free(cctx->remote_heap);
+
of_platform_depopulate(&rpdev->dev);
cctx->rpdev = NULL;
diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h
index 5e29f2cfa42d..2cdf2f137d33 100644
--- a/include/uapi/misc/fastrpc.h
+++ b/include/uapi/misc/fastrpc.h
@@ -16,6 +16,7 @@
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map)
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap)
#define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability)
+#define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 15, struct fastrpc_init_create_static)
/**
* enum fastrpc_map_flags - control flags for mapping memory on DSP user process
@@ -87,6 +88,12 @@ struct fastrpc_init_create {
__u64 file; /* pointer to elf file */
};
+struct fastrpc_init_create_static {
+ __u32 namelen; /* length of pd process name */
+ __u32 memlen;
+ __u64 name; /* pd process name */
+};
+
struct fastrpc_alloc_dma_buf {
__s32 fd; /* fd */
__u32 flags; /* flags to map with */
--
2.34.1
Hi Abel,
I love your patch! Perhaps something to improve:
[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on robh/for-next linus/master v6.0-rc3 next-20220901]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Abel-Vesa/misc-fastrpc-Add-audiopd-support-and-some-fixes/20220902-215548
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git 4ec7ac90ff399b7d9af81cc8afd430a22786c61b
config: ia64-allyesconfig (https://download.01.org/0day-ci/archive/20220904/202209041138.pdoIATKj-lkp@intel.com/config)
compiler: ia64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/40e5982368fa8e5eeb1a3ff7b955d0c0b54656d1
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Abel-Vesa/misc-fastrpc-Add-audiopd-support-and-some-fixes/20220902-215548
git checkout 40e5982368fa8e5eeb1a3ff7b955d0c0b54656d1
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=ia64 SHELL=/bin/bash drivers/misc/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
In file included from include/linux/printk.h:573,
from include/asm-generic/bug.h:22,
from arch/ia64/include/asm/bug.h:17,
from include/linux/bug.h:5,
from include/linux/thread_info.h:13,
from include/asm-generic/preempt.h:5,
from ./arch/ia64/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:55,
from include/linux/swait.h:7,
from include/linux/completion.h:12,
from drivers/misc/fastrpc.c:5:
drivers/misc/fastrpc.c: In function 'fastrpc_init_create_static_process':
>> drivers/misc/fastrpc.c:1259:48: warning: format '%x' expects argument of type 'unsigned int', but argument 7 has type 'struct qcom_scm_vmperm *' [-Wformat=]
1259 | dev_dbg(fl->sctx->dev, "Assinging memory with phys 0x%llx size 0x%llx perms 0x%x, vmperms %x, vmcount %x\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/dynamic_debug.h:134:29: note: in definition of macro '__dynamic_func_call'
134 | func(&id, ##__VA_ARGS__); \
| ^~~~~~~~~~~
include/linux/dynamic_debug.h:166:9: note: in expansion of macro '_dynamic_func_call'
166 | _dynamic_func_call(fmt,__dynamic_dev_dbg, \
| ^~~~~~~~~~~~~~~~~~
include/linux/dev_printk.h:155:9: note: in expansion of macro 'dynamic_dev_dbg'
155 | dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~
include/linux/dev_printk.h:155:30: note: in expansion of macro 'dev_fmt'
155 | dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~
drivers/misc/fastrpc.c:1259:25: note: in expansion of macro 'dev_dbg'
1259 | dev_dbg(fl->sctx->dev, "Assinging memory with phys 0x%llx size 0x%llx perms 0x%x, vmperms %x, vmcount %x\n",
| ^~~~~~~
drivers/misc/fastrpc.c:1259:116: note: format string is defined here
1259 | dev_dbg(fl->sctx->dev, "Assinging memory with phys 0x%llx size 0x%llx perms 0x%x, vmperms %x, vmcount %x\n",
| ~^
| |
| unsigned int
{standard input}: Assembler messages:
{standard input}:1031: Error: Register number out of range 0..4
{standard input}:1032: Error: Register number out of range 0..4
{standard input}:1032: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 44
{standard input}:1032: Warning: Only the first path encountering the conflict is reported
{standard input}:1031: Warning: This is the location of the conflicting usage
{standard input}:1036: Error: Register number out of range 0..4
{standard input}:1193: Error: Register number out of range 0..2
{standard input}:1193: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1193: Warning: Only the first path encountering the conflict is reported
{standard input}:1189: Warning: This is the location of the conflicting usage
{standard input}:1194: Error: Register number out of range 0..2
{standard input}:1194: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1194: Warning: Only the first path encountering the conflict is reported
{standard input}:1189: Warning: This is the location of the conflicting usage
{standard input}:1194: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1194: Warning: Only the first path encountering the conflict is reported
{standard input}:1193: Warning: This is the location of the conflicting usage
{standard input}:1195: Error: Register number out of range 0..2
{standard input}:1195: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1195: Warning: Only the first path encountering the conflict is reported
{standard input}:1189: Warning: This is the location of the conflicting usage
{standard input}:1195: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1195: Warning: Only the first path encountering the conflict is reported
{standard input}:1193: Warning: This is the location of the conflicting usage
{standard input}:1195: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1195: Warning: Only the first path encountering the conflict is reported
{standard input}:1194: Warning: This is the location of the conflicting usage
{standard input}:1198: Error: Register number out of range 0..2
{standard input}:1199: Error: Register number out of range 0..2
{standard input}:1199: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 38
{standard input}:1199: Warning: Only the first path encountering the conflict is reported
{standard input}:1198: Warning: This is the location of the conflicting usage
{standard input}:2810: Error: Register number out of range 0..3
{standard input}:2811: Error: Register number out of range 0..3
{standard input}:2811: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 46
{standard input}:2811: Warning: Only the first path encountering the conflict is reported
{standard input}:2810: Warning: This is the location of the conflicting usage
{standard input}:2812: Error: Register number out of range 0..3
{standard input}:2812: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 46
{standard input}:2812: Warning: Only the first path encountering the conflict is reported
{standard input}:2810: Warning: This is the location of the conflicting usage
{standard input}:2812: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 46
{standard input}:2812: Warning: Only the first path encountering the conflict is reported
{standard input}:2811: Warning: This is the location of the conflicting usage
{standard input}:2816: Error: Register number out of range 0..3
{standard input}:3634: Error: Register number out of range 0..3
{standard input}:3635: Error: Register number out of range 0..3
{standard input}:3635: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 51
{standard input}:3635: Warning: Only the first path encountering the conflict is reported
{standard input}:3634: Warning: This is the location of the conflicting usage
{standard input}:3636: Error: Register number out of range 0..3
{standard input}:3636: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 51
{standard input}:3636: Warning: Only the first path encountering the conflict is reported
{standard input}:3634: Warning: This is the location of the conflicting usage
{standard input}:3636: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 51
{standard input}:3636: Warning: Only the first path encountering the conflict is reported
{standard input}:3635: Warning: This is the location of the conflicting usage
{standard input}:3640: Error: Register number out of range 0..3
{standard input}:3955: Error: Register number out of range 0..4
{standard input}:3955: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 44
{standard input}:3955: Warning: Only the first path encountering the conflict is reported
{standard input}:3949: Warning: This is the location of the conflicting usage
{standard input}:3958: Error: Register number out of range 0..4
{standard input}:3959: Error: Register number out of range 0..4
{standard input}:3959: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 44
{standard input}:3959: Warning: Only the first path encountering the conflict is reported
{standard input}:3958: Warning: This is the location of the conflicting usage
{standard input}:4343: Error: Register number out of range 0..4
{standard input}:4343: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 43
{standard input}:4343: Warning: Only the first path encountering the conflict is reported
{standard input}:4337: Warning: This is the location of the conflicting usage
{standard input}:4346: Error: Register number out of range 0..4
{standard input}:4347: Error: Register number out of range 0..4
{standard input}:4347: Warning: Use of 'mov' violates WAW dependency 'GR%, % in 1 - 127' (impliedf), specific resource number is 43
{standard input}:4347: Warning: Only the first path encountering the conflict is reported
{standard input}:4346: Warning: This is the location of the conflicting usage
{standard input}:4497: Error: Register number out of range 0..2
vim +1259 drivers/misc/fastrpc.c
1208
1209 static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
1210 char __user *argp)
1211 {
1212 struct fastrpc_init_create_static init;
1213 struct fastrpc_invoke_args *args;
1214 struct fastrpc_phy_page pages[1];
1215 char *name;
1216 int err;
1217 struct {
1218 int pgid;
1219 u32 namelen;
1220 u32 pageslen;
1221 } inbuf;
1222 u32 sc;
1223
1224 args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
1225 if (!args)
1226 return -ENOMEM;
1227
1228 if (copy_from_user(&init, argp, sizeof(init))) {
1229 err = -EFAULT;
1230 goto err;
1231 }
1232
1233 if (init.namelen > INIT_FILE_NAMELEN_MAX) {
1234 err = -EINVAL;
1235 goto err;
1236 }
1237
1238 name = kzalloc(init.namelen, GFP_KERNEL);
1239 if (!name) {
1240 err = -ENOMEM;
1241 goto err;
1242 }
1243
1244 if (copy_from_user(name, (void __user *)(uintptr_t)init.name, init.namelen)) {
1245 err = -EFAULT;
1246 goto err_name;
1247 }
1248
1249 if (!fl->cctx->remote_heap) {
1250 err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
1251 &fl->cctx->remote_heap);
1252 if (err)
1253 goto err_name;
1254
1255 /* Map if we have any heap VMIDs associated with this ADSP Static Process. */
1256 if (fl->cctx->vmcount) {
1257 unsigned int perms = BIT(QCOM_SCM_VMID_HLOS);
1258
> 1259 dev_dbg(fl->sctx->dev, "Assinging memory with phys 0x%llx size 0x%llx perms 0x%x, vmperms %x, vmcount %x\n",
1260 fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size,
1261 perms, fl->cctx->vmperms, fl->cctx->vmcount);
1262 err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
1263 (u64)fl->cctx->remote_heap->size, &perms,
1264 fl->cctx->vmperms, fl->cctx->vmcount);
1265 if (err) {
1266 dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",
1267 fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
1268 goto err_map;
1269 }
1270 }
1271 }
1272
1273 inbuf.pgid = fl->tgid;
1274 inbuf.namelen = init.namelen;
1275 inbuf.pageslen = 0;
1276 fl->pd = USER_PD;
1277
1278 args[0].ptr = (u64)(uintptr_t)&inbuf;
1279 args[0].length = sizeof(inbuf);
1280 args[0].fd = -1;
1281
1282 args[1].ptr = (u64)(uintptr_t)name;
1283 args[1].length = inbuf.namelen;
1284 args[1].fd = -1;
1285
1286 pages[0].addr = fl->cctx->remote_heap->phys;
1287 pages[0].size = fl->cctx->remote_heap->size;
1288
1289 args[2].ptr = (u64)(uintptr_t) pages;
1290 args[2].length = sizeof(*pages);
1291 args[2].fd = -1;
1292
1293 sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0);
1294
1295 err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
1296 sc, args);
1297 if (err)
1298 goto err_invoke;
1299
1300 kfree(args);
1301
1302 return 0;
1303 err_invoke:
1304 err_map:
1305 fastrpc_buf_free(fl->cctx->remote_heap);
1306 err_name:
1307 kfree(name);
1308 err:
1309 kfree(args);
1310
1311 return err;
1312 }
1313
--
0-DAY CI Kernel Test Service
https://01.org/lkp
© 2016 - 2026 Red Hat, Inc.