Message ID | 20220126135304.16340-3-srinivas.kandagatla@linaro.org (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | misc: fastrpc: Add missing DSP FastRPC features | expand |
Hi Srinivas, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on char-misc/char-misc-testing] [also build test WARNING on robh/for-next linux/master linus/master v5.17-rc1 next-20220125] [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] url: https://github.com/0day-ci/linux/commits/Srinivas-Kandagatla/misc-fastrpc-Add-missing-DSP-FastRPC-features/20220126-215705 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git 515a2f507491e7c3818e74ef4f4e088c1fecb190 config: nds32-randconfig-r014-20220126 (https://download.01.org/0day-ci/archive/20220127/202201270134.bsVprnF9-lkp@intel.com/config) compiler: nds32le-linux-gcc (GCC) 11.2.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/0day-ci/linux/commit/b1c0b7969aa491881596e862a90a07afae4bdfd7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Srinivas-Kandagatla/misc-fastrpc-Add-missing-DSP-FastRPC-features/20220126-215705 git checkout b1c0b7969aa491881596e862a90a07afae4bdfd7 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nds32 SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): drivers/misc/fastrpc.c: In function 'fastrpc_req_mem_unmap_impl': >> drivers/misc/fastrpc.c:1544:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 1544 | args[0].ptr = (u64) &req_msg; | ^ drivers/misc/fastrpc.c: In function 'fastrpc_req_mem_map': >> drivers/misc/fastrpc.c:1594:19: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 1594 | map->va = (void *) req.vaddrin; | ^ drivers/misc/fastrpc.c:1599:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 1599 | args[0].ptr = (u64) &req_msg; | ^ drivers/misc/fastrpc.c:1605:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 1605 | args[1].ptr = (u64) &pages; | ^ drivers/misc/fastrpc.c:1608:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 1608 | args[2].ptr = (u64) &pages; | ^ drivers/misc/fastrpc.c:1611:23: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 1611 | args[3].ptr = (u64) &rsp_msg; | ^ vim +1544 drivers/misc/fastrpc.c 1515 1516 static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req) 1517 { 1518 struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; 1519 struct fastrpc_map *map = NULL, *m; 1520 struct fastrpc_mem_unmap_req_msg req_msg = { 0 }; 1521 int err = 0; 1522 u32 sc; 1523 struct device *dev = fl->sctx->dev; 1524 1525 spin_lock(&fl->lock); 1526 list_for_each_entry_safe(map, m, &fl->maps, node) { 1527 if ((req->fd < 0 || map->fd == req->fd) && (map->raddr == req->vaddr)) 1528 break; 1529 map = NULL; 1530 } 1531 1532 spin_unlock(&fl->lock); 1533 1534 if (!map) { 1535 dev_err(dev, "map not in list\n"); 1536 return -EINVAL; 1537 } 1538 1539 req_msg.pgid = fl->tgid; 1540 req_msg.len = map->len; 1541 req_msg.vaddrin = map->raddr; 1542 req_msg.fd = map->fd; 1543 > 1544 args[0].ptr = (u64) &req_msg; 1545 args[0].length = sizeof(req_msg); 1546 1547 sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0); 1548 err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, 1549 &args[0]); 1550 fastrpc_map_put(map); 1551 if (err) 1552 dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); 1553 1554 return err; 1555 } 1556 1557 static int fastrpc_req_mem_unmap(struct fastrpc_user *fl, char __user *argp) 1558 { 1559 struct fastrpc_mem_unmap req; 1560 1561 if (copy_from_user(&req, argp, sizeof(req))) 1562 return -EFAULT; 1563 1564 return fastrpc_req_mem_unmap_impl(fl, &req); 1565 } 1566 1567 static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) 1568 { 1569 struct fastrpc_invoke_args args[4] = { [0 ... 3] = { 0 } }; 1570 struct fastrpc_mem_map_req_msg req_msg = { 0 }; 1571 struct fastrpc_mmap_rsp_msg rsp_msg = { 0 }; 1572 struct fastrpc_mem_unmap req_unmap = { 0 }; 1573 struct fastrpc_phy_page pages = { 0 }; 1574 struct fastrpc_mem_map req; 1575 struct device *dev = fl->sctx->dev; 1576 struct fastrpc_map *map = NULL; 1577 int err; 1578 u32 sc; 1579 1580 if (copy_from_user(&req, argp, sizeof(req))) 1581 return -EFAULT; 1582 1583 /* create SMMU mapping */ 1584 err = fastrpc_map_create(fl, req.fd, req.length, &map); 1585 if (err) { 1586 dev_err(dev, "failed to map buffer, fd = %d\n", req.fd); 1587 return err; 1588 } 1589 1590 req_msg.pgid = fl->tgid; 1591 req_msg.fd = req.fd; 1592 req_msg.offset = req.offset; 1593 req_msg.vaddrin = req.vaddrin; > 1594 map->va = (void *) req.vaddrin; 1595 req_msg.flags = req.flags; 1596 req_msg.num = sizeof(pages); 1597 req_msg.data_len = 0; 1598 1599 args[0].ptr = (u64) &req_msg; 1600 args[0].length = sizeof(req_msg); 1601 1602 pages.addr = map->phys; 1603 pages.size = map->size; 1604 1605 args[1].ptr = (u64) &pages; 1606 args[1].length = sizeof(pages); 1607 1608 args[2].ptr = (u64) &pages; 1609 args[2].length = 0; 1610 1611 args[3].ptr = (u64) &rsp_msg; 1612 args[3].length = sizeof(rsp_msg); 1613 1614 sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_MAP, 3, 1); 1615 err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); 1616 if (err) { 1617 dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n", 1618 req.fd, req.vaddrin, map->size); 1619 goto err_invoke; 1620 } 1621 1622 /* update the buffer to be able to deallocate the memory on the DSP */ 1623 map->raddr = rsp_msg.vaddr; 1624 1625 /* let the client know the address to use */ 1626 req.vaddrout = rsp_msg.vaddr; 1627 1628 if (copy_to_user((void __user *)argp, &req, sizeof(req))) { 1629 /* unmap the memory and release the buffer */ 1630 req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr; 1631 req_unmap.length = map->size; 1632 fastrpc_req_mem_unmap_impl(fl, &req_unmap); 1633 return -EFAULT; 1634 } 1635 1636 return 0; 1637 1638 err_invoke: 1639 if (map) 1640 fastrpc_map_put(map); 1641 1642 return err; 1643 } 1644 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Srinivas, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on char-misc/char-misc-testing] [also build test WARNING on robh/for-next linux/master linus/master v5.17-rc1 next-20220125] [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] url: https://github.com/0day-ci/linux/commits/Srinivas-Kandagatla/misc-fastrpc-Add-missing-DSP-FastRPC-features/20220126-215705 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git 515a2f507491e7c3818e74ef4f4e088c1fecb190 config: csky-randconfig-s031-20220124 (https://download.01.org/0day-ci/archive/20220127/202201271240.IB5pvRUs-lkp@intel.com/config) compiler: csky-linux-gcc (GCC) 11.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-dirty # https://github.com/0day-ci/linux/commit/b1c0b7969aa491881596e862a90a07afae4bdfd7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Srinivas-Kandagatla/misc-fastrpc-Add-missing-DSP-FastRPC-features/20220126-215705 git checkout b1c0b7969aa491881596e862a90a07afae4bdfd7 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=csky SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> drivers/misc/fastrpc.c:1544:30: sparse: sparse: non size-preserving pointer to integer cast drivers/misc/fastrpc.c:1599:30: sparse: sparse: non size-preserving pointer to integer cast drivers/misc/fastrpc.c:1605:30: sparse: sparse: non size-preserving pointer to integer cast drivers/misc/fastrpc.c:1608:30: sparse: sparse: non size-preserving pointer to integer cast drivers/misc/fastrpc.c:1611:30: sparse: sparse: non size-preserving pointer to integer cast vim +1544 drivers/misc/fastrpc.c 1515 1516 static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req) 1517 { 1518 struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; 1519 struct fastrpc_map *map = NULL, *m; 1520 struct fastrpc_mem_unmap_req_msg req_msg = { 0 }; 1521 int err = 0; 1522 u32 sc; 1523 struct device *dev = fl->sctx->dev; 1524 1525 spin_lock(&fl->lock); 1526 list_for_each_entry_safe(map, m, &fl->maps, node) { 1527 if ((req->fd < 0 || map->fd == req->fd) && (map->raddr == req->vaddr)) 1528 break; 1529 map = NULL; 1530 } 1531 1532 spin_unlock(&fl->lock); 1533 1534 if (!map) { 1535 dev_err(dev, "map not in list\n"); 1536 return -EINVAL; 1537 } 1538 1539 req_msg.pgid = fl->tgid; 1540 req_msg.len = map->len; 1541 req_msg.vaddrin = map->raddr; 1542 req_msg.fd = map->fd; 1543 > 1544 args[0].ptr = (u64) &req_msg; 1545 args[0].length = sizeof(req_msg); 1546 1547 sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0); 1548 err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, 1549 &args[0]); 1550 fastrpc_map_put(map); 1551 if (err) 1552 dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); 1553 1554 return err; 1555 } 1556 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 00cf0dbb6084..a840b8dabf0e 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -72,6 +72,8 @@ #define FASTRPC_RMID_INIT_CREATE 6 #define FASTRPC_RMID_INIT_CREATE_ATTR 7 #define FASTRPC_RMID_INIT_CREATE_STATIC 8 +#define FASTRPC_RMID_INIT_MEM_MAP 10 +#define FASTRPC_RMID_INIT_MEM_UNMAP 11 /* Protection Domain(PD) ids */ #define AUDIO_PD (0) /* also GUEST_OS PD? */ @@ -108,12 +110,29 @@ struct fastrpc_mmap_req_msg { s32 num; }; +struct fastrpc_mem_map_req_msg { + s32 pgid; + s32 fd; + s32 offset; + u32 flags; + u64 vaddrin; + s32 num; + s32 data_len; +}; + struct fastrpc_munmap_req_msg { s32 pgid; u64 vaddr; u64 size; }; +struct fastrpc_mem_unmap_req_msg { + s32 pgid; + s32 fd; + u64 vaddrin; + u64 len; +}; + struct fastrpc_msg { int pid; /* process group id */ int tid; /* thread id */ @@ -170,6 +189,7 @@ struct fastrpc_map { u64 size; void *va; u64 len; + u64 raddr; struct kref refcount; }; @@ -1493,6 +1513,135 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) return err; } +static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req) +{ + struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; + struct fastrpc_map *map = NULL, *m; + struct fastrpc_mem_unmap_req_msg req_msg = { 0 }; + int err = 0; + u32 sc; + struct device *dev = fl->sctx->dev; + + spin_lock(&fl->lock); + list_for_each_entry_safe(map, m, &fl->maps, node) { + if ((req->fd < 0 || map->fd == req->fd) && (map->raddr == req->vaddr)) + break; + map = NULL; + } + + spin_unlock(&fl->lock); + + if (!map) { + dev_err(dev, "map not in list\n"); + return -EINVAL; + } + + req_msg.pgid = fl->tgid; + req_msg.len = map->len; + req_msg.vaddrin = map->raddr; + req_msg.fd = map->fd; + + args[0].ptr = (u64) &req_msg; + args[0].length = sizeof(req_msg); + + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0); + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, + &args[0]); + fastrpc_map_put(map); + if (err) + dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr); + + return err; +} + +static int fastrpc_req_mem_unmap(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_mem_unmap req; + + if (copy_from_user(&req, argp, sizeof(req))) + return -EFAULT; + + return fastrpc_req_mem_unmap_impl(fl, &req); +} + +static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_invoke_args args[4] = { [0 ... 3] = { 0 } }; + struct fastrpc_mem_map_req_msg req_msg = { 0 }; + struct fastrpc_mmap_rsp_msg rsp_msg = { 0 }; + struct fastrpc_mem_unmap req_unmap = { 0 }; + struct fastrpc_phy_page pages = { 0 }; + struct fastrpc_mem_map req; + struct device *dev = fl->sctx->dev; + struct fastrpc_map *map = NULL; + int err; + u32 sc; + + if (copy_from_user(&req, argp, sizeof(req))) + return -EFAULT; + + /* create SMMU mapping */ + err = fastrpc_map_create(fl, req.fd, req.length, &map); + if (err) { + dev_err(dev, "failed to map buffer, fd = %d\n", req.fd); + return err; + } + + req_msg.pgid = fl->tgid; + req_msg.fd = req.fd; + req_msg.offset = req.offset; + req_msg.vaddrin = req.vaddrin; + map->va = (void *) req.vaddrin; + req_msg.flags = req.flags; + req_msg.num = sizeof(pages); + req_msg.data_len = 0; + + args[0].ptr = (u64) &req_msg; + args[0].length = sizeof(req_msg); + + pages.addr = map->phys; + pages.size = map->size; + + args[1].ptr = (u64) &pages; + args[1].length = sizeof(pages); + + args[2].ptr = (u64) &pages; + args[2].length = 0; + + args[3].ptr = (u64) &rsp_msg; + args[3].length = sizeof(rsp_msg); + + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_MAP, 3, 1); + err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); + if (err) { + dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n", + req.fd, req.vaddrin, map->size); + goto err_invoke; + } + + /* update the buffer to be able to deallocate the memory on the DSP */ + map->raddr = rsp_msg.vaddr; + + /* let the client know the address to use */ + req.vaddrout = rsp_msg.vaddr; + + if (copy_to_user((void __user *)argp, &req, sizeof(req))) { + /* unmap the memory and release the buffer */ + req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr; + req_unmap.length = map->size; + fastrpc_req_mem_unmap_impl(fl, &req_unmap); + return -EFAULT; + } + + return 0; + +err_invoke: + if (map) + fastrpc_map_put(map); + + return err; +} + static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1522,6 +1671,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_MUNMAP: err = fastrpc_req_munmap(fl, argp); break; + case FASTRPC_IOCTL_MEM_MAP: + err = fastrpc_req_mem_map(fl, argp); + break; + case FASTRPC_IOCTL_MEM_UNMAP: + err = fastrpc_req_mem_unmap(fl, argp); + break; default: err = -ENOTTY; break; diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 0a89f95463f6..d248eeb20e67 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -13,6 +13,37 @@ #define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_req_mmap) #define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_req_munmap) #define FASTRPC_IOCTL_INIT_ATTACH_SNS _IO('R', 8) +#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map) +#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap) + +/** + * enum fastrpc_map_flags - control flags for mapping memory on DSP user process + * @FASTRPC_MAP_STATIC: Map memory pages with RW- permission and CACHE WRITEBACK. + * The driver is responsible for cache maintenance when passed + * the buffer to FastRPC calls. Same virtual address will be + * assigned for subsequent FastRPC calls. + * @FASTRPC_MAP_RESERVED: Reserved + * @FASTRPC_MAP_FD: Map memory pages with RW- permission and CACHE WRITEBACK. + * Mapping tagged with a file descriptor. User is responsible for + * CPU and DSP cache maintenance for the buffer. Get virtual address + * of buffer on DSP using HAP_mmap_get() and HAP_mmap_put() APIs. + * @FASTRPC_MAP_FD_DELAYED: Mapping delayed until user call HAP_mmap() and HAP_munmap() + * functions on DSP. It is useful to map a buffer with cache modes + * other than default modes. User is responsible for CPU and DSP + * cache maintenance for the buffer. + * @FASTRPC_MAP_FD_NOMAP: This flag is used to skip CPU mapping, + * otherwise behaves similar to FASTRPC_MAP_FD_DELAYED flag. + * @FASTRPC_MAP_MAX: max count for flags + * + */ +enum fastrpc_map_flags { + FASTRPC_MAP_STATIC = 0, + FASTRPC_MAP_RESERVED, + FASTRPC_MAP_FD = 2, + FASTRPC_MAP_FD_DELAYED, + FASTRPC_MAP_FD_NOMAP = 16, + FASTRPC_MAP_MAX, +}; struct fastrpc_invoke_args { __u64 ptr; @@ -49,9 +80,29 @@ struct fastrpc_req_mmap { __u64 vaddrout; /* dsp virtual address */ }; +struct fastrpc_mem_map { + __s32 version; + __s32 fd; /* fd */ + __s32 offset; /* buffer offset */ + __u32 flags; /* flags defined in enum fastrpc_map_flags */ + __u64 vaddrin; /* buffer virtual address */ + __u64 length; /* buffer length */ + __u64 vaddrout; /* [out] remote virtual address */ + __s32 attrs; /* buffer attributes used for SMMU mapping */ + __s32 reserved[4]; +}; + struct fastrpc_req_munmap { __u64 vaddrout; /* address to unmap */ __u64 size; /* size */ }; +struct fastrpc_mem_unmap { + __s32 vesion; + __s32 fd; /* fd */ + __u64 vaddr; /* remote process (dsp) virtual address */ + __u64 length; /* buffer size */ + __s32 reserved[5]; +}; + #endif /* __QCOM_FASTRPC_H__ */