]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 13:04:22 +0000 (15:04 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 13:04:22 +0000 (15:04 +0200)
added patches:
arm64-fix-null-dereference-in-have_cpu_die.patch
brcmfmac-avoid-writing-channel-out-of-allocated-array.patch
clk-scpi-don-t-add-cpufreq-device-if-the-scpi-dvfs-node-is-disabled.patch
cpufreq-s3c2416-double-free-on-driver-init-error-path.patch
i2c-brcmstb-fix-start-and-stop-conditions.patch
infiniband-hns-avoid-gcc-7.0.1-warning-for-uninitialized-data.patch
iommu-amd-fix-incorrect-error-handling-in-amd_iommu_bind_pasid.patch
iommu-amd-fix-interrupt-remapping-when-disable-guest_mode.patch
iommu-dma-don-t-reserve-pci-i-o-windows.patch
iommu-handle-default-domain-attach-failure.patch
iommu-vt-d-don-t-over-free-page-table-directories.patch
kvm-nvmx-fix-exception-injection.patch
kvm-x86-fix-emulation-of-rsm-and-iret-instructions.patch
kvm-x86-vpmu-fix-undefined-shift-in-intel_pmu_refresh.patch
kvm-x86-zero-base3-of-unusable-segments.patch
mtd-nand-brcmnand-check-flash-wp-pin-status-before-nand-erase-program.patch
objtool-fix-another-gcc-jump-table-detection-issue.patch

18 files changed:
queue-4.9/arm64-fix-null-dereference-in-have_cpu_die.patch [new file with mode: 0644]
queue-4.9/brcmfmac-avoid-writing-channel-out-of-allocated-array.patch [new file with mode: 0644]
queue-4.9/clk-scpi-don-t-add-cpufreq-device-if-the-scpi-dvfs-node-is-disabled.patch [new file with mode: 0644]
queue-4.9/cpufreq-s3c2416-double-free-on-driver-init-error-path.patch [new file with mode: 0644]
queue-4.9/i2c-brcmstb-fix-start-and-stop-conditions.patch [new file with mode: 0644]
queue-4.9/infiniband-hns-avoid-gcc-7.0.1-warning-for-uninitialized-data.patch [new file with mode: 0644]
queue-4.9/iommu-amd-fix-incorrect-error-handling-in-amd_iommu_bind_pasid.patch [new file with mode: 0644]
queue-4.9/iommu-amd-fix-interrupt-remapping-when-disable-guest_mode.patch [new file with mode: 0644]
queue-4.9/iommu-dma-don-t-reserve-pci-i-o-windows.patch [new file with mode: 0644]
queue-4.9/iommu-handle-default-domain-attach-failure.patch [new file with mode: 0644]
queue-4.9/iommu-vt-d-don-t-over-free-page-table-directories.patch [new file with mode: 0644]
queue-4.9/kvm-nvmx-fix-exception-injection.patch [new file with mode: 0644]
queue-4.9/kvm-x86-fix-emulation-of-rsm-and-iret-instructions.patch [new file with mode: 0644]
queue-4.9/kvm-x86-vpmu-fix-undefined-shift-in-intel_pmu_refresh.patch [new file with mode: 0644]
queue-4.9/kvm-x86-zero-base3-of-unusable-segments.patch [new file with mode: 0644]
queue-4.9/mtd-nand-brcmnand-check-flash-wp-pin-status-before-nand-erase-program.patch [new file with mode: 0644]
queue-4.9/objtool-fix-another-gcc-jump-table-detection-issue.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/arm64-fix-null-dereference-in-have_cpu_die.patch b/queue-4.9/arm64-fix-null-dereference-in-have_cpu_die.patch
new file mode 100644 (file)
index 0000000..67c836f
--- /dev/null
@@ -0,0 +1,37 @@
+From 335d2c2d192266358c5dfa64953a4c162f46e464 Mon Sep 17 00:00:00 2001
+From: Mark Salter <msalter@redhat.com>
+Date: Fri, 24 Mar 2017 09:53:56 -0400
+Subject: arm64: fix NULL dereference in have_cpu_die()
+
+From: Mark Salter <msalter@redhat.com>
+
+commit 335d2c2d192266358c5dfa64953a4c162f46e464 upstream.
+
+Commit 5c492c3f5255 ("arm64: smp: Add function to determine if cpus are
+stuck in the kernel") added a helper function to determine if die() is
+supported in cpu_ops. This function assumes a cpu will have a valid
+cpu_ops entry, but that may not be the case for cpu0 is spin-table or
+parking protocol is used to boot secondary cpus. In that case, there
+is a NULL dereference if have_cpu_die() is called by cpu0. So add a
+check for a valid cpu_ops before dereferencing it.
+
+Fixes: 5c492c3f5255 ("arm64: smp: Add function to determine if cpus are stuck in the kernel")
+Signed-off-by: Mark Salter <msalter@redhat.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/smp.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/kernel/smp.c
++++ b/arch/arm64/kernel/smp.c
+@@ -934,7 +934,7 @@ static bool have_cpu_die(void)
+ #ifdef CONFIG_HOTPLUG_CPU
+       int any_cpu = raw_smp_processor_id();
+-      if (cpu_ops[any_cpu]->cpu_die)
++      if (cpu_ops[any_cpu] && cpu_ops[any_cpu]->cpu_die)
+               return true;
+ #endif
+       return false;
diff --git a/queue-4.9/brcmfmac-avoid-writing-channel-out-of-allocated-array.patch b/queue-4.9/brcmfmac-avoid-writing-channel-out-of-allocated-array.patch
new file mode 100644 (file)
index 0000000..123a8f7
--- /dev/null
@@ -0,0 +1,110 @@
+From 77c0d0cd10e793989d1e8b835a9a09694182cb39 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 4 Jan 2017 12:09:41 +0100
+Subject: brcmfmac: avoid writing channel out of allocated array
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+commit 77c0d0cd10e793989d1e8b835a9a09694182cb39 upstream.
+
+Our code was assigning number of channels to the index variable by
+default. If firmware reported channel we didn't predict this would
+result in using that initial index value and writing out of array. This
+never happened so far (we got a complete list of supported channels) but
+it means possible memory corruption so we should handle it anyway.
+
+This patch simply detects unexpected channel and ignores it.
+
+As we don't try to create new entry now, it's also safe to drop hw_value
+and center_freq assignment. For known channels we have these set anyway.
+
+I decided to fix this issue by assigning NULL or a target channel to the
+channel variable. This was one of possible ways, I prefefred this one as
+it also avoids using channel[index] over and over.
+
+Fixes: 58de92d2f95e ("brcmfmac: use static superset of channels for wiphy bands")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |   32 ++++++------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -5913,7 +5913,6 @@ static int brcmf_construct_chaninfo(stru
+       u32 i, j;
+       u32 total;
+       u32 chaninfo;
+-      u32 index;
+       pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
+@@ -5961,33 +5960,36 @@ static int brcmf_construct_chaninfo(stru
+                   ch.bw == BRCMU_CHAN_BW_80)
+                       continue;
+-              channel = band->channels;
+-              index = band->n_channels;
++              channel = NULL;
+               for (j = 0; j < band->n_channels; j++) {
+-                      if (channel[j].hw_value == ch.control_ch_num) {
+-                              index = j;
++                      if (band->channels[j].hw_value == ch.control_ch_num) {
++                              channel = &band->channels[j];
+                               break;
+                       }
+               }
+-              channel[index].center_freq =
+-                      ieee80211_channel_to_frequency(ch.control_ch_num,
+-                                                     band->band);
+-              channel[index].hw_value = ch.control_ch_num;
++              if (!channel) {
++                      /* It seems firmware supports some channel we never
++                       * considered. Something new in IEEE standard?
++                       */
++                      brcmf_err("Ignoring unexpected firmware channel %d\n",
++                                ch.control_ch_num);
++                      continue;
++              }
+               /* assuming the chanspecs order is HT20,
+                * HT40 upper, HT40 lower, and VHT80.
+                */
+               if (ch.bw == BRCMU_CHAN_BW_80) {
+-                      channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
++                      channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
+               } else if (ch.bw == BRCMU_CHAN_BW_40) {
+-                      brcmf_update_bw40_channel_flag(&channel[index], &ch);
++                      brcmf_update_bw40_channel_flag(channel, &ch);
+               } else {
+                       /* enable the channel and disable other bandwidths
+                        * for now as mentioned order assure they are enabled
+                        * for subsequent chanspecs.
+                        */
+-                      channel[index].flags = IEEE80211_CHAN_NO_HT40 |
+-                                             IEEE80211_CHAN_NO_80MHZ;
++                      channel->flags = IEEE80211_CHAN_NO_HT40 |
++                                       IEEE80211_CHAN_NO_80MHZ;
+                       ch.bw = BRCMU_CHAN_BW_20;
+                       cfg->d11inf.encchspec(&ch);
+                       chaninfo = ch.chspec;
+@@ -5995,11 +5997,11 @@ static int brcmf_construct_chaninfo(stru
+                                                      &chaninfo);
+                       if (!err) {
+                               if (chaninfo & WL_CHAN_RADAR)
+-                                      channel[index].flags |=
++                                      channel->flags |=
+                                               (IEEE80211_CHAN_RADAR |
+                                                IEEE80211_CHAN_NO_IR);
+                               if (chaninfo & WL_CHAN_PASSIVE)
+-                                      channel[index].flags |=
++                                      channel->flags |=
+                                               IEEE80211_CHAN_NO_IR;
+                       }
+               }
diff --git a/queue-4.9/clk-scpi-don-t-add-cpufreq-device-if-the-scpi-dvfs-node-is-disabled.patch b/queue-4.9/clk-scpi-don-t-add-cpufreq-device-if-the-scpi-dvfs-node-is-disabled.patch
new file mode 100644 (file)
index 0000000..d100eac
--- /dev/null
@@ -0,0 +1,56 @@
+From 67bcc2c5f1da8c5bb58e72354274ea5c59a3950a Mon Sep 17 00:00:00 2001
+From: Sudeep Holla <sudeep.holla@arm.com>
+Date: Fri, 6 Jan 2017 12:34:30 +0000
+Subject: clk: scpi: don't add cpufreq device if the scpi dvfs node is disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+commit 67bcc2c5f1da8c5bb58e72354274ea5c59a3950a upstream.
+
+Currently we add the virtual cpufreq device unconditionally even when
+the SCPI DVFS clock provider node is disabled. This will cause cpufreq
+driver to throw errors when it gets initailised on boot/modprobe and
+also when the CPUs are hot-plugged back in.
+
+This patch fixes the issue by adding the virtual cpufreq device only if
+the SCPI DVFS clock provider is available and registered.
+
+Fixes: 9490f01e2471 ("clk: scpi: add support for cpufreq virtual device")
+Reported-by: Michał Zegan <webczat_200@poczta.onet.pl>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Tested-by: Michał Zegan <webczat_200@poczta.onet.pl>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/clk-scpi.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/clk/clk-scpi.c
++++ b/drivers/clk/clk-scpi.c
+@@ -290,13 +290,15 @@ static int scpi_clocks_probe(struct plat
+                       of_node_put(child);
+                       return ret;
+               }
+-      }
+-      /* Add the virtual cpufreq device */
+-      cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
+-                                                    -1, NULL, 0);
+-      if (IS_ERR(cpufreq_dev))
+-              pr_warn("unable to register cpufreq device");
++              if (match->data != &scpi_dvfs_ops)
++                      continue;
++              /* Add the virtual cpufreq device if it's DVFS clock provider */
++              cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
++                                                            -1, NULL, 0);
++              if (IS_ERR(cpufreq_dev))
++                      pr_warn("unable to register cpufreq device");
++      }
+       return 0;
+ }
diff --git a/queue-4.9/cpufreq-s3c2416-double-free-on-driver-init-error-path.patch b/queue-4.9/cpufreq-s3c2416-double-free-on-driver-init-error-path.patch
new file mode 100644 (file)
index 0000000..8e3ca13
--- /dev/null
@@ -0,0 +1,33 @@
+From a69261e4470d680185a15f748d9cdafb37c57a33 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 7 Feb 2017 16:19:06 +0300
+Subject: cpufreq: s3c2416: double free on driver init error path
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit a69261e4470d680185a15f748d9cdafb37c57a33 upstream.
+
+The "goto err_armclk;" error path already does a clk_put(s3c_freq->hclk);
+so this is a double free.
+
+Fixes: 34ee55075265 ([CPUFREQ] Add S3C2416/S3C2450 cpufreq driver)
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/s3c2416-cpufreq.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/cpufreq/s3c2416-cpufreq.c
++++ b/drivers/cpufreq/s3c2416-cpufreq.c
+@@ -400,7 +400,6 @@ static int s3c2416_cpufreq_driver_init(s
+       rate = clk_get_rate(s3c_freq->hclk);
+       if (rate < 133 * 1000 * 1000) {
+               pr_err("cpufreq: HCLK not at 133MHz\n");
+-              clk_put(s3c_freq->hclk);
+               ret = -EINVAL;
+               goto err_armclk;
+       }
diff --git a/queue-4.9/i2c-brcmstb-fix-start-and-stop-conditions.patch b/queue-4.9/i2c-brcmstb-fix-start-and-stop-conditions.patch
new file mode 100644 (file)
index 0000000..fdf7bbc
--- /dev/null
@@ -0,0 +1,87 @@
+From 2de3ec4f1d4ba6ee380478055104eb918bd50cce Mon Sep 17 00:00:00 2001
+From: Jaedon Shin <jaedon.shin@gmail.com>
+Date: Fri, 3 Mar 2017 10:55:03 +0900
+Subject: i2c: brcmstb: Fix START and STOP conditions
+
+From: Jaedon Shin <jaedon.shin@gmail.com>
+
+commit 2de3ec4f1d4ba6ee380478055104eb918bd50cce upstream.
+
+The BSC data buffers to send and receive data are each of size 32 bytes
+or 8 bytes 'xfersz' depending on SoC. The problem observed for all the
+combined message transfer was if length of data transfer was a multiple
+of 'xfersz' a repeated START was being transmitted by BSC driver. Fixed
+this by appropriately setting START/STOP conditions for such transfers.
+
+Fixes: dd1aa2524bc5 ("i2c: brcmstb: Add Broadcom settop SoC i2c controller driver")
+Signed-off-by: Jaedon Shin <jaedon.shin@gmail.com>
+Acked-by: Kamal Dasu <kdasu.kdev@gmail.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/busses/i2c-brcmstb.c |   27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-brcmstb.c
++++ b/drivers/i2c/busses/i2c-brcmstb.c
+@@ -465,6 +465,7 @@ static int brcmstb_i2c_xfer(struct i2c_a
+       u8 *tmp_buf;
+       int len = 0;
+       int xfersz = brcmstb_i2c_get_xfersz(dev);
++      u32 cond, cond_per_msg;
+       if (dev->is_suspended)
+               return -EBUSY;
+@@ -481,10 +482,11 @@ static int brcmstb_i2c_xfer(struct i2c_a
+                       pmsg->buf ? pmsg->buf[0] : '0', pmsg->len);
+               if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART))
+-                      brcmstb_set_i2c_start_stop(dev, ~(COND_START_STOP));
++                      cond = ~COND_START_STOP;
+               else
+-                      brcmstb_set_i2c_start_stop(dev,
+-                                                 COND_RESTART | COND_NOSTOP);
++                      cond = COND_RESTART | COND_NOSTOP;
++
++              brcmstb_set_i2c_start_stop(dev, cond);
+               /* Send slave address */
+               if (!(pmsg->flags & I2C_M_NOSTART)) {
+@@ -497,13 +499,24 @@ static int brcmstb_i2c_xfer(struct i2c_a
+                       }
+               }
++              cond_per_msg = cond;
++
+               /* Perform data transfer */
+               while (len) {
+                       bytes_to_xfer = min(len, xfersz);
+-                      if (len <= xfersz && i == (num - 1))
+-                              brcmstb_set_i2c_start_stop(dev,
+-                                                         ~(COND_START_STOP));
++                      if (len <= xfersz) {
++                              if (i == (num - 1))
++                                      cond_per_msg = cond_per_msg &
++                                              ~(COND_RESTART | COND_NOSTOP);
++                              else
++                                      cond_per_msg = cond;
++                      } else {
++                              cond_per_msg = (cond_per_msg & ~COND_RESTART) |
++                                      COND_NOSTOP;
++                      }
++
++                      brcmstb_set_i2c_start_stop(dev, cond_per_msg);
+                       rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf,
+                                                      bytes_to_xfer, pmsg);
+@@ -512,6 +525,8 @@ static int brcmstb_i2c_xfer(struct i2c_a
+                       len -=  bytes_to_xfer;
+                       tmp_buf += bytes_to_xfer;
++
++                      cond_per_msg = COND_NOSTART | COND_NOSTOP;
+               }
+       }
diff --git a/queue-4.9/infiniband-hns-avoid-gcc-7.0.1-warning-for-uninitialized-data.patch b/queue-4.9/infiniband-hns-avoid-gcc-7.0.1-warning-for-uninitialized-data.patch
new file mode 100644 (file)
index 0000000..3651e32
--- /dev/null
@@ -0,0 +1,43 @@
+From 5b0ff9a00755d4d9c209033a77f1ed8f3186fe5c Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Fri, 24 Mar 2017 23:02:48 +0100
+Subject: infiniband: hns: avoid gcc-7.0.1 warning for uninitialized data
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 5b0ff9a00755d4d9c209033a77f1ed8f3186fe5c upstream.
+
+hns_roce_v1_cq_set_ci() calls roce_set_bit() on an uninitialized field,
+which will then change only a few of its bits, causing a warning with
+the latest gcc:
+
+infiniband/hw/hns/hns_roce_hw_v1.c: In function 'hns_roce_v1_cq_set_ci':
+infiniband/hw/hns/hns_roce_hw_v1.c:1854:23: error: 'doorbell[1]' is used uninitialized in this function [-Werror=uninitialized]
+  roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
+
+The code is actually correct since we always set all bits of the
+port_vlan field, but gcc correctly points out that the first
+access does contain uninitialized data.
+
+This initializes the field to zero first before setting the
+individual bits.
+
+Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v1.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+@@ -1267,6 +1267,7 @@ void hns_roce_v1_cq_set_ci(struct hns_ro
+       u32 doorbell[2];
+       doorbell[0] = cons_index & ((hr_cq->cq_depth << 1) - 1);
++      doorbell[1] = 0;
+       roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
+       roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M,
+                      ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S, 3);
diff --git a/queue-4.9/iommu-amd-fix-incorrect-error-handling-in-amd_iommu_bind_pasid.patch b/queue-4.9/iommu-amd-fix-incorrect-error-handling-in-amd_iommu_bind_pasid.patch
new file mode 100644 (file)
index 0000000..597fdc3
--- /dev/null
@@ -0,0 +1,37 @@
+From 73dbd4a4230216b6a5540a362edceae0c9b4876b Mon Sep 17 00:00:00 2001
+From: Pan Bian <bianpan2016@163.com>
+Date: Sun, 23 Apr 2017 18:23:21 +0800
+Subject: iommu/amd: Fix incorrect error handling in amd_iommu_bind_pasid()
+
+From: Pan Bian <bianpan2016@163.com>
+
+commit 73dbd4a4230216b6a5540a362edceae0c9b4876b upstream.
+
+In function amd_iommu_bind_pasid(), the control flow jumps
+to label out_free when pasid_state->mm and mm is NULL. And
+mmput(mm) is called.  In function mmput(mm), mm is
+referenced without validation. This will result in a NULL
+dereference bug. This patch fixes the bug.
+
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Fixes: f0aac63b873b ('iommu/amd: Don't hold a reference to mm_struct')
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu_v2.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/amd_iommu_v2.c
++++ b/drivers/iommu/amd_iommu_v2.c
+@@ -695,9 +695,9 @@ out_clear_state:
+ out_unregister:
+       mmu_notifier_unregister(&pasid_state->mn, mm);
++      mmput(mm);
+ out_free:
+-      mmput(mm);
+       free_pasid_state(pasid_state);
+ out:
diff --git a/queue-4.9/iommu-amd-fix-interrupt-remapping-when-disable-guest_mode.patch b/queue-4.9/iommu-amd-fix-interrupt-remapping-when-disable-guest_mode.patch
new file mode 100644 (file)
index 0000000..ee74b34
--- /dev/null
@@ -0,0 +1,55 @@
+From 84a21dbdef0b96d773599c33c2afbb002198d303 Mon Sep 17 00:00:00 2001
+From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Date: Mon, 26 Jun 2017 04:28:04 -0500
+Subject: iommu/amd: Fix interrupt remapping when disable guest_mode
+
+From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+
+commit 84a21dbdef0b96d773599c33c2afbb002198d303 upstream.
+
+Pass-through devices to VM guest can get updated IRQ affinity
+information via irq_set_affinity() when not running in guest mode.
+Currently, AMD IOMMU driver in GA mode ignores the updated information
+if the pass-through device is setup to use vAPIC regardless of guest_mode.
+This could cause invalid interrupt remapping.
+
+Also, the guest_mode bit should be set and cleared only when
+SVM updates posted-interrupt interrupt remapping information.
+
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Cc: Joerg Roedel <jroedel@suse.de>
+Fixes: d98de49a53e48 ('iommu/amd: Enable vAPIC interrupt remapping mode by default')
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -3857,11 +3857,9 @@ static void irte_ga_prepare(void *entry,
+                           u8 vector, u32 dest_apicid, int devid)
+ {
+       struct irte_ga *irte = (struct irte_ga *) entry;
+-      struct iommu_dev_data *dev_data = search_dev_data(devid);
+       irte->lo.val                      = 0;
+       irte->hi.val                      = 0;
+-      irte->lo.fields_remap.guest_mode  = dev_data ? dev_data->use_vapic : 0;
+       irte->lo.fields_remap.int_type    = delivery_mode;
+       irte->lo.fields_remap.dm          = dest_mode;
+       irte->hi.fields.vector            = vector;
+@@ -3917,10 +3915,10 @@ static void irte_ga_set_affinity(void *e
+       struct irte_ga *irte = (struct irte_ga *) entry;
+       struct iommu_dev_data *dev_data = search_dev_data(devid);
+-      if (!dev_data || !dev_data->use_vapic) {
++      if (!dev_data || !dev_data->use_vapic ||
++          !irte->lo.fields_remap.guest_mode) {
+               irte->hi.fields.vector = vector;
+               irte->lo.fields_remap.destination = dest_apicid;
+-              irte->lo.fields_remap.guest_mode = 0;
+               modify_irte_ga(devid, index, irte, NULL);
+       }
+ }
diff --git a/queue-4.9/iommu-dma-don-t-reserve-pci-i-o-windows.patch b/queue-4.9/iommu-dma-don-t-reserve-pci-i-o-windows.patch
new file mode 100644 (file)
index 0000000..ad05ac2
--- /dev/null
@@ -0,0 +1,36 @@
+From 938f1bbe35e3a7cb07e1fa7c512e2ef8bb866bdf Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Thu, 16 Mar 2017 17:00:17 +0000
+Subject: iommu/dma: Don't reserve PCI I/O windows
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+commit 938f1bbe35e3a7cb07e1fa7c512e2ef8bb866bdf upstream.
+
+Even if a host controller's CPU-side MMIO windows into PCI I/O space do
+happen to leak into PCI memory space such that it might treat them as
+peer addresses, trying to reserve the corresponding I/O space addresses
+doesn't do anything to help solve that problem. Stop doing a silly thing.
+
+Fixes: fade1ec055dc ("iommu/dma: Avoid PCI host bridge windows")
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/dma-iommu.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/iommu/dma-iommu.c
++++ b/drivers/iommu/dma-iommu.c
+@@ -112,8 +112,7 @@ static void iova_reserve_pci_windows(str
+       unsigned long lo, hi;
+       resource_list_for_each_entry(window, &bridge->windows) {
+-              if (resource_type(window->res) != IORESOURCE_MEM &&
+-                  resource_type(window->res) != IORESOURCE_IO)
++              if (resource_type(window->res) != IORESOURCE_MEM)
+                       continue;
+               lo = iova_pfn(iovad, window->res->start - window->offset);
diff --git a/queue-4.9/iommu-handle-default-domain-attach-failure.patch b/queue-4.9/iommu-handle-default-domain-attach-failure.patch
new file mode 100644 (file)
index 0000000..22d4c13
--- /dev/null
@@ -0,0 +1,111 @@
+From 797a8b4d768c58caac58ee3e8cb36a164d1b7751 Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Mon, 16 Jan 2017 12:58:07 +0000
+Subject: iommu: Handle default domain attach failure
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+commit 797a8b4d768c58caac58ee3e8cb36a164d1b7751 upstream.
+
+We wouldn't normally expect ops->attach_dev() to fail, but on IOMMUs
+with limited hardware resources, or generally misconfigured systems,
+it is certainly possible. We report failure correctly from the external
+iommu_attach_device() interface, but do not do so in iommu_group_add()
+when attaching to the default domain. The result of failure there is
+that the device, group and domain all get left in a broken,
+part-configured state which leads to weird errors and misbehaviour down
+the line when IOMMU API calls sort-of-but-don't-quite work.
+
+Check the return value of __iommu_attach_device() on the default domain,
+and refactor the error handling paths to cope with its failure and clean
+up correctly in such cases.
+
+Fixes: e39cb8a3aa98 ("iommu: Make sure a device is always attached to a domain")
+Reported-by: Punit Agrawal <punit.agrawal@arm.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/iommu.c |   37 ++++++++++++++++++++++++-------------
+ 1 file changed, 24 insertions(+), 13 deletions(-)
+
+--- a/drivers/iommu/iommu.c
++++ b/drivers/iommu/iommu.c
+@@ -383,36 +383,30 @@ int iommu_group_add_device(struct iommu_
+       device->dev = dev;
+       ret = sysfs_create_link(&dev->kobj, &group->kobj, "iommu_group");
+-      if (ret) {
+-              kfree(device);
+-              return ret;
+-      }
++      if (ret)
++              goto err_free_device;
+       device->name = kasprintf(GFP_KERNEL, "%s", kobject_name(&dev->kobj));
+ rename:
+       if (!device->name) {
+-              sysfs_remove_link(&dev->kobj, "iommu_group");
+-              kfree(device);
+-              return -ENOMEM;
++              ret = -ENOMEM;
++              goto err_remove_link;
+       }
+       ret = sysfs_create_link_nowarn(group->devices_kobj,
+                                      &dev->kobj, device->name);
+       if (ret) {
+-              kfree(device->name);
+               if (ret == -EEXIST && i >= 0) {
+                       /*
+                        * Account for the slim chance of collision
+                        * and append an instance to the name.
+                        */
++                      kfree(device->name);
+                       device->name = kasprintf(GFP_KERNEL, "%s.%d",
+                                                kobject_name(&dev->kobj), i++);
+                       goto rename;
+               }
+-
+-              sysfs_remove_link(&dev->kobj, "iommu_group");
+-              kfree(device);
+-              return ret;
++              goto err_free_name;
+       }
+       kobject_get(group->devices_kobj);
+@@ -424,8 +418,10 @@ rename:
+       mutex_lock(&group->mutex);
+       list_add_tail(&device->list, &group->devices);
+       if (group->domain)
+-              __iommu_attach_device(group->domain, dev);
++              ret = __iommu_attach_device(group->domain, dev);
+       mutex_unlock(&group->mutex);
++      if (ret)
++              goto err_put_group;
+       /* Notify any listeners about change to group. */
+       blocking_notifier_call_chain(&group->notifier,
+@@ -436,6 +432,21 @@ rename:
+       pr_info("Adding device %s to group %d\n", dev_name(dev), group->id);
+       return 0;
++
++err_put_group:
++      mutex_lock(&group->mutex);
++      list_del(&device->list);
++      mutex_unlock(&group->mutex);
++      dev->iommu_group = NULL;
++      kobject_put(group->devices_kobj);
++err_free_name:
++      kfree(device->name);
++err_remove_link:
++      sysfs_remove_link(&dev->kobj, "iommu_group");
++err_free_device:
++      kfree(device);
++      pr_err("Failed to add device %s to group %d: %d\n", dev_name(dev), group->id, ret);
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(iommu_group_add_device);
diff --git a/queue-4.9/iommu-vt-d-don-t-over-free-page-table-directories.patch b/queue-4.9/iommu-vt-d-don-t-over-free-page-table-directories.patch
new file mode 100644 (file)
index 0000000..77881a6
--- /dev/null
@@ -0,0 +1,57 @@
+From f7116e115acdd74bc75a4daf6492b11d43505125 Mon Sep 17 00:00:00 2001
+From: David Dillow <dillow@google.com>
+Date: Mon, 30 Jan 2017 19:11:11 -0800
+Subject: iommu/vt-d: Don't over-free page table directories
+
+From: David Dillow <dillow@google.com>
+
+commit f7116e115acdd74bc75a4daf6492b11d43505125 upstream.
+
+dma_pte_free_level() recurses down the IOMMU page tables and frees
+directory pages that are entirely contained in the given PFN range.
+Unfortunately, it incorrectly calculates the starting address covered
+by the PTE under consideration, which can lead to it clearing an entry
+that is still in use.
+
+This occurs if we have a scatterlist with an entry that has a length
+greater than 1026 MB and is aligned to 2 MB for both the IOMMU and
+physical addresses. For example, if __domain_mapping() is asked to map a
+two-entry scatterlist with 2 MB and 1028 MB segments to PFN 0xffff80000,
+it will ask if dma_pte_free_pagetable() is asked to PFNs from
+0xffff80200 to 0xffffc05ff, it will also incorrectly clear the PFNs from
+0xffff80000 to 0xffff801ff because of this issue. The current code will
+set level_pfn to 0xffff80200, and 0xffff80200-0xffffc01ff fits inside
+the range being cleared. Properly setting the level_pfn for the current
+level under consideration catches that this PTE is outside of the range
+being cleared.
+
+This patch also changes the value passed into dma_pte_free_level() when
+it recurses. This only affects the first PTE of the range being cleared,
+and is handled by the existing code that ensures we start our cursor no
+lower than start_pfn.
+
+This was found when using dma_map_sg() to map large chunks of contiguous
+memory, which immediatedly led to faults on the first access of the
+erroneously-deleted mappings.
+
+Fixes: 3269ee0bd668 ("intel-iommu: Fix leaks in pagetable freeing")
+Reviewed-by: Benjamin Serebrin <serebrin@google.com>
+Signed-off-by: David Dillow <dillow@google.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -1144,7 +1144,7 @@ static void dma_pte_free_level(struct dm
+               if (!dma_pte_present(pte) || dma_pte_superpage(pte))
+                       goto next;
+-              level_pfn = pfn & level_mask(level - 1);
++              level_pfn = pfn & level_mask(level);
+               level_pte = phys_to_virt(dma_pte_addr(pte));
+               if (level > 2)
diff --git a/queue-4.9/kvm-nvmx-fix-exception-injection.patch b/queue-4.9/kvm-nvmx-fix-exception-injection.patch
new file mode 100644 (file)
index 0000000..2855eac
--- /dev/null
@@ -0,0 +1,73 @@
+From d4912215d1031e4fb3d1038d2e1857218dba0d0a Mon Sep 17 00:00:00 2001
+From: Wanpeng Li <wanpeng.li@hotmail.com>
+Date: Mon, 5 Jun 2017 05:19:09 -0700
+Subject: KVM: nVMX: Fix exception injection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wanpeng Li <wanpeng.li@hotmail.com>
+
+commit d4912215d1031e4fb3d1038d2e1857218dba0d0a upstream.
+
+ WARNING: CPU: 3 PID: 2840 at arch/x86/kvm/vmx.c:10966 nested_vmx_vmexit+0xdcd/0xde0 [kvm_intel]
+ CPU: 3 PID: 2840 Comm: qemu-system-x86 Tainted: G           OE   4.12.0-rc3+ #23
+ RIP: 0010:nested_vmx_vmexit+0xdcd/0xde0 [kvm_intel]
+ Call Trace:
+  ? kvm_check_async_pf_completion+0xef/0x120 [kvm]
+  ? rcu_read_lock_sched_held+0x79/0x80
+  vmx_queue_exception+0x104/0x160 [kvm_intel]
+  ? vmx_queue_exception+0x104/0x160 [kvm_intel]
+  kvm_arch_vcpu_ioctl_run+0x1171/0x1ce0 [kvm]
+  ? kvm_arch_vcpu_load+0x47/0x240 [kvm]
+  ? kvm_arch_vcpu_load+0x62/0x240 [kvm]
+  kvm_vcpu_ioctl+0x384/0x7b0 [kvm]
+  ? kvm_vcpu_ioctl+0x384/0x7b0 [kvm]
+  ? __fget+0xf3/0x210
+  do_vfs_ioctl+0xa4/0x700
+  ? __fget+0x114/0x210
+  SyS_ioctl+0x79/0x90
+  do_syscall_64+0x81/0x220
+  entry_SYSCALL64_slow_path+0x25/0x25
+
+This is triggered occasionally by running both win7 and win2016 in L2, in
+addition, EPT is disabled on both L1 and L2. It can't be reproduced easily.
+
+Commit 0b6ac343fc (KVM: nVMX: Correct handling of exception injection) mentioned
+that "KVM wants to inject page-faults which it got to the guest. This function
+assumes it is called with the exit reason in vmcs02 being a #PF exception".
+Commit e011c663 (KVM: nVMX: Check all exceptions for intercept during delivery to
+L2) allows to check all exceptions for intercept during delivery to L2. However,
+there is no guarantee the exit reason is exception currently, when there is an
+external interrupt occurred on host, maybe a time interrupt for host which should
+not be injected to guest, and somewhere queues an exception, then the function
+nested_vmx_check_exception() will be called and the vmexit emulation codes will
+try to emulate the "Acknowledge interrupt on exit" behavior, the warning is
+triggered.
+
+Reusing the exit reason from the L2->L0 vmexit is wrong in this case,
+the reason must always be EXCEPTION_NMI when injecting an exception into
+L1 as a nested vmexit.
+
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
+Fixes: e011c663b9c7 ("KVM: nVMX: Check all exceptions for intercept during delivery to L2")
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2455,7 +2455,7 @@ static int nested_vmx_check_exception(st
+       if (!(vmcs12->exception_bitmap & (1u << nr)))
+               return 0;
+-      nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
++      nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
+                         vmcs_read32(VM_EXIT_INTR_INFO),
+                         vmcs_readl(EXIT_QUALIFICATION));
+       return 1;
diff --git a/queue-4.9/kvm-x86-fix-emulation-of-rsm-and-iret-instructions.patch b/queue-4.9/kvm-x86-fix-emulation-of-rsm-and-iret-instructions.patch
new file mode 100644 (file)
index 0000000..9a2ecc8
--- /dev/null
@@ -0,0 +1,183 @@
+From 6ed071f051e12cf7baa1b69d3becb8f232fdfb7b Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Tue, 25 Apr 2017 16:42:44 +0200
+Subject: KVM: x86: fix emulation of RSM and IRET instructions
+
+From: Ladi Prosek <lprosek@redhat.com>
+
+commit 6ed071f051e12cf7baa1b69d3becb8f232fdfb7b upstream.
+
+On AMD, the effect of set_nmi_mask called by emulate_iret_real and em_rsm
+on hflags is reverted later on in x86_emulate_instruction where hflags are
+overwritten with ctxt->emul_flags (the kvm_set_hflags call). This manifests
+as a hang when rebooting Windows VMs with QEMU, OVMF, and >1 vcpu.
+
+Instead of trying to merge ctxt->emul_flags into vcpu->arch.hflags after
+an instruction is emulated, this commit deletes emul_flags altogether and
+makes the emulator access vcpu->arch.hflags using two new accessors. This
+way all changes, on the emulator side as well as in functions called from
+the emulator and accessing vcpu state with emul_to_vcpu, are preserved.
+
+More details on the bug and its manifestation with Windows and OVMF:
+
+  It's a KVM bug in the interaction between SMI/SMM and NMI, specific to AMD.
+  I believe that the SMM part explains why we started seeing this only with
+  OVMF.
+
+  KVM masks and unmasks NMI when entering and leaving SMM. When KVM emulates
+  the RSM instruction in em_rsm, the set_nmi_mask call doesn't stick because
+  later on in x86_emulate_instruction we overwrite arch.hflags with
+  ctxt->emul_flags, effectively reverting the effect of the set_nmi_mask call.
+  The AMD-specific hflag of interest here is HF_NMI_MASK.
+
+  When rebooting the system, Windows sends an NMI IPI to all but the current
+  cpu to shut them down. Only after all of them are parked in HLT will the
+  initiating cpu finish the restart. If NMI is masked, other cpus never get
+  the memo and the initiating cpu spins forever, waiting for
+  hal!HalpInterruptProcessorsStarted to drop. That's the symptom we observe.
+
+Fixes: a584539b24b8 ("KVM: x86: pass the whole hflags field to emulator and back")
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/kvm_emulate.h |    4 +++-
+ arch/x86/kvm/emulate.c             |   16 +++++++++-------
+ arch/x86/kvm/x86.c                 |   15 ++++++++++++---
+ 3 files changed, 24 insertions(+), 11 deletions(-)
+
+--- a/arch/x86/include/asm/kvm_emulate.h
++++ b/arch/x86/include/asm/kvm_emulate.h
+@@ -221,6 +221,9 @@ struct x86_emulate_ops {
+       void (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
+                         u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
+       void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
++
++      unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);
++      void (*set_hflags)(struct x86_emulate_ctxt *ctxt, unsigned hflags);
+ };
+ typedef u32 __attribute__((vector_size(16))) sse128_t;
+@@ -290,7 +293,6 @@ struct x86_emulate_ctxt {
+       /* interruptibility state, as a result of execution of STI or MOV SS */
+       int interruptibility;
+-      int emul_flags;
+       bool perm_ok; /* do not check permissions if true */
+       bool ud;        /* inject an #UD if host doesn't support insn */
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -2543,7 +2543,7 @@ static int em_rsm(struct x86_emulate_ctx
+       u64 smbase;
+       int ret;
+-      if ((ctxt->emul_flags & X86EMUL_SMM_MASK) == 0)
++      if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_MASK) == 0)
+               return emulate_ud(ctxt);
+       /*
+@@ -2592,11 +2592,11 @@ static int em_rsm(struct x86_emulate_ctx
+               return X86EMUL_UNHANDLEABLE;
+       }
+-      if ((ctxt->emul_flags & X86EMUL_SMM_INSIDE_NMI_MASK) == 0)
++      if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_INSIDE_NMI_MASK) == 0)
+               ctxt->ops->set_nmi_mask(ctxt, false);
+-      ctxt->emul_flags &= ~X86EMUL_SMM_INSIDE_NMI_MASK;
+-      ctxt->emul_flags &= ~X86EMUL_SMM_MASK;
++      ctxt->ops->set_hflags(ctxt, ctxt->ops->get_hflags(ctxt) &
++              ~(X86EMUL_SMM_INSIDE_NMI_MASK | X86EMUL_SMM_MASK));
+       return X86EMUL_CONTINUE;
+ }
+@@ -5312,6 +5312,7 @@ int x86_emulate_insn(struct x86_emulate_
+       const struct x86_emulate_ops *ops = ctxt->ops;
+       int rc = X86EMUL_CONTINUE;
+       int saved_dst_type = ctxt->dst.type;
++      unsigned emul_flags;
+       ctxt->mem_read.pos = 0;
+@@ -5326,6 +5327,7 @@ int x86_emulate_insn(struct x86_emulate_
+               goto done;
+       }
++      emul_flags = ctxt->ops->get_hflags(ctxt);
+       if (unlikely(ctxt->d &
+                    (No64|Undefined|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) {
+               if ((ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & No64)) ||
+@@ -5359,7 +5361,7 @@ int x86_emulate_insn(struct x86_emulate_
+                               fetch_possible_mmx_operand(ctxt, &ctxt->dst);
+               }
+-              if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
++              if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
+                       rc = emulator_check_intercept(ctxt, ctxt->intercept,
+                                                     X86_ICPT_PRE_EXCEPT);
+                       if (rc != X86EMUL_CONTINUE)
+@@ -5388,7 +5390,7 @@ int x86_emulate_insn(struct x86_emulate_
+                               goto done;
+               }
+-              if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
++              if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
+                       rc = emulator_check_intercept(ctxt, ctxt->intercept,
+                                                     X86_ICPT_POST_EXCEPT);
+                       if (rc != X86EMUL_CONTINUE)
+@@ -5442,7 +5444,7 @@ int x86_emulate_insn(struct x86_emulate_
+ special_insn:
+-      if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
++      if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
+               rc = emulator_check_intercept(ctxt, ctxt->intercept,
+                                             X86_ICPT_POST_MEMACCESS);
+               if (rc != X86EMUL_CONTINUE)
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -5154,6 +5154,16 @@ static void emulator_set_nmi_mask(struct
+       kvm_x86_ops->set_nmi_mask(emul_to_vcpu(ctxt), masked);
+ }
++static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt)
++{
++      return emul_to_vcpu(ctxt)->arch.hflags;
++}
++
++static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags)
++{
++      kvm_set_hflags(emul_to_vcpu(ctxt), emul_flags);
++}
++
+ static const struct x86_emulate_ops emulate_ops = {
+       .read_gpr            = emulator_read_gpr,
+       .write_gpr           = emulator_write_gpr,
+@@ -5193,6 +5203,8 @@ static const struct x86_emulate_ops emul
+       .intercept           = emulator_intercept,
+       .get_cpuid           = emulator_get_cpuid,
+       .set_nmi_mask        = emulator_set_nmi_mask,
++      .get_hflags          = emulator_get_hflags,
++      .set_hflags          = emulator_set_hflags,
+ };
+ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
+@@ -5245,7 +5257,6 @@ static void init_emulate_ctxt(struct kvm
+       BUILD_BUG_ON(HF_GUEST_MASK != X86EMUL_GUEST_MASK);
+       BUILD_BUG_ON(HF_SMM_MASK != X86EMUL_SMM_MASK);
+       BUILD_BUG_ON(HF_SMM_INSIDE_NMI_MASK != X86EMUL_SMM_INSIDE_NMI_MASK);
+-      ctxt->emul_flags = vcpu->arch.hflags;
+       init_decode_cache(ctxt);
+       vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
+@@ -5636,8 +5647,6 @@ restart:
+               unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
+               toggle_interruptibility(vcpu, ctxt->interruptibility);
+               vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+-              if (vcpu->arch.hflags != ctxt->emul_flags)
+-                      kvm_set_hflags(vcpu, ctxt->emul_flags);
+               kvm_rip_write(vcpu, ctxt->eip);
+               if (r == EMULATE_DONE)
+                       kvm_vcpu_check_singlestep(vcpu, rflags, &r);
diff --git a/queue-4.9/kvm-x86-vpmu-fix-undefined-shift-in-intel_pmu_refresh.patch b/queue-4.9/kvm-x86-vpmu-fix-undefined-shift-in-intel_pmu_refresh.patch
new file mode 100644 (file)
index 0000000..c0e4fb5
--- /dev/null
@@ -0,0 +1,39 @@
+From 34b0dadbdf698f9b277a31b2747b625b9a75ea1f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com>
+Date: Thu, 18 May 2017 19:37:31 +0200
+Subject: KVM: x86/vPMU: fix undefined shift in intel_pmu_refresh()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Radim Krčmář <rkrcmar@redhat.com>
+
+commit 34b0dadbdf698f9b277a31b2747b625b9a75ea1f upstream.
+
+Static analysis noticed that pmu->nr_arch_gp_counters can be 32
+(INTEL_PMC_MAX_GENERIC) and therefore cannot be used to shift 'int'.
+
+I didn't add BUILD_BUG_ON for it as we have a better checker.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Fixes: 25462f7f5295 ("KVM: x86/vPMU: Define kvm_pmu_ops to support vPMU function dispatch")
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/pmu_intel.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/pmu_intel.c
++++ b/arch/x86/kvm/pmu_intel.c
+@@ -294,7 +294,7 @@ static void intel_pmu_refresh(struct kvm
+                       ((u64)1 << edx.split.bit_width_fixed) - 1;
+       }
+-      pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
++      pmu->global_ctrl = ((1ull << pmu->nr_arch_gp_counters) - 1) |
+               (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
+       pmu->global_ctrl_mask = ~pmu->global_ctrl;
diff --git a/queue-4.9/kvm-x86-zero-base3-of-unusable-segments.patch b/queue-4.9/kvm-x86-zero-base3-of-unusable-segments.patch
new file mode 100644 (file)
index 0000000..d57c373
--- /dev/null
@@ -0,0 +1,38 @@
+From f0367ee1d64d27fa08be2407df5c125442e885e3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com>
+Date: Thu, 18 May 2017 19:37:30 +0200
+Subject: KVM: x86: zero base3 of unusable segments
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Radim Krčmář <rkrcmar@redhat.com>
+
+commit f0367ee1d64d27fa08be2407df5c125442e885e3 upstream.
+
+Static checker noticed that base3 could be used uninitialized if the
+segment was not present (useable).  Random stack values probably would
+not pass VMCS entry checks.
+
+Reported-by:  Dan Carpenter <dan.carpenter@oracle.com>
+Fixes: 1aa366163b8b ("KVM: x86 emulator: consolidate segment accessors")
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/x86.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -4999,6 +4999,8 @@ static bool emulator_get_segment(struct
+       if (var.unusable) {
+               memset(desc, 0, sizeof(*desc));
++              if (base3)
++                      *base3 = 0;
+               return false;
+       }
diff --git a/queue-4.9/mtd-nand-brcmnand-check-flash-wp-pin-status-before-nand-erase-program.patch b/queue-4.9/mtd-nand-brcmnand-check-flash-wp-pin-status-before-nand-erase-program.patch
new file mode 100644 (file)
index 0000000..4fb9116
--- /dev/null
@@ -0,0 +1,131 @@
+From 9d2ee0a60b8bd9bef2a0082c533736d6a7b39873 Mon Sep 17 00:00:00 2001
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+Date: Fri, 3 Mar 2017 16:16:53 -0500
+Subject: mtd: nand: brcmnand: Check flash #WP pin status before nand erase/program
+
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+
+commit 9d2ee0a60b8bd9bef2a0082c533736d6a7b39873 upstream.
+
+On brcmnand controller v6.x and v7.x, the #WP pin is controlled through
+the NAND_WP bit in CS_SELECT register.
+
+The driver currently assumes that toggling the #WP pin is
+instantaneously enabling/disabling write-protection, but it actually
+takes some time to propagate the new state to the internal NAND chip
+logic. This behavior is sometime causing data corruptions when an
+erase/program operation is executed before write-protection has really
+been disabled.
+
+Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller")
+Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/brcmnand/brcmnand.c |   61 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 58 insertions(+), 3 deletions(-)
+
+--- a/drivers/mtd/nand/brcmnand/brcmnand.c
++++ b/drivers/mtd/nand/brcmnand/brcmnand.c
+@@ -101,6 +101,9 @@ struct brcm_nand_dma_desc {
+ #define BRCMNAND_MIN_BLOCKSIZE        (8 * 1024)
+ #define BRCMNAND_MIN_DEVSIZE  (4ULL * 1024 * 1024)
++#define NAND_CTRL_RDY                 (INTFC_CTLR_READY | INTFC_FLASH_READY)
++#define NAND_POLL_STATUS_TIMEOUT_MS   100
++
+ /* Controller feature flags */
+ enum {
+       BRCMNAND_HAS_1K_SECTORS                 = BIT(0),
+@@ -765,6 +768,31 @@ enum {
+       CS_SELECT_AUTO_DEVICE_ID_CFG            = BIT(30),
+ };
++static int bcmnand_ctrl_poll_status(struct brcmnand_controller *ctrl,
++                                  u32 mask, u32 expected_val,
++                                  unsigned long timeout_ms)
++{
++      unsigned long limit;
++      u32 val;
++
++      if (!timeout_ms)
++              timeout_ms = NAND_POLL_STATUS_TIMEOUT_MS;
++
++      limit = jiffies + msecs_to_jiffies(timeout_ms);
++      do {
++              val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
++              if ((val & mask) == expected_val)
++                      return 0;
++
++              cpu_relax();
++      } while (time_after(limit, jiffies));
++
++      dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
++               expected_val, val & mask);
++
++      return -ETIMEDOUT;
++}
++
+ static inline void brcmnand_set_wp(struct brcmnand_controller *ctrl, bool en)
+ {
+       u32 val = en ? CS_SELECT_NAND_WP : 0;
+@@ -1024,12 +1052,39 @@ static void brcmnand_wp(struct mtd_info
+       if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) {
+               static int old_wp = -1;
++              int ret;
+               if (old_wp != wp) {
+                       dev_dbg(ctrl->dev, "WP %s\n", wp ? "on" : "off");
+                       old_wp = wp;
+               }
++
++              /*
++               * make sure ctrl/flash ready before and after
++               * changing state of #WP pin
++               */
++              ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY |
++                                             NAND_STATUS_READY,
++                                             NAND_CTRL_RDY |
++                                             NAND_STATUS_READY, 0);
++              if (ret)
++                      return;
++
+               brcmnand_set_wp(ctrl, wp);
++              chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
++              /* NAND_STATUS_WP 0x00 = protected, 0x80 = not protected */
++              ret = bcmnand_ctrl_poll_status(ctrl,
++                                             NAND_CTRL_RDY |
++                                             NAND_STATUS_READY |
++                                             NAND_STATUS_WP,
++                                             NAND_CTRL_RDY |
++                                             NAND_STATUS_READY |
++                                             (wp ? 0 : NAND_STATUS_WP), 0);
++
++              if (ret)
++                      dev_err_ratelimited(&host->pdev->dev,
++                                          "nand #WP expected %s\n",
++                                          wp ? "on" : "off");
+       }
+ }
+@@ -1157,15 +1212,15 @@ static irqreturn_t brcmnand_dma_irq(int
+ static void brcmnand_send_cmd(struct brcmnand_host *host, int cmd)
+ {
+       struct brcmnand_controller *ctrl = host->ctrl;
+-      u32 intfc;
++      int ret;
+       dev_dbg(ctrl->dev, "send native cmd %d addr_lo 0x%x\n", cmd,
+               brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS));
+       BUG_ON(ctrl->cmd_pending != 0);
+       ctrl->cmd_pending = cmd;
+-      intfc = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
+-      WARN_ON(!(intfc & INTFC_CTLR_READY));
++      ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0);
++      WARN_ON(ret);
+       mb(); /* flush previous writes */
+       brcmnand_write_reg(ctrl, BRCMNAND_CMD_START,
diff --git a/queue-4.9/objtool-fix-another-gcc-jump-table-detection-issue.patch b/queue-4.9/objtool-fix-another-gcc-jump-table-detection-issue.patch
new file mode 100644 (file)
index 0000000..2231d27
--- /dev/null
@@ -0,0 +1,99 @@
+From 5c51f4ae84df0f9df33ac08aa5be50061a8b4242 Mon Sep 17 00:00:00 2001
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+Date: Thu, 2 Mar 2017 16:57:23 -0600
+Subject: objtool: Fix another GCC jump table detection issue
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+commit 5c51f4ae84df0f9df33ac08aa5be50061a8b4242 upstream.
+
+Arnd Bergmann reported a (false positive) objtool warning:
+
+  drivers/infiniband/sw/rxe/rxe_resp.o: warning: objtool: rxe_responder()+0xfe: sibling call from callable instruction with changed frame pointer
+
+The issue is in find_switch_table().  It tries to find a switch
+statement's jump table by walking backwards from an indirect jump
+instruction, looking for a relocation to the .rodata section.  In this
+case it stopped walking prematurely: the first .rodata relocation it
+encountered was for a variable (resp_state_name) instead of a jump
+table, so it just assumed there wasn't a jump table.
+
+The fix is to ignore any .rodata relocation which refers to an ELF
+object symbol.  This works because the jump tables are anonymous and
+have no symbols associated with them.
+
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Tested-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Fixes: 3732710ff6f2 ("objtool: Improve rare switch jump table pattern detection")
+Link: http://lkml.kernel.org/r/20170302225723.3ndbsnl4hkqbne7a@treble
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/objtool/builtin-check.c |   15 ++++++++++++---
+ tools/objtool/elf.c           |   12 ++++++++++++
+ tools/objtool/elf.h           |    1 +
+ 3 files changed, 25 insertions(+), 3 deletions(-)
+
+--- a/tools/objtool/builtin-check.c
++++ b/tools/objtool/builtin-check.c
+@@ -757,11 +757,20 @@ static struct rela *find_switch_table(st
+                    insn->jump_dest->offset > orig_insn->offset))
+                   break;
++              /* look for a relocation which references .rodata */
+               text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
+                                                   insn->len);
+-              if (text_rela && text_rela->sym == file->rodata->sym)
+-                      return find_rela_by_dest(file->rodata,
+-                                               text_rela->addend);
++              if (!text_rela || text_rela->sym != file->rodata->sym)
++                      continue;
++
++              /*
++               * Make sure the .rodata address isn't associated with a
++               * symbol.  gcc jump tables are anonymous data.
++               */
++              if (find_symbol_containing(file->rodata, text_rela->addend))
++                      continue;
++
++              return find_rela_by_dest(file->rodata, text_rela->addend);
+       }
+       return NULL;
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -85,6 +85,18 @@ struct symbol *find_symbol_by_offset(str
+       return NULL;
+ }
++struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
++{
++      struct symbol *sym;
++
++      list_for_each_entry(sym, &sec->symbol_list, list)
++              if (sym->type != STT_SECTION &&
++                  offset >= sym->offset && offset < sym->offset + sym->len)
++                      return sym;
++
++      return NULL;
++}
++
+ struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
+                                    unsigned int len)
+ {
+--- a/tools/objtool/elf.h
++++ b/tools/objtool/elf.h
+@@ -79,6 +79,7 @@ struct elf {
+ struct elf *elf_open(const char *name);
+ struct section *find_section_by_name(struct elf *elf, const char *name);
+ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
++struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
+ struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
+ struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
+                                    unsigned int len);
index a7a70789ca561f4f0d5db0b82077e13eaefc1298..5aca3c4cd00083d977932949784b71b1240b9fac 100644 (file)
@@ -153,3 +153,20 @@ x86-boot-kaslr-fix-kexec-crash-due-to-virt_addr-calculation-bug.patch
 x86-mpx-correctly-report-do_mpx_bt_fault-failures-to-user-space.patch
 x86-mm-fix-flush_tlb_page-on-xen.patch
 ocfs2-o2hb-revert-hb-threshold-to-keep-compatible.patch
+iommu-vt-d-don-t-over-free-page-table-directories.patch
+iommu-handle-default-domain-attach-failure.patch
+iommu-dma-don-t-reserve-pci-i-o-windows.patch
+iommu-amd-fix-incorrect-error-handling-in-amd_iommu_bind_pasid.patch
+iommu-amd-fix-interrupt-remapping-when-disable-guest_mode.patch
+cpufreq-s3c2416-double-free-on-driver-init-error-path.patch
+clk-scpi-don-t-add-cpufreq-device-if-the-scpi-dvfs-node-is-disabled.patch
+objtool-fix-another-gcc-jump-table-detection-issue.patch
+infiniband-hns-avoid-gcc-7.0.1-warning-for-uninitialized-data.patch
+brcmfmac-avoid-writing-channel-out-of-allocated-array.patch
+i2c-brcmstb-fix-start-and-stop-conditions.patch
+mtd-nand-brcmnand-check-flash-wp-pin-status-before-nand-erase-program.patch
+arm64-fix-null-dereference-in-have_cpu_die.patch
+kvm-x86-fix-emulation-of-rsm-and-iret-instructions.patch
+kvm-x86-vpmu-fix-undefined-shift-in-intel_pmu_refresh.patch
+kvm-x86-zero-base3-of-unusable-segments.patch
+kvm-nvmx-fix-exception-injection.patch