--- /dev/null
+From 85b8350ae99d1300eb6dc072459246c2649a8e50 Mon Sep 17 00:00:00 2001
+From: Nicolas Ferre <nicolas.ferre@microchip.com>
+Date: Thu, 3 Dec 2020 10:19:49 +0100
+Subject: ARM: dts: at91: sama5d2: fix CAN message ram offset and size
+
+From: Nicolas Ferre <nicolas.ferre@microchip.com>
+
+commit 85b8350ae99d1300eb6dc072459246c2649a8e50 upstream.
+
+CAN0 and CAN1 instances share the same message ram configured
+at 0x210000 on sama5d2 Linux systems.
+According to current configuration of CAN0, we need 0x1c00 bytes
+so that the CAN1 don't overlap its message ram:
+64 x RX FIFO0 elements => 64 x 72 bytes
+32 x TXE (TX Event FIFO) elements => 32 x 8 bytes
+32 x TXB (TX Buffer) elements => 32 x 72 bytes
+So a total of 7168 bytes (0x1C00).
+
+Fix offset to match this needed size.
+Make the CAN0 message ram ioremap match exactly this size so that is
+easily understandable. Adapt CAN1 size accordingly.
+
+Fixes: bc6d5d7666b7 ("ARM: dts: at91: sama5d2: add m_can nodes")
+Reported-by: Dan Sneddon <dan.sneddon@microchip.com>
+Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Tested-by: Cristian Birsan <cristian.birsan@microchip.com>
+Cc: stable@vger.kernel.org # v4.13+
+Link: https://lore.kernel.org/r/20201203091949.9015-1-nicolas.ferre@microchip.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/sama5d2.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/sama5d2.dtsi
++++ b/arch/arm/boot/dts/sama5d2.dtsi
+@@ -717,7 +717,7 @@
+
+ can0: can@f8054000 {
+ compatible = "bosch,m_can";
+- reg = <0xf8054000 0x4000>, <0x210000 0x4000>;
++ reg = <0xf8054000 0x4000>, <0x210000 0x1c00>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>,
+ <64 IRQ_TYPE_LEVEL_HIGH 7>;
+@@ -939,7 +939,7 @@
+
+ can1: can@fc050000 {
+ compatible = "bosch,m_can";
+- reg = <0xfc050000 0x4000>, <0x210000 0x4000>;
++ reg = <0xfc050000 0x4000>, <0x210000 0x3800>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>,
+ <65 IRQ_TYPE_LEVEL_HIGH 7>;
+@@ -949,7 +949,7 @@
+ assigned-clocks = <&pmc PMC_TYPE_GCK 57>;
+ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>;
+ assigned-clock-rates = <40000000>;
+- bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>;
++ bosch,mram-cfg = <0x1c00 0 0 64 0 0 32 32>;
+ status = "disabled";
+ };
+
--- /dev/null
+From df9dbaf2c415cd94ad520067a1eccfee62f00a33 Mon Sep 17 00:00:00 2001
+From: "H. Nikolaus Schaller" <hns@goldelico.com>
+Date: Sat, 3 Oct 2020 16:10:00 +0200
+Subject: ARM: dts: pandaboard: fix pinmux for gpio user button of Pandaboard ES
+
+From: H. Nikolaus Schaller <hns@goldelico.com>
+
+commit df9dbaf2c415cd94ad520067a1eccfee62f00a33 upstream.
+
+The pinmux control register offset passed to OMAP4_IOPAD is odd.
+
+Fixes: ab9a13665e7c ("ARM: dts: pandaboard: add gpio user button")
+Cc: stable@vger.kernel.org
+Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/omap4-panda-es.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/omap4-panda-es.dts
++++ b/arch/arm/boot/dts/omap4-panda-es.dts
+@@ -46,7 +46,7 @@
+
+ button_pins: pinmux_button_pins {
+ pinctrl-single,pins = <
+- OMAP4_IOPAD(0x11b, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */
++ OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */
+ >;
+ };
+ };
--- /dev/null
+From 9076dbd5ee837c3882fc42891c14cecd0354a849 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Fri, 23 Oct 2020 09:58:04 -0400
+Subject: btrfs: do not shorten unpin len for caching block groups
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 9076dbd5ee837c3882fc42891c14cecd0354a849 upstream.
+
+While fixing up our ->last_byte_to_unpin locking I noticed that we will
+shorten len based on ->last_byte_to_unpin if we're caching when we're
+adding back the free space. This is correct for the free space, as we
+cannot unpin more than ->last_byte_to_unpin, however we use len to
+adjust the ->bytes_pinned counters and such, which need to track the
+actual pinned usage. This could result in
+WARN_ON(space_info->bytes_pinned) triggering at unmount time.
+
+Fix this by using a local variable for the amount to add to free space
+cache, and leave len untouched in this case.
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -2838,10 +2838,10 @@ static int unpin_extent_range(struct btr
+ len = cache->key.objectid + cache->key.offset - start;
+ len = min(len, end + 1 - start);
+
+- if (start < cache->last_byte_to_unpin) {
+- len = min(len, cache->last_byte_to_unpin - start);
+- if (return_free_space)
+- btrfs_add_free_space(cache, start, len);
++ if (start < cache->last_byte_to_unpin && return_free_space) {
++ u64 add_len = min(len, cache->last_byte_to_unpin - start);
++
++ btrfs_add_free_space(cache, start, add_len);
+ }
+
+ start += len;
--- /dev/null
+From foo@baz Mon Dec 28 10:15:12 AM CET 2020
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 31 Jul 2020 19:29:11 +0800
+Subject: btrfs: trim: fix underflow in trim length to prevent access beyond device boundary
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit c57dd1f2f6a7cd1bb61802344f59ccdc5278c983 upstream
+
+[BUG]
+The following script can lead to tons of beyond device boundary access:
+
+ mkfs.btrfs -f $dev -b 10G
+ mount $dev $mnt
+ trimfs $mnt
+ btrfs filesystem resize 1:-1G $mnt
+ trimfs $mnt
+
+[CAUSE]
+Since commit 929be17a9b49 ("btrfs: Switch btrfs_trim_free_extents to
+find_first_clear_extent_bit"), we try to avoid trimming ranges that's
+already trimmed.
+
+So we check device->alloc_state by finding the first range which doesn't
+have CHUNK_TRIMMED and CHUNK_ALLOCATED not set.
+
+But if we shrunk the device, that bits are not cleared, thus we could
+easily got a range starts beyond the shrunk device size.
+
+This results the returned @start and @end are all beyond device size,
+then we call "end = min(end, device->total_bytes -1);" making @end
+smaller than device size.
+
+Then finally we goes "len = end - start + 1", totally underflow the
+result, and lead to the beyond-device-boundary access.
+
+[FIX]
+This patch will fix the problem in two ways:
+
+- Clear CHUNK_TRIMMED | CHUNK_ALLOCATED bits when shrinking device
+ This is the root fix
+
+- Add extra safety check when trimming free device extents
+ We check and warn if the returned range is already beyond current
+ device.
+
+Link: https://github.com/kdave/btrfs-progs/issues/282
+Fixes: 929be17a9b49 ("btrfs: Switch btrfs_trim_free_extents to find_first_clear_extent_bit")
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+[sudip: adjust context and use extent_io.h]
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent-tree.c | 14 ++++++++++++++
+ fs/btrfs/extent_io.h | 2 ++
+ fs/btrfs/volumes.c | 4 ++++
+ 3 files changed, 20 insertions(+)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -32,6 +32,7 @@
+ #include "block-rsv.h"
+ #include "delalloc-space.h"
+ #include "block-group.h"
++#include "rcu-string.h"
+
+ #undef SCRAMBLE_DELAYED_REFS
+
+@@ -5618,6 +5619,19 @@ static int btrfs_trim_free_extents(struc
+ &start, &end,
+ CHUNK_TRIMMED | CHUNK_ALLOCATED);
+
++ /* Check if there are any CHUNK_* bits left */
++ if (start > device->total_bytes) {
++ WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
++ btrfs_warn_in_rcu(fs_info,
++"ignoring attempt to trim beyond device size: offset %llu length %llu device %s device size %llu",
++ start, end - start + 1,
++ rcu_str_deref(device->name),
++ device->total_bytes);
++ mutex_unlock(&fs_info->chunk_mutex);
++ ret = 0;
++ break;
++ }
++
+ /* Ensure we skip the reserved area in the first 1M */
+ start = max_t(u64, start, SZ_1M);
+
+--- a/fs/btrfs/extent_io.h
++++ b/fs/btrfs/extent_io.h
+@@ -35,6 +35,8 @@
+ */
+ #define CHUNK_ALLOCATED EXTENT_DIRTY
+ #define CHUNK_TRIMMED EXTENT_DEFRAG
++#define CHUNK_STATE_MASK (CHUNK_ALLOCATED | \
++ CHUNK_TRIMMED)
+
+ /*
+ * flags for bio submission. The high bits indicate the compression
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -4908,6 +4908,10 @@ again:
+ }
+
+ mutex_lock(&fs_info->chunk_mutex);
++ /* Clear all state bits beyond the shrunk device size */
++ clear_extent_bits(&device->alloc_state, new_size, (u64)-1,
++ CHUNK_STATE_MASK);
++
+ btrfs_device_set_disk_total_bytes(device, new_size);
+ if (list_empty(&device->post_commit_list))
+ list_add_tail(&device->post_commit_list,
--- /dev/null
+From e5cafce3ad0f8652d6849314d951459c2bff7233 Mon Sep 17 00:00:00 2001
+From: Luis Henriques <lhenriques@suse.de>
+Date: Thu, 12 Nov 2020 10:45:12 +0000
+Subject: ceph: fix race in concurrent __ceph_remove_cap invocations
+
+From: Luis Henriques <lhenriques@suse.de>
+
+commit e5cafce3ad0f8652d6849314d951459c2bff7233 upstream.
+
+A NULL pointer dereference may occur in __ceph_remove_cap with some of the
+callbacks used in ceph_iterate_session_caps, namely trim_caps_cb and
+remove_session_caps_cb. Those callers hold the session->s_mutex, so they
+are prevented from concurrent execution, but ceph_evict_inode does not.
+
+Since the callers of this function hold the i_ceph_lock, the fix is simply
+a matter of returning immediately if caps->ci is NULL.
+
+Cc: stable@vger.kernel.org
+URL: https://tracker.ceph.com/issues/43272
+Suggested-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Luis Henriques <lhenriques@suse.de>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/caps.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -1052,12 +1052,19 @@ void __ceph_remove_cap(struct ceph_cap *
+ {
+ struct ceph_mds_session *session = cap->session;
+ struct ceph_inode_info *ci = cap->ci;
+- struct ceph_mds_client *mdsc =
+- ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
++ struct ceph_mds_client *mdsc;
+ int removed = 0;
+
++ /* 'ci' being NULL means the remove have already occurred */
++ if (!ci) {
++ dout("%s: cap inode is NULL\n", __func__);
++ return;
++ }
++
+ dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
+
++ mdsc = ceph_inode_to_client(&ci->vfs_inode)->mdsc;
++
+ /* remove from inode's cap rbtree, and clear auth cap */
+ rb_erase(&cap->ci_node, &ci->i_caps);
+ if (ci->i_auth_cap == cap)
--- /dev/null
+From cca415537244f6102cbb09b5b90db6ae2c953bdd Mon Sep 17 00:00:00 2001
+From: Chunguang Xu <brookxu@tencent.com>
+Date: Sat, 7 Nov 2020 23:58:18 +0800
+Subject: ext4: fix a memory leak of ext4_free_data
+
+From: Chunguang Xu <brookxu@tencent.com>
+
+commit cca415537244f6102cbb09b5b90db6ae2c953bdd upstream.
+
+When freeing metadata, we will create an ext4_free_data and
+insert it into the pending free list. After the current
+transaction is committed, the object will be freed.
+
+ext4_mb_free_metadata() will check whether the area to be freed
+overlaps with the pending free list. If true, return directly. At this
+time, ext4_free_data is leaked. Fortunately, the probability of this
+problem is small, since it only occurs if the file system is corrupted
+such that a block is claimed by more one inode and those inodes are
+deleted within a single jbd2 transaction.
+
+Signed-off-by: Chunguang Xu <brookxu@tencent.com>
+Link: https://lore.kernel.org/r/1604764698-4269-8-git-send-email-brookxu@tencent.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/mballoc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4691,6 +4691,7 @@ ext4_mb_free_metadata(handle_t *handle,
+ ext4_group_first_block_no(sb, group) +
+ EXT4_C2B(sbi, cluster),
+ "Block already on to-be-freed list");
++ kmem_cache_free(ext4_free_data_cachep, new_entry);
+ return 0;
+ }
+ }
--- /dev/null
+From 46e294efc355c48d1dd4d58501aa56dac461792a Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 27 Nov 2020 12:06:49 +0100
+Subject: ext4: fix deadlock with fs freezing and EA inodes
+
+From: Jan Kara <jack@suse.cz>
+
+commit 46e294efc355c48d1dd4d58501aa56dac461792a upstream.
+
+Xattr code using inodes with large xattr data can end up dropping last
+inode reference (and thus deleting the inode) from places like
+ext4_xattr_set_entry(). That function is called with transaction started
+and so ext4_evict_inode() can deadlock against fs freezing like:
+
+CPU1 CPU2
+
+removexattr() freeze_super()
+ vfs_removexattr()
+ ext4_xattr_set()
+ handle = ext4_journal_start()
+ ...
+ ext4_xattr_set_entry()
+ iput(old_ea_inode)
+ ext4_evict_inode(old_ea_inode)
+ sb->s_writers.frozen = SB_FREEZE_FS;
+ sb_wait_write(sb, SB_FREEZE_FS);
+ ext4_freeze()
+ jbd2_journal_lock_updates()
+ -> blocks waiting for all
+ handles to stop
+ sb_start_intwrite()
+ -> blocks as sb is already in SB_FREEZE_FS state
+
+Generally it is advisable to delete inodes from a separate transaction
+as it can consume quite some credits however in this case it would be
+quite clumsy and furthermore the credits for inode deletion are quite
+limited and already accounted for. So just tweak ext4_evict_inode() to
+avoid freeze protection if we have transaction already started and thus
+it is not really needed anyway.
+
+Cc: stable@vger.kernel.org
+Fixes: dec214d00e0d ("ext4: xattr inode deduplication")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Link: https://lore.kernel.org/r/20201127110649.24730-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -203,6 +203,7 @@ void ext4_evict_inode(struct inode *inod
+ */
+ int extra_credits = 6;
+ struct ext4_xattr_inode_array *ea_inode_array = NULL;
++ bool freeze_protected = false;
+
+ trace_ext4_evict_inode(inode);
+
+@@ -250,9 +251,14 @@ void ext4_evict_inode(struct inode *inod
+
+ /*
+ * Protect us against freezing - iput() caller didn't have to have any
+- * protection against it
+- */
+- sb_start_intwrite(inode->i_sb);
++ * protection against it. When we are in a running transaction though,
++ * we are already protected against freezing and we cannot grab further
++ * protection due to lock ordering constraints.
++ */
++ if (!ext4_journal_current_handle()) {
++ sb_start_intwrite(inode->i_sb);
++ freeze_protected = true;
++ }
+
+ if (!IS_NOQUOTA(inode))
+ extra_credits += EXT4_MAXQUOTAS_DEL_BLOCKS(inode->i_sb);
+@@ -271,7 +277,8 @@ void ext4_evict_inode(struct inode *inod
+ * cleaned up.
+ */
+ ext4_orphan_del(NULL, inode);
+- sb_end_intwrite(inode->i_sb);
++ if (freeze_protected)
++ sb_end_intwrite(inode->i_sb);
+ goto no_delete;
+ }
+
+@@ -312,7 +319,8 @@ void ext4_evict_inode(struct inode *inod
+ stop_handle:
+ ext4_journal_stop(handle);
+ ext4_orphan_del(NULL, inode);
+- sb_end_intwrite(inode->i_sb);
++ if (freeze_protected)
++ sb_end_intwrite(inode->i_sb);
+ ext4_xattr_inode_array_free(ea_inode_array);
+ goto no_delete;
+ }
+@@ -341,7 +349,8 @@ stop_handle:
+ else
+ ext4_free_inode(handle, inode);
+ ext4_journal_stop(handle);
+- sb_end_intwrite(inode->i_sb);
++ if (freeze_protected)
++ sb_end_intwrite(inode->i_sb);
+ ext4_xattr_inode_array_free(ea_inode_array);
+ return;
+ no_delete:
--- /dev/null
+From 207cdd565dfc95a0a5185263a567817b7ebf5467 Mon Sep 17 00:00:00 2001
+From: Roberto Sassu <roberto.sassu@huawei.com>
+Date: Thu, 26 Nov 2020 11:34:56 +0100
+Subject: ima: Don't modify file descriptor mode on the fly
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+commit 207cdd565dfc95a0a5185263a567817b7ebf5467 upstream.
+
+Commit a408e4a86b36b ("ima: open a new file instance if no read
+permissions") already introduced a second open to measure a file when the
+original file descriptor does not allow it. However, it didn't remove the
+existing method of changing the mode of the original file descriptor, which
+is still necessary if the current process does not have enough privileges
+to open a new one.
+
+Changing the mode isn't really an option, as the filesystem might need to
+do preliminary steps to make the read possible. Thus, this patch removes
+the code and keeps the second open as the only option to measure a file
+when it is unreadable with the original file descriptor.
+
+Cc: <stable@vger.kernel.org> # 4.20.x: 0014cc04e8ec0 ima: Set file->f_mode
+Fixes: 2fe5d6def1672 ("ima: integrity appraisal extension")
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/integrity/ima/ima_crypto.c | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+--- a/security/integrity/ima/ima_crypto.c
++++ b/security/integrity/ima/ima_crypto.c
+@@ -411,7 +411,7 @@ int ima_calc_file_hash(struct file *file
+ loff_t i_size;
+ int rc;
+ struct file *f = file;
+- bool new_file_instance = false, modified_mode = false;
++ bool new_file_instance = false;
+
+ /*
+ * For consistency, fail file's opened with the O_DIRECT flag on
+@@ -429,18 +429,10 @@ int ima_calc_file_hash(struct file *file
+ O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
+ flags |= O_RDONLY;
+ f = dentry_open(&file->f_path, flags, file->f_cred);
+- if (IS_ERR(f)) {
+- /*
+- * Cannot open the file again, lets modify f_mode
+- * of original and continue
+- */
+- pr_info_ratelimited("Unable to reopen file for reading.\n");
+- f = file;
+- f->f_mode |= FMODE_READ;
+- modified_mode = true;
+- } else {
+- new_file_instance = true;
+- }
++ if (IS_ERR(f))
++ return PTR_ERR(f);
++
++ new_file_instance = true;
+ }
+
+ i_size = i_size_read(file_inode(f));
+@@ -455,8 +447,6 @@ int ima_calc_file_hash(struct file *file
+ out:
+ if (new_file_instance)
+ fput(f);
+- else if (modified_mode)
+- f->f_mode &= ~FMODE_READ;
+ return rc;
+ }
+
--- /dev/null
+From 9afc9a8a4909fece0e911e72b1060614ba2f7969 Mon Sep 17 00:00:00 2001
+From: Zhe Li <lizhe67@huawei.com>
+Date: Fri, 29 May 2020 11:37:11 +0800
+Subject: jffs2: Fix GC exit abnormally
+
+From: Zhe Li <lizhe67@huawei.com>
+
+commit 9afc9a8a4909fece0e911e72b1060614ba2f7969 upstream.
+
+The log of this problem is:
+jffs2: Error garbage collecting node at 0x***!
+jffs2: No space for garbage collection. Aborting GC thread
+
+This is because GC believe that it do nothing, so it abort.
+
+After going over the image of jffs2, I find a scene that
+can trigger this problem stably.
+The scene is: there is a normal dirent node at summary-area,
+but abnormal at corresponding not-summary-area with error
+name_crc.
+
+The reason that GC exit abnormally is because it find that
+abnormal dirent node to GC, but when it goes to function
+jffs2_add_fd_to_list, it cannot meet the condition listed
+below:
+
+if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name))
+
+So no node is marked obsolete, statistical information of
+erase_block do not change, which cause GC exit abnormally.
+
+The root cause of this problem is: we do not check the
+name_crc of the abnormal dirent node with summary is enabled.
+
+Noticed that in function jffs2_scan_dirent_node, we use
+function jffs2_scan_dirty_space to deal with the dirent
+node with error name_crc. So this patch add a checking
+code in function read_direntry to ensure the correctness
+of dirent node. If checked failed, the dirent node will
+be marked obsolete so GC will pass this node and this
+problem will be fixed.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Zhe Li <lizhe67@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jffs2/readinode.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/jffs2/readinode.c
++++ b/fs/jffs2/readinode.c
+@@ -672,6 +672,22 @@ static inline int read_direntry(struct j
+ jffs2_free_full_dirent(fd);
+ return -EIO;
+ }
++
++#ifdef CONFIG_JFFS2_SUMMARY
++ /*
++ * we use CONFIG_JFFS2_SUMMARY because without it, we
++ * have checked it while mounting
++ */
++ crc = crc32(0, fd->name, rd->nsize);
++ if (unlikely(crc != je32_to_cpu(rd->name_crc))) {
++ JFFS2_NOTICE("name CRC failed on dirent node at"
++ "%#08x: read %#08x,calculated %#08x\n",
++ ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
++ jffs2_mark_node_obsolete(c, ref);
++ jffs2_free_full_dirent(fd);
++ return 0;
++ }
++#endif
+ }
+
+ fd->nhash = full_name_hash(NULL, fd->name, rd->nsize);
--- /dev/null
+From 08cd274f9b8283a1da93e2ccab216a336da83525 Mon Sep 17 00:00:00 2001
+From: lizhe <lizhe67@huawei.com>
+Date: Wed, 14 Oct 2020 14:54:42 +0800
+Subject: jffs2: Fix ignoring mounting options problem during remounting
+
+From: lizhe <lizhe67@huawei.com>
+
+commit 08cd274f9b8283a1da93e2ccab216a336da83525 upstream.
+
+The jffs2 mount options will be ignored when remounting jffs2.
+It can be easily reproduced with the steps listed below.
+1. mount -t jffs2 -o compr=none /dev/mtdblockx /mnt
+2. mount -o remount compr=zlib /mnt
+
+Since ec10a24f10c8, the option parsing happens before fill_super and
+then pass fc, which contains the options parsing results, to function
+jffs2_reconfigure during remounting. But function jffs2_reconfigure do
+not update c->mount_opts.
+
+This patch add a function jffs2_update_mount_opts to fix this problem.
+
+By the way, I notice that tmpfs use the same way to update remounting
+options. If it is necessary to unify them?
+
+Cc: <stable@vger.kernel.org>
+Fixes: ec10a24f10c8 ("vfs: Convert jffs2 to use the new mount API")
+Signed-off-by: lizhe <lizhe67@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jffs2/super.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/fs/jffs2/super.c
++++ b/fs/jffs2/super.c
+@@ -221,11 +221,28 @@ static int jffs2_parse_param(struct fs_c
+ return 0;
+ }
+
++static inline void jffs2_update_mount_opts(struct fs_context *fc)
++{
++ struct jffs2_sb_info *new_c = fc->s_fs_info;
++ struct jffs2_sb_info *c = JFFS2_SB_INFO(fc->root->d_sb);
++
++ mutex_lock(&c->alloc_sem);
++ if (new_c->mount_opts.override_compr) {
++ c->mount_opts.override_compr = new_c->mount_opts.override_compr;
++ c->mount_opts.compr = new_c->mount_opts.compr;
++ }
++ if (new_c->mount_opts.rp_size)
++ c->mount_opts.rp_size = new_c->mount_opts.rp_size;
++ mutex_unlock(&c->alloc_sem);
++}
++
+ static int jffs2_reconfigure(struct fs_context *fc)
+ {
+ struct super_block *sb = fc->root->d_sb;
+
+ sync_filesystem(sb);
++ jffs2_update_mount_opts(fc);
++
+ return jffs2_do_remount_fs(sb, fc);
+ }
+
--- /dev/null
+From ca4e514774930f30b66375a974b5edcbebaf0e7e Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Tue, 10 Nov 2020 11:10:15 +0000
+Subject: KVM: arm64: Introduce handling of AArch32 TTBCR2 traps
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit ca4e514774930f30b66375a974b5edcbebaf0e7e upstream.
+
+ARMv8.2 introduced TTBCR2, which shares TCR_EL1 with TTBCR.
+Gracefully handle traps to this register when HCR_EL2.TVM is set.
+
+Cc: stable@vger.kernel.org
+Reported-by: James Morse <james.morse@arm.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/kvm_host.h | 1 +
+ arch/arm64/kvm/sys_regs.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -182,6 +182,7 @@ enum vcpu_sysreg {
+ #define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */
+ #define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */
+ #define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */
++#define c2_TTBCR2 (c2_TTBCR + 1) /* Translation Table Base Control R. 2 */
+ #define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */
+ #define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */
+ #define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */
+--- a/arch/arm64/kvm/sys_regs.c
++++ b/arch/arm64/kvm/sys_regs.c
+@@ -1837,6 +1837,7 @@ static const struct sys_reg_desc cp15_re
+ { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 },
+ { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 },
+ { Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, c2_TTBCR },
++ { Op1( 0), CRn( 2), CRm( 0), Op2( 3), access_vm_reg, NULL, c2_TTBCR2 },
+ { Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, c3_DACR },
+ { Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, c5_DFSR },
+ { Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, c5_IFSR },
--- /dev/null
+From 1e78f723d6a52966bfe3804209dbf404fdc9d3bb Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Fri, 4 Dec 2020 10:11:34 +0000
+Subject: powerpc/8xx: Fix early debug when SMC1 is relocated
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+commit 1e78f723d6a52966bfe3804209dbf404fdc9d3bb upstream.
+
+When SMC1 is relocated and early debug is selected, the
+board hangs is ppc_md.setup_arch(). This is because ones
+the microcode has been loaded and SMC1 relocated, early
+debug writes in the weed.
+
+To allow smooth continuation, the SMC1 parameter RAM set up
+by the bootloader have to be copied into the new location.
+
+Fixes: 43db76f41824 ("powerpc/8xx: Add microcode patch to move SMC parameter RAM.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/b2f71f39eca543f1e4ec06596f09a8b12235c701.1607076683.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/cpm1.h | 1 +
+ arch/powerpc/platforms/8xx/micropatch.c | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/arch/powerpc/include/asm/cpm1.h
++++ b/arch/powerpc/include/asm/cpm1.h
+@@ -68,6 +68,7 @@ extern void cpm_reset(void);
+ #define PROFF_SPI ((uint)0x0180)
+ #define PROFF_SCC3 ((uint)0x0200)
+ #define PROFF_SMC1 ((uint)0x0280)
++#define PROFF_DSP1 ((uint)0x02c0)
+ #define PROFF_SCC4 ((uint)0x0300)
+ #define PROFF_SMC2 ((uint)0x0380)
+
+--- a/arch/powerpc/platforms/8xx/micropatch.c
++++ b/arch/powerpc/platforms/8xx/micropatch.c
+@@ -361,6 +361,17 @@ void __init cpm_load_patch(cpm8xx_t *cp)
+ if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) {
+ smc_uart_t *smp;
+
++ if (IS_ENABLED(CONFIG_PPC_EARLY_DEBUG_CPM)) {
++ int i;
++
++ for (i = 0; i < sizeof(*smp); i += 4) {
++ u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i];
++ u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i];
++
++ out_be32(dst, in_be32(src));
++ }
++ }
++
+ smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
+ out_be16(&smp->smc_rpbase, 0x1ec0);
+ smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
--- /dev/null
+From 197493af414ee22427be3343637ac290a791925a Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Mon, 12 Oct 2020 08:02:13 +0000
+Subject: powerpc/feature: Add CPU_FTR_NOEXECUTE to G2_LE
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+commit 197493af414ee22427be3343637ac290a791925a upstream.
+
+G2_LE has a 603 core, add CPU_FTR_NOEXECUTE.
+
+Fixes: 385e89d5b20f ("powerpc/mm: add exec protection on powerpc 603")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/39a530ee41d83f49747ab3af8e39c056450b9b4d.1602489653.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/cputable.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/include/asm/cputable.h
++++ b/arch/powerpc/include/asm/cputable.h
+@@ -367,7 +367,7 @@ static inline void cpu_feature_keys_init
+ CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX)
+ #define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_NOEXECUTE)
+ #define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
+- CPU_FTR_MAYBE_CAN_NAP)
++ CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NOEXECUTE)
+ #define CPU_FTRS_E300 (CPU_FTR_MAYBE_CAN_DOZE | \
+ CPU_FTR_MAYBE_CAN_NAP | \
+ CPU_FTR_COMMON | CPU_FTR_NOEXECUTE)
--- /dev/null
+From d85be8a49e733dcd23674aa6202870d54bf5600d Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Thu, 22 Oct 2020 09:29:20 +0000
+Subject: powerpc: Fix incorrect stw{, ux, u, x} instructions in __set_pte_at
+
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+commit d85be8a49e733dcd23674aa6202870d54bf5600d upstream.
+
+The placeholder for instruction selection should use the second
+argument's operand, which is %1, not %0. This could generate incorrect
+assembly code if the memory addressing of operand %0 is a different
+form from that of operand %1.
+
+Also remove the %Un placeholder because having %Un placeholders
+for two operands which are based on the same local var (ptep) doesn't
+make much sense. By the way, it doesn't change the current behaviour
+because "<>" constraint is missing for the associated "=m".
+
+[chleroy: revised commit log iaw segher's comments and removed %U0]
+
+Fixes: 9bf2b5cdc5fe ("powerpc: Fixes for CONFIG_PTE_64BIT for SMP support")
+Cc: <stable@vger.kernel.org> # v2.6.28+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Acked-by: Segher Boessenkool <segher@kernel.crashing.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/96354bd77977a6a933fe9020da57629007fdb920.1603358942.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/book3s/32/pgtable.h | 4 ++--
+ arch/powerpc/include/asm/nohash/pgtable.h | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
++++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
+@@ -557,9 +557,9 @@ static inline void __set_pte_at(struct m
+ if (pte_val(*ptep) & _PAGE_HASHPTE)
+ flush_hash_entry(mm, ptep, addr);
+ __asm__ __volatile__("\
+- stw%U0%X0 %2,%0\n\
++ stw%X0 %2,%0\n\
+ eieio\n\
+- stw%U0%X0 %L2,%1"
++ stw%X1 %L2,%1"
+ : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+ : "r" (pte) : "memory");
+
+--- a/arch/powerpc/include/asm/nohash/pgtable.h
++++ b/arch/powerpc/include/asm/nohash/pgtable.h
+@@ -199,9 +199,9 @@ static inline void __set_pte_at(struct m
+ */
+ if (IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_PTE_64BIT) && !percpu) {
+ __asm__ __volatile__("\
+- stw%U0%X0 %2,%0\n\
++ stw%X0 %2,%0\n\
+ eieio\n\
+- stw%U0%X0 %L2,%1"
++ stw%X1 %L2,%1"
+ : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+ : "r" (pte) : "memory");
+ return;
--- /dev/null
+From 17179aeb9d34cc81e1a4ae3f85e5b12b13a1f8d0 Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Sat, 10 Oct 2020 17:30:59 +0000
+Subject: powerpc/mm: Fix verification of MMU_FTR_TYPE_44x
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+commit 17179aeb9d34cc81e1a4ae3f85e5b12b13a1f8d0 upstream.
+
+MMU_FTR_TYPE_44x cannot be checked by cpu_has_feature()
+
+Use mmu_has_feature() instead
+
+Fixes: 23eb7f560a2a ("powerpc: Convert flush_icache_range & friends to C")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/ceede82fadf37f3b8275e61fcf8cf29a3e2ec7fe.1602351011.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/mm/mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/mm/mem.c
++++ b/arch/powerpc/mm/mem.c
+@@ -530,7 +530,7 @@ void __flush_dcache_icache(void *p)
+ * space occurs, before returning to user space.
+ */
+
+- if (cpu_has_feature(MMU_FTR_TYPE_44x))
++ if (mmu_has_feature(MMU_FTR_TYPE_44x))
+ return;
+
+ invalidate_icache_range(addr, addr + PAGE_SIZE);
--- /dev/null
+From c74cf7a3d59a21b290fe0468f5b470d0b8ee37df Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Wed, 11 Nov 2020 15:53:15 +0100
+Subject: powerpc/powernv/memtrace: Don't leak kernel memory to user space
+
+From: David Hildenbrand <david@redhat.com>
+
+commit c74cf7a3d59a21b290fe0468f5b470d0b8ee37df upstream.
+
+We currently leak kernel memory to user space, because memory
+offlining doesn't do any implicit clearing of memory and we are
+missing explicit clearing of memory.
+
+Let's keep it simple and clear pages before removing the linear
+mapping.
+
+Reproduced in QEMU/TCG with 10 GiB of main memory:
+ [root@localhost ~]# dd obs=9G if=/dev/urandom of=/dev/null
+ [... wait until "free -m" used counter no longer changes and cancel]
+ 19665802+0 records in
+ 1+0 records out
+ 9663676416 bytes (9.7 GB, 9.0 GiB) copied, 135.548 s, 71.3 MB/s
+ [root@localhost ~]# cat /sys/devices/system/memory/block_size_bytes
+ 40000000
+ [root@localhost ~]# echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
+ [ 402.978663][ T1086] page:000000001bc4bc74 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x24900
+ [ 402.980063][ T1086] flags: 0x7ffff000001000(reserved)
+ [ 402.980415][ T1086] raw: 007ffff000001000 c00c000000924008 c00c000000924008 0000000000000000
+ [ 402.980627][ T1086] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
+ [ 402.980845][ T1086] page dumped because: unmovable page
+ [ 402.989608][ T1086] Offlined Pages 16384
+ [ 403.324155][ T1086] memtrace: Allocated trace memory on node 0 at 0x0000000200000000
+
+Before this patch:
+ [root@localhost ~]# hexdump -C /sys/kernel/debug/powerpc/memtrace/00000000/trace | head
+ 00000000 c8 25 72 51 4d 26 36 c5 5c c2 56 15 d5 1a cd 10 |.%rQM&6.\.V.....|
+ 00000010 19 b9 50 b2 cb e3 60 b8 ec 0a f3 ec 4b 3c 39 f0 |..P...`.....K<9.|$
+ 00000020 4e 5a 4c cf bd 26 19 ff 37 79 13 67 24 b7 b8 57 |NZL..&..7y.g$..W|$
+ 00000030 98 3e f5 be 6f 14 6a bd a4 52 bc 6e e9 e0 c1 5d |.>..o.j..R.n...]|$
+ 00000040 76 b3 ae b5 88 d7 da e3 64 23 85 2c 10 88 07 b6 |v.......d#.,....|$
+ 00000050 9a d8 91 de f7 50 27 69 2e 64 9c 6f d3 19 45 79 |.....P'i.d.o..Ey|$
+ 00000060 6a 6f 8a 61 71 19 1f c7 f1 df 28 26 ca 0f 84 55 |jo.aq.....(&...U|$
+ 00000070 01 3f be e4 e2 e1 da ff 7b 8c 8e 32 37 b4 24 53 |.?......{..27.$S|$
+ 00000080 1b 70 30 45 56 e6 8c c4 0e b5 4c fb 9f dd 88 06 |.p0EV.....L.....|$
+ 00000090 ef c4 18 79 f1 60 b1 5c 79 59 4d f4 36 d7 4a 5c |...y.`.\yYM.6.J\|$
+
+After this patch:
+ [root@localhost ~]# hexdump -C /sys/kernel/debug/powerpc/memtrace/00000000/trace | head
+ 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+ *
+ 40000000
+
+Fixes: 9d5171a8f248 ("powerpc/powernv: Enable removal of memory for in memory tracing")
+Cc: stable@vger.kernel.org # v4.14+
+Reported-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Oscar Salvador <osalvador@suse.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20201111145322.15793-2-david@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/memtrace.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/arch/powerpc/platforms/powernv/memtrace.c
++++ b/arch/powerpc/platforms/powernv/memtrace.c
+@@ -67,6 +67,23 @@ static int change_memblock_state(struct
+ return 0;
+ }
+
++static void memtrace_clear_range(unsigned long start_pfn,
++ unsigned long nr_pages)
++{
++ unsigned long pfn;
++
++ /*
++ * As pages are offline, we cannot trust the memmap anymore. As HIGHMEM
++ * does not apply, avoid passing around "struct page" and use
++ * clear_page() instead directly.
++ */
++ for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
++ if (IS_ALIGNED(pfn, PAGES_PER_SECTION))
++ cond_resched();
++ clear_page(__va(PFN_PHYS(pfn)));
++ }
++}
++
+ /* called with device_hotplug_lock held */
+ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages)
+ {
+@@ -112,6 +129,11 @@ static u64 memtrace_alloc_node(u32 nid,
+ for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) {
+ if (memtrace_offline_pages(nid, base_pfn, nr_pages) == true) {
+ /*
++ * Clear the range while we still have a linear
++ * mapping.
++ */
++ memtrace_clear_range(base_pfn, nr_pages);
++ /*
+ * Remove memory in memory block size chunks so that
+ * iomem resources are always split to the same size and
+ * we never try to remove memory that spans two iomem
--- /dev/null
+From d6718941a2767fb383e105d257d2105fe4f15f0e Mon Sep 17 00:00:00 2001
+From: David Hildenbrand <david@redhat.com>
+Date: Wed, 11 Nov 2020 15:53:16 +0100
+Subject: powerpc/powernv/memtrace: Fix crashing the kernel when enabling concurrently
+
+From: David Hildenbrand <david@redhat.com>
+
+commit d6718941a2767fb383e105d257d2105fe4f15f0e upstream.
+
+It's very easy to crash the kernel right now by simply trying to
+enable memtrace concurrently, hammering on the "enable" interface
+
+loop.sh:
+ #!/bin/bash
+
+ dmesg --console-off
+
+ while true; do
+ echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
+ done
+
+[root@localhost ~]# loop.sh &
+[root@localhost ~]# loop.sh &
+
+Resulting quickly in a kernel crash. Let's properly protect using a
+mutex.
+
+Fixes: 9d5171a8f248 ("powerpc/powernv: Enable removal of memory for in memory tracing")
+Cc: stable@vger.kernel.org# v4.14+
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Oscar Salvador <osalvador@suse.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20201111145322.15793-3-david@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/memtrace.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+--- a/arch/powerpc/platforms/powernv/memtrace.c
++++ b/arch/powerpc/platforms/powernv/memtrace.c
+@@ -30,6 +30,7 @@ struct memtrace_entry {
+ char name[16];
+ };
+
++static DEFINE_MUTEX(memtrace_mutex);
+ static u64 memtrace_size;
+
+ static struct memtrace_entry *memtrace_array;
+@@ -290,6 +291,7 @@ static int memtrace_online(void)
+
+ static int memtrace_enable_set(void *data, u64 val)
+ {
++ int rc = -EAGAIN;
+ u64 bytes;
+
+ /*
+@@ -302,25 +304,31 @@ static int memtrace_enable_set(void *dat
+ return -EINVAL;
+ }
+
++ mutex_lock(&memtrace_mutex);
++
+ /* Re-add/online previously removed/offlined memory */
+ if (memtrace_size) {
+ if (memtrace_online())
+- return -EAGAIN;
++ goto out_unlock;
+ }
+
+- if (!val)
+- return 0;
++ if (!val) {
++ rc = 0;
++ goto out_unlock;
++ }
+
+ /* Offline and remove memory */
+ if (memtrace_init_regions_runtime(val))
+- return -EINVAL;
++ goto out_unlock;
+
+ if (memtrace_init_debugfs())
+- return -EINVAL;
++ goto out_unlock;
+
+ memtrace_size = val;
+-
+- return 0;
++ rc = 0;
++out_unlock:
++ mutex_unlock(&memtrace_mutex);
++ return rc;
+ }
+
+ static int memtrace_enable_get(void *data, u64 *val)
--- /dev/null
+From b1198a88230f2ce50c271e22b82a8b8610b2eea9 Mon Sep 17 00:00:00 2001
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+Date: Sun, 22 Nov 2020 18:38:28 +1100
+Subject: powerpc/powernv/npu: Do not attempt NPU2 setup on POWER8NVL NPU
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+commit b1198a88230f2ce50c271e22b82a8b8610b2eea9 upstream.
+
+We execute certain NPU2 setup code (such as mapping an LPID to a device
+in NPU2) unconditionally if an Nvlink bridge is detected. However this
+cannot succeed on POWER8NVL machines and errors appear in dmesg. This is
+harmless as skiboot returns an error and the only place we check it is
+vfio-pci but that code does not get called on P8+ either.
+
+This adds a check if pnv_npu2_xxx helpers are called on a machine with
+NPU2 which initializes pnv_phb::npu in pnv_npu2_init();
+pnv_phb::npu==NULL on POWER8/NVL (Naples).
+
+While at this, fix NULL derefencing in pnv_npu_peers_take_ownership/
+pnv_npu_peers_release_ownership which occurs when GPUs on mentioned P8s
+cause EEH which happens if "vfio-pci" disables devices using
+the D3 power state; the vfio-pci's disable_idle_d3 module parameter
+controls this and must be set on Naples. The EEH handling clears
+the entire pnv_ioda_pe struct in pnv_ioda_free_pe() hence
+the NULL derefencing. We cannot recover from that but at least we stop
+crashing.
+
+Tested on
+- POWER9 pvr=004e1201, Ubuntu 19.04 host, Ubuntu 18.04 vm,
+ NVIDIA GV100 10de:1db1 driver 418.39
+- POWER8 pvr=004c0100, RHEL 7.6 host, Ubuntu 16.10 vm,
+ NVIDIA P100 10de:15f9 driver 396.47
+
+Fixes: 1b785611e119 ("powerpc/powernv/npu: Add release_ownership hook")
+Cc: stable@vger.kernel.org # 5.0
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20201122073828.15446-1-aik@ozlabs.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/npu-dma.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/platforms/powernv/npu-dma.c
++++ b/arch/powerpc/platforms/powernv/npu-dma.c
+@@ -384,7 +384,8 @@ static void pnv_npu_peers_take_ownership
+ for (i = 0; i < npucomp->pe_num; ++i) {
+ struct pnv_ioda_pe *pe = npucomp->pe[i];
+
+- if (!pe->table_group.ops->take_ownership)
++ if (!pe->table_group.ops ||
++ !pe->table_group.ops->take_ownership)
+ continue;
+ pe->table_group.ops->take_ownership(&pe->table_group);
+ }
+@@ -400,7 +401,8 @@ static void pnv_npu_peers_release_owners
+ for (i = 0; i < npucomp->pe_num; ++i) {
+ struct pnv_ioda_pe *pe = npucomp->pe[i];
+
+- if (!pe->table_group.ops->release_ownership)
++ if (!pe->table_group.ops ||
++ !pe->table_group.ops->release_ownership)
+ continue;
+ pe->table_group.ops->release_ownership(&pe->table_group);
+ }
+@@ -560,6 +562,11 @@ int pnv_npu2_map_lpar_dev(struct pci_dev
+ return -ENODEV;
+
+ hose = pci_bus_to_host(npdev->bus);
++ if (hose->npu == NULL) {
++ dev_info_once(&npdev->dev, "Nvlink1 does not support contexts");
++ return 0;
++ }
++
+ nphb = hose->private_data;
+
+ dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=%u\n",
+@@ -607,6 +614,11 @@ int pnv_npu2_unmap_lpar_dev(struct pci_d
+ return -ENODEV;
+
+ hose = pci_bus_to_host(npdev->bus);
++ if (hose->npu == NULL) {
++ dev_info_once(&npdev->dev, "Nvlink1 does not support contexts");
++ return 0;
++ }
++
+ nphb = hose->private_data;
+
+ dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n",
--- /dev/null
+From f10881a46f8914428110d110140a455c66bdf27b Mon Sep 17 00:00:00 2001
+From: Tyrel Datwyler <tyreld@linux.ibm.com>
+Date: Tue, 8 Dec 2020 13:54:34 -0600
+Subject: powerpc/rtas: Fix typo of ibm,open-errinjct in RTAS filter
+
+From: Tyrel Datwyler <tyreld@linux.ibm.com>
+
+commit f10881a46f8914428110d110140a455c66bdf27b upstream.
+
+Commit bd59380c5ba4 ("powerpc/rtas: Restrict RTAS requests from userspace")
+introduced the following error when invoking the errinjct userspace
+tool:
+
+ [root@ltcalpine2-lp5 librtas]# errinjct open
+ [327884.071171] sys_rtas: RTAS call blocked - exploit attempt?
+ [327884.071186] sys_rtas: token=0x26, nargs=0 (called by errinjct)
+ errinjct: Could not open RTAS error injection facility
+ errinjct: librtas: open: Unexpected I/O error
+
+The entry for ibm,open-errinjct in rtas_filter array has a typo where
+the "j" is omitted in the rtas call name. After fixing this typo the
+errinjct tool functions again as expected.
+
+ [root@ltcalpine2-lp5 linux]# errinjct open
+ RTAS error injection facility open, token = 1
+
+Fixes: bd59380c5ba4 ("powerpc/rtas: Restrict RTAS requests from userspace")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20201208195434.8289-1-tyreld@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/rtas.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -978,7 +978,7 @@ static struct rtas_filter rtas_filters[]
+ { "ibm,display-message", -1, 0, -1, -1, -1 },
+ { "ibm,errinjct", -1, 2, -1, -1, -1, 1024 },
+ { "ibm,close-errinjct", -1, -1, -1, -1, -1 },
+- { "ibm,open-errinct", -1, -1, -1, -1, -1 },
++ { "ibm,open-errinjct", -1, -1, -1, -1, -1 },
+ { "ibm,get-config-addr-info2", -1, -1, -1, -1, -1 },
+ { "ibm,get-dynamic-sensor-state", -1, 1, -1, -1, -1 },
+ { "ibm,get-indices", -1, 2, 3, -1, -1 },
--- /dev/null
+From 7c6c86b36a36dd4a13d30bba07718e767aa2e7a1 Mon Sep 17 00:00:00 2001
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Fri, 4 Dec 2020 10:35:38 +0000
+Subject: powerpc/xmon: Change printk() to pr_cont()
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+commit 7c6c86b36a36dd4a13d30bba07718e767aa2e7a1 upstream.
+
+Since some time now, printk() adds carriage return, leading to
+unusable xmon output if there is no udbg backend available:
+
+ [ 54.288722] sysrq: Entering xmon
+ [ 54.292209] Vector: 0 at [cace3d2c]
+ [ 54.292274] pc:
+ [ 54.292331] c0023650
+ [ 54.292468] : xmon+0x28/0x58
+ [ 54.292519]
+ [ 54.292574] lr:
+ [ 54.292630] c0023724
+ [ 54.292749] : sysrq_handle_xmon+0xa4/0xfc
+ [ 54.292801]
+ [ 54.292867] sp: cace3de8
+ [ 54.292931] msr: 9032
+ [ 54.292999] current = 0xc28d0000
+ [ 54.293072] pid = 377, comm = sh
+ [ 54.293157] Linux version 5.10.0-rc6-s3k-dev-01364-gedf13f0ccd76-dirty (root@po17688vm.idsi0.si.c-s.fr) (powerpc64-linux-gcc (GCC) 10.1.0, GNU ld (GNU Binutils) 2.34) #4211 PREEMPT Fri Dec 4 09:32:11 UTC 2020
+ [ 54.293287] enter ? for help
+ [ 54.293470] [cace3de8]
+ [ 54.293532] c0023724
+ [ 54.293654] sysrq_handle_xmon+0xa4/0xfc
+ [ 54.293711] (unreliable)
+ ...
+ [ 54.296002]
+ [ 54.296159] --- Exception: c01 (System Call) at
+ [ 54.296217] 0fd4e784
+ [ 54.296303]
+ [ 54.296375] SP (7fca6ff0) is in userspace
+ [ 54.296431] mon>
+ [ 54.296484] <no input ...>
+
+Use pr_cont() instead.
+
+Fixes: 4bcc595ccd80 ("printk: reinstate KERN_CONT for printing continuation lines")
+Cc: stable@vger.kernel.org # v4.9+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+[mpe: Mention that it only happens when udbg is not available]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/c8a6ec704416ecd5ff2bd26213c9bc026bdd19de.1607077340.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/xmon/nonstdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/xmon/nonstdio.c
++++ b/arch/powerpc/xmon/nonstdio.c
+@@ -178,7 +178,7 @@ void xmon_printf(const char *format, ...
+
+ if (n && rc == 0) {
+ /* No udbg hooks, fallback to printk() - dangerous */
+- printk("%s", xmon_outbuf);
++ pr_cont("%s", xmon_outbuf);
+ }
+ }
+
usb-serial-keyspan_pda-fix-write-wakeup-use-after-free.patch
usb-serial-keyspan_pda-fix-tx-unthrottle-use-after-free.patch
usb-serial-keyspan_pda-fix-write-unthrottling.patch
+btrfs-do-not-shorten-unpin-len-for-caching-block-groups.patch
+btrfs-trim-fix-underflow-in-trim-length-to-prevent-access-beyond-device-boundary.patch
+ext4-fix-a-memory-leak-of-ext4_free_data.patch
+ext4-fix-deadlock-with-fs-freezing-and-ea-inodes.patch
+kvm-arm64-introduce-handling-of-aarch32-ttbcr2-traps.patch
+arm-dts-pandaboard-fix-pinmux-for-gpio-user-button-of-pandaboard-es.patch
+arm-dts-at91-sama5d2-fix-can-message-ram-offset-and-size.patch
+xprtrdma-fix-xdrbuf_sparse_pages-support.patch
+powerpc-fix-incorrect-stw-ux-u-x-instructions-in-__set_pte_at.patch
+powerpc-rtas-fix-typo-of-ibm-open-errinjct-in-rtas-filter.patch
+powerpc-feature-add-cpu_ftr_noexecute-to-g2_le.patch
+powerpc-xmon-change-printk-to-pr_cont.patch
+powerpc-8xx-fix-early-debug-when-smc1-is-relocated.patch
+powerpc-mm-fix-verification-of-mmu_ftr_type_44x.patch
+powerpc-powernv-npu-do-not-attempt-npu2-setup-on-power8nvl-npu.patch
+powerpc-powernv-memtrace-don-t-leak-kernel-memory-to-user-space.patch
+powerpc-powernv-memtrace-fix-crashing-the-kernel-when-enabling-concurrently.patch
+ima-don-t-modify-file-descriptor-mode-on-the-fly.patch
+um-remove-use-of-asprinf-in-umid.c.patch
+ceph-fix-race-in-concurrent-__ceph_remove_cap-invocations.patch
+smb3-avoid-confusing-warning-message-on-mount-to-azure.patch
+ubifs-wbuf-don-t-leak-kernel-memory-to-flash.patch
+jffs2-fix-gc-exit-abnormally.patch
+jffs2-fix-ignoring-mounting-options-problem-during-remounting.patch
--- /dev/null
+From ebcd6de98754d9b6a5f89d7835864b1c365d432f Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Tue, 8 Dec 2020 21:13:31 -0600
+Subject: SMB3: avoid confusing warning message on mount to Azure
+
+From: Steve French <stfrench@microsoft.com>
+
+commit ebcd6de98754d9b6a5f89d7835864b1c365d432f upstream.
+
+Mounts to Azure cause an unneeded warning message in dmesg
+ "CIFS: VFS: parse_server_interfaces: incomplete interface info"
+
+Azure rounds up the size (by 8 additional bytes, to a
+16 byte boundary) of the structure returned on the query
+of the server interfaces at mount time. This is permissible
+even though different than other servers so do not log a warning
+if query network interfaces response is only rounded up by 8
+bytes or fewer.
+
+CC: Stable <stable@vger.kernel.org>
+Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -478,7 +478,8 @@ parse_server_interfaces(struct network_i
+ goto out;
+ }
+
+- if (bytes_left || p->Next)
++ /* Azure rounds the buffer size up 8, to a 16 byte boundary */
++ if ((bytes_left > 8) || p->Next)
+ cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
+
+
--- /dev/null
+From 20f1431160c6b590cdc269a846fc5a448abf5b98 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Mon, 16 Nov 2020 22:05:30 +0100
+Subject: ubifs: wbuf: Don't leak kernel memory to flash
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 20f1431160c6b590cdc269a846fc5a448abf5b98 upstream.
+
+Write buffers use a kmalloc()'ed buffer, they can leak
+up to seven bytes of kernel memory to flash if writes are not
+aligned.
+So use ubifs_pad() to fill these gaps with padding bytes.
+This was never a problem while scanning because the scanner logic
+manually aligns node lengths and skips over these gaps.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 1e51764a3c2ac05a2 ("UBIFS: add new flash file system")
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ubifs/io.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/fs/ubifs/io.c
++++ b/fs/ubifs/io.c
+@@ -319,7 +319,7 @@ void ubifs_pad(const struct ubifs_info *
+ {
+ uint32_t crc;
+
+- ubifs_assert(c, pad >= 0 && !(pad & 7));
++ ubifs_assert(c, pad >= 0);
+
+ if (pad >= UBIFS_PAD_NODE_SZ) {
+ struct ubifs_ch *ch = buf;
+@@ -764,6 +764,10 @@ int ubifs_wbuf_write_nolock(struct ubifs
+ * write-buffer.
+ */
+ memcpy(wbuf->buf + wbuf->used, buf, len);
++ if (aligned_len > len) {
++ ubifs_assert(c, aligned_len - len < 8);
++ ubifs_pad(c, wbuf->buf + wbuf->used + len, aligned_len - len);
++ }
+
+ if (aligned_len == wbuf->avail) {
+ dbg_io("flush jhead %s wbuf to LEB %d:%d",
+@@ -856,13 +860,18 @@ int ubifs_wbuf_write_nolock(struct ubifs
+ }
+
+ spin_lock(&wbuf->lock);
+- if (aligned_len)
++ if (aligned_len) {
+ /*
+ * And now we have what's left and what does not take whole
+ * max. write unit, so write it to the write-buffer and we are
+ * done.
+ */
+ memcpy(wbuf->buf, buf + written, len);
++ if (aligned_len > len) {
++ ubifs_assert(c, aligned_len - len < 8);
++ ubifs_pad(c, wbuf->buf + len, aligned_len - len);
++ }
++ }
+
+ if (c->leb_size - wbuf->offs >= c->max_write_size)
+ wbuf->size = c->max_write_size;
--- /dev/null
+From 97be7ceaf7fea68104824b6aa874cff235333ac1 Mon Sep 17 00:00:00 2001
+From: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Date: Fri, 13 Nov 2020 10:26:17 +0000
+Subject: um: Remove use of asprinf in umid.c
+
+From: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+
+commit 97be7ceaf7fea68104824b6aa874cff235333ac1 upstream.
+
+asprintf is not compatible with the existing uml memory allocation
+mechanism. Its use on the "user" side of UML results in a corrupt slab
+state.
+
+Fixes: 0d4e5ac7e780 ("um: remove uses of variable length arrays")
+Cc: stable@vger.kernel.org
+Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/um/os-Linux/umid.c | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+--- a/arch/um/os-Linux/umid.c
++++ b/arch/um/os-Linux/umid.c
+@@ -137,20 +137,13 @@ static inline int is_umdir_used(char *di
+ {
+ char pid[sizeof("nnnnn\0")], *end, *file;
+ int dead, fd, p, n, err;
+- size_t filelen;
++ size_t filelen = strlen(dir) + sizeof("/pid") + 1;
+
+- err = asprintf(&file, "%s/pid", dir);
+- if (err < 0)
+- return 0;
++ file = malloc(filelen);
++ if (!file)
++ return -ENOMEM;
+
+- filelen = strlen(file);
+-
+- n = snprintf(file, filelen, "%s/pid", dir);
+- if (n >= filelen) {
+- printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
+- err = -E2BIG;
+- goto out;
+- }
++ snprintf(file, filelen, "%s/pid", dir);
+
+ dead = 0;
+ fd = open(file, O_RDONLY);
--- /dev/null
+From 15261b9126cd5bb2ad8521da49d8f5c042d904c7 Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Tue, 8 Dec 2020 18:29:02 -0500
+Subject: xprtrdma: Fix XDRBUF_SPARSE_PAGES support
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit 15261b9126cd5bb2ad8521da49d8f5c042d904c7 upstream.
+
+Olga K. observed that rpcrdma_marsh_req() allocates sparse pages
+only when it has determined that a Reply chunk is necessary. There
+are plenty of cases where no Reply chunk is needed, but the
+XDRBUF_SPARSE_PAGES flag is set. The result would be a crash in
+rpcrdma_inline_fixup() when it tries to copy parts of the received
+Reply into a missing page.
+
+To avoid crashing, handle sparse page allocation up front.
+
+Until XATTR support was added, this issue did not appear often
+because the only SPARSE_PAGES consumer always expected a reply large
+enough to always require a Reply chunk.
+
+Reported-by: Olga Kornievskaia <kolga@netapp.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xprtrdma/rpc_rdma.c | 40 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 31 insertions(+), 9 deletions(-)
+
+--- a/net/sunrpc/xprtrdma/rpc_rdma.c
++++ b/net/sunrpc/xprtrdma/rpc_rdma.c
+@@ -183,6 +183,31 @@ rpcrdma_nonpayload_inline(const struct r
+ r_xprt->rx_ep.rep_max_inline_recv;
+ }
+
++/* ACL likes to be lazy in allocating pages. For TCP, these
++ * pages can be allocated during receive processing. Not true
++ * for RDMA, which must always provision receive buffers
++ * up front.
++ */
++static noinline int
++rpcrdma_alloc_sparse_pages(struct xdr_buf *buf)
++{
++ struct page **ppages;
++ int len;
++
++ len = buf->page_len;
++ ppages = buf->pages + (buf->page_base >> PAGE_SHIFT);
++ while (len > 0) {
++ if (!*ppages)
++ *ppages = alloc_page(GFP_NOWAIT | __GFP_NOWARN);
++ if (!*ppages)
++ return -ENOBUFS;
++ ppages++;
++ len -= PAGE_SIZE;
++ }
++
++ return 0;
++}
++
+ /* Split @vec on page boundaries into SGEs. FMR registers pages, not
+ * a byte range. Other modes coalesce these SGEs into a single MR
+ * when they can.
+@@ -237,15 +262,6 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt
+ ppages = xdrbuf->pages + (xdrbuf->page_base >> PAGE_SHIFT);
+ page_base = offset_in_page(xdrbuf->page_base);
+ while (len) {
+- /* ACL likes to be lazy in allocating pages - ACLs
+- * are small by default but can get huge.
+- */
+- if (unlikely(xdrbuf->flags & XDRBUF_SPARSE_PAGES)) {
+- if (!*ppages)
+- *ppages = alloc_page(GFP_NOWAIT | __GFP_NOWARN);
+- if (!*ppages)
+- return -ENOBUFS;
+- }
+ seg->mr_page = *ppages;
+ seg->mr_offset = (char *)page_base;
+ seg->mr_len = min_t(u32, PAGE_SIZE - page_base, len);
+@@ -800,6 +816,12 @@ rpcrdma_marshal_req(struct rpcrdma_xprt
+ __be32 *p;
+ int ret;
+
++ if (unlikely(rqst->rq_rcv_buf.flags & XDRBUF_SPARSE_PAGES)) {
++ ret = rpcrdma_alloc_sparse_pages(&rqst->rq_rcv_buf);
++ if (ret)
++ return ret;
++ }
++
+ rpcrdma_set_xdrlen(&req->rl_hdrbuf, 0);
+ xdr_init_encode(xdr, &req->rl_hdrbuf, rdmab_data(req->rl_rdmabuf),
+ rqst);