--- /dev/null
+From 238f1cdf61f9fb4633d5be47be3582fa82088ad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 13:23:31 +0100
+Subject: accel/ivpu/37xx: Fix interrupt_clear_with_0 WA initialization
+
+From: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
+
+[ Upstream commit 35c49cfc8b702eda7a0d3f05497b16f81b69e289 ]
+
+Using PCI Device ID/Revision to initialize the interrupt_clear_with_0
+workaround is problematic - there are many pre-production
+steppings with different behavior, even with the same PCI ID/Revision
+
+Instead of checking for PCI Device ID/Revision, check the VPU
+buttress interrupt status register behavior - if this register
+is not zero after writing 1s it means there register is RW
+instead of RW1C and we need to enable the interrupt_clear_with_0
+workaround.
+
+Fixes: 7f34e01f77f8 ("accel/ivpu: Clear specific interrupt status bits on C0")
+Signed-off-by: Andrzej Kacprowski <Andrzej.Kacprowski@intel.com>
+Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://lore.kernel.org/all/20231204122331.40560-1-jacek.lawrynowicz@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_hw_37xx.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/accel/ivpu/ivpu_hw_37xx.c b/drivers/accel/ivpu/ivpu_hw_37xx.c
+index 2409ff0dda619..ddf03498fd4c1 100644
+--- a/drivers/accel/ivpu/ivpu_hw_37xx.c
++++ b/drivers/accel/ivpu/ivpu_hw_37xx.c
+@@ -53,10 +53,12 @@
+
+ #define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK)
+
+-#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \
+- (REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
++#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
+ (REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, UFI_ERR)))
+
++#define BUTTRESS_ALL_IRQ_MASK (BUTTRESS_IRQ_MASK | \
++ (REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)))
++
+ #define BUTTRESS_IRQ_ENABLE_MASK ((u32)~BUTTRESS_IRQ_MASK)
+ #define BUTTRESS_IRQ_DISABLE_MASK ((u32)-1)
+
+@@ -102,8 +104,12 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
+ vdev->wa.clear_runtime_mem = false;
+ vdev->wa.d3hot_after_power_off = true;
+
+- if (ivpu_device_id(vdev) == PCI_DEVICE_ID_MTL && ivpu_revision(vdev) < 4)
++ REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, BUTTRESS_ALL_IRQ_MASK);
++ if (REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) == BUTTRESS_ALL_IRQ_MASK) {
++ /* Writing 1s does not clear the interrupt status register */
+ vdev->wa.interrupt_clear_with_0 = true;
++ REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, 0x0);
++ }
+
+ IVPU_PRINT_WA(punit_disabled);
+ IVPU_PRINT_WA(clear_runtime_mem);
+--
+2.43.0
+
--- /dev/null
+From 456c8fddc6e6381a47683c8b79007d79a2f2066e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Sep 2023 11:49:51 +0200
+Subject: accel/ivpu: Print information about used workarounds
+
+From: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
+
+[ Upstream commit eefa13a69053a09f20b2d1c00dda59be9c98cfe9 ]
+
+Use ivpu_dbg(MISC) to print information about workarounds.
+
+Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230901094957.168898-6-stanislaw.gruszka@linux.intel.com
+Stable-dep-of: 35c49cfc8b70 ("accel/ivpu/37xx: Fix interrupt_clear_with_0 WA initialization")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/accel/ivpu/ivpu_drv.h | 5 +++++
+ drivers/accel/ivpu/ivpu_hw_37xx.c | 5 +++++
+ drivers/accel/ivpu/ivpu_hw_40xx.c | 4 ++++
+ 3 files changed, 14 insertions(+)
+
+diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h
+index 2adc349126bb6..6853dfe1c7e58 100644
+--- a/drivers/accel/ivpu/ivpu_drv.h
++++ b/drivers/accel/ivpu/ivpu_drv.h
+@@ -76,6 +76,11 @@
+
+ #define IVPU_WA(wa_name) (vdev->wa.wa_name)
+
++#define IVPU_PRINT_WA(wa_name) do { \
++ if (IVPU_WA(wa_name)) \
++ ivpu_dbg(vdev, MISC, "Using WA: " #wa_name "\n"); \
++} while (0)
++
+ struct ivpu_wa_table {
+ bool punit_disabled;
+ bool clear_runtime_mem;
+diff --git a/drivers/accel/ivpu/ivpu_hw_37xx.c b/drivers/accel/ivpu/ivpu_hw_37xx.c
+index b8010c07eec17..2409ff0dda619 100644
+--- a/drivers/accel/ivpu/ivpu_hw_37xx.c
++++ b/drivers/accel/ivpu/ivpu_hw_37xx.c
+@@ -104,6 +104,11 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
+
+ if (ivpu_device_id(vdev) == PCI_DEVICE_ID_MTL && ivpu_revision(vdev) < 4)
+ vdev->wa.interrupt_clear_with_0 = true;
++
++ IVPU_PRINT_WA(punit_disabled);
++ IVPU_PRINT_WA(clear_runtime_mem);
++ IVPU_PRINT_WA(d3hot_after_power_off);
++ IVPU_PRINT_WA(interrupt_clear_with_0);
+ }
+
+ static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
+diff --git a/drivers/accel/ivpu/ivpu_hw_40xx.c b/drivers/accel/ivpu/ivpu_hw_40xx.c
+index 7c3ff25232a2c..03600a7a5aca8 100644
+--- a/drivers/accel/ivpu/ivpu_hw_40xx.c
++++ b/drivers/accel/ivpu/ivpu_hw_40xx.c
+@@ -125,6 +125,10 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
+
+ if (ivpu_hw_gen(vdev) == IVPU_HW_40XX)
+ vdev->wa.disable_clock_relinquish = true;
++
++ IVPU_PRINT_WA(punit_disabled);
++ IVPU_PRINT_WA(clear_runtime_mem);
++ IVPU_PRINT_WA(disable_clock_relinquish);
+ }
+
+ static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
+--
+2.43.0
+
--- /dev/null
+From e933bea28d7c6b0563f8bf8cd82e38a147016dd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Nov 2023 14:32:34 +0900
+Subject: arm64: add dependency between vmlinuz.efi and Image
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit c0a8574204054effad6ac83cc75c02576e2985fe ]
+
+A common issue in Makefile is a race in parallel building.
+
+You need to be careful to prevent multiple threads from writing to the
+same file simultaneously.
+
+Commit 3939f3345050 ("ARM: 8418/1: add boot image dependencies to not
+generate invalid images") addressed such a bad scenario.
+
+A similar symptom occurs with the following command:
+
+ $ make -j$(nproc) ARCH=arm64 Image vmlinuz.efi
+ [ snip ]
+ SORTTAB vmlinux
+ OBJCOPY arch/arm64/boot/Image
+ OBJCOPY arch/arm64/boot/Image
+ AS arch/arm64/boot/zboot-header.o
+ PAD arch/arm64/boot/vmlinux.bin
+ GZIP arch/arm64/boot/vmlinuz
+ OBJCOPY arch/arm64/boot/vmlinuz.o
+ LD arch/arm64/boot/vmlinuz.efi.elf
+ OBJCOPY arch/arm64/boot/vmlinuz.efi
+
+The log "OBJCOPY arch/arm64/boot/Image" is displayed twice.
+
+It indicates that two threads simultaneously enter arch/arm64/boot/
+and write to arch/arm64/boot/Image.
+
+It occasionally leads to a build failure:
+
+ $ make -j$(nproc) ARCH=arm64 Image vmlinuz.efi
+ [ snip ]
+ SORTTAB vmlinux
+ OBJCOPY arch/arm64/boot/Image
+ PAD arch/arm64/boot/vmlinux.bin
+ truncate: Invalid number: 'arch/arm64/boot/vmlinux.bin'
+ make[2]: *** [drivers/firmware/efi/libstub/Makefile.zboot:13:
+ arch/arm64/boot/vmlinux.bin] Error 1
+ make[2]: *** Deleting file 'arch/arm64/boot/vmlinux.bin'
+ make[1]: *** [arch/arm64/Makefile:163: vmlinuz.efi] Error 2
+ make[1]: *** Waiting for unfinished jobs....
+ make: *** [Makefile:234: __sub-make] Error 2
+
+vmlinuz.efi depends on Image, but such a dependency is not specified
+in arch/arm64/Makefile.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: SImon Glass <sjg@chromium.org>
+Link: https://lore.kernel.org/r/20231119053234.2367621-1-masahiroy@kernel.org
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
+index 2d49aea0ff67a..26b8c7630a214 100644
+--- a/arch/arm64/Makefile
++++ b/arch/arm64/Makefile
+@@ -158,7 +158,7 @@ endif
+
+ all: $(notdir $(KBUILD_IMAGE))
+
+-
++vmlinuz.efi: Image
+ Image vmlinuz.efi: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+--
+2.43.0
+
--- /dev/null
+From 314416cbe16fc1cfbe5fc87711aea4b069c34ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Nov 2023 22:22:13 -0800
+Subject: asm-generic: qspinlock: fix queued_spin_value_unlocked()
+ implementation
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 125b0bb95dd6bec81b806b997a4ccb026eeecf8f ]
+
+We really don't want to do atomic_read() or anything like that, since we
+already have the value, not the lock. The whole point of this is that
+we've loaded the lock from memory, and we want to check whether the
+value we loaded was a locked one or not.
+
+The main use of this is the lockref code, which loads both the lock and
+the reference count in one atomic operation, and then works on that
+combined value. With the atomic_read(), the compiler would pointlessly
+spill the value to the stack, in order to then be able to read it back
+"atomically".
+
+This is the qspinlock version of commit c6f4a9002252 ("asm-generic:
+ticket-lock: Optimize arch_spin_value_unlocked()") which fixed this same
+bug for ticket locks.
+
+Cc: Guo Ren <guoren@kernel.org>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Waiman Long <longman@redhat.com>
+Link: https://lore.kernel.org/all/CAHk-=whNRv0v6kQiV5QO6DJhjH4KEL36vWQ6Re8Csrnh4zbRkQ@mail.gmail.com/
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/asm-generic/qspinlock.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
+index 995513fa26904..0655aa5b57b29 100644
+--- a/include/asm-generic/qspinlock.h
++++ b/include/asm-generic/qspinlock.h
+@@ -70,7 +70,7 @@ static __always_inline int queued_spin_is_locked(struct qspinlock *lock)
+ */
+ static __always_inline int queued_spin_value_unlocked(struct qspinlock lock)
+ {
+- return !atomic_read(&lock.val);
++ return !lock.val.counter;
+ }
+
+ /**
+--
+2.43.0
+
--- /dev/null
+From 7043cfa1dbb180f518603c87c92673789b5413d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:25:02 +0800
+Subject: bcache: add code comments for bch_btree_node_get() and
+ __bch_btree_node_alloc()
+
+From: Coly Li <colyli@suse.de>
+
+[ Upstream commit 31f5b956a197d4ec25c8a07cb3a2ab69d0c0b82f ]
+
+This patch adds code comments to bch_btree_node_get() and
+__bch_btree_node_alloc() that NULL pointer will not be returned and it
+is unnecessary to check NULL pointer by the callers of these routines.
+
+Signed-off-by: Coly Li <colyli@suse.de>
+Link: https://lore.kernel.org/r/20231120052503.6122-10-colyli@suse.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/btree.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
+index 3084c57248f69..b709c2fde782a 100644
+--- a/drivers/md/bcache/btree.c
++++ b/drivers/md/bcache/btree.c
+@@ -995,6 +995,9 @@ static struct btree *mca_alloc(struct cache_set *c, struct btree_op *op,
+ *
+ * The btree node will have either a read or a write lock held, depending on
+ * level and op->lock.
++ *
++ * Note: Only error code or btree pointer will be returned, it is unncessary
++ * for callers to check NULL pointer.
+ */
+ struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op,
+ struct bkey *k, int level, bool write,
+@@ -1106,6 +1109,10 @@ static void btree_node_free(struct btree *b)
+ mutex_unlock(&b->c->bucket_lock);
+ }
+
++/*
++ * Only error code or btree pointer will be returned, it is unncessary for
++ * callers to check NULL pointer.
++ */
+ struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op,
+ int level, bool wait,
+ struct btree *parent)
+--
+2.43.0
+
--- /dev/null
+From 1952acfdb22851fed364abb8e81aa7caebec4455 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:25:03 +0800
+Subject: bcache: avoid NULL checking to c->root in run_cache_set()
+
+From: Coly Li <colyli@suse.de>
+
+[ Upstream commit 3eba5e0b2422aec3c9e79822029599961fdcab97 ]
+
+In run_cache_set() after c->root returned from bch_btree_node_get(), it
+is checked by IS_ERR_OR_NULL(). Indeed it is unncessary to check NULL
+because bch_btree_node_get() will not return NULL pointer to caller.
+
+This patch replaces IS_ERR_OR_NULL() by IS_ERR() for the above reason.
+
+Signed-off-by: Coly Li <colyli@suse.de>
+Link: https://lore.kernel.org/r/20231120052503.6122-11-colyli@suse.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/super.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index 93791e46b1e8f..1e677af385211 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -2017,7 +2017,7 @@ static int run_cache_set(struct cache_set *c)
+ c->root = bch_btree_node_get(c, NULL, k,
+ j->btree_level,
+ true, NULL);
+- if (IS_ERR_OR_NULL(c->root))
++ if (IS_ERR(c->root))
+ goto err;
+
+ list_del_init(&c->root->list);
+--
+2.43.0
+
--- /dev/null
+From 9d4d2855eb45b49d9a37e49d06202d80d50e5aa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:24:54 +0800
+Subject: bcache: avoid oversize memory allocation by small stripe_size
+
+From: Coly Li <colyli@suse.de>
+
+[ Upstream commit baf8fb7e0e5ec54ea0839f0c534f2cdcd79bea9c ]
+
+Arraies bcache->stripe_sectors_dirty and bcache->full_dirty_stripes are
+used for dirty data writeback, their sizes are decided by backing device
+capacity and stripe size. Larger backing device capacity or smaller
+stripe size make these two arraies occupies more dynamic memory space.
+
+Currently bcache->stripe_size is directly inherited from
+queue->limits.io_opt of underlying storage device. For normal hard
+drives, its limits.io_opt is 0, and bcache sets the corresponding
+stripe_size to 1TB (1<<31 sectors), it works fine 10+ years. But for
+devices do declare value for queue->limits.io_opt, small stripe_size
+(comparing to 1TB) becomes an issue for oversize memory allocations of
+bcache->stripe_sectors_dirty and bcache->full_dirty_stripes, while the
+capacity of hard drives gets much larger in recent decade.
+
+For example a raid5 array assembled by three 20TB hardrives, the raid
+device capacity is 40TB with typical 512KB limits.io_opt. After the math
+calculation in bcache code, these two arraies will occupy 400MB dynamic
+memory. Even worse Andrea Tomassetti reports that a 4KB limits.io_opt is
+declared on a new 2TB hard drive, then these two arraies request 2GB and
+512MB dynamic memory from kzalloc(). The result is that bcache device
+always fails to initialize on his system.
+
+To avoid the oversize memory allocation, bcache->stripe_size should not
+directly inherited by queue->limits.io_opt from the underlying device.
+This patch defines BCH_MIN_STRIPE_SZ (4MB) as minimal bcache stripe size
+and set bcache device's stripe size against the declared limits.io_opt
+value from the underlying storage device,
+- If the declared limits.io_opt > BCH_MIN_STRIPE_SZ, bcache device will
+ set its stripe size directly by this limits.io_opt value.
+- If the declared limits.io_opt < BCH_MIN_STRIPE_SZ, bcache device will
+ set its stripe size by a value multiplying limits.io_opt and euqal or
+ large than BCH_MIN_STRIPE_SZ.
+
+Then the minimal stripe size of a bcache device will always be >= 4MB.
+For a 40TB raid5 device with 512KB limits.io_opt, memory occupied by
+bcache->stripe_sectors_dirty and bcache->full_dirty_stripes will be 50MB
+in total. For a 2TB hard drive with 4KB limits.io_opt, memory occupied
+by these two arraies will be 2.5MB in total.
+
+Such mount of memory allocated for bcache->stripe_sectors_dirty and
+bcache->full_dirty_stripes is reasonable for most of storage devices.
+
+Reported-by: Andrea Tomassetti <andrea.tomassetti-opensource@devo.com>
+Signed-off-by: Coly Li <colyli@suse.de>
+Reviewed-by: Eric Wheeler <bcache@lists.ewheeler.net>
+Link: https://lore.kernel.org/r/20231120052503.6122-2-colyli@suse.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/bcache.h | 1 +
+ drivers/md/bcache/super.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
+index 5a79bb3c272f1..83eb7f27db3d4 100644
+--- a/drivers/md/bcache/bcache.h
++++ b/drivers/md/bcache/bcache.h
+@@ -265,6 +265,7 @@ struct bcache_device {
+ #define BCACHE_DEV_WB_RUNNING 3
+ #define BCACHE_DEV_RATE_DW_RUNNING 4
+ int nr_stripes;
++#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT)
+ unsigned int stripe_size;
+ atomic_t *stripe_sectors_dirty;
+ unsigned long *full_dirty_stripes;
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index 0ae2b36762930..93791e46b1e8f 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -905,6 +905,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
+
+ if (!d->stripe_size)
+ d->stripe_size = 1 << 31;
++ else if (d->stripe_size < BCH_MIN_STRIPE_SZ)
++ d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size);
+
+ n = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
+ if (!n || n > max_stripes) {
+--
+2.43.0
+
--- /dev/null
+From 5a66c66cf50e1ec245dd25f9fa82ec0fc5d23e04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:24:56 +0800
+Subject: bcache: remove redundant assignment to variable cur_idx
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+[ Upstream commit be93825f0e6428c2d3f03a6e4d447dc48d33d7ff ]
+
+Variable cur_idx is being initialized with a value that is never read,
+it is being re-assigned later in a while-loop. Remove the redundant
+assignment. Cleans up clang scan build warning:
+
+drivers/md/bcache/writeback.c:916:2: warning: Value stored to 'cur_idx'
+is never read [deadcode.DeadStores]
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Reviewed-by: Coly Li <colyli@suse.de>
+Signed-off-by: Coly Li <colyli@suse.de>
+Link: https://lore.kernel.org/r/20231120052503.6122-4-colyli@suse.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/writeback.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
+index d4432b3a6f96e..3accfdaee6b19 100644
+--- a/drivers/md/bcache/writeback.c
++++ b/drivers/md/bcache/writeback.c
+@@ -913,7 +913,7 @@ static int bch_dirty_init_thread(void *arg)
+ int cur_idx, prev_idx, skip_nr;
+
+ k = p = NULL;
+- cur_idx = prev_idx = 0;
++ prev_idx = 0;
+
+ bch_btree_iter_init(&c->root->keys, &iter, NULL);
+ k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
+--
+2.43.0
+
--- /dev/null
+From 1de3019aea383de1a56c90c6ea360a9339a1ae06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 10:35:24 +0800
+Subject: blk-cgroup: bypass blkcg_deactivate_policy after destroying
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit e63a57303599b17290cd8bc48e6f20b24289a8bc ]
+
+blkcg_deactivate_policy() can be called after blkg_destroy_all()
+returns, and it isn't necessary since blkg_destroy_all has covered
+policy deactivation.
+
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20231117023527.3188627-4-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 4a42ea2972ad8..4b48c2c440981 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -577,6 +577,7 @@ static void blkg_destroy_all(struct gendisk *disk)
+ struct request_queue *q = disk->queue;
+ struct blkcg_gq *blkg, *n;
+ int count = BLKG_DESTROY_BATCH_SIZE;
++ int i;
+
+ restart:
+ spin_lock_irq(&q->queue_lock);
+@@ -602,6 +603,18 @@ static void blkg_destroy_all(struct gendisk *disk)
+ }
+ }
+
++ /*
++ * Mark policy deactivated since policy offline has been done, and
++ * the free is scheduled, so future blkcg_deactivate_policy() can
++ * be bypassed
++ */
++ for (i = 0; i < BLKCG_MAX_POLS; i++) {
++ struct blkcg_policy *pol = blkcg_policy[i];
++
++ if (pol)
++ __clear_bit(pol->plid, q->blkcg_pols);
++ }
++
+ q->root_blkg = NULL;
+ spin_unlock_irq(&q->queue_lock);
+ }
+--
+2.43.0
+
--- /dev/null
+From 6211c6507d37ea69ee7f63814e8122b3867cbb11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 10:35:22 +0800
+Subject: blk-throttle: fix lockdep warning of "cgroup_mutex or RCU read lock
+ required!"
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 27b13e209ddca5979847a1b57890e0372c1edcee ]
+
+Inside blkg_for_each_descendant_pre(), both
+css_for_each_descendant_pre() and blkg_lookup() requires RCU read lock,
+and either cgroup_assert_mutex_or_rcu_locked() or rcu_read_lock_held()
+is called.
+
+Fix the warning by adding rcu read lock.
+
+Reported-by: Changhui Zhong <czhong@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20231117023527.3188627-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-throttle.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 13e4377a8b286..16f5766620a41 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -1320,6 +1320,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global)
+ tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE),
+ tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE));
+
++ rcu_read_lock();
+ /*
+ * Update has_rules[] flags for the updated tg's subtree. A tg is
+ * considered to have rules if either the tg itself or any of its
+@@ -1347,6 +1348,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global)
+ this_tg->latency_target = max(this_tg->latency_target,
+ parent_tg->latency_target);
+ }
++ rcu_read_unlock();
+
+ /*
+ * We're already holding queue_lock and know @tg is valid. Let's
+--
+2.43.0
+
--- /dev/null
+From 0694552af78fef53fc167798f7906b6d1bcd48f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 12:21:08 +0000
+Subject: drm/i915/selftests: Fix engine reset count storage for multi-tile
+
+From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+
+[ Upstream commit 7c7c863bf89c5f76d8c7fda177a81559b61dc15b ]
+
+Engine->id namespace is per-tile so struct igt_live_test->reset_engine[]
+needs to be two-dimensional so engine reset counts from all tiles can be
+stored with no aliasing. With aliasing, if we had a real multi-tile
+platform, the reset counts would be incorrect for same engine instance on
+different tiles.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Fixes: 0c29efa23f5c ("drm/i915/selftests: Consider multi-gt instead of to_gt()")
+Reported-by: Alan Previn Teres Alexis <alan.previn.teres.alexis@intel.com>
+Cc: Tejas Upadhyay <tejas.upadhyay@intel.com>
+Cc: Andi Shyti <andi.shyti@linux.intel.com>
+Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231201122109.729006-1-tvrtko.ursulin@linux.intel.com
+(cherry picked from commit 0647ece3819b018cb62a71c3bcb7c2c3243e78ac)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/selftests/igt_live_test.c | 9 +++++----
+ drivers/gpu/drm/i915/selftests/igt_live_test.h | 3 ++-
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/selftests/igt_live_test.c b/drivers/gpu/drm/i915/selftests/igt_live_test.c
+index 4ddc6d902752a..7d41874a49c58 100644
+--- a/drivers/gpu/drm/i915/selftests/igt_live_test.c
++++ b/drivers/gpu/drm/i915/selftests/igt_live_test.c
+@@ -37,8 +37,9 @@ int igt_live_test_begin(struct igt_live_test *t,
+ }
+
+ for_each_engine(engine, gt, id)
+- t->reset_engine[id] =
+- i915_reset_engine_count(&i915->gpu_error, engine);
++ t->reset_engine[i][id] =
++ i915_reset_engine_count(&i915->gpu_error,
++ engine);
+ }
+
+ t->reset_global = i915_reset_count(&i915->gpu_error);
+@@ -66,14 +67,14 @@ int igt_live_test_end(struct igt_live_test *t)
+
+ for_each_gt(gt, i915, i) {
+ for_each_engine(engine, gt, id) {
+- if (t->reset_engine[id] ==
++ if (t->reset_engine[i][id] ==
+ i915_reset_engine_count(&i915->gpu_error, engine))
+ continue;
+
+ gt_err(gt, "%s(%s): engine '%s' was reset %d times!\n",
+ t->func, t->name, engine->name,
+ i915_reset_engine_count(&i915->gpu_error, engine) -
+- t->reset_engine[id]);
++ t->reset_engine[i][id]);
+ return -EIO;
+ }
+ }
+diff --git a/drivers/gpu/drm/i915/selftests/igt_live_test.h b/drivers/gpu/drm/i915/selftests/igt_live_test.h
+index 36ed42736c521..83e3ad430922f 100644
+--- a/drivers/gpu/drm/i915/selftests/igt_live_test.h
++++ b/drivers/gpu/drm/i915/selftests/igt_live_test.h
+@@ -7,6 +7,7 @@
+ #ifndef IGT_LIVE_TEST_H
+ #define IGT_LIVE_TEST_H
+
++#include "gt/intel_gt_defines.h" /* for I915_MAX_GT */
+ #include "gt/intel_engine.h" /* for I915_NUM_ENGINES */
+
+ struct drm_i915_private;
+@@ -17,7 +18,7 @@ struct igt_live_test {
+ const char *name;
+
+ unsigned int reset_global;
+- unsigned int reset_engine[I915_NUM_ENGINES];
++ unsigned int reset_engine[I915_MAX_GT][I915_NUM_ENGINES];
+ };
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 3d736118f1053005a0af9226a3de673037a9fe4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 12:21:09 +0000
+Subject: drm/i915: Use internal class when counting engine resets
+
+From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+
+[ Upstream commit 1f721a93a528268fa97875cff515d1fcb69f4f44 ]
+
+Commit 503579448db9 ("drm/i915/gsc: Mark internal GSC engine with reserved uabi class")
+made the GSC0 engine not have a valid uabi class and so broke the engine
+reset counting, which in turn was made class based in cb823ed9915b ("drm/i915/gt: Use intel_gt as the primary object for handling resets").
+
+Despite the title and commit text of the latter is not mentioning it (and
+has left the storage array incorrectly sized), tracking by class, despite
+it adding aliasing in hypthotetical multi-tile systems, is handy for
+virtual engines which for instance do not have a valid engine->id.
+
+Therefore we keep that but just change it to use the internal class which
+is always valid. We also add a helper to increment the count, which
+aligns with the existing getter.
+
+What was broken without this fix were out of bounds reads every time a
+reset would happen on the GSC0 engine, or during selftests when storing
+and cross-checking the counts in igt_live_test_begin and
+igt_live_test_end.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Fixes: 503579448db9 ("drm/i915/gsc: Mark internal GSC engine with reserved uabi class")
+[tursulin: fixed Fixes tag]
+Reported-by: Alan Previn Teres Alexis <alan.previn.teres.alexis@intel.com>
+Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231201122109.729006-2-tvrtko.ursulin@linux.intel.com
+(cherry picked from commit cf9cb028ac56696ff879af1154c4b2f0b12701fd)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_reset.c | 2 +-
+ drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 5 +++--
+ drivers/gpu/drm/i915/i915_gpu_error.h | 12 ++++++++++--
+ 3 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
+index cc6bd21a3e51f..5fa57a34cf4bb 100644
+--- a/drivers/gpu/drm/i915/gt/intel_reset.c
++++ b/drivers/gpu/drm/i915/gt/intel_reset.c
+@@ -1297,7 +1297,7 @@ int __intel_engine_reset_bh(struct intel_engine_cs *engine, const char *msg)
+ if (msg)
+ drm_notice(&engine->i915->drm,
+ "Resetting %s for %s\n", engine->name, msg);
+- atomic_inc(&engine->i915->gpu_error.reset_engine_count[engine->uabi_class]);
++ i915_increase_reset_engine_count(&engine->i915->gpu_error, engine);
+
+ ret = intel_gt_reset_engine(engine);
+ if (ret) {
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index dc7b40e06e38a..836e4d9d65ef6 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -4774,7 +4774,8 @@ static void capture_error_state(struct intel_guc *guc,
+ if (match) {
+ intel_engine_set_hung_context(e, ce);
+ engine_mask |= e->mask;
+- atomic_inc(&i915->gpu_error.reset_engine_count[e->uabi_class]);
++ i915_increase_reset_engine_count(&i915->gpu_error,
++ e);
+ }
+ }
+
+@@ -4786,7 +4787,7 @@ static void capture_error_state(struct intel_guc *guc,
+ } else {
+ intel_engine_set_hung_context(ce->engine, ce);
+ engine_mask = ce->engine->mask;
+- atomic_inc(&i915->gpu_error.reset_engine_count[ce->engine->uabi_class]);
++ i915_increase_reset_engine_count(&i915->gpu_error, ce->engine);
+ }
+
+ with_intel_runtime_pm(&i915->runtime_pm, wakeref)
+diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
+index 9f5971f5e9801..48f6c00402c47 100644
+--- a/drivers/gpu/drm/i915/i915_gpu_error.h
++++ b/drivers/gpu/drm/i915/i915_gpu_error.h
+@@ -16,6 +16,7 @@
+
+ #include "display/intel_display_device.h"
+ #include "gt/intel_engine.h"
++#include "gt/intel_engine_types.h"
+ #include "gt/intel_gt_types.h"
+ #include "gt/uc/intel_uc_fw.h"
+
+@@ -232,7 +233,7 @@ struct i915_gpu_error {
+ atomic_t reset_count;
+
+ /** Number of times an engine has been reset */
+- atomic_t reset_engine_count[I915_NUM_ENGINES];
++ atomic_t reset_engine_count[MAX_ENGINE_CLASS];
+ };
+
+ struct drm_i915_error_state_buf {
+@@ -255,7 +256,14 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
+ static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
+ const struct intel_engine_cs *engine)
+ {
+- return atomic_read(&error->reset_engine_count[engine->uabi_class]);
++ return atomic_read(&error->reset_engine_count[engine->class]);
++}
++
++static inline void
++i915_increase_reset_engine_count(struct i915_gpu_error *error,
++ const struct intel_engine_cs *engine)
++{
++ atomic_inc(&error->reset_engine_count[engine->class]);
+ }
+
+ #define CORE_DUMP_FLAG_NONE 0x0
+--
+2.43.0
+
--- /dev/null
+From 498855466d3e87a7a71aa9e60dd00c444561ab9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Sep 2023 17:06:58 +0800
+Subject: drm/mediatek: Add spinlock for setting vblank event in atomic_begin
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit fe4c5f662097978b6c91c23a13c24ed92339a180 ]
+
+Add spinlock protection to avoid race condition on vblank event
+between mtk_drm_crtc_atomic_begin() and mtk_drm_finish_page_flip().
+
+Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Suggested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: Fei Shao <fshao@chromium.org>
+Tested-by: Fei Shao <fshao@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230920090658.31181-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index 0a511d7688a3a..a033da279a943 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -747,6 +747,7 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+ crtc);
+ struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state);
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
++ unsigned long flags;
+
+ if (mtk_crtc->event && mtk_crtc_state->base.event)
+ DRM_ERROR("new event while there is still a pending event\n");
+@@ -754,7 +755,11 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+ if (mtk_crtc_state->base.event) {
+ mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc);
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
++
++ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ mtk_crtc->event = mtk_crtc_state->base.event;
++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
++
+ mtk_crtc_state->base.event = NULL;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From fac24ec2df957c5e2898d004469ce62a74049fbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Sep 2023 10:49:21 +0200
+Subject: drm/mediatek: fix kernel oops if no crtc is found
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Walle <mwalle@kernel.org>
+
+[ Upstream commit 4662817aed5a9d6c695658d0105d8ff4b84ac6cb ]
+
+drm_crtc_from_index(0) might return NULL if there are no CRTCs
+registered at all which will lead to a kernel oops in
+mtk_drm_crtc_dma_dev_get(). Add the missing return value check.
+
+Fixes: 0d9eee9118b7 ("drm/mediatek: Add drm ovl_adaptor sub driver for MT8195")
+Signed-off-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: NÃcolas F. R. A. Prado <nfraprado@collabora.com>
+Tested-by: NÃcolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Eugen Hristev <eugen.hristev@collabora.com>
+Reviewed-by: Eugen Hristev <eugen.hristev@collabora.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230905084922.3908121-1-mwalle@kernel.org/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+index 2d6a979afe8f9..cdd506c803733 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+@@ -421,6 +421,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
+ struct mtk_drm_private *private = drm->dev_private;
+ struct mtk_drm_private *priv_n;
+ struct device *dma_dev = NULL;
++ struct drm_crtc *crtc;
+ int ret, i, j;
+
+ if (drm_firmware_drivers_only())
+@@ -495,7 +496,9 @@ static int mtk_drm_kms_init(struct drm_device *drm)
+ }
+
+ /* Use OVL device for all DMA memory allocations */
+- dma_dev = mtk_drm_crtc_dma_dev_get(drm_crtc_from_index(drm, 0));
++ crtc = drm_crtc_from_index(drm, 0);
++ if (crtc)
++ dma_dev = mtk_drm_crtc_dma_dev_get(crtc);
+ if (!dma_dev) {
+ ret = -ENODEV;
+ dev_err(drm->dev, "Need at least one OVL device\n");
+--
+2.43.0
+
--- /dev/null
+From 7bc0520e60ef2405caac564f238951a65da84997 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 18:10:06 -0500
+Subject: eventfs: Do not allow NULL parent to eventfs_start_creating()
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit fc4561226feaad5fcdcb55646c348d77b8ee69c5 ]
+
+The eventfs directory is dynamically created via the meta data supplied by
+the existing trace events. All files and directories in eventfs has a
+parent. Do not allow NULL to be passed into eventfs_start_creating() as
+the parent because that should never happen. Warn if it does.
+
+Link: https://lkml.kernel.org/r/20231121231112.693841807@goodmis.org
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/tracefs/inode.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
+index 891653ba9cf35..0292c6a2bed9f 100644
+--- a/fs/tracefs/inode.c
++++ b/fs/tracefs/inode.c
+@@ -509,20 +509,15 @@ struct dentry *eventfs_start_creating(const char *name, struct dentry *parent)
+ struct dentry *dentry;
+ int error;
+
++ /* Must always have a parent. */
++ if (WARN_ON_ONCE(!parent))
++ return ERR_PTR(-EINVAL);
++
+ error = simple_pin_fs(&trace_fs_type, &tracefs_mount,
+ &tracefs_mount_count);
+ if (error)
+ return ERR_PTR(error);
+
+- /*
+- * If the parent is not specified, we create it in the root.
+- * We need the root dentry to do this, which is in the super
+- * block. A pointer to that is in the struct vfsmount that we
+- * have around.
+- */
+- if (!parent)
+- parent = tracefs_mount->mnt_root;
+-
+ if (unlikely(IS_DEADDIR(parent->d_inode)))
+ dentry = ERR_PTR(-ENOENT);
+ else
+--
+2.43.0
+
--- /dev/null
+From fe8850e9922f89fa1cba233f3fb9f72997eb375d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Nov 2023 15:54:30 +0100
+Subject: HID: add ALWAYS_POLL quirk for Apple kb
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit c55092187d9ad7b2f8f5a8645286fa03997d442f ]
+
+These devices disconnect if suspended without remote wakeup. They can operate
+with the standard driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-quirks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 5a48fcaa32f00..ea472923fab07 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
+--
+2.43.0
+
--- /dev/null
+From 3d5407076026c85a228e3f05932ff88dd96d1454 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Oct 2023 01:05:38 +0800
+Subject: HID: apple: add Jamesdonkey and A3R to non-apple keyboards list
+
+From: Yihong Cao <caoyihong4@outlook.com>
+
+[ Upstream commit 113f736655e4f20633e107d731dd5bd097d5938c ]
+
+Jamesdonkey A3R keyboard is identified as "Jamesdonkey A3R" in wired
+mode, "A3R-U" in wireless mode and "A3R" in bluetooth mode. Adding them
+to non-apple keyboards fixes function key.
+
+Signed-off-by: Yihong Cao <caoyihong4@outlook.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-apple.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index 3ca45975c686e..d9e9829b22001 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -345,6 +345,8 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = {
+ { "AONE" },
+ { "GANSS" },
+ { "Hailuck" },
++ { "Jamesdonkey" },
++ { "A3R" },
+ };
+
+ static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
+--
+2.43.0
+
--- /dev/null
+From 83acad209b98f55205e22d3e27e8706aa80626be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Nov 2023 18:10:38 -0700
+Subject: HID: glorious: fix Glorious Model I HID report
+
+From: Brett Raye <braye@fastmail.com>
+
+[ Upstream commit a5e913c25b6b2b6ae02acef6d9400645ac03dfdf ]
+
+The Glorious Model I mouse has a buggy HID report descriptor for its
+keyboard endpoint (used for programmable buttons). For report ID 2, there
+is a mismatch between Logical Minimum and Usage Minimum in the array that
+reports keycodes.
+
+The offending portion of the descriptor: (from hid-decode)
+
+0x95, 0x05, // Report Count (5) 30
+0x75, 0x08, // Report Size (8) 32
+0x15, 0x00, // Logical Minimum (0) 34
+0x25, 0x65, // Logical Maximum (101) 36
+0x05, 0x07, // Usage Page (Keyboard) 38
+0x19, 0x01, // Usage Minimum (1) 40
+0x29, 0x65, // Usage Maximum (101) 42
+0x81, 0x00, // Input (Data,Arr,Abs) 44
+
+This bug shifts all programmed keycodes up by 1. Importantly, this causes
+"empty" array indexes of 0x00 to be interpreted as 0x01, ErrorRollOver.
+The presence of ErrorRollOver causes the system to ignore all keypresses
+from the endpoint and breaks the ability to use the programmable buttons.
+
+Setting byte 41 to 0x00 fixes this, and causes keycodes to be interpreted
+correctly.
+
+Also, USB_VENDOR_ID_GLORIOUS is changed to USB_VENDOR_ID_SINOWEALTH,
+and a new ID for Laview Technology is added. Glorious seems to be
+white-labeling controller boards or mice from these vendors. There isn't a
+single canonical vendor ID for Glorious products.
+
+Signed-off-by: Brett Raye <braye@fastmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-glorious.c | 16 ++++++++++++++--
+ drivers/hid/hid-ids.h | 11 +++++++----
+ 2 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-glorious.c b/drivers/hid/hid-glorious.c
+index 558eb08c19ef9..281b3a7187cec 100644
+--- a/drivers/hid/hid-glorious.c
++++ b/drivers/hid/hid-glorious.c
+@@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice");
+ * Glorious Model O and O- specify the const flag in the consumer input
+ * report descriptor, which leads to inputs being ignored. Fix this
+ * by patching the descriptor.
++ *
++ * Glorious Model I incorrectly specifes the Usage Minimum for its
++ * keyboard HID report, causing keycodes to be misinterpreted.
++ * Fix this by setting Usage Minimum to 0 in that report.
+ */
+ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+@@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ rdesc[85] = rdesc[113] = rdesc[141] = \
+ HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE;
+ }
++ if (*rsize == 156 && rdesc[41] == 1) {
++ hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n");
++ rdesc[41] = 0;
++ }
+ return rdesc;
+ }
+
+@@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev)
+ model = "Model O"; break;
+ case USB_DEVICE_ID_GLORIOUS_MODEL_D:
+ model = "Model D"; break;
++ case USB_DEVICE_ID_GLORIOUS_MODEL_I:
++ model = "Model I"; break;
+ }
+
+ snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model);
+@@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev,
+ }
+
+ static const struct hid_device_id glorious_devices[] = {
+- { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS,
++ { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,
+ USB_DEVICE_ID_GLORIOUS_MODEL_O) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS,
++ { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,
+ USB_DEVICE_ID_GLORIOUS_MODEL_D) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW,
++ USB_DEVICE_ID_GLORIOUS_MODEL_I) },
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, glorious_devices);
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index d10ccfa17e168..c6e4e0d1f2147 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -511,10 +511,6 @@
+ #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
+ #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
+
+-#define USB_VENDOR_ID_GLORIOUS 0x258a
+-#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
+-#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
+-
+ #define I2C_VENDOR_ID_GOODIX 0x27c6
+ #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
+
+@@ -745,6 +741,9 @@
+ #define USB_VENDOR_ID_LABTEC 0x1020
+ #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
+
++#define USB_VENDOR_ID_LAVIEW 0x22D4
++#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503
++
+ #define USB_VENDOR_ID_LCPOWER 0x1241
+ #define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
+
+@@ -1159,6 +1158,10 @@
+ #define USB_VENDOR_ID_SIGMATEL 0x066F
+ #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
+
++#define USB_VENDOR_ID_SINOWEALTH 0x258a
++#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
++#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
++
+ #define USB_VENDOR_ID_SIS_TOUCH 0x0457
+ #define USB_DEVICE_ID_SIS9200_TOUCH 0x9200
+ #define USB_DEVICE_ID_SIS817_TOUCH 0x0817
+--
+2.43.0
+
--- /dev/null
+From 8d7bdf3fa51feb45c4e91faf673afa9b05f6673e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 14:15:55 +1300
+Subject: HID: hid-asus: add const to read-only outgoing usb buffer
+
+From: Denis Benato <benato.denis96@gmail.com>
+
+[ Upstream commit 06ae5afce8cc1f7621cc5c7751e449ce20d68af7 ]
+
+In the function asus_kbd_set_report the parameter buf is read-only
+as it gets copied in a memory portion suitable for USB transfer,
+but the parameter is not marked as const: add the missing const and mark
+const immutable buffers passed to that function.
+
+Signed-off-by: Denis Benato <benato.denis96@gmail.com>
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-asus.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
+index 194a86cf30db4..78cdfb8b9a7ae 100644
+--- a/drivers/hid/hid-asus.c
++++ b/drivers/hid/hid-asus.c
+@@ -381,7 +381,7 @@ static int asus_raw_event(struct hid_device *hdev,
+ return 0;
+ }
+
+-static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size)
++static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size)
+ {
+ unsigned char *dmabuf;
+ int ret;
+@@ -404,7 +404,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size
+
+ static int asus_kbd_init(struct hid_device *hdev)
+ {
+- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
+ 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
+ int ret;
+
+@@ -418,7 +418,7 @@ static int asus_kbd_init(struct hid_device *hdev)
+ static int asus_kbd_get_functions(struct hid_device *hdev,
+ unsigned char *kbd_func)
+ {
+- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
+ u8 *readbuf;
+ int ret;
+
+@@ -449,7 +449,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev,
+
+ static int rog_nkey_led_init(struct hid_device *hdev)
+ {
+- u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
++ const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
+ u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20,
+ 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
+ u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1,
+--
+2.43.0
+
--- /dev/null
+From 2fb5236b732e4a5bd5b38af29ea2c710762b4c8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 14:15:56 +1300
+Subject: HID: hid-asus: reset the backlight brightness level on resume
+
+From: Denis Benato <benato.denis96@gmail.com>
+
+[ Upstream commit 546edbd26cff7ae990e480a59150e801a06f77b1 ]
+
+Some devices managed by this driver automatically set brightness to 0
+before entering a suspended state and reset it back to a default
+brightness level after the resume:
+this has the effect of having the kernel report wrong brightness
+status after a sleep, and on some devices (like the Asus RC71L) that
+brightness is the intensity of LEDs directly facing the user.
+
+Fix the above issue by setting back brightness to the level it had
+before entering a sleep state.
+
+Signed-off-by: Denis Benato <benato.denis96@gmail.com>
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-asus.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
+index fd61dba882338..194a86cf30db4 100644
+--- a/drivers/hid/hid-asus.c
++++ b/drivers/hid/hid-asus.c
+@@ -1000,6 +1000,24 @@ static int asus_start_multitouch(struct hid_device *hdev)
+ return 0;
+ }
+
++static int __maybe_unused asus_resume(struct hid_device *hdev) {
++ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
++ int ret = 0;
++
++ if (drvdata->kbd_backlight) {
++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4,
++ drvdata->kbd_backlight->cdev.brightness };
++ ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
++ if (ret < 0) {
++ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
++ goto asus_resume_err;
++ }
++ }
++
++asus_resume_err:
++ return ret;
++}
++
+ static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
+ {
+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
+@@ -1294,6 +1312,7 @@ static struct hid_driver asus_driver = {
+ .input_configured = asus_input_configured,
+ #ifdef CONFIG_PM
+ .reset_resume = asus_reset_resume,
++ .resume = asus_resume,
+ #endif
+ .event = asus_event,
+ .raw_event = asus_raw_event
+--
+2.43.0
+
--- /dev/null
+From 9106c6a2e872cbddd4499c266e5490cf28a925f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Oct 2023 16:55:11 +1300
+Subject: HID: mcp2221: Allow IO to start during probe
+
+From: Hamish Martin <hamish.martin@alliedtelesis.co.nz>
+
+[ Upstream commit 73ce9f1f2741a38f5d27393e627702ae2c46e6f2 ]
+
+During the probe we add an I2C adapter and as soon as we add that adapter
+it may be used for a transfer (e.g via the code in i2cdetect()).
+Those transfers are not able to complete and time out. This is because the
+HID raw_event callback (mcp2221_raw_event) will not be invoked until the
+HID device's 'driver_input_lock' is marked up at the completion of the
+probe in hid_device_probe(). This starves the driver of the responses it
+is waiting for.
+In order to allow the I2C transfers to complete while we are still in the
+probe, start the IO once we have completed init of the HID device.
+
+This issue seems to have been seen before and a patch was submitted but
+it seems it was never accepted. See:
+https://lore.kernel.org/all/20221103222714.21566-3-Enrik.Berkhan@inka.de/
+
+Signed-off-by: Hamish Martin <hamish.martin@alliedtelesis.co.nz>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-mcp2221.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
+index b95f31cf0fa21..aef0785c91cc2 100644
+--- a/drivers/hid/hid-mcp2221.c
++++ b/drivers/hid/hid-mcp2221.c
+@@ -1142,6 +1142,8 @@ static int mcp2221_probe(struct hid_device *hdev,
+ if (ret)
+ return ret;
+
++ hid_device_io_start(hdev);
++
+ /* Set I2C bus clock diviser */
+ if (i2c_clk_freq > 400)
+ i2c_clk_freq = 400;
+--
+2.43.0
+
--- /dev/null
+From 3a67241bb8087b5d27be690ac7e6cffbfeb6af75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Oct 2023 16:55:10 +1300
+Subject: HID: mcp2221: Set driver data before I2C adapter add
+
+From: Hamish Martin <hamish.martin@alliedtelesis.co.nz>
+
+[ Upstream commit f2d4a5834638bbc967371b9168c0b481519f7c5e ]
+
+The process of adding an I2C adapter can invoke I2C accesses on that new
+adapter (see i2c_detect()).
+
+Ensure we have set the adapter's driver data to avoid null pointer
+dereferences in the xfer functions during the adapter add.
+
+This has been noted in the past and the same fix proposed but not
+completed. See:
+https://lore.kernel.org/lkml/ef597e73-ed71-168e-52af-0d19b03734ac@vigem.de/
+
+Signed-off-by: Hamish Martin <hamish.martin@alliedtelesis.co.nz>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-mcp2221.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
+index 72883e0ce7575..b95f31cf0fa21 100644
+--- a/drivers/hid/hid-mcp2221.c
++++ b/drivers/hid/hid-mcp2221.c
+@@ -1157,12 +1157,12 @@ static int mcp2221_probe(struct hid_device *hdev,
+ snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
+ "MCP2221 usb-i2c bridge");
+
++ i2c_set_adapdata(&mcp->adapter, mcp);
+ ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);
+ if (ret) {
+ hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret);
+ return ret;
+ }
+- i2c_set_adapdata(&mcp->adapter, mcp);
+
+ #if IS_REACHABLE(CONFIG_GPIOLIB)
+ /* Setup GPIO chip */
+--
+2.43.0
+
--- /dev/null
+From da20fb9aac71617cab5034a6effc247f69fe5ebc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 20:23:11 +0800
+Subject: HID: multitouch: Add quirk for HONOR GLO-GXXX touchpad
+
+From: Aoba K <nexp_0x17@outlook.com>
+
+[ Upstream commit 9ffccb691adb854e7b7f3ee57fbbda12ff70533f ]
+
+Honor MagicBook 13 2023 has a touchpad which do not switch to the multitouch
+mode until the input mode feature is written by the host. The touchpad do
+report the input mode at touchpad(3), while itself working under mouse mode. As
+a workaround, it is possible to call MT_QUIRE_FORCE_GET_FEATURE to force set
+feature in mt_set_input_mode for such device.
+
+The touchpad reports as BLTP7853, which cannot retrive any useful manufacture
+information on the internel by this string at present. As the serial number of
+the laptop is GLO-G52, while DMI info reports the laptop serial number as
+GLO-GXXX, this workaround should applied to all models which has the GLO-GXXX.
+
+Signed-off-by: Aoba K <nexp_0x17@outlook.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-multitouch.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 8db4ae05febc8..5ec1f174127a3 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -2048,6 +2048,11 @@ static const struct hid_device_id mt_devices[] = {
+ MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
+ USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
+
++ /* HONOR GLO-GXXX panel */
++ { .driver_data = MT_CLS_VTL,
++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
++ 0x347d, 0x7853) },
++
+ /* Ilitek dual touch panel */
+ { .driver_data = MT_CLS_NSMU,
+ MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
+--
+2.43.0
+
--- /dev/null
+From 6f751880fef5043069a0ae8e833dfcf1d00d5962 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 15:03:25 +0800
+Subject: LoongArch: Add dependency between vmlinuz.efi and vmlinux.efi
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit d3ec75bc635cb0cb8185b63293d33a3d1b942d22 ]
+
+A common issue in Makefile is a race in parallel building.
+
+You need to be careful to prevent multiple threads from writing to the
+same file simultaneously.
+
+Commit 3939f3345050 ("ARM: 8418/1: add boot image dependencies to not
+generate invalid images") addressed such a bad scenario.
+
+A similar symptom occurs with the following command:
+
+ $ make -j$(nproc) ARCH=loongarch vmlinux.efi vmlinuz.efi
+ [ snip ]
+ SORTTAB vmlinux
+ OBJCOPY arch/loongarch/boot/vmlinux.efi
+ OBJCOPY arch/loongarch/boot/vmlinux.efi
+ PAD arch/loongarch/boot/vmlinux.bin
+ GZIP arch/loongarch/boot/vmlinuz
+ OBJCOPY arch/loongarch/boot/vmlinuz.o
+ LD arch/loongarch/boot/vmlinuz.efi.elf
+ OBJCOPY arch/loongarch/boot/vmlinuz.efi
+
+The log "OBJCOPY arch/loongarch/boot/vmlinux.efi" is displayed twice.
+
+It indicates that two threads simultaneously enter arch/loongarch/boot/
+and write to arch/loongarch/boot/vmlinux.efi.
+
+It occasionally leads to a build failure:
+
+ $ make -j$(nproc) ARCH=loongarch vmlinux.efi vmlinuz.efi
+ [ snip ]
+ SORTTAB vmlinux
+ OBJCOPY arch/loongarch/boot/vmlinux.efi
+ PAD arch/loongarch/boot/vmlinux.bin
+ truncate: Invalid number: ‘arch/loongarch/boot/vmlinux.bin’
+ make[2]: *** [drivers/firmware/efi/libstub/Makefile.zboot:13:
+ arch/loongarch/boot/vmlinux.bin] Error 1
+ make[2]: *** Deleting file 'arch/loongarch/boot/vmlinux.bin'
+ make[1]: *** [arch/loongarch/Makefile:146: vmlinuz.efi] Error 2
+ make[1]: *** Waiting for unfinished jobs....
+ make: *** [Makefile:234: __sub-make] Error 2
+
+vmlinuz.efi depends on vmlinux.efi, but such a dependency is not
+specified in arch/loongarch/Makefile.
+
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/Makefile | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
+index fb0fada43197e..96747bfec1a10 100644
+--- a/arch/loongarch/Makefile
++++ b/arch/loongarch/Makefile
+@@ -142,6 +142,8 @@ vdso_install:
+
+ all: $(notdir $(KBUILD_IMAGE))
+
++vmlinuz.efi: vmlinux.efi
++
+ vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@
+
+--
+2.43.0
+
--- /dev/null
+From 17e0ed1640c5a2ada215130d25e51a3d3dd8e1c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 15:03:25 +0800
+Subject: LoongArch: Implement constant timer shutdown interface
+
+From: Bibo Mao <maobibo@loongson.cn>
+
+[ Upstream commit d43f37b73468c172bc89ac4824a1511b411f0778 ]
+
+When a cpu is hot-unplugged, it is put in idle state and the function
+arch_cpu_idle_dead() is called. The timer interrupt for this processor
+should be disabled, otherwise there will be pending timer interrupt for
+the unplugged cpu, so that vcpu is prevented from giving up scheduling
+when system is running in vm mode.
+
+This patch implements the timer shutdown interface so that the constant
+timer will be properly disabled when a CPU is hot-unplugged.
+
+Reviewed-by: WANG Xuerui <git@xen0n.name>
+Signed-off-by: Bibo Mao <maobibo@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/time.c | 23 +++++++++--------------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c
+index 3064af94db9c2..e7015f7b70e37 100644
+--- a/arch/loongarch/kernel/time.c
++++ b/arch/loongarch/kernel/time.c
+@@ -58,14 +58,16 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
+ return 0;
+ }
+
+-static int constant_set_state_oneshot_stopped(struct clock_event_device *evt)
++static int constant_set_state_periodic(struct clock_event_device *evt)
+ {
++ unsigned long period;
+ unsigned long timer_config;
+
+ raw_spin_lock(&state_lock);
+
+- timer_config = csr_read64(LOONGARCH_CSR_TCFG);
+- timer_config &= ~CSR_TCFG_EN;
++ period = const_clock_freq / HZ;
++ timer_config = period & CSR_TCFG_VAL;
++ timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
+ csr_write64(timer_config, LOONGARCH_CSR_TCFG);
+
+ raw_spin_unlock(&state_lock);
+@@ -73,16 +75,14 @@ static int constant_set_state_oneshot_stopped(struct clock_event_device *evt)
+ return 0;
+ }
+
+-static int constant_set_state_periodic(struct clock_event_device *evt)
++static int constant_set_state_shutdown(struct clock_event_device *evt)
+ {
+- unsigned long period;
+ unsigned long timer_config;
+
+ raw_spin_lock(&state_lock);
+
+- period = const_clock_freq / HZ;
+- timer_config = period & CSR_TCFG_VAL;
+- timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
++ timer_config = csr_read64(LOONGARCH_CSR_TCFG);
++ timer_config &= ~CSR_TCFG_EN;
+ csr_write64(timer_config, LOONGARCH_CSR_TCFG);
+
+ raw_spin_unlock(&state_lock);
+@@ -90,11 +90,6 @@ static int constant_set_state_periodic(struct clock_event_device *evt)
+ return 0;
+ }
+
+-static int constant_set_state_shutdown(struct clock_event_device *evt)
+-{
+- return 0;
+-}
+-
+ static int constant_timer_next_event(unsigned long delta, struct clock_event_device *evt)
+ {
+ unsigned long timer_config;
+@@ -161,7 +156,7 @@ int constant_clockevent_init(void)
+ cd->rating = 320;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_state_oneshot = constant_set_state_oneshot;
+- cd->set_state_oneshot_stopped = constant_set_state_oneshot_stopped;
++ cd->set_state_oneshot_stopped = constant_set_state_shutdown;
+ cd->set_state_periodic = constant_set_state_periodic;
+ cd->set_state_shutdown = constant_set_state_shutdown;
+ cd->set_next_event = constant_timer_next_event;
+--
+2.43.0
+
--- /dev/null
+From 597cb1ee5eecfa2f7418f72d700bdc81ff49397d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 15:03:25 +0800
+Subject: LoongArch: Mark {dmw,tlb}_virt_to_page() exports as non-GPL
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+[ Upstream commit 19d86a496233731882aea7ec24505ce6641b1c0c ]
+
+Mark {dmw,tlb}_virt_to_page() exports as non-GPL, in order to let
+out-of-tree modules (e.g. OpenZFS) be built without errors. Otherwise
+we get:
+
+ERROR: modpost: GPL-incompatible module zfs.ko uses GPL-only symbol 'dmw_virt_to_page'
+ERROR: modpost: GPL-incompatible module zfs.ko uses GPL-only symbol 'tlb_virt_to_page'
+
+Reported-by: Haowu Ge <gehaowu@bitmoe.com>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/mm/pgtable.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/loongarch/mm/pgtable.c b/arch/loongarch/mm/pgtable.c
+index 71d0539e2d0b0..2aae72e638713 100644
+--- a/arch/loongarch/mm/pgtable.c
++++ b/arch/loongarch/mm/pgtable.c
+@@ -13,13 +13,13 @@ struct page *dmw_virt_to_page(unsigned long kaddr)
+ {
+ return pfn_to_page(virt_to_pfn(kaddr));
+ }
+-EXPORT_SYMBOL_GPL(dmw_virt_to_page);
++EXPORT_SYMBOL(dmw_virt_to_page);
+
+ struct page *tlb_virt_to_page(unsigned long kaddr)
+ {
+ return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr)));
+ }
+-EXPORT_SYMBOL_GPL(tlb_virt_to_page);
++EXPORT_SYMBOL(tlb_virt_to_page);
+
+ pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+--
+2.43.0
+
--- /dev/null
+From cec6fee8bbb8adc5d599ca8bab1706f28b5f1e55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 15:03:25 +0800
+Subject: LoongArch: Record pc instead of offset in la_abs relocation
+
+From: WANG Rui <wangrui@loongson.cn>
+
+[ Upstream commit aa0cbc1b506b090c3a775b547c693ada108cc0d7 ]
+
+To clarify, the previous version functioned flawlessly. However, it's
+worth noting that the LLVM's LoongArch backend currently lacks support
+for cross-section label calculations. With this patch, we enable the use
+of clang to compile relocatable kernels.
+
+Tested-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: WANG Rui <wangrui@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/include/asm/asmmacro.h | 3 +--
+ arch/loongarch/include/asm/setup.h | 2 +-
+ arch/loongarch/kernel/relocate.c | 2 +-
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/arch/loongarch/include/asm/asmmacro.h b/arch/loongarch/include/asm/asmmacro.h
+index c9544f358c339..655db7d7a4279 100644
+--- a/arch/loongarch/include/asm/asmmacro.h
++++ b/arch/loongarch/include/asm/asmmacro.h
+@@ -609,8 +609,7 @@
+ lu32i.d \reg, 0
+ lu52i.d \reg, \reg, 0
+ .pushsection ".la_abs", "aw", %progbits
+- 768:
+- .dword 768b-766b
++ .dword 766b
+ .dword \sym
+ .popsection
+ #endif
+diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h
+index a0bc159ce8bdc..ee52fb1e99631 100644
+--- a/arch/loongarch/include/asm/setup.h
++++ b/arch/loongarch/include/asm/setup.h
+@@ -25,7 +25,7 @@ extern void set_merr_handler(unsigned long offset, void *addr, unsigned long len
+ #ifdef CONFIG_RELOCATABLE
+
+ struct rela_la_abs {
+- long offset;
++ long pc;
+ long symvalue;
+ };
+
+diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
+index 6c3eff9af9fb1..288b739ca88dd 100644
+--- a/arch/loongarch/kernel/relocate.c
++++ b/arch/loongarch/kernel/relocate.c
+@@ -52,7 +52,7 @@ static inline void __init relocate_absolute(long random_offset)
+ for (p = begin; (void *)p < end; p++) {
+ long v = p->symvalue;
+ uint32_t lu12iw, ori, lu32id, lu52id;
+- union loongarch_instruction *insn = (void *)p - p->offset;
++ union loongarch_instruction *insn = (void *)p->pc;
+
+ lu12iw = (v >> 12) & 0xfffff;
+ ori = v & 0xfff;
+--
+2.43.0
+
--- /dev/null
+From 2d6218f396b4feb6815d00e0bcab09968aa1182b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 15:03:25 +0800
+Subject: LoongArch: Silence the boot warning about 'nokaslr'
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+[ Upstream commit 902d75cdf0cf0a3fb58550089ee519abf12566f5 ]
+
+The kernel parameter 'nokaslr' is handled before start_kernel(), so we
+don't need early_param() to mark it technically. But it can cause a boot
+warning as follows:
+
+Unknown kernel command line parameters "nokaslr", will be passed to user space.
+
+When we use 'init=/bin/bash', 'nokaslr' which passed to user space will
+even cause a kernel panic. So we use early_param() to mark 'nokaslr',
+simply print a notice and silence the boot warning (also fix a potential
+panic). This logic is similar to RISC-V.
+
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/relocate.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
+index 288b739ca88dd..1acfa704c8d09 100644
+--- a/arch/loongarch/kernel/relocate.c
++++ b/arch/loongarch/kernel/relocate.c
+@@ -102,6 +102,14 @@ static inline __init unsigned long get_random_boot(void)
+ return hash;
+ }
+
++static int __init nokaslr(char *p)
++{
++ pr_info("KASLR is disabled.\n");
++
++ return 0; /* Print a notice and silence the boot warning */
++}
++early_param("nokaslr", nokaslr);
++
+ static inline __init bool kaslr_disabled(void)
+ {
+ char *str;
+--
+2.43.0
+
--- /dev/null
+From 2df5b46de95405f5f2eb992aa8e185c493456847 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 00:23:15 +0800
+Subject: nbd: factor out a helper to get nbd_config without holding
+ 'config_lock'
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 3123ac77923341774ca3ad1196ad20bb0732bf70 ]
+
+There are no functional changes, just to make code cleaner and prepare
+to fix null-ptr-dereference while accessing 'nbd->config'.
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Link: https://lore.kernel.org/r/20231116162316.1740402-3-linan666@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 02f844832d912..daaf8805e876c 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -395,6 +395,14 @@ static u32 req_to_nbd_cmd_type(struct request *req)
+ }
+ }
+
++static struct nbd_config *nbd_get_config_unlocked(struct nbd_device *nbd)
++{
++ if (refcount_inc_not_zero(&nbd->config_refs))
++ return nbd->config;
++
++ return NULL;
++}
++
+ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
+ {
+ struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
+@@ -409,13 +417,13 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
+ return BLK_EH_DONE;
+ }
+
+- if (!refcount_inc_not_zero(&nbd->config_refs)) {
++ config = nbd_get_config_unlocked(nbd);
++ if (!config) {
+ cmd->status = BLK_STS_TIMEOUT;
+ __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
+ mutex_unlock(&cmd->lock);
+ goto done;
+ }
+- config = nbd->config;
+
+ if (config->num_connections > 1 ||
+ (config->num_connections == 1 && nbd->tag_set.timeout)) {
+@@ -977,12 +985,12 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
+ struct nbd_sock *nsock;
+ int ret;
+
+- if (!refcount_inc_not_zero(&nbd->config_refs)) {
++ config = nbd_get_config_unlocked(nbd);
++ if (!config) {
+ dev_err_ratelimited(disk_to_dev(nbd->disk),
+ "Socks array is empty\n");
+ return -EINVAL;
+ }
+- config = nbd->config;
+
+ if (index >= config->num_connections) {
+ dev_err_ratelimited(disk_to_dev(nbd->disk),
+@@ -1560,6 +1568,7 @@ static int nbd_alloc_and_init_config(struct nbd_device *nbd)
+ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
+ {
+ struct nbd_device *nbd;
++ struct nbd_config *config;
+ int ret = 0;
+
+ mutex_lock(&nbd_index_mutex);
+@@ -1572,7 +1581,9 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
+ ret = -ENXIO;
+ goto out;
+ }
+- if (!refcount_inc_not_zero(&nbd->config_refs)) {
++
++ config = nbd_get_config_unlocked(nbd);
++ if (!config) {
+ mutex_lock(&nbd->config_lock);
+ if (refcount_inc_not_zero(&nbd->config_refs)) {
+ mutex_unlock(&nbd->config_lock);
+@@ -1588,7 +1599,7 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
+ mutex_unlock(&nbd->config_lock);
+ if (max_part)
+ set_bit(GD_NEED_PART_SCAN, &disk->state);
+- } else if (nbd_disconnected(nbd->config)) {
++ } else if (nbd_disconnected(config)) {
+ if (max_part)
+ set_bit(GD_NEED_PART_SCAN, &disk->state);
+ }
+@@ -2205,7 +2216,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
+ }
+ mutex_unlock(&nbd_index_mutex);
+
+- if (!refcount_inc_not_zero(&nbd->config_refs)) {
++ config = nbd_get_config_unlocked(nbd);
++ if (!config) {
+ dev_err(nbd_to_dev(nbd),
+ "not configured, cannot reconfigure\n");
+ nbd_put(nbd);
+@@ -2213,7 +2225,6 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
+ }
+
+ mutex_lock(&nbd->config_lock);
+- config = nbd->config;
+ if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
+ !nbd->pid) {
+ dev_err(nbd_to_dev(nbd),
+--
+2.43.0
+
--- /dev/null
+From 4db06087adc14fc343ce5e5827fcb70d34fc45a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 00:23:16 +0800
+Subject: nbd: fix null-ptr-dereference while accessing 'nbd->config'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit c2da049f419417808466c529999170f5c3ef7d3d ]
+
+Memory reordering may occur in nbd_genl_connect(), causing config_refs
+to be set to 1 while nbd->config is still empty. Opening nbd at this
+time will cause null-ptr-dereference.
+
+ T1 T2
+ nbd_open
+ nbd_get_config_unlocked
+ nbd_genl_connect
+ nbd_alloc_and_init_config
+ //memory reordered
+ refcount_set(&nbd->config_refs, 1) // 2
+ nbd->config
+ ->null point
+ nbd->config = config // 1
+
+Fix it by adding smp barrier to guarantee the execution sequence.
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Link: https://lore.kernel.org/r/20231116162316.1740402-4-linan666@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index daaf8805e876c..3f03cb3dc33cc 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -397,8 +397,16 @@ static u32 req_to_nbd_cmd_type(struct request *req)
+
+ static struct nbd_config *nbd_get_config_unlocked(struct nbd_device *nbd)
+ {
+- if (refcount_inc_not_zero(&nbd->config_refs))
++ if (refcount_inc_not_zero(&nbd->config_refs)) {
++ /*
++ * Add smp_mb__after_atomic to ensure that reading nbd->config_refs
++ * and reading nbd->config is ordered. The pair is the barrier in
++ * nbd_alloc_and_init_config(), avoid nbd->config_refs is set
++ * before nbd->config.
++ */
++ smp_mb__after_atomic();
+ return nbd->config;
++ }
+
+ return NULL;
+ }
+@@ -1559,7 +1567,15 @@ static int nbd_alloc_and_init_config(struct nbd_device *nbd)
+ init_waitqueue_head(&config->conn_wait);
+ config->blksize_bits = NBD_DEF_BLKSIZE_BITS;
+ atomic_set(&config->live_connections, 0);
++
+ nbd->config = config;
++ /*
++ * Order refcount_set(&nbd->config_refs, 1) and nbd->config assignment,
++ * its pair is the barrier in nbd_get_config_unlocked().
++ * So nbd_get_config_unlocked() won't see nbd->config as null after
++ * refcount_inc_not_zero() succeed.
++ */
++ smp_mb__before_atomic();
+ refcount_set(&nbd->config_refs, 1);
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 41ad27598683afe98520d45f3ed30ccb9301fce8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 00:23:14 +0800
+Subject: nbd: fold nbd config initialization into nbd_alloc_config()
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 1b59860540a4018e8071dc18d4893ec389506b7d ]
+
+There are no functional changes, make the code cleaner and prepare to
+fix null-ptr-dereference while accessing 'nbd->config'.
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Link: https://lore.kernel.org/r/20231116162316.1740402-2-linan666@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 41 +++++++++++++++++++----------------------
+ 1 file changed, 19 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 855fdf5c3b4ea..02f844832d912 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -1530,17 +1530,20 @@ static int nbd_ioctl(struct block_device *bdev, blk_mode_t mode,
+ return error;
+ }
+
+-static struct nbd_config *nbd_alloc_config(void)
++static int nbd_alloc_and_init_config(struct nbd_device *nbd)
+ {
+ struct nbd_config *config;
+
++ if (WARN_ON(nbd->config))
++ return -EINVAL;
++
+ if (!try_module_get(THIS_MODULE))
+- return ERR_PTR(-ENODEV);
++ return -ENODEV;
+
+ config = kzalloc(sizeof(struct nbd_config), GFP_NOFS);
+ if (!config) {
+ module_put(THIS_MODULE);
+- return ERR_PTR(-ENOMEM);
++ return -ENOMEM;
+ }
+
+ atomic_set(&config->recv_threads, 0);
+@@ -1548,7 +1551,10 @@ static struct nbd_config *nbd_alloc_config(void)
+ init_waitqueue_head(&config->conn_wait);
+ config->blksize_bits = NBD_DEF_BLKSIZE_BITS;
+ atomic_set(&config->live_connections, 0);
+- return config;
++ nbd->config = config;
++ refcount_set(&nbd->config_refs, 1);
++
++ return 0;
+ }
+
+ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
+@@ -1567,21 +1573,17 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
+ goto out;
+ }
+ if (!refcount_inc_not_zero(&nbd->config_refs)) {
+- struct nbd_config *config;
+-
+ mutex_lock(&nbd->config_lock);
+ if (refcount_inc_not_zero(&nbd->config_refs)) {
+ mutex_unlock(&nbd->config_lock);
+ goto out;
+ }
+- config = nbd_alloc_config();
+- if (IS_ERR(config)) {
+- ret = PTR_ERR(config);
++ ret = nbd_alloc_and_init_config(nbd);
++ if (ret) {
+ mutex_unlock(&nbd->config_lock);
+ goto out;
+ }
+- nbd->config = config;
+- refcount_set(&nbd->config_refs, 1);
++
+ refcount_inc(&nbd->refs);
+ mutex_unlock(&nbd->config_lock);
+ if (max_part)
+@@ -1990,22 +1992,17 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
+ pr_err("nbd%d already in use\n", index);
+ return -EBUSY;
+ }
+- if (WARN_ON(nbd->config)) {
+- mutex_unlock(&nbd->config_lock);
+- nbd_put(nbd);
+- return -EINVAL;
+- }
+- config = nbd_alloc_config();
+- if (IS_ERR(config)) {
++
++ ret = nbd_alloc_and_init_config(nbd);
++ if (ret) {
+ mutex_unlock(&nbd->config_lock);
+ nbd_put(nbd);
+ pr_err("couldn't allocate config\n");
+- return PTR_ERR(config);
++ return ret;
+ }
+- nbd->config = config;
+- refcount_set(&nbd->config_refs, 1);
+- set_bit(NBD_RT_BOUND, &config->runtime_flags);
+
++ config = nbd->config;
++ set_bit(NBD_RT_BOUND, &config->runtime_flags);
+ ret = nbd_genl_size_set(info, nbd);
+ if (ret)
+ goto out;
+--
+2.43.0
+
--- /dev/null
+From e3966180e55c5b23376f336c11e9659f43782d42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 10:33:08 +0800
+Subject: nbd: pass nbd_sock to nbd_read_reply() instead of index
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 98c598afc22d4e43c2ad91860b65996d0c099a5d ]
+
+If a socket is processing ioctl 'NBD_SET_SOCK', config->socks might be
+krealloc in nbd_add_socket(), and a garbage request is received now, a UAF
+may occurs.
+
+ T1
+ nbd_ioctl
+ __nbd_ioctl
+ nbd_add_socket
+ blk_mq_freeze_queue
+ T2
+ recv_work
+ nbd_read_reply
+ sock_xmit
+ krealloc config->socks
+ def config->socks
+
+Pass nbd_sock to nbd_read_reply(). And introduce a new function
+sock_xmit_recv(), which differs from sock_xmit only in the way it get
+socket.
+
+==================================================================
+BUG: KASAN: use-after-free in sock_xmit+0x525/0x550
+Read of size 8 at addr ffff8880188ec428 by task kworker/u12:1/18779
+
+Workqueue: knbd4-recv recv_work
+Call Trace:
+ __dump_stack
+ dump_stack+0xbe/0xfd
+ print_address_description.constprop.0+0x19/0x170
+ __kasan_report.cold+0x6c/0x84
+ kasan_report+0x3a/0x50
+ sock_xmit+0x525/0x550
+ nbd_read_reply+0xfe/0x2c0
+ recv_work+0x1c2/0x750
+ process_one_work+0x6b6/0xf10
+ worker_thread+0xdd/0xd80
+ kthread+0x30a/0x410
+ ret_from_fork+0x22/0x30
+
+Allocated by task 18784:
+ kasan_save_stack+0x1b/0x40
+ kasan_set_track
+ set_alloc_info
+ __kasan_kmalloc
+ __kasan_kmalloc.constprop.0+0xf0/0x130
+ slab_post_alloc_hook
+ slab_alloc_node
+ slab_alloc
+ __kmalloc_track_caller+0x157/0x550
+ __do_krealloc
+ krealloc+0x37/0xb0
+ nbd_add_socket
+ +0x2d3/0x880
+ __nbd_ioctl
+ nbd_ioctl+0x584/0x8e0
+ __blkdev_driver_ioctl
+ blkdev_ioctl+0x2a0/0x6e0
+ block_ioctl+0xee/0x130
+ vfs_ioctl
+ __do_sys_ioctl
+ __se_sys_ioctl+0x138/0x190
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x61/0xc6
+
+Freed by task 18784:
+ kasan_save_stack+0x1b/0x40
+ kasan_set_track+0x1c/0x30
+ kasan_set_free_info+0x20/0x40
+ __kasan_slab_free.part.0+0x13f/0x1b0
+ slab_free_hook
+ slab_free_freelist_hook
+ slab_free
+ kfree+0xcb/0x6c0
+ krealloc+0x56/0xb0
+ nbd_add_socket+0x2d3/0x880
+ __nbd_ioctl
+ nbd_ioctl+0x584/0x8e0
+ __blkdev_driver_ioctl
+ blkdev_ioctl+0x2a0/0x6e0
+ block_ioctl+0xee/0x130
+ vfs_ioctl
+ __do_sys_ioctl
+ __se_sys_ioctl+0x138/0x190
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x61/0xc6
+
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20230911023308.3467802-1-linan666@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 3f03cb3dc33cc..b6414e1e645b7 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -67,6 +67,7 @@ struct nbd_sock {
+ struct recv_thread_args {
+ struct work_struct work;
+ struct nbd_device *nbd;
++ struct nbd_sock *nsock;
+ int index;
+ };
+
+@@ -505,15 +506,9 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
+ return BLK_EH_DONE;
+ }
+
+-/*
+- * Send or receive packet. Return a positive value on success and
+- * negtive value on failue, and never return 0.
+- */
+-static int sock_xmit(struct nbd_device *nbd, int index, int send,
+- struct iov_iter *iter, int msg_flags, int *sent)
++static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send,
++ struct iov_iter *iter, int msg_flags, int *sent)
+ {
+- struct nbd_config *config = nbd->config;
+- struct socket *sock = config->socks[index]->sock;
+ int result;
+ struct msghdr msg;
+ unsigned int noreclaim_flag;
+@@ -556,6 +551,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
+ return result;
+ }
+
++/*
++ * Send or receive packet. Return a positive value on success and
++ * negtive value on failure, and never return 0.
++ */
++static int sock_xmit(struct nbd_device *nbd, int index, int send,
++ struct iov_iter *iter, int msg_flags, int *sent)
++{
++ struct nbd_config *config = nbd->config;
++ struct socket *sock = config->socks[index]->sock;
++
++ return __sock_xmit(nbd, sock, send, iter, msg_flags, sent);
++}
++
+ /*
+ * Different settings for sk->sk_sndtimeo can result in different return values
+ * if there is a signal pending when we enter sendmsg, because reasons?
+@@ -712,7 +720,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
+ return 0;
+ }
+
+-static int nbd_read_reply(struct nbd_device *nbd, int index,
++static int nbd_read_reply(struct nbd_device *nbd, struct socket *sock,
+ struct nbd_reply *reply)
+ {
+ struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)};
+@@ -721,7 +729,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index,
+
+ reply->magic = 0;
+ iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply));
+- result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL);
++ result = __sock_xmit(nbd, sock, 0, &to, MSG_WAITALL, NULL);
+ if (result < 0) {
+ if (!nbd_disconnected(nbd->config))
+ dev_err(disk_to_dev(nbd->disk),
+@@ -845,14 +853,14 @@ static void recv_work(struct work_struct *work)
+ struct nbd_device *nbd = args->nbd;
+ struct nbd_config *config = nbd->config;
+ struct request_queue *q = nbd->disk->queue;
+- struct nbd_sock *nsock;
++ struct nbd_sock *nsock = args->nsock;
+ struct nbd_cmd *cmd;
+ struct request *rq;
+
+ while (1) {
+ struct nbd_reply reply;
+
+- if (nbd_read_reply(nbd, args->index, &reply))
++ if (nbd_read_reply(nbd, nsock->sock, &reply))
+ break;
+
+ /*
+@@ -887,7 +895,6 @@ static void recv_work(struct work_struct *work)
+ percpu_ref_put(&q->q_usage_counter);
+ }
+
+- nsock = config->socks[args->index];
+ mutex_lock(&nsock->tx_lock);
+ nbd_mark_nsock_dead(nbd, nsock, 1);
+ mutex_unlock(&nsock->tx_lock);
+@@ -1231,6 +1238,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
+ INIT_WORK(&args->work, recv_work);
+ args->index = i;
+ args->nbd = nbd;
++ args->nsock = nsock;
+ nsock->cookie++;
+ mutex_unlock(&nsock->tx_lock);
+ sockfd_put(old);
+@@ -1413,6 +1421,7 @@ static int nbd_start_device(struct nbd_device *nbd)
+ refcount_inc(&nbd->config_refs);
+ INIT_WORK(&args->work, recv_work);
+ args->nbd = nbd;
++ args->nsock = config->socks[i];
+ args->index = i;
+ queue_work(nbd->recv_workq, &args->work);
+ }
+--
+2.43.0
+
--- /dev/null
+From 9e155c226fc891cf3839d66cfafab5caa2df7e8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Nov 2023 00:19:18 +0100
+Subject: net: usb: qmi_wwan: claim interface 4 for ZTE MF290
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lech Perczak <lech.perczak@gmail.com>
+
+[ Upstream commit 99360d9620f09fb8bc15548d855011bbb198c680 ]
+
+Interface 4 is used by for QMI interface in stock firmware of MF28D, the
+router which uses MF290 modem. Rebind it to qmi_wwan after freeing it up
+from option driver.
+The proper configuration is:
+
+Interface mapping is:
+0: QCDM, 1: (unknown), 2: AT (PCUI), 2: AT (Modem), 4: QMI
+
+T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 4 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=19d2 ProdID=0189 Rev= 0.00
+S: Manufacturer=ZTE, Incorporated
+S: Product=ZTE LTE Technologies MSM
+C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
+I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
+I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=2ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
+I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
+E: Ad=86(I) Atr=03(Int.) MxPS= 64 Ivl=2ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
+
+Cc: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
+Link: https://lore.kernel.org/r/20231117231918.100278-3-lech.perczak@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/qmi_wwan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 344af3c5c8366..e2e181378f412 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1289,6 +1289,7 @@ static const struct usb_device_id products[] = {
+ {QMI_FIXED_INTF(0x19d2, 0x0168, 4)},
+ {QMI_FIXED_INTF(0x19d2, 0x0176, 3)},
+ {QMI_FIXED_INTF(0x19d2, 0x0178, 3)},
++ {QMI_FIXED_INTF(0x19d2, 0x0189, 4)}, /* ZTE MF290 */
+ {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */
+ {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */
+ {QMI_FIXED_INTF(0x19d2, 0x0200, 1)},
+--
+2.43.0
+
--- /dev/null
+From 098e83c907b3fc6348d20443751e63c3e1fb6935 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 15:53:57 +0800
+Subject: nfc: virtual_ncidev: Add variable to check if ndev is running
+
+From: Nguyen Dinh Phi <phind.uet@gmail.com>
+
+[ Upstream commit 84d2db91f14a32dc856a5972e3f0907089093c7a ]
+
+syzbot reported an memory leak that happens when an skb is add to
+send_buff after virtual nci closed.
+This patch adds a variable to track if the ndev is running before
+handling new skb in send function.
+
+Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
+Reported-by: syzbot+6eb09d75211863f15e3e@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/lkml/00000000000075472b06007df4fb@google.com
+Reviewed-by: Bongsu Jeon
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nfc/virtual_ncidev.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
+index b027be0b0b6ff..590b038e449e5 100644
+--- a/drivers/nfc/virtual_ncidev.c
++++ b/drivers/nfc/virtual_ncidev.c
+@@ -26,10 +26,14 @@ struct virtual_nci_dev {
+ struct mutex mtx;
+ struct sk_buff *send_buff;
+ struct wait_queue_head wq;
++ bool running;
+ };
+
+ static int virtual_nci_open(struct nci_dev *ndev)
+ {
++ struct virtual_nci_dev *vdev = nci_get_drvdata(ndev);
++
++ vdev->running = true;
+ return 0;
+ }
+
+@@ -40,6 +44,7 @@ static int virtual_nci_close(struct nci_dev *ndev)
+ mutex_lock(&vdev->mtx);
+ kfree_skb(vdev->send_buff);
+ vdev->send_buff = NULL;
++ vdev->running = false;
+ mutex_unlock(&vdev->mtx);
+
+ return 0;
+@@ -50,7 +55,7 @@ static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ struct virtual_nci_dev *vdev = nci_get_drvdata(ndev);
+
+ mutex_lock(&vdev->mtx);
+- if (vdev->send_buff) {
++ if (vdev->send_buff || !vdev->running) {
+ mutex_unlock(&vdev->mtx);
+ kfree_skb(skb);
+ return -1;
+--
+2.43.0
+
--- /dev/null
+From 13bd6672a92669fe2f6b75ac60f68da8fc5b732c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 08:45:12 +0000
+Subject: nvme-auth: set explanation code for failure2 msgs
+
+From: Mark O'Donovan <shiftee@posteo.net>
+
+[ Upstream commit 38ce1570e2c46e7e9af983aa337edd7e43723aa2 ]
+
+Some error cases were not setting an auth-failure-reason-code-explanation.
+This means an AUTH_Failure2 message will be sent with an explanation value
+of 0 which is a reserved value.
+
+Signed-off-by: Mark O'Donovan <shiftee@posteo.net>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/auth.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c
+index cc02a95a50c9a..a31080b7fd7de 100644
+--- a/drivers/nvme/host/auth.c
++++ b/drivers/nvme/host/auth.c
+@@ -839,6 +839,8 @@ static void nvme_queue_auth_work(struct work_struct *work)
+ }
+
+ fail2:
++ if (chap->status == 0)
++ chap->status = NVME_AUTH_DHCHAP_FAILURE_FAILED;
+ dev_dbg(ctrl->device, "%s: qid %d send failure2, status %x\n",
+ __func__, chap->qid, chap->status);
+ tl = nvme_auth_set_dhchap_failure2_data(ctrl, chap);
+--
+2.43.0
+
--- /dev/null
+From 4a83ca57595f9a95efc27c396ecb08f4286bf92e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 08:45:11 +0000
+Subject: nvme-auth: unlock mutex in one place only
+
+From: Mark O'Donovan <shiftee@posteo.net>
+
+[ Upstream commit 616add70bfdc0274a253e84fc78155c27aacde91 ]
+
+Signed-off-by: Mark O'Donovan <shiftee@posteo.net>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/auth.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c
+index 064592a5d546a..cc02a95a50c9a 100644
+--- a/drivers/nvme/host/auth.c
++++ b/drivers/nvme/host/auth.c
+@@ -758,12 +758,11 @@ static void nvme_queue_auth_work(struct work_struct *work)
+ __func__, chap->qid);
+ mutex_lock(&ctrl->dhchap_auth_mutex);
+ ret = nvme_auth_dhchap_setup_host_response(ctrl, chap);
++ mutex_unlock(&ctrl->dhchap_auth_mutex);
+ if (ret) {
+- mutex_unlock(&ctrl->dhchap_auth_mutex);
+ chap->error = ret;
+ goto fail2;
+ }
+- mutex_unlock(&ctrl->dhchap_auth_mutex);
+
+ /* DH-HMAC-CHAP Step 3: send reply */
+ dev_dbg(ctrl->device, "%s: qid %d send reply\n",
+--
+2.43.0
+
--- /dev/null
+From 404e7444a9043c10f3d8cd700b9a37085d5e9b52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Nov 2023 14:27:01 +0100
+Subject: nvme: catch errors from nvme_configure_metadata()
+
+From: Hannes Reinecke <hare@suse.de>
+
+[ Upstream commit cd9aed606088d36a7ffff3e808db4e76b1854285 ]
+
+nvme_configure_metadata() is issuing I/O, so we might incur an I/O
+error which will cause the connection to be reset.
+But in that case any further probing will race with reset and
+cause UAF errors.
+So return a status from nvme_configure_metadata() and abort
+probing if there was an I/O error.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index c09048984a277..d5c8b0a08d494 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1813,16 +1813,18 @@ static int nvme_init_ms(struct nvme_ns *ns, struct nvme_id_ns *id)
+ return ret;
+ }
+
+-static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
++static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+ {
+ struct nvme_ctrl *ctrl = ns->ctrl;
++ int ret;
+
+- if (nvme_init_ms(ns, id))
+- return;
++ ret = nvme_init_ms(ns, id);
++ if (ret)
++ return ret;
+
+ ns->features &= ~(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS);
+ if (!ns->ms || !(ctrl->ops->flags & NVME_F_METADATA_SUPPORTED))
+- return;
++ return 0;
+
+ if (ctrl->ops->flags & NVME_F_FABRICS) {
+ /*
+@@ -1831,7 +1833,7 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+ * remap the separate metadata buffer from the block layer.
+ */
+ if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT)))
+- return;
++ return 0;
+
+ ns->features |= NVME_NS_EXT_LBAS;
+
+@@ -1858,6 +1860,7 @@ static void nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
+ else
+ ns->features |= NVME_NS_METADATA_SUPPORTED;
+ }
++ return 0;
+ }
+
+ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
+@@ -2038,7 +2041,11 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
+ ns->lba_shift = id->lbaf[lbaf].ds;
+ nvme_set_queue_limits(ns->ctrl, ns->queue);
+
+- nvme_configure_metadata(ns, id);
++ ret = nvme_configure_metadata(ns, id);
++ if (ret < 0) {
++ blk_mq_unfreeze_queue(ns->disk->queue);
++ goto out;
++ }
+ nvme_set_chunk_sectors(ns, id);
+ nvme_update_disk_info(ns->disk, ns, id);
+
+--
+2.43.0
+
--- /dev/null
+From 2c2aa20361c3c08b4b4a882f48ef1ddda5b54f5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 17:07:56 +0200
+Subject: platform/x86: intel_telemetry: Fix kernel doc descriptions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit a6584711e64d9d12ab79a450ec3628fd35e4f476 ]
+
+LKP found issues with a kernel doc in the driver:
+
+core.c:116: warning: Function parameter or member 'ioss_evtconfig' not described in 'telemetry_update_events'
+core.c:188: warning: Function parameter or member 'ioss_evtconfig' not described in 'telemetry_get_eventconfig'
+
+It looks like it were copy'n'paste typos when these descriptions
+had been introduced. Fix the typos.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202310070743.WALmRGSY-lkp@intel.com/
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20231120150756.1661425-1-andriy.shevchenko@linux.intel.com
+Reviewed-by: Rajneesh Bhardwaj <irenic.rajneesh@gmail.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel/telemetry/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/platform/x86/intel/telemetry/core.c b/drivers/platform/x86/intel/telemetry/core.c
+index fdf55b5d69480..e4be40f73eebf 100644
+--- a/drivers/platform/x86/intel/telemetry/core.c
++++ b/drivers/platform/x86/intel/telemetry/core.c
+@@ -102,7 +102,7 @@ static const struct telemetry_core_ops telm_defpltops = {
+ /**
+ * telemetry_update_events() - Update telemetry Configuration
+ * @pss_evtconfig: PSS related config. No change if num_evts = 0.
+- * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
++ * @ioss_evtconfig: IOSS related config. No change if num_evts = 0.
+ *
+ * This API updates the IOSS & PSS Telemetry configuration. Old config
+ * is overwritten. Call telemetry_reset_events when logging is over
+@@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(telemetry_reset_events);
+ /**
+ * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
+ * @pss_evtconfig: Pointer to PSS related configuration.
+- * @pss_evtconfig: Pointer to IOSS related configuration.
++ * @ioss_evtconfig: Pointer to IOSS related configuration.
+ * @pss_len: Number of u32 elements allocated for pss_evtconfig array
+ * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array
+ *
+--
+2.43.0
+
--- /dev/null
+From 385e6d9a2ad60a6888ad6ef1019e2472eafe10ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Nov 2023 17:15:40 +0000
+Subject: rxrpc: Fix some minor issues with bundle tracing
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 0c3bd086d12d185650d095a906662593ec607bd0 ]
+
+Fix some superficial issues with the tracing of rxrpc_bundle structs,
+including:
+
+ (1) Set the debug_id when the bundle is allocated rather than when it is
+ set up so that the "NEW" trace line displays the correct bundle ID.
+
+ (2) Show the refcount when emitting the "FREE" traceline.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: "David S. Miller" <davem@davemloft.net>
+cc: Eric Dumazet <edumazet@google.com>
+cc: Jakub Kicinski <kuba@kernel.org>
+cc: Paolo Abeni <pabeni@redhat.com>
+cc: linux-afs@lists.infradead.org
+cc: netdev@vger.kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/conn_client.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
+index 981ca5b98bcb9..1d95f8bc769fa 100644
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -73,6 +73,7 @@ static void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local)
+ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_call *call,
+ gfp_t gfp)
+ {
++ static atomic_t rxrpc_bundle_id;
+ struct rxrpc_bundle *bundle;
+
+ bundle = kzalloc(sizeof(*bundle), gfp);
+@@ -85,6 +86,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_call *call,
+ bundle->upgrade = test_bit(RXRPC_CALL_UPGRADE, &call->flags);
+ bundle->service_id = call->dest_srx.srx_service;
+ bundle->security_level = call->security_level;
++ bundle->debug_id = atomic_inc_return(&rxrpc_bundle_id);
+ refcount_set(&bundle->ref, 1);
+ atomic_set(&bundle->active, 1);
+ INIT_LIST_HEAD(&bundle->waiting_calls);
+@@ -105,7 +107,8 @@ struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle,
+
+ static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
+ {
+- trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_free);
++ trace_rxrpc_bundle(bundle->debug_id, refcount_read(&bundle->ref),
++ rxrpc_bundle_free);
+ rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle);
+ key_put(bundle->key);
+ kfree(bundle);
+@@ -239,7 +242,6 @@ static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn)
+ */
+ int rxrpc_look_up_bundle(struct rxrpc_call *call, gfp_t gfp)
+ {
+- static atomic_t rxrpc_bundle_id;
+ struct rxrpc_bundle *bundle, *candidate;
+ struct rxrpc_local *local = call->local;
+ struct rb_node *p, **pp, *parent;
+@@ -306,7 +308,6 @@ int rxrpc_look_up_bundle(struct rxrpc_call *call, gfp_t gfp)
+ }
+
+ _debug("new bundle");
+- candidate->debug_id = atomic_inc_return(&rxrpc_bundle_id);
+ rb_link_node(&candidate->local_node, parent, pp);
+ rb_insert_color(&candidate->local_node, &local->client_bundles);
+ call->bundle = rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call);
+--
+2.43.0
+
--- /dev/null
+From 6bb2d39d07816d17658c128418eb9046edc42477 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:00:00 +0100
+Subject: scripts/checkstack.pl: match all stack sizes for s390
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit aab1f809d7540def24498e81347740a7239a74d5 ]
+
+For some unknown reason the regular expression for checkstack only matches
+three digit numbers starting with the number "3", or any higher
+number. Which means that it skips any stack sizes smaller than 304
+bytes. This makes the checkstack script a bit less useful than it could be.
+
+Change the script to match any number. To be filtered out stack sizes
+can be configured with the min_stack variable, which omits any stack
+frame sizes smaller than 100 bytes by default.
+
+Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/checkstack.pl | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
+index ac74f8629ceac..f27d552aec43f 100755
+--- a/scripts/checkstack.pl
++++ b/scripts/checkstack.pl
+@@ -97,8 +97,7 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack);
+ # 11160: a7 fb ff 60 aghi %r15,-160
+ # or
+ # 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15)
+- $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})
+- (?:\(\%r15\))?$/ox;
++ $re = qr/.*(?:lay|ag?hi).*\%r15,-([0-9]+)(?:\(\%r15\))?$/o;
+ } elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
+ # f0019d10: 9d e3 bf 90 save %sp, -112, %sp
+ $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
+--
+2.43.0
+
--- /dev/null
+From e3dd967f96b34c2015ff92ba9940fc611a19d56a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 04:06:53 +0200
+Subject: selftests/bpf: fix bpf_loop_bench for new callback verification
+ scheme
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eduard Zingerman <eddyz87@gmail.com>
+
+[ Upstream commit f40bfd1679446b22d321e64a1fa98b7d07d2be08 ]
+
+This is a preparatory change. A follow-up patch "bpf: verify callbacks
+as if they are called unknown number of times" changes logic for
+callbacks handling. While previously callbacks were verified as a
+single function call, new scheme takes into account that callbacks
+could be executed unknown number of times.
+
+This has dire implications for bpf_loop_bench:
+
+ SEC("fentry/" SYS_PREFIX "sys_getpgid")
+ int benchmark(void *ctx)
+ {
+ for (int i = 0; i < 1000; i++) {
+ bpf_loop(nr_loops, empty_callback, NULL, 0);
+ __sync_add_and_fetch(&hits, nr_loops);
+ }
+ return 0;
+ }
+
+W/o callbacks change verifier sees it as a 1000 calls to
+empty_callback(). However, with callbacks change things become
+exponential:
+- i=0: state exploring empty_callback is scheduled with i=0 (a);
+- i=1: state exploring empty_callback is scheduled with i=1;
+ ...
+- i=999: state exploring empty_callback is scheduled with i=999;
+- state (a) is popped from stack;
+- i=1: state exploring empty_callback is scheduled with i=1;
+ ...
+
+Avoid this issue by rewriting outer loop as bpf_loop().
+Unfortunately, this adds a function call to a loop at runtime, which
+negatively affects performance:
+
+ throughput latency
+ before: 149.919 ± 0.168 M ops/s, 6.670 ns/op
+ after : 137.040 ± 0.187 M ops/s, 7.297 ns/op
+
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
+Link: https://lore.kernel.org/r/20231121020701.26440-4-eddyz87@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/progs/bpf_loop_bench.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/progs/bpf_loop_bench.c b/tools/testing/selftests/bpf/progs/bpf_loop_bench.c
+index 4ce76eb064c41..d461746fd3c1e 100644
+--- a/tools/testing/selftests/bpf/progs/bpf_loop_bench.c
++++ b/tools/testing/selftests/bpf/progs/bpf_loop_bench.c
+@@ -15,13 +15,16 @@ static int empty_callback(__u32 index, void *data)
+ return 0;
+ }
+
++static int outer_loop(__u32 index, void *data)
++{
++ bpf_loop(nr_loops, empty_callback, NULL, 0);
++ __sync_add_and_fetch(&hits, nr_loops);
++ return 0;
++}
++
+ SEC("fentry/" SYS_PREFIX "sys_getpgid")
+ int benchmark(void *ctx)
+ {
+- for (int i = 0; i < 1000; i++) {
+- bpf_loop(nr_loops, empty_callback, NULL, 0);
+-
+- __sync_add_and_fetch(&hits, nr_loops);
+- }
++ bpf_loop(1000, outer_loop, NULL, 0);
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From a90c3c7bc1713f0515c3bfa7dc9fbb5ca31fa72b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 11:35:58 +0100
+Subject: selftests/mm: cow: print ksft header before printing anything else
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit a6fcd57cf2df409d35e9225b8dbad6f937b28df0 ]
+
+Doing a ksft_print_msg() before the ksft_print_header() seems to confuse
+the ksft framework in a strange way: running the test on the cmdline
+results in the expected output.
+
+But piping the output somewhere else, results in some odd output,
+whereby we repeatedly get the same info printed:
+ # [INFO] detected THP size: 2048 KiB
+ # [INFO] detected hugetlb page size: 2048 KiB
+ # [INFO] detected hugetlb page size: 1048576 KiB
+ # [INFO] huge zeropage is enabled
+ TAP version 13
+ 1..190
+ # [INFO] Anonymous memory tests in private mappings
+ # [RUN] Basic COW after fork() ... with base page
+ # [INFO] detected THP size: 2048 KiB
+ # [INFO] detected hugetlb page size: 2048 KiB
+ # [INFO] detected hugetlb page size: 1048576 KiB
+ # [INFO] huge zeropage is enabled
+ TAP version 13
+ 1..190
+ # [INFO] Anonymous memory tests in private mappings
+ # [RUN] Basic COW after fork() ... with base page
+ ok 1 No leak from parent into child
+ # [RUN] Basic COW after fork() ... with swapped out base page
+ # [INFO] detected THP size: 2048 KiB
+ # [INFO] detected hugetlb page size: 2048 KiB
+ # [INFO] detected hugetlb page size: 1048576 KiB
+ # [INFO] huge zeropage is enabled
+
+Doing the ksft_print_header() first seems to resolve that and gives us
+the output we expect:
+ TAP version 13
+ # [INFO] detected THP size: 2048 KiB
+ # [INFO] detected hugetlb page size: 2048 KiB
+ # [INFO] detected hugetlb page size: 1048576 KiB
+ # [INFO] huge zeropage is enabled
+ 1..190
+ # [INFO] Anonymous memory tests in private mappings
+ # [RUN] Basic COW after fork() ... with base page
+ ok 1 No leak from parent into child
+ # [RUN] Basic COW after fork() ... with swapped out base page
+ ok 2 No leak from parent into child
+ # [RUN] Basic COW after fork() ... with THP
+ ok 3 No leak from parent into child
+ # [RUN] Basic COW after fork() ... with swapped-out THP
+ ok 4 No leak from parent into child
+ # [RUN] Basic COW after fork() ... with PTE-mapped THP
+ ok 5 No leak from parent into child
+
+Link: https://lkml.kernel.org/r/20231206103558.38040-1-david@redhat.com
+Fixes: f4b5fd6946e2 ("selftests/vm: anon_cow: THP tests")
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reported-by: Nico Pache <npache@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/mm/cow.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
+index 7324ce5363c0c..6f2f839904416 100644
+--- a/tools/testing/selftests/mm/cow.c
++++ b/tools/testing/selftests/mm/cow.c
+@@ -1680,6 +1680,8 @@ int main(int argc, char **argv)
+ {
+ int err;
+
++ ksft_print_header();
++
+ pagesize = getpagesize();
+ thpsize = read_pmd_pagesize();
+ if (thpsize)
+@@ -1689,7 +1691,6 @@ int main(int argc, char **argv)
+ ARRAY_SIZE(hugetlbsizes));
+ detect_huge_zeropage();
+
+- ksft_print_header();
+ ksft_set_plan(ARRAY_SIZE(anon_test_cases) * tests_per_anon_test_case() +
+ ARRAY_SIZE(anon_thp_test_cases) * tests_per_anon_thp_test_case() +
+ ARRAY_SIZE(non_anon_test_cases) * tests_per_non_anon_test_case());
+--
+2.43.0
+
net-stmmac-handle-disabled-mdio-busses-from-devicetr.patch
appletalk-fix-use-after-free-in-atalk_ioctl.patch
net-atlantic-fix-double-free-in-ring-reinit-logic.patch
+drm-mediatek-fix-kernel-oops-if-no-crtc-is-found.patch
+drm-mediatek-add-spinlock-for-setting-vblank-event-i.patch
+accel-ivpu-print-information-about-used-workarounds.patch
+accel-ivpu-37xx-fix-interrupt_clear_with_0-wa-initia.patch
+drm-i915-selftests-fix-engine-reset-count-storage-fo.patch
+drm-i915-use-internal-class-when-counting-engine-res.patch
+selftests-mm-cow-print-ksft-header-before-printing-a.patch
+x86-hyperv-fix-the-detection-of-e820_type_pram-in-a-.patch
+usb-aqc111-check-packet-for-fixup-for-true-limit.patch
+stmmac-dwmac-loongson-add-architecture-dependency.patch
+rxrpc-fix-some-minor-issues-with-bundle-tracing.patch
+blk-throttle-fix-lockdep-warning-of-cgroup_mutex-or-.patch
+blk-cgroup-bypass-blkcg_deactivate_policy-after-dest.patch
+bcache-avoid-oversize-memory-allocation-by-small-str.patch
+bcache-remove-redundant-assignment-to-variable-cur_i.patch
+bcache-add-code-comments-for-bch_btree_node_get-and-.patch
+bcache-avoid-null-checking-to-c-root-in-run_cache_se.patch
+nbd-fold-nbd-config-initialization-into-nbd_alloc_co.patch
+nbd-factor-out-a-helper-to-get-nbd_config-without-ho.patch
+nbd-fix-null-ptr-dereference-while-accessing-nbd-con.patch
+nvme-auth-unlock-mutex-in-one-place-only.patch
+nvme-auth-set-explanation-code-for-failure2-msgs.patch
+nvme-catch-errors-from-nvme_configure_metadata.patch
+selftests-bpf-fix-bpf_loop_bench-for-new-callback-ve.patch
+loongarch-add-dependency-between-vmlinuz.efi-and-vml.patch
+loongarch-record-pc-instead-of-offset-in-la_abs-relo.patch
+loongarch-silence-the-boot-warning-about-nokaslr.patch
+loongarch-mark-dmw-tlb-_virt_to_page-exports-as-non-.patch
+loongarch-implement-constant-timer-shutdown-interfac.patch
+platform-x86-intel_telemetry-fix-kernel-doc-descript.patch
+hid-mcp2221-set-driver-data-before-i2c-adapter-add.patch
+hid-mcp2221-allow-io-to-start-during-probe.patch
+hid-apple-add-jamesdonkey-and-a3r-to-non-apple-keybo.patch
+hid-glorious-fix-glorious-model-i-hid-report.patch
+hid-add-always_poll-quirk-for-apple-kb.patch
+nbd-pass-nbd_sock-to-nbd_read_reply-instead-of-index.patch
+hid-hid-asus-reset-the-backlight-brightness-level-on.patch
+hid-multitouch-add-quirk-for-honor-glo-gxxx-touchpad.patch
+nfc-virtual_ncidev-add-variable-to-check-if-ndev-is-.patch
+scripts-checkstack.pl-match-all-stack-sizes-for-s390.patch
+asm-generic-qspinlock-fix-queued_spin_value_unlocked.patch
+eventfs-do-not-allow-null-parent-to-eventfs_start_cr.patch
+net-usb-qmi_wwan-claim-interface-4-for-zte-mf290.patch
+smb-client-implement-query_reparse_point-for-smb1.patch
+smb-client-introduce-parse_reparse_point.patch
+smb-client-set-correct-file-type-from-nfs-reparse-po.patch
+arm64-add-dependency-between-vmlinuz.efi-and-image.patch
+hid-hid-asus-add-const-to-read-only-outgoing-usb-buf.patch
--- /dev/null
+From 5154d73ccbb61e30dac53a4a9dabbf946e7f78b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 20:12:52 -0300
+Subject: smb: client: implement ->query_reparse_point() for SMB1
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit ed3e0a149b58ea8cfd10cc4f7cefb39877ff07ac ]
+
+Reparse points are not limited to symlinks, so implement
+->query_reparse_point() in order to handle different file types.
+
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifspdu.h | 2 +-
+ fs/smb/client/cifsproto.h | 9 ++
+ fs/smb/client/cifssmb.c | 193 +++++++++++++++-----------------------
+ fs/smb/client/smb1ops.c | 49 ++--------
+ fs/smb/client/smb2ops.c | 35 ++++---
+ 5 files changed, 113 insertions(+), 175 deletions(-)
+
+diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
+index a75220db5c1e1..2a90134331a48 100644
+--- a/fs/smb/client/cifspdu.h
++++ b/fs/smb/client/cifspdu.h
+@@ -1356,7 +1356,7 @@ typedef struct smb_com_transaction_ioctl_rsp {
+ __le32 DataDisplacement;
+ __u8 SetupCount; /* 1 */
+ __le16 ReturnedDataLen;
+- __u16 ByteCount;
++ __le16 ByteCount;
+ } __attribute__((packed)) TRANSACT_IOCTL_RSP;
+
+ #define CIFS_ACL_OWNER 1
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index 8e53abcfc5ec4..dc2c43dd6a910 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -457,6 +457,12 @@ extern int CIFSSMBUnixQuerySymLink(const unsigned int xid,
+ struct cifs_tcon *tcon,
+ const unsigned char *searchName, char **syminfo,
+ const struct nls_table *nls_codepage, int remap);
++extern int cifs_query_reparse_point(const unsigned int xid,
++ struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb,
++ const char *full_path,
++ u32 *tag, struct kvec *rsp,
++ int *rsp_buftype);
+ extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
+ __u16 fid, char **symlinkinfo,
+ const struct nls_table *nls_codepage);
+@@ -656,6 +662,9 @@ void cifs_put_tcp_super(struct super_block *sb);
+ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix);
+ char *extract_hostname(const char *unc);
+ char *extract_sharename(const char *unc);
++int parse_reparse_point(struct reparse_data_buffer *buf,
++ u32 plen, struct cifs_sb_info *cifs_sb,
++ bool unicode, char **target_path);
+
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
+diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
+index 25503f1a4fd21..bad91ba6c3a9c 100644
+--- a/fs/smb/client/cifssmb.c
++++ b/fs/smb/client/cifssmb.c
+@@ -2690,136 +2690,97 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
+ return rc;
+ }
+
+-/*
+- * Recent Windows versions now create symlinks more frequently
+- * and they use the "reparse point" mechanism below. We can of course
+- * do symlinks nicely to Samba and other servers which support the
+- * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
+- * "MF" symlinks optionally, but for recent Windows we really need to
+- * reenable the code below and fix the cifs_symlink callers to handle this.
+- * In the interim this code has been moved to its own config option so
+- * it is not compiled in by default until callers fixed up and more tested.
+- */
+-int
+-CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
+- __u16 fid, char **symlinkinfo,
+- const struct nls_table *nls_codepage)
++int cifs_query_reparse_point(const unsigned int xid,
++ struct cifs_tcon *tcon,
++ struct cifs_sb_info *cifs_sb,
++ const char *full_path,
++ u32 *tag, struct kvec *rsp,
++ int *rsp_buftype)
+ {
+- int rc = 0;
+- int bytes_returned;
+- struct smb_com_transaction_ioctl_req *pSMB;
+- struct smb_com_transaction_ioctl_rsp *pSMBr;
+- bool is_unicode;
+- unsigned int sub_len;
+- char *sub_start;
+- struct reparse_symlink_data *reparse_buf;
+- struct reparse_posix_data *posix_buf;
++ struct cifs_open_parms oparms;
++ TRANSACT_IOCTL_REQ *io_req = NULL;
++ TRANSACT_IOCTL_RSP *io_rsp = NULL;
++ struct cifs_fid fid;
+ __u32 data_offset, data_count;
+- char *end_of_smb;
++ __u8 *start, *end;
++ int io_rsp_len;
++ int oplock = 0;
++ int rc;
+
+- cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid);
+- rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
+- (void **) &pSMBr);
++ cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
++
++ if (cap_unix(tcon->ses))
++ return -EOPNOTSUPP;
++
++ oparms = (struct cifs_open_parms) {
++ .tcon = tcon,
++ .cifs_sb = cifs_sb,
++ .desired_access = FILE_READ_ATTRIBUTES,
++ .create_options = cifs_create_options(cifs_sb,
++ OPEN_REPARSE_POINT),
++ .disposition = FILE_OPEN,
++ .path = full_path,
++ .fid = &fid,
++ };
++
++ rc = CIFS_open(xid, &oparms, &oplock, NULL);
+ if (rc)
+ return rc;
+
+- pSMB->TotalParameterCount = 0 ;
+- pSMB->TotalDataCount = 0;
+- pSMB->MaxParameterCount = cpu_to_le32(2);
+- /* BB find exact data count max from sess structure BB */
+- pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
+- pSMB->MaxSetupCount = 4;
+- pSMB->Reserved = 0;
+- pSMB->ParameterOffset = 0;
+- pSMB->DataCount = 0;
+- pSMB->DataOffset = 0;
+- pSMB->SetupCount = 4;
+- pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
+- pSMB->ParameterCount = pSMB->TotalParameterCount;
+- pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
+- pSMB->IsFsctl = 1; /* FSCTL */
+- pSMB->IsRootFlag = 0;
+- pSMB->Fid = fid; /* file handle always le */
+- pSMB->ByteCount = 0;
++ rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
++ (void **)&io_req, (void **)&io_rsp);
++ if (rc)
++ goto error;
+
+- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+- if (rc) {
+- cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc);
+- goto qreparse_out;
+- }
++ io_req->TotalParameterCount = 0;
++ io_req->TotalDataCount = 0;
++ io_req->MaxParameterCount = cpu_to_le32(2);
++ /* BB find exact data count max from sess structure BB */
++ io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
++ io_req->MaxSetupCount = 4;
++ io_req->Reserved = 0;
++ io_req->ParameterOffset = 0;
++ io_req->DataCount = 0;
++ io_req->DataOffset = 0;
++ io_req->SetupCount = 4;
++ io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
++ io_req->ParameterCount = io_req->TotalParameterCount;
++ io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
++ io_req->IsFsctl = 1;
++ io_req->IsRootFlag = 0;
++ io_req->Fid = fid.netfid;
++ io_req->ByteCount = 0;
++
++ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
++ (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
++ if (rc)
++ goto error;
+
+- data_offset = le32_to_cpu(pSMBr->DataOffset);
+- data_count = le32_to_cpu(pSMBr->DataCount);
+- if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
+- /* BB also check enough total bytes returned */
+- rc = -EIO; /* bad smb */
+- goto qreparse_out;
+- }
+- if (!data_count || (data_count > 2048)) {
++ data_offset = le32_to_cpu(io_rsp->DataOffset);
++ data_count = le32_to_cpu(io_rsp->DataCount);
++ if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
++ !data_count || data_count > 2048) {
+ rc = -EIO;
+- cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n");
+- goto qreparse_out;
+- }
+- end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
+- reparse_buf = (struct reparse_symlink_data *)
+- ((char *)&pSMBr->hdr.Protocol + data_offset);
+- if ((char *)reparse_buf >= end_of_smb) {
+- rc = -EIO;
+- goto qreparse_out;
+- }
+- if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) {
+- cifs_dbg(FYI, "NFS style reparse tag\n");
+- posix_buf = (struct reparse_posix_data *)reparse_buf;
+-
+- if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) {
+- cifs_dbg(FYI, "unsupported file type 0x%llx\n",
+- le64_to_cpu(posix_buf->InodeType));
+- rc = -EOPNOTSUPP;
+- goto qreparse_out;
+- }
+- is_unicode = true;
+- sub_len = le16_to_cpu(reparse_buf->ReparseDataLength);
+- if (posix_buf->PathBuffer + sub_len > end_of_smb) {
+- cifs_dbg(FYI, "reparse buf beyond SMB\n");
+- rc = -EIO;
+- goto qreparse_out;
+- }
+- *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer,
+- sub_len, is_unicode, nls_codepage);
+- goto qreparse_out;
+- } else if (reparse_buf->ReparseTag !=
+- cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) {
+- rc = -EOPNOTSUPP;
+- goto qreparse_out;
++ goto error;
+ }
+
+- /* Reparse tag is NTFS symlink */
+- sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) +
+- reparse_buf->PathBuffer;
+- sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength);
+- if (sub_start + sub_len > end_of_smb) {
+- cifs_dbg(FYI, "reparse buf beyond SMB\n");
++ end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
++ start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
++ if (start >= end) {
+ rc = -EIO;
+- goto qreparse_out;
++ goto error;
+ }
+- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
+- is_unicode = true;
+- else
+- is_unicode = false;
+-
+- /* BB FIXME investigate remapping reserved chars here */
+- *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode,
+- nls_codepage);
+- if (!*symlinkinfo)
+- rc = -ENOMEM;
+-qreparse_out:
+- cifs_buf_release(pSMB);
+
+- /*
+- * Note: On -EAGAIN error only caller can retry on handle based calls
+- * since file handle passed in no longer valid.
+- */
++ *tag = le32_to_cpu(((struct reparse_data_buffer *)start)->ReparseTag);
++ rsp->iov_base = io_rsp;
++ rsp->iov_len = io_rsp_len;
++ *rsp_buftype = CIFS_LARGE_BUFFER;
++ CIFSSMBClose(xid, tcon, fid.netfid);
++ return 0;
++
++error:
++ cifs_buf_release(io_req);
++ CIFSSMBClose(xid, tcon, fid.netfid);
+ return rc;
+ }
+
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index 9bf8735cdd1e8..6b4d8effa79df 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -979,18 +979,13 @@ static int cifs_query_symlink(const unsigned int xid,
+ char **target_path,
+ struct kvec *rsp_iov)
+ {
++ struct reparse_data_buffer *buf;
++ TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
++ bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
++ u32 plen = le16_to_cpu(io->ByteCount);
+ int rc;
+- int oplock = 0;
+- bool is_reparse_point = !!rsp_iov;
+- struct cifs_fid fid;
+- struct cifs_open_parms oparms;
+
+- cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
+-
+- if (is_reparse_point) {
+- cifs_dbg(VFS, "reparse points not handled for SMB1 symlinks\n");
+- return -EOPNOTSUPP;
+- }
++ cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
+
+ /* Check for unix extensions */
+ if (cap_unix(tcon->ses)) {
+@@ -1001,37 +996,12 @@ static int cifs_query_symlink(const unsigned int xid,
+ rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
+ target_path,
+ cifs_sb->local_nls);
+-
+- goto out;
++ return rc;
+ }
+
+- oparms = (struct cifs_open_parms) {
+- .tcon = tcon,
+- .cifs_sb = cifs_sb,
+- .desired_access = FILE_READ_ATTRIBUTES,
+- .create_options = cifs_create_options(cifs_sb,
+- OPEN_REPARSE_POINT),
+- .disposition = FILE_OPEN,
+- .path = full_path,
+- .fid = &fid,
+- };
+-
+- rc = CIFS_open(xid, &oparms, &oplock, NULL);
+- if (rc)
+- goto out;
+-
+- rc = CIFSSMBQuerySymLink(xid, tcon, fid.netfid, target_path,
+- cifs_sb->local_nls);
+- if (rc)
+- goto out_close;
+-
+- convert_delimiter(*target_path, '/');
+-out_close:
+- CIFSSMBClose(xid, tcon, fid.netfid);
+-out:
+- if (!rc)
+- cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
+- return rc;
++ buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +
++ le32_to_cpu(io->DataOffset));
++ return parse_reparse_point(buf, plen, cifs_sb, unicode, target_path);
+ }
+
+ static bool
+@@ -1214,6 +1184,7 @@ struct smb_version_operations smb1_operations = {
+ .is_path_accessible = cifs_is_path_accessible,
+ .can_echo = cifs_can_echo,
+ .query_path_info = cifs_query_path_info,
++ .query_reparse_point = cifs_query_reparse_point,
+ .query_file_info = cifs_query_file_info,
+ .get_srv_inum = cifs_get_srv_inum,
+ .set_path_size = CIFSSMBSetEOF,
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 386b62d5c1332..f1966ab9941cb 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -2894,27 +2894,26 @@ parse_reparse_posix(struct reparse_posix_data *symlink_buf,
+ return 0;
+ }
+
+-static int
+-parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf,
+- u32 plen, char **target_path,
+- struct cifs_sb_info *cifs_sb)
++static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym,
++ u32 plen, bool unicode, char **target_path,
++ struct cifs_sb_info *cifs_sb)
+ {
+ unsigned int sub_len;
+ unsigned int sub_offset;
+
+ /* We handle Symbolic Link reparse tag here. See: MS-FSCC 2.1.2.4 */
+
+- sub_offset = le16_to_cpu(symlink_buf->SubstituteNameOffset);
+- sub_len = le16_to_cpu(symlink_buf->SubstituteNameLength);
++ sub_offset = le16_to_cpu(sym->SubstituteNameOffset);
++ sub_len = le16_to_cpu(sym->SubstituteNameLength);
+ if (sub_offset + 20 > plen ||
+ sub_offset + sub_len + 20 > plen) {
+ cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
+ return -EIO;
+ }
+
+- *target_path = cifs_strndup_from_utf16(
+- symlink_buf->PathBuffer + sub_offset,
+- sub_len, true, cifs_sb->local_nls);
++ *target_path = cifs_strndup_from_utf16(sym->PathBuffer + sub_offset,
++ sub_len, unicode,
++ cifs_sb->local_nls);
+ if (!(*target_path))
+ return -ENOMEM;
+
+@@ -2924,19 +2923,17 @@ parse_reparse_symlink(struct reparse_symlink_data_buffer *symlink_buf,
+ return 0;
+ }
+
+-static int
+-parse_reparse_point(struct reparse_data_buffer *buf,
+- u32 plen, char **target_path,
+- struct cifs_sb_info *cifs_sb)
++int parse_reparse_point(struct reparse_data_buffer *buf,
++ u32 plen, struct cifs_sb_info *cifs_sb,
++ bool unicode, char **target_path)
+ {
+- if (plen < sizeof(struct reparse_data_buffer)) {
++ if (plen < sizeof(*buf)) {
+ cifs_dbg(VFS, "reparse buffer is too small. Must be at least 8 bytes but was %d\n",
+ plen);
+ return -EIO;
+ }
+
+- if (plen < le16_to_cpu(buf->ReparseDataLength) +
+- sizeof(struct reparse_data_buffer)) {
++ if (plen < le16_to_cpu(buf->ReparseDataLength) + sizeof(*buf)) {
+ cifs_dbg(VFS, "srv returned invalid reparse buf length: %d\n",
+ plen);
+ return -EIO;
+@@ -2951,7 +2948,7 @@ parse_reparse_point(struct reparse_data_buffer *buf,
+ case IO_REPARSE_TAG_SYMLINK:
+ return parse_reparse_symlink(
+ (struct reparse_symlink_data_buffer *)buf,
+- plen, target_path, cifs_sb);
++ plen, unicode, target_path, cifs_sb);
+ default:
+ cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n",
+ le32_to_cpu(buf->ReparseTag));
+@@ -2970,11 +2967,11 @@ static int smb2_query_symlink(const unsigned int xid,
+ struct smb2_ioctl_rsp *io = rsp_iov->iov_base;
+ u32 plen = le32_to_cpu(io->OutputCount);
+
+- cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
++ cifs_tcon_dbg(FYI, "%s: path: %s\n", __func__, full_path);
+
+ buf = (struct reparse_data_buffer *)((u8 *)io +
+ le32_to_cpu(io->OutputOffset));
+- return parse_reparse_point(buf, plen, target_path, cifs_sb);
++ return parse_reparse_point(buf, plen, cifs_sb, true, target_path);
+ }
+
+ static int smb2_query_reparse_point(const unsigned int xid,
+--
+2.43.0
+
--- /dev/null
+From 8f44657743f49bb357beab8496eb9e14cacf804e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 20:12:53 -0300
+Subject: smb: client: introduce ->parse_reparse_point()
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 539aad7f14dab7f947e5ab81901c0b20513a50db ]
+
+Parse reparse point into cifs_open_info_data structure and feed it
+through cifs_open_info_to_fattr().
+
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 6 ++++--
+ fs/smb/client/inode.c | 23 +++++++++++++---------
+ fs/smb/client/smb1ops.c | 41 ++++++++++++++++++++++------------------
+ fs/smb/client/smb2ops.c | 28 ++++++++++++++-------------
+ 4 files changed, 56 insertions(+), 42 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index b8d1c19f67714..7180b5713bea6 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -395,8 +395,7 @@ struct smb_version_operations {
+ struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb,
+ const char *full_path,
+- char **target_path,
+- struct kvec *rsp_iov);
++ char **target_path);
+ /* open a file for non-posix mounts */
+ int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
+ void *buf);
+@@ -551,6 +550,9 @@ struct smb_version_operations {
+ bool (*is_status_io_timeout)(char *buf);
+ /* Check for STATUS_NETWORK_NAME_DELETED */
+ bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv);
++ int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb,
++ struct kvec *rsp_iov,
++ struct cifs_open_info_data *data);
+ };
+
+ struct smb_version_values {
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index d6aa5e474d5e7..7a2a013bb05ef 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -457,8 +457,7 @@ static int cifs_get_unix_fattr(const unsigned char *full_path,
+ return -EOPNOTSUPP;
+ rc = server->ops->query_symlink(xid, tcon,
+ cifs_sb, full_path,
+- &fattr->cf_symlink_target,
+- NULL);
++ &fattr->cf_symlink_target);
+ cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc);
+ }
+ return rc;
+@@ -1035,22 +1034,28 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
+ if (!rc)
+ iov = &rsp_iov;
+ }
++
++ rc = -EOPNOTSUPP;
+ switch ((data->reparse_tag = tag)) {
+ case 0: /* SMB1 symlink */
+- iov = NULL;
+- fallthrough;
+- case IO_REPARSE_TAG_NFS:
+- case IO_REPARSE_TAG_SYMLINK:
+- if (!data->symlink_target && server->ops->query_symlink) {
++ if (server->ops->query_symlink) {
+ rc = server->ops->query_symlink(xid, tcon,
+ cifs_sb, full_path,
+- &data->symlink_target,
+- iov);
++ &data->symlink_target);
+ }
+ break;
+ case IO_REPARSE_TAG_MOUNT_POINT:
+ cifs_create_junction_fattr(fattr, sb);
++ rc = 0;
+ goto out;
++ default:
++ if (data->symlink_target) {
++ rc = 0;
++ } else if (server->ops->parse_reparse_point) {
++ rc = server->ops->parse_reparse_point(cifs_sb,
++ iov, data);
++ }
++ break;
+ }
+
+ cifs_open_info_to_fattr(fattr, data, sb);
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index 6b4d8effa79df..0dd599004e042 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -976,32 +976,36 @@ static int cifs_query_symlink(const unsigned int xid,
+ struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb,
+ const char *full_path,
+- char **target_path,
+- struct kvec *rsp_iov)
++ char **target_path)
+ {
+- struct reparse_data_buffer *buf;
+- TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
+- bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
+- u32 plen = le16_to_cpu(io->ByteCount);
+ int rc;
+
+ cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
+
+- /* Check for unix extensions */
+- if (cap_unix(tcon->ses)) {
+- rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
+- cifs_sb->local_nls,
+- cifs_remap(cifs_sb));
+- if (rc == -EREMOTE)
+- rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
+- target_path,
+- cifs_sb->local_nls);
+- return rc;
+- }
++ if (!cap_unix(tcon->ses))
++ return -EOPNOTSUPP;
++
++ rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
++ cifs_sb->local_nls, cifs_remap(cifs_sb));
++ if (rc == -EREMOTE)
++ rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
++ target_path, cifs_sb->local_nls);
++ return rc;
++}
++
++static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb,
++ struct kvec *rsp_iov,
++ struct cifs_open_info_data *data)
++{
++ struct reparse_data_buffer *buf;
++ TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
++ bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
++ u32 plen = le16_to_cpu(io->ByteCount);
+
+ buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +
+ le32_to_cpu(io->DataOffset));
+- return parse_reparse_point(buf, plen, cifs_sb, unicode, target_path);
++ return parse_reparse_point(buf, plen, cifs_sb, unicode,
++ &data->symlink_target);
+ }
+
+ static bool
+@@ -1200,6 +1204,7 @@ struct smb_version_operations smb1_operations = {
+ .rename = CIFSSMBRename,
+ .create_hardlink = CIFSCreateHardLink,
+ .query_symlink = cifs_query_symlink,
++ .parse_reparse_point = cifs_parse_reparse_point,
+ .open = cifs_open_file,
+ .set_fid = cifs_set_fid,
+ .close = cifs_close_file,
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index f1966ab9941cb..0390d7a801d18 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -2949,6 +2949,12 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
+ return parse_reparse_symlink(
+ (struct reparse_symlink_data_buffer *)buf,
+ plen, unicode, target_path, cifs_sb);
++ case IO_REPARSE_TAG_LX_SYMLINK:
++ case IO_REPARSE_TAG_AF_UNIX:
++ case IO_REPARSE_TAG_LX_FIFO:
++ case IO_REPARSE_TAG_LX_CHR:
++ case IO_REPARSE_TAG_LX_BLK:
++ return 0;
+ default:
+ cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n",
+ le32_to_cpu(buf->ReparseTag));
+@@ -2956,22 +2962,18 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
+ }
+ }
+
+-static int smb2_query_symlink(const unsigned int xid,
+- struct cifs_tcon *tcon,
+- struct cifs_sb_info *cifs_sb,
+- const char *full_path,
+- char **target_path,
+- struct kvec *rsp_iov)
++static int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
++ struct kvec *rsp_iov,
++ struct cifs_open_info_data *data)
+ {
+ struct reparse_data_buffer *buf;
+ struct smb2_ioctl_rsp *io = rsp_iov->iov_base;
+ u32 plen = le32_to_cpu(io->OutputCount);
+
+- cifs_tcon_dbg(FYI, "%s: path: %s\n", __func__, full_path);
+-
+ buf = (struct reparse_data_buffer *)((u8 *)io +
+ le32_to_cpu(io->OutputOffset));
+- return parse_reparse_point(buf, plen, cifs_sb, true, target_path);
++ return parse_reparse_point(buf, plen, cifs_sb,
++ true, &data->symlink_target);
+ }
+
+ static int smb2_query_reparse_point(const unsigned int xid,
+@@ -5215,7 +5217,7 @@ struct smb_version_operations smb20_operations = {
+ .unlink = smb2_unlink,
+ .rename = smb2_rename_path,
+ .create_hardlink = smb2_create_hardlink,
+- .query_symlink = smb2_query_symlink,
++ .parse_reparse_point = smb2_parse_reparse_point,
+ .query_mf_symlink = smb3_query_mf_symlink,
+ .create_mf_symlink = smb3_create_mf_symlink,
+ .open = smb2_open_file,
+@@ -5317,7 +5319,7 @@ struct smb_version_operations smb21_operations = {
+ .unlink = smb2_unlink,
+ .rename = smb2_rename_path,
+ .create_hardlink = smb2_create_hardlink,
+- .query_symlink = smb2_query_symlink,
++ .parse_reparse_point = smb2_parse_reparse_point,
+ .query_mf_symlink = smb3_query_mf_symlink,
+ .create_mf_symlink = smb3_create_mf_symlink,
+ .open = smb2_open_file,
+@@ -5422,7 +5424,7 @@ struct smb_version_operations smb30_operations = {
+ .unlink = smb2_unlink,
+ .rename = smb2_rename_path,
+ .create_hardlink = smb2_create_hardlink,
+- .query_symlink = smb2_query_symlink,
++ .parse_reparse_point = smb2_parse_reparse_point,
+ .query_mf_symlink = smb3_query_mf_symlink,
+ .create_mf_symlink = smb3_create_mf_symlink,
+ .open = smb2_open_file,
+@@ -5536,7 +5538,7 @@ struct smb_version_operations smb311_operations = {
+ .unlink = smb2_unlink,
+ .rename = smb2_rename_path,
+ .create_hardlink = smb2_create_hardlink,
+- .query_symlink = smb2_query_symlink,
++ .parse_reparse_point = smb2_parse_reparse_point,
+ .query_mf_symlink = smb3_query_mf_symlink,
+ .create_mf_symlink = smb3_create_mf_symlink,
+ .open = smb2_open_file,
+--
+2.43.0
+
--- /dev/null
+From 0ff93cb69e3e5736058156835d2381fe98fb9f0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Nov 2023 20:12:54 -0300
+Subject: smb: client: set correct file type from NFS reparse points
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 45e724022e2704b5a5193fd96f378822b0448e07 ]
+
+Handle all file types in NFS reparse points as specified in MS-FSCC
+2.1.2.6 Network File System (NFS) Reparse Data Buffer.
+
+The client is now able to set all file types based on the parsed NFS
+reparse point, which used to support only symlinks. This works for
+SMB1+.
+
+Before patch:
+
+$ mount.cifs //srv/share /mnt -o ...
+$ ls -l /mnt
+ls: cannot access 'block': Operation not supported
+ls: cannot access 'char': Operation not supported
+ls: cannot access 'fifo': Operation not supported
+ls: cannot access 'sock': Operation not supported
+total 1
+l????????? ? ? ? ? ? block
+l????????? ? ? ? ? ? char
+-rwxr-xr-x 1 root root 5 Nov 18 23:22 f0
+l????????? ? ? ? ? ? fifo
+l--------- 1 root root 0 Nov 18 23:23 link -> f0
+l????????? ? ? ? ? ? sock
+
+After patch:
+
+$ mount.cifs //srv/share /mnt -o ...
+$ ls -l /mnt
+total 1
+brwxr-xr-x 1 root root 123, 123 Nov 18 00:34 block
+crwxr-xr-x 1 root root 1234, 1234 Nov 18 00:33 char
+-rwxr-xr-x 1 root root 5 Nov 18 23:22 f0
+prwxr-xr-x 1 root root 0 Nov 18 23:23 fifo
+lrwxr-xr-x 1 root root 0 Nov 18 23:23 link -> f0
+srwxr-xr-x 1 root root 0 Nov 19 2023 sock
+
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 8 ++-
+ fs/smb/client/cifspdu.h | 2 +-
+ fs/smb/client/cifsproto.h | 4 +-
+ fs/smb/client/inode.c | 51 +++++++++++++++++--
+ fs/smb/client/readdir.c | 6 ++-
+ fs/smb/client/smb1ops.c | 3 +-
+ fs/smb/client/smb2inode.c | 2 +-
+ fs/smb/client/smb2ops.c | 101 ++++++++++++++++++++------------------
+ 8 files changed, 116 insertions(+), 61 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 7180b5713bea6..bd7fc20c49de4 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -191,7 +191,13 @@ struct cifs_open_info_data {
+ bool reparse_point;
+ bool symlink;
+ };
+- __u32 reparse_tag;
++ struct {
++ __u32 tag;
++ union {
++ struct reparse_data_buffer *buf;
++ struct reparse_posix_data *posix;
++ };
++ } reparse;
+ char *symlink_target;
+ union {
+ struct smb2_file_all_info fi;
+diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
+index 2a90134331a48..83ccc51a54d03 100644
+--- a/fs/smb/client/cifspdu.h
++++ b/fs/smb/client/cifspdu.h
+@@ -1509,7 +1509,7 @@ struct reparse_posix_data {
+ __le16 ReparseDataLength;
+ __u16 Reserved;
+ __le64 InodeType; /* LNK, FIFO, CHR etc. */
+- char PathBuffer[];
++ __u8 DataBuffer[];
+ } __attribute__((packed));
+
+ struct cifs_quota_data {
+diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
+index dc2c43dd6a910..c858feaf4f926 100644
+--- a/fs/smb/client/cifsproto.h
++++ b/fs/smb/client/cifsproto.h
+@@ -209,7 +209,7 @@ int cifs_get_inode_info(struct inode **inode, const char *full_path,
+ const struct cifs_fid *fid);
+ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
+ struct cifs_fattr *fattr,
+- u32 tag);
++ struct cifs_open_info_data *data);
+ extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path,
+ struct super_block *sb, unsigned int xid);
+ extern int cifs_get_inode_info_unix(struct inode **pinode,
+@@ -664,7 +664,7 @@ char *extract_hostname(const char *unc);
+ char *extract_sharename(const char *unc);
+ int parse_reparse_point(struct reparse_data_buffer *buf,
+ u32 plen, struct cifs_sb_info *cifs_sb,
+- bool unicode, char **target_path);
++ bool unicode, struct cifs_open_info_data *data);
+
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index 7a2a013bb05ef..6a856945f2b42 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -719,10 +719,51 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr,
+ fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
+ }
+
++static inline dev_t nfs_mkdev(struct reparse_posix_data *buf)
++{
++ u64 v = le64_to_cpu(*(__le64 *)buf->DataBuffer);
++
++ return MKDEV(v >> 32, v & 0xffffffff);
++}
++
+ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
+ struct cifs_fattr *fattr,
+- u32 tag)
++ struct cifs_open_info_data *data)
+ {
++ struct reparse_posix_data *buf = data->reparse.posix;
++ u32 tag = data->reparse.tag;
++
++ if (tag == IO_REPARSE_TAG_NFS && buf) {
++ switch (le64_to_cpu(buf->InodeType)) {
++ case NFS_SPECFILE_CHR:
++ fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode;
++ fattr->cf_dtype = DT_CHR;
++ fattr->cf_rdev = nfs_mkdev(buf);
++ break;
++ case NFS_SPECFILE_BLK:
++ fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
++ fattr->cf_dtype = DT_BLK;
++ fattr->cf_rdev = nfs_mkdev(buf);
++ break;
++ case NFS_SPECFILE_FIFO:
++ fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode;
++ fattr->cf_dtype = DT_FIFO;
++ break;
++ case NFS_SPECFILE_SOCK:
++ fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode;
++ fattr->cf_dtype = DT_SOCK;
++ break;
++ case NFS_SPECFILE_LNK:
++ fattr->cf_mode = S_IFLNK | cifs_sb->ctx->file_mode;
++ fattr->cf_dtype = DT_LNK;
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ return false;
++ }
++ return true;
++ }
++
+ switch (tag) {
+ case IO_REPARSE_TAG_LX_SYMLINK:
+ fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode;
+@@ -788,7 +829,7 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr,
+ fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
+
+ if (cifs_open_data_reparse(data) &&
+- cifs_reparse_point_to_fattr(cifs_sb, fattr, data->reparse_tag))
++ cifs_reparse_point_to_fattr(cifs_sb, fattr, data))
+ goto out_reparse;
+
+ if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+@@ -855,7 +896,7 @@ cifs_get_file_info(struct file *filp)
+ data.adjust_tz = false;
+ if (data.symlink_target) {
+ data.symlink = true;
+- data.reparse_tag = IO_REPARSE_TAG_SYMLINK;
++ data.reparse.tag = IO_REPARSE_TAG_SYMLINK;
+ }
+ cifs_open_info_to_fattr(&fattr, &data, inode->i_sb);
+ break;
+@@ -1024,7 +1065,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct kvec rsp_iov, *iov = NULL;
+ int rsp_buftype = CIFS_NO_BUFFER;
+- u32 tag = data->reparse_tag;
++ u32 tag = data->reparse.tag;
+ int rc = 0;
+
+ if (!tag && server->ops->query_reparse_point) {
+@@ -1036,7 +1077,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
+ }
+
+ rc = -EOPNOTSUPP;
+- switch ((data->reparse_tag = tag)) {
++ switch ((data->reparse.tag = tag)) {
+ case 0: /* SMB1 symlink */
+ if (server->ops->query_symlink) {
+ rc = server->ops->query_symlink(xid, tcon,
+diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
+index 47fc22de8d20c..d30ea2005eb36 100644
+--- a/fs/smb/client/readdir.c
++++ b/fs/smb/client/readdir.c
+@@ -153,6 +153,10 @@ static bool reparse_file_needs_reval(const struct cifs_fattr *fattr)
+ static void
+ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
+ {
++ struct cifs_open_info_data data = {
++ .reparse = { .tag = fattr->cf_cifstag, },
++ };
++
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
+
+@@ -165,7 +169,7 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
+ * reasonably map some of them to directories vs. files vs. symlinks
+ */
+ if ((fattr->cf_cifsattrs & ATTR_REPARSE) &&
+- cifs_reparse_point_to_fattr(cifs_sb, fattr, fattr->cf_cifstag))
++ cifs_reparse_point_to_fattr(cifs_sb, fattr, &data))
+ goto out_reparse;
+
+ if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index 0dd599004e042..64e25233e85de 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -1004,8 +1004,7 @@ static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb,
+
+ buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +
+ le32_to_cpu(io->DataOffset));
+- return parse_reparse_point(buf, plen, cifs_sb, unicode,
+- &data->symlink_target);
++ return parse_reparse_point(buf, plen, cifs_sb, unicode, data);
+ }
+
+ static bool
+diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
+index 0b89f7008ac0f..c94940af5d4b8 100644
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -555,7 +555,7 @@ static int parse_create_response(struct cifs_open_info_data *data,
+ break;
+ }
+ data->reparse_point = reparse_point;
+- data->reparse_tag = tag;
++ data->reparse.tag = tag;
+ return rc;
+ }
+
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 0390d7a801d18..0ca6dcf20261f 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -2866,89 +2866,95 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
+ return rc;
+ }
+
+-static int
+-parse_reparse_posix(struct reparse_posix_data *symlink_buf,
+- u32 plen, char **target_path,
+- struct cifs_sb_info *cifs_sb)
++/* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */
++static int parse_reparse_posix(struct reparse_posix_data *buf,
++ struct cifs_sb_info *cifs_sb,
++ struct cifs_open_info_data *data)
+ {
+ unsigned int len;
+-
+- /* See MS-FSCC 2.1.2.6 for the 'NFS' style reparse tags */
+- len = le16_to_cpu(symlink_buf->ReparseDataLength);
+-
+- if (le64_to_cpu(symlink_buf->InodeType) != NFS_SPECFILE_LNK) {
+- cifs_dbg(VFS, "%lld not a supported symlink type\n",
+- le64_to_cpu(symlink_buf->InodeType));
++ u64 type;
++
++ switch ((type = le64_to_cpu(buf->InodeType))) {
++ case NFS_SPECFILE_LNK:
++ len = le16_to_cpu(buf->ReparseDataLength);
++ data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
++ len, true,
++ cifs_sb->local_nls);
++ if (!data->symlink_target)
++ return -ENOMEM;
++ convert_delimiter(data->symlink_target, '/');
++ cifs_dbg(FYI, "%s: target path: %s\n",
++ __func__, data->symlink_target);
++ break;
++ case NFS_SPECFILE_CHR:
++ case NFS_SPECFILE_BLK:
++ case NFS_SPECFILE_FIFO:
++ case NFS_SPECFILE_SOCK:
++ break;
++ default:
++ cifs_dbg(VFS, "%s: unhandled inode type: 0x%llx\n",
++ __func__, type);
+ return -EOPNOTSUPP;
+ }
+-
+- *target_path = cifs_strndup_from_utf16(
+- symlink_buf->PathBuffer,
+- len, true, cifs_sb->local_nls);
+- if (!(*target_path))
+- return -ENOMEM;
+-
+- convert_delimiter(*target_path, '/');
+- cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
+-
+ return 0;
+ }
+
+ static int parse_reparse_symlink(struct reparse_symlink_data_buffer *sym,
+- u32 plen, bool unicode, char **target_path,
+- struct cifs_sb_info *cifs_sb)
++ u32 plen, bool unicode,
++ struct cifs_sb_info *cifs_sb,
++ struct cifs_open_info_data *data)
+ {
+- unsigned int sub_len;
+- unsigned int sub_offset;
++ unsigned int len;
++ unsigned int offs;
+
+ /* We handle Symbolic Link reparse tag here. See: MS-FSCC 2.1.2.4 */
+
+- sub_offset = le16_to_cpu(sym->SubstituteNameOffset);
+- sub_len = le16_to_cpu(sym->SubstituteNameLength);
+- if (sub_offset + 20 > plen ||
+- sub_offset + sub_len + 20 > plen) {
++ offs = le16_to_cpu(sym->SubstituteNameOffset);
++ len = le16_to_cpu(sym->SubstituteNameLength);
++ if (offs + 20 > plen || offs + len + 20 > plen) {
+ cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
+ return -EIO;
+ }
+
+- *target_path = cifs_strndup_from_utf16(sym->PathBuffer + sub_offset,
+- sub_len, unicode,
+- cifs_sb->local_nls);
+- if (!(*target_path))
++ data->symlink_target = cifs_strndup_from_utf16(sym->PathBuffer + offs,
++ len, unicode,
++ cifs_sb->local_nls);
++ if (!data->symlink_target)
+ return -ENOMEM;
+
+- convert_delimiter(*target_path, '/');
+- cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
++ convert_delimiter(data->symlink_target, '/');
++ cifs_dbg(FYI, "%s: target path: %s\n", __func__, data->symlink_target);
+
+ return 0;
+ }
+
+ int parse_reparse_point(struct reparse_data_buffer *buf,
+ u32 plen, struct cifs_sb_info *cifs_sb,
+- bool unicode, char **target_path)
++ bool unicode, struct cifs_open_info_data *data)
+ {
+ if (plen < sizeof(*buf)) {
+- cifs_dbg(VFS, "reparse buffer is too small. Must be at least 8 bytes but was %d\n",
+- plen);
++ cifs_dbg(VFS, "%s: reparse buffer is too small. Must be at least 8 bytes but was %d\n",
++ __func__, plen);
+ return -EIO;
+ }
+
+ if (plen < le16_to_cpu(buf->ReparseDataLength) + sizeof(*buf)) {
+- cifs_dbg(VFS, "srv returned invalid reparse buf length: %d\n",
+- plen);
++ cifs_dbg(VFS, "%s: invalid reparse buf length: %d\n",
++ __func__, plen);
+ return -EIO;
+ }
+
++ data->reparse.buf = buf;
++
+ /* See MS-FSCC 2.1.2 */
+ switch (le32_to_cpu(buf->ReparseTag)) {
+ case IO_REPARSE_TAG_NFS:
+- return parse_reparse_posix(
+- (struct reparse_posix_data *)buf,
+- plen, target_path, cifs_sb);
++ return parse_reparse_posix((struct reparse_posix_data *)buf,
++ cifs_sb, data);
+ case IO_REPARSE_TAG_SYMLINK:
+ return parse_reparse_symlink(
+ (struct reparse_symlink_data_buffer *)buf,
+- plen, unicode, target_path, cifs_sb);
++ plen, unicode, cifs_sb, data);
+ case IO_REPARSE_TAG_LX_SYMLINK:
+ case IO_REPARSE_TAG_AF_UNIX:
+ case IO_REPARSE_TAG_LX_FIFO:
+@@ -2956,8 +2962,8 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
+ case IO_REPARSE_TAG_LX_BLK:
+ return 0;
+ default:
+- cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n",
+- le32_to_cpu(buf->ReparseTag));
++ cifs_dbg(VFS, "%s: unhandled reparse tag: 0x%08x\n",
++ __func__, le32_to_cpu(buf->ReparseTag));
+ return -EOPNOTSUPP;
+ }
+ }
+@@ -2972,8 +2978,7 @@ static int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
+
+ buf = (struct reparse_data_buffer *)((u8 *)io +
+ le32_to_cpu(io->OutputOffset));
+- return parse_reparse_point(buf, plen, cifs_sb,
+- true, &data->symlink_target);
++ return parse_reparse_point(buf, plen, cifs_sb, true, data);
+ }
+
+ static int smb2_query_reparse_point(const unsigned int xid,
+--
+2.43.0
+
--- /dev/null
+From 087d3ddf4e993d9afe3d2cd5133d11d2e9f2ea16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Nov 2023 11:53:31 +0100
+Subject: stmmac: dwmac-loongson: Add architecture dependency
+
+From: Jean Delvare <jdelvare@suse.de>
+
+[ Upstream commit 7fbd5fc2b35a8f559a6b380dfa9bcd964a758186 ]
+
+Only present the DWMAC_LOONGSON option on architectures where it can
+actually be used.
+
+This follows the same logic as the DWMAC_INTEL option.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Cc: Keguang Zhang <keguang.zhang@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+index 06c6871f87886..25f2d42de406d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
++++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
+@@ -269,7 +269,7 @@ config DWMAC_INTEL
+ config DWMAC_LOONGSON
+ tristate "Loongson PCI DWMAC support"
+ default MACH_LOONGSON64
+- depends on STMMAC_ETH && PCI
++ depends on (MACH_LOONGSON64 || COMPILE_TEST) && STMMAC_ETH && PCI
+ depends on COMMON_CLK
+ help
+ This selects the LOONGSON PCI bus support for the stmmac driver,
+--
+2.43.0
+
--- /dev/null
+From 452065f986d4745271e5ea04986cc16804feb7f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Nov 2023 11:08:57 +0100
+Subject: usb: aqc111: check packet for fixup for true limit
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit ccab434e674ca95d483788b1895a70c21b7f016a ]
+
+If a device sends a packet that is inbetween 0
+and sizeof(u64) the value passed to skb_trim()
+as length will wrap around ending up as some very
+large value.
+
+The driver will then proceed to parse the header
+located at that position, which will either oops or
+process some random value.
+
+The fix is to check against sizeof(u64) rather than
+0, which the driver currently does. The issue exists
+since the introduction of the driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/aqc111.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
+index a017e9de2119d..7b8afa589a53c 100644
+--- a/drivers/net/usb/aqc111.c
++++ b/drivers/net/usb/aqc111.c
+@@ -1079,17 +1079,17 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ u16 pkt_count = 0;
+ u64 desc_hdr = 0;
+ u16 vlan_tag = 0;
+- u32 skb_len = 0;
++ u32 skb_len;
+
+ if (!skb)
+ goto err;
+
+- if (skb->len == 0)
++ skb_len = skb->len;
++ if (skb_len < sizeof(desc_hdr))
+ goto err;
+
+- skb_len = skb->len;
+ /* RX Descriptor Header */
+- skb_trim(skb, skb->len - sizeof(desc_hdr));
++ skb_trim(skb, skb_len - sizeof(desc_hdr));
+ desc_hdr = le64_to_cpup((u64 *)skb_tail_pointer(skb));
+
+ /* Check these packets */
+--
+2.43.0
+
--- /dev/null
+From 2baa1210f74e30e0ceefc0ed695e3f426fb6b2ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Nov 2023 00:37:47 -0800
+Subject: x86/hyperv: Fix the detection of E820_TYPE_PRAM in a Gen2 VM
+
+From: Saurabh Sengar <ssengar@linux.microsoft.com>
+
+[ Upstream commit 7e8037b099c0bbe8f2109dc452dbcab8d400fc53 ]
+
+A Gen2 VM doesn't support legacy PCI/PCIe, so both raw_pci_ops and
+raw_pci_ext_ops are NULL, and pci_subsys_init() -> pcibios_init()
+doesn't call pcibios_resource_survey() -> e820__reserve_resources_late();
+as a result, any emulated persistent memory of E820_TYPE_PRAM (12) via
+the kernel parameter memmap=nn[KMG]!ss is not added into iomem_resource
+and hence can't be detected by register_e820_pmem().
+
+Fix this by directly calling e820__reserve_resources_late() in
+hv_pci_init(), which is called from arch_initcall(pci_arch_init).
+
+It's ok to move a Gen2 VM's e820__reserve_resources_late() from
+subsys_initcall(pci_subsys_init) to arch_initcall(pci_arch_init) because
+the code in-between doesn't depend on the E820 resources.
+e820__reserve_resources_late() depends on e820__reserve_resources(),
+which has been called earlier from setup_arch().
+
+For a Gen-2 VM, the new hv_pci_init() also adds any memory of
+E820_TYPE_PMEM (7) into iomem_resource, and acpi_nfit_register_region() ->
+acpi_nfit_insert_resource() -> region_intersects() returns
+REGION_INTERSECTS, so the memory of E820_TYPE_PMEM won't get added twice.
+
+Changed the local variable "int gen2vm" to "bool gen2vm".
+
+Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <1699691867-9827-1-git-send-email-ssengar@linux.microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_init.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index 21556ad87f4ba..8f3a4d16bb791 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -15,6 +15,7 @@
+ #include <linux/io.h>
+ #include <asm/apic.h>
+ #include <asm/desc.h>
++#include <asm/e820/api.h>
+ #include <asm/sev.h>
+ #include <asm/ibt.h>
+ #include <asm/hypervisor.h>
+@@ -286,15 +287,31 @@ static int hv_cpu_die(unsigned int cpu)
+
+ static int __init hv_pci_init(void)
+ {
+- int gen2vm = efi_enabled(EFI_BOOT);
++ bool gen2vm = efi_enabled(EFI_BOOT);
+
+ /*
+- * For Generation-2 VM, we exit from pci_arch_init() by returning 0.
+- * The purpose is to suppress the harmless warning:
++ * A Generation-2 VM doesn't support legacy PCI/PCIe, so both
++ * raw_pci_ops and raw_pci_ext_ops are NULL, and pci_subsys_init() ->
++ * pcibios_init() doesn't call pcibios_resource_survey() ->
++ * e820__reserve_resources_late(); as a result, any emulated persistent
++ * memory of E820_TYPE_PRAM (12) via the kernel parameter
++ * memmap=nn[KMG]!ss is not added into iomem_resource and hence can't be
++ * detected by register_e820_pmem(). Fix this by directly calling
++ * e820__reserve_resources_late() here: e820__reserve_resources_late()
++ * depends on e820__reserve_resources(), which has been called earlier
++ * from setup_arch(). Note: e820__reserve_resources_late() also adds
++ * any memory of E820_TYPE_PMEM (7) into iomem_resource, and
++ * acpi_nfit_register_region() -> acpi_nfit_insert_resource() ->
++ * region_intersects() returns REGION_INTERSECTS, so the memory of
++ * E820_TYPE_PMEM won't get added twice.
++ *
++ * We return 0 here so that pci_arch_init() won't print the warning:
+ * "PCI: Fatal: No config space access function found"
+ */
+- if (gen2vm)
++ if (gen2vm) {
++ e820__reserve_resources_late();
+ return 0;
++ }
+
+ /* For Generation-1 VM, we'll proceed in pci_arch_init(). */
+ return 1;
+--
+2.43.0
+