--- /dev/null
+From 12ac1d0f6c3e95732d144ffa65c8b20fbd9aa462 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 5 Sep 2017 10:12:20 +0200
+Subject: genirq: Make sparse_irq_lock protect what it should protect
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 12ac1d0f6c3e95732d144ffa65c8b20fbd9aa462 upstream.
+
+for_each_active_irq() iterates the sparse irq allocation bitmap. The caller
+must hold sparse_irq_lock. Several code pathes expect that an active bit in
+the sparse bitmap also has a valid interrupt descriptor.
+
+Unfortunately that's not true. The (de)allocation is a two step process,
+which holds the sparse_irq_lock only across the queue/remove from the radix
+tree and the set/clear in the allocation bitmap.
+
+If a iteration locks sparse_irq_lock between the two steps, then it might
+see an active bit but the corresponding irq descriptor is NULL. If that is
+dereferenced unconditionally, then the kernel oopses. Of course, all
+iterator sites could be audited and fixed, but....
+
+There is no reason why the sparse_irq_lock needs to be dropped between the
+two steps, in fact the code becomes simpler when the mutex is held across
+both and the semantics become more straight forward, so future problems of
+missing NULL pointer checks in the iteration are avoided and all existing
+sites are fixed in one go.
+
+Expand the lock held sections so both operations are covered and the bitmap
+and the radixtree are in sync.
+
+Fixes: a05a900a51c7 ("genirq: Make sparse_lock a mutex")
+Reported-and-tested-by: Huang Ying <ying.huang@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/irqdesc.c | 24 +++++++-----------------
+ 1 file changed, 7 insertions(+), 17 deletions(-)
+
+--- a/kernel/irq/irqdesc.c
++++ b/kernel/irq/irqdesc.c
+@@ -405,10 +405,8 @@ static void free_desc(unsigned int irq)
+ * The sysfs entry must be serialized against a concurrent
+ * irq_sysfs_init() as well.
+ */
+- mutex_lock(&sparse_irq_lock);
+ kobject_del(&desc->kobj);
+ delete_irq_desc(irq);
+- mutex_unlock(&sparse_irq_lock);
+
+ /*
+ * We free the descriptor, masks and stat fields via RCU. That
+@@ -446,20 +444,15 @@ static int alloc_descs(unsigned int star
+ desc = alloc_desc(start + i, node, flags, mask, owner);
+ if (!desc)
+ goto err;
+- mutex_lock(&sparse_irq_lock);
+ irq_insert_desc(start + i, desc);
+ irq_sysfs_add(start + i, desc);
+- mutex_unlock(&sparse_irq_lock);
+ }
++ bitmap_set(allocated_irqs, start, cnt);
+ return start;
+
+ err:
+ for (i--; i >= 0; i--)
+ free_desc(start + i);
+-
+- mutex_lock(&sparse_irq_lock);
+- bitmap_clear(allocated_irqs, start, cnt);
+- mutex_unlock(&sparse_irq_lock);
+ return -ENOMEM;
+ }
+
+@@ -558,6 +551,7 @@ static inline int alloc_descs(unsigned i
+
+ desc->owner = owner;
+ }
++ bitmap_set(allocated_irqs, start, cnt);
+ return start;
+ }
+
+@@ -653,10 +647,10 @@ void irq_free_descs(unsigned int from, u
+ if (from >= nr_irqs || (from + cnt) > nr_irqs)
+ return;
+
++ mutex_lock(&sparse_irq_lock);
+ for (i = 0; i < cnt; i++)
+ free_desc(from + i);
+
+- mutex_lock(&sparse_irq_lock);
+ bitmap_clear(allocated_irqs, from, cnt);
+ mutex_unlock(&sparse_irq_lock);
+ }
+@@ -703,19 +697,15 @@ __irq_alloc_descs(int irq, unsigned int
+ from, cnt, 0);
+ ret = -EEXIST;
+ if (irq >=0 && start != irq)
+- goto err;
++ goto unlock;
+
+ if (start + cnt > nr_irqs) {
+ ret = irq_expand_nr_irqs(start + cnt);
+ if (ret)
+- goto err;
++ goto unlock;
+ }
+-
+- bitmap_set(allocated_irqs, start, cnt);
+- mutex_unlock(&sparse_irq_lock);
+- return alloc_descs(start, cnt, node, affinity, owner);
+-
+-err:
++ ret = alloc_descs(start, cnt, node, affinity, owner);
++unlock:
+ mutex_unlock(&sparse_irq_lock);
+ return ret;
+ }
--- /dev/null
+From 53168215909281a09d3afc6fb51a9d4f81f74d39 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 22 Jun 2017 12:20:30 +0200
+Subject: mac80211: fix VLAN handling with TXQs
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 53168215909281a09d3afc6fb51a9d4f81f74d39 upstream.
+
+With TXQs, the AP_VLAN interfaces are resolved to their owner AP
+interface when enqueuing the frame, which makes sense since the
+frame really goes out on that as far as the driver is concerned.
+
+However, this introduces a problem: frames to be encrypted with
+a VLAN-specific GTK will now be encrypted with the AP GTK, since
+the information about which virtual interface to use to select
+the key is taken from the TXQ.
+
+Fix this by preserving info->control.vif and using that in the
+dequeue function. This now requires doing the driver-mapping
+in the dequeue as well.
+
+Since there's no way to filter the frames that are sitting on a
+TXQ, drop all frames, which may affect other interfaces, when an
+AP_VLAN is removed.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/mac80211.h | 15 ++-------------
+ net/mac80211/iface.c | 17 +++++++++++++++--
+ net/mac80211/tx.c | 36 +++++++++++++++++++++++++++++-------
+ 3 files changed, 46 insertions(+), 22 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -902,21 +902,10 @@ struct ieee80211_tx_info {
+ unsigned long jiffies;
+ };
+ /* NB: vif can be NULL for injected frames */
+- union {
+- /* NB: vif can be NULL for injected frames */
+- struct ieee80211_vif *vif;
+-
+- /* When packets are enqueued on txq it's easy
+- * to re-construct the vif pointer. There's no
+- * more space in tx_info so it can be used to
+- * store the necessary enqueue time for packet
+- * sojourn time computation.
+- */
+- codel_time_t enqueue_time;
+- };
++ struct ieee80211_vif *vif;
+ struct ieee80211_key_conf *hw_key;
+ u32 flags;
+- /* 4 bytes free */
++ codel_time_t enqueue_time;
+ } control;
+ struct {
+ u64 cookie;
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -791,6 +791,7 @@ static int ieee80211_open(struct net_dev
+ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
+ bool going_down)
+ {
++ struct ieee80211_sub_if_data *txq_sdata = sdata;
+ struct ieee80211_local *local = sdata->local;
+ struct fq *fq = &local->fq;
+ unsigned long flags;
+@@ -931,6 +932,9 @@ static void ieee80211_do_stop(struct iee
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP_VLAN:
++ txq_sdata = container_of(sdata->bss,
++ struct ieee80211_sub_if_data, u.ap);
++
+ mutex_lock(&local->mtx);
+ list_del(&sdata->u.vlan.list);
+ mutex_unlock(&local->mtx);
+@@ -1001,8 +1005,17 @@ static void ieee80211_do_stop(struct iee
+ }
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
+- if (sdata->vif.txq) {
+- struct txq_info *txqi = to_txq_info(sdata->vif.txq);
++ if (txq_sdata->vif.txq) {
++ struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);
++
++ /*
++ * FIXME FIXME
++ *
++ * We really shouldn't purge the *entire* txqi since that
++ * contains frames for the other AP_VLANs (and possibly
++ * the AP itself) as well, but there's no API in FQ now
++ * to be able to filter.
++ */
+
+ spin_lock_bh(&fq->lock);
+ ieee80211_txq_purge(local, txqi);
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1277,11 +1277,6 @@ static void ieee80211_set_skb_enqueue_ti
+ IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
+ }
+
+-static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi)
+-{
+- IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif;
+-}
+-
+ static u32 codel_skb_len_func(const struct sk_buff *skb)
+ {
+ return skb->len;
+@@ -3388,6 +3383,7 @@ struct sk_buff *ieee80211_tx_dequeue(str
+ struct ieee80211_tx_info *info;
+ struct ieee80211_tx_data tx;
+ ieee80211_tx_result r;
++ struct ieee80211_vif *vif;
+
+ spin_lock_bh(&fq->lock);
+
+@@ -3404,8 +3400,6 @@ begin:
+ if (!skb)
+ goto out;
+
+- ieee80211_set_skb_vif(skb, txqi);
+-
+ hdr = (struct ieee80211_hdr *)skb->data;
+ info = IEEE80211_SKB_CB(skb);
+
+@@ -3462,6 +3456,34 @@ begin:
+ }
+ }
+
++ switch (tx.sdata->vif.type) {
++ case NL80211_IFTYPE_MONITOR:
++ if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
++ vif = &tx.sdata->vif;
++ break;
++ }
++ tx.sdata = rcu_dereference(local->monitor_sdata);
++ if (tx.sdata) {
++ vif = &tx.sdata->vif;
++ info->hw_queue =
++ vif->hw_queue[skb_get_queue_mapping(skb)];
++ } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
++ ieee80211_free_txskb(&local->hw, skb);
++ goto begin;
++ } else {
++ vif = NULL;
++ }
++ break;
++ case NL80211_IFTYPE_AP_VLAN:
++ tx.sdata = container_of(tx.sdata->bss,
++ struct ieee80211_sub_if_data, u.ap);
++ /* fall through */
++ default:
++ vif = &tx.sdata->vif;
++ break;
++ }
++
++ IEEE80211_SKB_CB(skb)->control.vif = vif;
+ out:
+ spin_unlock_bh(&fq->lock);
+
--- /dev/null
+From 6e46d8ce894374fc135c96a8d1057c6af1fef237 Mon Sep 17 00:00:00 2001
+From: Avraham Stern <avraham.stern@intel.com>
+Date: Fri, 18 Aug 2017 15:33:57 +0300
+Subject: mac80211: flush hw_roc_start work before cancelling the ROC
+
+From: Avraham Stern <avraham.stern@intel.com>
+
+commit 6e46d8ce894374fc135c96a8d1057c6af1fef237 upstream.
+
+When HW ROC is supported it is possible that after the HW notified
+that the ROC has started, the ROC was cancelled and another ROC was
+added while the hw_roc_start worker is waiting on the mutex (since
+cancelling the ROC and adding another one also holds the same mutex).
+As a result, the hw_roc_start worker will continue to run after the
+new ROC is added but before it is actually started by the HW.
+This may result in notifying userspace that the ROC has started before
+it actually does, or in case of management tx ROC, in an attempt to
+tx while not on the right channel.
+
+In addition, when the driver will notify mac80211 that the second ROC
+has started, mac80211 will warn that this ROC has already been
+notified.
+
+Fix this by flushing the hw_roc_start work before cancelling an ROC.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Avraham Stern <avraham.stern@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/offchannel.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/mac80211/offchannel.c
++++ b/net/mac80211/offchannel.c
+@@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct i
+ if (!cookie)
+ return -ENOENT;
+
++ flush_work(&local->hw_roc_start);
++
+ mutex_lock(&local->mtx);
+ list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
+ if (!mgmt_tx && roc->cookie != cookie)
--- /dev/null
+From 9de981f507474f326e42117858dc9a9321331ae5 Mon Sep 17 00:00:00 2001
+From: Beni Lev <beni.lev@intel.com>
+Date: Tue, 25 Jul 2017 11:25:25 +0300
+Subject: mac80211_hwsim: Use proper TX power
+
+From: Beni Lev <beni.lev@intel.com>
+
+commit 9de981f507474f326e42117858dc9a9321331ae5 upstream.
+
+In struct ieee80211_tx_info, control.vif pointer and rate_driver_data[0]
+falls on the same place, depending on the union usage.
+During the whole TX process, the union is referred to as a control struct,
+which holds the vif that is later used in the tx flow, especially in order
+to derive the used tx power.
+Referring direcly to rate_driver_data[0] and assigning a value to it,
+overwrites the vif pointer, hence making all later references irrelevant.
+Moreover, rate_driver_data[0] isn't used later in the flow in order to
+retrieve the channel that it is pointing to.
+
+Signed-off-by: Beni Lev <beni.lev@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/mac80211_hwsim.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -1357,8 +1357,6 @@ static void mac80211_hwsim_tx(struct iee
+ txi->control.rates,
+ ARRAY_SIZE(txi->control.rates));
+
+- txi->rate_driver_data[0] = channel;
+-
+ if (skb->len >= 24 + 8 &&
+ ieee80211_is_probe_resp(hdr->frame_control)) {
+ /* fake header transmission time */