From: Greg Kroah-Hartman Date: Tue, 29 Nov 2016 15:34:34 +0000 (+0100) Subject: 4.8-stable patches X-Git-Tag: v4.4.36~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f9f09e053de2797dc9a5bc21c1c0e0dcf483c991;p=thirdparty%2Fkernel%2Fstable-queue.git 4.8-stable patches added patches: apparmor-fix-change_hat-not-finding-hat-after-policy-replacement.patch can-bcm-fix-support-for-can-fd-frames.patch cfg80211-limit-scan-results-cache-size.patch device-dax-check-devm_nsio_enable-return-value.patch device-dax-fail-all-private-mapping-attempts.patch drm-amdgpu-fix-power-state-when-port-pm-is-unavailable.patch drm-radeon-fix-power-state-when-port-pm-is-unavailable-v2.patch fix-usb-cb-cbi-storage-devices-with-config_vmap_stack-y.patch iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch iommu-vt-d-fix-pasid-table-allocation.patch kvm-x86-check-for-pic-and-ioapic-presence-before-use.patch kvm-x86-drop-error-recovery-in-em_jmp_far-and-em_ret_far.patch kvm-x86-fix-out-of-bounds-access-in-lapic.patch kvm-x86-fix-out-of-bounds-accesses-of-rtc_eoi-map.patch mmc-sdhci-of-esdhc-fixup-present_state-read.patch mpi-fix-null-ptr-dereference-in-mpi_powm.patch nfsv4.x-hide-array-bounds-warning.patch parisc-also-flush-data-tlb-in-flush_icache_page_asm.patch parisc-fix-race-in-pci-dma.c.patch parisc-fix-races-in-parisc_setup_cache_timing.patch parisc-switch-to-generic-sched_clock-implementation.patch perf-core-fix-address-filter-parser.patch perf-x86-intel-cure-bogus-unwind-from-pebs-entries.patch powerpc-boot-fix-the-early-opal-console-wrappers.patch powerpc-mm-fixup-kernel-read-only-mapping.patch powerpc-set-missing-wakeup-bit-in-lpcr-on-power9.patch scsi-mpt3sas-fix-secure-erase-premature-termination.patch thermal-powerclamp-add-back-module-device-table.patch tile-avoid-using-clocksource_cyc2ns-with-absolute-cycle-count.patch usb-chipidea-move-the-lock-initialization-to-core-file.patch usb-serial-cp210x-add-id-for-the-zone-dpmx.patch usb-serial-ftdi_sio-add-support-for-ti-cc3200-launchpad.patch x.509-fix-double-free-in-x509_cert_parse.patch x86-fpu-fix-invalid-fpu-ptrace-state-after-execve.patch x86-traps-ignore-high-word-of-regs-cs-in-early_fixup_exception.patch xc2028-fix-use-after-free-bug-properly.patch --- diff --git a/queue-4.8/apparmor-fix-change_hat-not-finding-hat-after-policy-replacement.patch b/queue-4.8/apparmor-fix-change_hat-not-finding-hat-after-policy-replacement.patch new file mode 100644 index 00000000000..ebdfc3af44c --- /dev/null +++ b/queue-4.8/apparmor-fix-change_hat-not-finding-hat-after-policy-replacement.patch @@ -0,0 +1,48 @@ +From 3d40658c977769ce2138f286cf131537bf68bdfe Mon Sep 17 00:00:00 2001 +From: John Johansen +Date: Wed, 31 Aug 2016 21:10:06 -0700 +Subject: apparmor: fix change_hat not finding hat after policy replacement + +From: John Johansen + +commit 3d40658c977769ce2138f286cf131537bf68bdfe upstream. + +After a policy replacement, the task cred may be out of date and need +to be updated. However change_hat is using the stale profiles from +the out of date cred resulting in either: a stale profile being applied +or, incorrect failure when searching for a hat profile as it has been +migrated to the new parent profile. + +Fixes: 01e2b670aa898a39259bc85c78e3d74820f4d3b6 (failure to find hat) +Fixes: 898127c34ec03291c86f4ff3856d79e9e18952bc (stale policy being applied) +Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000287 +Signed-off-by: John Johansen +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + security/apparmor/domain.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/security/apparmor/domain.c ++++ b/security/apparmor/domain.c +@@ -621,8 +621,8 @@ int aa_change_hat(const char *hats[], in + /* released below */ + cred = get_current_cred(); + cxt = cred_cxt(cred); +- profile = aa_cred_profile(cred); +- previous_profile = cxt->previous; ++ profile = aa_get_newest_profile(aa_cred_profile(cred)); ++ previous_profile = aa_get_newest_profile(cxt->previous); + + if (unconfined(profile)) { + info = "unconfined"; +@@ -718,6 +718,8 @@ audit: + out: + aa_put_profile(hat); + kfree(name); ++ aa_put_profile(profile); ++ aa_put_profile(previous_profile); + put_cred(cred); + + return error; diff --git a/queue-4.8/can-bcm-fix-support-for-can-fd-frames.patch b/queue-4.8/can-bcm-fix-support-for-can-fd-frames.patch new file mode 100644 index 00000000000..ca7b15ec903 --- /dev/null +++ b/queue-4.8/can-bcm-fix-support-for-can-fd-frames.patch @@ -0,0 +1,103 @@ +From 5499a6b22e5508b921c447757685b0a5e40a07ed Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Wed, 23 Nov 2016 14:33:25 +0100 +Subject: can: bcm: fix support for CAN FD frames + +From: Oliver Hartkopp + +commit 5499a6b22e5508b921c447757685b0a5e40a07ed upstream. + +Since commit 6f3b911d5f29b98 ("can: bcm: add support for CAN FD frames") the +CAN broadcast manager supports CAN and CAN FD data frames. + +As these data frames are embedded in struct can[fd]_frames which have a +different length the access to the provided array of CAN frames became +dependend of op->cfsiz. By using a struct canfd_frame pointer for the array of +CAN frames the new offset calculation based on op->cfsiz was accidently applied +to CAN FD frame element lengths. + +This fix makes the pointer to the arrays of the different CAN frame types a +void pointer so that the offset calculation in bytes accesses the correct CAN +frame elements. + +Reference: http://marc.info/?l=linux-netdev&m=147980658909653 + +Reported-by: Andrey Konovalov +Signed-off-by: Oliver Hartkopp +Tested-by: Andrey Konovalov +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + net/can/bcm.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -77,7 +77,7 @@ + (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG) : \ + (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) + +-#define CAN_BCM_VERSION "20160617" ++#define CAN_BCM_VERSION "20161123" + + MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); + MODULE_LICENSE("Dual BSD/GPL"); +@@ -109,8 +109,9 @@ struct bcm_op { + u32 count; + u32 nframes; + u32 currframe; +- struct canfd_frame *frames; +- struct canfd_frame *last_frames; ++ /* void pointers to arrays of struct can[fd]_frame */ ++ void *frames; ++ void *last_frames; + struct canfd_frame sframe; + struct canfd_frame last_sframe; + struct sock *sk; +@@ -681,7 +682,7 @@ static void bcm_rx_handler(struct sk_buf + + if (op->flags & RX_FILTER_ID) { + /* the easiest case */ +- bcm_rx_update_and_send(op, &op->last_frames[0], rxframe); ++ bcm_rx_update_and_send(op, op->last_frames, rxframe); + goto rx_starttimer; + } + +@@ -1068,7 +1069,7 @@ static int bcm_rx_setup(struct bcm_msg_h + + if (msg_head->nframes) { + /* update CAN frames content */ +- err = memcpy_from_msg((u8 *)op->frames, msg, ++ err = memcpy_from_msg(op->frames, msg, + msg_head->nframes * op->cfsiz); + if (err < 0) + return err; +@@ -1118,7 +1119,7 @@ static int bcm_rx_setup(struct bcm_msg_h + } + + if (msg_head->nframes) { +- err = memcpy_from_msg((u8 *)op->frames, msg, ++ err = memcpy_from_msg(op->frames, msg, + msg_head->nframes * op->cfsiz); + if (err < 0) { + if (op->frames != &op->sframe) +@@ -1163,6 +1164,7 @@ static int bcm_rx_setup(struct bcm_msg_h + /* check flags */ + + if (op->flags & RX_RTR_FRAME) { ++ struct canfd_frame *frame0 = op->frames; + + /* no timers in RTR-mode */ + hrtimer_cancel(&op->thrtimer); +@@ -1174,8 +1176,8 @@ static int bcm_rx_setup(struct bcm_msg_h + * prevent a full-load-loopback-test ... ;-] + */ + if ((op->flags & TX_CP_CAN_ID) || +- (op->frames[0].can_id == op->can_id)) +- op->frames[0].can_id = op->can_id & ~CAN_RTR_FLAG; ++ (frame0->can_id == op->can_id)) ++ frame0->can_id = op->can_id & ~CAN_RTR_FLAG; + + } else { + if (op->flags & SETTIMER) { diff --git a/queue-4.8/cfg80211-limit-scan-results-cache-size.patch b/queue-4.8/cfg80211-limit-scan-results-cache-size.patch new file mode 100644 index 00000000000..a75646139a7 --- /dev/null +++ b/queue-4.8/cfg80211-limit-scan-results-cache-size.patch @@ -0,0 +1,159 @@ +From 9853a55ef1bb66d7411136046060bbfb69c714fa Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 15 Nov 2016 12:05:11 +0100 +Subject: cfg80211: limit scan results cache size + +From: Johannes Berg + +commit 9853a55ef1bb66d7411136046060bbfb69c714fa upstream. + +It's possible to make scanning consume almost arbitrary amounts +of memory, e.g. by sending beacon frames with random BSSIDs at +high rates while somebody is scanning. + +Limit the number of BSS table entries we're willing to cache to +1000, limiting maximum memory usage to maybe 4-5MB, but lower +in practice - that would be the case for having both full-sized +beacon and probe response frames for each entry; this seems not +possible in practice, so a limit of 1000 entries will likely be +closer to 0.5 MB. + +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/core.h | 1 + net/wireless/scan.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 70 insertions(+) + +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -71,6 +71,7 @@ struct cfg80211_registered_device { + struct list_head bss_list; + struct rb_root bss_tree; + u32 bss_generation; ++ u32 bss_entries; + struct cfg80211_scan_request *scan_req; /* protected by RTNL */ + struct sk_buff *scan_msg; + struct cfg80211_sched_scan_request __rcu *sched_scan_req; +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -57,6 +57,19 @@ + * also linked into the probe response struct. + */ + ++/* ++ * Limit the number of BSS entries stored in mac80211. Each one is ++ * a bit over 4k at most, so this limits to roughly 4-5M of memory. ++ * If somebody wants to really attack this though, they'd likely ++ * use small beacons, and only one type of frame, limiting each of ++ * the entries to a much smaller size (in order to generate more ++ * entries in total, so overhead is bigger.) ++ */ ++static int bss_entries_limit = 1000; ++module_param(bss_entries_limit, int, 0644); ++MODULE_PARM_DESC(bss_entries_limit, ++ "limit to number of scan BSS entries (per wiphy, default 1000)"); ++ + #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) + + static void bss_free(struct cfg80211_internal_bss *bss) +@@ -137,6 +150,10 @@ static bool __cfg80211_unlink_bss(struct + + list_del_init(&bss->list); + rb_erase(&bss->rbn, &rdev->bss_tree); ++ rdev->bss_entries--; ++ WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list), ++ "rdev bss entries[%d]/list[empty:%d] corruption\n", ++ rdev->bss_entries, list_empty(&rdev->bss_list)); + bss_ref_put(rdev, bss); + return true; + } +@@ -163,6 +180,40 @@ static void __cfg80211_bss_expire(struct + rdev->bss_generation++; + } + ++static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev) ++{ ++ struct cfg80211_internal_bss *bss, *oldest = NULL; ++ bool ret; ++ ++ lockdep_assert_held(&rdev->bss_lock); ++ ++ list_for_each_entry(bss, &rdev->bss_list, list) { ++ if (atomic_read(&bss->hold)) ++ continue; ++ ++ if (!list_empty(&bss->hidden_list) && ++ !bss->pub.hidden_beacon_bss) ++ continue; ++ ++ if (oldest && time_before(oldest->ts, bss->ts)) ++ continue; ++ oldest = bss; ++ } ++ ++ if (WARN_ON(!oldest)) ++ return false; ++ ++ /* ++ * The callers make sure to increase rdev->bss_generation if anything ++ * gets removed (and a new entry added), so there's no need to also do ++ * it here. ++ */ ++ ++ ret = __cfg80211_unlink_bss(rdev, oldest); ++ WARN_ON(!ret); ++ return ret; ++} ++ + void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, + bool send_message) + { +@@ -693,6 +744,7 @@ static bool cfg80211_combine_bsses(struc + const u8 *ie; + int i, ssidlen; + u8 fold = 0; ++ u32 n_entries = 0; + + ies = rcu_access_pointer(new->pub.beacon_ies); + if (WARN_ON(!ies)) +@@ -716,6 +768,12 @@ static bool cfg80211_combine_bsses(struc + /* This is the bad part ... */ + + list_for_each_entry(bss, &rdev->bss_list, list) { ++ /* ++ * we're iterating all the entries anyway, so take the ++ * opportunity to validate the list length accounting ++ */ ++ n_entries++; ++ + if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid)) + continue; + if (bss->pub.channel != new->pub.channel) +@@ -744,6 +802,10 @@ static bool cfg80211_combine_bsses(struc + new->pub.beacon_ies); + } + ++ WARN_ONCE(n_entries != rdev->bss_entries, ++ "rdev bss entries[%d]/list[len:%d] corruption\n", ++ rdev->bss_entries, n_entries); ++ + return true; + } + +@@ -898,7 +960,14 @@ cfg80211_bss_update(struct cfg80211_regi + } + } + ++ if (rdev->bss_entries >= bss_entries_limit && ++ !cfg80211_bss_expire_oldest(rdev)) { ++ kfree(new); ++ goto drop; ++ } ++ + list_add_tail(&new->list, &rdev->bss_list); ++ rdev->bss_entries++; + rb_insert_bss(rdev, new); + found = new; + } diff --git a/queue-4.8/device-dax-check-devm_nsio_enable-return-value.patch b/queue-4.8/device-dax-check-devm_nsio_enable-return-value.patch new file mode 100644 index 00000000000..23b2ecffd67 --- /dev/null +++ b/queue-4.8/device-dax-check-devm_nsio_enable-return-value.patch @@ -0,0 +1,49 @@ +From 6a84fb4b4e439a8ef0ce19ec7e7661ad76f655c9 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Fri, 28 Oct 2016 14:34:51 -0700 +Subject: device-dax: check devm_nsio_enable() return value + +From: Dan Williams + +commit 6a84fb4b4e439a8ef0ce19ec7e7661ad76f655c9 upstream. + +If the dax_pmem driver is passed a resource that is already busy the +driver probe attempt should fail with a message like the following: + + dax_pmem dax0.1: could not reserve region [mem 0x100000000-0x11fffffff] + +However, if we do not catch the error we crash for the obvious reason of +accessing memory that is not mapped. + + BUG: unable to handle kernel paging request at ffffc90020001000 + IP: [] __memcpy+0x12/0x20 + [..] + Call Trace: + [] ? nsio_rw_bytes+0x60/0x180 + [] nd_pfn_validate+0x75/0x320 + [] nvdimm_setup_pfn+0xb9/0x5d0 + [] ? devm_nsio_enable+0xff/0x110 + [] dax_pmem_probe+0x59/0x260 + +Fixes: ab68f2622136 ("/dev/dax, pmem: direct access to persistent memory") +Reported-by: Dave Hansen +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dax/pmem.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/dax/pmem.c ++++ b/drivers/dax/pmem.c +@@ -77,7 +77,9 @@ static int dax_pmem_probe(struct device + nsio = to_nd_namespace_io(&ndns->dev); + + /* parse the 'pfn' info block via ->rw_bytes */ +- devm_nsio_enable(dev, nsio); ++ rc = devm_nsio_enable(dev, nsio); ++ if (rc) ++ return rc; + altmap = nvdimm_setup_pfn(nd_pfn, &res, &__altmap); + if (IS_ERR(altmap)) + return PTR_ERR(altmap); diff --git a/queue-4.8/device-dax-fail-all-private-mapping-attempts.patch b/queue-4.8/device-dax-fail-all-private-mapping-attempts.patch new file mode 100644 index 00000000000..d4a270c5161 --- /dev/null +++ b/queue-4.8/device-dax-fail-all-private-mapping-attempts.patch @@ -0,0 +1,38 @@ +From 4cb19355ea19995941ccaad115dbfac6b75215ca Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 16 Nov 2016 09:00:38 -0800 +Subject: device-dax: fail all private mapping attempts + +From: Dan Williams + +commit 4cb19355ea19995941ccaad115dbfac6b75215ca upstream. + +The device-dax implementation originally tried to be tricky and allow +private read-only mappings, but in the process allowed writable +MAP_PRIVATE + MAP_NORESERVE mappings. For simplicity and predictability +just fail all private mapping attempts since device-dax memory is +statically allocated and will never support overcommit. + +Cc: Dave Hansen +Fixes: dee410792419 ("/dev/dax, core: file operations and dax-mmap") +Reported-by: Pawel Lebioda +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dax/dax.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/dax/dax.c ++++ b/drivers/dax/dax.c +@@ -323,8 +323,8 @@ static int check_vma(struct dax_dev *dax + if (!dax_dev->alive) + return -ENXIO; + +- /* prevent private / writable mappings from being established */ +- if ((vma->vm_flags & (VM_NORESERVE|VM_SHARED|VM_WRITE)) == VM_WRITE) { ++ /* prevent private mappings from being established */ ++ if ((vma->vm_flags & VM_SHARED) != VM_SHARED) { + dev_info(dev, "%s: %s: fail, attempted private mapping\n", + current->comm, func); + return -EINVAL; diff --git a/queue-4.8/drm-amdgpu-fix-power-state-when-port-pm-is-unavailable.patch b/queue-4.8/drm-amdgpu-fix-power-state-when-port-pm-is-unavailable.patch new file mode 100644 index 00000000000..5c0564082f0 --- /dev/null +++ b/queue-4.8/drm-amdgpu-fix-power-state-when-port-pm-is-unavailable.patch @@ -0,0 +1,73 @@ +From 1db4496f167bcc7c6541d449355ade2e7d339d52 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Wed, 23 Nov 2016 02:22:24 +0100 +Subject: drm/amdgpu: fix power state when port pm is unavailable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Wu + +commit 1db4496f167bcc7c6541d449355ade2e7d339d52 upstream. + +When PCIe port PM is not enabled (system BIOS is pre-2015 or the +pcie_port_pm=off parameter is set), legacy ATPX PM should still be +marked as supported. Otherwise the GPU can fail to power on after +runtime suspend. This affected a Dell Inspiron 5548. + +Ideally the BIOS date in the PCI core is lowered to 2013 (the first year +where hybrid graphics platforms using power resources was introduced), +but that seems more risky at this point and would not solve the +pcie_port_pm=off issue. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98505 +Reported-and-tested-by: Nayan Deshmukh +Signed-off-by: Peter Wu +Signed-off-by: Alex Deucher +Acked-by: Christian König +Reviewed-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +@@ -33,6 +33,7 @@ struct amdgpu_atpx { + + static struct amdgpu_atpx_priv { + bool atpx_detected; ++ bool bridge_pm_usable; + /* handle for device - and atpx */ + acpi_handle dhandle; + acpi_handle other_handle; +@@ -200,7 +201,11 @@ static int amdgpu_atpx_validate(struct a + atpx->is_hybrid = false; + if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { + printk("ATPX Hybrid Graphics\n"); +- atpx->functions.power_cntl = false; ++ /* ++ * Disable legacy PM methods only when pcie port PM is usable, ++ * otherwise the device might fail to power off or power on. ++ */ ++ atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable; + atpx->is_hybrid = true; + } + +@@ -471,6 +476,7 @@ static int amdgpu_atpx_power_state(enum + */ + static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev) + { ++ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); + acpi_handle dhandle, atpx_handle; + acpi_status status; + +@@ -485,6 +491,7 @@ static bool amdgpu_atpx_pci_probe_handle + } + amdgpu_atpx_priv.dhandle = dhandle; + amdgpu_atpx_priv.atpx.handle = atpx_handle; ++ amdgpu_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3; + return true; + } + diff --git a/queue-4.8/drm-radeon-fix-power-state-when-port-pm-is-unavailable-v2.patch b/queue-4.8/drm-radeon-fix-power-state-when-port-pm-is-unavailable-v2.patch new file mode 100644 index 00000000000..9f2de752853 --- /dev/null +++ b/queue-4.8/drm-radeon-fix-power-state-when-port-pm-is-unavailable-v2.patch @@ -0,0 +1,70 @@ +From d3ac31f3b4bf9fade93d69770cb9c34912e017be Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Wed, 23 Nov 2016 02:22:25 +0100 +Subject: drm/radeon: fix power state when port pm is unavailable (v2) + +From: Peter Wu + +commit d3ac31f3b4bf9fade93d69770cb9c34912e017be upstream. + +When PCIe port PM is not enabled (system BIOS is pre-2015 or the +pcie_port_pm=off parameter is set), legacy ATPX PM should still be +marked as supported. Otherwise the GPU can fail to power on after +runtime suspend. This affected a Dell Inspiron 5548. + +Ideally the BIOS date in the PCI core is lowered to 2013 (the first year +where hybrid graphics platforms using power resources was introduced), +but that seems more risky at this point and would not solve the +pcie_port_pm=off issue. + +v2: agd: fix typo + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98505 +Signed-off-by: Peter Wu +Signed-off-by: Alex Deucher +Reviewed-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_atpx_handler.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c ++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +@@ -33,6 +33,7 @@ struct radeon_atpx { + + static struct radeon_atpx_priv { + bool atpx_detected; ++ bool bridge_pm_usable; + /* handle for device - and atpx */ + acpi_handle dhandle; + struct radeon_atpx atpx; +@@ -198,7 +199,11 @@ static int radeon_atpx_validate(struct r + atpx->is_hybrid = false; + if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) { + printk("ATPX Hybrid Graphics\n"); +- atpx->functions.power_cntl = false; ++ /* ++ * Disable legacy PM methods only when pcie port PM is usable, ++ * otherwise the device might fail to power off or power on. ++ */ ++ atpx->functions.power_cntl = !radeon_atpx_priv.bridge_pm_usable; + atpx->is_hybrid = true; + } + +@@ -469,6 +474,7 @@ static int radeon_atpx_power_state(enum + */ + static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) + { ++ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); + acpi_handle dhandle, atpx_handle; + acpi_status status; + +@@ -482,6 +488,7 @@ static bool radeon_atpx_pci_probe_handle + + radeon_atpx_priv.dhandle = dhandle; + radeon_atpx_priv.atpx.handle = atpx_handle; ++ radeon_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3; + return true; + } + diff --git a/queue-4.8/fix-usb-cb-cbi-storage-devices-with-config_vmap_stack-y.patch b/queue-4.8/fix-usb-cb-cbi-storage-devices-with-config_vmap_stack-y.patch new file mode 100644 index 00000000000..9d3caf7b98a --- /dev/null +++ b/queue-4.8/fix-usb-cb-cbi-storage-devices-with-config_vmap_stack-y.patch @@ -0,0 +1,43 @@ +From 2ce9d2272b98743b911196c49e7af5841381c206 Mon Sep 17 00:00:00 2001 +From: Petr Vandrovec +Date: Thu, 10 Nov 2016 13:57:14 -0800 +Subject: Fix USB CB/CBI storage devices with CONFIG_VMAP_STACK=y + +From: Petr Vandrovec + +commit 2ce9d2272b98743b911196c49e7af5841381c206 upstream. + +Some code (all error handling) submits CDBs that are allocated +on the stack. This breaks with CB/CBI code that tries to create +URB directly from SCSI command buffer - which happens to be in +vmalloced memory with vmalloced kernel stacks. + +Let's make copy of the command in usb_stor_CB_transport. + +Signed-off-by: Petr Vandrovec +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/transport.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/transport.c ++++ b/drivers/usb/storage/transport.c +@@ -954,10 +954,15 @@ int usb_stor_CB_transport(struct scsi_cm + + /* COMMAND STAGE */ + /* let's send the command via the control pipe */ ++ /* ++ * Command is sometime (f.e. after scsi_eh_prep_cmnd) on the stack. ++ * Stack may be vmallocated. So no DMA for us. Make a copy. ++ */ ++ memcpy(us->iobuf, srb->cmnd, srb->cmd_len); + result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, + US_CBI_ADSC, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, +- us->ifnum, srb->cmnd, srb->cmd_len); ++ us->ifnum, us->iobuf, srb->cmd_len); + + /* check the return code for the command */ + usb_stor_dbg(us, "Call to usb_stor_ctrl_transfer() returned %d\n", diff --git a/queue-4.8/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch b/queue-4.8/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch new file mode 100644 index 00000000000..30f556b1a6d --- /dev/null +++ b/queue-4.8/iommu-vt-d-fix-iommu-lookup-for-sr-iov-virtual-functions.patch @@ -0,0 +1,81 @@ +From 1c387188c60f53b338c20eee32db055dfe022a9b Mon Sep 17 00:00:00 2001 +From: Ashok Raj +Date: Fri, 21 Oct 2016 15:32:05 -0700 +Subject: iommu/vt-d: Fix IOMMU lookup for SR-IOV Virtual Functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ashok Raj + +commit 1c387188c60f53b338c20eee32db055dfe022a9b upstream. + +The VT-d specification (§8.3.3) says: + ‘Virtual Functions’ of a ‘Physical Function’ are under the scope + of the same remapping unit as the ‘Physical Function’. + +The BIOS is not required to list all the possible VFs in the scope +tables, and arguably *shouldn't* make any attempt to do so, since there +could be a huge number of them. + +This has been broken basically for ever — the VF is never going to match +against a specific unit's scope, so it ends up being assigned to the +INCLUDE_ALL IOMMU. Which was always actually correct by coincidence, but +now we're looking at Root-Complex integrated devices with SR-IOV support +it's going to start being wrong. + +Fix it to simply use pci_physfn() before doing the lookup for PCI devices. + +Signed-off-by: Sainath Grandhi +Signed-off-by: Ashok Raj +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dmar.c | 4 +++- + drivers/iommu/intel-iommu.c | 13 +++++++++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -338,7 +338,9 @@ static int dmar_pci_bus_notifier(struct + struct pci_dev *pdev = to_pci_dev(data); + struct dmar_pci_notify_info *info; + +- /* Only care about add/remove events for physical functions */ ++ /* Only care about add/remove events for physical functions. ++ * For VFs we actually do the lookup based on the corresponding ++ * PF in device_to_iommu() anyway. */ + if (pdev->is_virtfn) + return NOTIFY_DONE; + if (action != BUS_NOTIFY_ADD_DEVICE && +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -892,7 +892,13 @@ static struct intel_iommu *device_to_iom + return NULL; + + if (dev_is_pci(dev)) { ++ struct pci_dev *pf_pdev; ++ + pdev = to_pci_dev(dev); ++ /* VFs aren't listed in scope tables; we need to look up ++ * the PF instead to find the IOMMU. */ ++ pf_pdev = pci_physfn(pdev); ++ dev = &pf_pdev->dev; + segment = pci_domain_nr(pdev->bus); + } else if (has_acpi_companion(dev)) + dev = &ACPI_COMPANION(dev)->dev; +@@ -905,6 +911,13 @@ static struct intel_iommu *device_to_iom + for_each_active_dev_scope(drhd->devices, + drhd->devices_cnt, i, tmp) { + if (tmp == dev) { ++ /* For a VF use its original BDF# not that of the PF ++ * which we used for the IOMMU lookup. Strictly speaking ++ * we could do this for all PCI devices; we only need to ++ * get the BDF# from the scope table for ACPI matches. */ ++ if (pdev->is_virtfn) ++ goto got_pdev; ++ + *bus = drhd->devices[i].bus; + *devfn = drhd->devices[i].devfn; + goto out; diff --git a/queue-4.8/iommu-vt-d-fix-pasid-table-allocation.patch b/queue-4.8/iommu-vt-d-fix-pasid-table-allocation.patch new file mode 100644 index 00000000000..1f2f154f45c --- /dev/null +++ b/queue-4.8/iommu-vt-d-fix-pasid-table-allocation.patch @@ -0,0 +1,102 @@ +From 910170442944e1f8674fd5ddbeeb8ccd1877ea98 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Mon, 12 Sep 2016 10:49:11 +0800 +Subject: iommu/vt-d: Fix PASID table allocation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Woodhouse + +commit 910170442944e1f8674fd5ddbeeb8ccd1877ea98 upstream. + +Somehow I ended up with an off-by-three error in calculating the size of +the PASID and PASID State tables, which triggers allocations failures as +those tables unfortunately have to be physically contiguous. + +In fact, even the *correct* maximum size of 8MiB is problematic and is +wont to lead to allocation failures. Since I have extracted a promise +that this *will* be fixed in hardware, I'm happy to limit it on the +current hardware to a maximum of 0x20000 PASIDs, which gives us 1MiB +tables — still not ideal, but better than before. + +Reported by Mika Kuoppala and also by +Xunlei Pang who submitted a simpler patch to fix +only the allocation (and not the free) to the "correct" limit... which +was still problematic. + +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/intel-svm.c | 26 ++++++++++++++++---------- + include/linux/intel-iommu.h | 1 + + 2 files changed, 17 insertions(+), 10 deletions(-) + +--- a/drivers/iommu/intel-svm.c ++++ b/drivers/iommu/intel-svm.c +@@ -39,10 +39,18 @@ int intel_svm_alloc_pasid_tables(struct + struct page *pages; + int order; + +- order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; +- if (order < 0) +- order = 0; ++ /* Start at 2 because it's defined as 2^(1+PSS) */ ++ iommu->pasid_max = 2 << ecap_pss(iommu->ecap); + ++ /* Eventually I'm promised we will get a multi-level PASID table ++ * and it won't have to be physically contiguous. Until then, ++ * limit the size because 8MiB contiguous allocations can be hard ++ * to come by. The limit of 0x20000, which is 1MiB for each of ++ * the PASID and PASID-state tables, is somewhat arbitrary. */ ++ if (iommu->pasid_max > 0x20000) ++ iommu->pasid_max = 0x20000; ++ ++ order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); + if (!pages) { + pr_warn("IOMMU: %s: Failed to allocate PASID table\n", +@@ -53,6 +61,8 @@ int intel_svm_alloc_pasid_tables(struct + pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order); + + if (ecap_dis(iommu->ecap)) { ++ /* Just making it explicit... */ ++ BUILD_BUG_ON(sizeof(struct pasid_entry) != sizeof(struct pasid_state_entry)); + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); + if (pages) + iommu->pasid_state_table = page_address(pages); +@@ -68,11 +78,7 @@ int intel_svm_alloc_pasid_tables(struct + + int intel_svm_free_pasid_tables(struct intel_iommu *iommu) + { +- int order; +- +- order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT; +- if (order < 0) +- order = 0; ++ int order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); + + if (iommu->pasid_table) { + free_pages((unsigned long)iommu->pasid_table, order); +@@ -371,8 +377,8 @@ int intel_svm_bind_mm(struct device *dev + } + svm->iommu = iommu; + +- if (pasid_max > 2 << ecap_pss(iommu->ecap)) +- pasid_max = 2 << ecap_pss(iommu->ecap); ++ if (pasid_max > iommu->pasid_max) ++ pasid_max = iommu->pasid_max; + + /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ + ret = idr_alloc(&iommu->pasid_idr, svm, +--- a/include/linux/intel-iommu.h ++++ b/include/linux/intel-iommu.h +@@ -429,6 +429,7 @@ struct intel_iommu { + struct page_req_dsc *prq; + unsigned char prq_name[16]; /* Name for PRQ interrupt */ + struct idr pasid_idr; ++ u32 pasid_max; + #endif + struct q_inval *qi; /* Queued invalidation info */ + u32 *iommu_state; /* Store iommu states between suspend and resume.*/ diff --git a/queue-4.8/kvm-x86-check-for-pic-and-ioapic-presence-before-use.patch b/queue-4.8/kvm-x86-check-for-pic-and-ioapic-presence-before-use.patch new file mode 100644 index 00000000000..06172cd8ec0 --- /dev/null +++ b/queue-4.8/kvm-x86-check-for-pic-and-ioapic-presence-before-use.patch @@ -0,0 +1,92 @@ +From df492896e6dfb44fd1154f5402428d8e52705081 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= +Date: Wed, 23 Nov 2016 21:25:48 +0100 +Subject: KVM: x86: check for pic and ioapic presence before use +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Radim Krčmář + +commit df492896e6dfb44fd1154f5402428d8e52705081 upstream. + +Split irqchip allows pic and ioapic routes to be used without them being +created, which results in NULL access. Check for NULL and avoid it. +(The setup is too racy for a nicer solutions.) + +Found by syzkaller: + + general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN + Dumping ftrace buffer: + (ftrace buffer empty) + Modules linked in: + CPU: 3 PID: 11923 Comm: kworker/3:2 Not tainted 4.9.0-rc5+ #27 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + Workqueue: events irqfd_inject + task: ffff88006a06c7c0 task.stack: ffff880068638000 + RIP: 0010:[...] [...] __lock_acquire+0xb35/0x3380 kernel/locking/lockdep.c:3221 + RSP: 0000:ffff88006863ea20 EFLAGS: 00010006 + RAX: dffffc0000000000 RBX: dffffc0000000000 RCX: 0000000000000000 + RDX: 0000000000000039 RSI: 0000000000000000 RDI: 1ffff1000d0c7d9e + RBP: ffff88006863ef58 R08: 0000000000000001 R09: 0000000000000000 + R10: 00000000000001c8 R11: 0000000000000000 R12: ffff88006a06c7c0 + R13: 0000000000000001 R14: ffffffff8baab1a0 R15: 0000000000000001 + FS: 0000000000000000(0000) GS:ffff88006d100000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00000000004abdd0 CR3: 000000003e2f2000 CR4: 00000000000026e0 + Stack: + ffffffff894d0098 1ffff1000d0c7d56 ffff88006863ecd0 dffffc0000000000 + ffff88006a06c7c0 0000000000000000 ffff88006863ecf8 0000000000000082 + 0000000000000000 ffffffff815dd7c1 ffffffff00000000 ffffffff00000000 + Call Trace: + [...] lock_acquire+0x2a2/0x790 kernel/locking/lockdep.c:3746 + [...] __raw_spin_lock include/linux/spinlock_api_smp.h:144 + [...] _raw_spin_lock+0x38/0x50 kernel/locking/spinlock.c:151 + [...] spin_lock include/linux/spinlock.h:302 + [...] kvm_ioapic_set_irq+0x4c/0x100 arch/x86/kvm/ioapic.c:379 + [...] kvm_set_ioapic_irq+0x8f/0xc0 arch/x86/kvm/irq_comm.c:52 + [...] kvm_set_irq+0x239/0x640 arch/x86/kvm/../../../virt/kvm/irqchip.c:101 + [...] irqfd_inject+0xb4/0x150 arch/x86/kvm/../../../virt/kvm/eventfd.c:60 + [...] process_one_work+0xb40/0x1ba0 kernel/workqueue.c:2096 + [...] worker_thread+0x214/0x18a0 kernel/workqueue.c:2230 + [...] kthread+0x328/0x3e0 kernel/kthread.c:209 + [...] ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:433 + +Reported-by: Dmitry Vyukov +Fixes: 49df6397edfc ("KVM: x86: Split the APIC from the rest of IRQCHIP.") +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/irq_comm.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/x86/kvm/irq_comm.c ++++ b/arch/x86/kvm/irq_comm.c +@@ -41,6 +41,15 @@ static int kvm_set_pic_irq(struct kvm_ke + bool line_status) + { + struct kvm_pic *pic = pic_irqchip(kvm); ++ ++ /* ++ * XXX: rejecting pic routes when pic isn't in use would be better, ++ * but the default routing table is installed while kvm->arch.vpic is ++ * NULL and KVM_CREATE_IRQCHIP can race with KVM_IRQ_LINE. ++ */ ++ if (!pic) ++ return -1; ++ + return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); + } + +@@ -49,6 +58,10 @@ static int kvm_set_ioapic_irq(struct kvm + bool line_status) + { + struct kvm_ioapic *ioapic = kvm->arch.vioapic; ++ ++ if (!ioapic) ++ return -1; ++ + return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level, + line_status); + } diff --git a/queue-4.8/kvm-x86-drop-error-recovery-in-em_jmp_far-and-em_ret_far.patch b/queue-4.8/kvm-x86-drop-error-recovery-in-em_jmp_far-and-em_ret_far.patch new file mode 100644 index 00000000000..96b183bd496 --- /dev/null +++ b/queue-4.8/kvm-x86-drop-error-recovery-in-em_jmp_far-and-em_ret_far.patch @@ -0,0 +1,128 @@ +From 2117d5398c81554fbf803f5fd1dc55eb78216c0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= +Date: Wed, 23 Nov 2016 21:15:00 +0100 +Subject: KVM: x86: drop error recovery in em_jmp_far and em_ret_far +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Radim Krčmář + +commit 2117d5398c81554fbf803f5fd1dc55eb78216c0c upstream. + +em_jmp_far and em_ret_far assumed that setting IP can only fail in 64 +bit mode, but syzkaller proved otherwise (and SDM agrees). +Code segment was restored upon failure, but it was left uninitialized +outside of long mode, which could lead to a leak of host kernel stack. +We could have fixed that by always saving and restoring the CS, but we +take a simpler approach and just break any guest that manages to fail +as the error recovery is error-prone and modern CPUs don't need emulator +for this. + +Found by syzkaller: + + WARNING: CPU: 2 PID: 3668 at arch/x86/kvm/emulate.c:2217 em_ret_far+0x428/0x480 + Kernel panic - not syncing: panic_on_warn set ... + + CPU: 2 PID: 3668 Comm: syz-executor Not tainted 4.9.0-rc4+ #49 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + [...] + Call Trace: + [...] __dump_stack lib/dump_stack.c:15 + [...] dump_stack+0xb3/0x118 lib/dump_stack.c:51 + [...] panic+0x1b7/0x3a3 kernel/panic.c:179 + [...] __warn+0x1c4/0x1e0 kernel/panic.c:542 + [...] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585 + [...] em_ret_far+0x428/0x480 arch/x86/kvm/emulate.c:2217 + [...] em_ret_far_imm+0x17/0x70 arch/x86/kvm/emulate.c:2227 + [...] x86_emulate_insn+0x87a/0x3730 arch/x86/kvm/emulate.c:5294 + [...] x86_emulate_instruction+0x520/0x1ba0 arch/x86/kvm/x86.c:5545 + [...] emulate_instruction arch/x86/include/asm/kvm_host.h:1116 + [...] complete_emulated_io arch/x86/kvm/x86.c:6870 + [...] complete_emulated_mmio+0x4e9/0x710 arch/x86/kvm/x86.c:6934 + [...] kvm_arch_vcpu_ioctl_run+0x3b7a/0x5a90 arch/x86/kvm/x86.c:6978 + [...] kvm_vcpu_ioctl+0x61e/0xdd0 arch/x86/kvm/../../../virt/kvm/kvm_main.c:2557 + [...] vfs_ioctl fs/ioctl.c:43 + [...] do_vfs_ioctl+0x18c/0x1040 fs/ioctl.c:679 + [...] SYSC_ioctl fs/ioctl.c:694 + [...] SyS_ioctl+0x8f/0xc0 fs/ioctl.c:685 + [...] entry_SYSCALL_64_fastpath+0x1f/0xc2 + +Reported-by: Dmitry Vyukov +Fixes: d1442d85cc30 ("KVM: x86: Handle errors when RIP is set during far jumps") +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/emulate.c | 36 +++++++++++------------------------- + 1 file changed, 11 insertions(+), 25 deletions(-) + +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -2105,16 +2105,10 @@ static int em_iret(struct x86_emulate_ct + static int em_jmp_far(struct x86_emulate_ctxt *ctxt) + { + int rc; +- unsigned short sel, old_sel; +- struct desc_struct old_desc, new_desc; +- const struct x86_emulate_ops *ops = ctxt->ops; ++ unsigned short sel; ++ struct desc_struct new_desc; + u8 cpl = ctxt->ops->cpl(ctxt); + +- /* Assignment of RIP may only fail in 64-bit mode */ +- if (ctxt->mode == X86EMUL_MODE_PROT64) +- ops->get_segment(ctxt, &old_sel, &old_desc, NULL, +- VCPU_SREG_CS); +- + memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); + + rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl, +@@ -2124,12 +2118,10 @@ static int em_jmp_far(struct x86_emulate + return rc; + + rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); +- if (rc != X86EMUL_CONTINUE) { +- WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); +- /* assigning eip failed; restore the old cs */ +- ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); +- return rc; +- } ++ /* Error handling is not implemented. */ ++ if (rc != X86EMUL_CONTINUE) ++ return X86EMUL_UNHANDLEABLE; ++ + return rc; + } + +@@ -2189,14 +2181,8 @@ static int em_ret_far(struct x86_emulate + { + int rc; + unsigned long eip, cs; +- u16 old_cs; + int cpl = ctxt->ops->cpl(ctxt); +- struct desc_struct old_desc, new_desc; +- const struct x86_emulate_ops *ops = ctxt->ops; +- +- if (ctxt->mode == X86EMUL_MODE_PROT64) +- ops->get_segment(ctxt, &old_cs, &old_desc, NULL, +- VCPU_SREG_CS); ++ struct desc_struct new_desc; + + rc = emulate_pop(ctxt, &eip, ctxt->op_bytes); + if (rc != X86EMUL_CONTINUE) +@@ -2213,10 +2199,10 @@ static int em_ret_far(struct x86_emulate + if (rc != X86EMUL_CONTINUE) + return rc; + rc = assign_eip_far(ctxt, eip, &new_desc); +- if (rc != X86EMUL_CONTINUE) { +- WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); +- ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); +- } ++ /* Error handling is not implemented. */ ++ if (rc != X86EMUL_CONTINUE) ++ return X86EMUL_UNHANDLEABLE; ++ + return rc; + } + diff --git a/queue-4.8/kvm-x86-fix-out-of-bounds-access-in-lapic.patch b/queue-4.8/kvm-x86-fix-out-of-bounds-access-in-lapic.patch new file mode 100644 index 00000000000..b458156a61f --- /dev/null +++ b/queue-4.8/kvm-x86-fix-out-of-bounds-access-in-lapic.patch @@ -0,0 +1,64 @@ +From 444fdad88f35de9fd1c130b2c4e4550671758fd2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= +Date: Tue, 22 Nov 2016 20:20:14 +0100 +Subject: KVM: x86: fix out-of-bounds access in lapic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Radim Krčmář + +commit 444fdad88f35de9fd1c130b2c4e4550671758fd2 upstream. + +Cluster xAPIC delivery incorrectly assumed that dest_id <= 0xff. +With enabled KVM_X2APIC_API_USE_32BIT_IDS in KVM_CAP_X2APIC_API, a +userspace can send an interrupt with dest_id that results in +out-of-bounds access. + +Found by syzkaller: + + BUG: KASAN: slab-out-of-bounds in kvm_irq_delivery_to_apic_fast+0x11fa/0x1210 at addr ffff88003d9ca750 + Read of size 8 by task syz-executor/22923 + CPU: 0 PID: 22923 Comm: syz-executor Not tainted 4.9.0-rc4+ #49 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + [...] + Call Trace: + [...] __dump_stack lib/dump_stack.c:15 + [...] dump_stack+0xb3/0x118 lib/dump_stack.c:51 + [...] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156 + [...] print_address_description mm/kasan/report.c:194 + [...] kasan_report_error mm/kasan/report.c:283 + [...] kasan_report+0x231/0x500 mm/kasan/report.c:303 + [...] __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:329 + [...] kvm_irq_delivery_to_apic_fast+0x11fa/0x1210 arch/x86/kvm/lapic.c:824 + [...] kvm_irq_delivery_to_apic+0x132/0x9a0 arch/x86/kvm/irq_comm.c:72 + [...] kvm_set_msi+0x111/0x160 arch/x86/kvm/irq_comm.c:157 + [...] kvm_send_userspace_msi+0x201/0x280 arch/x86/kvm/../../../virt/kvm/irqchip.c:74 + [...] kvm_vm_ioctl+0xba5/0x1670 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3015 + [...] vfs_ioctl fs/ioctl.c:43 + [...] do_vfs_ioctl+0x18c/0x1040 fs/ioctl.c:679 + [...] SYSC_ioctl fs/ioctl.c:694 + [...] SyS_ioctl+0x8f/0xc0 fs/ioctl.c:685 + [...] entry_SYSCALL_64_fastpath+0x1f/0xc2 + +Reported-by: Dmitry Vyukov +Fixes: e45115b62f9a ("KVM: x86: use physical LAPIC array for logical x2APIC") +Reviewed-by: Paolo Bonzini +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/lapic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -138,7 +138,7 @@ static inline bool kvm_apic_map_get_logi + *mask = dest_id & 0xff; + return true; + case KVM_APIC_MODE_XAPIC_CLUSTER: +- *cluster = map->xapic_cluster_map[dest_id >> 4]; ++ *cluster = map->xapic_cluster_map[(dest_id >> 4) & 0xf]; + *mask = dest_id & 0xf; + return true; + default: diff --git a/queue-4.8/kvm-x86-fix-out-of-bounds-accesses-of-rtc_eoi-map.patch b/queue-4.8/kvm-x86-fix-out-of-bounds-accesses-of-rtc_eoi-map.patch new file mode 100644 index 00000000000..64803f25f12 --- /dev/null +++ b/queue-4.8/kvm-x86-fix-out-of-bounds-accesses-of-rtc_eoi-map.patch @@ -0,0 +1,76 @@ +From 81cdb259fb6d8c1c4ecfeea389ff5a73c07f5755 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= +Date: Wed, 23 Nov 2016 21:15:27 +0100 +Subject: KVM: x86: fix out-of-bounds accesses of rtc_eoi map +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Radim Krčmář + +commit 81cdb259fb6d8c1c4ecfeea389ff5a73c07f5755 upstream. + +KVM was using arrays of size KVM_MAX_VCPUS with vcpu_id, but ID can be +bigger that the maximal number of VCPUs, resulting in out-of-bounds +access. + +Found by syzkaller: + + BUG: KASAN: slab-out-of-bounds in __apic_accept_irq+0xb33/0xb50 at addr [...] + Write of size 1 by task a.out/27101 + CPU: 1 PID: 27101 Comm: a.out Not tainted 4.9.0-rc5+ #49 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + [...] + Call Trace: + [...] __apic_accept_irq+0xb33/0xb50 arch/x86/kvm/lapic.c:905 + [...] kvm_apic_set_irq+0x10e/0x180 arch/x86/kvm/lapic.c:495 + [...] kvm_irq_delivery_to_apic+0x732/0xc10 arch/x86/kvm/irq_comm.c:86 + [...] ioapic_service+0x41d/0x760 arch/x86/kvm/ioapic.c:360 + [...] ioapic_set_irq+0x275/0x6c0 arch/x86/kvm/ioapic.c:222 + [...] kvm_ioapic_inject_all arch/x86/kvm/ioapic.c:235 + [...] kvm_set_ioapic+0x223/0x310 arch/x86/kvm/ioapic.c:670 + [...] kvm_vm_ioctl_set_irqchip arch/x86/kvm/x86.c:3668 + [...] kvm_arch_vm_ioctl+0x1a08/0x23c0 arch/x86/kvm/x86.c:3999 + [...] kvm_vm_ioctl+0x1fa/0x1a70 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3099 + +Reported-by: Dmitry Vyukov +Fixes: af1bae5497b9 ("KVM: x86: bump KVM_MAX_VCPU_ID to 1023") +Reviewed-by: Paolo Bonzini +Reviewed-by: David Hildenbrand +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/ioapic.c | 2 +- + arch/x86/kvm/ioapic.h | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/x86/kvm/ioapic.c ++++ b/arch/x86/kvm/ioapic.c +@@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirec + static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) + { + ioapic->rtc_status.pending_eoi = 0; +- bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPUS); ++ bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID); + } + + static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); +--- a/arch/x86/kvm/ioapic.h ++++ b/arch/x86/kvm/ioapic.h +@@ -42,13 +42,13 @@ struct kvm_vcpu; + + struct dest_map { + /* vcpu bitmap where IRQ has been sent */ +- DECLARE_BITMAP(map, KVM_MAX_VCPUS); ++ DECLARE_BITMAP(map, KVM_MAX_VCPU_ID); + + /* + * Vector sent to a given vcpu, only valid when + * the vcpu's bit in map is set + */ +- u8 vectors[KVM_MAX_VCPUS]; ++ u8 vectors[KVM_MAX_VCPU_ID]; + }; + + diff --git a/queue-4.8/mmc-sdhci-of-esdhc-fixup-present_state-read.patch b/queue-4.8/mmc-sdhci-of-esdhc-fixup-present_state-read.patch new file mode 100644 index 00000000000..ae15a265bcb --- /dev/null +++ b/queue-4.8/mmc-sdhci-of-esdhc-fixup-present_state-read.patch @@ -0,0 +1,65 @@ +From b0921d5c9ed6ffa8a4d6afc5ee5f136b87445f14 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Tue, 15 Nov 2016 11:13:16 +0100 +Subject: mmc: sdhci-of-esdhc: fixup PRESENT_STATE read + +From: Michael Walle + +commit b0921d5c9ed6ffa8a4d6afc5ee5f136b87445f14 upstream. + +Since commit 87a18a6a5652 ("mmc: mmc: Use ->card_busy() to detect busy +cards in __mmc_switch()") the ESDHC driver is broken: + mmc0: Card stuck in programming state! __mmc_switch + mmc0: error -110 whilst initialising MMC card + +Since this commit __mmc_switch() uses ->card_busy(), which is +sdhci_card_busy() for the esdhc driver. sdhci_card_busy() uses the +PRESENT_STATE register, specifically the DAT0 signal level bit. But the +ESDHC uses a non-conformant PRESENT_STATE register, thus a read fixup is +required to make the driver work again. + +Signed-off-by: Michael Walle +Fixes: 87a18a6a5652 ("mmc: mmc: Use ->card_busy() to detect busy cards in __mmc_switch()") +Acked-by: Yangbo Lu +Acked-by: Adrian Hunter +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-of-esdhc.c | 14 ++++++++++++++ + drivers/mmc/host/sdhci.h | 1 + + 2 files changed, 15 insertions(+) + +--- a/drivers/mmc/host/sdhci-of-esdhc.c ++++ b/drivers/mmc/host/sdhci-of-esdhc.c +@@ -66,6 +66,20 @@ static u32 esdhc_readl_fixup(struct sdhc + return ret; + } + } ++ /* ++ * The DAT[3:0] line signal levels and the CMD line signal level are ++ * not compatible with standard SDHC register. The line signal levels ++ * DAT[7:0] are at bits 31:24 and the command line signal level is at ++ * bit 23. All other bits are the same as in the standard SDHC ++ * register. ++ */ ++ if (spec_reg == SDHCI_PRESENT_STATE) { ++ ret = value & 0x000fffff; ++ ret |= (value >> 4) & SDHCI_DATA_LVL_MASK; ++ ret |= (value << 1) & SDHCI_CMD_LVL; ++ return ret; ++ } ++ + ret = value; + return ret; + } +--- a/drivers/mmc/host/sdhci.h ++++ b/drivers/mmc/host/sdhci.h +@@ -73,6 +73,7 @@ + #define SDHCI_DATA_LVL_MASK 0x00F00000 + #define SDHCI_DATA_LVL_SHIFT 20 + #define SDHCI_DATA_0_LVL_MASK 0x00100000 ++#define SDHCI_CMD_LVL 0x01000000 + + #define SDHCI_HOST_CONTROL 0x28 + #define SDHCI_CTRL_LED 0x01 diff --git a/queue-4.8/mpi-fix-null-ptr-dereference-in-mpi_powm.patch b/queue-4.8/mpi-fix-null-ptr-dereference-in-mpi_powm.patch new file mode 100644 index 00000000000..548ea402023 --- /dev/null +++ b/queue-4.8/mpi-fix-null-ptr-dereference-in-mpi_powm.patch @@ -0,0 +1,100 @@ +From f5527fffff3f002b0a6b376163613b82f69de073 Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Thu, 24 Nov 2016 13:23:10 +0000 +Subject: mpi: Fix NULL ptr dereference in mpi_powm() [ver #3] + +From: Andrey Ryabinin + +commit f5527fffff3f002b0a6b376163613b82f69de073 upstream. + +This fixes CVE-2016-8650. + +If mpi_powm() is given a zero exponent, it wants to immediately return +either 1 or 0, depending on the modulus. However, if the result was +initalised with zero limb space, no limbs space is allocated and a +NULL-pointer exception ensues. + +Fix this by allocating a minimal amount of limb space for the result when +the 0-exponent case when the result is 1 and not touching the limb space +when the result is 0. + +This affects the use of RSA keys and X.509 certificates that carry them. + +BUG: unable to handle kernel NULL pointer dereference at (null) +IP: [] mpi_powm+0x32/0x7e6 +PGD 0 +Oops: 0002 [#1] SMP +Modules linked in: +CPU: 3 PID: 3014 Comm: keyctl Not tainted 4.9.0-rc6-fscache+ #278 +Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014 +task: ffff8804011944c0 task.stack: ffff880401294000 +RIP: 0010:[] [] mpi_powm+0x32/0x7e6 +RSP: 0018:ffff880401297ad8 EFLAGS: 00010212 +RAX: 0000000000000000 RBX: ffff88040868bec0 RCX: ffff88040868bba0 +RDX: ffff88040868b260 RSI: ffff88040868bec0 RDI: ffff88040868bee0 +RBP: ffff880401297ba8 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000047 R11: ffffffff8183b210 R12: 0000000000000000 +R13: ffff8804087c7600 R14: 000000000000001f R15: ffff880401297c50 +FS: 00007f7a7918c700(0000) GS:ffff88041fb80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000000 CR3: 0000000401250000 CR4: 00000000001406e0 +Stack: + ffff88040868bec0 0000000000000020 ffff880401297b00 ffffffff81376cd4 + 0000000000000100 ffff880401297b10 ffffffff81376d12 ffff880401297b30 + ffffffff81376f37 0000000000000100 0000000000000000 ffff880401297ba8 +Call Trace: + [] ? __sg_page_iter_next+0x43/0x66 + [] ? sg_miter_get_next_page+0x1b/0x5d + [] ? sg_miter_next+0x17/0xbd + [] ? mpi_read_raw_from_sgl+0xf2/0x146 + [] rsa_verify+0x9d/0xee + [] ? pkcs1pad_sg_set_buf+0x2e/0xbb + [] pkcs1pad_verify+0xc0/0xe1 + [] public_key_verify_signature+0x1b0/0x228 + [] x509_check_for_self_signed+0xa1/0xc4 + [] x509_cert_parse+0x167/0x1a1 + [] x509_key_preparse+0x21/0x1a1 + [] asymmetric_key_preparse+0x34/0x61 + [] key_create_or_update+0x145/0x399 + [] SyS_add_key+0x154/0x19e + [] do_syscall_64+0x80/0x191 + [] entry_SYSCALL64_slow_path+0x25/0x25 +Code: 56 41 55 41 54 53 48 81 ec a8 00 00 00 44 8b 71 04 8b 42 04 4c 8b 67 18 45 85 f6 89 45 80 0f 84 b4 06 00 00 85 c0 75 2f 41 ff ce <49> c7 04 24 01 00 00 00 b0 01 75 0b 48 8b 41 18 48 83 38 01 0f +RIP [] mpi_powm+0x32/0x7e6 + RSP +CR2: 0000000000000000 +---[ end trace d82015255d4a5d8d ]--- + +Basically, this is a backport of a libgcrypt patch: + + http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=6e1adb05d290aeeb1c230c763970695f4a538526 + +Fixes: cdec9cb5167a ("crypto: GnuPG based MPI lib - source files (part 1)") +Signed-off-by: Andrey Ryabinin +Signed-off-by: David Howells +cc: Dmitry Kasatkin +cc: linux-ima-devel@lists.sourceforge.net +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + lib/mpi/mpi-pow.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/lib/mpi/mpi-pow.c ++++ b/lib/mpi/mpi-pow.c +@@ -64,8 +64,13 @@ int mpi_powm(MPI res, MPI base, MPI exp, + if (!esize) { + /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 + * depending on if MOD equals 1. */ +- rp[0] = 1; + res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1; ++ if (res->nlimbs) { ++ if (mpi_resize(res, 1) < 0) ++ goto enomem; ++ rp = res->d; ++ rp[0] = 1; ++ } + res->sign = 0; + goto leave; + } diff --git a/queue-4.8/nfsv4.x-hide-array-bounds-warning.patch b/queue-4.8/nfsv4.x-hide-array-bounds-warning.patch new file mode 100644 index 00000000000..1c35c94a2b6 --- /dev/null +++ b/queue-4.8/nfsv4.x-hide-array-bounds-warning.patch @@ -0,0 +1,46 @@ +From d55b352b01bc78fbc3d1bb650140668b87e58bf9 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 22 Nov 2016 21:50:52 +0100 +Subject: NFSv4.x: hide array-bounds warning + +From: Arnd Bergmann + +commit d55b352b01bc78fbc3d1bb650140668b87e58bf9 upstream. + +A correct bugfix introduced a harmless warning that shows up with gcc-7: + +fs/nfs/callback.c: In function 'nfs_callback_up': +fs/nfs/callback.c:214:14: error: array subscript is outside array bounds [-Werror=array-bounds] + +What happens here is that the 'minorversion == 0' check tells the +compiler that we assume minorversion can be something other than 0, +but when CONFIG_NFS_V4_1 is disabled that would be invalid and +result in an out-of-bounds access. + +The added check for IS_ENABLED(CONFIG_NFS_V4_1) tells gcc that this +really can't happen, which makes the code slightly smaller and also +avoids the warning. + +The bugfix that introduced the warning is marked for stable backports, +we want this one backported to the same releases. + +Fixes: 98b0f80c2396 ("NFSv4.x: Fix a refcount leak in nfs_callback_up_net") +Signed-off-by: Arnd Bergmann +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/callback.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/callback.c ++++ b/fs/nfs/callback.c +@@ -261,7 +261,7 @@ static int nfs_callback_up_net(int minor + } + + ret = -EPROTONOSUPPORT; +- if (minorversion == 0) ++ if (!IS_ENABLED(CONFIG_NFS_V4_1) || minorversion == 0) + ret = nfs4_callback_up_net(serv, net); + else if (xprt->ops->bc_up) + ret = xprt->ops->bc_up(serv, net); diff --git a/queue-4.8/parisc-also-flush-data-tlb-in-flush_icache_page_asm.patch b/queue-4.8/parisc-also-flush-data-tlb-in-flush_icache_page_asm.patch new file mode 100644 index 00000000000..fb4e2611e57 --- /dev/null +++ b/queue-4.8/parisc-also-flush-data-tlb-in-flush_icache_page_asm.patch @@ -0,0 +1,141 @@ +From 5035b230e7b67ac12691ed3b5495bbb617027b68 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Thu, 24 Nov 2016 20:18:14 -0500 +Subject: parisc: Also flush data TLB in flush_icache_page_asm + +From: John David Anglin + +commit 5035b230e7b67ac12691ed3b5495bbb617027b68 upstream. + +This is the second issue I noticed in reviewing the parisc TLB code. + +The fic instruction may use either the instruction or data TLB in +flushing the instruction cache. Thus, on machines with a split TLB, we +should also flush the data TLB after setting up the temporary alias +registers. + +Although this has no functional impact, I changed the pdtlb and pitlb +instructions to consistently use the index register %r0. These +instructions do not support integer displacements. + +Tested on rp3440 and c8000. + +Signed-off-by: John David Anglin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/pacache.S | 37 ++++++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 15 deletions(-) + +--- a/arch/parisc/kernel/pacache.S ++++ b/arch/parisc/kernel/pacache.S +@@ -96,7 +96,7 @@ fitmanyloop: /* Loop if LOOP >= 2 */ + + fitmanymiddle: /* Loop if LOOP >= 2 */ + addib,COND(>) -1, %r31, fitmanymiddle /* Adjusted inner loop decr */ +- pitlbe 0(%sr1, %r28) ++ pitlbe %r0(%sr1, %r28) + pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */ + addib,COND(>) -1, %r29, fitmanymiddle /* Middle loop decr */ + copy %arg3, %r31 /* Re-init inner loop count */ +@@ -139,7 +139,7 @@ fdtmanyloop: /* Loop if LOOP >= 2 */ + + fdtmanymiddle: /* Loop if LOOP >= 2 */ + addib,COND(>) -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */ +- pdtlbe 0(%sr1, %r28) ++ pdtlbe %r0(%sr1, %r28) + pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */ + addib,COND(>) -1, %r29, fdtmanymiddle /* Middle loop decr */ + copy %arg3, %r31 /* Re-init inner loop count */ +@@ -620,12 +620,12 @@ ENTRY(copy_user_page_asm) + /* Purge any old translations */ + + #ifdef CONFIG_PA20 +- pdtlb,l 0(%r28) +- pdtlb,l 0(%r29) ++ pdtlb,l %r0(%r28) ++ pdtlb,l %r0(%r29) + #else + tlb_lock %r20,%r21,%r22 +- pdtlb 0(%r28) +- pdtlb 0(%r29) ++ pdtlb %r0(%r28) ++ pdtlb %r0(%r29) + tlb_unlock %r20,%r21,%r22 + #endif + +@@ -768,10 +768,10 @@ ENTRY(clear_user_page_asm) + /* Purge any old translation */ + + #ifdef CONFIG_PA20 +- pdtlb,l 0(%r28) ++ pdtlb,l %r0(%r28) + #else + tlb_lock %r20,%r21,%r22 +- pdtlb 0(%r28) ++ pdtlb %r0(%r28) + tlb_unlock %r20,%r21,%r22 + #endif + +@@ -852,10 +852,10 @@ ENTRY(flush_dcache_page_asm) + /* Purge any old translation */ + + #ifdef CONFIG_PA20 +- pdtlb,l 0(%r28) ++ pdtlb,l %r0(%r28) + #else + tlb_lock %r20,%r21,%r22 +- pdtlb 0(%r28) ++ pdtlb %r0(%r28) + tlb_unlock %r20,%r21,%r22 + #endif + +@@ -892,10 +892,10 @@ ENTRY(flush_dcache_page_asm) + sync + + #ifdef CONFIG_PA20 +- pdtlb,l 0(%r25) ++ pdtlb,l %r0(%r25) + #else + tlb_lock %r20,%r21,%r22 +- pdtlb 0(%r25) ++ pdtlb %r0(%r25) + tlb_unlock %r20,%r21,%r22 + #endif + +@@ -925,13 +925,18 @@ ENTRY(flush_icache_page_asm) + depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */ + #endif + +- /* Purge any old translation */ ++ /* Purge any old translation. Note that the FIC instruction ++ * may use either the instruction or data TLB. Given that we ++ * have a flat address space, it's not clear which TLB will be ++ * used. So, we purge both entries. */ + + #ifdef CONFIG_PA20 ++ pdtlb,l %r0(%r28) + pitlb,l %r0(%sr4,%r28) + #else + tlb_lock %r20,%r21,%r22 +- pitlb (%sr4,%r28) ++ pdtlb %r0(%r28) ++ pitlb %r0(%sr4,%r28) + tlb_unlock %r20,%r21,%r22 + #endif + +@@ -970,10 +975,12 @@ ENTRY(flush_icache_page_asm) + sync + + #ifdef CONFIG_PA20 ++ pdtlb,l %r0(%r28) + pitlb,l %r0(%sr4,%r25) + #else + tlb_lock %r20,%r21,%r22 +- pitlb (%sr4,%r25) ++ pdtlb %r0(%r28) ++ pitlb %r0(%sr4,%r25) + tlb_unlock %r20,%r21,%r22 + #endif + diff --git a/queue-4.8/parisc-fix-race-in-pci-dma.c.patch b/queue-4.8/parisc-fix-race-in-pci-dma.c.patch new file mode 100644 index 00000000000..44fd73e684c --- /dev/null +++ b/queue-4.8/parisc-fix-race-in-pci-dma.c.patch @@ -0,0 +1,42 @@ +From c0452fb9fb8f49c7d68ab9fa0ad092016be7b45f Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Thu, 24 Nov 2016 20:06:32 -0500 +Subject: parisc: Fix race in pci-dma.c + +From: John David Anglin + +commit c0452fb9fb8f49c7d68ab9fa0ad092016be7b45f upstream. + +We are still troubled by occasional random segmentation faults and +memory memory corruption on SMP machines. The causes quite a few +package builds to fail on the Debian buildd machines for parisc. When +gcc-6 failed to build three times in a row, I looked again at the TLB +related code. I found a couple of issues. This is the first. + +In general, we need to ensure page table updates and corresponding TLB +purges are atomic. The attached patch fixes an instance in pci-dma.c +where the page table update was not guarded by the TLB lock. + +Tested on rp3440 and c8000. So far, no further random segmentation +faults have been observed. + +Signed-off-by: John David Anglin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/pci-dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/parisc/kernel/pci-dma.c ++++ b/arch/parisc/kernel/pci-dma.c +@@ -95,8 +95,8 @@ static inline int map_pte_uncached(pte_t + + if (!pte_none(*pte)) + printk(KERN_ERR "map_pte_uncached: page already exists\n"); +- set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC)); + purge_tlb_start(flags); ++ set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC)); + pdtlb_kernel(orig_vaddr); + purge_tlb_end(flags); + vaddr += PAGE_SIZE; diff --git a/queue-4.8/parisc-fix-races-in-parisc_setup_cache_timing.patch b/queue-4.8/parisc-fix-races-in-parisc_setup_cache_timing.patch new file mode 100644 index 00000000000..ef9ebeb3b65 --- /dev/null +++ b/queue-4.8/parisc-fix-races-in-parisc_setup_cache_timing.patch @@ -0,0 +1,199 @@ +From 741dc7bf1c7c7d93b853bb55efe77baa27e1b0a9 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Sun, 20 Nov 2016 21:12:36 -0500 +Subject: parisc: Fix races in parisc_setup_cache_timing() + +From: John David Anglin + +commit 741dc7bf1c7c7d93b853bb55efe77baa27e1b0a9 upstream. + +Helge reported to me the following startup crash: + +[ 0.000000] Linux version 4.8.0-1-parisc64-smp (debian-kernel@lists.debian.org) (gcc version 5.4.1 20161019 (GCC) ) #1 SMP Debian 4.8.7-1 (2016-11-13) +[ 0.000000] The 64-bit Kernel has started... +[ 0.000000] Kernel default page size is 4 KB. Huge pages enabled with 1 MB physical and 2 MB virtual size. +[ 0.000000] Determining PDC firmware type: System Map. +[ 0.000000] model 9000/785/J5000 +[ 0.000000] Total Memory: 2048 MB +[ 0.000000] Memory: 2018528K/2097152K available (9272K kernel code, 3053K rwdata, 1319K rodata, 1024K init, 840K bss, 78624K reserved, 0K cma-reserved) +[ 0.000000] virtual kernel memory layout: +[ 0.000000] vmalloc : 0x0000000000008000 - 0x000000003f000000 (1007 MB) +[ 0.000000] memory : 0x0000000040000000 - 0x00000000c0000000 (2048 MB) +[ 0.000000] .init : 0x0000000040100000 - 0x0000000040200000 (1024 kB) +[ 0.000000] .data : 0x0000000040b0e000 - 0x0000000040f533e0 (4372 kB) +[ 0.000000] .text : 0x0000000040200000 - 0x0000000040b0e000 (9272 kB) +[ 0.768910] Brought up 1 CPUs +[ 0.992465] NET: Registered protocol family 16 +[ 2.429981] Releasing cpu 1 now, hpa=fffffffffffa2000 +[ 2.635751] CPU(s): 2 out of 2 PA8500 (PCX-W) at 440.000000 MHz online +[ 2.726692] Setting cache flush threshold to 1024 kB +[ 2.729932] Not-handled unaligned insn 0x43ffff80 +[ 2.798114] Setting TLB flush threshold to 140 kB +[ 2.928039] Unaligned handler failed, ret = -1 +[ 3.000419] _______________________________ +[ 3.000419] < Your System ate a SPARC! Gah! > +[ 3.000419] ------------------------------- +[ 3.000419] \ ^__^ +[ 3.000419] (__)\ )\/\ +[ 3.000419] U ||----w | +[ 3.000419] || || +[ 9.340055] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-1-parisc64-smp #1 Debian 4.8.7-1 +[ 9.448082] task: 00000000bfd48060 task.stack: 00000000bfd50000 +[ 9.528040] +[ 10.760029] IASQ: 0000000000000000 0000000000000000 IAOQ: 000000004025d154 000000004025d158 +[ 10.868052] IIR: 43ffff80 ISR: 0000000000340000 IOR: 000001ff54150960 +[ 10.960029] CPU: 1 CR30: 00000000bfd50000 CR31: 0000000011111111 +[ 11.052057] ORIG_R28: 000000004021e3b4 +[ 11.100045] IAOQ[0]: irq_exit+0x94/0x120 +[ 11.152062] IAOQ[1]: irq_exit+0x98/0x120 +[ 11.208031] RP(r2): irq_exit+0xb8/0x120 +[ 11.256074] Backtrace: +[ 11.288067] [<00000000402cd944>] cpu_startup_entry+0x1e4/0x598 +[ 11.368058] [<0000000040109528>] smp_callin+0x2c0/0x2f0 +[ 11.436308] [<00000000402b53fc>] update_curr+0x18c/0x2d0 +[ 11.508055] [<00000000402b73b8>] dequeue_entity+0x2c0/0x1030 +[ 11.584040] [<00000000402b3cc0>] set_next_entity+0x80/0xd30 +[ 11.660069] [<00000000402c1594>] pick_next_task_fair+0x614/0x720 +[ 11.740085] [<000000004020dd34>] __schedule+0x394/0xa60 +[ 11.808054] [<000000004020e488>] schedule+0x88/0x118 +[ 11.876039] [<0000000040283d3c>] rescuer_thread+0x4d4/0x5b0 +[ 11.948090] [<000000004028fc4c>] kthread+0x1ec/0x248 +[ 12.016053] [<0000000040205020>] end_fault_vector+0x20/0xc0 +[ 12.092239] [<00000000402050c0>] _switch_to_ret+0x0/0xf40 +[ 12.164044] +[ 12.184036] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-1-parisc64-smp #1 Debian 4.8.7-1 +[ 12.244040] Backtrace: +[ 12.244040] [<000000004021c480>] show_stack+0x68/0x80 +[ 12.244040] [<00000000406f332c>] dump_stack+0xec/0x168 +[ 12.244040] [<000000004021c74c>] die_if_kernel+0x25c/0x430 +[ 12.244040] [<000000004022d320>] handle_unaligned+0xb48/0xb50 +[ 12.244040] +[ 12.632066] ---[ end trace 9ca05a7215c7bbb2 ]--- +[ 12.692036] Kernel panic - not syncing: Attempted to kill the idle task! + +We have the insn 0x43ffff80 in IIR but from IAOQ we should have: + 4025d150: 0f f3 20 df ldd,s r19(r31),r31 + 4025d154: 0f 9f 00 9c ldw r31(ret0),ret0 + 4025d158: bf 80 20 58 cmpb,*<> r0,ret0,4025d18c + +Cpu0 has just completed running parisc_setup_cache_timing: + +[ 2.429981] Releasing cpu 1 now, hpa=fffffffffffa2000 +[ 2.635751] CPU(s): 2 out of 2 PA8500 (PCX-W) at 440.000000 MHz online +[ 2.726692] Setting cache flush threshold to 1024 kB +[ 2.729932] Not-handled unaligned insn 0x43ffff80 +[ 2.798114] Setting TLB flush threshold to 140 kB +[ 2.928039] Unaligned handler failed, ret = -1 + +From the backtrace, cpu1 is in smp_callin: + +void __init smp_callin(void) +{ + int slave_id = cpu_now_booting; + + smp_cpu_init(slave_id); + preempt_disable(); + + flush_cache_all_local(); /* start with known state */ + flush_tlb_all_local(NULL); + + local_irq_enable(); /* Interrupts have been off until now */ + + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + +So, it has just flushed its caches and the TLB. It would seem either the +flushes in parisc_setup_cache_timing or smp_callin have corrupted kernel +memory. + +The attached patch reworks parisc_setup_cache_timing to remove the races +in setting the cache and TLB flush thresholds. It also corrects the +number of bytes flushed in the TLB calculation. + +The patch flushes the cache and TLB on cpu0 before starting the +secondary processors so that they are started from a known state. + +Tested with a few reboots on c8000. + +Signed-off-by: John David Anglin +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/cache.c | 31 ++++++++++++------------------- + arch/parisc/kernel/setup.c | 4 ++++ + 2 files changed, 16 insertions(+), 19 deletions(-) + +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -369,6 +369,7 @@ void __init parisc_setup_cache_timing(vo + { + unsigned long rangetime, alltime; + unsigned long size, start; ++ unsigned long threshold; + + alltime = mfctl(16); + flush_data_cache(); +@@ -382,17 +383,12 @@ void __init parisc_setup_cache_timing(vo + printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n", + alltime, size, rangetime); + +- /* Racy, but if we see an intermediate value, it's ok too... */ +- parisc_cache_flush_threshold = size * alltime / rangetime; +- +- parisc_cache_flush_threshold = L1_CACHE_ALIGN(parisc_cache_flush_threshold); +- if (!parisc_cache_flush_threshold) +- parisc_cache_flush_threshold = FLUSH_THRESHOLD; +- +- if (parisc_cache_flush_threshold > cache_info.dc_size) +- parisc_cache_flush_threshold = cache_info.dc_size; +- +- printk(KERN_INFO "Setting cache flush threshold to %lu kB\n", ++ threshold = L1_CACHE_ALIGN(size * alltime / rangetime); ++ if (threshold > cache_info.dc_size) ++ threshold = cache_info.dc_size; ++ if (threshold) ++ parisc_cache_flush_threshold = threshold; ++ printk(KERN_INFO "Cache flush threshold set to %lu KiB\n", + parisc_cache_flush_threshold/1024); + + /* calculate TLB flush threshold */ +@@ -401,7 +397,7 @@ void __init parisc_setup_cache_timing(vo + flush_tlb_all(); + alltime = mfctl(16) - alltime; + +- size = PAGE_SIZE; ++ size = 0; + start = (unsigned long) _text; + rangetime = mfctl(16); + while (start < (unsigned long) _end) { +@@ -414,13 +410,10 @@ void __init parisc_setup_cache_timing(vo + printk(KERN_DEBUG "Whole TLB flush %lu cycles, flushing %lu bytes %lu cycles\n", + alltime, size, rangetime); + +- parisc_tlb_flush_threshold = size * alltime / rangetime; +- parisc_tlb_flush_threshold *= num_online_cpus(); +- parisc_tlb_flush_threshold = PAGE_ALIGN(parisc_tlb_flush_threshold); +- if (!parisc_tlb_flush_threshold) +- parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD; +- +- printk(KERN_INFO "Setting TLB flush threshold to %lu kB\n", ++ threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime); ++ if (threshold) ++ parisc_tlb_flush_threshold = threshold; ++ printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", + parisc_tlb_flush_threshold/1024); + } + +--- a/arch/parisc/kernel/setup.c ++++ b/arch/parisc/kernel/setup.c +@@ -334,6 +334,10 @@ static int __init parisc_init(void) + /* tell PDC we're Linux. Nevermind failure. */ + pdc_stable_write(0x40, &osid, sizeof(osid)); + ++ /* start with known state */ ++ flush_cache_all_local(); ++ flush_tlb_all_local(NULL); ++ + processor_init(); + #ifdef CONFIG_SMP + pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n", diff --git a/queue-4.8/parisc-switch-to-generic-sched_clock-implementation.patch b/queue-4.8/parisc-switch-to-generic-sched_clock-implementation.patch new file mode 100644 index 00000000000..368b273a3a2 --- /dev/null +++ b/queue-4.8/parisc-switch-to-generic-sched_clock-implementation.patch @@ -0,0 +1,140 @@ +From 43b1f6abd59063a088416a0df042b36450f91f75 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 22 Nov 2016 18:08:30 +0100 +Subject: parisc: Switch to generic sched_clock implementation + +From: Helge Deller + +commit 43b1f6abd59063a088416a0df042b36450f91f75 upstream. + +Drop the open-coded sched_clock() function and replace it by the provided +GENERIC_SCHED_CLOCK implementation. We have seen quite some hung tasks in the +past, which seem to be fixed by this patch. + +Signed-off-by: Helge Deller +Signed-off-by: Helge Deller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/Kconfig | 4 ++- + arch/parisc/kernel/time.c | 57 ++++++++-------------------------------------- + 2 files changed, 14 insertions(+), 47 deletions(-) + +--- a/arch/parisc/Kconfig ++++ b/arch/parisc/Kconfig +@@ -33,7 +33,9 @@ config PARISC + select HAVE_ARCH_HASH + select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_TRACEHOOK +- select HAVE_UNSTABLE_SCHED_CLOCK if (SMP || !64BIT) ++ select GENERIC_SCHED_CLOCK ++ select HAVE_UNSTABLE_SCHED_CLOCK if SMP ++ select GENERIC_CLOCKEVENTS + select ARCH_NO_COHERENT_DMA_MMAP + select CPU_NO_EFFICIENT_FFS + +--- a/arch/parisc/kernel/time.c ++++ b/arch/parisc/kernel/time.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -39,18 +40,6 @@ + + static unsigned long clocktick __read_mostly; /* timer cycles per tick */ + +-#ifndef CONFIG_64BIT +-/* +- * The processor-internal cycle counter (Control Register 16) is used as time +- * source for the sched_clock() function. This register is 64bit wide on a +- * 64-bit kernel and 32bit on a 32-bit kernel. Since sched_clock() always +- * requires a 64bit counter we emulate on the 32-bit kernel the higher 32bits +- * with a per-cpu variable which we increase every time the counter +- * wraps-around (which happens every ~4 secounds). +- */ +-static DEFINE_PER_CPU(unsigned long, cr16_high_32_bits); +-#endif +- + /* + * We keep time on PA-RISC Linux by using the Interval Timer which is + * a pair of registers; one is read-only and one is write-only; both +@@ -121,12 +110,6 @@ irqreturn_t __irq_entry timer_interrupt( + */ + mtctl(next_tick, 16); + +-#if !defined(CONFIG_64BIT) +- /* check for overflow on a 32bit kernel (every ~4 seconds). */ +- if (unlikely(next_tick < now)) +- this_cpu_inc(cr16_high_32_bits); +-#endif +- + /* Skip one clocktick on purpose if we missed next_tick. + * The new CR16 must be "later" than current CR16 otherwise + * itimer would not fire until CR16 wrapped - e.g 4 seconds +@@ -208,7 +191,7 @@ EXPORT_SYMBOL(profile_pc); + + /* clock source code */ + +-static cycle_t read_cr16(struct clocksource *cs) ++static cycle_t notrace read_cr16(struct clocksource *cs) + { + return get_cycles(); + } +@@ -287,26 +270,9 @@ void read_persistent_clock(struct timesp + } + + +-/* +- * sched_clock() framework +- */ +- +-static u32 cyc2ns_mul __read_mostly; +-static u32 cyc2ns_shift __read_mostly; +- +-u64 sched_clock(void) ++static u64 notrace read_cr16_sched_clock(void) + { +- u64 now; +- +- /* Get current cycle counter (Control Register 16). */ +-#ifdef CONFIG_64BIT +- now = mfctl(16); +-#else +- now = mfctl(16) + (((u64) this_cpu_read(cr16_high_32_bits)) << 32); +-#endif +- +- /* return the value in ns (cycles_2_ns) */ +- return mul_u64_u32_shr(now, cyc2ns_mul, cyc2ns_shift); ++ return get_cycles(); + } + + +@@ -316,17 +282,16 @@ u64 sched_clock(void) + + void __init time_init(void) + { +- unsigned long current_cr16_khz; ++ unsigned long cr16_hz; + +- current_cr16_khz = PAGE0->mem_10msec/10; /* kHz */ + clocktick = (100 * PAGE0->mem_10msec) / HZ; +- +- /* calculate mult/shift values for cr16 */ +- clocks_calc_mult_shift(&cyc2ns_mul, &cyc2ns_shift, current_cr16_khz, +- NSEC_PER_MSEC, 0); +- + start_cpu_itimer(); /* get CPU 0 started */ + ++ cr16_hz = 100 * PAGE0->mem_10msec; /* Hz */ ++ + /* register at clocksource framework */ +- clocksource_register_khz(&clocksource_cr16, current_cr16_khz); ++ clocksource_register_hz(&clocksource_cr16, cr16_hz); ++ ++ /* register as sched_clock source */ ++ sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz); + } diff --git a/queue-4.8/perf-core-fix-address-filter-parser.patch b/queue-4.8/perf-core-fix-address-filter-parser.patch new file mode 100644 index 00000000000..060d31bb410 --- /dev/null +++ b/queue-4.8/perf-core-fix-address-filter-parser.patch @@ -0,0 +1,53 @@ +From e96271f3ed7e702fa36dd0605c0c5b5f065af816 Mon Sep 17 00:00:00 2001 +From: Alexander Shishkin +Date: Fri, 18 Nov 2016 13:38:43 +0200 +Subject: perf/core: Fix address filter parser + +From: Alexander Shishkin + +commit e96271f3ed7e702fa36dd0605c0c5b5f065af816 upstream. + +The token table passed into match_token() must be null-terminated, which +it currently is not in the perf's address filter string parser, as caught +by Vince's perf_fuzzer and KASAN. + +It doesn't blow up otherwise because of the alignment padding of the table +to the next element in the .rodata, which is luck. + +Fixing by adding a null-terminator to the token table. + +Reported-by: Vince Weaver +Tested-by: Vince Weaver +Signed-off-by: Alexander Shishkin +Acked-by: Peter Zijlstra (Intel) +Cc: Arnaldo Carvalho de Melo +Cc: Linus Torvalds +Cc: Thomas Gleixner +Cc: dvyukov@google.com +Fixes: 375637bc524 ("perf/core: Introduce address range filtering") +Link: http://lkml.kernel.org/r/877f81f264.fsf@ashishki-desk.ger.corp.intel.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/events/core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -7908,6 +7908,7 @@ restart: + * if is not specified, the range is treated as a single address. + */ + enum { ++ IF_ACT_NONE = -1, + IF_ACT_FILTER, + IF_ACT_START, + IF_ACT_STOP, +@@ -7931,6 +7932,7 @@ static const match_table_t if_tokens = { + { IF_SRC_KERNEL, "%u/%u" }, + { IF_SRC_FILEADDR, "%u@%s" }, + { IF_SRC_KERNELADDR, "%u" }, ++ { IF_ACT_NONE, NULL }, + }; + + /* diff --git a/queue-4.8/perf-x86-intel-cure-bogus-unwind-from-pebs-entries.patch b/queue-4.8/perf-x86-intel-cure-bogus-unwind-from-pebs-entries.patch new file mode 100644 index 00000000000..e38cff14481 --- /dev/null +++ b/queue-4.8/perf-x86-intel-cure-bogus-unwind-from-pebs-entries.patch @@ -0,0 +1,127 @@ +From b8000586c90b4804902058a38d3a59ce5708e695 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 17 Nov 2016 18:17:31 +0100 +Subject: perf/x86/intel: Cure bogus unwind from PEBS entries + +From: Peter Zijlstra + +commit b8000586c90b4804902058a38d3a59ce5708e695 upstream. + +Vince Weaver reported that perf_fuzzer + KASAN detects that PEBS event +unwinds sometimes do 'weird' things. In particular, we seemed to be +ending up unwinding from random places on the NMI stack. + +While it was somewhat expected that the event record BP,SP would not +match the interrupt BP,SP in that the interrupt is strictly later than +the record event, it was overlooked that it could be on an already +overwritten stack. + +Therefore, don't copy the recorded BP,SP over the interrupted BP,SP +when we need stack unwinds. + +Note that its still possible the unwind doesn't full match the actual +event, as its entirely possible to have done an (I)RET between record +and interrupt, but on average it should still point in the general +direction of where the event came from. Also, it's the best we can do, +considering. + +The particular scenario that triggered the bogus NMI stack unwind was +a PEBS event with very short period, upon enabling the event at the +tail of the PMI handler (FREEZE_ON_PMI is not used), it instantly +triggers a record (while still on the NMI stack) which in turn +triggers the next PMI. This then causes back-to-back NMIs and we'll +try and unwind the stack-frame from the last NMI, which obviously is +now overwritten by our own. + +Analyzed-by: Josh Poimboeuf +Reported-by: Vince Weaver +Signed-off-by: Peter Zijlstra (Intel) +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Arnaldo Carvalho de Melo +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: davej@codemonkey.org.uk +Cc: dvyukov@google.com +Fixes: ca037701a025 ("perf, x86: Add PEBS infrastructure") +Link: http://lkml.kernel.org/r/20161117171731.GV3157@twins.programming.kicks-ass.net +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/events/intel/ds.c | 35 +++++++++++++++++++++++------------ + arch/x86/events/perf_event.h | 2 +- + 2 files changed, 24 insertions(+), 13 deletions(-) + +--- a/arch/x86/events/intel/ds.c ++++ b/arch/x86/events/intel/ds.c +@@ -1070,20 +1070,20 @@ static void setup_pebs_sample_data(struc + } + + /* +- * We use the interrupt regs as a base because the PEBS record +- * does not contain a full regs set, specifically it seems to +- * lack segment descriptors, which get used by things like +- * user_mode(). ++ * We use the interrupt regs as a base because the PEBS record does not ++ * contain a full regs set, specifically it seems to lack segment ++ * descriptors, which get used by things like user_mode(). + * +- * In the simple case fix up only the IP and BP,SP regs, for +- * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly. +- * A possible PERF_SAMPLE_REGS will have to transfer all regs. ++ * In the simple case fix up only the IP for PERF_SAMPLE_IP. ++ * ++ * We must however always use BP,SP from iregs for the unwinder to stay ++ * sane; the record BP,SP can point into thin air when the record is ++ * from a previous PMI context or an (I)RET happend between the record ++ * and PMI. + */ + *regs = *iregs; + regs->flags = pebs->flags; + set_linear_ip(regs, pebs->ip); +- regs->bp = pebs->bp; +- regs->sp = pebs->sp; + + if (sample_type & PERF_SAMPLE_REGS_INTR) { + regs->ax = pebs->ax; +@@ -1092,10 +1092,21 @@ static void setup_pebs_sample_data(struc + regs->dx = pebs->dx; + regs->si = pebs->si; + regs->di = pebs->di; +- regs->bp = pebs->bp; +- regs->sp = pebs->sp; + +- regs->flags = pebs->flags; ++ /* ++ * Per the above; only set BP,SP if we don't need callchains. ++ * ++ * XXX: does this make sense? ++ */ ++ if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { ++ regs->bp = pebs->bp; ++ regs->sp = pebs->sp; ++ } ++ ++ /* ++ * Preserve PERF_EFLAGS_VM from set_linear_ip(). ++ */ ++ regs->flags = pebs->flags | (regs->flags & PERF_EFLAGS_VM); + #ifndef CONFIG_X86_32 + regs->r8 = pebs->r8; + regs->r9 = pebs->r9; +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -113,7 +113,7 @@ struct debug_store { + * Per register state. + */ + struct er_account { +- raw_spinlock_t lock; /* per-core: protect structure */ ++ raw_spinlock_t lock; /* per-core: protect structure */ + u64 config; /* extra MSR config */ + u64 reg; /* extra MSR number */ + atomic_t ref; /* reference count */ diff --git a/queue-4.8/powerpc-boot-fix-the-early-opal-console-wrappers.patch b/queue-4.8/powerpc-boot-fix-the-early-opal-console-wrappers.patch new file mode 100644 index 00000000000..47db1265421 --- /dev/null +++ b/queue-4.8/powerpc-boot-fix-the-early-opal-console-wrappers.patch @@ -0,0 +1,110 @@ +From a1ff57416af9a7971a801d553cd53edd8afb28d6 Mon Sep 17 00:00:00 2001 +From: Oliver O'Halloran +Date: Wed, 23 Nov 2016 13:55:13 +1100 +Subject: powerpc/boot: Fix the early OPAL console wrappers + +From: Oliver O'Halloran + +commit a1ff57416af9a7971a801d553cd53edd8afb28d6 upstream. + +When configured with CONFIG_PPC_EARLY_DEBUG_OPAL=y the kernel expects +the OPAL entry and base addresses to be passed in r8 and r9 +respectively. Currently the wrapper does not attempt to restore these +values before entering the decompressed kernel which causes the kernel +to branch into whatever happens to be in r9 when doing a write to the +OPAL console in early boot. + +This patch adds a platform_ops hook that can be used to branch into the +new kernel. The OPAL console driver patches this at runtime so that if +the console is used it will be restored just prior to entering the +kernel. + +Fixes: 656ad58ef19e ("powerpc/boot: Add OPAL console to epapr wrappers") +Signed-off-by: Oliver O'Halloran +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/boot/main.c | 8 ++++++-- + arch/powerpc/boot/opal-calls.S | 13 +++++++++++++ + arch/powerpc/boot/opal.c | 11 +++++++++++ + arch/powerpc/boot/ops.h | 1 + + 4 files changed, 31 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/boot/main.c ++++ b/arch/powerpc/boot/main.c +@@ -217,8 +217,12 @@ void start(void) + console_ops.close(); + + kentry = (kernel_entry_t) vmlinux.addr; +- if (ft_addr) +- kentry(ft_addr, 0, NULL); ++ if (ft_addr) { ++ if(platform_ops.kentry) ++ platform_ops.kentry(ft_addr, vmlinux.addr); ++ else ++ kentry(ft_addr, 0, NULL); ++ } + else + kentry((unsigned long)initrd.addr, initrd.size, + loader_info.promptr); +--- a/arch/powerpc/boot/opal-calls.S ++++ b/arch/powerpc/boot/opal-calls.S +@@ -12,6 +12,19 @@ + + .text + ++ .globl opal_kentry ++opal_kentry: ++ /* r3 is the fdt ptr */ ++ mtctr r4 ++ li r4, 0 ++ li r5, 0 ++ li r6, 0 ++ li r7, 0 ++ ld r11,opal@got(r2) ++ ld r8,0(r11) ++ ld r9,8(r11) ++ bctr ++ + #define OPAL_CALL(name, token) \ + .globl name; \ + name: \ +--- a/arch/powerpc/boot/opal.c ++++ b/arch/powerpc/boot/opal.c +@@ -23,14 +23,25 @@ struct opal { + + static u32 opal_con_id; + ++/* see opal-wrappers.S */ + int64_t opal_console_write(int64_t term_number, u64 *length, const u8 *buffer); + int64_t opal_console_read(int64_t term_number, uint64_t *length, u8 *buffer); + int64_t opal_console_write_buffer_space(uint64_t term_number, uint64_t *length); + int64_t opal_console_flush(uint64_t term_number); + int64_t opal_poll_events(uint64_t *outstanding_event_mask); + ++void opal_kentry(unsigned long fdt_addr, void *vmlinux_addr); ++ + static int opal_con_open(void) + { ++ /* ++ * When OPAL loads the boot kernel it stashes the OPAL base and entry ++ * address in r8 and r9 so the kernel can use the OPAL console ++ * before unflattening the devicetree. While executing the wrapper will ++ * probably trash r8 and r9 so this kentry hook restores them before ++ * entering the decompressed kernel. ++ */ ++ platform_ops.kentry = opal_kentry; + return 0; + } + +--- a/arch/powerpc/boot/ops.h ++++ b/arch/powerpc/boot/ops.h +@@ -30,6 +30,7 @@ struct platform_ops { + void * (*realloc)(void *ptr, unsigned long size); + void (*exit)(void); + void * (*vmlinux_alloc)(unsigned long size); ++ void (*kentry)(unsigned long fdt_addr, void *vmlinux_addr); + }; + extern struct platform_ops platform_ops; + diff --git a/queue-4.8/powerpc-mm-fixup-kernel-read-only-mapping.patch b/queue-4.8/powerpc-mm-fixup-kernel-read-only-mapping.patch new file mode 100644 index 00000000000..3ce9243f920 --- /dev/null +++ b/queue-4.8/powerpc-mm-fixup-kernel-read-only-mapping.patch @@ -0,0 +1,81 @@ +From 984d7a1ec67ce3a46324fa4bcb4c745bbc266cf2 Mon Sep 17 00:00:00 2001 +From: "Aneesh Kumar K.V" +Date: Thu, 24 Nov 2016 15:09:54 +0530 +Subject: powerpc/mm: Fixup kernel read only mapping + +From: Aneesh Kumar K.V + +commit 984d7a1ec67ce3a46324fa4bcb4c745bbc266cf2 upstream. + +With commit e58e87adc8bf9 ("powerpc/mm: Update _PAGE_KERNEL_RO") we +started using the ppp value 0b110 to map kernel readonly. But that +facility was only added as part of ISA 2.04. For earlier ISA version +only supported ppp bit value for readonly mapping is 0b011. (This +implies both user and kernel get mapped using the same ppp bit value for +readonly mapping.). +Update the code such that for earlier architecture version we use ppp +value 0b011 for readonly mapping. We don't differentiate between power5+ +and power5 here and apply the new ppp bits only from power6 (ISA 2.05). +This keep the changes minimal. + +This fixes issue with PS3 spu usage reported at +https://lkml.kernel.org/r/rep.1421449714.geoff@infradead.org + +Fixes: e58e87adc8bf9 ("powerpc/mm: Update _PAGE_KERNEL_RO") +Tested-by: Geoff Levand +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/mmu.h | 14 ++++++++++---- + arch/powerpc/mm/hash_utils_64.c | 8 ++++++-- + 2 files changed, 16 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/include/asm/mmu.h ++++ b/arch/powerpc/include/asm/mmu.h +@@ -29,6 +29,12 @@ + */ + + /* ++ * Kernel read only support. ++ * We added the ppp value 0b110 in ISA 2.04. ++ */ ++#define MMU_FTR_KERNEL_RO ASM_CONST(0x00004000) ++ ++/* + * We need to clear top 16bits of va (from the remaining 64 bits )in + * tlbie* instructions + */ +@@ -103,10 +109,10 @@ + #define MMU_FTRS_POWER4 MMU_FTRS_DEFAULT_HPTE_ARCH_V2 + #define MMU_FTRS_PPC970 MMU_FTRS_POWER4 | MMU_FTR_TLBIE_CROP_VA + #define MMU_FTRS_POWER5 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE +-#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE +-#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE +-#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE +-#define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE ++#define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO ++#define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO ++#define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO ++#define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO + #define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ + MMU_FTR_CI_LARGE_PAGE + #define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ +--- a/arch/powerpc/mm/hash_utils_64.c ++++ b/arch/powerpc/mm/hash_utils_64.c +@@ -190,8 +190,12 @@ unsigned long htab_convert_pte_flags(uns + /* + * Kernel read only mapped with ppp bits 0b110 + */ +- if (!(pteflags & _PAGE_WRITE)) +- rflags |= (HPTE_R_PP0 | 0x2); ++ if (!(pteflags & _PAGE_WRITE)) { ++ if (mmu_has_feature(MMU_FTR_KERNEL_RO)) ++ rflags |= (HPTE_R_PP0 | 0x2); ++ else ++ rflags |= 0x3; ++ } + } else { + if (pteflags & _PAGE_RWX) + rflags |= 0x2; diff --git a/queue-4.8/powerpc-set-missing-wakeup-bit-in-lpcr-on-power9.patch b/queue-4.8/powerpc-set-missing-wakeup-bit-in-lpcr-on-power9.patch new file mode 100644 index 00000000000..705dcc1add8 --- /dev/null +++ b/queue-4.8/powerpc-set-missing-wakeup-bit-in-lpcr-on-power9.patch @@ -0,0 +1,61 @@ +From 7a43906f5cbfb74712af168988455e350707e310 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Mon, 21 Nov 2016 18:08:05 +1100 +Subject: powerpc: Set missing wakeup bit in LPCR on POWER9 + +From: Benjamin Herrenschmidt + +commit 7a43906f5cbfb74712af168988455e350707e310 upstream. + +There is a new bit, LPCR_PECE_HVEE (Hypervisor Virtualization Exit +Enable), which controls wakeup from STOP states on Hypervisor +Virtualization Interrupts (which happen to also be all external +interrupts in host or bare metal mode). + +It needs to be set or we will miss wakeups. + +Fixes: 9baaef0a22c8 ("powerpc/irq: Add support for HV virtualization interrupts") +Signed-off-by: Benjamin Herrenschmidt +[mpe: Rename it to HVEE to match the name in the ISA] +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/reg.h | 1 + + arch/powerpc/kernel/cpu_setup_power.S | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/arch/powerpc/include/asm/reg.h ++++ b/arch/powerpc/include/asm/reg.h +@@ -355,6 +355,7 @@ + #define LPCR_PECE0 ASM_CONST(0x0000000000004000) /* ext. exceptions can cause exit */ + #define LPCR_PECE1 ASM_CONST(0x0000000000002000) /* decrementer can cause exit */ + #define LPCR_PECE2 ASM_CONST(0x0000000000001000) /* machine check etc can cause exit */ ++#define LPCR_PECE_HVEE ASM_CONST(0x0000400000000000) /* P9 Wakeup on HV interrupts */ + #define LPCR_MER ASM_CONST(0x0000000000000800) /* Mediated External Exception */ + #define LPCR_MER_SH 11 + #define LPCR_TC ASM_CONST(0x0000000000000200) /* Translation control */ +--- a/arch/powerpc/kernel/cpu_setup_power.S ++++ b/arch/powerpc/kernel/cpu_setup_power.S +@@ -98,8 +98,8 @@ _GLOBAL(__setup_cpu_power9) + li r0,0 + mtspr SPRN_LPID,r0 + mfspr r3,SPRN_LPCR +- ori r3, r3, LPCR_PECEDH +- ori r3, r3, LPCR_HVICE ++ LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE) ++ or r3, r3, r4 + bl __init_LPCR + bl __init_HFSCR + bl __init_tlb_power9 +@@ -118,8 +118,8 @@ _GLOBAL(__restore_cpu_power9) + li r0,0 + mtspr SPRN_LPID,r0 + mfspr r3,SPRN_LPCR +- ori r3, r3, LPCR_PECEDH +- ori r3, r3, LPCR_HVICE ++ LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE) ++ or r3, r3, r4 + bl __init_LPCR + bl __init_HFSCR + bl __init_tlb_power9 diff --git a/queue-4.8/scsi-mpt3sas-fix-secure-erase-premature-termination.patch b/queue-4.8/scsi-mpt3sas-fix-secure-erase-premature-termination.patch new file mode 100644 index 00000000000..944b06aa43c --- /dev/null +++ b/queue-4.8/scsi-mpt3sas-fix-secure-erase-premature-termination.patch @@ -0,0 +1,73 @@ +From 18f6084a989ba1b38702f9af37a2e4049a924be6 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky +Date: Thu, 10 Nov 2016 09:35:27 -0500 +Subject: scsi: mpt3sas: Fix secure erase premature termination + +From: Andrey Grodzovsky + +commit 18f6084a989ba1b38702f9af37a2e4049a924be6 upstream. + +This is a work around for a bug with LSI Fusion MPT SAS2 when perfoming +secure erase. Due to the very long time the operation takes, commands +issued during the erase will time out and will trigger execution of the +abort hook. Even though the abort hook is called for the specific +command which timed out, this leads to entire device halt +(scsi_state terminated) and premature termination of the secure erase. + +Set device state to busy while ATA passthrough commands are in progress. + +[mkp: hand applied to 4.9/scsi-fixes, tweaked patch description] + +Signed-off-by: Andrey Grodzovsky +Acked-by: Sreekanth Reddy +Cc: +Cc: Sathya Prakash +Cc: Chaitra P B +Cc: Suganath Prabu Subramani +Cc: Sreekanth Reddy +Cc: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -4019,7 +4019,10 @@ _scsih_eedp_error_handling(struct scsi_c + SAM_STAT_CHECK_CONDITION; + } + +- ++static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd) ++{ ++ return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16); ++} + + /** + * scsih_qcmd - main scsi request entry point +@@ -4047,6 +4050,13 @@ scsih_qcmd(struct Scsi_Host *shost, stru + if (ioc->logging_level & MPT_DEBUG_SCSI) + scsi_print_command(scmd); + ++ /* ++ * Lock the device for any subsequent command until command is ++ * done. ++ */ ++ if (ata_12_16_cmd(scmd)) ++ scsi_internal_device_block(scmd->device); ++ + sas_device_priv_data = scmd->device->hostdata; + if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { + scmd->result = DID_NO_CONNECT << 16; +@@ -4622,6 +4632,9 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *i + if (scmd == NULL) + return 1; + ++ if (ata_12_16_cmd(scmd)) ++ scsi_internal_device_unblock(scmd->device, SDEV_RUNNING); ++ + mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); + + if (mpi_reply == NULL) { diff --git a/queue-4.8/thermal-powerclamp-add-back-module-device-table.patch b/queue-4.8/thermal-powerclamp-add-back-module-device-table.patch new file mode 100644 index 00000000000..03c25cfa91d --- /dev/null +++ b/queue-4.8/thermal-powerclamp-add-back-module-device-table.patch @@ -0,0 +1,42 @@ +From ec638db8cb9ddd5ca08b23f2835b6c9c15eb616d Mon Sep 17 00:00:00 2001 +From: Jacob Pan +Date: Mon, 14 Nov 2016 11:08:45 -0800 +Subject: thermal/powerclamp: add back module device table + +From: Jacob Pan + +commit ec638db8cb9ddd5ca08b23f2835b6c9c15eb616d upstream. + +Commit 3105f234e0aba43e44e277c20f9b32ee8add43d4 replaced module +cpu id table with a cpu feature check, which is logically correct. +But we need the module device table to allow module auto loading. + +Fixes:3105f234 thermal/powerclamp: correct cpu support check +Signed-off-by: Jacob Pan +Signed-off-by: Zhang Rui +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/intel_powerclamp.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/thermal/intel_powerclamp.c ++++ b/drivers/thermal/intel_powerclamp.c +@@ -669,9 +669,16 @@ static struct thermal_cooling_device_ops + .set_cur_state = powerclamp_set_cur_state, + }; + ++static const struct x86_cpu_id __initconst intel_powerclamp_ids[] = { ++ { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_MWAIT }, ++ {} ++}; ++MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); ++ + static int __init powerclamp_probe(void) + { +- if (!boot_cpu_has(X86_FEATURE_MWAIT)) { ++ ++ if (!x86_match_cpu(intel_powerclamp_ids)) { + pr_err("CPU does not support MWAIT"); + return -ENODEV; + } diff --git a/queue-4.8/tile-avoid-using-clocksource_cyc2ns-with-absolute-cycle-count.patch b/queue-4.8/tile-avoid-using-clocksource_cyc2ns-with-absolute-cycle-count.patch new file mode 100644 index 00000000000..501a2471041 --- /dev/null +++ b/queue-4.8/tile-avoid-using-clocksource_cyc2ns-with-absolute-cycle-count.patch @@ -0,0 +1,65 @@ +From e658a6f14d7c0243205f035979d0ecf6c12a036f Mon Sep 17 00:00:00 2001 +From: Chris Metcalf +Date: Wed, 16 Nov 2016 11:18:05 -0500 +Subject: tile: avoid using clocksource_cyc2ns with absolute cycle count + +From: Chris Metcalf + +commit e658a6f14d7c0243205f035979d0ecf6c12a036f upstream. + +For large values of "mult" and long uptimes, the intermediate +result of "cycles * mult" can overflow 64 bits. For example, +the tile platform calls clocksource_cyc2ns with a 1.2 GHz clock; +we have mult = 853, and after 208.5 days, we overflow 64 bits. + +Since clocksource_cyc2ns() is intended to be used for relative +cycle counts, not absolute cycle counts, performance is more +importance than accepting a wider range of cycle values. So, +just use mult_frac() directly in tile's sched_clock(). + +Commit 4cecf6d401a0 ("sched, x86: Avoid unnecessary overflow +in sched_clock") by Salman Qazi results in essentially the same +generated code for x86 as this change does for tile. In fact, +a follow-on change by Salman introduced mult_frac() and switched +to using it, so the C code was largely identical at that point too. + +Peter Zijlstra then added mul_u64_u32_shr() and switched x86 +to use it. This is, in principle, better; by optimizing the +64x64->64 multiplies to be 32x32->64 multiplies we can potentially +save some time. However, the compiler piplines the 64x64->64 +multiplies pretty well, and the conditional branch in the generic +mul_u64_u32_shr() causes some bubbles in execution, with the +result that it's pretty much a wash. If tilegx provided its own +implementation of mul_u64_u32_shr() without the conditional branch, +we could potentially save 3 cycles, but that seems like small gain +for a fair amount of additional build scaffolding; no other platform +currently provides a mul_u64_u32_shr() override, and tile doesn't +currently have an header to put the override in. + +Additionally, gcc currently has an optimization bug that prevents +it from recognizing the opportunity to use a 32x32->64 multiply, +and so the result would be no better than the existing mult_frac() +until such time as the compiler is fixed. + +For now, just using mult_frac() seems like the right answer. + +Signed-off-by: Chris Metcalf +Signed-off-by: Greg Kroah-Hartman + +--- + arch/tile/kernel/time.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/tile/kernel/time.c ++++ b/arch/tile/kernel/time.c +@@ -218,8 +218,8 @@ void do_timer_interrupt(struct pt_regs * + */ + unsigned long long sched_clock(void) + { +- return clocksource_cyc2ns(get_cycles(), +- sched_clock_mult, SCHED_CLOCK_SHIFT); ++ return mult_frac(get_cycles(), ++ sched_clock_mult, 1ULL << SCHED_CLOCK_SHIFT); + } + + int setup_profiling_timer(unsigned int multiplier) diff --git a/queue-4.8/usb-chipidea-move-the-lock-initialization-to-core-file.patch b/queue-4.8/usb-chipidea-move-the-lock-initialization-to-core-file.patch new file mode 100644 index 00000000000..f2089e6e2d0 --- /dev/null +++ b/queue-4.8/usb-chipidea-move-the-lock-initialization-to-core-file.patch @@ -0,0 +1,137 @@ +From a5d906bb261cde5f881a949d3b0fbaa285dcc574 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Tue, 15 Nov 2016 18:05:33 +0800 +Subject: usb: chipidea: move the lock initialization to core file + +From: Peter Chen + +commit a5d906bb261cde5f881a949d3b0fbaa285dcc574 upstream. + +This can fix below dump when the lock is accessed at host +mode due to it is not initialized. + +[ 46.119638] INFO: trying to register non-static key. +[ 46.124643] the code is fine but needs lockdep annotation. +[ 46.130144] turning off the locking correctness validator. +[ 46.135659] CPU: 0 PID: 690 Comm: cat Not tainted 4.9.0-rc3-00079-g4b75f1d #1210 +[ 46.143075] Hardware name: Freescale i.MX6 SoloX (Device Tree) +[ 46.148923] Backtrace: +[ 46.151448] [] (dump_backtrace) from [] (show_stack+0x18/0x1c) +[ 46.159038] r7:edf52000 +[ 46.161412] r6:60000193 +[ 46.163967] r5:00000000 +[ 46.165035] r4:c0e25c2c + +[ 46.169109] [] (show_stack) from [] (dump_stack+0xb4/0xe8) +[ 46.176362] [] (dump_stack) from [] (register_lock_class+0x4fc/0x56c) +[ 46.184554] r10:c0e25d24 +[ 46.187014] r9:edf53e70 +[ 46.189569] r8:c1642444 +[ 46.190637] r7:ee9da024 +[ 46.193191] r6:00000000 +[ 46.194258] r5:00000000 +[ 46.196812] r4:00000000 +[ 46.199185] r3:00000001 + +[ 46.203259] [] (register_lock_class) from [] (__lock_acquire+0x80/0x10f0) +[ 46.211797] r10:c0e25d24 +[ 46.214257] r9:edf53e70 +[ 46.216813] r8:ee9da024 +[ 46.217880] r7:c1642444 +[ 46.220435] r6:edcd1800 +[ 46.221502] r5:60000193 +[ 46.224057] r4:00000000 + +[ 46.227953] [] (__lock_acquire) from [] (lock_acquire+0x74/0x94) +[ 46.235710] r10:00000001 +[ 46.238169] r9:edf53e70 +[ 46.240723] r8:edf53f80 +[ 46.241790] r7:00000001 +[ 46.244344] r6:00000001 +[ 46.245412] r5:60000193 +[ 46.247966] r4:00000000 + +[ 46.251866] [] (lock_acquire) from [] (_raw_spin_lock_irqsave+0x40/0x54) +[ 46.260319] r7:ee1c6a00 +[ 46.262691] r6:c062a570 +[ 46.265247] r5:20000113 +[ 46.266314] r4:ee9da014 + +[ 46.270393] [] (_raw_spin_lock_irqsave) from [] (ci_port_test_show+0x2c/0x70) +[ 46.279280] r6:eebd2000 +[ 46.281652] r5:ee9da010 +[ 46.284207] r4:ee9da014 + +[ 46.286810] [] (ci_port_test_show) from [] (seq_read+0x1ac/0x4f8) +[ 46.294655] r9:edf53e70 +[ 46.297028] r8:edf53f80 +[ 46.299583] r7:ee1c6a00 +[ 46.300650] r6:00000001 +[ 46.303205] r5:00000000 +[ 46.304273] r4:eebd2000 +[ 46.306850] [] (seq_read) from [] (full_proxy_read+0x54/0x6c) +[ 46.314348] r10:00000000 +[ 46.316808] r9:c0a6ad30 +[ 46.319363] r8:edf53f80 +[ 46.320430] r7:00020000 +[ 46.322986] r6:b6de3000 +[ 46.324053] r5:ee1c6a00 +[ 46.326607] r4:c0248b58 + +[ 46.330505] [] (full_proxy_read) from [] (__vfs_read+0x34/0x118) +[ 46.338262] r9:edf52000 +[ 46.340635] r8:c0107fc4 +[ 46.343190] r7:00020000 +[ 46.344257] r6:edf53f80 +[ 46.346812] r5:c039e810 +[ 46.347879] r4:ee1c6a00 +[ 46.350447] [] (__vfs_read) from [] (vfs_read+0x8c/0x11c) +[ 46.357597] r9:edf52000 +[ 46.359969] r8:c0107fc4 +[ 46.362524] r7:edf53f80 +[ 46.363592] r6:b6de3000 +[ 46.366147] r5:ee1c6a00 +[ 46.367214] r4:00020000 +[ 46.369782] [] (vfs_read) from [] (SyS_read+0x4c/0xa8) +[ 46.376672] r8:c0107fc4 +[ 46.379045] r7:00020000 +[ 46.381600] r6:b6de3000 +[ 46.382667] r5:ee1c6a00 +[ 46.385222] r4:ee1c6a00 + +[ 46.387817] [] (SyS_read) from [] (ret_fast_syscall+0x0/0x1c) +[ 46.395314] r7:00000003 +[ 46.397687] r6:b6de3000 +[ 46.400243] r5:00020000 +[ 46.401310] r4:00020000 + +Fixes: 26c696c678c4 ("USB: Chipidea: rename struct ci13xxx variables from udc to ci") +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/core.c | 1 + + drivers/usb/chipidea/udc.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -914,6 +914,7 @@ static int ci_hdrc_probe(struct platform + if (!ci) + return -ENOMEM; + ++ spin_lock_init(&ci->lock); + ci->dev = dev; + ci->platdata = dev_get_platdata(dev); + ci->imx28_write_fix = !!(ci->platdata->flags & +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -1895,8 +1895,6 @@ static int udc_start(struct ci_hdrc *ci) + struct usb_otg_caps *otg_caps = &ci->platdata->ci_otg_caps; + int retval = 0; + +- spin_lock_init(&ci->lock); +- + ci->gadget.ops = &usb_gadget_ops; + ci->gadget.speed = USB_SPEED_UNKNOWN; + ci->gadget.max_speed = USB_SPEED_HIGH; diff --git a/queue-4.8/usb-serial-cp210x-add-id-for-the-zone-dpmx.patch b/queue-4.8/usb-serial-cp210x-add-id-for-the-zone-dpmx.patch new file mode 100644 index 00000000000..e1de5a79565 --- /dev/null +++ b/queue-4.8/usb-serial-cp210x-add-id-for-the-zone-dpmx.patch @@ -0,0 +1,32 @@ +From 2ab13292d7a314fa45de0acc808e41aaad31989c Mon Sep 17 00:00:00 2001 +From: Paul Jakma +Date: Wed, 16 Nov 2016 10:13:49 +0000 +Subject: USB: serial: cp210x: add ID for the Zone DPMX + +From: Paul Jakma + +commit 2ab13292d7a314fa45de0acc808e41aaad31989c upstream. + +The BRIM Brothers Zone DPMX is a bicycle powermeter. This ID is for the USB +serial interface in its charging dock for the control pods, via which some +settings for the pods can be modified. + +Signed-off-by: Paul Jakma +Cc: Barry Redmond +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -131,6 +131,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ ++ { USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */ + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ diff --git a/queue-4.8/usb-serial-ftdi_sio-add-support-for-ti-cc3200-launchpad.patch b/queue-4.8/usb-serial-ftdi_sio-add-support-for-ti-cc3200-launchpad.patch new file mode 100644 index 00000000000..cb22558f9d9 --- /dev/null +++ b/queue-4.8/usb-serial-ftdi_sio-add-support-for-ti-cc3200-launchpad.patch @@ -0,0 +1,48 @@ +From 9bfef729a3d11f04d12788d749a3ce6b47645734 Mon Sep 17 00:00:00 2001 +From: Doug Brown +Date: Fri, 4 Nov 2016 21:18:20 -0700 +Subject: USB: serial: ftdi_sio: add support for TI CC3200 LaunchPad + +From: Doug Brown + +commit 9bfef729a3d11f04d12788d749a3ce6b47645734 upstream. + +This patch adds support for the TI CC3200 LaunchPad board, which uses a +custom USB vendor ID and product ID. Channel A is used for JTAG, and +channel B is used for a UART. + +Signed-off-by: Doug Brown +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 2 ++ + drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ + 2 files changed, 8 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1012,6 +1012,8 @@ static const struct usb_device_id id_tab + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, + { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, + { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, ++ { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), ++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { } /* Terminating entry */ + }; + +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -596,6 +596,12 @@ + #define STK541_PID 0x2109 /* Zigbee Controller */ + + /* ++ * Texas Instruments ++ */ ++#define TI_VID 0x0451 ++#define TI_CC3200_LAUNCHPAD_PID 0xC32A /* SimpleLink Wi-Fi CC3200 LaunchPad */ ++ ++/* + * Blackfin gnICE JTAG + * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + */ diff --git a/queue-4.8/x.509-fix-double-free-in-x509_cert_parse.patch b/queue-4.8/x.509-fix-double-free-in-x509_cert_parse.patch new file mode 100644 index 00000000000..92de71e9d36 --- /dev/null +++ b/queue-4.8/x.509-fix-double-free-in-x509_cert_parse.patch @@ -0,0 +1,62 @@ +From 2b95fda2c4fcb6d6625963f889247538f247fce0 Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Thu, 24 Nov 2016 13:23:03 +0000 +Subject: X.509: Fix double free in x509_cert_parse() [ver #3] + +From: Andrey Ryabinin + +commit 2b95fda2c4fcb6d6625963f889247538f247fce0 upstream. + +We shouldn't free cert->pub->key in x509_cert_parse() because +x509_free_certificate() also does this: + BUG: Double free or freeing an invalid pointer + ... + Call Trace: + [] dump_stack+0x63/0x83 + [] kasan_object_err+0x21/0x70 + [] kasan_report_double_free+0x49/0x60 + [] kasan_slab_free+0x9d/0xc0 + [] kfree+0x8a/0x1a0 + [] public_key_free+0x1f/0x30 + [] x509_free_certificate+0x24/0x90 + [] x509_cert_parse+0x2bc/0x300 + [] x509_key_preparse+0x3e/0x330 + [] asymmetric_key_preparse+0x6f/0x100 + [] key_create_or_update+0x260/0x5f0 + [] SyS_add_key+0x199/0x2a0 + [] entry_SYSCALL_64_fastpath+0x1e/0xad + Object at ffff880110bd1900, in cache kmalloc-512 size: 512 + .... + Freed: + PID = 2579 + [] save_stack_trace+0x1b/0x20 + [] save_stack+0x46/0xd0 + [] kasan_slab_free+0x73/0xc0 + [] kfree+0x8a/0x1a0 + [] x509_cert_parse+0x2a3/0x300 + [] x509_key_preparse+0x3e/0x330 + [] asymmetric_key_preparse+0x6f/0x100 + [] key_create_or_update+0x260/0x5f0 + [] SyS_add_key+0x199/0x2a0 + [] entry_SYSCALL_64_fastpath+0x1e/0xad + +Fixes: db6c43bd2132 ("crypto: KEYS: convert public key and digsig asym to the akcipher api") +Signed-off-by: Andrey Ryabinin +Signed-off-by: David Howells +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/asymmetric_keys/x509_cert_parser.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/crypto/asymmetric_keys/x509_cert_parser.c ++++ b/crypto/asymmetric_keys/x509_cert_parser.c +@@ -133,7 +133,6 @@ struct x509_certificate *x509_cert_parse + return cert; + + error_decode: +- kfree(cert->pub->key); + kfree(ctx); + error_no_ctx: + x509_free_certificate(cert); diff --git a/queue-4.8/x86-fpu-fix-invalid-fpu-ptrace-state-after-execve.patch b/queue-4.8/x86-fpu-fix-invalid-fpu-ptrace-state-after-execve.patch new file mode 100644 index 00000000000..cc70e4cce9a --- /dev/null +++ b/queue-4.8/x86-fpu-fix-invalid-fpu-ptrace-state-after-execve.patch @@ -0,0 +1,63 @@ +From b22cbe404a9cc3c7949e380fa1861e31934c8978 Mon Sep 17 00:00:00 2001 +From: Yu-cheng Yu +Date: Thu, 17 Nov 2016 09:11:35 -0800 +Subject: x86/fpu: Fix invalid FPU ptrace state after execve() + +From: Yu-cheng Yu + +commit b22cbe404a9cc3c7949e380fa1861e31934c8978 upstream. + +Robert O'Callahan reported that after an execve PTRACE_GETREGSET +NT_X86_XSTATE continues to return the pre-exec register values +until the exec'ed task modifies FPU state. + +The test code is at: + + https://bugzilla.redhat.com/attachment.cgi?id=1164286. + +What is happening is fpu__clear() does not properly clear fpstate. +Fix it by doing just that. + +Reported-by: Robert O'Callahan +Signed-off-by: Yu-cheng Yu +Cc: Andy Lutomirski +Cc: Borislav Petkov +Cc: David Hansen +Cc: Fenghua Yu +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Ravi V. Shankar +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/1479402695-6553-1-git-send-email-yu-cheng.yu@intel.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/fpu/core.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -517,14 +517,14 @@ void fpu__clear(struct fpu *fpu) + { + WARN_ON_FPU(fpu != ¤t->thread.fpu); /* Almost certainly an anomaly */ + +- if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) { +- /* FPU state will be reallocated lazily at the first use. */ +- fpu__drop(fpu); +- } else { +- if (!fpu->fpstate_active) { +- fpu__activate_curr(fpu); +- user_fpu_begin(); +- } ++ fpu__drop(fpu); ++ ++ /* ++ * Make sure fpstate is cleared and initialized. ++ */ ++ if (static_cpu_has(X86_FEATURE_FPU)) { ++ fpu__activate_curr(fpu); ++ user_fpu_begin(); + copy_init_fpstate_to_fpregs(); + } + } diff --git a/queue-4.8/x86-traps-ignore-high-word-of-regs-cs-in-early_fixup_exception.patch b/queue-4.8/x86-traps-ignore-high-word-of-regs-cs-in-early_fixup_exception.patch new file mode 100644 index 00000000000..de5950775f2 --- /dev/null +++ b/queue-4.8/x86-traps-ignore-high-word-of-regs-cs-in-early_fixup_exception.patch @@ -0,0 +1,67 @@ +From fc0e81b2bea0ebceb71889b61d2240856141c9ee Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Sat, 19 Nov 2016 18:42:40 -0800 +Subject: x86/traps: Ignore high word of regs->cs in early_fixup_exception() + +From: Andy Lutomirski + +commit fc0e81b2bea0ebceb71889b61d2240856141c9ee upstream. + +On the 80486 DX, it seems that some exceptions may leave garbage in +the high bits of CS. This causes sporadic failures in which +early_fixup_exception() refuses to fix up an exception. + +As far as I can tell, this has been buggy for a long time, but the +problem seems to have been exacerbated by commits: + + 1e02ce4cccdc ("x86: Store a per-cpu shadow copy of CR4") + e1bfc11c5a6f ("x86/init: Fix cr4_init_shadow() on CR4-less machines") + +This appears to have broken for as long as we've had early +exception handling. + +[ Note to stable maintainers: This patch is needed all the way back to 3.4, + but it will only apply to 4.6 and up, as it depends on commit: + + 0e861fbb5bda ("x86/head: Move early exception panic code into early_fixup_exception()") + + If you want to backport to kernels before 4.6, please don't backport the + prerequisites (there was a big chain of them that rewrote a lot of the + early exception machinery); instead, ask me and I can send you a one-liner + that will apply. ] + +Reported-by: Matthew Whitehead +Signed-off-by: Andy Lutomirski +Cc: Borislav Petkov +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: H. Peter Anvin +Cc: Josh Poimboeuf +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: 4c5023a3fa2e ("x86-32: Handle exception table entries during early boot") +Link: http://lkml.kernel.org/r/cb32c69920e58a1a58e7b5cad975038a69c0ce7d.1479609510.git.luto@kernel.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/extable.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/x86/mm/extable.c ++++ b/arch/x86/mm/extable.c +@@ -135,7 +135,12 @@ void __init early_fixup_exception(struct + if (early_recursion_flag > 2) + goto halt_loop; + +- if (regs->cs != __KERNEL_CS) ++ /* ++ * Old CPUs leave the high bits of CS on the stack ++ * undefined. I'm not sure which CPUs do this, but at least ++ * the 486 DX works this way. ++ */ ++ if ((regs->cs & 0xFFFF) != __KERNEL_CS) + goto fail; + + /* diff --git a/queue-4.8/xc2028-fix-use-after-free-bug-properly.patch b/queue-4.8/xc2028-fix-use-after-free-bug-properly.patch new file mode 100644 index 00000000000..a171eba68a8 --- /dev/null +++ b/queue-4.8/xc2028-fix-use-after-free-bug-properly.patch @@ -0,0 +1,129 @@ +From 22a1e7783e173ab3d86018eb590107d68df46c11 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 17 Nov 2016 10:49:31 +0100 +Subject: xc2028: Fix use-after-free bug properly + +From: Takashi Iwai + +commit 22a1e7783e173ab3d86018eb590107d68df46c11 upstream. + +The commit 8dfbcc4351a0 ("[media] xc2028: avoid use after free") tried +to address the reported use-after-free by clearing the reference. + +However, it's clearing the wrong pointer; it sets NULL to +priv->ctrl.fname, but it's anyway overwritten by the next line +memcpy(&priv->ctrl, p, sizeof(priv->ctrl)). + +OTOH, the actual code accessing the freed string is the strcmp() call +with priv->fname: + if (!firmware_name[0] && p->fname && + priv->fname && strcmp(p->fname, priv->fname)) + free_firmware(priv); + +where priv->fname points to the previous file name, and this was +already freed by kfree(). + +For fixing the bug properly, this patch does the following: + +- Keep the copy of firmware file name in only priv->fname, + priv->ctrl.fname isn't changed; +- The allocation is done only when the firmware gets loaded; +- The kfree() is called in free_firmware() commonly + +Fixes: commit 8dfbcc4351a0 ('[media] xc2028: avoid use after free') +Signed-off-by: Takashi Iwai +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/tuners/tuner-xc2028.c | 37 +++++++++++++++--------------------- + 1 file changed, 16 insertions(+), 21 deletions(-) + +--- a/drivers/media/tuners/tuner-xc2028.c ++++ b/drivers/media/tuners/tuner-xc2028.c +@@ -281,6 +281,14 @@ static void free_firmware(struct xc2028_ + int i; + tuner_dbg("%s called\n", __func__); + ++ /* free allocated f/w string */ ++ if (priv->fname != firmware_name) ++ kfree(priv->fname); ++ priv->fname = NULL; ++ ++ priv->state = XC2028_NO_FIRMWARE; ++ memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); ++ + if (!priv->firm) + return; + +@@ -291,9 +299,6 @@ static void free_firmware(struct xc2028_ + + priv->firm = NULL; + priv->firm_size = 0; +- priv->state = XC2028_NO_FIRMWARE; +- +- memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); + } + + static int load_all_firmwares(struct dvb_frontend *fe, +@@ -884,9 +889,8 @@ read_not_reliable: + return 0; + + fail: +- priv->state = XC2028_NO_FIRMWARE; ++ free_firmware(priv); + +- memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); + if (retry_count < 8) { + msleep(50); + retry_count++; +@@ -1332,11 +1336,8 @@ static int xc2028_dvb_release(struct dvb + mutex_lock(&xc2028_list_mutex); + + /* only perform final cleanup if this is the last instance */ +- if (hybrid_tuner_report_instance_count(priv) == 1) { ++ if (hybrid_tuner_report_instance_count(priv) == 1) + free_firmware(priv); +- kfree(priv->ctrl.fname); +- priv->ctrl.fname = NULL; +- } + + if (priv) + hybrid_tuner_release_state(priv); +@@ -1399,19 +1400,8 @@ static int xc2028_set_config(struct dvb_ + + /* + * Copy the config data. +- * For the firmware name, keep a local copy of the string, +- * in order to avoid troubles during device release. + */ +- kfree(priv->ctrl.fname); +- priv->ctrl.fname = NULL; + memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); +- if (p->fname) { +- priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); +- if (priv->ctrl.fname == NULL) { +- rc = -ENOMEM; +- goto unlock; +- } +- } + + /* + * If firmware name changed, frees firmware. As free_firmware will +@@ -1426,10 +1416,15 @@ static int xc2028_set_config(struct dvb_ + + if (priv->state == XC2028_NO_FIRMWARE) { + if (!firmware_name[0]) +- priv->fname = priv->ctrl.fname; ++ priv->fname = kstrdup(p->fname, GFP_KERNEL); + else + priv->fname = firmware_name; + ++ if (!priv->fname) { ++ rc = -ENOMEM; ++ goto unlock; ++ } ++ + rc = request_firmware_nowait(THIS_MODULE, 1, + priv->fname, + priv->i2c_props.adap->dev.parent,