]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Feb 2018 13:02:54 +0000 (14:02 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Feb 2018 13:02:54 +0000 (14:02 +0100)
added patches:
arm64-mm-don-t-write-garbage-into-ttbr1_el1-register.patch
ip_tunnel-fix-preempt-warning-in-ip-tunnel-creation-updating.patch
ip_tunnel-replace-dst_cache-with-generic-implementation.patch
pci-keystone-fix-interrupt-controller-node-lookup.patch

queue-4.4/arm64-mm-don-t-write-garbage-into-ttbr1_el1-register.patch [new file with mode: 0644]
queue-4.4/ip_tunnel-fix-preempt-warning-in-ip-tunnel-creation-updating.patch [new file with mode: 0644]
queue-4.4/ip_tunnel-replace-dst_cache-with-generic-implementation.patch [new file with mode: 0644]
queue-4.4/pci-keystone-fix-interrupt-controller-node-lookup.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/arm64-mm-don-t-write-garbage-into-ttbr1_el1-register.patch b/queue-4.4/arm64-mm-don-t-write-garbage-into-ttbr1_el1-register.patch
new file mode 100644 (file)
index 0000000..920108a
--- /dev/null
@@ -0,0 +1,41 @@
+From ard.biesheuvel@linaro.org  Mon Feb 26 13:53:22 2018
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri, 23 Feb 2018 18:29:02 +0000
+Subject: arm64: mm: don't write garbage into TTBR1_EL1 register
+To: linux-arm-kernel@lists.infradead.org
+Cc: catalin.marinas@arm.com, will.deacon@arm.com, marc.zyngier@arm.com, mark.rutland@arm.com, nicolas.dechesne@linaro.org, gregkh@linuxfoundation.org, Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Message-ID: <20180223182902.24873-1-ard.biesheuvel@linaro.org>
+
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+Stable backport commit 173358a49173 ("arm64: kpti: Add ->enable callback
+to remap swapper using nG mappings") of upstream commit f992b4dfd58b did
+not survive the backporting process unscathed, and ends up writing garbage
+into the TTBR1_EL1 register, rather than pointing it to the zero page to
+disable translations. Fix that.
+
+Cc: <stable@vger.kernel.org> #v4.14
+Reported-by: Nicolas Dechesne <nicolas.dechesne@linaro.org>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/mm/proc.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
+index 08572f95bd8a..2b473ddeb7a3 100644
+--- a/arch/arm64/mm/proc.S
++++ b/arch/arm64/mm/proc.S
+@@ -155,7 +155,7 @@ ENDPROC(cpu_do_switch_mm)
+ .macro        __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2
+       adrp    \tmp1, empty_zero_page
+-      msr     ttbr1_el1, \tmp2
++      msr     ttbr1_el1, \tmp1
+       isb
+       tlbi    vmalle1
+       dsb     nsh
+-- 
+2.11.0
+
diff --git a/queue-4.4/ip_tunnel-fix-preempt-warning-in-ip-tunnel-creation-updating.patch b/queue-4.4/ip_tunnel-fix-preempt-warning-in-ip-tunnel-creation-updating.patch
new file mode 100644 (file)
index 0000000..833fe45
--- /dev/null
@@ -0,0 +1,47 @@
+From f27337e16f2d0e52a8d05ea599ed13cd266ac291 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 28 Apr 2016 11:04:51 +0200
+Subject: ip_tunnel: fix preempt warning in ip tunnel creation/updating
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit f27337e16f2d0e52a8d05ea599ed13cd266ac291 upstream.
+
+After the commit e09acddf873b ("ip_tunnel: replace dst_cache with generic
+implementation"), a preemption debug warning is triggered on ip4
+tunnels updating; the dst cache helper needs to be invoked in unpreemptible
+context.
+
+We don't need to load the cache on tunnel update, so this commit fixes
+the warning replacing the load with a dst cache reset, which is
+preempt safe.
+
+Fixes: e09acddf873b ("ip_tunnel: replace dst_cache with generic implementation")
+Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Nathan Chancellor <natechancellor@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/ip_tunnel.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -327,12 +327,12 @@ static int ip_tunnel_bind_dev(struct net
+               if (!IS_ERR(rt)) {
+                       tdev = rt->dst.dev;
+-                      dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
+-                                        fl4.saddr);
+                       ip_rt_put(rt);
+               }
+               if (dev->type != ARPHRD_ETHER)
+                       dev->flags |= IFF_POINTOPOINT;
++
++              dst_cache_reset(&tunnel->dst_cache);
+       }
+       if (!tdev && tunnel->parms.link)
diff --git a/queue-4.4/ip_tunnel-replace-dst_cache-with-generic-implementation.patch b/queue-4.4/ip_tunnel-replace-dst_cache-with-generic-implementation.patch
new file mode 100644 (file)
index 0000000..eec0cd5
--- /dev/null
@@ -0,0 +1,288 @@
+From e09acddf873bf775b208b452a4c3a3fd26fa9427 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Fri, 12 Feb 2016 15:43:55 +0100
+Subject: ip_tunnel: replace dst_cache with generic implementation
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit e09acddf873bf775b208b452a4c3a3fd26fa9427 upstream.
+
+The current ip_tunnel cache implementation is prone to a race
+that will cause the wrong dst to be cached on cuncurrent dst cache
+miss and ip tunnel update via netlink.
+
+Replacing with the generic implementation fix the issue.
+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Suggested-and-acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Nathan Chancellor <natechancellor@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/ip_tunnels.h |    9 +----
+ net/ipv4/Kconfig         |    1 
+ net/ipv4/ip_tunnel.c     |   78 +++++++----------------------------------------
+ net/ipv6/sit.c           |   17 +++++-----
+ 4 files changed, 25 insertions(+), 80 deletions(-)
+
+--- a/include/net/ip_tunnels.h
++++ b/include/net/ip_tunnels.h
+@@ -13,6 +13,7 @@
+ #include <net/netns/generic.h>
+ #include <net/rtnetlink.h>
+ #include <net/lwtunnel.h>
++#include <net/dst_cache.h>
+ #if IS_ENABLED(CONFIG_IPV6)
+ #include <net/ipv6.h>
+@@ -85,11 +86,6 @@ struct ip_tunnel_prl_entry {
+       struct rcu_head                 rcu_head;
+ };
+-struct ip_tunnel_dst {
+-      struct dst_entry __rcu          *dst;
+-      __be32                           saddr;
+-};
+-
+ struct metadata_dst;
+ struct ip_tunnel {
+@@ -108,7 +104,7 @@ struct ip_tunnel {
+       int             tun_hlen;       /* Precalculated header length */
+       int             mlink;
+-      struct ip_tunnel_dst __percpu *dst_cache;
++      struct dst_cache dst_cache;
+       struct ip_tunnel_parm parms;
+@@ -248,7 +244,6 @@ int ip_tunnel_changelink(struct net_devi
+ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
+                     struct ip_tunnel_parm *p);
+ void ip_tunnel_setup(struct net_device *dev, int net_id);
+-void ip_tunnel_dst_reset_all(struct ip_tunnel *t);
+ int ip_tunnel_encap_setup(struct ip_tunnel *t,
+                         struct ip_tunnel_encap *ipencap);
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -186,6 +186,7 @@ config NET_IPGRE_DEMUX
+ config NET_IP_TUNNEL
+       tristate
++      select DST_CACHE
+       default n
+ config NET_IPGRE
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -69,61 +69,6 @@ static unsigned int ip_tunnel_hash(__be3
+                        IP_TNL_HASH_BITS);
+ }
+-static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
+-                           struct dst_entry *dst, __be32 saddr)
+-{
+-      struct dst_entry *old_dst;
+-
+-      dst_clone(dst);
+-      old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
+-      dst_release(old_dst);
+-      idst->saddr = saddr;
+-}
+-
+-static noinline void tunnel_dst_set(struct ip_tunnel *t,
+-                         struct dst_entry *dst, __be32 saddr)
+-{
+-      __tunnel_dst_set(raw_cpu_ptr(t->dst_cache), dst, saddr);
+-}
+-
+-static void tunnel_dst_reset(struct ip_tunnel *t)
+-{
+-      tunnel_dst_set(t, NULL, 0);
+-}
+-
+-void ip_tunnel_dst_reset_all(struct ip_tunnel *t)
+-{
+-      int i;
+-
+-      for_each_possible_cpu(i)
+-              __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0);
+-}
+-EXPORT_SYMBOL(ip_tunnel_dst_reset_all);
+-
+-static struct rtable *tunnel_rtable_get(struct ip_tunnel *t,
+-                                      u32 cookie, __be32 *saddr)
+-{
+-      struct ip_tunnel_dst *idst;
+-      struct dst_entry *dst;
+-
+-      rcu_read_lock();
+-      idst = raw_cpu_ptr(t->dst_cache);
+-      dst = rcu_dereference(idst->dst);
+-      if (dst && !atomic_inc_not_zero(&dst->__refcnt))
+-              dst = NULL;
+-      if (dst) {
+-              if (!dst->obsolete || dst->ops->check(dst, cookie)) {
+-                      *saddr = idst->saddr;
+-              } else {
+-                      tunnel_dst_reset(t);
+-                      dst_release(dst);
+-                      dst = NULL;
+-              }
+-      }
+-      rcu_read_unlock();
+-      return (struct rtable *)dst;
+-}
+-
+ static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
+                               __be16 flags, __be32 key)
+ {
+@@ -382,7 +327,8 @@ static int ip_tunnel_bind_dev(struct net
+               if (!IS_ERR(rt)) {
+                       tdev = rt->dst.dev;
+-                      tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
++                      dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
++                                        fl4.saddr);
+                       ip_rt_put(rt);
+               }
+               if (dev->type != ARPHRD_ETHER)
+@@ -733,7 +679,8 @@ void ip_tunnel_xmit(struct sk_buff *skb,
+       if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
+               goto tx_error;
+-      rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
++      rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr) :
++                       NULL;
+       if (!rt) {
+               rt = ip_route_output_key(tunnel->net, &fl4);
+@@ -743,7 +690,8 @@ void ip_tunnel_xmit(struct sk_buff *skb,
+                       goto tx_error;
+               }
+               if (connected)
+-                      tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
++                      dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
++                                        fl4.saddr);
+       }
+       if (rt->dst.dev == dev) {
+@@ -841,7 +789,7 @@ static void ip_tunnel_update(struct ip_t
+               if (set_mtu)
+                       dev->mtu = mtu;
+       }
+-      ip_tunnel_dst_reset_all(t);
++      dst_cache_reset(&t->dst_cache);
+       netdev_state_change(dev);
+ }
+@@ -980,7 +928,7 @@ static void ip_tunnel_dev_free(struct ne
+       struct ip_tunnel *tunnel = netdev_priv(dev);
+       gro_cells_destroy(&tunnel->gro_cells);
+-      free_percpu(tunnel->dst_cache);
++      dst_cache_destroy(&tunnel->dst_cache);
+       free_percpu(dev->tstats);
+       free_netdev(dev);
+ }
+@@ -1174,15 +1122,15 @@ int ip_tunnel_init(struct net_device *de
+       if (!dev->tstats)
+               return -ENOMEM;
+-      tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
+-      if (!tunnel->dst_cache) {
++      err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
++      if (err) {
+               free_percpu(dev->tstats);
+-              return -ENOMEM;
++              return err;
+       }
+       err = gro_cells_init(&tunnel->gro_cells, dev);
+       if (err) {
+-              free_percpu(tunnel->dst_cache);
++              dst_cache_destroy(&tunnel->dst_cache);
+               free_percpu(dev->tstats);
+               return err;
+       }
+@@ -1212,7 +1160,7 @@ void ip_tunnel_uninit(struct net_device
+       if (itn->fb_tunnel_dev != dev)
+               ip_tunnel_del(itn, netdev_priv(dev));
+-      ip_tunnel_dst_reset_all(tunnel);
++      dst_cache_reset(&tunnel->dst_cache);
+ }
+ EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -475,7 +475,7 @@ static void ipip6_tunnel_uninit(struct n
+               ipip6_tunnel_unlink(sitn, tunnel);
+               ipip6_tunnel_del_prl(tunnel, NULL);
+       }
+-      ip_tunnel_dst_reset_all(tunnel);
++      dst_cache_reset(&tunnel->dst_cache);
+       dev_put(dev);
+ }
+@@ -1098,7 +1098,7 @@ static void ipip6_tunnel_update(struct i
+               t->parms.link = p->link;
+               ipip6_tunnel_bind_dev(t->dev);
+       }
+-      ip_tunnel_dst_reset_all(t);
++      dst_cache_reset(&t->dst_cache);
+       netdev_state_change(t->dev);
+ }
+@@ -1129,7 +1129,7 @@ static int ipip6_tunnel_update_6rd(struc
+       t->ip6rd.relay_prefix = relay_prefix;
+       t->ip6rd.prefixlen = ip6rd->prefixlen;
+       t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen;
+-      ip_tunnel_dst_reset_all(t);
++      dst_cache_reset(&t->dst_cache);
+       netdev_state_change(t->dev);
+       return 0;
+ }
+@@ -1283,7 +1283,7 @@ ipip6_tunnel_ioctl(struct net_device *de
+                       err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
+                       break;
+               }
+-              ip_tunnel_dst_reset_all(t);
++              dst_cache_reset(&t->dst_cache);
+               netdev_state_change(dev);
+               break;
+@@ -1344,7 +1344,7 @@ static void ipip6_dev_free(struct net_de
+ {
+       struct ip_tunnel *tunnel = netdev_priv(dev);
+-      free_percpu(tunnel->dst_cache);
++      dst_cache_destroy(&tunnel->dst_cache);
+       free_percpu(dev->tstats);
+       free_netdev(dev);
+ }
+@@ -1377,6 +1377,7 @@ static void ipip6_tunnel_setup(struct ne
+ static int ipip6_tunnel_init(struct net_device *dev)
+ {
+       struct ip_tunnel *tunnel = netdev_priv(dev);
++      int err;
+       tunnel->dev = dev;
+       tunnel->net = dev_net(dev);
+@@ -1387,11 +1388,11 @@ static int ipip6_tunnel_init(struct net_
+       if (!dev->tstats)
+               return -ENOMEM;
+-      tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
+-      if (!tunnel->dst_cache) {
++      err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
++      if (err) {
+               free_percpu(dev->tstats);
+               dev->tstats = NULL;
+-              return -ENOMEM;
++              return err;
+       }
+       return 0;
diff --git a/queue-4.4/pci-keystone-fix-interrupt-controller-node-lookup.patch b/queue-4.4/pci-keystone-fix-interrupt-controller-node-lookup.patch
new file mode 100644 (file)
index 0000000..1b2a8e0
--- /dev/null
@@ -0,0 +1,62 @@
+From eac56aa3bc8af3d9b9850345d0f2da9d83529134 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Nov 2017 14:38:31 +0100
+Subject: PCI: keystone: Fix interrupt-controller-node lookup
+
+From: Johan Hovold <johan@kernel.org>
+
+commit eac56aa3bc8af3d9b9850345d0f2da9d83529134 upstream.
+
+Fix child-node lookup during initialisation which was using the wrong
+OF-helper and ended up searching the whole device tree depth-first
+starting at the parent rather than just matching on its children.
+
+To make things worse, the parent pci node could end up being prematurely
+freed as of_find_node_by_name() drops a reference to its first argument.
+Any matching child interrupt-controller node was also leaked.
+
+Fixes: 0c4ffcfe1fbc ("PCI: keystone: Add TI Keystone PCIe driver")
+Cc: stable <stable@vger.kernel.org>     # 3.18
+Acked-by: Murali Karicheri <m-karicheri2@ti.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+[lorenzo.pieralisi@arm.com: updated commit subject]
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+[johan: backport to 4.4]
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/host/pci-keystone.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/host/pci-keystone.c
++++ b/drivers/pci/host/pci-keystone.c
+@@ -179,14 +179,16 @@ static int ks_pcie_get_irq_controller_in
+       }
+       /* interrupt controller is in a child node */
+-      *np_temp = of_find_node_by_name(np_pcie, controller);
++      *np_temp = of_get_child_by_name(np_pcie, controller);
+       if (!(*np_temp)) {
+               dev_err(dev, "Node for %s is absent\n", controller);
+               goto out;
+       }
+       temp = of_irq_count(*np_temp);
+-      if (!temp)
++      if (!temp) {
++              of_node_put(*np_temp);
+               goto out;
++      }
+       if (temp > max_host_irqs)
+               dev_warn(dev, "Too many %s interrupts defined %u\n",
+                       (legacy ? "legacy" : "MSI"), temp);
+@@ -200,6 +202,9 @@ static int ks_pcie_get_irq_controller_in
+               if (!host_irqs[temp])
+                       break;
+       }
++
++      of_node_put(*np_temp);
++
+       if (temp) {
+               *num_irqs = temp;
+               ret = 0;
index 219d4ddf7d66075c249ee291b8904f31db01e68f..3269ef277443f3e226e87bc957ce3d556364607c 100644 (file)
@@ -1,2 +1,6 @@
 netfilter-drop-outermost-socket-lock-in-getsockopt.patch
 powerpc-64s-fix-rfi-flush-dependency-on-hardlockup_detector.patch
+pci-keystone-fix-interrupt-controller-node-lookup.patch
+ip_tunnel-replace-dst_cache-with-generic-implementation.patch
+ip_tunnel-fix-preempt-warning-in-ip-tunnel-creation-updating.patch
+arm64-mm-don-t-write-garbage-into-ttbr1_el1-register.patch