From d53208876d17c01b7a4eb94b6863f1ea67f68d28 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 1 Oct 2024 12:55:08 +0200 Subject: [PATCH] 5.15-stable patches added patches: bus-integrator-lm-fix-of-node-leak-in-probe.patch crypto-ccp-properly-unregister-dev-sev-on-sev-platform_status-failure.patch firmware_loader-block-path-traversal.patch scsi-mac_scsi-disallow-bus-errors-during-pdma-send.patch scsi-mac_scsi-refactor-polling-loop.patch scsi-mac_scsi-revise-printk-kern_debug-...-messages.patch tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch usb-appledisplay-close-race-between-probe-and-completion-handler.patch usb-cdnsp-fix-incorrect-usb_request-status.patch usb-class-cdc-acm-fix-race-between-get_serial-and-set_serial.patch usb-dwc2-drd-fix-clock-gating-on-usb-role-switch.patch usb-misc-cypress_cy7c63-check-for-short-transfer.patch usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch xhci-set-quirky-xhc-pci-hosts-to-d3-_after_-stopping-and-freeing-them.patch --- ...egrator-lm-fix-of-node-leak-in-probe.patch | 33 ++++ ...v-sev-on-sev-platform_status-failure.patch | 80 ++++++++ ...firmware_loader-block-path-traversal.patch | 106 ++++++++++ ...disallow-bus-errors-during-pdma-send.patch | 143 ++++++++++++++ .../scsi-mac_scsi-refactor-polling-loop.patch | 185 ++++++++++++++++++ ...evise-printk-kern_debug-...-messages.patch | 129 ++++++++++++ queue-5.15/series | 14 ++ ...with-non-forgiving-pcie-host-bridges.patch | 44 +++++ ...between-probe-and-completion-handler.patch | 66 +++++++ ...nsp-fix-incorrect-usb_request-status.patch | 54 +++++ ...ce-between-get_serial-and-set_serial.patch | 41 ++++ ...-fix-clock-gating-on-usb-role-switch.patch | 45 +++++ ...ress_cy7c63-check-for-short-transfer.patch | 42 ++++ ...l-race-on-disconnect-with-work-queue.patch | 140 +++++++++++++ ...d3-_after_-stopping-and-freeing-them.patch | 53 +++++ 15 files changed, 1175 insertions(+) create mode 100644 queue-5.15/bus-integrator-lm-fix-of-node-leak-in-probe.patch create mode 100644 queue-5.15/crypto-ccp-properly-unregister-dev-sev-on-sev-platform_status-failure.patch create mode 100644 queue-5.15/firmware_loader-block-path-traversal.patch create mode 100644 queue-5.15/scsi-mac_scsi-disallow-bus-errors-during-pdma-send.patch create mode 100644 queue-5.15/scsi-mac_scsi-refactor-polling-loop.patch create mode 100644 queue-5.15/scsi-mac_scsi-revise-printk-kern_debug-...-messages.patch create mode 100644 queue-5.15/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch create mode 100644 queue-5.15/usb-appledisplay-close-race-between-probe-and-completion-handler.patch create mode 100644 queue-5.15/usb-cdnsp-fix-incorrect-usb_request-status.patch create mode 100644 queue-5.15/usb-class-cdc-acm-fix-race-between-get_serial-and-set_serial.patch create mode 100644 queue-5.15/usb-dwc2-drd-fix-clock-gating-on-usb-role-switch.patch create mode 100644 queue-5.15/usb-misc-cypress_cy7c63-check-for-short-transfer.patch create mode 100644 queue-5.15/usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch create mode 100644 queue-5.15/xhci-set-quirky-xhc-pci-hosts-to-d3-_after_-stopping-and-freeing-them.patch diff --git a/queue-5.15/bus-integrator-lm-fix-of-node-leak-in-probe.patch b/queue-5.15/bus-integrator-lm-fix-of-node-leak-in-probe.patch new file mode 100644 index 00000000000..347e8c72def --- /dev/null +++ b/queue-5.15/bus-integrator-lm-fix-of-node-leak-in-probe.patch @@ -0,0 +1,33 @@ +From 15a62b81175885b5adfcaf49870466e3603f06c7 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Mon, 26 Aug 2024 07:49:34 +0200 +Subject: bus: integrator-lm: fix OF node leak in probe() + +From: Krzysztof Kozlowski + +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 +Acked-by: Liviu Dudau +Link: https://lore.kernel.org/20240826054934.10724-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman +--- + 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"); diff --git a/queue-5.15/crypto-ccp-properly-unregister-dev-sev-on-sev-platform_status-failure.patch b/queue-5.15/crypto-ccp-properly-unregister-dev-sev-on-sev-platform_status-failure.patch new file mode 100644 index 00000000000..a011549ada3 --- /dev/null +++ b/queue-5.15/crypto-ccp-properly-unregister-dev-sev-on-sev-platform_status-failure.patch @@ -0,0 +1,80 @@ +From ce3d2d6b150ba8528f3218ebf0cee2c2c572662d Mon Sep 17 00:00:00 2001 +From: Pavan Kumar Paluri +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 + +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: + + 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 + + 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 +Acked-by: Tom Lendacky +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1141,6 +1141,8 @@ void sev_pci_init(void) + return; + + err: ++ sev_dev_destroy(psp_master); ++ + psp_master->sev_data = NULL; + } + diff --git a/queue-5.15/firmware_loader-block-path-traversal.patch b/queue-5.15/firmware_loader-block-path-traversal.patch new file mode 100644 index 00000000000..7e9b4be1140 --- /dev/null +++ b/queue-5.15/firmware_loader-block-path-traversal.patch @@ -0,0 +1,106 @@ +From f0e5311aa8022107d63c54e2f03684ec097d1394 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 28 Aug 2024 01:45:48 +0200 +Subject: firmware_loader: Block path traversal + +From: Jann Horn + +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 +Fixes: abb139e75c2c ("firmware: teach the kernel to load firmware files directly from the filesystem") +Signed-off-by: Jann Horn +Acked-by: Luis Chamberlain +Link: https://lore.kernel.org/r/20240828-firmware-traversal-v3-1-c76529c63b5f@google.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -788,6 +788,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, +@@ -808,6 +828,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 */ +@@ -878,6 +906,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. + * diff --git a/queue-5.15/scsi-mac_scsi-disallow-bus-errors-during-pdma-send.patch b/queue-5.15/scsi-mac_scsi-disallow-bus-errors-during-pdma-send.patch new file mode 100644 index 00000000000..c971f962d36 --- /dev/null +++ b/queue-5.15/scsi-mac_scsi-disallow-bus-errors-during-pdma-send.patch @@ -0,0 +1,143 @@ +From 5551bc30e4a69ad86d0d008e2f56cd59b6583476 Mon Sep 17 00:00:00 2001 +From: Finn Thain +Date: Wed, 7 Aug 2024 13:36:28 +1000 +Subject: scsi: mac_scsi: Disallow bus errors during PDMA send + +From: Finn Thain + +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 +Fixes: 7c1f3e3447a1 ("scsi: mac_scsi: Treat Last Byte Sent time-out as failure") +Signed-off-by: Finn Thain +Link: https://lore.kernel.org/r/cc38df687ace2c4ffc375a683b2502fc476b600d.1723001788.git.fthain@linux-m68k.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + 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, diff --git a/queue-5.15/scsi-mac_scsi-refactor-polling-loop.patch b/queue-5.15/scsi-mac_scsi-refactor-polling-loop.patch new file mode 100644 index 00000000000..dcd4e63eb74 --- /dev/null +++ b/queue-5.15/scsi-mac_scsi-refactor-polling-loop.patch @@ -0,0 +1,185 @@ +From 5545c3165cbc98615fe65a44f41167cbb557e410 Mon Sep 17 00:00:00 2001 +From: Finn Thain +Date: Wed, 7 Aug 2024 13:36:28 +1000 +Subject: scsi: mac_scsi: Refactor polling loop + +From: Finn Thain + +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 +Signed-off-by: Finn Thain +Link: https://lore.kernel.org/r/6a5ffabb4290c0d138c6d285fda8fa3902e926f0.1723001788.git.fthain@linux-m68k.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/mac_scsi.c | 80 +++++++++++++++++++++-------------------- + 1 file changed, 42 insertions(+), 38 deletions(-) + +diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c +index e67b038a3577..99a2008f8752 100644 +--- 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 NCR5380_hostdata *hostdata, u32 value) + 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 NCR5380_hostdata *hostdata, + + 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 NCR5380_hostdata *hostdata, + 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 NCR5380_hostdata *hostdata, + 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 NCR5380_hostdata *hostdata, + + 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 NCR5380_hostdata *hostdata, + 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 NCR5380_hostdata *hostdata, + "%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 NCR5380_hostdata *hostdata, + 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; + } + +-- +2.46.2 + diff --git a/queue-5.15/scsi-mac_scsi-revise-printk-kern_debug-...-messages.patch b/queue-5.15/scsi-mac_scsi-revise-printk-kern_debug-...-messages.patch new file mode 100644 index 00000000000..15a8b11282c --- /dev/null +++ b/queue-5.15/scsi-mac_scsi-revise-printk-kern_debug-...-messages.patch @@ -0,0 +1,129 @@ +From 5ec4f820cb9766e4583df947150a6febce8da794 Mon Sep 17 00:00:00 2001 +From: Finn Thain +Date: Wed, 7 Aug 2024 13:36:28 +1000 +Subject: scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages + +From: Finn Thain + +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 +Signed-off-by: Finn Thain +Link: https://lore.kernel.org/r/7573c79f4e488fc00af2b8a191e257ca945e0409.1723001788.git.fthain@linux-m68k.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/mac_scsi.c | 42 +++++++++++++++++++++-------------------- + 1 file changed, 22 insertions(+), 20 deletions(-) + +diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c +index 53ee8f84d094..e67b038a3577 100644 +--- a/drivers/scsi/mac_scsi.c ++++ b/drivers/scsi/mac_scsi.c +@@ -286,13 +286,14 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata, + 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 NCR5380_hostdata *hostdata, + 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 NCR5380_hostdata *hostdata, + 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 NCR5380_hostdata *hostdata, + 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; + } +-- +2.46.2 + diff --git a/queue-5.15/series b/queue-5.15/series index 0cd4095c0ca..a68b4c5eaad 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -308,3 +308,17 @@ input-i8042-add-tuxedo-stellaris-15-slim-gen6-amd-to-i8042-quirk-table.patch input-i8042-add-another-board-name-for-tuxedo-stellaris-gen5-amd-line.patch drm-amd-display-round-calculated-vtotal.patch drm-amd-display-validate-backlight-caps-are-sane.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 +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 +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 diff --git a/queue-5.15/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch b/queue-5.15/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch new file mode 100644 index 00000000000..279829107fa --- /dev/null +++ b/queue-5.15/tty-rp2-fix-reset-with-non-forgiving-pcie-host-bridges.patch @@ -0,0 +1,44 @@ +From f16dd10ba342c429b1e36ada545fb36d4d1f0e63 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Fri, 6 Sep 2024 15:54:33 -0700 +Subject: tty: rp2: Fix reset with non forgiving PCIe host bridges + +From: Florian Fainelli + +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 +Suggested-by: Jim Quinlan +Signed-off-by: Florian Fainelli +Link: https://lore.kernel.org/r/20240906225435.707837-1-florian.fainelli@broadcom.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -598,8 +598,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 */ diff --git a/queue-5.15/usb-appledisplay-close-race-between-probe-and-completion-handler.patch b/queue-5.15/usb-appledisplay-close-race-between-probe-and-completion-handler.patch new file mode 100644 index 00000000000..ba0fa1c5058 --- /dev/null +++ b/queue-5.15/usb-appledisplay-close-race-between-probe-and-completion-handler.patch @@ -0,0 +1,66 @@ +From 8265d06b7794493d82c5c21a12d7ba43eccc30cb Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 12 Sep 2024 14:32:59 +0200 +Subject: USB: appledisplay: close race between probe and completion handler + +From: Oliver Neukum + +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 +CC: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240912123317.1026049-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-5.15/usb-cdnsp-fix-incorrect-usb_request-status.patch b/queue-5.15/usb-cdnsp-fix-incorrect-usb_request-status.patch new file mode 100644 index 00000000000..5dc6d66426c --- /dev/null +++ b/queue-5.15/usb-cdnsp-fix-incorrect-usb_request-status.patch @@ -0,0 +1,54 @@ +From 1702bec4477cc7d31adb4a760d14d33fac928b7a Mon Sep 17 00:00:00 2001 +From: Pawel Laszczak +Date: Fri, 6 Sep 2024 06:48:54 +0000 +Subject: usb: cdnsp: Fix incorrect usb_request status + +From: Pawel Laszczak + +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 +Reviewed-by: Peter Chen +Link: https://lore.kernel.org/r/PH7PR07MB9538E8CA7A2096AAF6A3718FDD9E2@PH7PR07MB9538.namprd07.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } diff --git a/queue-5.15/usb-class-cdc-acm-fix-race-between-get_serial-and-set_serial.patch b/queue-5.15/usb-class-cdc-acm-fix-race-between-get_serial-and-set_serial.patch new file mode 100644 index 00000000000..331b8219e76 --- /dev/null +++ b/queue-5.15/usb-class-cdc-acm-fix-race-between-get_serial-and-set_serial.patch @@ -0,0 +1,41 @@ +From b41c1fa155ba56d125885b0191aabaf3c508d0a3 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +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 + +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 +Cc: stable +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 +--- + 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 +@@ -942,10 +942,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; + } + diff --git a/queue-5.15/usb-dwc2-drd-fix-clock-gating-on-usb-role-switch.patch b/queue-5.15/usb-dwc2-drd-fix-clock-gating-on-usb-role-switch.patch new file mode 100644 index 00000000000..8a7330a8215 --- /dev/null +++ b/queue-5.15/usb-dwc2-drd-fix-clock-gating-on-usb-role-switch.patch @@ -0,0 +1,45 @@ +From 2c6b6afa59e78bebcb65bbc8a76b3459f139547c Mon Sep 17 00:00:00 2001 +From: Tomas Marek +Date: Fri, 6 Sep 2024 07:50:25 +0200 +Subject: usb: dwc2: drd: fix clock gating on USB role switch + +From: Tomas Marek + +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 +Link: https://lore.kernel.org/r/20240906055025.25057-1-tomas.marek@elrest.cz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/drd.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/usb/dwc2/drd.c ++++ b/drivers/usb/dwc2/drd.c +@@ -105,6 +105,15 @@ static int dwc2_drd_role_sw_set(struct u + + spin_lock_irqsave(&hsotg->lock, flags); + ++ 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) { diff --git a/queue-5.15/usb-misc-cypress_cy7c63-check-for-short-transfer.patch b/queue-5.15/usb-misc-cypress_cy7c63-check-for-short-transfer.patch new file mode 100644 index 00000000000..5a3754bcb5f --- /dev/null +++ b/queue-5.15/usb-misc-cypress_cy7c63-check-for-short-transfer.patch @@ -0,0 +1,42 @@ +From 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 12 Sep 2024 14:54:43 +0200 +Subject: USB: misc: cypress_cy7c63: check for short transfer + +From: Oliver Neukum + +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 +CC: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240912125449.1030536-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-5.15/usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch b/queue-5.15/usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch new file mode 100644 index 00000000000..e160f32dd7d --- /dev/null +++ b/queue-5.15/usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch @@ -0,0 +1,140 @@ +From 04e906839a053f092ef53f4fb2d610983412b904 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 19 Sep 2024 14:33:42 +0200 +Subject: usbnet: fix cyclical race on disconnect with work queue + +From: Oliver Neukum + +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 +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -467,10 +467,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); + +@@ -538,7 +543,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"); +@@ -848,9 +854,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); + +@@ -1176,7 +1191,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); + } + } + +@@ -1201,7 +1217,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); + } + } + +@@ -1557,6 +1574,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)) { +@@ -1604,6 +1622,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 +@@ -84,8 +84,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); diff --git a/queue-5.15/xhci-set-quirky-xhc-pci-hosts-to-d3-_after_-stopping-and-freeing-them.patch b/queue-5.15/xhci-set-quirky-xhc-pci-hosts-to-d3-_after_-stopping-and-freeing-them.patch new file mode 100644 index 00000000000..e566469dd1f --- /dev/null +++ b/queue-5.15/xhci-set-quirky-xhc-pci-hosts-to-d3-_after_-stopping-and-freeing-them.patch @@ -0,0 +1,53 @@ +From f81dfa3b57c624c56f2bff171c431bc7f5b558f2 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +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 + +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 +Link: https://lore.kernel.org/r/20240905143300.1959279-12-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -535,8 +535,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; + +@@ -549,11 +551,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 -- 2.47.3