--- /dev/null
+From 354136bcc3c4f40a2813bba8f57ca5267d812d15 Mon Sep 17 00:00:00 2001
+From: Marek Lindner <mareklindner@neomailbox.ch>
+Date: Tue, 9 Jun 2015 21:24:36 +0800
+Subject: batman-adv: fix kernel crash due to missing NULL checks
+
+From: Marek Lindner <mareklindner@neomailbox.ch>
+
+commit 354136bcc3c4f40a2813bba8f57ca5267d812d15 upstream.
+
+batadv_softif_vlan_get() may return NULL which has to be verified
+by the caller.
+
+Fixes: 35df3b298fc8 ("batman-adv: fix TT VLAN inconsistency on VLAN re-add")
+Reported-by: Ryan Thompson <ryan@eero.com>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/batman-adv/soft-interface.c | 3 +++
+ net/batman-adv/translation-table.c | 18 ++++++++++++++----
+ 2 files changed, 17 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -449,6 +449,9 @@ out:
+ */
+ void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *vlan)
+ {
++ if (!vlan)
++ return;
++
+ if (atomic_dec_and_test(&vlan->refcount)) {
+ spin_lock_bh(&vlan->bat_priv->softif_vlan_list_lock);
+ hlist_del_rcu(&vlan->list);
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -575,6 +575,9 @@ bool batadv_tt_local_add(struct net_devi
+
+ /* increase the refcounter of the related vlan */
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
++ if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
++ addr, BATADV_PRINT_VID(vid)))
++ goto out;
+
+ batadv_dbg(BATADV_DBG_TT, bat_priv,
+ "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
+@@ -1047,6 +1050,9 @@ uint16_t batadv_tt_local_remove(struct b
+
+ /* decrease the reference held for this vlan */
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
++ if (!vlan)
++ goto out;
++
+ batadv_softif_vlan_free_ref(vlan);
+ batadv_softif_vlan_free_ref(vlan);
+
+@@ -1147,8 +1153,10 @@ static void batadv_tt_local_table_free(s
+ /* decrease the reference held for this vlan */
+ vlan = batadv_softif_vlan_get(bat_priv,
+ tt_common_entry->vid);
+- batadv_softif_vlan_free_ref(vlan);
+- batadv_softif_vlan_free_ref(vlan);
++ if (vlan) {
++ batadv_softif_vlan_free_ref(vlan);
++ batadv_softif_vlan_free_ref(vlan);
++ }
+
+ batadv_tt_local_entry_free_ref(tt_local);
+ }
+@@ -3188,8 +3196,10 @@ static void batadv_tt_local_purge_pendin
+
+ /* decrease the reference held for this vlan */
+ vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid);
+- batadv_softif_vlan_free_ref(vlan);
+- batadv_softif_vlan_free_ref(vlan);
++ if (vlan) {
++ batadv_softif_vlan_free_ref(vlan);
++ batadv_softif_vlan_free_ref(vlan);
++ }
+
+ batadv_tt_local_entry_free_ref(tt_local);
+ }
--- /dev/null
+From 65d7d46050704bcdb8121ddbf4110bfbf2b38baa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+Date: Tue, 16 Jun 2015 17:10:22 +0200
+Subject: batman-adv: Make DAT capability changes atomic
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+
+commit 65d7d46050704bcdb8121ddbf4110bfbf2b38baa upstream.
+
+Bitwise OR/AND assignments in C aren't guaranteed to be atomic. One
+OGM handler might undo the set/clear of a specific bit from another
+handler run in between.
+
+Fix this by using the atomic set_bit()/clear_bit()/test_bit() functions.
+
+Fixes: 17cf0ea455f1 ("batman-adv: tvlv - add distributed arp table container")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/batman-adv/distributed-arp-table.c | 7 ++++---
+ net/batman-adv/types.h | 4 ++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- a/net/batman-adv/distributed-arp-table.c
++++ b/net/batman-adv/distributed-arp-table.c
+@@ -15,6 +15,7 @@
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
++#include <linux/bitops.h>
+ #include <linux/if_ether.h>
+ #include <linux/if_arp.h>
+ #include <linux/if_vlan.h>
+@@ -422,7 +423,7 @@ static bool batadv_is_orig_node_eligible
+ int j;
+
+ /* check if orig node candidate is running DAT */
+- if (!(candidate->capabilities & BATADV_ORIG_CAPA_HAS_DAT))
++ if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities))
+ goto out;
+
+ /* Check if this node has already been selected... */
+@@ -682,9 +683,9 @@ static void batadv_dat_tvlv_ogm_handler_
+ uint16_t tvlv_value_len)
+ {
+ if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
+- orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_DAT;
++ clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities);
+ else
+- orig->capabilities |= BATADV_ORIG_CAPA_HAS_DAT;
++ set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities);
+ }
+
+ /**
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -256,7 +256,7 @@ struct batadv_orig_node {
+ struct hlist_node mcast_want_all_ipv4_node;
+ struct hlist_node mcast_want_all_ipv6_node;
+ #endif
+- uint8_t capabilities;
++ unsigned long capabilities;
+ uint8_t capa_initialized;
+ atomic_t last_ttvn;
+ unsigned char *tt_buff;
+@@ -296,7 +296,7 @@ struct batadv_orig_node {
+ * (= orig node announces a tvlv of type BATADV_TVLV_MCAST)
+ */
+ enum batadv_orig_capabilities {
+- BATADV_ORIG_CAPA_HAS_DAT = BIT(0),
++ BATADV_ORIG_CAPA_HAS_DAT,
+ BATADV_ORIG_CAPA_HAS_NC = BIT(1),
+ BATADV_ORIG_CAPA_HAS_TT = BIT(2),
+ BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
--- /dev/null
+From ef72706a0543d0c3a5ab29bd6378fdfb368118d9 Mon Sep 17 00:00:00 2001
+From: Marek Lindner <mareklindner@neomailbox.ch>
+Date: Wed, 17 Jun 2015 20:01:36 +0800
+Subject: batman-adv: protect tt_local_entry from concurrent delete events
+
+From: Marek Lindner <mareklindner@neomailbox.ch>
+
+commit ef72706a0543d0c3a5ab29bd6378fdfb368118d9 upstream.
+
+The tt_local_entry deletion performed in batadv_tt_local_remove() was neither
+protecting against simultaneous deletes nor checking whether the element was
+still part of the list before calling hlist_del_rcu().
+
+Replacing the hlist_del_rcu() call with batadv_hash_remove() provides adequate
+protection via hash spinlocks as well as an is-element-still-in-hash check to
+avoid 'blind' hash removal.
+
+Fixes: 068ee6e204e1 ("batman-adv: roaming handling mechanism redesign")
+Reported-by: alfonsname@web.de
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/batman-adv/translation-table.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -1018,6 +1018,7 @@ uint16_t batadv_tt_local_remove(struct b
+ struct batadv_tt_local_entry *tt_local_entry;
+ uint16_t flags, curr_flags = BATADV_NO_FLAGS;
+ struct batadv_softif_vlan *vlan;
++ void *tt_entry_exists;
+
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
+ if (!tt_local_entry)
+@@ -1045,7 +1046,15 @@ uint16_t batadv_tt_local_remove(struct b
+ * immediately purge it
+ */
+ batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
+- hlist_del_rcu(&tt_local_entry->common.hash_entry);
++
++ tt_entry_exists = batadv_hash_remove(bat_priv->tt.local_hash,
++ batadv_compare_tt,
++ batadv_choose_tt,
++ &tt_local_entry->common);
++ if (!tt_entry_exists)
++ goto out;
++
++ /* extra call to free the local tt entry */
+ batadv_tt_local_entry_free_ref(tt_local_entry);
+
+ /* decrease the reference held for this vlan */
--- /dev/null
+From 2701fa0864ecb9e49d47a4aa1c02f172ab79639a Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Tue, 28 Jul 2015 15:31:12 +0200
+Subject: fbdev: select versatile helpers for the integrator
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+commit 2701fa0864ecb9e49d47a4aa1c02f172ab79639a upstream.
+
+Commit 11c32d7b6274cb0f554943d65bd4a126c4a86dcd
+"video: move Versatile CLCD helpers" missed the fact
+that the Integrator/CP is also using the helper, and
+as a result the platform got only stubs and no graphics.
+Add this as a default selection to Kconfig so we have
+graphics again.
+
+Fixes: 11c32d7b6274 (video: move Versatile CLCD helpers)
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/video/fbdev/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -298,7 +298,7 @@ config FB_ARMCLCD
+
+ # Helper logic selected only by the ARM Versatile platform family.
+ config PLAT_VERSATILE_CLCD
+- def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
++ def_bool ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_INTEGRATOR
+ depends on ARM
+ depends on FB_ARMCLCD && FB=y
+
--- /dev/null
+From b9a532277938798b53178d5a66af6e2915cb27cf Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Wed, 30 Sep 2015 12:48:40 -0400
+Subject: Initialize msg/shm IPC objects before doing ipc_addid()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit b9a532277938798b53178d5a66af6e2915cb27cf upstream.
+
+As reported by Dmitry Vyukov, we really shouldn't do ipc_addid() before
+having initialized the IPC object state. Yes, we initialize the IPC
+object in a locked state, but with all the lockless RCU lookup work,
+that IPC object lock no longer means that the state cannot be seen.
+
+We already did this for the IPC semaphore code (see commit e8577d1f0329:
+"ipc/sem.c: fully initialize sem_array before making it visible") but we
+clearly forgot about msg and shm.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Cc: Manfred Spraul <manfred@colorfullife.com>
+Cc: Davidlohr Bueso <dbueso@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c | 14 +++++++-------
+ ipc/shm.c | 13 +++++++------
+ ipc/util.c | 8 ++++----
+ 3 files changed, 18 insertions(+), 17 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -137,13 +137,6 @@ static int newque(struct ipc_namespace *
+ return retval;
+ }
+
+- /* ipc_addid() locks msq upon success. */
+- id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
+- if (id < 0) {
+- ipc_rcu_putref(msq, msg_rcu_free);
+- return id;
+- }
+-
+ msq->q_stime = msq->q_rtime = 0;
+ msq->q_ctime = get_seconds();
+ msq->q_cbytes = msq->q_qnum = 0;
+@@ -153,6 +146,13 @@ static int newque(struct ipc_namespace *
+ INIT_LIST_HEAD(&msq->q_receivers);
+ INIT_LIST_HEAD(&msq->q_senders);
+
++ /* ipc_addid() locks msq upon success. */
++ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
++ if (id < 0) {
++ ipc_rcu_putref(msq, msg_rcu_free);
++ return id;
++ }
++
+ ipc_unlock_object(&msq->q_perm);
+ rcu_read_unlock();
+
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -550,12 +550,6 @@ static int newseg(struct ipc_namespace *
+ if (IS_ERR(file))
+ goto no_file;
+
+- id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
+- if (id < 0) {
+- error = id;
+- goto no_id;
+- }
+-
+ shp->shm_cprid = task_tgid_vnr(current);
+ shp->shm_lprid = 0;
+ shp->shm_atim = shp->shm_dtim = 0;
+@@ -564,6 +558,13 @@ static int newseg(struct ipc_namespace *
+ shp->shm_nattch = 0;
+ shp->shm_file = file;
+ shp->shm_creator = current;
++
++ id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
++ if (id < 0) {
++ error = id;
++ goto no_id;
++ }
++
+ list_add(&shp->shm_clist, ¤t->sysvshm.shm_clist);
+
+ /*
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -237,6 +237,10 @@ int ipc_addid(struct ipc_ids *ids, struc
+ rcu_read_lock();
+ spin_lock(&new->lock);
+
++ current_euid_egid(&euid, &egid);
++ new->cuid = new->uid = euid;
++ new->gid = new->cgid = egid;
++
+ id = idr_alloc(&ids->ipcs_idr, new,
+ (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0,
+ GFP_NOWAIT);
+@@ -249,10 +253,6 @@ int ipc_addid(struct ipc_ids *ids, struc
+
+ ids->in_use++;
+
+- current_euid_egid(&euid, &egid);
+- new->cuid = new->uid = euid;
+- new->gid = new->cgid = egid;
+-
+ if (next_id < 0) {
+ new->seq = ids->seq++;
+ if (ids->seq > IPCID_SEQ_MAX)
--- /dev/null
+From e3895c0334d0ef46e80f22eaf2a52401ff6d5a67 Mon Sep 17 00:00:00 2001
+From: Julian Anastasov <ja@ssi.bg>
+Date: Thu, 9 Jul 2015 11:15:27 +0300
+Subject: ipvs: call skb_sender_cpu_clear
+
+From: Julian Anastasov <ja@ssi.bg>
+
+commit e3895c0334d0ef46e80f22eaf2a52401ff6d5a67 upstream.
+
+Reset XPS's sender_cpu on forwarding.
+
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Fixes: 2bd82484bb4c ("xps: fix xps for stacked devices")
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -518,6 +518,8 @@ static inline int ip_vs_tunnel_xmit_prep
+ if (ret == NF_ACCEPT) {
+ nf_reset(skb);
+ skb_forward_csum(skb);
++ if (!skb->sk)
++ skb_sender_cpu_clear(skb);
+ }
+ return ret;
+ }
+@@ -558,6 +560,8 @@ static inline int ip_vs_nat_send_or_cont
+
+ if (!local) {
+ skb_forward_csum(skb);
++ if (!skb->sk)
++ skb_sender_cpu_clear(skb);
+ NF_HOOK(pf, NF_INET_LOCAL_OUT, NULL, skb,
+ NULL, skb_dst(skb)->dev, dst_output_sk);
+ } else
+@@ -578,6 +582,8 @@ static inline int ip_vs_send_or_cont(int
+ if (!local) {
+ ip_vs_drop_early_demux_sk(skb);
+ skb_forward_csum(skb);
++ if (!skb->sk)
++ skb_sender_cpu_clear(skb);
+ NF_HOOK(pf, NF_INET_LOCAL_OUT, NULL, skb,
+ NULL, skb_dst(skb)->dev, dst_output_sk);
+ } else
--- /dev/null
+From 4754957f04f5f368792a0eb7dab0ae89fb93dcfd Mon Sep 17 00:00:00 2001
+From: Julian Anastasov <ja@ssi.bg>
+Date: Sat, 27 Jun 2015 14:39:30 +0300
+Subject: ipvs: do not use random local source address for tunnels
+
+From: Julian Anastasov <ja@ssi.bg>
+
+commit 4754957f04f5f368792a0eb7dab0ae89fb93dcfd upstream.
+
+Michael Vallaly reports about wrong source address used
+in rare cases for tunneled traffic. Looks like
+__ip_vs_get_out_rt in 3.10+ is providing uninitialized
+dest_dst->dst_saddr.ip because ip_vs_dest_dst_alloc uses
+kmalloc. While we retry after seeing EINVAL from routing
+for data that does not look like valid local address, it
+still succeeded when this memory was previously used from
+other dests and with different local addresses. As result,
+we can use valid local address that is not suitable for
+our real server.
+
+Fix it by providing 0.0.0.0 every time our cache is refreshed.
+By this way we will get preferred source address from routing.
+
+Reported-by: Michael Vallaly <lvs@nolatency.com>
+Fixes: 026ace060dfe ("ipvs: optimize dst usage for real server")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -130,7 +130,6 @@ static struct rtable *do_output_route4(s
+
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.daddr = daddr;
+- fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0;
+ fl4.flowi4_flags = (rt_mode & IP_VS_RT_MODE_KNOWN_NH) ?
+ FLOWI_FLAG_KNOWN_NH : 0;
+
--- /dev/null
+From 05f00505a89acd21f5d0d20f5797dfbc4cf85243 Mon Sep 17 00:00:00 2001
+From: Julian Anastasov <ja@ssi.bg>
+Date: Mon, 29 Jun 2015 21:51:40 +0300
+Subject: ipvs: fix crash if scheduler is changed
+
+From: Julian Anastasov <ja@ssi.bg>
+
+commit 05f00505a89acd21f5d0d20f5797dfbc4cf85243 upstream.
+
+I overlooked the svc->sched_data usage from schedulers
+when the services were converted to RCU in 3.10. Now
+the rare ipvsadm -E command can change the scheduler
+but due to the reverse order of ip_vs_bind_scheduler
+and ip_vs_unbind_scheduler we provide new sched_data
+to the old scheduler resulting in a crash.
+
+To fix it without changing the scheduler methods we
+have to use synchronize_rcu() only for the editing case.
+It means all svc->scheduler readers should expect a
+NULL value. To avoid breakage for the service listing
+and ipvsadm -R we can use the "none" name to indicate
+that scheduler is not assigned, a state when we drop
+new connections.
+
+Reported-by: Alexander Vasiliev <a.vasylev@404-group.com>
+Fixes: ceec4c381681 ("ipvs: convert services to rcu")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipvs/ip_vs_core.c | 16 +++++++-
+ net/netfilter/ipvs/ip_vs_ctl.c | 78 ++++++++++++++++++++++++---------------
+ net/netfilter/ipvs/ip_vs_sched.c | 12 +++---
+ 3 files changed, 69 insertions(+), 37 deletions(-)
+
+--- a/net/netfilter/ipvs/ip_vs_core.c
++++ b/net/netfilter/ipvs/ip_vs_core.c
+@@ -319,7 +319,13 @@ ip_vs_sched_persist(struct ip_vs_service
+ * return *ignored=0 i.e. ICMP and NF_DROP
+ */
+ sched = rcu_dereference(svc->scheduler);
+- dest = sched->schedule(svc, skb, iph);
++ if (sched) {
++ /* read svc->sched_data after svc->scheduler */
++ smp_rmb();
++ dest = sched->schedule(svc, skb, iph);
++ } else {
++ dest = NULL;
++ }
+ if (!dest) {
+ IP_VS_DBG(1, "p-schedule: no dest found.\n");
+ kfree(param.pe_data);
+@@ -467,7 +473,13 @@ ip_vs_schedule(struct ip_vs_service *svc
+ }
+
+ sched = rcu_dereference(svc->scheduler);
+- dest = sched->schedule(svc, skb, iph);
++ if (sched) {
++ /* read svc->sched_data after svc->scheduler */
++ smp_rmb();
++ dest = sched->schedule(svc, skb, iph);
++ } else {
++ dest = NULL;
++ }
+ if (dest == NULL) {
+ IP_VS_DBG(1, "Schedule: no dest found.\n");
+ return NULL;
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -842,15 +842,16 @@ __ip_vs_update_dest(struct ip_vs_service
+ __ip_vs_dst_cache_reset(dest);
+ spin_unlock_bh(&dest->dst_lock);
+
+- sched = rcu_dereference_protected(svc->scheduler, 1);
+ if (add) {
+ ip_vs_start_estimator(svc->net, &dest->stats);
+ list_add_rcu(&dest->n_list, &svc->destinations);
+ svc->num_dests++;
+- if (sched->add_dest)
++ sched = rcu_dereference_protected(svc->scheduler, 1);
++ if (sched && sched->add_dest)
+ sched->add_dest(svc, dest);
+ } else {
+- if (sched->upd_dest)
++ sched = rcu_dereference_protected(svc->scheduler, 1);
++ if (sched && sched->upd_dest)
+ sched->upd_dest(svc, dest);
+ }
+ }
+@@ -1084,7 +1085,7 @@ static void __ip_vs_unlink_dest(struct i
+ struct ip_vs_scheduler *sched;
+
+ sched = rcu_dereference_protected(svc->scheduler, 1);
+- if (sched->del_dest)
++ if (sched && sched->del_dest)
+ sched->del_dest(svc, dest);
+ }
+ }
+@@ -1175,11 +1176,14 @@ ip_vs_add_service(struct net *net, struc
+ ip_vs_use_count_inc();
+
+ /* Lookup the scheduler by 'u->sched_name' */
+- sched = ip_vs_scheduler_get(u->sched_name);
+- if (sched == NULL) {
+- pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name);
+- ret = -ENOENT;
+- goto out_err;
++ if (strcmp(u->sched_name, "none")) {
++ sched = ip_vs_scheduler_get(u->sched_name);
++ if (!sched) {
++ pr_info("Scheduler module ip_vs_%s not found\n",
++ u->sched_name);
++ ret = -ENOENT;
++ goto out_err;
++ }
+ }
+
+ if (u->pe_name && *u->pe_name) {
+@@ -1240,10 +1244,12 @@ ip_vs_add_service(struct net *net, struc
+ spin_lock_init(&svc->stats.lock);
+
+ /* Bind the scheduler */
+- ret = ip_vs_bind_scheduler(svc, sched);
+- if (ret)
+- goto out_err;
+- sched = NULL;
++ if (sched) {
++ ret = ip_vs_bind_scheduler(svc, sched);
++ if (ret)
++ goto out_err;
++ sched = NULL;
++ }
+
+ /* Bind the ct retriever */
+ RCU_INIT_POINTER(svc->pe, pe);
+@@ -1291,17 +1297,20 @@ ip_vs_add_service(struct net *net, struc
+ static int
+ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
+ {
+- struct ip_vs_scheduler *sched, *old_sched;
++ struct ip_vs_scheduler *sched = NULL, *old_sched;
+ struct ip_vs_pe *pe = NULL, *old_pe = NULL;
+ int ret = 0;
+
+ /*
+ * Lookup the scheduler, by 'u->sched_name'
+ */
+- sched = ip_vs_scheduler_get(u->sched_name);
+- if (sched == NULL) {
+- pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name);
+- return -ENOENT;
++ if (strcmp(u->sched_name, "none")) {
++ sched = ip_vs_scheduler_get(u->sched_name);
++ if (!sched) {
++ pr_info("Scheduler module ip_vs_%s not found\n",
++ u->sched_name);
++ return -ENOENT;
++ }
+ }
+ old_sched = sched;
+
+@@ -1329,14 +1338,20 @@ ip_vs_edit_service(struct ip_vs_service
+
+ old_sched = rcu_dereference_protected(svc->scheduler, 1);
+ if (sched != old_sched) {
++ if (old_sched) {
++ ip_vs_unbind_scheduler(svc, old_sched);
++ RCU_INIT_POINTER(svc->scheduler, NULL);
++ /* Wait all svc->sched_data users */
++ synchronize_rcu();
++ }
+ /* Bind the new scheduler */
+- ret = ip_vs_bind_scheduler(svc, sched);
+- if (ret) {
+- old_sched = sched;
+- goto out;
++ if (sched) {
++ ret = ip_vs_bind_scheduler(svc, sched);
++ if (ret) {
++ ip_vs_scheduler_put(sched);
++ goto out;
++ }
+ }
+- /* Unbind the old scheduler on success */
+- ip_vs_unbind_scheduler(svc, old_sched);
+ }
+
+ /*
+@@ -1982,6 +1997,7 @@ static int ip_vs_info_seq_show(struct se
+ const struct ip_vs_iter *iter = seq->private;
+ const struct ip_vs_dest *dest;
+ struct ip_vs_scheduler *sched = rcu_dereference(svc->scheduler);
++ char *sched_name = sched ? sched->name : "none";
+
+ if (iter->table == ip_vs_svc_table) {
+ #ifdef CONFIG_IP_VS_IPV6
+@@ -1990,18 +2006,18 @@ static int ip_vs_info_seq_show(struct se
+ ip_vs_proto_name(svc->protocol),
+ &svc->addr.in6,
+ ntohs(svc->port),
+- sched->name);
++ sched_name);
+ else
+ #endif
+ seq_printf(seq, "%s %08X:%04X %s %s ",
+ ip_vs_proto_name(svc->protocol),
+ ntohl(svc->addr.ip),
+ ntohs(svc->port),
+- sched->name,
++ sched_name,
+ (svc->flags & IP_VS_SVC_F_ONEPACKET)?"ops ":"");
+ } else {
+ seq_printf(seq, "FWM %08X %s %s",
+- svc->fwmark, sched->name,
++ svc->fwmark, sched_name,
+ (svc->flags & IP_VS_SVC_F_ONEPACKET)?"ops ":"");
+ }
+
+@@ -2427,13 +2443,15 @@ ip_vs_copy_service(struct ip_vs_service_
+ {
+ struct ip_vs_scheduler *sched;
+ struct ip_vs_kstats kstats;
++ char *sched_name;
+
+ sched = rcu_dereference_protected(src->scheduler, 1);
++ sched_name = sched ? sched->name : "none";
+ dst->protocol = src->protocol;
+ dst->addr = src->addr.ip;
+ dst->port = src->port;
+ dst->fwmark = src->fwmark;
+- strlcpy(dst->sched_name, sched->name, sizeof(dst->sched_name));
++ strlcpy(dst->sched_name, sched_name, sizeof(dst->sched_name));
+ dst->flags = src->flags;
+ dst->timeout = src->timeout / HZ;
+ dst->netmask = src->netmask;
+@@ -2892,6 +2910,7 @@ static int ip_vs_genl_fill_service(struc
+ struct ip_vs_flags flags = { .flags = svc->flags,
+ .mask = ~0 };
+ struct ip_vs_kstats kstats;
++ char *sched_name;
+
+ nl_service = nla_nest_start(skb, IPVS_CMD_ATTR_SERVICE);
+ if (!nl_service)
+@@ -2910,8 +2929,9 @@ static int ip_vs_genl_fill_service(struc
+ }
+
+ sched = rcu_dereference_protected(svc->scheduler, 1);
++ sched_name = sched ? sched->name : "none";
+ pe = rcu_dereference_protected(svc->pe, 1);
+- if (nla_put_string(skb, IPVS_SVC_ATTR_SCHED_NAME, sched->name) ||
++ if (nla_put_string(skb, IPVS_SVC_ATTR_SCHED_NAME, sched_name) ||
+ (pe && nla_put_string(skb, IPVS_SVC_ATTR_PE_NAME, pe->name)) ||
+ nla_put(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags) ||
+ nla_put_u32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ) ||
+--- a/net/netfilter/ipvs/ip_vs_sched.c
++++ b/net/netfilter/ipvs/ip_vs_sched.c
+@@ -74,7 +74,7 @@ void ip_vs_unbind_scheduler(struct ip_vs
+
+ if (sched->done_service)
+ sched->done_service(svc);
+- /* svc->scheduler can not be set to NULL */
++ /* svc->scheduler can be set to NULL only by caller */
+ }
+
+
+@@ -147,21 +147,21 @@ void ip_vs_scheduler_put(struct ip_vs_sc
+
+ void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg)
+ {
+- struct ip_vs_scheduler *sched;
++ struct ip_vs_scheduler *sched = rcu_dereference(svc->scheduler);
++ char *sched_name = sched ? sched->name : "none";
+
+- sched = rcu_dereference(svc->scheduler);
+ if (svc->fwmark) {
+ IP_VS_ERR_RL("%s: FWM %u 0x%08X - %s\n",
+- sched->name, svc->fwmark, svc->fwmark, msg);
++ sched_name, svc->fwmark, svc->fwmark, msg);
+ #ifdef CONFIG_IP_VS_IPV6
+ } else if (svc->af == AF_INET6) {
+ IP_VS_ERR_RL("%s: %s [%pI6c]:%d - %s\n",
+- sched->name, ip_vs_proto_name(svc->protocol),
++ sched_name, ip_vs_proto_name(svc->protocol),
+ &svc->addr.in6, ntohs(svc->port), msg);
+ #endif
+ } else {
+ IP_VS_ERR_RL("%s: %s %pI4:%d - %s\n",
+- sched->name, ip_vs_proto_name(svc->protocol),
++ sched_name, ip_vs_proto_name(svc->protocol),
+ &svc->addr.ip, ntohs(svc->port), msg);
+ }
+ }
--- /dev/null
+From 56184858d1fc95c46723436b455cb7261cd8be6f Mon Sep 17 00:00:00 2001
+From: Julian Anastasov <ja@ssi.bg>
+Date: Wed, 8 Jul 2015 08:31:33 +0300
+Subject: ipvs: fix crash with sync protocol v0 and FTP
+
+From: Julian Anastasov <ja@ssi.bg>
+
+commit 56184858d1fc95c46723436b455cb7261cd8be6f upstream.
+
+Fix crash in 3.5+ if FTP is used after switching
+sync_version to 0.
+
+Fixes: 749c42b620a9 ("ipvs: reduce sync rate with time thresholds")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipvs/ip_vs_sync.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/netfilter/ipvs/ip_vs_sync.c
++++ b/net/netfilter/ipvs/ip_vs_sync.c
+@@ -612,7 +612,7 @@ static void ip_vs_sync_conn_v0(struct ne
+ pkts = atomic_add_return(1, &cp->in_pkts);
+ else
+ pkts = sysctl_sync_threshold(ipvs);
+- ip_vs_sync_conn(net, cp->control, pkts);
++ ip_vs_sync_conn(net, cp, pkts);
+ }
+ }
+
--- /dev/null
+From 71563f3414e917c62acd8e0fb0edf8ed6af63e4b Mon Sep 17 00:00:00 2001
+From: Alex Gartrell <agartrell@fb.com>
+Date: Sun, 5 Jul 2015 14:28:26 -0700
+Subject: ipvs: skb_orphan in case of forwarding
+
+From: Alex Gartrell <agartrell@fb.com>
+
+commit 71563f3414e917c62acd8e0fb0edf8ed6af63e4b upstream.
+
+It is possible that we bind against a local socket in early_demux when we
+are actually going to want to forward it. In this case, the socket serves
+no purpose and only serves to confuse things (particularly functions which
+implicitly expect sk_fullsock to be true, like ip_local_out).
+Additionally, skb_set_owner_w is totally broken for non full-socks.
+
+Signed-off-by: Alex Gartrell <agartrell@fb.com>
+Fixes: 41063e9dd119 ("ipv4: Early TCP socket demux.")
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -522,6 +522,21 @@ static inline int ip_vs_tunnel_xmit_prep
+ return ret;
+ }
+
++/* In the event of a remote destination, it's possible that we would have
++ * matches against an old socket (particularly a TIME-WAIT socket). This
++ * causes havoc down the line (ip_local_out et. al. expect regular sockets
++ * and invalid memory accesses will happen) so simply drop the association
++ * in this case.
++*/
++static inline void ip_vs_drop_early_demux_sk(struct sk_buff *skb)
++{
++ /* If dev is set, the packet came from the LOCAL_IN callback and
++ * not from a local TCP socket.
++ */
++ if (skb->dev)
++ skb_orphan(skb);
++}
++
+ /* return NF_STOLEN (sent) or NF_ACCEPT if local=1 (not sent) */
+ static inline int ip_vs_nat_send_or_cont(int pf, struct sk_buff *skb,
+ struct ip_vs_conn *cp, int local)
+@@ -533,12 +548,21 @@ static inline int ip_vs_nat_send_or_cont
+ ip_vs_notrack(skb);
+ else
+ ip_vs_update_conntrack(skb, cp, 1);
++
++ /* Remove the early_demux association unless it's bound for the
++ * exact same port and address on this host after translation.
++ */
++ if (!local || cp->vport != cp->dport ||
++ !ip_vs_addr_equal(cp->af, &cp->vaddr, &cp->daddr))
++ ip_vs_drop_early_demux_sk(skb);
++
+ if (!local) {
+ skb_forward_csum(skb);
+ NF_HOOK(pf, NF_INET_LOCAL_OUT, NULL, skb,
+ NULL, skb_dst(skb)->dev, dst_output_sk);
+ } else
+ ret = NF_ACCEPT;
++
+ return ret;
+ }
+
+@@ -552,6 +576,7 @@ static inline int ip_vs_send_or_cont(int
+ if (likely(!(cp->flags & IP_VS_CONN_F_NFCT)))
+ ip_vs_notrack(skb);
+ if (!local) {
++ ip_vs_drop_early_demux_sk(skb);
+ skb_forward_csum(skb);
+ NF_HOOK(pf, NF_INET_LOCAL_OUT, NULL, skb,
+ NULL, skb_dst(skb)->dev, dst_output_sk);
+@@ -840,6 +865,8 @@ ip_vs_prepare_tunneled_skb(struct sk_buf
+ struct ipv6hdr *old_ipv6h = NULL;
+ #endif
+
++ ip_vs_drop_early_demux_sk(skb);
++
+ if (skb_headroom(skb) < max_headroom || skb_cloned(skb)) {
+ new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (!new_skb)
--- /dev/null
+From 54d27365cae88fbcc853b391dcd561e71acb81fa Mon Sep 17 00:00:00 2001
+From: Ben Segall <bsegall@google.com>
+Date: Mon, 6 Apr 2015 15:28:10 -0700
+Subject: sched/fair: Prevent throttling in early pick_next_task_fair()
+
+From: Ben Segall <bsegall@google.com>
+
+commit 54d27365cae88fbcc853b391dcd561e71acb81fa upstream.
+
+The optimized task selection logic optimistically selects a new task
+to run without first doing a full put_prev_task(). This is so that we
+can avoid a put/set on the common ancestors of the old and new task.
+
+Similarly, we should only call check_cfs_rq_runtime() to throttle
+eligible groups if they're part of the common ancestry, otherwise it
+is possible to end up with no eligible task in the simple task
+selection.
+
+Imagine:
+ /root
+ /prev /next
+ /A /B
+
+If our optimistic selection ends up throttling /next, we goto simple
+and our put_prev_task() ends up throttling /prev, after which we're
+going to bug out in set_next_entity() because there aren't any tasks
+left.
+
+Avoid this scenario by only throttling common ancestors.
+
+Reported-by: Mohammed Naser <mnaser@vexxhost.com>
+Reported-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Signed-off-by: Ben Segall <bsegall@google.com>
+[ munged Changelog ]
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Roman Gushchin <klamm@yandex-team.ru>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: pjt@google.com
+Fixes: 678d5718d8d0 ("sched/fair: Optimize cgroup pick_next_task_fair()")
+Link: http://lkml.kernel.org/r/xm26wq1oswoq.fsf@sword-of-the-dawn.mtv.corp.google.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/fair.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -5126,18 +5126,21 @@ again:
+ * entity, update_curr() will update its vruntime, otherwise
+ * forget we've ever seen it.
+ */
+- if (curr && curr->on_rq)
+- update_curr(cfs_rq);
+- else
+- curr = NULL;
++ if (curr) {
++ if (curr->on_rq)
++ update_curr(cfs_rq);
++ else
++ curr = NULL;
+
+- /*
+- * This call to check_cfs_rq_runtime() will do the throttle and
+- * dequeue its entity in the parent(s). Therefore the 'simple'
+- * nr_running test will indeed be correct.
+- */
+- if (unlikely(check_cfs_rq_runtime(cfs_rq)))
+- goto simple;
++ /*
++ * This call to check_cfs_rq_runtime() will do the
++ * throttle and dequeue its entity in the parent(s).
++ * Therefore the 'simple' nr_running test will indeed
++ * be correct.
++ */
++ if (unlikely(check_cfs_rq_runtime(cfs_rq)))
++ goto simple;
++ }
+
+ se = pick_next_entity(cfs_rq, curr);
+ cfs_rq = group_cfs_rq(se);
--- /dev/null
+From Dave.Martin@arm.com Sat Oct 17 13:59:05 2015
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Fri, 24 Jul 2015 17:39:21 +0100
+Subject: [PATCH REPOST] serial/amba-pl011: Disable interrupts around TX softirq
+To: linux-serial@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Russell King <linux@arm.linux.org.uk>, Robin Murphy <Robin.Murphy@arm.com>, linux-arm-kernel@lists.infradead.org, Jakub Kiciński <moorray3@wp.pl>, Andrew Jackson <Andrew.Jackson@arm.com>, Graeme Gregory <gg@slimlogic.co.uk>, Andre Przywara <Andre.Przywara@arm.com>, Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>, popcorn mix <popcornmix@gmail.com>, stable <stable@vger.kernel.org>
+Message-ID: <1437755961-15403-1-git-send-email-Dave.Martin@arm.com>
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+pl011_tx_softirq() currently uses spin_{,un}lock(), which are not
+sufficient to inhibit pl011_int() from being triggered by a local
+IRQ and trying to re-take the same lock. This can lead to
+deadlocks.
+
+This patch uses the _irq() locking variants instead to ensure that
+pl011_int() handling for a given port is deferred until any
+pl011_tx_softirq() work for that port is complete.
+
+
+Notes for stable:
+
+This patch fixes an issue that is fixed by the following upstream
+commit, which is a more substantial rewrite of the affected code,
+fixing multiple, mostly more minor issues:
+
+ 1e84d22322ceed4767db1e5342c830dd60c8210f
+ serial/amba-pl011: Refactor and simplify TX FIFO handling
+
+The upstream patch was rejected for stable on the reasonable grounds
+that it was too big and complex a patch. The original buggy code was
+merged in v4.1, and the rewrite was merged in v4.2, leaving only v4.1
+affected.
+
+
+This patch replaces the 1e84d22, for 4.1.x only.
+
+Fixes: 734745caeb9f serial/amba-pl011: Activate TX IRQ passively
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Tested-by: Robin Murphy <robin.murphy@arm.com>
+Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/amba-pl011.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1360,9 +1360,9 @@ static void pl011_tx_softirq(struct work
+ struct uart_amba_port *uap =
+ container_of(dwork, struct uart_amba_port, tx_softirq_work);
+
+- spin_lock(&uap->port.lock);
++ spin_lock_irq(&uap->port.lock);
+ while (pl011_tx_chars(uap)) ;
+- spin_unlock(&uap->port.lock);
++ spin_unlock_irq(&uap->port.lock);
+ }
+
+ static void pl011_tx_irq_seen(struct uart_amba_port *uap)
xhci-change-xhci-1.0-only-restrictions-to-support-xhci-1.1.patch
xhci-init-command-timeout-timer-earlier-to-avoid-deleting-it-uninitialized.patch
usb-xhci-add-support-for-urb_zero_packet-to-bulk-sg-transfers.patch
+initialize-msg-shm-ipc-objects-before-doing-ipc_addid.patch
+sched-fair-prevent-throttling-in-early-pick_next_task_fair.patch
+serial-amba-pl011-disable-interrupts-around-tx-softirq.patch
+ipvs-do-not-use-random-local-source-address-for-tunnels.patch
+ipvs-fix-crash-if-scheduler-is-changed.patch
+ipvs-skb_orphan-in-case-of-forwarding.patch
+ipvs-fix-crash-with-sync-protocol-v0-and-ftp.patch
+ipvs-call-skb_sender_cpu_clear.patch
+fbdev-select-versatile-helpers-for-the-integrator.patch
+batman-adv-fix-kernel-crash-due-to-missing-null-checks.patch
+batman-adv-protect-tt_local_entry-from-concurrent-delete-events.patch
+batman-adv-make-dat-capability-changes-atomic.patch