--- /dev/null
+From 17b88a2050e9d1f89a53562f2adb709a8959e763 Mon Sep 17 00:00:00 2001
+From: Deepak Kumar Singh <quic_deesin@quicinc.com>
+Date: Mon, 19 Sep 2022 16:23:59 +0530
+Subject: rpmsg: char: Add lock to avoid race when rpmsg device is released
+
+From: Deepak Kumar Singh <quic_deesin@quicinc.com>
+
+commit 17b88a2050e9d1f89a53562f2adb709a8959e763 upstream.
+
+When remote host goes down glink char device channel is freed and
+associated rpdev is destroyed through rpmsg_chrdev_eptdev_destroy(),
+At the same time user space apps can still try to open/poll rpmsg
+char device which will result in calling rpmsg_create_ept()/rpmsg_poll().
+These functions will try to reference rpdev which has already been freed
+through rpmsg_chrdev_eptdev_destroy().
+
+File operation functions and device removal function must be protected
+with lock. This patch adds existing ept lock in remove function as well.
+
+Signed-off-by: Deepak Kumar Singh <quic_deesin@quicinc.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/1663584840-15762-2-git-send-email-quic_deesin@quicinc.com
+Signed-off-by: Wen Yang <wen.yang@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/rpmsg/rpmsg_char.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/rpmsg/rpmsg_char.c
++++ b/drivers/rpmsg/rpmsg_char.c
+@@ -75,6 +75,7 @@ int rpmsg_chrdev_eptdev_destroy(struct d
+ struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
+
+ mutex_lock(&eptdev->ept_lock);
++ eptdev->rpdev = NULL;
+ if (eptdev->ept) {
+ /* The default endpoint is released by the rpmsg core */
+ if (!eptdev->default_ept)
+@@ -128,6 +129,11 @@ static int rpmsg_eptdev_open(struct inod
+ return -EBUSY;
+ }
+
++ if (!eptdev->rpdev) {
++ mutex_unlock(&eptdev->ept_lock);
++ return -ENETRESET;
++ }
++
+ get_device(dev);
+
+ /*
+@@ -279,7 +285,9 @@ static __poll_t rpmsg_eptdev_poll(struct
+ if (!skb_queue_empty(&eptdev->queue))
+ mask |= EPOLLIN | EPOLLRDNORM;
+
++ mutex_lock(&eptdev->ept_lock);
+ mask |= rpmsg_poll(eptdev->ept, filp, wait);
++ mutex_unlock(&eptdev->ept_lock);
+
+ return mask;
+ }