--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Jane Chu <jane.chu@oracle.com>
+Date: Tue, 6 Jun 2017 14:32:29 -0600
+Subject: arch/sparc: support NR_CPUS = 4096
+
+From: Jane Chu <jane.chu@oracle.com>
+
+
+[ Upstream commit c79a13734d104b5b147d7cb0870276ccdd660dae ]
+
+Linux SPARC64 limits NR_CPUS to 4064 because init_cpu_send_mondo_info()
+only allocates a single page for NR_CPUS mondo entries. Thus we cannot
+use all 4096 CPUs on some SPARC platforms.
+
+To fix, allocate (2^order) pages where order is set according to the size
+of cpu_list for possible cpus. Since cpu_list_pa and cpu_mondo_block_pa
+are not used in asm code, there are no imm13 offsets from the base PA
+that will break because they can only reach one page.
+
+Orabug: 25505750
+
+Signed-off-by: Jane Chu <jane.chu@oracle.com>
+
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Atish Patra <atish.patra@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/Kconfig | 4 ++--
+ arch/sparc/kernel/irq_64.c | 17 +++++++++++++----
+ 2 files changed, 15 insertions(+), 6 deletions(-)
+
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -182,9 +182,9 @@ config NR_CPUS
+ int "Maximum number of CPUs"
+ depends on SMP
+ range 2 32 if SPARC32
+- range 2 1024 if SPARC64
++ range 2 4096 if SPARC64
+ default 32 if SPARC32
+- default 64 if SPARC64
++ default 4096 if SPARC64
+
+ source kernel/Kconfig.hz
+
+--- a/arch/sparc/kernel/irq_64.c
++++ b/arch/sparc/kernel/irq_64.c
+@@ -1034,17 +1034,26 @@ static void __init init_cpu_send_mondo_i
+ {
+ #ifdef CONFIG_SMP
+ unsigned long page;
++ void *mondo, *p;
+
+- BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
++ BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > PAGE_SIZE);
++
++ /* Make sure mondo block is 64byte aligned */
++ p = kzalloc(127, GFP_KERNEL);
++ if (!p) {
++ prom_printf("SUN4V: Error, cannot allocate mondo block.\n");
++ prom_halt();
++ }
++ mondo = (void *)(((unsigned long)p + 63) & ~0x3f);
++ tb->cpu_mondo_block_pa = __pa(mondo);
+
+ page = get_zeroed_page(GFP_KERNEL);
+ if (!page) {
+- prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
++ prom_printf("SUN4V: Error, cannot allocate cpu list page.\n");
+ prom_halt();
+ }
+
+- tb->cpu_mondo_block_pa = __pa(page);
+- tb->cpu_list_pa = __pa(page + 64);
++ tb->cpu_list_pa = __pa(page);
+ #endif
+ }
+
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: "Mintz, Yuval" <Yuval.Mintz@cavium.com>
+Date: Thu, 1 Jun 2017 15:57:56 +0300
+Subject: bnx2x: Fix Multi-Cos
+
+From: "Mintz, Yuval" <Yuval.Mintz@cavium.com>
+
+
+[ Upstream commit 3968d38917eb9bd0cd391265f6c9c538d9b33ffa ]
+
+Apparently multi-cos isn't working for bnx2x quite some time -
+driver implements ndo_select_queue() to allow queue-selection
+for FCoE, but the regular L2 flow would cause it to modulo the
+fallback's result by the number of queues.
+The fallback would return a queue matching the needed tc
+[via __skb_tx_hash()], but since the modulo is by the number of TSS
+queues where number of TCs is not accounted, transmission would always
+be done by a queue configured into using TC0.
+
+Fixes: ada7c19e6d27 ("bnx2x: use XPS if possible for bnx2x_select_queue instead of pure hash")
+Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -1949,7 +1949,7 @@ u16 bnx2x_select_queue(struct net_device
+ }
+
+ /* select a non-FCoE queue */
+- return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);
++ return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
+ }
+
+ void bnx2x_set_num_queues(struct bnx2x *bp)
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Ganesh Goudar <ganeshgr@chelsio.com>
+Date: Wed, 31 May 2017 18:26:28 +0530
+Subject: cxgb4: avoid enabling napi twice to the same queue
+
+From: Ganesh Goudar <ganeshgr@chelsio.com>
+
+
+[ Upstream commit e7519f9926f1d0d11c776eb0475eb098c7760f68 ]
+
+Take uld mutex to avoid race between cxgb_up() and
+cxgb4_register_uld() to enable napi for the same uld
+queue.
+
+Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -2714,10 +2714,14 @@ static int cxgb_up(struct adapter *adap)
+ if (err)
+ goto irq_err;
+ }
++
++ mutex_lock(&uld_mutex);
+ enable_rx(adap);
+ t4_sge_start(adap);
+ t4_intr_enable(adap);
+ adap->flags |= FULL_INIT_DONE;
++ mutex_unlock(&uld_mutex);
++
+ notify_ulds(adap, CXGB4_STATE_UP);
+ #if IS_ENABLED(CONFIG_IPV6)
+ update_clip(adap);
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: "David S. Miller" <davem@davemloft.net>
+Date: Sun, 4 Jun 2017 21:41:10 -0400
+Subject: ipv6: Fix leak in ipv6_gso_segment().
+
+From: "David S. Miller" <davem@davemloft.net>
+
+
+[ Upstream commit e3e86b5119f81e5e2499bea7ea1ebe8ac6aab789 ]
+
+If ip6_find_1stfragopt() fails and we return an error we have to free
+up 'segs' because nobody else is going to.
+
+Fixes: 2423496af35d ("ipv6: Prevent overrun when parsing v6 header options")
+Reported-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_offload.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -121,8 +121,10 @@ static struct sk_buff *ipv6_gso_segment(
+
+ if (udpfrag) {
+ int err = ip6_find_1stfragopt(skb, &prevhdr);
+- if (err < 0)
++ if (err < 0) {
++ kfree_skb_list(segs);
+ return ERR_PTR(err);
++ }
+ fptr = (struct frag_hdr *)((u8 *)ipv6h + err);
+ fptr->frag_off = htons(offset);
+ if (skb->next)
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 31 May 2017 13:15:41 +0100
+Subject: ipv6: xfrm: Handle errors reported by xfrm6_find_1stfragopt()
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+
+[ Upstream commit 6e80ac5cc992ab6256c3dae87f7e57db15e1a58c ]
+
+xfrm6_find_1stfragopt() may now return an error code and we must
+not treat it as a length.
+
+Fixes: 2423496af35d ("ipv6: Prevent overrun when parsing v6 header options")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Acked-by: Craig Gallek <kraig@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/xfrm6_mode_ro.c | 2 ++
+ net/ipv6/xfrm6_mode_transport.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/net/ipv6/xfrm6_mode_ro.c
++++ b/net/ipv6/xfrm6_mode_ro.c
+@@ -47,6 +47,8 @@ static int xfrm6_ro_output(struct xfrm_s
+ iph = ipv6_hdr(skb);
+
+ hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
++ if (hdr_len < 0)
++ return hdr_len;
+ skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
+ skb_set_network_header(skb, -x->props.header_len);
+ skb->transport_header = skb->network_header + hdr_len;
+--- a/net/ipv6/xfrm6_mode_transport.c
++++ b/net/ipv6/xfrm6_mode_transport.c
+@@ -28,6 +28,8 @@ static int xfrm6_transport_output(struct
+ iph = ipv6_hdr(skb);
+
+ hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
++ if (hdr_len < 0)
++ return hdr_len;
+ skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
+ skb_set_network_header(skb, -x->props.header_len);
+ skb->transport_header = skb->network_header + hdr_len;
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Thu, 1 Jun 2017 18:07:55 +0300
+Subject: net: bridge: start hello timer only if device is up
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+
+[ Upstream commit aeb073241fe7a2b932e04e20c60e47718332877f ]
+
+When the transition of NO_STP -> KERNEL_STP was fixed by always calling
+mod_timer in br_stp_start, it introduced a new regression which causes
+the timer to be armed even when the bridge is down, and since we stop
+the timers in its ndo_stop() function, they never get disabled if the
+device is destroyed before it's upped.
+
+To reproduce:
+$ while :; do ip l add br0 type bridge hello_time 100; brctl stp br0 on;
+ip l del br0; done;
+
+CC: Xin Long <lucien.xin@gmail.com>
+CC: Ivan Vecera <cera@cera.cz>
+CC: Sebastian Ott <sebott@linux.vnet.ibm.com>
+Reported-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
+Fixes: 6d18c732b95c ("bridge: start hello_timer when enabling KERNEL_STP in br_stp_start")
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_stp_if.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/bridge/br_stp_if.c
++++ b/net/bridge/br_stp_if.c
+@@ -166,7 +166,8 @@ static void br_stp_start(struct net_brid
+ br_debug(br, "using kernel STP\n");
+
+ /* To start timers on any ports left in blocking */
+- mod_timer(&br->hello_timer, jiffies + br->hello_time);
++ if (br->dev->flags & IFF_UP)
++ mod_timer(&br->hello_timer, jiffies + br->hello_time);
+ br_port_state_selection(br);
+ }
+
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Mon, 5 Jun 2017 18:31:16 -0700
+Subject: net: ethoc: enable NAPI before poll may be scheduled
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+
+[ Upstream commit d220b942a4b6a0640aee78841608f4aa5e8e185e ]
+
+ethoc_reset enables device interrupts, ethoc_interrupt may schedule a
+NAPI poll before NAPI is enabled in the ethoc_open, which results in
+device being unable to send or receive anything until it's closed and
+reopened. In case the device is flooded with ingress packets it may be
+unable to recover at all.
+Move napi_enable above ethoc_reset in the ethoc_open to fix that.
+
+Fixes: a1702857724f ("net: Add support for the OpenCores 10/100 Mbps Ethernet MAC.")
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Reviewed-by: Tobias Klauser <tklauser@distanz.ch>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/ethoc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/ethoc.c
++++ b/drivers/net/ethernet/ethoc.c
+@@ -713,6 +713,8 @@ static int ethoc_open(struct net_device
+ if (ret)
+ return ret;
+
++ napi_enable(&priv->napi);
++
+ ethoc_init_ring(priv, dev->mem_start);
+ ethoc_reset(priv);
+
+@@ -725,7 +727,6 @@ static int ethoc_open(struct net_device
+ }
+
+ phy_start(priv->phy);
+- napi_enable(&priv->napi);
+
+ if (netif_msg_ifup(priv)) {
+ dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n",
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Eric Dumazet <edumazet@google.com>
+Date: Sat, 3 Jun 2017 09:29:25 -0700
+Subject: net: ping: do not abuse udp_poll()
+
+From: Eric Dumazet <edumazet@google.com>
+
+
+[ Upstream commit 77d4b1d36926a9b8387c6b53eeba42bcaaffcea3 ]
+
+Alexander reported various KASAN messages triggered in recent kernels
+
+The problem is that ping sockets should not use udp_poll() in the first
+place, and recent changes in UDP stack finally exposed this old bug.
+
+Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind")
+Fixes: 6d0bfe226116 ("net: ipv6: Add IPv6 support to the ping socket.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Sasha Levin <alexander.levin@verizon.com>
+Cc: Solar Designer <solar@openwall.com>
+Cc: Vasiliy Kulikov <segoon@openwall.com>
+Cc: Lorenzo Colitti <lorenzo@google.com>
+Acked-By: Lorenzo Colitti <lorenzo@google.com>
+Tested-By: Lorenzo Colitti <lorenzo@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ipv6.h | 1 +
+ net/ipv4/af_inet.c | 2 +-
+ net/ipv6/ping.c | 2 +-
+ net/ipv6/raw.c | 2 +-
+ 4 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -958,6 +958,7 @@ int inet6_hash_connect(struct inet_timew
+ */
+ extern const struct proto_ops inet6_stream_ops;
+ extern const struct proto_ops inet6_dgram_ops;
++extern const struct proto_ops inet6_sockraw_ops;
+
+ struct group_source_req;
+ struct group_filter;
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1014,7 +1014,7 @@ static struct inet_protosw inetsw_array[
+ .type = SOCK_DGRAM,
+ .protocol = IPPROTO_ICMP,
+ .prot = &ping_prot,
+- .ops = &inet_dgram_ops,
++ .ops = &inet_sockraw_ops,
+ .flags = INET_PROTOSW_REUSE,
+ },
+
+--- a/net/ipv6/ping.c
++++ b/net/ipv6/ping.c
+@@ -50,7 +50,7 @@ static struct inet_protosw pingv6_protos
+ .type = SOCK_DGRAM,
+ .protocol = IPPROTO_ICMPV6,
+ .prot = &pingv6_prot,
+- .ops = &inet6_dgram_ops,
++ .ops = &inet6_sockraw_ops,
+ .flags = INET_PROTOSW_REUSE,
+ };
+
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -1303,7 +1303,7 @@ void raw6_proc_exit(void)
+ #endif /* CONFIG_PROC_FS */
+
+ /* Same as inet6_dgram_ops, sans udp_poll. */
+-static const struct proto_ops inet6_sockraw_ops = {
++const struct proto_ops inet6_sockraw_ops = {
+ .family = PF_INET6,
+ .owner = THIS_MODULE,
+ .release = inet6_release,
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: James Clarke <jrtc27@jrtc27.com>
+Date: Mon, 29 May 2017 20:17:56 +0100
+Subject: sparc: Machine description indices can vary
+
+From: James Clarke <jrtc27@jrtc27.com>
+
+
+[ Upstream commit c982aa9c304bf0b9a7522fd118fed4afa5a0263c ]
+
+VIO devices were being looked up by their index in the machine
+description node block, but this often varies over time as devices are
+added and removed. Instead, store the ID and look up using the type,
+config handle and ID.
+
+Signed-off-by: James Clarke <jrtc27@jrtc27.com>
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112541
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/include/asm/vio.h | 1
+ arch/sparc/kernel/vio.c | 68 ++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 65 insertions(+), 4 deletions(-)
+
+--- a/arch/sparc/include/asm/vio.h
++++ b/arch/sparc/include/asm/vio.h
+@@ -327,6 +327,7 @@ struct vio_dev {
+ int compat_len;
+
+ u64 dev_no;
++ u64 id;
+
+ unsigned long channel_id;
+
+--- a/arch/sparc/kernel/vio.c
++++ b/arch/sparc/kernel/vio.c
+@@ -284,13 +284,16 @@ static struct vio_dev *vio_create_one(st
+ if (!id) {
+ dev_set_name(&vdev->dev, "%s", bus_id_name);
+ vdev->dev_no = ~(u64)0;
++ vdev->id = ~(u64)0;
+ } else if (!cfg_handle) {
+ dev_set_name(&vdev->dev, "%s-%llu", bus_id_name, *id);
+ vdev->dev_no = *id;
++ vdev->id = ~(u64)0;
+ } else {
+ dev_set_name(&vdev->dev, "%s-%llu-%llu", bus_id_name,
+ *cfg_handle, *id);
+ vdev->dev_no = *cfg_handle;
++ vdev->id = *id;
+ }
+
+ vdev->dev.parent = parent;
+@@ -333,27 +336,84 @@ static void vio_add(struct mdesc_handle
+ (void) vio_create_one(hp, node, &root_vdev->dev);
+ }
+
++struct vio_md_node_query {
++ const char *type;
++ u64 dev_no;
++ u64 id;
++};
++
+ static int vio_md_node_match(struct device *dev, void *arg)
+ {
++ struct vio_md_node_query *query = (struct vio_md_node_query *) arg;
+ struct vio_dev *vdev = to_vio_dev(dev);
+
+- if (vdev->mp == (u64) arg)
+- return 1;
++ if (vdev->dev_no != query->dev_no)
++ return 0;
++ if (vdev->id != query->id)
++ return 0;
++ if (strcmp(vdev->type, query->type))
++ return 0;
+
+- return 0;
++ return 1;
+ }
+
+ static void vio_remove(struct mdesc_handle *hp, u64 node)
+ {
++ const char *type;
++ const u64 *id, *cfg_handle;
++ u64 a;
++ struct vio_md_node_query query;
+ struct device *dev;
+
+- dev = device_find_child(&root_vdev->dev, (void *) node,
++ type = mdesc_get_property(hp, node, "device-type", NULL);
++ if (!type) {
++ type = mdesc_get_property(hp, node, "name", NULL);
++ if (!type)
++ type = mdesc_node_name(hp, node);
++ }
++
++ query.type = type;
++
++ id = mdesc_get_property(hp, node, "id", NULL);
++ cfg_handle = NULL;
++ mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
++ u64 target;
++
++ target = mdesc_arc_target(hp, a);
++ cfg_handle = mdesc_get_property(hp, target,
++ "cfg-handle", NULL);
++ if (cfg_handle)
++ break;
++ }
++
++ if (!id) {
++ query.dev_no = ~(u64)0;
++ query.id = ~(u64)0;
++ } else if (!cfg_handle) {
++ query.dev_no = *id;
++ query.id = ~(u64)0;
++ } else {
++ query.dev_no = *cfg_handle;
++ query.id = *id;
++ }
++
++ dev = device_find_child(&root_vdev->dev, &query,
+ vio_md_node_match);
+ if (dev) {
+ printk(KERN_INFO "VIO: Removing device %s\n", dev_name(dev));
+
+ device_unregister(dev);
+ put_device(dev);
++ } else {
++ if (!id)
++ printk(KERN_ERR "VIO: Removed unknown %s node.\n",
++ type);
++ else if (!cfg_handle)
++ printk(KERN_ERR "VIO: Removed unknown %s node %llu.\n",
++ type, *id);
++ else
++ printk(KERN_ERR "VIO: Removed unknown %s node %llu-%llu.\n",
++ type, *cfg_handle, *id);
+ }
+ }
+
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: "David S. Miller" <davem@davemloft.net>
+Date: Mon, 5 Jun 2017 11:28:57 -0700
+Subject: sparc64: Add __multi3 for gcc 7.x and later.
+
+From: "David S. Miller" <davem@davemloft.net>
+
+
+[ Upstream commit 1b4af13ff2cc6897557bb0b8d9e2fad4fa4d67aa ]
+
+Reported-by: Waldemar Brodkorb <wbx@openadk.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/lib/Makefile | 1 +
+ arch/sparc/lib/multi3.S | 35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 36 insertions(+)
+ create mode 100644 arch/sparc/lib/multi3.S
+
+--- a/arch/sparc/lib/Makefile
++++ b/arch/sparc/lib/Makefile
+@@ -15,6 +15,7 @@ lib-$(CONFIG_SPARC32) += copy_user.o loc
+ lib-$(CONFIG_SPARC64) += atomic_64.o
+ lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
+ lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
++lib-$(CONFIG_SPARC64) += multi3.o
+
+ lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
+ lib-$(CONFIG_SPARC64) += csum_copy.o csum_copy_from_user.o csum_copy_to_user.o
+--- /dev/null
++++ b/arch/sparc/lib/multi3.S
+@@ -0,0 +1,35 @@
++#include <linux/linkage.h>
++#include <asm/export.h>
++
++ .text
++ .align 4
++ENTRY(__multi3) /* %o0 = u, %o1 = v */
++ mov %o1, %g1
++ srl %o3, 0, %g4
++ mulx %g4, %g1, %o1
++ srlx %g1, 0x20, %g3
++ mulx %g3, %g4, %g5
++ sllx %g5, 0x20, %o5
++ srl %g1, 0, %g4
++ sub %o1, %o5, %o5
++ srlx %o5, 0x20, %o5
++ addcc %g5, %o5, %g5
++ srlx %o3, 0x20, %o5
++ mulx %g4, %o5, %g4
++ mulx %g3, %o5, %o5
++ sethi %hi(0x80000000), %g3
++ addcc %g5, %g4, %g5
++ srlx %g5, 0x20, %g5
++ add %g3, %g3, %g3
++ movcc %xcc, %g0, %g3
++ addcc %o5, %g5, %o5
++ sllx %g4, 0x20, %g4
++ add %o1, %g4, %o1
++ add %o5, %g3, %g2
++ mulx %g1, %o2, %g1
++ add %g1, %g2, %g1
++ mulx %o0, %o3, %o0
++ retl
++ add %g1, %o0, %o0
++ENDPROC(__multi3)
++EXPORT_SYMBOL(__multi3)
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Wed, 31 May 2017 11:25:23 -0400
+Subject: sparc64: add per-cpu mm of secondary contexts
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+
+[ Upstream commit 7a5b4bbf49fe86ce77488a70c5dccfe2d50d7a2d ]
+
+The new wrap is going to use information from this array to figure out
+mm's that currently have valid secondary contexts setup.
+
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/include/asm/mmu_context_64.h | 5 +++--
+ arch/sparc/mm/init_64.c | 1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/include/asm/mmu_context_64.h
++++ b/arch/sparc/include/asm/mmu_context_64.h
+@@ -17,6 +17,7 @@ extern spinlock_t ctx_alloc_lock;
+ extern unsigned long tlb_context_cache;
+ extern unsigned long mmu_context_bmap[];
+
++DECLARE_PER_CPU(struct mm_struct *, per_cpu_secondary_mm);
+ void get_new_mmu_context(struct mm_struct *mm);
+ #ifdef CONFIG_SMP
+ void smp_new_mmu_context_version(void);
+@@ -74,8 +75,9 @@ void __flush_tlb_mm(unsigned long, unsig
+ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
+ {
+ unsigned long ctx_valid, flags;
+- int cpu;
++ int cpu = smp_processor_id();
+
++ per_cpu(per_cpu_secondary_mm, cpu) = mm;
+ if (unlikely(mm == &init_mm))
+ return;
+
+@@ -121,7 +123,6 @@ static inline void switch_mm(struct mm_s
+ * for the first time, we must flush that context out of the
+ * local TLB.
+ */
+- cpu = smp_processor_id();
+ if (!ctx_valid || !cpumask_test_cpu(cpu, mm_cpumask(mm))) {
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
+ __flush_tlb_mm(CTX_HWBITS(mm->context),
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -660,6 +660,7 @@ unsigned long tlb_context_cache = CTX_FI
+ #define MAX_CTX_NR (1UL << CTX_NR_BITS)
+ #define CTX_BMAP_SLOTS BITS_TO_LONGS(MAX_CTX_NR)
+ DECLARE_BITMAP(mmu_context_bmap, MAX_CTX_NR);
++DEFINE_PER_CPU(struct mm_struct *, per_cpu_secondary_mm) = {0};
+
+ /* Caller does TLB context flushing on local CPU if necessary.
+ * The caller also ensures that CTX_VALID(mm->context) is false.
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Wed, 31 May 2017 11:25:21 -0400
+Subject: sparc64: combine activate_mm and switch_mm
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+
+[ Upstream commit 14d0334c6748ff2aedb3f2f7fdc51ee90a9b54e7 ]
+
+The only difference between these two functions is that in activate_mm we
+unconditionally flush context. However, there is no need to keep this
+difference after fixing a bug where cpumask was not reset on a wrap. So, in
+this patch we combine these.
+
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/include/asm/mmu_context_64.h | 21 +--------------------
+ 1 file changed, 1 insertion(+), 20 deletions(-)
+
+--- a/arch/sparc/include/asm/mmu_context_64.h
++++ b/arch/sparc/include/asm/mmu_context_64.h
+@@ -131,26 +131,7 @@ static inline void switch_mm(struct mm_s
+ }
+
+ #define deactivate_mm(tsk,mm) do { } while (0)
+-
+-/* Activate a new MM instance for the current task. */
+-static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
+-{
+- unsigned long flags;
+- int cpu;
+-
+- spin_lock_irqsave(&mm->context.lock, flags);
+- if (!CTX_VALID(mm->context))
+- get_new_mmu_context(mm);
+- cpu = smp_processor_id();
+- if (!cpumask_test_cpu(cpu, mm_cpumask(mm)))
+- cpumask_set_cpu(cpu, mm_cpumask(mm));
+-
+- load_secondary_context(mm);
+- __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
+- tsb_context_switch(mm);
+- spin_unlock_irqrestore(&mm->context.lock, flags);
+-}
+-
++#define activate_mm(active_mm, mm) switch_mm(active_mm, mm, NULL)
+ #endif /* !(__ASSEMBLY__) */
+
+ #endif /* !(__SPARC64_MMU_CONTEXT_H) */
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Wed, 31 May 2017 11:25:25 -0400
+Subject: sparc64: delete old wrap code
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+
+[ Upstream commit 0197e41ce70511dc3b71f7fefa1a676e2b5cd60b ]
+
+The old method that is using xcall and softint to get new context id is
+deleted, as it is replaced by a method of using per_cpu_secondary_mm
+without xcall to perform the context wrap.
+
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/include/asm/mmu_context_64.h | 6 ------
+ arch/sparc/include/asm/pil.h | 1 -
+ arch/sparc/kernel/kernel.h | 1 -
+ arch/sparc/kernel/smp_64.c | 31 -------------------------------
+ arch/sparc/kernel/ttable_64.S | 2 +-
+ arch/sparc/mm/ultra.S | 5 -----
+ 6 files changed, 1 insertion(+), 45 deletions(-)
+
+--- a/arch/sparc/include/asm/mmu_context_64.h
++++ b/arch/sparc/include/asm/mmu_context_64.h
+@@ -19,12 +19,6 @@ extern unsigned long mmu_context_bmap[];
+
+ DECLARE_PER_CPU(struct mm_struct *, per_cpu_secondary_mm);
+ void get_new_mmu_context(struct mm_struct *mm);
+-#ifdef CONFIG_SMP
+-void smp_new_mmu_context_version(void);
+-#else
+-#define smp_new_mmu_context_version() do { } while (0)
+-#endif
+-
+ int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+ void destroy_context(struct mm_struct *mm);
+
+--- a/arch/sparc/include/asm/pil.h
++++ b/arch/sparc/include/asm/pil.h
+@@ -20,7 +20,6 @@
+ #define PIL_SMP_CALL_FUNC 1
+ #define PIL_SMP_RECEIVE_SIGNAL 2
+ #define PIL_SMP_CAPTURE 3
+-#define PIL_SMP_CTX_NEW_VERSION 4
+ #define PIL_DEVICE_IRQ 5
+ #define PIL_SMP_CALL_FUNC_SNGL 6
+ #define PIL_DEFERRED_PCR_WORK 7
+--- a/arch/sparc/kernel/kernel.h
++++ b/arch/sparc/kernel/kernel.h
+@@ -37,7 +37,6 @@ void handle_stdfmna(struct pt_regs *regs
+ /* smp_64.c */
+ void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs);
+ void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs);
+-void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs);
+ void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs);
+ void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs);
+
+--- a/arch/sparc/kernel/smp_64.c
++++ b/arch/sparc/kernel/smp_64.c
+@@ -959,37 +959,6 @@ void flush_dcache_page_all(struct mm_str
+ preempt_enable();
+ }
+
+-void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
+-{
+- struct mm_struct *mm;
+- unsigned long flags;
+-
+- clear_softint(1 << irq);
+-
+- /* See if we need to allocate a new TLB context because
+- * the version of the one we are using is now out of date.
+- */
+- mm = current->active_mm;
+- if (unlikely(!mm || (mm == &init_mm)))
+- return;
+-
+- spin_lock_irqsave(&mm->context.lock, flags);
+-
+- if (unlikely(!CTX_VALID(mm->context)))
+- get_new_mmu_context(mm);
+-
+- spin_unlock_irqrestore(&mm->context.lock, flags);
+-
+- load_secondary_context(mm);
+- __flush_tlb_mm(CTX_HWBITS(mm->context),
+- SECONDARY_CONTEXT);
+-}
+-
+-void smp_new_mmu_context_version(void)
+-{
+- smp_cross_call(&xcall_new_mmu_context_version, 0, 0, 0);
+-}
+-
+ #ifdef CONFIG_KGDB
+ void kgdb_roundup_cpus(unsigned long flags)
+ {
+--- a/arch/sparc/kernel/ttable_64.S
++++ b/arch/sparc/kernel/ttable_64.S
+@@ -50,7 +50,7 @@ tl0_resv03e: BTRAP(0x3e) BTRAP(0x3f) BTR
+ tl0_irq1: TRAP_IRQ(smp_call_function_client, 1)
+ tl0_irq2: TRAP_IRQ(smp_receive_signal_client, 2)
+ tl0_irq3: TRAP_IRQ(smp_penguin_jailcell, 3)
+-tl0_irq4: TRAP_IRQ(smp_new_mmu_context_version_client, 4)
++tl0_irq4: BTRAP(0x44)
+ #else
+ tl0_irq1: BTRAP(0x41)
+ tl0_irq2: BTRAP(0x42)
+--- a/arch/sparc/mm/ultra.S
++++ b/arch/sparc/mm/ultra.S
+@@ -971,11 +971,6 @@ xcall_capture:
+ wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint
+ retry
+
+- .globl xcall_new_mmu_context_version
+-xcall_new_mmu_context_version:
+- wr %g0, (1 << PIL_SMP_CTX_NEW_VERSION), %set_softint
+- retry
+-
+ #ifdef CONFIG_KGDB
+ .globl xcall_kgdb_capture
+ xcall_kgdb_capture:
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Mike Kravetz <mike.kravetz@oracle.com>
+Date: Fri, 2 Jun 2017 14:51:12 -0700
+Subject: sparc64: mm: fix copy_tsb to correctly copy huge page TSBs
+
+From: Mike Kravetz <mike.kravetz@oracle.com>
+
+
+[ Upstream commit 654f4807624a657f364417c2a7454f0df9961734 ]
+
+When a TSB grows beyond its current capacity, a new TSB is allocated
+and copy_tsb is called to copy entries from the old TSB to the new.
+A hash shift based on page size is used to calculate the index of an
+entry in the TSB. copy_tsb has hard coded PAGE_SHIFT in these
+calculations. However, for huge page TSBs the value REAL_HPAGE_SHIFT
+should be used. As a result, when copy_tsb is called for a huge page
+TSB the entries are placed at the incorrect index in the newly
+allocated TSB. When doing hardware table walk, the MMU does not
+match these entries and we end up in the TSB miss handling code.
+This code will then create and write an entry to the correct index
+in the TSB. We take a performance hit for the table walk miss and
+recreation of these entries.
+
+Pass a new parameter to copy_tsb that is the page size shift to be
+used when copying the TSB.
+
+Suggested-by: Anthony Yznaga <anthony.yznaga@oracle.com>
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/kernel/tsb.S | 11 +++++++----
+ arch/sparc/mm/tsb.c | 7 +++++--
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/arch/sparc/kernel/tsb.S
++++ b/arch/sparc/kernel/tsb.S
+@@ -470,13 +470,16 @@ __tsb_context_switch:
+ .type copy_tsb,#function
+ copy_tsb: /* %o0=old_tsb_base, %o1=old_tsb_size
+ * %o2=new_tsb_base, %o3=new_tsb_size
++ * %o4=page_size_shift
+ */
+ sethi %uhi(TSB_PASS_BITS), %g7
+ srlx %o3, 4, %o3
+- add %o0, %o1, %g1 /* end of old tsb */
++ add %o0, %o1, %o1 /* end of old tsb */
+ sllx %g7, 32, %g7
+ sub %o3, 1, %o3 /* %o3 == new tsb hash mask */
+
++ mov %o4, %g1 /* page_size_shift */
++
+ 661: prefetcha [%o0] ASI_N, #one_read
+ .section .tsb_phys_patch, "ax"
+ .word 661b
+@@ -501,9 +504,9 @@ copy_tsb: /* %o0=old_tsb_base, %o1=old_
+ /* This can definitely be computed faster... */
+ srlx %o0, 4, %o5 /* Build index */
+ and %o5, 511, %o5 /* Mask index */
+- sllx %o5, PAGE_SHIFT, %o5 /* Put into vaddr position */
++ sllx %o5, %g1, %o5 /* Put into vaddr position */
+ or %o4, %o5, %o4 /* Full VADDR. */
+- srlx %o4, PAGE_SHIFT, %o4 /* Shift down to create index */
++ srlx %o4, %g1, %o4 /* Shift down to create index */
+ and %o4, %o3, %o4 /* Mask with new_tsb_nents-1 */
+ sllx %o4, 4, %o4 /* Shift back up into tsb ent offset */
+ TSB_STORE(%o2 + %o4, %g2) /* Store TAG */
+@@ -511,7 +514,7 @@ copy_tsb: /* %o0=old_tsb_base, %o1=old_
+ TSB_STORE(%o2 + %o4, %g3) /* Store TTE */
+
+ 80: add %o0, 16, %o0
+- cmp %o0, %g1
++ cmp %o0, %o1
+ bne,pt %xcc, 90b
+ nop
+
+--- a/arch/sparc/mm/tsb.c
++++ b/arch/sparc/mm/tsb.c
+@@ -451,7 +451,8 @@ retry_tsb_alloc:
+ extern void copy_tsb(unsigned long old_tsb_base,
+ unsigned long old_tsb_size,
+ unsigned long new_tsb_base,
+- unsigned long new_tsb_size);
++ unsigned long new_tsb_size,
++ unsigned long page_size_shift);
+ unsigned long old_tsb_base = (unsigned long) old_tsb;
+ unsigned long new_tsb_base = (unsigned long) new_tsb;
+
+@@ -459,7 +460,9 @@ retry_tsb_alloc:
+ old_tsb_base = __pa(old_tsb_base);
+ new_tsb_base = __pa(new_tsb_base);
+ }
+- copy_tsb(old_tsb_base, old_size, new_tsb_base, new_size);
++ copy_tsb(old_tsb_base, old_size, new_tsb_base, new_size,
++ tsb_index == MM_TSB_BASE ?
++ PAGE_SHIFT : REAL_HPAGE_SHIFT);
+ }
+
+ mm->context.tsb_block[tsb_index].tsb = new_tsb;
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Wed, 31 May 2017 11:25:24 -0400
+Subject: sparc64: new context wrap
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+
+[ Upstream commit a0582f26ec9dfd5360ea2f35dd9a1b026f8adda0 ]
+
+The current wrap implementation has a race issue: it is called outside of
+the ctx_alloc_lock, and also does not wait for all CPUs to complete the
+wrap. This means that a thread can get a new context with a new version
+and another thread might still be running with the same context. The
+problem is especially severe on CPUs with shared TLBs, like sun4v. I used
+the following test to very quickly reproduce the problem:
+- start over 8K processes (must be more than context IDs)
+- write and read values at a memory location in every process.
+
+Very quickly memory corruptions start happening, and what we read back
+does not equal what we wrote.
+
+Several approaches were explored before settling on this one:
+
+Approach 1:
+Move smp_new_mmu_context_version() inside ctx_alloc_lock, and wait for
+every process to complete the wrap. (Note: every CPU must WAIT before
+leaving smp_new_mmu_context_version_client() until every one arrives).
+
+This approach ends up with deadlocks, as some threads own locks which other
+threads are waiting for, and they never receive softint until these threads
+exit smp_new_mmu_context_version_client(). Since we do not allow the exit,
+deadlock happens.
+
+Approach 2:
+Handle wrap right during mondo interrupt. Use etrap/rtrap to enter into
+into C code, and issue new versions to every CPU.
+This approach adds some overhead to runtime: in switch_mm() we must add
+some checks to make sure that versions have not changed due to wrap while
+we were loading the new secondary context. (could be protected by PSTATE_IE
+but that degrades performance as on M7 and older CPUs as it takes 50 cycles
+for each access). Also, we still need a global per-cpu array of MMs to know
+where we need to load new contexts, otherwise we can change context to a
+thread that is going way (if we received mondo between switch_mm() and
+switch_to() time). Finally, there are some issues with window registers in
+rtrap() when context IDs are changed during CPU mondo time.
+
+The approach in this patch is the simplest and has almost no impact on
+runtime. We use the array with mm's where last secondary contexts were
+loaded onto CPUs and bump their versions to the new generation without
+changing context IDs. If a new process comes in to get a context ID, it
+will go through get_new_mmu_context() because of version mismatch. But the
+running processes do not need to be interrupted. And wrap is quicker as we
+do not need to xcall and wait for everyone to receive and complete wrap.
+
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/mm/init_64.c | 81 ++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 54 insertions(+), 27 deletions(-)
+
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -662,6 +662,53 @@ unsigned long tlb_context_cache = CTX_FI
+ DECLARE_BITMAP(mmu_context_bmap, MAX_CTX_NR);
+ DEFINE_PER_CPU(struct mm_struct *, per_cpu_secondary_mm) = {0};
+
++static void mmu_context_wrap(void)
++{
++ unsigned long old_ver = tlb_context_cache & CTX_VERSION_MASK;
++ unsigned long new_ver, new_ctx, old_ctx;
++ struct mm_struct *mm;
++ int cpu;
++
++ bitmap_zero(mmu_context_bmap, 1 << CTX_NR_BITS);
++
++ /* Reserve kernel context */
++ set_bit(0, mmu_context_bmap);
++
++ new_ver = (tlb_context_cache & CTX_VERSION_MASK) + CTX_FIRST_VERSION;
++ if (unlikely(new_ver == 0))
++ new_ver = CTX_FIRST_VERSION;
++ tlb_context_cache = new_ver;
++
++ /*
++ * Make sure that any new mm that are added into per_cpu_secondary_mm,
++ * are going to go through get_new_mmu_context() path.
++ */
++ mb();
++
++ /*
++ * Updated versions to current on those CPUs that had valid secondary
++ * contexts
++ */
++ for_each_online_cpu(cpu) {
++ /*
++ * If a new mm is stored after we took this mm from the array,
++ * it will go into get_new_mmu_context() path, because we
++ * already bumped the version in tlb_context_cache.
++ */
++ mm = per_cpu(per_cpu_secondary_mm, cpu);
++
++ if (unlikely(!mm || mm == &init_mm))
++ continue;
++
++ old_ctx = mm->context.sparc64_ctx_val;
++ if (likely((old_ctx & CTX_VERSION_MASK) == old_ver)) {
++ new_ctx = (old_ctx & ~CTX_VERSION_MASK) | new_ver;
++ set_bit(new_ctx & CTX_NR_MASK, mmu_context_bmap);
++ mm->context.sparc64_ctx_val = new_ctx;
++ }
++ }
++}
++
+ /* Caller does TLB context flushing on local CPU if necessary.
+ * The caller also ensures that CTX_VALID(mm->context) is false.
+ *
+@@ -676,50 +723,30 @@ void get_new_mmu_context(struct mm_struc
+ {
+ unsigned long ctx, new_ctx;
+ unsigned long orig_pgsz_bits;
+- int new_version;
+
+ spin_lock(&ctx_alloc_lock);
++retry:
++ /* wrap might have happened, test again if our context became valid */
++ if (unlikely(CTX_VALID(mm->context)))
++ goto out;
+ orig_pgsz_bits = (mm->context.sparc64_ctx_val & CTX_PGSZ_MASK);
+ ctx = (tlb_context_cache + 1) & CTX_NR_MASK;
+ new_ctx = find_next_zero_bit(mmu_context_bmap, 1 << CTX_NR_BITS, ctx);
+- new_version = 0;
+ if (new_ctx >= (1 << CTX_NR_BITS)) {
+ new_ctx = find_next_zero_bit(mmu_context_bmap, ctx, 1);
+ if (new_ctx >= ctx) {
+- int i;
+- new_ctx = (tlb_context_cache & CTX_VERSION_MASK) +
+- CTX_FIRST_VERSION + 1;
+- if (new_ctx == 1)
+- new_ctx = CTX_FIRST_VERSION + 1;
+-
+- /* Don't call memset, for 16 entries that's just
+- * plain silly...
+- */
+- mmu_context_bmap[0] = 3;
+- mmu_context_bmap[1] = 0;
+- mmu_context_bmap[2] = 0;
+- mmu_context_bmap[3] = 0;
+- for (i = 4; i < CTX_BMAP_SLOTS; i += 4) {
+- mmu_context_bmap[i + 0] = 0;
+- mmu_context_bmap[i + 1] = 0;
+- mmu_context_bmap[i + 2] = 0;
+- mmu_context_bmap[i + 3] = 0;
+- }
+- new_version = 1;
+- goto out;
++ mmu_context_wrap();
++ goto retry;
+ }
+ }
+ if (mm->context.sparc64_ctx_val)
+ cpumask_clear(mm_cpumask(mm));
+ mmu_context_bmap[new_ctx>>6] |= (1UL << (new_ctx & 63));
+ new_ctx |= (tlb_context_cache & CTX_VERSION_MASK);
+-out:
+ tlb_context_cache = new_ctx;
+ mm->context.sparc64_ctx_val = new_ctx | orig_pgsz_bits;
++out:
+ spin_unlock(&ctx_alloc_lock);
+-
+- if (unlikely(new_version))
+- smp_new_mmu_context_version();
+ }
+
+ static int numa_enabled = 1;
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Wed, 31 May 2017 11:25:22 -0400
+Subject: sparc64: redefine first version
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+
+[ Upstream commit c4415235b2be0cc791572e8e7f7466ab8f73a2bf ]
+
+CTX_FIRST_VERSION defines the first context version, but also it defines
+first context. This patch redefines it to only include the first context
+version.
+
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/include/asm/mmu_64.h | 2 +-
+ arch/sparc/mm/init_64.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/sparc/include/asm/mmu_64.h
++++ b/arch/sparc/include/asm/mmu_64.h
+@@ -52,7 +52,7 @@
+ #define CTX_NR_MASK TAG_CONTEXT_BITS
+ #define CTX_HW_MASK (CTX_NR_MASK | CTX_PGSZ_MASK)
+
+-#define CTX_FIRST_VERSION ((_AC(1,UL) << CTX_VERSION_SHIFT) + _AC(1,UL))
++#define CTX_FIRST_VERSION BIT(CTX_VERSION_SHIFT)
+ #define CTX_VALID(__ctx) \
+ (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK))
+ #define CTX_HWBITS(__ctx) ((__ctx.sparc64_ctx_val) & CTX_HW_MASK)
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -656,7 +656,7 @@ EXPORT_SYMBOL(__flush_dcache_range);
+
+ /* get_new_mmu_context() uses "cache + 1". */
+ DEFINE_SPINLOCK(ctx_alloc_lock);
+-unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1;
++unsigned long tlb_context_cache = CTX_FIRST_VERSION;
+ #define MAX_CTX_NR (1UL << CTX_NR_BITS)
+ #define CTX_BMAP_SLOTS BITS_TO_LONGS(MAX_CTX_NR)
+ DECLARE_BITMAP(mmu_context_bmap, MAX_CTX_NR);
+@@ -687,9 +687,9 @@ void get_new_mmu_context(struct mm_struc
+ if (new_ctx >= ctx) {
+ int i;
+ new_ctx = (tlb_context_cache & CTX_VERSION_MASK) +
+- CTX_FIRST_VERSION;
++ CTX_FIRST_VERSION + 1;
+ if (new_ctx == 1)
+- new_ctx = CTX_FIRST_VERSION;
++ new_ctx = CTX_FIRST_VERSION + 1;
+
+ /* Don't call memset, for 16 entries that's just
+ * plain silly...
--- /dev/null
+From foo@baz Thu Jun 8 09:20:28 CEST 2017
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Wed, 31 May 2017 11:25:20 -0400
+Subject: sparc64: reset mm cpumask after wrap
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+
+[ Upstream commit 588974857359861891f478a070b1dc7ae04a3880 ]
+
+After a wrap (getting a new context version) a process must get a new
+context id, which means that we would need to flush the context id from
+the TLB before running for the first time with this ID on every CPU. But,
+we use mm_cpumask to determine if this process has been running on this CPU
+before, and this mask is not reset after a wrap. So, there are two possible
+fixes for this issue:
+
+1. Clear mm cpumask whenever mm gets a new context id
+2. Unconditionally flush context every time process is running on a CPU
+
+This patch implements the first solution
+
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/sparc/mm/init_64.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -708,6 +708,8 @@ void get_new_mmu_context(struct mm_struc
+ goto out;
+ }
+ }
++ if (mm->context.sparc64_ctx_val)
++ cpumask_clear(mm_cpumask(mm));
+ mmu_context_bmap[new_ctx>>6] |= (1UL << (new_ctx & 63));
+ new_ctx |= (tlb_context_cache & CTX_VERSION_MASK);
+ out:
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Yuchung Cheng <ycheng@google.com>
+Date: Wed, 31 May 2017 11:21:27 -0700
+Subject: tcp: disallow cwnd undo when switching congestion control
+
+From: Yuchung Cheng <ycheng@google.com>
+
+
+[ Upstream commit 44abafc4cc094214a99f860f778c48ecb23422fc ]
+
+When the sender switches its congestion control during loss
+recovery, if the recovery is spurious then it may incorrectly
+revert cwnd and ssthresh to the older values set by a previous
+congestion control. Consider a congestion control (like BBR)
+that does not use ssthresh and keeps it infinite: the connection
+may incorrectly revert cwnd to an infinite value when switching
+from BBR to another congestion control.
+
+This patch fixes it by disallowing such cwnd undo operation
+upon switching congestion control. Note that undo_marker
+is not reset s.t. the packets that were incorrectly marked
+lost would be corrected. We only avoid undoing the cwnd in
+tcp_undo_cwnd_reduction().
+
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_cong.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/tcp_cong.c
++++ b/net/ipv4/tcp_cong.c
+@@ -183,6 +183,7 @@ void tcp_init_congestion_control(struct
+ {
+ const struct inet_connection_sock *icsk = inet_csk(sk);
+
++ tcp_sk(sk)->prior_ssthresh = 0;
+ if (icsk->icsk_ca_ops->init)
+ icsk->icsk_ca_ops->init(sk);
+ if (tcp_ca_needs_ecn(sk))
--- /dev/null
+From foo@baz Thu Jun 8 09:11:25 CEST 2017
+From: Mark Bloch <markb@mellanox.com>
+Date: Fri, 2 Jun 2017 03:24:08 +0300
+Subject: vxlan: fix use-after-free on deletion
+
+From: Mark Bloch <markb@mellanox.com>
+
+
+[ Upstream commit a53cb29b0af346af44e4abf13d7e59f807fba690 ]
+
+Adding a vxlan interface to a socket isn't symmetrical, while adding
+is done in vxlan_open() the deletion is done in vxlan_dellink().
+This can cause a use-after-free error when we close the vxlan
+interface before deleting it.
+
+We add vxlan_vs_del_dev() to match vxlan_vs_add_dev() and call
+it from vxlan_stop() to match the call from vxlan_open().
+
+Fixes: 56ef9c909b40 ("vxlan: Move socket initialization to within rtnl scope")
+Acked-by: Jiri Benc <jbenc@redhat.com>
+Tested-by: Roi Dayan <roid@mellanox.com>
+Signed-off-by: Mark Bloch <markb@mellanox.com>
+Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -77,6 +77,8 @@ static const u8 all_zeros_mac[ETH_ALEN];
+
+ static int vxlan_sock_add(struct vxlan_dev *vxlan);
+
++static void vxlan_vs_del_dev(struct vxlan_dev *vxlan);
++
+ /* per-network namespace private data for this module */
+ struct vxlan_net {
+ struct list_head vxlan_list;
+@@ -1052,6 +1054,8 @@ static void __vxlan_sock_release(struct
+
+ static void vxlan_sock_release(struct vxlan_dev *vxlan)
+ {
++ vxlan_vs_del_dev(vxlan);
++
+ __vxlan_sock_release(vxlan->vn4_sock);
+ #if IS_ENABLED(CONFIG_IPV6)
+ __vxlan_sock_release(vxlan->vn6_sock);
+@@ -2255,6 +2259,15 @@ static void vxlan_cleanup(unsigned long
+ mod_timer(&vxlan->age_timer, next_timer);
+ }
+
++static void vxlan_vs_del_dev(struct vxlan_dev *vxlan)
++{
++ struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
++
++ spin_lock(&vn->sock_lock);
++ hlist_del_init_rcu(&vxlan->hlist);
++ spin_unlock(&vn->sock_lock);
++}
++
+ static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
+ {
+ struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+@@ -3028,12 +3041,6 @@ static int vxlan_newlink(struct net *src
+ static void vxlan_dellink(struct net_device *dev, struct list_head *head)
+ {
+ struct vxlan_dev *vxlan = netdev_priv(dev);
+- struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+-
+- spin_lock(&vn->sock_lock);
+- if (!hlist_unhashed(&vxlan->hlist))
+- hlist_del_rcu(&vxlan->hlist);
+- spin_unlock(&vn->sock_lock);
+
+ gro_cells_destroy(&vxlan->gro_cells);
+ list_del(&vxlan->next);