Move the lookup of the munmap request to the fastrpc_req_munmap and pass on only the buf to the lower level fastrpc_req_munmap_impl. That way we can use the lower level fastrpc_req_munmap_impl on error path in fastrpc_req_mmap to free the buf without searching for the munmap request it belongs to.
Unified · Split
| @@ -1627,30 +1627,14 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp) · 1626 unmodified lines | |||
| 1627 | return 0; | 1627 | return 0; |
| 1628 | } | 1628 | } |
| 1629 | 1629 | ||
| 1630 | static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, | 1630 | static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *buf) |
| 1631 | struct fastrpc_req_munmap *req) | ||
| 1632 | { | 1631 | { |
| 1633 | struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; | 1632 | struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; |
| 1634 | struct fastrpc_buf *buf = NULL, *iter, *b; | ||
| 1635 | struct fastrpc_munmap_req_msg req_msg; | 1633 | struct fastrpc_munmap_req_msg req_msg; |
| 1636 | struct device *dev = fl->sctx->dev; | 1634 | struct device *dev = fl->sctx->dev; |
| 1637 | int err; | 1635 | int err; |
| 1638 | u32 sc; | 1636 | u32 sc; |
| 1639 | 1637 | ||
| 1640 | spin_lock(&fl->lock); | ||
| 1641 | list_for_each_entry_safe(iter, b, &fl->mmaps, node) { | ||
| 1642 | if ((iter->raddr == req->vaddrout) && (iter->size == req->size)) { | ||
| 1643 | buf = iter; | ||
| 1644 | break; | ||
| 1645 | } | ||
| 1646 | } | ||
| 1647 | spin_unlock(&fl->lock); | ||
| 1648 | |||
| 1649 | if (!buf) { | ||
| 1650 | dev_err(dev, "mmap not in list\n"); | ||
| 1651 | return -EINVAL; | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | req_msg.pgid = fl->tgid; | 1638 | req_msg.pgid = fl->tgid; |
| 1655 | req_msg.size = buf->size; | 1639 | req_msg.size = buf->size; |
| 1656 | req_msg.vaddr = buf->raddr; | 1640 | req_msg.vaddr = buf->raddr; |
| @@ -1676,12 +1660,29 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, · 19 unmodified lines | |||
| 1676 | 1660 | ||
| 1677 | static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) | 1661 | static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) |
| 1678 | { | 1662 | { |
| 1663 | struct fastrpc_buf *buf = NULL, *iter, *b; | ||
| 1679 | struct fastrpc_req_munmap req; | 1664 | struct fastrpc_req_munmap req; |
| 1665 | struct device *dev = fl->sctx->dev; | ||
| 1680 | 1666 | ||
| 1681 | if (copy_from_user(&req, argp, sizeof(req))) | 1667 | if (copy_from_user(&req, argp, sizeof(req))) |
| 1682 | return -EFAULT; | 1668 | return -EFAULT; |
| 1683 | 1669 | ||
| 1684 | return fastrpc_req_munmap_impl(fl, &req); | 1670 | spin_lock(&fl->lock); |
| 1671 | list_for_each_entry_safe(iter, b, &fl->mmaps, node) { | ||
| 1672 | if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) { | ||
| 1673 | buf = iter; | ||
| 1674 | break; | ||
| 1675 | } | ||
| 1676 | } | ||
| 1677 | spin_unlock(&fl->lock); | ||
| 1678 | |||
| 1679 | if (!buf) { | ||
| 1680 | dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n", | ||
| 1681 | req.vaddrout, req.size); | ||
| 1682 | return -EINVAL; | ||
| 1683 | } | ||
| 1684 | |||
| 1685 | return fastrpc_req_munmap_impl(fl, buf); | ||
| 1685 | } | 1686 | } |
| 1686 | 1687 | ||
| 1687 | static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) | 1688 | static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) |
| @@ -1690,7 +1691,6 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) · 2 unmodified lines | |||
| 1690 | struct fastrpc_buf *buf = NULL; | 1691 | struct fastrpc_buf *buf = NULL; |
| 1691 | struct fastrpc_mmap_req_msg req_msg; | 1692 | struct fastrpc_mmap_req_msg req_msg; |
| 1692 | struct fastrpc_mmap_rsp_msg rsp_msg; | 1693 | struct fastrpc_mmap_rsp_msg rsp_msg; |
| 1693 | struct fastrpc_req_munmap req_unmap; | ||
| 1694 | struct fastrpc_phy_page pages; | 1694 | struct fastrpc_phy_page pages; |
| 1695 | struct fastrpc_req_mmap req; | 1695 | struct fastrpc_req_mmap req; |
| 1696 | struct device *dev = fl->sctx->dev; | 1696 | struct device *dev = fl->sctx->dev; |
| @@ -1752,11 +1752,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) · 55 unmodified lines | |||
| 1752 | spin_unlock(&fl->lock); | 1752 | spin_unlock(&fl->lock); |
| 1753 | 1753 | ||
| 1754 | if (copy_to_user((void __user *)argp, &req, sizeof(req))) { | 1754 | if (copy_to_user((void __user *)argp, &req, sizeof(req))) { |
| 1755 | /* unmap the memory and release the buffer */ | 1755 | err = -EFAULT; |
| 1756 | req_unmap.vaddrout = buf->raddr; | 1756 | goto err_assign; |
| 1757 | req_unmap.size = buf->size; | ||
| 1758 | fastrpc_req_munmap_impl(fl, &req_unmap); | ||
| 1759 | return -EFAULT; | ||
| 1760 | } | 1757 | } |
| 1761 | 1758 | ||
| 1762 | dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n", | 1759 | dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n", |
| @@ -1764,6 +1761,8 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) · 1 unmodified line | |||
| 1764 | 1761 | ||
| 1765 | return 0; | 1762 | return 0; |
| 1766 | 1763 | ||
| 1764 | err_assign: | ||
| 1765 | fastrpc_req_munmap_impl(fl, buf); | ||
| 1767 | err_invoke: | 1766 | err_invoke: |
| 1768 | fastrpc_buf_free(buf); | 1767 | fastrpc_buf_free(buf); |
| 1769 | 1768 | ||