--- /dev/null
+From 09d385679487c58f0859c1ad4f404ba3df2f8830 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Wed, 31 Jul 2024 11:44:08 +0800
+Subject: arm64: dts: mediatek: mt8195-cherry: Mark USB 3.0 on xhci1 as disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+commit 09d385679487c58f0859c1ad4f404ba3df2f8830 upstream.
+
+USB 3.0 on xhci1 is not used, as the controller shares the same PHY as
+pcie1. The latter is enabled to support the M.2 PCIe WLAN card on this
+design.
+
+Mark USB 3.0 as disabled on this controller using the
+"mediatek,u3p-dis-msk" property.
+
+Reported-by: NĂcolas F. R. A. Prado <nfraprado@collabora.com> #KernelCI
+Closes: https://lore.kernel.org/all/9fce9838-ef87-4d1b-b3df-63e1ddb0ec51@notapiano/
+Fixes: b6267a396e1c ("arm64: dts: mediatek: cherry: Enable T-PHYs and USB XHCI controllers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20240731034411.371178-2-wenst@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+@@ -922,6 +922,7 @@
+ usb2-lpm-disable;
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ vbus-supply = <&usb_vbus>;
++ mediatek,u3p-dis-msk = <1>;
+ };
+
+ #include <arm/cros-ec-keyboard.dtsi>
--- /dev/null
+From 15a62b81175885b5adfcaf49870466e3603f06c7 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Mon, 26 Aug 2024 07:49:34 +0200
+Subject: bus: integrator-lm: fix OF node leak in probe()
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+commit 15a62b81175885b5adfcaf49870466e3603f06c7 upstream.
+
+Driver code is leaking OF node reference from of_find_matching_node() in
+probe().
+
+Fixes: ccea5e8a5918 ("bus: Add driver for Integrator/AP logic modules")
+Cc: stable@vger.kernel.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://lore.kernel.org/20240826054934.10724-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/arm-integrator-lm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/bus/arm-integrator-lm.c
++++ b/drivers/bus/arm-integrator-lm.c
+@@ -85,6 +85,7 @@ static int integrator_ap_lm_probe(struct
+ return -ENODEV;
+ }
+ map = syscon_node_to_regmap(syscon);
++ of_node_put(syscon);
+ if (IS_ERR(map)) {
+ dev_err(dev,
+ "could not find Integrator/AP system controller\n");
--- /dev/null
+From bfc5ca0fd1ea7aceae0b682fa4bd8079c52f96c8 Mon Sep 17 00:00:00 2001
+From: Fabio Porcedda <fabio.porcedda@gmail.com>
+Date: Tue, 20 Aug 2024 10:04:39 +0200
+Subject: bus: mhi: host: pci_generic: Fix the name for the Telit FE990A
+
+From: Fabio Porcedda <fabio.porcedda@gmail.com>
+
+commit bfc5ca0fd1ea7aceae0b682fa4bd8079c52f96c8 upstream.
+
+Add a mhi_pci_dev_info struct specific for the Telit FE990A modem in
+order to use the correct product name.
+
+Cc: stable@vger.kernel.org # 6.1+
+Fixes: 0724869ede9c ("bus: mhi: host: pci_generic: add support for Telit FE990 modem")
+Signed-off-by: Fabio Porcedda <fabio.porcedda@gmail.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240820080439.837666-1-fabio.porcedda@gmail.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/pci_generic.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/bus/mhi/host/pci_generic.c
++++ b/drivers/bus/mhi/host/pci_generic.c
+@@ -538,6 +538,15 @@ static const struct mhi_pci_dev_info mhi
+ .mru_default = 32768,
+ };
+
++static const struct mhi_pci_dev_info mhi_telit_fe990a_info = {
++ .name = "telit-fe990a",
++ .config = &modem_telit_fn990_config,
++ .bar_num = MHI_PCI_DEFAULT_BAR_NUM,
++ .dma_data_width = 32,
++ .sideband_wake = false,
++ .mru_default = 32768,
++};
++
+ /* Keep the list sorted based on the PID. New VID should be added as the last entry */
+ static const struct pci_device_id mhi_pci_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304),
+@@ -553,9 +562,9 @@ static const struct pci_device_id mhi_pc
+ /* Telit FN990 */
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
+ .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
+- /* Telit FE990 */
++ /* Telit FE990A */
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
+- .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
++ .driver_data = (kernel_ulong_t) &mhi_telit_fe990a_info },
+ { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
+ .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
+ { PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */
--- /dev/null
+From ce3d2d6b150ba8528f3218ebf0cee2c2c572662d Mon Sep 17 00:00:00 2001
+From: Pavan Kumar Paluri <papaluri@amd.com>
+Date: Thu, 15 Aug 2024 07:25:00 -0500
+Subject: crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure
+
+From: Pavan Kumar Paluri <papaluri@amd.com>
+
+commit ce3d2d6b150ba8528f3218ebf0cee2c2c572662d upstream.
+
+In case of sev PLATFORM_STATUS failure, sev_get_api_version() fails
+resulting in sev_data field of psp_master nulled out. This later becomes
+a problem when unloading the ccp module because the device has not been
+unregistered (via misc_deregister()) before clearing the sev_data field
+of psp_master. As a result, on reloading the ccp module, a duplicate
+device issue is encountered as can be seen from the dmesg log below.
+
+on reloading ccp module via modprobe ccp
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xd7/0xf0
+ dump_stack+0x10/0x20
+ sysfs_warn_dup+0x5c/0x70
+ sysfs_create_dir_ns+0xbc/0xd
+ kobject_add_internal+0xb1/0x2f0
+ kobject_add+0x7a/0xe0
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ ? get_device_parent+0xd4/0x1e0
+ ? __pfx_klist_children_get+0x10/0x10
+ device_add+0x121/0x870
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ device_create_groups_vargs+0xdc/0x100
+ device_create_with_groups+0x3f/0x60
+ misc_register+0x13b/0x1c0
+ sev_dev_init+0x1d4/0x290 [ccp]
+ psp_dev_init+0x136/0x300 [ccp]
+ sp_init+0x6f/0x80 [ccp]
+ sp_pci_probe+0x2a6/0x310 [ccp]
+ ? srso_alias_return_thunk+0x5/0xfbef5
+ local_pci_probe+0x4b/0xb0
+ work_for_cpu_fn+0x1a/0x30
+ process_one_work+0x203/0x600
+ worker_thread+0x19e/0x350
+ ? __pfx_worker_thread+0x10/0x10
+ kthread+0xeb/0x120
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x3c/0x60
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+ kobject: kobject_add_internal failed for sev with -EEXIST, don't try to register things with the same name in the same directory.
+ ccp 0000:22:00.1: sev initialization failed
+ ccp 0000:22:00.1: psp initialization failed
+ ccp 0000:a2:00.1: no command queues available
+ ccp 0000:a2:00.1: psp enabled
+
+Address this issue by unregistering the /dev/sev before clearing out
+sev_data in case of PLATFORM_STATUS failure.
+
+Fixes: 200664d5237f ("crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavan Kumar Paluri <papaluri@amd.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -1362,6 +1362,8 @@ void sev_pci_init(void)
+ return;
+
+ err:
++ sev_dev_destroy(psp_master);
++
+ psp_master->sev_data = NULL;
+ }
+
--- /dev/null
+From f0e5311aa8022107d63c54e2f03684ec097d1394 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Wed, 28 Aug 2024 01:45:48 +0200
+Subject: firmware_loader: Block path traversal
+
+From: Jann Horn <jannh@google.com>
+
+commit f0e5311aa8022107d63c54e2f03684ec097d1394 upstream.
+
+Most firmware names are hardcoded strings, or are constructed from fairly
+constrained format strings where the dynamic parts are just some hex
+numbers or such.
+
+However, there are a couple codepaths in the kernel where firmware file
+names contain string components that are passed through from a device or
+semi-privileged userspace; the ones I could find (not counting interfaces
+that require root privileges) are:
+
+ - lpfc_sli4_request_firmware_update() seems to construct the firmware
+ filename from "ModelName", a string that was previously parsed out of
+ some descriptor ("Vital Product Data") in lpfc_fill_vpd()
+ - nfp_net_fw_find() seems to construct a firmware filename from a model
+ name coming from nfp_hwinfo_lookup(pf->hwinfo, "nffw.partno"), which I
+ think parses some descriptor that was read from the device.
+ (But this case likely isn't exploitable because the format string looks
+ like "netronome/nic_%s", and there shouldn't be any *folders* starting
+ with "netronome/nic_". The previous case was different because there,
+ the "%s" is *at the start* of the format string.)
+ - module_flash_fw_schedule() is reachable from the
+ ETHTOOL_MSG_MODULE_FW_FLASH_ACT netlink command, which is marked as
+ GENL_UNS_ADMIN_PERM (meaning CAP_NET_ADMIN inside a user namespace is
+ enough to pass the privilege check), and takes a userspace-provided
+ firmware name.
+ (But I think to reach this case, you need to have CAP_NET_ADMIN over a
+ network namespace that a special kind of ethernet device is mapped into,
+ so I think this is not a viable attack path in practice.)
+
+Fix it by rejecting any firmware names containing ".." path components.
+
+For what it's worth, I went looking and haven't found any USB device
+drivers that use the firmware loader dangerously.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Danilo Krummrich <dakr@kernel.org>
+Fixes: abb139e75c2c ("firmware: teach the kernel to load firmware files directly from the filesystem")
+Signed-off-by: Jann Horn <jannh@google.com>
+Acked-by: Luis Chamberlain <mcgrof@kernel.org>
+Link: https://lore.kernel.org/r/20240828-firmware-traversal-v3-1-c76529c63b5f@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/firmware_loader/main.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/drivers/base/firmware_loader/main.c
++++ b/drivers/base/firmware_loader/main.c
+@@ -791,6 +791,26 @@ static void fw_abort_batch_reqs(struct f
+ mutex_unlock(&fw_lock);
+ }
+
++/*
++ * Reject firmware file names with ".." path components.
++ * There are drivers that construct firmware file names from device-supplied
++ * strings, and we don't want some device to be able to tell us "I would like to
++ * be sent my firmware from ../../../etc/shadow, please".
++ *
++ * Search for ".." surrounded by either '/' or start/end of string.
++ *
++ * This intentionally only looks at the firmware name, not at the firmware base
++ * directory or at symlink contents.
++ */
++static bool name_contains_dotdot(const char *name)
++{
++ size_t name_len = strlen(name);
++
++ return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 ||
++ strstr(name, "/../") != NULL ||
++ (name_len >= 3 && strcmp(name+name_len-3, "/..") == 0);
++}
++
+ /* called from request_firmware() and request_firmware_work_func() */
+ static int
+ _request_firmware(const struct firmware **firmware_p, const char *name,
+@@ -811,6 +831,14 @@ _request_firmware(const struct firmware
+ goto out;
+ }
+
++ if (name_contains_dotdot(name)) {
++ dev_warn(device,
++ "Firmware load for '%s' refused, path contains '..' component\n",
++ name);
++ ret = -EINVAL;
++ goto out;
++ }
++
+ ret = _request_firmware_prepare(&fw, name, device, buf, size,
+ offset, opt_flags);
+ if (ret <= 0) /* error or already assigned */
+@@ -886,6 +914,8 @@ _request_firmware(const struct firmware
+ * @name will be used as $FIRMWARE in the uevent environment and
+ * should be distinctive enough not to be confused with any other
+ * firmware image for this or any other device.
++ * It must not contain any ".." path components - "foo/bar..bin" is
++ * allowed, but "foo/../bar.bin" is not.
+ *
+ * Caller must hold the reference count of @device.
+ *
--- /dev/null
+From 42c3732fa8073717dd7d924472f1c0bc5b452fdc Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Sat, 30 Dec 2023 19:46:00 -0500
+Subject: fs: Create a generic is_dot_dotdot() utility
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit 42c3732fa8073717dd7d924472f1c0bc5b452fdc upstream.
+
+De-duplicate the same functionality in several places by hoisting
+the is_dot_dotdot() utility function into linux/fs.h.
+
+Suggested-by: Amir Goldstein <amir73il@gmail.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Acked-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/crypto/fname.c | 8 +-------
+ fs/ecryptfs/crypto.c | 10 ----------
+ fs/f2fs/f2fs.h | 11 -----------
+ fs/namei.c | 6 ++----
+ include/linux/fs.h | 11 +++++++++++
+ 5 files changed, 14 insertions(+), 32 deletions(-)
+
+--- a/fs/crypto/fname.c
++++ b/fs/crypto/fname.c
+@@ -74,13 +74,7 @@ struct fscrypt_nokey_name {
+
+ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
+ {
+- if (str->len == 1 && str->name[0] == '.')
+- return true;
+-
+- if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
+- return true;
+-
+- return false;
++ return is_dot_dotdot(str->name, str->len);
+ }
+
+ /**
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -1973,16 +1973,6 @@ out:
+ return rc;
+ }
+
+-static bool is_dot_dotdot(const char *name, size_t name_size)
+-{
+- if (name_size == 1 && name[0] == '.')
+- return true;
+- else if (name_size == 2 && name[0] == '.' && name[1] == '.')
+- return true;
+-
+- return false;
+-}
+-
+ /**
+ * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext
+ * @plaintext_name: The plaintext name
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3335,17 +3335,6 @@ static inline bool f2fs_cp_error(struct
+ return is_set_ckpt_flags(sbi, CP_ERROR_FLAG);
+ }
+
+-static inline bool is_dot_dotdot(const u8 *name, size_t len)
+-{
+- if (len == 1 && name[0] == '.')
+- return true;
+-
+- if (len == 2 && name[0] == '.' && name[1] == '.')
+- return true;
+-
+- return false;
+-}
+-
+ static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,
+ size_t size, gfp_t flags)
+ {
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -2663,10 +2663,8 @@ static int lookup_one_common(struct user
+ if (!len)
+ return -EACCES;
+
+- if (unlikely(name[0] == '.')) {
+- if (len < 2 || (len == 2 && name[1] == '.'))
+- return -EACCES;
+- }
++ if (is_dot_dotdot(name, len))
++ return -EACCES;
+
+ while (len--) {
+ unsigned int c = *(const unsigned char *)name++;
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3107,6 +3107,17 @@ extern bool path_is_under(const struct p
+
+ extern char *file_path(struct file *, char *, int);
+
++/**
++ * is_dot_dotdot - returns true only if @name is "." or ".."
++ * @name: file name to check
++ * @len: length of file name, in bytes
++ */
++static inline bool is_dot_dotdot(const char *name, size_t len)
++{
++ return len && unlikely(name[0] == '.') &&
++ (len == 1 || (len == 2 && name[1] == '.'));
++}
++
+ #include <linux/err.h>
+
+ /* needed for stackable file system support */
--- /dev/null
+From 70fd1966c93bf3bfe3fe6d753eb3d83a76597eef Mon Sep 17 00:00:00 2001
+From: Roman Smirnov <r.smirnov@omp.ru>
+Date: Tue, 17 Sep 2024 18:54:53 +0300
+Subject: KEYS: prevent NULL pointer dereference in find_asymmetric_key()
+
+From: Roman Smirnov <r.smirnov@omp.ru>
+
+commit 70fd1966c93bf3bfe3fe6d753eb3d83a76597eef upstream.
+
+In find_asymmetric_key(), if all NULLs are passed in the id_{0,1,2}
+arguments, the kernel will first emit WARN but then have an oops
+because id_2 gets dereferenced anyway.
+
+Add the missing id_2 check and move WARN_ON() to the final else branch
+to avoid duplicate NULL checks.
+
+Found by Linux Verification Center (linuxtesting.org) with Svace static
+analysis tool.
+
+Cc: stable@vger.kernel.org # v5.17+
+Fixes: 7d30198ee24f ("keys: X.509 public key issuer lookup without AKID")
+Suggested-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/asymmetric_keys/asymmetric_type.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/crypto/asymmetric_keys/asymmetric_type.c
++++ b/crypto/asymmetric_keys/asymmetric_type.c
+@@ -61,17 +61,18 @@ struct key *find_asymmetric_key(struct k
+ char *req, *p;
+ int len;
+
+- WARN_ON(!id_0 && !id_1 && !id_2);
+-
+ if (id_0) {
+ lookup = id_0->data;
+ len = id_0->len;
+ } else if (id_1) {
+ lookup = id_1->data;
+ len = id_1->len;
+- } else {
++ } else if (id_2) {
+ lookup = id_2->data;
+ len = id_2->len;
++ } else {
++ WARN_ON(1);
++ return ERR_PTR(-EINVAL);
+ }
+
+ /* Construct an identifier "id:<keyid>". */
--- /dev/null
+From 2fb9b5dc80cabcee636a6ccd020740dd925b4580 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Tue, 3 Sep 2024 20:26:33 +0900
+Subject: ksmbd: allow write with FILE_APPEND_DATA
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit 2fb9b5dc80cabcee636a6ccd020740dd925b4580 upstream.
+
+Windows client write with FILE_APPEND_DATA when using git.
+ksmbd should allow write it with this flags.
+
+Z:\test>git commit -m "test"
+fatal: cannot update the ref 'HEAD': unable to append to
+ '.git/logs/HEAD': Bad file descriptor
+
+Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers")
+Cc: stable@vger.kernel.org # v5.15+
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/vfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/smb/server/vfs.c
++++ b/fs/smb/server/vfs.c
+@@ -493,7 +493,7 @@ int ksmbd_vfs_write(struct ksmbd_work *w
+ int err = 0;
+
+ if (work->conn->connection_type) {
+- if (!(fp->daccess & FILE_WRITE_DATA_LE)) {
++ if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) {
+ pr_err("no right to write(%pD)\n", fp->filp);
+ err = -EACCES;
+ goto out;
--- /dev/null
+From c5a709f08d40b1a082e44ffcde1aea4d2822ddd5 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Sun, 8 Sep 2024 15:23:48 +0900
+Subject: ksmbd: handle caseless file creation
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit c5a709f08d40b1a082e44ffcde1aea4d2822ddd5 upstream.
+
+Ray Zhang reported ksmbd can not create file if parent filename is
+caseless.
+
+Y:\>mkdir A
+Y:\>echo 123 >a\b.txt
+The system cannot find the path specified.
+Y:\>echo 123 >A\b.txt
+
+This patch convert name obtained by caseless lookup to parent name.
+
+Cc: stable@vger.kernel.org # v5.15+
+Reported-by: Ray Zhang <zhanglei002@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/vfs.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+--- a/fs/smb/server/vfs.c
++++ b/fs/smb/server/vfs.c
+@@ -1154,7 +1154,7 @@ static bool __caseless_lookup(struct dir
+ if (cmp < 0)
+ cmp = strncasecmp((char *)buf->private, name, namlen);
+ if (!cmp) {
+- memcpy((char *)buf->private, name, namlen);
++ memcpy((char *)buf->private, name, buf->used);
+ buf->dirent_count = 1;
+ return false;
+ }
+@@ -1220,10 +1220,7 @@ int ksmbd_vfs_kern_path_locked(struct ks
+ char *filepath;
+ size_t path_len, remain_len;
+
+- filepath = kstrdup(name, GFP_KERNEL);
+- if (!filepath)
+- return -ENOMEM;
+-
++ filepath = name;
+ path_len = strlen(filepath);
+ remain_len = path_len;
+
+@@ -1266,10 +1263,9 @@ int ksmbd_vfs_kern_path_locked(struct ks
+ err = -EINVAL;
+ out2:
+ path_put(parent_path);
+-out1:
+- kfree(filepath);
+ }
+
++out1:
+ if (!err) {
+ err = mnt_want_write(parent_path->mnt);
+ if (err) {
--- /dev/null
+From ca4974ca954561e79f8871d220bb08f14f64f57c Mon Sep 17 00:00:00 2001
+From: Hobin Woo <hobin.woo@samsung.com>
+Date: Wed, 4 Sep 2024 13:36:35 +0900
+Subject: ksmbd: make __dir_empty() compatible with POSIX
+
+From: Hobin Woo <hobin.woo@samsung.com>
+
+commit ca4974ca954561e79f8871d220bb08f14f64f57c upstream.
+
+Some file systems may not provide dot (.) and dot-dot (..) as they are
+optional in POSIX. ksmbd can misjudge emptiness of a directory in those
+file systems, since it assumes there are always at least two entries:
+dot and dot-dot.
+Just don't count dot and dot-dot.
+
+Cc: stable@vger.kernel.org # v6.1+
+Signed-off-by: Hobin Woo <hobin.woo@samsung.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/vfs.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/fs/smb/server/vfs.c
++++ b/fs/smb/server/vfs.c
+@@ -1102,9 +1102,10 @@ static bool __dir_empty(struct dir_conte
+ struct ksmbd_readdir_data *buf;
+
+ buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
+- buf->dirent_count++;
++ if (!is_dot_dotdot(name, namlen))
++ buf->dirent_count++;
+
+- return buf->dirent_count <= 2;
++ return !buf->dirent_count;
+ }
+
+ /**
+@@ -1124,7 +1125,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_fil
+ readdir_data.dirent_count = 0;
+
+ err = iterate_dir(fp->filp, &readdir_data.ctx);
+- if (readdir_data.dirent_count > 2)
++ if (readdir_data.dirent_count)
+ err = -ENOTEMPTY;
+ else
+ err = 0;
--- /dev/null
+From 5551bc30e4a69ad86d0d008e2f56cd59b6583476 Mon Sep 17 00:00:00 2001
+From: Finn Thain <fthain@linux-m68k.org>
+Date: Wed, 7 Aug 2024 13:36:28 +1000
+Subject: scsi: mac_scsi: Disallow bus errors during PDMA send
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+commit 5551bc30e4a69ad86d0d008e2f56cd59b6583476 upstream.
+
+SD cards can produce write latency spikes on the order of a hundred
+milliseconds. If the target firmware does not hide that latency during DATA
+IN and OUT phases it can cause the PDMA circuitry to raise a processor bus
+fault which in turn leads to an unreliable byte count and a DMA overrun.
+
+The Last Byte Sent flag is used to detect the overrun but this mechanism is
+unreliable on some systems. Instead, set a DID_ERROR result whenever there
+is a bus fault during a PDMA send, unless the cause was a phase mismatch.
+
+Cc: stable@vger.kernel.org # 5.15+
+Reported-and-tested-by: Stan Johnson <userm57@yahoo.com>
+Fixes: 7c1f3e3447a1 ("scsi: mac_scsi: Treat Last Byte Sent time-out as failure")
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Link: https://lore.kernel.org/r/cc38df687ace2c4ffc375a683b2502fc476b600d.1723001788.git.fthain@linux-m68k.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/mac_scsi.c | 44 +++++++++++++++++++-------------------------
+ 1 file changed, 19 insertions(+), 25 deletions(-)
+
+--- a/drivers/scsi/mac_scsi.c
++++ b/drivers/scsi/mac_scsi.c
+@@ -102,11 +102,15 @@ __setup("mac5380=", mac_scsi_setup);
+ * Linux SCSI drivers lack knowledge of the timing behaviour of SCSI targets
+ * so bus errors are unavoidable.
+ *
+- * If a MOVE.B instruction faults, we assume that zero bytes were transferred
+- * and simply retry. That assumption probably depends on target behaviour but
+- * seems to hold up okay. The NOP provides synchronization: without it the
+- * fault can sometimes occur after the program counter has moved past the
+- * offending instruction. Post-increment addressing can't be used.
++ * If a MOVE.B instruction faults during a receive operation, we assume the
++ * target sent nothing and try again. That assumption probably depends on
++ * target firmware but it seems to hold up okay. If a fault happens during a
++ * send operation, the target may or may not have seen /ACK and got the byte.
++ * It's uncertain so the whole SCSI command gets retried.
++ *
++ * The NOP is needed for synchronization because the fault address in the
++ * exception stack frame may or may not be the instruction that actually
++ * caused the bus error. Post-increment addressing can't be used.
+ */
+
+ #define MOVE_BYTE(operands) \
+@@ -243,22 +247,21 @@ static inline int mac_pdma_send(unsigned
+ if (n >= 1) {
+ MOVE_BYTE("%0@,%3@");
+ if (result)
+- goto out;
++ return -1;
+ }
+ if (n >= 1 && ((unsigned long)addr & 1)) {
+ MOVE_BYTE("%0@,%3@");
+ if (result)
+- goto out;
++ return -2;
+ }
+ while (n >= 32)
+ MOVE_16_WORDS("%0@+,%3@");
+ while (n >= 2)
+ MOVE_WORD("%0@+,%3@");
+ if (result)
+- return start - addr; /* Negated to indicate uncertain length */
++ return start - addr - 1; /* Negated to indicate uncertain length */
+ if (n == 1)
+ MOVE_BYTE("%0@,%3@");
+-out:
+ return addr - start;
+ }
+
+@@ -307,7 +310,6 @@ static inline int macscsi_pread(struct N
+ {
+ u8 __iomem *s = hostdata->pdma_io + (INPUT_DATA_REG << 4);
+ unsigned char *d = dst;
+- int result = 0;
+
+ hostdata->pdma_residual = len;
+
+@@ -343,11 +345,12 @@ static inline int macscsi_pread(struct N
+ if (bytes == 0)
+ continue;
+
+- result = -1;
++ if (macscsi_wait_for_drq(hostdata) <= 0)
++ set_host_byte(hostdata->connected, DID_ERROR);
+ break;
+ }
+
+- return result;
++ return 0;
+ }
+
+ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
+@@ -355,7 +358,6 @@ static inline int macscsi_pwrite(struct
+ {
+ unsigned char *s = src;
+ u8 __iomem *d = hostdata->pdma_io + (OUTPUT_DATA_REG << 4);
+- int result = 0;
+
+ hostdata->pdma_residual = len;
+
+@@ -377,17 +379,8 @@ static inline int macscsi_pwrite(struct
+ hostdata->pdma_residual -= bytes;
+ }
+
+- if (hostdata->pdma_residual == 0) {
+- if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
+- TCR_LAST_BYTE_SENT,
+- TCR_LAST_BYTE_SENT,
+- 0) < 0) {
+- scmd_printk(KERN_ERR, hostdata->connected,
+- "%s: Last Byte Sent timeout\n", __func__);
+- result = -1;
+- }
++ if (hostdata->pdma_residual == 0)
+ break;
+- }
+
+ if (bytes > 0)
+ continue;
+@@ -400,11 +393,12 @@ static inline int macscsi_pwrite(struct
+ if (bytes == 0)
+ continue;
+
+- result = -1;
++ if (macscsi_wait_for_drq(hostdata) <= 0)
++ set_host_byte(hostdata->connected, DID_ERROR);
+ break;
+ }
+
+- return result;
++ return 0;
+ }
+
+ static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
--- /dev/null
+From 5545c3165cbc98615fe65a44f41167cbb557e410 Mon Sep 17 00:00:00 2001
+From: Finn Thain <fthain@linux-m68k.org>
+Date: Wed, 7 Aug 2024 13:36:28 +1000
+Subject: scsi: mac_scsi: Refactor polling loop
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+commit 5545c3165cbc98615fe65a44f41167cbb557e410 upstream.
+
+Before the error handling can be revised, some preparation is needed.
+Refactor the polling loop with a new function, macscsi_wait_for_drq().
+This function will gain more call sites in the next patch.
+
+Cc: stable@vger.kernel.org # 5.15+
+Tested-by: Stan Johnson <userm57@yahoo.com>
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Link: https://lore.kernel.org/r/6a5ffabb4290c0d138c6d285fda8fa3902e926f0.1723001788.git.fthain@linux-m68k.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/mac_scsi.c | 80 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 42 insertions(+), 38 deletions(-)
+
+--- a/drivers/scsi/mac_scsi.c
++++ b/drivers/scsi/mac_scsi.c
+@@ -208,8 +208,6 @@ __setup("mac5380=", mac_scsi_setup);
+ ".previous \n" \
+ : "+a" (addr), "+r" (n), "+r" (result) : "a" (io))
+
+-#define MAC_PDMA_DELAY 32
+-
+ static inline int mac_pdma_recv(void __iomem *io, unsigned char *start, int n)
+ {
+ unsigned char *addr = start;
+@@ -274,6 +272,36 @@ static inline void write_ctrl_reg(struct
+ out_be32(hostdata->io + (CTRL_REG << 4), value);
+ }
+
++static inline int macscsi_wait_for_drq(struct NCR5380_hostdata *hostdata)
++{
++ unsigned int n = 1; /* effectively multiplies NCR5380_REG_POLL_TIME */
++ unsigned char basr;
++
++again:
++ basr = NCR5380_read(BUS_AND_STATUS_REG);
++
++ if (!(basr & BASR_PHASE_MATCH))
++ return 1;
++
++ if (basr & BASR_IRQ)
++ return -1;
++
++ if (basr & BASR_DRQ)
++ return 0;
++
++ if (n-- == 0) {
++ NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
++ dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
++ "%s: DRQ timeout\n", __func__);
++ return -1;
++ }
++
++ NCR5380_poll_politely2(hostdata,
++ BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
++ BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, 0);
++ goto again;
++}
++
+ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
+ unsigned char *dst, int len)
+ {
+@@ -283,9 +311,7 @@ static inline int macscsi_pread(struct N
+
+ hostdata->pdma_residual = len;
+
+- while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
+- BASR_DRQ | BASR_PHASE_MATCH,
+- BASR_DRQ | BASR_PHASE_MATCH, 0)) {
++ while (macscsi_wait_for_drq(hostdata) == 0) {
+ int bytes, chunk_bytes;
+
+ if (macintosh_config->ident == MAC_MODEL_IIFX)
+@@ -295,19 +321,16 @@ static inline int macscsi_pread(struct N
+ chunk_bytes = min(hostdata->pdma_residual, 512);
+ bytes = mac_pdma_recv(s, d, chunk_bytes);
+
++ if (macintosh_config->ident == MAC_MODEL_IIFX)
++ write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
++
+ if (bytes > 0) {
+ d += bytes;
+ hostdata->pdma_residual -= bytes;
+ }
+
+ if (hostdata->pdma_residual == 0)
+- goto out;
+-
+- if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+- goto out;
+-
+- if (bytes == 0)
+- udelay(MAC_PDMA_DELAY);
++ break;
+
+ if (bytes > 0)
+ continue;
+@@ -321,16 +344,9 @@ static inline int macscsi_pread(struct N
+ continue;
+
+ result = -1;
+- goto out;
++ break;
+ }
+
+- scmd_printk(KERN_ERR, hostdata->connected,
+- "%s: phase mismatch or !DRQ\n", __func__);
+- NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
+- result = -1;
+-out:
+- if (macintosh_config->ident == MAC_MODEL_IIFX)
+- write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
+ return result;
+ }
+
+@@ -343,9 +359,7 @@ static inline int macscsi_pwrite(struct
+
+ hostdata->pdma_residual = len;
+
+- while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
+- BASR_DRQ | BASR_PHASE_MATCH,
+- BASR_DRQ | BASR_PHASE_MATCH, 0)) {
++ while (macscsi_wait_for_drq(hostdata) == 0) {
+ int bytes, chunk_bytes;
+
+ if (macintosh_config->ident == MAC_MODEL_IIFX)
+@@ -355,6 +369,9 @@ static inline int macscsi_pwrite(struct
+ chunk_bytes = min(hostdata->pdma_residual, 512);
+ bytes = mac_pdma_send(s, d, chunk_bytes);
+
++ if (macintosh_config->ident == MAC_MODEL_IIFX)
++ write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
++
+ if (bytes > 0) {
+ s += bytes;
+ hostdata->pdma_residual -= bytes;
+@@ -369,15 +386,9 @@ static inline int macscsi_pwrite(struct
+ "%s: Last Byte Sent timeout\n", __func__);
+ result = -1;
+ }
+- goto out;
++ break;
+ }
+
+- if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+- goto out;
+-
+- if (bytes == 0)
+- udelay(MAC_PDMA_DELAY);
+-
+ if (bytes > 0)
+ continue;
+
+@@ -390,16 +401,9 @@ static inline int macscsi_pwrite(struct
+ continue;
+
+ result = -1;
+- goto out;
++ break;
+ }
+
+- scmd_printk(KERN_ERR, hostdata->connected,
+- "%s: phase mismatch or !DRQ\n", __func__);
+- NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
+- result = -1;
+-out:
+- if (macintosh_config->ident == MAC_MODEL_IIFX)
+- write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
+ return result;
+ }
+
--- /dev/null
+From 5ec4f820cb9766e4583df947150a6febce8da794 Mon Sep 17 00:00:00 2001
+From: Finn Thain <fthain@linux-m68k.org>
+Date: Wed, 7 Aug 2024 13:36:28 +1000
+Subject: scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+commit 5ec4f820cb9766e4583df947150a6febce8da794 upstream.
+
+After a bus fault, capture and log the chip registers immediately, if the
+NDEBUG_PSEUDO_DMA macro is defined. Remove some printk(KERN_DEBUG ...)
+messages that aren't needed any more. Don't skip the debug message when
+bytes == 0. Show all of the byte counters in the debug messages.
+
+Cc: stable@vger.kernel.org # 5.15+
+Tested-by: Stan Johnson <userm57@yahoo.com>
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Link: https://lore.kernel.org/r/7573c79f4e488fc00af2b8a191e257ca945e0409.1723001788.git.fthain@linux-m68k.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/mac_scsi.c | 42 ++++++++++++++++++++++--------------------
+ 1 file changed, 22 insertions(+), 20 deletions(-)
+
+--- a/drivers/scsi/mac_scsi.c
++++ b/drivers/scsi/mac_scsi.c
+@@ -286,13 +286,14 @@ static inline int macscsi_pread(struct N
+ while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
+ BASR_DRQ | BASR_PHASE_MATCH,
+ BASR_DRQ | BASR_PHASE_MATCH, 0)) {
+- int bytes;
++ int bytes, chunk_bytes;
+
+ if (macintosh_config->ident == MAC_MODEL_IIFX)
+ write_ctrl_reg(hostdata, CTRL_HANDSHAKE_MODE |
+ CTRL_INTERRUPTS_ENABLE);
+
+- bytes = mac_pdma_recv(s, d, min(hostdata->pdma_residual, 512));
++ chunk_bytes = min(hostdata->pdma_residual, 512);
++ bytes = mac_pdma_recv(s, d, chunk_bytes);
+
+ if (bytes > 0) {
+ d += bytes;
+@@ -302,23 +303,23 @@ static inline int macscsi_pread(struct N
+ if (hostdata->pdma_residual == 0)
+ goto out;
+
+- if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
+- BUS_AND_STATUS_REG, BASR_ACK,
+- BASR_ACK, 0) < 0)
+- scmd_printk(KERN_DEBUG, hostdata->connected,
+- "%s: !REQ and !ACK\n", __func__);
+ if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+ goto out;
+
+ if (bytes == 0)
+ udelay(MAC_PDMA_DELAY);
+
+- if (bytes >= 0)
++ if (bytes > 0)
+ continue;
+
+- dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
+- "%s: bus error (%d/%d)\n", __func__, d - dst, len);
+ NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
++ dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
++ "%s: bus error [%d/%d] (%d/%d)\n",
++ __func__, d - dst, len, bytes, chunk_bytes);
++
++ if (bytes == 0)
++ continue;
++
+ result = -1;
+ goto out;
+ }
+@@ -345,13 +346,14 @@ static inline int macscsi_pwrite(struct
+ while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
+ BASR_DRQ | BASR_PHASE_MATCH,
+ BASR_DRQ | BASR_PHASE_MATCH, 0)) {
+- int bytes;
++ int bytes, chunk_bytes;
+
+ if (macintosh_config->ident == MAC_MODEL_IIFX)
+ write_ctrl_reg(hostdata, CTRL_HANDSHAKE_MODE |
+ CTRL_INTERRUPTS_ENABLE);
+
+- bytes = mac_pdma_send(s, d, min(hostdata->pdma_residual, 512));
++ chunk_bytes = min(hostdata->pdma_residual, 512);
++ bytes = mac_pdma_send(s, d, chunk_bytes);
+
+ if (bytes > 0) {
+ s += bytes;
+@@ -370,23 +372,23 @@ static inline int macscsi_pwrite(struct
+ goto out;
+ }
+
+- if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
+- BUS_AND_STATUS_REG, BASR_ACK,
+- BASR_ACK, 0) < 0)
+- scmd_printk(KERN_DEBUG, hostdata->connected,
+- "%s: !REQ and !ACK\n", __func__);
+ if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
+ goto out;
+
+ if (bytes == 0)
+ udelay(MAC_PDMA_DELAY);
+
+- if (bytes >= 0)
++ if (bytes > 0)
+ continue;
+
+- dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
+- "%s: bus error (%d/%d)\n", __func__, s - src, len);
+ NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
++ dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
++ "%s: bus error [%d/%d] (%d/%d)\n",
++ __func__, s - src, len, bytes, chunk_bytes);
++
++ if (bytes == 0)
++ continue;
++
+ result = -1;
+ goto out;
+ }
--- /dev/null
+From f81eaf08385ddd474a2f41595a7757502870c0eb Mon Sep 17 00:00:00 2001
+From: Martin Wilck <mwilck@suse.com>
+Date: Thu, 12 Sep 2024 15:43:08 +0200
+Subject: scsi: sd: Fix off-by-one error in sd_read_block_characteristics()
+
+From: Martin Wilck <mwilck@suse.com>
+
+commit f81eaf08385ddd474a2f41595a7757502870c0eb upstream.
+
+Ff the device returns page 0xb1 with length 8 (happens with qemu v2.x, for
+example), sd_read_block_characteristics() may attempt an out-of-bounds
+memory access when accessing the zoned field at offset 8.
+
+Fixes: 7fb019c46eee ("scsi: sd: Switch to using scsi_device VPD pages")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Wilck <mwilck@suse.com>
+Link: https://lore.kernel.org/r/20240912134308.282824-1-mwilck@suse.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/sd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -2998,7 +2998,7 @@ static void sd_read_block_characteristic
+ rcu_read_lock();
+ vpd = rcu_dereference(sdkp->device->vpd_pgb1);
+
+- if (!vpd || vpd->len < 8) {
++ if (!vpd || vpd->len <= 8) {
+ rcu_read_unlock();
+ return;
+ }
drm-amd-display-skip-recompute-dsc-params-if-no-stream-on-link.patch
drm-amd-display-round-calculated-vtotal.patch
drm-amd-display-validate-backlight-caps-are-sane.patch
+keys-prevent-null-pointer-dereference-in-find_asymmetric_key.patch
+fs-create-a-generic-is_dot_dotdot-utility.patch
+ksmbd-make-__dir_empty-compatible-with-posix.patch
+ksmbd-allow-write-with-file_append_data.patch
+ksmbd-handle-caseless-file-creation.patch
+scsi-sd-fix-off-by-one-error-in-sd_read_block_characteristics.patch
+scsi-mac_scsi-revise-printk-kern_debug-...-messages.patch
+scsi-mac_scsi-refactor-polling-loop.patch
+scsi-mac_scsi-disallow-bus-errors-during-pdma-send.patch
+usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch
+arm64-dts-mediatek-mt8195-cherry-mark-usb-3.0-on-xhci1-as-disabled.patch
+usb-appledisplay-close-race-between-probe-and-completion-handler.patch
+usb-misc-cypress_cy7c63-check-for-short-transfer.patch
+usb-class-cdc-acm-fix-race-between-get_serial-and-set_serial.patch
+usb-cdnsp-fix-incorrect-usb_request-status.patch
+usb-dwc2-drd-fix-clock-gating-on-usb-role-switch.patch
+bus-integrator-lm-fix-of-node-leak-in-probe.patch
+bus-mhi-host-pci_generic-fix-the-name-for-the-telit-fe990a.patch
+firmware_loader-block-path-traversal.patch
+tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch
+xhci-set-quirky-xhc-pci-hosts-to-d3-_after_-stopping-and-freeing-them.patch
+crypto-ccp-properly-unregister-dev-sev-on-sev-platform_status-failure.patch
--- /dev/null
+From f16dd10ba342c429b1e36ada545fb36d4d1f0e63 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+Date: Fri, 6 Sep 2024 15:54:33 -0700
+Subject: tty: rp2: Fix reset with non forgiving PCIe host bridges
+
+From: Florian Fainelli <florian.fainelli@broadcom.com>
+
+commit f16dd10ba342c429b1e36ada545fb36d4d1f0e63 upstream.
+
+The write to RP2_GLOBAL_CMD followed by an immediate read of
+RP2_GLOBAL_CMD in rp2_reset_asic() is intented to flush out the write,
+however by then the device is already in reset and cannot respond to a
+memory cycle access.
+
+On platforms such as the Raspberry Pi 4 and others using the
+pcie-brcmstb.c driver, any memory access to a device that cannot respond
+is met with a fatal system error, rather than being substituted with all
+1s as is usually the case on PC platforms.
+
+Swapping the delay and the read ensures that the device has finished
+resetting before we attempt to read from it.
+
+Fixes: 7d9f49afa451 ("serial: rp2: New driver for Comtrol RocketPort 2 cards")
+Cc: stable <stable@kernel.org>
+Suggested-by: Jim Quinlan <james.quinlan@broadcom.com>
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/20240906225435.707837-1-florian.fainelli@broadcom.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/rp2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/rp2.c
++++ b/drivers/tty/serial/rp2.c
+@@ -597,8 +597,8 @@ static void rp2_reset_asic(struct rp2_ca
+ u32 clk_cfg;
+
+ writew(1, base + RP2_GLOBAL_CMD);
+- readw(base + RP2_GLOBAL_CMD);
+ msleep(100);
++ readw(base + RP2_GLOBAL_CMD);
+ writel(0, base + RP2_CLK_PRESCALER);
+
+ /* TDM clock configuration */
--- /dev/null
+From 8265d06b7794493d82c5c21a12d7ba43eccc30cb Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 12 Sep 2024 14:32:59 +0200
+Subject: USB: appledisplay: close race between probe and completion handler
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 8265d06b7794493d82c5c21a12d7ba43eccc30cb upstream.
+
+There is a small window during probing when IO is running
+but the backlight is not registered. Processing events
+during that time will crash. The completion handler
+needs to check for a backlight before scheduling work.
+
+The bug is as old as the driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+CC: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240912123317.1026049-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/appledisplay.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/misc/appledisplay.c
++++ b/drivers/usb/misc/appledisplay.c
+@@ -107,7 +107,12 @@ static void appledisplay_complete(struct
+ case ACD_BTN_BRIGHT_UP:
+ case ACD_BTN_BRIGHT_DOWN:
+ pdata->button_pressed = 1;
+- schedule_delayed_work(&pdata->work, 0);
++ /*
++ * there is a window during which no device
++ * is registered
++ */
++ if (pdata->bd )
++ schedule_delayed_work(&pdata->work, 0);
+ break;
+ case ACD_BTN_NONE:
+ default:
+@@ -202,6 +207,7 @@ static int appledisplay_probe(struct usb
+ const struct usb_device_id *id)
+ {
+ struct backlight_properties props;
++ struct backlight_device *backlight;
+ struct appledisplay *pdata;
+ struct usb_device *udev = interface_to_usbdev(iface);
+ struct usb_endpoint_descriptor *endpoint;
+@@ -272,13 +278,14 @@ static int appledisplay_probe(struct usb
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = 0xff;
+- pdata->bd = backlight_device_register(bl_name, NULL, pdata,
++ backlight = backlight_device_register(bl_name, NULL, pdata,
+ &appledisplay_bl_data, &props);
+- if (IS_ERR(pdata->bd)) {
++ if (IS_ERR(backlight)) {
+ dev_err(&iface->dev, "Backlight registration failed\n");
+- retval = PTR_ERR(pdata->bd);
++ retval = PTR_ERR(backlight);
+ goto error;
+ }
++ pdata->bd = backlight;
+
+ /* Try to get brightness */
+ brightness = appledisplay_bl_get_brightness(pdata->bd);
--- /dev/null
+From 1702bec4477cc7d31adb4a760d14d33fac928b7a Mon Sep 17 00:00:00 2001
+From: Pawel Laszczak <pawell@cadence.com>
+Date: Fri, 6 Sep 2024 06:48:54 +0000
+Subject: usb: cdnsp: Fix incorrect usb_request status
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+commit 1702bec4477cc7d31adb4a760d14d33fac928b7a upstream.
+
+Fix changes incorrect usb_request->status returned during disabling
+endpoints. Before fix the status returned during dequeuing requests
+while disabling endpoint was ECONNRESET.
+Patch change it to ESHUTDOWN.
+
+Patch fixes issue detected during testing UVC gadget.
+During stopping streaming the class starts dequeuing usb requests and
+controller driver returns the -ECONNRESET status. After completion
+requests the class or application "uvc-gadget" try to queue this
+request again. Changing this status to ESHUTDOWN cause that UVC assumes
+that endpoint is disabled, or device is disconnected and stops
+re-queuing usb requests.
+
+Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
+cc: stable@vger.kernel.org
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Reviewed-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/PH7PR07MB9538E8CA7A2096AAF6A3718FDD9E2@PH7PR07MB9538.namprd07.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdnsp-ring.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -718,7 +718,8 @@ int cdnsp_remove_request(struct cdnsp_de
+ seg = cdnsp_trb_in_td(pdev, cur_td->start_seg, cur_td->first_trb,
+ cur_td->last_trb, hw_deq);
+
+- if (seg && (pep->ep_state & EP_ENABLED))
++ if (seg && (pep->ep_state & EP_ENABLED) &&
++ !(pep->ep_state & EP_DIS_IN_RROGRESS))
+ cdnsp_find_new_dequeue_state(pdev, pep, preq->request.stream_id,
+ cur_td, &deq_state);
+ else
+@@ -736,7 +737,8 @@ int cdnsp_remove_request(struct cdnsp_de
+ * During disconnecting all endpoint will be disabled so we don't
+ * have to worry about updating dequeue pointer.
+ */
+- if (pdev->cdnsp_state & CDNSP_STATE_DISCONNECT_PENDING) {
++ if (pdev->cdnsp_state & CDNSP_STATE_DISCONNECT_PENDING ||
++ pep->ep_state & EP_DIS_IN_RROGRESS) {
+ status = -ESHUTDOWN;
+ ret = cdnsp_cmd_set_deq(pdev, pep, &deq_state);
+ }
--- /dev/null
+From b41c1fa155ba56d125885b0191aabaf3c508d0a3 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 12 Sep 2024 16:19:06 +0200
+Subject: USB: class: CDC-ACM: fix race between get_serial and set_serial
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit b41c1fa155ba56d125885b0191aabaf3c508d0a3 upstream.
+
+TIOCGSERIAL is an ioctl. Thus it must be atomic. It returns
+two values. Racing with set_serial it can return an inconsistent
+result. The mutex must be taken.
+
+In terms of logic the bug is as old as the driver. In terms of
+code it goes back to the conversion to the get_serial and
+set_serial methods.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: stable <stable@kernel.org>
+Fixes: 99f75a1fcd865 ("cdc-acm: switch to ->[sg]et_serial()")
+Link: https://lore.kernel.org/r/20240912141916.1044393-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -938,10 +938,12 @@ static int get_serial_info(struct tty_st
+ struct acm *acm = tty->driver_data;
+
+ ss->line = acm->minor;
++ mutex_lock(&acm->port.mutex);
+ ss->close_delay = jiffies_to_msecs(acm->port.close_delay) / 10;
+ ss->closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE :
+ jiffies_to_msecs(acm->port.closing_wait) / 10;
++ mutex_unlock(&acm->port.mutex);
+ return 0;
+ }
+
--- /dev/null
+From 2c6b6afa59e78bebcb65bbc8a76b3459f139547c Mon Sep 17 00:00:00 2001
+From: Tomas Marek <tomas.marek@elrest.cz>
+Date: Fri, 6 Sep 2024 07:50:25 +0200
+Subject: usb: dwc2: drd: fix clock gating on USB role switch
+
+From: Tomas Marek <tomas.marek@elrest.cz>
+
+commit 2c6b6afa59e78bebcb65bbc8a76b3459f139547c upstream.
+
+The dwc2_handle_usb_suspend_intr() function disables gadget clocks in USB
+peripheral mode when no other power-down mode is available (introduced by
+commit 0112b7ce68ea ("usb: dwc2: Update dwc2_handle_usb_suspend_intr function.")).
+However, the dwc2_drd_role_sw_set() USB role update handler attempts to
+read DWC2 registers if the USB role has changed while the USB is in suspend
+mode (when the clocks are gated). This causes the system to hang.
+
+Release the gadget clocks before handling the USB role update.
+
+Fixes: 0112b7ce68ea ("usb: dwc2: Update dwc2_handle_usb_suspend_intr function.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tomas Marek <tomas.marek@elrest.cz>
+Link: https://lore.kernel.org/r/20240906055025.25057-1-tomas.marek@elrest.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc2/drd.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/usb/dwc2/drd.c
++++ b/drivers/usb/dwc2/drd.c
+@@ -127,6 +127,15 @@ static int dwc2_drd_role_sw_set(struct u
+ role = USB_ROLE_DEVICE;
+ }
+
++ if ((IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) ||
++ IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)) &&
++ dwc2_is_device_mode(hsotg) &&
++ hsotg->lx_state == DWC2_L2 &&
++ hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
++ hsotg->bus_suspended &&
++ !hsotg->params.no_clock_gating)
++ dwc2_gadget_exit_clock_gating(hsotg, 0);
++
+ if (role == USB_ROLE_HOST) {
+ already = dwc2_ovr_avalid(hsotg, true);
+ } else if (role == USB_ROLE_DEVICE) {
--- /dev/null
+From 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 12 Sep 2024 14:54:43 +0200
+Subject: USB: misc: cypress_cy7c63: check for short transfer
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 upstream.
+
+As we process the second byte of a control transfer, transfers
+of less than 2 bytes must be discarded.
+
+This bug is as old as the driver.
+
+SIgned-off-by: Oliver Neukum <oneukum@suse.com>
+CC: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240912125449.1030536-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/cypress_cy7c63.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/misc/cypress_cy7c63.c
++++ b/drivers/usb/misc/cypress_cy7c63.c
+@@ -88,6 +88,9 @@ static int vendor_command(struct cypress
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ address, data, iobuf, CYPRESS_MAX_REQSIZE,
+ USB_CTRL_GET_TIMEOUT);
++ /* we must not process garbage */
++ if (retval < 2)
++ goto err_buf;
+
+ /* store returned data (more READs to be added) */
+ switch (request) {
+@@ -107,6 +110,7 @@ static int vendor_command(struct cypress
+ break;
+ }
+
++err_buf:
+ kfree(iobuf);
+ error:
+ return retval;
--- /dev/null
+From 04e906839a053f092ef53f4fb2d610983412b904 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 19 Sep 2024 14:33:42 +0200
+Subject: usbnet: fix cyclical race on disconnect with work queue
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 04e906839a053f092ef53f4fb2d610983412b904 upstream.
+
+The work can submit URBs and the URBs can schedule the work.
+This cycle needs to be broken, when a device is to be stopped.
+Use a flag to do so.
+This is a design issue as old as the driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+CC: stable@vger.kernel.org
+Link: https://patch.msgid.link/20240919123525.688065-1-oneukum@suse.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/usbnet.c | 37 ++++++++++++++++++++++++++++---------
+ include/linux/usb/usbnet.h | 15 +++++++++++++++
+ 2 files changed, 43 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -464,10 +464,15 @@ static enum skb_state defer_bh(struct us
+ void usbnet_defer_kevent (struct usbnet *dev, int work)
+ {
+ set_bit (work, &dev->flags);
+- if (!schedule_work (&dev->kevent))
+- netdev_dbg(dev->net, "kevent %s may have been dropped\n", usbnet_event_names[work]);
+- else
+- netdev_dbg(dev->net, "kevent %s scheduled\n", usbnet_event_names[work]);
++ if (!usbnet_going_away(dev)) {
++ if (!schedule_work(&dev->kevent))
++ netdev_dbg(dev->net,
++ "kevent %s may have been dropped\n",
++ usbnet_event_names[work]);
++ else
++ netdev_dbg(dev->net,
++ "kevent %s scheduled\n", usbnet_event_names[work]);
++ }
+ }
+ EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
+
+@@ -535,7 +540,8 @@ static int rx_submit (struct usbnet *dev
+ tasklet_schedule (&dev->bh);
+ break;
+ case 0:
+- __usbnet_queue_skb(&dev->rxq, skb, rx_start);
++ if (!usbnet_going_away(dev))
++ __usbnet_queue_skb(&dev->rxq, skb, rx_start);
+ }
+ } else {
+ netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
+@@ -845,9 +851,18 @@ int usbnet_stop (struct net_device *net)
+
+ /* deferred work (timer, softirq, task) must also stop */
+ dev->flags = 0;
+- del_timer_sync (&dev->delay);
+- tasklet_kill (&dev->bh);
++ del_timer_sync(&dev->delay);
++ tasklet_kill(&dev->bh);
+ cancel_work_sync(&dev->kevent);
++
++ /* We have cyclic dependencies. Those calls are needed
++ * to break a cycle. We cannot fall into the gaps because
++ * we have a flag
++ */
++ tasklet_kill(&dev->bh);
++ del_timer_sync(&dev->delay);
++ cancel_work_sync(&dev->kevent);
++
+ if (!pm)
+ usb_autopm_put_interface(dev->intf);
+
+@@ -1173,7 +1188,8 @@ fail_halt:
+ status);
+ } else {
+ clear_bit (EVENT_RX_HALT, &dev->flags);
+- tasklet_schedule (&dev->bh);
++ if (!usbnet_going_away(dev))
++ tasklet_schedule(&dev->bh);
+ }
+ }
+
+@@ -1198,7 +1214,8 @@ fail_halt:
+ usb_autopm_put_interface(dev->intf);
+ fail_lowmem:
+ if (resched)
+- tasklet_schedule (&dev->bh);
++ if (!usbnet_going_away(dev))
++ tasklet_schedule(&dev->bh);
+ }
+ }
+
+@@ -1554,6 +1571,7 @@ static void usbnet_bh (struct timer_list
+ } else if (netif_running (dev->net) &&
+ netif_device_present (dev->net) &&
+ netif_carrier_ok(dev->net) &&
++ !usbnet_going_away(dev) &&
+ !timer_pending(&dev->delay) &&
+ !test_bit(EVENT_RX_PAUSED, &dev->flags) &&
+ !test_bit(EVENT_RX_HALT, &dev->flags)) {
+@@ -1601,6 +1619,7 @@ void usbnet_disconnect (struct usb_inter
+ usb_set_intfdata(intf, NULL);
+ if (!dev)
+ return;
++ usbnet_mark_going_away(dev);
+
+ xdev = interface_to_usbdev (intf);
+
+--- a/include/linux/usb/usbnet.h
++++ b/include/linux/usb/usbnet.h
+@@ -76,8 +76,23 @@ struct usbnet {
+ # define EVENT_LINK_CHANGE 11
+ # define EVENT_SET_RX_MODE 12
+ # define EVENT_NO_IP_ALIGN 13
++/* This one is special, as it indicates that the device is going away
++ * there are cyclic dependencies between tasklet, timer and bh
++ * that must be broken
++ */
++# define EVENT_UNPLUG 31
+ };
+
++static inline bool usbnet_going_away(struct usbnet *ubn)
++{
++ return test_bit(EVENT_UNPLUG, &ubn->flags);
++}
++
++static inline void usbnet_mark_going_away(struct usbnet *ubn)
++{
++ set_bit(EVENT_UNPLUG, &ubn->flags);
++}
++
+ static inline struct usb_driver *driver_of(struct usb_interface *intf)
+ {
+ return to_usb_driver(intf->dev.driver);
--- /dev/null
+From f81dfa3b57c624c56f2bff171c431bc7f5b558f2 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 5 Sep 2024 17:32:59 +0300
+Subject: xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit f81dfa3b57c624c56f2bff171c431bc7f5b558f2 upstream.
+
+PCI xHC host should be stopped and xhci driver memory freed before putting
+host to PCI D3 state during PCI remove callback.
+
+Hosts with XHCI_SPURIOUS_WAKEUP quirk did this the wrong way around
+and set the host to D3 before calling usb_hcd_pci_remove(dev), which will
+access the host to stop it, and then free xhci.
+
+Fixes: f1f6d9a8b540 ("xhci: don't dereference a xhci member after removing xhci")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240905143300.1959279-12-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-pci.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -534,8 +534,10 @@ put_runtime_pm:
+ static void xhci_pci_remove(struct pci_dev *dev)
+ {
+ struct xhci_hcd *xhci;
++ bool set_power_d3;
+
+ xhci = hcd_to_xhci(pci_get_drvdata(dev));
++ set_power_d3 = xhci->quirks & XHCI_SPURIOUS_WAKEUP;
+
+ xhci->xhc_state |= XHCI_STATE_REMOVING;
+
+@@ -548,11 +550,11 @@ static void xhci_pci_remove(struct pci_d
+ xhci->shared_hcd = NULL;
+ }
+
++ usb_hcd_pci_remove(dev);
++
+ /* Workaround for spurious wakeups at shutdown with HSW */
+- if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
++ if (set_power_d3)
+ pci_set_power_state(dev, PCI_D3hot);
+-
+- usb_hcd_pci_remove(dev);
+ }
+
+ #ifdef CONFIG_PM