+++ /dev/null
-From 094a4a4442788dac53a1c3ae6743841d97a15d5f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 7 May 2020 18:35:39 -0700
-Subject: ipc/mqueue.c: change __do_notify() to bypass check_kill_permission()
-
-From: Oleg Nesterov <oleg@redhat.com>
-
-[ Upstream commit b5f2006144c6ae941726037120fa1001ddede784 ]
-
-Commit cc731525f26a ("signal: Remove kernel interal si_code magic")
-changed the value of SI_FROMUSER(SI_MESGQ), this means that mq_notify() no
-longer works if the sender doesn't have rights to send a signal.
-
-Change __do_notify() to use do_send_sig_info() instead of kill_pid_info()
-to avoid check_kill_permission().
-
-This needs the additional notify.sigev_signo != 0 check, shouldn't we
-change do_mq_notify() to deny sigev_signo == 0 ?
-
-Test-case:
-
- #include <signal.h>
- #include <mqueue.h>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <assert.h>
-
- static int notified;
-
- static void sigh(int sig)
- {
- notified = 1;
- }
-
- int main(void)
- {
- signal(SIGIO, sigh);
-
- int fd = mq_open("/mq", O_RDWR|O_CREAT, 0666, NULL);
- assert(fd >= 0);
-
- struct sigevent se = {
- .sigev_notify = SIGEV_SIGNAL,
- .sigev_signo = SIGIO,
- };
- assert(mq_notify(fd, &se) == 0);
-
- if (!fork()) {
- assert(setuid(1) == 0);
- mq_send(fd, "",1,0);
- return 0;
- }
-
- wait(NULL);
- mq_unlink("/mq");
- assert(notified);
- return 0;
- }
-
-[manfred@colorfullife.com: 1) Add self_exec_id evaluation so that the implementation matches do_notify_parent 2) use PIDTYPE_TGID everywhere]
-Fixes: cc731525f26a ("signal: Remove kernel interal si_code magic")
-Reported-by: Yoji <yoji.fujihar.min@gmail.com>
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
-Cc: Davidlohr Bueso <dave@stgolabs.net>
-Cc: Markus Elfring <elfring@users.sourceforge.net>
-Cc: <1vier1@web.de>
-Cc: <stable@vger.kernel.org>
-Link: http://lkml.kernel.org/r/e2a782e4-eab9-4f5c-c749-c07a8f7a4e66@colorfullife.com
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- ipc/mqueue.c | 34 ++++++++++++++++++++++++++--------
- 1 file changed, 26 insertions(+), 8 deletions(-)
-
-diff --git a/ipc/mqueue.c b/ipc/mqueue.c
-index dccd4ecb786ac..6829ea2ca1ea5 100644
---- a/ipc/mqueue.c
-+++ b/ipc/mqueue.c
-@@ -76,6 +76,7 @@ struct mqueue_inode_info {
-
- struct sigevent notify;
- struct pid *notify_owner;
-+ u32 notify_self_exec_id;
- struct user_namespace *notify_user_ns;
- struct user_struct *user; /* user who created, for accounting */
- struct sock *notify_sock;
-@@ -639,27 +640,43 @@ static void __do_notify(struct mqueue_inode_info *info)
- * synchronously. */
- if (info->notify_owner &&
- info->attr.mq_curmsgs == 1) {
-- struct siginfo sig_i;
- switch (info->notify.sigev_notify) {
- case SIGEV_NONE:
- break;
-- case SIGEV_SIGNAL:
-- /* sends signal */
-+ case SIGEV_SIGNAL: {
-+ struct siginfo sig_i;
-+ struct task_struct *task;
-+
-+ /* do_mq_notify() accepts sigev_signo == 0, why?? */
-+ if (!info->notify.sigev_signo)
-+ break;
-
- sig_i.si_signo = info->notify.sigev_signo;
- sig_i.si_errno = 0;
- sig_i.si_code = SI_MESGQ;
- sig_i.si_value = info->notify.sigev_value;
-- /* map current pid/uid into info->owner's namespaces */
- rcu_read_lock();
-+ /* map current pid/uid into info->owner's namespaces */
- sig_i.si_pid = task_tgid_nr_ns(current,
- ns_of_pid(info->notify_owner));
-- sig_i.si_uid = from_kuid_munged(info->notify_user_ns, current_uid());
-+ sig_i.si_uid = from_kuid_munged(info->notify_user_ns,
-+ current_uid());
-+ /*
-+ * We can't use kill_pid_info(), this signal should
-+ * bypass check_kill_permission(). It is from kernel
-+ * but si_fromuser() can't know this.
-+ * We do check the self_exec_id, to avoid sending
-+ * signals to programs that don't expect them.
-+ */
-+ task = pid_task(info->notify_owner, PIDTYPE_TGID);
-+ if (task && task->self_exec_id ==
-+ info->notify_self_exec_id) {
-+ do_send_sig_info(info->notify.sigev_signo,
-+ &sig_i, task, PIDTYPE_TGID);
-+ }
- rcu_read_unlock();
--
-- kill_pid_info(info->notify.sigev_signo,
-- &sig_i, info->notify_owner);
- break;
-+ }
- case SIGEV_THREAD:
- set_cookie(info->notify_cookie, NOTIFY_WOKENUP);
- netlink_sendskb(info->notify_sock, info->notify_cookie);
-@@ -1327,6 +1344,7 @@ retry:
- info->notify.sigev_signo = notification->sigev_signo;
- info->notify.sigev_value = notification->sigev_value;
- info->notify.sigev_notify = SIGEV_SIGNAL;
-+ info->notify_self_exec_id = current->self_exec_id;
- break;
- }
-
---
-2.20.1
-
--- /dev/null
+From 29555fa3de865630570b5f53c847b953413daf1a Mon Sep 17 00:00:00 2001
+From: Thierry Reding <treding@nvidia.com>
+Date: Thu, 24 May 2018 16:09:07 +0200
+Subject: net: stmmac: Use mutex instead of spinlock
+
+From: Thierry Reding <treding@nvidia.com>
+
+commit 29555fa3de865630570b5f53c847b953413daf1a upstream.
+
+Some drivers, such as DWC EQOS on Tegra, need to perform operations that
+can sleep under this lock (clk_set_rate() in tegra_eqos_fix_speed()) for
+proper operation. Since there is no need for this lock to be a spinlock,
+convert it to a mutex instead.
+
+Fixes: e6ea2d16fc61 ("net: stmmac: dwc-qos: Add Tegra186 support")
+Reported-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Tested-by: Bhadram Varka <vbhadram@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 -
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 12 +++----
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 31 ++++++++-----------
+ 3 files changed, 21 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -96,7 +96,7 @@ struct stmmac_priv {
+ struct net_device *dev;
+ struct device *device;
+ struct mac_device_info *hw;
+- spinlock_t lock;
++ struct mutex lock;
+
+ /* RX Queue */
+ struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES];
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -392,13 +392,13 @@ stmmac_ethtool_set_link_ksettings(struct
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full);
+
+- spin_lock(&priv->lock);
++ mutex_lock(&priv->lock);
+
+ if (priv->hw->mac->pcs_ctrl_ane)
+ priv->hw->mac->pcs_ctrl_ane(priv->ioaddr, 1,
+ priv->hw->ps, 0);
+
+- spin_unlock(&priv->lock);
++ mutex_unlock(&priv->lock);
+
+ return 0;
+ }
+@@ -615,12 +615,12 @@ static void stmmac_get_wol(struct net_de
+ {
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+- spin_lock_irq(&priv->lock);
++ mutex_lock(&priv->lock);
+ if (device_can_wakeup(priv->device)) {
+ wol->supported = WAKE_MAGIC | WAKE_UCAST;
+ wol->wolopts = priv->wolopts;
+ }
+- spin_unlock_irq(&priv->lock);
++ mutex_unlock(&priv->lock);
+ }
+
+ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+@@ -649,9 +649,9 @@ static int stmmac_set_wol(struct net_dev
+ disable_irq_wake(priv->wol_irq);
+ }
+
+- spin_lock_irq(&priv->lock);
++ mutex_lock(&priv->lock);
+ priv->wolopts = wol->wolopts;
+- spin_unlock_irq(&priv->lock);
++ mutex_unlock(&priv->lock);
+
+ return 0;
+ }
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -365,7 +365,6 @@ bool stmmac_eee_init(struct stmmac_priv
+ {
+ struct net_device *ndev = priv->dev;
+ int interface = priv->plat->interface;
+- unsigned long flags;
+ bool ret = false;
+
+ if ((interface != PHY_INTERFACE_MODE_MII) &&
+@@ -392,7 +391,7 @@ bool stmmac_eee_init(struct stmmac_priv
+ * changed).
+ * In that case the driver disable own timers.
+ */
+- spin_lock_irqsave(&priv->lock, flags);
++ mutex_lock(&priv->lock);
+ if (priv->eee_active) {
+ netdev_dbg(priv->dev, "disable EEE\n");
+ del_timer_sync(&priv->eee_ctrl_timer);
+@@ -400,11 +399,11 @@ bool stmmac_eee_init(struct stmmac_priv
+ tx_lpi_timer);
+ }
+ priv->eee_active = 0;
+- spin_unlock_irqrestore(&priv->lock, flags);
++ mutex_unlock(&priv->lock);
+ goto out;
+ }
+ /* Activate the EEE and start timers */
+- spin_lock_irqsave(&priv->lock, flags);
++ mutex_lock(&priv->lock);
+ if (!priv->eee_active) {
+ priv->eee_active = 1;
+ setup_timer(&priv->eee_ctrl_timer,
+@@ -421,7 +420,7 @@ bool stmmac_eee_init(struct stmmac_priv
+ priv->hw->mac->set_eee_pls(priv->hw, ndev->phydev->link);
+
+ ret = true;
+- spin_unlock_irqrestore(&priv->lock, flags);
++ mutex_unlock(&priv->lock);
+
+ netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
+ }
+@@ -799,13 +798,12 @@ static void stmmac_adjust_link(struct ne
+ {
+ struct stmmac_priv *priv = netdev_priv(dev);
+ struct phy_device *phydev = dev->phydev;
+- unsigned long flags;
+ bool new_state = false;
+
+ if (!phydev)
+ return;
+
+- spin_lock_irqsave(&priv->lock, flags);
++ mutex_lock(&priv->lock);
+
+ if (phydev->link) {
+ u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
+@@ -864,7 +862,7 @@ static void stmmac_adjust_link(struct ne
+ if (new_state && netif_msg_link(priv))
+ phy_print_status(phydev);
+
+- spin_unlock_irqrestore(&priv->lock, flags);
++ mutex_unlock(&priv->lock);
+
+ if (phydev->is_pseudo_fixed_link)
+ /* Stop PHY layer to call the hook to adjust the link in case
+@@ -4284,7 +4282,7 @@ int stmmac_dvr_probe(struct device *devi
+ (8 * priv->plat->rx_queues_to_use));
+ }
+
+- spin_lock_init(&priv->lock);
++ mutex_init(&priv->lock);
+
+ /* If a specific clk_csr value is passed from the platform
+ * this means that the CSR Clock Range selection cannot be
+@@ -4375,6 +4373,7 @@ int stmmac_dvr_remove(struct device *dev
+ priv->hw->pcs != STMMAC_PCS_TBI &&
+ priv->hw->pcs != STMMAC_PCS_RTBI)
+ stmmac_mdio_unregister(ndev);
++ mutex_destroy(&priv->lock);
+ free_netdev(ndev);
+
+ return 0;
+@@ -4392,7 +4391,6 @@ int stmmac_suspend(struct device *dev)
+ {
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
+- unsigned long flags;
+
+ if (!ndev || !netif_running(ndev))
+ return 0;
+@@ -4400,7 +4398,7 @@ int stmmac_suspend(struct device *dev)
+ if (ndev->phydev)
+ phy_stop(ndev->phydev);
+
+- spin_lock_irqsave(&priv->lock, flags);
++ mutex_lock(&priv->lock);
+
+ netif_device_detach(ndev);
+ stmmac_stop_all_queues(priv);
+@@ -4423,7 +4421,7 @@ int stmmac_suspend(struct device *dev)
+ clk_disable_unprepare(priv->plat->pclk);
+ clk_disable_unprepare(priv->plat->stmmac_clk);
+ }
+- spin_unlock_irqrestore(&priv->lock, flags);
++ mutex_unlock(&priv->lock);
+
+ priv->oldlink = false;
+ priv->speed = SPEED_UNKNOWN;
+@@ -4467,7 +4465,6 @@ int stmmac_resume(struct device *dev)
+ {
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
+- unsigned long flags;
+
+ if (!netif_running(ndev))
+ return 0;
+@@ -4479,9 +4476,9 @@ int stmmac_resume(struct device *dev)
+ * from another devices (e.g. serial console).
+ */
+ if (device_may_wakeup(priv->device)) {
+- spin_lock_irqsave(&priv->lock, flags);
++ mutex_lock(&priv->lock);
+ priv->hw->mac->pmt(priv->hw, 0);
+- spin_unlock_irqrestore(&priv->lock, flags);
++ mutex_unlock(&priv->lock);
+ priv->irq_wake = 0;
+ } else {
+ pinctrl_pm_select_default_state(priv->device);
+@@ -4497,7 +4494,7 @@ int stmmac_resume(struct device *dev)
+
+ netif_device_attach(ndev);
+
+- spin_lock_irqsave(&priv->lock, flags);
++ mutex_lock(&priv->lock);
+
+ stmmac_reset_queues_param(priv);
+
+@@ -4516,7 +4513,7 @@ int stmmac_resume(struct device *dev)
+
+ stmmac_start_all_queues(priv);
+
+- spin_unlock_irqrestore(&priv->lock, flags);
++ mutex_unlock(&priv->lock);
+
+ if (ndev->phydev)
+ phy_start(ndev->phydev);