From: Greg Kroah-Hartman Date: Mon, 3 Jul 2017 13:04:22 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.60~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e7acdaeb5538079631a80614da4eaf89272cb81;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches 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 --- 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 index 00000000000..67c836fad10 --- /dev/null +++ b/queue-4.9/arm64-fix-null-dereference-in-have_cpu_die.patch @@ -0,0 +1,37 @@ +From 335d2c2d192266358c5dfa64953a4c162f46e464 Mon Sep 17 00:00:00 2001 +From: Mark Salter +Date: Fri, 24 Mar 2017 09:53:56 -0400 +Subject: arm64: fix NULL dereference in have_cpu_die() + +From: Mark Salter + +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 +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..123a8f7f5fd --- /dev/null +++ b/queue-4.9/brcmfmac-avoid-writing-channel-out-of-allocated-array.patch @@ -0,0 +1,110 @@ +From 77c0d0cd10e793989d1e8b835a9a09694182cb39 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 + +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 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d100eac5dbf --- /dev/null +++ b/queue-4.9/clk-scpi-don-t-add-cpufreq-device-if-the-scpi-dvfs-node-is-disabled.patch @@ -0,0 +1,56 @@ +From 67bcc2c5f1da8c5bb58e72354274ea5c59a3950a Mon Sep 17 00:00:00 2001 +From: Sudeep Holla +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 + +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 +Cc: Neil Armstrong +Signed-off-by: Sudeep Holla +Tested-by: Michał Zegan +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8e3ca13fbcd --- /dev/null +++ b/queue-4.9/cpufreq-s3c2416-double-free-on-driver-init-error-path.patch @@ -0,0 +1,33 @@ +From a69261e4470d680185a15f748d9cdafb37c57a33 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 7 Feb 2017 16:19:06 +0300 +Subject: cpufreq: s3c2416: double free on driver init error path + +From: Dan Carpenter + +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 +Reviewed-by: Krzysztof Kozlowski +Acked-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..fdf7bbc89cc --- /dev/null +++ b/queue-4.9/i2c-brcmstb-fix-start-and-stop-conditions.patch @@ -0,0 +1,87 @@ +From 2de3ec4f1d4ba6ee380478055104eb918bd50cce Mon Sep 17 00:00:00 2001 +From: Jaedon Shin +Date: Fri, 3 Mar 2017 10:55:03 +0900 +Subject: i2c: brcmstb: Fix START and STOP conditions + +From: Jaedon Shin + +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 +Acked-by: Kamal Dasu +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3651e32ff67 --- /dev/null +++ b/queue-4.9/infiniband-hns-avoid-gcc-7.0.1-warning-for-uninitialized-data.patch @@ -0,0 +1,43 @@ +From 5b0ff9a00755d4d9c209033a77f1ed8f3186fe5c Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 24 Mar 2017 23:02:48 +0100 +Subject: infiniband: hns: avoid gcc-7.0.1 warning for uninitialized data + +From: Arnd Bergmann + +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 +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..597fdc3783e --- /dev/null +++ b/queue-4.9/iommu-amd-fix-incorrect-error-handling-in-amd_iommu_bind_pasid.patch @@ -0,0 +1,37 @@ +From 73dbd4a4230216b6a5540a362edceae0c9b4876b Mon Sep 17 00:00:00 2001 +From: Pan Bian +Date: Sun, 23 Apr 2017 18:23:21 +0800 +Subject: iommu/amd: Fix incorrect error handling in amd_iommu_bind_pasid() + +From: Pan Bian + +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 +Fixes: f0aac63b873b ('iommu/amd: Don't hold a reference to mm_struct') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ee74b34dffc --- /dev/null +++ b/queue-4.9/iommu-amd-fix-interrupt-remapping-when-disable-guest_mode.patch @@ -0,0 +1,55 @@ +From 84a21dbdef0b96d773599c33c2afbb002198d303 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Mon, 26 Jun 2017 04:28:04 -0500 +Subject: iommu/amd: Fix interrupt remapping when disable guest_mode + +From: Suravee Suthikulpanit + +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 +Cc: Joerg Roedel +Fixes: d98de49a53e48 ('iommu/amd: Enable vAPIC interrupt remapping mode by default') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ad05ac287fd --- /dev/null +++ b/queue-4.9/iommu-dma-don-t-reserve-pci-i-o-windows.patch @@ -0,0 +1,36 @@ +From 938f1bbe35e3a7cb07e1fa7c512e2ef8bb866bdf Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Thu, 16 Mar 2017 17:00:17 +0000 +Subject: iommu/dma: Don't reserve PCI I/O windows + +From: Robin Murphy + +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 +Signed-off-by: Robin Murphy +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..22d4c13611c --- /dev/null +++ b/queue-4.9/iommu-handle-default-domain-attach-failure.patch @@ -0,0 +1,111 @@ +From 797a8b4d768c58caac58ee3e8cb36a164d1b7751 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Mon, 16 Jan 2017 12:58:07 +0000 +Subject: iommu: Handle default domain attach failure + +From: Robin Murphy + +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 +Signed-off-by: Robin Murphy +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..77881a60abd --- /dev/null +++ b/queue-4.9/iommu-vt-d-don-t-over-free-page-table-directories.patch @@ -0,0 +1,57 @@ +From f7116e115acdd74bc75a4daf6492b11d43505125 Mon Sep 17 00:00:00 2001 +From: David Dillow +Date: Mon, 30 Jan 2017 19:11:11 -0800 +Subject: iommu/vt-d: Don't over-free page table directories + +From: David Dillow + +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 +Signed-off-by: David Dillow +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2855eacdab4 --- /dev/null +++ b/queue-4.9/kvm-nvmx-fix-exception-injection.patch @@ -0,0 +1,73 @@ +From d4912215d1031e4fb3d1038d2e1857218dba0d0a Mon Sep 17 00:00:00 2001 +From: Wanpeng Li +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 + +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 +Cc: Radim Krčmář +Signed-off-by: Wanpeng Li +Fixes: e011c663b9c7 ("KVM: nVMX: Check all exceptions for intercept during delivery to L2") +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9a2ecc82bbe --- /dev/null +++ b/queue-4.9/kvm-x86-fix-emulation-of-rsm-and-iret-instructions.patch @@ -0,0 +1,183 @@ +From 6ed071f051e12cf7baa1b69d3becb8f232fdfb7b Mon Sep 17 00:00:00 2001 +From: Ladi Prosek +Date: Tue, 25 Apr 2017 16:42:44 +0200 +Subject: KVM: x86: fix emulation of RSM and IRET instructions + +From: Ladi Prosek + +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 +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c0e4fb52bb5 --- /dev/null +++ b/queue-4.9/kvm-x86-vpmu-fix-undefined-shift-in-intel_pmu_refresh.patch @@ -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?= +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ář + +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 +Fixes: 25462f7f5295 ("KVM: x86/vPMU: Define kvm_pmu_ops to support vPMU function dispatch") +Reviewed-by: Paolo Bonzini +Reviewed-by: David Hildenbrand +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d57c3735a4f --- /dev/null +++ b/queue-4.9/kvm-x86-zero-base3-of-unusable-segments.patch @@ -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?= +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ář + +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 +Fixes: 1aa366163b8b ("KVM: x86 emulator: consolidate segment accessors") +Reviewed-by: Paolo Bonzini +Reviewed-by: David Hildenbrand +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4fb911601cf --- /dev/null +++ b/queue-4.9/mtd-nand-brcmnand-check-flash-wp-pin-status-before-nand-erase-program.patch @@ -0,0 +1,131 @@ +From 9d2ee0a60b8bd9bef2a0082c533736d6a7b39873 Mon Sep 17 00:00:00 2001 +From: Kamal Dasu +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 + +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 +Signed-off-by: Boris Brezillon +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2231d27492d --- /dev/null +++ b/queue-4.9/objtool-fix-another-gcc-jump-table-detection-issue.patch @@ -0,0 +1,99 @@ +From 5c51f4ae84df0f9df33ac08aa5be50061a8b4242 Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf +Date: Thu, 2 Mar 2017 16:57:23 -0600 +Subject: objtool: Fix another GCC jump table detection issue + +From: Josh Poimboeuf + +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 +Tested-by: Arnd Bergmann +Signed-off-by: Josh Poimboeuf +Cc: Denys Vlasenko +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: 3732710ff6f2 ("objtool: Improve rare switch jump table pattern detection") +Link: http://lkml.kernel.org/r/20170302225723.3ndbsnl4hkqbne7a@treble +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.9/series b/queue-4.9/series index a7a70789ca5..5aca3c4cd00 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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