]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Apr 2018 15:20:02 +0000 (17:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Apr 2018 15:20:02 +0000 (17:20 +0200)
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

42 files changed:
queue-4.16/asoc-ssm2602-replace-reg_default_raw-with-reg_default.patch [new file with mode: 0644]
queue-4.16/asoc-topology-fix-kcontrol-name-string-handling.patch [new file with mode: 0644]
queue-4.16/block-use-32-bit-blk_status_t-on-alpha.patch [new file with mode: 0644]
queue-4.16/ceph-always-update-atime-mtime-ctime-for-new-inode.patch [new file with mode: 0644]
queue-4.16/ext4-add-bounds-checking-to-ext4_xattr_find_entry.patch [new file with mode: 0644]
queue-4.16/ext4-add-extra-checks-to-ext4_xattr_block_get.patch [new file with mode: 0644]
queue-4.16/ext4-add-validity-checks-for-bitmap-block-numbers.patch [new file with mode: 0644]
queue-4.16/ext4-always-initialize-the-crc32c-checksum-driver.patch [new file with mode: 0644]
queue-4.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the-superblock.patch [new file with mode: 0644]
queue-4.16/ext4-don-t-update-checksum-of-new-initialized-bitmaps.patch [new file with mode: 0644]
queue-4.16/ext4-eliminate-sleep-from-shutdown-ioctl.patch [new file with mode: 0644]
queue-4.16/ext4-fail-ext4_iget-for-root-directory-if-unallocated.patch [new file with mode: 0644]
queue-4.16/ext4-fix-offset-overflow-on-32-bit-archs-in-ext4_iomap_begin.patch [new file with mode: 0644]
queue-4.16/ext4-force-revalidation-of-directory-pointer-after-seekdir-2.patch [new file with mode: 0644]
queue-4.16/ext4-limit-xattr-size-to-int_max.patch [new file with mode: 0644]
queue-4.16/ext4-move-call-to-ext4_error-into-ext4_xattr_check_block.patch [new file with mode: 0644]
queue-4.16/ext4-pass-eshutdown-code-to-jbd2-layer.patch [new file with mode: 0644]
queue-4.16/ext4-protect-i_disksize-update-by-i_data_sem-in-direct-write-path.patch [new file with mode: 0644]
queue-4.16/ext4-shutdown-should-not-prevent-get_write_access.patch [new file with mode: 0644]
queue-4.16/extcon-intel-cht-wc-set-direction-and-drv-flags-for-v5-boost-gpio.patch [new file with mode: 0644]
queue-4.16/hid-core-fix-size-as-type-u32.patch [new file with mode: 0644]
queue-4.16/hid-fix-hid_report_len-usage.patch [new file with mode: 0644]
queue-4.16/irqchip-gic-take-lock-when-updating-irq-type.patch [new file with mode: 0644]
queue-4.16/jbd2-if-the-journal-is-aborted-then-don-t-allow-update-of-the-log-tail.patch [new file with mode: 0644]
queue-4.16/powerpc-64-call-h_register_proc_tbl-when-running-as-a-hpt-guest-on-power9.patch [new file with mode: 0644]
queue-4.16/powerpc-64-fix-smp_wmb-barrier-definition-use-use-lwsync-consistently.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-fix-dt_cpu_ftrs-to-have-restore_cpu-clear-unwanted-lpcr-bits.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-fix-pkey-support-in-dt_cpu_ftrs-add-cpu_ftr_pkey-bit.patch [new file with mode: 0644]
queue-4.16/powerpc-eeh-fix-race-with-driver-un-bind.patch [new file with mode: 0644]
queue-4.16/powerpc-kexec_file-fix-error-code-when-trying-to-load-kdump-kernel.patch [new file with mode: 0644]
queue-4.16/powerpc-kprobes-fix-call-trace-due-to-incorrect-preempt-count.patch [new file with mode: 0644]
queue-4.16/powerpc-mm-radix-fix-checkstops-caused-by-invalid-tlbiel.patch [new file with mode: 0644]
queue-4.16/powerpc-powernv-fix-opal-nvram-driver-opal_busy-loops.patch [new file with mode: 0644]
queue-4.16/powerpc-powernv-handle-unknown-opal-errors-in-opal_nvram_write.patch [new file with mode: 0644]
queue-4.16/random-use-a-tighter-cap-in-credit_entropy_bits_safe.patch [new file with mode: 0644]
queue-4.16/series
queue-4.16/soc-mediatek-fix-the-mistaken-pointer-accessed-when-subdomains-are-added.patch [new file with mode: 0644]
queue-4.16/thunderbolt-handle-connecting-device-in-place-of-host-properly.patch [new file with mode: 0644]
queue-4.16/thunderbolt-prevent-crash-when-icm-firmware-is-not-running.patch [new file with mode: 0644]
queue-4.16/thunderbolt-resume-control-channel-after-hibernation-image-is-created.patch [new file with mode: 0644]
queue-4.16/thunderbolt-serialize-pcie-tunnel-creation-with-pci-rescan.patch [new file with mode: 0644]
queue-4.16/thunderbolt-wait-a-bit-longer-for-icm-to-authenticate-the-active-nvm.patch [new file with mode: 0644]

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 (file)
index 0000000..984a33c
--- /dev/null
@@ -0,0 +1,77 @@
+From a01df75ce737951ad13a08d101306e88c3f57cb2 Mon Sep 17 00:00:00 2001
+From: James Kelly <jamespeterkelly@gmail.com>
+Date: Mon, 19 Mar 2018 21:29:50 +1100
+Subject: ASoC: ssm2602: Replace reg_default_raw with reg_default
+
+From: James Kelly <jamespeterkelly@gmail.com>
+
+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 <jamespeterkelly@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..468216d
--- /dev/null
@@ -0,0 +1,106 @@
+From 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d Mon Sep 17 00:00:00 2001
+From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+Date: Tue, 27 Mar 2018 12:04:04 +0100
+Subject: ASoC: topology: Fix kcontrol name string handling
+
+From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
+
+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 <liam.r.girdwood@linux.intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..6207013
--- /dev/null
@@ -0,0 +1,53 @@
+From 6e2fb22103b99c26ae30a46512abe75526d8e4c9 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 21 Mar 2018 12:42:25 -0400
+Subject: block: use 32-bit blk_status_t on Alpha
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+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 <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org     # 4.13+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..986faef
--- /dev/null
@@ -0,0 +1,60 @@
+From ffdeec7aa41aa61ca4ee68fddf4669df9ce661d1 Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zyan@redhat.com>
+Date: Mon, 26 Mar 2018 16:46:39 +0800
+Subject: ceph: always update atime/mtime/ctime for new inode
+
+From: Yan, Zheng <zyan@redhat.com>
+
+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" <zyan@redhat.com>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1942797
--- /dev/null
@@ -0,0 +1,103 @@
+From 9496005d6ca4cf8f5ee8f828165a8956872dc59d Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Fri, 30 Mar 2018 20:00:56 -0400
+Subject: ext4: add bounds checking to ext4_xattr_find_entry()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..52eaf41
--- /dev/null
@@ -0,0 +1,108 @@
+From 54dd0e0a1b255f115f8647fc6fb93273251b01b9 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Fri, 30 Mar 2018 20:04:11 -0400
+Subject: ext4: add extra checks to ext4_xattr_block_get()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1ff5a43
--- /dev/null
@@ -0,0 +1,101 @@
+From 7dac4a1726a9c64a517d595c40e95e2d0d135f6f Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 26 Mar 2018 23:54:10 -0400
+Subject: ext4: add validity checks for bitmap block numbers
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <wen.xu@gatech.edu>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..69cedd4
--- /dev/null
@@ -0,0 +1,51 @@
+From a45403b51582a87872927a3e0fc0a389c26867f1 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 29 Mar 2018 22:10:31 -0400
+Subject: ext4: always initialize the crc32c checksum driver
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..e43718a
--- /dev/null
@@ -0,0 +1,51 @@
+From 18db4b4e6fc31eda838dd1c1296d67dbcb3dc957 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+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 <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..8391f57
--- /dev/null
@@ -0,0 +1,115 @@
+From 044e6e3d74a3d7103a0c8a9305dfd94d64000660 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 19 Feb 2018 14:16:47 -0500
+Subject: ext4: don't update checksum of new initialized bitmaps
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1c741a3
--- /dev/null
@@ -0,0 +1,35 @@
+From a6d9946bb925293fda9f5ed6d33d8580b001f006 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 18 Feb 2018 23:16:28 -0500
+Subject: ext4: eliminate sleep from shutdown ioctl
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..ef2c007
--- /dev/null
@@ -0,0 +1,45 @@
+From 8e4b5eae5decd9dfe5a4ee369c22028f90ab4c44 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 29 Mar 2018 21:56:09 -0400
+Subject: ext4: fail ext4_iget for root directory if unallocated
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <wen.xu@gatech.edu>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..98c48ca
--- /dev/null
@@ -0,0 +1,47 @@
+From fe23cb65c2c394ea306f3714a17d46ab2e6a0af1 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+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 <jslaby@suse.cz>
+
+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 <jslaby@suse.cz>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org # v4.15
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..2e91ffa
--- /dev/null
@@ -0,0 +1,44 @@
+From e40ff213898502d299351cc2fe1e350cd186f0d3 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 1 Apr 2018 23:21:03 -0400
+Subject: ext4: force revalidation of directory pointer after seekdir(2)
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..3b5684b
--- /dev/null
@@ -0,0 +1,53 @@
+From ce3fd194fcc6fbdc00ce095a852f22df97baa401 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 29 Mar 2018 14:31:42 -0400
+Subject: ext4: limit xattr size to INT_MAX
+
+From: Eric Biggers <ebiggers@google.com>
+
+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 <wen.xu@gatech.edu>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Fixes: e50e5129f384 ("ext4: xattr-in-inode support")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..61287c4
--- /dev/null
@@ -0,0 +1,153 @@
+From de05ca8526796c7e9f7c7282b7f89a818af19818 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+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 <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..98dfc20
--- /dev/null
@@ -0,0 +1,90 @@
+From fb7c02445c497943e7296cd3deee04422b63acb8 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 18 Feb 2018 23:45:18 -0500
+Subject: ext4: pass -ESHUTDOWN code to jbd2 layer
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..2278c2e
--- /dev/null
@@ -0,0 +1,58 @@
+From 73fdad00b208b139cf43f3163fbc0f67e4c6047c Mon Sep 17 00:00:00 2001
+From: Eryu Guan <guaneryu@gmail.com>
+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 <guaneryu@gmail.com>
+
+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 <jack@suse.cz>
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Eryu Guan <guaneryu@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..da66c3f
--- /dev/null
@@ -0,0 +1,38 @@
+From 576d18ed60f5465110087c5e0eb1010de13e374d Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 18 Feb 2018 22:07:36 -0500
+Subject: ext4: shutdown should not prevent get_write_access
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..888f3f6
--- /dev/null
@@ -0,0 +1,57 @@
+From ad49aee401dd1997ec71360df6e51a91ad3cf516 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+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 <hdegoede@redhat.com>
+
+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 <andy.shevchenko@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..26cbe3d
--- /dev/null
@@ -0,0 +1,98 @@
+From 6de0b13cc0b4ba10e98a9263d7a83b940720b77a Mon Sep 17 00:00:00 2001
+From: Aaron Ma <aaron.ma@canonical.com>
+Date: Mon, 8 Jan 2018 10:41:41 +0800
+Subject: HID: core: Fix size as type u32
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+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 <aaron.ma@canonical.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..7504702
--- /dev/null
@@ -0,0 +1,91 @@
+From 3064a03b94e60388f0955fcc29f3e8a978d28f75 Mon Sep 17 00:00:00 2001
+From: Aaron Ma <aaron.ma@canonical.com>
+Date: Sat, 3 Feb 2018 23:57:15 +0800
+Subject: HID: Fix hid_report_len usage
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+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 <aaron.ma@canonical.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..80b424c
--- /dev/null
@@ -0,0 +1,77 @@
+From aa08192a254d362a4d5317647a81de6996961aef Mon Sep 17 00:00:00 2001
+From: Aniruddha Banerjee <aniruddhab@nvidia.com>
+Date: Wed, 28 Mar 2018 19:12:00 +0530
+Subject: irqchip/gic: Take lock when updating irq type
+
+From: Aniruddha Banerjee <aniruddhab@nvidia.com>
+
+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 <aniruddhab@nvidia.com>
+[maz: updated changelog]
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..65d8335
--- /dev/null
@@ -0,0 +1,41 @@
+From 85e0c4e89c1b864e763c4e3bb15d0b6d501ad5d9 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+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 <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..c0db69d
--- /dev/null
@@ -0,0 +1,84 @@
+From dbfcf3cb9c681aa0c5d0bb46068f98d5b1823dd3 Mon Sep 17 00:00:00 2001
+From: Paul Mackerras <paulus@ozlabs.org>
+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 <paulus@ozlabs.org>
+
+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 <paulus@ozlabs.org>
+Reviewed-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..07aa7e7
--- /dev/null
@@ -0,0 +1,53 @@
+From 0bfdf598900fd62869659f360d3387ed80eb71cf Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Thu, 22 Mar 2018 20:41:46 +1000
+Subject: powerpc/64: Fix smp_wmb barrier definition use use lwsync consistently
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/stringify.h>
+ #include <asm/feature-fixups.h>
+-#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 (file)
index 0000000..e49b172
--- /dev/null
@@ -0,0 +1,81 @@
+From a57ac411832384eb93df4bfed2bf644c4089720e Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+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 <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..363e0a0
--- /dev/null
@@ -0,0 +1,43 @@
+From c130153e453cba0f37ad10fa18a1aa9c9a598a59 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+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 <npiggin@gmail.com>
+
+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 <linuxram@us.ibm.com>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1ad8d06
--- /dev/null
@@ -0,0 +1,258 @@
+From f0295e047fcf52ccb42561fb7de6942f5201b676 Mon Sep 17 00:00:00 2001
+From: Michael Neuling <mikey@neuling.org>
+Date: Mon, 26 Mar 2018 15:17:07 +1100
+Subject: powerpc/eeh: Fix race with driver un/bind
+
+From: Michael Neuling <mikey@neuling.org>
+
+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
+  <snip>
+  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 <mikey@neuling.org>
+Reviewed-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..53ad020
--- /dev/null
@@ -0,0 +1,51 @@
+From bf8a1abc3ddbd6e9a8312ea7d96e5dd89c140f18 Mon Sep 17 00:00:00 2001
+From: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
+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 <bauerman@linux.vnet.ibm.com>
+
+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 <dyoung@redhat.com>
+Signed-off-by: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Reviewed-by: Dave Young <dyoung@redhat.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..3c6dad7
--- /dev/null
@@ -0,0 +1,103 @@
+From e6e133c47e6bd4d5dac05b35d06634a8e5648615 Mon Sep 17 00:00:00 2001
+From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
+Date: Wed, 17 Jan 2018 17:52:24 +0530
+Subject: powerpc/kprobes: Fix call trace due to incorrect preempt count
+
+From: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+
+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 <mpe@ellerman.id.au>
+Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
+Acked-by: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..7f6572f
--- /dev/null
@@ -0,0 +1,75 @@
+From 2675c13b293a007b7b7f8229514126bd23df09a7 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Thu, 12 Apr 2018 11:35:55 +1000
+Subject: powerpc/mm/radix: Fix checkstops caused by invalid tlbiel
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+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 <SF,HV,ME,RI,LE>  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 <mpe@ellerman.id.au>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..0af35fc
--- /dev/null
@@ -0,0 +1,52 @@
+From 3b8070335f751aac9f1526ae2e012e6f5b8b0f21 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Tue, 10 Apr 2018 21:49:33 +1000
+Subject: powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/delay.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/of.h>
+@@ -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 (file)
index 0000000..41bc9a1
--- /dev/null
@@ -0,0 +1,38 @@
+From 741de617661794246f84a21a02fc5e327bffc9ad Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Tue, 27 Mar 2018 01:02:33 +1000
+Subject: powerpc/powernv: Handle unknown OPAL errors in opal_nvram_write()
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Acked-by: Stewart Smith <stewart@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..130de92
--- /dev/null
@@ -0,0 +1,38 @@
+From 9f886f4d1d292442b2f22a0a33321eae821bde40 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 25 Feb 2017 18:21:33 -0400
+Subject: random: use a tighter cap in credit_entropy_bits_safe()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Reported-by: Chen Feng <puck.chen@hisilicon.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
index 388bf2f4ea971d0b46021eb5660fcb28928168fe..8c6ec04844f68ceb0ef183bb1ce6a2649a7d0692 100644 (file)
@@ -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 (file)
index 0000000..f58300a
--- /dev/null
@@ -0,0 +1,35 @@
+From 73ce2ce129783813e1ebc37d2c757fe5e0fab1ef Mon Sep 17 00:00:00 2001
+From: Sean Wang <sean.wang@mediatek.com>
+Date: Fri, 9 Feb 2018 02:07:59 +0800
+Subject: soc: mediatek: fix the mistaken pointer accessed when subdomains are added
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+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 <weiyi.lu@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..18e5337
--- /dev/null
@@ -0,0 +1,83 @@
+From 79fae987518a3aa6c3c7b2e3ad5fe1e4080c12bc Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Fri, 9 Feb 2018 17:29:38 +0300
+Subject: thunderbolt: Handle connecting device in place of host properly
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+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 <mika.westerberg@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..05cb30b
--- /dev/null
@@ -0,0 +1,55 @@
+From ea9d7bb798900096f26c585957d6ad9c532417e6 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Fri, 9 Mar 2018 13:17:01 +0300
+Subject: thunderbolt: Prevent crash when ICM firmware is not running
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+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 <Golden_Miller83@protonmail.ch>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Acked-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1ba44ab
--- /dev/null
@@ -0,0 +1,38 @@
+From f2a659f7d8d5da803836583aa16df06bdf324252 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Tue, 19 Dec 2017 12:44:56 +0300
+Subject: thunderbolt: Resume control channel after hibernation image is created
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+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 <mika.westerberg@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..37e1dc5
--- /dev/null
@@ -0,0 +1,51 @@
+From a03e828915c00ed0ea5aa40647c81472cfa7a984 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+Date: Thu, 18 Jan 2018 20:27:47 +0300
+Subject: thunderbolt: Serialize PCIe tunnel creation with PCI rescan
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+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 <mika.westerberg@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a548625
--- /dev/null
@@ -0,0 +1,55 @@
+From e4be8c9b6a512e274cb6bbac4ac869d73880a8b3 Mon Sep 17 00:00:00 2001
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+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 <mika.westerberg@linux.intel.com>
+
+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 <mika.westerberg@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+               }