--- /dev/null
+From 8a4023c5b5e30b11f1f383186f4a7222b3b823cf 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:26 +0200
+Subject: batman-adv: Fix potential synchronization issues in mcast tvlv handler
+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 8a4023c5b5e30b11f1f383186f4a7222b3b823cf upstream.
+
+So far the mcast tvlv handler did not anticipate the processing of
+multiple incoming OGMs from the same originator at the same time. This
+can lead to various issues:
+
+* Broken refcounting: For instance two mcast handlers might both assume
+ that an originator just got multicast capabilities and will together
+ wrongly decrease mcast.num_disabled by two, potentially leading to
+ an integer underflow.
+
+* Potential kernel panic on hlist_del_rcu(): Two mcast handlers might
+ one after another try to do an
+ hlist_del_rcu(&orig->mcast_want_all_*_node). The second one will
+ cause memory corruption / crashes.
+ (Reported by: Sven Eckelmann <sven@narfation.org>)
+
+Right in the beginning the code path makes assumptions about the current
+multicast related state of an originator and bases all updates on that. The
+easiest and least error prune way to fix the issues in this case is to
+serialize multiple mcast handler invocations with a spinlock.
+
+Fixes: 60432d756cf0 ("batman-adv: Announce new capability via multicast TVLV")
+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/multicast.c | 63 ++++++++++++++++++++++++++++++++++----------
+ net/batman-adv/originator.c | 5 +++
+ net/batman-adv/types.h | 3 ++
+ 3 files changed, 58 insertions(+), 13 deletions(-)
+
+--- a/net/batman-adv/multicast.c
++++ b/net/batman-adv/multicast.c
+@@ -20,6 +20,7 @@
+
+ #include <linux/atomic.h>
+ #include <linux/bitops.h>
++#include <linux/bug.h>
+ #include <linux/byteorder/generic.h>
+ #include <linux/errno.h>
+ #include <linux/etherdevice.h>
+@@ -589,19 +590,26 @@ batadv_mcast_forw_mode(struct batadv_pri
+ *
+ * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
+ * orig, has toggled then this method updates counter and list accordingly.
++ *
++ * Caller needs to hold orig->mcast_handler_lock.
+ */
+ static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t mcast_flags)
+ {
++ struct hlist_node *node = &orig->mcast_want_all_unsnoopables_node;
++ struct hlist_head *head = &bat_priv->mcast.want_all_unsnoopables_list;
++
+ /* switched from flag unset to set */
+ if (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES &&
+ !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES)) {
+ atomic_inc(&bat_priv->mcast.num_want_all_unsnoopables);
+
+ spin_lock_bh(&bat_priv->mcast.want_lists_lock);
+- hlist_add_head_rcu(&orig->mcast_want_all_unsnoopables_node,
+- &bat_priv->mcast.want_all_unsnoopables_list);
++ /* flag checks above + mcast_handler_lock prevents this */
++ WARN_ON(!hlist_unhashed(node));
++
++ hlist_add_head_rcu(node, head);
+ spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
+ /* switched from flag set to unset */
+ } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) &&
+@@ -609,7 +617,10 @@ static void batadv_mcast_want_unsnoop_up
+ atomic_dec(&bat_priv->mcast.num_want_all_unsnoopables);
+
+ spin_lock_bh(&bat_priv->mcast.want_lists_lock);
+- hlist_del_rcu(&orig->mcast_want_all_unsnoopables_node);
++ /* flag checks above + mcast_handler_lock prevents this */
++ WARN_ON(hlist_unhashed(node));
++
++ hlist_del_init_rcu(node);
+ spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
+ }
+ }
+@@ -622,19 +633,26 @@ static void batadv_mcast_want_unsnoop_up
+ *
+ * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
+ * toggled then this method updates counter and list accordingly.
++ *
++ * Caller needs to hold orig->mcast_handler_lock.
+ */
+ static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t mcast_flags)
+ {
++ struct hlist_node *node = &orig->mcast_want_all_ipv4_node;
++ struct hlist_head *head = &bat_priv->mcast.want_all_ipv4_list;
++
+ /* switched from flag unset to set */
+ if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4 &&
+ !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV4)) {
+ atomic_inc(&bat_priv->mcast.num_want_all_ipv4);
+
+ spin_lock_bh(&bat_priv->mcast.want_lists_lock);
+- hlist_add_head_rcu(&orig->mcast_want_all_ipv4_node,
+- &bat_priv->mcast.want_all_ipv4_list);
++ /* flag checks above + mcast_handler_lock prevents this */
++ WARN_ON(!hlist_unhashed(node));
++
++ hlist_add_head_rcu(node, head);
+ spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
+ /* switched from flag set to unset */
+ } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) &&
+@@ -642,7 +660,10 @@ static void batadv_mcast_want_ipv4_updat
+ atomic_dec(&bat_priv->mcast.num_want_all_ipv4);
+
+ spin_lock_bh(&bat_priv->mcast.want_lists_lock);
+- hlist_del_rcu(&orig->mcast_want_all_ipv4_node);
++ /* flag checks above + mcast_handler_lock prevents this */
++ WARN_ON(hlist_unhashed(node));
++
++ hlist_del_init_rcu(node);
+ spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
+ }
+ }
+@@ -655,19 +676,26 @@ static void batadv_mcast_want_ipv4_updat
+ *
+ * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
+ * toggled then this method updates counter and list accordingly.
++ *
++ * Caller needs to hold orig->mcast_handler_lock.
+ */
+ static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig,
+ uint8_t mcast_flags)
+ {
++ struct hlist_node *node = &orig->mcast_want_all_ipv6_node;
++ struct hlist_head *head = &bat_priv->mcast.want_all_ipv6_list;
++
+ /* switched from flag unset to set */
+ if (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6 &&
+ !(orig->mcast_flags & BATADV_MCAST_WANT_ALL_IPV6)) {
+ atomic_inc(&bat_priv->mcast.num_want_all_ipv6);
+
+ spin_lock_bh(&bat_priv->mcast.want_lists_lock);
+- hlist_add_head_rcu(&orig->mcast_want_all_ipv6_node,
+- &bat_priv->mcast.want_all_ipv6_list);
++ /* flag checks above + mcast_handler_lock prevents this */
++ WARN_ON(!hlist_unhashed(node));
++
++ hlist_add_head_rcu(node, head);
+ spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
+ /* switched from flag set to unset */
+ } else if (!(mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) &&
+@@ -675,7 +703,10 @@ static void batadv_mcast_want_ipv6_updat
+ atomic_dec(&bat_priv->mcast.num_want_all_ipv6);
+
+ spin_lock_bh(&bat_priv->mcast.want_lists_lock);
+- hlist_del_rcu(&orig->mcast_want_all_ipv6_node);
++ /* flag checks above + mcast_handler_lock prevents this */
++ WARN_ON(hlist_unhashed(node));
++
++ hlist_del_init_rcu(node);
+ spin_unlock_bh(&bat_priv->mcast.want_lists_lock);
+ }
+ }
+@@ -698,6 +729,11 @@ static void batadv_mcast_tvlv_ogm_handle
+ uint8_t mcast_flags = BATADV_NO_FLAGS;
+ bool orig_initialized;
+
++ if (orig_mcast_enabled && tvlv_value &&
++ (tvlv_value_len >= sizeof(mcast_flags)))
++ mcast_flags = *(uint8_t *)tvlv_value;
++
++ spin_lock_bh(&orig->mcast_handler_lock);
+ orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
+ &orig->capa_initialized);
+
+@@ -723,15 +759,12 @@ static void batadv_mcast_tvlv_ogm_handle
+
+ set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
+
+- if (orig_mcast_enabled && tvlv_value &&
+- (tvlv_value_len >= sizeof(mcast_flags)))
+- mcast_flags = *(uint8_t *)tvlv_value;
+-
+ batadv_mcast_want_unsnoop_update(bat_priv, orig, mcast_flags);
+ batadv_mcast_want_ipv4_update(bat_priv, orig, mcast_flags);
+ batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
+
+ orig->mcast_flags = mcast_flags;
++ spin_unlock_bh(&orig->mcast_handler_lock);
+ }
+
+ /**
+@@ -765,6 +798,8 @@ void batadv_mcast_purge_orig(struct bata
+ {
+ struct batadv_priv *bat_priv = orig->bat_priv;
+
++ spin_lock_bh(&orig->mcast_handler_lock);
++
+ if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) &&
+ test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized))
+ atomic_dec(&bat_priv->mcast.num_disabled);
+@@ -772,4 +807,6 @@ void batadv_mcast_purge_orig(struct bata
+ batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
+ batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS);
+ batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS);
++
++ spin_unlock_bh(&orig->mcast_handler_lock);
+ }
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -696,8 +696,13 @@ struct batadv_orig_node *batadv_orig_nod
+ orig_node->last_seen = jiffies;
+ reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
+ orig_node->bcast_seqno_reset = reset_time;
++
+ #ifdef CONFIG_BATMAN_ADV_MCAST
+ orig_node->mcast_flags = BATADV_NO_FLAGS;
++ INIT_HLIST_NODE(&orig_node->mcast_want_all_unsnoopables_node);
++ INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv4_node);
++ INIT_HLIST_NODE(&orig_node->mcast_want_all_ipv6_node);
++ spin_lock_init(&orig_node->mcast_handler_lock);
+ #endif
+
+ /* create a vlan object for the "untagged" LAN */
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -221,6 +221,7 @@ struct batadv_orig_bat_iv {
+ * @batadv_dat_addr_t: address of the orig node in the distributed hash
+ * @last_seen: time when last packet from this node was received
+ * @bcast_seqno_reset: time when the broadcast seqno window was reset
++ * @mcast_handler_lock: synchronizes mcast-capability and -flag changes
+ * @mcast_flags: multicast flags announced by the orig node
+ * @mcast_want_all_unsnoop_node: a list node for the
+ * mcast.want_all_unsnoopables list
+@@ -268,6 +269,8 @@ struct batadv_orig_node {
+ unsigned long last_seen;
+ unsigned long bcast_seqno_reset;
+ #ifdef CONFIG_BATMAN_ADV_MCAST
++ /* synchronizes mcast tvlv specific orig changes */
++ spinlock_t mcast_handler_lock;
+ uint8_t mcast_flags;
+ struct hlist_node mcast_want_all_unsnoopables_node;
+ struct hlist_node mcast_want_all_ipv4_node;
--- /dev/null
+From 53cf037bf846417fd92dc92ddf97267f69b110f4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue>
+Date: Tue, 30 Jun 2015 23:45:26 +0200
+Subject: batman-adv: Fix potentially broken skb network header access
+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 53cf037bf846417fd92dc92ddf97267f69b110f4 upstream.
+
+The two commits noted below added calls to ip_hdr() and ipv6_hdr(). They
+need a correctly set skb network header.
+
+Unfortunately we cannot rely on the device drivers to set it for us.
+Therefore setting it in the beginning of the according ndo_start_xmit
+handler.
+
+Fixes: 1d8ab8d3c176 ("batman-adv: Modified forwarding behaviour for multicast packets")
+Fixes: ab49886e3da7 ("batman-adv: Add IPv4 link-local/IPv6-ll-all-nodes multicast support")
+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/soft-interface.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -202,6 +202,7 @@ static int batadv_interface_tx(struct sk
+ int gw_mode;
+ enum batadv_forw_mode forw_mode;
+ struct batadv_orig_node *mcast_single_orig = NULL;
++ int network_offset = ETH_HLEN;
+
+ if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
+ goto dropped;
+@@ -214,14 +215,18 @@ static int batadv_interface_tx(struct sk
+ case ETH_P_8021Q:
+ vhdr = vlan_eth_hdr(skb);
+
+- if (vhdr->h_vlan_encapsulated_proto != ethertype)
++ if (vhdr->h_vlan_encapsulated_proto != ethertype) {
++ network_offset += VLAN_HLEN;
+ break;
++ }
+
+ /* fall through */
+ case ETH_P_BATMAN:
+ goto dropped;
+ }
+
++ skb_set_network_header(skb, network_offset);
++
+ if (batadv_bla_tx(bat_priv, skb, vid))
+ goto dropped;
+
--- /dev/null
+From 9c936e3f4c4fad07abb6c082a89508b8f724c88f 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:25 +0200
+Subject: batman-adv: Make MCAST 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 9c936e3f4c4fad07abb6c082a89508b8f724c88f 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: 60432d756cf0 ("batman-adv: Announce new capability via multicast TVLV")
+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/multicast.c | 18 ++++++++++--------
+ net/batman-adv/types.h | 2 +-
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+--- a/net/batman-adv/multicast.c
++++ b/net/batman-adv/multicast.c
+@@ -19,6 +19,7 @@
+ #include "main.h"
+
+ #include <linux/atomic.h>
++#include <linux/bitops.h>
+ #include <linux/byteorder/generic.h>
+ #include <linux/errno.h>
+ #include <linux/etherdevice.h>
+@@ -697,29 +698,30 @@ static void batadv_mcast_tvlv_ogm_handle
+ uint8_t mcast_flags = BATADV_NO_FLAGS;
+ bool orig_initialized;
+
+- orig_initialized = orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST;
++ orig_initialized = test_bit(BATADV_ORIG_CAPA_HAS_MCAST,
++ &orig->capa_initialized);
+
+ /* If mcast support is turned on decrease the disabled mcast node
+ * counter only if we had increased it for this node before. If this
+ * is a completely new orig_node no need to decrease the counter.
+ */
+ if (orig_mcast_enabled &&
+- !(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST)) {
++ !test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities)) {
+ if (orig_initialized)
+ atomic_dec(&bat_priv->mcast.num_disabled);
+- orig->capabilities |= BATADV_ORIG_CAPA_HAS_MCAST;
++ set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
+ /* If mcast support is being switched off or if this is an initial
+ * OGM without mcast support then increase the disabled mcast
+ * node counter.
+ */
+ } else if (!orig_mcast_enabled &&
+- (orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST ||
++ (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) ||
+ !orig_initialized)) {
+ atomic_inc(&bat_priv->mcast.num_disabled);
+- orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_MCAST;
++ clear_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities);
+ }
+
+- orig->capa_initialized |= BATADV_ORIG_CAPA_HAS_MCAST;
++ set_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized);
+
+ if (orig_mcast_enabled && tvlv_value &&
+ (tvlv_value_len >= sizeof(mcast_flags)))
+@@ -763,8 +765,8 @@ void batadv_mcast_purge_orig(struct bata
+ {
+ struct batadv_priv *bat_priv = orig->bat_priv;
+
+- if (!(orig->capabilities & BATADV_ORIG_CAPA_HAS_MCAST) &&
+- orig->capa_initialized & BATADV_ORIG_CAPA_HAS_MCAST)
++ if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capabilities) &&
++ test_bit(BATADV_ORIG_CAPA_HAS_MCAST, &orig->capa_initialized))
+ atomic_dec(&bat_priv->mcast.num_disabled);
+
+ batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS);
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -316,7 +316,7 @@ enum batadv_orig_capabilities {
+ BATADV_ORIG_CAPA_HAS_DAT,
+ BATADV_ORIG_CAPA_HAS_NC,
+ BATADV_ORIG_CAPA_HAS_TT,
+- BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
++ BATADV_ORIG_CAPA_HAS_MCAST,
+ };
+
+ /**
--- /dev/null
+From 4635469f5c617282f18c69643af36cd8c0acf707 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:23 +0200
+Subject: batman-adv: Make NC 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 4635469f5c617282f18c69643af36cd8c0acf707 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: 3f4841ffb336 ("batman-adv: tvlv - add network coding 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/network-coding.c | 7 ++++---
+ net/batman-adv/types.h | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/network-coding.c
++++ b/net/batman-adv/network-coding.c
+@@ -19,6 +19,7 @@
+ #include "main.h"
+
+ #include <linux/atomic.h>
++#include <linux/bitops.h>
+ #include <linux/byteorder/generic.h>
+ #include <linux/compiler.h>
+ #include <linux/debugfs.h>
+@@ -134,9 +135,9 @@ static void batadv_nc_tvlv_ogm_handler_v
+ uint16_t tvlv_value_len)
+ {
+ if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND)
+- orig->capabilities &= ~BATADV_ORIG_CAPA_HAS_NC;
++ clear_bit(BATADV_ORIG_CAPA_HAS_NC, &orig->capabilities);
+ else
+- orig->capabilities |= BATADV_ORIG_CAPA_HAS_NC;
++ set_bit(BATADV_ORIG_CAPA_HAS_NC, &orig->capabilities);
+ }
+
+ /**
+@@ -894,7 +895,7 @@ void batadv_nc_update_nc_node(struct bat
+ goto out;
+
+ /* check if orig node is network coding enabled */
+- if (!(orig_node->capabilities & BATADV_ORIG_CAPA_HAS_NC))
++ if (!test_bit(BATADV_ORIG_CAPA_HAS_NC, &orig_node->capabilities))
+ goto out;
+
+ /* accept ogms from 'good' neighbors and single hop neighbors */
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -314,7 +314,7 @@ struct batadv_orig_node {
+ */
+ enum batadv_orig_capabilities {
+ BATADV_ORIG_CAPA_HAS_DAT,
+- BATADV_ORIG_CAPA_HAS_NC = BIT(1),
++ BATADV_ORIG_CAPA_HAS_NC,
+ BATADV_ORIG_CAPA_HAS_TT = BIT(2),
+ BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
+ };
--- /dev/null
+From ac4eebd48461ec993e7cb614d5afe7df8c72e6b7 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:24 +0200
+Subject: batman-adv: Make TT 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 ac4eebd48461ec993e7cb614d5afe7df8c72e6b7 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: e17931d1a61d ("batman-adv: introduce capability initialization bitfield")
+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/translation-table.c | 8 +++++---
+ net/batman-adv/types.h | 4 ++--
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -19,6 +19,7 @@
+ #include "main.h"
+
+ #include <linux/atomic.h>
++#include <linux/bitops.h>
+ #include <linux/bug.h>
+ #include <linux/byteorder/generic.h>
+ #include <linux/compiler.h>
+@@ -1882,7 +1883,7 @@ void batadv_tt_global_del_orig(struct ba
+ }
+ spin_unlock_bh(list_lock);
+ }
+- orig_node->capa_initialized &= ~BATADV_ORIG_CAPA_HAS_TT;
++ clear_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
+ }
+
+ static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
+@@ -2841,7 +2842,7 @@ static void _batadv_tt_update_changes(st
+ return;
+ }
+ }
+- orig_node->capa_initialized |= BATADV_ORIG_CAPA_HAS_TT;
++ set_bit(BATADV_ORIG_CAPA_HAS_TT, &orig_node->capa_initialized);
+ }
+
+ static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
+@@ -3343,7 +3344,8 @@ static void batadv_tt_update_orig(struct
+ bool has_tt_init;
+
+ tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
+- has_tt_init = orig_node->capa_initialized & BATADV_ORIG_CAPA_HAS_TT;
++ has_tt_init = test_bit(BATADV_ORIG_CAPA_HAS_TT,
++ &orig_node->capa_initialized);
+
+ /* orig table not initialised AND first diff is in the OGM OR the ttvn
+ * increased by one -> we can apply the attached changes
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -274,7 +274,7 @@ struct batadv_orig_node {
+ struct hlist_node mcast_want_all_ipv6_node;
+ #endif
+ unsigned long capabilities;
+- uint8_t capa_initialized;
++ unsigned long capa_initialized;
+ atomic_t last_ttvn;
+ unsigned char *tt_buff;
+ int16_t tt_buff_len;
+@@ -315,7 +315,7 @@ struct batadv_orig_node {
+ enum batadv_orig_capabilities {
+ BATADV_ORIG_CAPA_HAS_DAT,
+ BATADV_ORIG_CAPA_HAS_NC,
+- BATADV_ORIG_CAPA_HAS_TT = BIT(2),
++ BATADV_ORIG_CAPA_HAS_TT,
+ BATADV_ORIG_CAPA_HAS_MCAST = BIT(3),
+ };
+
--- /dev/null
+From 2110d70c5e58326a10e93cfefdc0b3686e2ada12 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Sat, 8 Aug 2015 10:46:02 +0200
+Subject: cpu/cacheinfo: Fix teardown path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Borislav Petkov <bp@suse.de>
+
+commit 2110d70c5e58326a10e93cfefdc0b3686e2ada12 upstream.
+
+Philip Müller reported a hang when booting 32-bit 4.1 kernel on an AMD
+box. A fragment of the splat was enough to pinpoint the issue:
+
+ task: f58e0000 ti: f58e8000 task.ti: f58e800
+ EIP: 0060:[<c135a903>] EFLAGS: 00010206 CPU: 0
+ EIP is at free_cache_attributes+0x83/0xd0
+ EAX: 00000001 EBX: f589d46c ECX: 00000090 EDX: 360c2000
+ ESI: 00000000 EDI: c1724a80 EBP: f58e9ec0 ESP: f58e9ea0
+ DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
+ CR0: 8005003b CR2: 000000ac CR3: 01731000 CR4: 000006d0
+
+cache_shared_cpu_map_setup() did check sibling CPUs cacheinfo descriptor
+while the respective teardown path cache_shared_cpu_map_remove() didn't.
+Fix that.
+
+>From tglx's version: to be on the safe side, move the cacheinfo
+descriptor check to free_cache_attributes(), thus cleaning up the
+hotplug path a little and making this even more robust.
+
+Reported-and-tested-by: Philip Müller <philm@manjaro.org>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Cc: Andre Przywara <andre.przywara@arm.com>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: linux-kernel@vger.kernel.org
+Cc: manjaro-dev@manjaro.org
+Cc: Philip Müller <philm@manjaro.org>
+Link: https://lkml.kernel.org/r/55B47BB8.6080202@manjaro.org
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/cacheinfo.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/cacheinfo.c
++++ b/drivers/base/cacheinfo.c
+@@ -148,7 +148,11 @@ static void cache_shared_cpu_map_remove(
+
+ if (sibling == cpu) /* skip itself */
+ continue;
++
+ sib_cpu_ci = get_cpu_cacheinfo(sibling);
++ if (!sib_cpu_ci->info_list)
++ continue;
++
+ sib_leaf = sib_cpu_ci->info_list + index;
+ cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map);
+ cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map);
+@@ -159,6 +163,9 @@ static void cache_shared_cpu_map_remove(
+
+ static void free_cache_attributes(unsigned int cpu)
+ {
++ if (!per_cpu_cacheinfo(cpu))
++ return;
++
+ cache_shared_cpu_map_remove(cpu);
+
+ kfree(per_cpu_cacheinfo(cpu));
+@@ -514,8 +521,7 @@ static int cacheinfo_cpu_callback(struct
+ break;
+ case CPU_DEAD:
+ cache_remove_dev(cpu);
+- if (per_cpu_cacheinfo(cpu))
+- free_cache_attributes(cpu);
++ free_cache_attributes(cpu);
+ break;
+ }
+ return notifier_from_errno(rc);
--- /dev/null
+From a2022001cebd0825b96aa0f3345ea3ad44ae79d4 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 2 Sep 2015 14:36:50 +0530
+Subject: cpufreq: dt: Tolerance applies on both sides of target voltage
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+commit a2022001cebd0825b96aa0f3345ea3ad44ae79d4 upstream.
+
+Tolerance applies on both sides of the target voltage, i.e. both min and
+max sides. But while checking if a voltage is supported by the regulator
+or not, we haven't taken care of tolerance on the lower side. Fix that.
+
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Fixes: 045ee45c4ff2 ("cpufreq: cpufreq-dt: disable unsupported OPPs")
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/cpufreq-dt.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -255,7 +255,8 @@ static int cpufreq_init(struct cpufreq_p
+ rcu_read_unlock();
+
+ tol_uV = opp_uV * priv->voltage_tolerance / 100;
+- if (regulator_is_supported_voltage(cpu_reg, opp_uV,
++ if (regulator_is_supported_voltage(cpu_reg,
++ opp_uV - tol_uV,
+ opp_uV + tol_uV)) {
+ if (opp_uV < min_uV)
+ min_uV = opp_uV;
--- /dev/null
+From cfcd2271a9076a9891014bc8e18d4fd48acccffe Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Fri, 18 Sep 2015 17:25:36 +0200
+Subject: crypto: marvell - properly handle CRYPTO_TFM_REQ_MAY_BACKLOG-flagged requests
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit cfcd2271a9076a9891014bc8e18d4fd48acccffe upstream.
+
+The mv_cesa_queue_req() function calls crypto_enqueue_request() to
+enqueue a request. In the normal case (i.e the queue isn't full), this
+function returns -EINPROGRESS. The current Marvell CESA crypto driver
+takes this into account and cleans up the request only if an error
+occured, i.e if the return value is not -EINPROGRESS.
+
+Unfortunately this causes problems with
+CRYPTO_TFM_REQ_MAY_BACKLOG-flagged requests. When such a request is
+passed to crypto_enqueue_request() and the queue is full,
+crypto_enqueue_request() will return -EBUSY, but will keep the request
+enqueued nonetheless. This situation was not properly handled by the
+Marvell CESA driver, which was anyway cleaning up the request in such
+a situation. When later on the request was taken out of the backlog
+and actually processed, a kernel crash occured due to the internal
+driver data structures for this structure having been cleaned up.
+
+To avoid this situation, this commit adds a
+mv_cesa_req_needs_cleanup() helper function which indicates if the
+request needs to be cleaned up or not after a call to
+crypto_enqueue_request(). This helper allows to do the cleanup only in
+the appropriate cases, and all call sites of mv_cesa_queue_req() are
+fixed to use this new helper function.
+
+Reported-by: Vincent Donnefort <vdonnefort@gmail.com>
+Fixes: db509a45339fd ("crypto: marvell/cesa - add TDMA support")
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Tested-by: Vincent Donnefort <vdonnefort@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/marvell/cesa.h | 27 +++++++++++++++++++++++++++
+ drivers/crypto/marvell/cipher.c | 7 +++----
+ drivers/crypto/marvell/hash.c | 8 +++-----
+ 3 files changed, 33 insertions(+), 9 deletions(-)
+
+--- a/drivers/crypto/marvell/cesa.h
++++ b/drivers/crypto/marvell/cesa.h
+@@ -687,6 +687,33 @@ static inline u32 mv_cesa_get_int_mask(s
+
+ int mv_cesa_queue_req(struct crypto_async_request *req);
+
++/*
++ * Helper function that indicates whether a crypto request needs to be
++ * cleaned up or not after being enqueued using mv_cesa_queue_req().
++ */
++static inline int mv_cesa_req_needs_cleanup(struct crypto_async_request *req,
++ int ret)
++{
++ /*
++ * The queue still had some space, the request was queued
++ * normally, so there's no need to clean it up.
++ */
++ if (ret == -EINPROGRESS)
++ return false;
++
++ /*
++ * The queue had not space left, but since the request is
++ * flagged with CRYPTO_TFM_REQ_MAY_BACKLOG, it was added to
++ * the backlog and will be processed later. There's no need to
++ * clean it up.
++ */
++ if (ret == -EBUSY && req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
++ return false;
++
++ /* Request wasn't queued, we need to clean it up */
++ return true;
++}
++
+ /* TDMA functions */
+
+ static inline void mv_cesa_req_dma_iter_init(struct mv_cesa_dma_iter *iter,
+--- a/drivers/crypto/marvell/cipher.c
++++ b/drivers/crypto/marvell/cipher.c
+@@ -189,7 +189,6 @@ static inline void mv_cesa_ablkcipher_pr
+ {
+ struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req);
+ struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq);
+-
+ creq->req.base.engine = engine;
+
+ if (creq->req.base.type == CESA_DMA_REQ)
+@@ -431,7 +430,7 @@ static int mv_cesa_des_op(struct ablkcip
+ return ret;
+
+ ret = mv_cesa_queue_req(&req->base);
+- if (ret && ret != -EINPROGRESS)
++ if (mv_cesa_req_needs_cleanup(&req->base, ret))
+ mv_cesa_ablkcipher_cleanup(req);
+
+ return ret;
+@@ -551,7 +550,7 @@ static int mv_cesa_des3_op(struct ablkci
+ return ret;
+
+ ret = mv_cesa_queue_req(&req->base);
+- if (ret && ret != -EINPROGRESS)
++ if (mv_cesa_req_needs_cleanup(&req->base, ret))
+ mv_cesa_ablkcipher_cleanup(req);
+
+ return ret;
+@@ -693,7 +692,7 @@ static int mv_cesa_aes_op(struct ablkcip
+ return ret;
+
+ ret = mv_cesa_queue_req(&req->base);
+- if (ret && ret != -EINPROGRESS)
++ if (mv_cesa_req_needs_cleanup(&req->base, ret))
+ mv_cesa_ablkcipher_cleanup(req);
+
+ return ret;
+--- a/drivers/crypto/marvell/hash.c
++++ b/drivers/crypto/marvell/hash.c
+@@ -739,10 +739,8 @@ static int mv_cesa_ahash_update(struct a
+ return 0;
+
+ ret = mv_cesa_queue_req(&req->base);
+- if (ret && ret != -EINPROGRESS) {
++ if (mv_cesa_req_needs_cleanup(&req->base, ret))
+ mv_cesa_ahash_cleanup(req);
+- return ret;
+- }
+
+ return ret;
+ }
+@@ -766,7 +764,7 @@ static int mv_cesa_ahash_final(struct ah
+ return 0;
+
+ ret = mv_cesa_queue_req(&req->base);
+- if (ret && ret != -EINPROGRESS)
++ if (mv_cesa_req_needs_cleanup(&req->base, ret))
+ mv_cesa_ahash_cleanup(req);
+
+ return ret;
+@@ -791,7 +789,7 @@ static int mv_cesa_ahash_finup(struct ah
+ return 0;
+
+ ret = mv_cesa_queue_req(&req->base);
+- if (ret && ret != -EINPROGRESS)
++ if (mv_cesa_req_needs_cleanup(&req->base, ret))
+ mv_cesa_ahash_cleanup(req);
+
+ return ret;
--- /dev/null
+From 88d3426942d748b90b051b7ef2d5d765f5f3054c Mon Sep 17 00:00:00 2001
+From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+Date: Thu, 3 Sep 2015 08:36:35 +0200
+Subject: MIPS: bootmem: Fix mapstart calculation for contiguous maps
+
+From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+
+commit 88d3426942d748b90b051b7ef2d5d765f5f3054c upstream.
+
+Commit a6335fa1 fixed the case with gap between initrd and next usable PFN zone,
+but broken the case when initrd is combined with usable memory into one region
+(in add_memory_region()). Restore the fixup initially brought in by f9a7febd.
+
+---- error message ----
+Unpacking initramfs...
+Initramfs unpacking failed: junk in compressed archive
+BUG: Bad page state in process swapper pfn:00261
+page:81004c20 count:0 mapcount:-127 mapping: (null) index:0x2
+flags: 0x0()
+page dumped because: nonzero mapcount
+CPU: 0 PID: 1 Comm: swapper Not tainted 4.2.0+ #1782
+-----------------------
+
+Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
+Reported-by: Tony Wu <tung7970@gmail.com>
+Tested-by: Tony Wu <tung7970@gmail.com>
+Cc: David Daney <david.daney@cavium.com>
+Cc: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+Cc: Huacai Chen <chenhc@lemote.com>
+Cc: Joe Perches <joe@perches.com>
+Cc: Steven J. Hill <Steven.Hill@imgtec.com>
+Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/11086/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/setup.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -338,7 +338,7 @@ static void __init bootmem_init(void)
+ if (end <= reserved_end)
+ continue;
+ #ifdef CONFIG_BLK_DEV_INITRD
+- /* mapstart should be after initrd_end */
++ /* Skip zones before initrd and initrd itself */
+ if (initrd_end && end <= (unsigned long)PFN_UP(__pa(initrd_end)))
+ continue;
+ #endif
+@@ -371,6 +371,14 @@ static void __init bootmem_init(void)
+ max_low_pfn = PFN_DOWN(HIGHMEM_START);
+ }
+
++#ifdef CONFIG_BLK_DEV_INITRD
++ /*
++ * mapstart should be after initrd_end
++ */
++ if (initrd_end)
++ mapstart = max(mapstart, (unsigned long)PFN_UP(__pa(initrd_end)));
++#endif
++
+ /*
+ * Initialize the boot-time allocator with low memory only.
+ */
--- /dev/null
+From faa9724a674e5e52316bb0d173aed16bd17d536c Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sat, 5 Sep 2015 18:46:56 +0200
+Subject: MIPS: BPF: Avoid unreachable code on little endian
+
+From: Aurelien Jarno <aurelien@aurel32.net>
+
+commit faa9724a674e5e52316bb0d173aed16bd17d536c upstream.
+
+On little endian, avoid generating the big endian version of the code
+by using #else in addition to #ifdef #endif. Also fix one alignment
+issue wrt delay slot.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+Reviewed-by: Markos Chandras <markos.chandras@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/11097/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/net/bpf_jit_asm.S | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/net/bpf_jit_asm.S
++++ b/arch/mips/net/bpf_jit_asm.S
+@@ -151,9 +151,10 @@ NESTED(bpf_slow_path_word, (6 * SZREG),
+ wsbh t0, $r_s0
+ jr $r_ra
+ rotr $r_A, t0, 16
+-#endif
++#else
+ jr $r_ra
+- move $r_A, $r_s0
++ move $r_A, $r_s0
++#endif
+
+ END(bpf_slow_path_word)
+
+@@ -162,9 +163,10 @@ NESTED(bpf_slow_path_half, (6 * SZREG),
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
+ jr $r_ra
+ wsbh $r_A, $r_s0
+-#endif
++#else
+ jr $r_ra
+ move $r_A, $r_s0
++#endif
+
+ END(bpf_slow_path_half)
+
--- /dev/null
+From b259e51f2e29390518021f9b8df55a3de42f371b Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sat, 5 Sep 2015 18:46:57 +0200
+Subject: MIPS: BPF: Fix build on pre-R2 little endian CPUs
+
+From: Aurelien Jarno <aurelien@aurel32.net>
+
+commit b259e51f2e29390518021f9b8df55a3de42f371b upstream.
+
+The rotr, seh and wsbh instructions have been introduced with the R2
+ISA. Thus the current BPF code fails to build on pre-R2 little endian
+CPUs:
+
+ CC arch/mips/net/bpf_jit.o
+ AS arch/mips/net/bpf_jit_asm.o
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S: Assembler messages:
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:67: Error: opcode not supported on this processor: mips32 (mips32) `wsbh $8,$19'
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:68: Error: opcode not supported on this processor: mips32 (mips32) `rotr $19,$8,16'
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:83: Error: opcode not supported on this processor: mips32 (mips32) `wsbh $8,$19'
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:84: Error: opcode not supported on this processor: mips32 (mips32) `seh $19,$8'
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:151: Error: opcode not supported on this processor: mips32 (mips32) `wsbh $8,$12'
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:153: Error: opcode not supported on this processor: mips32 (mips32) `rotr $19,$8,16'
+ /home/aurel32/linux-4.2/arch/mips/net/bpf_jit_asm.S:164: Error: opcode not supported on this processor: mips32 (mips32) `wsbh $19,$12'
+ /home/aurel32/linux-4.2/scripts/Makefile.build:294: recipe for target 'arch/mips/net/bpf_jit_asm.o' failed
+
+Fix that by providing equivalent code for these CPUs.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+Reviewed-by: Markos Chandras <markos.chandras@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/11098/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/net/bpf_jit_asm.S | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+--- a/arch/mips/net/bpf_jit_asm.S
++++ b/arch/mips/net/bpf_jit_asm.S
+@@ -64,8 +64,20 @@ sk_load_word_positive:
+ PTR_ADDU t1, $r_skb_data, offset
+ lw $r_A, 0(t1)
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
++# if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+ wsbh t0, $r_A
+ rotr $r_A, t0, 16
++# else
++ sll t0, $r_A, 24
++ srl t1, $r_A, 24
++ srl t2, $r_A, 8
++ or t0, t0, t1
++ andi t2, t2, 0xff00
++ andi t1, $r_A, 0xff00
++ or t0, t0, t2
++ sll t1, t1, 8
++ or $r_A, t0, t1
++# endif
+ #endif
+ jr $r_ra
+ move $r_ret, zero
+@@ -80,8 +92,16 @@ sk_load_half_positive:
+ PTR_ADDU t1, $r_skb_data, offset
+ lh $r_A, 0(t1)
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
++# if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+ wsbh t0, $r_A
+ seh $r_A, t0
++# else
++ sll t0, $r_A, 24
++ andi t1, $r_A, 0xff00
++ sra t0, t0, 16
++ srl t1, t1, 8
++ or $r_A, t0, t1
++# endif
+ #endif
+ jr $r_ra
+ move $r_ret, zero
+@@ -148,9 +168,22 @@ sk_load_byte_positive:
+ NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp)
+ bpf_slow_path_common(4)
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
++# if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+ wsbh t0, $r_s0
+ jr $r_ra
+ rotr $r_A, t0, 16
++# else
++ sll t0, $r_s0, 24
++ srl t1, $r_s0, 24
++ srl t2, $r_s0, 8
++ or t0, t0, t1
++ andi t2, t2, 0xff00
++ andi t1, $r_s0, 0xff00
++ or t0, t0, t2
++ sll t1, t1, 8
++ jr $r_ra
++ or $r_A, t0, t1
++# endif
+ #else
+ jr $r_ra
+ move $r_A, $r_s0
+@@ -161,8 +194,17 @@ NESTED(bpf_slow_path_word, (6 * SZREG),
+ NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp)
+ bpf_slow_path_common(2)
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
++# if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+ jr $r_ra
+ wsbh $r_A, $r_s0
++# else
++ sll t0, $r_s0, 8
++ andi t1, $r_s0, 0xff00
++ andi t0, t0, 0xff00
++ srl t1, t1, 8
++ jr $r_ra
++ or $r_A, t0, t1
++# endif
+ #else
+ jr $r_ra
+ move $r_A, $r_s0
--- /dev/null
+From a5b0f6db0e6cf6224e50f6585e9c8f0c2d38a8f8 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Wed, 5 Aug 2015 15:42:37 -0700
+Subject: MIPS: CPS: Don't include MT code in non-MT kernels.
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit a5b0f6db0e6cf6224e50f6585e9c8f0c2d38a8f8 upstream.
+
+The MT-specific code in mips_cps_boot_vpes can safely be omitted from
+kernels which don't support MT, with the default VPE==0 case being used
+as it would be after the has_mt (Config3.MT) check failed at runtime.
+Discarding the code entirely will save us a few bytes & allow cleaner
+handling of MT ASE instructions by later patches.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Cc: Markos Chandras <markos.chandras@imgtec.com>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/10866/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/cps-vec.S | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/mips/kernel/cps-vec.S
++++ b/arch/mips/kernel/cps-vec.S
+@@ -311,6 +311,7 @@ LEAF(mips_cps_boot_vpes)
+
+ /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
+ li t9, 0
++#ifdef CONFIG_MIPS_MT
+ has_mt ta2, 1f
+
+ /* Find the number of VPEs present in the core */
+@@ -330,6 +331,7 @@ LEAF(mips_cps_boot_vpes)
+ /* Retrieve the VPE ID from EBase.CPUNum */
+ mfc0 t9, $15, 1
+ and t9, t9, t1
++#endif
+
+ 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */
+ li t1, VPEBOOTCFG_SIZE
--- /dev/null
+From 7a63076d9a31a6c2073da45021eeb4f89d2a8b56 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Wed, 5 Aug 2015 15:42:38 -0700
+Subject: MIPS: CPS: #ifdef on CONFIG_MIPS_MT_SMP rather than CONFIG_MIPS_MT
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit 7a63076d9a31a6c2073da45021eeb4f89d2a8b56 upstream.
+
+The CONFIG_MIPS_MT symbol can be selected by CONFIG_MIPS_VPE_LOADER in
+addition to CONFIG_MIPS_MT_SMP. We only want MT code in the CPS SMP boot
+vector if we're using MT for SMP. Thus switch the config symbol we ifdef
+against to CONFIG_MIPS_MT_SMP.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Cc: Markos Chandras <markos.chandras@imgtec.com>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/10867/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/cps-vec.S | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/mips/kernel/cps-vec.S
++++ b/arch/mips/kernel/cps-vec.S
+@@ -224,7 +224,7 @@ LEAF(excep_ejtag)
+ END(excep_ejtag)
+
+ LEAF(mips_cps_core_init)
+-#ifdef CONFIG_MIPS_MT
++#ifdef CONFIG_MIPS_MT_SMP
+ /* Check that the core implements the MT ASE */
+ has_mt t0, 3f
+
+@@ -311,7 +311,7 @@ LEAF(mips_cps_boot_vpes)
+
+ /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
+ li t9, 0
+-#ifdef CONFIG_MIPS_MT
++#ifdef CONFIG_MIPS_MT_SMP
+ has_mt ta2, 1f
+
+ /* Find the number of VPEs present in the core */
+@@ -339,7 +339,7 @@ LEAF(mips_cps_boot_vpes)
+ PTR_L ta3, COREBOOTCFG_VPECONFIG(t0)
+ PTR_ADDU v0, v0, ta3
+
+-#ifdef CONFIG_MIPS_MT
++#ifdef CONFIG_MIPS_MT_SMP
+
+ /* If the core doesn't support MT then return */
+ bnez ta2, 1f
+@@ -453,7 +453,7 @@ LEAF(mips_cps_boot_vpes)
+
+ 2: .set pop
+
+-#endif /* CONFIG_MIPS_MT */
++#endif /* CONFIG_MIPS_MT_SMP */
+
+ /* Return */
+ jr ra
--- /dev/null
+From 1e5fb282f8eda889776ee83f9214d5df9edaa26d Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Wed, 5 Aug 2015 15:42:36 -0700
+Subject: MIPS: CPS: Stop dangling delay slot from has_mt.
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit 1e5fb282f8eda889776ee83f9214d5df9edaa26d upstream.
+
+The has_mt macro ended with a branch, leaving its callers with a delay
+slot that would be executed if Config3.MT is not set. However it would
+not be executed if Config3 (or earlier Config registers) don't exist
+which makes it somewhat inconsistent at best. Fill the delay slot in the
+macro & fix the mips_cps_boot_vpes caller appropriately.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Cc: Markos Chandras <markos.chandras@imgtec.com>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/10865/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/cps-vec.S | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/kernel/cps-vec.S
++++ b/arch/mips/kernel/cps-vec.S
+@@ -39,6 +39,7 @@
+ mfc0 \dest, CP0_CONFIG, 3
+ andi \dest, \dest, MIPS_CONF3_MT
+ beqz \dest, \nomt
++ nop
+ .endm
+
+ .section .text.cps-vec
+@@ -226,7 +227,6 @@ LEAF(mips_cps_core_init)
+ #ifdef CONFIG_MIPS_MT
+ /* Check that the core implements the MT ASE */
+ has_mt t0, 3f
+- nop
+
+ .set push
+ .set mips64r2
+@@ -310,8 +310,8 @@ LEAF(mips_cps_boot_vpes)
+ PTR_ADDU t0, t0, t1
+
+ /* Calculate this VPEs ID. If the core doesn't support MT use 0 */
++ li t9, 0
+ has_mt ta2, 1f
+- li t9, 0
+
+ /* Find the number of VPEs present in the core */
+ mfc0 t1, CP0_MVPCONF0
--- /dev/null
+From 53960059d56ecef67d4ddd546731623641a3d2d1 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 27 Mar 2015 08:33:43 +0000
+Subject: MIPS: dma-default: Fix 32-bit fall back to GFP_DMA
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 53960059d56ecef67d4ddd546731623641a3d2d1 upstream.
+
+If there is a DMA zone (usually 24bit = 16MB I believe), but no DMA32
+zone, as is the case for some 32-bit kernels, then massage_gfp_flags()
+will cause DMA memory allocated for devices with a 32..63-bit
+coherent_dma_mask to fall back to using __GFP_DMA, even though there may
+only be 32-bits of physical address available anyway.
+
+Correct that case to compare against a mask the size of phys_addr_t
+instead of always using a 64-bit mask.
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Fixes: a2e715a86c6d ("MIPS: DMA: Fix computation of DMA flags from device's coherent_dma_mask.")
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/9610/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/mm/dma-default.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/mm/dma-default.c
++++ b/arch/mips/mm/dma-default.c
+@@ -100,7 +100,7 @@ static gfp_t massage_gfp_flags(const str
+ else
+ #endif
+ #if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32)
+- if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
++ if (dev->coherent_dma_mask < DMA_BIT_MASK(sizeof(phys_addr_t) * 8))
+ dma_flag = __GFP_DMA;
+ else
+ #endif
--- /dev/null
+From fc2ca674470bbfe11d72a20a3f19fd3dc43bfca0 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sun, 30 Aug 2015 21:19:58 -0700
+Subject: MIPS: Fix console output for Fulong2e system
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit fc2ca674470bbfe11d72a20a3f19fd3dc43bfca0 upstream.
+
+Commit 3adeb2566b9b ("MIPS: Loongson: Improve LEFI firmware interface")
+made the number of UARTs dynamic if LEFI_FIRMWARE_INTERFACE is configured.
+Unfortunately, it did not initialize the number of UARTs if
+LEFI_FIRMWARE_INTERFACE is not configured. As a result, the Fulong2e
+system has no console.
+
+Fixes: 3adeb2566b9b ("MIPS: Loongson: Improve LEFI firmware interface")
+Acked-by: Huacai Chen <chenhc@lemote.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Markos Chandras <markos.chandras@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/11076/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/loongson64/common/env.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/mips/loongson64/common/env.c
++++ b/arch/mips/loongson64/common/env.c
+@@ -64,6 +64,9 @@ void __init prom_init_env(void)
+ }
+ if (memsize == 0)
+ memsize = 256;
++
++ loongson_sysconf.nr_uarts = 1;
++
+ pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize);
+ #else
+ struct boot_params *boot_p;
--- /dev/null
+From e297c939b745e420ef0b9dc989cb87bda617b399 Mon Sep 17 00:00:00 2001
+From: Paul Mackerras <paulus@ozlabs.org>
+Date: Thu, 10 Sep 2015 14:36:21 +1000
+Subject: powerpc/MSI: Fix race condition in tearing down MSI interrupts
+
+From: Paul Mackerras <paulus@ozlabs.org>
+
+commit e297c939b745e420ef0b9dc989cb87bda617b399 upstream.
+
+This fixes a race which can result in the same virtual IRQ number
+being assigned to two different MSI interrupts. The most visible
+consequence of that is usually a warning and stack trace from the
+sysfs code about an attempt to create a duplicate entry in sysfs.
+
+The race happens when one CPU (say CPU 0) is disposing of an MSI
+while another CPU (say CPU 1) is setting up an MSI. CPU 0 calls
+(for example) pnv_teardown_msi_irqs(), which calls
+msi_bitmap_free_hwirqs() to indicate that the MSI (i.e. its
+hardware IRQ number) is no longer in use. Then, before CPU 0 gets
+to calling irq_dispose_mapping() to free up the virtal IRQ number,
+CPU 1 comes in and calls msi_bitmap_alloc_hwirqs() to allocate an
+MSI, and gets the same hardware IRQ number that CPU 0 just freed.
+CPU 1 then calls irq_create_mapping() to get a virtual IRQ number,
+which sees that there is currently a mapping for that hardware IRQ
+number and returns the corresponding virtual IRQ number (which is
+the same virtual IRQ number that CPU 0 was using). CPU 0 then
+calls irq_dispose_mapping() and frees that virtual IRQ number.
+Now, if another CPU comes along and calls irq_create_mapping(), it
+is likely to get the virtual IRQ number that was just freed,
+resulting in the same virtual IRQ number apparently being used for
+two different hardware interrupts.
+
+To fix this race, we just move the call to msi_bitmap_free_hwirqs()
+to after the call to irq_dispose_mapping(). Since virq_to_hw()
+doesn't work for the virtual IRQ number after irq_dispose_mapping()
+has been called, we need to call it before irq_dispose_mapping() and
+remember the result for the msi_bitmap_free_hwirqs() call.
+
+The pattern of calling msi_bitmap_free_hwirqs() before
+irq_dispose_mapping() appears in 5 places under arch/powerpc, and
+appears to have originated in commit 05af7bd2d75e ("[POWERPC] MPIC
+U3/U4 MSI backend") from 2007.
+
+Fixes: 05af7bd2d75e ("[POWERPC] MPIC U3/U4 MSI backend")
+Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ arch/powerpc/platforms/pasemi/msi.c | 5 +++--
+ arch/powerpc/platforms/powernv/pci.c | 5 +++--
+ arch/powerpc/sysdev/fsl_msi.c | 5 +++--
+ arch/powerpc/sysdev/mpic_u3msi.c | 5 +++--
+ arch/powerpc/sysdev/ppc4xx_msi.c | 5 +++--
+ 5 files changed, 15 insertions(+), 10 deletions(-)
+
+--- a/arch/powerpc/platforms/pasemi/msi.c
++++ b/arch/powerpc/platforms/pasemi/msi.c
+@@ -63,6 +63,7 @@ static struct irq_chip mpic_pasemi_msi_c
+ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
+ {
+ struct msi_desc *entry;
++ irq_hw_number_t hwirq;
+
+ pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);
+
+@@ -70,10 +71,10 @@ static void pasemi_msi_teardown_msi_irqs
+ if (entry->irq == NO_IRQ)
+ continue;
+
++ hwirq = virq_to_hw(entry->irq);
+ irq_set_msi_desc(entry->irq, NULL);
+- msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
+- virq_to_hw(entry->irq), ALLOC_CHUNK);
+ irq_dispose_mapping(entry->irq);
++ msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, ALLOC_CHUNK);
+ }
+
+ return;
+--- a/arch/powerpc/platforms/powernv/pci.c
++++ b/arch/powerpc/platforms/powernv/pci.c
+@@ -99,6 +99,7 @@ void pnv_teardown_msi_irqs(struct pci_de
+ struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+ struct pnv_phb *phb = hose->private_data;
+ struct msi_desc *entry;
++ irq_hw_number_t hwirq;
+
+ if (WARN_ON(!phb))
+ return;
+@@ -106,10 +107,10 @@ void pnv_teardown_msi_irqs(struct pci_de
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
++ hwirq = virq_to_hw(entry->irq);
+ irq_set_msi_desc(entry->irq, NULL);
+- msi_bitmap_free_hwirqs(&phb->msi_bmp,
+- virq_to_hw(entry->irq) - phb->msi_base, 1);
+ irq_dispose_mapping(entry->irq);
++ msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq - phb->msi_base, 1);
+ }
+ }
+ #endif /* CONFIG_PCI_MSI */
+--- a/arch/powerpc/sysdev/fsl_msi.c
++++ b/arch/powerpc/sysdev/fsl_msi.c
+@@ -128,15 +128,16 @@ static void fsl_teardown_msi_irqs(struct
+ {
+ struct msi_desc *entry;
+ struct fsl_msi *msi_data;
++ irq_hw_number_t hwirq;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
++ hwirq = virq_to_hw(entry->irq);
+ msi_data = irq_get_chip_data(entry->irq);
+ irq_set_msi_desc(entry->irq, NULL);
+- msi_bitmap_free_hwirqs(&msi_data->bitmap,
+- virq_to_hw(entry->irq), 1);
+ irq_dispose_mapping(entry->irq);
++ msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
+ }
+
+ return;
+--- a/arch/powerpc/sysdev/mpic_u3msi.c
++++ b/arch/powerpc/sysdev/mpic_u3msi.c
+@@ -107,15 +107,16 @@ static u64 find_u4_magic_addr(struct pci
+ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
+ {
+ struct msi_desc *entry;
++ irq_hw_number_t hwirq;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
+
++ hwirq = virq_to_hw(entry->irq);
+ irq_set_msi_desc(entry->irq, NULL);
+- msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
+- virq_to_hw(entry->irq), 1);
+ irq_dispose_mapping(entry->irq);
++ msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq, 1);
+ }
+
+ return;
+--- a/arch/powerpc/sysdev/ppc4xx_msi.c
++++ b/arch/powerpc/sysdev/ppc4xx_msi.c
+@@ -124,16 +124,17 @@ void ppc4xx_teardown_msi_irqs(struct pci
+ {
+ struct msi_desc *entry;
+ struct ppc4xx_msi *msi_data = &ppc4xx_msi;
++ irq_hw_number_t hwirq;
+
+ dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");
+
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
++ hwirq = virq_to_hw(entry->irq);
+ irq_set_msi_desc(entry->irq, NULL);
+- msi_bitmap_free_hwirqs(&msi_data->bitmap,
+- virq_to_hw(entry->irq), 1);
+ irq_dispose_mapping(entry->irq);
++ msi_bitmap_free_hwirqs(&msi_data->bitmap, hwirq, 1);
+ }
+ }
+
regmap-debugfs-ensure-we-don-t-underflow-when-printing-access-masks.patch
regmap-debugfs-don-t-bother-actually-printing-when-calculating-max-length.patch
security-fix-typo-in-security_task_prctl.patch
+usb-musb-dsps-fix-polling-in-device-only-mode.patch
+usb-chipidea-udc-using-the-correct-stall-implementation.patch
+usb-use-the-usb_ss_mult-macro-to-get-the-burst-multiplier.patch
+usb-phy-phy-generic-fix-reset-behaviour-on-legacy-boot.patch
+usb-musb-cppi41-allow-it-to-work-again.patch
+usb-chaoskey-read-offset-bug.patch
+usb-add-device-quirk-for-logitech-ptz-cameras.patch
+usb-add-reset-resume-quirk-for-two-plantronics-usb-headphones.patch
+crypto-marvell-properly-handle-crypto_tfm_req_may_backlog-flagged-requests.patch
+cpu-cacheinfo-fix-teardown-path.patch
+cpufreq-dt-tolerance-applies-on-both-sides-of-target-voltage.patch
+mips-fix-console-output-for-fulong2e-system.patch
+mips-bootmem-fix-mapstart-calculation-for-contiguous-maps.patch
+mips-bpf-avoid-unreachable-code-on-little-endian.patch
+mips-bpf-fix-build-on-pre-r2-little-endian-cpus.patch
+mips-dma-default-fix-32-bit-fall-back-to-gfp_dma.patch
+mips-cps-stop-dangling-delay-slot-from-has_mt.patch
+mips-cps-don-t-include-mt-code-in-non-mt-kernels.patch
+mips-cps-ifdef-on-config_mips_mt_smp-rather-than-config_mips_mt.patch
+batman-adv-make-nc-capability-changes-atomic.patch
+batman-adv-make-tt-capability-changes-atomic.patch
+batman-adv-make-mcast-capability-changes-atomic.patch
+batman-adv-fix-potential-synchronization-issues-in-mcast-tvlv-handler.patch
+batman-adv-fix-potentially-broken-skb-network-header-access.patch
+tools-lib-traceevent-fix-string-handling-in-heterogeneous-arch-environments.patch
+powerpc-msi-fix-race-condition-in-tearing-down-msi-interrupts.patch
--- /dev/null
+From c2e4b24ff848bb180f9b9cd873a38327cd219ad2 Mon Sep 17 00:00:00 2001
+From: Kapileshwar Singh <kapileshwar.singh@arm.com>
+Date: Tue, 22 Sep 2015 14:22:03 +0100
+Subject: tools lib traceevent: Fix string handling in heterogeneous arch environments
+
+From: Kapileshwar Singh <kapileshwar.singh@arm.com>
+
+commit c2e4b24ff848bb180f9b9cd873a38327cd219ad2 upstream.
+
+When a trace recorded on a 32-bit device is processed with a 64-bit
+binary, the higher 32-bits of the address need to ignored.
+
+The lack of this results in the output of the 64-bit pointer
+value to the trace as the 32-bit address lookup fails in find_printk().
+
+Before:
+
+ burn-1778 [003] 548.600305: bputs: 0xc0046db2s: 2cec5c058d98c
+
+After:
+
+ burn-1778 [003] 548.600305: bputs: 0xc0046db2s: RT throttling activated
+
+The problem occurs in PRINT_FIELD when the field is recognized as a
+pointer to a string (of the type const char *)
+
+Heterogeneous architectures cases below can arise and should be handled:
+
+* Traces recorded using 32-bit addresses processed on a 64-bit machine
+* Traces recorded using 64-bit addresses processed on a 32-bit machine
+
+Reported-by: Juri Lelli <juri.lelli@arm.com>
+Signed-off-by: Kapileshwar Singh <kapileshwar.singh@arm.com>
+Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Javi Merino <javi.merino@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: http://lkml.kernel.org/r/1442928123-13824-1-git-send-email-kapileshwar.singh@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/lib/traceevent/event-parse.c | 23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+--- a/tools/lib/traceevent/event-parse.c
++++ b/tools/lib/traceevent/event-parse.c
+@@ -3721,7 +3721,7 @@ static void print_str_arg(struct trace_s
+ struct format_field *field;
+ struct printk_map *printk;
+ long long val, fval;
+- unsigned long addr;
++ unsigned long long addr;
+ char *str;
+ unsigned char *hex;
+ int print;
+@@ -3754,13 +3754,30 @@ static void print_str_arg(struct trace_s
+ */
+ if (!(field->flags & FIELD_IS_ARRAY) &&
+ field->size == pevent->long_size) {
+- addr = *(unsigned long *)(data + field->offset);
++
++ /* Handle heterogeneous recording and processing
++ * architectures
++ *
++ * CASE I:
++ * Traces recorded on 32-bit devices (32-bit
++ * addressing) and processed on 64-bit devices:
++ * In this case, only 32 bits should be read.
++ *
++ * CASE II:
++ * Traces recorded on 64 bit devices and processed
++ * on 32-bit devices:
++ * In this case, 64 bits must be read.
++ */
++ addr = (pevent->long_size == 8) ?
++ *(unsigned long long *)(data + field->offset) :
++ (unsigned long long)*(unsigned int *)(data + field->offset);
++
+ /* Check if it matches a print format */
+ printk = find_printk(pevent, addr);
+ if (printk)
+ trace_seq_puts(s, printk->printk);
+ else
+- trace_seq_printf(s, "%lx", addr);
++ trace_seq_printf(s, "%llx", addr);
+ break;
+ }
+ str = malloc(len + 1);
--- /dev/null
+From 72194739f54607bbf8cfded159627a2015381557 Mon Sep 17 00:00:00 2001
+From: Vincent Palatin <vpalatin@chromium.org>
+Date: Thu, 1 Oct 2015 14:10:22 -0700
+Subject: usb: Add device quirk for Logitech PTZ cameras
+
+From: Vincent Palatin <vpalatin@chromium.org>
+
+commit 72194739f54607bbf8cfded159627a2015381557 upstream.
+
+Add a device quirk for the Logitech PTZ Pro Camera and its sibling the
+ConferenceCam CC3000e Camera.
+This fixes the failed camera enumeration on some boot, particularly on
+machines with fast CPU.
+
+Tested by connecting a Logitech PTZ Pro Camera to a machine with a
+Haswell Core i7-4600U CPU @ 2.10GHz, and doing thousands of reboot cycles
+while recording the kernel logs and taking camera picture after each boot.
+Before the patch, more than 7% of the boots show some enumeration transfer
+failures and in a few of them, the kernel is giving up before actually
+enumerating the webcam. After the patch, the enumeration has been correct
+on every reboot.
+
+Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -54,6 +54,13 @@ static const struct usb_device_id usb_qu
+ { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
+ { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
+
++ /* Logitech ConferenceCam CC3000e */
++ { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT },
++ { USB_DEVICE(0x046d, 0x0848), .driver_info = USB_QUIRK_DELAY_INIT },
++
++ /* Logitech PTZ Pro Camera */
++ { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
++
+ /* Logitech Quickcam Fusion */
+ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
+
--- /dev/null
+From 8484bf2981b3d006426ac052a3642c9ce1d8d980 Mon Sep 17 00:00:00 2001
+From: Yao-Wen Mao <yaowen@google.com>
+Date: Mon, 31 Aug 2015 14:24:09 +0800
+Subject: USB: Add reset-resume quirk for two Plantronics usb headphones.
+
+From: Yao-Wen Mao <yaowen@google.com>
+
+commit 8484bf2981b3d006426ac052a3642c9ce1d8d980 upstream.
+
+These two headphones need a reset-resume quirk to properly resume to
+original volume level.
+
+Signed-off-by: Yao-Wen Mao <yaowen@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -85,6 +85,12 @@ static const struct usb_device_id usb_qu
+ /* Philips PSC805 audio device */
+ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+
++ /* Plantronic Audio 655 DSP */
++ { USB_DEVICE(0x047f, 0xc008), .driver_info = USB_QUIRK_RESET_RESUME },
++
++ /* Plantronic Audio 648 USB */
++ { USB_DEVICE(0x047f, 0xc013), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ /* Artisman Watchdog Dongle */
+ { USB_DEVICE(0x04b4, 0x0526), .driver_info =
+ USB_QUIRK_CONFIG_INTF_STRINGS },
--- /dev/null
+From 1d5c47f555c5ae050fad22e4a99f88856cae5d05 Mon Sep 17 00:00:00 2001
+From: Alexander Inyukhin <shurick@sectorb.msk.ru>
+Date: Sat, 26 Sep 2015 15:24:21 +0300
+Subject: USB: chaoskey read offset bug
+
+From: Alexander Inyukhin <shurick@sectorb.msk.ru>
+
+commit 1d5c47f555c5ae050fad22e4a99f88856cae5d05 upstream.
+
+Rng reads in chaoskey driver could return the same data under
+the certain conditions.
+
+Signed-off-by: Alexander Inyukhin <shurick@sectorb.msk.ru>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/chaoskey.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -472,7 +472,7 @@ static int chaoskey_rng_read(struct hwrn
+ if (this_time > max)
+ this_time = max;
+
+- memcpy(data, dev->buf, this_time);
++ memcpy(data, dev->buf + dev->used, this_time);
+
+ dev->used += this_time;
+
--- /dev/null
+From 56ffa1d154c7e12af16273f0cdc42690dd05caf5 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@freescale.com>
+Date: Mon, 24 Aug 2015 14:10:07 +0800
+Subject: usb: chipidea: udc: using the correct stall implementation
+
+From: Peter Chen <peter.chen@freescale.com>
+
+commit 56ffa1d154c7e12af16273f0cdc42690dd05caf5 upstream.
+
+According to spec, there are functional and protocol stalls.
+
+For functional stall, it is for bulk and interrupt endpoints,
+below are cases for it:
+- Host sends SET_FEATURE request for Set-Halt, the udc driver
+needs to set stall, and return true unconditionally.
+- The gadget driver may call usb_ep_set_halt to stall certain
+endpoints, if there is a transfer in pending, the udc driver
+should not set stall, and return -EAGAIN accordingly.
+These two kinds of stall need to be cleared by host using CLEAR_FEATURE
+request (Clear-Halt).
+
+For protocol stall, it is for control endpoint, this stall will
+be set if the control request has failed. This stall will be
+cleared by next setup request (hardware will do it).
+
+It fixed usbtest (drivers/usb/misc/usbtest.c) Test 13 "set/clear halt"
+test failure, meanwhile, this change has been verified by
+USB2 CV Compliance Test and MSC Tests.
+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Cc: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Peter Chen <peter.chen@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/udc.c | 84 +++++++++++++++++++++++----------------------
+ 1 file changed, 44 insertions(+), 40 deletions(-)
+
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -656,6 +656,44 @@ __acquires(hwep->lock)
+ return 0;
+ }
+
++static int _ep_set_halt(struct usb_ep *ep, int value, bool check_transfer)
++{
++ struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep);
++ int direction, retval = 0;
++ unsigned long flags;
++
++ if (ep == NULL || hwep->ep.desc == NULL)
++ return -EINVAL;
++
++ if (usb_endpoint_xfer_isoc(hwep->ep.desc))
++ return -EOPNOTSUPP;
++
++ spin_lock_irqsave(hwep->lock, flags);
++
++ if (value && hwep->dir == TX && check_transfer &&
++ !list_empty(&hwep->qh.queue) &&
++ !usb_endpoint_xfer_control(hwep->ep.desc)) {
++ spin_unlock_irqrestore(hwep->lock, flags);
++ return -EAGAIN;
++ }
++
++ direction = hwep->dir;
++ do {
++ retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value);
++
++ if (!value)
++ hwep->wedge = 0;
++
++ if (hwep->type == USB_ENDPOINT_XFER_CONTROL)
++ hwep->dir = (hwep->dir == TX) ? RX : TX;
++
++ } while (hwep->dir != direction);
++
++ spin_unlock_irqrestore(hwep->lock, flags);
++ return retval;
++}
++
++
+ /**
+ * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
+ * @gadget: gadget
+@@ -1051,7 +1089,7 @@ __acquires(ci->lock)
+ num += ci->hw_ep_max / 2;
+
+ spin_unlock(&ci->lock);
+- err = usb_ep_set_halt(&ci->ci_hw_ep[num].ep);
++ err = _ep_set_halt(&ci->ci_hw_ep[num].ep, 1, false);
+ spin_lock(&ci->lock);
+ if (!err)
+ isr_setup_status_phase(ci);
+@@ -1110,8 +1148,8 @@ delegate:
+
+ if (err < 0) {
+ spin_unlock(&ci->lock);
+- if (usb_ep_set_halt(&hwep->ep))
+- dev_err(ci->dev, "error: ep_set_halt\n");
++ if (_ep_set_halt(&hwep->ep, 1, false))
++ dev_err(ci->dev, "error: _ep_set_halt\n");
+ spin_lock(&ci->lock);
+ }
+ }
+@@ -1142,9 +1180,9 @@ __acquires(ci->lock)
+ err = isr_setup_status_phase(ci);
+ if (err < 0) {
+ spin_unlock(&ci->lock);
+- if (usb_ep_set_halt(&hwep->ep))
++ if (_ep_set_halt(&hwep->ep, 1, false))
+ dev_err(ci->dev,
+- "error: ep_set_halt\n");
++ "error: _ep_set_halt\n");
+ spin_lock(&ci->lock);
+ }
+ }
+@@ -1390,41 +1428,7 @@ static int ep_dequeue(struct usb_ep *ep,
+ */
+ static int ep_set_halt(struct usb_ep *ep, int value)
+ {
+- struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep);
+- int direction, retval = 0;
+- unsigned long flags;
+-
+- if (ep == NULL || hwep->ep.desc == NULL)
+- return -EINVAL;
+-
+- if (usb_endpoint_xfer_isoc(hwep->ep.desc))
+- return -EOPNOTSUPP;
+-
+- spin_lock_irqsave(hwep->lock, flags);
+-
+-#ifndef STALL_IN
+- /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
+- if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX &&
+- !list_empty(&hwep->qh.queue)) {
+- spin_unlock_irqrestore(hwep->lock, flags);
+- return -EAGAIN;
+- }
+-#endif
+-
+- direction = hwep->dir;
+- do {
+- retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value);
+-
+- if (!value)
+- hwep->wedge = 0;
+-
+- if (hwep->type == USB_ENDPOINT_XFER_CONTROL)
+- hwep->dir = (hwep->dir == TX) ? RX : TX;
+-
+- } while (hwep->dir != direction);
+-
+- spin_unlock_irqrestore(hwep->lock, flags);
+- return retval;
++ return _ep_set_halt(ep, value, true);
+ }
+
+ /**
--- /dev/null
+From b0a688ddcc5015eb26000c63841db7c46cfb380a Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Thu, 6 Aug 2015 10:51:29 -0500
+Subject: usb: musb: cppi41: allow it to work again
+
+From: Felipe Balbi <balbi@ti.com>
+
+commit b0a688ddcc5015eb26000c63841db7c46cfb380a upstream.
+
+since commit 33c300cb90a6 ("usb: musb: dsps:
+don't fake of_node to musb core") we have been
+preventing CPPI 4.1 from probing due to NULL
+of_node. We can't revert said commit otherwise
+a different regression would show up, so the fix
+is to look for the parent device's (glue layer's)
+of_node instead, since that's the thing which
+is actually described in DTS.
+
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_cppi41.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/musb/musb_cppi41.c
++++ b/drivers/usb/musb/musb_cppi41.c
+@@ -614,7 +614,7 @@ static int cppi41_dma_controller_start(s
+ {
+ struct musb *musb = controller->musb;
+ struct device *dev = musb->controller;
+- struct device_node *np = dev->of_node;
++ struct device_node *np = dev->parent->of_node;
+ struct cppi41_dma_channel *cppi41_channel;
+ int count;
+ int i;
+@@ -664,7 +664,7 @@ static int cppi41_dma_controller_start(s
+ musb_dma->status = MUSB_DMA_STATUS_FREE;
+ musb_dma->max_len = SZ_4M;
+
+- dc = dma_request_slave_channel(dev, str);
++ dc = dma_request_slave_channel(dev->parent, str);
+ if (!dc) {
+ dev_err(dev, "Failed to request %s.\n", str);
+ ret = -EPROBE_DEFER;
+@@ -695,7 +695,7 @@ cppi41_dma_controller_create(struct musb
+ struct cppi41_dma_controller *controller;
+ int ret = 0;
+
+- if (!musb->controller->of_node) {
++ if (!musb->controller->parent->of_node) {
+ dev_err(musb->controller, "Need DT for the DMA engine.\n");
+ return NULL;
+ }
--- /dev/null
+From b8239dcc03afbd0886c1d9b91ba8fee7c6c9a6cb Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Wed, 16 Sep 2015 14:49:28 -0500
+Subject: usb: musb: dsps: fix polling in device-only mode
+
+From: Bin Liu <b-liu@ti.com>
+
+commit b8239dcc03afbd0886c1d9b91ba8fee7c6c9a6cb upstream.
+
+Fix the regression caused by commit ad78c918602 ("usb: musb: dsps: just
+start polling already") which causes polling the ID pin status even in
+device-only mode.
+
+Fixes: ad78c918602c ("usb: musb: dsps: just start polling already")
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_dsps.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/musb/musb_dsps.c
++++ b/drivers/usb/musb/musb_dsps.c
+@@ -225,8 +225,11 @@ static void dsps_musb_enable(struct musb
+
+ dsps_writel(reg_base, wrp->epintr_set, epmask);
+ dsps_writel(reg_base, wrp->coreintr_set, coremask);
+- /* start polling for ID change. */
+- mod_timer(&glue->timer, jiffies + msecs_to_jiffies(wrp->poll_timeout));
++ /* start polling for ID change in dual-role idle mode */
++ if (musb->xceiv->otg->state == OTG_STATE_B_IDLE &&
++ musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
++ mod_timer(&glue->timer, jiffies +
++ msecs_to_jiffies(wrp->poll_timeout));
+ dsps_musb_try_idle(musb, 0);
+ }
+
--- /dev/null
+From 762982db33b23029e98c844611e2e8beeb75bc0d Mon Sep 17 00:00:00 2001
+From: Roger Quadros <rogerq@ti.com>
+Date: Thu, 13 Aug 2015 13:28:42 +0300
+Subject: usb: phy: phy-generic: Fix reset behaviour on legacy boot
+
+From: Roger Quadros <rogerq@ti.com>
+
+commit 762982db33b23029e98c844611e2e8beeb75bc0d upstream.
+
+The gpio-desc migration done in v4.0 caused a regression
+with legacy boots due to reversed reset logic.
+e.g. omap3-beagle USB host breaks on legacy boot.
+
+Request the reset GPIO with GPIOF_ACTIVE_LOW flag so that
+it matches the driver logic and pin behaviour.
+
+Fixes: e9f2cefb0cdc ("usb: phy: generic: migrate to gpio_desc")
+Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
+Signed-off-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/phy/phy-generic.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/phy/phy-generic.c
++++ b/drivers/usb/phy/phy-generic.c
+@@ -230,7 +230,8 @@ int usb_phy_gen_create_phy(struct device
+ clk_rate = pdata->clk_rate;
+ needs_vcc = pdata->needs_vcc;
+ if (gpio_is_valid(pdata->gpio_reset)) {
+- err = devm_gpio_request_one(dev, pdata->gpio_reset, 0,
++ err = devm_gpio_request_one(dev, pdata->gpio_reset,
++ GPIOF_ACTIVE_LOW,
+ dev_name(dev));
+ if (!err)
+ nop->gpiod_reset =
--- /dev/null
+From ff30cbc8da425754e8ab96904db1d295bd034f27 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 21 Sep 2015 17:46:09 +0300
+Subject: usb: Use the USB_SS_MULT() macro to get the burst multiplier.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit ff30cbc8da425754e8ab96904db1d295bd034f27 upstream.
+
+Bits 1:0 of the bmAttributes are used for the burst multiplier.
+The rest of the bits used to be reserved (zero), but USB3.1 takes bit 7
+into use.
+
+Use the existing USB_SS_MULT() macro instead to make sure the mult value
+and hence max packet calculations are correct for USB3.1 devices.
+
+Note that burst multiplier in bmAttributes is zero based and that
+the USB_SS_MULT() macro adds one.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -112,7 +112,7 @@ static void usb_parse_ss_endpoint_compan
+ cfgno, inum, asnum, ep->desc.bEndpointAddress);
+ ep->ss_ep_comp.bmAttributes = 16;
+ } else if (usb_endpoint_xfer_isoc(&ep->desc) &&
+- desc->bmAttributes > 2) {
++ USB_SS_MULT(desc->bmAttributes) > 3) {
+ dev_warn(ddev, "Isoc endpoint has Mult of %d in "
+ "config %d interface %d altsetting %d ep %d: "
+ "setting to 3\n", desc->bmAttributes + 1,
+@@ -121,7 +121,8 @@ static void usb_parse_ss_endpoint_compan
+ }
+
+ if (usb_endpoint_xfer_isoc(&ep->desc))
+- max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) *
++ max_tx = (desc->bMaxBurst + 1) *
++ (USB_SS_MULT(desc->bmAttributes)) *
+ usb_endpoint_maxp(&ep->desc);
+ else if (usb_endpoint_xfer_int(&ep->desc))
+ max_tx = usb_endpoint_maxp(&ep->desc) *