From 0f23eb5bac5a0bcd75f7b4d2e2e466463e59678c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Apr 2018 17:20:02 +0200 Subject: [PATCH] 4.16-stable patches added patches: asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch asoc-topology-fix-kcontrol-name-string-handling.patch block-use-32-bit-blk_status_t-on-alpha.patch ceph-always-update-atime-mtime-ctime-for-new-inode.patch ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch ext4-add-extra-checks-to-ext4_xattr_block_get.patch ext4-add-validity-checks-for-bitmap-block-numbers.patch ext4-always-initialize-the-crc32c-checksum-driver.patch ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch ext4-eliminate-sleep-from-shutdown-ioctl.patch ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch ext4-limit-xattr-size-to-int_max.patch ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch ext4-pass-eshutdown-code-to-jbd2-layer.patch ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch ext4-shutdown-should-not-prevent-get_write_access.patch extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch hid-core-fix-size-as-type-u32.patch hid-fix-hid_report_len-usage.patch irqchip-gic-take-lock-when-updating-irq-type.patch jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch powerpc-eeh-fix-race-with-driver-un-bind.patch powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch thunderbolt-handle-connecting-device-in-place-of-host-properly.patch thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch --- ...ace-reg_default_raw-with-reg_default.patch | 77 ++++++ ...gy-fix-kcontrol-name-string-handling.patch | 106 +++++++ ...ock-use-32-bit-blk_status_t-on-alpha.patch | 53 ++++ ...date-atime-mtime-ctime-for-new-inode.patch | 60 ++++ ...ds-checking-to-ext4_xattr_find_entry.patch | 103 +++++++ ...extra-checks-to-ext4_xattr_block_get.patch | 108 ++++++++ ...dity-checks-for-bitmap-block-numbers.patch | 101 +++++++ ...nitialize-the-crc32c-checksum-driver.patch | 51 ++++ ...tadata-blocks-overlap-the-superblock.patch | 51 ++++ ...-checksum-of-new-initialized-bitmaps.patch | 115 ++++++++ ...-eliminate-sleep-from-shutdown-ioctl.patch | 35 +++ ...et-for-root-directory-if-unallocated.patch | 45 +++ ...-on-32-bit-archs-in-ext4_iomap_begin.patch | 47 ++++ ...of-directory-pointer-after-seekdir-2.patch | 44 +++ .../ext4-limit-xattr-size-to-int_max.patch | 53 ++++ ...t4_error-into-ext4_xattr_check_block.patch | 153 +++++++++++ ...t4-pass-eshutdown-code-to-jbd2-layer.patch | 90 ++++++ ...e-by-i_data_sem-in-direct-write-path.patch | 58 ++++ ...-should-not-prevent-get_write_access.patch | 38 +++ ...tion-and-drv-flags-for-v5-boost-gpio.patch | 57 ++++ .../hid-core-fix-size-as-type-u32.patch | 98 +++++++ queue-4.16/hid-fix-hid_report_len-usage.patch | 91 ++++++ ...gic-take-lock-when-updating-irq-type.patch | 77 ++++++ ...n-don-t-allow-update-of-the-log-tail.patch | 41 +++ ...hen-running-as-a-hpt-guest-on-power9.patch | 84 ++++++ ...finition-use-use-lwsync-consistently.patch | 53 ++++ ...restore_cpu-clear-unwanted-lpcr-bits.patch | 81 ++++++ ...-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch | 43 +++ ...rpc-eeh-fix-race-with-driver-un-bind.patch | 258 ++++++++++++++++++ ...ode-when-trying-to-load-kdump-kernel.patch | 51 ++++ ...trace-due-to-incorrect-preempt-count.patch | 103 +++++++ ...-checkstops-caused-by-invalid-tlbiel.patch | 75 +++++ ...ix-opal-nvram-driver-opal_busy-loops.patch | 52 ++++ ...nown-opal-errors-in-opal_nvram_write.patch | 38 +++ ...hter-cap-in-credit_entropy_bits_safe.patch | 38 +++ queue-4.16/series | 41 +++ ...r-accessed-when-subdomains-are-added.patch | 35 +++ ...ing-device-in-place-of-host-properly.patch | 83 ++++++ ...ash-when-icm-firmware-is-not-running.patch | 55 ++++ ...l-after-hibernation-image-is-created.patch | 38 +++ ...pcie-tunnel-creation-with-pci-rescan.patch | 51 ++++ ...r-icm-to-authenticate-the-active-nvm.patch | 55 ++++ 42 files changed, 2986 insertions(+) create mode 100644 queue-4.16/asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch create mode 100644 queue-4.16/asoc-topology-fix-kcontrol-name-string-handling.patch create mode 100644 queue-4.16/block-use-32-bit-blk_status_t-on-alpha.patch create mode 100644 queue-4.16/ceph-always-update-atime-mtime-ctime-for-new-inode.patch create mode 100644 queue-4.16/ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch create mode 100644 queue-4.16/ext4-add-extra-checks-to-ext4_xattr_block_get.patch create mode 100644 queue-4.16/ext4-add-validity-checks-for-bitmap-block-numbers.patch create mode 100644 queue-4.16/ext4-always-initialize-the-crc32c-checksum-driver.patch create mode 100644 queue-4.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch create mode 100644 queue-4.16/ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch create mode 100644 queue-4.16/ext4-eliminate-sleep-from-shutdown-ioctl.patch create mode 100644 queue-4.16/ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch create mode 100644 queue-4.16/ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch create mode 100644 queue-4.16/ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch create mode 100644 queue-4.16/ext4-limit-xattr-size-to-int_max.patch create mode 100644 queue-4.16/ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch create mode 100644 queue-4.16/ext4-pass-eshutdown-code-to-jbd2-layer.patch create mode 100644 queue-4.16/ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch create mode 100644 queue-4.16/ext4-shutdown-should-not-prevent-get_write_access.patch create mode 100644 queue-4.16/extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch create mode 100644 queue-4.16/hid-core-fix-size-as-type-u32.patch create mode 100644 queue-4.16/hid-fix-hid_report_len-usage.patch create mode 100644 queue-4.16/irqchip-gic-take-lock-when-updating-irq-type.patch create mode 100644 queue-4.16/jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch create mode 100644 queue-4.16/powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch create mode 100644 queue-4.16/powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch create mode 100644 queue-4.16/powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch create mode 100644 queue-4.16/powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch create mode 100644 queue-4.16/powerpc-eeh-fix-race-with-driver-un-bind.patch create mode 100644 queue-4.16/powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch create mode 100644 queue-4.16/powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch create mode 100644 queue-4.16/powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch create mode 100644 queue-4.16/powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch create mode 100644 queue-4.16/powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch create mode 100644 queue-4.16/random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch create mode 100644 queue-4.16/soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch create mode 100644 queue-4.16/thunderbolt-handle-connecting-device-in-place-of-host-properly.patch create mode 100644 queue-4.16/thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch create mode 100644 queue-4.16/thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch create mode 100644 queue-4.16/thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch create mode 100644 queue-4.16/thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch diff --git a/queue-4.16/asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch b/queue-4.16/asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch new file mode 100644 index 00000000000..984a33c636a --- /dev/null +++ b/queue-4.16/asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch @@ -0,0 +1,77 @@ +From a01df75ce737951ad13a08d101306e88c3f57cb2 Mon Sep 17 00:00:00 2001 +From: James Kelly +Date: Mon, 19 Mar 2018 21:29:50 +1100 +Subject: ASoC: ssm2602: Replace reg_default_raw with reg_default + +From: James Kelly + +commit a01df75ce737951ad13a08d101306e88c3f57cb2 upstream. + +SSM2602 driver is broken on recent kernels (at least +since 4.9). User space applications such as amixer or +alsamixer get EIO when attempting to access codec +controls via the relevant IOCTLs. + +Root cause of these failures is the regcache_hw_init +function in drivers/base/regmap/regcache.c, which +prevents regmap cache initalization from the +reg_defaults_raw element of the regmap_config structure +when registers are write only. It also disables the +regmap cache entirely when all registers are write only +or volatile as is the case for the SSM2602 driver. + +Using the reg_defaults element of the regmap_config +structure rather than the reg_defaults_raw element to +initalize the regmap cache avoids the logic in the +regcache_hw_init function entirely. It also makes this +driver consistent with other ASoC codec drivers, as +this driver was the ONLY codec driver that used the +reg_defaults_raw element to initalize the cache. + +Tested on Digilent Zybo Z7 development board which has +a SSM2603 codec chip connected to a Xilinx Zynq SoC. + +Signed-off-by: James Kelly +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/ssm2602.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/sound/soc/codecs/ssm2602.c ++++ b/sound/soc/codecs/ssm2602.c +@@ -54,10 +54,17 @@ struct ssm2602_priv { + * using 2 wire for device control, so we cache them instead. + * There is no point in caching the reset register + */ +-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { +- 0x0097, 0x0097, 0x0079, 0x0079, +- 0x000a, 0x0008, 0x009f, 0x000a, +- 0x0000, 0x0000 ++static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = { ++ { .reg = 0x00, .def = 0x0097 }, ++ { .reg = 0x01, .def = 0x0097 }, ++ { .reg = 0x02, .def = 0x0079 }, ++ { .reg = 0x03, .def = 0x0079 }, ++ { .reg = 0x04, .def = 0x000a }, ++ { .reg = 0x05, .def = 0x0008 }, ++ { .reg = 0x06, .def = 0x009f }, ++ { .reg = 0x07, .def = 0x000a }, ++ { .reg = 0x08, .def = 0x0000 }, ++ { .reg = 0x09, .def = 0x0000 } + }; + + +@@ -620,8 +627,8 @@ const struct regmap_config ssm2602_regma + .volatile_reg = ssm2602_register_volatile, + + .cache_type = REGCACHE_RBTREE, +- .reg_defaults_raw = ssm2602_reg, +- .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), ++ .reg_defaults = ssm2602_reg, ++ .num_reg_defaults = ARRAY_SIZE(ssm2602_reg), + }; + EXPORT_SYMBOL_GPL(ssm2602_regmap_config); + diff --git a/queue-4.16/asoc-topology-fix-kcontrol-name-string-handling.patch b/queue-4.16/asoc-topology-fix-kcontrol-name-string-handling.patch new file mode 100644 index 00000000000..468216dac38 --- /dev/null +++ b/queue-4.16/asoc-topology-fix-kcontrol-name-string-handling.patch @@ -0,0 +1,106 @@ +From 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d Mon Sep 17 00:00:00 2001 +From: Liam Girdwood +Date: Tue, 27 Mar 2018 12:04:04 +0100 +Subject: ASoC: topology: Fix kcontrol name string handling + +From: Liam Girdwood + +commit 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d upstream. + +Fix the topology kcontrol string handling so that string pointer +references are strdup()ed instead of being copied. This fixes issues +with kcontrol templates on the stack or ones that are freed. Remember +and free the strings too when topology is unloaded. + +Signed-off-by: Liam Girdwood +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-topology.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- a/sound/soc/soc-topology.c ++++ b/sound/soc/soc-topology.c +@@ -523,6 +523,7 @@ static void remove_widget(struct snd_soc + kfree(se->dobj.control.dtexts[j]); + + kfree(se); ++ kfree(w->kcontrol_news[i].name); + } + kfree(w->kcontrol_news); + } else { +@@ -540,6 +541,7 @@ static void remove_widget(struct snd_soc + */ + kfree((void *)kcontrol->private_value); + snd_ctl_remove(card, kcontrol); ++ kfree(w->kcontrol_news[i].name); + } + kfree(w->kcontrol_news); + } +@@ -1233,7 +1235,9 @@ static struct snd_kcontrol_new *soc_tplg + dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n", + mc->hdr.name, i); + +- kc[i].name = mc->hdr.name; ++ kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL); ++ if (kc[i].name == NULL) ++ goto err_str; + kc[i].private_value = (long)sm; + kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kc[i].access = mc->hdr.access; +@@ -1278,8 +1282,10 @@ static struct snd_kcontrol_new *soc_tplg + err_str: + kfree(sm); + err: +- for (--i; i >= 0; i--) ++ for (--i; i >= 0; i--) { + kfree((void *)kc[i].private_value); ++ kfree(kc[i].name); ++ } + kfree(kc); + return NULL; + } +@@ -1310,7 +1316,9 @@ static struct snd_kcontrol_new *soc_tplg + dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n", + ec->hdr.name); + +- kc[i].name = ec->hdr.name; ++ kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL); ++ if (kc[i].name == NULL) ++ goto err_se; + kc[i].private_value = (long)se; + kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kc[i].access = ec->hdr.access; +@@ -1386,6 +1394,7 @@ err_se: + kfree(se->dobj.control.dtexts[j]); + + kfree(se); ++ kfree(kc[i].name); + } + err: + kfree(kc); +@@ -1424,7 +1433,9 @@ static struct snd_kcontrol_new *soc_tplg + "ASoC: adding bytes kcontrol %s with access 0x%x\n", + be->hdr.name, be->hdr.access); + +- kc[i].name = be->hdr.name; ++ kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL); ++ if (kc[i].name == NULL) ++ goto err; + kc[i].private_value = (long)sbe; + kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kc[i].access = be->hdr.access; +@@ -1454,8 +1465,10 @@ static struct snd_kcontrol_new *soc_tplg + return kc; + + err: +- for (--i; i >= 0; i--) ++ for (--i; i >= 0; i--) { + kfree((void *)kc[i].private_value); ++ kfree(kc[i].name); ++ } + + kfree(kc); + return NULL; diff --git a/queue-4.16/block-use-32-bit-blk_status_t-on-alpha.patch b/queue-4.16/block-use-32-bit-blk_status_t-on-alpha.patch new file mode 100644 index 00000000000..62070134a82 --- /dev/null +++ b/queue-4.16/block-use-32-bit-blk_status_t-on-alpha.patch @@ -0,0 +1,53 @@ +From 6e2fb22103b99c26ae30a46512abe75526d8e4c9 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 21 Mar 2018 12:42:25 -0400 +Subject: block: use 32-bit blk_status_t on Alpha + +From: Mikulas Patocka + +commit 6e2fb22103b99c26ae30a46512abe75526d8e4c9 upstream. + +Early alpha processors cannot write a single byte or word; they read 8 +bytes, modify the value in registers and write back 8 bytes. + +The type blk_status_t is defined as one byte, it is often written +asynchronously by I/O completion routines, this asynchronous modification +can corrupt content of nearby bytes if these nearby bytes can be written +simultaneously by another CPU. + +- one example of such corruption is the structure dm_io where + "blk_status_t status" is written by an asynchronous completion routine + and "atomic_t io_count" is modified synchronously +- another example is the structure dm_buffer where "unsigned hold_count" + is modified synchronously from process context and "blk_status_t + write_error" is modified asynchronously from bio completion routine + +This patch fixes the bug by changing the type blk_status_t to 32 bits if +we are on Alpha and if we are compiling for a processor that doesn't have +the byte-word-extension. + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org # 4.13+ +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/blk_types.h | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/include/linux/blk_types.h ++++ b/include/linux/blk_types.h +@@ -20,8 +20,13 @@ typedef void (bio_end_io_t) (struct bio + + /* + * Block error status values. See block/blk-core:blk_errors for the details. ++ * Alpha cannot write a byte atomically, so we need to use 32-bit value. + */ ++#if defined(CONFIG_ALPHA) && !defined(__alpha_bwx__) ++typedef u32 __bitwise blk_status_t; ++#else + typedef u8 __bitwise blk_status_t; ++#endif + #define BLK_STS_OK 0 + #define BLK_STS_NOTSUPP ((__force blk_status_t)1) + #define BLK_STS_TIMEOUT ((__force blk_status_t)2) diff --git a/queue-4.16/ceph-always-update-atime-mtime-ctime-for-new-inode.patch b/queue-4.16/ceph-always-update-atime-mtime-ctime-for-new-inode.patch new file mode 100644 index 00000000000..986faef85db --- /dev/null +++ b/queue-4.16/ceph-always-update-atime-mtime-ctime-for-new-inode.patch @@ -0,0 +1,60 @@ +From ffdeec7aa41aa61ca4ee68fddf4669df9ce661d1 Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" +Date: Mon, 26 Mar 2018 16:46:39 +0800 +Subject: ceph: always update atime/mtime/ctime for new inode + +From: Yan, Zheng + +commit ffdeec7aa41aa61ca4ee68fddf4669df9ce661d1 upstream. + +For new inode, atime/mtime/ctime are uninitialized. Don't compare +against them. + +Cc: stable@kernel.org +Signed-off-by: "Yan, Zheng" +Reviewed-by: Ilya Dryomov +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/inode.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/fs/ceph/inode.c ++++ b/fs/ceph/inode.c +@@ -660,13 +660,15 @@ void ceph_fill_file_time(struct inode *i + CEPH_CAP_FILE_BUFFER| + CEPH_CAP_AUTH_EXCL| + CEPH_CAP_XATTR_EXCL)) { +- if (timespec_compare(ctime, &inode->i_ctime) > 0) { ++ if (ci->i_version == 0 || ++ timespec_compare(ctime, &inode->i_ctime) > 0) { + dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n", + inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, + ctime->tv_sec, ctime->tv_nsec); + inode->i_ctime = *ctime; + } +- if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) { ++ if (ci->i_version == 0 || ++ ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) { + /* the MDS did a utimes() */ + dout("mtime %ld.%09ld -> %ld.%09ld " + "tw %d -> %d\n", +@@ -786,7 +788,6 @@ static int fill_inode(struct inode *inod + new_issued = ~issued & le32_to_cpu(info->cap.caps); + + /* update inode */ +- ci->i_version = le64_to_cpu(info->version); + inode->i_rdev = le32_to_cpu(info->rdev); + inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; + +@@ -857,6 +858,9 @@ static int fill_inode(struct inode *inod + xattr_blob = NULL; + } + ++ /* finally update i_version */ ++ ci->i_version = le64_to_cpu(info->version); ++ + inode->i_mapping->a_ops = &ceph_aops; + + switch (inode->i_mode & S_IFMT) { diff --git a/queue-4.16/ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch b/queue-4.16/ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch new file mode 100644 index 00000000000..1942797f994 --- /dev/null +++ b/queue-4.16/ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch @@ -0,0 +1,103 @@ +From 9496005d6ca4cf8f5ee8f828165a8956872dc59d Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Fri, 30 Mar 2018 20:00:56 -0400 +Subject: ext4: add bounds checking to ext4_xattr_find_entry() + +From: Theodore Ts'o + +commit 9496005d6ca4cf8f5ee8f828165a8956872dc59d upstream. + +Add some paranoia checks to make sure we don't stray beyond the end of +the valid memory region containing ext4 xattr entries while we are +scanning for a match. + +Also rename the function to xattr_find_entry() since it is static and +thus only used in fs/ext4/xattr.c + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -276,18 +276,22 @@ errout: + __xattr_check_inode((inode), (header), (end), __func__, __LINE__) + + static int +-ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index, +- const char *name, int sorted) ++xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry, ++ void *end, int name_index, const char *name, int sorted) + { +- struct ext4_xattr_entry *entry; ++ struct ext4_xattr_entry *entry, *next; + size_t name_len; + int cmp = 1; + + if (name == NULL) + return -EINVAL; + name_len = strlen(name); +- entry = *pentry; +- for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { ++ for (entry = *pentry; !IS_LAST_ENTRY(entry); entry = next) { ++ next = EXT4_XATTR_NEXT(entry); ++ if ((void *) next >= end) { ++ EXT4_ERROR_INODE(inode, "corrupted xattr entries"); ++ return -EFSCORRUPTED; ++ } + cmp = name_index - entry->e_name_index; + if (!cmp) + cmp = name_len - entry->e_name_len; +@@ -509,6 +513,7 @@ ext4_xattr_block_get(struct inode *inode + struct buffer_head *bh = NULL; + struct ext4_xattr_entry *entry; + size_t size; ++ void *end; + int error; + struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode); + +@@ -530,7 +535,8 @@ ext4_xattr_block_get(struct inode *inode + goto cleanup; + ext4_xattr_block_cache_insert(ea_block_cache, bh); + entry = BFIRST(bh); +- error = ext4_xattr_find_entry(&entry, name_index, name, 1); ++ end = bh->b_data + bh->b_size; ++ error = xattr_find_entry(inode, &entry, end, name_index, name, 1); + if (error) + goto cleanup; + size = le32_to_cpu(entry->e_value_size); +@@ -579,7 +585,7 @@ ext4_xattr_ibody_get(struct inode *inode + if (error) + goto cleanup; + entry = IFIRST(header); +- error = ext4_xattr_find_entry(&entry, name_index, name, 0); ++ error = xattr_find_entry(inode, &entry, end, name_index, name, 0); + if (error) + goto cleanup; + size = le32_to_cpu(entry->e_value_size); +@@ -1808,8 +1814,8 @@ ext4_xattr_block_find(struct inode *inod + bs->s.first = BFIRST(bs->bh); + bs->s.end = bs->bh->b_data + bs->bh->b_size; + bs->s.here = bs->s.first; +- error = ext4_xattr_find_entry(&bs->s.here, i->name_index, +- i->name, 1); ++ error = xattr_find_entry(inode, &bs->s.here, bs->s.end, ++ i->name_index, i->name, 1); + if (error && error != -ENODATA) + goto cleanup; + bs->s.not_found = error; +@@ -2168,8 +2174,8 @@ int ext4_xattr_ibody_find(struct inode * + if (error) + return error; + /* Find the named attribute. */ +- error = ext4_xattr_find_entry(&is->s.here, i->name_index, +- i->name, 0); ++ error = xattr_find_entry(inode, &is->s.here, is->s.end, ++ i->name_index, i->name, 0); + if (error && error != -ENODATA) + return error; + is->s.not_found = error; diff --git a/queue-4.16/ext4-add-extra-checks-to-ext4_xattr_block_get.patch b/queue-4.16/ext4-add-extra-checks-to-ext4_xattr_block_get.patch new file mode 100644 index 00000000000..52eaf41f2e6 --- /dev/null +++ b/queue-4.16/ext4-add-extra-checks-to-ext4_xattr_block_get.patch @@ -0,0 +1,108 @@ +From 54dd0e0a1b255f115f8647fc6fb93273251b01b9 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Fri, 30 Mar 2018 20:04:11 -0400 +Subject: ext4: add extra checks to ext4_xattr_block_get() + +From: Theodore Ts'o + +commit 54dd0e0a1b255f115f8647fc6fb93273251b01b9 upstream. + +Add explicit checks in ext4_xattr_block_get() just in case the +e_value_offs and e_value_size fields in the the xattr block are +corrupted in memory after the buffer_verified bit is set on the xattr +block. + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 26 +++++++++++++++++++------- + fs/ext4/xattr.h | 11 +++++++++++ + 2 files changed, 30 insertions(+), 7 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -197,7 +197,7 @@ ext4_xattr_check_entries(struct ext4_xat + while (!IS_LAST_ENTRY(entry)) { + u32 size = le32_to_cpu(entry->e_value_size); + +- if (size > INT_MAX) ++ if (size > EXT4_XATTR_SIZE_MAX) + return -EFSCORRUPTED; + + if (size != 0 && entry->e_value_inum == 0) { +@@ -540,8 +540,10 @@ ext4_xattr_block_get(struct inode *inode + if (error) + goto cleanup; + size = le32_to_cpu(entry->e_value_size); ++ error = -ERANGE; ++ if (unlikely(size > EXT4_XATTR_SIZE_MAX)) ++ goto cleanup; + if (buffer) { +- error = -ERANGE; + if (size > buffer_size) + goto cleanup; + if (entry->e_value_inum) { +@@ -550,8 +552,12 @@ ext4_xattr_block_get(struct inode *inode + if (error) + goto cleanup; + } else { +- memcpy(buffer, bh->b_data + +- le16_to_cpu(entry->e_value_offs), size); ++ u16 offset = le16_to_cpu(entry->e_value_offs); ++ void *p = bh->b_data + offset; ++ ++ if (unlikely(p + size > end)) ++ goto cleanup; ++ memcpy(buffer, p, size); + } + } + error = size; +@@ -589,8 +595,10 @@ ext4_xattr_ibody_get(struct inode *inode + if (error) + goto cleanup; + size = le32_to_cpu(entry->e_value_size); ++ error = -ERANGE; ++ if (unlikely(size > EXT4_XATTR_SIZE_MAX)) ++ goto cleanup; + if (buffer) { +- error = -ERANGE; + if (size > buffer_size) + goto cleanup; + if (entry->e_value_inum) { +@@ -599,8 +607,12 @@ ext4_xattr_ibody_get(struct inode *inode + if (error) + goto cleanup; + } else { +- memcpy(buffer, (void *)IFIRST(header) + +- le16_to_cpu(entry->e_value_offs), size); ++ u16 offset = le16_to_cpu(entry->e_value_offs); ++ void *p = (void *)IFIRST(header) + offset; ++ ++ if (unlikely(p + size > end)) ++ goto cleanup; ++ memcpy(buffer, p, size); + } + } + error = size; +--- a/fs/ext4/xattr.h ++++ b/fs/ext4/xattr.h +@@ -71,6 +71,17 @@ struct ext4_xattr_entry { + #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) + + /* ++ * XATTR_SIZE_MAX is currently 64k, but for the purposes of checking ++ * for file system consistency errors, we use a somewhat bigger value. ++ * This allows XATTR_SIZE_MAX to grow in the future, but by using this ++ * instead of INT_MAX for certain consistency checks, we don't need to ++ * worry about arithmetic overflows. (Actually XATTR_SIZE_MAX is ++ * defined in include/uapi/linux/limits.h, so changing it is going ++ * not going to be trivial....) ++ */ ++#define EXT4_XATTR_SIZE_MAX (1 << 24) ++ ++/* + * The minimum size of EA value when you start storing it in an external inode + * size of block - size of header - size of 1 entry - 4 null bytes + */ diff --git a/queue-4.16/ext4-add-validity-checks-for-bitmap-block-numbers.patch b/queue-4.16/ext4-add-validity-checks-for-bitmap-block-numbers.patch new file mode 100644 index 00000000000..1ff5a43651b --- /dev/null +++ b/queue-4.16/ext4-add-validity-checks-for-bitmap-block-numbers.patch @@ -0,0 +1,101 @@ +From 7dac4a1726a9c64a517d595c40e95e2d0d135f6f Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 26 Mar 2018 23:54:10 -0400 +Subject: ext4: add validity checks for bitmap block numbers + +From: Theodore Ts'o + +commit 7dac4a1726a9c64a517d595c40e95e2d0d135f6f upstream. + +An privileged attacker can cause a crash by mounting a crafted ext4 +image which triggers a out-of-bounds read in the function +ext4_valid_block_bitmap() in fs/ext4/balloc.c. + +This issue has been assigned CVE-2018-1093. + +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199181 +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1560782 +Reported-by: Wen Xu +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 16 ++++++++++++++-- + fs/ext4/ialloc.c | 7 +++++++ + 2 files changed, 21 insertions(+), 2 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -338,20 +338,25 @@ static ext4_fsblk_t ext4_valid_block_bit + /* check whether block bitmap block number is set */ + blk = ext4_block_bitmap(sb, desc); + offset = blk - group_first_block; +- if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) ++ if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || ++ !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) + /* bad block bitmap */ + return blk; + + /* check whether the inode bitmap block number is set */ + blk = ext4_inode_bitmap(sb, desc); + offset = blk - group_first_block; +- if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) ++ if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || ++ !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) + /* bad block bitmap */ + return blk; + + /* check whether the inode table block number is set */ + blk = ext4_inode_table(sb, desc); + offset = blk - group_first_block; ++ if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || ++ EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= sb->s_blocksize) ++ return blk; + next_zero_bit = ext4_find_next_zero_bit(bh->b_data, + EXT4_B2C(sbi, offset + sbi->s_itb_per_group), + EXT4_B2C(sbi, offset)); +@@ -417,6 +422,7 @@ struct buffer_head * + ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) + { + struct ext4_group_desc *desc; ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + struct buffer_head *bh; + ext4_fsblk_t bitmap_blk; + int err; +@@ -425,6 +431,12 @@ ext4_read_block_bitmap_nowait(struct sup + if (!desc) + return ERR_PTR(-EFSCORRUPTED); + bitmap_blk = ext4_block_bitmap(sb, desc); ++ if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || ++ (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { ++ ext4_error(sb, "Invalid block bitmap block %llu in " ++ "block_group %u", bitmap_blk, block_group); ++ return ERR_PTR(-EFSCORRUPTED); ++ } + bh = sb_getblk(sb, bitmap_blk); + if (unlikely(!bh)) { + ext4_error(sb, "Cannot get buffer for block bitmap - " +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -122,6 +122,7 @@ static struct buffer_head * + ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) + { + struct ext4_group_desc *desc; ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + struct buffer_head *bh = NULL; + ext4_fsblk_t bitmap_blk; + int err; +@@ -131,6 +132,12 @@ ext4_read_inode_bitmap(struct super_bloc + return ERR_PTR(-EFSCORRUPTED); + + bitmap_blk = ext4_inode_bitmap(sb, desc); ++ if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || ++ (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { ++ ext4_error(sb, "Invalid inode bitmap blk %llu in " ++ "block_group %u", bitmap_blk, block_group); ++ return ERR_PTR(-EFSCORRUPTED); ++ } + bh = sb_getblk(sb, bitmap_blk); + if (unlikely(!bh)) { + ext4_error(sb, "Cannot read inode bitmap - " diff --git a/queue-4.16/ext4-always-initialize-the-crc32c-checksum-driver.patch b/queue-4.16/ext4-always-initialize-the-crc32c-checksum-driver.patch new file mode 100644 index 00000000000..69cedd4619b --- /dev/null +++ b/queue-4.16/ext4-always-initialize-the-crc32c-checksum-driver.patch @@ -0,0 +1,51 @@ +From a45403b51582a87872927a3e0fc0a389c26867f1 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Thu, 29 Mar 2018 22:10:31 -0400 +Subject: ext4: always initialize the crc32c checksum driver + +From: Theodore Ts'o + +commit a45403b51582a87872927a3e0fc0a389c26867f1 upstream. + +The extended attribute code now uses the crc32c checksum for hashing +purposes, so we should just always always initialize it. We also want +to prevent NULL pointer dereferences if one of the metadata checksum +features is enabled after the file sytsem is originally mounted. + +This issue has been assigned CVE-2018-1094. + +https://bugzilla.kernel.org/show_bug.cgi?id=199183 +https://bugzilla.redhat.com/show_bug.cgi?id=1560788 + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3490,15 +3490,12 @@ static int ext4_fill_super(struct super_ + } + + /* Load the checksum driver */ +- if (ext4_has_feature_metadata_csum(sb) || +- ext4_has_feature_ea_inode(sb)) { +- sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); +- if (IS_ERR(sbi->s_chksum_driver)) { +- ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver."); +- ret = PTR_ERR(sbi->s_chksum_driver); +- sbi->s_chksum_driver = NULL; +- goto failed_mount; +- } ++ sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); ++ if (IS_ERR(sbi->s_chksum_driver)) { ++ ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver."); ++ ret = PTR_ERR(sbi->s_chksum_driver); ++ sbi->s_chksum_driver = NULL; ++ goto failed_mount; + } + + /* Check superblock checksum */ diff --git a/queue-4.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch b/queue-4.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch new file mode 100644 index 00000000000..e43718a7b8d --- /dev/null +++ b/queue-4.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch @@ -0,0 +1,51 @@ +From 18db4b4e6fc31eda838dd1c1296d67dbcb3dc957 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Thu, 29 Mar 2018 22:10:35 -0400 +Subject: ext4: don't allow r/w mounts if metadata blocks overlap the superblock + +From: Theodore Ts'o + +commit 18db4b4e6fc31eda838dd1c1296d67dbcb3dc957 upstream. + +If some metadata block, such as an allocation bitmap, overlaps the +superblock, it's very likely that if the file system is mounted +read/write, the results will not be pretty. So disallow r/w mounts +for file systems corrupted in this particular way. + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2333,6 +2333,8 @@ static int ext4_check_descriptors(struct + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Block bitmap for group %u overlaps " + "superblock", i); ++ if (!sb_rdonly(sb)) ++ return 0; + } + if (block_bitmap < first_block || block_bitmap > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " +@@ -2345,6 +2347,8 @@ static int ext4_check_descriptors(struct + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode bitmap for group %u overlaps " + "superblock", i); ++ if (!sb_rdonly(sb)) ++ return 0; + } + if (inode_bitmap < first_block || inode_bitmap > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " +@@ -2357,6 +2361,8 @@ static int ext4_check_descriptors(struct + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode table for group %u overlaps " + "superblock", i); ++ if (!sb_rdonly(sb)) ++ return 0; + } + if (inode_table < first_block || + inode_table + sbi->s_itb_per_group - 1 > last_block) { diff --git a/queue-4.16/ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch b/queue-4.16/ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch new file mode 100644 index 00000000000..8391f578d1a --- /dev/null +++ b/queue-4.16/ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch @@ -0,0 +1,115 @@ +From 044e6e3d74a3d7103a0c8a9305dfd94d64000660 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 19 Feb 2018 14:16:47 -0500 +Subject: ext4: don't update checksum of new initialized bitmaps + +From: Theodore Ts'o + +commit 044e6e3d74a3d7103a0c8a9305dfd94d64000660 upstream. + +When reading the inode or block allocation bitmap, if the bitmap needs +to be initialized, do not update the checksum in the block group +descriptor. That's because we're not set up to journal those changes. +Instead, just set the verified bit on the bitmap block, so that it's +not necessary to validate the checksum. + +When a block or inode allocation actually happens, at that point the +checksum will be calculated, and update of the bg descriptor block +will be properly journalled. + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 3 +-- + fs/ext4/ialloc.c | 47 +++-------------------------------------------- + 2 files changed, 4 insertions(+), 46 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -243,8 +243,6 @@ static int ext4_init_block_bitmap(struct + */ + ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), + sb->s_blocksize * 8, bh->b_data); +- ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); +- ext4_group_desc_csum_set(sb, block_group, gdp); + return 0; + } + +@@ -448,6 +446,7 @@ ext4_read_block_bitmap_nowait(struct sup + err = ext4_init_block_bitmap(sb, bh, block_group, desc); + set_bitmap_uptodate(bh); + set_buffer_uptodate(bh); ++ set_buffer_verified(bh); + ext4_unlock_group(sb, block_group); + unlock_buffer(bh); + if (err) { +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -66,44 +66,6 @@ void ext4_mark_bitmap_end(int start_bit, + memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); + } + +-/* Initializes an uninitialized inode bitmap */ +-static int ext4_init_inode_bitmap(struct super_block *sb, +- struct buffer_head *bh, +- ext4_group_t block_group, +- struct ext4_group_desc *gdp) +-{ +- struct ext4_group_info *grp; +- struct ext4_sb_info *sbi = EXT4_SB(sb); +- J_ASSERT_BH(bh, buffer_locked(bh)); +- +- /* If checksum is bad mark all blocks and inodes use to prevent +- * allocation, essentially implementing a per-group read-only flag. */ +- if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { +- grp = ext4_get_group_info(sb, block_group); +- if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) +- percpu_counter_sub(&sbi->s_freeclusters_counter, +- grp->bb_free); +- set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); +- if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { +- int count; +- count = ext4_free_inodes_count(sb, gdp); +- percpu_counter_sub(&sbi->s_freeinodes_counter, +- count); +- } +- set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); +- return -EFSBADCRC; +- } +- +- memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); +- ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, +- bh->b_data); +- ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh, +- EXT4_INODES_PER_GROUP(sb) / 8); +- ext4_group_desc_csum_set(sb, block_group, gdp); +- +- return 0; +-} +- + void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate) + { + if (uptodate) { +@@ -187,17 +149,14 @@ ext4_read_inode_bitmap(struct super_bloc + + ext4_lock_group(sb, block_group); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { +- err = ext4_init_inode_bitmap(sb, bh, block_group, desc); ++ memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); ++ ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), ++ sb->s_blocksize * 8, bh->b_data); + set_bitmap_uptodate(bh); + set_buffer_uptodate(bh); + set_buffer_verified(bh); + ext4_unlock_group(sb, block_group); + unlock_buffer(bh); +- if (err) { +- ext4_error(sb, "Failed to init inode bitmap for group " +- "%u: %d", block_group, err); +- goto out; +- } + return bh; + } + ext4_unlock_group(sb, block_group); diff --git a/queue-4.16/ext4-eliminate-sleep-from-shutdown-ioctl.patch b/queue-4.16/ext4-eliminate-sleep-from-shutdown-ioctl.patch new file mode 100644 index 00000000000..1c741a33a16 --- /dev/null +++ b/queue-4.16/ext4-eliminate-sleep-from-shutdown-ioctl.patch @@ -0,0 +1,35 @@ +From a6d9946bb925293fda9f5ed6d33d8580b001f006 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 18 Feb 2018 23:16:28 -0500 +Subject: ext4: eliminate sleep from shutdown ioctl + +From: Theodore Ts'o + +commit a6d9946bb925293fda9f5ed6d33d8580b001f006 upstream. + +The msleep() when processing EXT4_GOING_FLAGS_NOLOGFLUSH was a hack to +avoid some races (that are now fixed), but in fact it introduced its +own race. + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ioctl.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -497,10 +497,8 @@ static int ext4_shutdown(struct super_bl + break; + case EXT4_GOING_FLAGS_NOLOGFLUSH: + set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); +- if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) { +- msleep(100); ++ if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) + jbd2_journal_abort(sbi->s_journal, 0); +- } + break; + default: + return -EINVAL; diff --git a/queue-4.16/ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch b/queue-4.16/ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch new file mode 100644 index 00000000000..ef2c00720ff --- /dev/null +++ b/queue-4.16/ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch @@ -0,0 +1,45 @@ +From 8e4b5eae5decd9dfe5a4ee369c22028f90ab4c44 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Thu, 29 Mar 2018 21:56:09 -0400 +Subject: ext4: fail ext4_iget for root directory if unallocated + +From: Theodore Ts'o + +commit 8e4b5eae5decd9dfe5a4ee369c22028f90ab4c44 upstream. + +If the root directory has an i_links_count of zero, then when the file +system is mounted, then when ext4_fill_super() notices the problem and +tries to call iput() the root directory in the error return path, +ext4_evict_inode() will try to free the inode on disk, before all of +the file system structures are set up, and this will result in an OOPS +caused by a NULL pointer dereference. + +This issue has been assigned CVE-2018-1092. + +https://bugzilla.kernel.org/show_bug.cgi?id=199179 +https://bugzilla.redhat.com/show_bug.cgi?id=1560777 + +Reported-by: Wen Xu +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4745,6 +4745,12 @@ struct inode *ext4_iget(struct super_blo + goto bad_inode; + raw_inode = ext4_raw_inode(&iloc); + ++ if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { ++ EXT4_ERROR_INODE(inode, "root inode unallocated"); ++ ret = -EFSCORRUPTED; ++ goto bad_inode; ++ } ++ + if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { + ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); + if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > diff --git a/queue-4.16/ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch b/queue-4.16/ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch new file mode 100644 index 00000000000..98c48cad1aa --- /dev/null +++ b/queue-4.16/ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch @@ -0,0 +1,47 @@ +From fe23cb65c2c394ea306f3714a17d46ab2e6a0af1 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Thu, 22 Mar 2018 11:50:26 -0400 +Subject: ext4: fix offset overflow on 32-bit archs in ext4_iomap_begin() + +From: Jiri Slaby + +commit fe23cb65c2c394ea306f3714a17d46ab2e6a0af1 upstream. + +ext4_iomap_begin() has a bug where offset returned in the iomap +structure will be truncated to unsigned long size. On 64-bit +architectures this is fine but on 32-bit architectures obviously not. +Not many places actually use the offset stored in the iomap structure +but one of visible failures is in SEEK_HOLE / SEEK_DATA implementation. +If we create a file like: + +dd if=/dev/urandom of=file bs=1k seek=8m count=1 + +then + +lseek64("file", 0x100000000ULL, SEEK_DATA) + +wrongly returns 0x100000000 on unfixed kernel while it should return +0x200000000. Avoid the overflow by proper type cast. + +Fixes: 545052e9e35a ("ext4: Switch to iomap for SEEK_HOLE / SEEK_DATA") +Signed-off-by: Jiri Slaby +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org # v4.15 +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3524,7 +3524,7 @@ retry: + iomap->flags |= IOMAP_F_DIRTY; + iomap->bdev = inode->i_sb->s_bdev; + iomap->dax_dev = sbi->s_daxdev; +- iomap->offset = first_block << blkbits; ++ iomap->offset = (u64)first_block << blkbits; + iomap->length = (u64)map.m_len << blkbits; + + if (ret == 0) { diff --git a/queue-4.16/ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch b/queue-4.16/ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch new file mode 100644 index 00000000000..2e91ffa940c --- /dev/null +++ b/queue-4.16/ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch @@ -0,0 +1,44 @@ +From e40ff213898502d299351cc2fe1e350cd186f0d3 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 1 Apr 2018 23:21:03 -0400 +Subject: ext4: force revalidation of directory pointer after seekdir(2) + +From: Theodore Ts'o + +commit e40ff213898502d299351cc2fe1e350cd186f0d3 upstream. + +A malicious user could force the directory pointer to be in an invalid +spot by using seekdir(2). Use the mechanism we already have to notice +if the directory has changed since the last time we called +ext4_readdir() to force a revalidation of the pointer. + +Reported-by: syzbot+1236ce66f79263e8a862@syzkaller.appspotmail.com +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/dir.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -365,13 +365,15 @@ static loff_t ext4_dir_llseek(struct fil + { + struct inode *inode = file->f_mapping->host; + int dx_dir = is_dx_dir(inode); +- loff_t htree_max = ext4_get_htree_eof(file); ++ loff_t ret, htree_max = ext4_get_htree_eof(file); + + if (likely(dx_dir)) +- return generic_file_llseek_size(file, offset, whence, ++ ret = generic_file_llseek_size(file, offset, whence, + htree_max, htree_max); + else +- return ext4_llseek(file, offset, whence); ++ ret = ext4_llseek(file, offset, whence); ++ file->f_version = inode_peek_iversion(inode) - 1; ++ return ret; + } + + /* diff --git a/queue-4.16/ext4-limit-xattr-size-to-int_max.patch b/queue-4.16/ext4-limit-xattr-size-to-int_max.patch new file mode 100644 index 00000000000..3b5684b8b5b --- /dev/null +++ b/queue-4.16/ext4-limit-xattr-size-to-int_max.patch @@ -0,0 +1,53 @@ +From ce3fd194fcc6fbdc00ce095a852f22df97baa401 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 29 Mar 2018 14:31:42 -0400 +Subject: ext4: limit xattr size to INT_MAX + +From: Eric Biggers + +commit ce3fd194fcc6fbdc00ce095a852f22df97baa401 upstream. + +ext4 isn't validating the sizes of xattrs where the value of the xattr +is stored in an external inode. This is problematic because +->e_value_size is a u32, but ext4_xattr_get() returns an int. A very +large size is misinterpreted as an error code, which ext4_get_acl() +translates into a bogus ERR_PTR() for which IS_ERR() returns false, +causing a crash. + +Fix this by validating that all xattrs are <= INT_MAX bytes. + +This issue has been assigned CVE-2018-1095. + +https://bugzilla.kernel.org/show_bug.cgi?id=199185 +https://bugzilla.redhat.com/show_bug.cgi?id=1560793 + +Reported-by: Wen Xu +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Fixes: e50e5129f384 ("ext4: xattr-in-inode support") +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -195,10 +195,13 @@ ext4_xattr_check_entries(struct ext4_xat + + /* Check the values */ + while (!IS_LAST_ENTRY(entry)) { +- if (entry->e_value_size != 0 && +- entry->e_value_inum == 0) { ++ u32 size = le32_to_cpu(entry->e_value_size); ++ ++ if (size > INT_MAX) ++ return -EFSCORRUPTED; ++ ++ if (size != 0 && entry->e_value_inum == 0) { + u16 offs = le16_to_cpu(entry->e_value_offs); +- u32 size = le32_to_cpu(entry->e_value_size); + void *value; + + /* diff --git a/queue-4.16/ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch b/queue-4.16/ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch new file mode 100644 index 00000000000..61287c4333a --- /dev/null +++ b/queue-4.16/ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch @@ -0,0 +1,153 @@ +From de05ca8526796c7e9f7c7282b7f89a818af19818 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Fri, 30 Mar 2018 15:42:25 -0400 +Subject: ext4: move call to ext4_error() into ext4_xattr_check_block() + +From: Theodore Ts'o + +commit de05ca8526796c7e9f7c7282b7f89a818af19818 upstream. + +Refactor the call to EXT4_ERROR_INODE() into ext4_xattr_check_block(). +This simplifies the code, and fixes a problem where not all callers of +ext4_xattr_check_block() were not resulting in ext4_error() getting +called when the xattr block is corrupted. + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 60 +++++++++++++++++++++++++------------------------------- + 1 file changed, 27 insertions(+), 33 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -225,25 +225,36 @@ ext4_xattr_check_entries(struct ext4_xat + } + + static inline int +-ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh) ++__ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, ++ const char *function, unsigned int line) + { +- int error; ++ int error = -EFSCORRUPTED; + + if (buffer_verified(bh)) + return 0; + + if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || + BHDR(bh)->h_blocks != cpu_to_le32(1)) +- return -EFSCORRUPTED; ++ goto errout; ++ error = -EFSBADCRC; + if (!ext4_xattr_block_csum_verify(inode, bh)) +- return -EFSBADCRC; ++ goto errout; + error = ext4_xattr_check_entries(BFIRST(bh), bh->b_data + bh->b_size, + bh->b_data); +- if (!error) ++errout: ++ if (error) ++ __ext4_error_inode(inode, function, line, 0, ++ "corrupted xattr block %llu", ++ (unsigned long long) bh->b_blocknr); ++ else + set_buffer_verified(bh); + return error; + } + ++#define ext4_xattr_check_block(inode, bh) \ ++ __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) ++ ++ + static int + __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, + void *end, const char *function, unsigned int line) +@@ -514,12 +525,9 @@ ext4_xattr_block_get(struct inode *inode + goto cleanup; + ea_bdebug(bh, "b_count=%d, refcount=%d", + atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); +- if (ext4_xattr_check_block(inode, bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; ++ error = ext4_xattr_check_block(inode, bh); ++ if (error) + goto cleanup; +- } + ext4_xattr_block_cache_insert(ea_block_cache, bh); + entry = BFIRST(bh); + error = ext4_xattr_find_entry(&entry, name_index, name, 1); +@@ -679,12 +687,9 @@ ext4_xattr_block_list(struct dentry *den + goto cleanup; + ea_bdebug(bh, "b_count=%d, refcount=%d", + atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount)); +- if (ext4_xattr_check_block(inode, bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; ++ error = ext4_xattr_check_block(inode, bh); ++ if (error) + goto cleanup; +- } + ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh); + error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size); + +@@ -811,10 +816,9 @@ int ext4_get_inode_usage(struct inode *i + goto out; + } + +- if (ext4_xattr_check_block(inode, bh)) { +- ret = -EFSCORRUPTED; ++ ret = ext4_xattr_check_block(inode, bh); ++ if (ret) + goto out; +- } + + for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); + entry = EXT4_XATTR_NEXT(entry)) +@@ -1796,12 +1800,9 @@ ext4_xattr_block_find(struct inode *inod + ea_bdebug(bs->bh, "b_count=%d, refcount=%d", + atomic_read(&(bs->bh->b_count)), + le32_to_cpu(BHDR(bs->bh)->h_refcount)); +- if (ext4_xattr_check_block(inode, bs->bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; ++ error = ext4_xattr_check_block(inode, bs->bh); ++ if (error) + goto cleanup; +- } + /* Find the named attribute. */ + bs->s.base = BHDR(bs->bh); + bs->s.first = BFIRST(bs->bh); +@@ -2724,13 +2725,9 @@ retry: + error = -EIO; + if (!bh) + goto cleanup; +- if (ext4_xattr_check_block(inode, bh)) { +- EXT4_ERROR_INODE(inode, "bad block %llu", +- EXT4_I(inode)->i_file_acl); +- error = -EFSCORRUPTED; +- brelse(bh); ++ error = ext4_xattr_check_block(inode, bh); ++ if (error) + goto cleanup; +- } + base = BHDR(bh); + end = bh->b_data + bh->b_size; + min_offs = end - base; +@@ -2887,11 +2884,8 @@ int ext4_xattr_delete_inode(handle_t *ha + goto cleanup; + } + error = ext4_xattr_check_block(inode, bh); +- if (error) { +- EXT4_ERROR_INODE(inode, "bad block %llu (error %d)", +- EXT4_I(inode)->i_file_acl, error); ++ if (error) + goto cleanup; +- } + + if (ext4_has_feature_ea_inode(inode->i_sb)) { + for (entry = BFIRST(bh); !IS_LAST_ENTRY(entry); diff --git a/queue-4.16/ext4-pass-eshutdown-code-to-jbd2-layer.patch b/queue-4.16/ext4-pass-eshutdown-code-to-jbd2-layer.patch new file mode 100644 index 00000000000..98dfc209689 --- /dev/null +++ b/queue-4.16/ext4-pass-eshutdown-code-to-jbd2-layer.patch @@ -0,0 +1,90 @@ +From fb7c02445c497943e7296cd3deee04422b63acb8 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 18 Feb 2018 23:45:18 -0500 +Subject: ext4: pass -ESHUTDOWN code to jbd2 layer + +From: Theodore Ts'o + +commit fb7c02445c497943e7296cd3deee04422b63acb8 upstream. + +Previously the jbd2 layer assumed that a file system check would be +required after a journal abort. In the case of the deliberate file +system shutdown, this should not be necessary. Allow the jbd2 layer +to distinguish between these two cases by using the ESHUTDOWN errno. + +Also add proper locking to __journal_abort_soft(). + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ioctl.c | 4 ++-- + fs/jbd2/journal.c | 25 +++++++++++++++++++------ + 2 files changed, 21 insertions(+), 8 deletions(-) + +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -492,13 +492,13 @@ static int ext4_shutdown(struct super_bl + set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); + if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) { + (void) ext4_force_commit(sb); +- jbd2_journal_abort(sbi->s_journal, 0); ++ jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN); + } + break; + case EXT4_GOING_FLAGS_NOLOGFLUSH: + set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); + if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) +- jbd2_journal_abort(sbi->s_journal, 0); ++ jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN); + break; + default: + return -EINVAL; +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1486,12 +1486,15 @@ static void jbd2_mark_journal_empty(jour + void jbd2_journal_update_sb_errno(journal_t *journal) + { + journal_superblock_t *sb = journal->j_superblock; ++ int errcode; + + read_lock(&journal->j_state_lock); +- jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", +- journal->j_errno); +- sb->s_errno = cpu_to_be32(journal->j_errno); ++ errcode = journal->j_errno; + read_unlock(&journal->j_state_lock); ++ if (errcode == -ESHUTDOWN) ++ errcode = 0; ++ jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode); ++ sb->s_errno = cpu_to_be32(errcode); + + jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA); + } +@@ -2108,12 +2111,22 @@ void __jbd2_journal_abort_hard(journal_t + * but don't do any other IO. */ + static void __journal_abort_soft (journal_t *journal, int errno) + { +- if (journal->j_flags & JBD2_ABORT) +- return; ++ int old_errno; + +- if (!journal->j_errno) ++ write_lock(&journal->j_state_lock); ++ old_errno = journal->j_errno; ++ if (!journal->j_errno || errno == -ESHUTDOWN) + journal->j_errno = errno; + ++ if (journal->j_flags & JBD2_ABORT) { ++ write_unlock(&journal->j_state_lock); ++ if (!old_errno && old_errno != -ESHUTDOWN && ++ errno == -ESHUTDOWN) ++ jbd2_journal_update_sb_errno(journal); ++ return; ++ } ++ write_unlock(&journal->j_state_lock); ++ + __jbd2_journal_abort_hard(journal); + + if (errno) { diff --git a/queue-4.16/ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch b/queue-4.16/ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch new file mode 100644 index 00000000000..2278c2e838a --- /dev/null +++ b/queue-4.16/ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch @@ -0,0 +1,58 @@ +From 73fdad00b208b139cf43f3163fbc0f67e4c6047c Mon Sep 17 00:00:00 2001 +From: Eryu Guan +Date: Thu, 22 Mar 2018 11:41:25 -0400 +Subject: ext4: protect i_disksize update by i_data_sem in direct write path + +From: Eryu Guan + +commit 73fdad00b208b139cf43f3163fbc0f67e4c6047c upstream. + +i_disksize update should be protected by i_data_sem, by either taking +the lock explicitly or by using ext4_update_i_disksize() helper. But the +i_disksize updates in ext4_direct_IO_write() are not protected at all, +which may be racing with i_disksize updates in writeback path in +delalloc buffer write path. + +This is found by code inspection, and I didn't hit any i_disksize +corruption due to this bug. Thanks to Jan Kara for catching this bug and +suggesting the fix! + +Reported-by: Jan Kara +Suggested-by: Jan Kara +Signed-off-by: Eryu Guan +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3658,7 +3658,6 @@ static ssize_t ext4_direct_IO_write(stru + { + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; +- struct ext4_inode_info *ei = EXT4_I(inode); + ssize_t ret; + loff_t offset = iocb->ki_pos; + size_t count = iov_iter_count(iter); +@@ -3682,7 +3681,7 @@ static ssize_t ext4_direct_IO_write(stru + goto out; + } + orphan = 1; +- ei->i_disksize = inode->i_size; ++ ext4_update_i_disksize(inode, inode->i_size); + ext4_journal_stop(handle); + } + +@@ -3790,7 +3789,7 @@ static ssize_t ext4_direct_IO_write(stru + if (ret > 0) { + loff_t end = offset + ret; + if (end > inode->i_size) { +- ei->i_disksize = end; ++ ext4_update_i_disksize(inode, end); + i_size_write(inode, end); + /* + * We're going to return a positive `ret' diff --git a/queue-4.16/ext4-shutdown-should-not-prevent-get_write_access.patch b/queue-4.16/ext4-shutdown-should-not-prevent-get_write_access.patch new file mode 100644 index 00000000000..da66c3f01c6 --- /dev/null +++ b/queue-4.16/ext4-shutdown-should-not-prevent-get_write_access.patch @@ -0,0 +1,38 @@ +From 576d18ed60f5465110087c5e0eb1010de13e374d Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 18 Feb 2018 22:07:36 -0500 +Subject: ext4: shutdown should not prevent get_write_access + +From: Theodore Ts'o + +commit 576d18ed60f5465110087c5e0eb1010de13e374d upstream. + +The ext4 forced shutdown flag needs to prevent new handles from being +started, but it needs to allow existing handles to complete. So the +forced shutdown flag should not force ext4_journal_get_write_access to +fail. + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4_jbd2.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/fs/ext4/ext4_jbd2.c ++++ b/fs/ext4/ext4_jbd2.c +@@ -166,13 +166,6 @@ int __ext4_journal_get_write_access(cons + might_sleep(); + + if (ext4_handle_valid(handle)) { +- struct super_block *sb; +- +- sb = handle->h_transaction->t_journal->j_private; +- if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) { +- jbd2_journal_abort_handle(handle); +- return -EIO; +- } + err = jbd2_journal_get_write_access(handle, bh); + if (err) + ext4_journal_abort_handle(where, line, __func__, bh, diff --git a/queue-4.16/extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch b/queue-4.16/extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch new file mode 100644 index 00000000000..888f3f682ee --- /dev/null +++ b/queue-4.16/extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch @@ -0,0 +1,57 @@ +From ad49aee401dd1997ec71360df6e51a91ad3cf516 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 19 Feb 2018 14:20:46 +0100 +Subject: extcon: intel-cht-wc: Set direction and drv flags for V5 boost GPIO + +From: Hans de Goede + +commit ad49aee401dd1997ec71360df6e51a91ad3cf516 upstream. + +Sometimes (firmware bug?) the V5 boost GPIO is not configured as output +by the BIOS, leading to the 5V boost convertor being permanently on, + +Explicitly set the direction and drv flags rather then inheriting them +from the firmware to fix this. + +Fixes: 585cb239f4de ("extcon: intel-cht-wc: Disable external 5v boost ...") +Cc: stable@vger.kernel.org +Reviewed-by: Andy Shevchenko +Signed-off-by: Hans de Goede +Signed-off-by: Chanwoo Choi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/extcon/extcon-intel-cht-wc.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/extcon/extcon-intel-cht-wc.c ++++ b/drivers/extcon/extcon-intel-cht-wc.c +@@ -66,6 +66,8 @@ + + #define CHT_WC_VBUS_GPIO_CTLO 0x6e2d + #define CHT_WC_VBUS_GPIO_CTLO_OUTPUT BIT(0) ++#define CHT_WC_VBUS_GPIO_CTLO_DRV_OD BIT(4) ++#define CHT_WC_VBUS_GPIO_CTLO_DIR_OUT BIT(5) + + enum cht_wc_usb_id { + USB_ID_OTG, +@@ -183,14 +185,15 @@ static void cht_wc_extcon_set_5v_boost(s + { + int ret, val; + +- val = enable ? CHT_WC_VBUS_GPIO_CTLO_OUTPUT : 0; +- + /* + * The 5V boost converter is enabled through a gpio on the PMIC, since + * there currently is no gpio driver we access the gpio reg directly. + */ +- ret = regmap_update_bits(ext->regmap, CHT_WC_VBUS_GPIO_CTLO, +- CHT_WC_VBUS_GPIO_CTLO_OUTPUT, val); ++ val = CHT_WC_VBUS_GPIO_CTLO_DRV_OD | CHT_WC_VBUS_GPIO_CTLO_DIR_OUT; ++ if (enable) ++ val |= CHT_WC_VBUS_GPIO_CTLO_OUTPUT; ++ ++ ret = regmap_write(ext->regmap, CHT_WC_VBUS_GPIO_CTLO, val); + if (ret) + dev_err(ext->dev, "Error writing Vbus GPIO CTLO: %d\n", ret); + } diff --git a/queue-4.16/hid-core-fix-size-as-type-u32.patch b/queue-4.16/hid-core-fix-size-as-type-u32.patch new file mode 100644 index 00000000000..26cbe3d027c --- /dev/null +++ b/queue-4.16/hid-core-fix-size-as-type-u32.patch @@ -0,0 +1,98 @@ +From 6de0b13cc0b4ba10e98a9263d7a83b940720b77a Mon Sep 17 00:00:00 2001 +From: Aaron Ma +Date: Mon, 8 Jan 2018 10:41:41 +0800 +Subject: HID: core: Fix size as type u32 + +From: Aaron Ma + +commit 6de0b13cc0b4ba10e98a9263d7a83b940720b77a upstream. + +When size is negative, calling memset will make segment fault. +Declare the size as type u32 to keep memset safe. + +size in struct hid_report is unsigned, fix return type of +hid_report_len to u32. + +Cc: stable@vger.kernel.org +Signed-off-by: Aaron Ma +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-core.c | 10 +++++----- + include/linux/hid.h | 6 +++--- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1365,7 +1365,7 @@ u8 *hid_alloc_report_buf(struct hid_repo + * of implement() working on 8 byte chunks + */ + +- int len = hid_report_len(report) + 7; ++ u32 len = hid_report_len(report) + 7; + + return kmalloc(len, flags); + } +@@ -1430,7 +1430,7 @@ void __hid_request(struct hid_device *hi + { + char *buf; + int ret; +- int len; ++ u32 len; + + buf = hid_alloc_report_buf(report, GFP_KERNEL); + if (!buf) +@@ -1456,14 +1456,14 @@ out: + } + EXPORT_SYMBOL_GPL(__hid_request); + +-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, ++int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + int interrupt) + { + struct hid_report_enum *report_enum = hid->report_enum + type; + struct hid_report *report; + struct hid_driver *hdrv; + unsigned int a; +- int rsize, csize = size; ++ u32 rsize, csize = size; + u8 *cdata = data; + int ret = 0; + +@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); + * + * This is data entry for lower layers. + */ +-int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) ++int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) + { + struct hid_report_enum *report_enum; + struct hid_driver *hdrv; +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -851,7 +851,7 @@ extern int hidinput_connect(struct hid_d + extern void hidinput_disconnect(struct hid_device *); + + int hid_set_field(struct hid_field *, unsigned, __s32); +-int hid_input_report(struct hid_device *, int type, u8 *, int, int); ++int hid_input_report(struct hid_device *, int type, u8 *, u32, int); + int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); + struct hid_field *hidinput_get_led_field(struct hid_device *hid); + unsigned int hidinput_count_leds(struct hid_device *hid); +@@ -1102,13 +1102,13 @@ static inline void hid_hw_wait(struct hi + * + * @report: the report we want to know the length + */ +-static inline int hid_report_len(struct hid_report *report) ++static inline u32 hid_report_len(struct hid_report *report) + { + /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ + return ((report->size - 1) >> 3) + 1 + (report->id > 0); + } + +-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, ++int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + int interrupt); + + /* HID quirks API */ diff --git a/queue-4.16/hid-fix-hid_report_len-usage.patch b/queue-4.16/hid-fix-hid_report_len-usage.patch new file mode 100644 index 00000000000..7504702c35d --- /dev/null +++ b/queue-4.16/hid-fix-hid_report_len-usage.patch @@ -0,0 +1,91 @@ +From 3064a03b94e60388f0955fcc29f3e8a978d28f75 Mon Sep 17 00:00:00 2001 +From: Aaron Ma +Date: Sat, 3 Feb 2018 23:57:15 +0800 +Subject: HID: Fix hid_report_len usage + +From: Aaron Ma + +commit 3064a03b94e60388f0955fcc29f3e8a978d28f75 upstream. + +Follow the change of return type u32 of hid_report_len, +fix all the types of variables those get the return value of +hid_report_len to u32, and all other code already uses u32. + +Cc: stable@vger.kernel.org +Signed-off-by: Aaron Ma +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-input.c | 3 ++- + drivers/hid/hid-multitouch.c | 5 +++-- + drivers/hid/hid-rmi.c | 4 ++-- + drivers/hid/wacom_sys.c | 4 ++-- + 4 files changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -1368,7 +1368,8 @@ static void hidinput_led_worker(struct w + led_work); + struct hid_field *field; + struct hid_report *report; +- int len, ret; ++ int ret; ++ u32 len; + __u8 *buf; + + field = hidinput_get_led_field(hid); +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -370,7 +370,8 @@ static const struct attribute_group mt_a + static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) + { + struct mt_device *td = hid_get_drvdata(hdev); +- int ret, size = hid_report_len(report); ++ int ret; ++ u32 size = hid_report_len(report); + u8 *buf; + + /* +@@ -1183,7 +1184,7 @@ static void mt_set_input_mode(struct hid + struct hid_report_enum *re; + struct mt_class *cls = &td->mtclass; + char *buf; +- int report_len; ++ u32 report_len; + + if (td->inputmode < 0) + return; +--- a/drivers/hid/hid-rmi.c ++++ b/drivers/hid/hid-rmi.c +@@ -89,8 +89,8 @@ struct rmi_data { + u8 *writeReport; + u8 *readReport; + +- int input_report_size; +- int output_report_size; ++ u32 input_report_size; ++ u32 output_report_size; + + unsigned long flags; + +--- a/drivers/hid/wacom_sys.c ++++ b/drivers/hid/wacom_sys.c +@@ -219,7 +219,7 @@ static void wacom_feature_mapping(struct + unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); + u8 *data; + int ret; +- int n; ++ u32 n; + + switch (equivalent_usage) { + case HID_DG_CONTACTMAX: +@@ -519,7 +519,7 @@ static int wacom_set_device_mode(struct + u8 *rep_data; + struct hid_report *r; + struct hid_report_enum *re; +- int length; ++ u32 length; + int error = -ENOMEM, limit = 0; + + if (wacom_wac->mode_report < 0) diff --git a/queue-4.16/irqchip-gic-take-lock-when-updating-irq-type.patch b/queue-4.16/irqchip-gic-take-lock-when-updating-irq-type.patch new file mode 100644 index 00000000000..80b424c54f1 --- /dev/null +++ b/queue-4.16/irqchip-gic-take-lock-when-updating-irq-type.patch @@ -0,0 +1,77 @@ +From aa08192a254d362a4d5317647a81de6996961aef Mon Sep 17 00:00:00 2001 +From: Aniruddha Banerjee +Date: Wed, 28 Mar 2018 19:12:00 +0530 +Subject: irqchip/gic: Take lock when updating irq type + +From: Aniruddha Banerjee + +commit aa08192a254d362a4d5317647a81de6996961aef upstream. + +Most MMIO GIC register accesses use a 1-hot bit scheme that +avoids requiring any form of locking. This isn't true for the +GICD_ICFGRn registers, which require a RMW sequence. + +Unfortunately, we seem to be missing a lock for these particular +accesses, which could result in a race condition if changing the +trigger type on any two interrupts within the same set of 16 +interrupts (and thus controlled by the same CFGR register). + +Introduce a private lock in the GIC common comde for this +particular case, making it cover both GIC implementations +in one go. + +Cc: stable@vger.kernel.org +Signed-off-by: Aniruddha Banerjee +[maz: updated changelog] +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-gic-common.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-gic-common.c ++++ b/drivers/irqchip/irq-gic-common.c +@@ -21,6 +21,8 @@ + + #include "irq-gic-common.h" + ++static DEFINE_RAW_SPINLOCK(irq_controller_lock); ++ + static const struct gic_kvm_info *gic_kvm_info; + + const struct gic_kvm_info *gic_get_kvm_info(void) +@@ -53,11 +55,13 @@ int gic_configure_irq(unsigned int irq, + u32 confoff = (irq / 16) * 4; + u32 val, oldval; + int ret = 0; ++ unsigned long flags; + + /* + * Read current configuration register, and insert the config + * for "irq", depending on "type". + */ ++ raw_spin_lock_irqsave(&irq_controller_lock, flags); + val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); + if (type & IRQ_TYPE_LEVEL_MASK) + val &= ~confmask; +@@ -65,8 +69,10 @@ int gic_configure_irq(unsigned int irq, + val |= confmask; + + /* If the current configuration is the same, then we are done */ +- if (val == oldval) ++ if (val == oldval) { ++ raw_spin_unlock_irqrestore(&irq_controller_lock, flags); + return 0; ++ } + + /* + * Write back the new configuration, and possibly re-enable +@@ -84,6 +90,7 @@ int gic_configure_irq(unsigned int irq, + pr_warn("GIC: PPI%d is secure or misconfigured\n", + irq - 16); + } ++ raw_spin_unlock_irqrestore(&irq_controller_lock, flags); + + if (sync_access) + sync_access(); diff --git a/queue-4.16/jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch b/queue-4.16/jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch new file mode 100644 index 00000000000..65d833574bd --- /dev/null +++ b/queue-4.16/jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch @@ -0,0 +1,41 @@ +From 85e0c4e89c1b864e763c4e3bb15d0b6d501ad5d9 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 19 Feb 2018 12:22:53 -0500 +Subject: jbd2: if the journal is aborted then don't allow update of the log tail + +From: Theodore Ts'o + +commit 85e0c4e89c1b864e763c4e3bb15d0b6d501ad5d9 upstream. + +This updates the jbd2 superblock unnecessarily, and on an abort we +shouldn't truncate the log. + +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd2/journal.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -974,7 +974,7 @@ out: + } + + /* +- * This is a variaon of __jbd2_update_log_tail which checks for validity of ++ * This is a variation of __jbd2_update_log_tail which checks for validity of + * provided log tail and locks j_checkpoint_mutex. So it is safe against races + * with other threads updating log tail. + */ +@@ -1417,6 +1417,9 @@ int jbd2_journal_update_sb_log_tail(jour + journal_superblock_t *sb = journal->j_superblock; + int ret; + ++ if (is_journal_aborted(journal)) ++ return -EIO; ++ + BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); + jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", + tail_block, tail_tid); diff --git a/queue-4.16/powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch b/queue-4.16/powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch new file mode 100644 index 00000000000..c0db69d4ba6 --- /dev/null +++ b/queue-4.16/powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch @@ -0,0 +1,84 @@ +From dbfcf3cb9c681aa0c5d0bb46068f98d5b1823dd3 Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +Date: Thu, 16 Feb 2017 16:03:39 +1100 +Subject: powerpc/64: Call H_REGISTER_PROC_TBL when running as a HPT guest on POWER9 + +From: Paul Mackerras + +commit dbfcf3cb9c681aa0c5d0bb46068f98d5b1823dd3 upstream. + +On POWER9, since commit cc3d2940133d ("powerpc/64: Enable use of radix +MMU under hypervisor on POWER9", 2017-01-30), we set both the radix and +HPT bits in the client-architecture-support (CAS) vector, which tells +the hypervisor that we can do either radix or HPT. According to PAPR, +if we use this combination we are promising to do a H_REGISTER_PROC_TBL +hcall later on to let the hypervisor know whether we are doing radix +or HPT. We currently do this call if we are doing radix but not if +we are doing HPT. If the hypervisor is able to support both radix +and HPT guests, it would be entitled to defer allocation of the HPT +until the H_REGISTER_PROC_TBL call, and to fail any attempts to create +HPTEs until the H_REGISTER_PROC_TBL call. Thus we need to do a +H_REGISTER_PROC_TBL call when we are doing HPT; otherwise we may +crash at boot time. + +This adds the code to call H_REGISTER_PROC_TBL in this case, before +we attempt to create any HPT entries using H_ENTER. + +Fixes: cc3d2940133d ("powerpc/64: Enable use of radix MMU under hypervisor on POWER9") +Cc: stable@vger.kernel.org # v4.11+ +Signed-off-by: Paul Mackerras +Reviewed-by: Suraj Jitindar Singh +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/mm/hash_utils_64.c | 6 ++++++ + arch/powerpc/platforms/pseries/lpar.c | 8 ++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/mm/hash_utils_64.c ++++ b/arch/powerpc/mm/hash_utils_64.c +@@ -875,6 +875,12 @@ static void __init htab_initialize(void) + /* Using a hypervisor which owns the htab */ + htab_address = NULL; + _SDR1 = 0; ++ /* ++ * On POWER9, we need to do a H_REGISTER_PROC_TBL hcall ++ * to inform the hypervisor that we wish to use the HPT. ++ */ ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ register_process_table(0, 0, 0); + #ifdef CONFIG_FA_DUMP + /* + * If firmware assisted dump is active firmware preserves +--- a/arch/powerpc/platforms/pseries/lpar.c ++++ b/arch/powerpc/platforms/pseries/lpar.c +@@ -726,15 +726,18 @@ static int pseries_lpar_resize_hpt(unsig + return 0; + } + +-/* Actually only used for radix, so far */ + static int pseries_lpar_register_process_table(unsigned long base, + unsigned long page_size, unsigned long table_size) + { + long rc; +- unsigned long flags = PROC_TABLE_NEW; ++ unsigned long flags = 0; + ++ if (table_size) ++ flags |= PROC_TABLE_NEW; + if (radix_enabled()) + flags |= PROC_TABLE_RADIX | PROC_TABLE_GTSE; ++ else ++ flags |= PROC_TABLE_HPT_SLB; + for (;;) { + rc = plpar_hcall_norets(H_REGISTER_PROC_TBL, flags, base, + page_size, table_size); +@@ -760,6 +763,7 @@ void __init hpte_init_pseries(void) + mmu_hash_ops.flush_hash_range = pSeries_lpar_flush_hash_range; + mmu_hash_ops.hpte_clear_all = pseries_hpte_clear_all; + mmu_hash_ops.hugepage_invalidate = pSeries_lpar_hugepage_invalidate; ++ register_process_table = pseries_lpar_register_process_table; + + if (firmware_has_feature(FW_FEATURE_HPT_RESIZE)) + mmu_hash_ops.resize_hpt = pseries_lpar_resize_hpt; diff --git a/queue-4.16/powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch b/queue-4.16/powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch new file mode 100644 index 00000000000..07aa7e7941f --- /dev/null +++ b/queue-4.16/powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch @@ -0,0 +1,53 @@ +From 0bfdf598900fd62869659f360d3387ed80eb71cf Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Thu, 22 Mar 2018 20:41:46 +1000 +Subject: powerpc/64: Fix smp_wmb barrier definition use use lwsync consistently + +From: Nicholas Piggin + +commit 0bfdf598900fd62869659f360d3387ed80eb71cf upstream. + +asm/barrier.h is not always included after asm/synch.h, which meant +it was missing __SUBARCH_HAS_LWSYNC, so in some files smp_wmb() would +be eieio when it should be lwsync. kernel/time/hrtimer.c is one case. + +__SUBARCH_HAS_LWSYNC is only used in one place, so just fold it in +to where it's used. Previously with my small simulator config, 377 +instances of eieio in the tree. After this patch there are 55. + +Fixes: 46d075be585e ("powerpc: Optimise smp_wmb") +Cc: stable@vger.kernel.org # v2.6.29+ +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/barrier.h | 3 ++- + arch/powerpc/include/asm/synch.h | 4 ---- + 2 files changed, 2 insertions(+), 5 deletions(-) + +--- a/arch/powerpc/include/asm/barrier.h ++++ b/arch/powerpc/include/asm/barrier.h +@@ -35,7 +35,8 @@ + #define rmb() __asm__ __volatile__ ("sync" : : : "memory") + #define wmb() __asm__ __volatile__ ("sync" : : : "memory") + +-#ifdef __SUBARCH_HAS_LWSYNC ++/* The sub-arch has lwsync */ ++#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) + # define SMPWMB LWSYNC + #else + # define SMPWMB eieio +--- a/arch/powerpc/include/asm/synch.h ++++ b/arch/powerpc/include/asm/synch.h +@@ -6,10 +6,6 @@ + #include + #include + +-#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) +-#define __SUBARCH_HAS_LWSYNC +-#endif +- + #ifndef __ASSEMBLY__ + extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; + extern void do_lwsync_fixups(unsigned long value, void *fixup_start, diff --git a/queue-4.16/powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch b/queue-4.16/powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch new file mode 100644 index 00000000000..e49b1729732 --- /dev/null +++ b/queue-4.16/powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch @@ -0,0 +1,81 @@ +From a57ac411832384eb93df4bfed2bf644c4089720e Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Thu, 5 Apr 2018 15:50:49 +1000 +Subject: powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits + +From: Nicholas Piggin + +commit a57ac411832384eb93df4bfed2bf644c4089720e upstream. + +Presently the dt_cpu_ftrs restore_cpu will only add bits to the LPCR +for secondaries, but some bits must be removed (e.g., UPRT for HPT). +Not clearing these bits on secondaries causes checkstops when booting +with disable_radix. + +restore_cpu can not just set LPCR, because it is also called by the +idle wakeup code which relies on opal_slw_set_reg to restore the value +of LPCR, at least on P8 which does not save LPCR to stack in the idle +code. + +Fix this by including a mask of bits to clear from LPCR as well, which +is used by restore_cpu. + +This is a little messy now, but it's a minimal fix that can be +backported. Longer term, the idle SPR save/restore code can be +reworked to completely avoid calls to restore_cpu, then restore_cpu +would be able to unconditionally set LPCR to match boot processor +environment. + +Fixes: 5a61ef74f269f ("powerpc/64s: Support new device tree binding for discovering CPU features") +Cc: stable@vger.kernel.org # v4.12+ +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/dt_cpu_ftrs.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/kernel/dt_cpu_ftrs.c ++++ b/arch/powerpc/kernel/dt_cpu_ftrs.c +@@ -84,6 +84,7 @@ static int hv_mode; + + static struct { + u64 lpcr; ++ u64 lpcr_clear; + u64 hfscr; + u64 fscr; + } system_registers; +@@ -92,6 +93,8 @@ static void (*init_pmu_registers)(void); + + static void __restore_cpu_cpufeatures(void) + { ++ u64 lpcr; ++ + /* + * LPCR is restored by the power on engine already. It can be changed + * after early init e.g., by radix enable, and we have no unified API +@@ -104,8 +107,10 @@ static void __restore_cpu_cpufeatures(vo + * The best we can do to accommodate secondary boot and idle restore + * for now is "or" LPCR with existing. + */ +- +- mtspr(SPRN_LPCR, system_registers.lpcr | mfspr(SPRN_LPCR)); ++ lpcr = mfspr(SPRN_LPCR); ++ lpcr |= system_registers.lpcr; ++ lpcr &= ~system_registers.lpcr_clear; ++ mtspr(SPRN_LPCR, lpcr); + if (hv_mode) { + mtspr(SPRN_LPID, 0); + mtspr(SPRN_HFSCR, system_registers.hfscr); +@@ -325,8 +330,9 @@ static int __init feat_enable_mmu_hash_v + { + u64 lpcr; + ++ system_registers.lpcr_clear |= (LPCR_ISL | LPCR_UPRT | LPCR_HR); + lpcr = mfspr(SPRN_LPCR); +- lpcr &= ~LPCR_ISL; ++ lpcr &= ~(LPCR_ISL | LPCR_UPRT | LPCR_HR); + mtspr(SPRN_LPCR, lpcr); + + cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE; diff --git a/queue-4.16/powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch b/queue-4.16/powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch new file mode 100644 index 00000000000..363e0a08d55 --- /dev/null +++ b/queue-4.16/powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch @@ -0,0 +1,43 @@ +From c130153e453cba0f37ad10fa18a1aa9c9a598a59 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Thu, 5 Apr 2018 15:57:54 +1000 +Subject: powerpc/64s: Fix pkey support in dt_cpu_ftrs, add CPU_FTR_PKEY bit + +From: Nicholas Piggin + +commit c130153e453cba0f37ad10fa18a1aa9c9a598a59 upstream. + +The pkey code added a CPU_FTR_PKEY bit, but did not add it to the +dt_cpu_ftrs feature set. Although capability is supported by all +processors in the base dt_cpu_ftrs set for 64s, it's a significant +and sufficiently well defined feature to make it optional. So add +it as a quirk for now, which can be versioned out then controlled +by the firmware (once dt_cpu_ftrs gains versioning support). + +Fixes: cf43d3b26452 ("powerpc: Enable pkey subsystem") +Cc: stable@vger.kernel.org # v4.16+ +Cc: Ram Pai +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/dt_cpu_ftrs.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/powerpc/kernel/dt_cpu_ftrs.c ++++ b/arch/powerpc/kernel/dt_cpu_ftrs.c +@@ -658,6 +658,13 @@ static void __init cpufeatures_setup_sta + cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_300; + cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_00; + } ++ ++ /* ++ * PKEY was not in the initial base or feature node ++ * specification, but it should become optional in the next ++ * cpu feature version sequence. ++ */ ++ cur_cpu_spec->cpu_features |= CPU_FTR_PKEY; + } + + static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) diff --git a/queue-4.16/powerpc-eeh-fix-race-with-driver-un-bind.patch b/queue-4.16/powerpc-eeh-fix-race-with-driver-un-bind.patch new file mode 100644 index 00000000000..1ad8d06b912 --- /dev/null +++ b/queue-4.16/powerpc-eeh-fix-race-with-driver-un-bind.patch @@ -0,0 +1,258 @@ +From f0295e047fcf52ccb42561fb7de6942f5201b676 Mon Sep 17 00:00:00 2001 +From: Michael Neuling +Date: Mon, 26 Mar 2018 15:17:07 +1100 +Subject: powerpc/eeh: Fix race with driver un/bind + +From: Michael Neuling + +commit f0295e047fcf52ccb42561fb7de6942f5201b676 upstream. + +The current EEH callbacks can race with a driver unbind. This can +result in a backtraces like this: + + EEH: Frozen PHB#0-PE#1fc detected + EEH: PE location: S000009, PHB location: N/A + CPU: 2 PID: 2312 Comm: kworker/u258:3 Not tainted 4.15.6-openpower1 #2 + Workqueue: nvme-wq nvme_reset_work [nvme] + Call Trace: + dump_stack+0x9c/0xd0 (unreliable) + eeh_dev_check_failure+0x420/0x470 + eeh_check_failure+0xa0/0xa4 + nvme_reset_work+0x138/0x1414 [nvme] + process_one_work+0x1ec/0x328 + worker_thread+0x2e4/0x3a8 + kthread+0x14c/0x154 + ret_from_kernel_thread+0x5c/0xc8 + nvme nvme1: Removing after probe failure status: -19 + + cpu 0x23: Vector: 300 (Data Access) at [c000000ff50f3800] + pc: c0080000089a0eb0: nvme_error_detected+0x4c/0x90 [nvme] + lr: c000000000026564: eeh_report_error+0xe0/0x110 + sp: c000000ff50f3a80 + msr: 9000000000009033 + dar: 400 + dsisr: 40000000 + current = 0xc000000ff507c000 + paca = 0xc00000000fdc9d80 softe: 0 irq_happened: 0x01 + pid = 782, comm = eehd + Linux version 4.15.6-openpower1 (smc@smc-desktop) (gcc version 6.4.0 (Buildroot 2017.11.2-00008-g4b6188e)) #2 SM P Tue Feb 27 12:33:27 PST 2018 + enter ? for help + eeh_report_error+0xe0/0x110 + eeh_pe_dev_traverse+0xc0/0xdc + eeh_handle_normal_event+0x184/0x4c4 + eeh_handle_event+0x30/0x288 + eeh_event_handler+0x124/0x170 + kthread+0x14c/0x154 + ret_from_kernel_thread+0x5c/0xc8 + +The first part is an EEH (on boot), the second half is the resulting +crash. nvme probe starts the nvme_reset_work() worker thread. This +worker thread starts touching the device which see a device error +(EEH) and hence queues up an event in the powerpc EEH worker +thread. nvme_reset_work() then continues and runs +nvme_remove_dead_ctrl_work() which results in unbinding the driver +from the device and hence releases all resources. At the same time, +the EEH worker thread starts doing the EEH .error_detected() driver +callback, which no longer works since the resources have been freed. + +This fixes the problem in the same way the generic PCIe AER code (in +drivers/pci/pcie/aer/aerdrv_core.c) does. It makes the EEH code hold +the device_lock() while performing the driver EEH callbacks and +associated code. This ensures either the callbacks are no longer +register, or if they are registered the driver will not be removed +from underneath us. + +This has been broken forever. The EEH call backs were first introduced +in 2005 (in 77bd7415610) but it's not clear if a lock was needed back +then. + +Fixes: 77bd74156101 ("[PATCH] powerpc: PCI Error Recovery: PPC64 core recovery routines") +Cc: stable@vger.kernel.org # v2.6.16+ +Signed-off-by: Michael Neuling +Reviewed-by: Benjamin Herrenschmidt +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/eeh_driver.c | 68 ++++++++++++++++++++++++--------------- + 1 file changed, 42 insertions(+), 26 deletions(-) + +--- a/arch/powerpc/kernel/eeh_driver.c ++++ b/arch/powerpc/kernel/eeh_driver.c +@@ -207,18 +207,18 @@ static void *eeh_report_error(void *data + + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) + return NULL; ++ ++ device_lock(&dev->dev); + dev->error_state = pci_channel_io_frozen; + + driver = eeh_pcid_get(dev); +- if (!driver) return NULL; ++ if (!driver) goto out_no_dev; + + eeh_disable_irq(dev); + + if (!driver->err_handler || +- !driver->err_handler->error_detected) { +- eeh_pcid_put(dev); +- return NULL; +- } ++ !driver->err_handler->error_detected) ++ goto out; + + rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen); + +@@ -227,8 +227,12 @@ static void *eeh_report_error(void *data + if (*res == PCI_ERS_RESULT_NONE) *res = rc; + + edev->in_error = true; +- eeh_pcid_put(dev); + pci_uevent_ers(dev, PCI_ERS_RESULT_NONE); ++ ++out: ++ eeh_pcid_put(dev); ++out_no_dev: ++ device_unlock(&dev->dev); + return NULL; + } + +@@ -251,15 +255,14 @@ static void *eeh_report_mmio_enabled(voi + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) + return NULL; + ++ device_lock(&dev->dev); + driver = eeh_pcid_get(dev); +- if (!driver) return NULL; ++ if (!driver) goto out_no_dev; + + if (!driver->err_handler || + !driver->err_handler->mmio_enabled || +- (edev->mode & EEH_DEV_NO_HANDLER)) { +- eeh_pcid_put(dev); +- return NULL; +- } ++ (edev->mode & EEH_DEV_NO_HANDLER)) ++ goto out; + + rc = driver->err_handler->mmio_enabled(dev); + +@@ -267,7 +270,10 @@ static void *eeh_report_mmio_enabled(voi + if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; + if (*res == PCI_ERS_RESULT_NONE) *res = rc; + ++out: + eeh_pcid_put(dev); ++out_no_dev: ++ device_unlock(&dev->dev); + return NULL; + } + +@@ -290,20 +296,20 @@ static void *eeh_report_reset(void *data + + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) + return NULL; ++ ++ device_lock(&dev->dev); + dev->error_state = pci_channel_io_normal; + + driver = eeh_pcid_get(dev); +- if (!driver) return NULL; ++ if (!driver) goto out_no_dev; + + eeh_enable_irq(dev); + + if (!driver->err_handler || + !driver->err_handler->slot_reset || + (edev->mode & EEH_DEV_NO_HANDLER) || +- (!edev->in_error)) { +- eeh_pcid_put(dev); +- return NULL; +- } ++ (!edev->in_error)) ++ goto out; + + rc = driver->err_handler->slot_reset(dev); + if ((*res == PCI_ERS_RESULT_NONE) || +@@ -311,7 +317,10 @@ static void *eeh_report_reset(void *data + if (*res == PCI_ERS_RESULT_DISCONNECT && + rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; + ++out: + eeh_pcid_put(dev); ++out_no_dev: ++ device_unlock(&dev->dev); + return NULL; + } + +@@ -362,10 +371,12 @@ static void *eeh_report_resume(void *dat + + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) + return NULL; ++ ++ device_lock(&dev->dev); + dev->error_state = pci_channel_io_normal; + + driver = eeh_pcid_get(dev); +- if (!driver) return NULL; ++ if (!driver) goto out_no_dev; + + was_in_error = edev->in_error; + edev->in_error = false; +@@ -375,18 +386,20 @@ static void *eeh_report_resume(void *dat + !driver->err_handler->resume || + (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) { + edev->mode &= ~EEH_DEV_NO_HANDLER; +- eeh_pcid_put(dev); +- return NULL; ++ goto out; + } + + driver->err_handler->resume(dev); + +- eeh_pcid_put(dev); + pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED); ++out: ++ eeh_pcid_put(dev); + #ifdef CONFIG_PCI_IOV + if (eeh_ops->notify_resume && eeh_dev_to_pdn(edev)) + eeh_ops->notify_resume(eeh_dev_to_pdn(edev)); + #endif ++out_no_dev: ++ device_unlock(&dev->dev); + return NULL; + } + +@@ -406,23 +419,26 @@ static void *eeh_report_failure(void *da + + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) + return NULL; ++ ++ device_lock(&dev->dev); + dev->error_state = pci_channel_io_perm_failure; + + driver = eeh_pcid_get(dev); +- if (!driver) return NULL; ++ if (!driver) goto out_no_dev; + + eeh_disable_irq(dev); + + if (!driver->err_handler || +- !driver->err_handler->error_detected) { +- eeh_pcid_put(dev); +- return NULL; +- } ++ !driver->err_handler->error_detected) ++ goto out; + + driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); + +- eeh_pcid_put(dev); + pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT); ++out: ++ eeh_pcid_put(dev); ++out_no_dev: ++ device_unlock(&dev->dev); + return NULL; + } + diff --git a/queue-4.16/powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch b/queue-4.16/powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch new file mode 100644 index 00000000000..53ad02039cc --- /dev/null +++ b/queue-4.16/powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch @@ -0,0 +1,51 @@ +From bf8a1abc3ddbd6e9a8312ea7d96e5dd89c140f18 Mon Sep 17 00:00:00 2001 +From: Thiago Jung Bauermann +Date: Thu, 29 Mar 2018 16:05:43 -0300 +Subject: powerpc/kexec_file: Fix error code when trying to load kdump kernel + +From: Thiago Jung Bauermann + +commit bf8a1abc3ddbd6e9a8312ea7d96e5dd89c140f18 upstream. + +kexec_file_load() on powerpc doesn't support kdump kernels yet, so it +returns -ENOTSUPP in that case. + +I've recently learned that this errno is internal to the kernel and +isn't supposed to be exposed to userspace. Therefore, change to +-EOPNOTSUPP which is defined in an uapi header. + +This does indeed make kexec-tools happier. Before the patch, on +ppc64le: + + # ~bauermann/src/kexec-tools/build/sbin/kexec -s -p /boot/vmlinuz + kexec_file_load failed: Unknown error 524 + +After the patch: + + # ~bauermann/src/kexec-tools/build/sbin/kexec -s -p /boot/vmlinuz + kexec_file_load failed: Operation not supported + +Fixes: a0458284f062 ("powerpc: Add support code for kexec_file_load()") +Cc: stable@vger.kernel.org # v4.10+ +Reported-by: Dave Young +Signed-off-by: Thiago Jung Bauermann +Reviewed-by: Simon Horman +Reviewed-by: Dave Young +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/machine_kexec_file_64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/machine_kexec_file_64.c ++++ b/arch/powerpc/kernel/machine_kexec_file_64.c +@@ -43,7 +43,7 @@ int arch_kexec_kernel_image_probe(struct + + /* We don't support crash kernels yet. */ + if (image->type == KEXEC_TYPE_CRASH) +- return -ENOTSUPP; ++ return -EOPNOTSUPP; + + for (i = 0; i < ARRAY_SIZE(kexec_file_loaders); i++) { + fops = kexec_file_loaders[i]; diff --git a/queue-4.16/powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch b/queue-4.16/powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch new file mode 100644 index 00000000000..3c6dad7ced1 --- /dev/null +++ b/queue-4.16/powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch @@ -0,0 +1,103 @@ +From e6e133c47e6bd4d5dac05b35d06634a8e5648615 Mon Sep 17 00:00:00 2001 +From: "Naveen N. Rao" +Date: Wed, 17 Jan 2018 17:52:24 +0530 +Subject: powerpc/kprobes: Fix call trace due to incorrect preempt count + +From: Naveen N. Rao + +commit e6e133c47e6bd4d5dac05b35d06634a8e5648615 upstream. + +Michael Ellerman reported the following call trace when running +ftracetest: + + BUG: using __this_cpu_write() in preemptible [00000000] code: ftracetest/6178 + caller is opt_pre_handler+0xc4/0x110 + CPU: 1 PID: 6178 Comm: ftracetest Not tainted 4.15.0-rc7-gcc6x-gb2cd1df #1 + Call Trace: + [c0000000f9ec39c0] [c000000000ac4304] dump_stack+0xb4/0x100 (unreliable) + [c0000000f9ec3a00] [c00000000061159c] check_preemption_disabled+0x15c/0x170 + [c0000000f9ec3a90] [c000000000217e84] opt_pre_handler+0xc4/0x110 + [c0000000f9ec3af0] [c00000000004cf68] optimized_callback+0x148/0x170 + [c0000000f9ec3b40] [c00000000004d954] optinsn_slot+0xec/0x10000 + [c0000000f9ec3e30] [c00000000004bae0] kretprobe_trampoline+0x0/0x10 + +This is showing up since OPTPROBES is now enabled with CONFIG_PREEMPT. + +trampoline_probe_handler() considers itself to be a special kprobe +handler for kretprobes. In doing so, it expects to be called from +kprobe_handler() on a trap, and re-enables preemption before returning a +non-zero return value so as to suppress any subsequent processing of the +trap by the kprobe_handler(). + +However, with optprobes, we don't deal with special handlers (we ignore +the return code) and just try to re-enable preemption causing the above +trace. + +To address this, modify trampoline_probe_handler() to not be special. +The only additional processing done in kprobe_handler() is to emulate +the instruction (in this case, a 'nop'). We adjust the value of +regs->nip for the purpose and delegate the job of re-enabling +preemption and resetting current kprobe to the probe handlers +(kprobe_handler() or optimized_callback()). + +Fixes: 8a2d71a3f273 ("powerpc/kprobes: Disable preemption before invoking probe handler for optprobes") +Cc: stable@vger.kernel.org # v4.15+ +Reported-by: Michael Ellerman +Signed-off-by: Naveen N. Rao +Acked-by: Ananth N Mavinakayanahalli +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/kprobes.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +--- a/arch/powerpc/kernel/kprobes.c ++++ b/arch/powerpc/kernel/kprobes.c +@@ -455,29 +455,33 @@ static int trampoline_probe_handler(stru + } + + kretprobe_assert(ri, orig_ret_address, trampoline_address); +- regs->nip = orig_ret_address; ++ + /* +- * Make LR point to the orig_ret_address. +- * When the 'nop' inside the kretprobe_trampoline +- * is optimized, we can do a 'blr' after executing the +- * detour buffer code. ++ * We get here through one of two paths: ++ * 1. by taking a trap -> kprobe_handler() -> here ++ * 2. by optprobe branch -> optimized_callback() -> opt_pre_handler() -> here ++ * ++ * When going back through (1), we need regs->nip to be setup properly ++ * as it is used to determine the return address from the trap. ++ * For (2), since nip is not honoured with optprobes, we instead setup ++ * the link register properly so that the subsequent 'blr' in ++ * kretprobe_trampoline jumps back to the right instruction. ++ * ++ * For nip, we should set the address to the previous instruction since ++ * we end up emulating it in kprobe_handler(), which increments the nip ++ * again. + */ ++ regs->nip = orig_ret_address - 4; + regs->link = orig_ret_address; + +- reset_current_kprobe(); + kretprobe_hash_unlock(current, &flags); +- preempt_enable_no_resched(); + + hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { + hlist_del(&ri->hlist); + kfree(ri); + } +- /* +- * By returning a non-zero value, we are telling +- * kprobe_handler() that we don't want the post_handler +- * to run (and have re-enabled preemption) +- */ +- return 1; ++ ++ return 0; + } + NOKPROBE_SYMBOL(trampoline_probe_handler); + diff --git a/queue-4.16/powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch b/queue-4.16/powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch new file mode 100644 index 00000000000..7f6572f9ab5 --- /dev/null +++ b/queue-4.16/powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch @@ -0,0 +1,75 @@ +From 2675c13b293a007b7b7f8229514126bd23df09a7 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Thu, 12 Apr 2018 11:35:55 +1000 +Subject: powerpc/mm/radix: Fix checkstops caused by invalid tlbiel + +From: Michael Ellerman + +commit 2675c13b293a007b7b7f8229514126bd23df09a7 upstream. + +In tlbiel_radix_set_isa300() we use the PPC_TLBIEL() macro to +construct tlbiel instructions. The instruction takes 5 fields, two of +which are registers, and the others are constants. But because it's +constructed with inline asm the compiler doesn't know that. + +We got the constraint wrong on the 'r' field, using "r" tells the +compiler to put the value in a register. The value we then get in the +macro is the *register number*, not the value of the field. + +That means when we mask the register number with 0x1 we get 0 or 1 +depending on which register the compiler happens to put the constant +in, eg: + + li r10,1 + tlbiel r8,r9,2,0,0 + + li r7,1 + tlbiel r10,r6,0,0,1 + +If we're unlucky we might generate an invalid instruction form, for +example RIC=0, PRS=1 and R=0, tlbiel r8,r7,0,1,0, this has been +observed to cause machine checks: + + Oops: Machine check, sig: 7 [#1] + CPU: 24 PID: 0 Comm: swapper + NIP: 00000000000385f4 LR: 000000000100ed00 CTR: 000000000000007f + REGS: c00000000110bb40 TRAP: 0200 + MSR: 9000000000201003 CR: 48002222 XER: 20040000 + CFAR: 00000000000385d0 DAR: 0000000000001c00 DSISR: 00000200 SOFTE: 1 + +If the machine check happens early in boot while we have MSR_ME=0 it +will escalate into a checkstop and kill the box entirely. + +To fix it we could change the inline asm constraint to "i" which +tells the compiler the value is a constant. But a better fix is to just +pass a literal 1 into the macro, which bypasses any problems with inline +asm constraints. + +Fixes: d4748276ae14 ("powerpc/64s: Improve local TLB flush for boot and MCE on POWER9") +Cc: stable@vger.kernel.org # v4.16+ +Signed-off-by: Michael Ellerman +Reviewed-by: Nicholas Piggin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/mm/tlb-radix.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/mm/tlb-radix.c ++++ b/arch/powerpc/mm/tlb-radix.c +@@ -33,13 +33,12 @@ static inline void tlbiel_radix_set_isa3 + { + unsigned long rb; + unsigned long rs; +- unsigned int r = 1; /* radix format */ + + rb = (set << PPC_BITLSHIFT(51)) | (is << PPC_BITLSHIFT(53)); + rs = ((unsigned long)pid << PPC_BITLSHIFT(31)); + +- asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4) +- : : "r"(rb), "r"(rs), "i"(ric), "i"(prs), "r"(r) ++ asm volatile(PPC_TLBIEL(%0, %1, %2, %3, 1) ++ : : "r"(rb), "r"(rs), "i"(ric), "i"(prs) + : "memory"); + } + diff --git a/queue-4.16/powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch b/queue-4.16/powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch new file mode 100644 index 00000000000..0af35fc89bf --- /dev/null +++ b/queue-4.16/powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch @@ -0,0 +1,52 @@ +From 3b8070335f751aac9f1526ae2e012e6f5b8b0f21 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Tue, 10 Apr 2018 21:49:33 +1000 +Subject: powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops + +From: Nicholas Piggin + +commit 3b8070335f751aac9f1526ae2e012e6f5b8b0f21 upstream. + +The OPAL NVRAM driver does not sleep in case it gets OPAL_BUSY or +OPAL_BUSY_EVENT from firmware, which causes large scheduling +latencies, and various lockup errors to trigger (again, BMC reboot +can cause it). + +Fix this by converting it to the standard form OPAL_BUSY loop that +sleeps. + +Fixes: 628daa8d5abf ("powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks") +Depends-on: 34dd25de9fe3 ("powerpc/powernv: define a standard delay for OPAL_BUSY type retry loops") +Cc: stable@vger.kernel.org # v3.2+ +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/powernv/opal-nvram.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/platforms/powernv/opal-nvram.c ++++ b/arch/powerpc/platforms/powernv/opal-nvram.c +@@ -11,6 +11,7 @@ + + #define DEBUG + ++#include + #include + #include + #include +@@ -56,8 +57,12 @@ static ssize_t opal_nvram_write(char *bu + + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { + rc = opal_write_nvram(__pa(buf), count, off); +- if (rc == OPAL_BUSY_EVENT) ++ if (rc == OPAL_BUSY_EVENT) { ++ msleep(OPAL_BUSY_DELAY_MS); + opal_poll_events(NULL); ++ } else if (rc == OPAL_BUSY) { ++ msleep(OPAL_BUSY_DELAY_MS); ++ } + } + + if (rc) diff --git a/queue-4.16/powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch b/queue-4.16/powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch new file mode 100644 index 00000000000..41bc9a1e90e --- /dev/null +++ b/queue-4.16/powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch @@ -0,0 +1,38 @@ +From 741de617661794246f84a21a02fc5e327bffc9ad Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Tue, 27 Mar 2018 01:02:33 +1000 +Subject: powerpc/powernv: Handle unknown OPAL errors in opal_nvram_write() + +From: Nicholas Piggin + +commit 741de617661794246f84a21a02fc5e327bffc9ad upstream. + +opal_nvram_write currently just assumes success if it encounters an +error other than OPAL_BUSY or OPAL_BUSY_EVENT. Have it return -EIO +on other errors instead. + +Fixes: 628daa8d5abf ("powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks") +Cc: stable@vger.kernel.org # v3.2+ +Signed-off-by: Nicholas Piggin +Reviewed-by: Vasant Hegde +Acked-by: Stewart Smith +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/powernv/opal-nvram.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/powerpc/platforms/powernv/opal-nvram.c ++++ b/arch/powerpc/platforms/powernv/opal-nvram.c +@@ -59,6 +59,10 @@ static ssize_t opal_nvram_write(char *bu + if (rc == OPAL_BUSY_EVENT) + opal_poll_events(NULL); + } ++ ++ if (rc) ++ return -EIO; ++ + *index += count; + return count; + } diff --git a/queue-4.16/random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch b/queue-4.16/random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch new file mode 100644 index 00000000000..130de92e765 --- /dev/null +++ b/queue-4.16/random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch @@ -0,0 +1,38 @@ +From 9f886f4d1d292442b2f22a0a33321eae821bde40 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 25 Feb 2017 18:21:33 -0400 +Subject: random: use a tighter cap in credit_entropy_bits_safe() + +From: Theodore Ts'o + +commit 9f886f4d1d292442b2f22a0a33321eae821bde40 upstream. + +This fixes a harmless UBSAN where root could potentially end up +causing an overflow while bumping the entropy_total field (which is +ignored once the entropy pool has been initialized, and this generally +is completed during the boot sequence). + +This is marginal for the stable kernel series, but it's a really +trivial patch, and it fixes UBSAN warning that might cause security +folks to get overly excited for no reason. + +Signed-off-by: Theodore Ts'o +Reported-by: Chen Feng +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/random.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -732,7 +732,7 @@ retry: + + static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) + { +- const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); ++ const int nbits_max = r->poolinfo->poolwords * 32; + + if (nbits < 0) + return -EINVAL; diff --git a/queue-4.16/series b/queue-4.16/series index 388bf2f4ea9..8c6ec04844f 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -56,3 +56,44 @@ cifs-add-sha512-secmech.patch cifs-implement-v3.11-preauth-integrity.patch cifs-fix-sha512-check-in-cifs_crypto_secmech_release.patch swiotlb-fix-unexpected-swiotlb_alloc_coherent-failures.patch +powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch +powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch +powerpc-eeh-fix-race-with-driver-un-bind.patch +powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch +powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch +powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch +powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch +powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch +powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch +powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch +ceph-always-update-atime-mtime-ctime-for-new-inode.patch +hid-fix-hid_report_len-usage.patch +hid-core-fix-size-as-type-u32.patch +soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch +asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch +asoc-topology-fix-kcontrol-name-string-handling.patch +thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch +thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch +thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch +thunderbolt-handle-connecting-device-in-place-of-host-properly.patch +thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch +irqchip-gic-take-lock-when-updating-irq-type.patch +random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch +extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch +block-use-32-bit-blk_status_t-on-alpha.patch +jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch +ext4-shutdown-should-not-prevent-get_write_access.patch +ext4-eliminate-sleep-from-shutdown-ioctl.patch +ext4-pass-eshutdown-code-to-jbd2-layer.patch +ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch +ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch +ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch +ext4-add-validity-checks-for-bitmap-block-numbers.patch +ext4-limit-xattr-size-to-int_max.patch +ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch +ext4-always-initialize-the-crc32c-checksum-driver.patch +ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch +ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch +ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch +ext4-add-extra-checks-to-ext4_xattr_block_get.patch +ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch diff --git a/queue-4.16/soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch b/queue-4.16/soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch new file mode 100644 index 00000000000..f58300ab33f --- /dev/null +++ b/queue-4.16/soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch @@ -0,0 +1,35 @@ +From 73ce2ce129783813e1ebc37d2c757fe5e0fab1ef Mon Sep 17 00:00:00 2001 +From: Sean Wang +Date: Fri, 9 Feb 2018 02:07:59 +0800 +Subject: soc: mediatek: fix the mistaken pointer accessed when subdomains are added + +From: Sean Wang + +commit 73ce2ce129783813e1ebc37d2c757fe5e0fab1ef upstream. + +Fix the pointer to struct scp_subdomian not being moved forward +when each sub-domain is expected to be iteratively added through +pm_genpd_add_subdomain call. + +Cc: stable@vger.kernel.org +Fixes: 53fddb1a66dd ("soc: mediatek: reduce code duplication of scpsys_probe across all SoCs") +Reported-by: Weiyi Lu +Signed-off-by: Sean Wang +Signed-off-by: Matthias Brugger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/soc/mediatek/mtk-scpsys.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/soc/mediatek/mtk-scpsys.c ++++ b/drivers/soc/mediatek/mtk-scpsys.c +@@ -992,7 +992,7 @@ static int scpsys_probe(struct platform_ + + pd_data = &scp->pd_data; + +- for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) { ++ for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { + ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], + pd_data->domains[sd->subdomain]); + if (ret && IS_ENABLED(CONFIG_PM)) diff --git a/queue-4.16/thunderbolt-handle-connecting-device-in-place-of-host-properly.patch b/queue-4.16/thunderbolt-handle-connecting-device-in-place-of-host-properly.patch new file mode 100644 index 00000000000..18e53372e25 --- /dev/null +++ b/queue-4.16/thunderbolt-handle-connecting-device-in-place-of-host-properly.patch @@ -0,0 +1,83 @@ +From 79fae987518a3aa6c3c7b2e3ad5fe1e4080c12bc Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 9 Feb 2018 17:29:38 +0300 +Subject: thunderbolt: Handle connecting device in place of host properly + +From: Mika Westerberg + +commit 79fae987518a3aa6c3c7b2e3ad5fe1e4080c12bc upstream. + +If the system is suspended and user disconnects cable to another host +and connects it to a Thunderbolt device instead we get a warning from +driver core about adding duplicate sysfs attribute and adding the new +device fails. + +Handle this properly so that we first remove the existing XDomain +connection before adding new devices. + +Fixes: d1ff70241a27 ("thunderbolt: Add support for XDomain discovery protocol") +Signed-off-by: Mika Westerberg +Reviewed-by: Andy Shevchenko +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/icm.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +--- a/drivers/thunderbolt/icm.c ++++ b/drivers/thunderbolt/icm.c +@@ -383,6 +383,15 @@ static void remove_switch(struct tb_swit + tb_switch_remove(sw); + } + ++static void remove_xdomain(struct tb_xdomain *xd) ++{ ++ struct tb_switch *sw; ++ ++ sw = tb_to_switch(xd->dev.parent); ++ tb_port_at(xd->route, sw)->xdomain = NULL; ++ tb_xdomain_remove(xd); ++} ++ + static void + icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) + { +@@ -391,6 +400,7 @@ icm_fr_device_connected(struct tb *tb, c + struct tb_switch *sw, *parent_sw; + struct icm *icm = tb_priv(tb); + bool authorized = false; ++ struct tb_xdomain *xd; + u8 link, depth; + u64 route; + int ret; +@@ -467,6 +477,13 @@ icm_fr_device_connected(struct tb *tb, c + tb_switch_put(sw); + } + ++ /* Remove existing XDomain connection if found */ ++ xd = tb_xdomain_find_by_link_depth(tb, link, depth); ++ if (xd) { ++ remove_xdomain(xd); ++ tb_xdomain_put(xd); ++ } ++ + parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1); + if (!parent_sw) { + tb_err(tb, "failed to find parent switch for %u.%u\n", +@@ -529,15 +546,6 @@ icm_fr_device_disconnected(struct tb *tb + tb_switch_put(sw); + } + +-static void remove_xdomain(struct tb_xdomain *xd) +-{ +- struct tb_switch *sw; +- +- sw = tb_to_switch(xd->dev.parent); +- tb_port_at(xd->route, sw)->xdomain = NULL; +- tb_xdomain_remove(xd); +-} +- + static void + icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) + { diff --git a/queue-4.16/thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch b/queue-4.16/thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch new file mode 100644 index 00000000000..05cb30b462a --- /dev/null +++ b/queue-4.16/thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch @@ -0,0 +1,55 @@ +From ea9d7bb798900096f26c585957d6ad9c532417e6 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 9 Mar 2018 13:17:01 +0300 +Subject: thunderbolt: Prevent crash when ICM firmware is not running + +From: Mika Westerberg + +commit ea9d7bb798900096f26c585957d6ad9c532417e6 upstream. + +On Lenovo ThinkPad Yoga 370 (and possibly some other Lenovo models as +well) the Thunderbolt host controller sometimes comes up in such way +that the ICM firmware is not running properly. This is most likely an +issue in BIOS/firmware but as side-effect driver crashes the kernel due +to NULL pointer dereference: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000980 + IP: pci_write_config_dword+0x5/0x20 + Call Trace: + pcie2cio_write+0x3b/0x70 [thunderbolt] + icm_driver_ready+0x168/0x260 [thunderbolt] + ? tb_ctl_start+0x50/0x70 [thunderbolt] + tb_domain_add+0x73/0xf0 [thunderbolt] + nhi_probe+0x182/0x300 [thunderbolt] + local_pci_probe+0x42/0xa0 + ? pci_match_device+0xd9/0x100 + pci_device_probe+0x146/0x1b0 + driver_probe_device+0x315/0x480 + ... + +Instead of crashing update the driver to bail out gracefully if we +encounter such situation. + +Fixes: f67cf491175a ("thunderbolt: Add support for Internal Connection Manager (ICM)") +Reported-by: Jordan Glover +Signed-off-by: Mika Westerberg +Acked-by: Yehezkel Bernat +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/icm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/thunderbolt/icm.c ++++ b/drivers/thunderbolt/icm.c +@@ -923,6 +923,9 @@ static int icm_firmware_reset(struct tb + struct icm *icm = tb_priv(tb); + u32 val; + ++ if (!icm->upstream_port) ++ return -ENODEV; ++ + /* Put ARC to wait for CIO reset event to happen */ + val = ioread32(nhi->iobase + REG_FW_STS); + val |= REG_FW_STS_CIO_RESET_REQ; diff --git a/queue-4.16/thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch b/queue-4.16/thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch new file mode 100644 index 00000000000..1ba44abe39a --- /dev/null +++ b/queue-4.16/thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch @@ -0,0 +1,38 @@ +From f2a659f7d8d5da803836583aa16df06bdf324252 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Tue, 19 Dec 2017 12:44:56 +0300 +Subject: thunderbolt: Resume control channel after hibernation image is created + +From: Mika Westerberg + +commit f2a659f7d8d5da803836583aa16df06bdf324252 upstream. + +The driver misses implementation of PM hook that undoes what +->freeze_noirq() does after the hibernation image is created. This means +the control channel is not resumed properly and the Thunderbolt bus +becomes useless in later stages of hibernation (when the image is stored +or if the operation fails). + +Fix this by pointing ->thaw_noirq to driver nhi_resume_noirq(). This +makes sure the control channel is resumed properly. + +Fixes: 23dd5bb49d98 ("thunderbolt: Add suspend/hibernate support") +Signed-off-by: Mika Westerberg +Reviewed-by: Andy Shevchenko +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/nhi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -1064,6 +1064,7 @@ static const struct dev_pm_ops nhi_pm_op + * we just disable hotplug, the + * pci-tunnels stay alive. + */ ++ .thaw_noirq = nhi_resume_noirq, + .restore_noirq = nhi_resume_noirq, + .suspend = nhi_suspend, + .freeze = nhi_suspend, diff --git a/queue-4.16/thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch b/queue-4.16/thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch new file mode 100644 index 00000000000..37e1dc59e69 --- /dev/null +++ b/queue-4.16/thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch @@ -0,0 +1,51 @@ +From a03e828915c00ed0ea5aa40647c81472cfa7a984 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Thu, 18 Jan 2018 20:27:47 +0300 +Subject: thunderbolt: Serialize PCIe tunnel creation with PCI rescan + +From: Mika Westerberg + +commit a03e828915c00ed0ea5aa40647c81472cfa7a984 upstream. + +We need to make sure a new PCIe tunnel is not created in a middle of +previous PCI rescan because otherwise the rescan code might find too +much and fail to reconfigure devices properly. This is important when +native PCIe hotplug is used. In BIOS assisted hotplug there should be no +such issue. + +Fixes: f67cf491175a ("thunderbolt: Add support for Internal Connection Manager (ICM)") +Signed-off-by: Mika Westerberg +Reviewed-by: Andy Shevchenko +Cc: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/switch.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/thunderbolt/switch.c ++++ b/drivers/thunderbolt/switch.c +@@ -716,6 +716,13 @@ static int tb_switch_set_authorized(stru + if (sw->authorized) + goto unlock; + ++ /* ++ * Make sure there is no PCIe rescan ongoing when a new PCIe ++ * tunnel is created. Otherwise the PCIe rescan code might find ++ * the new tunnel too early. ++ */ ++ pci_lock_rescan_remove(); ++ + switch (val) { + /* Approve switch */ + case 1: +@@ -735,6 +742,8 @@ static int tb_switch_set_authorized(stru + break; + } + ++ pci_unlock_rescan_remove(); ++ + if (!ret) { + sw->authorized = val; + /* Notify status change to the userspace */ diff --git a/queue-4.16/thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch b/queue-4.16/thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch new file mode 100644 index 00000000000..a548625b12a --- /dev/null +++ b/queue-4.16/thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch @@ -0,0 +1,55 @@ +From e4be8c9b6a512e274cb6bbac4ac869d73880a8b3 Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Fri, 24 Nov 2017 17:51:12 +0300 +Subject: thunderbolt: Wait a bit longer for ICM to authenticate the active NVM + +From: Mika Westerberg + +commit e4be8c9b6a512e274cb6bbac4ac869d73880a8b3 upstream. + +Sometimes during cold boot ICM has not yet authenticated the active NVM +image leading to timeout and failing the driver probe. Allow ICM to take +some more time and increase the timeout to 3 seconds before we give up. + +While there fix icm_firmware_init() to return the real error code +without overwriting it with -ENODEV. + +Fixes: f67cf491175a ("thunderbolt: Add support for Internal Connection Manager (ICM)") +Signed-off-by: Mika Westerberg +Reviewed-by: Andy Shevchenko +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/icm.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/thunderbolt/icm.c ++++ b/drivers/thunderbolt/icm.c +@@ -728,14 +728,14 @@ static bool icm_ar_is_supported(struct t + static int icm_ar_get_mode(struct tb *tb) + { + struct tb_nhi *nhi = tb->nhi; +- int retries = 5; ++ int retries = 60; + u32 val; + + do { + val = ioread32(nhi->iobase + REG_FW_STS); + if (val & REG_FW_STS_NVM_AUTH_DONE) + break; +- msleep(30); ++ msleep(50); + } while (--retries); + + if (!retries) { +@@ -1054,6 +1054,9 @@ static int icm_firmware_init(struct tb * + break; + + default: ++ if (ret < 0) ++ return ret; ++ + tb_err(tb, "ICM firmware is in wrong mode: %u\n", ret); + return -ENODEV; + } -- 2.47.3