From 960675b76921a154450cd37fc71efb672feb6797 Mon Sep 17 00:00:00 2001 From: Yipeng Zou Date: Sat, 22 Nov 2025 17:39:42 +0800 Subject: [PATCH 0001/1449] timers: Fix NULL function pointer race in timer_shutdown_sync() ANBZ: #35228 commit 6665fbd7730b26d770c232b20d1b907e6a67a914 stable. commit 20739af07383e6eb1ec59dcd70b72ebfa9ac362c upstream. There is a race condition between timer_shutdown_sync() and timer expiration that can lead to hitting a WARN_ON in expire_timers(). The issue occurs when timer_shutdown_sync() clears the timer function to NULL while the timer is still running on another CPU. The race scenario looks like this: CPU0 CPU1 lock_timer_base() expire_timers() base->running_timer = timer; unlock_timer_base() [call_timer_fn enter] mod_timer() ... timer_shutdown_sync() lock_timer_base() // For now, will not detach the timer but only clear its function to NULL if (base->running_timer != timer) ret = detach_if_pending(timer, base, true); if (shutdown) timer->function = NULL; unlock_timer_base() [call_timer_fn exit] lock_timer_base() base->running_timer = NULL; unlock_timer_base() ... // Now timer is pending while its function set to NULL. // next timer trigger expire_timers() WARN_ON_ONCE(!fn) // hit ... lock_timer_base() // Now timer will detach if (base->running_timer != timer) ret = detach_if_pending(timer, base, true); if (shutdown) timer->function = NULL; unlock_timer_base() The problem is that timer_shutdown_sync() clears the timer function regardless of whether the timer is currently running. This can leave a pending timer with a NULL function pointer, which triggers the WARN_ON_ONCE(!fn) check in expire_timers(). Fix this by only clearing the timer function when actually detaching the timer. If the timer is running, leave the function pointer intact, which is safe because the timer will be properly detached when it finishes running. Fixes: 0cc04e80458a ("timers: Add shutdown mechanism to the internal functions") Signed-off-by: Yipeng Zou Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251122093942.301559-1-zouyipeng@huawei.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/time/timer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 63a8ce7177dd..4a2aeaa85af3 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1413,10 +1413,11 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown) base = lock_timer_base(timer, &flags); - if (base->running_timer != timer) + if (base->running_timer != timer) { ret = detach_if_pending(timer, base, true); - if (shutdown) - timer->function = NULL; + if (shutdown) + timer->function = NULL; + } raw_spin_unlock_irqrestore(&base->lock, flags); -- Gitee From a65645aba571fe453630beb42e02b345127e5630 Mon Sep 17 00:00:00 2001 From: Zhang Heng Date: Fri, 12 Sep 2025 20:38:18 +0800 Subject: [PATCH 0002/1449] HID: quirks: work around VID/PID conflict for 0x4c4a/0x4155 ANBZ: #35228 commit 49365455a63c4c628799c8026fb50dbc2c3f7c8a stable. commit beab067dbcff642243291fd528355d64c41dc3b2 upstream. Based on available evidence, the USB ID 4c4a:4155 used by multiple devices has been attributed to Jieli. The commit 1a8953f4f774 ("HID: Add IGNORE quirk for SMARTLINKTECHNOLOGY") affected touchscreen functionality. Added checks for manufacturer and serial number to maintain microphone compatibility, enabling both devices to function properly. [jkosina@suse.com: edit shortlog] Fixes: 1a8953f4f774 ("HID: Add IGNORE quirk for SMARTLINKTECHNOLOGY") Cc: stable@vger.kernel.org Tested-by: staffan.melin@oscillator.se Reviewed-by: Terry Junge Signed-off-by: Zhang Heng Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-ids.h | 4 ++-- drivers/hid/hid-quirks.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index fbbab353f040..6a538dca21a9 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1511,7 +1511,7 @@ #define USB_VENDOR_ID_SIGNOTEC 0x2133 #define USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011 0x0018 -#define USB_VENDOR_ID_SMARTLINKTECHNOLOGY 0x4c4a -#define USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155 0x4155 +#define USB_VENDOR_ID_JIELI_SDK_DEFAULT 0x4c4a +#define USB_DEVICE_ID_JIELI_SDK_4155 0x4155 #endif diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 75480ec3c15a..fa946666969b 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -900,7 +900,6 @@ static const struct hid_device_id hid_ignore_list[] = { #endif { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SMARTLINKTECHNOLOGY, USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155) }, { } }; @@ -1057,6 +1056,18 @@ bool hid_ignore(struct hid_device *hdev) strlen(elan_acpi_id[i].id))) return true; break; + case USB_VENDOR_ID_JIELI_SDK_DEFAULT: + /* + * Multiple USB devices with identical IDs (mic & touchscreen). + * The touch screen requires hid core processing, but the + * microphone does not. They can be distinguished by manufacturer + * and serial number. + */ + if (hdev->product == USB_DEVICE_ID_JIELI_SDK_4155 && + strncmp(hdev->name, "SmartlinkTechnology", 19) == 0 && + strncmp(hdev->uniq, "20201111000001", 14) == 0) + return true; + break; } if (hdev->type == HID_TYPE_USBMOUSE && -- Gitee From 4d1ac4b064917b296624da0f42cfe5e16d69f900 Mon Sep 17 00:00:00 2001 From: Niravkumar L Rabara Date: Thu, 23 Oct 2025 11:32:01 +0800 Subject: [PATCH 0003/1449] mtd: rawnand: cadence: fix DMA device NULL pointer dereference ANBZ: #35228 commit b146e0b085d9d6bfe838e0a15481cba7d093c67f stable. commit 5c56bf214af85ca042bf97f8584aab2151035840 upstream. The DMA device pointer `dma_dev` was being dereferenced before ensuring that `cdns_ctrl->dmac` is properly initialized. Move the assignment of `dma_dev` after successfully acquiring the DMA channel to ensure the pointer is valid before use. Fixes: d76d22b5096c ("mtd: rawnand: cadence: use dma_map_resource for sdma address") Cc: stable@vger.kernel.org Signed-off-by: Niravkumar L Rabara Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/nand/raw/cadence-nand-controller.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c index 4f37ca894d18..202b4fc064fa 100644 --- a/drivers/mtd/nand/raw/cadence-nand-controller.c +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c @@ -2876,7 +2876,7 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl) static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) { dma_cap_mask_t mask; - struct dma_device *dma_dev = cdns_ctrl->dmac->device; + struct dma_device *dma_dev; int ret; cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev, @@ -2920,6 +2920,7 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl) } } + dma_dev = cdns_ctrl->dmac->device; cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma, cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0); -- Gitee From 7a4351e3bdb0c892ee09676ac44a082f70223637 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 30 Sep 2025 20:32:34 +0800 Subject: [PATCH 0004/1449] mtdchar: fix integer overflow in read/write ioctls ANBZ: #35228 commit 457376c6fbf0c69326a9bf1f72416225f681192b stable. commit e4185bed738da755b191aa3f2e16e8b48450e1b8 upstream. The "req.start" and "req.len" variables are u64 values that come from the user at the start of the function. We mask away the high 32 bits of "req.len" so that's capped at U32_MAX but the "req.start" variable can go up to U64_MAX which means that the addition can still integer overflow. Use check_add_overflow() to fix this bug. Fixes: 095bb6e44eb1 ("mtdchar: add MEMREAD ioctl") Fixes: 6420ac0af95d ("mtdchar: prevent unbounded allocation in MEMWRITE ioctl") Cc: stable@vger.kernel.org Signed-off-by: Dan Carpenter Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/mtdchar.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8dc4f5c493fc..335c702633ff 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -599,6 +599,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp) uint8_t *datbuf = NULL, *oobbuf = NULL; size_t datbuf_len, oobbuf_len; int ret = 0; + u64 end; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -618,7 +619,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp) req.len &= 0xffffffff; req.ooblen &= 0xffffffff; - if (req.start + req.len > mtd->size) + if (check_add_overflow(req.start, req.len, &end) || end > mtd->size) return -EINVAL; datbuf_len = min_t(size_t, req.len, mtd->erasesize); @@ -698,6 +699,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp) size_t datbuf_len, oobbuf_len; size_t orig_len, orig_ooblen; int ret = 0; + u64 end; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -724,7 +726,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp) req.len &= 0xffffffff; req.ooblen &= 0xffffffff; - if (req.start + req.len > mtd->size) { + if (check_add_overflow(req.start, req.len, &end) || end > mtd->size) { ret = -EINVAL; goto out; } -- Gitee From b009d020b4a1398a07a32c8f9ced2eec72e4a7e4 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sat, 8 Nov 2025 19:09:47 +0000 Subject: [PATCH 0005/1449] shmem: fix tmpfs reconfiguration (remount) when noswap is set ANBZ: #35228 commit 583990e7dceaa6fd2b8285bfbc4dacae86d4a797 stable. commit 3cd1548a278c7d6a9bdef1f1866e7cf66bfd3518 upstream. In systemd we're trying to switch the internal credentials setup logic to new mount API [1], and I noticed fsconfig(FSCONFIG_CMD_RECONFIGURE) consistently fails on tmpfs with noswap option. This can be trivially reproduced with the following: ``` int fs_fd = fsopen("tmpfs", 0); fsconfig(fs_fd, FSCONFIG_SET_FLAG, "noswap", NULL, 0); fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0); fsmount(fs_fd, 0, 0); fsconfig(fs_fd, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, 0); <------ EINVAL ``` After some digging the culprit is shmem_reconfigure() rejecting !(ctx->seen & SHMEM_SEEN_NOSWAP) && sbinfo->noswap, which is bogus as ctx->seen serves as a mask for whether certain options are touched at all. On top of that, noswap option doesn't use fsparam_flag_no, hence it's not really possible to "reenable" swap to begin with. Drop the check and redundant SHMEM_SEEN_NOSWAP flag. [1] https://github.com/systemd/systemd/pull/39637 Fixes: 2c6efe9cf2d7 ("shmem: add support to ignore swap") Signed-off-by: Mike Yuan Link: https://patch.msgid.link/20251108190930.440685-1-me@yhndnzj.com Cc: Luis Chamberlain Cc: Christian Brauner Cc: Hugh Dickins Cc: stable@vger.kernel.org Signed-off-by: Christian Brauner Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- mm/shmem.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index ad08ac459bc6..b4b84a37636c 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -128,8 +128,7 @@ struct shmem_options { #define SHMEM_SEEN_INODES 2 #define SHMEM_SEEN_HUGE 4 #define SHMEM_SEEN_INUMS 8 -#define SHMEM_SEEN_NOSWAP 16 -#define SHMEM_SEEN_QUOTA 32 +#define SHMEM_SEEN_QUOTA 16 }; #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -4572,7 +4571,6 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) "Turning off swap in unprivileged tmpfs mounts unsupported"); } ctx->noswap = true; - ctx->seen |= SHMEM_SEEN_NOSWAP; break; case Opt_quota: if (fc->user_ns != &init_user_ns) @@ -4722,14 +4720,15 @@ static int shmem_reconfigure(struct fs_context *fc) err = "Current inum too high to switch to 32-bit inums"; goto out; } - if ((ctx->seen & SHMEM_SEEN_NOSWAP) && ctx->noswap && !sbinfo->noswap) { + + /* + * "noswap" doesn't use fsparam_flag_no, i.e. there's no "swap" + * counterpart for (re-)enabling swap. + */ + if (ctx->noswap && !sbinfo->noswap) { err = "Cannot disable swap on remount"; goto out; } - if (!(ctx->seen & SHMEM_SEEN_NOSWAP) && !ctx->noswap && sbinfo->noswap) { - err = "Cannot enable swap on remount if it was disabled on first mount"; - goto out; - } if (ctx->seen & SHMEM_SEEN_QUOTA && !sb_any_quota_loaded(fc->root->d_sb)) { -- Gitee From c0b1ba2b12bcb975b3cc3dc2a13da09def4772c7 Mon Sep 17 00:00:00 2001 From: Yongpeng Yang Date: Tue, 4 Nov 2025 20:50:07 +0800 Subject: [PATCH 0006/1449] exfat: check return value of sb_min_blocksize in exfat_read_boot_sector ANBZ: #35228 commit e65f1a2807c5b33ead9510bf143ce5aec90c31ca stable. commit f2c1f631630e01821fe4c3fdf6077bc7a8284f82 upstream. sb_min_blocksize() may return 0. Check its return value to avoid accessing the filesystem super block when sb->s_blocksize is 0. Cc: stable@vger.kernel.org # v6.15 Fixes: 719c1e1829166d ("exfat: add super block operations") Reviewed-by: Christoph Hellwig Signed-off-by: Yongpeng Yang Link: https://patch.msgid.link/20251104125009.2111925-3-yangyongpeng.storage@gmail.com Signed-off-by: Christian Brauner Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/exfat/super.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 5affc11d1461..957135f20cb6 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -411,7 +411,10 @@ static int exfat_read_boot_sector(struct super_block *sb) struct exfat_sb_info *sbi = EXFAT_SB(sb); /* set block size to read super block */ - sb_min_blocksize(sb, 512); + if (!sb_min_blocksize(sb, 512)) { + exfat_err(sb, "unable to set blocksize"); + return -EINVAL; + } /* read boot sector */ sbi->boot_bh = sb_bread(sb, 0); -- Gitee From 844ac499f5d6081339093beca1ccea6de511d273 Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Tue, 11 Nov 2025 14:02:50 +0800 Subject: [PATCH 0007/1449] mptcp: Disallow MPTCP subflows from sockmap ANBZ: #35228 commit 2ecd37dae7a62bc2d7f79128d126206a27ff2af9 stable. commit fbade4bd08ba52cbc74a71c4e86e736f059f99f7 upstream. The sockmap feature allows bpf syscall from userspace, or based on bpf sockops, replacing the sk_prot of sockets during protocol stack processing with sockmap's custom read/write interfaces. ''' tcp_rcv_state_process() subflow_syn_recv_sock() tcp_init_transfer(BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) bpf_skops_established <== sockops bpf_sock_map_update(sk) <== call bpf helper tcp_bpf_update_proto() <== update sk_prot ''' Consider two scenarios: 1. When the server has MPTCP enabled and the client also requests MPTCP, the sk passed to the BPF program is a subflow sk. Since subflows only handle partial data, replacing their sk_prot is meaningless and will cause traffic disruption. 2. When the server has MPTCP enabled but the client sends a TCP SYN without MPTCP, subflow_syn_recv_sock() performs a fallback on the subflow, replacing the subflow sk's sk_prot with the native sk_prot. ''' subflow_ulp_fallback() subflow_drop_ctx() mptcp_subflow_ops_undo_override() ''' Subsequently, accept::mptcp_stream_accept::mptcp_fallback_tcp_ops() converts the subflow to plain TCP. For the first case, we should prevent it from being combined with sockmap by setting sk_prot->psock_update_sk_prot to NULL, which will be blocked by sockmap's own flow. For the second case, since subflow_syn_recv_sock() has already restored sk_prot to native tcp_prot/tcpv6_prot, no further action is needed. Fixes: cec37a6e41aa ("mptcp: Handle MP_CAPABLE options for outgoing connections") Signed-off-by: Jiayuan Chen Signed-off-by: Martin KaFai Lau Reviewed-by: Matthieu Baerts (NGI0) Cc: Link: https://patch.msgid.link/20251111060307.194196-2-jiayuan.chen@linux.dev Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/subflow.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index dfee1890c841..b71675f46d10 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -2095,6 +2095,10 @@ void __init mptcp_subflow_init(void) tcp_prot_override = tcp_prot; tcp_prot_override.release_cb = tcp_release_cb_override; tcp_prot_override.diag_destroy = tcp_abort_override; +#ifdef CONFIG_BPF_SYSCALL + /* Disable sockmap processing for subflows */ + tcp_prot_override.psock_update_sk_prot = NULL; +#endif #if IS_ENABLED(CONFIG_MPTCP_IPV6) /* In struct mptcp_subflow_request_sock, we assume the TCP request sock @@ -2132,6 +2136,10 @@ void __init mptcp_subflow_init(void) tcpv6_prot_override = tcpv6_prot; tcpv6_prot_override.release_cb = tcp_release_cb_override; tcpv6_prot_override.diag_destroy = tcp_abort_override; +#ifdef CONFIG_BPF_SYSCALL + /* Disable sockmap processing for subflows */ + tcpv6_prot_override.psock_update_sk_prot = NULL; +#endif #endif mptcp_diag_subflow_init(&subflow_ulp_ops); -- Gitee From 67776ebccb5c13b313a7a20dc8cad9f8c40ebef2 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Wed, 19 Nov 2025 22:13:14 +0800 Subject: [PATCH 0008/1449] ata: libata-scsi: Fix system suspend for a security locked drive ANBZ: #35228 commit b8113c1ca469bec01344bac2bebbe1a0bcdf1ba7 stable. commit b11890683380a36b8488229f818d5e76e8204587 upstream. Commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") fixed ata_to_sense_error() to properly generate sense key ABORTED COMMAND (without any additional sense code), instead of the previous bogus sense key ILLEGAL REQUEST with the additional sense code UNALIGNED WRITE COMMAND, for a failed command. However, this broke suspend for Security locked drives (drives that have Security enabled, and have not been Security unlocked by boot firmware). The reason for this is that the SCSI disk driver, for the Synchronize Cache command only, treats any sense data with sense key ILLEGAL REQUEST as a successful command (regardless of ASC / ASCQ). After commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") the code that treats any sense data with sense key ILLEGAL REQUEST as a successful command is no longer applicable, so the command fails, which causes the system suspend to be aborted: sd 1:0:0:0: PM: dpm_run_callback(): scsi_bus_suspend returns -5 sd 1:0:0:0: PM: failed to suspend async: error -5 PM: Some devices failed to suspend, or early wake event detected To make suspend work once again, for a Security locked device only, return sense data LOGICAL UNIT ACCESS NOT AUTHORIZED, the actual sense data which a real SCSI device would have returned if locked. The SCSI disk driver treats this sense data as a successful command. Cc: stable@vger.kernel.org Reported-by: Ilia Baryshnikov Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220704 Fixes: cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") Reviewed-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ata/libata-scsi.c | 7 +++++++ include/linux/ata.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0b2f1e269ca4..f139e8b135d4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -992,6 +992,13 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) return; } + if (ata_id_is_locked(dev->id)) { + /* Security locked */ + /* LOGICAL UNIT ACCESS NOT AUTHORIZED */ + ata_scsi_set_sense(dev, cmd, DATA_PROTECT, 0x74, 0x71); + return; + } + if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ata_dev_dbg(dev, "Missing result TF: reporting aborted command\n"); diff --git a/include/linux/ata.h b/include/linux/ata.h index 792e10a09787..c9013e472aa3 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -566,6 +566,7 @@ struct ata_bmdma_prd { #define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8)) #define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1) #define ata_id_removable(id) ((id)[ATA_ID_CONFIG] & (1 << 7)) +#define ata_id_is_locked(id) (((id)[ATA_ID_DLF] & 0x7) == 0x7) #define ata_id_has_atapi_AN(id) \ ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ -- Gitee From dfc879b22e486df85c22b64de0726cc5dbacaf98 Mon Sep 17 00:00:00 2001 From: Henrique Carvalho Date: Fri, 14 Nov 2025 02:09:13 +0800 Subject: [PATCH 0009/1449] smb: client: introduce close_cached_dir_locked() ANBZ: #35228 commit 2a494b9e63646a7698a3b1c5d9df4e216438bf8f stable. commit a9d1f38df7ecd0e21233447c9cc6fa1799eddaf3 upstream. Replace close_cached_dir() calls under cfid_list_lock with a new close_cached_dir_locked() variant that uses kref_put() instead of kref_put_lock() to avoid recursive locking when dropping references. While the existing code works if the refcount >= 2 invariant holds, this area has proven error-prone. Make deadlocks impossible and WARN on invariant violations. Cc: stable@vger.kernel.org Reviewed-by: David Howells Signed-off-by: Henrique Carvalho Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/cached_dir.c | 41 +++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 539a9038fb0d..3fefe5e7b16f 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -16,6 +16,7 @@ static struct cached_fid *init_cached_dir(const char *path); static void free_cached_dir(struct cached_fid *cfid); static void smb2_close_cached_fid(struct kref *ref); static void cfids_laundromat_worker(struct work_struct *work); +static void close_cached_dir_locked(struct cached_fid *cfid); struct cached_dir_dentry { struct list_head entry; @@ -362,7 +363,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, * lease. Release one here, and the second below. */ cfid->has_lease = false; - close_cached_dir(cfid); + close_cached_dir_locked(cfid); } spin_unlock(&cfids->cfid_list_lock); @@ -448,18 +449,52 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon, spin_lock(&cfid->cfids->cfid_list_lock); if (cfid->has_lease) { cfid->has_lease = false; - close_cached_dir(cfid); + close_cached_dir_locked(cfid); } spin_unlock(&cfid->cfids->cfid_list_lock); close_cached_dir(cfid); } - +/** + * close_cached_dir - drop a reference of a cached dir + * + * The release function will be called with cfid_list_lock held to remove the + * cached dirs from the list before any other thread can take another @cfid + * ref. Must not be called with cfid_list_lock held; use + * close_cached_dir_locked() called instead. + * + * @cfid: cached dir + */ void close_cached_dir(struct cached_fid *cfid) { + lockdep_assert_not_held(&cfid->cfids->cfid_list_lock); kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock); } +/** + * close_cached_dir_locked - put a reference of a cached dir with + * cfid_list_lock held + * + * Calling close_cached_dir() with cfid_list_lock held has the potential effect + * of causing a deadlock if the invariant of refcount >= 2 is false. + * + * This function is used in paths that hold cfid_list_lock and expect at least + * two references. If that invariant is violated, WARNs and returns without + * dropping a reference; the final put must still go through + * close_cached_dir(). + * + * @cfid: cached dir + */ +static void close_cached_dir_locked(struct cached_fid *cfid) +{ + lockdep_assert_held(&cfid->cfids->cfid_list_lock); + + if (WARN_ON(kref_read(&cfid->refcount) < 2)) + return; + + kref_put(&cfid->refcount, smb2_close_cached_fid); +} + /* * Called from cifs_kill_sb when we unmount a share */ -- Gitee From 964b43fd89529f75af250bac832da7e379c14e9c Mon Sep 17 00:00:00 2001 From: Yihang Li Date: Thu, 20 Nov 2025 11:50:23 +0800 Subject: [PATCH 0010/1449] ata: libata-scsi: Add missing scsi_device_put() in ata_scsi_dev_rescan() ANBZ: #35228 commit 5968bcf785c668f13162a14a0feb0498653dd337 stable. commit b32cc17d607e8ae7af037303fe101368cb4dc44c upstream. Call scsi_device_put() in ata_scsi_dev_rescan() if the device or its queue are not running. Fixes: 0c76106cb975 ("scsi: sd: Fix TCG OPAL unlock on system resume") Cc: stable@vger.kernel.org Signed-off-by: Yihang Li Reviewed-by: Damien Le Moal Signed-off-by: Niklas Cassel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ata/libata-scsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f139e8b135d4..8f6a7acf770e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4838,8 +4838,10 @@ void ata_scsi_dev_rescan(struct work_struct *work) spin_unlock_irqrestore(ap->lock, flags); if (do_resume) { ret = scsi_resume_device(sdev); - if (ret == -EWOULDBLOCK) + if (ret == -EWOULDBLOCK) { + scsi_device_put(sdev); goto unlock_scan; + } dev->flags &= ~ATA_DFLAG_RESUMING; } ret = scsi_rescan_device(sdev); -- Gitee From 5673dbf9d19aa9230f75985667f4e0b61330d155 Mon Sep 17 00:00:00 2001 From: Andrey Vatoropin Date: Wed, 19 Nov 2025 18:51:12 +0800 Subject: [PATCH 0011/1449] be2net: pass wrb_params in case of OS2BMC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit ce0a3699244aca3acb659f143c9cb1327b210f89 stable. commit 7d277a7a58578dd62fd546ddaef459ec24ccae36 upstream. be_insert_vlan_in_pkt() is called with the wrb_params argument being NULL at be_send_pkt_to_bmc() call site.  This may lead to dereferencing a NULL pointer when processing a workaround for specific packet, as commit bc0c3405abbb ("be2net: fix a Tx stall bug caused by a specific ipv6 packet") states. The correct way would be to pass the wrb_params from be_xmit(). Fixes: 760c295e0e8d ("be2net: Support for OS2BMC.") Cc: stable@vger.kernel.org Signed-off-by: Andrey Vatoropin Link: https://patch.msgid.link/20251119105015.194501-1-a.vatoropin@crpt.ru Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/emulex/benet/be_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 490af6659429..8c3314445aca 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1296,7 +1296,8 @@ static void be_xmit_flush(struct be_adapter *adapter, struct be_tx_obj *txo) (adapter->bmc_filt_mask & BMC_FILT_MULTICAST) static bool be_send_pkt_to_bmc(struct be_adapter *adapter, - struct sk_buff **skb) + struct sk_buff **skb, + struct be_wrb_params *wrb_params) { struct ethhdr *eh = (struct ethhdr *)(*skb)->data; bool os2bmc = false; @@ -1360,7 +1361,7 @@ static bool be_send_pkt_to_bmc(struct be_adapter *adapter, * to BMC, asic expects the vlan to be inline in the packet. */ if (os2bmc) - *skb = be_insert_vlan_in_pkt(adapter, *skb, NULL); + *skb = be_insert_vlan_in_pkt(adapter, *skb, wrb_params); return os2bmc; } @@ -1387,7 +1388,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) /* if os2bmc is enabled and if the pkt is destined to bmc, * enqueue the pkt a 2nd time with mgmt bit set. */ - if (be_send_pkt_to_bmc(adapter, &skb)) { + if (be_send_pkt_to_bmc(adapter, &skb, &wrb_params)) { BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); if (unlikely(!wrb_cnt)) -- Gitee From 273f51e1a80f94e11fba54cef6b5701a13af4068 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 14 Nov 2025 17:09:51 +0800 Subject: [PATCH 0012/1449] net: dsa: microchip: lan937x: Fix RGMII delay tuning ANBZ: #35228 commit 00c56d55332c9c5286d4d2e7386f6997018544d4 stable. commit 3ceb6ac2116ecda1c5d779bb73271479e70fccb4 upstream. Correct RGMII delay application logic in lan937x_set_tune_adj(). The function was missing `data16 &= ~PORT_TUNE_ADJ` before setting the new delay value. This caused the new value to be bitwise-OR'd with the existing PORT_TUNE_ADJ field instead of replacing it. For example, when setting the RGMII 2 TX delay on port 4, the intended TUNE_ADJUST value of 0 (RGMII_2_TX_DELAY_2NS) was incorrectly OR'd with the default 0x1B (from register value 0xDA3), leaving the delay at the wrong setting. This patch adds the missing mask to clear the field, ensuring the correct delay value is written. Physical measurements on the RGMII TX lines confirm the fix, showing the delay changing from ~1ns (before change) to ~2ns. While testing on i.MX 8MP showed this was within the platform's timing tolerance, it did not match the intended hardware-characterized value. Fixes: b19ac41faa3f ("net: dsa: microchip: apply rgmii tx and rx delay in phylink mac config") Cc: stable@vger.kernel.org Signed-off-by: Oleksij Rempel Link: https://patch.msgid.link/20251114090951.4057261-1-o.rempel@pengutronix.de Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/microchip/lan937x_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c index dde37e61faa3..d2e98b5f0aca 100644 --- a/drivers/net/dsa/microchip/lan937x_main.c +++ b/drivers/net/dsa/microchip/lan937x_main.c @@ -336,6 +336,7 @@ static void lan937x_set_tune_adj(struct ksz_device *dev, int port, ksz_pread16(dev, port, reg, &data16); /* Update tune Adjust */ + data16 &= ~PORT_TUNE_ADJ; data16 |= FIELD_PREP(PORT_TUNE_ADJ, val); ksz_pwrite16(dev, port, reg, data16); -- Gitee From 9e6e03c30af9a2448d0c931ea0666c96d0ff61b5 Mon Sep 17 00:00:00 2001 From: Diogo Ivo Date: Mon, 3 Nov 2025 22:14:15 +0800 Subject: [PATCH 0013/1449] Revert "drm/tegra: dsi: Clear enable register if powered by bootloader" ANBZ: #35228 commit 7419d8064dab6f8a8ffef4c40ad8ba220cc06670 stable. commit 660b299bed2a2a55a1f9102d029549d0235f881c upstream. Commit b6bcbce33596 ("soc/tegra: pmc: Ensure power-domains are in a known state") was introduced so that all power domains get initialized to a known working state when booting and it does this by shutting them down (including asserting resets and disabling clocks) before registering each power domain with the genpd framework, leaving it to each driver to later on power its needed domains. This caused the Google Pixel C to hang when booting due to a workaround in the DSI driver introduced in commit b22fd0b9639e ("drm/tegra: dsi: Clear enable register if powered by bootloader") meant to handle the case where the bootloader enabled the DSI hardware module. The workaround relies on reading a hardware register to determine the current status and after b6bcbce33596 that now happens in a powered down state thus leading to the boot hang. Fix this by reverting b22fd0b9639e since currently we are guaranteed that the hardware will be fully reset by the time we start enabling the DSI module. Fixes: b6bcbce33596 ("soc/tegra: pmc: Ensure power-domains are in a known state") Cc: stable@vger.kernel.org Signed-off-by: Diogo Ivo Signed-off-by: Thierry Reding Link: https://patch.msgid.link/20251103-diogo-smaug_ec_typec-v1-1-be656ccda391@tecnico.ulisboa.pt Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/tegra/dsi.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 839dbad9bc48..49fc4690c63a 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -912,15 +912,6 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) u32 value; int err; - /* If the bootloader enabled DSI it needs to be disabled - * in order for the panel initialization commands to be - * properly sent. - */ - value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL); - - if (value & DSI_POWER_CONTROL_ENABLE) - tegra_dsi_disable(dsi); - err = tegra_dsi_prepare(dsi); if (err < 0) { dev_err(dsi->dev, "failed to prepare: %d\n", err); -- Gitee From 377d3820c8c2556e76543f64315f095693a8cd18 Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Tue, 4 Nov 2025 15:03:10 +0800 Subject: [PATCH 0014/1449] Input: cros_ec_keyb - fix an invalid memory access ANBZ: #35228 commit 9cf59f4724a9ee06ebb06c76b8678ac322e850b7 stable. commit e08969c4d65ac31297fcb4d31d4808c789152f68 upstream. If cros_ec_keyb_register_matrix() isn't called (due to `buttons_switches_only`) in cros_ec_keyb_probe(), `ckdev->idev` remains NULL. An invalid memory access is observed in cros_ec_keyb_process() when receiving an EC_MKBP_EVENT_KEY_MATRIX event in cros_ec_keyb_work() in such case. Unable to handle kernel read from unreadable memory at virtual address 0000000000000028 ... x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000 Call trace: input_event cros_ec_keyb_work blocking_notifier_call_chain ec_irq_thread It's still unknown about why the kernel receives such malformed event, in any cases, the kernel shouldn't access `ckdev->idev` and friends if the driver doesn't intend to initialize them. Signed-off-by: Tzung-Bi Shih Link: https://patch.msgid.link/20251104070310.3212712-1-tzungbi@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/keyboard/cros_ec_keyb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index e7ecfca838df..76fcf90ea7c7 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -263,6 +263,12 @@ static int cros_ec_keyb_work(struct notifier_block *nb, case EC_MKBP_EVENT_KEY_MATRIX: pm_wakeup_event(ckdev->dev, 0); + if (!ckdev->idev) { + dev_warn_once(ckdev->dev, + "Unexpected key matrix event\n"); + return NOTIFY_OK; + } + if (ckdev->ec->event_size != ckdev->cols) { dev_err(ckdev->dev, "Discarded incomplete key matrix event.\n"); -- Gitee From f38d830bb4fdbfcdf5029805b17c91b4f77bb07b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 14 Oct 2025 00:15:25 +0800 Subject: [PATCH 0015/1449] Input: goodix - add support for ACPI ID GDIX1003 ANBZ: #35228 commit 8a2d2a536c76ef511c159231b84cda0a3ad55ca7 stable. commit c6d99e488117201c63efd747ce17b80687c3f5a9 upstream. Some newer devices use an ACPI hardware ID of GDIX1003 for their Goodix touchscreen controller, instead of GDIX1001 / GDIX1002. Add GDIX1003 to the goodix_acpi_match[] table. Reported-by: Weikang Guo Closes: https://lore.kernel.org/linux-input/20250225024409.1467040-1-guoweikang.kernel@gmail.com/ Tested-by: Weikang Guo Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20251013121022.44333-1-hansg@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/touchscreen/goodix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index b068ff8afbc9..294bd942ee37 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -1519,6 +1519,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id); static const struct acpi_device_id goodix_acpi_match[] = { { "GDIX1001", 0 }, { "GDIX1002", 0 }, + { "GDIX1003", 0 }, { "GDX9110", 0 }, { } }; -- Gitee From 4367af7af217b2d9a2ca63fda936b8df69eada6b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 1 Nov 2025 21:25:27 +0800 Subject: [PATCH 0016/1449] Input: imx_sc_key - fix memory corruption on unload ANBZ: #35228 commit ca9a08de9b294422376f47ade323d69590dbc6f2 stable. commit d83f1512758f4ef6fc5e83219fe7eeeb6b428ea4 upstream. This is supposed to be "priv" but we accidentally pass "&priv" which is an address in the stack and so it will lead to memory corruption when the imx_sc_key_action() function is called. Remove the &. Fixes: 768062fd1284 ("Input: imx_sc_key - use devm_add_action_or_reset() to handle all cleanups") Signed-off-by: Dan Carpenter Reviewed-by: Peng Fan Reviewed-by: Frank Li Link: https://patch.msgid.link/aQYKR75r2VMFJutT@stanley.mountain Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/keyboard/imx_sc_key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c index d18839f1f4f6..b620cd310cdb 100644 --- a/drivers/input/keyboard/imx_sc_key.c +++ b/drivers/input/keyboard/imx_sc_key.c @@ -158,7 +158,7 @@ static int imx_sc_key_probe(struct platform_device *pdev) return error; } - error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, &priv); + error = devm_add_action_or_reset(&pdev->dev, imx_sc_key_action, priv); if (error) return error; -- Gitee From 9dd2f9c5ec1b9463e890d06ea73932b6ddcbee3b Mon Sep 17 00:00:00 2001 From: Seungjin Bae Date: Sat, 18 Oct 2025 06:36:31 +0800 Subject: [PATCH 0017/1449] Input: pegasus-notetaker - fix potential out-of-bounds access ANBZ: #35228 commit d344ea1baf1946c90f0cd6f9daeb5f3e0a0ca479 stable. commit 69aeb507312306f73495598a055293fa749d454e upstream. In the pegasus_notetaker driver, the pegasus_probe() function allocates the URB transfer buffer using the wMaxPacketSize value from the endpoint descriptor. An attacker can use a malicious USB descriptor to force the allocation of a very small buffer. Subsequently, if the device sends an interrupt packet with a specific pattern (e.g., where the first byte is 0x80 or 0x42), the pegasus_parse_packet() function parses the packet without checking the allocated buffer size. This leads to an out-of-bounds memory access. Fixes: 1afca2b66aac ("Input: add Pegasus Notetaker tablet driver") Signed-off-by: Seungjin Bae Link: https://lore.kernel.org/r/20251007214131.3737115-2-eeodqql09@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/tablet/pegasus_notetaker.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c index a68da2988f9c..26ab9924a7ae 100644 --- a/drivers/input/tablet/pegasus_notetaker.c +++ b/drivers/input/tablet/pegasus_notetaker.c @@ -63,6 +63,9 @@ #define BUTTON_PRESSED 0xb5 #define COMMAND_VERSION 0xa9 +/* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */ +#define NOTETAKER_PACKET_SIZE 6 + /* in xy data packet */ #define BATTERY_NO_REPORT 0x40 #define BATTERY_LOW 0x41 @@ -303,6 +306,12 @@ static int pegasus_probe(struct usb_interface *intf, } pegasus->data_len = usb_maxpacket(dev, pipe); + if (pegasus->data_len < NOTETAKER_PACKET_SIZE) { + dev_err(&intf->dev, "packet size is too small (%d)\n", + pegasus->data_len); + error = -EINVAL; + goto err_free_mem; + } pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, &pegasus->data_dma); -- Gitee From 0eef0dd3fe452420c087eb6b26d340fc15d50291 Mon Sep 17 00:00:00 2001 From: Nam Cao Date: Mon, 17 Nov 2025 16:42:31 +0800 Subject: [PATCH 0018/1449] nouveau/firmware: Add missing kfree() of nvkm_falcon_fw::boot ANBZ: #35228 commit 7d1977b4ae5c50e1aafc5c51500fc08bd7afd6a0 stable. commit 949f1fd2225baefbea2995afa807dba5cbdb6bd3 upstream. nvkm_falcon_fw::boot is allocated, but no one frees it. This causes a kmemleak warning. Make sure this data is deallocated. Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs") Signed-off-by: Nam Cao Cc: stable@vger.kernel.org Reviewed-by: Lyude Paul Signed-off-by: Lyude Paul Link: https://patch.msgid.link/20251117084231.2910561-1-namcao@linutronix.de Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/nouveau/nvkm/falcon/fw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c b/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c index cac6d64ab67d..4e8b3f1c7e25 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c @@ -159,6 +159,8 @@ nvkm_falcon_fw_dtor(struct nvkm_falcon_fw *fw) nvkm_memory_unref(&fw->inst); nvkm_falcon_fw_dtor_sigs(fw); nvkm_firmware_dtor(&fw->fw); + kfree(fw->boot); + fw->boot = NULL; } static const struct nvkm_firmware_func -- Gitee From 4883145208d72fc33c85023ec49ff55b6cdd088d Mon Sep 17 00:00:00 2001 From: "Ewan D. Milne" Date: Tue, 11 Nov 2025 05:20:00 +0800 Subject: [PATCH 0019/1449] nvme: nvme-fc: move tagset removal to nvme_fc_delete_ctrl() ANBZ: #35228 commit 5fe335a80548e2eda5d51fab801108b323600e95 stable. commit ea3442efabd0aa3930c5bab73c3901ef38ef6ac3 upstream. Now target is removed from nvme_fc_ctrl_free() which is the ctrl->ref release handler. And even admin queue is unquiesced there, this way is definitely wrong because the ctr->ref is grabbed when submitting command. And Marco observed that nvme_fc_ctrl_free() can be called from request completion code path, and trigger kernel warning since request completes from softirq context. Fix the issue by moveing target removal into nvme_fc_delete_ctrl(), which is also aligned with nvme-tcp and nvme-rdma. Patch originally proposed by Ming Lei, then modified to move the tagset removal down to after nvme_fc_delete_association() after further testing. Cc: Marco Patalano Cc: Ewan Milne Cc: James Smart Cc: Sagi Grimberg Signed-off-by: Ming Lei Cc: stable@vger.kernel.org Tested-by: Marco Patalano Reviewed-by: Justin Tee Signed-off-by: Ewan D. Milne Signed-off-by: Keith Busch Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/fc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index bf9ab0725764..9e3a584620e9 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2349,17 +2349,11 @@ nvme_fc_ctrl_free(struct kref *ref) container_of(ref, struct nvme_fc_ctrl, ref); unsigned long flags; - if (ctrl->ctrl.tagset) - nvme_remove_io_tag_set(&ctrl->ctrl); - /* remove from rport list */ spin_lock_irqsave(&ctrl->rport->lock, flags); list_del(&ctrl->ctrl_list); spin_unlock_irqrestore(&ctrl->rport->lock, flags); - nvme_unquiesce_admin_queue(&ctrl->ctrl); - nvme_remove_admin_tag_set(&ctrl->ctrl); - kfree(ctrl->queues); put_device(ctrl->dev); @@ -3250,11 +3244,18 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) cancel_work_sync(&ctrl->ioerr_work); cancel_delayed_work_sync(&ctrl->connect_work); + /* * kill the association on the link side. this will block * waiting for io to terminate */ nvme_fc_delete_association(ctrl); + + if (ctrl->ctrl.tagset) + nvme_remove_io_tag_set(&ctrl->ctrl); + + nvme_unquiesce_admin_queue(&ctrl->ctrl); + nvme_remove_admin_tag_set(&ctrl->ctrl); } static void -- Gitee From 738e3b704a41327d0303f44d3b98a3fc3c2d38ff Mon Sep 17 00:00:00 2001 From: "Ewan D. Milne" Date: Tue, 11 Nov 2025 05:20:01 +0800 Subject: [PATCH 0020/1449] nvme: nvme-fc: Ensure ->ioerr_work is cancelled in nvme_fc_delete_ctrl() ANBZ: #35228 commit 33f64600a12055219bda38b55320c62cdeda9167 stable. commit 0a2c5495b6d1ecb0fa18ef6631450f391a888256 upstream. nvme_fc_delete_assocation() waits for pending I/O to complete before returning, and an error can cause ->ioerr_work to be queued after cancel_work_sync() had been called. Move the call to cancel_work_sync() to be after nvme_fc_delete_association() to ensure ->ioerr_work is not running when the nvme_fc_ctrl object is freed. Otherwise the following can occur: [ 1135.911754] list_del corruption, ff2d24c8093f31f8->next is NULL [ 1135.917705] ------------[ cut here ]------------ [ 1135.922336] kernel BUG at lib/list_debug.c:52! [ 1135.926784] Oops: invalid opcode: 0000 [#1] SMP NOPTI [ 1135.931851] CPU: 48 UID: 0 PID: 726 Comm: kworker/u449:23 Kdump: loaded Not tainted 6.12.0 #1 PREEMPT(voluntary) [ 1135.943490] Hardware name: Dell Inc. PowerEdge R660/0HGTK9, BIOS 2.5.4 01/16/2025 [ 1135.950969] Workqueue: 0x0 (nvme-wq) [ 1135.954673] RIP: 0010:__list_del_entry_valid_or_report.cold+0xf/0x6f [ 1135.961041] Code: c7 c7 98 68 72 94 e8 26 45 fe ff 0f 0b 48 c7 c7 70 68 72 94 e8 18 45 fe ff 0f 0b 48 89 fe 48 c7 c7 80 69 72 94 e8 07 45 fe ff <0f> 0b 48 89 d1 48 c7 c7 a0 6a 72 94 48 89 c2 e8 f3 44 fe ff 0f 0b [ 1135.979788] RSP: 0018:ff579b19482d3e50 EFLAGS: 00010046 [ 1135.985015] RAX: 0000000000000033 RBX: ff2d24c8093f31f0 RCX: 0000000000000000 [ 1135.992148] RDX: 0000000000000000 RSI: ff2d24d6bfa1d0c0 RDI: ff2d24d6bfa1d0c0 [ 1135.999278] RBP: ff2d24c8093f31f8 R08: 0000000000000000 R09: ffffffff951e2b08 [ 1136.006413] R10: ffffffff95122ac8 R11: 0000000000000003 R12: ff2d24c78697c100 [ 1136.013546] R13: fffffffffffffff8 R14: 0000000000000000 R15: ff2d24c78697c0c0 [ 1136.020677] FS: 0000000000000000(0000) GS:ff2d24d6bfa00000(0000) knlGS:0000000000000000 [ 1136.028765] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1136.034510] CR2: 00007fd207f90b80 CR3: 000000163ea22003 CR4: 0000000000f73ef0 [ 1136.041641] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1136.048776] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 1136.055910] PKRU: 55555554 [ 1136.058623] Call Trace: [ 1136.061074] [ 1136.063179] ? show_trace_log_lvl+0x1b0/0x2f0 [ 1136.067540] ? show_trace_log_lvl+0x1b0/0x2f0 [ 1136.071898] ? move_linked_works+0x4a/0xa0 [ 1136.075998] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.081744] ? __die_body.cold+0x8/0x12 [ 1136.085584] ? die+0x2e/0x50 [ 1136.088469] ? do_trap+0xca/0x110 [ 1136.091789] ? do_error_trap+0x65/0x80 [ 1136.095543] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.101289] ? exc_invalid_op+0x50/0x70 [ 1136.105127] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.110874] ? asm_exc_invalid_op+0x1a/0x20 [ 1136.115059] ? __list_del_entry_valid_or_report.cold+0xf/0x6f [ 1136.120806] move_linked_works+0x4a/0xa0 [ 1136.124733] worker_thread+0x216/0x3a0 [ 1136.128485] ? __pfx_worker_thread+0x10/0x10 [ 1136.132758] kthread+0xfa/0x240 [ 1136.135904] ? __pfx_kthread+0x10/0x10 [ 1136.139657] ret_from_fork+0x31/0x50 [ 1136.143236] ? __pfx_kthread+0x10/0x10 [ 1136.146988] ret_from_fork_asm+0x1a/0x30 [ 1136.150915] Fixes: 19fce0470f05 ("nvme-fc: avoid calling _nvme_fc_abort_outstanding_ios from interrupt context") Cc: stable@vger.kernel.org Tested-by: Marco Patalano Reviewed-by: Justin Tee Signed-off-by: Ewan D. Milne Signed-off-by: Keith Busch Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/fc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 9e3a584620e9..37fede155b92 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3242,7 +3242,6 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) { struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); - cancel_work_sync(&ctrl->ioerr_work); cancel_delayed_work_sync(&ctrl->connect_work); /* @@ -3250,6 +3249,7 @@ nvme_fc_delete_ctrl(struct nvme_ctrl *nctrl) * waiting for io to terminate */ nvme_fc_delete_association(ctrl); + cancel_work_sync(&ctrl->ioerr_work); if (ctrl->ctrl.tagset) nvme_remove_io_tag_set(&ctrl->ctrl); -- Gitee From 7a2bf4d94f6e317cdcff542a9f14fb236d48398d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 14 Nov 2025 02:16:43 +0800 Subject: [PATCH 0021/1449] scsi: sg: Do not sleep in atomic context ANBZ: #35228 commit b343cee5df7e750d9033fba33e96fc4399fa88a5 stable. commit 90449f2d1e1f020835cba5417234636937dd657e upstream. sg_finish_rem_req() calls blk_rq_unmap_user(). The latter function may sleep. Hence, call sg_finish_rem_req() with interrupts enabled instead of disabled. Reported-by: syzbot+c01f8e6e73f20459912e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-scsi/691560c4.a70a0220.3124cb.001a.GAE@google.com/ Cc: Hannes Reinecke Cc: stable@vger.kernel.org Fixes: 97d27b0dd015 ("scsi: sg: close race condition in sg_remove_sfp_usercontext()") Signed-off-by: Bart Van Assche Link: https://patch.msgid.link/20251113181643.1108973-1-bvanassche@acm.org Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/sg.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 62574886a911..9258a1a8c23c 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2212,9 +2212,17 @@ sg_remove_sfp_usercontext(struct work_struct *work) write_lock_irqsave(&sfp->rq_list_lock, iflags); while (!list_empty(&sfp->rq_list)) { srp = list_first_entry(&sfp->rq_list, Sg_request, entry); - sg_finish_rem_req(srp); list_del(&srp->entry); + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + sg_finish_rem_req(srp); + /* + * sg_rq_end_io() uses srp->parentfp. Hence, only clear + * srp->parentfp after blk_mq_free_request() has been called. + */ srp->parentfp = NULL; + + write_lock_irqsave(&sfp->rq_list_lock, iflags); } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); -- Gitee From d1924d57e7293215e1b3231f73514feb163971ab Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Thu, 6 Nov 2025 03:25:46 +0800 Subject: [PATCH 0022/1449] scsi: target: tcm_loop: Fix segfault in tcm_loop_tpg_address_show() ANBZ: #35228 commit a6ef60898ddaf1414592ce3e5b0d94276d631663 stable. commit e6965188f84a7883e6a0d3448e86b0cf29b24dfc upstream. If the allocation of tl_hba->sh fails in tcm_loop_driver_probe() and we attempt to dereference it in tcm_loop_tpg_address_show() we will get a segfault, see below for an example. So, check tl_hba->sh before dereferencing it. Unable to allocate struct scsi_host BUG: kernel NULL pointer dereference, address: 0000000000000194 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 1 PID: 8356 Comm: tokio-runtime-w Not tainted 6.6.104.2-4.azl3 #1 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 09/28/2024 RIP: 0010:tcm_loop_tpg_address_show+0x2e/0x50 [tcm_loop] ... Call Trace: configfs_read_iter+0x12d/0x1d0 [configfs] vfs_read+0x1b5/0x300 ksys_read+0x6f/0xf0 ... Cc: stable@vger.kernel.org Fixes: 2628b352c3d4 ("tcm_loop: Show address of tpg in configfs") Signed-off-by: Hamza Mahfooz Reviewed-by: Chaitanya Kulkarni Reviewed-by: Allen Pais Link: https://patch.msgid.link/1762370746-6304-1-git-send-email-hamzamahfooz@linux.microsoft.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/target/loopback/tcm_loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 379d2c8ba30c..4f143f6f0316 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -897,6 +897,9 @@ static ssize_t tcm_loop_tpg_address_show(struct config_item *item, struct tcm_loop_tpg, tl_se_tpg); struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; + if (!tl_hba->sh) + return -ENODEV; + return snprintf(page, PAGE_SIZE, "%d:0:%d\n", tl_hba->sh->host_no, tl_tpg->tl_tpgt); } -- Gitee From 7e841ffbb5280802389f76ced3dd8fd15c22b54d Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 20 Oct 2025 09:11:49 +0800 Subject: [PATCH 0023/1449] MIPS: Malta: Fix !EVA SOC-it PCI MMIO ANBZ: #35228 commit 5ea58bb47c50a42807ee54b9a403d829263ad7fc stable. commit ebd729fef31620e0bf74cbf8a4c7fda73a2a4e7e upstream. Fix a regression that has caused accesses to the PCI MMIO window to complete unclaimed in non-EVA configurations with the SOC-it family of system controllers, preventing PCI devices from working that use MMIO. In the non-EVA case PHYS_OFFSET is set to 0, meaning that PCI_BAR0 is set with an empty mask (and PCI_HEAD4 matches addresses starting from 0 accordingly). Consequently all addresses are matched for incoming DMA accesses from PCI. This seems to confuse the system controller's logic and outgoing bus cycles targeting the PCI MMIO window seem not to make it to the intended devices. This happens as well when a wider mask is used with PCI_BAR0, such as 0x80000000 or 0xe0000000, that makes addresses match that overlap with the PCI MMIO window, which starts at 0x10000000 in our configuration. Set the mask in PCI_BAR0 to 0xf0000000 for non-EVA then, covering the non-EVA maximum 256 MiB of RAM, which is what YAMON does and which used to work correctly up to the offending commit. Set PCI_P2SCMSKL to match PCI_BAR0 as required by the system controller's specification, and match PCI_P2SCMAPL to PCI_HEAD4 for identity mapping. Verified with: Core board type/revision = 0x0d (Core74K) / 0x01 System controller/revision = MIPS SOC-it 101 OCP / 1.3 SDR-FW-4:1 Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x1c Processor ID/revision = 0x97 (MIPS 74Kf) / 0x4c for non-EVA and with: Core board type/revision = 0x0c (CoreFPGA-5) / 0x00 System controller/revision = MIPS ROC-it2 / 0.0 FW-1:1 (CLK_unknown) GIC Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00 Processor ID/revision = 0xa0 (MIPS interAptiv UP) / 0x20 for EVA/non-EVA, fixing: defxx 0000:00:12.0: assign IRQ: got 10 defxx: v1.12 2021/03/10 Lawrence V. Stefani and others 0000:00:12.0: Could not read adapter factory MAC address! vs: defxx 0000:00:12.0: assign IRQ: got 10 defxx: v1.12 2021/03/10 Lawrence V. Stefani and others 0000:00:12.0: DEFPA at MMIO addr = 0x10142000, IRQ = 10, Hardware addr = 00-00-f8-xx-xx-xx 0000:00:12.0: registered as fddi0 for non-EVA and causing no change for EVA. Signed-off-by: Maciej W. Rozycki Fixes: 422dd256642b ("MIPS: Malta: Allow PCI devices DMA to lower 2GB physical") Cc: stable@vger.kernel.org # v4.9+ Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/mips/mti-malta/malta-init.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 000d6d50520a..82b0fd8576a2 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -241,16 +241,22 @@ void __init prom_init(void) #endif /* - * Setup the Malta max (2GB) memory for PCI DMA in host bridge - * in transparent addressing mode. + * Set up memory mapping in host bridge for PCI DMA masters, + * in transparent addressing mode. For EVA use the Malta + * maximum of 2 GiB memory in the alias space at 0x80000000 + * as per PHYS_OFFSET. Otherwise use 256 MiB of memory in + * the regular space, avoiding mapping the PCI MMIO window + * for DMA as it seems to confuse the system controller's + * logic, causing PCI MMIO to stop working. */ - mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH; - MSC_WRITE(MSC01_PCI_BAR0, mask); - MSC_WRITE(MSC01_PCI_HEAD4, mask); + mask = PHYS_OFFSET ? PHYS_OFFSET : 0xf0000000; + MSC_WRITE(MSC01_PCI_BAR0, + mask | PCI_BASE_ADDRESS_MEM_PREFETCH); + MSC_WRITE(MSC01_PCI_HEAD4, + PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH); - mask &= MSC01_PCI_BAR0_SIZE_MSK; MSC_WRITE(MSC01_PCI_P2SCMSKL, mask); - MSC_WRITE(MSC01_PCI_P2SCMAPL, mask); + MSC_WRITE(MSC01_PCI_P2SCMAPL, PHYS_OFFSET); /* Don't handle target retries indefinitely. */ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == -- Gitee From 55b5962693b3703f87c98a48389ce6d3210fe5ff Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 22 Oct 2025 21:34:26 +0800 Subject: [PATCH 0024/1449] dt-bindings: pinctrl: toshiba,visconti: Fix number of items in groups ANBZ: #35228 commit 6aa22377ef273193fdbb5b31ef358c49a7e3aeb4 stable. commit 316e361b5d2cdeb8d778983794a1c6eadcb26814 upstream. The "groups" property can hold multiple entries (e.g. toshiba/tmpv7708-rm-mbrc.dts file), so allow that by dropping incorrect type (pinmux-node.yaml schema already defines that as string-array) and adding constraints for items. This fixes dtbs_check warnings like: toshiba/tmpv7708-rm-mbrc.dtb: pinctrl@24190000 (toshiba,tmpv7708-pinctrl): pwm-pins:groups: ['pwm0_gpio16_grp', 'pwm1_gpio17_grp', 'pwm2_gpio18_grp', 'pwm3_gpio19_grp'] is too long Fixes: 1825c1fe0057 ("pinctrl: Add DT bindings for Toshiba Visconti TMPV7700 SoC") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Acked-by: Conor Dooley Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../pinctrl/toshiba,visconti-pinctrl.yaml | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml index 19d47fd414bc..ce04d2eadec9 100644 --- a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml @@ -50,18 +50,20 @@ patternProperties: groups: description: Name of the pin group to use for the functions. - $ref: /schemas/types.yaml#/definitions/string - enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, - i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, - spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, - spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, - uart0_grp, uart1_grp, uart2_grp, uart3_grp, - pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, - pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, - pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, - pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, - pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, - pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] + items: + enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, + i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, + spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, + spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, + uart0_grp, uart1_grp, uart2_grp, uart3_grp, + pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, + pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, + pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, + pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, + pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, + pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] + minItems: 1 + maxItems: 8 drive-strength: enum: [2, 4, 6, 8, 16, 24, 32] -- Gitee From 70a1ffc334c7005e67c7a2d2d3708eb3ca5be42c Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Thu, 20 Nov 2025 14:42:05 +0800 Subject: [PATCH 0025/1449] LoongArch: Don't panic if no valid cache info for PCI ANBZ: #35228 commit fe694895d3b7d391130bb505220383ab0b70e7b4 stable. commit a6b533adfc05ba15360631e019d3e18275080275 upstream. If there is no valid cache info detected (may happen in virtual machine) for pci_dfl_cache_line_size, kernel shouldn't panic. Because in the PCI core it will be evaluated to (L1_CACHE_BYTES >> 2). Cc: Signed-off-by: Jiaxun Yang Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/pci/pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 2726639150bc..927dd31f82b9 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -51,11 +51,11 @@ static int __init pcibios_init(void) */ lsize = cpu_last_level_cache_line_size(); - BUG_ON(!lsize); + if (lsize) { + pci_dfl_cache_line_size = lsize >> 2; - pci_dfl_cache_line_size = lsize >> 2; - - pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); + pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); + } return 0; } -- Gitee From dfc3ac8adef513858d8b847d502a68acae95a711 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 13 Nov 2025 18:39:24 +0800 Subject: [PATCH 0026/1449] mptcp: fix race condition in mptcp_schedule_work() ANBZ: #35228 commit 8f9ba1a99a89feef9b5867c15a0141a97e893309 stable. commit 035bca3f017ee9dea3a5a756e77a6f7138cc6eea upstream. syzbot reported use-after-free in mptcp_schedule_work() [1] Issue here is that mptcp_schedule_work() schedules a work, then gets a refcount on sk->sk_refcnt if the work was scheduled. This refcount will be released by mptcp_worker(). [A] if (schedule_work(...)) { [B] sock_hold(sk); return true; } Problem is that mptcp_worker() can run immediately and complete before [B] We need instead : sock_hold(sk); if (schedule_work(...)) return true; sock_put(sk); [1] refcount_t: addition on 0; use-after-free. WARNING: CPU: 1 PID: 29 at lib/refcount.c:25 refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:25 Call Trace: __refcount_add include/linux/refcount.h:-1 [inline] __refcount_inc include/linux/refcount.h:366 [inline] refcount_inc include/linux/refcount.h:383 [inline] sock_hold include/net/sock.h:816 [inline] mptcp_schedule_work+0x164/0x1a0 net/mptcp/protocol.c:943 mptcp_tout_timer+0x21/0xa0 net/mptcp/protocol.c:2316 call_timer_fn+0x17e/0x5f0 kernel/time/timer.c:1747 expire_timers kernel/time/timer.c:1798 [inline] __run_timers kernel/time/timer.c:2372 [inline] __run_timer_base+0x648/0x970 kernel/time/timer.c:2384 run_timer_base kernel/time/timer.c:2393 [inline] run_timer_softirq+0xb7/0x180 kernel/time/timer.c:2403 handle_softirqs+0x22f/0x710 kernel/softirq.c:622 __do_softirq kernel/softirq.c:656 [inline] run_ktimerd+0xcf/0x190 kernel/softirq.c:1138 smpboot_thread_fn+0x542/0xa60 kernel/smpboot.c:160 kthread+0x711/0x8a0 kernel/kthread.c:463 ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 Cc: stable@vger.kernel.org Fixes: 3b1d6210a957 ("mptcp: implement and use MPTCP-level retransmission") Reported-by: syzbot+355158e7e301548a1424@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6915b46f.050a0220.3565dc.0028.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Reviewed-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251113103924.3737425-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index eb50c7fc4e71..1fef12e40bda 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -961,14 +961,19 @@ static void mptcp_reset_rtx_timer(struct sock *sk) bool mptcp_schedule_work(struct sock *sk) { - if (inet_sk_state_load(sk) != TCP_CLOSE && - schedule_work(&mptcp_sk(sk)->work)) { - /* each subflow already holds a reference to the sk, and the - * workqueue is invoked by a subflow, so sk can't go away here. - */ - sock_hold(sk); + if (inet_sk_state_load(sk) == TCP_CLOSE) + return false; + + /* Get a reference on this socket, mptcp_worker() will release it. + * As mptcp_worker() might complete before us, we can not avoid + * a sock_hold()/sock_put() if schedule_work() returns false. + */ + sock_hold(sk); + + if (schedule_work(&mptcp_sk(sk)->work)) return true; - } + + sock_put(sk); return false; } -- Gitee From 7482b57f9100f7d85c03ade04ed48c16dcaed754 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 18 Nov 2025 15:20:19 +0800 Subject: [PATCH 0027/1449] mptcp: fix ack generation for fallback msk ANBZ: #35228 commit 3d513efe18a987bc0924e4fc799260dc4f28ef14 stable. commit 5e15395f6d9ec07395866c5511f4b4ac566c0c9b upstream. mptcp_cleanup_rbuf() needs to know the last most recent, mptcp-level rcv_wnd sent, and such information is tracked into the msk->old_wspace field, updated at ack transmission time by mptcp_write_options(). Fallback socket do not add any mptcp options, such helper is never invoked, and msk->old_wspace value remain stale. That in turn makes ack generation at recvmsg() time quite random. Address the issue ensuring mptcp_write_options() is invoked even for fallback sockets, and just update the needed info in such a case. The issue went unnoticed for a long time, as mptcp currently overshots the fallback socket receive buffer autotune significantly. It is going to change in the near future. Fixes: e3859603ba13 ("mptcp: better msk receive window updates") Cc: stable@vger.kernel.org Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/594 Signed-off-by: Paolo Abeni Reviewed-by: Geliang Tang Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-1-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/options.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index b245abd08c82..94c074385655 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -839,8 +839,11 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, opts->suboptions = 0; + /* Force later mptcp_write_options(), but do not use any actual + * option space. + */ if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb))) - return false; + return true; if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) { if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) || @@ -1318,6 +1321,20 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); } +static void mptcp_track_rwin(struct tcp_sock *tp) +{ + const struct sock *ssk = (const struct sock *)tp; + struct mptcp_subflow_context *subflow; + struct mptcp_sock *msk; + + if (!ssk) + return; + + subflow = mptcp_subflow_ctx(ssk); + msk = mptcp_sk(subflow->conn); + WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); +} + __sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum) { struct csum_pseudo_header header; @@ -1610,6 +1627,10 @@ void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp, opts->reset_transient, opts->reset_reason); return; + } else if (unlikely(!opts->suboptions)) { + /* Fallback to TCP */ + mptcp_track_rwin(tp); + return; } if (OPTION_MPTCP_PRIO & opts->suboptions) { -- Gitee From 2609ca7673bf1409aa5cff442adb3476ae5e3316 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 18 Nov 2025 15:20:21 +0800 Subject: [PATCH 0028/1449] mptcp: fix premature close in case of fallback ANBZ: #35228 commit d019cbb455ee27c8d7d7894e9985bf7c76664135 stable. commit 17393fa7b7086664be519e7230cb6ed7ec7d9462 upstream. I'm observing very frequent self-tests failures in case of fallback when running on a CONFIG_PREEMPT kernel. The root cause is that subflow_sched_work_if_closed() closes any subflow as soon as it is half-closed and has no incoming data pending. That works well for regular subflows - MPTCP needs bi-directional connectivity to operate on a given subflow - but for fallback socket is race prone. When TCP peer closes the connection before the MPTCP one, subflow_sched_work_if_closed() will schedule the MPTCP worker to gracefully close the subflow, and shortly after will do another schedule to inject and process a dummy incoming DATA_FIN. On CONFIG_PREEMPT kernel, the MPTCP worker can kick-in and close the fallback subflow before subflow_sched_work_if_closed() is able to create the dummy DATA_FIN, unexpectedly interrupting the transfer. Address the issue explicitly avoiding closing fallback subflows on when the peer is only half-closed. Note that, when the subflow is able to create the DATA_FIN before the worker invocation, the worker will change the msk state before trying to close the subflow and will skip the latter operation as the msk will not match anymore the precondition in __mptcp_close_subflow(). Fixes: f09b0ad55a11 ("mptcp: close subflow when receiving TCP+FIN") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-3-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 1fef12e40bda..20ef4714598c 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2585,7 +2585,8 @@ static void __mptcp_close_subflow(struct sock *sk) if (ssk_state != TCP_CLOSE && (ssk_state != TCP_CLOSE_WAIT || - inet_sk_state_load(sk) != TCP_ESTABLISHED)) + inet_sk_state_load(sk) != TCP_ESTABLISHED || + __mptcp_check_fallback(msk))) continue; /* 'subflow_data_ready' will re-sched once rx queue is empty */ -- Gitee From 11da3ce205bb637ec7df8292b0e670750e694e7e Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 18 Nov 2025 15:20:20 +0800 Subject: [PATCH 0029/1449] mptcp: avoid unneeded subflow-level drops ANBZ: #35228 commit 28e4d5fd731eee07535ebd4763e8eb123d5d43ed stable. commit 4f102d747cadd8f595f2b25882eed9bec1675fb1 upstream. The rcv window is shared among all the subflows. Currently, MPTCP sync the TCP-level rcv window with the MPTCP one at tcp_transmit_skb() time. The above means that incoming data may sporadically observe outdated TCP-level rcv window and being wrongly dropped by TCP. Address the issue checking for the edge condition before queuing the data at TCP level, and eventually syncing the rcv window as needed. Note that the issue is actually present from the very first MPTCP implementation, but backports older than the blamed commit below will range from impossible to useless. Before: $ nstat -n; sleep 1; nstat -z TcpExtBeyondWindow TcpExtBeyondWindow 14 0.0 After: $ nstat -n; sleep 1; nstat -z TcpExtBeyondWindow TcpExtBeyondWindow 0 0.0 Fixes: fa3fe2b15031 ("mptcp: track window announced to peer") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-2-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/options.c | 31 +++++++++++++++++++++++++++++++ net/mptcp/protocol.h | 1 + 2 files changed, 32 insertions(+) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 94c074385655..f1edae5f9079 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -1044,6 +1044,31 @@ static void __mptcp_snd_una_update(struct mptcp_sock *msk, u64 new_snd_una) msk->snd_una = new_snd_una; } +static void rwin_update(struct mptcp_sock *msk, struct sock *ssk, + struct sk_buff *skb) +{ + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + struct tcp_sock *tp = tcp_sk(ssk); + u64 mptcp_rcv_wnd; + + /* Avoid touching extra cachelines if TCP is going to accept this + * skb without filling the TCP-level window even with a possibly + * outdated mptcp-level rwin. + */ + if (!skb->len || skb->len < tcp_receive_window(tp)) + return; + + mptcp_rcv_wnd = atomic64_read(&msk->rcv_wnd_sent); + if (!after64(mptcp_rcv_wnd, subflow->rcv_wnd_sent)) + return; + + /* Some other subflow grew the mptcp-level rwin since rcv_wup, + * resync. + */ + tp->rcv_wnd += mptcp_rcv_wnd - subflow->rcv_wnd_sent; + subflow->rcv_wnd_sent = mptcp_rcv_wnd; +} + static void ack_update_msk(struct mptcp_sock *msk, struct sock *ssk, struct mptcp_options_received *mp_opt) @@ -1210,6 +1235,7 @@ bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) */ if (mp_opt.use_ack) ack_update_msk(msk, sk, &mp_opt); + rwin_update(msk, sk, skb); /* Zero-data-length packets are dropped by the caller and not * propagated to the MPTCP layer, so the skb extension does not @@ -1296,6 +1322,10 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) if (rcv_wnd_new != rcv_wnd_old) { raise_win: + /* The msk-level rcv wnd is after the tcp level one, + * sync the latter. + */ + rcv_wnd_new = rcv_wnd_old; win = rcv_wnd_old - ack_seq; tp->rcv_wnd = min_t(u64, win, U32_MAX); new_win = tp->rcv_wnd; @@ -1319,6 +1349,7 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th) update_wspace: WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); + subflow->rcv_wnd_sent = rcv_wnd_new; } static void mptcp_track_rwin(struct tcp_sock *tp) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index dc98f588c8a8..01bdc5473638 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -478,6 +478,7 @@ struct mptcp_subflow_context { u64 remote_key; u64 idsn; u64 map_seq; + u64 rcv_wnd_sent; u32 snd_isn; u32 token; u32 rel_write_seq; -- Gitee From eb2d056c2f5887650605f8b95d46739a17009157 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 18 Nov 2025 15:20:23 +0800 Subject: [PATCH 0030/1449] mptcp: decouple mptcp fastclose from tcp close ANBZ: #35228 commit 8a5d1ceef950892831bd986808b29bddd4ec3060 stable. commit fff0c87996672816a84c3386797a5e69751c5888 upstream. With the current fastclose implementation, the mptcp_do_fastclose() helper is in charge of two distinct actions: send the fastclose reset and cleanup the subflows. Formally decouple the two steps, ensuring that mptcp explicitly closes all the subflows after the mentioned helper. This will make the upcoming fix simpler, and allows dropping the 2nd argument from mptcp_destroy_common(). The Fixes tag is then the same as in the next commit to help with the backports. Fixes: d21f83485518 ("mptcp: use fastclose on more edge scenarios") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Geliang Tang Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-5-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 13 +++++++++---- net/mptcp/protocol.h | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 20ef4714598c..07281edd877a 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2822,7 +2822,11 @@ static void mptcp_worker(struct work_struct *work) __mptcp_close_subflow(sk); if (mptcp_close_tout_expired(sk)) { + struct mptcp_subflow_context *subflow, *tmp; + mptcp_do_fastclose(sk); + mptcp_for_each_subflow_safe(msk, subflow, tmp) + __mptcp_close_ssk(sk, subflow->tcp_sock, subflow, 0); mptcp_close_wake_up(sk); } @@ -3250,7 +3254,8 @@ static int mptcp_disconnect(struct sock *sk, int flags) /* msk->subflow is still intact, the following will not free the first * subflow */ - mptcp_destroy_common(msk, MPTCP_CF_FASTCLOSE); + mptcp_do_fastclose(sk); + mptcp_destroy_common(msk); /* The first subflow is already in TCP_CLOSE status, the following * can't overlap with a fallback anymore @@ -3432,7 +3437,7 @@ void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk) msk->rcvq_space.space = TCP_INIT_CWND * TCP_MSS_DEFAULT; } -void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags) +void mptcp_destroy_common(struct mptcp_sock *msk) { struct mptcp_subflow_context *subflow, *tmp; struct sock *sk = (struct sock *)msk; @@ -3441,7 +3446,7 @@ void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags) /* join list will be eventually flushed (with rst) at sock lock release time */ mptcp_for_each_subflow_safe(msk, subflow, tmp) - __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, flags); + __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, 0); /* move to sk_receive_queue, sk_stream_kill_queues will purge it */ mptcp_data_lock(sk); @@ -3466,7 +3471,7 @@ static void mptcp_destroy(struct sock *sk) /* allow the following to close even the initial subflow */ msk->free_first = 1; - mptcp_destroy_common(msk, 0); + mptcp_destroy_common(msk); sk_sockets_allocated_dec(sk); } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 01bdc5473638..5d218c27c077 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -871,7 +871,7 @@ static inline void mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk) local_bh_enable(); } -void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags); +void mptcp_destroy_common(struct mptcp_sock *msk); #define MPTCP_TOKEN_MAX_RETRIES 4 -- Gitee From e980177bf625fe00aa44aa138723222228aec169 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 18 Nov 2025 15:20:22 +0800 Subject: [PATCH 0031/1449] mptcp: do not fallback when OoO is present ANBZ: #35228 commit 642561238c98ffcbde5b15e128ae2e4dc74c9bfb stable. commit 1bba3f219c5e8c29e63afa3c1fc24f875ebec119 upstream. In case of DSS corruption, the MPTCP protocol tries to avoid the subflow reset if fallback is possible. Such corruptions happen in the receive path; to ensure fallback is possible the stack additionally needs to check for OoO data, otherwise the fallback will break the data stream. Fixes: e32d262c89e2 ("mptcp: handle consistently DSS corruption") Cc: stable@vger.kernel.org Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/598 Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-4-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 07281edd877a..73b3a44b183f 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -904,6 +904,13 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk) if (sk->sk_state != TCP_ESTABLISHED) return false; + /* The caller possibly is not holding the msk socket lock, but + * in the fallback case only the current subflow is touching + * the OoO queue. + */ + if (!RB_EMPTY_ROOT(&msk->out_of_order_queue)) + return false; + spin_lock_bh(&msk->fallback_lock); if (!msk->allow_subflows) { spin_unlock_bh(&msk->fallback_lock); -- Gitee From 2e0e91b276d013200b5bd9d6cb3e698e4a03c907 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Wed, 22 Oct 2025 19:47:20 +0800 Subject: [PATCH 0032/1449] drm/tegra: dc: Fix reference leak in tegra_dc_couple() ANBZ: #35228 commit 8b57f812708696f17e26ac32e16a19acc7d5debd stable. commit 4c5376b4b143c4834ebd392aef2215847752b16a upstream. driver_find_device() calls get_device() to increment the reference count once a matching device is found, but there is no put_device() to balance the reference count. To avoid reference count leakage, add put_device() to decrease the reference count. Found by code review. Cc: stable@vger.kernel.org Fixes: a31500fe7055 ("drm/tegra: dc: Restore coupling of display controllers") Signed-off-by: Ma Ke Acked-by: Mikko Perttunen Signed-off-by: Thierry Reding Link: https://patch.msgid.link/20251022114720.24937-1-make24@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/tegra/dc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 980d85bc7f37..caa1fe6cc386 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -3140,6 +3140,7 @@ static int tegra_dc_couple(struct tegra_dc *dc) dc->client.parent = &parent->client; dev_dbg(dc->dev, "coupled to %s\n", dev_name(companion)); + put_device(companion); } return 0; -- Gitee From 55ca5d34908042f8fb83b0cb95b64b84d5cb1470 Mon Sep 17 00:00:00 2001 From: Yifan Zha Date: Fri, 14 Nov 2025 17:48:58 +0800 Subject: [PATCH 0033/1449] drm/amdgpu: Skip emit de meta data on gfx11 with rs64 enabled ANBZ: #35228 commit 06a79f1bffe7d74d2f65556643e406ffb96523f2 stable. commit 80d8a9ad1587b64c545d515ab6cb7ecb9908e1b3 upstream. [Why] Accoreding to CP updated to RS64 on gfx11, WRITE_DATA with PREEMPTION_META_MEMORY(dst_sel=8) is illegal for CP FW. That packet is used for MCBP on F32 based system. So it would lead to incorrect GRBM write and FW is not handling that extra case correctly. [How] With gfx11 rs64 enabled, skip emit de meta data. Signed-off-by: Yifan Zha Acked-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 8366cd442d226463e673bed5d199df916f4ecbcf) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 480d718d09cb..7591a2803ae1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -5296,9 +5296,9 @@ static void gfx_v11_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, if (flags & AMDGPU_IB_PREEMPTED) control |= INDIRECT_BUFFER_PRE_RESUME(1); - if (vmid) + if (vmid && !ring->adev->gfx.rs64_enable) gfx_v11_0_ring_emit_de_meta(ring, - (!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false); + !amdgpu_sriov_vf(ring->adev) && (flags & AMDGPU_IB_PREEMPTED)); } if (ring->is_mes_queue) -- Gitee From ad7ea07e55c1bb2a8a30b9a7d1a3e8c9b5946562 Mon Sep 17 00:00:00 2001 From: Jianbo Liu Date: Tue, 28 Oct 2025 10:22:48 +0800 Subject: [PATCH 0034/1449] xfrm: Determine inner GSO type from packet inner protocol ANBZ: #35228 commit a2b61573e6a3947f6b198f0e01705295dd9918ca stable. commit 61fafbee6cfed283c02a320896089f658fa67e56 upstream. The GSO segmentation functions for ESP tunnel mode (xfrm4_tunnel_gso_segment and xfrm6_tunnel_gso_segment) were determining the inner packet's L2 protocol type by checking the static x->inner_mode.family field from the xfrm state. This is unreliable. In tunnel mode, the state's actual inner family could be defined by x->inner_mode.family or by x->inner_mode_iaf.family. Checking only the former can lead to a mismatch with the actual packet being processed, causing GSO to create segments with the wrong L2 header type. This patch fixes the bug by deriving the inner mode directly from the packet's inner protocol stored in XFRM_MODE_SKB_CB(skb)->protocol. Instead of replicating the code, this patch modifies the xfrm_ip2inner_mode helper function. It now correctly returns &x->inner_mode if the selector family (x->sel.family) is already specified, thereby handling both specific and AF_UNSPEC cases appropriately. With this change, ESP GSO can use xfrm_ip2inner_mode to get the correct inner mode. It doesn't affect existing callers, as the updated logic now mirrors the checks they were already performing externally. Fixes: 26dbd66eab80 ("esp: choose the correct inner protocol for GSO on inter address family tunnels") Signed-off-by: Jianbo Liu Reviewed-by: Cosmin Ratiu Reviewed-by: Sabrina Dubroca Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/xfrm.h | 3 ++- net/ipv4/esp4_offload.c | 6 ++++-- net/ipv6/esp6_offload.c | 6 ++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index b6141f408005..ca20cddf71fd 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -463,7 +463,8 @@ static inline int xfrm_af2proto(unsigned int family) static inline const struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto) { - if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || + if ((x->sel.family != AF_UNSPEC) || + (ipproto == IPPROTO_IPIP && x->props.family == AF_INET) || (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6)) return &x->inner_mode; else diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index 10e96ed6c9e3..11e33a431267 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -111,8 +111,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { - __be16 type = x->inner_mode.family == AF_INET6 ? htons(ETH_P_IPV6) - : htons(ETH_P_IP); + const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, + XFRM_MODE_SKB_CB(skb)->protocol); + __be16 type = inner_mode->family == AF_INET6 ? htons(ETH_P_IPV6) + : htons(ETH_P_IP); return skb_eth_gso_segment(skb, features, type); } diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index a189e08370a5..438f9cbdca29 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -145,8 +145,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { - __be16 type = x->inner_mode.family == AF_INET ? htons(ETH_P_IP) - : htons(ETH_P_IPV6); + const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, + XFRM_MODE_SKB_CB(skb)->protocol); + __be16 type = inner_mode->family == AF_INET ? htons(ETH_P_IP) + : htons(ETH_P_IPV6); return skb_eth_gso_segment(skb, features, type); } -- Gitee From f8760a6dff2def23fd3ed95e8273e2f7b4572c1a Mon Sep 17 00:00:00 2001 From: Jianbo Liu Date: Wed, 29 Oct 2025 17:50:25 +0800 Subject: [PATCH 0035/1449] xfrm: Prevent locally generated packets from direct output in tunnel mode ANBZ: #35228 commit a620b091c4dfc071ef6ac6adbaa394b77e0579d9 stable. commit 59630e2ccd728703cc826e3a3515d70f8c7a766c upstream. Add a check to ensure locally generated packets (skb->sk != NULL) do not use direct output in tunnel mode, as these packets require proper L2 header setup that is handled by the normal XFRM processing path. Fixes: 5eddd76ec2fd ("xfrm: fix tunnel mode TX datapath in packet offload mode") Signed-off-by: Jianbo Liu Reviewed-by: Leon Romanovsky Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/xfrm/xfrm_output.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index a30538a980cc..9277dd4ed541 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -766,8 +766,12 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb) /* Exclusive direct xmit for tunnel mode, as * some filtering or matching rules may apply * in transport mode. + * Locally generated packets also require + * the normal XFRM path for L2 header setup, + * as the hardware needs the L2 header to match + * for encryption, so skip direct output as well. */ - if (x->props.mode == XFRM_MODE_TUNNEL) + if (x->props.mode == XFRM_MODE_TUNNEL && !skb->sk) return xfrm_dev_direct_output(sk, x, skb); return xfrm_output_resume(sk, skb, 0); -- Gitee From 288065d31e6948137fb5baf9bfaf051fd536d81f Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 28 Oct 2025 11:05:09 +0800 Subject: [PATCH 0036/1449] pinctrl: cirrus: Fix fwnode leak in cs42l43_pin_probe() ANBZ: #35228 commit 9026f31a520d43cc01eb1c08938fc19efadd78cc stable. commit 9b07cdf86a0b90556f5b68a6b20b35833b558df3 upstream. The driver calls fwnode_get_named_child_node() which takes a reference on the child node, but never releases it, which causes a reference leak. Fix by using devm_add_action_or_reset() to automatically release the reference when the device is removed. Fixes: d5282a539297 ("pinctrl: cs42l43: Add support for the cs42l43") Suggested-by: Charles Keepax Signed-off-by: Haotian Zhang Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/cirrus/pinctrl-cs42l43.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c index c09646318419..e1ac89be7c84 100644 --- a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c +++ b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c @@ -532,6 +532,11 @@ static int cs42l43_gpio_add_pin_ranges(struct gpio_chip *chip) return ret; } +static void cs42l43_fwnode_put(void *data) +{ + fwnode_handle_put(data); +} + static int cs42l43_pin_probe(struct platform_device *pdev) { struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent); @@ -563,10 +568,20 @@ static int cs42l43_pin_probe(struct platform_device *pdev) priv->gpio_chip.ngpio = CS42L43_NUM_GPIOS; if (is_of_node(fwnode)) { - fwnode = fwnode_get_named_child_node(fwnode, "pinctrl"); - - if (fwnode && !fwnode->dev) - fwnode->dev = priv->dev; + struct fwnode_handle *child; + + child = fwnode_get_named_child_node(fwnode, "pinctrl"); + if (child) { + ret = devm_add_action_or_reset(&pdev->dev, + cs42l43_fwnode_put, child); + if (ret) { + fwnode_handle_put(child); + return ret; + } + if (!child->dev) + child->dev = priv->dev; + fwnode = child; + } } priv->gpio_chip.fwnode = fwnode; -- Gitee From 2c895e9b030fc38d2a927676c111db21dfdb5be2 Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Tue, 4 Nov 2025 02:11:31 +0800 Subject: [PATCH 0037/1449] drm/amd/display: Increase DPCD read retries ANBZ: #35228 commit e688c20f088efce41beea0b9a907d0048dd007ac stable. commit 8612badc331bcab2068baefa69e1458085ed89e3 upstream. [Why] Empirical measurement of some monitors that fail to read EDID while booting shows that the number of retries with a 30ms delay between tries is as high as 16. [How] Increase number of retries to 20. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4672 Reviewed-by: Alex Hung Signed-off-by: Mario Limonciello (AMD) Signed-off-by: Ivan Lipski Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit ad1c59ad7cf74ec06e32fe2c330ac1e957222288) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index adf0ef8b70e4..bb52a747da26 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1552,7 +1552,7 @@ static bool retrieve_link_cap(struct dc_link *link) union edp_configuration_cap edp_config_cap; union dp_downstream_port_present ds_port = { 0 }; enum dc_status status = DC_ERROR_UNEXPECTED; - uint32_t read_dpcd_retry_cnt = 3; + uint32_t read_dpcd_retry_cnt = 20; int i; struct dp_sink_hw_fw_revision dp_hw_fw_revision; const uint32_t post_oui_delay = 30; // 30ms -- Gitee From 5eae787436004b6b0fc30102e5a9f030b8e0c4cd Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Tue, 4 Nov 2025 01:17:44 +0800 Subject: [PATCH 0038/1449] drm/amd/display: Move sleep into each retry for retrieve_link_cap() ANBZ: #35228 commit b3b27876f3bef5e0232a689562d1f497c5772af5 stable. commit 71ad9054c1f241be63f9d11df8cbd0aa0352fe16 upstream. [Why] When a monitor is booting it's possible that it isn't ready to retrieve link caps and this can lead to an EDID read failure: ``` [drm:retrieve_link_cap [amdgpu]] *ERROR* retrieve_link_cap: Read receiver caps dpcd data failed. amdgpu 0000:c5:00.0: [drm] *ERROR* No EDID read. ``` [How] Rather than msleep once and try a few times, msleep each time. Should be no changes for existing working monitors, but should correct reading caps on a monitor that is slow to boot. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4672 Reviewed-by: Alex Hung Signed-off-by: Mario Limonciello (AMD) Signed-off-by: Ivan Lipski Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit 669dca37b3348a447db04bbdcbb3def94d5997cc) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../amd/display/dc/link/protocols/link_dp_capability.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index bb52a747da26..56999657f4d8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1598,12 +1598,13 @@ static bool retrieve_link_cap(struct dc_link *link) status = dpcd_get_tunneling_device_data(link); dpcd_set_source_specific_data(link); - /* Sink may need to configure internals based on vendor, so allow some - * time before proceeding with possibly vendor specific transactions - */ - msleep(post_oui_delay); for (i = 0; i < read_dpcd_retry_cnt; i++) { + /* + * Sink may need to configure internals based on vendor, so allow some + * time before proceeding with possibly vendor specific transactions + */ + msleep(post_oui_delay); status = core_link_read_dpcd( link, DP_DPCD_REV, -- Gitee From 49c3ea122adbd3fe5e1645b83155600088aa7c37 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 12 Nov 2025 13:21:14 +0800 Subject: [PATCH 0039/1449] mlxsw: spectrum: Fix memory leak in mlxsw_sp_flower_stats() ANBZ: #35228 commit ddb483ce2136e3a8a8b2926598fc8b6cd7beee77 stable. commit 407a06507c2358554958e8164dc97176feddcafc upstream. The function mlxsw_sp_flower_stats() calls mlxsw_sp_acl_ruleset_get() to obtain a ruleset reference. If the subsequent call to mlxsw_sp_acl_rule_lookup() fails to find a rule, the function returns an error without releasing the ruleset reference, causing a memory leak. Fix this by using a goto to the existing error handling label, which calls mlxsw_sp_acl_ruleset_put() to properly release the reference. Fixes: 7c1b8eb175b69 ("mlxsw: spectrum: Add support for TC flower offload statistics") Signed-off-by: Zilin Guan Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20251112052114.1591695-1-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 9fd1ca079258..fba545938fd7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -816,8 +816,10 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, return -EINVAL; rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie); - if (!rule) - return -EINVAL; + if (!rule) { + err = -EINVAL; + goto err_rule_get_stats; + } err = mlxsw_sp_acl_rule_get_stats(mlxsw_sp, rule, &packets, &bytes, &drops, &lastuse, &used_hw_stats); -- Gitee From a25fe3e55963375cd1b1ee7386f082b610891338 Mon Sep 17 00:00:00 2001 From: Prateek Agarwal Date: Fri, 19 Sep 2025 12:25:40 +0800 Subject: [PATCH 0040/1449] drm/tegra: Add call to put_pid() ANBZ: #35228 commit 2e78580e6e7deac6556236ef96db5bbf7b46857e stable. commit 6cbab9f0da72b4dc3c3f9161197aa3b9daa1fa3a upstream. Add a call to put_pid() corresponding to get_task_pid(). host1x_memory_context_alloc() does not take ownership of the PID so we need to free it here to avoid leaking. Signed-off-by: Prateek Agarwal Fixes: e09db97889ec ("drm/tegra: Support context isolation") [mperttunen@nvidia.com: reword commit message] Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding Link: https://patch.msgid.link/20250919-host1x-put-pid-v1-1-19c2163dfa87@nvidia.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/tegra/uapi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tegra/uapi.c b/drivers/gpu/drm/tegra/uapi.c index 5adab6b22916..d0b6a1fa6efa 100644 --- a/drivers/gpu/drm/tegra/uapi.c +++ b/drivers/gpu/drm/tegra/uapi.c @@ -114,9 +114,12 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_ if (err) goto put_channel; - if (supported) + if (supported) { + struct pid *pid = get_task_pid(current, PIDTYPE_TGID); context->memory_context = host1x_memory_context_alloc( - host, client->base.dev, get_task_pid(current, PIDTYPE_TGID)); + host, client->base.dev, pid); + put_pid(pid); + } if (IS_ERR(context->memory_context)) { if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) { -- Gitee From fab7f0f6b4e55ff0846b120476bde66906f241de Mon Sep 17 00:00:00 2001 From: Pavel Zhigulin Date: Thu, 13 Nov 2025 21:57:44 +0800 Subject: [PATCH 0041/1449] net: dsa: hellcreek: fix missing error handling in LED registration ANBZ: #35228 commit 385fd7ec321414f0ed1541595280d456ce718913 stable. commit e6751b0b19a6baab219a62e1e302b8aa6b5a55b2 upstream. The LED setup routine registered both led_sync_good and led_is_gm devices without checking the return values of led_classdev_register(). If either registration failed, the function continued silently, leaving the driver in a partially-initialized state and leaking a registered LED classdev. Add proper error handling Fixes: 7d9ee2e8ff15 ("net: dsa: hellcreek: Add PTP status LEDs") Signed-off-by: Pavel Zhigulin Reviewed-by: Andrew Lunn Acked-by: Kurt Kanzenbach Link: https://patch.msgid.link/20251113135745.92375-1-Pavel.Zhigulin@kaspersky.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/hirschmann/hellcreek_ptp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/hirschmann/hellcreek_ptp.c b/drivers/net/dsa/hirschmann/hellcreek_ptp.c index 5249a1c2a80b..1bb994f78596 100644 --- a/drivers/net/dsa/hirschmann/hellcreek_ptp.c +++ b/drivers/net/dsa/hirschmann/hellcreek_ptp.c @@ -371,8 +371,18 @@ static int hellcreek_led_setup(struct hellcreek *hellcreek) hellcreek_set_brightness(hellcreek, STATUS_OUT_IS_GM, 1); /* Register both leds */ - led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good); - led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm); + ret = led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good); + if (ret) { + dev_err(hellcreek->dev, "Failed to register sync_good LED\n"); + goto out; + } + + ret = led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm); + if (ret) { + dev_err(hellcreek->dev, "Failed to register is_gm LED\n"); + led_classdev_unregister(&hellcreek->led_sync_good); + goto out; + } ret = 0; -- Gitee From 07efd3600099f3061264cf1bfc6db8dff0127955 Mon Sep 17 00:00:00 2001 From: Pavel Zhigulin Date: Fri, 14 Nov 2025 00:19:21 +0800 Subject: [PATCH 0042/1449] net: mlxsw: linecards: fix missing error check in mlxsw_linecard_devlink_info_get() ANBZ: #35228 commit f8c496e20b7a2d4d74ca89c17db7e1f26ee1c36a stable. commit b0c959fec18f4595a6a6317ffc30615cfa37bf69 upstream. The call to devlink_info_version_fixed_put() in mlxsw_linecard_devlink_info_get() did not check for errors, although it is checked everywhere in the code. Add missed 'err' check to the mlxsw_linecard_devlink_info_get() Fixes: 3fc0c51905fb ("mlxsw: core_linecards: Expose device PSID over device info") Signed-off-by: Pavel Zhigulin Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20251113161922.813828-1-Pavel.Zhigulin@kaspersky.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlxsw/core_linecards.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c index b032d5a4b3b8..10f5bc4892fc 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c @@ -601,6 +601,8 @@ int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard, err = devlink_info_version_fixed_put(req, DEVLINK_INFO_VERSION_GENERIC_FW_PSID, info->psid); + if (err) + goto unlock; sprintf(buf, "%u.%u.%u", info->fw_major, info->fw_minor, info->fw_sub_minor); -- Gitee From 4ddcda1372ba4cfceb55bbef4cf6d64fd2cc3110 Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Wed, 12 Nov 2025 19:14:03 +0800 Subject: [PATCH 0043/1449] net: openvswitch: remove never-working support for setting nsh fields ANBZ: #35228 commit 0b903f33c31c82b1c3591279fd8a23893802b987 stable. commit dfe28c4167a9259fc0c372d9f9473e1ac95cff67 upstream. The validation of the set(nsh(...)) action is completely wrong. It runs through the nsh_key_put_from_nlattr() function that is the same function that validates NSH keys for the flow match and the push_nsh() action. However, the set(nsh(...)) has a very different memory layout. Nested attributes in there are doubled in size in case of the masked set(). That makes proper validation impossible. There is also confusion in the code between the 'masked' flag, that says that the nested attributes are doubled in size containing both the value and the mask, and the 'is_mask' that says that the value we're parsing is the mask. This is causing kernel crash on trying to write into mask part of the match with SW_FLOW_KEY_PUT() during validation, while validate_nsh() doesn't allocate any memory for it: BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 1c2383067 P4D 1c2383067 PUD 20b703067 PMD 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 8 UID: 0 Kdump: loaded Not tainted 6.17.0-rc4+ #107 PREEMPT(voluntary) RIP: 0010:nsh_key_put_from_nlattr+0x19d/0x610 [openvswitch] Call Trace: validate_nsh+0x60/0x90 [openvswitch] validate_set.constprop.0+0x270/0x3c0 [openvswitch] __ovs_nla_copy_actions+0x477/0x860 [openvswitch] ovs_nla_copy_actions+0x8d/0x100 [openvswitch] ovs_packet_cmd_execute+0x1cc/0x310 [openvswitch] genl_family_rcv_msg_doit+0xdb/0x130 genl_family_rcv_msg+0x14b/0x220 genl_rcv_msg+0x47/0xa0 netlink_rcv_skb+0x53/0x100 genl_rcv+0x24/0x40 netlink_unicast+0x280/0x3b0 netlink_sendmsg+0x1f7/0x430 ____sys_sendmsg+0x36b/0x3a0 ___sys_sendmsg+0x87/0xd0 __sys_sendmsg+0x6d/0xd0 do_syscall_64+0x7b/0x2c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e The third issue with this process is that while trying to convert the non-masked set into masked one, validate_set() copies and doubles the size of the OVS_KEY_ATTR_NSH as if it didn't have any nested attributes. It should be copying each nested attribute and doubling them in size independently. And the process must be properly reversed during the conversion back from masked to a non-masked variant during the flow dump. In the end, the only two outcomes of trying to use this action are either validation failure or a kernel crash. And if somehow someone manages to install a flow with such an action, it will most definitely not do what it is supposed to, since all the keys and the masks are mixed up. Fixing all the issues is a complex task as it requires re-writing most of the validation code. Given that and the fact that this functionality never worked since introduction, let's just remove it altogether. It's better to re-introduce it later with a proper implementation instead of trying to fix it in stable releases. Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support") Reported-by: Junvy Yang Signed-off-by: Ilya Maximets Acked-by: Eelco Chaudron Reviewed-by: Aaron Conole Link: https://patch.msgid.link/20251112112246.95064-1-i.maximets@ovn.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/openvswitch/actions.c | 68 +--------------------------------- net/openvswitch/flow_netlink.c | 64 ++++---------------------------- net/openvswitch/flow_netlink.h | 2 - 3 files changed, 9 insertions(+), 125 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 10c646b32b9d..0ea4fc2a755b 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -597,69 +597,6 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key, return 0; } -static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key, - const struct nlattr *a) -{ - struct nshhdr *nh; - size_t length; - int err; - u8 flags; - u8 ttl; - int i; - - struct ovs_key_nsh key; - struct ovs_key_nsh mask; - - err = nsh_key_from_nlattr(a, &key, &mask); - if (err) - return err; - - /* Make sure the NSH base header is there */ - if (!pskb_may_pull(skb, skb_network_offset(skb) + NSH_BASE_HDR_LEN)) - return -ENOMEM; - - nh = nsh_hdr(skb); - length = nsh_hdr_len(nh); - - /* Make sure the whole NSH header is there */ - err = skb_ensure_writable(skb, skb_network_offset(skb) + - length); - if (unlikely(err)) - return err; - - nh = nsh_hdr(skb); - skb_postpull_rcsum(skb, nh, length); - flags = nsh_get_flags(nh); - flags = OVS_MASKED(flags, key.base.flags, mask.base.flags); - flow_key->nsh.base.flags = flags; - ttl = nsh_get_ttl(nh); - ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl); - flow_key->nsh.base.ttl = ttl; - nsh_set_flags_and_ttl(nh, flags, ttl); - nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr, - mask.base.path_hdr); - flow_key->nsh.base.path_hdr = nh->path_hdr; - switch (nh->mdtype) { - case NSH_M_TYPE1: - for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) { - nh->md1.context[i] = - OVS_MASKED(nh->md1.context[i], key.context[i], - mask.context[i]); - } - memcpy(flow_key->nsh.context, nh->md1.context, - sizeof(nh->md1.context)); - break; - case NSH_M_TYPE2: - memset(flow_key->nsh.context, 0, - sizeof(flow_key->nsh.context)); - break; - default: - return -EINVAL; - } - skb_postpush_rcsum(skb, nh, length); - return 0; -} - /* Must follow skb_ensure_writable() since that can move the skb data. */ static void set_tp_port(struct sk_buff *skb, __be16 *port, __be16 new_port, __sum16 *check) @@ -1143,10 +1080,6 @@ static int execute_masked_set_action(struct sk_buff *skb, get_mask(a, struct ovs_key_ethernet *)); break; - case OVS_KEY_ATTR_NSH: - err = set_nsh(skb, flow_key, a); - break; - case OVS_KEY_ATTR_IPV4: err = set_ipv4(skb, flow_key, nla_data(a), get_mask(a, struct ovs_key_ipv4 *)); @@ -1183,6 +1116,7 @@ static int execute_masked_set_action(struct sk_buff *skb, case OVS_KEY_ATTR_CT_LABELS: case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4: case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6: + case OVS_KEY_ATTR_NSH: err = -EINVAL; break; } diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 089ab1826e1d..836e8e705d40 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -1292,6 +1292,11 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match, return 0; } +/* + * Constructs NSH header 'nh' from attributes of OVS_ACTION_ATTR_PUSH_NSH, + * where 'nh' points to a memory block of 'size' bytes. It's assumed that + * attributes were previously validated with validate_push_nsh(). + */ int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh, size_t size) { @@ -1301,8 +1306,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr, u8 ttl = 0; int mdlen = 0; - /* validate_nsh has check this, so we needn't do duplicate check here - */ if (size < NSH_BASE_HDR_LEN) return -ENOBUFS; @@ -1346,46 +1349,6 @@ int nsh_hdr_from_nlattr(const struct nlattr *attr, return 0; } -int nsh_key_from_nlattr(const struct nlattr *attr, - struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask) -{ - struct nlattr *a; - int rem; - - /* validate_nsh has check this, so we needn't do duplicate check here - */ - nla_for_each_nested(a, attr, rem) { - int type = nla_type(a); - - switch (type) { - case OVS_NSH_KEY_ATTR_BASE: { - const struct ovs_nsh_key_base *base = nla_data(a); - const struct ovs_nsh_key_base *base_mask = base + 1; - - nsh->base = *base; - nsh_mask->base = *base_mask; - break; - } - case OVS_NSH_KEY_ATTR_MD1: { - const struct ovs_nsh_key_md1 *md1 = nla_data(a); - const struct ovs_nsh_key_md1 *md1_mask = md1 + 1; - - memcpy(nsh->context, md1->context, sizeof(*md1)); - memcpy(nsh_mask->context, md1_mask->context, - sizeof(*md1_mask)); - break; - } - case OVS_NSH_KEY_ATTR_MD2: - /* Not supported yet */ - return -ENOTSUPP; - default: - return -EINVAL; - } - } - - return 0; -} - static int nsh_key_put_from_nlattr(const struct nlattr *attr, struct sw_flow_match *match, bool is_mask, bool is_push_nsh, bool log) @@ -2825,17 +2788,13 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, return err; } -static bool validate_nsh(const struct nlattr *attr, bool is_mask, - bool is_push_nsh, bool log) +static bool validate_push_nsh(const struct nlattr *attr, bool log) { struct sw_flow_match match; struct sw_flow_key key; - int ret = 0; ovs_match_init(&match, &key, true, NULL); - ret = nsh_key_put_from_nlattr(attr, &match, is_mask, - is_push_nsh, log); - return !ret; + return !nsh_key_put_from_nlattr(attr, &match, false, true, log); } /* Return false if there are any non-masked bits set. @@ -2983,13 +2942,6 @@ static int validate_set(const struct nlattr *a, break; - case OVS_KEY_ATTR_NSH: - if (eth_type != htons(ETH_P_NSH)) - return -EINVAL; - if (!validate_nsh(nla_data(a), masked, false, log)) - return -EINVAL; - break; - default: return -EINVAL; } @@ -3399,7 +3351,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, return -EINVAL; } mac_proto = MAC_PROTO_NONE; - if (!validate_nsh(nla_data(a), false, true, true)) + if (!validate_push_nsh(nla_data(a), log)) return -EINVAL; break; diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h index fe7f77fc5f18..ff8cdecbe346 100644 --- a/net/openvswitch/flow_netlink.h +++ b/net/openvswitch/flow_netlink.h @@ -65,8 +65,6 @@ int ovs_nla_put_actions(const struct nlattr *attr, void ovs_nla_free_flow_actions(struct sw_flow_actions *); void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *); -int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh, - struct ovs_key_nsh *nsh_mask); int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh, size_t size); -- Gitee From 89ab49ac914b413127851f60a66f98e52f141776 Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Mon, 17 Nov 2025 10:23:39 +0800 Subject: [PATCH 0044/1449] nvme-multipath: fix lockdep WARN due to partition scan work ANBZ: #35228 commit e2a897ad5f538d314955c747a0a2edb184fcdecd stable. commit 6d87cd5335784351280f82c47cc8a657271929c3 upstream. Blktests test cases nvme/014, 057 and 058 fail occasionally due to a lockdep WARN. As reported in the Closes tag URL, the WARN indicates that a deadlock can happen due to the dependency among disk->open_mutex, kblockd workqueue completion and partition_scan_work completion. To avoid the lockdep WARN and the potential deadlock, cut the dependency by running the partition_scan_work not by kblockd workqueue but by nvme_wq. Reported-by: Yi Zhang Closes: https://lore.kernel.org/linux-block/CAHj4cs8mJ+R_GmQm9R8ebResKAWUE8kF5+_WVg0v8zndmqd6BQ@mail.gmail.com/ Link: https://lore.kernel.org/linux-block/oeyzci6ffshpukpfqgztsdeke5ost5hzsuz4rrsjfmvpqcevax@5nhnwbkzbrpa/ Fixes: 1f021341eef4 ("nvme-multipath: defer partition scanning") Signed-off-by: Shin'ichiro Kawasaki Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 57416bbf9344..578f4f29eacf 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -686,7 +686,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) return; } nvme_add_ns_head_cdev(head); - kblockd_schedule_work(&head->partition_scan_work); + queue_work(nvme_wq, &head->partition_scan_work); } mutex_lock(&head->lock); -- Gitee From 2d5d187bae94f5b5b8f14c11a77b07b168252b95 Mon Sep 17 00:00:00 2001 From: Aleksei Nikiforov Date: Thu, 13 Nov 2025 02:27:24 +0800 Subject: [PATCH 0045/1449] s390/ctcm: Fix double-kfree ANBZ: #35228 commit 3b177b2ded563df16f6d5920671ffcfe5915d472 stable. commit da02a1824884d6c84c5e5b5ac373b0c9e3288ec2 upstream. The function 'mpc_rcvd_sweep_req(mpcginfo)' is called conditionally from function 'ctcmpc_unpack_skb'. It frees passed mpcginfo. After that a call to function 'kfree' in function 'ctcmpc_unpack_skb' frees it again. Remove 'kfree' call in function 'mpc_rcvd_sweep_req(mpcginfo)'. Bug detected by the clang static analyzer. Fixes: 0c0b20587b9f25a2 ("s390/ctcm: fix potential memory leak") Reviewed-by: Aswin Karuvally Signed-off-by: Aleksei Nikiforov Signed-off-by: Aswin Karuvally Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251112182724.1109474-1-aswin@linux.ibm.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/s390/net/ctcm_mpc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 7a2f34a5e0e0..f8b3e3f7b8ce 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -700,7 +700,6 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo) grp->sweep_req_pend_num--; ctcmpc_send_sweep_resp(ch); - kfree(mpcginfo); return; } -- Gitee From e814181d4cfa318d538760af08fee58cd5c6659d Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 17 Nov 2025 11:33:54 +0800 Subject: [PATCH 0046/1449] platform/x86/intel/speed_select_if: Convert PCIBIOS_* return codes to errnos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9bbb4afff974d663d9e595ae82425fb7257794ea stable. commit d8bb447efc5622577994287dc77c684fa8840b30 upstream. isst_if_probe() uses pci_read_config_dword() that returns PCIBIOS_* codes. The return code is returned from the probe function as is but probe functions should return normal errnos. A proper implementation can be found in drivers/leds/leds-ss4200.c. Convert PCIBIOS_* return codes using pcibios_err_to_errno() into normal errno before returning. Fixes: d3a23584294c ("platform/x86: ISST: Add Intel Speed Select mmio interface") Signed-off-by: Haotian Zhang Acked-by: Srinivas Pandruvada Link: https://patch.msgid.link/20251117033354.132-1-vulab@iscas.ac.cn Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c b/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c index 3f4343147dad..950ede5eab76 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_if_mmio.c @@ -108,11 +108,11 @@ static int isst_if_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ret = pci_read_config_dword(pdev, 0xD0, &mmio_base); if (ret) - return ret; + return pcibios_err_to_errno(ret); ret = pci_read_config_dword(pdev, 0xFC, &pcu_base); if (ret) - return ret; + return pcibios_err_to_errno(ret); pcu_base &= GENMASK(10, 0); base_addr = (u64)mmio_base << 23 | (u64) pcu_base << 12; -- Gitee From 1d1e2dde657c9aa16c997bea1806168133f2a2fd Mon Sep 17 00:00:00 2001 From: Pavel Zhigulin Date: Thu, 13 Nov 2025 19:27:56 +0800 Subject: [PATCH 0047/1449] net: qlogic/qede: fix potential out-of-bounds read in qede_tpa_cont() and qede_tpa_end() ANBZ: #35228 commit f0923011c1261b33a2ac1de349256d39cb750dd0 stable. commit 896f1a2493b59beb2b5ccdf990503dbb16cb2256 upstream. The loops in 'qede_tpa_cont()' and 'qede_tpa_end()', iterate over 'cqe->len_list[]' using only a zero-length terminator as the stopping condition. If the terminator was missing or malformed, the loop could run past the end of the fixed-size array. Add an explicit bound check using ARRAY_SIZE() in both loops to prevent a potential out-of-bounds access. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 55482edc25f0 ("qede: Add slowpath/fastpath support and enable hardware GRO") Signed-off-by: Pavel Zhigulin Link: https://patch.msgid.link/20251113112757.4166625-1-Pavel.Zhigulin@kaspersky.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/qlogic/qede/qede_fp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c index cb1746bc0e0c..273dae622c41 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c @@ -4,6 +4,7 @@ * Copyright (c) 2019-2020 Marvell International Ltd. */ +#include #include #include #include @@ -960,7 +961,7 @@ static inline void qede_tpa_cont(struct qede_dev *edev, { int i; - for (i = 0; cqe->len_list[i]; i++) + for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++) qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index, le16_to_cpu(cqe->len_list[i])); @@ -985,7 +986,7 @@ static int qede_tpa_end(struct qede_dev *edev, dma_unmap_page(rxq->dev, tpa_info->buffer.mapping, PAGE_SIZE, rxq->data_direction); - for (i = 0; cqe->len_list[i]; i++) + for (i = 0; cqe->len_list[i] && i < ARRAY_SIZE(cqe->len_list); i++) qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index, le16_to_cpu(cqe->len_list[i])); if (unlikely(i > 1)) -- Gitee From 812d87873b18eccd12ab0dac992f560740a7e061 Mon Sep 17 00:00:00 2001 From: Jared Kangas Date: Wed, 12 Nov 2025 05:54:11 +0800 Subject: [PATCH 0048/1449] pinctrl: s32cc: fix uninitialized memory in s32_pinctrl_desc ANBZ: #35228 commit 3b90bd8aaeb21b513ecc4ed03299e80ece44a333 stable. commit 97ea34defbb57bfaf71ce487b1b0865ffd186e81 upstream. s32_pinctrl_desc is allocated with devm_kmalloc(), but not all of its fields are initialized. Notably, num_custom_params is used in pinconf_generic_parse_dt_config(), resulting in intermittent allocation errors, such as the following splat when probing i2c-imx: WARNING: CPU: 0 PID: 176 at mm/page_alloc.c:4795 __alloc_pages_noprof+0x290/0x300 [...] Hardware name: NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3) (DT) [...] Call trace: __alloc_pages_noprof+0x290/0x300 (P) ___kmalloc_large_node+0x84/0x168 __kmalloc_large_node_noprof+0x34/0x120 __kmalloc_noprof+0x2ac/0x378 pinconf_generic_parse_dt_config+0x68/0x1a0 s32_dt_node_to_map+0x104/0x248 dt_to_map_one_config+0x154/0x1d8 pinctrl_dt_to_map+0x12c/0x280 create_pinctrl+0x6c/0x270 pinctrl_get+0xc0/0x170 devm_pinctrl_get+0x50/0xa0 pinctrl_bind_pins+0x60/0x2a0 really_probe+0x60/0x3a0 [...] __platform_driver_register+0x2c/0x40 i2c_adap_imx_init+0x28/0xff8 [i2c_imx] [...] This results in later parse failures that can cause issues in dependent drivers: s32g-siul2-pinctrl 4009c240.pinctrl: /soc@0/pinctrl@4009c240/i2c0-pins/i2c0-grp0: could not parse node property s32g-siul2-pinctrl 4009c240.pinctrl: /soc@0/pinctrl@4009c240/i2c0-pins/i2c0-grp0: could not parse node property [...] pca953x 0-0022: failed writing register: -6 i2c i2c-0: IMX I2C adapter registered s32g-siul2-pinctrl 4009c240.pinctrl: /soc@0/pinctrl@4009c240/i2c2-pins/i2c2-grp0: could not parse node property s32g-siul2-pinctrl 4009c240.pinctrl: /soc@0/pinctrl@4009c240/i2c2-pins/i2c2-grp0: could not parse node property i2c i2c-1: IMX I2C adapter registered s32g-siul2-pinctrl 4009c240.pinctrl: /soc@0/pinctrl@4009c240/i2c4-pins/i2c4-grp0: could not parse node property s32g-siul2-pinctrl 4009c240.pinctrl: /soc@0/pinctrl@4009c240/i2c4-pins/i2c4-grp0: could not parse node property i2c i2c-2: IMX I2C adapter registered Fix this by initializing s32_pinctrl_desc with devm_kzalloc() instead of devm_kmalloc() in s32_pinctrl_probe(), which sets the previously uninitialized fields to zero. Fixes: fd84aaa8173d ("pinctrl: add NXP S32 SoC family support") Signed-off-by: Jared Kangas Tested-by: Jan Petrous (OSS) Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/nxp/pinctrl-s32cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c index 08d80fb935b3..9e97968e25fc 100644 --- a/drivers/pinctrl/nxp/pinctrl-s32cc.c +++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c @@ -943,7 +943,7 @@ int s32_pinctrl_probe(struct platform_device *pdev, spin_lock_init(&ipctl->gpio_configs_lock); s32_pinctrl_desc = - devm_kmalloc(&pdev->dev, sizeof(*s32_pinctrl_desc), GFP_KERNEL); + devm_kzalloc(&pdev->dev, sizeof(*s32_pinctrl_desc), GFP_KERNEL); if (!s32_pinctrl_desc) return -ENOMEM; -- Gitee From 37cdc7da09832a15f1ce03a819fba43e98fa6708 Mon Sep 17 00:00:00 2001 From: Jared Kangas Date: Wed, 12 Nov 2025 05:54:12 +0800 Subject: [PATCH 0049/1449] pinctrl: s32cc: initialize gpio_pin_config::list after kmalloc() ANBZ: #35228 commit 6d9f0036d21e86d6500b7c3d264216854c7d12e6 stable. commit 6010d4d8b55b5d3ae1efb5502c54312e15c14f21 upstream. s32_pmx_gpio_request_enable() does not initialize the newly-allocated gpio_pin_config::list before adding it to s32_pinctrl::gpio_configs. This could result in a linked list corruption. Initialize the new list_head with INIT_LIST_HEAD() to fix this. Fixes: fd84aaa8173d ("pinctrl: add NXP S32 SoC family support") Signed-off-by: Jared Kangas Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/nxp/pinctrl-s32cc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c index 9e97968e25fc..9c435e44abb4 100644 --- a/drivers/pinctrl/nxp/pinctrl-s32cc.c +++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c @@ -392,6 +392,7 @@ static int s32_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, gpio_pin->pin_id = offset; gpio_pin->config = config; + INIT_LIST_HEAD(&gpio_pin->list); spin_lock_irqsave(&ipctl->gpio_configs_lock, flags); list_add(&gpio_pin->list, &ipctl->gpio_configs); -- Gitee From 0f8f376383466db0286167c2b0440a8b934fe1f1 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Mon, 17 Nov 2025 20:05:49 +0800 Subject: [PATCH 0050/1449] devlink: rate: Unset parent pointer in devl_rate_nodes_destroy ANBZ: #35228 commit 715d9cda646a8a38ea8b2bb5afb679a7464055e2 stable. commit f94c1a114ac209977bdf5ca841b98424295ab1f0 upstream. The function devl_rate_nodes_destroy is documented to "Unset parent for all rate objects". However, it was only calling the driver-specific `rate_leaf_parent_set` or `rate_node_parent_set` ops and decrementing the parent's refcount, without actually setting the `devlink_rate->parent` pointer to NULL. This leaves a dangling pointer in the `devlink_rate` struct, which cause refcount error in netdevsim[1] and mlx5[2]. In addition, this is inconsistent with the behavior of `devlink_nl_rate_parent_node_set`, where the parent pointer is correctly cleared. This patch fixes the issue by explicitly setting `devlink_rate->parent` to NULL after notifying the driver, thus fulfilling the function's documented behavior for all rate objects. [1] repro steps: echo 1 > /sys/bus/netdevsim/new_device devlink dev eswitch set netdevsim/netdevsim1 mode switchdev echo 1 > /sys/bus/netdevsim/devices/netdevsim1/sriov_numvfs devlink port function rate add netdevsim/netdevsim1/test_node devlink port function rate set netdevsim/netdevsim1/128 parent test_node echo 1 > /sys/bus/netdevsim/del_device dmesg: refcount_t: decrement hit 0; leaking memory. WARNING: CPU: 8 PID: 1530 at lib/refcount.c:31 refcount_warn_saturate+0x42/0xe0 CPU: 8 UID: 0 PID: 1530 Comm: bash Not tainted 6.18.0-rc4+ #1 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:refcount_warn_saturate+0x42/0xe0 Call Trace: devl_rate_leaf_destroy+0x8d/0x90 __nsim_dev_port_del+0x6c/0x70 [netdevsim] nsim_dev_reload_destroy+0x11c/0x140 [netdevsim] nsim_drv_remove+0x2b/0xb0 [netdevsim] device_release_driver_internal+0x194/0x1f0 bus_remove_device+0xc6/0x130 device_del+0x159/0x3c0 device_unregister+0x1a/0x60 del_device_store+0x111/0x170 [netdevsim] kernfs_fop_write_iter+0x12e/0x1e0 vfs_write+0x215/0x3d0 ksys_write+0x5f/0xd0 do_syscall_64+0x55/0x10f0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 [2] devlink dev eswitch set pci/0000:08:00.0 mode switchdev devlink port add pci/0000:08:00.0 flavour pcisf pfnum 0 sfnum 1000 devlink port function rate add pci/0000:08:00.0/group1 devlink port function rate set pci/0000:08:00.0/32768 parent group1 modprobe -r mlx5_ib mlx5_fwctl mlx5_core dmesg: refcount_t: decrement hit 0; leaking memory. WARNING: CPU: 7 PID: 16151 at lib/refcount.c:31 refcount_warn_saturate+0x42/0xe0 CPU: 7 UID: 0 PID: 16151 Comm: bash Not tainted 6.17.0-rc7_for_upstream_min_debug_2025_10_02_12_44 #1 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 RIP: 0010:refcount_warn_saturate+0x42/0xe0 Call Trace: devl_rate_leaf_destroy+0x8d/0x90 mlx5_esw_offloads_devlink_port_unregister+0x33/0x60 [mlx5_core] mlx5_esw_offloads_unload_rep+0x3f/0x50 [mlx5_core] mlx5_eswitch_unload_sf_vport+0x40/0x90 [mlx5_core] mlx5_sf_esw_event+0xc4/0x120 [mlx5_core] notifier_call_chain+0x33/0xa0 blocking_notifier_call_chain+0x3b/0x50 mlx5_eswitch_disable_locked+0x50/0x110 [mlx5_core] mlx5_eswitch_disable+0x63/0x90 [mlx5_core] mlx5_unload+0x1d/0x170 [mlx5_core] mlx5_uninit_one+0xa2/0x130 [mlx5_core] remove_one+0x78/0xd0 [mlx5_core] pci_device_remove+0x39/0xa0 device_release_driver_internal+0x194/0x1f0 unbind_store+0x99/0xa0 kernfs_fop_write_iter+0x12e/0x1e0 vfs_write+0x215/0x3d0 ksys_write+0x5f/0xd0 do_syscall_64+0x53/0x1f0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 Fixes: d75559845078 ("devlink: Allow setting parent node of rate objects") Signed-off-by: Shay Drory Reviewed-by: Carolina Jubran Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1763381149-1234377-1-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/devlink/rate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/devlink/rate.c b/net/devlink/rate.c index dff1593b8406..e7e80af4abaf 100644 --- a/net/devlink/rate.c +++ b/net/devlink/rate.c @@ -702,13 +702,15 @@ void devl_rate_nodes_destroy(struct devlink *devlink) if (!devlink_rate->parent) continue; - refcount_dec(&devlink_rate->parent->refcnt); if (devlink_rate_is_leaf(devlink_rate)) ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, NULL, NULL); else if (devlink_rate_is_node(devlink_rate)) ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, NULL, NULL); + + refcount_dec(&devlink_rate->parent->refcnt); + devlink_rate->parent = NULL; } list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { if (devlink_rate_is_node(devlink_rate)) { -- Gitee From abc91c663d57d1d259616255fbb495d4cae2c098 Mon Sep 17 00:00:00 2001 From: Pradyumn Rahar Date: Mon, 17 Nov 2025 20:16:08 +0800 Subject: [PATCH 0051/1449] net/mlx5: Clean up only new IRQ glue on request_irq() failure ANBZ: #35228 commit 69e043bce09c9a77e5f55b9ac7505874a2a1a9f0 stable. commit d47515af6cccd7484d8b0870376858c9848a18ec upstream. The mlx5_irq_alloc() function can inadvertently free the entire rmap and end up in a crash[1] when the other threads tries to access this, when request_irq() fails due to exhausted IRQ vectors. This commit modifies the cleanup to remove only the specific IRQ mapping that was just added. This prevents removal of other valid mappings and ensures precise cleanup of the failed IRQ allocation's associated glue object. Note: This error is observed when both fwctl and rds configs are enabled. [1] mlx5_core 0000:05:00.0: Successfully registered panic handler for port 1 mlx5_core 0000:05:00.0: mlx5_irq_alloc:293:(pid 66740): Failed to request irq. err = -28 infiniband mlx5_0: mlx5_ib_test_wc:290:(pid 66740): Error -28 while trying to test write-combining support mlx5_core 0000:05:00.0: Successfully unregistered panic handler for port 1 mlx5_core 0000:06:00.0: Successfully registered panic handler for port 1 mlx5_core 0000:06:00.0: mlx5_irq_alloc:293:(pid 66740): Failed to request irq. err = -28 infiniband mlx5_0: mlx5_ib_test_wc:290:(pid 66740): Error -28 while trying to test write-combining support mlx5_core 0000:06:00.0: Successfully unregistered panic handler for port 1 mlx5_core 0000:03:00.0: mlx5_irq_alloc:293:(pid 28895): Failed to request irq. err = -28 mlx5_core 0000:05:00.0: mlx5_irq_alloc:293:(pid 28895): Failed to request irq. err = -28 general protection fault, probably for non-canonical address 0xe277a58fde16f291: 0000 [#1] SMP NOPTI RIP: 0010:free_irq_cpu_rmap+0x23/0x7d Call Trace: ? show_trace_log_lvl+0x1d6/0x2f9 ? show_trace_log_lvl+0x1d6/0x2f9 ? mlx5_irq_alloc.cold+0x5d/0xf3 [mlx5_core] ? __die_body.cold+0x8/0xa ? die_addr+0x39/0x53 ? exc_general_protection+0x1c4/0x3e9 ? dev_vprintk_emit+0x5f/0x90 ? asm_exc_general_protection+0x22/0x27 ? free_irq_cpu_rmap+0x23/0x7d mlx5_irq_alloc.cold+0x5d/0xf3 [mlx5_core] irq_pool_request_vector+0x7d/0x90 [mlx5_core] mlx5_irq_request+0x2e/0xe0 [mlx5_core] mlx5_irq_request_vector+0xad/0xf7 [mlx5_core] comp_irq_request_pci+0x64/0xf0 [mlx5_core] create_comp_eq+0x71/0x385 [mlx5_core] ? mlx5e_open_xdpsq+0x11c/0x230 [mlx5_core] mlx5_comp_eqn_get+0x72/0x90 [mlx5_core] ? xas_load+0x8/0x91 mlx5_comp_irqn_get+0x40/0x90 [mlx5_core] mlx5e_open_channel+0x7d/0x3c7 [mlx5_core] mlx5e_open_channels+0xad/0x250 [mlx5_core] mlx5e_open_locked+0x3e/0x110 [mlx5_core] mlx5e_open+0x23/0x70 [mlx5_core] __dev_open+0xf1/0x1a5 __dev_change_flags+0x1e1/0x249 dev_change_flags+0x21/0x5c do_setlink+0x28b/0xcc4 ? __nla_parse+0x22/0x3d ? inet6_validate_link_af+0x6b/0x108 ? cpumask_next+0x1f/0x35 ? __snmp6_fill_stats64.constprop.0+0x66/0x107 ? __nla_validate_parse+0x48/0x1e6 __rtnl_newlink+0x5ff/0xa57 ? kmem_cache_alloc_trace+0x164/0x2ce rtnl_newlink+0x44/0x6e rtnetlink_rcv_msg+0x2bb/0x362 ? __netlink_sendskb+0x4c/0x6c ? netlink_unicast+0x28f/0x2ce ? rtnl_calcit.isra.0+0x150/0x146 netlink_rcv_skb+0x5f/0x112 netlink_unicast+0x213/0x2ce netlink_sendmsg+0x24f/0x4d9 __sock_sendmsg+0x65/0x6a ____sys_sendmsg+0x28f/0x2c9 ? import_iovec+0x17/0x2b ___sys_sendmsg+0x97/0xe0 __sys_sendmsg+0x81/0xd8 do_syscall_64+0x35/0x87 entry_SYSCALL_64_after_hwframe+0x6e/0x0 RIP: 0033:0x7fc328603727 Code: c3 66 90 41 54 41 89 d4 55 48 89 f5 53 89 fb 48 83 ec 10 e8 0b ed ff ff 44 89 e2 48 89 ee 89 df 41 89 c0 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 48 89 44 24 08 e8 44 ed ff ff 48 RSP: 002b:00007ffe8eb3f1a0 EFLAGS: 00000293 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 000000000000000d RCX: 00007fc328603727 RDX: 0000000000000000 RSI: 00007ffe8eb3f1f0 RDI: 000000000000000d RBP: 00007ffe8eb3f1f0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000293 R12: 0000000000000000 R13: 0000000000000000 R14: 00007ffe8eb3f3c8 R15: 00007ffe8eb3f3bc ---[ end trace f43ce73c3c2b13a2 ]--- RIP: 0010:free_irq_cpu_rmap+0x23/0x7d Code: 0f 1f 80 00 00 00 00 48 85 ff 74 6b 55 48 89 fd 53 66 83 7f 06 00 74 24 31 db 48 8b 55 08 0f b7 c3 48 8b 04 c2 48 85 c0 74 09 <8b> 38 31 f6 e8 c4 0a b8 ff 83 c3 01 66 3b 5d 06 72 de b8 ff ff ff RSP: 0018:ff384881640eaca0 EFLAGS: 00010282 RAX: e277a58fde16f291 RBX: 0000000000000000 RCX: 0000000000000000 RDX: ff2335e2e20b3600 RSI: 0000000000000000 RDI: ff2335e2e20b3400 RBP: ff2335e2e20b3400 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 00000000ffffffe4 R12: ff384881640ead88 R13: ff2335c3760751e0 R14: ff2335e2e1672200 R15: ff2335c3760751f8 FS: 00007fc32ac22480(0000) GS:ff2335e2d6e00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f651ab54000 CR3: 00000029f1206003 CR4: 0000000000771ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Kernel panic - not syncing: Fatal exception Kernel Offset: 0x1dc00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) kvm-guest: disable async PF for cpu 0 Fixes: 3354822cde5a ("net/mlx5: Use dynamic msix vectors allocation") Signed-off-by: Mohith Kumar Thummaluru Tested-by: Mohith Kumar Thummaluru Reviewed-by: Moshe Shemesh Reviewed-by: Shay Drori Signed-off-by: Pradyumn Rahar Reviewed-by: Jacob Keller Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1763381768-1234998-1-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c index a8d6fd18c0f5..487d8b413a41 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -323,10 +323,8 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i, free_irq(irq->map.virq, &irq->nh); err_req_irq: #ifdef CONFIG_RFS_ACCEL - if (i && rmap && *rmap) { - free_irq_cpu_rmap(*rmap); - *rmap = NULL; - } + if (i && rmap && *rmap) + irq_cpu_rmap_remove(*rmap, irq->map.virq); err_irq_rmap: #endif if (i && pci_msix_can_alloc_dyn(dev->pdev)) -- Gitee From 83b17ea0ab730dadf0d7c05165cf4f4e5cfd8171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Thu, 20 Nov 2025 14:42:05 +0800 Subject: [PATCH 0052/1449] LoongArch: Use UAPI types in ptrace UAPI header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 496d1383e4414e15325513b48f5bd8751776bf94 stable. commit 20d7338f2d3bcb570068dd6d39b16f1a909fe976 upstream. The kernel UAPI headers already contain fixed-width integer types, there is no need to rely on the libc types. There may not be a libc available or the libc may not provides the , like for example on nolibc. This also aligns the header with the rest of the LoongArch UAPI headers. Fixes: 803b0fc5c3f2 ("LoongArch: Add process management") Signed-off-by: Thomas Weißschuh Signed-off-by: Huacai Chen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/include/uapi/asm/ptrace.h | 40 +++++++++++------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/arch/loongarch/include/uapi/asm/ptrace.h b/arch/loongarch/include/uapi/asm/ptrace.h index aafb3cd9e943..215e0f9e8aa3 100644 --- a/arch/loongarch/include/uapi/asm/ptrace.h +++ b/arch/loongarch/include/uapi/asm/ptrace.h @@ -10,10 +10,6 @@ #include -#ifndef __KERNEL__ -#include -#endif - /* * For PTRACE_{POKE,PEEK}USR. 0 - 31 are GPRs, * 32 is syscall's original ARG0, 33 is PC, 34 is BADVADDR. @@ -41,44 +37,44 @@ struct user_pt_regs { } __attribute__((aligned(8))); struct user_fp_state { - uint64_t fpr[32]; - uint64_t fcc; - uint32_t fcsr; + __u64 fpr[32]; + __u64 fcc; + __u32 fcsr; }; struct user_lsx_state { /* 32 registers, 128 bits width per register. */ - uint64_t vregs[32*2]; + __u64 vregs[32*2]; }; struct user_lasx_state { /* 32 registers, 256 bits width per register. */ - uint64_t vregs[32*4]; + __u64 vregs[32*4]; }; struct user_lbt_state { - uint64_t scr[4]; - uint32_t eflags; - uint32_t ftop; + __u64 scr[4]; + __u32 eflags; + __u32 ftop; }; struct user_watch_state { - uint64_t dbg_info; + __u64 dbg_info; struct { - uint64_t addr; - uint64_t mask; - uint32_t ctrl; - uint32_t pad; + __u64 addr; + __u64 mask; + __u32 ctrl; + __u32 pad; } dbg_regs[8]; }; struct user_watch_state_v2 { - uint64_t dbg_info; + __u64 dbg_info; struct { - uint64_t addr; - uint64_t mask; - uint32_t ctrl; - uint32_t pad; + __u64 addr; + __u64 mask; + __u32 ctrl; + __u32 pad; } dbg_regs[14]; }; -- Gitee From 8e38b262f7048c37fb4bc454670dd9a5f2f2d0f9 Mon Sep 17 00:00:00 2001 From: Shaurya Rane Date: Tue, 18 Nov 2025 23:02:57 +0800 Subject: [PATCH 0053/1449] cifs: fix memory leak in smb3_fs_context_parse_param error path ANBZ: #35228 commit 7627864dc3121f39e220f5253a227edf472de59e stable. commit 7e4d9120cfa413dd34f4f434befc5dbe6c38b2e5 upstream. Add proper cleanup of ctx->source and fc->source to the cifs_parse_mount_err error handler. This ensures that memory allocated for the source strings is correctly freed on all error paths, matching the cleanup already performed in the success path by smb3_cleanup_fs_context_contents(). Pointers are also set to NULL after freeing to prevent potential double-free issues. This change fixes a memory leak originally detected by syzbot. The leak occurred when processing Opt_source mount options if an error happened after ctx->source and fc->source were successfully allocated but before the function completed. The specific leak sequence was: 1. ctx->source = smb3_fs_context_fullpath(ctx, '/') allocates memory 2. fc->source = kstrdup(ctx->source, GFP_KERNEL) allocates more memory 3. A subsequent error jumps to cifs_parse_mount_err 4. The old error handler freed passwords but not the source strings, causing the memory to leak. This issue was not addressed by commit e8c73eb7db0a ("cifs: client: fix memory leak in smb3_fs_context_parse_param"), which only fixed leaks from repeated fsconfig() calls but not this error path. Patch updated with minor change suggested by kernel test robot Reported-by: syzbot+87be6809ed9bf6d718e3@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=87be6809ed9bf6d718e3 Fixes: 24e0a1eff9e2 ("cifs: switch to new mount api") Reviewed-by: David Howells Signed-off-by: Shaurya Rane Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/fs_context.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index cf233cb9c194..a64c0b0dbec7 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -1726,6 +1726,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, ctx->password = NULL; kfree_sensitive(ctx->password2); ctx->password2 = NULL; + kfree(ctx->source); + ctx->source = NULL; + kfree(fc->source); + fc->source = NULL; return -EINVAL; } -- Gitee From f244d4026fd7db60c581a9bd25a96649abf4147a Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Wed, 19 Nov 2025 22:02:59 +0800 Subject: [PATCH 0054/1449] vsock: Ignore signal/timeout on connect() if already established ANBZ: #35228 commit 5998da5a8208ae9ad7838ba322bccb2bdcd95e81 stable. commit 002541ef650b742a198e4be363881439bb9d86b4 upstream. During connect(), acting on a signal/timeout by disconnecting an already established socket leads to several issues: 1. connect() invoking vsock_transport_cancel_pkt() -> virtio_transport_purge_skbs() may race with sendmsg() invoking virtio_transport_get_credit(). This results in a permanently elevated `vvs->bytes_unsent`. Which, in turn, confuses the SOCK_LINGER handling. 2. connect() resetting a connected socket's state may race with socket being placed in a sockmap. A disconnected socket remaining in a sockmap breaks sockmap's assumptions. And gives rise to WARNs. 3. connect() transitioning SS_CONNECTED -> SS_UNCONNECTED allows for a transport change/drop after TCP_ESTABLISHED. Which poses a problem for any simultaneous sendmsg() or connect() and may result in a use-after-free/null-ptr-deref. Do not disconnect socket on signal/timeout. Keep the logic for unconnected sockets: they don't linger, can't be placed in a sockmap, are rejected by sendmsg(). [1]: https://lore.kernel.org/netdev/e07fd95c-9a38-4eea-9638-133e38c2ec9b@rbox.co/ [2]: https://lore.kernel.org/netdev/20250317-vsock-trans-signal-race-v4-0-fc8837f3f1d4@rbox.co/ [3]: https://lore.kernel.org/netdev/60f1b7db-3099-4f6a-875e-af9f6ef194f6@rbox.co/ Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Signed-off-by: Michal Luczaj Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251119-vsock-interrupted-connect-v2-1-70734cf1233f@rbox.co Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/vmw_vsock/af_vsock.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 64790062cfa2..ca1289e64bcc 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1550,18 +1550,40 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr, timeout = schedule_timeout(timeout); lock_sock(sk); - if (signal_pending(current)) { - err = sock_intr_errno(timeout); - sk->sk_state = sk->sk_state == TCP_ESTABLISHED ? TCP_CLOSING : TCP_CLOSE; - sock->state = SS_UNCONNECTED; - vsock_transport_cancel_pkt(vsk); - vsock_remove_connected(vsk); - goto out_wait; - } else if ((sk->sk_state != TCP_ESTABLISHED) && (timeout == 0)) { - err = -ETIMEDOUT; + /* Connection established. Whatever happens to socket once we + * release it, that's not connect()'s concern. No need to go + * into signal and timeout handling. Call it a day. + * + * Note that allowing to "reset" an already established socket + * here is racy and insecure. + */ + if (sk->sk_state == TCP_ESTABLISHED) + break; + + /* If connection was _not_ established and a signal/timeout came + * to be, we want the socket's state reset. User space may want + * to retry. + * + * sk_state != TCP_ESTABLISHED implies that socket is not on + * vsock_connected_table. We keep the binding and the transport + * assigned. + */ + if (signal_pending(current) || timeout == 0) { + err = timeout == 0 ? -ETIMEDOUT : sock_intr_errno(timeout); + + /* Listener might have already responded with + * VIRTIO_VSOCK_OP_RESPONSE. Its handling expects our + * sk_state == TCP_SYN_SENT, which hereby we break. + * In such case VIRTIO_VSOCK_OP_RST will follow. + */ sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; + + /* Try to cancel VIRTIO_VSOCK_OP_REQUEST skb sent out by + * transport->connect(). + */ vsock_transport_cancel_pkt(vsk); + goto out_wait; } -- Gitee From 6c0c260a108c50046983956bb9502d90c5d0c902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 3 Oct 2025 20:51:26 +0800 Subject: [PATCH 0055/1449] bcma: don't register devices disabled in OF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d89ae707cfe684f934fb175ae48e5d698d55f83e stable. commit a2a69add80411dd295c9088c1bcf925b1f4e53d7 upstream. Some bus devices can be marked as disabled for specific SoCs or models. Those should not be registered to avoid probing them. Signed-off-by: Rafał Miłecki Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20251003125126.27950-1-zajec5@gmail.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bcma/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 7061d3ee836a..c69c05256b59 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -294,6 +294,8 @@ static int bcma_register_devices(struct bcma_bus *bus) int err; list_for_each_entry(core, &bus->cores, list) { + struct device_node *np; + /* We support that core ourselves */ switch (core->id.id) { case BCMA_CORE_4706_CHIPCOMMON: @@ -311,6 +313,10 @@ static int bcma_register_devices(struct bcma_bus *bus) if (bcma_is_core_needed_early(core->id.id)) continue; + np = core->dev.of_node; + if (np && !of_device_is_available(np)) + continue; + /* Only first GMAC core on BCM4706 is connected and working */ if (core->id.id == BCMA_CORE_4706_MAC_GBIT && core->core_unit > 0) -- Gitee From 292f34bee55f7c115eca730533d9f88078e65e96 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 25 Oct 2025 10:17:01 +0800 Subject: [PATCH 0056/1449] cifs: fix typo in enable_gcm_256 module parameter ANBZ: #35228 commit 1f8e4d6c1d2057be6d7008c6db7adc82c740f9c4 stable. commit f765fdfcd8b5bce92c6aa1a517ff549529ddf590 upstream. Fix typo in description of enable_gcm_256 module parameter Suggested-by: Thomas Spear Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/cifsfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 2744d5580d19..0461f89c4852 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -133,7 +133,7 @@ module_param(enable_oplocks, bool, 0644); MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1"); module_param(enable_gcm_256, bool, 0644); -MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/0"); +MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: y/Y/1"); module_param(require_gcm_256, bool, 0644); MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0"); -- Gitee From cd8d44fd8f02807b3b8487a89c346a3262639a99 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 8 Oct 2025 05:48:00 +0800 Subject: [PATCH 0057/1449] scsi: core: Fix a regression triggered by scsi_host_busy() ANBZ: #35228 commit 5d778778b40bcdfd9f8817fea1ec6ebcbec69c0a stable. commit a0b7780602b1b196f47e527fec82166a7e67c4d0 upstream. Commit 995412e23bb2 ("blk-mq: Replace tags->lock with SRCU for tag iterators") introduced the following regression: Call trace: __srcu_read_lock+0x30/0x80 (P) blk_mq_tagset_busy_iter+0x44/0x300 scsi_host_busy+0x38/0x70 ufshcd_print_host_state+0x34/0x1bc ufshcd_link_startup.constprop.0+0xe4/0x2e0 ufshcd_init+0x944/0xf80 ufshcd_pltfrm_init+0x504/0x820 ufs_rockchip_probe+0x2c/0x88 platform_probe+0x5c/0xa4 really_probe+0xc0/0x38c __driver_probe_device+0x7c/0x150 driver_probe_device+0x40/0x120 __driver_attach+0xc8/0x1e0 bus_for_each_dev+0x7c/0xdc driver_attach+0x24/0x30 bus_add_driver+0x110/0x230 driver_register+0x68/0x130 __platform_driver_register+0x20/0x2c ufs_rockchip_pltform_init+0x1c/0x28 do_one_initcall+0x60/0x1e0 kernel_init_freeable+0x248/0x2c4 kernel_init+0x20/0x140 ret_from_fork+0x10/0x20 Fix this regression by making scsi_host_busy() check whether the SCSI host tag set has already been initialized. tag_set->ops is set by scsi_mq_setup_tags() just before blk_mq_alloc_tag_set() is called. This fix is based on the assumption that scsi_host_busy() and scsi_mq_setup_tags() calls are serialized. This is the case in the UFS driver. Reported-by: Sebastian Reichel Closes: https://lore.kernel.org/linux-block/pnezafputodmqlpumwfbn644ohjybouveehcjhz2hmhtcf2rka@sdhoiivync4y/ Cc: Ming Lei Cc: Jens Axboe Signed-off-by: Bart Van Assche Reviewed-by: Ming Lei Tested-by: Sebastian Reichel Link: https://patch.msgid.link/20251007214800.1678255-1-bvanassche@acm.org Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/hosts.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 445f4a220df3..f274812aee1e 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -602,8 +602,9 @@ int scsi_host_busy(struct Scsi_Host *shost) { int cnt = 0; - blk_mq_tagset_busy_iter(&shost->tag_set, - scsi_host_check_in_flight, &cnt); + if (shost->tag_set.ops) + blk_mq_tagset_busy_iter(&shost->tag_set, + scsi_host_check_in_flight, &cnt); return cnt; } EXPORT_SYMBOL(scsi_host_busy); -- Gitee From ec068ad87eccccab0dedb29a33937af9e3f5619a Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Thu, 23 Oct 2025 14:46:29 +0200 Subject: [PATCH 0058/1449] x86/microcode/AMD: Limit Entrysign signature checking to known generations ANBZ: #35228 commit 3ab328a0258fd51c348205efbd77f076a60bd75f stable. commit 8a9fb5129e8e64d24543ebc70de941a2d77a9e77 upstream. Limit Entrysign sha256 signature checking to CPUs in the range Zen1-Zen5. X86_BUG cannot be used here because the loading on the BSP happens way too early, before the cpufeatures machinery has been set up. Signed-off-by: Borislav Petkov (AMD) Link: https://patch.msgid.link/all/20251023124629.5385-1-bp@kernel.org Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- arch/x86/kernel/cpu/microcode/amd.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 5f9672625883..d01bd393a151 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -226,6 +226,24 @@ static bool need_sha_check(u32 cur_rev) return true; } +static bool cpu_has_entrysign(void) +{ + unsigned int fam = x86_family(bsp_cpuid_1_eax); + unsigned int model = x86_model(bsp_cpuid_1_eax); + + if (fam == 0x17 || fam == 0x19) + return true; + + if (fam == 0x1a) { + if (model <= 0x2f || + (0x40 <= model && model <= 0x4f) || + (0x60 <= model && model <= 0x6f)) + return true; + } + + return false; +} + static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsigned int len) { struct patch_digest *pd = NULL; @@ -233,9 +251,8 @@ static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsi struct sha256_state s; int i; - if ((x86_cpuid_vendor() == X86_VENDOR_AMD && - x86_family(bsp_cpuid_1_eax) < 0x17) || + !cpu_has_entrysign()) || x86_cpuid_vendor() == X86_VENDOR_HYGON) return true; -- Gitee From 6d5c6b9795188a1cf3667609d3eb00ba7c641416 Mon Sep 17 00:00:00 2001 From: Po-Hsu Lin Date: Mon, 27 Oct 2025 17:57:10 +0800 Subject: [PATCH 0059/1449] selftests: net: use BASH for bareudp testing ANBZ: #35228 commit 1bc765f0f75a8f7d5e6edda96772d681c536fcf4 stable. commit 9311e9540a8b406d9f028aa87fb072a3819d4c82 upstream. In bareudp.sh, this script uses /bin/sh and it will load another lib.sh BASH script at the very beginning. But on some operating systems like Ubuntu, /bin/sh is actually pointed to DASH, thus it will try to run BASH commands with DASH and consequently leads to syntax issues: # ./bareudp.sh: 4: ./lib.sh: Bad substitution # ./bareudp.sh: 5: ./lib.sh: source: not found # ./bareudp.sh: 24: ./lib.sh: Syntax error: "(" unexpected Fix this by explicitly using BASH for bareudp.sh. This fixes test execution failures on systems where /bin/sh is not BASH. Reported-by: Edoardo Canepa Link: https://bugs.launchpad.net/bugs/2129812 Signed-off-by: Po-Hsu Lin Reviewed-by: Przemek Kitszel Link: https://patch.msgid.link/20251027095710.2036108-2-po-hsu.lin@canonical.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/bareudp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/bareudp.sh b/tools/testing/selftests/net/bareudp.sh index f366cadbc5e8..ff4308b48e65 100755 --- a/tools/testing/selftests/net/bareudp.sh +++ b/tools/testing/selftests/net/bareudp.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Test various bareudp tunnel configurations. -- Gitee From 13c03143d78c643b9d4c4590eb1c73bca015f827 Mon Sep 17 00:00:00 2001 From: Shahar Shitrit Date: Mon, 27 Oct 2025 04:03:02 +0800 Subject: [PATCH 0060/1449] net: tls: Cancel RX async resync request on rcd_delta overflow ANBZ: #35228 commit 6ae0613ea6f54795d7e1d8986e06574fbaff9546 stable. commit c15d5c62ab313c19121f10e25d4fec852bd1c40c upstream. When a netdev issues a RX async resync request for a TLS connection, the TLS module handles it by logging record headers and attempting to match them to the tcp_sn provided by the device. If a match is found, the TLS module approves the tcp_sn for resynchronization. While waiting for a device response, the TLS module also increments rcd_delta each time a new TLS record is received, tracking the distance from the original resync request. However, if the device response is delayed or fails (e.g due to unstable connection and device getting out of tracking, hardware errors, resource exhaustion etc.), the TLS module keeps logging and incrementing, which can lead to a WARN() when rcd_delta exceeds the threshold. To address this, introduce tls_offload_rx_resync_async_request_cancel() to explicitly cancel resync requests when a device response failure is detected. Call this helper also as a final safeguard when rcd_delta crosses its threshold, as reaching this point implies that earlier cancellation did not occur. Signed-off-by: Shahar Shitrit Reviewed-by: Sabrina Dubroca Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1761508983-937977-3-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/tls.h | 6 ++++++ net/tls/tls_device.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/net/tls.h b/include/net/tls.h index f0f8309c2db6..4dd57b944daf 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -491,6 +491,12 @@ tls_offload_rx_resync_async_request_end(struct sock *sk, __be32 seq) ((u64)ntohl(seq) << 32) | RESYNC_REQ); } +static inline void +tls_offload_rx_resync_async_request_cancel(struct tls_offload_resync_async *resync_async) +{ + atomic64_set(&resync_async->req, 0); +} + static inline void tls_offload_rx_resync_set_type(struct sock *sk, enum tls_offload_sync_type type) { diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 8c94c926606a..4f72fd26ab40 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -727,8 +727,10 @@ tls_device_rx_resync_async(struct tls_offload_resync_async *resync_async, /* shouldn't get to wraparound: * too long in async stage, something bad happened */ - if (WARN_ON_ONCE(resync_async->rcd_delta == USHRT_MAX)) + if (WARN_ON_ONCE(resync_async->rcd_delta == USHRT_MAX)) { + tls_offload_rx_resync_async_request_cancel(resync_async); return false; + } /* asynchronous stage: log all headers seq such that * req_seq <= seq <= end_seq, and wait for real resync request -- Gitee From 28316ac5e726de1410401f23b1306f8738f7f643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Hork=C3=BD?= Date: Tue, 14 Oct 2025 23:49:32 +0800 Subject: [PATCH 0061/1449] kconfig/mconf: Initialize the default locale at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit be46fa4de9dad39a84f38a37d0b134146ec175a2 stable. commit 3927c4a1084c48ef97f11281a0a43ecb2cb4d6f1 upstream. Fix bug where make menuconfig doesn't initialize the default locale, which causes ncurses menu borders to be displayed incorrectly (lqqqqk) in UTF-8 terminals that don't support VT100 ACS by default, such as PuTTY. Signed-off-by: Jakub Horký Link: https://patch.msgid.link/20251014154933.3990990-1-jakub.git@horky.net [nathan: Alphabetize locale.h include] Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- scripts/kconfig/mconf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 3795c36a9181..2364140596c5 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1015,6 +1016,8 @@ int main(int ac, char **av) signal(SIGINT, sig_handler); + setlocale(LC_ALL, ""); + if (ac > 1 && strcmp(av[1], "-s") == 0) { silent = 1; /* Silence conf_read() until the real callback is set up */ -- Gitee From 2d5538b6436149c07af988565861c334eea17d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Hork=C3=BD?= Date: Tue, 14 Oct 2025 22:44:06 +0800 Subject: [PATCH 0062/1449] kconfig/nconf: Initialize the default locale at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d0141cf6ab1fa80fa3b3928c12369a44ea784332 stable. commit 43c2931a95e6b295bfe9e3b90dbe0f7596933e91 upstream. Fix bug where make nconfig doesn't initialize the default locale, which causes ncurses menu borders to be displayed incorrectly (lqqqqk) in UTF-8 terminals that don't support VT100 ACS by default, such as PuTTY. Signed-off-by: Jakub Horký Link: https://patch.msgid.link/20251014144405.3975275-2-jakub.git@horky.net [nathan: Alphabetize locale.h include] Signed-off-by: Nathan Chancellor Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- scripts/kconfig/nconf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 7a17c94a1594..a7cfa6813c63 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -7,6 +7,7 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif +#include #include #include #include @@ -1569,6 +1570,8 @@ int main(int ac, char **av) int lines, columns; char *mode; + setlocale(LC_ALL, ""); + if (ac > 1 && strcmp(av[1], "-s") == 0) { /* Silence conf_read() until the real callback is set up */ conf_set_message_callback(NULL); -- Gitee From 9e9c578bdb94c3d936a197c25717b3548ff6c91e Mon Sep 17 00:00:00 2001 From: Zhiguo Niu Date: Tue, 25 Nov 2025 14:40:27 +0800 Subject: [PATCH 0063/1449] f2fs: compress: change the first parameter of page_array_{alloc,free} to sbi ANBZ: #35228 commit 4e9efe0d56e73d10e2f72e0328b537cea93198ec stable. commit 8e2a9b656474d67c55010f2c003ea2cf889a19ff upstream. No logic changes, just cleanup and prepare for fixing the UAF issue in f2fs_free_dic. Signed-off-by: Zhiguo Niu Signed-off-by: Baocong Liu Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Bin Lan Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/compress.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 01de40477136..6a660acb8a45 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -23,20 +23,18 @@ static struct kmem_cache *cic_entry_slab; static struct kmem_cache *dic_entry_slab; -static void *page_array_alloc(struct inode *inode, int nr) +static void *page_array_alloc(struct f2fs_sb_info *sbi, int nr) { - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); unsigned int size = sizeof(struct page *) * nr; if (likely(size <= sbi->page_array_slab_size)) return f2fs_kmem_cache_alloc(sbi->page_array_slab, - GFP_F2FS_ZERO, false, F2FS_I_SB(inode)); + GFP_F2FS_ZERO, false, sbi); return f2fs_kzalloc(sbi, size, GFP_NOFS); } -static void page_array_free(struct inode *inode, void *pages, int nr) +static void page_array_free(struct f2fs_sb_info *sbi, void *pages, int nr) { - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); unsigned int size = sizeof(struct page *) * nr; if (!pages) @@ -145,13 +143,13 @@ int f2fs_init_compress_ctx(struct compress_ctx *cc) if (cc->rpages) return 0; - cc->rpages = page_array_alloc(cc->inode, cc->cluster_size); + cc->rpages = page_array_alloc(F2FS_I_SB(cc->inode), cc->cluster_size); return cc->rpages ? 0 : -ENOMEM; } void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse) { - page_array_free(cc->inode, cc->rpages, cc->cluster_size); + page_array_free(F2FS_I_SB(cc->inode), cc->rpages, cc->cluster_size); cc->rpages = NULL; cc->nr_rpages = 0; cc->nr_cpages = 0; @@ -614,6 +612,7 @@ static void *f2fs_vmap(struct page **pages, unsigned int count) static int f2fs_compress_pages(struct compress_ctx *cc) { + struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); struct f2fs_inode_info *fi = F2FS_I(cc->inode); const struct f2fs_compress_ops *cops = f2fs_cops[fi->i_compress_algorithm]; @@ -634,7 +633,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc) cc->nr_cpages = DIV_ROUND_UP(max_len, PAGE_SIZE); cc->valid_nr_cpages = cc->nr_cpages; - cc->cpages = page_array_alloc(cc->inode, cc->nr_cpages); + cc->cpages = page_array_alloc(sbi, cc->nr_cpages); if (!cc->cpages) { ret = -ENOMEM; goto destroy_compress_ctx; @@ -709,7 +708,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc) if (cc->cpages[i]) f2fs_compress_free_page(cc->cpages[i]); } - page_array_free(cc->inode, cc->cpages, cc->nr_cpages); + page_array_free(sbi, cc->cpages, cc->nr_cpages); cc->cpages = NULL; destroy_compress_ctx: if (cops->destroy_compress_ctx) @@ -1302,7 +1301,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, cic->magic = F2FS_COMPRESSED_PAGE_MAGIC; cic->inode = inode; atomic_set(&cic->pending_pages, cc->valid_nr_cpages); - cic->rpages = page_array_alloc(cc->inode, cc->cluster_size); + cic->rpages = page_array_alloc(sbi, cc->cluster_size); if (!cic->rpages) goto out_put_cic; @@ -1395,13 +1394,13 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, spin_unlock(&fi->i_size_lock); f2fs_put_rpages(cc); - page_array_free(cc->inode, cc->cpages, cc->nr_cpages); + page_array_free(sbi, cc->cpages, cc->nr_cpages); cc->cpages = NULL; f2fs_destroy_compress_ctx(cc, false); return 0; out_destroy_crypt: - page_array_free(cc->inode, cic->rpages, cc->cluster_size); + page_array_free(sbi, cic->rpages, cc->cluster_size); for (--i; i >= 0; i--) fscrypt_finalize_bounce_page(&cc->cpages[i]); @@ -1419,7 +1418,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, f2fs_compress_free_page(cc->cpages[i]); cc->cpages[i] = NULL; } - page_array_free(cc->inode, cc->cpages, cc->nr_cpages); + page_array_free(sbi, cc->cpages, cc->nr_cpages); cc->cpages = NULL; return -EAGAIN; } @@ -1449,7 +1448,7 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page) end_page_writeback(cic->rpages[i]); } - page_array_free(cic->inode, cic->rpages, cic->nr_rpages); + page_array_free(sbi, cic->rpages, cic->nr_rpages); kmem_cache_free(cic_entry_slab, cic); } @@ -1587,7 +1586,7 @@ static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) return 0; - dic->tpages = page_array_alloc(dic->inode, dic->cluster_size); + dic->tpages = page_array_alloc(F2FS_I_SB(dic->inode), dic->cluster_size); if (!dic->tpages) return -ENOMEM; @@ -1647,7 +1646,7 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) if (!dic) return ERR_PTR(-ENOMEM); - dic->rpages = page_array_alloc(cc->inode, cc->cluster_size); + dic->rpages = page_array_alloc(sbi, cc->cluster_size); if (!dic->rpages) { kmem_cache_free(dic_entry_slab, dic); return ERR_PTR(-ENOMEM); @@ -1668,7 +1667,7 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) dic->rpages[i] = cc->rpages[i]; dic->nr_rpages = cc->cluster_size; - dic->cpages = page_array_alloc(dic->inode, dic->nr_cpages); + dic->cpages = page_array_alloc(sbi, dic->nr_cpages); if (!dic->cpages) { ret = -ENOMEM; goto out_free; @@ -1698,6 +1697,7 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic, bool bypass_destroy_callback) { int i; + struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); f2fs_release_decomp_mem(dic, bypass_destroy_callback, true); @@ -1709,7 +1709,7 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic, continue; f2fs_compress_free_page(dic->tpages[i]); } - page_array_free(dic->inode, dic->tpages, dic->cluster_size); + page_array_free(sbi, dic->tpages, dic->cluster_size); } if (dic->cpages) { @@ -1718,10 +1718,10 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic, continue; f2fs_compress_free_page(dic->cpages[i]); } - page_array_free(dic->inode, dic->cpages, dic->nr_cpages); + page_array_free(sbi, dic->cpages, dic->nr_cpages); } - page_array_free(dic->inode, dic->rpages, dic->nr_rpages); + page_array_free(sbi, dic->rpages, dic->nr_rpages); kmem_cache_free(dic_entry_slab, dic); } -- Gitee From fad7c164c85368b1fbb1e781df9c6fdaa95f5b09 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 25 Nov 2025 18:51:07 +0800 Subject: [PATCH 0064/1449] s390/mm: Fix __ptep_rdp() inline assembly ANBZ: #35228 commit e822e902f8e63cdbadfd53f17ee1d268d2e8eca7 stable. commit 31475b88110c4725b4f9a79c3a0d9bbf97e69e1c upstream. When a zero ASCE is passed to the __ptep_rdp() inline assembly, the generated instruction should have the R3 field of the instruction set to zero. However the inline assembly is written incorrectly: for such cases a zero is loaded into a register allocated by the compiler and this register is then used by the instruction. This means that selected TLB entries may not be flushed since the specified ASCE does not match the one which was used when the selected TLB entries were created. Fix this by removing the asce and opt parameters of __ptep_rdp(), since all callers always pass zero, and use a hard-coded register zero for the R3 field. Fixes: 0807b856521f ("s390/mm: add support for RDP (Reset DAT-Protection)") Cc: stable@vger.kernel.org Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/s390/include/asm/pgtable.h | 12 +++++------- arch/s390/mm/pgtable.c | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 8fa940d9a974..afc9d5d1aef2 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1067,17 +1067,15 @@ static inline pte_t pte_mkhuge(pte_t pte) #define IPTE_NODAT 0x400 #define IPTE_GUEST_ASCE 0x800 -static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, - unsigned long opt, unsigned long asce, - int local) +static __always_inline void __ptep_rdp(unsigned long addr, pte_t *ptep, int local) { unsigned long pto; pto = __pa(ptep) & ~(PTRS_PER_PTE * sizeof(pte_t) - 1); - asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%[asce],%[m4]" + asm volatile(".insn rrf,0xb98b0000,%[r1],%[r2],%%r0,%[m4]" : "+m" (*ptep) - : [r1] "a" (pto), [r2] "a" ((addr & PAGE_MASK) | opt), - [asce] "a" (asce), [m4] "i" (local)); + : [r1] "a" (pto), [r2] "a" (addr & PAGE_MASK), + [m4] "i" (local)); } static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep, @@ -1261,7 +1259,7 @@ static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma, * A local RDP can be used to do the flush. */ if (MACHINE_HAS_RDP && !(pte_val(*ptep) & _PAGE_PROTECT)) - __ptep_rdp(address, ptep, 0, 0, 1); + __ptep_rdp(address, ptep, 1); } #define flush_tlb_fix_spurious_fault flush_tlb_fix_spurious_fault diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 5e349869590a..1fb435b3913c 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -312,9 +312,9 @@ void ptep_reset_dat_prot(struct mm_struct *mm, unsigned long addr, pte_t *ptep, preempt_disable(); atomic_inc(&mm->context.flush_count); if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __ptep_rdp(addr, ptep, 0, 0, 1); + __ptep_rdp(addr, ptep, 1); else - __ptep_rdp(addr, ptep, 0, 0, 0); + __ptep_rdp(addr, ptep, 0); /* * PTE is not invalidated by RDP, only _PAGE_PROTECT is cleared. That * means it is still valid and active, and must not be changed according -- Gitee From 86acef1e076b57173bc39039ea9b52b1f1621ea7 Mon Sep 17 00:00:00 2001 From: Zhiguo Niu Date: Tue, 25 Nov 2025 14:40:28 +0800 Subject: [PATCH 0065/1449] f2fs: compress: fix UAF of f2fs_inode_info in f2fs_free_dic ANBZ: #35228 commit 5d604d40cd3232b09cb339941ef958e49283ed0a stable. commit 39868685c2a94a70762bc6d77dc81d781d05bff5 upstream. The decompress_io_ctx may be released asynchronously after I/O completion. If this file is deleted immediately after read, and the kworker of processing post_read_wq has not been executed yet due to high workloads, It is possible that the inode(f2fs_inode_info) is evicted and freed before it is used f2fs_free_dic. The UAF case as below: Thread A Thread B - f2fs_decompress_end_io - f2fs_put_dic - queue_work add free_dic work to post_read_wq - do_unlink - iput - evict - call_rcu This file is deleted after read. Thread C kworker to process post_read_wq - rcu_do_batch - f2fs_free_inode - kmem_cache_free inode is freed by rcu - process_scheduled_works - f2fs_late_free_dic - f2fs_free_dic - f2fs_release_decomp_mem read (dic->inode)->i_compress_algorithm This patch store compress_algorithm and sbi in dic to avoid inode UAF. In addition, the previous solution is deprecated in [1] may cause system hang. [1] https://lore.kernel.org/all/c36ab955-c8db-4a8b-a9d0-f07b5f426c3f@kernel.org Cc: Daeho Jeong Fixes: bff139b49d9f ("f2fs: handle decompress only post processing in softirq") Signed-off-by: Zhiguo Niu Signed-off-by: Baocong Liu Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim [ In Linux 6.6.y, the f2fs_vmalloc() function parameters are not related to the f2fs_sb_info structure, the code changes for f2fs_vmalloc() have not been backported. ] Signed-off-by: Bin Lan Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/compress.c | 38 +++++++++++++++++++------------------- fs/f2fs/f2fs.h | 2 ++ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 6a660acb8a45..0b0a049be681 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -209,13 +209,13 @@ static int lzo_decompress_pages(struct decompress_io_ctx *dic) ret = lzo1x_decompress_safe(dic->cbuf->cdata, dic->clen, dic->rbuf, &dic->rlen); if (ret != LZO_E_OK) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "lzo decompress failed, ret:%d", ret); return -EIO; } if (dic->rlen != PAGE_SIZE << dic->log_cluster_size) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "lzo invalid rlen:%zu, expected:%lu", dic->rlen, PAGE_SIZE << dic->log_cluster_size); return -EIO; @@ -289,13 +289,13 @@ static int lz4_decompress_pages(struct decompress_io_ctx *dic) ret = LZ4_decompress_safe(dic->cbuf->cdata, dic->rbuf, dic->clen, dic->rlen); if (ret < 0) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "lz4 decompress failed, ret:%d", ret); return -EIO; } if (ret != PAGE_SIZE << dic->log_cluster_size) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "lz4 invalid ret:%d, expected:%lu", ret, PAGE_SIZE << dic->log_cluster_size); return -EIO; @@ -423,7 +423,7 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic) stream = zstd_init_dstream(max_window_size, workspace, workspace_size); if (!stream) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "%s zstd_init_dstream failed", __func__); vfree(workspace); return -EIO; @@ -459,14 +459,14 @@ static int zstd_decompress_pages(struct decompress_io_ctx *dic) ret = zstd_decompress_stream(stream, &outbuf, &inbuf); if (zstd_is_error(ret)) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "%s zstd_decompress_stream failed, ret: %d", __func__, zstd_get_error_code(ret)); return -EIO; } if (dic->rlen != outbuf.pos) { - f2fs_err_ratelimited(F2FS_I_SB(dic->inode), + f2fs_err_ratelimited(dic->sbi, "%s ZSTD invalid rlen:%zu, expected:%lu", __func__, dic->rlen, PAGE_SIZE << dic->log_cluster_size); @@ -726,7 +726,7 @@ static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) { - struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); + struct f2fs_sb_info *sbi = dic->sbi; struct f2fs_inode_info *fi = F2FS_I(dic->inode); const struct f2fs_compress_ops *cops = f2fs_cops[fi->i_compress_algorithm]; @@ -799,7 +799,7 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed, { struct decompress_io_ctx *dic = (struct decompress_io_ctx *)page_private(page); - struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); + struct f2fs_sb_info *sbi = dic->sbi; dec_page_count(sbi, F2FS_RD_DATA); @@ -1579,14 +1579,13 @@ static inline bool allow_memalloc_for_decomp(struct f2fs_sb_info *sbi, static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, bool pre_alloc) { - const struct f2fs_compress_ops *cops = - f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; + const struct f2fs_compress_ops *cops = f2fs_cops[dic->compress_algorithm]; int i; - if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) + if (!allow_memalloc_for_decomp(dic->sbi, pre_alloc)) return 0; - dic->tpages = page_array_alloc(F2FS_I_SB(dic->inode), dic->cluster_size); + dic->tpages = page_array_alloc(dic->sbi, dic->cluster_size); if (!dic->tpages) return -ENOMEM; @@ -1616,10 +1615,9 @@ static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, bool bypass_destroy_callback, bool pre_alloc) { - const struct f2fs_compress_ops *cops = - f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; + const struct f2fs_compress_ops *cops = f2fs_cops[dic->compress_algorithm]; - if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) + if (!allow_memalloc_for_decomp(dic->sbi, pre_alloc)) return; if (!bypass_destroy_callback && cops->destroy_decompress_ctx) @@ -1654,6 +1652,8 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) dic->magic = F2FS_COMPRESSED_PAGE_MAGIC; dic->inode = cc->inode; + dic->sbi = sbi; + dic->compress_algorithm = F2FS_I(cc->inode)->i_compress_algorithm; atomic_set(&dic->remaining_pages, cc->nr_cpages); dic->cluster_idx = cc->cluster_idx; dic->cluster_size = cc->cluster_size; @@ -1697,7 +1697,8 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic, bool bypass_destroy_callback) { int i; - struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); + /* use sbi in dic to avoid UFA of dic->inode*/ + struct f2fs_sb_info *sbi = dic->sbi; f2fs_release_decomp_mem(dic, bypass_destroy_callback, true); @@ -1740,8 +1741,7 @@ static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task) f2fs_free_dic(dic, false); } else { INIT_WORK(&dic->free_work, f2fs_late_free_dic); - queue_work(F2FS_I_SB(dic->inode)->post_read_wq, - &dic->free_work); + queue_work(dic->sbi->post_read_wq, &dic->free_work); } } } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ab2ddd09d813..406243395b94 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1493,6 +1493,7 @@ struct compress_io_ctx { struct decompress_io_ctx { u32 magic; /* magic number to indicate page is compressed */ struct inode *inode; /* inode the context belong to */ + struct f2fs_sb_info *sbi; /* f2fs_sb_info pointer */ pgoff_t cluster_idx; /* cluster index number */ unsigned int cluster_size; /* page count in cluster */ unsigned int log_cluster_size; /* log of cluster size */ @@ -1533,6 +1534,7 @@ struct decompress_io_ctx { bool failed; /* IO error occurred before decompression? */ bool need_verity; /* need fs-verity verification after decompression? */ + unsigned char compress_algorithm; /* backup algorithm type */ void *private; /* payload buffer for specified decompression algorithm */ void *private2; /* extra payload buffer */ struct work_struct verity_work; /* work to verify the decompressed pages */ -- Gitee From 9e1f4d8d5f1f1c193117adad33bc7b83af83d059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Tue, 25 Nov 2025 22:41:49 +0800 Subject: [PATCH 0066/1449] ALSA: usb-audio: fix uac2 clock source at terminal parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 1ee10e90e1607fbde1c9ae01f4a5049c9cb1c172 stable. commit d26e9f669cc0a6a85cf17180c09a6686db9f4002 upstream. Since 8b3a087f7f65 ("ALSA: usb-audio: Unify virtual type units type to UAC3 values") usb-audio is using UAC3_CLOCK_SOURCE instead of bDescriptorSubtype, later refactored with e0ccdef9265 ("ALSA: usb-audio: Clean up check_input_term()") into parse_term_uac2_clock_source(). This breaks the clock source selection for at least my 1397:0003 BEHRINGER International GmbH FCA610 Pro. Fix by using UAC2_CLOCK_SOURCE in parse_term_uac2_clock_source(). Fixes: 8b3a087f7f65 ("ALSA: usb-audio: Unify virtual type units type to UAC3 values") Signed-off-by: René Rebe Link: https://patch.msgid.link/20251125.154149.1121389544970412061.rene@exactco.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 787cdeddbdf4..e19d962fab87 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -930,7 +930,7 @@ static int parse_term_uac2_clock_source(struct mixer_build *state, { struct uac_clock_source_descriptor *d = p1; - term->type = UAC3_CLOCK_SOURCE << 16; /* virtual type */ + term->type = UAC2_CLOCK_SOURCE << 16; /* virtual type */ term->id = id; term->name = d->iClockSource; return 0; -- Gitee From b08c37c7209daeb45957d852629e9f8f26e6ce61 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 4 Nov 2025 00:28:11 +0800 Subject: [PATCH 0067/1449] net: ethernet: ti: netcp: Standardize knav_dma_open_channel to return NULL on error ANBZ: #35228 commit 952637c5b9be64539cd0e13ef88db71a1df46373 stable. commit 90a88306eb874fe4bbdd860e6c9787f5bbc588b5 upstream. Make knav_dma_open_channel consistently return NULL on error instead of ERR_PTR. Currently the header include/linux/soc/ti/knav_dma.h returns NULL when the driver is disabled, but the driver implementation does not even return NULL or ERR_PTR on failure, causing inconsistency in the users. This results in a crash in netcp_free_navigator_resources as followed (trimmed): Unhandled fault: alignment exception (0x221) at 0xfffffff2 [fffffff2] *pgd=80000800207003, *pmd=82ffda003, *pte=00000000 Internal error: : 221 [#1] SMP ARM Modules linked in: CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.17.0-rc7 #1 NONE Hardware name: Keystone PC is at knav_dma_close_channel+0x30/0x19c LR is at netcp_free_navigator_resources+0x2c/0x28c [... TRIM...] Call trace: knav_dma_close_channel from netcp_free_navigator_resources+0x2c/0x28c netcp_free_navigator_resources from netcp_ndo_open+0x430/0x46c netcp_ndo_open from __dev_open+0x114/0x29c __dev_open from __dev_change_flags+0x190/0x208 __dev_change_flags from netif_change_flags+0x1c/0x58 netif_change_flags from dev_change_flags+0x38/0xa0 dev_change_flags from ip_auto_config+0x2c4/0x11f0 ip_auto_config from do_one_initcall+0x58/0x200 do_one_initcall from kernel_init_freeable+0x1cc/0x238 kernel_init_freeable from kernel_init+0x1c/0x12c kernel_init from ret_from_fork+0x14/0x38 [... TRIM...] Standardize the error handling by making the function return NULL on all error conditions. The API is used in just the netcp_core.c so the impact is limited. Note, this change, in effect reverts commit 5b6cb43b4d62 ("net: ethernet: ti: netcp_core: return error while dma channel open issue"), but provides a less error prone implementation. Suggested-by: Simon Horman Suggested-by: Jacob Keller Signed-off-by: Nishanth Menon Reviewed-by: Jacob Keller Link: https://patch.msgid.link/20251103162811.3730055-1-nm@ti.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/ti/netcp_core.c | 10 +++++----- drivers/soc/ti/knav_dma.c | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index d829113c16ee..1c33a9c9ddb5 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -1338,10 +1338,10 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) tx_pipe->dma_channel = knav_dma_open_channel(dev, tx_pipe->dma_chan_name, &config); - if (IS_ERR(tx_pipe->dma_channel)) { + if (!tx_pipe->dma_channel) { dev_err(dev, "failed opening tx chan(%s)\n", tx_pipe->dma_chan_name); - ret = PTR_ERR(tx_pipe->dma_channel); + ret = -EINVAL; goto err; } @@ -1359,7 +1359,7 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) return 0; err: - if (!IS_ERR_OR_NULL(tx_pipe->dma_channel)) + if (tx_pipe->dma_channel) knav_dma_close_channel(tx_pipe->dma_channel); tx_pipe->dma_channel = NULL; return ret; @@ -1678,10 +1678,10 @@ static int netcp_setup_navigator_resources(struct net_device *ndev) netcp->rx_channel = knav_dma_open_channel(netcp->netcp_device->device, netcp->dma_chan_name, &config); - if (IS_ERR(netcp->rx_channel)) { + if (!netcp->rx_channel) { dev_err(netcp->ndev_dev, "failed opening rx chan(%s\n", netcp->dma_chan_name); - ret = PTR_ERR(netcp->rx_channel); + ret = -EINVAL; goto fail; } diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 0fbc37cd5123..f599eaab3c56 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -402,7 +402,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name, * @name: slave channel name * @config: dma configuration parameters * - * Returns pointer to appropriate DMA channel on success or error. + * Return: Pointer to appropriate DMA channel on success or NULL on error. */ void *knav_dma_open_channel(struct device *dev, const char *name, struct knav_dma_cfg *config) @@ -414,13 +414,13 @@ void *knav_dma_open_channel(struct device *dev, const char *name, if (!kdev) { pr_err("keystone-navigator-dma driver not registered\n"); - return (void *)-EINVAL; + return NULL; } chan_num = of_channel_match_helper(dev->of_node, name, &instance); if (chan_num < 0) { dev_err(kdev->dev, "No DMA instance with name %s\n", name); - return (void *)-EINVAL; + return NULL; } dev_dbg(kdev->dev, "initializing %s channel %d from DMA %s\n", @@ -431,7 +431,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name, if (config->direction != DMA_MEM_TO_DEV && config->direction != DMA_DEV_TO_MEM) { dev_err(kdev->dev, "bad direction\n"); - return (void *)-EINVAL; + return NULL; } /* Look for correct dma instance */ @@ -443,7 +443,7 @@ void *knav_dma_open_channel(struct device *dev, const char *name, } if (!dma) { dev_err(kdev->dev, "No DMA instance with name %s\n", instance); - return (void *)-EINVAL; + return NULL; } /* Look for correct dma channel from dma instance */ @@ -463,14 +463,14 @@ void *knav_dma_open_channel(struct device *dev, const char *name, if (!chan) { dev_err(kdev->dev, "channel %d is not in DMA %s\n", chan_num, instance); - return (void *)-EINVAL; + return NULL; } if (atomic_read(&chan->ref_count) >= 1) { if (!check_config(chan, config)) { dev_err(kdev->dev, "channel %d config miss-match\n", chan_num); - return (void *)-EINVAL; + return NULL; } } -- Gitee From 40f0d15e3961ca41cd0e72879c864931f34de3a7 Mon Sep 17 00:00:00 2001 From: Zhang Chujun Date: Thu, 6 Nov 2025 11:10:40 +0800 Subject: [PATCH 0068/1449] tracing/tools: Fix incorrcet short option in usage text for --threads ANBZ: #35228 commit 6917e894f86ffc7394d53d7e6a06d4bec90bc312 stable. commit 53afec2c8fb2a562222948cb1c2aac48598578c9 upstream. The help message incorrectly listed '-t' as the short option for --threads, but the actual getopt_long configuration uses '-e'. This mismatch can confuse users and lead to incorrect command-line usage. This patch updates the usage string to correctly show: "-e, --threads NRTHR" to match the implementation. Note: checkpatch.pl reports a false-positive spelling warning on 'Run', which is intentional. Link: https://patch.msgid.link/20251106031040.1869-1-zhangchujun@cmss.chinamobile.com Signed-off-by: Zhang Chujun Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/tracing/latency/latency-collector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tracing/latency/latency-collector.c b/tools/tracing/latency/latency-collector.c index cf263fe9deaf..ef97916e3873 100644 --- a/tools/tracing/latency/latency-collector.c +++ b/tools/tracing/latency/latency-collector.c @@ -1725,7 +1725,7 @@ static void show_usage(void) "-n, --notrace\t\tIf latency is detected, do not print out the content of\n" "\t\t\tthe trace file to standard output\n\n" -"-t, --threads NRTHR\tRun NRTHR threads for printing. Default is %d.\n\n" +"-e, --threads NRTHR\tRun NRTHR threads for printing. Default is %d.\n\n" "-r, --random\t\tArbitrarily sleep a certain amount of time, default\n" "\t\t\t%ld ms, before reading the trace file. The\n" -- Gitee From 33aec6ecce35e9664ade39b3206790dc7520ddeb Mon Sep 17 00:00:00 2001 From: Henrique Carvalho Date: Wed, 26 Nov 2025 21:55:53 +0800 Subject: [PATCH 0069/1449] smb: client: fix incomplete backport in cfids_invalidation_worker() ANBZ: #35228 commit 64332afa9f769135972021b8f2b06b089f024068 stable. The previous commit bdb596ceb4b7 ("smb: client: fix potential UAF in smb2_close_cached_fid()") was an incomplete backport and missed one kref_put() call in cfids_invalidation_worker() that should have been converted to close_cached_dir(). Fixes: cb52d9c86d70 ("smb: client: fix potential UAF in smb2_close_cached_fid()")" Signed-off-by: Henrique Carvalho Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/cached_dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 3fefe5e7b16f..e92a61e934e4 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -727,7 +727,7 @@ static void cfids_invalidation_worker(struct work_struct *work) list_for_each_entry_safe(cfid, q, &entry, entry) { list_del(&cfid->entry); /* Drop the ref-count acquired in invalidate_all_cached_dirs */ - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } } -- Gitee From a8467d4dffab063c107cb8ea5dff0404e2162993 Mon Sep 17 00:00:00 2001 From: Sebastian Ene Date: Fri, 17 Oct 2025 15:57:10 +0800 Subject: [PATCH 0070/1449] KVM: arm64: Check the untrusted offset in FF-A memory share ANBZ: #35228 commit fc3139d9f4c1fe1c7d5f25f99676bd8e9c6a1041 stable. commit 103e17aac09cdd358133f9e00998b75d6c1f1518 upstream. Verify the offset to prevent OOB access in the hypervisor FF-A buffer in case an untrusted large enough value [U32_MAX - sizeof(struct ffa_composite_mem_region) + 1, U32_MAX] is set from the host kernel. Signed-off-by: Sebastian Ene Acked-by: Will Deacon Link: https://patch.msgid.link/20251017075710.2605118-1-sebastianene@google.com Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/kvm/hyp/nvhe/ffa.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index 8d21ab904f1a..eacf4ba1d88e 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -425,7 +425,7 @@ static void __do_ffa_mem_xfer(const u64 func_id, DECLARE_REG(u32, npages_mbz, ctxt, 4); struct ffa_composite_mem_region *reg; struct ffa_mem_region *buf; - u32 offset, nr_ranges; + u32 offset, nr_ranges, checked_offset; int ret = 0; if (addr_mbz || npages_mbz || fraglen > len || @@ -460,7 +460,12 @@ static void __do_ffa_mem_xfer(const u64 func_id, goto out_unlock; } - if (fraglen < offset + sizeof(struct ffa_composite_mem_region)) { + if (check_add_overflow(offset, sizeof(struct ffa_composite_mem_region), &checked_offset)) { + ret = FFA_RET_INVALID_PARAMETERS; + goto out_unlock; + } + + if (fraglen < checked_offset) { ret = FFA_RET_INVALID_PARAMETERS; goto out_unlock; } -- Gitee From 1daec9b95097d63f4fef20908063c9d9480b144b Mon Sep 17 00:00:00 2001 From: Long Li Date: Tue, 11 Mar 2025 06:12:01 +0800 Subject: [PATCH 0071/1449] uio_hv_generic: Set event for all channels on the device ANBZ: #35228 commit bf07df375d208fb3a7392d99bd390b5a6d9a7b5d stable. commit d062463edf1770427dc2d637df4088df4835aa47 upstream. Hyper-V may offer a non latency sensitive device with subchannels without monitor bit enabled. The decision is entirely on the Hyper-V host not configurable within guest. When a device has subchannels, also signal events for the subchannel if its monitor bit is disabled. This patch also removes the memory barrier when monitor bit is enabled as it is not necessary. The memory barrier is only needed between setting up interrupt mask and calling vmbus_set_event() when monitor bit is disabled. Signed-off-by: Long Li Reviewed-by: Michael Kelley Reviewed-by: Saurabh Sengar Link: https://lore.kernel.org/r/1741644721-20389-1-git-send-email-longli@linuxonhyperv.com Fixes: b15b7d2a1b09 ("uio_hv_generic: Let userspace take care of interrupt mask") Closes: https://bugs.debian.org/1120602 Signed-off-by: Naman Jain Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/uio/uio_hv_generic.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 2724656bf634..69e5016ebd46 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -80,9 +80,15 @@ hv_uio_irqcontrol(struct uio_info *info, s32 irq_state) { struct hv_uio_private_data *pdata = info->priv; struct hv_device *dev = pdata->device; + struct vmbus_channel *primary, *sc; - dev->channel->inbound.ring_buffer->interrupt_mask = !irq_state; - virt_mb(); + primary = dev->channel; + primary->inbound.ring_buffer->interrupt_mask = !irq_state; + + mutex_lock(&vmbus_connection.channel_mutex); + list_for_each_entry(sc, &primary->sc_list, sc_list) + sc->inbound.ring_buffer->interrupt_mask = !irq_state; + mutex_unlock(&vmbus_connection.channel_mutex); return 0; } @@ -93,11 +99,18 @@ hv_uio_irqcontrol(struct uio_info *info, s32 irq_state) static void hv_uio_channel_cb(void *context) { struct vmbus_channel *chan = context; - struct hv_device *hv_dev = chan->device_obj; - struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev); + struct hv_device *hv_dev; + struct hv_uio_private_data *pdata; virt_mb(); + /* + * The callback may come from a subchannel, in which case look + * for the hv device in the primary channel + */ + hv_dev = chan->primary_channel ? + chan->primary_channel->device_obj : chan->device_obj; + pdata = hv_get_drvdata(hv_dev); uio_event_notify(&pdata->info); } -- Gitee From b9a9ae03ec330e605be393ee47cdedf0b59f0a29 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Thu, 30 Oct 2025 23:55:05 +0800 Subject: [PATCH 0072/1449] maple_tree: fix tracepoint string pointers ANBZ: #35228 commit 29150018bf19d922725ac5cee9970784aacf6a1e stable. commit 91a54090026f84ceffaa12ac53c99b9f162946f6 upstream. maple_tree tracepoints contain pointers to function names. Such a pointer is saved when a tracepoint logs an event. There's no guarantee that it's still valid when the event is parsed later and the pointer is dereferenced. The kernel warns about these unsafe pointers. event 'ma_read' has unsafe pointer field 'fn' WARNING: kernel/trace/trace.c:3779 at ignore_event+0x1da/0x1e4 Mark the function names as tracepoint_string() to fix the events. One case that doesn't work without my patch would be trace-cmd record to save the binary ringbuffer and trace-cmd report to parse it in userspace. The address of __func__ can't be dereferenced from userspace but tracepoint_string will add an entry to /sys/kernel/tracing/printk_formats Link: https://lkml.kernel.org/r/20251030155537.87972-1-martin@kaiser.cx Fixes: 54a611b60590 ("Maple Tree: add new data structure") Signed-off-by: Martin Kaiser Acked-by: Liam R. Howlett Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- lib/maple_tree.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 61406f6d2515..eb5a0979c096 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -64,6 +64,8 @@ #define CREATE_TRACE_POINTS #include +#define TP_FCT tracepoint_string(__func__) + #define MA_ROOT_PARENT 1 /* @@ -3002,7 +3004,7 @@ static inline int mas_rebalance(struct ma_state *mas, MA_STATE(l_mas, mas->tree, mas->index, mas->last); MA_STATE(r_mas, mas->tree, mas->index, mas->last); - trace_ma_op(__func__, mas); + trace_ma_op(TP_FCT, mas); /* * Rebalancing occurs if a node is insufficient. Data is rebalanced @@ -3377,7 +3379,7 @@ static int mas_split(struct ma_state *mas, struct maple_big_node *b_node) MA_STATE(prev_l_mas, mas->tree, mas->index, mas->last); MA_STATE(prev_r_mas, mas->tree, mas->index, mas->last); - trace_ma_op(__func__, mas); + trace_ma_op(TP_FCT, mas); mas->depth = mas_mt_height(mas); /* Allocation failures will happen early. */ mas_node_count(mas, 1 + mas->depth * 2); @@ -3610,7 +3612,7 @@ static bool mas_is_span_wr(struct ma_wr_state *wr_mas) return false; } - trace_ma_write(__func__, wr_mas->mas, wr_mas->r_max, entry); + trace_ma_write(TP_FCT, wr_mas->mas, wr_mas->r_max, entry); return true; } @@ -3857,7 +3859,7 @@ static inline int mas_wr_spanning_store(struct ma_wr_state *wr_mas) * of data may happen. */ mas = wr_mas->mas; - trace_ma_op(__func__, mas); + trace_ma_op(TP_FCT, mas); if (unlikely(!mas->index && mas->last == ULONG_MAX)) return mas_new_root(mas, wr_mas->entry); @@ -4008,7 +4010,7 @@ static inline bool mas_wr_node_store(struct ma_wr_state *wr_mas, } else { memcpy(wr_mas->node, newnode, sizeof(struct maple_node)); } - trace_ma_write(__func__, mas, 0, wr_mas->entry); + trace_ma_write(TP_FCT, mas, 0, wr_mas->entry); mas_update_gap(mas); return true; } @@ -4054,7 +4056,7 @@ static inline bool mas_wr_slot_store(struct ma_wr_state *wr_mas) return false; } - trace_ma_write(__func__, mas, 0, wr_mas->entry); + trace_ma_write(TP_FCT, mas, 0, wr_mas->entry); /* * Only update gap when the new entry is empty or there is an empty * entry in the original two ranges. @@ -4190,7 +4192,7 @@ static inline bool mas_wr_append(struct ma_wr_state *wr_mas, if (!wr_mas->content || !wr_mas->entry) mas_update_gap(mas); - trace_ma_write(__func__, mas, new_end, wr_mas->entry); + trace_ma_write(TP_FCT, mas, new_end, wr_mas->entry); return true; } @@ -4204,7 +4206,7 @@ static void mas_wr_bnode(struct ma_wr_state *wr_mas) { struct maple_big_node b_node; - trace_ma_write(__func__, wr_mas->mas, 0, wr_mas->entry); + trace_ma_write(TP_FCT, wr_mas->mas, 0, wr_mas->entry); memset(&b_node, 0, sizeof(struct maple_big_node)); mas_store_b_node(wr_mas, &b_node, wr_mas->offset_end); mas_commit_b_node(wr_mas, &b_node, wr_mas->node_end); @@ -5407,7 +5409,7 @@ void *mas_store(struct ma_state *mas, void *entry) { MA_WR_STATE(wr_mas, mas, entry); - trace_ma_write(__func__, mas, 0, entry); + trace_ma_write(TP_FCT, mas, 0, entry); #ifdef CONFIG_DEBUG_MAPLE_TREE if (MAS_WARN_ON(mas, mas->index > mas->last)) pr_err("Error %lX > %lX %p\n", mas->index, mas->last, entry); @@ -5445,7 +5447,7 @@ int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp) MA_WR_STATE(wr_mas, mas, entry); mas_wr_store_setup(&wr_mas); - trace_ma_write(__func__, mas, 0, entry); + trace_ma_write(TP_FCT, mas, 0, entry); retry: mas_wr_store_entry(&wr_mas); if (unlikely(mas_nomem(mas, gfp))) @@ -5469,7 +5471,7 @@ void mas_store_prealloc(struct ma_state *mas, void *entry) MA_WR_STATE(wr_mas, mas, entry); mas_wr_store_setup(&wr_mas); - trace_ma_write(__func__, mas, 0, entry); + trace_ma_write(TP_FCT, mas, 0, entry); mas_wr_store_entry(&wr_mas); MAS_WR_BUG_ON(&wr_mas, mas_is_err(mas)); mas_destroy(mas); @@ -6257,7 +6259,7 @@ void *mtree_load(struct maple_tree *mt, unsigned long index) MA_STATE(mas, mt, index, index); void *entry; - trace_ma_read(__func__, &mas); + trace_ma_read(TP_FCT, &mas); rcu_read_lock(); retry: entry = mas_start(&mas); @@ -6300,7 +6302,7 @@ int mtree_store_range(struct maple_tree *mt, unsigned long index, MA_STATE(mas, mt, index, last); MA_WR_STATE(wr_mas, &mas, entry); - trace_ma_write(__func__, &mas, 0, entry); + trace_ma_write(TP_FCT, &mas, 0, entry); if (WARN_ON_ONCE(xa_is_advanced(entry))) return -EINVAL; @@ -6482,7 +6484,7 @@ void *mtree_erase(struct maple_tree *mt, unsigned long index) void *entry = NULL; MA_STATE(mas, mt, index, index); - trace_ma_op(__func__, &mas); + trace_ma_op(TP_FCT, &mas); mtree_lock(mt); entry = mas_erase(&mas); @@ -6820,7 +6822,7 @@ void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max) unsigned long copy = *index; #endif - trace_ma_read(__func__, &mas); + trace_ma_read(TP_FCT, &mas); if ((*index) > max) return NULL; -- Gitee From ee5fb354b594407e05cd6484bc5f0be4578d6e66 Mon Sep 17 00:00:00 2001 From: Alexander Wetzel Date: Fri, 18 Jul 2025 00:25:45 +0800 Subject: [PATCH 0073/1449] wifi: cfg80211: Add missing lock in cfg80211_check_and_end_cac() ANBZ: #35228 commit b3d24038eb775f2f7a1dfef58d8e1dc444a12820 stable. commit 2c5dee15239f3f3e31aa5c8808f18996c039e2c1 upstream. Callers of wdev_chandef() must hold the wiphy mutex. But the worker cfg80211_propagate_cac_done_wk() never takes the lock. Which triggers the warning below with the mesh_peer_connected_dfs test from hostapd and not (yet) released mac80211 code changes: WARNING: CPU: 0 PID: 495 at net/wireless/chan.c:1552 wdev_chandef+0x60/0x165 Modules linked in: CPU: 0 UID: 0 PID: 495 Comm: kworker/u4:2 Not tainted 6.14.0-rc5-wt-g03960e6f9d47 #33 13c287eeabfe1efea01c0bcc863723ab082e17cf Workqueue: cfg80211 cfg80211_propagate_cac_done_wk Stack: 00000000 00000001 ffffff00 6093267c 00000000 6002ec30 6d577c50 60037608 00000000 67e8d108 6063717b 00000000 Call Trace: [<6002ec30>] ? _printk+0x0/0x98 [<6003c2b3>] show_stack+0x10e/0x11a [<6002ec30>] ? _printk+0x0/0x98 [<60037608>] dump_stack_lvl+0x71/0xb8 [<6063717b>] ? wdev_chandef+0x60/0x165 [<6003766d>] dump_stack+0x1e/0x20 [<6005d1b7>] __warn+0x101/0x20f [<6005d3a8>] warn_slowpath_fmt+0xe3/0x15d [<600b0c5c>] ? mark_lock.part.0+0x0/0x4ec [<60751191>] ? __this_cpu_preempt_check+0x0/0x16 [<600b11a2>] ? mark_held_locks+0x5a/0x6e [<6005d2c5>] ? warn_slowpath_fmt+0x0/0x15d [<60052e53>] ? unblock_signals+0x3a/0xe7 [<60052f2d>] ? um_set_signals+0x2d/0x43 [<60751191>] ? __this_cpu_preempt_check+0x0/0x16 [<607508b2>] ? lock_is_held_type+0x207/0x21f [<6063717b>] wdev_chandef+0x60/0x165 [<605f89b4>] regulatory_propagate_dfs_state+0x247/0x43f [<60052f00>] ? um_set_signals+0x0/0x43 [<605e6bfd>] cfg80211_propagate_cac_done_wk+0x3a/0x4a [<6007e460>] process_scheduled_works+0x3bc/0x60e [<6007d0ec>] ? move_linked_works+0x4d/0x81 [<6007d120>] ? assign_work+0x0/0xaa [<6007f81f>] worker_thread+0x220/0x2dc [<600786ef>] ? set_pf_worker+0x0/0x57 [<60087c96>] ? to_kthread+0x0/0x43 [<6008ab3c>] kthread+0x2d3/0x2e2 [<6007f5ff>] ? worker_thread+0x0/0x2dc [<6006c05b>] ? calculate_sigpending+0x0/0x56 [<6003b37d>] new_thread_handler+0x4a/0x64 irq event stamp: 614611 hardirqs last enabled at (614621): [<00000000600bc96b>] __up_console_sem+0x82/0xaf hardirqs last disabled at (614630): [<00000000600bc92c>] __up_console_sem+0x43/0xaf softirqs last enabled at (614268): [<00000000606c55c6>] __ieee80211_wake_queue+0x933/0x985 softirqs last disabled at (614266): [<00000000606c52d6>] __ieee80211_wake_queue+0x643/0x985 Fixes: 26ec17a1dc5e ("cfg80211: Fix radar event during another phy CAC") Signed-off-by: Alexander Wetzel Link: https://patch.msgid.link/20250717162547.94582-1-Alexander@wetzel-home.de Signed-off-by: Johannes Berg [ The author recommends that when porting to older kernels, we should use wiphy_lock() and wiphy_unlock() instead of guard(). ] Signed-off-by: Alva Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/wireless/reg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9e0366ea86f4..4c695f29dfed 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -4208,6 +4208,9 @@ EXPORT_SYMBOL(regulatory_pre_cac_allowed); static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev) { struct wireless_dev *wdev; + + wiphy_lock(&rdev->wiphy); + /* If we finished CAC or received radar, we should end any * CAC running on the same channels. * the check !cfg80211_chandef_dfs_usable contain 2 options: @@ -4231,6 +4234,8 @@ static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev) if (!cfg80211_chandef_dfs_usable(&rdev->wiphy, chandef)) rdev_end_cac(rdev, wdev->netdev); } + + wiphy_unlock(&rdev->wiphy); } void regulatory_propagate_dfs_state(struct wiphy *wiphy, -- Gitee From 3d2f57b1ccd7d0b95ffb82c051b1cb81e9d52e7b Mon Sep 17 00:00:00 2001 From: Sourabh Jain Date: Fri, 21 Nov 2025 23:11:40 +0800 Subject: [PATCH 0074/1449] crash: fix crashkernel resource shrink ANBZ: #35228 commit f01f9c348d76d40bf104a94449e3ce4057fdefee stable. commit 00fbff75c5acb4755f06f08bd1071879c63940c5 upstream. When crashkernel is configured with a high reservation, shrinking its value below the low crashkernel reservation causes two issues: 1. Invalid crashkernel resource objects 2. Kernel crash if crashkernel shrinking is done twice For example, with crashkernel=200M,high, the kernel reserves 200MB of high memory and some default low memory (say 256MB). The reservation appears as: cat /proc/iomem | grep -i crash af000000-beffffff : Crash kernel 433000000-43f7fffff : Crash kernel If crashkernel is then shrunk to 50MB (echo 52428800 > /sys/kernel/kexec_crash_size), /proc/iomem still shows 256MB reserved: af000000-beffffff : Crash kernel Instead, it should show 50MB: af000000-b21fffff : Crash kernel Further shrinking crashkernel to 40MB causes a kernel crash with the following trace (x86): BUG: kernel NULL pointer dereference, address: 0000000000000038 PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP NOPTI Call Trace: ? __die_body.cold+0x19/0x27 ? page_fault_oops+0x15a/0x2f0 ? search_module_extables+0x19/0x60 ? search_bpf_extables+0x5f/0x80 ? exc_page_fault+0x7e/0x180 ? asm_exc_page_fault+0x26/0x30 ? __release_resource+0xd/0xb0 release_resource+0x26/0x40 __crash_shrink_memory+0xe5/0x110 crash_shrink_memory+0x12a/0x190 kexec_crash_size_store+0x41/0x80 kernfs_fop_write_iter+0x141/0x1f0 vfs_write+0x294/0x460 ksys_write+0x6d/0xf0 This happens because __crash_shrink_memory()/kernel/crash_core.c incorrectly updates the crashk_res resource object even when crashk_low_res should be updated. Fix this by ensuring the correct crashkernel resource object is updated when shrinking crashkernel memory. Link: https://lkml.kernel.org/r/20251101193741.289252-1-sourabhjain@linux.ibm.com Fixes: 16c6006af4d4 ("kexec: enable kexec_crash_size to support two crash kernel regions") Signed-off-by: Sourabh Jain Acked-by: Baoquan He Cc: Zhen Lei Cc: Signed-off-by: Andrew Morton [ Applied fix to `kernel/kexec_core.c` instead of `kernel/crash_core.c` ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/kexec_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 76c61f666555..1231786f98c2 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1133,7 +1133,7 @@ static int __crash_shrink_memory(struct resource *old_res, old_res->start = 0; old_res->end = 0; } else { - crashk_res.end = ram_res->start - 1; + old_res->end = ram_res->start - 1; } crash_free_reserved_phys_range(ram_res->start, ram_res->end); -- Gitee From ff09bbd44eee3d989c09ac0cf3965fa0cf83ad84 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Fri, 21 Nov 2025 23:20:00 +0800 Subject: [PATCH 0075/1449] ftrace: Fix BPF fexit with livepatch ANBZ: #35228 commit 7ea2ea68df08bcfabb59bf0012120ffec4901d21 stable. commit 56b3c85e153b84f27e6cff39623ba40a1ad299d3 upstream. When livepatch is attached to the same function as bpf trampoline with a fexit program, bpf trampoline code calls register_ftrace_direct() twice. The first time will fail with -EAGAIN, and the second time it will succeed. This requires register_ftrace_direct() to unregister the address on the first attempt. Otherwise, the bpf trampoline cannot attach. Here is an easy way to reproduce this issue: insmod samples/livepatch/livepatch-sample.ko bpftrace -e 'fexit:cmdline_proc_show {}' ERROR: Unable to attach probe: fexit:vmlinux:cmdline_proc_show... Fix this by cleaning up the hash when register_ftrace_function_nolock hits errors. Also, move the code that resets ops->func and ops->trampoline to the error path of register_ftrace_direct(); and add a helper function reset_direct() in register_ftrace_direct() and unregister_ftrace_direct(). Fixes: d05cb470663a ("ftrace: Fix modification of direct_function hash while in use") Cc: stable@vger.kernel.org # v6.6+ Reported-by: Andrey Grodzovsky Closes: https://lore.kernel.org/live-patching/c5058315a39d4615b333e485893345be@crowdstrike.com/ Cc: Steven Rostedt (Google) Cc: Masami Hiramatsu (Google) Acked-and-tested-by: Andrey Grodzovsky Signed-off-by: Song Liu Reviewed-by: Jiri Olsa Link: https://lore.kernel.org/r/20251027175023.1521602-2-song@kernel.org Signed-off-by: Alexei Starovoitov Acked-by: Steven Rostedt (Google) [ moved cleanup to reset_direct() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/bpf/trampoline.c | 4 ---- kernel/trace/ftrace.c | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 45477c604a1a..521a32636d75 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -460,10 +460,6 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut * BPF_TRAMP_F_SHARE_IPMODIFY is set, we can generate the * trampoline again, and retry register. */ - /* reset fops->func and fops->trampoline for re-register */ - tr->fops->func = NULL; - tr->fops->trampoline = 0; - /* reset im->image memory attr for arch_prepare_bpf_trampoline */ set_memory_nx((long)im->image, 1); set_memory_rw((long)im->image, 1); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ebee3296aebe..60e7bcb450b8 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5370,6 +5370,17 @@ static void remove_direct_functions_hash(struct ftrace_hash *hash, unsigned long } } +static void reset_direct(struct ftrace_ops *ops, unsigned long addr) +{ + struct ftrace_hash *hash = ops->func_hash->filter_hash; + + remove_direct_functions_hash(hash, addr); + + /* cleanup for possible another register call */ + ops->func = NULL; + ops->trampoline = 0; +} + /** * register_ftrace_direct - Call a custom trampoline directly * for multiple functions registered in @ops @@ -5465,6 +5476,8 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) ops->direct_call = addr; err = register_ftrace_function_nolock(ops); + if (err) + reset_direct(ops, addr); out_unlock: mutex_unlock(&direct_mutex); @@ -5497,7 +5510,6 @@ EXPORT_SYMBOL_GPL(register_ftrace_direct); int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr, bool free_filters) { - struct ftrace_hash *hash = ops->func_hash->filter_hash; int err; if (check_direct_multi(ops)) @@ -5507,13 +5519,9 @@ int unregister_ftrace_direct(struct ftrace_ops *ops, unsigned long addr, mutex_lock(&direct_mutex); err = unregister_ftrace_function(ops); - remove_direct_functions_hash(hash, addr); + reset_direct(ops, addr); mutex_unlock(&direct_mutex); - /* cleanup for possible another register call */ - ops->func = NULL; - ops->trampoline = 0; - if (free_filters) ftrace_free_filter(ops); return err; -- Gitee From 0065c22890475a4994db1b5b04ff2c94102efca4 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 21 Nov 2025 23:43:01 +0800 Subject: [PATCH 0076/1449] pmdomain: arm: scmi: Fix genpd leak on provider registration failure ANBZ: #35228 commit ad120c08b89a81d41d091490bbe150343473b659 stable. commit 7458f72cc28f9eb0de811effcb5376d0ec19094a upstream. If of_genpd_add_provider_onecell() fails during probe, the previously created generic power domains are not removed, leading to a memory leak and potential kernel crash later in genpd_debug_add(). Add proper error handling to unwind the initialized domains before returning from probe to ensure all resources are correctly released on failure. Example crash trace observed without this fix: | Unable to handle kernel paging request at virtual address fffffffffffffc70 | CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc1 #405 PREEMPT | Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : genpd_debug_add+0x2c/0x160 | lr : genpd_debug_init+0x74/0x98 | Call trace: | genpd_debug_add+0x2c/0x160 (P) | genpd_debug_init+0x74/0x98 | do_one_initcall+0xd0/0x2d8 | do_initcall_level+0xa0/0x140 | do_initcalls+0x60/0xa8 | do_basic_setup+0x28/0x40 | kernel_init_freeable+0xe8/0x170 | kernel_init+0x2c/0x140 | ret_from_fork+0x10/0x20 Fixes: 898216c97ed2 ("firmware: arm_scmi: add device power domain support using genpd") Signed-off-by: Sudeep Holla Reviewed-by: Peng Fan Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson [ drivers/pmdomain/arm/scmi_pm_domain.c -> drivers/firmware/arm_scmi/scmi_pm_domain.c ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/arm_scmi/scmi_pm_domain.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c index 0e05a79de82d..82d923a9d75d 100644 --- a/drivers/firmware/arm_scmi/scmi_pm_domain.c +++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c @@ -54,7 +54,7 @@ static int scmi_pd_power_off(struct generic_pm_domain *domain) static int scmi_pm_domain_probe(struct scmi_device *sdev) { - int num_domains, i; + int num_domains, i, ret; struct device *dev = &sdev->dev; struct device_node *np = dev->of_node; struct scmi_pm_domain *scmi_pd; @@ -112,9 +112,18 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; + ret = of_genpd_add_provider_onecell(np, scmi_pd_data); + if (ret) + goto err_rm_genpds; + dev_set_drvdata(dev, scmi_pd_data); - return of_genpd_add_provider_onecell(np, scmi_pd_data); + return 0; +err_rm_genpds: + for (i = num_domains - 1; i >= 0; i--) + pm_genpd_remove(domains[i]); + + return ret; } static void scmi_pm_domain_remove(struct scmi_device *sdev) -- Gitee From bde0952d5539c45c4744af36ed9c8bd7447fbbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 21 Nov 2025 23:40:40 +0800 Subject: [PATCH 0077/1449] pmdomain: imx-gpc: Convert to platform remove callback returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit a5958b1bcf4af14648218c7dbd3dfb3ebada997c stable. commit da07c5871d18157608a0d0702cb093168d79080a upstream. The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove(). In the error path emit an error message replacing the (less useful) message by the core. Apart from the improved error message there is no change in behaviour. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20231124080623.564924-3-u.kleine-koenig@pengutronix.de Signed-off-by: Ulf Hansson Stable-dep-of: bbde14682eba ("pmdomain: imx: Fix reference count leak in imx_gpc_remove") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/gpc.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index 419ed15cc10c..66703395b179 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -512,7 +512,7 @@ static int imx_gpc_probe(struct platform_device *pdev) return 0; } -static int imx_gpc_remove(struct platform_device *pdev) +static void imx_gpc_remove(struct platform_device *pdev) { struct device_node *pgc_node; int ret; @@ -522,7 +522,7 @@ static int imx_gpc_remove(struct platform_device *pdev) /* bail out if DT too old and doesn't provide the necessary info */ if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") && !pgc_node) - return 0; + return; /* * If the old DT binding is used the toplevel driver needs to @@ -532,16 +532,20 @@ static int imx_gpc_remove(struct platform_device *pdev) of_genpd_del_provider(pdev->dev.of_node); ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_PU].base); - if (ret) - return ret; + if (ret) { + dev_err(&pdev->dev, "Failed to remove PU power domain (%pe)\n", + ERR_PTR(ret)); + return; + } imx_pgc_put_clocks(&imx_gpc_domains[GPC_PGC_DOMAIN_PU]); ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_ARM].base); - if (ret) - return ret; + if (ret) { + dev_err(&pdev->dev, "Failed to remove ARM power domain (%pe)\n", + ERR_PTR(ret)); + return; + } } - - return 0; } static struct platform_driver imx_gpc_driver = { @@ -550,6 +554,6 @@ static struct platform_driver imx_gpc_driver = { .of_match_table = imx_gpc_dt_ids, }, .probe = imx_gpc_probe, - .remove = imx_gpc_remove, + .remove_new = imx_gpc_remove, }; builtin_platform_driver(imx_gpc_driver) -- Gitee From 15bda3e45cea8d2309cbaddadbb28c6abef7be37 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 21 Nov 2025 23:40:41 +0800 Subject: [PATCH 0078/1449] pmdomain: imx: Fix reference count leak in imx_gpc_remove ANBZ: #35228 commit 378e6136b8c06564944ba78b316f38555fcb013a stable. commit bbde14682eba21d86f5f3d6fe2d371b1f97f1e61 upstream. of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not needed anymore. Add the missing of_node_put() to avoid refcount leak. Fixes: 721cabf6c660 ("soc: imx: move PGC handling to a new GPC driver") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/gpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index 66703395b179..d7c0301a7121 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -546,6 +546,8 @@ static void imx_gpc_remove(struct platform_device *pdev) return; } } + + of_node_put(pgc_node); } static struct platform_driver imx_gpc_driver = { -- Gitee From 5106742ccf8d601a671cbe5f951c6348eb475478 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Mon, 24 Nov 2025 00:55:57 +0800 Subject: [PATCH 0079/1449] selftests: mptcp: join: endpoints: longer transfer ANBZ: #35228 commit 4948db9c9ca8be8fbe8e8d8f6d24c1384ef677d8 stable. commit 6457595db9870298ee30b6d75287b8548e33fe19 upstream. In rare cases, when the test environment is very slow, some userspace tests can fail because some expected events have not been seen. Because the tests are expecting a long on-going connection, and they are not waiting for the end of the transfer, it is fine to make the connection longer. This connection will be killed at the end, after the verifications, so making it longer doesn't change anything, apart from avoid it to end before the end of the verifications To play it safe, all endpoints tests not waiting for the end of the transfer are now sharing a longer file (128KB) at slow speed. Fixes: 69c6ce7b6eca ("selftests: mptcp: add implicit endpoint test case") Cc: stable@vger.kernel.org Fixes: e274f7154008 ("selftests: mptcp: add subflow limits test-cases") Fixes: b5e2fb832f48 ("selftests: mptcp: add explicit test case for remove/readd") Fixes: e06959e9eebd ("selftests: mptcp: join: test for flush/re-add endpoints") Reviewed-by: Geliang Tang Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251110-net-mptcp-sft-join-unstable-v1-3-a4332c714e10@kernel.org Signed-off-by: Jakub Kicinski [ removed curly braces and stderr redirection ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/mptcp/mptcp_join.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index 250577b11a91..ef16edce4759 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -3741,7 +3741,7 @@ endpoint_tests() pm_nl_set_limits $ns1 2 2 pm_nl_set_limits $ns2 2 2 pm_nl_add_endpoint $ns1 10.0.2.1 flags signal - speed=slow \ + test_linkfail=128 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 & local tests_pid=$! @@ -3768,7 +3768,7 @@ endpoint_tests() pm_nl_set_limits $ns2 0 3 pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow pm_nl_add_endpoint $ns2 10.0.2.2 id 2 dev ns2eth2 flags subflow - test_linkfail=4 speed=5 \ + test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & local tests_pid=$! @@ -3845,7 +3845,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns1 10.0.1.1 id 42 flags signal - test_linkfail=4 speed=5 \ + test_linkfail=128 speed=5 \ run_tests $ns1 $ns2 10.0.1.1 & local tests_pid=$! @@ -3917,7 +3917,7 @@ endpoint_tests() # broadcast IP: no packet for this address will be received on ns1 pm_nl_add_endpoint $ns1 224.0.0.1 id 2 flags signal pm_nl_add_endpoint $ns2 10.0.3.2 id 3 flags subflow - test_linkfail=4 speed=20 \ + test_linkfail=128 speed=20 \ run_tests $ns1 $ns2 10.0.1.1 & local tests_pid=$! -- Gitee From d588f5c430cfb01227a6d83dba8baee2dfc740bf Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Mon, 24 Nov 2025 22:54:31 +0800 Subject: [PATCH 0080/1449] HID: amd_sfh: Stop sensor before starting ANBZ: #35228 commit f38b91f7adedf9250167de1d6c7e358a56f3eee0 stable. commit 4d3a13afa8b64dc49293b3eab3e7beac11072c12 upstream. Titas reports that the accelerometer sensor on their laptop only works after a warm boot or unloading/reloading the amd-sfh kernel module. Presumably the sensor is in a bad state on cold boot and failing to start, so explicitly stop it before starting. Cc: stable@vger.kernel.org Fixes: 93ce5e0231d79 ("HID: amd_sfh: Implement SFH1.1 functionality") Reported-by: Titas Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220670 Tested-by: Titas Signed-off-by: Mario Limonciello (AMD) Signed-off-by: Jiri Kosina [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c index 862ca8d07232..e2047ef864eb 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c @@ -163,6 +163,8 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata) if (rc) goto cleanup; + mp2_ops->stop(privdata, cl_data->sensor_idx[i]); + amd_sfh_wait_for_response(privdata, cl_data->sensor_idx[i], DISABLE_SENSOR); writel(0, privdata->mmio + AMD_P2C_MSG(0)); mp2_ops->start(privdata, info); status = amd_sfh_wait_for_response -- Gitee From 137c4f9b0819b33d948b1e896d1bd825baae5f71 Mon Sep 17 00:00:00 2001 From: "Fabio M. De Francesco" Date: Tue, 25 Nov 2025 04:59:40 +0800 Subject: [PATCH 0081/1449] mm/mempool: replace kmap_atomic() with kmap_local_page() ANBZ: #35228 commit 0d40c4ef4b4b1c3f35bdf64f2903c344a1578437 stable. commit f2bcc99a5e901a13b754648d1dbab60f4adf9375 upstream. kmap_atomic() has been deprecated in favor of kmap_local_page(). Therefore, replace kmap_atomic() with kmap_local_page(). kmap_atomic() is implemented like a kmap_local_page() which also disables page-faults and preemption (the latter only in !PREEMPT_RT kernels). The kernel virtual addresses returned by these two API are only valid in the context of the callers (i.e., they cannot be handed to other threads). With kmap_local_page() the mappings are per thread and CPU local like in kmap_atomic(); however, they can handle page-faults and can be called from any context (including interrupts). The tasks that call kmap_local_page() can be preempted and, when they are scheduled to run again, the kernel virtual addresses are restored and are still valid. The code blocks between the mappings and un-mappings don't rely on the above-mentioned side effects of kmap_atomic(), so that mere replacements of the old API with the new one is all that they require (i.e., there is no need to explicitly call pagefault_disable() and/or preempt_disable()). Link: https://lkml.kernel.org/r/20231120142640.7077-1-fabio.maria.de.francesco@linux.intel.com Signed-off-by: Fabio M. De Francesco Cc: Ira Weiny Signed-off-by: Andrew Morton Stable-dep-of: ec33b59542d9 ("mm/mempool: fix poisoning order>0 pages with HIGHMEM") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/mempool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm/mempool.c b/mm/mempool.c index 2d9581a4be6c..8d88bb7b39f9 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -64,10 +64,10 @@ static void check_element(mempool_t *pool, void *element) } else if (pool->free == mempool_free_pages) { /* Mempools backed by page allocator */ int order = (int)(long)pool->pool_data; - void *addr = kmap_atomic((struct page *)element); + void *addr = kmap_local_page((struct page *)element); __check_element(pool, addr, 1UL << (PAGE_SHIFT + order)); - kunmap_atomic(addr); + kunmap_local(addr); } } @@ -89,10 +89,10 @@ static void poison_element(mempool_t *pool, void *element) } else if (pool->alloc == mempool_alloc_pages) { /* Mempools backed by page allocator */ int order = (int)(long)pool->pool_data; - void *addr = kmap_atomic((struct page *)element); + void *addr = kmap_local_page((struct page *)element); __poison_element(addr, 1UL << (PAGE_SHIFT + order)); - kunmap_atomic(addr); + kunmap_local(addr); } } #else /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */ -- Gitee From d3c7a431ec011b97a8ad2de84bd71a8b9aae8a98 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Tue, 25 Nov 2025 04:59:41 +0800 Subject: [PATCH 0082/1449] mm/mempool: fix poisoning order>0 pages with HIGHMEM ANBZ: #35228 commit 19de79aaea33ee1ea058c8711b3b2b4a7e4decd4 stable. commit ec33b59542d96830e3c89845ff833cf7b25ef172 upstream. The kernel test has reported: BUG: unable to handle page fault for address: fffba000 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page *pde = 03171067 *pte = 00000000 Oops: Oops: 0002 [#1] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Tainted: G T 6.18.0-rc2-00031-gec7f31b2a2d3 #1 NONE a1d066dfe789f54bc7645c7989957d2bdee593ca Tainted: [T]=RANDSTRUCT Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 EIP: memset (arch/x86/include/asm/string_32.h:168 arch/x86/lib/memcpy_32.c:17) Code: a5 8b 4d f4 83 e1 03 74 02 f3 a4 83 c4 04 5e 5f 5d 2e e9 73 41 01 00 90 90 90 3e 8d 74 26 00 55 89 e5 57 56 89 c6 89 d0 89 f7 aa 89 f0 5e 5f 5d 2e e9 53 41 01 00 cc cc cc 55 89 e5 53 57 56 EAX: 0000006b EBX: 00000015 ECX: 001fefff EDX: 0000006b ESI: fffb9000 EDI: fffba000 EBP: c611fbf0 ESP: c611fbe8 DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 EFLAGS: 00010287 CR0: 80050033 CR2: fffba000 CR3: 0316e000 CR4: 00040690 Call Trace: poison_element (mm/mempool.c:83 mm/mempool.c:102) mempool_init_node (mm/mempool.c:142 mm/mempool.c:226) mempool_init_noprof (mm/mempool.c:250 (discriminator 1)) ? mempool_alloc_pages (mm/mempool.c:640) bio_integrity_initfn (block/bio-integrity.c:483 (discriminator 8)) ? mempool_alloc_pages (mm/mempool.c:640) do_one_initcall (init/main.c:1283) Christoph found out this is due to the poisoning code not dealing properly with CONFIG_HIGHMEM because only the first page is mapped but then the whole potentially high-order page is accessed. We could give up on HIGHMEM here, but it's straightforward to fix this with a loop that's mapping, poisoning or checking and unmapping individual pages. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202511111411.9ebfa1ba-lkp@intel.com Analyzed-by: Christoph Hellwig Fixes: bdfedb76f4f5 ("mm, mempool: poison elements backed by slab allocator") Cc: stable@vger.kernel.org Tested-by: kernel test robot Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20251113-mempool-poison-v1-1-233b3ef984c3@suse.cz Signed-off-by: Vlastimil Babka Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/mempool.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/mm/mempool.c b/mm/mempool.c index 8d88bb7b39f9..e6b5fe644a88 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -64,10 +64,20 @@ static void check_element(mempool_t *pool, void *element) } else if (pool->free == mempool_free_pages) { /* Mempools backed by page allocator */ int order = (int)(long)pool->pool_data; - void *addr = kmap_local_page((struct page *)element); - __check_element(pool, addr, 1UL << (PAGE_SHIFT + order)); - kunmap_local(addr); +#ifdef CONFIG_HIGHMEM + for (int i = 0; i < (1 << order); i++) { + struct page *page = (struct page *)element; + void *addr = kmap_local_page(page + i); + + __check_element(pool, addr, PAGE_SIZE); + kunmap_local(addr); + } +#else + void *addr = page_address((struct page *)element); + + __check_element(pool, addr, PAGE_SIZE << order); +#endif } } @@ -89,10 +99,20 @@ static void poison_element(mempool_t *pool, void *element) } else if (pool->alloc == mempool_alloc_pages) { /* Mempools backed by page allocator */ int order = (int)(long)pool->pool_data; - void *addr = kmap_local_page((struct page *)element); - __poison_element(addr, 1UL << (PAGE_SHIFT + order)); - kunmap_local(addr); +#ifdef CONFIG_HIGHMEM + for (int i = 0; i < (1 << order); i++) { + struct page *page = (struct page *)element; + void *addr = kmap_local_page(page + i); + + __poison_element(addr, PAGE_SIZE); + kunmap_local(addr); + } +#else + void *addr = page_address((struct page *)element); + + __poison_element(addr, PAGE_SIZE << order); +#endif } } #else /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */ -- Gitee From 8940902712075bfb518d545219a34d5c52d33a70 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 25 Nov 2025 08:46:33 +0800 Subject: [PATCH 0083/1449] mptcp: fix a race in mptcp_pm_del_add_timer() ANBZ: #35228 commit c602cc344b4b8d41515fec3ffa98457ac963ee12 stable. commit 426358d9be7ce3518966422f87b96f1bad27295f upstream. mptcp_pm_del_add_timer() can call sk_stop_timer_sync(sk, &entry->add_timer) while another might have free entry already, as reported by syzbot. Add RCU protection to fix this issue. Also change confusing add_timer variable with stop_timer boolean. syzbot report: BUG: KASAN: slab-use-after-free in __timer_delete_sync+0x372/0x3f0 kernel/time/timer.c:1616 Read of size 4 at addr ffff8880311e4150 by task kworker/1:1/44 CPU: 1 UID: 0 PID: 44 Comm: kworker/1:1 Not tainted syzkaller #0 PREEMPT_{RT,(full)} Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025 Workqueue: events mptcp_worker Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xca/0x240 mm/kasan/report.c:482 kasan_report+0x118/0x150 mm/kasan/report.c:595 __timer_delete_sync+0x372/0x3f0 kernel/time/timer.c:1616 sk_stop_timer_sync+0x1b/0x90 net/core/sock.c:3631 mptcp_pm_del_add_timer+0x283/0x310 net/mptcp/pm.c:362 mptcp_incoming_options+0x1357/0x1f60 net/mptcp/options.c:1174 tcp_data_queue+0xca/0x6450 net/ipv4/tcp_input.c:5361 tcp_rcv_established+0x1335/0x2670 net/ipv4/tcp_input.c:6441 tcp_v4_do_rcv+0x98b/0xbf0 net/ipv4/tcp_ipv4.c:1931 tcp_v4_rcv+0x252a/0x2dc0 net/ipv4/tcp_ipv4.c:2374 ip_protocol_deliver_rcu+0x221/0x440 net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x3bb/0x6f0 net/ipv4/ip_input.c:239 NF_HOOK+0x30c/0x3a0 include/linux/netfilter.h:318 NF_HOOK+0x30c/0x3a0 include/linux/netfilter.h:318 __netif_receive_skb_one_core net/core/dev.c:6079 [inline] __netif_receive_skb+0x143/0x380 net/core/dev.c:6192 process_backlog+0x31e/0x900 net/core/dev.c:6544 __napi_poll+0xb6/0x540 net/core/dev.c:7594 napi_poll net/core/dev.c:7657 [inline] net_rx_action+0x5f7/0xda0 net/core/dev.c:7784 handle_softirqs+0x22f/0x710 kernel/softirq.c:622 __do_softirq kernel/softirq.c:656 [inline] __local_bh_enable_ip+0x1a0/0x2e0 kernel/softirq.c:302 mptcp_pm_send_ack net/mptcp/pm.c:210 [inline] mptcp_pm_addr_send_ack+0x41f/0x500 net/mptcp/pm.c:-1 mptcp_pm_worker+0x174/0x320 net/mptcp/pm.c:1002 mptcp_worker+0xd5/0x1170 net/mptcp/protocol.c:2762 process_one_work kernel/workqueue.c:3263 [inline] process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3346 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427 kthread+0x711/0x8a0 kernel/kthread.c:463 ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 Allocated by task 44: kasan_save_stack mm/kasan/common.c:56 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:77 poison_kmalloc_redzone mm/kasan/common.c:400 [inline] __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:417 kasan_kmalloc include/linux/kasan.h:262 [inline] __kmalloc_cache_noprof+0x1ef/0x6c0 mm/slub.c:5748 kmalloc_noprof include/linux/slab.h:957 [inline] mptcp_pm_alloc_anno_list+0x104/0x460 net/mptcp/pm.c:385 mptcp_pm_create_subflow_or_signal_addr+0xf9d/0x1360 net/mptcp/pm_kernel.c:355 mptcp_pm_nl_fully_established net/mptcp/pm_kernel.c:409 [inline] __mptcp_pm_kernel_worker+0x417/0x1ef0 net/mptcp/pm_kernel.c:1529 mptcp_pm_worker+0x1ee/0x320 net/mptcp/pm.c:1008 mptcp_worker+0xd5/0x1170 net/mptcp/protocol.c:2762 process_one_work kernel/workqueue.c:3263 [inline] process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3346 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427 kthread+0x711/0x8a0 kernel/kthread.c:463 ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 Freed by task 6630: kasan_save_stack mm/kasan/common.c:56 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:77 __kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:587 kasan_save_free_info mm/kasan/kasan.h:406 [inline] poison_slab_object mm/kasan/common.c:252 [inline] __kasan_slab_free+0x5c/0x80 mm/kasan/common.c:284 kasan_slab_free include/linux/kasan.h:234 [inline] slab_free_hook mm/slub.c:2523 [inline] slab_free mm/slub.c:6611 [inline] kfree+0x197/0x950 mm/slub.c:6818 mptcp_remove_anno_list_by_saddr+0x2d/0x40 net/mptcp/pm.c:158 mptcp_pm_flush_addrs_and_subflows net/mptcp/pm_kernel.c:1209 [inline] mptcp_nl_flush_addrs_list net/mptcp/pm_kernel.c:1240 [inline] mptcp_pm_nl_flush_addrs_doit+0x593/0xbb0 net/mptcp/pm_kernel.c:1281 genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115 genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210 netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219 netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline] netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346 netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg+0x21c/0x270 net/socket.c:742 ____sys_sendmsg+0x508/0x820 net/socket.c:2630 ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2684 __sys_sendmsg net/socket.c:2716 [inline] __do_sys_sendmsg net/socket.c:2721 [inline] __se_sys_sendmsg net/socket.c:2719 [inline] __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2719 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Cc: stable@vger.kernel.org Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout") Reported-by: syzbot+2a6fbf0f0530375968df@syzkaller.appspotmail.com Closes: https://lore.kernel.org/691ad3c3.a70a0220.f6df1.0004.GAE@google.com Signed-off-by: Eric Dumazet Cc: Geliang Tang Reviewed-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251117100745.1913963-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/pm_netlink.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 7fd6714f41fe..8dbe826555d2 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -29,6 +29,7 @@ struct mptcp_pm_add_entry { u8 retrans_times; struct timer_list add_timer; struct mptcp_sock *sock; + struct rcu_head rcu; }; struct pm_nl_pernet { @@ -344,22 +345,27 @@ mptcp_pm_del_add_timer(struct mptcp_sock *msk, { struct mptcp_pm_add_entry *entry; struct sock *sk = (struct sock *)msk; - struct timer_list *add_timer = NULL; + bool stop_timer = false; + + rcu_read_lock(); spin_lock_bh(&msk->pm.lock); entry = mptcp_lookup_anno_list_by_saddr(msk, addr); if (entry && (!check_id || entry->addr.id == addr->id)) { entry->retrans_times = ADD_ADDR_RETRANS_MAX; - add_timer = &entry->add_timer; + stop_timer = true; } if (!check_id && entry) list_del(&entry->list); spin_unlock_bh(&msk->pm.lock); - /* no lock, because sk_stop_timer_sync() is calling del_timer_sync() */ - if (add_timer) - sk_stop_timer_sync(sk, add_timer); + /* Note: entry might have been removed by another thread. + * We hold rcu_read_lock() to ensure it is not freed under us. + */ + if (stop_timer) + sk_stop_timer_sync(sk, &entry->add_timer); + rcu_read_unlock(); return entry; } @@ -415,7 +421,7 @@ void mptcp_pm_free_anno_list(struct mptcp_sock *msk) list_for_each_entry_safe(entry, tmp, &free_list, list) { sk_stop_timer_sync(sk, &entry->add_timer); - kfree(entry); + kfree_rcu(entry, rcu); } } @@ -1573,7 +1579,7 @@ static bool remove_anno_list_by_saddr(struct mptcp_sock *msk, entry = mptcp_pm_del_add_timer(msk, addr, false); if (entry) { - kfree(entry); + kfree_rcu(entry, rcu); return true; } -- Gitee From 2213b2eff27ab3d1b489e0693fdc9e277b7789b5 Mon Sep 17 00:00:00 2001 From: Seungjin Bae Date: Fri, 24 Oct 2025 00:27:09 +0800 Subject: [PATCH 0084/1449] can: kvaser_usb: leaf: Fix potential infinite loop in command parsers ANBZ: #35228 commit e9dd83a75a7274edef21682c823bf0b66d7b6b7f stable. commit 0c73772cd2b8cc108d5f5334de89ad648d89b9ec upstream. The `kvaser_usb_leaf_wait_cmd()` and `kvaser_usb_leaf_read_bulk_callback` functions contain logic to zero-length commands. These commands are used to align data to the USB endpoint's wMaxPacketSize boundary. The driver attempts to skip these placeholders by aligning the buffer position `pos` to the next packet boundary using `round_up()` function. However, if zero-length command is found exactly on a packet boundary (i.e., `pos` is a multiple of wMaxPacketSize, including 0), `round_up` function will return the unchanged value of `pos`. This prevents `pos` to be increased, causing an infinite loop in the parsing logic. This patch fixes this in the function by using `pos + 1` instead. This ensures that even if `pos` is on a boundary, the calculation is based on `pos + 1`, forcing `round_up()` to always return the next aligned boundary. Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c") Signed-off-by: Seungjin Bae Reviewed-by: Jimmy Assarsson Tested-by: Jimmy Assarsson Link: https://patch.msgid.link/20251023162709.348240-1-eeodqql09@gmail.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index 23bd7574b1c7..7b931953dadc 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -611,7 +611,7 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id, * for further details. */ if (tmp->len == 0) { - pos = round_up(pos, + pos = round_up(pos + 1, le16_to_cpu (dev->bulk_in->wMaxPacketSize)); continue; @@ -1590,7 +1590,7 @@ static void kvaser_usb_leaf_read_bulk_callback(struct kvaser_usb *dev, * number of events in case of a heavy rx load on the bus. */ if (cmd->len == 0) { - pos = round_up(pos, le16_to_cpu + pos = round_up(pos + 1, le16_to_cpu (dev->bulk_in->wMaxPacketSize)); continue; } -- Gitee From f88abd6ec4643d543ca17e5fabc9d92a2f14a0ca Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 8 Nov 2025 17:01:01 +0800 Subject: [PATCH 0085/1449] can: gs_usb: gs_usb_xmit_callback(): fix handling of failed transmitted URBs ANBZ: #35228 commit 1a588c40a422a3663a52f1c5535e8fb6b044167d stable. commit 516a0cd1c03fa266bb67dd87940a209fd4e53ce7 upstream. The driver lacks the cleanup of failed transfers of URBs. This reduces the number of available URBs per error by 1. This leads to reduced performance and ultimately to a complete stop of the transmission. If the sending of a bulk URB fails do proper cleanup: - increase netdev stats - mark the echo_sbk as free - free the driver's context and do accounting - wake the send queue Closes: https://github.com/candle-usb/candleLight_fw/issues/187 Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-1-a29b42eacada@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 9bd61fd8e501..1ba6395a5a66 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -747,8 +747,21 @@ static void gs_usb_xmit_callback(struct urb *urb) struct gs_can *dev = txc->dev; struct net_device *netdev = dev->netdev; - if (urb->status) - netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id); + if (!urb->status) + return; + + if (urb->status != -ESHUTDOWN && net_ratelimit()) + netdev_info(netdev, "failed to xmit URB %u: %pe\n", + txc->echo_id, ERR_PTR(urb->status)); + + netdev->stats.tx_dropped++; + netdev->stats.tx_errors++; + + can_free_echo_skb(netdev, txc->echo_id, NULL); + gs_free_tx_context(txc); + atomic_dec(&dev->active_tx_urbs); + + netif_wake_queue(netdev); } static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, -- Gitee From bb1f0e2e5bad3ff28fbec59906315e2f787f5c75 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 8 Nov 2025 17:01:02 +0800 Subject: [PATCH 0086/1449] can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing header ANBZ: #35228 commit 3433680b759646efcacc64fe36aa2e51ae34b8f0 stable. commit 6fe9f3279f7d2518439a7962c5870c6e9ecbadcf upstream. The driver expects to receive a struct gs_host_frame in gs_usb_receive_bulk_callback(). Use struct_group to describe the header of the struct gs_host_frame and check that we have at least received the header before accessing any members of it. To resubmit the URB, do not dereference the pointer chain "dev->parent->hf_size_rx" but use "parent->hf_size_rx" instead. Since "urb->context" contains "parent", it is always defined, while "dev" is not defined if the URB it too short. Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-2-a29b42eacada@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 1ba6395a5a66..e786616d167b 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -259,13 +259,15 @@ struct canfd_quirk { } __packed; struct gs_host_frame { - u32 echo_id; - __le32 can_id; + struct_group(header, + u32 echo_id; + __le32 can_id; - u8 can_dlc; - u8 channel; - u8 flags; - u8 reserved; + u8 can_dlc; + u8 channel; + u8 flags; + u8 reserved; + ); union { DECLARE_FLEX_ARRAY(struct classic_can, classic_can); @@ -573,6 +575,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) int rc; struct net_device_stats *stats; struct gs_host_frame *hf = urb->transfer_buffer; + unsigned int minimum_length; struct gs_tx_context *txc; struct can_frame *cf; struct canfd_frame *cfd; @@ -591,6 +594,15 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) return; } + minimum_length = sizeof(hf->header); + if (urb->actual_length < minimum_length) { + dev_err_ratelimited(&parent->udev->dev, + "short read (actual_length=%u, minimum_length=%u)\n", + urb->actual_length, minimum_length); + + goto resubmit_urb; + } + /* device reports out of range channel id */ if (hf->channel >= parent->channel_cnt) goto device_detach; @@ -684,7 +696,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) resubmit_urb: usb_fill_bulk_urb(urb, parent->udev, parent->pipe_in, - hf, dev->parent->hf_size_rx, + hf, parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); rc = usb_submit_urb(urb, GFP_ATOMIC); -- Gitee From ea3e50800b47c84d0e46d4933903c84e37862311 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 8 Nov 2025 17:01:03 +0800 Subject: [PATCH 0087/1449] can: gs_usb: gs_usb_receive_bulk_callback(): check actual_length before accessing data ANBZ: #35228 commit 4ffac725154cf6a253f5e6aa0c8946232b6a0af5 stable. commit 395d988f93861101ec89d0dd9e3b876ae9392a5b upstream. The URB received in gs_usb_receive_bulk_callback() contains a struct gs_host_frame. The length of the data after the header depends on the gs_host_frame hf::flags and the active device features (e.g. time stamping). Introduce a new function gs_usb_get_minimum_length() and check that we have at least received the required amount of data before accessing it. Only copy the data to that skb that has actually been received. Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") Link: https://patch.msgid.link/20251114-gs_usb-fix-usb-callbacks-v1-3-a29b42eacada@pengutronix.de [mkl: rename gs_usb_get_minimum_length() -> +gs_usb_get_minimum_rx_length()] Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index e786616d167b..72997312c956 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -258,6 +258,11 @@ struct canfd_quirk { u8 quirk; } __packed; +/* struct gs_host_frame::echo_id == GS_HOST_FRAME_ECHO_ID_RX indicates + * a regular RX'ed CAN frame + */ +#define GS_HOST_FRAME_ECHO_ID_RX 0xffffffff + struct gs_host_frame { struct_group(header, u32 echo_id; @@ -567,6 +572,37 @@ gs_usb_get_echo_skb(struct gs_can *dev, struct sk_buff *skb, return len; } +static unsigned int +gs_usb_get_minimum_rx_length(const struct gs_can *dev, const struct gs_host_frame *hf, + unsigned int *data_length_p) +{ + unsigned int minimum_length, data_length = 0; + + if (hf->flags & GS_CAN_FLAG_FD) { + if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) + data_length = can_fd_dlc2len(hf->can_dlc); + + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) + /* timestamp follows data field of max size */ + minimum_length = struct_size(hf, canfd_ts, 1); + else + minimum_length = sizeof(hf->header) + data_length; + } else { + if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX && + !(hf->can_id & cpu_to_le32(CAN_RTR_FLAG))) + data_length = can_cc_dlc2len(hf->can_dlc); + + if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) + /* timestamp follows data field of max size */ + minimum_length = struct_size(hf, classic_can_ts, 1); + else + minimum_length = sizeof(hf->header) + data_length; + } + + *data_length_p = data_length; + return minimum_length; +} + static void gs_usb_receive_bulk_callback(struct urb *urb) { struct gs_usb *parent = urb->context; @@ -575,7 +611,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) int rc; struct net_device_stats *stats; struct gs_host_frame *hf = urb->transfer_buffer; - unsigned int minimum_length; + unsigned int minimum_length, data_length; struct gs_tx_context *txc; struct can_frame *cf; struct canfd_frame *cfd; @@ -618,20 +654,33 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) if (!netif_running(netdev)) goto resubmit_urb; - if (hf->echo_id == -1) { /* normal rx */ + minimum_length = gs_usb_get_minimum_rx_length(dev, hf, &data_length); + if (urb->actual_length < minimum_length) { + stats->rx_errors++; + stats->rx_length_errors++; + + if (net_ratelimit()) + netdev_err(netdev, + "short read (actual_length=%u, minimum_length=%u)\n", + urb->actual_length, minimum_length); + + goto resubmit_urb; + } + + if (hf->echo_id == GS_HOST_FRAME_ECHO_ID_RX) { /* normal rx */ if (hf->flags & GS_CAN_FLAG_FD) { skb = alloc_canfd_skb(netdev, &cfd); if (!skb) return; cfd->can_id = le32_to_cpu(hf->can_id); - cfd->len = can_fd_dlc2len(hf->can_dlc); + cfd->len = data_length; if (hf->flags & GS_CAN_FLAG_BRS) cfd->flags |= CANFD_BRS; if (hf->flags & GS_CAN_FLAG_ESI) cfd->flags |= CANFD_ESI; - memcpy(cfd->data, hf->canfd->data, cfd->len); + memcpy(cfd->data, hf->canfd->data, data_length); } else { skb = alloc_can_skb(netdev, &cf); if (!skb) @@ -640,7 +689,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) cf->can_id = le32_to_cpu(hf->can_id); can_frame_set_cc_len(cf, hf->can_dlc, dev->can.ctrlmode); - memcpy(cf->data, hf->classic_can->data, 8); + memcpy(cf->data, hf->classic_can->data, data_length); /* ERROR frames tell us information about the controller */ if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG) -- Gitee From 863473e260a9e0e5df1abafba839fa0dbf2e0d93 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Sun, 16 Nov 2025 17:04:43 +0800 Subject: [PATCH 0088/1449] Bluetooth: hci_sock: Prevent race in socket write iter and sock bind ANBZ: #35228 commit fe68510fc99bb4b88c9c611f83699749002d515a stable. commit 89bb613511cc21ed5ba6bddc1c9b9ae9c0dad392 upstream. There is a potential race condition between sock bind and socket write iter. bind may free the same cmd via mgmt_pending before write iter sends the cmd, just as syzbot reported in UAF[1]. Here we use hci_dev_lock to synchronize the two, thereby avoiding the UAF mentioned in [1]. [1] syzbot reported: BUG: KASAN: slab-use-after-free in mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316 Read of size 8 at addr ffff888077164818 by task syz.0.17/5989 Call Trace: mgmt_pending_remove+0x3b/0x210 net/bluetooth/mgmt_util.c:316 set_link_security+0x5c2/0x710 net/bluetooth/mgmt.c:1918 hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719 hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg+0x21c/0x270 net/socket.c:742 sock_write_iter+0x279/0x360 net/socket.c:1195 Allocated by task 5989: mgmt_pending_add+0x35/0x140 net/bluetooth/mgmt_util.c:296 set_link_security+0x557/0x710 net/bluetooth/mgmt.c:1910 hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719 hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg+0x21c/0x270 net/socket.c:742 sock_write_iter+0x279/0x360 net/socket.c:1195 Freed by task 5991: mgmt_pending_free net/bluetooth/mgmt_util.c:311 [inline] mgmt_pending_foreach+0x30d/0x380 net/bluetooth/mgmt_util.c:257 mgmt_index_removed+0x112/0x2f0 net/bluetooth/mgmt.c:9477 hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314 Fixes: 6fe26f694c82 ("Bluetooth: MGMT: Protect mgmt_pending list with its own lock") Reported-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9aa47cd4633a3cf92a80 Tested-by: syzbot+9aa47cd4633a3cf92a80@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bluetooth/hci_sock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index d2613bd3e6db..8b3ef088ed14 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -1304,7 +1304,9 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, goto done; } + hci_dev_lock(hdev); mgmt_index_removed(hdev); + hci_dev_unlock(hdev); err = hci_dev_open(hdev->id); if (err) { -- Gitee From 62c31c4d53f1134f487c1cb1ff77e32c110f31a0 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 18 Nov 2025 02:45:13 +0800 Subject: [PATCH 0089/1449] Bluetooth: SMP: Fix not generating mackey and ltk when repairing ANBZ: #35228 commit fd6a1261d05d7f4d6630229e1f280dd7256b9ce8 stable. commit 545d7827b2cd5de5eb85580cebeda6b35b3ff443 upstream. The change eed467b517e8 ("Bluetooth: fix passkey uninitialized when used") introduced a goto that bypasses the creation of temporary mackey and ltk which are later used by the likes of DHKey Check step. Later ffee202a78c2 ("Bluetooth: Always request for user confirmation for Just Works (LE SC)") which means confirm_hint is always set in case JUST_WORKS so the branch checking for an existing LTK becomes pointless as confirm_hint will always be set, so this just merge both cases of malicious or legitimate devices to be confirmed before continuing with the pairing procedure. Link: https://github.com/bluez/bluez/issues/1622 Fixes: eed467b517e8 ("Bluetooth: fix passkey uninitialized when used") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bluetooth/smp.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 4c00bc50de81..e7ee13fe83a7 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -2137,7 +2137,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) struct smp_chan *smp = chan->data; struct hci_conn *hcon = conn->hcon; u8 *pkax, *pkbx, *na, *nb, confirm_hint; - u32 passkey; + u32 passkey = 0; int err; bt_dev_dbg(hcon->hdev, "conn %p", conn); @@ -2189,24 +2189,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), smp->prnd); SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK); - - /* Only Just-Works pairing requires extra checks */ - if (smp->method != JUST_WORKS) - goto mackey_and_ltk; - - /* If there already exists long term key in local host, leave - * the decision to user space since the remote device could - * be legitimate or malicious. - */ - if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, - hcon->role)) { - /* Set passkey to 0. The value can be any number since - * it'll be ignored anyway. - */ - passkey = 0; - confirm_hint = 1; - goto confirm; - } } mackey_and_ltk: @@ -2227,11 +2209,12 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) if (err) return SMP_UNSPECIFIED; - confirm_hint = 0; - -confirm: - if (smp->method == JUST_WORKS) - confirm_hint = 1; + /* Always require user confirmation for Just-Works pairing to prevent + * impersonation attacks, or in case of a legitimate device that is + * repairing use the confirmation as acknowledgment to proceed with the + * creation of new keys. + */ + confirm_hint = smp->method == JUST_WORKS ? 1 : 0; err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, passkey, confirm_hint); -- Gitee From 2c91f355722eeeefef2f81feb16f4c6ef884243c Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Thu, 20 Nov 2025 22:17:13 +0800 Subject: [PATCH 0090/1449] net: phy: mxl-gpy: fix bogus error on USXGMII and integrated PHY ANBZ: #35228 commit ff45dd52bd189cc35d590fd948dd852ac370c4e0 stable. commit ec3803b5917b6ff2f86ea965d0985c95d8a85119 upstream. As the interface mode doesn't need to be updated on PHYs connected with USXGMII and integrated PHYs, gpy_update_interface() should just return 0 in these cases rather than -EINVAL which has wrongly been introduced by commit 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface() function return type"), as this breaks support for those PHYs. Fixes: 7a495dde27ebc ("net: phy: mxl-gpy: Change gpy_update_interface() function return type") Signed-off-by: Daniel Golle Reviewed-by: Maxime Chevallier Reviewed-by: Russell King (Oracle) Link: https://patch.msgid.link/f744f721a1fcc5e2e936428c62ff2c7d94d2a293.1763648168.git.daniel@makrotopia.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/mxl-gpy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c index 034f5c4d0337..5868a0747097 100644 --- a/drivers/net/phy/mxl-gpy.c +++ b/drivers/net/phy/mxl-gpy.c @@ -515,7 +515,7 @@ static int gpy_update_interface(struct phy_device *phydev) /* Interface mode is fixed for USXGMII and integrated PHY */ if (phydev->interface == PHY_INTERFACE_MODE_USXGMII || phydev->interface == PHY_INTERFACE_MODE_INTERNAL) - return -EINVAL; + return 0; /* Automatically switch SERDES interface between SGMII and 2500-BaseX * according to speed. Disable ANEG in 2500-BaseX mode. -- Gitee From a76a251140348c1a7e42c72fb924246e700f784e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 22 Nov 2025 01:51:28 +0800 Subject: [PATCH 0091/1449] platform/x86: intel: punit_ipc: fix memory corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 3e7442c5802146fd418ba3f68dcb9ca92b5cec83 stable. commit 9b9c0adbc3f8a524d291baccc9d0c04097fb4869 upstream. This passes the address of the pointer "&punit_ipcdev" when the intent was to pass the pointer itself "punit_ipcdev" (without the ampersand). This means that the: complete(&ipcdev->cmd_complete); in intel_punit_ioc() will write to a wrong memory address corrupting it. Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/aSCmoBipSQ_tlD-D@stanley.mountain Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/intel/punit_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c index cd0ba84cc8e4..9e48229538a5 100644 --- a/drivers/platform/x86/intel/punit_ipc.c +++ b/drivers/platform/x86/intel/punit_ipc.c @@ -283,7 +283,7 @@ static int intel_punit_ipc_probe(struct platform_device *pdev) } else { ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc, IRQF_NO_SUSPEND, "intel_punit_ipc", - &punit_ipcdev); + punit_ipcdev); if (ret) { dev_err(&pdev->dev, "Failed to request irq: %d\n", irq); return ret; -- Gitee From d77dd5cdd4e98d028fbeb2fb022f3570523c015f Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 20 Nov 2025 12:15:33 +0800 Subject: [PATCH 0092/1449] net: aquantia: Add missing descriptor cache invalidation on ATL2 ANBZ: #35228 commit 30a1d3db72bc60591c546b29042e7f789976fc38 stable. commit 7526183cfdbe352c51c285762f0e15b7c428ea06 upstream. ATL2 hardware was missing descriptor cache invalidation in hw_stop(), causing SMMU translation faults during device shutdown and module removal: [ 70.355743] arm-smmu-v3 arm-smmu-v3.5.auto: event 0x10 received: [ 70.361893] arm-smmu-v3 arm-smmu-v3.5.auto: 0x0002060000000010 [ 70.367948] arm-smmu-v3 arm-smmu-v3.5.auto: 0x0000020000000000 [ 70.374002] arm-smmu-v3 arm-smmu-v3.5.auto: 0x00000000ff9bc000 [ 70.380055] arm-smmu-v3 arm-smmu-v3.5.auto: 0x0000000000000000 [ 70.386109] arm-smmu-v3 arm-smmu-v3.5.auto: event: F_TRANSLATION client: 0001:06:00.0 sid: 0x20600 ssid: 0x0 iova: 0xff9bc000 ipa: 0x0 [ 70.398531] arm-smmu-v3 arm-smmu-v3.5.auto: unpriv data write s1 "Input address caused fault" stag: 0x0 Commit 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after driver unbind") and commit ed4d81c4b3f2 ("net: aquantia: when cleaning hw cache it should be toggled") fixed cache invalidation for ATL B0, but ATL2 was left with only interrupt disabling. This allowed hardware to write to cached descriptors after DMA memory was unmapped, triggering SMMU faults. Once cache invalidation is applied to ATL2, the translation fault can't be observed anymore. Add shared aq_hw_invalidate_descriptor_cache() helper and use it in both ATL B0 and ATL2 hw_stop() implementations for consistent behavior. Fixes: e54dcf4bba3e ("net: atlantic: basic A2 init/deinit hw_ops") Tested-by: Carol Soto Signed-off-by: Kai-Heng Feng Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251120041537.62184-1-kaihengf@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../ethernet/aquantia/atlantic/aq_hw_utils.c | 22 +++++++++++++++++++ .../ethernet/aquantia/atlantic/aq_hw_utils.h | 1 + .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 19 +--------------- .../aquantia/atlantic/hw_atl2/hw_atl2.c | 2 +- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c index 1921741f7311..18b08277d2e1 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c @@ -15,6 +15,7 @@ #include "aq_hw.h" #include "aq_nic.h" +#include "hw_atl/hw_atl_llh.h" void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift, u32 val) @@ -81,6 +82,27 @@ void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value) lo_hi_writeq(value, hw->mmio + reg); } +int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw) +{ + int err; + u32 val; + + /* Invalidate Descriptor Cache to prevent writing to the cached + * descriptors and to the data pointer of those descriptors + */ + hw_atl_rdm_rx_dma_desc_cache_init_tgl(hw); + + err = aq_hw_err_from_flags(hw); + if (err) + goto err_exit; + + readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get, + hw, val, val == 1, 1000U, 10000U); + +err_exit: + return err; +} + int aq_hw_err_from_flags(struct aq_hw_s *hw) { int err = 0; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h index ffa6e4067c21..d89c63d88e4a 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h @@ -35,6 +35,7 @@ u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg); void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg); void aq_hw_write_reg64(struct aq_hw_s *hw, u32 reg, u64 value); +int aq_hw_invalidate_descriptor_cache(struct aq_hw_s *hw); int aq_hw_err_from_flags(struct aq_hw_s *hw); int aq_hw_num_tcs(struct aq_hw_s *hw); int aq_hw_q_per_tc(struct aq_hw_s *hw); diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 54e70f07b573..7b4814b3ba44 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -1198,26 +1198,9 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) static int hw_atl_b0_hw_stop(struct aq_hw_s *self) { - int err; - u32 val; - hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK); - /* Invalidate Descriptor Cache to prevent writing to the cached - * descriptors and to the data pointer of those descriptors - */ - hw_atl_rdm_rx_dma_desc_cache_init_tgl(self); - - err = aq_hw_err_from_flags(self); - - if (err) - goto err_exit; - - readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get, - self, val, val == 1, 1000U, 10000U); - -err_exit: - return err; + return aq_hw_invalidate_descriptor_cache(self); } int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, struct aq_ring_s *ring) diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c index 220400a633f5..a7bef9da823d 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c @@ -759,7 +759,7 @@ static int hw_atl2_hw_stop(struct aq_hw_s *self) { hw_atl_b0_hw_irq_disable(self, HW_ATL2_INT_MASK); - return 0; + return aq_hw_invalidate_descriptor_cache(self); } static struct aq_stats_s *hw_atl2_utils_get_hw_stats(struct aq_hw_s *self) -- Gitee From 51584d46565a6b3cbbf6db3386f3ee4843c88572 Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Fri, 21 Nov 2025 14:14:11 +0800 Subject: [PATCH 0093/1449] net: lan966x: Fix the initialization of taprio ANBZ: #35228 commit 58c411509141244c576ec86d5a5e6a5b63bede94 stable. commit 9780f535f8e0f20b4632b5a173ead71aa8f095d2 upstream. To initialize the taprio block in lan966x, it is required to configure the register REVISIT_DLY. The purpose of this register is to set the delay before revisit the next gate and the value of this register depends on the system clock. The problem is that the we calculated wrong the value of the system clock period in picoseconds. The actual system clock is ~165.617754MHZ and this correspond to a period of 6038 pico seconds and not 15125 as currently set. Fixes: e462b2717380b4 ("net: lan966x: Add offload support for taprio") Signed-off-by: Horatiu Vultur Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251121061411.810571-1-horatiu.vultur@microchip.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c index 87e5e81d40dc..84f5b4410e48 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c @@ -1,11 +1,14 @@ // SPDX-License-Identifier: GPL-2.0+ #include +#include #include "lan966x_main.h" #include "vcap_api.h" #include "vcap_api_client.h" +#define LAN9X66_CLOCK_RATE 165617754 + #define LAN966X_MAX_PTP_ID 512 /* Represents 1ppm adjustment in 2^59 format with 6.037735849ns as reference @@ -1132,5 +1135,5 @@ void lan966x_ptp_rxtstamp(struct lan966x *lan966x, struct sk_buff *skb, u32 lan966x_ptp_get_period_ps(void) { /* This represents the system clock period in picoseconds */ - return 15125; + return PICO / LAN9X66_CLOCK_RATE; } -- Gitee From bea3f4aa2fabd718b9e097d34fe794bcfbe20bba Mon Sep 17 00:00:00 2001 From: Danielle Costantino Date: Tue, 25 Nov 2025 02:00:43 +0800 Subject: [PATCH 0094/1449] net/mlx5e: Fix validation logic in rate limiting ANBZ: #35228 commit aa20dcff033cb31744455db3cb45d94e13769c80 stable. commit d2099d9f16dbfa1c5266d4230ff7860047bb0b68 upstream. The rate limiting validation condition currently checks the output variable max_bw_value[i] instead of the input value maxrate->tc_maxrate[i]. This causes the validation to compare an uninitialized or stale value rather than the actual requested rate. The condition should check the input rate to properly validate against the upper limit: } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) { This aligns with the pattern used in the first branch, which correctly checks maxrate->tc_maxrate[i] against upper_limit_mbps. The current implementation can lead to unreliable validation behavior: - For rates between 25.5 Gbps and 255 Gbps, if max_bw_value[i] is 0 from initialization, the GBPS path may be taken regardless of whether the actual rate is within bounds - When processing multiple TCs (i > 0), max_bw_value[i] contains the value computed for the previous TC, affecting the validation logic - The overflow check for rates exceeding 255 Gbps may not trigger consistently depending on previous array values This patch ensures the validation correctly examines the requested rate value for proper bounds checking. Fixes: 43b27d1bd88a ("net/mlx5e: Fix wraparound in rate limiting for values above 255 Gbps") Signed-off-by: Danielle Costantino Reviewed-by: Gal Pressman Link: https://patch.msgid.link/20251124180043.2314428-1-dcostantino@meta.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index 29e633e6dd3f..e29a8ed7e7ac 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -619,7 +619,7 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev, MLX5E_100MB); max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1; max_bw_unit[i] = MLX5_100_MBPS_UNIT; - } else if (max_bw_value[i] <= upper_limit_gbps) { + } else if (maxrate->tc_maxrate[i] <= upper_limit_gbps) { max_bw_value[i] = div_u64(maxrate->tc_maxrate[i], MLX5E_1GB); max_bw_unit[i] = MLX5_GBPS_UNIT; -- Gitee From 8d5a717ebb67cf1a739f8582cb316f307918ab69 Mon Sep 17 00:00:00 2001 From: Alexey Kodanev Date: Fri, 21 Nov 2025 20:38:34 +0800 Subject: [PATCH 0095/1449] net: sxgbe: fix potential NULL dereference in sxgbe_rx() ANBZ: #35228 commit 7fd789d6ea4915034eb6bcb72f6883c8151083e5 stable. commit f5bce28f6b9125502abec4a67d68eabcd24b3b17 upstream. Currently, when skb is null, the driver prints an error and then dereferences skb on the next line. To fix this, let's add a 'break' after the error message to switch to sxgbe_rx_refill(), which is similar to the approach taken by the other drivers in this particular case, e.g. calxeda with xgmac_rx(). Found during a code review. Fixes: 1edb9ca69e8a ("net: sxgbe: add basic framework for Samsung 10Gb ethernet driver") Signed-off-by: Alexey Kodanev Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251121123834.97748-1-aleksei.kodanev@bell-sw.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 71439825ea4e..d662679c2983 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -1521,8 +1521,10 @@ static int sxgbe_rx(struct sxgbe_priv_data *priv, int limit) skb = priv->rxq[qnum]->rx_skbuff[entry]; - if (unlikely(!skb)) + if (unlikely(!skb)) { netdev_err(priv->dev, "rx descriptor is not consistent\n"); + break; + } prefetch(skb->data - NET_IP_ALIGN); priv->rxq[qnum]->rx_skbuff[entry] = NULL; -- Gitee From 84802b6e0221715e3a52682a49781b9b550c427e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 26 Nov 2025 22:40:31 +0800 Subject: [PATCH 0096/1449] drm/amdgpu: fix cyan_skillfish2 gpu info fw handling ANBZ: #35228 commit 0be4d79f8a1b6ac792fdf401cbd3a7216a45c1f9 stable. commit 7fa666ab07ba9e08f52f357cb8e1aad753e83ac6 upstream. If the board supports IP discovery, we don't need to parse the gpu info firmware. Backport to 6.18. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4721 Fixes: fa819e3a7c1e ("drm/amdgpu: add support for cyan skillfish gpu_info") Signed-off-by: Alex Deucher (cherry picked from commit 5427e32fa3a0ba9a016db83877851ed277b065fb) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b2a1dc193cb8..c1b9333d7b78 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1941,6 +1941,8 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) chip_name = "navi12"; break; case CHIP_CYAN_SKILLFISH: + if (adev->mman.discovery_bin) + return 0; chip_name = "cyan_skillfish"; break; } -- Gitee From 31ae5d35a41438aee20ea6585801da62d7abd016 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Wed, 2 Oct 2024 00:04:36 +0800 Subject: [PATCH 0097/1449] net: dsa: sja1105: simplify static configuration reload ANBZ: #35228 commit d25c17507e804743e314ed1467c247e1303e0d4e stable. commit a18891b55703a45b700618ef40edd5e9aaecc345 upstream. The static configuration reload saves the port speed in the static configuration tables by first converting it from the internal respresentation to the SPEED_xxx ethtool representation, and then converts it back to restore the setting. This is because sja1105_adjust_port_config() takes the speed as SPEED_xxx. However, this is unnecessarily complex. If we split sja1105_adjust_port_config() up, we can simply save and restore the mac[port].speed member in the static configuration tables. Signed-off-by: Russell King (Oracle) Link: https://patch.msgid.link/E1svfMa-005ZIX-If@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski Stable-dep-of: da62abaaa268 ("net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/sja1105/sja1105_main.c | 65 ++++++++++++++------------ 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 843e50b5a0ec..0de73a6257f9 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -1261,29 +1261,11 @@ static int sja1105_parse_dt(struct sja1105_private *priv) return rc; } -/* Convert link speed from SJA1105 to ethtool encoding */ -static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv, - u64 speed) -{ - if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) - return SPEED_10; - if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) - return SPEED_100; - if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) - return SPEED_1000; - if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS]) - return SPEED_2500; - return SPEED_UNKNOWN; -} - -/* Set link speed in the MAC configuration for a specific port. */ -static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, - int speed_mbps) +static int sja1105_set_port_speed(struct sja1105_private *priv, int port, + int speed_mbps) { struct sja1105_mac_config_entry *mac; - struct device *dev = priv->ds->dev; u64 speed; - int rc; /* On P/Q/R/S, one can read from the device via the MAC reconfiguration * tables. On E/T, MAC reconfig tables are not readable, only writable. @@ -1317,7 +1299,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; break; default: - dev_err(dev, "Invalid speed %iMbps\n", speed_mbps); + dev_err(priv->ds->dev, "Invalid speed %iMbps\n", speed_mbps); return -EINVAL; } @@ -1329,11 +1311,31 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * we need to configure the PCS only (if even that). */ if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) - mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; + speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX) - mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; - else - mac[port].speed = speed; + speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; + + mac[port].speed = speed; + + return 0; +} + +/* Write the MAC Configuration Table entry and, if necessary, the CGU settings, + * after a link speedchange for this port. + */ +static int sja1105_set_port_config(struct sja1105_private *priv, int port) +{ + struct sja1105_mac_config_entry *mac; + struct device *dev = priv->ds->dev; + int rc; + + /* On P/Q/R/S, one can read from the device via the MAC reconfiguration + * tables. On E/T, MAC reconfig tables are not readable, only writable. + * We have to *know* what the MAC looks like. For the sake of keeping + * the code common, we'll use the static configuration tables as a + * reasonable approximation for both E/T and P/Q/R/S. + */ + mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; /* Write to the dynamic reconfiguration tables */ rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port, @@ -1383,7 +1385,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port, { struct sja1105_private *priv = ds->priv; - sja1105_adjust_port_config(priv, port, speed); + if (!sja1105_set_port_speed(priv, port, speed)) + sja1105_set_port_config(priv, port); sja1105_inhibit_tx(priv, BIT(port), false); } @@ -2284,8 +2287,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, { struct ptp_system_timestamp ptp_sts_before; struct ptp_system_timestamp ptp_sts_after; - int speed_mbps[SJA1105_MAX_NUM_PORTS]; u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0}; + u64 mac_speed[SJA1105_MAX_NUM_PORTS]; struct sja1105_mac_config_entry *mac; struct dsa_switch *ds = priv->ds; s64 t1, t2, t3, t4; @@ -2298,14 +2301,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv, mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; - /* Back up the dynamic link speed changed by sja1105_adjust_port_config + /* Back up the dynamic link speed changed by sja1105_set_port_speed() * in order to temporarily restore it to SJA1105_SPEED_AUTO - which the * switch wants to see in the static config in order to allow us to * change it through the dynamic interface later. */ for (i = 0; i < ds->num_ports; i++) { - speed_mbps[i] = sja1105_port_speed_to_ethtool(priv, - mac[i].speed); + mac_speed[i] = mac[i].speed; mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; if (priv->xpcs[i]) @@ -2368,7 +2370,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, struct dw_xpcs *xpcs = priv->xpcs[i]; unsigned int neg_mode; - rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]); + mac[i].speed = mac_speed[i]; + rc = sja1105_set_port_config(priv, i); if (rc < 0) goto out; -- Gitee From b72d37595f794ca09baa7e3f767e21b1c57f131c Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sat, 22 Nov 2025 19:13:24 +0800 Subject: [PATCH 0098/1449] net: dsa: sja1105: fix SGMII linking at 10M or 100M but not passing traffic ANBZ: #35228 commit 90daa70a4d6239103f3d67e2b4bc0bad15297b8c stable. commit da62abaaa268357b1aa66b372ace562189a05df1 upstream. When using the SGMII PCS as a fixed-link chip-to-chip connection, it is easy to miss the fact that traffic passes only at 1G, since that's what any normal such connection would use. When using the SGMII PCS connected towards an on-board PHY or an SFP module, it is immediately noticeable that when the link resolves to a speed other than 1G, traffic from the MAC fails to pass: TX counters increase, but nothing gets decoded by the other end, and no local RX counters increase either. Artificially lowering a fixed-link rate to speed = <100> makes us able to see the same issue as in the case of having an SGMII PHY. Some debugging shows that the XPCS configuration is A-OK, but that the MAC Configuration Table entry for the port has the SPEED bits still set to 1000Mbps, due to a special condition in the driver. Deleting that condition, and letting the resolved link speed be programmed directly into the MAC speed field, results in a functional link at all 3 speeds. This piece of evidence, based on testing on both generations with SGMII support (SJA1105S and SJA1110A) directly contradicts the statement from the blamed commit that "the MAC is fixed at 1 Gbps and we need to configure the PCS only (if even that)". Worse, that statement is not backed by any documentation, and no one from NXP knows what it might refer to. I am unable to recall sufficient context regarding my testing from March 2020 to understand what led me to draw such a braindead and factually incorrect conclusion. Yet, there is nothing of value regarding forcing the MAC speed, either for SGMII or 2500Base-X (introduced at a later stage), so remove all such logic. Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port") Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20251122111324.136761-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/sja1105/sja1105_main.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 0de73a6257f9..1acc5d912d16 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -1307,14 +1307,7 @@ static int sja1105_set_port_speed(struct sja1105_private *priv, int port, * table, since this will be used for the clocking setup, and we no * longer need to store it in the static config (already told hardware * we want auto during upload phase). - * Actually for the SGMII port, the MAC is fixed at 1 Gbps and - * we need to configure the PCS only (if even that). */ - if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) - speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; - else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX) - speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; - mac[port].speed = speed; return 0; -- Gitee From dd56e9621da93719e92885b4eafaf1bd4feda484 Mon Sep 17 00:00:00 2001 From: Jiefeng Zhang Date: Wed, 26 Nov 2025 11:22:49 +0800 Subject: [PATCH 0099/1449] net: atlantic: fix fragment overflow handling in RX path ANBZ: #35228 commit 3be37c3c96b16462394fcb8e15e757c691377038 stable. commit 5ffcb7b890f61541201461580bb6622ace405aec upstream. The atlantic driver can receive packets with more than MAX_SKB_FRAGS (17) fragments when handling large multi-descriptor packets. This causes an out-of-bounds write in skb_add_rx_frag_netmem() leading to kernel panic. The issue occurs because the driver doesn't check the total number of fragments before calling skb_add_rx_frag(). When a packet requires more than MAX_SKB_FRAGS fragments, the fragment index exceeds the array bounds. Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE, then all fragments are accounted for. And reusing the existing check to prevent the overflow earlier in the code path. This crash occurred in production with an Aquantia AQC113 10G NIC. Stack trace from production environment: ``` RIP: 0010:skb_add_rx_frag_netmem+0x29/0xd0 Code: 90 f3 0f 1e fa 0f 1f 44 00 00 48 89 f8 41 89 ca 48 89 d7 48 63 ce 8b 90 c0 00 00 00 48 c1 e1 04 48 01 ca 48 03 90 c8 00 00 00 <48> 89 7a 30 44 89 52 3c 44 89 42 38 40 f6 c7 01 75 74 48 89 fa 83 RSP: 0018:ffffa9bec02a8d50 EFLAGS: 00010287 RAX: ffff925b22e80a00 RBX: ffff925ad38d2700 RCX: fffffffe0a0c8000 RDX: ffff9258ea95bac0 RSI: ffff925ae0a0c800 RDI: 0000000000037a40 RBP: 0000000000000024 R08: 0000000000000000 R09: 0000000000000021 R10: 0000000000000848 R11: 0000000000000000 R12: ffffa9bec02a8e24 R13: ffff925ad8615570 R14: 0000000000000000 R15: ffff925b22e80a00 FS: 0000000000000000(0000) GS:ffff925e47880000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff9258ea95baf0 CR3: 0000000166022004 CR4: 0000000000f72ef0 PKRU: 55555554 Call Trace: aq_ring_rx_clean+0x175/0xe60 [atlantic] ? aq_ring_rx_clean+0x14d/0xe60 [atlantic] ? aq_ring_tx_clean+0xdf/0x190 [atlantic] ? kmem_cache_free+0x348/0x450 ? aq_vec_poll+0x81/0x1d0 [atlantic] ? __napi_poll+0x28/0x1c0 ? net_rx_action+0x337/0x420 ``` Fixes: 6aecbba12b5c ("net: atlantic: add check for MAX_SKB_FRAGS") Changes in v4: - Add Fixes: tag to satisfy patch validation requirements. Changes in v3: - Fix by assuming there will be an extra frag if buff->len > AQ_CFG_RX_HDR_SIZE, then all fragments are accounted for. Signed-off-by: Jiefeng Zhang Link: https://patch.msgid.link/20251126032249.69358-1-jiefeng.z.zhang@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index f7433abd6591..3f004d08307f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -547,6 +547,11 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, if (!buff->is_eop) { unsigned int frag_cnt = 0U; + + /* There will be an extra fragment */ + if (buff->len > AQ_CFG_RX_HDR_SIZE) + frag_cnt++; + buff_ = buff; do { bool is_rsc_completed = true; -- Gitee From 84a8ab5885ef5ded2489e983b8379f177da4f6fb Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Tue, 25 Nov 2025 16:52:07 +0800 Subject: [PATCH 0100/1449] net: fec: cancel perout_timer when PEROUT is disabled ANBZ: #35228 commit 2d8f6acf56235e28bd55bd86b253bf7aa839e8ac stable. commit 50caa744689e505414673c20359b04aa918439e3 upstream. The PEROUT allows the user to set a specified future time to output the periodic signal. If the future time is far from the current time, the FEC driver will use hrtimer to configure PEROUT one second before the future time. However, the hrtimer will not be canceled if the PEROUT is disabled before the hrtimer expires. So the PEROUT will be configured when the hrtimer expires, which is not as expected. Therefore, cancel the hrtimer in fec_ptp_pps_disable() to fix this issue. Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS") Signed-off-by: Wei Fang Link: https://patch.msgid.link/20251125085210.1094306-2-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/fec_ptp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 7f6b57432071..cb3f05da3eee 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -498,6 +498,8 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel) { unsigned long flags; + hrtimer_cancel(&fep->perout_timer); + spin_lock_irqsave(&fep->tmreg_lock, flags); writel(0, fep->hwp + FEC_TCSR(channel)); spin_unlock_irqrestore(&fep->tmreg_lock, flags); -- Gitee From 9de87980007d71f18afa43878370dd2f50212711 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Tue, 25 Nov 2025 16:52:08 +0800 Subject: [PATCH 0101/1449] net: fec: do not update PEROUT if it is enabled ANBZ: #35228 commit b332c433489e46c9ec94c0e846701722453aca79 stable. commit e97faa0c20ea8840f45569ba434e30538fff8fc9 upstream. If the previously set PEROUT is already active, updating it will cause the new PEROUT to start immediately instead of at the specified time. This is because fep->reload_period is updated whithout check whether the PEROUT is enabled, and the old PEROUT is not disabled. Therefore, the pulse period will be updated immediately in the pulse interrupt handler fec_pps_interrupt(). Currently, the driver does not support directly updating PEROUT and it will make the logic be more complicated. To fix the current issue, add a check before enabling the PEROUT, the driver will return an error if PEROUT is enabled. If users wants to update a new PEROUT, they should disable the old PEROUT first. Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS") Signed-off-by: Wei Fang Link: https://patch.msgid.link/20251125085210.1094306-3-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/fec.h | 1 + drivers/net/ethernet/freescale/fec_ptp.c | 43 ++++++++++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 733af928caff..d80a8c07c020 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -683,6 +683,7 @@ struct fec_enet_private { unsigned int reload_period; int pps_enable; unsigned int next_counter; + bool perout_enable; struct hrtimer perout_timer; u64 perout_stime; diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index cb3f05da3eee..a3853fccdc7b 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -244,6 +244,7 @@ static int fec_ptp_pps_perout(struct fec_enet_private *fep) * the FEC_TCCR register in time and missed the start time. */ if (fep->perout_stime < curr_time + 100 * NSEC_PER_MSEC) { + fep->perout_enable = false; dev_err(&fep->pdev->dev, "Current time is too close to the start time!\n"); spin_unlock_irqrestore(&fep->tmreg_lock, flags); return -1; @@ -501,6 +502,7 @@ static int fec_ptp_pps_disable(struct fec_enet_private *fep, uint channel) hrtimer_cancel(&fep->perout_timer); spin_lock_irqsave(&fep->tmreg_lock, flags); + fep->perout_enable = false; writel(0, fep->hwp + FEC_TCSR(channel)); spin_unlock_irqrestore(&fep->tmreg_lock, flags); @@ -532,6 +534,8 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, return ret; } else if (rq->type == PTP_CLK_REQ_PEROUT) { + u32 reload_period; + /* Reject requests with unsupported flags */ if (rq->perout.flags) return -EOPNOTSUPP; @@ -551,12 +555,14 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, return -EOPNOTSUPP; } - fep->reload_period = div_u64(period_ns, 2); - if (on && fep->reload_period) { + reload_period = div_u64(period_ns, 2); + if (on && reload_period) { + u64 perout_stime; + /* Convert 1588 timestamp to ns*/ start_time.tv_sec = rq->perout.start.sec; start_time.tv_nsec = rq->perout.start.nsec; - fep->perout_stime = timespec64_to_ns(&start_time); + perout_stime = timespec64_to_ns(&start_time); mutex_lock(&fep->ptp_clk_mutex); if (!fep->ptp_clk_on) { @@ -565,18 +571,35 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, return -EOPNOTSUPP; } spin_lock_irqsave(&fep->tmreg_lock, flags); + + if (fep->perout_enable) { + dev_err(&fep->pdev->dev, + "PEROUT has been enabled\n"); + ret = -EBUSY; + goto unlock; + } + /* Read current timestamp */ curr_time = timecounter_read(&fep->tc); - spin_unlock_irqrestore(&fep->tmreg_lock, flags); - mutex_unlock(&fep->ptp_clk_mutex); + if (perout_stime <= curr_time) { + dev_err(&fep->pdev->dev, + "Start time must be greater than current time\n"); + ret = -EINVAL; + goto unlock; + } /* Calculate time difference */ - delta = fep->perout_stime - curr_time; + delta = perout_stime - curr_time; + fep->reload_period = reload_period; + fep->perout_stime = perout_stime; + fep->perout_enable = true; - if (fep->perout_stime <= curr_time) { - dev_err(&fep->pdev->dev, "Start time must larger than current time!\n"); - return -EINVAL; - } +unlock: + spin_unlock_irqrestore(&fep->tmreg_lock, flags); + mutex_unlock(&fep->ptp_clk_mutex); + + if (ret) + return ret; /* Because the timer counter of FEC only has 31-bits, correspondingly, * the time comparison register FEC_TCCR also only low 31 bits can be -- Gitee From db68dbaca69d243573c21ddec888655ee782333e Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Tue, 25 Nov 2025 16:52:09 +0800 Subject: [PATCH 0102/1449] net: fec: do not allow enabling PPS and PEROUT simultaneously ANBZ: #35228 commit 2648b8b519925284383e390cc58fdce163be23e5 stable. commit c0a1f3d7e128e8d1b6c0fe09c68eac5ebcf677c8 upstream. In the current driver, PPS and PEROUT use the same channel to generate the events, so they cannot be enabled at the same time. Otherwise, the later configuration will overwrite the earlier configuration. Therefore, when configuring PPS, the driver will check whether PEROUT is enabled. Similarly, when configuring PEROUT, the driver will check whether PPS is enabled. Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS") Signed-off-by: Wei Fang Link: https://patch.msgid.link/20251125085210.1094306-4-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/fec_ptp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index a3853fccdc7b..beb1d98fa741 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -129,6 +129,12 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable) spin_lock_irqsave(&fep->tmreg_lock, flags); + if (fep->perout_enable) { + spin_unlock_irqrestore(&fep->tmreg_lock, flags); + dev_err(&fep->pdev->dev, "PEROUT is running"); + return -EBUSY; + } + if (fep->pps_enable == enable) { spin_unlock_irqrestore(&fep->tmreg_lock, flags); return 0; @@ -572,6 +578,12 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, } spin_lock_irqsave(&fep->tmreg_lock, flags); + if (fep->pps_enable) { + dev_err(&fep->pdev->dev, "PPS is running"); + ret = -EBUSY; + goto unlock; + } + if (fep->perout_enable) { dev_err(&fep->pdev->dev, "PEROUT has been enabled\n"); -- Gitee From 9075cc63ff6e184f9173914ed8d6385dd745f910 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Tue, 25 Nov 2025 16:52:10 +0800 Subject: [PATCH 0103/1449] net: fec: do not register PPS event for PEROUT ANBZ: #35228 commit 21f867e3da98c96a2b3009f7eaa0ea9e795ce34e stable. commit 9a060d0fac9e75524f72864adec6d8cdb70a5bca upstream. There are currently two situations that can trigger the PTP interrupt, one is the PPS event, the other is the PEROUT event. However, the irq handler fec_pps_interrupt() does not check the irq event type and directly registers a PPS event into the system, but the event may be a PEROUT event. This is incorrect because PEROUT is an output signal, while PPS is the input of the kernel PPS system. Therefore, add a check for the event type, if pps_enable is true, it means that the current event is a PPS event, and then the PPS event is registered. Fixes: 350749b909bf ("net: fec: Add support for periodic output signal of PPS") Signed-off-by: Wei Fang Link: https://patch.msgid.link/20251125085210.1094306-5-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/fec_ptp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index beb1d98fa741..4bb894b5afcb 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -719,8 +719,11 @@ static irqreturn_t fec_pps_interrupt(int irq, void *dev_id) fep->next_counter = (fep->next_counter + fep->reload_period) & fep->cc.mask; - event.type = PTP_CLOCK_PPS; - ptp_clock_event(fep->ptp_clock, &event); + if (fep->pps_enable) { + event.type = PTP_CLOCK_PPS; + ptp_clock_event(fep->ptp_clock, &event); + } + return IRQ_HANDLED; } -- Gitee From 657140d33b98a5594efe9deb33fccba6ffaeb80a Mon Sep 17 00:00:00 2001 From: Mario Tesi Date: Thu, 16 Oct 2025 00:16:19 +0800 Subject: [PATCH 0104/1449] iio: st_lsm6dsx: Fixed calibrated timestamp calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit cad94b17e2760fded801907e73dea34159fb3c97 stable. commit 8abbf45fcda028c2c05ba38eb14ede9fa9e7341b upstream. The calibrated timestamp is calculated from the nominal value using the formula: ts_gain[ns] ≈ ts_sensitivity - (ts_trim_coeff * val) / 1000. The values of ts_sensitivity and ts_trim_coeff are not the same for all devices, so it is necessary to differentiate them based on the part name. For the correct values please consult the relevant AN. Fixes: cb3b6b8e1bc0 ("iio: imu: st_lsm6dsx: add odr calibration feature") Signed-off-by: Mario Tesi Acked-by: Lorenzo Bianconi Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 18 ++++++++++++++++++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 19 ++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index c19237717e81..0f347684f6fc 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -190,6 +190,22 @@ struct st_lsm6dsx_fifo_ops { * @fifo_en: Hw timer FIFO enable register info (addr + mask). * @decimator: Hw timer FIFO decimator register info (addr + mask). * @freq_fine: Difference in % of ODR with respect to the typical. + * @ts_sensitivity: Nominal timestamp sensitivity. + * @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain. + * This coefficient comes into play when linearizing the formula + * used to calculate the calibrated timestamp (please see the + * relevant formula in the AN for the specific IMU). + * For example, in the case of LSM6DSO we have: + * + * 1 / (1 + x) ~= 1 - x (Taylor’s Series) + * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192) + * ttrim[ns] ~= 25000 - 37.5 * val + * ttrim[ns] ~= 25000 - (37500 * val) / 1000 + * + * so, replacing ts_sensitivity = 25000 and + * ts_trim_coeff = 37500 + * + * ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000 */ struct st_lsm6dsx_hw_ts_settings { struct st_lsm6dsx_reg timer_en; @@ -197,6 +213,8 @@ struct st_lsm6dsx_hw_ts_settings { struct st_lsm6dsx_reg fifo_en; struct st_lsm6dsx_reg decimator; u8 freq_fine; + u16 ts_sensitivity; + u16 ts_trim_coeff; }; /** diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index b6e6b1df8a61..6e42e0c659e0 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -77,8 +77,6 @@ #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f -#define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */ - static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), @@ -962,6 +960,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(7, 6), }, .freq_fine = 0x63, + .ts_sensitivity = 25000, + .ts_trim_coeff = 37500, }, .shub_settings = { .page_mux = { @@ -1175,6 +1175,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(7, 6), }, .freq_fine = 0x63, + .ts_sensitivity = 25000, + .ts_trim_coeff = 37500, }, .event_settings = { .enable_reg = { @@ -1350,6 +1352,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(7, 6), }, .freq_fine = 0x4f, + .ts_sensitivity = 21701, + .ts_trim_coeff = 28212, }, .shub_settings = { .page_mux = { @@ -2243,20 +2247,13 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) } /* calibrate timestamp sensitivity */ - hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY; + hw->ts_gain = ts_settings->ts_sensitivity; if (ts_settings->freq_fine) { err = regmap_read(hw->regmap, ts_settings->freq_fine, &val); if (err < 0) return err; - /* - * linearize the AN5192 formula: - * 1 / (1 + x) ~= 1 - x (Taylor’s Series) - * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) - * ttrim[ns] ~= 25000 - 37.5 * val - * ttrim[ns] ~= 25000 - (37500 * val) / 1000 - */ - hw->ts_gain -= ((s8)val * 37500) / 1000; + hw->ts_gain -= ((s8)val * ts_settings->ts_trim_coeff) / 1000; } return 0; -- Gitee From 43e135377ed3c6d81c40b474803cbc328a77b577 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 24 Nov 2025 10:22:15 +0800 Subject: [PATCH 0105/1449] usb: gadget: renesas_usbf: Handle devm_pm_runtime_enable() errors ANBZ: #35228 commit 826785925627fce1dd34bd0307c923340fa8e160 stable. commit 74851fbb6d647304f8a7dc491434d3a335ef4b8d upstream. devm_pm_runtime_enable() can fail due to memory allocation. The current code ignores its return value, potentially causing pm_runtime_resume_and_get() to operate on uninitialized runtime PM state. Check the return value of devm_pm_runtime_enable() and return on failure. Fixes: 3e6e14ffdea4 ("usb: gadget: udc: add Renesas RZ/N1 USBF controller support") Signed-off-by: Haotian Zhang Acked-by: Herve Codina Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251124022215.1619-1-vulab@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/udc/renesas_usbf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c index 657f265ac7cc..8463f681ae67 100644 --- a/drivers/usb/gadget/udc/renesas_usbf.c +++ b/drivers/usb/gadget/udc/renesas_usbf.c @@ -3262,7 +3262,9 @@ static int usbf_probe(struct platform_device *pdev) if (IS_ERR(udc->regs)) return PTR_ERR(udc->regs); - devm_pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; -- Gitee From 1a5502558d40f55ea852498d93a601726f3c3af7 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Thu, 20 Nov 2025 10:40:39 +0800 Subject: [PATCH 0106/1449] mailbox: mailbox-test: Fix debugfs_create_dir error checking ANBZ: #35228 commit 5550f9021895ea7b9203cae1d8463216d0d9f410 stable. commit 3acf1028f5003731977f750a7070f3321a9cb740 upstream. The debugfs_create_dir() function returns ERR_PTR() on error, not NULL. The current null-check fails to catch errors. Use IS_ERR() to correctly check for errors. Fixes: 8ea4484d0c2b ("mailbox: Add generic mechanism for testing Mailbox Controllers") Signed-off-by: Haotian Zhang Signed-off-by: Jassi Brar Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mailbox/mailbox-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c index 22d6018ceec3..6bdee87f3083 100644 --- a/drivers/mailbox/mailbox-test.c +++ b/drivers/mailbox/mailbox-test.c @@ -268,7 +268,7 @@ static int mbox_test_add_debugfs(struct platform_device *pdev, return 0; tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL); - if (!tdev->root_debugfs_dir) { + if (IS_ERR(tdev->root_debugfs_dir)) { dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n"); return -EINVAL; } -- Gitee From b3070c3707e31c4977f16ff41c35e7fff3eca63d Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 13 Mar 2025 23:28:52 +0800 Subject: [PATCH 0107/1449] mailbox: pcc: Refactor error handling in irq handler into separate function ANBZ: #35228 commit ea621f472cfe3c2a0833a22e494c0aee23d794cf stable. commit 3a675f50415b95f2ae10bfd932e2154ba1a08ee7 upstream. The existing error handling logic in pcc_mbox_irq() is intermixed with the main flow of the function. The command complete check and the complete complete update/acknowledgment are nicely factored into separate functions. Moves error detection and clearing logic into a separate function called: pcc_mbox_error_check_and_clear() by extracting error-handling logic from pcc_mbox_irq(). This ensures error checking and clearing are handled separately and it improves maintainability by keeping the IRQ handler focused on processing events. Acked-by: Huisong Li Tested-by: Huisong Li Tested-by: Adam Young Signed-off-by: Sudeep Holla Signed-off-by: Jassi Brar Stable-dep-of: ff0e4d4c97c9 ("mailbox: pcc: don't zero error register") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mailbox/pcc.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 49254d99a8ad..bb977cf8ad42 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -269,6 +269,25 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan) return !!val; } +static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan) +{ + u64 val; + int ret; + + ret = pcc_chan_reg_read(&pchan->error, &val); + if (ret) + return ret; + + val &= pchan->error.status_mask; + if (val) { + val &= ~pchan->error.status_mask; + pcc_chan_reg_write(&pchan->error, val); + return -EIO; + } + + return 0; +} + static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan) { struct acpi_pcct_ext_pcc_shared_memory pcc_hdr; @@ -309,8 +328,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) { struct pcc_chan_info *pchan; struct mbox_chan *chan = p; - u64 val; - int ret; pchan = chan->con_priv; @@ -324,15 +341,8 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) if (!pcc_mbox_cmd_complete_check(pchan)) return IRQ_NONE; - ret = pcc_chan_reg_read(&pchan->error, &val); - if (ret) + if (pcc_mbox_error_check_and_clear(pchan)) return IRQ_NONE; - val &= pchan->error.status_mask; - if (val) { - val &= ~pchan->error.status_mask; - pcc_chan_reg_write(&pchan->error, val); - return IRQ_NONE; - } /* * Clear this flag after updating interrupt ack register and just -- Gitee From 881d502346b6b1a563370ccb22eb8c2f58e63ddf Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Wed, 5 Nov 2025 22:42:29 +0800 Subject: [PATCH 0108/1449] mailbox: pcc: don't zero error register ANBZ: #35228 commit f29b58e974c70d7a7c4b6e6d8afd479b4fd8821e stable. commit ff0e4d4c97c94af34cc9cad37b5a5cdbe597a3b0 upstream. The error status mask for a type 3/4 subspace is used for reading the error status, and the bitwise inverse is used for clearing the error with the intent being to preserve any of the non-error bits. However, we were previously applying the mask to extract the status and then applying the inverse to the result which ended up clearing all bits. Instead, store the inverse mask in the preserve mask and then use that on the original value read from the error status so that only the error is cleared. Fixes: c45ded7e1135 ("mailbox: pcc: Add support for PCCT extended PCC subspaces(type 3/4)") Signed-off-by: Jamie Iles Signed-off-by: Punit Agrawal Signed-off-by: Jassi Brar Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mailbox/pcc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index bb977cf8ad42..2b7d0bc92072 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -278,9 +278,8 @@ static int pcc_mbox_error_check_and_clear(struct pcc_chan_info *pchan) if (ret) return ret; - val &= pchan->error.status_mask; - if (val) { - val &= ~pchan->error.status_mask; + if (val & pchan->error.status_mask) { + val &= pchan->error.preserve_mask; pcc_chan_reg_write(&pchan->error, val); return -EIO; } @@ -673,7 +672,8 @@ static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan, ret = pcc_chan_reg_init(&pchan->error, &pcct_ext->error_status_register, - 0, 0, pcct_ext->error_status_mask, + ~pcct_ext->error_status_mask, 0, + pcct_ext->error_status_mask, "Error Status"); } return ret; -- Gitee From c18cbf13320891a437ac29e0431255aac35d6c96 Mon Sep 17 00:00:00 2001 From: Francesco Lavra Date: Wed, 26 Nov 2025 17:50:27 +0800 Subject: [PATCH 0109/1449] spi: tegra114: remove Kconfig dependency on TEGRA20_APB_DMA ANBZ: #35228 commit dbb60bd12950349f2c68d4ea8aeed9d34869e630 stable. commit 3dcf44ab56e1d3ca3532083c0d5390b758e45b45 upstream. This driver runs also on Tegra SoCs without a Tegra20 APB DMA controller (e.g. Tegra234). Remove the Kconfig dependency on TEGRA20_APB_DMA; in addition, amend the help text to reflect the fact that this driver works on SoCs different from Tegra114. Fixes: bb9667d8187b ("arm64: tegra: Add SPI device tree nodes for Tegra234") Signed-off-by: Francesco Lavra Link: https://patch.msgid.link/20251126095027.4102004-1-flavra@baylibre.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- anolis/configs/L2-OPTIONAL/arm64/CONFIG_SPI_TEGRA114 | 1 + drivers/spi/Kconfig | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 anolis/configs/L2-OPTIONAL/arm64/CONFIG_SPI_TEGRA114 diff --git a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_SPI_TEGRA114 b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_SPI_TEGRA114 new file mode 100644 index 000000000000..658bd7d096ed --- /dev/null +++ b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_SPI_TEGRA114 @@ -0,0 +1 @@ +# CONFIG_SPI_TEGRA114 is not set diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e3217ce5a3f6..e5d0a4d17919 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -1074,10 +1074,10 @@ config SPI_TEGRA210_QUAD config SPI_TEGRA114 tristate "NVIDIA Tegra114 SPI Controller" - depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST + depends on ARCH_TEGRA || COMPILE_TEST depends on RESET_CONTROLLER help - SPI driver for NVIDIA Tegra114 SPI Controller interface. This controller + SPI controller driver for NVIDIA Tegra114 and later SoCs. This controller is different than the older SoCs SPI controller and also register interface get changed with this controller. -- Gitee From a4eb661e80e932c68e31aa83ce046140c7e39e51 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 24 Nov 2025 09:58:52 +0800 Subject: [PATCH 0110/1449] spi: amlogic-spifc-a1: Handle devm_pm_runtime_enable() errors ANBZ: #35228 commit 99aff13bcc13305f1c56b119a3cf574a0f190c03 stable. commit a90903c2a3c38bce475f46ea3f93dbf6a9971553 upstream. devm_pm_runtime_enable() can fail due to memory allocation. The current code ignores its return value, potentially causing runtime PM operations to fail silently after autosuspend configuration. Check the return value of devm_pm_runtime_enable() and return on failure. Fixes: 909fac05b926 ("spi: add support for Amlogic A1 SPI Flash Controller") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251124015852.937-1-vulab@iscas.ac.cn Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-amlogic-spifc-a1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-amlogic-spifc-a1.c b/drivers/spi/spi-amlogic-spifc-a1.c index fadf6667cd51..b430bca4f8bc 100644 --- a/drivers/spi/spi-amlogic-spifc-a1.c +++ b/drivers/spi/spi-amlogic-spifc-a1.c @@ -349,7 +349,9 @@ static int amlogic_spifc_a1_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(spifc->dev, 500); pm_runtime_use_autosuspend(spifc->dev); - devm_pm_runtime_enable(spifc->dev); + ret = devm_pm_runtime_enable(spifc->dev); + if (ret) + return ret; ctrl->num_chipselect = 1; ctrl->dev.of_node = pdev->dev.of_node; -- Gitee From 298f6d3540f58a6decb4d139ffa218e3c671b55d Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 26 Sep 2024 22:19:52 +0800 Subject: [PATCH 0111/1449] spi: spi-mem: Allow specifying the byte order in Octal DTR mode ANBZ: #35228 commit 94b3c7558748672bea30c4e5d2fa0c36ee34647a stable. commit 030ace430afcf847f537227afceb22dfe8fb8fc8 upstream. There are NOR flashes (Macronix) that swap the bytes on a 16-bit boundary when configured in Octal DTR mode. The byte order of 16-bit words is swapped when read or written in Octal Double Transfer Rate (DTR) mode compared to Single Transfer Rate (STR) modes. If one writes D0 D1 D2 D3 bytes using 1-1-1 mode, and uses 8D-8D-8D SPI mode for reading, it will read back D1 D0 D3 D2. Swapping the bytes may introduce some endianness problems. It can affect the boot sequence if the entire boot sequence is not handled in either 8D-8D-8D mode or 1-1-1 mode. Therefore, it is necessary to swap the bytes back to ensure the same byte order as in STR modes. Fortunately there are controllers that could swap the bytes back at runtime, addressing the flash's endianness requirements. Provide a way for the upper layers to specify the byte order in Octal DTR mode. Merge Tudor's patch and add modifications for suiting newer version of Linux kernel. Suggested-by: Michael Walle Signed-off-by: JaimeLiao Signed-off-by: AlvinZhou Acked-by: Mark Brown Link: https://lore.kernel.org/r/20240926141956.2386374-3-alvinzhou.tw@gmail.com Signed-off-by: Tudor Ambarus Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-mem.c | 3 +++ include/linux/spi/spi-mem.h | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index edd7430d4c05..84b250703e13 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -172,6 +172,9 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, if (!spi_mem_controller_is_capable(ctlr, dtr)) return false; + if (op->data.swap16 && !spi_mem_controller_is_capable(ctlr, swap16)) + return false; + if (op->cmd.nbytes != 2) return false; } else { diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 6b0a7dc48a4b..eed6e016d69c 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -90,6 +90,8 @@ enum spi_mem_data_dir { * @data.buswidth: number of IO lanes used to send/receive the data * @data.dtr: whether the data should be sent in DTR mode or not * @data.ecc: whether error correction is required or not + * @data.swap16: whether the byte order of 16-bit words is swapped when read + * or written in Octal DTR mode compared to STR mode. * @data.dir: direction of the transfer * @data.nbytes: number of data bytes to send/receive. Can be zero if the * operation does not involve transferring data @@ -124,7 +126,8 @@ struct spi_mem_op { u8 buswidth; u8 dtr : 1; u8 ecc : 1; - u8 __pad : 6; + u8 swap16 : 1; + u8 __pad : 5; enum spi_mem_data_dir dir; unsigned int nbytes; union { @@ -295,10 +298,13 @@ struct spi_controller_mem_ops { * struct spi_controller_mem_caps - SPI memory controller capabilities * @dtr: Supports DTR operations * @ecc: Supports operations with error correction + * @swap16: Supports swapping bytes on a 16 bit boundary when configured in + * Octal DTR */ struct spi_controller_mem_caps { bool dtr; bool ecc; + bool swap16; }; #define spi_mem_controller_is_capable(ctlr, cap) \ -- Gitee From 84fd166e8ec1f74999e97c28879ba0f2dee18a00 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 25 Dec 2024 01:05:46 +0800 Subject: [PATCH 0112/1449] spi: spi-mem: Extend spi-mem operations with a per-operation maximum frequency ANBZ: #35228 commit f1ea0e8b4a154f28642fa402c5ae5db1b47e71ba stable. commit 0fefeade90e74bc8f40ab0e460f483565c492e28 upstream. In the spi subsystem, the bus frequency is derived as follows: - the controller may expose a minimum and maximum operating frequency - the hardware description, through the spi peripheral properties, advise what is the maximum acceptable frequency from a device/wiring point of view. Transfers must be observed at a frequency which fits both (so in practice, the lowest maximum). Actually, this second point mixes two information and already takes the lowest frequency among: - what the spi device is capable of (what is written in the component datasheet) - what the wiring allows (electromagnetic sensibility, crossovers, terminations, antenna effect, etc). This logic works until spi devices are no longer capable of sustaining their highest frequency regardless of the operation. Spi memories are typically subject to such variation. Some devices are capable of spitting their internally stored data (essentially in read mode) at a very fast rate, typically up to 166MHz on Winbond SPI-NAND chips, using "fast" commands. However, some of the low-end operations, such as regular page read-from-cache commands, are more limited and can only be executed at 54MHz at most. This is currently a problem in the SPI-NAND subsystem. Another situation, even if not yet supported, will be with DTR commands, when the data is latched on both edges of the clock. The same chips as mentioned previously are in this case limited to 80MHz. Yet another example might be continuous reads, which, under certain circumstances, can also run at most at 104 or 120MHz. As a matter of fact, the "one frequency per chip" policy is outdated and more fine grain configuration is needed: we need to allow per-operation frequency limitations. So far, all datasheets I encountered advertise a maximum default frequency, which need to be lowered for certain specific operations. So based on the current infrastructure, we can still expect firmware (device trees in general) to continued advertising the same maximum speed which is a mix between the PCB limitations and the chip maximum capability, and expect per-operation lower frequencies when this is relevant. Add a `struct spi_mem_op` member to carry this information. Not providing this field explicitly from upper layers means that there is no further constraint and the default spi device maximum speed will be carried instead. The SPI_MEM_OP() macro is also expanded with an optional frequency argument, because virtually all operations can be subject to such a limitation, and this will allow for a smooth and discrete transition. For controller drivers which do not implement the spi-mem interface, the per-transfer speed is also set acordingly to a lower (than the maximum default) speed when relevant. Acked-by: Pratyush Yadav Signed-off-by: Miquel Raynal Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-1-ad218dbc406f@bootlin.com Signed-off-by: Mark Brown Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/nand/spi/core.c | 2 ++ drivers/spi/spi-mem.c | 28 ++++++++++++++++++++++++++++ include/linux/spi/spi-mem.h | 12 +++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index ee61b2d88232..4c2776f52fee 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1044,6 +1044,8 @@ spinand_select_op_variant(struct spinand_device *spinand, if (ret) break; + spi_mem_adjust_op_freq(spinand->spimem, &op); + if (!spi_mem_supports_op(spinand->spimem, &op)) break; diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 84b250703e13..b73a659e268d 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -187,6 +187,10 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, return false; } + if (op->max_freq && mem->spi->controller->min_speed_hz && + op->max_freq < mem->spi->controller->min_speed_hz) + return false; + return spi_mem_check_buswidth(mem, op); } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); @@ -321,6 +325,9 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) u8 *tmpbuf; int ret; + /* Make sure the operation frequency is correct before going futher */ + spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op); + ret = spi_mem_check_op(op); if (ret) return ret; @@ -363,6 +370,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].tx_buf = tmpbuf; xfers[xferpos].len = op->cmd.nbytes; xfers[xferpos].tx_nbits = op->cmd.buswidth; + xfers[xferpos].speed_hz = op->max_freq; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen++; @@ -377,6 +385,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].tx_buf = tmpbuf + 1; xfers[xferpos].len = op->addr.nbytes; xfers[xferpos].tx_nbits = op->addr.buswidth; + xfers[xferpos].speed_hz = op->max_freq; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen += op->addr.nbytes; @@ -388,6 +397,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].len = op->dummy.nbytes; xfers[xferpos].tx_nbits = op->dummy.buswidth; xfers[xferpos].dummy_data = 1; + xfers[xferpos].speed_hz = op->max_freq; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen += op->dummy.nbytes; @@ -403,6 +413,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) } xfers[xferpos].len = op->data.nbytes; + xfers[xferpos].speed_hz = op->max_freq; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen += op->data.nbytes; @@ -481,6 +492,23 @@ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); +/** + * spi_mem_adjust_op_freq() - Adjust the frequency of a SPI mem operation to + * match controller, PCB and chip limitations + * @mem: the SPI memory + * @op: the operation to adjust + * + * Some chips have per-op frequency limitations and must adapt the maximum + * speed. This function allows SPI mem drivers to set @op->max_freq to the + * maximum supported value. + */ +void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op) +{ + if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz) + op->max_freq = mem->spi->max_speed_hz; +} +EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq); + static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf) { diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index eed6e016d69c..cceebf8c78ba 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -68,6 +68,9 @@ enum spi_mem_data_dir { SPI_MEM_DATA_OUT, }; +#define SPI_MEM_OP_MAX_FREQ(__freq) \ + .max_freq = __freq + /** * struct spi_mem_op - describes a SPI memory operation * @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is @@ -97,6 +100,9 @@ enum spi_mem_data_dir { * operation does not involve transferring data * @data.buf.in: input buffer (must be DMA-able) * @data.buf.out: output buffer (must be DMA-able) + * @max_freq: frequency limitation wrt this operation. 0 means there is no + * specific constraint and the highest achievable frequency can be + * attempted. */ struct spi_mem_op { struct { @@ -135,14 +141,17 @@ struct spi_mem_op { const void *out; } buf; } data; + + unsigned int max_freq; }; -#define SPI_MEM_OP(__cmd, __addr, __dummy, __data) \ +#define SPI_MEM_OP(__cmd, __addr, __dummy, __data, ...) \ { \ .cmd = __cmd, \ .addr = __addr, \ .dummy = __dummy, \ .data = __data, \ + __VA_ARGS__ \ } /** @@ -369,6 +378,7 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, #endif /* CONFIG_SPI_MEM */ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); +void spi_mem_adjust_op_freq(struct spi_mem *mem, struct spi_mem_op *op); bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op); -- Gitee From bbb6dd7df3793a9d508a759307426355a484210c Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 25 Dec 2024 01:05:47 +0800 Subject: [PATCH 0113/1449] spi: spi-mem: Add a new controller capability ANBZ: #35228 commit a25cc746f7d0dc6b6211b0f73defba7be7c90f3e stable. commit 1248c9b8d54120950fda10fbeb98fb8932b4d45c upstream. There are spi devices with multiple frequency limitations depending on the invoked command. We probably do not want to afford running at the lowest supported frequency all the time, so if we want to get the most of our hardware, we need to allow per-operation frequency limitations. Among all the SPI memory controllers, I believe all are capable of changing the spi frequency on the fly. Some of the drivers do not make any frequency setup though. And some others will derive a per chip prescaler value which will be used forever. Actually changing the frequency on the fly is something new in Linux, so we need to carefully flag the drivers which do and do not support it. A controller capability is created for that, and the presence for this capability will always be checked before accepting such pattern. Signed-off-by: Miquel Raynal Reviewed-by: Tudor Ambarus Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-2-ad218dbc406f@bootlin.com Signed-off-by: Mark Brown Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-mem.c | 6 ++++++ include/linux/spi/spi-mem.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index b73a659e268d..c581aa5fbf7c 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -191,6 +191,12 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, op->max_freq < mem->spi->controller->min_speed_hz) return false; + if (op->max_freq && + op->max_freq < mem->spi->max_speed_hz) { + if (!spi_mem_controller_is_capable(ctlr, per_op_freq)) + return false; + } + return spi_mem_check_buswidth(mem, op); } EXPORT_SYMBOL_GPL(spi_mem_default_supports_op); diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index cceebf8c78ba..6bd0b548bd1e 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -309,11 +309,13 @@ struct spi_controller_mem_ops { * @ecc: Supports operations with error correction * @swap16: Supports swapping bytes on a 16 bit boundary when configured in * Octal DTR + * @per_op_freq: Supports per operation frequency switching */ struct spi_controller_mem_caps { bool dtr; bool ecc; bool swap16; + bool per_op_freq; }; #define spi_mem_controller_is_capable(ctlr, cap) \ -- Gitee From 4c6f24832912aa8611389902e2e39a98bd1b6265 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 25 Dec 2024 01:05:57 +0800 Subject: [PATCH 0114/1449] spi: nxp-fspi: Support per spi-mem operation frequency switches ANBZ: #35228 commit 5fc6f8175b8bb37a15d776f3615210e77dc20d07 stable. commit 26851cf65ffca2d3a8d529a125e54cf0084d69e7 upstream. Every ->exec_op() call correctly configures the spi bus speed to the maximum allowed frequency for the memory using the constant spi default parameter. Since we can now have per-operation constraints, let's use the value that comes from the spi-mem operation structure instead. In case there is no specific limitation for this operation, the default spi device value will be given anyway. The per-operation frequency capability is thus advertised to the spi-mem core. Cc: AngeloGioacchino Del Regno Signed-off-by: Miquel Raynal Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-12-ad218dbc406f@bootlin.com Signed-off-by: Mark Brown Stable-dep-of: 40ad64ac25bb ("spi: nxp-fspi: Propagate fwnode in ACPI case as well") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-nxp-fspi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c index 731504ec7ef8..5d631f8c593e 100644 --- a/drivers/spi/spi-nxp-fspi.c +++ b/drivers/spi/spi-nxp-fspi.c @@ -711,9 +711,10 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f) * Value for rest of the CS FLSHxxCR0 register would be zero. * */ -static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi) +static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, + const struct spi_mem_op *op) { - unsigned long rate = spi->max_speed_hz; + unsigned long rate = op->max_freq; int ret; uint64_t size_kb; @@ -938,7 +939,7 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true); WARN_ON(err); - nxp_fspi_select_mem(f, mem->spi); + nxp_fspi_select_mem(f, mem->spi, op); nxp_fspi_prepare_lut(f, op); /* @@ -1156,6 +1157,10 @@ static const struct spi_controller_mem_ops nxp_fspi_mem_ops = { .get_name = nxp_fspi_get_name, }; +static const struct spi_controller_mem_caps nxp_fspi_mem_caps = { + .per_op_freq = true, +}; + static int nxp_fspi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; @@ -1253,6 +1258,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) ctlr->bus_num = -1; ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT; ctlr->mem_ops = &nxp_fspi_mem_ops; + ctlr->mem_caps = &nxp_fspi_mem_caps; nxp_fspi_default_setup(f); -- Gitee From a6af2437396223c96c844dadb6237d6c6ec56c9e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 27 Nov 2025 04:25:01 +0800 Subject: [PATCH 0115/1449] spi: nxp-fspi: Propagate fwnode in ACPI case as well ANBZ: #35228 commit 01511983d7b8571bc4581f108bd2640022a2845d stable. commit 40ad64ac25bb736740f895d99a4aebbda9b80991 upstream. Propagate fwnode of the ACPI device to the SPI controller Linux device. Currently only OF case propagates fwnode to the controller. While at it, replace several calls to dev_fwnode() with a single one cached in a local variable, and unify checks for fwnode type by using is_*_node() APIs. Fixes: 55ab8487e01d ("spi: spi-nxp-fspi: Add ACPI support") Signed-off-by: Andy Shevchenko Reviewed-by: Haibo Chen Link: https://patch.msgid.link/20251126202501.2319679-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-nxp-fspi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c index 5d631f8c593e..ce110035a359 100644 --- a/drivers/spi/spi-nxp-fspi.c +++ b/drivers/spi/spi-nxp-fspi.c @@ -1165,7 +1165,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; + struct fwnode_handle *fwnode = dev_fwnode(dev); struct resource *res; struct nxp_fspi *f; int ret; @@ -1189,7 +1189,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, f); /* find the resources - configuration register address space */ - if (is_acpi_node(dev_fwnode(f->dev))) + if (is_acpi_node(fwnode)) f->iobase = devm_platform_ioremap_resource(pdev, 0); else f->iobase = devm_platform_ioremap_resource_byname(pdev, "fspi_base"); @@ -1200,7 +1200,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) } /* find the resources - controller memory mapped space */ - if (is_acpi_node(dev_fwnode(f->dev))) + if (is_acpi_node(fwnode)) res = platform_get_resource(pdev, IORESOURCE_MEM, 1); else res = platform_get_resource_byname(pdev, @@ -1216,7 +1216,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) f->memmap_phy_size = resource_size(res); /* find the clocks */ - if (dev_of_node(&pdev->dev)) { + if (is_of_node(fwnode)) { f->clk_en = devm_clk_get(dev, "fspi_en"); if (IS_ERR(f->clk_en)) { ret = PTR_ERR(f->clk_en); @@ -1262,7 +1262,7 @@ static int nxp_fspi_probe(struct platform_device *pdev) nxp_fspi_default_setup(f); - ctlr->dev.of_node = np; + device_set_node(&ctlr->dev, fwnode); ret = devm_spi_register_controller(&pdev->dev, ctlr); if (ret) -- Gitee From 063b19f79e944d00ee6f13512c7eee621cf361a7 Mon Sep 17 00:00:00 2001 From: Hang Zhou <929513338@qq.com> Date: Sun, 16 Nov 2025 22:08:35 +0800 Subject: [PATCH 0116/1449] spi: bcm63xx: fix premature CS deassertion on RX-only transactions ANBZ: #35228 commit c538dae04a4c958fb304d14e92a3b4f674de9af9 stable. commit fd9862f726aedbc2f29a29916cabed7bcf5cadb6 upstream. On BCM6358 (and also observed on BCM6368) the controller appears to only generate as many SPI clocks as bytes that have been written into the TX FIFO. For RX-only transfers the driver programs the transfer length in SPI_MSG_CTL but does not write anything into the FIFO, so chip select is deasserted early and the RX transfer segment is never fully clocked in. A concrete failing case is a three-transfer MAC address read from SPI-NOR: - TX 0x03 (read command) - TX 3-byte address - RX 6 bytes (MAC) In contrast, a two-transfer JEDEC-ID read (0x9f + 6-byte RX) works because the driver uses prepend_len and writes dummy bytes into the TX FIFO for the RX part. Fix this by writing 0xff dummy bytes into the TX FIFO for RX-only segments so that the number of bytes written to the FIFO matches the total message length seen by the controller. Fixes: b17de076062a ("spi/bcm63xx: work around inability to keep CS up") Signed-off-by: Hang Zhou <929513338@qq.com> Link: https://patch.msgid.link/tencent_7AC88FCB3076489A4A7E6C2163DF1ACF8D06@qq.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-bcm63xx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index a95badb7b711..ba66fe9f1f54 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -247,6 +247,20 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, if (t->rx_buf) { do_rx = true; + + /* + * In certain hardware implementations, there appears to be a + * hidden accumulator that tracks the number of bytes written into + * the hardware FIFO, and this accumulator overrides the length in + * the SPI_MSG_CTL register. + * + * Therefore, for read-only transfers, we need to write some dummy + * value into the FIFO to keep the accumulator tracking the correct + * length. + */ + if (!t->tx_buf) + memset_io(bs->tx_io + len, 0xFF, t->len); + /* prepend is half-duplex write only */ if (t == first) prepend_len = 0; -- Gitee From 6b49375963f770a1396b4f12e86b3f989d58446d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 5 Nov 2025 05:54:02 +0800 Subject: [PATCH 0117/1449] Revert "perf/x86: Always store regs->ip in perf_callchain_kernel()" ANBZ: #35228 commit d59a7824444e72488aac619d90f361b71ca7d151 stable. commit 6d08340d1e354787d6c65a8c3cdd4d41ffb8a5ed upstream. This reverts commit 83f44ae0f8afcc9da659799db8693f74847e66b3. Currently we store initial stacktrace entry twice for non-HW ot_regs, which means callers that fail perf_hw_regs(regs) condition in perf_callchain_kernel. It's easy to reproduce this bpftrace: # bpftrace -e 'tracepoint:sched:sched_process_exec { print(kstack()); }' Attaching 1 probe... bprm_execve+1767 bprm_execve+1767 do_execveat_common.isra.0+425 __x64_sys_execve+56 do_syscall_64+133 entry_SYSCALL_64_after_hwframe+118 When perf_callchain_kernel calls unwind_start with first_frame, AFAICS we do not skip regs->ip, but it's added as part of the unwind process. Hence reverting the extra perf_callchain_store for non-hw regs leg. I was not able to bisect this, so I'm not really sure why this was needed in v5.2 and why it's not working anymore, but I could see double entries as far as v5.10. I did the test for both ORC and framepointer unwind with and without the this fix and except for the initial entry the stacktraces are the same. Acked-by: Song Liu Signed-off-by: Jiri Olsa Link: https://lore.kernel.org/r/20251104215405.168643-2-jolsa@kernel.org Signed-off-by: Alexei Starovoitov Acked-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/events/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index db2f39578097..ecac36678bc8 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2804,13 +2804,13 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re return; } - if (perf_callchain_store(entry, regs->ip)) - return; - - if (perf_hw_regs(regs)) + if (perf_hw_regs(regs)) { + if (perf_callchain_store(entry, regs->ip)) + return; unwind_start(&state, current, regs, NULL); - else + } else { unwind_start(&state, current, NULL, (void *)regs->sp); + } for (; !unwind_done(&state); unwind_next_frame(&state)) { addr = unwind_get_return_address(&state); -- Gitee From f2dd635a82bbb09629b2bfea57a5f77807116b1e Mon Sep 17 00:00:00 2001 From: Francesco Lavra Date: Sat, 18 Oct 2025 01:32:08 +0800 Subject: [PATCH 0118/1449] iio: imu: st_lsm6dsx: fix array size for st_lsm6dsx_settings fields ANBZ: #35228 commit 936e082a7c079d06a8a7682ee89d3020da95a722 stable. commit 3af0c1fb1cdc351b64ff1a4bc06d491490c1f10a upstream. The `decimator` and `batch` fields of struct st_lsm6dsx_settings are arrays indexed by sensor type, not by sensor hardware identifier; moreover, the `batch` field is only used for the accelerometer and gyroscope. Change the array size for `decimator` from ST_LSM6DSX_MAX_ID to ST_LSM6DSX_ID_MAX, and change the array size for `batch` from ST_LSM6DSX_MAX_ID to 2; move the enum st_lsm6dsx_sensor_id definition so that the ST_LSM6DSX_ID_MAX value is usable within the struct st_lsm6dsx_settings definition. Fixes: 801a6e0af0c6c ("iio: imu: st_lsm6dsx: add support to LSM6DSO") Signed-off-by: Francesco Lavra Acked-by: Lorenzo Bianconi Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 0f347684f6fc..35325d2e1ce6 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -268,6 +268,15 @@ struct st_lsm6dsx_event_settings { u8 wakeup_src_x_mask; }; +enum st_lsm6dsx_sensor_id { + ST_LSM6DSX_ID_GYRO, + ST_LSM6DSX_ID_ACC, + ST_LSM6DSX_ID_EXT0, + ST_LSM6DSX_ID_EXT1, + ST_LSM6DSX_ID_EXT2, + ST_LSM6DSX_ID_MAX +}; + enum st_lsm6dsx_ext_sensor_id { ST_LSM6DSX_ID_MAGN, }; @@ -353,23 +362,14 @@ struct st_lsm6dsx_settings { struct st_lsm6dsx_odr_table_entry odr_table[2]; struct st_lsm6dsx_samples_to_discard samples_to_discard[2]; struct st_lsm6dsx_fs_table_entry fs_table[2]; - struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; - struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; + struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX]; + struct st_lsm6dsx_reg batch[2]; struct st_lsm6dsx_fifo_ops fifo_ops; struct st_lsm6dsx_hw_ts_settings ts_settings; struct st_lsm6dsx_shub_settings shub_settings; struct st_lsm6dsx_event_settings event_settings; }; -enum st_lsm6dsx_sensor_id { - ST_LSM6DSX_ID_GYRO, - ST_LSM6DSX_ID_ACC, - ST_LSM6DSX_ID_EXT0, - ST_LSM6DSX_ID_EXT1, - ST_LSM6DSX_ID_EXT2, - ST_LSM6DSX_ID_MAX, -}; - enum st_lsm6dsx_fifo_mode { ST_LSM6DSX_FIFO_BYPASS = 0x0, ST_LSM6DSX_FIFO_CONT = 0x6, -- Gitee From ebdef26ad77e38458a07d7fc91c5984421975cc3 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 11 Oct 2025 02:58:48 +0800 Subject: [PATCH 0119/1449] iio:common:ssp_sensors: Fix an error handling path ssp_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit a8f6a8256a68671ca18df78d0d446d68752850ea stable. commit 21553258b94861a73d7f2cf15469d69240e1170d upstream. If an error occurs after a successful mfd_add_devices() call, it should be undone by a corresponding mfd_remove_devices() call, as already done in the remove function. Fixes: 50dd64d57eee ("iio: common: ssp_sensors: Add sensorhub driver") Signed-off-by: Christophe JAILLET Reviewed-by: Nuno Sá Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/common/ssp_sensors/ssp_dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c index e64d242145e0..0c6629da2112 100644 --- a/drivers/iio/common/ssp_sensors/ssp_dev.c +++ b/drivers/iio/common/ssp_sensors/ssp_dev.c @@ -503,7 +503,7 @@ static int ssp_probe(struct spi_device *spi) ret = spi_setup(spi); if (ret < 0) { dev_err(&spi->dev, "Failed to setup spi\n"); - return ret; + goto err_setup_spi; } data->fw_dl_state = SSP_FW_DL_STATE_NONE; @@ -568,6 +568,8 @@ static int ssp_probe(struct spi_device *spi) err_setup_irq: mutex_destroy(&data->pending_lock); mutex_destroy(&data->comm_lock); +err_setup_spi: + mfd_remove_devices(&spi->dev); dev_err(&spi->dev, "Probe failed!\n"); -- Gitee From bf6fce969c2eed5f94643922c8647e33b07fd512 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 3 Nov 2025 17:36:18 +0800 Subject: [PATCH 0120/1449] iio: accel: bmc150: Fix irq assumption regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit cdd4a9e98004bd7c7488311951fa6dbae38b2b80 stable. commit 3aa385a9c75c09b59dcab2ff76423439d23673ab upstream. The code in bmc150-accel-core.c unconditionally calls bmc150_accel_set_interrupt() in the iio_buffer_setup_ops, such as on the runtime PM resume path giving a kernel splat like this if the device has no interrupts: Unable to handle kernel NULL pointer dereference at virtual address 00000001 when read PC is at bmc150_accel_set_interrupt+0x98/0x194 LR is at __pm_runtime_resume+0x5c/0x64 (...) Call trace: bmc150_accel_set_interrupt from bmc150_accel_buffer_postenable+0x40/0x108 bmc150_accel_buffer_postenable from __iio_update_buffers+0xbe0/0xcbc __iio_update_buffers from enable_store+0x84/0xc8 enable_store from kernfs_fop_write_iter+0x154/0x1b4 This bug seems to have been in the driver since the beginning, but it only manifests recently, I do not know why. Store the IRQ number in the state struct, as this is a common pattern in other drivers, then use this to determine if we have IRQ support or not. Cc: stable@vger.kernel.org Signed-off-by: Linus Walleij Reviewed-by: Andy Shevchenko Reviewed-by: Nuno Sá Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/accel/bmc150-accel-core.c | 5 +++++ drivers/iio/accel/bmc150-accel.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 110591804b4c..9bc5957123c5 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -569,6 +569,10 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i, const struct bmc150_accel_interrupt_info *info = intr->info; int ret; + /* We do not always have an IRQ */ + if (data->irq <= 0) + return 0; + if (state) { if (atomic_inc_return(&intr->users) > 1) return 0; @@ -1743,6 +1747,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, } if (irq > 0) { + data->irq = irq; ret = devm_request_threaded_irq(dev, irq, bmc150_accel_irq_handler, bmc150_accel_irq_thread_handler, diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h index 7775c5edaeef..f8d9c8ae4693 100644 --- a/drivers/iio/accel/bmc150-accel.h +++ b/drivers/iio/accel/bmc150-accel.h @@ -57,6 +57,7 @@ enum bmc150_accel_trigger_id { struct bmc150_accel_data { struct regmap *regmap; + int irq; struct regulator_bulk_data regulators[2]; struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS]; struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS]; -- Gitee From feb0761e50c40d8a257d3bcd9ee00f31f0e3a047 Mon Sep 17 00:00:00 2001 From: Valek Andrej Date: Tue, 14 Oct 2025 15:13:44 +0800 Subject: [PATCH 0121/1449] iio: accel: fix ADXL355 startup race condition ANBZ: #35228 commit a9fa254af33acfb54e99ba7a4edafc8cdad70cf2 stable. commit c92c1bc408e9e11ae3c7011b062fdd74c09283a3 upstream. There is an race-condition where device is not full working after SW reset. Therefore it's necessary to wait some time after reset and verify shadow registers values by reading and comparing the values before/after reset. This mechanism is described in datasheet at least from revision D. Fixes: 12ed27863ea3 ("iio: accel: Add driver support for ADXL355") Signed-off-by: Valek Andrej Signed-off-by: Kessler Markus Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/accel/adxl355_core.c | 44 ++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index 4973e8da5399..93b8bd6f929d 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -56,6 +56,8 @@ #define ADXL355_POWER_CTL_DRDY_MSK BIT(2) #define ADXL355_SELF_TEST_REG 0x2E #define ADXL355_RESET_REG 0x2F +#define ADXL355_BASE_ADDR_SHADOW_REG 0x50 +#define ADXL355_SHADOW_REG_COUNT 5 #define ADXL355_DEVID_AD_VAL 0xAD #define ADXL355_DEVID_MST_VAL 0x1D @@ -294,7 +296,12 @@ static void adxl355_fill_3db_frequency_table(struct adxl355_data *data) static int adxl355_setup(struct adxl355_data *data) { unsigned int regval; + int retries = 5; /* the number is chosen based on empirical reasons */ int ret; + u8 *shadow_regs __free(kfree) = kzalloc(ADXL355_SHADOW_REG_COUNT, GFP_KERNEL); + + if (!shadow_regs) + return -ENOMEM; ret = regmap_read(data->regmap, ADXL355_DEVID_AD_REG, ®val); if (ret) @@ -321,14 +328,41 @@ static int adxl355_setup(struct adxl355_data *data) if (regval != ADXL355_PARTID_VAL) dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval); - /* - * Perform a software reset to make sure the device is in a consistent - * state after start-up. - */ - ret = regmap_write(data->regmap, ADXL355_RESET_REG, ADXL355_RESET_CODE); + /* Read shadow registers to be compared after reset */ + ret = regmap_bulk_read(data->regmap, + ADXL355_BASE_ADDR_SHADOW_REG, + shadow_regs, ADXL355_SHADOW_REG_COUNT); if (ret) return ret; + do { + if (--retries == 0) { + dev_err(data->dev, "Shadow registers mismatch\n"); + return -EIO; + } + + /* + * Perform a software reset to make sure the device is in a consistent + * state after start-up. + */ + ret = regmap_write(data->regmap, ADXL355_RESET_REG, + ADXL355_RESET_CODE); + if (ret) + return ret; + + /* Wait at least 5ms after software reset */ + usleep_range(5000, 10000); + + /* Read shadow registers for comparison */ + ret = regmap_bulk_read(data->regmap, + ADXL355_BASE_ADDR_SHADOW_REG, + data->buffer.buf, + ADXL355_SHADOW_REG_COUNT); + if (ret) + return ret; + } while (memcmp(shadow_regs, data->buffer.buf, + ADXL355_SHADOW_REG_COUNT)); + ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG, ADXL355_POWER_CTL_DRDY_MSK, FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 1)); -- Gitee From 1720ec65f1660445d6f9cea4e5024eed47bb38a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BChlbacher?= Date: Sat, 15 Nov 2025 23:34:56 +0800 Subject: [PATCH 0122/1449] can: sja1000: fix max irq loop handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit c952664fd54f1a9b7b0995510195daa262842839 stable. commit 30db4451c7f6aabcada029b15859a76962ec0cf8 upstream. Reading the interrupt register `SJA1000_IR` causes all of its bits to be reset. If we ever reach the condition of handling more than `SJA1000_MAX_IRQ` IRQs, we will have read the register and reset all its bits but without actually handling the interrupt inside of the loop body. This may, among other issues, cause us to never `netif_wake_queue()` again after a transmission interrupt. Fixes: 429da1cc841b ("can: Driver for the SJA1000 CAN controller") Cc: stable@vger.kernel.org Signed-off-by: Thomas Mühlbacher Acked-by: Oliver Hartkopp Link: https://patch.msgid.link/20251115153437.11419-1-tmuehlbacher@posteo.net Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/sja1000/sja1000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 10e211d917e3..0a328885729e 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -548,8 +548,8 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF) goto out; - while ((isrc = priv->read_reg(priv, SJA1000_IR)) && - (n < SJA1000_MAX_IRQ)) { + while ((n < SJA1000_MAX_IRQ) && + (isrc = priv->read_reg(priv, SJA1000_IR))) { status = priv->read_reg(priv, SJA1000_SR); /* check for absent controller due to hw unplug */ -- Gitee From bc8df5c11fea8c1f7eccb885f67a7761164d087c Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 16 Nov 2025 23:55:26 +0800 Subject: [PATCH 0123/1449] can: sun4i_can: sun4i_can_interrupt(): fix max irq loop handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 61089dd37ccd9b2a7f8552e59f887dcaadc8bad6 stable. commit 76544beea7cfe5bcce6d60f53811657b88ec8be1 upstream. Reading the interrupt register `SUN4I_REG_INT_ADDR` causes all of its bits to be reset. If we ever reach the condition of handling more than `SUN4I_CAN_MAX_IRQ` IRQs, we will have read the register and reset all its bits but without actually handling the interrupt inside of the loop body. This may, among other issues, cause us to never `netif_wake_queue()` again after a transmission interrupt. Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module") Cc: stable@vger.kernel.org Co-developed-by: Thomas Mühlbacher Signed-off-by: Thomas Mühlbacher Acked-by: Jernej Skrabec Link: https://patch.msgid.link/20251116-sun4i-fix-loop-v1-1-3d76d3f81950@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/sun4i_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c index 5ab1f9c7288e..c7b82de8447a 100644 --- a/drivers/net/can/sun4i_can.c +++ b/drivers/net/can/sun4i_can.c @@ -657,8 +657,8 @@ static irqreturn_t sun4i_can_interrupt(int irq, void *dev_id) u8 isrc, status; int n = 0; - while ((isrc = readl(priv->base + SUN4I_REG_INT_ADDR)) && - (n < SUN4I_CAN_MAX_IRQ)) { + while ((n < SUN4I_CAN_MAX_IRQ) && + (isrc = readl(priv->base + SUN4I_REG_INT_ADDR))) { n++; status = readl(priv->base + SUN4I_REG_STA_ADDR); -- Gitee From 64e5e8c093a27c1b9dc95bd7775dabd20eb6f041 Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Fri, 14 Nov 2025 06:36:24 +0800 Subject: [PATCH 0124/1449] ceph: fix crash in process_v2_sparse_read() for encrypted directories ANBZ: #35228 commit 5a3f3e39b18705bc578fae58abacc8ef93c15194 stable. commit 43962db4a6f593903340c85591056a0cef812dfd upstream. The crash in process_v2_sparse_read() for fscrypt-encrypted directories has been reported. Issue takes place for Ceph msgr2 protocol in secure mode. It can be reproduced by the steps: sudo mount -t ceph :/ /mnt/cephfs/ -o name=admin,fs=cephfs,ms_mode=secure (1) mkdir /mnt/cephfs/fscrypt-test-3 (2) cp area_decrypted.tar /mnt/cephfs/fscrypt-test-3 (3) fscrypt encrypt --source=raw_key --key=./my.key /mnt/cephfs/fscrypt-test-3 (4) fscrypt lock /mnt/cephfs/fscrypt-test-3 (5) fscrypt unlock --key=my.key /mnt/cephfs/fscrypt-test-3 (6) cat /mnt/cephfs/fscrypt-test-3/area_decrypted.tar (7) Issue has been triggered [ 408.072247] ------------[ cut here ]------------ [ 408.072251] WARNING: CPU: 1 PID: 392 at net/ceph/messenger_v2.c:865 ceph_con_v2_try_read+0x4b39/0x72f0 [ 408.072267] Modules linked in: intel_rapl_msr intel_rapl_common intel_uncore_frequency_common intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec kvm_intel joydev kvm irqbypass polyval_clmulni ghash_clmulni_intel aesni_intel rapl input_leds psmouse serio_raw i2c_piix4 vga16fb bochs vgastate i2c_smbus floppy mac_hid qemu_fw_cfg pata_acpi sch_fq_codel rbd msr parport_pc ppdev lp parport efi_pstore [ 408.072304] CPU: 1 UID: 0 PID: 392 Comm: kworker/1:3 Not tainted 6.17.0-rc7+ [ 408.072307] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-5.fc42 04/01/2014 [ 408.072310] Workqueue: ceph-msgr ceph_con_workfn [ 408.072314] RIP: 0010:ceph_con_v2_try_read+0x4b39/0x72f0 [ 408.072317] Code: c7 c1 20 f0 d4 ae 50 31 d2 48 c7 c6 60 27 d5 ae 48 c7 c7 f8 8e 6f b0 68 60 38 d5 ae e8 00 47 61 fe 48 83 c4 18 e9 ac fc ff ff <0f> 0b e9 06 fe ff ff 4c 8b 9d 98 fd ff ff 0f 84 64 e7 ff ff 89 85 [ 408.072319] RSP: 0018:ffff88811c3e7a30 EFLAGS: 00010246 [ 408.072322] RAX: ffffed1024874c6f RBX: ffffea00042c2b40 RCX: 0000000000000f38 [ 408.072324] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 408.072325] RBP: ffff88811c3e7ca8 R08: 0000000000000000 R09: 00000000000000c8 [ 408.072326] R10: 00000000000000c8 R11: 0000000000000000 R12: 00000000000000c8 [ 408.072327] R13: dffffc0000000000 R14: ffff8881243a6030 R15: 0000000000003000 [ 408.072329] FS: 0000000000000000(0000) GS:ffff88823eadf000(0000) knlGS:0000000000000000 [ 408.072331] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 408.072332] CR2: 000000c0003c6000 CR3: 000000010c106005 CR4: 0000000000772ef0 [ 408.072336] PKRU: 55555554 [ 408.072337] Call Trace: [ 408.072338] [ 408.072340] ? sched_clock_noinstr+0x9/0x10 [ 408.072344] ? __pfx_ceph_con_v2_try_read+0x10/0x10 [ 408.072347] ? _raw_spin_unlock+0xe/0x40 [ 408.072349] ? finish_task_switch.isra.0+0x15d/0x830 [ 408.072353] ? __kasan_check_write+0x14/0x30 [ 408.072357] ? mutex_lock+0x84/0xe0 [ 408.072359] ? __pfx_mutex_lock+0x10/0x10 [ 408.072361] ceph_con_workfn+0x27e/0x10e0 [ 408.072364] ? metric_delayed_work+0x311/0x2c50 [ 408.072367] process_one_work+0x611/0xe20 [ 408.072371] ? __kasan_check_write+0x14/0x30 [ 408.072373] worker_thread+0x7e3/0x1580 [ 408.072375] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 408.072378] ? __pfx_worker_thread+0x10/0x10 [ 408.072381] kthread+0x381/0x7a0 [ 408.072383] ? __pfx__raw_spin_lock_irq+0x10/0x10 [ 408.072385] ? __pfx_kthread+0x10/0x10 [ 408.072387] ? __kasan_check_write+0x14/0x30 [ 408.072389] ? recalc_sigpending+0x160/0x220 [ 408.072392] ? _raw_spin_unlock_irq+0xe/0x50 [ 408.072394] ? calculate_sigpending+0x78/0xb0 [ 408.072395] ? __pfx_kthread+0x10/0x10 [ 408.072397] ret_from_fork+0x2b6/0x380 [ 408.072400] ? __pfx_kthread+0x10/0x10 [ 408.072402] ret_from_fork_asm+0x1a/0x30 [ 408.072406] [ 408.072407] ---[ end trace 0000000000000000 ]--- [ 408.072418] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI [ 408.072984] KASAN: null-ptr-deref in range [0x0000000000000000- 0x0000000000000007] [ 408.073350] CPU: 1 UID: 0 PID: 392 Comm: kworker/1:3 Tainted: G W 6.17.0-rc7+ #1 PREEMPT(voluntary) [ 408.073886] Tainted: [W]=WARN [ 408.074042] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-5.fc42 04/01/2014 [ 408.074468] Workqueue: ceph-msgr ceph_con_workfn [ 408.074694] RIP: 0010:ceph_msg_data_advance+0x79/0x1a80 [ 408.074976] Code: fc ff df 49 8d 77 08 48 c1 ee 03 80 3c 16 00 0f 85 07 11 00 00 48 ba 00 00 00 00 00 fc ff df 49 8b 5f 08 48 89 de 48 c1 ee 03 <0f> b6 14 16 84 d2 74 09 80 fa 03 0f 8e 0f 0e 00 00 8b 13 83 fa 03 [ 408.075884] RSP: 0018:ffff88811c3e7990 EFLAGS: 00010246 [ 408.076305] RAX: ffff8881243a6388 RBX: 0000000000000000 RCX: 0000000000000000 [ 408.076909] RDX: dffffc0000000000 RSI: 0000000000000000 RDI: ffff8881243a6378 [ 408.077466] RBP: ffff88811c3e7a20 R08: 0000000000000000 R09: 00000000000000c8 [ 408.078034] R10: ffff8881243a6388 R11: 0000000000000000 R12: ffffed1024874c71 [ 408.078575] R13: dffffc0000000000 R14: ffff8881243a6030 R15: ffff8881243a6378 [ 408.079159] FS: 0000000000000000(0000) GS:ffff88823eadf000(0000) knlGS:0000000000000000 [ 408.079736] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 408.080039] CR2: 000000c0003c6000 CR3: 000000010c106005 CR4: 0000000000772ef0 [ 408.080376] PKRU: 55555554 [ 408.080513] Call Trace: [ 408.080630] [ 408.080729] ceph_con_v2_try_read+0x49b9/0x72f0 [ 408.081115] ? __pfx_ceph_con_v2_try_read+0x10/0x10 [ 408.081348] ? _raw_spin_unlock+0xe/0x40 [ 408.081538] ? finish_task_switch.isra.0+0x15d/0x830 [ 408.081768] ? __kasan_check_write+0x14/0x30 [ 408.081986] ? mutex_lock+0x84/0xe0 [ 408.082160] ? __pfx_mutex_lock+0x10/0x10 [ 408.082343] ceph_con_workfn+0x27e/0x10e0 [ 408.082529] ? metric_delayed_work+0x311/0x2c50 [ 408.082737] process_one_work+0x611/0xe20 [ 408.082948] ? __kasan_check_write+0x14/0x30 [ 408.083156] worker_thread+0x7e3/0x1580 [ 408.083331] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 408.083557] ? __pfx_worker_thread+0x10/0x10 [ 408.083751] kthread+0x381/0x7a0 [ 408.083922] ? __pfx__raw_spin_lock_irq+0x10/0x10 [ 408.084139] ? __pfx_kthread+0x10/0x10 [ 408.084310] ? __kasan_check_write+0x14/0x30 [ 408.084510] ? recalc_sigpending+0x160/0x220 [ 408.084708] ? _raw_spin_unlock_irq+0xe/0x50 [ 408.084917] ? calculate_sigpending+0x78/0xb0 [ 408.085138] ? __pfx_kthread+0x10/0x10 [ 408.085335] ret_from_fork+0x2b6/0x380 [ 408.085525] ? __pfx_kthread+0x10/0x10 [ 408.085720] ret_from_fork_asm+0x1a/0x30 [ 408.085922] [ 408.086036] Modules linked in: intel_rapl_msr intel_rapl_common intel_uncore_frequency_common intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec kvm_intel joydev kvm irqbypass polyval_clmulni ghash_clmulni_intel aesni_intel rapl input_leds psmouse serio_raw i2c_piix4 vga16fb bochs vgastate i2c_smbus floppy mac_hid qemu_fw_cfg pata_acpi sch_fq_codel rbd msr parport_pc ppdev lp parport efi_pstore [ 408.087778] ---[ end trace 0000000000000000 ]--- [ 408.088007] RIP: 0010:ceph_msg_data_advance+0x79/0x1a80 [ 408.088260] Code: fc ff df 49 8d 77 08 48 c1 ee 03 80 3c 16 00 0f 85 07 11 00 00 48 ba 00 00 00 00 00 fc ff df 49 8b 5f 08 48 89 de 48 c1 ee 03 <0f> b6 14 16 84 d2 74 09 80 fa 03 0f 8e 0f 0e 00 00 8b 13 83 fa 03 [ 408.089118] RSP: 0018:ffff88811c3e7990 EFLAGS: 00010246 [ 408.089357] RAX: ffff8881243a6388 RBX: 0000000000000000 RCX: 0000000000000000 [ 408.089678] RDX: dffffc0000000000 RSI: 0000000000000000 RDI: ffff8881243a6378 [ 408.090020] RBP: ffff88811c3e7a20 R08: 0000000000000000 R09: 00000000000000c8 [ 408.090360] R10: ffff8881243a6388 R11: 0000000000000000 R12: ffffed1024874c71 [ 408.090687] R13: dffffc0000000000 R14: ffff8881243a6030 R15: ffff8881243a6378 [ 408.091035] FS: 0000000000000000(0000) GS:ffff88823eadf000(0000) knlGS:0000000000000000 [ 408.091452] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 408.092015] CR2: 000000c0003c6000 CR3: 000000010c106005 CR4: 0000000000772ef0 [ 408.092530] PKRU: 55555554 [ 417.112915] ================================================================== [ 417.113491] BUG: KASAN: slab-use-after-free in __mutex_lock.constprop.0+0x1522/0x1610 [ 417.114014] Read of size 4 at addr ffff888124870034 by task kworker/2:0/4951 [ 417.114587] CPU: 2 UID: 0 PID: 4951 Comm: kworker/2:0 Tainted: G D W 6.17.0-rc7+ #1 PREEMPT(voluntary) [ 417.114592] Tainted: [D]=DIE, [W]=WARN [ 417.114593] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-5.fc42 04/01/2014 [ 417.114596] Workqueue: events handle_timeout [ 417.114601] Call Trace: [ 417.114602] [ 417.114604] dump_stack_lvl+0x5c/0x90 [ 417.114610] print_report+0x171/0x4dc [ 417.114613] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 417.114617] ? kasan_complete_mode_report_info+0x80/0x220 [ 417.114621] kasan_report+0xbd/0x100 [ 417.114625] ? __mutex_lock.constprop.0+0x1522/0x1610 [ 417.114628] ? __mutex_lock.constprop.0+0x1522/0x1610 [ 417.114630] __asan_report_load4_noabort+0x14/0x30 [ 417.114633] __mutex_lock.constprop.0+0x1522/0x1610 [ 417.114635] ? queue_con_delay+0x8d/0x200 [ 417.114638] ? __pfx___mutex_lock.constprop.0+0x10/0x10 [ 417.114641] ? __send_subscribe+0x529/0xb20 [ 417.114644] __mutex_lock_slowpath+0x13/0x20 [ 417.114646] mutex_lock+0xd4/0xe0 [ 417.114649] ? __pfx_mutex_lock+0x10/0x10 [ 417.114652] ? ceph_monc_renew_subs+0x2a/0x40 [ 417.114654] ceph_con_keepalive+0x22/0x110 [ 417.114656] handle_timeout+0x6b3/0x11d0 [ 417.114659] ? _raw_spin_unlock_irq+0xe/0x50 [ 417.114662] ? __pfx_handle_timeout+0x10/0x10 [ 417.114664] ? queue_delayed_work_on+0x8e/0xa0 [ 417.114669] process_one_work+0x611/0xe20 [ 417.114672] ? __kasan_check_write+0x14/0x30 [ 417.114676] worker_thread+0x7e3/0x1580 [ 417.114678] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 417.114682] ? __pfx_sched_setscheduler_nocheck+0x10/0x10 [ 417.114687] ? __pfx_worker_thread+0x10/0x10 [ 417.114689] kthread+0x381/0x7a0 [ 417.114692] ? __pfx__raw_spin_lock_irq+0x10/0x10 [ 417.114694] ? __pfx_kthread+0x10/0x10 [ 417.114697] ? __kasan_check_write+0x14/0x30 [ 417.114699] ? recalc_sigpending+0x160/0x220 [ 417.114703] ? _raw_spin_unlock_irq+0xe/0x50 [ 417.114705] ? calculate_sigpending+0x78/0xb0 [ 417.114707] ? __pfx_kthread+0x10/0x10 [ 417.114710] ret_from_fork+0x2b6/0x380 [ 417.114713] ? __pfx_kthread+0x10/0x10 [ 417.114715] ret_from_fork_asm+0x1a/0x30 [ 417.114720] [ 417.125171] Allocated by task 2: [ 417.125333] kasan_save_stack+0x26/0x60 [ 417.125522] kasan_save_track+0x14/0x40 [ 417.125742] kasan_save_alloc_info+0x39/0x60 [ 417.125945] __kasan_slab_alloc+0x8b/0xb0 [ 417.126133] kmem_cache_alloc_node_noprof+0x13b/0x460 [ 417.126381] copy_process+0x320/0x6250 [ 417.126595] kernel_clone+0xb7/0x840 [ 417.126792] kernel_thread+0xd6/0x120 [ 417.126995] kthreadd+0x85c/0xbe0 [ 417.127176] ret_from_fork+0x2b6/0x380 [ 417.127378] ret_from_fork_asm+0x1a/0x30 [ 417.127692] Freed by task 0: [ 417.127851] kasan_save_stack+0x26/0x60 [ 417.128057] kasan_save_track+0x14/0x40 [ 417.128267] kasan_save_free_info+0x3b/0x60 [ 417.128491] __kasan_slab_free+0x6c/0xa0 [ 417.128708] kmem_cache_free+0x182/0x550 [ 417.128906] free_task+0xeb/0x140 [ 417.129070] __put_task_struct+0x1d2/0x4f0 [ 417.129259] __put_task_struct_rcu_cb+0x15/0x20 [ 417.129480] rcu_do_batch+0x3d3/0xe70 [ 417.129681] rcu_core+0x549/0xb30 [ 417.129839] rcu_core_si+0xe/0x20 [ 417.130005] handle_softirqs+0x160/0x570 [ 417.130190] __irq_exit_rcu+0x189/0x1e0 [ 417.130369] irq_exit_rcu+0xe/0x20 [ 417.130531] sysvec_apic_timer_interrupt+0x9f/0xd0 [ 417.130768] asm_sysvec_apic_timer_interrupt+0x1b/0x20 [ 417.131082] Last potentially related work creation: [ 417.131305] kasan_save_stack+0x26/0x60 [ 417.131484] kasan_record_aux_stack+0xae/0xd0 [ 417.131695] __call_rcu_common+0xcd/0x14b0 [ 417.131909] call_rcu+0x31/0x50 [ 417.132071] delayed_put_task_struct+0x128/0x190 [ 417.132295] rcu_do_batch+0x3d3/0xe70 [ 417.132478] rcu_core+0x549/0xb30 [ 417.132658] rcu_core_si+0xe/0x20 [ 417.132808] handle_softirqs+0x160/0x570 [ 417.132993] __irq_exit_rcu+0x189/0x1e0 [ 417.133181] irq_exit_rcu+0xe/0x20 [ 417.133353] sysvec_apic_timer_interrupt+0x9f/0xd0 [ 417.133584] asm_sysvec_apic_timer_interrupt+0x1b/0x20 [ 417.133921] Second to last potentially related work creation: [ 417.134183] kasan_save_stack+0x26/0x60 [ 417.134362] kasan_record_aux_stack+0xae/0xd0 [ 417.134566] __call_rcu_common+0xcd/0x14b0 [ 417.134782] call_rcu+0x31/0x50 [ 417.134929] put_task_struct_rcu_user+0x58/0xb0 [ 417.135143] finish_task_switch.isra.0+0x5d3/0x830 [ 417.135366] __schedule+0xd30/0x5100 [ 417.135534] schedule_idle+0x5a/0x90 [ 417.135712] do_idle+0x25f/0x410 [ 417.135871] cpu_startup_entry+0x53/0x70 [ 417.136053] start_secondary+0x216/0x2c0 [ 417.136233] common_startup_64+0x13e/0x141 [ 417.136894] The buggy address belongs to the object at ffff888124870000 which belongs to the cache task_struct of size 10504 [ 417.138122] The buggy address is located 52 bytes inside of freed 10504-byte region [ffff888124870000, ffff888124872908) [ 417.139465] The buggy address belongs to the physical page: [ 417.140016] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x124870 [ 417.140789] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 417.141519] memcg:ffff88811aa20e01 [ 417.141874] anon flags: 0x17ffffc0000040(head|node=0|zone=2|lastcpupid=0x1fffff) [ 417.142600] page_type: f5(slab) [ 417.142922] raw: 0017ffffc0000040 ffff88810094f040 0000000000000000 dead000000000001 [ 417.143554] raw: 0000000000000000 0000000000030003 00000000f5000000 ffff88811aa20e01 [ 417.143954] head: 0017ffffc0000040 ffff88810094f040 0000000000000000 dead000000000001 [ 417.144329] head: 0000000000000000 0000000000030003 00000000f5000000 ffff88811aa20e01 [ 417.144710] head: 0017ffffc0000003 ffffea0004921c01 00000000ffffffff 00000000ffffffff [ 417.145106] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008 [ 417.145485] page dumped because: kasan: bad access detected [ 417.145859] Memory state around the buggy address: [ 417.146094] ffff88812486ff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 417.146439] ffff88812486ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 417.146791] >ffff888124870000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 417.147145] ^ [ 417.147387] ffff888124870080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 417.147751] ffff888124870100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 417.148123] ================================================================== First of all, we have warning in get_bvec_at() because cursor->total_resid contains zero value. And, finally, we have crash in ceph_msg_data_advance() because cursor->data is NULL. It means that get_bvec_at() receives not initialized ceph_msg_data_cursor structure because data is NULL and total_resid contains zero. Moreover, we don't have likewise issue for the case of Ceph msgr1 protocol because ceph_msg_data_cursor_init() has been called before reading sparse data. This patch adds calling of ceph_msg_data_cursor_init() in the beginning of process_v2_sparse_read() with the goal to guarantee that logic of reading sparse data works correctly for the case of Ceph msgr2 protocol. Cc: stable@vger.kernel.org Link: https://tracker.ceph.com/issues/73152 Signed-off-by: Viacheslav Dubeyko Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/messenger_v2.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index f9ed6bf6c477..73ac1c1f3394 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -1091,13 +1091,16 @@ static int decrypt_control_remainder(struct ceph_connection *con) static int process_v2_sparse_read(struct ceph_connection *con, struct page **pages, int spos) { - struct ceph_msg_data_cursor *cursor = &con->v2.in_cursor; + struct ceph_msg_data_cursor cursor; int ret; + ceph_msg_data_cursor_init(&cursor, con->in_msg, + con->in_msg->sparse_read_total); + for (;;) { char *buf = NULL; - ret = con->ops->sparse_read(con, cursor, &buf); + ret = con->ops->sparse_read(con, &cursor, &buf); if (ret <= 0) return ret; @@ -1115,11 +1118,11 @@ static int process_v2_sparse_read(struct ceph_connection *con, } else { struct bio_vec bv; - get_bvec_at(cursor, &bv); + get_bvec_at(&cursor, &bv); len = min_t(int, len, bv.bv_len); memcpy_page(bv.bv_page, bv.bv_offset, spage, soff, len); - ceph_msg_data_advance(cursor, len); + ceph_msg_data_advance(&cursor, len); } spos += len; ret -= len; -- Gitee From d78d703dc3705e6e0d260ba0601419c4c1878dd0 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 18 Nov 2025 04:42:02 +0800 Subject: [PATCH 0125/1449] dm-verity: fix unreliable memory allocation ANBZ: #35228 commit f8d1f166289f242a7c7a819709c45ff3a0c7f149 stable. commit fe680d8c747f4e676ac835c8c7fb0f287cd98758 upstream. GFP_NOWAIT allocation may fail anytime. It needs to be changed to GFP_NOIO. There's no need to handle an error because mempool_alloc with GFP_NOIO can't fail. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org Reviewed-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/dm-verity-fec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c index 8007e2e21972..4474352ad3d1 100644 --- a/drivers/md/dm-verity-fec.c +++ b/drivers/md/dm-verity-fec.c @@ -330,11 +330,7 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio) if (fio->bufs[n]) continue; - fio->bufs[n] = mempool_alloc(&v->fec->prealloc_pool, GFP_NOWAIT); - if (unlikely(!fio->bufs[n])) { - DMERR("failed to allocate FEC buffer"); - return -ENOMEM; - } + fio->bufs[n] = mempool_alloc(&v->fec->prealloc_pool, GFP_NOIO); } /* try to allocate the maximum number of buffers */ -- Gitee From c7b743c0da469754975827a927b799aea4417ada Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Fri, 7 Nov 2025 18:44:37 +0800 Subject: [PATCH 0126/1449] drivers/usb/dwc3: fix PCI parent check ANBZ: #35228 commit 4c257170c81dfd22e0130c149cd8514119c1aa02 stable. commit 40f8d17eed7533ed2bbb5e3cc680049b19411b2e upstream. The sysdev_is_parent check was being used to infer PCI devices that have the DMA mask set from the PCI capabilities, but sysdev_is_parent is also used for non-PCI ACPI devices in which case the DMA mask would be the bus default or as set by the _DMA method. Without this fix the DMA mask would default to 32-bits and so allocation would fail if there was no DRAM below 4GB. Fixes: 47ce45906ca9 ("usb: dwc3: leave default DMA for PCI devices") Cc: stable Signed-off-by: Jamie Iles Signed-off-by: Punit Agrawal Acked-by: Thinh Nguyen Link: https://patch.msgid.link/20251107104437.1602509-1-punit.agrawal@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b7eaad099309..22975a4b19a4 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1990,7 +1991,7 @@ static int dwc3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dwc); dwc3_cache_hwparams(dwc); - if (!dwc->sysdev_is_parent && + if (!dev_is_pci(dwc->sysdev) && DWC3_GHWPARAMS0_AWIDTH(dwc->hwparams.hwparams0) == 64) { ret = dma_set_mask_and_coherent(dwc->sysdev, DMA_BIT_MASK(64)); if (ret) -- Gitee From c64d80c91682f278504e6c970b107cce8b1b9163 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 25 Nov 2025 04:00:36 +0800 Subject: [PATCH 0127/1449] smb: client: fix memory leak in cifs_construct_tcon() ANBZ: #35228 commit f62ffdfb431bdfa4b6d24233b7fd830eca0b801e stable. commit 3184b6a5a24ec9ee74087b2a550476f386df7dc2 upstream. When having a multiuser mount with domain= specified and using cifscreds, cifs_set_cifscreds() will end up setting @ctx->domainname, so it needs to be freed before leaving cifs_construct_tcon(). This fixes the following memory leak reported by kmemleak: mount.cifs //srv/share /mnt -o domain=ZELDA,multiuser,... su - testuser cifscreds add -d ZELDA -u testuser ... ls /mnt/1 ... umount /mnt echo scan > /sys/kernel/debug/kmemleak cat /sys/kernel/debug/kmemleak unreferenced object 0xffff8881203c3f08 (size 8): comm "ls", pid 5060, jiffies 4307222943 hex dump (first 8 bytes): 5a 45 4c 44 41 00 cc cc ZELDA... backtrace (crc d109a8cf): __kmalloc_node_track_caller_noprof+0x572/0x710 kstrdup+0x3a/0x70 cifs_sb_tlink+0x1209/0x1770 [cifs] cifs_get_fattr+0xe1/0xf50 [cifs] cifs_get_inode_info+0xb5/0x240 [cifs] cifs_revalidate_dentry_attr+0x2d1/0x470 [cifs] cifs_getattr+0x28e/0x450 [cifs] vfs_getattr_nosec+0x126/0x180 vfs_statx+0xf6/0x220 do_statx+0xab/0x110 __x64_sys_statx+0xd5/0x130 do_syscall_64+0xbb/0x380 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: f2aee329a68f ("cifs: set domainName when a domain-key is used in multiuser") Signed-off-by: Paulo Alcantara (Red Hat) Reviewed-by: David Howells Cc: Jay Shin Cc: stable@vger.kernel.org Cc: linux-cifs@vger.kernel.org Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/connect.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 986286ef4046..86c89917f18e 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -4224,6 +4224,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) out: kfree(ctx->username); + kfree(ctx->domainname); kfree_sensitive(ctx->password); kfree(origin_fullpath); kfree(ctx); -- Gitee From 6e230019ffe60b32331fc3b9cbce318813da6a66 Mon Sep 17 00:00:00 2001 From: Alan Borzeszkowski Date: Thu, 14 Nov 2024 17:55:44 +0800 Subject: [PATCH 0128/1449] thunderbolt: Add support for Intel Wildcat Lake ANBZ: #35228 commit c4ba90485bfd2d2b1da6411b5bdd2afa0041505c stable. commit 3575254546a27210a4b661ea37fbbfb836c0815d upstream. Intel Wildcat Lake derives its Thunderbolt/USB4 controller from Lunar Lake platform. Add Wildcat Lake PCI ID to the driver list of supported devices. Signed-off-by: Alan Borzeszkowski Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/thunderbolt/nhi.c | 2 ++ drivers/thunderbolt/nhi.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 79f2bf5df19a..d13063e69571 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -1536,6 +1536,8 @@ static struct pci_device_id nhi_ids[] = { .driver_data = (kernel_ulong_t)&icl_nhi_ops }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI1), .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_WCL_NHI0), + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) }, diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index 16744f25a9a0..24ac4246d0ca 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -75,6 +75,7 @@ extern const struct tb_nhi_ops icl_nhi_ops; #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef #define PCI_DEVICE_ID_INTEL_ADL_NHI0 0x463e #define PCI_DEVICE_ID_INTEL_ADL_NHI1 0x466d +#define PCI_DEVICE_ID_INTEL_WCL_NHI0 0x4d33 #define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI 0x5781 #define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI 0x5784 #define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE 0x5786 -- Gitee From 37955e995a7a6921a24e00898be3f2bac4fab184 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 27 Oct 2025 14:06:01 +0800 Subject: [PATCH 0129/1449] slimbus: ngd: Fix reference count leak in qcom_slim_ngd_notify_slaves ANBZ: #35228 commit 87b3d01051921117a0ab8292bcd806383a532435 stable. commit 96cf8500934e0ce2a6c486f1dbc3b1fff12f7a5e upstream. The function qcom_slim_ngd_notify_slaves() calls of_slim_get_device() which internally uses device_find_child() to obtain a device reference. According to the device_find_child() documentation, the caller must drop the reference with put_device() after use. Found via static analysis and this is similar to commit 4e65bda8273c ("ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()") Fixes: 917809e2280b ("slimbus: ngd: Add qcom SLIMBus NGD driver") Cc: stable Signed-off-by: Miaoqian Lin Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20251027060601.33228-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/slimbus/qcom-ngd-ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 0da5d9d1af03..fe3a96577f31 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1239,6 +1239,7 @@ static void qcom_slim_ngd_notify_slaves(struct qcom_slim_ngd_ctrl *ctrl) if (slim_get_logical_addr(sbdev)) dev_err(ctrl->dev, "Failed to get logical address\n"); + put_device(&sbdev->dev); } } -- Gitee From 2b38e3a43d3b61d170073a6db0157990828b952c Mon Sep 17 00:00:00 2001 From: Khairul Anuar Romli Date: Mon, 3 Nov 2025 07:21:28 +0800 Subject: [PATCH 0130/1449] firmware: stratix10-svc: fix bug in saving controller data ANBZ: #35228 commit 71796c91ee8e33faf4434a9e210b5063c28ea907 stable. commit d0fcf70c680e4d1669fcb3a8632f41400b9a73c2 upstream. Fix the incorrect usage of platform_set_drvdata and dev_set_drvdata. They both are of the same data and overrides each other. This resulted in the rmmod of the svc driver to fail and throw a kernel panic for kthread_stop and fifo free. Fixes: b5dc75c915cd ("firmware: stratix10-svc: extend svc to support new RSU features") Cc: stable@vger.kernel.org # 6.6+ Signed-off-by: Ang Tien Sung Signed-off-by: Khairul Anuar Romli Signed-off-by: Dinh Nguyen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/stratix10-svc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index c693da60e9a9..766ced12345c 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -134,6 +134,7 @@ struct stratix10_svc_data { * @complete_status: state for completion * @svc_fifo_lock: protect access to service message data queue * @invoke_fn: function to issue secure monitor call or hypervisor call + * @svc: manages the list of client svc drivers * * This struct is used to create communication channels for service clients, to * handle secure monitor or hypervisor call. @@ -150,6 +151,7 @@ struct stratix10_svc_controller { struct completion complete_status; spinlock_t svc_fifo_lock; svc_invoke_fn *invoke_fn; + struct stratix10_svc *svc; }; /** @@ -1209,6 +1211,7 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_free_kfifo; } + controller->svc = svc; svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0); if (!svc->stratix10_svc_rsu) { @@ -1236,8 +1239,6 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) goto err_unregister_dev; } - dev_set_drvdata(dev, svc); - pr_info("Intel Service Layer Driver Initialized\n"); return 0; @@ -1253,8 +1254,8 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) static int stratix10_svc_drv_remove(struct platform_device *pdev) { - struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev); struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev); + struct stratix10_svc *svc = ctrl->svc; platform_device_unregister(svc->intel_svc_fcs); platform_device_unregister(svc->stratix10_svc_rsu); -- Gitee From e6013934803494429bd7b6543abafc862b855c24 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 10 Oct 2025 23:44:45 +0800 Subject: [PATCH 0131/1449] iio: adc: ad7280a: fix ad7280_store_balance_timer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit ad70338c1b87881bd7340d2dad8e0bbbbc8a34a2 stable. commit bd886cdcbf9e746f61c74035a3acd42e9108e115 upstream. Use correct argument to iio_str_to_fixpoint() to parse 3 decimal places. iio_str_to_fixpoint() has a bit of an unintuitive API where the fract_mult parameter is the multiplier of the first decimal place as if it was already an integer. So to get 3 decimal places, fract_mult must be 100 rather than 1000. Fixes: 96ccdbc07a74 ("staging:iio:adc:ad7280a: Standardize extended ABI naming") Signed-off-by: David Lechner Reviewed-by: Nuno Sá Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/ad7280a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c index d4a4e15c8244..9080c795dcb7 100644 --- a/drivers/iio/adc/ad7280a.c +++ b/drivers/iio/adc/ad7280a.c @@ -540,7 +540,7 @@ static ssize_t ad7280_store_balance_timer(struct iio_dev *indio_dev, int val, val2; int ret; - ret = iio_str_to_fixpoint(buf, 1000, &val, &val2); + ret = iio_str_to_fixpoint(buf, 100, &val, &val2); if (ret) return ret; -- Gitee From c6fed878e81a7a21189e6a04c9b5a783e5e0f335 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 13 Nov 2025 13:21:10 +0800 Subject: [PATCH 0132/1449] MIPS: mm: Prevent a TLB shutdown on initial uniquification ANBZ: #35228 commit 135713cd0751bf296e515f5fdec234320f73bbd8 stable. commit 9f048fa487409e364cf866c957cf0b0d782ca5a3 upstream. Depending on the particular CPU implementation a TLB shutdown may occur if multiple matching entries are detected upon the execution of a TLBP or the TLBWI/TLBWR instructions. Given that we don't know what entries we have been handed we need to be very careful with the initial TLB setup and avoid all these instructions. Therefore read all the TLB entries one by one with the TLBR instruction, bypassing the content addressing logic, and truncate any large pages in place so as to avoid a case in the second step where an incoming entry for a large page at a lower address overlaps with a replacement entry chosen at another index. Then preinitialize the TLB using addresses outside our usual unique range and avoiding clashes with any entries received, before making the usual call to local_flush_tlb_all(). This fixes (at least) R4x00 cores if TLBP hits multiple matching TLB entries (SGI IP22 PROM for examples sets up all TLBs to the same virtual address). Signed-off-by: Maciej W. Rozycki Fixes: 35ad7e181541 ("MIPS: mm: tlb-r4k: Uniquify TLB entries on init") Cc: stable@vger.kernel.org Reviewed-by: Jiaxun Yang Tested-by: Jiaxun Yang # Boston I6400, M5150 sim Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/mips/mm/tlb-r4k.c | 100 ++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index ab8102f94e06..19956b7c4b12 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -506,54 +507,78 @@ static int __init set_ntlb(char *str) __setup("ntlb=", set_ntlb); -/* Initialise all TLB entries with unique values */ + +/* Comparison function for EntryHi VPN fields. */ +static int r4k_vpn_cmp(const void *a, const void *b) +{ + long v = *(unsigned long *)a - *(unsigned long *)b; + int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0; + return s ? (v != 0) | v >> s : v; +} + +/* + * Initialise all TLB entries with unique values that do not clash with + * what we have been handed over and what we'll be using ourselves. + */ static void r4k_tlb_uniquify(void) { - int entry = num_wired_entries(); + unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; + int tlbsize = current_cpu_data.tlbsize; + int start = num_wired_entries(); + unsigned long vpn_mask; + int cnt, ent, idx, i; + + vpn_mask = GENMASK(cpu_vmbits - 1, 13); + vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; htw_stop(); + + for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { + unsigned long vpn; + + write_c0_index(i); + mtc0_tlbr_hazard(); + tlb_read(); + tlb_read_hazard(); + vpn = read_c0_entryhi(); + vpn &= vpn_mask & PAGE_MASK; + tlb_vpns[cnt] = vpn; + + /* Prevent any large pages from overlapping regular ones. */ + write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK); + mtc0_tlbw_hazard(); + tlb_write_indexed(); + tlbw_use_hazard(); + } + + sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL); + + write_c0_pagemask(PM_DEFAULT_MASK); write_c0_entrylo0(0); write_c0_entrylo1(0); - while (entry < current_cpu_data.tlbsize) { - unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); - unsigned long asid = 0; - int idx; + idx = 0; + ent = tlbsize; + for (i = start; i < tlbsize; i++) + while (1) { + unsigned long entryhi, vpn; - /* Skip wired MMID to make ginvt_mmid work */ - if (cpu_has_mmid) - asid = MMID_KERNEL_WIRED + 1; + entryhi = UNIQUE_ENTRYHI(ent); + vpn = entryhi & vpn_mask & PAGE_MASK; - /* Check for match before using UNIQUE_ENTRYHI */ - do { - if (cpu_has_mmid) { - write_c0_memorymapid(asid); - write_c0_entryhi(UNIQUE_ENTRYHI(entry)); + if (idx >= cnt || vpn < tlb_vpns[idx]) { + write_c0_entryhi(entryhi); + write_c0_index(i); + mtc0_tlbw_hazard(); + tlb_write_indexed(); + ent++; + break; + } else if (vpn == tlb_vpns[idx]) { + ent++; } else { - write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid); + idx++; } - mtc0_tlbw_hazard(); - tlb_probe(); - tlb_probe_hazard(); - idx = read_c0_index(); - /* No match or match is on current entry */ - if (idx < 0 || idx == entry) - break; - /* - * If we hit a match, we need to try again with - * a different ASID. - */ - asid++; - } while (asid < asid_mask); - - if (idx >= 0 && idx != entry) - panic("Unable to uniquify TLB entry %d", idx); - - write_c0_index(entry); - mtc0_tlbw_hazard(); - tlb_write_indexed(); - entry++; - } + } tlbw_use_hazard(); htw_start(); @@ -600,6 +625,7 @@ static void r4k_tlb_configure(void) /* From this point on the ARC firmware is dead. */ r4k_tlb_uniquify(); + local_flush_tlb_all(); /* Did I tell you that ARC SUCKS? */ } -- Gitee From 8cddfa21bfea9978dcee8ef54299e4148917ae6e Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Sat, 29 Nov 2025 00:53:46 +0800 Subject: [PATCH 0133/1449] MIPS: mm: kmalloc tlb_vpn array to avoid stack overflow ANBZ: #35228 commit 231ac951fabae2aaed8b2c00b4a097107be49c8c stable. commit 841ecc979b18d3227fad5e2d6a1e6f92688776b5 upstream. Owing to Config4.MMUSizeExt and VTLB/FTLB MMU features later MIPSr2+ cores can have more than 64 TLB entries. Therefore allocate an array for uniquification instead of placing too an small array on the stack. Fixes: 35ad7e181541 ("MIPS: mm: tlb-r4k: Uniquify TLB entries on init") Co-developed-by: Maciej W. Rozycki Signed-off-by: Maciej W. Rozycki Cc: stable@vger.kernel.org # v6.17+: 9f048fa48740: MIPS: mm: Prevent a TLB shutdown on initial uniquification Cc: stable@vger.kernel.org # v6.17+ Tested-by: Gregory CLEMENT Tested-by: Klara Modin Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/mips/mm/tlb-r4k.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 19956b7c4b12..06cb140476ea 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -520,17 +521,26 @@ static int r4k_vpn_cmp(const void *a, const void *b) * Initialise all TLB entries with unique values that do not clash with * what we have been handed over and what we'll be using ourselves. */ -static void r4k_tlb_uniquify(void) +static void __ref r4k_tlb_uniquify(void) { - unsigned long tlb_vpns[1 << MIPS_CONF1_TLBS_SIZE]; int tlbsize = current_cpu_data.tlbsize; + bool use_slab = slab_is_available(); int start = num_wired_entries(); + phys_addr_t tlb_vpn_size; + unsigned long *tlb_vpns; unsigned long vpn_mask; int cnt, ent, idx, i; vpn_mask = GENMASK(cpu_vmbits - 1, 13); vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; + tlb_vpn_size = tlbsize * sizeof(*tlb_vpns); + tlb_vpns = (use_slab ? + kmalloc(tlb_vpn_size, GFP_KERNEL) : + memblock_alloc_raw(tlb_vpn_size, sizeof(*tlb_vpns))); + if (WARN_ON(!tlb_vpns)) + return; /* Pray local_flush_tlb_all() is good enough. */ + htw_stop(); for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { @@ -583,6 +593,10 @@ static void r4k_tlb_uniquify(void) tlbw_use_hazard(); htw_start(); flush_micro_tlb(); + if (use_slab) + kfree(tlb_vpns); + else + memblock_free(tlb_vpns, tlb_vpn_size); } /* -- Gitee From 6414e837b22604b5e152b63f0ab42732492c76a7 Mon Sep 17 00:00:00 2001 From: Ivan Zhaldak Date: Mon, 17 Nov 2025 20:58:35 +0800 Subject: [PATCH 0134/1449] ALSA: usb-audio: Add DSD quirk for LEAK Stereo 230 ANBZ: #35228 commit b4abe6826926f6a4d4d68bdd266a824052661fb0 stable. commit c83fc13960643c4429cd9dfef1321e6430a81b47 upstream. Integrated amplifier LEAK Stereo 230 by IAG Limited has built-in ESS9038Q2M DAC served by XMOS controller. It supports both DSD Native and DSD-over-PCM (DoP) operational modes. But it doesn't work properly by default and tries DSD-to-PCM conversion. USB quirks below allow it to operate as designed. Add DSD_RAW quirk flag for IAG Limited devices (vendor ID 0x2622) Add DSD format quirk for LEAK Stereo 230 (USB ID 0x2622:0x0061) Signed-off-by: Ivan Zhaldak Cc: Link: https://patch.msgid.link/20251117125848.30769-1-i.v.zhaldak@gmail.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 7d747677b58d..68238e62020b 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1928,6 +1928,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */ case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */ + case USB_ID(0x2622, 0x0061): /* LEAK Stereo 230 */ case USB_ID(0x278b, 0x5100): /* Rotel RC-1590 */ case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */ case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */ @@ -2311,6 +2312,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x25ce, /* Mytek devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2622, /* IAG Limited devices */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x278b, /* Rotel? */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x292b, /* Gustard/Ess based devices */ -- Gitee From e71da1993d1a7850a1b69c85fa6023e330b6fab3 Mon Sep 17 00:00:00 2001 From: Maarten Zanders Date: Fri, 24 Oct 2025 22:21:06 +0800 Subject: [PATCH 0135/1449] ARM: dts: nxp: imx6ul: correct SAI3 interrupt line ANBZ: #35228 commit 5b88725e5ea1e38f0287ca2d66180b266b9eced3 stable. commit 1b03346314b791ad966d3c6d59253328226a2b2d upstream. The i.MX6UL reference manual lists two possible interrupt lines for SAI3 (56 and 57, offset +32). The current device tree entry uses the first one (24), which prevents IRQs from being handled properly. Use the second interrupt line (25), which does allow interrupts to work as expected. Fixes: 36e2edf6ac07 ("ARM: dts: imx6ul: add sai support") Signed-off-by: Maarten Zanders Cc: stable@vger.kernel.org Signed-off-by: Shawn Guo Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/nxp/imx/imx6ul.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi index 3b87d980e9f4..2019cebe8bb6 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi @@ -333,7 +333,7 @@ sai3: sai@2030000 { #sound-dai-cells = <0>; compatible = "fsl,imx6ul-sai", "fsl,imx6sx-sai"; reg = <0x02030000 0x4000>; - interrupts = ; + interrupts = ; clocks = <&clks IMX6UL_CLK_SAI3_IPG>, <&clks IMX6UL_CLK_SAI3>, <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>; -- Gitee From 4a1e233b392463d5d88398e91f25867e2de22daf Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Thu, 20 Nov 2025 20:06:57 +0800 Subject: [PATCH 0136/1449] atm/fore200e: Fix possible data race in fore200e_open() ANBZ: #35228 commit 9917ba597cf95f307778e495f71ff25a5064d167 stable. commit 82fca3d8a4a34667f01ec2351a607135249c9cff upstream. Protect access to fore200e->available_cell_rate with rate_mtx lock in the error handling path of fore200e_open() to prevent a data race. The field fore200e->available_cell_rate is a shared resource used to track available bandwidth. It is concurrently accessed by fore200e_open(), fore200e_close(), and fore200e_change_qos(). In fore200e_open(), the lock rate_mtx is correctly held when subtracting vcc->qos.txtp.max_pcr from available_cell_rate to reserve bandwidth. However, if the subsequent call to fore200e_activate_vcin() fails, the function restores the reserved bandwidth by adding back to available_cell_rate without holding the lock. This introduces a race condition because available_cell_rate is a global device resource shared across all VCCs. If the error path in fore200e_open() executes concurrently with operations like fore200e_close() or fore200e_change_qos() on other VCCs, a read-modify-write race occurs. Specifically, the error path reads the rate without the lock. If another CPU acquires the lock and modifies the rate (e.g., releasing bandwidth in fore200e_close()) between this read and the subsequent write, the error path will overwrite the concurrent update with a stale value. This results in incorrect bandwidth accounting. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251120120657.2462194-1-hanguidong02@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/atm/fore200e.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index fb2be3574c26..b57faf6dc327 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -1377,7 +1377,9 @@ fore200e_open(struct atm_vcc *vcc) vcc->dev_data = NULL; + mutex_lock(&fore200e->rate_mtx); fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; + mutex_unlock(&fore200e->rate_mtx); kfree(fore200e_vcc); return -EINVAL; -- Gitee From 76f69bd729a6d885476f30f8c6c2ed701ab0d84e Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Wed, 26 Nov 2025 00:59:11 +0800 Subject: [PATCH 0137/1449] mptcp: clear scheduled subflows on retransmit ANBZ: #35228 commit ce318ec9864bc3dbaa37d71ec4813f0358f0d44a stable. commit 27fd02860164bfa78cec2640dfad630d832e302c upstream. When __mptcp_retrans() kicks-in, it schedules one or more subflows for retransmission, but such subflows could be actually left alone if there is no more data to retransmit and/or in case of concurrent fallback. Scheduled subflows could be processed much later in time, i.e. when new data will be transmitted, leading to bad subflow selection. Explicitly clear all scheduled subflows before leaving the retransmission function. Fixes: ee2708aedad0 ("mptcp: use get_retrans wrapper") Cc: stable@vger.kernel.org Reported-by: Filip Pokryvka Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251125-net-mptcp-clear-sched-rtx-v1-1-1cea4ad2165f@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 73b3a44b183f..90e0a9e8e014 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2691,7 +2691,7 @@ static void __mptcp_retrans(struct sock *sk) } if (!mptcp_send_head(sk)) - return; + goto clear_scheduled; goto reset_timer; } @@ -2722,7 +2722,7 @@ static void __mptcp_retrans(struct sock *sk) if (__mptcp_check_fallback(msk)) { spin_unlock_bh(&msk->fallback_lock); release_sock(ssk); - return; + goto clear_scheduled; } while (info.sent < info.limit) { @@ -2754,6 +2754,15 @@ static void __mptcp_retrans(struct sock *sk) if (!mptcp_rtx_timer_pending(sk)) mptcp_reset_rtx_timer(sk); + +clear_scheduled: + /* If no rtx data was available or in case of fallback, there + * could be left-over scheduled subflows; clear them all + * or later xmit could use bad ones + */ + mptcp_for_each_subflow(msk, subflow) + if (READ_ONCE(subflow->scheduled)) + mptcp_subflow_set_scheduled(subflow, false); } /* schedule the timeout timer for the relevant event: either close timeout -- Gitee From 863c71cf62188dc00a6e3d49cef8e41fb84235ae Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 27 Oct 2025 17:20:50 +0800 Subject: [PATCH 0138/1449] serial: amba-pl011: prefer dma_mapping_error() over explicit address checking ANBZ: #35228 commit 41ae1203c5ab6036f3628e22a3ab0d5f8fe104d1 stable. commit eb4917f557d43c7a1c805dd73ffcdfddb2aba39a upstream. Check for returned DMA addresses using specialized dma_mapping_error() helper which is generally recommended for this purpose by Documentation/core-api/dma-api.rst: "In some circumstances dma_map_single(), ... will fail to create a mapping. A driver can check for these errors by testing the returned DMA address with dma_mapping_error()." Found via static analysis and this is similar to commit fa0308134d26 ("ALSA: memalloc: prefer dma_mapping_error() over explicit address checking") Fixes: 58ac1b379979 ("ARM: PL011: Fix DMA support") Cc: stable Signed-off-by: Miaoqian Lin Reviewed-by: Gregory CLEMENT Link: https://patch.msgid.link/20251027092053.87937-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index bb31ac9cae8c..8aa71a51cdab 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -636,7 +636,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap) dmatx->len = count; dmatx->dma = dma_map_single(dma_dev->dev, dmatx->buf, count, DMA_TO_DEVICE); - if (dmatx->dma == DMA_MAPPING_ERROR) { + if (dma_mapping_error(dma_dev->dev, dmatx->dma)) { uap->dmatx.queued = false; dev_dbg(uap->port.dev, "unable to map TX DMA\n"); return -EBUSY; -- Gitee From b46a83c647e81015444cb8050b6f332dcd69dfab Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 29 Oct 2025 17:30:29 +0800 Subject: [PATCH 0139/1449] most: usb: fix double free on late probe failure ANBZ: #35228 commit 993bfdc3842893c394de13c8200c338ebb979589 stable. commit baadf2a5c26e802a46573eaad331b427b49aaa36 upstream. The MOST subsystem has a non-standard registration function which frees the interface on registration failures and on deregistration. This unsurprisingly leads to bugs in the MOST drivers, and a couple of recent changes turned a reference underflow and use-after-free in the USB driver into several double free and a use-after-free on late probe failures. Fixes: 723de0f9171e ("staging: most: remove device from interface structure") Fixes: 4b1270902609 ("most: usb: Fix use-after-free in hdm_disconnect") Fixes: a8cc9e5fcb0e ("most: usb: hdm_probe: Fix calling put_device() before device initialization") Cc: stable@vger.kernel.org Cc: Christian Gromm Cc: Victoria Votokina Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251029093029.28922-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/most/most_usb.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/most/most_usb.c b/drivers/most/most_usb.c index 988e33f27970..9cfa33bd37d7 100644 --- a/drivers/most/most_usb.c +++ b/drivers/most/most_usb.c @@ -1058,7 +1058,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) ret = most_register_interface(&mdev->iface); if (ret) - goto err_free_busy_urbs; + return ret; mutex_lock(&mdev->io_mutex); if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || @@ -1068,8 +1068,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) if (!mdev->dci) { mutex_unlock(&mdev->io_mutex); most_deregister_interface(&mdev->iface); - ret = -ENOMEM; - goto err_free_busy_urbs; + return -ENOMEM; } mdev->dci->dev.init_name = "dci"; @@ -1078,18 +1077,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) mdev->dci->dev.release = release_dci; if (device_register(&mdev->dci->dev)) { mutex_unlock(&mdev->io_mutex); + put_device(&mdev->dci->dev); most_deregister_interface(&mdev->iface); - ret = -ENOMEM; - goto err_free_dci; + return -ENOMEM; } mdev->dci->usb_device = mdev->usb_device; } mutex_unlock(&mdev->io_mutex); return 0; -err_free_dci: - put_device(&mdev->dci->dev); -err_free_busy_urbs: - kfree(mdev->busy_urbs); + err_free_ep_address: kfree(mdev->ep_address); err_free_cap: -- Gitee From a23f0bc3fd0e945c74d54cfe086150e85f1cfd98 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Sun, 26 Oct 2025 17:08:59 +0800 Subject: [PATCH 0140/1449] usb: cdns3: Fix double resource release in cdns3_pci_probe ANBZ: #35228 commit 730c13a9701c5721ae89a7b0c282d37a39d9ae37 stable. commit 1ec39d2cd88dac2e7cdbac248762f1f057971c5d upstream. The driver uses pcim_enable_device() to enable the PCI device, the device will be automatically disabled on driver detach through the managed device framework. The manual pci_disable_device() calls in the error paths are therefore redundant and should be removed. Found via static anlaysis and this is similar to commit 99ca0b57e49f ("thermal: intel: int340x: processor: Fix warning during module unload"). Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Cc: stable Signed-off-by: Miaoqian Lin Acked-by: Peter Chen Link: https://patch.msgid.link/20251026090859.33107-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/cdns3/cdns3-pci-wrap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns3-pci-wrap.c index 1f6320d98a76..92ae5d443350 100644 --- a/drivers/usb/cdns3/cdns3-pci-wrap.c +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c @@ -101,10 +101,8 @@ static int cdns3_pci_probe(struct pci_dev *pdev, wrap = pci_get_drvdata(func); } else { wrap = kzalloc(sizeof(*wrap), GFP_KERNEL); - if (!wrap) { - pci_disable_device(pdev); + if (!wrap) return -ENOMEM; - } } res = wrap->dev_res; @@ -163,7 +161,6 @@ static int cdns3_pci_probe(struct pci_dev *pdev, /* register platform device */ wrap->plat_dev = platform_device_register_full(&plat_info); if (IS_ERR(wrap->plat_dev)) { - pci_disable_device(pdev); err = PTR_ERR(wrap->plat_dev); kfree(wrap); return err; -- Gitee From 65d32bb8fd0bd8048874b612e30943f44bf43d9b Mon Sep 17 00:00:00 2001 From: Kuen-Han Tsai Date: Mon, 3 Nov 2025 20:17:59 +0800 Subject: [PATCH 0141/1449] usb: gadget: f_eem: Fix memory leak in eem_unwrap ANBZ: #35228 commit 41434488ca714ab15cb2a4d0378418d1be8052d2 stable. commit e4f5ce990818d37930cd9fb0be29eee0553c59d9 upstream. The existing code did not handle the failure case of usb_ep_queue in the command path, potentially leading to memory leaks. Improve error handling to free all allocated resources on usb_ep_queue failure. This patch continues to use goto logic for error handling, as the existing error handling is complex and not easily adaptable to auto-cleanup helpers. kmemleak results: unreferenced object 0xffffff895a512300 (size 240): backtrace: slab_post_alloc_hook+0xbc/0x3a4 kmem_cache_alloc+0x1b4/0x358 skb_clone+0x90/0xd8 eem_unwrap+0x1cc/0x36c unreferenced object 0xffffff8a157f4000 (size 256): backtrace: slab_post_alloc_hook+0xbc/0x3a4 __kmem_cache_alloc_node+0x1b4/0x2dc kmalloc_trace+0x48/0x140 dwc3_gadget_ep_alloc_request+0x58/0x11c usb_ep_alloc_request+0x40/0xe4 eem_unwrap+0x204/0x36c unreferenced object 0xffffff8aadbaac00 (size 128): backtrace: slab_post_alloc_hook+0xbc/0x3a4 __kmem_cache_alloc_node+0x1b4/0x2dc __kmalloc+0x64/0x1a8 eem_unwrap+0x218/0x36c unreferenced object 0xffffff89ccef3500 (size 64): backtrace: slab_post_alloc_hook+0xbc/0x3a4 __kmem_cache_alloc_node+0x1b4/0x2dc kmalloc_trace+0x48/0x140 eem_unwrap+0x238/0x36c Fixes: 4249d6fbc10f ("usb: gadget: eem: fix echo command packet response issue") Cc: stable@kernel.org Signed-off-by: Kuen-Han Tsai Link: https://patch.msgid.link/20251103121814.1559719-1-khtsai@google.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/function/f_eem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index 3b445bd88498..f2478b48a30b 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -477,8 +477,13 @@ static int eem_unwrap(struct gether *port, req->complete = eem_cmd_complete; req->zero = 1; req->context = ctx; - if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) + if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) { DBG(cdev, "echo response queue fail\n"); + kfree(ctx); + kfree(req->buf); + usb_ep_free_request(ep, req); + dev_kfree_skb_any(skb2); + } break; case 1: /* echo response */ -- Gitee From 90add4cd80aacd66c1da9d47cbe598d563e7673d Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 27 Oct 2025 22:07:41 +0800 Subject: [PATCH 0142/1449] usb: renesas_usbhs: Fix synchronous external abort on unbind ANBZ: #35228 commit 9d86bc8b188a77c8d6f7252280ec2bd24ad6fbc1 stable. commit eb9ac779830b2235847b72cb15cf07c7e3333c5e upstream. A synchronous external abort occurs on the Renesas RZ/G3S SoC if unbind is executed after the configuration sequence described above: modprobe usb_f_ecm modprobe libcomposite modprobe configfs cd /sys/kernel/config/usb_gadget mkdir -p g1 cd g1 echo "0x1d6b" > idVendor echo "0x0104" > idProduct mkdir -p strings/0x409 echo "0123456789" > strings/0x409/serialnumber echo "Renesas." > strings/0x409/manufacturer echo "Ethernet Gadget" > strings/0x409/product mkdir -p functions/ecm.usb0 mkdir -p configs/c.1 mkdir -p configs/c.1/strings/0x409 echo "ECM" > configs/c.1/strings/0x409/configuration if [ ! -L configs/c.1/ecm.usb0 ]; then ln -s functions/ecm.usb0 configs/c.1 fi echo 11e20000.usb > UDC echo 11e20000.usb > /sys/bus/platform/drivers/renesas_usbhs/unbind The displayed trace is as follows: Internal error: synchronous external abort: 0000000096000010 [#1] SMP CPU: 0 UID: 0 PID: 188 Comm: sh Tainted: G M 6.17.0-rc7-next-20250922-00010-g41050493b2bd #55 PREEMPT Tainted: [M]=MACHINE_CHECK Hardware name: Renesas SMARC EVK version 2 based on r9a08g045s33 (DT) pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : usbhs_sys_function_pullup+0x10/0x40 [renesas_usbhs] lr : usbhsg_update_pullup+0x3c/0x68 [renesas_usbhs] sp : ffff8000838b3920 x29: ffff8000838b3920 x28: ffff00000d585780 x27: 0000000000000000 x26: 0000000000000000 x25: 0000000000000000 x24: ffff00000c3e3810 x23: ffff00000d5e5c80 x22: ffff00000d5e5d40 x21: 0000000000000000 x20: 0000000000000000 x19: ffff00000d5e5c80 x18: 0000000000000020 x17: 2e30303230316531 x16: 312d7968703a7968 x15: 3d454d414e5f4344 x14: 000000000000002c x13: 0000000000000000 x12: 0000000000000000 x11: ffff00000f358f38 x10: ffff00000f358db0 x9 : ffff00000b41f418 x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff6364626d x5 : 8080808000000000 x4 : 000000004b5ccb9d x3 : 0000000000000000 x2 : 0000000000000000 x1 : ffff800083790000 x0 : ffff00000d5e5c80 Call trace: usbhs_sys_function_pullup+0x10/0x40 [renesas_usbhs] (P) usbhsg_pullup+0x4c/0x7c [renesas_usbhs] usb_gadget_disconnect_locked+0x48/0xd4 gadget_unbind_driver+0x44/0x114 device_remove+0x4c/0x80 device_release_driver_internal+0x1c8/0x224 device_release_driver+0x18/0x24 bus_remove_device+0xcc/0x10c device_del+0x14c/0x404 usb_del_gadget+0x88/0xc0 usb_del_gadget_udc+0x18/0x30 usbhs_mod_gadget_remove+0x24/0x44 [renesas_usbhs] usbhs_mod_remove+0x20/0x30 [renesas_usbhs] usbhs_remove+0x98/0xdc [renesas_usbhs] platform_remove+0x20/0x30 device_remove+0x4c/0x80 device_release_driver_internal+0x1c8/0x224 device_driver_detach+0x18/0x24 unbind_store+0xb4/0xb8 drv_attr_store+0x24/0x38 sysfs_kf_write+0x7c/0x94 kernfs_fop_write_iter+0x128/0x1b8 vfs_write+0x2ac/0x350 ksys_write+0x68/0xfc __arm64_sys_write+0x1c/0x28 invoke_syscall+0x48/0x110 el0_svc_common.constprop.0+0xc0/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x34/0xf0 el0t_64_sync_handler+0xa0/0xe4 el0t_64_sync+0x198/0x19c Code: 7100003f 1a9f07e1 531c6c22 f9400001 (79400021) ---[ end trace 0000000000000000 ]--- note: sh[188] exited with irqs disabled note: sh[188] exited with preempt_count 1 The issue occurs because usbhs_sys_function_pullup(), which accesses the IP registers, is executed after the USBHS clocks have been disabled. The problem is reproducible on the Renesas RZ/G3S SoC starting with the addition of module stop in the clock enable/disable APIs. With module stop functionality enabled, a bus error is expected if a master accesses a module whose clock has been stopped and module stop activated. Disable the IP clocks at the end of remove. Cc: stable Fixes: f1407d5c6624 ("usb: renesas_usbhs: Add Renesas USBHS common code") Signed-off-by: Claudiu Beznea Link: https://patch.msgid.link/20251027140741.557198-1-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/renesas_usbhs/common.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index b720899725e5..2978e869ac8f 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -798,18 +798,18 @@ static void usbhs_remove(struct platform_device *pdev) flush_delayed_work(&priv->notify_hotplug_work); - /* power off */ - if (!usbhs_get_dparam(priv, runtime_pwctrl)) - usbhsc_power_ctrl(priv, 0); - - pm_runtime_disable(&pdev->dev); - usbhs_platform_call(priv, hardware_exit, pdev); - usbhsc_clk_put(priv); reset_control_assert(priv->rsts); usbhs_mod_remove(priv); usbhs_fifo_remove(priv); usbhs_pipe_remove(priv); + + /* power off */ + if (!usbhs_get_dparam(priv, runtime_pwctrl)) + usbhsc_power_ctrl(priv, 0); + + usbhsc_clk_put(priv); + pm_runtime_disable(&pdev->dev); } static __maybe_unused int usbhsc_suspend(struct device *dev) -- Gitee From 90735cc16d8568cb67e399ee7a48964c5a9b5ae2 Mon Sep 17 00:00:00 2001 From: Desnes Nunes Date: Fri, 31 Oct 2025 12:34:36 +0800 Subject: [PATCH 0143/1449] usb: storage: Fix memory leak in USB bulk transport ANBZ: #35228 commit cb1401b5bcc2feb5b038fc4b512e5968b016e05e stable. commit 41e99fe2005182139b1058db71f0d241f8f0078c upstream. A kernel memory leak was identified by the 'ioctl_sg01' test from Linux Test Project (LTP). The following bytes were mainly observed: 0x53425355. When USB storage devices incorrectly skip the data phase with status data, the code extracts/validates the CSW from the sg buffer, but fails to clear it afterwards. This leaves status protocol data in srb's transfer buffer, such as the US_BULK_CS_SIGN 'USBS' signature observed here. Thus, this can lead to USB protocols leaks to user space through SCSI generic (/dev/sg*) interfaces, such as the one seen here when the LTP test requested 512 KiB. Fix the leak by zeroing the CSW data in srb's transfer buffer immediately after the validation of devices that skip data phase. Note: Differently from CVE-2018-1000204, which fixed a big leak by zero- ing pages at allocation time, this leak occurs after allocation, when USB protocol data is written to already-allocated sg pages. Fixes: a45b599ad808 ("scsi: sg: allocate with __GFP_ZERO in sg_build_indirect()") Cc: stable Signed-off-by: Desnes Nunes Reviewed-by: Alan Stern Link: https://patch.msgid.link/20251031043436.55929-1-desnesn@redhat.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/storage/transport.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 7449e379077a..f79b449d0f11 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1204,7 +1204,23 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) US_BULK_CS_WRAP_LEN && bcs->Signature == cpu_to_le32(US_BULK_CS_SIGN)) { + unsigned char buf[US_BULK_CS_WRAP_LEN]; + usb_stor_dbg(us, "Device skipped data phase\n"); + + /* + * Devices skipping data phase might leave CSW data in srb's + * transfer buffer. Zero it to prevent USB protocol leakage. + */ + sg = NULL; + offset = 0; + memset(buf, 0, sizeof(buf)); + if (usb_stor_access_xfer_buf(buf, + US_BULK_CS_WRAP_LEN, srb, &sg, + &offset, TO_XFER_BUF) != + US_BULK_CS_WRAP_LEN) + usb_stor_dbg(us, "Failed to clear CSW data\n"); + scsi_set_resid(srb, transfer_length); goto skipped_data_phase; } -- Gitee From f164f2bdeefeace997cd378a41439483736dc8cb Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 22 Nov 2025 05:29:34 +0800 Subject: [PATCH 0144/1449] USB: storage: Remove subclass and protocol overrides from Novatek quirk ANBZ: #35228 commit f5b6b214db1256c557c9d09fbd1f0d8b9194be84 stable. commit df5fde297e617041449f603ed5f646861c80000b upstream. A report from Oleg Smirnov indicates that the unusual_devs quirks entry for the Novatek camera does not need to override the subclass and protocol parameters: [3266355.209532] usb 1-3: new high-speed USB device number 10 using xhci_hcd [3266355.333031] usb 1-3: New USB device found, idVendor=0603, idProduct=8611, bcdDevice= 1.00 [3266355.333040] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [3266355.333043] usb 1-3: Product: YICARCAM [3266355.333045] usb 1-3: Manufacturer: XIAO-YI [3266355.333047] usb 1-3: SerialNumber: 966110000000100 [3266355.338621] usb-storage 1-3:1.0: USB Mass Storage device detected [3266355.338817] usb-storage 1-3:1.0: Quirks match for vid 0603 pid 8611: 4000 [3266355.338821] usb-storage 1-3:1.0: This device (0603,8611,0100 S 06 P 50) has unneeded SubClass and Protocol entries in unusual_devs.h (kernel 6.16.10-arch1-1) Please send a copy of this message to and The overrides are harmless but they do provoke the driver into logging this annoying message. Update the entry to remove the unneeded entries. Reported-by: stealth Closes: https://lore.kernel.org/CAKxjRRxhC0s19iEWoN=pEMqXJ_z8w_moC0GCXSqSKCcOddnWjQ@mail.gmail.com/ Fixes: 6ca8af3c8fb5 ("USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera") Signed-off-by: Alan Stern Cc: stable Link: https://patch.msgid.link/b440f177-f0b8-4d5a-8f7b-10855d4424ee@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index dfa5276a5a43..47f50d7a385c 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -938,7 +938,7 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, UNUSUAL_DEV( 0x0603, 0x8611, 0x0000, 0xffff, "Novatek", "NTK96550-based camera", - USB_SC_SCSI, USB_PR_BULK, NULL, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_BULK_IGNORE_TAG ), /* -- Gitee From 0fd5a8b5e4405e3d2fcebd5be181fcbefa000fde Mon Sep 17 00:00:00 2001 From: Tianchu Chen Date: Sun, 16 Nov 2025 12:46:18 +0800 Subject: [PATCH 0145/1449] usb: storage: sddr55: Reject out-of-bound new_pba ANBZ: #35228 commit 04a8a6393f3f2f471e05eacca33282dd30b01432 stable. commit b59d4fda7e7d0aff1043a7f742487cb829f5aac1 upstream. Discovered by Atuin - Automated Vulnerability Discovery Engine. new_pba comes from the status packet returned after each write. A bogus device could report values beyond the block count derived from info->capacity, letting the driver walk off the end of pba_to_lba[] and corrupt heap memory. Reject PBAs that exceed the computed block count and fail the transfer so we avoid touching out-of-range mapping entries. Signed-off-by: Tianchu Chen Cc: stable Link: https://patch.msgid.link/B2DC73A3EE1E3A1D+202511161322001664687@tencent.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/storage/sddr55.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 15dc25801cdc..f53b2471a21c 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -469,6 +469,12 @@ static int sddr55_write_data(struct us_data *us, new_pba = (status[3] + (status[4] << 8) + (status[5] << 16)) >> info->blockshift; + /* check if device-reported new_pba is out of range */ + if (new_pba >= (info->capacity >> (info->blockshift + info->pageshift))) { + result = USB_STOR_TRANSPORT_FAILED; + goto leave; + } + /* check status for error */ if (status[0] == 0xff && status[1] == 0x4) { info->pba_to_lba[new_pba] = BAD_BLOCK; -- Gitee From 113d8895bf6736ed40f81b50961f2e38a53ff8fe Mon Sep 17 00:00:00 2001 From: Owen Gu Date: Thu, 20 Nov 2025 20:33:36 +0800 Subject: [PATCH 0146/1449] usb: uas: fix urb unmapping issue when the uas device is remove during ongoing data transfer ANBZ: #35228 commit e3a55221f4de080cb7a91ba10f01c4f708603f8d stable. commit 26d56a9fcb2014b99e654127960aa0a48a391e3c upstream. When a UAS device is unplugged during data transfer, there is a probability of a system panic occurring. The root cause is an access to an invalid memory address during URB callback handling. Specifically, this happens when the dma_direct_unmap_sg() function is called within the usb_hcd_unmap_urb_for_dma() interface, but the sg->dma_address field is 0 and the sg data structure has already been freed. The SCSI driver sends transfer commands by invoking uas_queuecommand_lck() in uas.c, using the uas_submit_urbs() function to submit requests to USB. Within the uas_submit_urbs() implementation, three URBs (sense_urb, data_urb, and cmd_urb) are sequentially submitted. Device removal may occur at any point during uas_submit_urbs execution, which may result in URB submission failure. However, some URBs might have been successfully submitted before the failure, and uas_submit_urbs will return the -ENODEV error code in this case. The current error handling directly calls scsi_done(). In the SCSI driver, this eventually triggers scsi_complete() to invoke scsi_end_request() for releasing the sgtable. The successfully submitted URBs, when being unlinked to giveback, call usb_hcd_unmap_urb_for_dma() in hcd.c, leading to exceptions during sg unmapping operations since the sg data structure has already been freed. This patch modifies the error condition check in the uas_submit_urbs() function. When a UAS device is removed but one or more URBs have already been successfully submitted to USB, it avoids immediately invoking scsi_done() and save the cmnd to devinfo->cmnd array. If the successfully submitted URBs is completed before devinfo->resetting being set, then the scsi_done() function will be called within uas_try_complete() after all pending URB operations are finalized. Otherwise, the scsi_done() function will be called within uas_zap_pending(), which is executed after usb_kill_anchored_urbs(). The error handling only takes effect when uas_queuecommand_lck() calls uas_submit_urbs() and returns the error value -ENODEV . In this case, the device is disconnected, and the flow proceeds to uas_disconnect(), where uas_zap_pending() is invoked to call uas_try_complete(). Fixes: eb2a86ae8c54 ("USB: UAS: fix disconnect by unplugging a hub") Cc: stable Signed-off-by: Yu Chen Signed-off-by: Owen Gu Acked-by: Oliver Neukum Link: https://patch.msgid.link/20251120123336.3328-1-guhuinan@xiaomi.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/storage/uas.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index f794cb39cc31..b54b4bfeb45e 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -697,6 +697,10 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd) * of queueing, no matter how fatal the error */ if (err == -ENODEV) { + if (cmdinfo->state & (COMMAND_INFLIGHT | DATA_IN_URB_INFLIGHT | + DATA_OUT_URB_INFLIGHT)) + goto out; + set_host_byte(cmnd, DID_NO_CONNECT); scsi_done(cmnd); goto zombie; @@ -710,6 +714,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd) uas_add_work(cmnd); } +out: devinfo->cmnd[idx] = cmnd; zombie: spin_unlock_irqrestore(&devinfo->lock, flags); -- Gitee From c1708d3205a634a1b4e35b0aabc82f94b7bd402f Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 6 Nov 2025 19:59:26 +0800 Subject: [PATCH 0147/1449] usb: dwc3: pci: add support for the Intel Nova Lake -S ANBZ: #35228 commit 9dab9859b10efecd68049af4d4cc9d3e801dc1c2 stable. commit c57ce99ec6cb55b53910b6b3d7437f80159ff9d8 upstream. This patch adds the necessary PCI ID for Intel Nova Lake -S devices. Signed-off-by: Heikki Krogerus Cc: stable Acked-by: Thinh Nguyen Link: https://patch.msgid.link/20251106115926.2317877-1-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/dwc3-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 39c72cb52ce7..c2bab6d4d507 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -53,6 +53,7 @@ #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1 #define PCI_DEVICE_ID_INTEL_MTLS 0x7f6f #define PCI_DEVICE_ID_INTEL_MTL 0x7e7e +#define PCI_DEVICE_ID_INTEL_NVLS_PCH 0x6e6f #define PCI_DEVICE_ID_INTEL_ARLH_PCH 0x777e #define PCI_DEVICE_ID_INTEL_TGL 0x9a15 #define PCI_DEVICE_ID_INTEL_PTLH 0xe332 @@ -443,6 +444,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE_DATA(INTEL, MTLM, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, MTLP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, MTL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, NVLS_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, MTLS, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ARLH_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, TGL, &dwc3_pci_intel_swnode) }, -- Gitee From e89c7a386b57ce21c588463bca64e6aa164e4263 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 7 Nov 2025 20:15:47 +0800 Subject: [PATCH 0148/1449] usb: dwc3: pci: Sort out the Intel device IDs ANBZ: #35228 commit 5428c75e92e4f951ff963ce5f4d4dbe3ba4ab0c0 stable. commit 46b28d2fbd13148981d91246bc0e13f4fc055987 upstream. The PCI device IDs were organised based on the Intel architecture generation in most cases, but not with every ID. That left the device ID table with no real order. Sorting the table based on the device ID. Suggested-by: Thinh Nguyen Cc: stable Signed-off-by: Heikki Krogerus Acked-by: Thinh Nguyen Link: https://patch.msgid.link/20251107121548.2702900-1-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/dwc3-pci.c | 82 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index c2bab6d4d507..8f5faf632a8b 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -21,41 +21,41 @@ #include #include +#define PCI_DEVICE_ID_INTEL_CMLLP 0x02ee +#define PCI_DEVICE_ID_INTEL_CMLH 0x06ee +#define PCI_DEVICE_ID_INTEL_BXT 0x0aaa #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e -#define PCI_DEVICE_ID_INTEL_BSW 0x22b7 -#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 -#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 -#define PCI_DEVICE_ID_INTEL_BXT 0x0aaa #define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa -#define PCI_DEVICE_ID_INTEL_APL 0x5aaa -#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 -#define PCI_DEVICE_ID_INTEL_CMLLP 0x02ee -#define PCI_DEVICE_ID_INTEL_CMLH 0x06ee +#define PCI_DEVICE_ID_INTEL_BSW 0x22b7 #define PCI_DEVICE_ID_INTEL_GLK 0x31aa -#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee -#define PCI_DEVICE_ID_INTEL_CNPH 0xa36e -#define PCI_DEVICE_ID_INTEL_CNPV 0xa3b0 #define PCI_DEVICE_ID_INTEL_ICLLP 0x34ee -#define PCI_DEVICE_ID_INTEL_EHL 0x4b7e -#define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee #define PCI_DEVICE_ID_INTEL_TGPH 0x43ee -#define PCI_DEVICE_ID_INTEL_JSP 0x4dee -#define PCI_DEVICE_ID_INTEL_WCL 0x4d7e #define PCI_DEVICE_ID_INTEL_ADL 0x460e -#define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee #define PCI_DEVICE_ID_INTEL_ADLN 0x465e +#define PCI_DEVICE_ID_INTEL_EHL 0x4b7e +#define PCI_DEVICE_ID_INTEL_WCL 0x4d7e +#define PCI_DEVICE_ID_INTEL_JSP 0x4dee +#define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee #define PCI_DEVICE_ID_INTEL_ADLN_PCH 0x54ee -#define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 -#define PCI_DEVICE_ID_INTEL_RPL 0xa70e +#define PCI_DEVICE_ID_INTEL_APL 0x5aaa +#define PCI_DEVICE_ID_INTEL_NVLS_PCH 0x6e6f +#define PCI_DEVICE_ID_INTEL_ARLH_PCH 0x777e #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61 +#define PCI_DEVICE_ID_INTEL_MTL 0x7e7e +#define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 #define PCI_DEVICE_ID_INTEL_MTLM 0x7eb1 #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1 #define PCI_DEVICE_ID_INTEL_MTLS 0x7f6f -#define PCI_DEVICE_ID_INTEL_MTL 0x7e7e -#define PCI_DEVICE_ID_INTEL_NVLS_PCH 0x6e6f -#define PCI_DEVICE_ID_INTEL_ARLH_PCH 0x777e #define PCI_DEVICE_ID_INTEL_TGL 0x9a15 +#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 +#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee +#define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee +#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 +#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 +#define PCI_DEVICE_ID_INTEL_CNPH 0xa36e +#define PCI_DEVICE_ID_INTEL_CNPV 0xa3b0 +#define PCI_DEVICE_ID_INTEL_RPL 0xa70e #define PCI_DEVICE_ID_INTEL_PTLH 0xe332 #define PCI_DEVICE_ID_INTEL_PTLH_PCH 0xe37e #define PCI_DEVICE_ID_INTEL_PTLU 0xe432 @@ -413,41 +413,41 @@ static void dwc3_pci_remove(struct pci_dev *pci) } static const struct pci_device_id dwc3_pci_id_table[] = { - { PCI_DEVICE_DATA(INTEL, BSW, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, BYT, &dwc3_pci_intel_byt_swnode) }, - { PCI_DEVICE_DATA(INTEL, MRFLD, &dwc3_pci_intel_mrfld_swnode) }, { PCI_DEVICE_DATA(INTEL, CMLLP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, CMLH, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, SPTLP, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, SPTH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, BXT, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, BYT, &dwc3_pci_intel_byt_swnode) }, + { PCI_DEVICE_DATA(INTEL, MRFLD, &dwc3_pci_intel_mrfld_swnode) }, { PCI_DEVICE_DATA(INTEL, BXT_M, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, APL, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, KBP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, BSW, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, GLK, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, CNPLP, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, CNPH, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, CNPV, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ICLLP, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, EHL, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, EHL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADLN_PCH, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, ADLS, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, RPL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, APL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, NVLS_PCH, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, ARLH_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, RPLS, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, MTL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, ADLS, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, MTLM, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, MTLP, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, MTL, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, NVLS_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, MTLS, &dwc3_pci_intel_swnode) }, - { PCI_DEVICE_DATA(INTEL, ARLH_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, TGL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, SPTLP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, CNPLP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, SPTH, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, KBP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, CNPH, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, CNPV, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, RPL, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, PTLH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, PTLH_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, PTLU, &dwc3_pci_intel_swnode) }, -- Gitee From 4b0721b7cc632177d55af550b33ff6f0d023dfa4 Mon Sep 17 00:00:00 2001 From: Manish Nagar Date: Thu, 20 Nov 2025 15:44:35 +0800 Subject: [PATCH 0149/1449] usb: dwc3: Fix race condition between concurrent dwc3_remove_requests() call paths ANBZ: #35228 commit afc0e34f161ce61ad351303c46eb57bd44b8b090 stable. commit e4037689a366743c4233966f0e74bc455820d316 upstream. This patch addresses a race condition caused by unsynchronized execution of multiple call paths invoking `dwc3_remove_requests()`, leading to premature freeing of USB requests and subsequent crashes. Three distinct execution paths interact with `dwc3_remove_requests()`: Path 1: Triggered via `dwc3_gadget_reset_interrupt()` during USB reset handling. The call stack includes: - `dwc3_ep0_reset_state()` - `dwc3_ep0_stall_and_restart()` - `dwc3_ep0_out_start()` - `dwc3_remove_requests()` - `dwc3_gadget_del_and_unmap_request()` Path 2: Also initiated from `dwc3_gadget_reset_interrupt()`, but through `dwc3_stop_active_transfers()`. The call stack includes: - `dwc3_stop_active_transfers()` - `dwc3_remove_requests()` - `dwc3_gadget_del_and_unmap_request()` Path 3: Occurs independently during `adb root` execution, which triggers USB function unbind and bind operations. The sequence includes: - `gserial_disconnect()` - `usb_ep_disable()` - `dwc3_gadget_ep_disable()` - `dwc3_remove_requests()` with `-ESHUTDOWN` status Path 3 operates asynchronously and lacks synchronization with Paths 1 and 2. When Path 3 completes, it disables endpoints and frees 'out' requests. If Paths 1 or 2 are still processing these requests, accessing freed memory leads to a crash due to use-after-free conditions. To fix this added check for request completion and skip processing if already completed and added the request status for ep0 while queue. Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver") Cc: stable Suggested-by: Thinh Nguyen Acked-by: Thinh Nguyen Signed-off-by: Manish Nagar Link: https://patch.msgid.link/20251120074435.1983091-1-manish.nagar@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/ep0.c | 1 + drivers/usb/dwc3/gadget.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 876a839f2d1d..bcc9cc398068 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -94,6 +94,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, req->request.actual = 0; req->request.status = -EINPROGRESS; req->epnum = dep->number; + req->status = DWC3_REQUEST_STATUS_QUEUED; list_add_tail(&req->list, &dep->pending_list); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 6e90f2ad0426..821e51eada18 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -229,6 +229,13 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, { struct dwc3 *dwc = dep->dwc; + /* + * The request might have been processed and completed while the + * spinlock was released. Skip processing if already completed. + */ + if (req->status == DWC3_REQUEST_STATUS_COMPLETED) + return; + dwc3_gadget_del_and_unmap_request(dep, req, status); req->status = DWC3_REQUEST_STATUS_COMPLETED; -- Gitee From 5ca1e4c9aa79e33e7ce81446c75977cece179367 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Sat, 8 Nov 2025 00:28:17 +0800 Subject: [PATCH 0150/1449] xhci: dbgtty: Fix data corruption when transmitting data form DbC to host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit da7a52bcee3f8d828789f1d012262482a712c883 stable. commit f6bb3b67be9af0cfb90075c60850b6af5338a508 upstream. Data read from a DbC device may be corrupted due to a race between ongoing write and write request completion handler both queuing new transfer blocks (TRBs) if there are remining data in the kfifo. TRBs may be in incorrct order compared to the data in the kfifo. Driver fails to keep lock between reading data from kfifo into a dbc request buffer, and queuing the request to the transfer ring. This allows completed request to re-queue itself in the middle of an ongoing transfer loop, forcing itself between a kfifo read and request TRB write of another request cpu0 cpu1 (re-queue completed req2) lock(port_lock) dbc_start_tx() kfifo_out(fifo, req1->buffer) unlock(port_lock) lock(port_lock) dbc_write_complete(req2) dbc_start_tx() kfifo_out(fifo, req2->buffer) unlock(port_lock) lock(port_lock) req2->trb = ring->enqueue; ring->enqueue++ unlock(port_lock) lock(port_lock) req1->trb = ring->enqueue; ring->enqueue++ unlock(port_lock) In the above scenario a kfifo containing "12345678" would read "1234" to req1 and "5678" to req2, but req2 is queued before req1 leading to data being transmitted as "56781234" Solve this by adding a flag that prevents starting a new tx if we are already mid dbc_start_tx() during the unlocked part. The already running dbc_do_start_tx() will make sure the newly completed request gets re-queued as it is added to the request write_pool while holding the lock. Cc: stable@vger.kernel.org Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") Tested-by: Łukasz Bartosik Signed-off-by: Mathias Nyman Link: https://patch.msgid.link/20251107162819.1362579-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/xhci-dbgcap.h | 1 + drivers/usb/host/xhci-dbgtty.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h index 1fab3eb9c831..e6aab11ed6f2 100644 --- a/drivers/usb/host/xhci-dbgcap.h +++ b/drivers/usb/host/xhci-dbgcap.h @@ -113,6 +113,7 @@ struct dbc_port { unsigned int tx_boundary; bool registered; + bool tx_running; }; struct dbc_driver { diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index aa689fbd3dce..098735d65092 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -47,7 +47,7 @@ dbc_kfifo_to_req(struct dbc_port *port, char *packet) return len; } -static int dbc_start_tx(struct dbc_port *port) +static int dbc_do_start_tx(struct dbc_port *port) __releases(&port->port_lock) __acquires(&port->port_lock) { @@ -57,6 +57,8 @@ static int dbc_start_tx(struct dbc_port *port) bool do_tty_wake = false; struct list_head *pool = &port->write_pool; + port->tx_running = true; + while (!list_empty(pool)) { req = list_entry(pool->next, struct dbc_request, list_pool); len = dbc_kfifo_to_req(port, req->buf); @@ -77,12 +79,25 @@ static int dbc_start_tx(struct dbc_port *port) } } + port->tx_running = false; + if (do_tty_wake && port->port.tty) tty_wakeup(port->port.tty); return status; } +/* must be called with port->port_lock held */ +static int dbc_start_tx(struct dbc_port *port) +{ + lockdep_assert_held(&port->port_lock); + + if (port->tx_running) + return -EBUSY; + + return dbc_do_start_tx(port); +} + static void dbc_start_rx(struct dbc_port *port) __releases(&port->port_lock) __acquires(&port->port_lock) -- Gitee From 67adf549cb1d9ad92ea9ea22a5f7ce19d15b370a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= Date: Thu, 20 Nov 2025 05:29:09 +0800 Subject: [PATCH 0151/1449] xhci: dbgtty: fix device unregister MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit b75d2030170342a8235ee4f769b35cb2999a36a6 stable. commit 1f73b8b56cf35de29a433aee7bfff26cea98be3f upstream. When DbC is disconnected then xhci_dbc_tty_unregister_device() is called. However if there is any user space process blocked on write to DbC terminal device then it will never be signalled and thus stay blocked indifinitely. This fix adds a tty_vhangup() call in xhci_dbc_tty_unregister_device(). The tty_vhangup() wakes up any blocked writers and causes subsequent write attempts to DbC terminal device to fail. Cc: stable Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") Signed-off-by: Łukasz Bartosik Link: https://patch.msgid.link/20251119212910.1245694-1-ukaszb@google.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/xhci-dbgtty.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index 098735d65092..f2c74e20b572 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -518,6 +518,12 @@ static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc) if (!port->registered) return; + /* + * Hang up the TTY. This wakes up any blocked + * writers and causes subsequent writes to fail. + */ + tty_vhangup(port->port.tty); + tty_unregister_device(dbc_tty_driver, port->minor); xhci_dbc_tty_exit_port(port); port->registered = false; -- Gitee From a70c51b884bb86628e1653283eef1476426ecde0 Mon Sep 17 00:00:00 2001 From: Oleksandr Suvorov Date: Thu, 30 Oct 2025 23:42:54 +0800 Subject: [PATCH 0152/1449] USB: serial: ftdi_sio: add support for u-blox EVK-M101 ANBZ: #35228 commit 17cab1f3aefb37d1d6a2b25aaff301d600789470 stable. commit 2d8ab771d5316de64f3bb920b82575c58eb00b1b upstream. The U-Blox EVK-M101 enumerates as 1546:0506 [1] with four FTDI interfaces: - EVK-M101 current sensors - EVK-M101 I2C - EVK-M101 UART - EVK-M101 port D Only the third USB interface is a UART. This change lets ftdi_sio probe the VID/PID and registers only interface #3 as a TTY, leaving the rest available for other drivers. [1] usb 5-1.3: new high-speed USB device number 11 using xhci_hcd usb 5-1.3: New USB device found, idVendor=1546, idProduct=0506, bcdDevice= 8.00 usb 5-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 5-1.3: Product: EVK-M101 usb 5-1.3: Manufacturer: u-blox AG Datasheet: https://content.u-blox.com/sites/default/files/documents/EVK-M10_UserGuide_UBX-21003949.pdf Signed-off-by: Oleksandr Suvorov Link: https://lore.kernel.org/20250926060235.3442748-1-cryosay@gmail.com/ Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8906c9dc348e..2bc5d21ef6b9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1074,6 +1074,7 @@ static const struct usb_device_id id_table_combined[] = { /* U-Blox devices */ { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, + { USB_DEVICE_INTERFACE_NUMBER(UBLOX_VID, UBLOX_EVK_M101_PID, 2) }, /* FreeCalypso USB adapters */ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 4cc1fae8acb9..2539b9e2f712 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1614,6 +1614,7 @@ #define UBLOX_VID 0x1546 #define UBLOX_C099F9P_ZED_PID 0x0502 #define UBLOX_C099F9P_ODIN_PID 0x0503 +#define UBLOX_EVK_M101_PID 0x0506 /* * GMC devices -- Gitee From 515d54fc31593956e2940223d1e84bda1f6d339e Mon Sep 17 00:00:00 2001 From: Vanillan Wang Date: Mon, 10 Nov 2025 12:20:41 +0800 Subject: [PATCH 0153/1449] USB: serial: option: add support for Rolling RW101R-GL ANBZ: #35228 commit 28a385af4a94426556b5f01bebda1b1a44cbe444 stable. commit 523bf0a59e674b52e4b5607a2aba655fbfa20ff2 upstream. - VID:PID 33f8:0301, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS) 0x0301: mbim, pipe T: Bus=04 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=33f8 ProdID=0301 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms - VID:PID 33f8:01a8, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS) 0x01a8: mbim, diag, AT, ADB, pipe1, pipe2 T: Bus=04 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=33f8 ProdID=01a8 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 10 Ivl=32ms - VID:PID 33f8:0302, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS) 0x0302: mbim, pipe T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=33f8 ProdID=0302 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms - VID:PID 33f8:01a9, RW101R-GL for laptop debug M.2 cards (with MBIM interface for Linux/Chrome OS) 0x01a9: mbim, diag, AT, ADB, pipe1, pipe2 T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=33f8 ProdID=01a9 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW101R-GL Module S: SerialNumber=3ec4efdf C: #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 10 Ivl=32ms Signed-off-by: Vanillan Wang Cc: stable@vger.kernel.org [ johan: sort vendor entries, edit commit message slightly ] Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/option.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e9d0d8591a01..8cc4ed4857cd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2424,12 +2424,18 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ { USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */ + .driver_info = RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a3, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a4, 0xff), /* Rolling RW101-GL (laptop MBIM) */ .driver_info = RSVD(4) }, - { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */ - .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a8, 0xff), /* Rolling RW101R-GL (laptop MBIM) */ + .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a9, 0xff), /* Rolling RW101R-GL (laptop MBIM) */ + .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0301, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0302, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0802, 0xff), /* Rolling RW350-GL (laptop MBIM) */ .driver_info = RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */ -- Gitee From 0f11cb944619cca339bc592e82f0742962e1fef0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 22 Sep 2025 20:20:12 +0800 Subject: [PATCH 0154/1449] drm: sti: fix device leaks at component probe ANBZ: #35228 commit 748ed1b6a2ca79a4330de1e1360970525ba92632 stable. commit 620a8f131154250f6a64a07d049a4f235d6451a5 upstream. Make sure to drop the references taken to the vtg devices by of_find_device_by_node() when looking up their driver data during component probe. Note that holding a reference to a platform device does not prevent its driver data from going away so there is no point in keeping the reference after the lookup helper returns. Fixes: cc6b741c6f63 ("drm: sti: remove useless fields from vtg structure") Cc: stable@vger.kernel.org # 4.16 Cc: Benjamin Gaignard Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20250922122012.27407-1-johan@kernel.org Signed-off-by: Raphael Gallais-Pou Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/sti/sti_vtg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c index 5e5f82b6a5d9..644837fb8623 100644 --- a/drivers/gpu/drm/sti/sti_vtg.c +++ b/drivers/gpu/drm/sti/sti_vtg.c @@ -143,12 +143,17 @@ struct sti_vtg { struct sti_vtg *of_vtg_find(struct device_node *np) { struct platform_device *pdev; + struct sti_vtg *vtg; pdev = of_find_device_by_node(np); if (!pdev) return NULL; - return (struct sti_vtg *)platform_get_drvdata(pdev); + vtg = platform_get_drvdata(pdev); + + put_device(&pdev->dev); + + return vtg; } static void vtg_reset(struct sti_vtg *vtg) -- Gitee From 3318e6cfbe1f08fba758eab5a6a215a585da985b Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Sat, 8 Nov 2025 06:35:58 +0800 Subject: [PATCH 0155/1449] drm/amd/display: Check NULL before accessing ANBZ: #35228 commit 9d1a65cbe3ec5da3003c8434ac7a38dcdc958fd9 stable. commit 3ce62c189693e8ed7b3abe551802bbc67f3ace54 upstream. [WHAT] IGT kms_cursor_legacy's long-nonblocking-modeset-vs-cursor-atomic fails with NULL pointer dereference. This can be reproduced with both an eDP panel and a DP monitors connected. BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 13 UID: 0 PID: 2960 Comm: kms_cursor_lega Not tainted 6.16.0-99-custom #8 PREEMPT(voluntary) Hardware name: AMD ........ RIP: 0010:dc_stream_get_scanoutpos+0x34/0x130 [amdgpu] Code: 57 4d 89 c7 41 56 49 89 ce 41 55 49 89 d5 41 54 49 89 fc 53 48 83 ec 18 48 8b 87 a0 64 00 00 48 89 75 d0 48 c7 c6 e0 41 30 c2 <48> 8b 38 48 8b 9f 68 06 00 00 e8 8d d7 fd ff 31 c0 48 81 c3 e0 02 RSP: 0018:ffffd0f3c2bd7608 EFLAGS: 00010292 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffd0f3c2bd7668 RDX: ffffd0f3c2bd7664 RSI: ffffffffc23041e0 RDI: ffff8b32494b8000 RBP: ffffd0f3c2bd7648 R08: ffffd0f3c2bd766c R09: ffffd0f3c2bd7760 R10: ffffd0f3c2bd7820 R11: 0000000000000000 R12: ffff8b32494b8000 R13: ffffd0f3c2bd7664 R14: ffffd0f3c2bd7668 R15: ffffd0f3c2bd766c FS: 000071f631b68700(0000) GS:ffff8b399f114000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001b8105000 CR4: 0000000000f50ef0 PKRU: 55555554 Call Trace: dm_crtc_get_scanoutpos+0xd7/0x180 [amdgpu] amdgpu_display_get_crtc_scanoutpos+0x86/0x1c0 [amdgpu] ? __pfx_amdgpu_crtc_get_scanout_position+0x10/0x10[amdgpu] amdgpu_crtc_get_scanout_position+0x27/0x50 [amdgpu] drm_crtc_vblank_helper_get_vblank_timestamp_internal+0xf7/0x400 drm_crtc_vblank_helper_get_vblank_timestamp+0x1c/0x30 drm_crtc_get_last_vbltimestamp+0x55/0x90 drm_crtc_next_vblank_start+0x45/0xa0 drm_atomic_helper_wait_for_fences+0x81/0x1f0 ... Cc: Mario Limonciello Cc: Alex Deucher Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Hung Signed-off-by: Alex Deucher (cherry picked from commit 621e55f1919640acab25383362b96e65f2baea3c) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index ebe571fcefe3..0e210407131e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -634,9 +634,14 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream, { uint8_t i; bool ret = false; - struct dc *dc = stream->ctx->dc; - struct resource_context *res_ctx = - &dc->current_state->res_ctx; + struct dc *dc; + struct resource_context *res_ctx; + + if (!stream->ctx) + return false; + + dc = stream->ctx->dc; + res_ctx = &dc->current_state->res_ctx; for (i = 0; i < MAX_PIPES; i++) { struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; -- Gitee From 56a47260f0bd88fb3345b8373799dca0ae83669c Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Thu, 20 Nov 2025 17:12:00 +0800 Subject: [PATCH 0156/1449] net: dsa: microchip: common: Fix checks on irq_find_mapping() ANBZ: #35228 commit 1759edf0e688a58989c60efd4f621d9059dcf5d6 stable. commit 7b3c09e1667977edee11de94a85e2593a7c15e87 upstream. irq_find_mapping() returns a positive IRQ number or 0 if no IRQ is found but it never returns a negative value. However, on each irq_find_mapping() call, we verify that the returned value isn't negative. Fix the irq_find_mapping() checks to enter error paths when 0 is returned. Return -EINVAL in such cases. CC: stable@vger.kernel.org Fixes: c9cd961c0d43 ("net: dsa: microchip: lan937x: add interrupt support for port phy link") Reviewed-by: Andrew Lunn Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20251120-ksz-fix-v6-1-891f80ae7f8f@bootlin.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/microchip/ksz_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index cff83a8fb7d2..a3c5a174e302 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -1870,8 +1870,8 @@ static int ksz_irq_phy_setup(struct ksz_device *dev) if (BIT(phy) & ds->phys_mii_mask) { irq = irq_find_mapping(dev->ports[phy].pirq.domain, PORT_SRC_PHY_INT); - if (irq < 0) { - ret = irq; + if (!irq) { + ret = -EINVAL; goto out; } ds->slave_mii_bus->irq[phy] = irq; @@ -2095,8 +2095,8 @@ static int ksz_pirq_setup(struct ksz_device *dev, u8 p) snprintf(pirq->name, sizeof(pirq->name), "port_irq-%d", p); pirq->irq_num = irq_find_mapping(dev->girq.domain, p); - if (pirq->irq_num < 0) - return pirq->irq_num; + if (!pirq->irq_num) + return -EINVAL; return ksz_irq_common_setup(dev, pirq); } -- Gitee From 244dc733e10047df9ce78633729b577d516067d1 Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Thu, 20 Nov 2025 17:12:01 +0800 Subject: [PATCH 0157/1449] net: dsa: microchip: ptp: Fix checks on irq_find_mapping() ANBZ: #35228 commit 1c6fb1cc503504082319a6509060a523b13a3070 stable. commit 9e059305be41a5bd27e03458d8333cf30d70be34 upstream. irq_find_mapping() returns a positive IRQ number or 0 if no IRQ is found but it never returns a negative value. However, during the PTP IRQ setup, we verify that its returned value isn't negative. Fix the irq_find_mapping() check to enter the error path when 0 is returned. Return -EINVAL in such case. Cc: stable@vger.kernel.org Fixes: cc13ab18b201 ("net: dsa: microchip: ptp: enable interrupt for timestamping") Reviewed-by: Andrew Lunn Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20251120-ksz-fix-v6-2-891f80ae7f8f@bootlin.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/microchip/ksz_ptp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c index 7ef5fac69657..dca0c5124457 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.c +++ b/drivers/net/dsa/microchip/ksz_ptp.c @@ -1145,8 +1145,8 @@ int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p) irq_create_mapping(ptpirq->domain, irq); ptpirq->irq_num = irq_find_mapping(port->pirq.domain, PORT_SRC_PTP_INT); - if (ptpirq->irq_num < 0) { - ret = ptpirq->irq_num; + if (!ptpirq->irq_num) { + ret = -EINVAL; goto out; } -- Gitee From 9d9fe8f4d9f34cb3a672c3e7080fd5b92ae631a9 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 4 Nov 2025 04:34:01 +0800 Subject: [PATCH 0158/1449] libceph: fix potential use-after-free in have_mon_and_osd_map() ANBZ: #35228 commit 183ad6e3b651e8fb0b66d6a2678f4b80bfbba092 stable. commit 076381c261374c587700b3accf410bdd2dba334e upstream. The wait loop in __ceph_open_session() can race with the client receiving a new monmap or osdmap shortly after the initial map is received. Both ceph_monc_handle_map() and handle_one_map() install a new map immediately after freeing the old one kfree(monc->monmap); monc->monmap = monmap; ceph_osdmap_destroy(osdc->osdmap); osdc->osdmap = newmap; under client->monc.mutex and client->osdc.lock respectively, but because neither is taken in have_mon_and_osd_map() it's possible for client->monc.monmap->epoch and client->osdc.osdmap->epoch arms in client->monc.monmap && client->monc.monmap->epoch && client->osdc.osdmap && client->osdc.osdmap->epoch; condition to dereference an already freed map. This happens to be reproducible with generic/395 and generic/397 with KASAN enabled: BUG: KASAN: slab-use-after-free in have_mon_and_osd_map+0x56/0x70 Read of size 4 at addr ffff88811012d810 by task mount.ceph/13305 CPU: 2 UID: 0 PID: 13305 Comm: mount.ceph Not tainted 6.14.0-rc2-build2+ #1266 ... Call Trace: have_mon_and_osd_map+0x56/0x70 ceph_open_session+0x182/0x290 ceph_get_tree+0x333/0x680 vfs_get_tree+0x49/0x180 do_new_mount+0x1a3/0x2d0 path_mount+0x6dd/0x730 do_mount+0x99/0xe0 __do_sys_mount+0x141/0x180 do_syscall_64+0x9f/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7e Allocated by task 13305: ceph_osdmap_alloc+0x16/0x130 ceph_osdc_init+0x27a/0x4c0 ceph_create_client+0x153/0x190 create_fs_client+0x50/0x2a0 ceph_get_tree+0xff/0x680 vfs_get_tree+0x49/0x180 do_new_mount+0x1a3/0x2d0 path_mount+0x6dd/0x730 do_mount+0x99/0xe0 __do_sys_mount+0x141/0x180 do_syscall_64+0x9f/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7e Freed by task 9475: kfree+0x212/0x290 handle_one_map+0x23c/0x3b0 ceph_osdc_handle_map+0x3c9/0x590 mon_dispatch+0x655/0x6f0 ceph_con_process_message+0xc3/0xe0 ceph_con_v1_try_read+0x614/0x760 ceph_con_workfn+0x2de/0x650 process_one_work+0x486/0x7c0 process_scheduled_works+0x73/0x90 worker_thread+0x1c8/0x2a0 kthread+0x2ec/0x300 ret_from_fork+0x24/0x40 ret_from_fork_asm+0x1a/0x30 Rewrite the wait loop to check the above condition directly with client->monc.mutex and client->osdc.lock taken as appropriate. While at it, improve the timeout handling (previously mount_timeout could be exceeded in case wait_event_interruptible_timeout() slept more than once) and access client->auth_err under client->monc.mutex to match how it's set in finish_auth(). monmap_show() and osdmap_show() now take the respective lock before accessing the map as well. Cc: stable@vger.kernel.org Reported-by: David Howells Signed-off-by: Ilya Dryomov Reviewed-by: Viacheslav Dubeyko Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/ceph_common.c | 53 +++++++++++++++++++++++++----------------- net/ceph/debugfs.c | 14 +++++++---- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 4c6441536d55..285e981730e5 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -785,42 +785,53 @@ void ceph_reset_client_addr(struct ceph_client *client) } EXPORT_SYMBOL(ceph_reset_client_addr); -/* - * true if we have the mon map (and have thus joined the cluster) - */ -static bool have_mon_and_osd_map(struct ceph_client *client) -{ - return client->monc.monmap && client->monc.monmap->epoch && - client->osdc.osdmap && client->osdc.osdmap->epoch; -} - /* * mount: join the ceph cluster, and open root directory. */ int __ceph_open_session(struct ceph_client *client, unsigned long started) { - unsigned long timeout = client->options->mount_timeout; - long err; + DEFINE_WAIT_FUNC(wait, woken_wake_function); + long timeout = ceph_timeout_jiffies(client->options->mount_timeout); + bool have_monmap, have_osdmap; + int err; /* open session, and wait for mon and osd maps */ err = ceph_monc_open_session(&client->monc); if (err < 0) return err; - while (!have_mon_and_osd_map(client)) { - if (timeout && time_after_eq(jiffies, started + timeout)) - return -ETIMEDOUT; + add_wait_queue(&client->auth_wq, &wait); + for (;;) { + mutex_lock(&client->monc.mutex); + err = client->auth_err; + have_monmap = client->monc.monmap && client->monc.monmap->epoch; + mutex_unlock(&client->monc.mutex); + + down_read(&client->osdc.lock); + have_osdmap = client->osdc.osdmap && client->osdc.osdmap->epoch; + up_read(&client->osdc.lock); + + if (err || (have_monmap && have_osdmap)) + break; + + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; + } + + if (!timeout) { + err = -ETIMEDOUT; + break; + } /* wait */ dout("mount waiting for mon_map\n"); - err = wait_event_interruptible_timeout(client->auth_wq, - have_mon_and_osd_map(client) || (client->auth_err < 0), - ceph_timeout_jiffies(timeout)); - if (err < 0) - return err; - if (client->auth_err < 0) - return client->auth_err; + timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout); } + remove_wait_queue(&client->auth_wq, &wait); + + if (err) + return err; pr_info("client%llu fsid %pU\n", ceph_client_gid(client), &client->fsid); diff --git a/net/ceph/debugfs.c b/net/ceph/debugfs.c index 2110439f8a24..83c270bce63c 100644 --- a/net/ceph/debugfs.c +++ b/net/ceph/debugfs.c @@ -36,8 +36,9 @@ static int monmap_show(struct seq_file *s, void *p) int i; struct ceph_client *client = s->private; + mutex_lock(&client->monc.mutex); if (client->monc.monmap == NULL) - return 0; + goto out_unlock; seq_printf(s, "epoch %d\n", client->monc.monmap->epoch); for (i = 0; i < client->monc.monmap->num_mon; i++) { @@ -48,6 +49,9 @@ static int monmap_show(struct seq_file *s, void *p) ENTITY_NAME(inst->name), ceph_pr_addr(&inst->addr)); } + +out_unlock: + mutex_unlock(&client->monc.mutex); return 0; } @@ -56,13 +60,14 @@ static int osdmap_show(struct seq_file *s, void *p) int i; struct ceph_client *client = s->private; struct ceph_osd_client *osdc = &client->osdc; - struct ceph_osdmap *map = osdc->osdmap; + struct ceph_osdmap *map; struct rb_node *n; + down_read(&osdc->lock); + map = osdc->osdmap; if (map == NULL) - return 0; + goto out_unlock; - down_read(&osdc->lock); seq_printf(s, "epoch %u barrier %u flags 0x%x\n", map->epoch, osdc->epoch_barrier, map->flags); @@ -131,6 +136,7 @@ static int osdmap_show(struct seq_file *s, void *p) seq_printf(s, "]\n"); } +out_unlock: up_read(&osdc->lock); return 0; } -- Gitee From 09253f7613ef6ac04549d4f97f3c1e6ef36e6a2f Mon Sep 17 00:00:00 2001 From: ziming zhang Date: Fri, 14 Nov 2025 16:56:10 +0800 Subject: [PATCH 0159/1449] libceph: prevent potential out-of-bounds writes in handle_auth_session_key() ANBZ: #35228 commit ccbccfba25e9aa395daaea156b5e7790910054c4 stable. commit 7fce830ecd0a0256590ee37eb65a39cbad3d64fc upstream. The len field originates from untrusted network packets. Boundary checks have been added to prevent potential out-of-bounds writes when decrypting the connection secret or processing service tickets. [ idryomov: changelog ] Cc: stable@vger.kernel.org Signed-off-by: ziming zhang Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/auth_x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index b71b1635916e..a21c157daf7d 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -631,6 +631,7 @@ static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id, /* connection secret */ ceph_decode_32_safe(p, end, len, e_inval); + ceph_decode_need(p, end, len, e_inval); dout("%s connection secret blob len %d\n", __func__, len); if (len > 0) { dp = *p + ceph_x_encrypt_offset(); @@ -648,6 +649,7 @@ static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id, /* service tickets */ ceph_decode_32_safe(p, end, len, e_inval); + ceph_decode_need(p, end, len, e_inval); dout("%s service tickets blob len %d\n", __func__, len); if (len > 0) { ret = ceph_x_proc_ticket_reply(ac, &th->session_key, -- Gitee From 2aff4f307f6ea061f73f1337ab18aa42504b6be7 Mon Sep 17 00:00:00 2001 From: ziming zhang Date: Mon, 17 Nov 2025 18:07:41 +0800 Subject: [PATCH 0160/1449] libceph: replace BUG_ON with bounds check for map->max_osd ANBZ: #35228 commit becc488a4d864db338ebd4e313aa3c77da24b604 stable. commit ec3797f043756a94ea2d0f106022e14ac4946c02 upstream. OSD indexes come from untrusted network packets. Boundary checks are added to validate these against map->max_osd. [ idryomov: drop BUG_ON in ceph_get_primary_affinity(), minor cosmetic edits ] Cc: stable@vger.kernel.org Signed-off-by: ziming zhang Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/osdmap.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 295098873861..d245fa508e1c 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -1504,8 +1504,6 @@ static int decode_new_primary_temp(void **p, void *end, u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd) { - BUG_ON(osd >= map->max_osd); - if (!map->osd_primary_affinity) return CEPH_OSD_DEFAULT_PRIMARY_AFFINITY; @@ -1514,8 +1512,6 @@ u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd) static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff) { - BUG_ON(osd >= map->max_osd); - if (!map->osd_primary_affinity) { int i; @@ -1577,6 +1573,8 @@ static int decode_new_primary_affinity(void **p, void *end, ceph_decode_32_safe(p, end, osd, e_inval); ceph_decode_32_safe(p, end, aff, e_inval); + if (osd >= map->max_osd) + goto e_inval; ret = set_primary_affinity(map, osd, aff); if (ret) @@ -1879,7 +1877,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, ceph_decode_need(p, end, 2*sizeof(u32), e_inval); osd = ceph_decode_32(p); w = ceph_decode_32(p); - BUG_ON(osd >= map->max_osd); + if (osd >= map->max_osd) + goto e_inval; + osdmap_info(map, "osd%d weight 0x%x %s\n", osd, w, w == CEPH_OSD_IN ? "(in)" : (w == CEPH_OSD_OUT ? "(out)" : "")); @@ -1905,13 +1905,15 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, u32 xorstate; osd = ceph_decode_32(p); + if (osd >= map->max_osd) + goto e_inval; + if (struct_v >= 5) xorstate = ceph_decode_32(p); else xorstate = ceph_decode_8(p); if (xorstate == 0) xorstate = CEPH_OSD_UP; - BUG_ON(osd >= map->max_osd); if ((map->osd_state[osd] & CEPH_OSD_UP) && (xorstate & CEPH_OSD_UP)) osdmap_info(map, "osd%d down\n", osd); @@ -1937,7 +1939,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, struct ceph_entity_addr addr; osd = ceph_decode_32(p); - BUG_ON(osd >= map->max_osd); + if (osd >= map->max_osd) + goto e_inval; + if (struct_v >= 7) ret = ceph_decode_entity_addrvec(p, end, msgr2, &addr); else -- Gitee From 5b46fb539c01dfd4da6bda0af05fd7e011ea7968 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Fri, 28 Nov 2025 17:26:17 +0800 Subject: [PATCH 0161/1449] bonding: return detailed error when loading native XDP fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 694a354ddf98c0a69ee0686bea099d23d3355d51 stable. commit 22ccb684c1cae37411450e6e86a379cd3c29cb8f upstream. Bonding only supports native XDP for specific modes, which can lead to confusion for users regarding why XDP loads successfully at times and fails at others. This patch enhances error handling by returning detailed error messages, providing users with clearer insights into the specific reasons for the failure when loading native XDP. Reviewed-by: Nikolay Aleksandrov Reviewed-by: Toke Høiland-Jørgensen Signed-off-by: Hangbin Liu Link: https://patch.msgid.link/20241021031211.814-2-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/bonding/bond_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 31248e5ccbb6..f6dfd03690a6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5663,8 +5663,11 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog, ASSERT_RTNL(); - if (!bond_xdp_check(bond)) + if (!bond_xdp_check(bond)) { + BOND_NL_ERR(dev, extack, + "No native XDP support for the current bonding mode"); return -EOPNOTSUPP; + } old_prog = bond->xdp_prog; bond->xdp_prog = prog; -- Gitee From ea1f0c21a4e0726d14ca7e72cc41ed4e19d6cfa5 Mon Sep 17 00:00:00 2001 From: Wang Liang Date: Fri, 28 Nov 2025 17:26:18 +0800 Subject: [PATCH 0162/1449] bonding: check xdp prog when set bond mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 5106da73b01668a1aa5d0f352b95d2b832b5caa7 stable. commit 094ee6017ea09c11d6af187935a949df32803ce0 upstream. Following operations can trigger a warning[1]: ip netns add ns1 ip netns exec ns1 ip link add bond0 type bond mode balance-rr ip netns exec ns1 ip link set dev bond0 xdp obj af_xdp_kern.o sec xdp ip netns exec ns1 ip link set bond0 type bond mode broadcast ip netns del ns1 When delete the namespace, dev_xdp_uninstall() is called to remove xdp program on bond dev, and bond_xdp_set() will check the bond mode. If bond mode is changed after attaching xdp program, the warning may occur. Some bond modes (broadcast, etc.) do not support native xdp. Set bond mode with xdp program attached is not good. Add check for xdp program when set bond mode. [1] ------------[ cut here ]------------ WARNING: CPU: 0 PID: 11 at net/core/dev.c:9912 unregister_netdevice_many_notify+0x8d9/0x930 Modules linked in: CPU: 0 UID: 0 PID: 11 Comm: kworker/u4:0 Not tainted 6.14.0-rc4 #107 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 Workqueue: netns cleanup_net RIP: 0010:unregister_netdevice_many_notify+0x8d9/0x930 Code: 00 00 48 c7 c6 6f e3 a2 82 48 c7 c7 d0 b3 96 82 e8 9c 10 3e ... RSP: 0018:ffffc90000063d80 EFLAGS: 00000282 RAX: 00000000ffffffa1 RBX: ffff888004959000 RCX: 00000000ffffdfff RDX: 0000000000000000 RSI: 00000000ffffffea RDI: ffffc90000063b48 RBP: ffffc90000063e28 R08: ffffffff82d39b28 R09: 0000000000009ffb R10: 0000000000000175 R11: ffffffff82d09b40 R12: ffff8880049598e8 R13: 0000000000000001 R14: dead000000000100 R15: ffffc90000045000 FS: 0000000000000000(0000) GS:ffff888007a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000d406b60 CR3: 000000000483e000 CR4: 00000000000006f0 Call Trace: ? __warn+0x83/0x130 ? unregister_netdevice_many_notify+0x8d9/0x930 ? report_bug+0x18e/0x1a0 ? handle_bug+0x54/0x90 ? exc_invalid_op+0x18/0x70 ? asm_exc_invalid_op+0x1a/0x20 ? unregister_netdevice_many_notify+0x8d9/0x930 ? bond_net_exit_batch_rtnl+0x5c/0x90 cleanup_net+0x237/0x3d0 process_one_work+0x163/0x390 worker_thread+0x293/0x3b0 ? __pfx_worker_thread+0x10/0x10 kthread+0xec/0x1e0 ? __pfx_kthread+0x10/0x10 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2f/0x50 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 ---[ end trace 0000000000000000 ]--- Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver") Signed-off-by: Wang Liang Acked-by: Jussi Maki Reviewed-by: Nikolay Aleksandrov Reviewed-by: Toke Høiland-Jørgensen Link: https://patch.msgid.link/20250321044852.1086551-1-wangliang74@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/bonding/bond_main.c | 8 ++++---- drivers/net/bonding/bond_options.c | 3 +++ include/net/bonding.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f6dfd03690a6..5f30863e1906 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -322,9 +322,9 @@ static bool bond_sk_check(struct bonding *bond) } } -static bool bond_xdp_check(struct bonding *bond) +bool bond_xdp_check(struct bonding *bond, int mode) { - switch (BOND_MODE(bond)) { + switch (mode) { case BOND_MODE_ROUNDROBIN: case BOND_MODE_ACTIVEBACKUP: return true; @@ -1855,7 +1855,7 @@ void bond_xdp_set_features(struct net_device *bond_dev) ASSERT_RTNL(); - if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) { + if (!bond_xdp_check(bond, BOND_MODE(bond)) || !bond_has_slaves(bond)) { xdp_clear_features_flag(bond_dev); return; } @@ -5663,7 +5663,7 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog, ASSERT_RTNL(); - if (!bond_xdp_check(bond)) { + if (!bond_xdp_check(bond, BOND_MODE(bond))) { BOND_NL_ERR(dev, extack, "No native XDP support for the current bonding mode"); return -EOPNOTSUPP; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 8291803e4f00..a2fa068193e3 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -868,6 +868,9 @@ static bool bond_set_xfrm_features(struct bonding *bond) static int bond_option_mode_set(struct bonding *bond, const struct bond_opt_value *newval) { + if (bond->xdp_prog && !bond_xdp_check(bond, newval->value)) + return -EOPNOTSUPP; + if (!bond_mode_uses_arp(newval->value)) { if (bond->params.arp_interval) { netdev_dbg(bond->dev, "%s mode is incompatible with arp monitoring, start mii monitoring\n", diff --git a/include/net/bonding.h b/include/net/bonding.h index deff150c92f9..e25be8d9e1a6 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -697,6 +697,7 @@ void bond_debug_register(struct bonding *bond); void bond_debug_unregister(struct bonding *bond); void bond_debug_reregister(struct bonding *bond); const char *bond_mode_name(int mode); +bool bond_xdp_check(struct bonding *bond, int mode); void bond_setup(struct net_device *bond_dev); unsigned int bond_get_num_tx_queues(void); int bond_netlink_init(void); -- Gitee From f05c7949e7bae423a097079e594cd75ade7d26fe Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 15 Nov 2025 05:19:22 +0800 Subject: [PATCH 0163/1449] nfsd: Replace clamp_t in nfsd4_get_drc_mem() ANBZ: #35228 commit 0722d804f7ad664424480cbb5d08292fd8ca08fb stable. A recent change to clamp_t() in 6.1.y caused fs/nfsd/nfs4state.c to fail to compile with gcc-9. The code in nfsd4_get_drc_mem() was written with the assumption that when "max < min", clamp(val, min, max) would return max. This assumption is not documented as an API promise and the change caused a compile failure if it could be statically determined that "max < min". The relevant code was no longer present upstream when commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") landed there, so there is no upstream change to nfsd4_get_drc_mem() to backport. There is no clear case that the existing code in nfsd4_get_drc_mem() is functioning incorrectly. The goal of this patch is to permit the clean application of commit 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()"), and any commits that depend on it, to LTS kernels without affecting the ability to compile those kernels. This is done by open-coding the __clamp() macro sans the built-in type checking. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220745#c0 Signed-off-by: NeilBrown Stable-dep-of: 1519fbc8832b ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()") Signed-off-by: Chuck Lever Reviewed_by: David Laight Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/nfs4state.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 548a0ec29b66..9ef1c2372c66 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1820,8 +1820,10 @@ static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn */ scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads); - avail = clamp_t(unsigned long, avail, slotsize, - total_avail/scale_factor); + if (avail > total_avail / scale_factor) + avail = total_avail / scale_factor; + else if (avail < slotsize) + avail = slotsize; num = min_t(int, num, avail / slotsize); num = max_t(int, num, 1); nfsd_drc_mem_used += num * slotsize; -- Gitee From fbc4e0f68d816f76192b8c3dfdc12a744d643468 Mon Sep 17 00:00:00 2001 From: Kuen-Han Tsai Date: Tue, 2 Dec 2025 09:59:48 +0800 Subject: [PATCH 0164/1449] usb: udc: Add trace event for usb_gadget_set_state ANBZ: #35228 commit 92234ee7fc23186346f2c659c7d36350ad4df066 stable. commit 7bf1158514e410310aec975e630cec99d4e4092f upstream. While the userspace program can be notified of gadget state changes, timing issue can lead to missed transitions when reading the state value. Introduce a trace event for usb_gadget_set_state to reliably track state transitions. Signed-off-by: Kuen-Han Tsai Link: https://lore.kernel.org/r/20250818082722.2952867-1-khtsai@google.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: baeb66fbd420 ("usb: gadget: udc: fix use-after-free in usb_gadget_state_work") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/udc/core.c | 1 + drivers/usb/gadget/udc/trace.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 25bbb7a440ce..a2a760e716ec 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1123,6 +1123,7 @@ void usb_gadget_set_state(struct usb_gadget *gadget, { gadget->state = state; schedule_work(&gadget->work); + trace_usb_gadget_set_state(gadget, 0); } EXPORT_SYMBOL_GPL(usb_gadget_set_state); diff --git a/drivers/usb/gadget/udc/trace.h b/drivers/usb/gadget/udc/trace.h index a5ed26fbc2da..661158d3a39c 100644 --- a/drivers/usb/gadget/udc/trace.h +++ b/drivers/usb/gadget/udc/trace.h @@ -81,6 +81,11 @@ DECLARE_EVENT_CLASS(udc_log_gadget, __entry->ret) ); +DEFINE_EVENT(udc_log_gadget, usb_gadget_set_state, + TP_PROTO(struct usb_gadget *g, int ret), + TP_ARGS(g, ret) +); + DEFINE_EVENT(udc_log_gadget, usb_gadget_frame_number, TP_PROTO(struct usb_gadget *g, int ret), TP_ARGS(g, ret) -- Gitee From 51fd52215d5db8de4a4885d839fc2161f53ff028 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Tue, 2 Dec 2025 09:59:49 +0800 Subject: [PATCH 0165/1449] usb: gadget: udc: fix use-after-free in usb_gadget_state_work ANBZ: #35228 commit f02a412c0a18f02f0f91b0a3d9788315a721b7fd stable. commit baeb66fbd4201d1c4325074e78b1f557dff89b5b upstream. A race condition during gadget teardown can lead to a use-after-free in usb_gadget_state_work(), as reported by KASAN: BUG: KASAN: invalid-access in sysfs_notify+0x2c/0xd0 Workqueue: events usb_gadget_state_work The fundamental race occurs because a concurrent event (e.g., an interrupt) can call usb_gadget_set_state() and schedule gadget->work at any time during the cleanup process in usb_del_gadget(). Commit 399a45e5237c ("usb: gadget: core: flush gadget workqueue after device removal") attempted to fix this by moving flush_work() to after device_del(). However, this does not fully solve the race, as a new work item can still be scheduled *after* flush_work() completes but before the gadget's memory is freed, leading to the same use-after-free. This patch fixes the race condition robustly by introducing a 'teardown' flag and a 'state_lock' spinlock to the usb_gadget struct. The flag is set during cleanup in usb_del_gadget() *before* calling flush_work() to prevent any new work from being scheduled once cleanup has commenced. The scheduling site, usb_gadget_set_state(), now checks this flag under the lock before queueing the work, thus safely closing the race window. Fixes: 5702f75375aa9 ("usb: gadget: udc-core: move sysfs_notify() to a workqueue") Cc: stable Signed-off-by: Jimmy Hu Link: https://patch.msgid.link/20251023054945.233861-1-hhhuuu@google.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/udc/core.c | 17 ++++++++++++++++- include/linux/usb/gadget.h | 5 +++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index a2a760e716ec..0cad5cf19543 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1121,8 +1121,13 @@ static void usb_gadget_state_work(struct work_struct *work) void usb_gadget_set_state(struct usb_gadget *gadget, enum usb_device_state state) { + unsigned long flags; + + spin_lock_irqsave(&gadget->state_lock, flags); gadget->state = state; - schedule_work(&gadget->work); + if (!gadget->teardown) + schedule_work(&gadget->work); + spin_unlock_irqrestore(&gadget->state_lock, flags); trace_usb_gadget_set_state(gadget, 0); } EXPORT_SYMBOL_GPL(usb_gadget_set_state); @@ -1356,6 +1361,8 @@ static void usb_udc_nop_release(struct device *dev) void usb_initialize_gadget(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)) { + spin_lock_init(&gadget->state_lock); + gadget->teardown = false; INIT_WORK(&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent; @@ -1530,6 +1537,7 @@ EXPORT_SYMBOL_GPL(usb_add_gadget_udc); void usb_del_gadget(struct usb_gadget *gadget) { struct usb_udc *udc = gadget->udc; + unsigned long flags; if (!udc) return; @@ -1543,6 +1551,13 @@ void usb_del_gadget(struct usb_gadget *gadget) kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); sysfs_remove_link(&udc->dev.kobj, "gadget"); device_del(&gadget->dev); + /* + * Set the teardown flag before flushing the work to prevent new work + * from being scheduled while we are cleaning up. + */ + spin_lock_irqsave(&gadget->state_lock, flags); + gadget->teardown = true; + spin_unlock_irqrestore(&gadget->state_lock, flags); flush_work(&gadget->work); ida_free(&gadget_id_numbers, gadget->id_number); cancel_work_sync(&udc->vbus_work); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index aa831e16c3d3..1a13d0c01b0a 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -374,6 +374,9 @@ struct usb_gadget_ops { * can handle. The UDC must support this and all slower speeds and lower * number of lanes. * @state: the state we are now (attached, suspended, configured, etc) + * @state_lock: Spinlock protecting the `state` and `teardown` members. + * @teardown: True if the device is undergoing teardown, used to prevent + * new work from being scheduled during cleanup. * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. @@ -449,6 +452,8 @@ struct usb_gadget { enum usb_ssp_rate max_ssp_rate; enum usb_device_state state; + spinlock_t state_lock; + bool teardown; const char *name; struct device dev; unsigned isoch_delay; -- Gitee From 7cecda54cb26b4f2b00845a53bf00f167af21fec Mon Sep 17 00:00:00 2001 From: Jameson Thies Date: Tue, 2 Dec 2025 08:40:51 +0800 Subject: [PATCH 0166/1449] usb: typec: ucsi: psy: Set max current to zero when disconnected ANBZ: #35228 commit eecd163fa6da94d58b7d26d1efba70863dbf5cb2 stable. commit 23379a17334fc24c4a9cbd9967d33dcd9323cc7c upstream. The ucsi_psy_get_current_max function defaults to 0.1A when it is not clear how much current the partner device can support. But this does not check the port is connected, and will report 0.1A max current when nothing is connected. Update ucsi_psy_get_current_max to report 0A when there is no connection. Fixes: af833e7f7db3 ("usb: typec: ucsi: psy: Set current max to 100mA for BC 1.2 and Default") Cc: stable@vger.kernel.org Signed-off-by: Jameson Thies Reviewed-by: Benson Leung Reviewed-by: Heikki Krogerus Reviewed-by: Sebastian Reichel Tested-by: Kenneth R. Crudup Rule: add Link: https://lore.kernel.org/stable/20251017000051.2094101-1-jthies%40google.com Link: https://patch.msgid.link/20251106011446.2052583-1-jthies@google.com Signed-off-by: Greg Kroah-Hartman [ adapted UCSI_CONSTAT() macro to direct flag access ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/typec/ucsi/psy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c index 9b0157063df0..c80c23d3384e 100644 --- a/drivers/usb/typec/ucsi/psy.c +++ b/drivers/usb/typec/ucsi/psy.c @@ -144,6 +144,11 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, { u32 pdo; + if (!(con->status.flags & UCSI_CONSTAT_CONNECTED)) { + val->intval = 0; + return 0; + } + switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) { case UCSI_CONSTAT_PWR_OPMODE_PD: if (con->num_pdos > 0) { -- Gitee From 2751c5b58c2df89c590a10b165d9c8be5f9bdea4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 2 Dec 2025 07:29:00 +0800 Subject: [PATCH 0167/1449] can: rcar_canfd: Fix CAN-FD mode as default ANBZ: #35228 commit 094f10f3f290d4bfcded29856c0d9892905e45c4 stable. commit 6d849ff573722afcf5508d2800017bdd40f27eb9 upstream. The commit 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") has aligned with the flow mentioned in the hardware manual for all SoCs except R-Car Gen3 and RZ/G2L SoCs. On R-Car Gen4 and RZ/G3E SoCs, due to the wrong logic in the commit[1] sets the default mode to FD-Only mode instead of CAN-FD mode. This patch sets the CAN-FD mode as the default for all SoCs by dropping the rcar_canfd_set_mode() as some SoC requires mode setting in global reset mode, and the rest of the SoCs in channel reset mode and update the rcar_canfd_reset_controller() to take care of these constraints. Moreover, the RZ/G3E and R-Car Gen4 SoCs support 3 modes compared to 2 modes on the R-Car Gen3. Use inverted logic in rcar_canfd_reset_controller() to simplify the code later to support FD-only mode. [1] commit 45721c406dcf ("can: rcar_canfd: Add support for r8a779a0 SoC") Fixes: 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") Cc: stable@vger.kernel.org Signed-off-by: Biju Das Link: https://patch.msgid.link/20251118123926.193445-1-biju.das.jz@bp.renesas.com Signed-off-by: Marc Kleine-Budde [ adapted to use existing is_gen4() helper and RCANFD_GEN4_FDCFG() macro instead of new ch_interface_mode field and fcbase struct ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/rcar/rcar_canfd.c | 53 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index ae4ebcee6077..5a30667001c9 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -687,26 +687,6 @@ static void rcar_canfd_tx_failure_cleanup(struct net_device *ndev) can_free_echo_skb(ndev, i, NULL); } -static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv) -{ - if (is_gen4(gpriv)) { - u32 ch, val = gpriv->fdmode ? RCANFD_GEN4_FDCFG_FDOE - : RCANFD_GEN4_FDCFG_CLOE; - - for_each_set_bit(ch, &gpriv->channels_mask, - gpriv->info->max_channels) - rcar_canfd_set_bit(gpriv->base, RCANFD_GEN4_FDCFG(ch), - val); - } else { - if (gpriv->fdmode) - rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, - RCANFD_GRMCFG_RCMC); - else - rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG, - RCANFD_GRMCFG_RCMC); - } -} - static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) { u32 sts, ch; @@ -738,6 +718,16 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) /* Reset Global error flags */ rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0); + /* Set the controller into appropriate mode */ + if (!is_gen4(gpriv)) { + if (gpriv->fdmode) + rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, + RCANFD_GRMCFG_RCMC); + else + rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG, + RCANFD_GRMCFG_RCMC); + } + /* Transition all Channels to reset mode */ for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { rcar_canfd_clear_bit(gpriv->base, @@ -756,10 +746,27 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) "channel %u reset failed\n", ch); return err; } - } - /* Set the controller into appropriate mode */ - rcar_canfd_set_mode(gpriv); + /* Set the controller into appropriate mode */ + if (is_gen4(gpriv)) { + /* Do not set CLOE and FDOE simultaneously */ + if (!gpriv->fdmode) { + rcar_canfd_clear_bit(gpriv->base, + RCANFD_GEN4_FDCFG(ch), + RCANFD_GEN4_FDCFG_FDOE); + rcar_canfd_set_bit(gpriv->base, + RCANFD_GEN4_FDCFG(ch), + RCANFD_GEN4_FDCFG_CLOE); + } else { + rcar_canfd_clear_bit(gpriv->base, + RCANFD_GEN4_FDCFG(ch), + RCANFD_GEN4_FDCFG_FDOE); + rcar_canfd_clear_bit(gpriv->base, + RCANFD_GEN4_FDCFG(ch), + RCANFD_GEN4_FDCFG_CLOE); + } + } + } return 0; } -- Gitee From a331862591c7acd473c17c419b38877c7a99c43c Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Tue, 2 Dec 2025 05:14:31 +0800 Subject: [PATCH 0168/1449] iio: adc: rtq6056: Correct the sign bit index ANBZ: #35228 commit a395121fe29efdc9b41edaf0d0cd2abbae83645d stable. commit 9b45744bf09fc2a3287e05287141d6e123c125a7 upstream. The vshunt/current reported register is a signed 16bit integer. The sign bit index should be '15', not '16'. Fixes: 4396f45d211b ("iio: adc: Add rtq6056 support") Reported-by: Andy Hsu Signed-off-by: ChiYuan Huang Reviewed-by: David Lechner Cc: Signed-off-by: Jonathan Cameron [ adapted switch statement to existing if-else structure for sign_extend32() fix ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/rtq6056.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/rtq6056.c b/drivers/iio/adc/rtq6056.c index ad4cea6839b2..3ffdcb9f8833 100644 --- a/drivers/iio/adc/rtq6056.c +++ b/drivers/iio/adc/rtq6056.c @@ -171,7 +171,7 @@ static int rtq6056_adc_read_channel(struct rtq6056_priv *priv, if (addr == RTQ6056_REG_BUSVOLT || addr == RTQ6056_REG_POWER) *val = regval; else - *val = sign_extend32(regval, 16); + *val = sign_extend32(regval, 15); return IIO_VAL_INT; } -- Gitee From 66f3713de3e44a71b3143e92b95cca3c6477c718 Mon Sep 17 00:00:00 2001 From: luoguangfei <15388634752@163.com> Date: Fri, 28 Nov 2025 16:20:24 +0800 Subject: [PATCH 0169/1449] net: macb: fix unregister_netdev call order in macb_remove() ANBZ: #35228 commit 2b9719ccad38dffad7dbdd2f39896f723f9b9011 stable. commit 01b9128c5db1b470575d07b05b67ffa3cb02ebf1 upstream. When removing a macb device, the driver calls phy_exit() before unregister_netdev(). This leads to a WARN from kernfs: ------------[ cut here ]------------ kernfs: can not remove 'attached_dev', no directory WARNING: CPU: 1 PID: 27146 at fs/kernfs/dir.c:1683 Call trace: kernfs_remove_by_name_ns+0xd8/0xf0 sysfs_remove_link+0x24/0x58 phy_detach+0x5c/0x168 phy_disconnect+0x4c/0x70 phylink_disconnect_phy+0x6c/0xc0 [phylink] macb_close+0x6c/0x170 [macb] ... macb_remove+0x60/0x168 [macb] platform_remove+0x5c/0x80 ... The warning happens because the PHY is being exited while the netdev is still registered. The correct order is to unregister the netdev before shutting down the PHY and cleaning up the MDIO bus. Fix this by moving unregister_netdev() ahead of phy_exit() in macb_remove(). Fixes: 8b73fa3ae02b ("net: macb: Added ZynqMP-specific initialization") Signed-off-by: luoguangfei <15388634752@163.com> Link: https://patch.msgid.link/20250818232527.1316-1-15388634752@163.com Signed-off-by: Jakub Kicinski [ Minor context change fixed. ] Signed-off-by: Alva Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 7593255e6e53..bf7b5d1d5616 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -5182,11 +5182,11 @@ static int macb_remove(struct platform_device *pdev) if (dev) { bp = netdev_priv(dev); + unregister_netdev(dev); phy_exit(bp->sgmii_phy); mdiobus_unregister(bp->mii_bus); mdiobus_free(bp->mii_bus); - unregister_netdev(dev); tasklet_kill(&bp->hresp_err_tasklet); pm_runtime_disable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); -- Gitee From 4c2e99b673b448a34cad8c43c15e282f45376bba Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Fri, 28 Nov 2025 03:34:43 +0800 Subject: [PATCH 0170/1449] staging: rtl8712: Remove driver using deprecated API wext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit f12f4c657617425924aead7b45825bda09905e8b stable. commit 41e883c137ebe6eec042658ef750cbb0529f6ca8 upstream. This driver is in the staging area since 2010. The following reasons lead to the removal: - This driver generates maintenance workload for itself and for API wext - A MAC80211 driver was available in 2016 time frame; This driver does not compile anymore but would be a better starting point than the current driver. Here the note from the TODO file: A replacement for this driver with MAC80211 support is available at https://github.com/chunkeey/rtl8192su - no progress changing to mac80211 - Using this hardware is security wise not state of the art as WPA3 is not supported. Find further discussions in the Link below. Link: https://lore.kernel.org/linux-staging/a02e3e0b-8a9b-47d5-87cf-2c957a474daa@gmail.com/T/#t Signed-off-by: Philipp Hortmann Tested-by: Dominik Karol Piątkowski Link: https://lore.kernel.org/r/20241020144933.10956-1-philipp.g.hortmann@gmail.com Signed-off-by: Greg Kroah-Hartman [groeck: Resolved conflicts; dropped statement about hardware support in longterm kernels] Signed-off-by: Guenter Roeck Link: https://lore.kernel.org/stable/20251204021604.GA843400@ax162/T/#t Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- MAINTAINERS | 6 - .../configs/L2-OPTIONAL/arm64/CONFIG_R8712U | 1 - drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rtl8712/Kconfig | 21 - drivers/staging/rtl8712/Makefile | 35 - drivers/staging/rtl8712/TODO | 13 - drivers/staging/rtl8712/basic_types.h | 28 - drivers/staging/rtl8712/drv_types.h | 175 -- drivers/staging/rtl8712/ethernet.h | 21 - drivers/staging/rtl8712/hal_init.c | 401 --- drivers/staging/rtl8712/ieee80211.c | 415 --- drivers/staging/rtl8712/ieee80211.h | 165 -- drivers/staging/rtl8712/mlme_linux.c | 160 -- drivers/staging/rtl8712/mlme_osdep.h | 31 - drivers/staging/rtl8712/mp_custom_oid.h | 287 -- drivers/staging/rtl8712/os_intfs.c | 482 ---- drivers/staging/rtl8712/osdep_intf.h | 32 - drivers/staging/rtl8712/osdep_service.h | 60 - drivers/staging/rtl8712/recv_linux.c | 139 - drivers/staging/rtl8712/recv_osdep.h | 39 - drivers/staging/rtl8712/rtl8712_bitdef.h | 26 - drivers/staging/rtl8712/rtl8712_cmd.c | 409 --- drivers/staging/rtl8712/rtl8712_cmd.h | 231 -- .../staging/rtl8712/rtl8712_cmdctrl_bitdef.h | 95 - .../staging/rtl8712/rtl8712_cmdctrl_regdef.h | 19 - .../rtl8712/rtl8712_debugctrl_bitdef.h | 41 - .../rtl8712/rtl8712_debugctrl_regdef.h | 32 - .../rtl8712/rtl8712_edcasetting_bitdef.h | 65 - .../rtl8712/rtl8712_edcasetting_regdef.h | 24 - drivers/staging/rtl8712/rtl8712_efuse.c | 564 ---- drivers/staging/rtl8712/rtl8712_efuse.h | 44 - drivers/staging/rtl8712/rtl8712_event.h | 86 - .../staging/rtl8712/rtl8712_fifoctrl_bitdef.h | 131 - .../staging/rtl8712/rtl8712_fifoctrl_regdef.h | 61 - drivers/staging/rtl8712/rtl8712_gp_bitdef.h | 68 - drivers/staging/rtl8712/rtl8712_gp_regdef.h | 29 - drivers/staging/rtl8712/rtl8712_hal.h | 142 - .../rtl8712/rtl8712_interrupt_bitdef.h | 44 - drivers/staging/rtl8712/rtl8712_io.c | 99 - drivers/staging/rtl8712/rtl8712_led.c | 1830 ------------- .../rtl8712/rtl8712_macsetting_bitdef.h | 31 - .../rtl8712/rtl8712_macsetting_regdef.h | 20 - .../rtl8712/rtl8712_powersave_bitdef.h | 39 - .../rtl8712/rtl8712_powersave_regdef.h | 26 - .../staging/rtl8712/rtl8712_ratectrl_bitdef.h | 36 - .../staging/rtl8712/rtl8712_ratectrl_regdef.h | 43 - drivers/staging/rtl8712/rtl8712_recv.c | 1080 -------- drivers/staging/rtl8712/rtl8712_recv.h | 145 - drivers/staging/rtl8712/rtl8712_regdef.h | 32 - .../staging/rtl8712/rtl8712_security_bitdef.h | 34 - drivers/staging/rtl8712/rtl8712_spec.h | 121 - .../staging/rtl8712/rtl8712_syscfg_bitdef.h | 163 -- .../staging/rtl8712/rtl8712_syscfg_regdef.h | 42 - .../staging/rtl8712/rtl8712_timectrl_bitdef.h | 49 - .../staging/rtl8712/rtl8712_timectrl_regdef.h | 26 - drivers/staging/rtl8712/rtl8712_wmac_bitdef.h | 49 - drivers/staging/rtl8712/rtl8712_wmac_regdef.h | 36 - drivers/staging/rtl8712/rtl8712_xmit.c | 744 ------ drivers/staging/rtl8712/rtl8712_xmit.h | 108 - drivers/staging/rtl8712/rtl871x_cmd.c | 796 ------ drivers/staging/rtl8712/rtl871x_cmd.h | 761 ------ drivers/staging/rtl8712/rtl871x_debug.h | 130 - drivers/staging/rtl8712/rtl871x_eeprom.c | 220 -- drivers/staging/rtl8712/rtl871x_eeprom.h | 88 - drivers/staging/rtl8712/rtl871x_event.h | 109 - drivers/staging/rtl8712/rtl871x_ht.h | 33 - drivers/staging/rtl8712/rtl871x_io.c | 147 -- drivers/staging/rtl8712/rtl871x_io.h | 236 -- drivers/staging/rtl8712/rtl871x_ioctl.h | 94 - drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 2330 ----------------- drivers/staging/rtl8712/rtl871x_ioctl_rtl.c | 519 ---- drivers/staging/rtl8712/rtl871x_ioctl_rtl.h | 109 - drivers/staging/rtl8712/rtl871x_ioctl_set.c | 354 --- drivers/staging/rtl8712/rtl871x_ioctl_set.h | 45 - drivers/staging/rtl8712/rtl871x_led.h | 118 - drivers/staging/rtl8712/rtl871x_mlme.c | 1710 ------------ drivers/staging/rtl8712/rtl871x_mlme.h | 205 -- drivers/staging/rtl8712/rtl871x_mp.c | 724 ----- drivers/staging/rtl8712/rtl871x_mp.h | 275 -- drivers/staging/rtl8712/rtl871x_mp_ioctl.c | 883 ------- drivers/staging/rtl8712/rtl871x_mp_ioctl.h | 328 --- .../staging/rtl8712/rtl871x_mp_phy_regdef.h | 1034 -------- drivers/staging/rtl8712/rtl871x_pwrctrl.c | 234 -- drivers/staging/rtl8712/rtl871x_pwrctrl.h | 113 - drivers/staging/rtl8712/rtl871x_recv.c | 671 ----- drivers/staging/rtl8712/rtl871x_recv.h | 208 -- drivers/staging/rtl8712/rtl871x_rf.h | 55 - drivers/staging/rtl8712/rtl871x_security.c | 1386 ---------- drivers/staging/rtl8712/rtl871x_security.h | 218 -- drivers/staging/rtl8712/rtl871x_sta_mgt.c | 263 -- drivers/staging/rtl8712/rtl871x_wlan_sme.h | 35 - drivers/staging/rtl8712/rtl871x_xmit.c | 1059 -------- drivers/staging/rtl8712/rtl871x_xmit.h | 288 -- drivers/staging/rtl8712/sta_info.h | 132 - drivers/staging/rtl8712/usb_halinit.c | 307 --- drivers/staging/rtl8712/usb_intf.c | 638 ----- drivers/staging/rtl8712/usb_ops.c | 195 -- drivers/staging/rtl8712/usb_ops.h | 38 - drivers/staging/rtl8712/usb_ops_linux.c | 515 ---- drivers/staging/rtl8712/usb_osintf.h | 35 - drivers/staging/rtl8712/wifi.h | 196 -- drivers/staging/rtl8712/wlan_bssdef.h | 223 -- drivers/staging/rtl8712/xmit_linux.c | 181 -- drivers/staging/rtl8712/xmit_osdep.h | 52 - 105 files changed, 27668 deletions(-) delete mode 100644 anolis/configs/L2-OPTIONAL/arm64/CONFIG_R8712U delete mode 100644 drivers/staging/rtl8712/Kconfig delete mode 100644 drivers/staging/rtl8712/Makefile delete mode 100644 drivers/staging/rtl8712/TODO delete mode 100644 drivers/staging/rtl8712/basic_types.h delete mode 100644 drivers/staging/rtl8712/drv_types.h delete mode 100644 drivers/staging/rtl8712/ethernet.h delete mode 100644 drivers/staging/rtl8712/hal_init.c delete mode 100644 drivers/staging/rtl8712/ieee80211.c delete mode 100644 drivers/staging/rtl8712/ieee80211.h delete mode 100644 drivers/staging/rtl8712/mlme_linux.c delete mode 100644 drivers/staging/rtl8712/mlme_osdep.h delete mode 100644 drivers/staging/rtl8712/mp_custom_oid.h delete mode 100644 drivers/staging/rtl8712/os_intfs.c delete mode 100644 drivers/staging/rtl8712/osdep_intf.h delete mode 100644 drivers/staging/rtl8712/osdep_service.h delete mode 100644 drivers/staging/rtl8712/recv_linux.c delete mode 100644 drivers/staging/rtl8712/recv_osdep.h delete mode 100644 drivers/staging/rtl8712/rtl8712_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_cmd.c delete mode 100644 drivers/staging/rtl8712/rtl8712_cmd.h delete mode 100644 drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_efuse.c delete mode 100644 drivers/staging/rtl8712/rtl8712_efuse.h delete mode 100644 drivers/staging/rtl8712/rtl8712_event.h delete mode 100644 drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_gp_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_gp_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_hal.h delete mode 100644 drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_io.c delete mode 100644 drivers/staging/rtl8712/rtl8712_led.c delete mode 100644 drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_macsetting_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_powersave_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_powersave_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_recv.c delete mode 100644 drivers/staging/rtl8712/rtl8712_recv.h delete mode 100644 drivers/staging/rtl8712/rtl8712_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_security_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_spec.h delete mode 100644 drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_syscfg_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_timectrl_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_wmac_bitdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_wmac_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl8712_xmit.c delete mode 100644 drivers/staging/rtl8712/rtl8712_xmit.h delete mode 100644 drivers/staging/rtl8712/rtl871x_cmd.c delete mode 100644 drivers/staging/rtl8712/rtl871x_cmd.h delete mode 100644 drivers/staging/rtl8712/rtl871x_debug.h delete mode 100644 drivers/staging/rtl8712/rtl871x_eeprom.c delete mode 100644 drivers/staging/rtl8712/rtl871x_eeprom.h delete mode 100644 drivers/staging/rtl8712/rtl871x_event.h delete mode 100644 drivers/staging/rtl8712/rtl871x_ht.h delete mode 100644 drivers/staging/rtl8712/rtl871x_io.c delete mode 100644 drivers/staging/rtl8712/rtl871x_io.h delete mode 100644 drivers/staging/rtl8712/rtl871x_ioctl.h delete mode 100644 drivers/staging/rtl8712/rtl871x_ioctl_linux.c delete mode 100644 drivers/staging/rtl8712/rtl871x_ioctl_rtl.c delete mode 100644 drivers/staging/rtl8712/rtl871x_ioctl_rtl.h delete mode 100644 drivers/staging/rtl8712/rtl871x_ioctl_set.c delete mode 100644 drivers/staging/rtl8712/rtl871x_ioctl_set.h delete mode 100644 drivers/staging/rtl8712/rtl871x_led.h delete mode 100644 drivers/staging/rtl8712/rtl871x_mlme.c delete mode 100644 drivers/staging/rtl8712/rtl871x_mlme.h delete mode 100644 drivers/staging/rtl8712/rtl871x_mp.c delete mode 100644 drivers/staging/rtl8712/rtl871x_mp.h delete mode 100644 drivers/staging/rtl8712/rtl871x_mp_ioctl.c delete mode 100644 drivers/staging/rtl8712/rtl871x_mp_ioctl.h delete mode 100644 drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h delete mode 100644 drivers/staging/rtl8712/rtl871x_pwrctrl.c delete mode 100644 drivers/staging/rtl8712/rtl871x_pwrctrl.h delete mode 100644 drivers/staging/rtl8712/rtl871x_recv.c delete mode 100644 drivers/staging/rtl8712/rtl871x_recv.h delete mode 100644 drivers/staging/rtl8712/rtl871x_rf.h delete mode 100644 drivers/staging/rtl8712/rtl871x_security.c delete mode 100644 drivers/staging/rtl8712/rtl871x_security.h delete mode 100644 drivers/staging/rtl8712/rtl871x_sta_mgt.c delete mode 100644 drivers/staging/rtl8712/rtl871x_wlan_sme.h delete mode 100644 drivers/staging/rtl8712/rtl871x_xmit.c delete mode 100644 drivers/staging/rtl8712/rtl871x_xmit.h delete mode 100644 drivers/staging/rtl8712/sta_info.h delete mode 100644 drivers/staging/rtl8712/usb_halinit.c delete mode 100644 drivers/staging/rtl8712/usb_intf.c delete mode 100644 drivers/staging/rtl8712/usb_ops.c delete mode 100644 drivers/staging/rtl8712/usb_ops.h delete mode 100644 drivers/staging/rtl8712/usb_ops_linux.c delete mode 100644 drivers/staging/rtl8712/usb_osintf.h delete mode 100644 drivers/staging/rtl8712/wifi.h delete mode 100644 drivers/staging/rtl8712/wlan_bssdef.h delete mode 100644 drivers/staging/rtl8712/xmit_linux.c delete mode 100644 drivers/staging/rtl8712/xmit_osdep.h diff --git a/MAINTAINERS b/MAINTAINERS index 3501c95f7cde..12d7b5c1cb82 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20620,12 +20620,6 @@ S: Maintained W: http://wiki.laptop.org/go/DCON F: drivers/staging/olpc_dcon/ -STAGING - REALTEK RTL8712U DRIVERS -M: Larry Finger -M: Florian Schilhabel . -S: Odd Fixes -F: drivers/staging/rtl8712/ - STAGING - SEPS525 LCD CONTROLLER DRIVERS M: Michael Hennerich L: linux-fbdev@vger.kernel.org diff --git a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_R8712U b/anolis/configs/L2-OPTIONAL/arm64/CONFIG_R8712U deleted file mode 100644 index e9c62ab3149f..000000000000 --- a/anolis/configs/L2-OPTIONAL/arm64/CONFIG_R8712U +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_R8712U is not set diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index f9aef39cac2e..abaa7af6ee7d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -34,8 +34,6 @@ source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/rtl8723bs/Kconfig" -source "drivers/staging/rtl8712/Kconfig" - source "drivers/staging/rts5208/Kconfig" source "drivers/staging/octeon/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ffa70dda481d..b363618109ce 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ -obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig deleted file mode 100644 index 8de26425225b..000000000000 --- a/drivers/staging/rtl8712/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config R8712U - tristate "RealTek RTL8712U (RTL8192SU) Wireless LAN NIC driver" - depends on WLAN && USB && CFG80211 - select WIRELESS_EXT - select WEXT_PRIV - select FW_LOADER - help - This option adds the Realtek RTL8712 USB device such as the - D-Link DWA-130. - - If built as a module, it will be called r8712u. - -config R8712_TX_AGGR - bool "Realtek RTL8712U Transmit Aggregation code" - depends on R8712U && BROKEN - help - This option provides transmit aggregation for the Realtek - RTL8712 USB device. - - diff --git a/drivers/staging/rtl8712/Makefile b/drivers/staging/rtl8712/Makefile deleted file mode 100644 index 3ae216b6621b..000000000000 --- a/drivers/staging/rtl8712/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -r8712u-y := \ - rtl871x_cmd.o \ - rtl8712_cmd.o \ - rtl871x_security.o \ - rtl871x_eeprom.o \ - rtl8712_efuse.o \ - hal_init.o \ - usb_halinit.o \ - usb_ops.o \ - usb_ops_linux.o \ - rtl871x_io.o \ - rtl8712_io.o \ - rtl871x_ioctl_linux.o \ - rtl871x_ioctl_rtl.o \ - rtl871x_ioctl_set.o \ - rtl8712_led.o \ - rtl871x_mlme.o \ - ieee80211.o \ - rtl871x_mp_ioctl.o \ - rtl871x_mp.o \ - mlme_linux.o \ - recv_linux.o \ - xmit_linux.o \ - usb_intf.o \ - os_intfs.o \ - rtl871x_pwrctrl.o \ - rtl8712_recv.o \ - rtl871x_recv.o \ - rtl871x_sta_mgt.o \ - rtl871x_xmit.o \ - rtl8712_xmit.o - -obj-$(CONFIG_R8712U) := r8712u.o - diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO deleted file mode 100644 index 847c8c41f4f7..000000000000 --- a/drivers/staging/rtl8712/TODO +++ /dev/null @@ -1,13 +0,0 @@ -TODO: -- merge Realtek's bugfixes and new features into the driver -- switch to use LIB80211 -- switch to use MAC80211 -- checkpatch.pl fixes - only a few remain - -A replacement for this driver with MAC80211 support is available -at https://github.com/chunkeey/rtl8192su - -Please send any patches to Greg Kroah-Hartman , -Larry Finger , -Florian Schilhabel and -Linux Driver Project Developer List . diff --git a/drivers/staging/rtl8712/basic_types.h b/drivers/staging/rtl8712/basic_types.h deleted file mode 100644 index aecded87dd4c..000000000000 --- a/drivers/staging/rtl8712/basic_types.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __BASIC_TYPES_H__ -#define __BASIC_TYPES_H__ - -#include - -#define sint signed int - -/* Should we extend this to be host_addr_t and target_addr_t for case: - * host : x86_64 - * target : mips64 - */ -#define addr_t unsigned long - -#endif /*__BASIC_TYPES_H__*/ - diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h deleted file mode 100644 index 76ac798642bd..000000000000 --- a/drivers/staging/rtl8712/drv_types.h +++ /dev/null @@ -1,175 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -/* --------------------------------------------------------------------- - * - * For type defines and data structure defines - * - * --------------------------------------------------------------------- - */ -#ifndef __DRV_TYPES_H__ -#define __DRV_TYPES_H__ - -struct _adapter; - -#include "osdep_service.h" -#include "wlan_bssdef.h" -#include "rtl8712_spec.h" -#include "rtl8712_hal.h" -#include -#include - -enum _NIC_VERSION { - RTL8711_NIC, - RTL8712_NIC, - RTL8713_NIC, - RTL8716_NIC -}; - -struct qos_priv { - /* bit mask option: u-apsd, s-apsd, ts, block ack... */ - unsigned int qos_option; -}; - -#include "rtl871x_ht.h" -#include "rtl871x_cmd.h" -#include "rtl871x_xmit.h" -#include "rtl871x_recv.h" -#include "rtl871x_security.h" -#include "rtl871x_pwrctrl.h" -#include "rtl871x_io.h" -#include "rtl871x_eeprom.h" -#include "sta_info.h" -#include "rtl871x_mlme.h" -#include "rtl871x_mp.h" -#include "rtl871x_debug.h" -#include "rtl871x_rf.h" -#include "rtl871x_event.h" -#include "rtl871x_led.h" - -#define SPEC_DEV_ID_DISABLE_HT BIT(1) - -struct specific_device_id { - u32 flags; - u16 idVendor; - u16 idProduct; - -}; - -struct registry_priv { - u8 chip_version; - u8 rfintfs; - u8 lbkmode; - u8 hci; - u8 network_mode; /*infra, ad-hoc, auto*/ - struct ndis_802_11_ssid ssid; - u8 channel;/* ad-hoc support requirement */ - u8 wireless_mode;/* A, B, G, auto */ - u8 vrtl_carrier_sense; /*Enable, Disable, Auto*/ - u8 vcs_type;/*RTS/CTS, CTS-to-self*/ - u16 rts_thresh; - u16 frag_thresh; - u8 preamble;/*long, short, auto*/ - u8 scan_mode;/*active, passive*/ - u8 adhoc_tx_pwr; - u8 soft_ap; - u8 smart_ps; - u8 power_mgnt; - u8 radio_enable; - u8 long_retry_lmt; - u8 short_retry_lmt; - u16 busy_thresh; - u8 ack_policy; - u8 mp_mode; - u8 software_encrypt; - u8 software_decrypt; - /* UAPSD */ - u8 wmm_enable; - u8 uapsd_enable; - u8 uapsd_max_sp; - u8 uapsd_acbk_en; - u8 uapsd_acbe_en; - u8 uapsd_acvi_en; - u8 uapsd_acvo_en; - - struct wlan_bssid_ex dev_network; - - u8 ht_enable; - u8 cbw40_enable; - u8 ampdu_enable;/*for tx*/ - u8 rf_config; - u8 low_power; - u8 wifi_test; -}; - -struct dvobj_priv { - struct _adapter *padapter; - u32 nr_endpoint; - u8 ishighspeed; - uint (*inirp_init)(struct _adapter *adapter); - uint (*inirp_deinit)(struct _adapter *adapter); - struct usb_device *pusbdev; -}; - -/** - * struct _adapter - the main adapter structure for this device. - * - * bup: True indicates that the interface is up. - */ -struct _adapter { - struct dvobj_priv dvobjpriv; - struct mlme_priv mlmepriv; - struct cmd_priv cmdpriv; - struct evt_priv evtpriv; - struct io_queue *pio_queue; - struct xmit_priv xmitpriv; - struct recv_priv recvpriv; - struct sta_priv stapriv; - struct security_priv securitypriv; - struct registry_priv registrypriv; - struct wlan_acl_pool acl_list; - struct pwrctrl_priv pwrctrlpriv; - struct eeprom_priv eeprompriv; - struct hal_priv halpriv; - struct led_priv ledpriv; - struct mp_priv mppriv; - bool driver_stopped; - bool surprise_removed; - bool suspended; - u8 eeprom_address_size; - u8 hw_init_completed; - struct task_struct *cmd_thread; - uint (*dvobj_init)(struct _adapter *adapter); - void (*dvobj_deinit)(struct _adapter *adapter); - struct net_device *pnetdev; - int bup; - struct net_device_stats stats; - struct iw_statistics iwstats; - int pid; /*process id from UI*/ - struct work_struct wk_filter_rx_ff0; - const struct firmware *fw; - struct usb_interface *pusb_intf; - struct mutex mutex_start; - struct completion rtl8712_fw_ready; - struct completion rx_filter_ready; -}; - -static inline u8 *myid(struct eeprom_priv *peepriv) -{ - return peepriv->mac_addr; -} - -u8 r8712_usb_hal_bus_init(struct _adapter *adapter); - -#endif /*__DRV_TYPES_H__*/ - diff --git a/drivers/staging/rtl8712/ethernet.h b/drivers/staging/rtl8712/ethernet.h deleted file mode 100644 index 4b9b8a97a0bc..000000000000 --- a/drivers/staging/rtl8712/ethernet.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __INC_ETHERNET_H -#define __INC_ETHERNET_H - -#define ETHERNET_HEADER_SIZE 14 /*!< Ethernet Header Length*/ -#define LLC_HEADER_SIZE 6 /*!< LLC Header Length*/ - -#endif /* #ifndef __INC_ETHERNET_H */ - diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c deleted file mode 100644 index 1148075f0cd6..000000000000 --- a/drivers/staging/rtl8712/hal_init.c +++ /dev/null @@ -1,401 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _HAL_INIT_C_ - -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "usb_osintf.h" - -#define FWBUFF_ALIGN_SZ 512 -#define MAX_DUMP_FWSZ (48 * 1024) - -static void rtl871x_load_fw_fail(struct _adapter *adapter) -{ - struct usb_device *udev = adapter->dvobjpriv.pusbdev; - struct device *dev = &udev->dev; - struct device *parent = dev->parent; - - complete(&adapter->rtl8712_fw_ready); - - dev_err(&udev->dev, "r8712u: Firmware request failed\n"); - - if (parent) - device_lock(parent); - - device_release_driver(dev); - - if (parent) - device_unlock(parent); -} - -static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context) -{ - struct _adapter *adapter = context; - - if (!firmware) { - rtl871x_load_fw_fail(adapter); - return; - } - adapter->fw = firmware; - /* firmware available - start netdev */ - register_netdev(adapter->pnetdev); - complete(&adapter->rtl8712_fw_ready); -} - -static const char firmware_file[] = "rtlwifi/rtl8712u.bin"; - -int rtl871x_load_fw(struct _adapter *padapter) -{ - struct device *dev = &padapter->dvobjpriv.pusbdev->dev; - int rc; - - init_completion(&padapter->rtl8712_fw_ready); - dev_info(dev, "r8712u: Loading firmware from \"%s\"\n", firmware_file); - rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev, - GFP_KERNEL, padapter, rtl871x_load_fw_cb); - if (rc) - dev_err(dev, "r8712u: Firmware request error %d\n", rc); - return rc; -} -MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); - -static u32 rtl871x_open_fw(struct _adapter *adapter, const u8 **mappedfw) -{ - if (adapter->fw->size > 200000) { - dev_err(&adapter->pnetdev->dev, "r8712u: Bad fw->size of %zu\n", - adapter->fw->size); - return 0; - } - *mappedfw = adapter->fw->data; - return adapter->fw->size; -} - -static void fill_fwpriv(struct _adapter *adapter, struct fw_priv *fwpriv) -{ - struct dvobj_priv *dvobj = &adapter->dvobjpriv; - struct registry_priv *regpriv = &adapter->registrypriv; - - memset(fwpriv, 0, sizeof(struct fw_priv)); - /* todo: check if needs endian conversion */ - fwpriv->hci_sel = RTL8712_HCI_TYPE_72USB; - fwpriv->usb_ep_num = (u8)dvobj->nr_endpoint; - fwpriv->bw_40MHz_en = regpriv->cbw40_enable; - switch (regpriv->rf_config) { - case RTL8712_RF_1T1R: - fwpriv->rf_config = RTL8712_RFC_1T1R; - break; - case RTL8712_RF_2T2R: - fwpriv->rf_config = RTL8712_RFC_2T2R; - break; - case RTL8712_RF_1T2R: - default: - fwpriv->rf_config = RTL8712_RFC_1T2R; - } - fwpriv->mp_mode = (regpriv->mp_mode == 1); - /* 0:off 1:on 2:auto */ - fwpriv->vcs_type = regpriv->vrtl_carrier_sense; - fwpriv->vcs_mode = regpriv->vcs_type; /* 1:RTS/CTS 2:CTS to self */ - /* default enable turbo_mode */ - fwpriv->turbo_mode = (regpriv->wifi_test != 1); - fwpriv->low_power_mode = regpriv->low_power; -} - -static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw) -{ - pfwhdr->signature = le16_to_cpu(*(__le16 *)pmappedfw); - pfwhdr->version = le16_to_cpu(*(__le16 *)(pmappedfw + 2)); - /* define the size of boot loader */ - pfwhdr->dmem_size = le32_to_cpu(*(__le32 *)(pmappedfw + 4)); - /* define the size of FW in IMEM */ - pfwhdr->img_IMEM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 8)); - /* define the size of FW in SRAM */ - pfwhdr->img_SRAM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 12)); - /* define the size of DMEM variable */ - pfwhdr->fw_priv_sz = le32_to_cpu(*(__le32 *)(pmappedfw + 16)); -} - -static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength) -{ - u32 fwhdrsz, fw_sz; - - /* check signature */ - if ((pfwhdr->signature != 0x8712) && (pfwhdr->signature != 0x8192)) - return _FAIL; - /* check fw_priv_sze & sizeof(struct fw_priv) */ - if (pfwhdr->fw_priv_sz != sizeof(struct fw_priv)) - return _FAIL; - /* check fw_sz & image_fw_sz */ - fwhdrsz = offsetof(struct fw_hdr, fwpriv) + pfwhdr->fw_priv_sz; - fw_sz = fwhdrsz + pfwhdr->img_IMEM_size + pfwhdr->img_SRAM_size + - pfwhdr->dmem_size; - if (fw_sz != ulfilelength) - return _FAIL; - return _SUCCESS; -} - -static u8 rtl8712_dl_fw(struct _adapter *adapter) -{ - sint i; - u8 tmp8, tmp8_a; - u16 tmp16; - u32 maxlen = 0; /* for compare usage */ - uint dump_imem_sz, imem_sz, dump_emem_sz, emem_sz; /* max = 49152; */ - struct fw_hdr fwhdr; - u32 ulfilelength; /* FW file size */ - const u8 *mappedfw = NULL; - u8 *tmpchar = NULL, *payload, *ptr; - struct tx_desc *txdesc; - u32 txdscp_sz = sizeof(struct tx_desc); - u8 ret = _FAIL; - - ulfilelength = rtl871x_open_fw(adapter, &mappedfw); - if (mappedfw && (ulfilelength > 0)) { - update_fwhdr(&fwhdr, mappedfw); - if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL) - return ret; - fill_fwpriv(adapter, &fwhdr.fwpriv); - /* firmware check ok */ - maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ? - fwhdr.img_IMEM_size : fwhdr.img_SRAM_size; - maxlen += txdscp_sz; - tmpchar = kmalloc(maxlen + FWBUFF_ALIGN_SZ, GFP_KERNEL); - if (!tmpchar) - return ret; - - txdesc = (struct tx_desc *)(tmpchar + FWBUFF_ALIGN_SZ - - ((addr_t)(tmpchar) & (FWBUFF_ALIGN_SZ - 1))); - payload = (u8 *)(txdesc) + txdscp_sz; - ptr = (u8 *)mappedfw + offsetof(struct fw_hdr, fwpriv) + - fwhdr.fw_priv_sz; - /* Download FirmWare */ - /* 1. determine IMEM code size and Load IMEM Code Section */ - imem_sz = fwhdr.img_IMEM_size; - do { - memset(txdesc, 0, TXDESC_SIZE); - if (imem_sz > MAX_DUMP_FWSZ/*49152*/) { - dump_imem_sz = MAX_DUMP_FWSZ; - } else { - dump_imem_sz = imem_sz; - txdesc->txdw0 |= cpu_to_le32(BIT(28)); - } - txdesc->txdw0 |= cpu_to_le32(dump_imem_sz & - 0x0000ffff); - memcpy(payload, ptr, dump_imem_sz); - r8712_write_mem(adapter, RTL8712_DMA_VOQ, - dump_imem_sz + TXDESC_SIZE, - (u8 *)txdesc); - ptr += dump_imem_sz; - imem_sz -= dump_imem_sz; - } while (imem_sz > 0); - i = 10; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _IMEM_CODE_DONE) == 0) && (i > 0)) { - usleep_range(10, 1000); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0 || (tmp16 & _IMEM_CHK_RPT) == 0) - goto exit_fail; - - /* 2.Download EMEM code size and Load EMEM Code Section */ - emem_sz = fwhdr.img_SRAM_size; - do { - memset(txdesc, 0, TXDESC_SIZE); - if (emem_sz > MAX_DUMP_FWSZ) { /* max=48k */ - dump_emem_sz = MAX_DUMP_FWSZ; - } else { - dump_emem_sz = emem_sz; - txdesc->txdw0 |= cpu_to_le32(BIT(28)); - } - txdesc->txdw0 |= cpu_to_le32(dump_emem_sz & - 0x0000ffff); - memcpy(payload, ptr, dump_emem_sz); - r8712_write_mem(adapter, RTL8712_DMA_VOQ, - dump_emem_sz + TXDESC_SIZE, - (u8 *)txdesc); - ptr += dump_emem_sz; - emem_sz -= dump_emem_sz; - } while (emem_sz > 0); - i = 5; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _EMEM_CODE_DONE) == 0) && (i > 0)) { - usleep_range(10, 1000); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0 || (tmp16 & _EMEM_CHK_RPT) == 0) - goto exit_fail; - - /* 3.Enable CPU */ - tmp8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, tmp8 | BIT(2)); - tmp8_a = r8712_read8(adapter, SYS_CLKR); - if (tmp8_a != (tmp8 | BIT(2))) - goto exit_fail; - - tmp8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, tmp8 | BIT(2)); - tmp8_a = r8712_read8(adapter, SYS_FUNC_EN + 1); - if (tmp8_a != (tmp8 | BIT(2))) - goto exit_fail; - - r8712_read32(adapter, TCR); - - /* 4.polling IMEM Ready */ - i = 100; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _IMEM_RDY) == 0) && (i > 0)) { - msleep(20); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0) { - r8712_write16(adapter, 0x10250348, 0xc000); - r8712_write16(adapter, 0x10250348, 0xc001); - r8712_write16(adapter, 0x10250348, 0x2000); - r8712_write16(adapter, 0x10250348, 0x2001); - r8712_write16(adapter, 0x10250348, 0x2002); - r8712_write16(adapter, 0x10250348, 0x2003); - goto exit_fail; - } - /* 5.Download DMEM code size and Load EMEM Code Section */ - memset(txdesc, 0, TXDESC_SIZE); - txdesc->txdw0 |= cpu_to_le32(fwhdr.fw_priv_sz & 0x0000ffff); - txdesc->txdw0 |= cpu_to_le32(BIT(28)); - memcpy(payload, &fwhdr.fwpriv, fwhdr.fw_priv_sz); - r8712_write_mem(adapter, RTL8712_DMA_VOQ, - fwhdr.fw_priv_sz + TXDESC_SIZE, (u8 *)txdesc); - - /* polling dmem code done */ - i = 100; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _DMEM_CODE_DONE) == 0) && (i > 0)) { - msleep(20); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0) - goto exit_fail; - - tmp8 = r8712_read8(adapter, 0x1025000A); - if (tmp8 & BIT(4)) /* When boot from EEPROM, - * & FW need more time to read EEPROM - */ - i = 60; - else /* boot from EFUSE */ - i = 30; - tmp16 = r8712_read16(adapter, TCR); - while (((tmp16 & _FWRDY) == 0) && (i > 0)) { - msleep(100); - tmp16 = r8712_read16(adapter, TCR); - i--; - } - if (i == 0) - goto exit_fail; - } else { - goto exit_fail; - } - ret = _SUCCESS; - -exit_fail: - kfree(tmpchar); - return ret; -} - -uint rtl8712_hal_init(struct _adapter *padapter) -{ - u32 val32; - int i; - - /* r8712 firmware download */ - if (rtl8712_dl_fw(padapter) != _SUCCESS) - return _FAIL; - - netdev_info(padapter->pnetdev, "1 RCR=0x%x\n", - r8712_read32(padapter, RCR)); - val32 = r8712_read32(padapter, RCR); - r8712_write32(padapter, RCR, (val32 | BIT(26))); /* Enable RX TCP - * Checksum offload - */ - netdev_info(padapter->pnetdev, "2 RCR=0x%x\n", - r8712_read32(padapter, RCR)); - val32 = r8712_read32(padapter, RCR); - r8712_write32(padapter, RCR, (val32 | BIT(25))); /* Append PHY status */ - val32 = r8712_read32(padapter, 0x10250040); - r8712_write32(padapter, 0x10250040, (val32 & 0x00FFFFFF)); - /* for usb rx aggregation */ - r8712_write8(padapter, 0x102500B5, r8712_read8(padapter, 0x102500B5) | - BIT(0)); /* page = 128bytes */ - r8712_write8(padapter, 0x102500BD, r8712_read8(padapter, 0x102500BD) | - BIT(7)); /* enable usb rx aggregation */ - r8712_write8(padapter, 0x102500D9, 1); /* TH=1 => means that invalidate - * usb rx aggregation - */ - r8712_write8(padapter, 0x1025FE5B, 0x04); /* 1.7ms/4 */ - /* Fix the RX FIFO issue(USB error) */ - r8712_write8(padapter, 0x1025fe5C, r8712_read8(padapter, 0x1025fe5C) - | BIT(7)); - for (i = 0; i < ETH_ALEN; i++) - padapter->eeprompriv.mac_addr[i] = r8712_read8(padapter, - MACID + i); - return _SUCCESS; -} - -uint rtl8712_hal_deinit(struct _adapter *padapter) -{ - r8712_write8(padapter, RF_CTRL, 0x00); - /* Turn off BB */ - msleep(20); - /* Turn off MAC */ - r8712_write8(padapter, SYS_CLKR + 1, 0x38); /* Switch Control Path */ - r8712_write8(padapter, SYS_FUNC_EN + 1, 0x70); - r8712_write8(padapter, PMC_FSM, 0x06); /* Enable Loader Data Keep */ - r8712_write8(padapter, SYS_ISO_CTRL, 0xF9); /* Isolation signals from - * CORE, PLL - */ - r8712_write8(padapter, SYS_ISO_CTRL + 1, 0xe8); /* Enable EFUSE 1.2V */ - r8712_write8(padapter, AFE_PLL_CTRL, 0x00); /* Disable AFE PLL. */ - r8712_write8(padapter, LDOA15_CTRL, 0x54); /* Disable A15V */ - r8712_write8(padapter, SYS_FUNC_EN + 1, 0x50); /* Disable E-Fuse 1.2V */ - r8712_write8(padapter, LDOV12D_CTRL, 0x24); /* Disable LDO12(for CE) */ - r8712_write8(padapter, AFE_MISC, 0x30); /* Disable AFE BG&MB */ - /* Option for Disable 1.6V LDO. */ - r8712_write8(padapter, SPS0_CTRL, 0x56); /* Disable 1.6V LDO */ - r8712_write8(padapter, SPS0_CTRL + 1, 0x43); /* Set SW PFM */ - return _SUCCESS; -} - -uint rtl871x_hal_init(struct _adapter *padapter) -{ - padapter->hw_init_completed = false; - if (!padapter->halpriv.hal_bus_init) - return _FAIL; - if (padapter->halpriv.hal_bus_init(padapter) != _SUCCESS) - return _FAIL; - if (rtl8712_hal_init(padapter) == _SUCCESS) { - padapter->hw_init_completed = true; - } else { - padapter->hw_init_completed = false; - return _FAIL; - } - return _SUCCESS; -} diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c deleted file mode 100644 index 7d8f1a29d18a..000000000000 --- a/drivers/staging/rtl8712/ieee80211.c +++ /dev/null @@ -1,415 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * ieee80211.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _IEEE80211_C - -#include "drv_types.h" -#include "ieee80211.h" -#include "wifi.h" -#include "osdep_service.h" -#include "wlan_bssdef.h" - -static const u8 WPA_OUI_TYPE[] = {0x00, 0x50, 0xf2, 1}; -static const u8 WPA_CIPHER_SUITE_NONE[] = {0x00, 0x50, 0xf2, 0}; -static const u8 WPA_CIPHER_SUITE_WEP40[] = {0x00, 0x50, 0xf2, 1}; -static const u8 WPA_CIPHER_SUITE_TKIP[] = {0x00, 0x50, 0xf2, 2}; -static const u8 WPA_CIPHER_SUITE_CCMP[] = {0x00, 0x50, 0xf2, 4}; -static const u8 WPA_CIPHER_SUITE_WEP104[] = {0x00, 0x50, 0xf2, 5}; - -static const u8 RSN_CIPHER_SUITE_NONE[] = {0x00, 0x0f, 0xac, 0}; -static const u8 RSN_CIPHER_SUITE_WEP40[] = {0x00, 0x0f, 0xac, 1}; -static const u8 RSN_CIPHER_SUITE_TKIP[] = {0x00, 0x0f, 0xac, 2}; -static const u8 RSN_CIPHER_SUITE_CCMP[] = {0x00, 0x0f, 0xac, 4}; -static const u8 RSN_CIPHER_SUITE_WEP104[] = {0x00, 0x0f, 0xac, 5}; - -/*----------------------------------------------------------- - * for adhoc-master to generate ie and provide supported-rate to fw - *----------------------------------------------------------- - */ - -static u8 WIFI_CCKRATES[] = { - (IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK), - (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK), - (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK), - (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK) -}; - -static u8 WIFI_OFDMRATES[] = { - (IEEE80211_OFDM_RATE_6MB), - (IEEE80211_OFDM_RATE_9MB), - (IEEE80211_OFDM_RATE_12MB), - (IEEE80211_OFDM_RATE_18MB), - (IEEE80211_OFDM_RATE_24MB), - (IEEE80211_OFDM_RATE_36MB), - (IEEE80211_OFDM_RATE_48MB), - (IEEE80211_OFDM_RATE_54MB) -}; - -uint r8712_is_cckrates_included(u8 *rate) -{ - u32 i = 0; - - while (rate[i] != 0) { - if ((((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || - (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) - return true; - i++; - } - return false; -} - -uint r8712_is_cckratesonly_included(u8 *rate) -{ - u32 i = 0; - - while (rate[i] != 0) { - if ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && - (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) - return false; - i++; - } - return true; -} - -/* r8712_set_ie will update frame length */ -u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen) -{ - *pbuf = (u8)index; - *(pbuf + 1) = (u8)len; - if (len > 0) - memcpy((void *)(pbuf + 2), (void *)source, len); - *frlen = *frlen + (len + 2); - return pbuf + len + 2; -} - -/* --------------------------------------------------------------------------- - * index: the information element id index, limit is the limit for search - * --------------------------------------------------------------------------- - */ -u8 *r8712_get_ie(u8 *pbuf, sint index, uint *len, sint limit) -{ - sint tmp, i; - u8 *p; - - if (limit < 1) - return NULL; - p = pbuf; - i = 0; - *len = 0; - while (1) { - if (*p == index) { - *len = *(p + 1); - return p; - } - tmp = *(p + 1); - p += (tmp + 2); - i += (tmp + 2); - if (i >= limit) - break; - } - return NULL; -} - -static void set_supported_rate(u8 *rates, uint mode) -{ - memset(rates, 0, NDIS_802_11_LENGTH_RATES_EX); - switch (mode) { - case WIRELESS_11B: - memcpy(rates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); - break; - case WIRELESS_11G: - case WIRELESS_11A: - memcpy(rates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN); - break; - case WIRELESS_11BG: - memcpy(rates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN); - memcpy(rates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, - IEEE80211_NUM_OFDM_RATESLEN); - break; - } -} - -static uint r8712_get_rateset_len(u8 *rateset) -{ - uint i = 0; - - while (1) { - if ((rateset[i]) == 0) - break; - if (i > 12) - break; - i++; - } - return i; -} - -int r8712_generate_ie(struct registry_priv *registrypriv) -{ - int rate_len; - uint sz = 0; - struct wlan_bssid_ex *dev_network = ®istrypriv->dev_network; - u8 *ie = dev_network->IEs; - u16 beacon_period = (u16)dev_network->Configuration.BeaconPeriod; - - /*timestamp will be inserted by hardware*/ - sz += 8; - ie += sz; - /*beacon interval : 2bytes*/ - *(__le16 *)ie = cpu_to_le16(beacon_period); - sz += 2; - ie += 2; - /*capability info*/ - *(u16 *)ie = 0; - *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_IBSS); - if (registrypriv->preamble == PREAMBLE_SHORT) - *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); - if (dev_network->Privacy) - *(__le16 *)ie |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - sz += 2; - ie += 2; - /*SSID*/ - ie = r8712_set_ie(ie, WLAN_EID_SSID, dev_network->Ssid.SsidLength, - dev_network->Ssid.Ssid, &sz); - /*supported rates*/ - set_supported_rate(dev_network->rates, registrypriv->wireless_mode); - rate_len = r8712_get_rateset_len(dev_network->rates); - if (rate_len > 8) { - ie = r8712_set_ie(ie, WLAN_EID_SUPP_RATES, 8, - dev_network->rates, &sz); - ie = r8712_set_ie(ie, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8), - (dev_network->rates + 8), &sz); - } else { - ie = r8712_set_ie(ie, WLAN_EID_SUPP_RATES, - rate_len, dev_network->rates, &sz); - } - /*DS parameter set*/ - ie = r8712_set_ie(ie, WLAN_EID_DS_PARAMS, 1, - (u8 *)&dev_network->Configuration.DSConfig, &sz); - /*IBSS Parameter Set*/ - ie = r8712_set_ie(ie, WLAN_EID_IBSS_PARAMS, 2, - (u8 *)&dev_network->Configuration.ATIMWindow, &sz); - return sz; -} - -unsigned char *r8712_get_wpa_ie(unsigned char *ie, uint *wpa_ie_len, int limit) -{ - u32 len; - u16 val16; - unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01}; - u8 *buf = ie; - - while (1) { - buf = r8712_get_ie(buf, _WPA_IE_ID_, &len, limit); - if (buf) { - /*check if oui matches...*/ - if (memcmp((buf + 2), wpa_oui_type, - sizeof(wpa_oui_type))) - goto check_next_ie; - /*check version...*/ - memcpy((u8 *)&val16, (buf + 6), sizeof(val16)); - le16_to_cpus(&val16); - if (val16 != 0x0001) - goto check_next_ie; - *wpa_ie_len = *(buf + 1); - return buf; - } - *wpa_ie_len = 0; - return NULL; -check_next_ie: - limit = limit - (buf - ie) - 2 - len; - if (limit <= 0) - break; - buf += (2 + len); - } - *wpa_ie_len = 0; - return NULL; -} - -unsigned char *r8712_get_wpa2_ie(unsigned char *pie, uint *rsn_ie_len, - int limit) -{ - return r8712_get_ie(pie, _WPA2_IE_ID_, rsn_ie_len, limit); -} - -static int r8712_get_wpa_cipher_suite(u8 *s) -{ - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN)) - return WPA_CIPHER_NONE; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN)) - return WPA_CIPHER_WEP40; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN)) - return WPA_CIPHER_TKIP; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN)) - return WPA_CIPHER_CCMP; - if (!memcmp(s, (void *)WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN)) - return WPA_CIPHER_WEP104; - return 0; -} - -static int r8712_get_wpa2_cipher_suite(u8 *s) -{ - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN)) - return WPA_CIPHER_NONE; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN)) - return WPA_CIPHER_WEP40; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN)) - return WPA_CIPHER_TKIP; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN)) - return WPA_CIPHER_CCMP; - if (!memcmp(s, (void *)RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN)) - return WPA_CIPHER_WEP104; - return 0; -} - -int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, - int *pairwise_cipher) -{ - int i; - int left, count; - u8 *pos; - - if (wpa_ie_len <= 0) { - /* No WPA IE - fail silently */ - return -EINVAL; - } - if ((*wpa_ie != _WPA_IE_ID_) || - (*(wpa_ie + 1) != (u8)(wpa_ie_len - 2)) || - (memcmp(wpa_ie + 2, (void *)WPA_OUI_TYPE, WPA_SELECTOR_LEN))) - return -EINVAL; - pos = wpa_ie; - pos += 8; - left = wpa_ie_len - 8; - /*group_cipher*/ - if (left >= WPA_SELECTOR_LEN) { - *group_cipher = r8712_get_wpa_cipher_suite(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } else if (left > 0) { - return -EINVAL; - } - /*pairwise_cipher*/ - if (left >= 2) { - count = le16_to_cpu(*(__le16 *)pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * WPA_SELECTOR_LEN) - return -EINVAL; - for (i = 0; i < count; i++) { - *pairwise_cipher |= r8712_get_wpa_cipher_suite(pos); - pos += WPA_SELECTOR_LEN; - left -= WPA_SELECTOR_LEN; - } - } else if (left == 1) { - return -EINVAL; - } - return 0; -} - -int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, - int *pairwise_cipher) -{ - int i; - int left, count; - u8 *pos; - - if (rsn_ie_len <= 0) { - /* No RSN IE - fail silently */ - return -EINVAL; - } - if ((*rsn_ie != _WPA2_IE_ID_) || - (*(rsn_ie + 1) != (u8)(rsn_ie_len - 2))) - return -EINVAL; - pos = rsn_ie; - pos += 4; - left = rsn_ie_len - 4; - /*group_cipher*/ - if (left >= RSN_SELECTOR_LEN) { - *group_cipher = r8712_get_wpa2_cipher_suite(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } else if (left > 0) { - return -EINVAL; - } - /*pairwise_cipher*/ - if (left >= 2) { - count = le16_to_cpu(*(__le16 *)pos); - pos += 2; - left -= 2; - if (count == 0 || left < count * RSN_SELECTOR_LEN) - return -EINVAL; - for (i = 0; i < count; i++) { - *pairwise_cipher |= r8712_get_wpa2_cipher_suite(pos); - pos += RSN_SELECTOR_LEN; - left -= RSN_SELECTOR_LEN; - } - } else if (left == 1) { - return -EINVAL; - } - return 0; -} - -int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, - u8 *wpa_ie, u16 *wpa_len) -{ - u8 authmode; - u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; - uint cnt; - - /*Search required WPA or WPA2 IE and copy to sec_ie[ ]*/ - cnt = _TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_; - while (cnt < in_len) { - authmode = in_ie[cnt]; - if ((authmode == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { - memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); - *wpa_len = in_ie[cnt + 1] + 2; - cnt += in_ie[cnt + 1] + 2; /*get next */ - } else { - if (authmode == _WPA2_IE_ID_) { - memcpy(rsn_ie, &in_ie[cnt], - in_ie[cnt + 1] + 2); - *rsn_len = in_ie[cnt + 1] + 2; - cnt += in_ie[cnt + 1] + 2; /*get next*/ - } else { - cnt += in_ie[cnt + 1] + 2; /*get next*/ - } - } - } - return *rsn_len + *wpa_len; -} - -int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) -{ - int match; - uint cnt; - u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - - cnt = 12; - match = false; - while (cnt < in_len) { - eid = in_ie[cnt]; - if ((eid == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], wps_oui, 4))) { - memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); - *wps_ielen = in_ie[cnt + 1] + 2; - cnt += in_ie[cnt + 1] + 2; - match = true; - break; - } - cnt += in_ie[cnt + 1] + 2; /* goto next */ - } - return match; -} diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h deleted file mode 100644 index 65ceaca9b51e..000000000000 --- a/drivers/staging/rtl8712/ieee80211.h +++ /dev/null @@ -1,165 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __IEEE80211_H -#define __IEEE80211_H - -#include - -#define IEEE_CMD_SET_WPA_PARAM 1 -#define IEEE_CMD_SET_WPA_IE 2 -#define IEEE_CMD_SET_ENCRYPTION 3 -#define IEEE_CMD_MLME 4 - -#define IEEE_PARAM_WPA_ENABLED 1 -#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 -#define IEEE_PARAM_DROP_UNENCRYPTED 3 -#define IEEE_PARAM_PRIVACY_INVOKED 4 -#define IEEE_PARAM_AUTH_ALGS 5 -#define IEEE_PARAM_IEEE_802_1X 6 -#define IEEE_PARAM_WPAX_SELECT 7 - -#define AUTH_ALG_OPEN_SYSTEM 0x1 -#define AUTH_ALG_SHARED_KEY 0x2 -#define AUTH_ALG_LEAP 0x00000004 - -#define IEEE_MLME_STA_DEAUTH 1 -#define IEEE_MLME_STA_DISASSOC 2 - -#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 -#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 -#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 - -#define IEEE_CRYPT_ALG_NAME_LEN 16 - -#define WPA_CIPHER_NONE BIT(0) -#define WPA_CIPHER_WEP40 BIT(1) -#define WPA_CIPHER_WEP104 BIT(2) -#define WPA_CIPHER_TKIP BIT(3) -#define WPA_CIPHER_CCMP BIT(4) - -#define WPA_SELECTOR_LEN 4 -#define RSN_HEADER_LEN 4 - -#define RSN_SELECTOR_LEN 4 - -enum NETWORK_TYPE { - WIRELESS_INVALID = 0, - WIRELESS_11B = 1, - WIRELESS_11G = 2, - WIRELESS_11BG = (WIRELESS_11B | WIRELESS_11G), - WIRELESS_11A = 4, - WIRELESS_11N = 8, - WIRELESS_11GN = (WIRELESS_11G | WIRELESS_11N), - WIRELESS_11BGN = (WIRELESS_11B | WIRELESS_11G | WIRELESS_11N), -}; - -struct ieee_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[]; - } wpa_ie; - struct { - int command; - int reason_code; - } mlme; - struct { - u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[]; - } crypt; - } u; -}; - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - -/* QoS,QOS */ -#define NORMAL_ACK 0 - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct ieee80211_snap_hdr { - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ -} __packed; - -#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) - -#define IEEE80211_CCK_RATE_LEN 4 -#define IEEE80211_NUM_OFDM_RATESLEN 8 - -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define WEP_KEYS 4 - -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... - */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_WPA_IE_LEN 128 - -struct registry_priv; - -u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen); -u8 *r8712_get_ie(u8 *pbuf, sint index, uint *len, sint limit); -unsigned char *r8712_get_wpa_ie(unsigned char *pie, uint *rsn_ie_len, - int limit); -unsigned char *r8712_get_wpa2_ie(unsigned char *pie, uint *rsn_ie_len, - int limit); -int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, - int *pairwise_cipher); -int r8712_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, - int *pairwise_cipher); -int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, - u8 *wpa_ie, u16 *wpa_len); -int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); -int r8712_generate_ie(struct registry_priv *pregistrypriv); -uint r8712_is_cckrates_included(u8 *rate); -uint r8712_is_cckratesonly_included(u8 *rate); - -#endif /* IEEE80211_H */ - diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c deleted file mode 100644 index b9f5104f3bf7..000000000000 --- a/drivers/staging/rtl8712/mlme_linux.c +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * mlme_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _MLME_OSDEP_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "mlme_osdep.h" - -static void sitesurvey_ctrl_handler(struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, - mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer); - - _r8712_sitesurvey_ctrl_handler(adapter); - mod_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, - jiffies + msecs_to_jiffies(3000)); -} - -static void join_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.assoc_timer); - - _r8712_join_timeout_handler(adapter); -} - -static void _scan_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.scan_to_timer); - - r8712_scan_timeout_handler(adapter); -} - -static void dhcp_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.dhcp_timer); - - _r8712_dhcp_timeout_handler(adapter); -} - -static void wdg_timeout_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, mlmepriv.wdg_timer); - - r8712_wdg_wk_cmd(adapter); - - mod_timer(&adapter->mlmepriv.wdg_timer, - jiffies + msecs_to_jiffies(2000)); -} - -void r8712_init_mlme_timer(struct _adapter *adapter) -{ - struct mlme_priv *mlmepriv = &adapter->mlmepriv; - - timer_setup(&mlmepriv->assoc_timer, join_timeout_handler, 0); - timer_setup(&mlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer, - sitesurvey_ctrl_handler, 0); - timer_setup(&mlmepriv->scan_to_timer, _scan_timeout_handler, 0); - timer_setup(&mlmepriv->dhcp_timer, dhcp_timeout_handler, 0); - timer_setup(&mlmepriv->wdg_timer, wdg_timeout_handler, 0); -} - -void r8712_os_indicate_connect(struct _adapter *adapter) -{ - r8712_indicate_wx_assoc_event(adapter); - netif_carrier_on(adapter->pnetdev); -} - -static struct RT_PMKID_LIST backupPMKIDList[NUM_PMKID_CACHE]; -void r8712_os_indicate_disconnect(struct _adapter *adapter) -{ - u8 backupPMKIDIndex = 0; - u8 backupTKIPCountermeasure = 0x00; - - r8712_indicate_wx_disassoc_event(adapter); - netif_carrier_off(adapter->pnetdev); - if (adapter->securitypriv.AuthAlgrthm == 2) { /*/802.1x*/ - /* We have to backup the PMK information for WiFi PMK Caching - * test item. Backup the btkip_countermeasure information. - * When the countermeasure is trigger, the driver have to - * disconnect with AP for 60 seconds. - */ - - memcpy(&backupPMKIDList[0], - &adapter->securitypriv.PMKIDList[0], - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - backupPMKIDIndex = adapter->securitypriv.PMKIDIndex; - backupTKIPCountermeasure = - adapter->securitypriv.btkip_countermeasure; - memset((unsigned char *)&adapter->securitypriv, 0, - sizeof(struct security_priv)); - timer_setup(&adapter->securitypriv.tkip_timer, - r8712_use_tkipkey_handler, 0); - /* Restore the PMK information to securitypriv structure - * for the following connection. - */ - memcpy(&adapter->securitypriv.PMKIDList[0], - &backupPMKIDList[0], - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - adapter->securitypriv.PMKIDIndex = backupPMKIDIndex; - adapter->securitypriv.btkip_countermeasure = - backupTKIPCountermeasure; - } else { /*reset values in securitypriv*/ - struct security_priv *sec_priv = &adapter->securitypriv; - - sec_priv->AuthAlgrthm = 0; /*open system*/ - sec_priv->PrivacyAlgrthm = _NO_PRIVACY_; - sec_priv->PrivacyKeyIndex = 0; - sec_priv->XGrpPrivacy = _NO_PRIVACY_; - sec_priv->XGrpKeyid = 1; - sec_priv->ndisauthtype = Ndis802_11AuthModeOpen; - sec_priv->ndisencryptstatus = Ndis802_11WEPDisabled; - sec_priv->wps_phase = false; - } -} - -void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie) -{ - uint len; - u8 *buff, *p, i; - union iwreq_data wrqu; - - buff = NULL; - if (authmode == _WPA_IE_ID_) { - buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC); - if (!buff) - return; - p = buff; - p += sprintf(p, "ASSOCINFO(ReqIEs="); - len = sec_ie[1] + 2; - len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX; - for (i = 0; i < len; i++) - p += sprintf(p, "%02x", sec_ie[i]); - p += sprintf(p, ")"); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = p - buff; - wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? - wrqu.data.length : IW_CUSTOM_MAX; - wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff); - kfree(buff); - } -} diff --git a/drivers/staging/rtl8712/mlme_osdep.h b/drivers/staging/rtl8712/mlme_osdep.h deleted file mode 100644 index a02c782588dd..000000000000 --- a/drivers/staging/rtl8712/mlme_osdep.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __MLME_OSDEP_H_ -#define __MLME_OSDEP_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -void r8712_init_mlme_timer(struct _adapter *padapter); -void r8712_os_indicate_disconnect(struct _adapter *adapter); -void r8712_os_indicate_connect(struct _adapter *adapter); -void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie); -int r8712_recv_indicatepkts_in_order(struct _adapter *adapter, - struct recv_reorder_ctrl *precvreorder_ctrl, - int bforced); -void r8712_indicate_wx_assoc_event(struct _adapter *padapter); -void r8712_indicate_wx_disassoc_event(struct _adapter *padapter); - -#endif /*_MLME_OSDEP_H_*/ - diff --git a/drivers/staging/rtl8712/mp_custom_oid.h b/drivers/staging/rtl8712/mp_custom_oid.h deleted file mode 100644 index a9fac87fcabc..000000000000 --- a/drivers/staging/rtl8712/mp_custom_oid.h +++ /dev/null @@ -1,287 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __CUSTOM_OID_H -#define __CUSTOM_OID_H - -/* 0xFF818000 - 0xFF81802F RTL8180 Mass Production Kit - * 0xFF818500 - 0xFF81850F RTL8185 Setup Utility - * 0xFF818580 - 0xFF81858F RTL8185 Phy Status Utility - * - * by Owen for Production Kit - * For Production Kit with Agilent Equipments - * in order to make our custom oids hopefully somewhat unique - * we will use 0xFF (indicating implementation specific OID) - * 81(first byte of non zero Realtek unique identifier) - * 80 (second byte of non zero Realtek unique identifier) - * XX (the custom OID number - providing 255 possible custom oids) - */ -#define OID_RT_PRO_RESET_DUT 0xFF818000 -#define OID_RT_PRO_SET_DATA_RATE 0xFF818001 -#define OID_RT_PRO_START_TEST 0xFF818002 -#define OID_RT_PRO_STOP_TEST 0xFF818003 -#define OID_RT_PRO_SET_PREAMBLE 0xFF818004 -#define OID_RT_PRO_SET_SCRAMBLER 0xFF818005 -#define OID_RT_PRO_SET_FILTER_BB 0xFF818006 -#define OID_RT_PRO_SET_MANUAL_DIVERSITY_BB 0xFF818007 -#define OID_RT_PRO_SET_CHANNEL_DIRECT_CALL 0xFF818008 -#define OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL 0xFF818009 -#define OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL 0xFF81800A - -#define OID_RT_PRO_SET_TX_ANTENNA_BB 0xFF81800D -#define OID_RT_PRO_SET_ANTENNA_BB 0xFF81800E -#define OID_RT_PRO_SET_CR_SCRAMBLER 0xFF81800F -#define OID_RT_PRO_SET_CR_NEW_FILTER 0xFF818010 -#define OID_RT_PRO_SET_TX_POWER_CONTROL 0xFF818011 -#define OID_RT_PRO_SET_CR_TX_CONFIG 0xFF818012 -#define OID_RT_PRO_GET_TX_POWER_CONTROL 0xFF818013 -#define OID_RT_PRO_GET_CR_SIGNAL_QUALITY 0xFF818014 -#define OID_RT_PRO_SET_CR_SETPOINT 0xFF818015 -#define OID_RT_PRO_SET_INTEGRATOR 0xFF818016 -#define OID_RT_PRO_SET_SIGNAL_QUALITY 0xFF818017 -#define OID_RT_PRO_GET_INTEGRATOR 0xFF818018 -#define OID_RT_PRO_GET_SIGNAL_QUALITY 0xFF818019 -#define OID_RT_PRO_QUERY_EEPROM_TYPE 0xFF81801A -#define OID_RT_PRO_WRITE_MAC_ADDRESS 0xFF81801B -#define OID_RT_PRO_READ_MAC_ADDRESS 0xFF81801C -#define OID_RT_PRO_WRITE_CIS_DATA 0xFF81801D -#define OID_RT_PRO_READ_CIS_DATA 0xFF81801E -#define OID_RT_PRO_WRITE_POWER_CONTROL 0xFF81801F -#define OID_RT_PRO_READ_POWER_CONTROL 0xFF818020 -#define OID_RT_PRO_WRITE_EEPROM 0xFF818021 -#define OID_RT_PRO_READ_EEPROM 0xFF818022 -#define OID_RT_PRO_RESET_TX_PACKET_SENT 0xFF818023 -#define OID_RT_PRO_QUERY_TX_PACKET_SENT 0xFF818024 -#define OID_RT_PRO_RESET_RX_PACKET_RECEIVED 0xFF818025 -#define OID_RT_PRO_QUERY_RX_PACKET_RECEIVED 0xFF818026 -#define OID_RT_PRO_QUERY_RX_PACKET_CRC32_ERROR 0xFF818027 -#define OID_RT_PRO_QUERY_CURRENT_ADDRESS 0xFF818028 -#define OID_RT_PRO_QUERY_PERMANENT_ADDRESS 0xFF818029 -#define OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS 0xFF81802A -#define OID_RT_PRO_RECEIVE_PACKET 0xFF81802C -#define OID_RT_PRO_WRITE_EEPROM_BYTE 0xFF81802D -#define OID_RT_PRO_READ_EEPROM_BYTE 0xFF81802E -#define OID_RT_PRO_SET_MODULATION 0xFF81802F -#define OID_RT_DRIVER_OPTION 0xFF818080 -#define OID_RT_RF_OFF 0xFF818081 -#define OID_RT_AUTH_STATUS 0xFF818082 -#define OID_RT_PRO_SET_CONTINUOUS_TX 0xFF81800B -#define OID_RT_PRO_SET_SINGLE_CARRIER_TX 0xFF81800C -#define OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX 0xFF81802B -#define OID_RT_PRO_SET_SINGLE_TONE_TX 0xFF818043 -#define OID_RT_UTILITY_FALSE_ALARM_COUNTERS 0xFF818580 -#define OID_RT_UTILITY_SELECT_DEBUG_MODE 0xFF818581 -#define OID_RT_UTILITY_SELECT_SUBCARRIER_NUMBER 0xFF818582 -#define OID_RT_UTILITY_GET_RSSI_STATUS 0xFF818583 -#define OID_RT_UTILITY_GET_FRAME_DETECTION_STATUS 0xFF818584 -#define OID_RT_UTILITY_GET_AGC_AND_FREQUENCY_OFFSET_ESTIMATION_STATUS \ - 0xFF818585 -#define OID_RT_UTILITY_GET_CHANNEL_ESTIMATION_STATUS 0xFF818586 -#define OID_RT_WIRELESS_MODE 0xFF818500 -#define OID_RT_SUPPORTED_RATES 0xFF818501 -#define OID_RT_DESIRED_RATES 0xFF818502 -#define OID_RT_WIRELESS_MODE_STARTING_ADHOC 0xFF818503 -#define OID_RT_GET_CONNECT_STATE 0xFF030001 -#define OID_RT_RESCAN 0xFF030002 -#define OID_RT_SET_KEY_LENGTH 0xFF030003 -#define OID_RT_SET_DEFAULT_KEY_ID 0xFF030004 -#define OID_RT_SET_CHANNEL 0xFF010182 -#define OID_RT_SET_SNIFFER_MODE 0xFF010183 -#define OID_RT_GET_SIGNAL_QUALITY 0xFF010184 -#define OID_RT_GET_SMALL_PACKET_CRC 0xFF010185 -#define OID_RT_GET_MIDDLE_PACKET_CRC 0xFF010186 -#define OID_RT_GET_LARGE_PACKET_CRC 0xFF010187 -#define OID_RT_GET_TX_RETRY 0xFF010188 -#define OID_RT_GET_RX_RETRY 0xFF010189 -#define OID_RT_PRO_SET_FW_DIG_STATE 0xFF01018A -#define OID_RT_PRO_SET_FW_RA_STATE 0xFF01018B -#define OID_RT_GET_RX_TOTAL_PACKET 0xFF010190 -#define OID_RT_GET_TX_BEACON_OK 0xFF010191 -#define OID_RT_GET_TX_BEACON_ERR 0xFF010192 -#define OID_RT_GET_RX_ICV_ERR 0xFF010193 -#define OID_RT_SET_ENCRYPTION_ALGORITHM 0xFF010194 -#define OID_RT_SET_NO_AUTO_RESCAN 0xFF010195 -#define OID_RT_GET_PREAMBLE_MODE 0xFF010196 -#define OID_RT_GET_DRIVER_UP_DELTA_TIME 0xFF010197 -#define OID_RT_GET_AP_IP 0xFF010198 -#define OID_RT_GET_CHANNELPLAN 0xFF010199 -#define OID_RT_SET_PREAMBLE_MODE 0xFF01019A -#define OID_RT_SET_BCN_INTVL 0xFF01019B -#define OID_RT_GET_RF_VENDER 0xFF01019C -#define OID_RT_DEDICATE_PROBE 0xFF01019D -#define OID_RT_PRO_RX_FILTER_PATTERN 0xFF01019E -#define OID_RT_GET_DCST_CURRENT_THRESHOLD 0xFF01019F -#define OID_RT_GET_CCA_ERR 0xFF0101A0 -#define OID_RT_GET_CCA_UPGRADE_THRESHOLD 0xFF0101A1 -#define OID_RT_GET_CCA_FALLBACK_THRESHOLD 0xFF0101A2 -#define OID_RT_GET_CCA_UPGRADE_EVALUATE_TIMES 0xFF0101A3 -#define OID_RT_GET_CCA_FALLBACK_EVALUATE_TIMES 0xFF0101A4 -#define OID_RT_SET_RATE_ADAPTIVE 0xFF0101A5 -#define OID_RT_GET_DCST_EVALUATE_PERIOD 0xFF0101A5 -#define OID_RT_GET_DCST_TIME_UNIT_INDEX 0xFF0101A6 -#define OID_RT_GET_TOTAL_TX_BYTES 0xFF0101A7 -#define OID_RT_GET_TOTAL_RX_BYTES 0xFF0101A8 -#define OID_RT_CURRENT_TX_POWER_LEVEL 0xFF0101A9 -#define OID_RT_GET_ENC_KEY_MISMATCH_COUNT 0xFF0101AA -#define OID_RT_GET_ENC_KEY_MATCH_COUNT 0xFF0101AB -#define OID_RT_GET_CHANNEL 0xFF0101AC -#define OID_RT_SET_CHANNELPLAN 0xFF0101AD -#define OID_RT_GET_HARDWARE_RADIO_OFF 0xFF0101AE -#define OID_RT_CHANNELPLAN_BY_COUNTRY 0xFF0101AF -#define OID_RT_SCAN_AVAILABLE_BSSID 0xFF0101B0 -#define OID_RT_GET_HARDWARE_VERSION 0xFF0101B1 -#define OID_RT_GET_IS_ROAMING 0xFF0101B2 -#define OID_RT_GET_IS_PRIVACY 0xFF0101B3 -#define OID_RT_GET_KEY_MISMATCH 0xFF0101B4 -#define OID_RT_SET_RSSI_ROAM_TRAFFIC_TH 0xFF0101B5 -#define OID_RT_SET_RSSI_ROAM_SIGNAL_TH 0xFF0101B6 -#define OID_RT_RESET_LOG 0xFF0101B7 -#define OID_RT_GET_LOG 0xFF0101B8 -#define OID_RT_SET_INDICATE_HIDDEN_AP 0xFF0101B9 -#define OID_RT_GET_HEADER_FAIL 0xFF0101BA -#define OID_RT_SUPPORTED_WIRELESS_MODE 0xFF0101BB -#define OID_RT_GET_CHANNEL_LIST 0xFF0101BC -#define OID_RT_GET_SCAN_IN_PROGRESS 0xFF0101BD -#define OID_RT_GET_TX_INFO 0xFF0101BE -#define OID_RT_RF_READ_WRITE_OFFSET 0xFF0101BF -#define OID_RT_RF_READ_WRITE 0xFF0101C0 -#define OID_RT_FORCED_DATA_RATE 0xFF0101C1 -#define OID_RT_WIRELESS_MODE_FOR_SCAN_LIST 0xFF0101C2 -#define OID_RT_GET_BSS_WIRELESS_MODE 0xFF0101C3 -#define OID_RT_SCAN_WITH_MAGIC_PACKET 0xFF0101C4 -#define OID_RT_PRO_RX_FILTER 0xFF0111C0 -#define OID_CE_USB_WRITE_REGISTRY 0xFF0111C1 -#define OID_CE_USB_READ_REGISTRY 0xFF0111C2 -#define OID_RT_PRO_SET_INITIAL_GAIN 0xFF0111C3 -#define OID_RT_PRO_SET_BB_RF_STANDBY_MODE 0xFF0111C4 -#define OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE 0xFF0111C5 -#define OID_RT_PRO_SET_TX_CHARGE_PUMP 0xFF0111C6 -#define OID_RT_PRO_SET_RX_CHARGE_PUMP 0xFF0111C7 -#define OID_RT_PRO_RF_WRITE_REGISTRY 0xFF0111C8 -#define OID_RT_PRO_RF_READ_REGISTRY 0xFF0111C9 -#define OID_RT_PRO_QUERY_RF_TYPE 0xFF0111CA -#define OID_RT_AP_GET_ASSOCIATED_STATION_LIST 0xFF010300 -#define OID_RT_AP_GET_CURRENT_TIME_STAMP 0xFF010301 -#define OID_RT_AP_SWITCH_INTO_AP_MODE 0xFF010302 -#define OID_RT_AP_SET_DTIM_PERIOD 0xFF010303 -#define OID_RT_AP_SUPPORTED 0xFF010304 -#define OID_RT_AP_SET_PASSPHRASE 0xFF010305 -#define OID_RT_PRO8187_WI_POLL 0xFF818780 -#define OID_RT_PRO_WRITE_BB_REG 0xFF818781 -#define OID_RT_PRO_READ_BB_REG 0xFF818782 -#define OID_RT_PRO_WRITE_RF_REG 0xFF818783 -#define OID_RT_PRO_READ_RF_REG 0xFF818784 -#define OID_RT_MH_VENDER_ID 0xFFEDC100 -#define OID_RT_PRO8711_JOIN_BSS 0xFF871100 -#define OID_RT_PRO_READ_REGISTER 0xFF871101 -#define OID_RT_PRO_WRITE_REGISTER 0xFF871102 -#define OID_RT_PRO_BURST_READ_REGISTER 0xFF871103 -#define OID_RT_PRO_BURST_WRITE_REGISTER 0xFF871104 -#define OID_RT_PRO_WRITE_TXCMD 0xFF871105 -#define OID_RT_PRO_READ16_EEPROM 0xFF871106 -#define OID_RT_PRO_WRITE16_EEPROM 0xFF871107 -#define OID_RT_PRO_H2C_SET_COMMAND 0xFF871108 -#define OID_RT_PRO_H2C_QUERY_RESULT 0xFF871109 -#define OID_RT_PRO8711_WI_POLL 0xFF87110A -#define OID_RT_PRO8711_PKT_LOSS 0xFF87110B -#define OID_RT_RD_ATTRIB_MEM 0xFF87110C -#define OID_RT_WR_ATTRIB_MEM 0xFF87110D -/*Method 2 for H2C/C2H*/ -#define OID_RT_PRO_H2C_CMD_MODE 0xFF871110 -#define OID_RT_PRO_H2C_CMD_RSP_MODE 0xFF871111 -#define OID_RT_PRO_H2C_CMD_EVENT_MODE 0xFF871112 -#define OID_RT_PRO_WAIT_C2H_EVENT 0xFF871113 -#define OID_RT_PRO_RW_ACCESS_PROTOCOL_TEST 0xFF871114 -#define OID_RT_PRO_SCSI_ACCESS_TEST 0xFF871115 -#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_OUT 0xFF871116 -#define OID_RT_PRO_SCSI_TCPIPOFFLOAD_IN 0xFF871117 -#define OID_RT_RRO_RX_PKT_VIA_IOCTRL 0xFF871118 -#define OID_RT_RRO_RX_PKTARRAY_VIA_IOCTRL 0xFF871119 -#define OID_RT_RPO_SET_PWRMGT_TEST 0xFF87111A -#define OID_RT_PRO_QRY_PWRMGT_TEST 0XFF87111B -#define OID_RT_RPO_ASYNC_RWIO_TEST 0xFF87111C -#define OID_RT_RPO_ASYNC_RWIO_POLL 0xFF87111D -#define OID_RT_PRO_SET_RF_INTFS 0xFF87111E -#define OID_RT_POLL_RX_STATUS 0xFF87111F -#define OID_RT_PRO_CFG_DEBUG_MESSAGE 0xFF871120 -#define OID_RT_PRO_SET_DATA_RATE_EX 0xFF871121 -#define OID_RT_PRO_SET_BASIC_RATE 0xFF871122 -#define OID_RT_PRO_READ_TSSI 0xFF871123 -#define OID_RT_PRO_SET_POWER_TRACKING 0xFF871124 -#define OID_RT_PRO_QRY_PWRSTATE 0xFF871150 -#define OID_RT_PRO_SET_PWRSTATE 0xFF871151 -/*Method 2 , using workitem */ -#define OID_RT_SET_READ_REG 0xFF871181 -#define OID_RT_SET_WRITE_REG 0xFF871182 -#define OID_RT_SET_BURST_READ_REG 0xFF871183 -#define OID_RT_SET_BURST_WRITE_REG 0xFF871184 -#define OID_RT_SET_WRITE_TXCMD 0xFF871185 -#define OID_RT_SET_READ16_EEPROM 0xFF871186 -#define OID_RT_SET_WRITE16_EEPROM 0xFF871187 -#define OID_RT_QRY_POLL_WKITEM 0xFF871188 - -/*For SDIO INTERFACE only*/ -#define OID_RT_PRO_SYNCPAGERW_SRAM 0xFF8711A0 -#define OID_RT_PRO_871X_DRV_EXT 0xFF8711A1 - -/*For USB INTERFACE only*/ -#define OID_RT_PRO_USB_VENDOR_REQ 0xFF8711B0 -#define OID_RT_PRO_SCSI_AUTO_TEST 0xFF8711B1 -#define OID_RT_PRO_USB_MAC_AC_FIFO_WRITE 0xFF8711B2 -#define OID_RT_PRO_USB_MAC_RX_FIFO_READ 0xFF8711B3 -#define OID_RT_PRO_USB_MAC_RX_FIFO_POLLING 0xFF8711B4 - -#define OID_RT_PRO_H2C_SET_RATE_TABLE 0xFF8711FB -#define OID_RT_PRO_H2C_GET_RATE_TABLE 0xFF8711FC -#define OID_RT_PRO_H2C_C2H_LBK_TEST 0xFF8711FE - -#define OID_RT_PRO_ENCRYPTION_CTRL 0xFF871200 -#define OID_RT_PRO_ADD_STA_INFO 0xFF871201 -#define OID_RT_PRO_DELE_STA_INFO 0xFF871202 -#define OID_RT_PRO_QUERY_DR_VARIABLE 0xFF871203 - -#define OID_RT_PRO_RX_PACKET_TYPE 0xFF871204 - -#define OID_RT_PRO_READ_EFUSE 0xFF871205 -#define OID_RT_PRO_WRITE_EFUSE 0xFF871206 -#define OID_RT_PRO_RW_EFUSE_PGPKT 0xFF871207 -#define OID_RT_GET_EFUSE_CURRENT_SIZE 0xFF871208 - -#define OID_RT_SET_BANDWIDTH 0xFF871209 -#define OID_RT_SET_CRYSTAL_CAP 0xFF87120A - -#define OID_RT_SET_RX_PACKET_TYPE 0xFF87120B - -#define OID_RT_GET_EFUSE_MAX_SIZE 0xFF87120C - -#define OID_RT_PRO_SET_TX_AGC_OFFSET 0xFF87120D - -#define OID_RT_PRO_SET_PKT_TEST_MODE 0xFF87120E - -#define OID_RT_PRO_FOR_EVM_TEST_SETTING 0xFF87120F - -#define OID_RT_PRO_GET_THERMAL_METER 0xFF871210 - -#define OID_RT_RESET_PHY_RX_PACKET_COUNT 0xFF871211 -#define OID_RT_GET_PHY_RX_PACKET_RECEIVED 0xFF871212 -#define OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR 0xFF871213 - -#define OID_RT_SET_POWER_DOWN 0xFF871214 - -#define OID_RT_GET_POWER_MODE 0xFF871215 - -#define OID_RT_PRO_EFUSE 0xFF871216 -#define OID_RT_PRO_EFUSE_MAP 0xFF871217 - -#endif /*#ifndef __CUSTOM_OID_H */ - diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c deleted file mode 100644 index b18e6d9c832b..000000000000 --- a/drivers/staging/rtl8712/os_intfs.c +++ /dev/null @@ -1,482 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * os_intfs.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _OS_INTFS_C_ - -#include -#include -#include -#include "osdep_service.h" -#include "drv_types.h" -#include "xmit_osdep.h" -#include "recv_osdep.h" -#include "rtl871x_ioctl.h" -#include "usb_osintf.h" - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("rtl871x wireless lan driver"); -MODULE_AUTHOR("Larry Finger"); - -static char ifname[IFNAMSIZ] = "wlan%d"; - -/* module param defaults */ -static int chip_version = RTL8712_2ndCUT; -static int rfintfs = HWPI; -static int lbkmode = RTL8712_AIR_TRX; -static int hci = RTL8712_USB; -static int ampdu_enable = 1;/*for enable tx_ampdu*/ - -/* The video_mode variable is for video mode.*/ -/* It may be specify when inserting module with video_mode=1 parameter.*/ -static int video_mode = 1; /* enable video mode*/ - -/*Ndis802_11Infrastructure; infra, ad-hoc, auto*/ -static int network_mode = Ndis802_11IBSS; -static int channel = 1;/*ad-hoc support requirement*/ -static int wireless_mode = WIRELESS_11BG; -static int vrtl_carrier_sense = AUTO_VCS; -static int vcs_type = RTS_CTS; -static int frag_thresh = 2346; -static int preamble = PREAMBLE_LONG;/*long, short, auto*/ -static int scan_mode = 1;/*active, passive*/ -static int adhoc_tx_pwr = 1; -static int soft_ap; -static int smart_ps = 1; -static int power_mgnt = PS_MODE_ACTIVE; -static int radio_enable = 1; -static int long_retry_lmt = 7; -static int short_retry_lmt = 7; -static int busy_thresh = 40; -static int ack_policy = NORMAL_ACK; -static int mp_mode; -static int software_encrypt; -static int software_decrypt; - -static int wmm_enable;/* default is set to disable the wmm.*/ -static int uapsd_enable; -static int uapsd_max_sp = NO_LIMIT; -static int uapsd_acbk_en; -static int uapsd_acbe_en; -static int uapsd_acvi_en; -static int uapsd_acvo_en; - -static int ht_enable = 1; -static int cbw40_enable = 1; -static int rf_config = RTL8712_RF_1T2R; /* 1T2R*/ -static int low_power; -/* mac address to use instead of the one stored in Efuse */ -char *r8712_initmac; -static char *initmac; -/* if wifi_test = 1, driver will disable the turbo mode and pass it to - * firmware private. - */ -static int wifi_test; - -module_param_string(ifname, ifname, sizeof(ifname), 0644); -module_param(wifi_test, int, 0644); -module_param(initmac, charp, 0644); -module_param(video_mode, int, 0644); -module_param(chip_version, int, 0644); -module_param(rfintfs, int, 0644); -module_param(lbkmode, int, 0644); -module_param(hci, int, 0644); -module_param(network_mode, int, 0644); -module_param(channel, int, 0644); -module_param(mp_mode, int, 0644); -module_param(wmm_enable, int, 0644); -module_param(vrtl_carrier_sense, int, 0644); -module_param(vcs_type, int, 0644); -module_param(busy_thresh, int, 0644); -module_param(ht_enable, int, 0644); -module_param(cbw40_enable, int, 0644); -module_param(ampdu_enable, int, 0644); -module_param(rf_config, int, 0644); -module_param(power_mgnt, int, 0644); -module_param(low_power, int, 0644); - -MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); -MODULE_PARM_DESC(initmac, "MAC-Address, default: use FUSE"); - -static int netdev_open(struct net_device *pnetdev); -static int netdev_close(struct net_device *pnetdev); - -static void loadparam(struct _adapter *padapter, struct net_device *pnetdev) -{ - struct registry_priv *registry_par = &padapter->registrypriv; - - registry_par->chip_version = (u8)chip_version; - registry_par->rfintfs = (u8)rfintfs; - registry_par->lbkmode = (u8)lbkmode; - registry_par->hci = (u8)hci; - registry_par->network_mode = (u8)network_mode; - memcpy(registry_par->ssid.Ssid, "ANY", 3); - registry_par->ssid.SsidLength = 3; - registry_par->channel = (u8)channel; - registry_par->wireless_mode = (u8)wireless_mode; - registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense; - registry_par->vcs_type = (u8)vcs_type; - registry_par->frag_thresh = (u16)frag_thresh; - registry_par->preamble = (u8)preamble; - registry_par->scan_mode = (u8)scan_mode; - registry_par->adhoc_tx_pwr = (u8)adhoc_tx_pwr; - registry_par->soft_ap = (u8)soft_ap; - registry_par->smart_ps = (u8)smart_ps; - registry_par->power_mgnt = (u8)power_mgnt; - registry_par->radio_enable = (u8)radio_enable; - registry_par->long_retry_lmt = (u8)long_retry_lmt; - registry_par->short_retry_lmt = (u8)short_retry_lmt; - registry_par->busy_thresh = (u16)busy_thresh; - registry_par->ack_policy = (u8)ack_policy; - registry_par->mp_mode = (u8)mp_mode; - registry_par->software_encrypt = (u8)software_encrypt; - registry_par->software_decrypt = (u8)software_decrypt; - /*UAPSD*/ - registry_par->wmm_enable = (u8)wmm_enable; - registry_par->uapsd_enable = (u8)uapsd_enable; - registry_par->uapsd_max_sp = (u8)uapsd_max_sp; - registry_par->uapsd_acbk_en = (u8)uapsd_acbk_en; - registry_par->uapsd_acbe_en = (u8)uapsd_acbe_en; - registry_par->uapsd_acvi_en = (u8)uapsd_acvi_en; - registry_par->uapsd_acvo_en = (u8)uapsd_acvo_en; - registry_par->ht_enable = (u8)ht_enable; - registry_par->cbw40_enable = (u8)cbw40_enable; - registry_par->ampdu_enable = (u8)ampdu_enable; - registry_par->rf_config = (u8)rf_config; - registry_par->low_power = (u8)low_power; - registry_par->wifi_test = (u8)wifi_test; - r8712_initmac = initmac; -} - -static int r871x_net_set_mac_address(struct net_device *pnetdev, void *p) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - struct sockaddr *addr = p; - - if (!padapter->bup) - eth_hw_addr_set(pnetdev, addr->sa_data); - return 0; -} - -static struct net_device_stats *r871x_net_get_stats(struct net_device *pnetdev) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct recv_priv *precvpriv = &padapter->recvpriv; - - padapter->stats.tx_packets = pxmitpriv->tx_pkts; - padapter->stats.rx_packets = precvpriv->rx_pkts; - padapter->stats.tx_dropped = pxmitpriv->tx_drop; - padapter->stats.rx_dropped = precvpriv->rx_drop; - padapter->stats.tx_bytes = pxmitpriv->tx_bytes; - padapter->stats.rx_bytes = precvpriv->rx_bytes; - return &padapter->stats; -} - -static const struct net_device_ops rtl8712_netdev_ops = { - .ndo_open = netdev_open, - .ndo_stop = netdev_close, - .ndo_start_xmit = r8712_xmit_entry, - .ndo_set_mac_address = r871x_net_set_mac_address, - .ndo_get_stats = r871x_net_get_stats, - .ndo_do_ioctl = r871x_ioctl, -}; - -struct net_device *r8712_init_netdev(void) -{ - struct _adapter *padapter; - struct net_device *pnetdev; - - pnetdev = alloc_etherdev(sizeof(struct _adapter)); - if (!pnetdev) - return NULL; - if (dev_alloc_name(pnetdev, ifname) < 0) { - strscpy(ifname, "wlan%d", sizeof(ifname)); - dev_alloc_name(pnetdev, ifname); - } - padapter = netdev_priv(pnetdev); - padapter->pnetdev = pnetdev; - pr_info("r8712u: register rtl8712_netdev_ops to netdev_ops\n"); - pnetdev->netdev_ops = &rtl8712_netdev_ops; - pnetdev->watchdog_timeo = HZ; /* 1 second timeout */ - pnetdev->wireless_handlers = (struct iw_handler_def *) - &r871x_handlers_def; - loadparam(padapter, pnetdev); - netif_carrier_off(pnetdev); - padapter->pid = 0; /* Initial the PID value used for HW PBC.*/ - return pnetdev; -} - -static u32 start_drv_threads(struct _adapter *padapter) -{ - padapter->cmd_thread = kthread_run(r8712_cmd_thread, padapter, "%s", - padapter->pnetdev->name); - if (IS_ERR(padapter->cmd_thread)) - return _FAIL; - return _SUCCESS; -} - -void r8712_stop_drv_threads(struct _adapter *padapter) -{ - struct completion *completion = - &padapter->cmdpriv.terminate_cmdthread_comp; - - /*Below is to terminate r8712_cmd_thread & event_thread...*/ - complete(&padapter->cmdpriv.cmd_queue_comp); - if (padapter->cmd_thread) - wait_for_completion_interruptible(completion); - padapter->cmdpriv.cmd_seq = 1; -} - -static void start_drv_timers(struct _adapter *padapter) -{ - mod_timer(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, - jiffies + msecs_to_jiffies(5000)); - mod_timer(&padapter->mlmepriv.wdg_timer, - jiffies + msecs_to_jiffies(2000)); -} - -void r8712_stop_drv_timers(struct _adapter *padapter) -{ - del_timer_sync(&padapter->mlmepriv.assoc_timer); - del_timer_sync(&padapter->securitypriv.tkip_timer); - del_timer_sync(&padapter->mlmepriv.scan_to_timer); - del_timer_sync(&padapter->mlmepriv.dhcp_timer); - del_timer_sync(&padapter->mlmepriv.wdg_timer); - del_timer_sync(&padapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer); -} - -static void init_default_value(struct _adapter *padapter) -{ - struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - /*xmit_priv*/ - pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense; - pxmitpriv->vcs = pregistrypriv->vcs_type; - pxmitpriv->vcs_type = pregistrypriv->vcs_type; - pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; - pxmitpriv->frag_len = pregistrypriv->frag_thresh; - /* mlme_priv */ - /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/ - pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */ - /*ht_priv*/ - { - int i; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - phtpriv->ampdu_enable = false;/*set to disabled*/ - for (i = 0; i < 16; i++) - phtpriv->baddbareq_issued[i] = false; - } - /*security_priv*/ - psecuritypriv->sw_encrypt = pregistrypriv->software_encrypt; - psecuritypriv->sw_decrypt = pregistrypriv->software_decrypt; - psecuritypriv->binstallGrpkey = _FAIL; - /*pwrctrl_priv*/ - /*registry_priv*/ - r8712_init_registrypriv_dev_network(padapter); - r8712_update_registrypriv_dev_network(padapter); - /*misc.*/ -} - -int r8712_init_drv_sw(struct _adapter *padapter) -{ - int ret; - - ret = r8712_init_cmd_priv(&padapter->cmdpriv); - if (ret) - return ret; - padapter->cmdpriv.padapter = padapter; - ret = r8712_init_evt_priv(&padapter->evtpriv); - if (ret) - goto free_cmd; - ret = r8712_init_mlme_priv(padapter); - if (ret) - goto free_evt; - ret = _r8712_init_xmit_priv(&padapter->xmitpriv, padapter); - if (ret) - goto free_mlme; - ret = _r8712_init_recv_priv(&padapter->recvpriv, padapter); - if (ret) - goto free_xmit; - memset((unsigned char *)&padapter->securitypriv, 0, - sizeof(struct security_priv)); - timer_setup(&padapter->securitypriv.tkip_timer, - r8712_use_tkipkey_handler, 0); - ret = _r8712_init_sta_priv(&padapter->stapriv); - if (ret) - goto free_recv; - padapter->stapriv.padapter = padapter; - r8712_init_bcmc_stainfo(padapter); - r8712_init_pwrctrl_priv(padapter); - mp871xinit(padapter); - init_default_value(padapter); - r8712_InitSwLeds(padapter); - mutex_init(&padapter->mutex_start); - - return 0; - -free_recv: - _r8712_free_recv_priv(&padapter->recvpriv); -free_xmit: - _free_xmit_priv(&padapter->xmitpriv); -free_mlme: - r8712_free_mlme_priv(&padapter->mlmepriv); -free_evt: - r8712_free_evt_priv(&padapter->evtpriv); -free_cmd: - r8712_free_cmd_priv(&padapter->cmdpriv); - return ret; -} - -void r8712_free_drv_sw(struct _adapter *padapter) -{ - r8712_free_cmd_priv(&padapter->cmdpriv); - r8712_free_evt_priv(&padapter->evtpriv); - r8712_DeInitSwLeds(padapter); - r8712_free_mlme_priv(&padapter->mlmepriv); - _free_xmit_priv(&padapter->xmitpriv); - _r8712_free_sta_priv(&padapter->stapriv); - _r8712_free_recv_priv(&padapter->recvpriv); - mp871xdeinit(padapter); -} - -static void enable_video_mode(struct _adapter *padapter, int cbw40_value) -{ - /* bit 8: - * 1 -> enable video mode to 96B AP - * 0 -> disable video mode to 96B AP - * bit 9: - * 1 -> enable 40MHz mode - * 0 -> disable 40MHz mode - * bit 10: - * 1 -> enable STBC - * 0 -> disable STBC - */ - u32 intcmd = 0xf4000500; /* enable bit8, bit10*/ - - if (cbw40_value) { - /* if the driver supports the 40M bandwidth, - * we can enable the bit 9. - */ - intcmd |= 0x200; - } - r8712_fw_cmd(padapter, intcmd); -} - -/* - * - * This function intends to handle the activation of an interface - * i.e. when it is brought Up/Active from a Down state. - * - */ -static int netdev_open(struct net_device *pnetdev) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - - mutex_lock(&padapter->mutex_start); - if (!padapter->bup) { - padapter->driver_stopped = false; - padapter->surprise_removed = false; - padapter->bup = true; - if (rtl871x_hal_init(padapter) != _SUCCESS) - goto netdev_open_error; - if (!r8712_initmac) { - /* Use the mac address stored in the Efuse */ - eth_hw_addr_set(pnetdev, - padapter->eeprompriv.mac_addr); - } else { - /* We have to inform f/w to use user-supplied MAC - * address. - */ - msleep(200); - r8712_setMacAddr_cmd(padapter, - (const u8 *)pnetdev->dev_addr); - /* - * The "myid" function will get the wifi mac address - * from eeprompriv structure instead of netdev - * structure. So, we have to overwrite the mac_addr - * stored in the eeprompriv structure. In this case, - * the real mac address won't be used anymore. So that, - * the eeprompriv.mac_addr should store the mac which - * users specify. - */ - memcpy(padapter->eeprompriv.mac_addr, - pnetdev->dev_addr, ETH_ALEN); - } - if (start_drv_threads(padapter) != _SUCCESS) - goto netdev_open_error; - if (!padapter->dvobjpriv.inirp_init) - goto netdev_open_error; - else - padapter->dvobjpriv.inirp_init(padapter); - r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, - padapter->registrypriv.smart_ps); - } - if (!netif_queue_stopped(pnetdev)) - netif_start_queue(pnetdev); - else - netif_wake_queue(pnetdev); - - if (video_mode) - enable_video_mode(padapter, cbw40_enable); - /* start driver mlme relation timer */ - start_drv_timers(padapter); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); - mutex_unlock(&padapter->mutex_start); - return 0; -netdev_open_error: - padapter->bup = false; - netif_carrier_off(pnetdev); - netif_stop_queue(pnetdev); - mutex_unlock(&padapter->mutex_start); - return -1; -} - -/* - * - * This function intends to handle the shutdown of an interface - * i.e. when it is brought Down from an Up/Active state. - * - */ -static int netdev_close(struct net_device *pnetdev) -{ - struct _adapter *padapter = netdev_priv(pnetdev); - - /* Close LED*/ - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_POWER_OFF); - msleep(200); - - /*s1.*/ - if (pnetdev) { - if (!netif_queue_stopped(pnetdev)) - netif_stop_queue(pnetdev); - } - /*s2.*/ - /*s2-1. issue disassoc_cmd to fw*/ - r8712_disassoc_cmd(padapter); - /*s2-2. indicate disconnect to os*/ - r8712_ind_disconnect(padapter); - /*s2-3.*/ - r8712_free_assoc_resources(padapter); - /*s2-4.*/ - r8712_free_network_queue(padapter); - return 0; -} - -#include "mlme_osdep.h" diff --git a/drivers/staging/rtl8712/osdep_intf.h b/drivers/staging/rtl8712/osdep_intf.h deleted file mode 100644 index 9e75116c987e..000000000000 --- a/drivers/staging/rtl8712/osdep_intf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __OSDEP_INTF_H_ -#define __OSDEP_INTF_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define RND4(x) (((x >> 2) + ((x & 3) != 0)) << 2) - -struct intf_priv { - u8 *intf_dev; - /* when in USB, IO is through interrupt in/out endpoints */ - struct usb_device *udev; - struct urb *piorw_urb; - struct completion io_retevt_comp; -}; - -int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); - -#endif /*_OSDEP_INTF_H_*/ diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h deleted file mode 100644 index 0d9bb42cbc58..000000000000 --- a/drivers/staging/rtl8712/osdep_service.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __OSDEP_SERVICE_H_ -#define __OSDEP_SERVICE_H_ - -#define _SUCCESS 1 -#define _FAIL 0 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include /* Necessary because we use the proc fs */ - -#include "basic_types.h" - -struct __queue { - struct list_head queue; - spinlock_t lock; -}; - -#define _pkt struct sk_buff -#define _buffer unsigned char - -#define _init_queue(pqueue) \ - do { \ - INIT_LIST_HEAD(&((pqueue)->queue)); \ - spin_lock_init(&((pqueue)->lock)); \ - } while (0) - -static inline u32 end_of_queue_search(struct list_head *head, - struct list_head *plist) -{ - return (head == plist); -} - -static inline void flush_signals_thread(void) -{ - if (signal_pending(current)) - flush_signals(current); -} - -#endif - diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c deleted file mode 100644 index 215fca4abb3a..000000000000 --- a/drivers/staging/rtl8712/recv_linux.c +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * recv_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RECV_OSDEP_C_ - -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "wifi.h" -#include "recv_osdep.h" -#include "osdep_intf.h" -#include "ethernet.h" -#include -#include "usb_ops.h" - -/*init os related resource in struct recv_priv*/ -/*alloc os related resource in union recv_frame*/ -void r8712_os_recv_resource_alloc(struct _adapter *padapter, - union recv_frame *precvframe) -{ - precvframe->u.hdr.pkt_newalloc = NULL; - precvframe->u.hdr.pkt = NULL; -} - -/*alloc os related resource in struct recv_buf*/ -int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, - struct recv_buf *precvbuf) -{ - int res = 0; - - precvbuf->irp_pending = false; - precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); - if (!precvbuf->purb) - res = -ENOMEM; - precvbuf->pskb = NULL; - precvbuf->pallocated_buf = NULL; - precvbuf->pbuf = NULL; - precvbuf->pdata = NULL; - precvbuf->phead = NULL; - precvbuf->ptail = NULL; - precvbuf->pend = NULL; - precvbuf->transfer_len = 0; - precvbuf->len = 0; - return res; -} - -/*free os related resource in struct recv_buf*/ -void r8712_os_recvbuf_resource_free(struct _adapter *padapter, - struct recv_buf *precvbuf) -{ - if (precvbuf->pskb) - dev_kfree_skb_any(precvbuf->pskb); - if (precvbuf->purb) { - usb_kill_urb(precvbuf->purb); - usb_free_urb(precvbuf->purb); - } -} - -void r8712_handle_tkip_mic_err(struct _adapter *adapter, u8 bgroup) -{ - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - struct mlme_priv *mlmepriv = &adapter->mlmepriv; - - memset(&ev, 0x00, sizeof(ev)); - if (bgroup) - ev.flags |= IW_MICFAILURE_GROUP; - else - ev.flags |= IW_MICFAILURE_PAIRWISE; - ev.src_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(ev.src_addr.sa_data, &mlmepriv->assoc_bssid[0]); - memset(&wrqu, 0x00, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(adapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, - (char *)&ev); -} - -void r8712_recv_indicatepkt(struct _adapter *adapter, - union recv_frame *recvframe) -{ - struct recv_priv *recvpriv; - struct __queue *free_recv_queue; - _pkt *skb; - struct rx_pkt_attrib *attrib = &recvframe->u.hdr.attrib; - - recvpriv = &adapter->recvpriv; - free_recv_queue = &recvpriv->free_recv_queue; - skb = recvframe->u.hdr.pkt; - if (!skb) - goto _recv_indicatepkt_drop; - skb->data = recvframe->u.hdr.rx_data; - skb->len = recvframe->u.hdr.len; - skb_set_tail_pointer(skb, skb->len); - if ((attrib->tcpchk_valid == 1) && (attrib->tcp_chkrpt == 1)) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb->ip_summed = CHECKSUM_NONE; - skb->dev = adapter->pnetdev; - skb->protocol = eth_type_trans(skb, adapter->pnetdev); - netif_rx(skb); - recvframe->u.hdr.pkt = NULL; /* pointers to NULL before - * r8712_free_recvframe() - */ - r8712_free_recvframe(recvframe, free_recv_queue); - return; -_recv_indicatepkt_drop: - /*enqueue back to free_recv_queue*/ - if (recvframe) - r8712_free_recvframe(recvframe, free_recv_queue); - recvpriv->rx_drop++; -} - -static void _r8712_reordering_ctrl_timeout_handler (struct timer_list *t) -{ - struct recv_reorder_ctrl *reorder_ctrl = - from_timer(reorder_ctrl, t, reordering_ctrl_timer); - - r8712_reordering_ctrl_timeout_handler(reorder_ctrl); -} - -void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) -{ - timer_setup(&preorder_ctrl->reordering_ctrl_timer, - _r8712_reordering_ctrl_timeout_handler, 0); -} diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h deleted file mode 100644 index fbe3f2868506..000000000000 --- a/drivers/staging/rtl8712/recv_osdep.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RECV_OSDEP_H_ -#define __RECV_OSDEP_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include - -int _r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); -void _r8712_free_recv_priv(struct recv_priv *precvpriv); -void r8712_recv_entry(union recv_frame *precv_frame); -void r8712_recv_indicatepkt(struct _adapter *adapter, - union recv_frame *precv_frame); -void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup); -int r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter); -void r8712_free_recv_priv(struct recv_priv *precvpriv); -void r8712_os_recv_resource_alloc(struct _adapter *padapter, - union recv_frame *precvframe); -int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter, - struct recv_buf *precvbuf); -void r8712_os_recvbuf_resource_free(struct _adapter *padapter, - struct recv_buf *precvbuf); -void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_bitdef.h b/drivers/staging/rtl8712/rtl8712_bitdef.h deleted file mode 100644 index a4a687dcc2e7..000000000000 --- a/drivers/staging/rtl8712/rtl8712_bitdef.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ - -#ifndef __RTL8712_BITDEF_H__ -#define __RTL8712_BITDEF_H__ - -#include "rtl8712_cmdctrl_bitdef.h" -#include "rtl8712_syscfg_bitdef.h" -#include "rtl8712_macsetting_bitdef.h" -#include "rtl8712_timectrl_bitdef.h" -#include "rtl8712_fifoctrl_bitdef.h" -#include "rtl8712_ratectrl_bitdef.h" -#include "rtl8712_edcasetting_bitdef.h" -#include "rtl8712_wmac_bitdef.h" -#include "rtl8712_security_bitdef.h" -#include "rtl8712_powersave_bitdef.h" -#include "rtl8712_gp_bitdef.h" -#include "rtl8712_interrupt_bitdef.h" -#include "rtl8712_debugctrl_bitdef.h" - -#endif /* __RTL8712_BITDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c deleted file mode 100644 index bb7db96ed821..000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ /dev/null @@ -1,409 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_cmd.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_CMD_C_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" -#include "rtl871x_ioctl_set.h" - -static void check_hw_pbc(struct _adapter *padapter) -{ - u8 tmp1byte; - - r8712_write8(padapter, MAC_PINMUX_CTRL, (GPIOMUX_EN | GPIOSEL_GPIO)); - tmp1byte = r8712_read8(padapter, GPIO_IO_SEL); - tmp1byte &= ~(HAL_8192S_HW_GPIO_WPS_BIT); - r8712_write8(padapter, GPIO_IO_SEL, tmp1byte); - tmp1byte = r8712_read8(padapter, GPIO_CTRL); - if (tmp1byte == 0xff) - return; - if (tmp1byte & HAL_8192S_HW_GPIO_WPS_BIT) { - /* Here we only set bPbcPressed to true - * After trigger PBC, the variable will be set to false - */ - netdev_dbg(padapter->pnetdev, "CheckPbcGPIO - PBC is pressed !!!!\n"); - /* 0 is the default value and it means the application monitors - * the HW PBC doesn't provide its pid to driver. - */ - if (padapter->pid == 0) - return; - kill_pid(find_vpid(padapter->pid), SIGUSR1, 1); - } -} - -/* query rx phy status from fw. - * Adhoc mode: beacon. - * Infrastructure mode: beacon , data. - */ -static void query_fw_rx_phy_status(struct _adapter *padapter) -{ - u32 val32 = 0; - int pollingcnts = 50; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { - r8712_write32(padapter, IOCMD_CTRL_REG, 0xf4000001); - msleep(100); - /* Wait FW complete IO Cmd */ - while ((r8712_read32(padapter, IOCMD_CTRL_REG)) && - (pollingcnts > 0)) { - pollingcnts--; - msleep(20); - } - if (pollingcnts != 0) - val32 = r8712_read32(padapter, IOCMD_DATA_REG); - else /* time out */ - val32 = 0; - val32 >>= 4; - padapter->recvpriv.fw_rssi = - (u8)r8712_signal_scale_mapping(val32); - } -} - -/* check mlme, hw, phy, or dynamic algorithm status. */ -static void StatusWatchdogCallback(struct _adapter *padapter) -{ - check_hw_pbc(padapter); - query_fw_rx_phy_status(padapter); -} - -static void r871x_internal_cmd_hdl(struct _adapter *padapter, u8 *pbuf) -{ - struct drvint_cmd_parm *pdrvcmd; - - if (!pbuf) - return; - pdrvcmd = (struct drvint_cmd_parm *)pbuf; - switch (pdrvcmd->i_cid) { - case WDG_WK_CID: - StatusWatchdogCallback(padapter); - break; - default: - break; - } - kfree(pdrvcmd->pbuf); -} - -static u8 read_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - r8712_free_cmd_obj(pcmd); - return H2C_SUCCESS; -} - -static u8 write_bbreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); - return H2C_SUCCESS; -} - -static u8 read_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - u32 val; - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - if (pcmd->rsp && pcmd->rspsz > 0) - memcpy(pcmd->rsp, (u8 *)&val, pcmd->rspsz); - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); - return H2C_SUCCESS; -} - -static u8 write_rfreg_hdl(struct _adapter *padapter, u8 *pbuf) -{ - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - pcmd_callback = cmd_callback[pcmd->cmdcode].callback; - if (!pcmd_callback) - r8712_free_cmd_obj(pcmd); - else - pcmd_callback(padapter, pcmd); - return H2C_SUCCESS; -} - -static u8 sys_suspend_hdl(struct _adapter *padapter, u8 *pbuf) -{ - struct cmd_obj *pcmd = (struct cmd_obj *)pbuf; - - r8712_free_cmd_obj(pcmd); - return H2C_SUCCESS; -} - -static struct cmd_obj *cmd_hdl_filter(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - struct cmd_obj *pcmd_r; - - if (!pcmd) - return pcmd; - pcmd_r = NULL; - - switch (pcmd->cmdcode) { - case GEN_CMD_CODE(_Read_BBREG): - read_bbreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_Write_BBREG): - write_bbreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_Read_RFREG): - read_rfreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_Write_RFREG): - write_rfreg_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_SetUsbSuspend): - sys_suspend_hdl(padapter, (u8 *)pcmd); - break; - case GEN_CMD_CODE(_JoinBss): - r8712_joinbss_reset(padapter); - /* Before set JoinBss_CMD to FW, driver must ensure FW is in - * PS_MODE_ACTIVE. Directly write rpwm to radio on and assign - * new pwr_mode to Driver, instead of use workitem to change - * state. - */ - if (padapter->pwrctrlpriv.pwr_mode > PS_MODE_ACTIVE) { - padapter->pwrctrlpriv.pwr_mode = PS_MODE_ACTIVE; - mutex_lock(&padapter->pwrctrlpriv.mutex_lock); - r8712_set_rpwm(padapter, PS_STATE_S4); - mutex_unlock(&padapter->pwrctrlpriv.mutex_lock); - } - pcmd_r = pcmd; - break; - case _DRV_INT_CMD_: - r871x_internal_cmd_hdl(padapter, pcmd->parmbuf); - r8712_free_cmd_obj(pcmd); - pcmd_r = NULL; - break; - default: - pcmd_r = pcmd; - break; - } - return pcmd_r; /* if returning pcmd_r == NULL, pcmd must be free. */ -} - -u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd) -{ - int pollingcnts = 50; - - r8712_write32(pAdapter, IOCMD_CTRL_REG, cmd); - msleep(100); - while ((r8712_read32(pAdapter, IOCMD_CTRL_REG != 0)) && - (pollingcnts > 0)) { - pollingcnts--; - msleep(20); - } - if (pollingcnts == 0) - return false; - return true; -} - -void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag) -{ - if (flag == 0) /* set */ - r8712_write32(pAdapter, IOCMD_DATA_REG, *value); - else /* query */ - *value = r8712_read32(pAdapter, IOCMD_DATA_REG); -} - -int r8712_cmd_thread(void *context) -{ - struct cmd_obj *pcmd; - unsigned int cmdsz, wr_sz; - __le32 *pcmdbuf; - struct tx_desc *pdesc; - void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); - struct _adapter *padapter = context; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct completion *cmd_queue_comp = - &pcmdpriv->cmd_queue_comp; - struct mutex *pwctrl_lock = &padapter->pwrctrlpriv.mutex_lock; - - allow_signal(SIGTERM); - while (1) { - if (wait_for_completion_interruptible(cmd_queue_comp)) - break; - if (padapter->driver_stopped || padapter->surprise_removed) - break; - if (r8712_register_cmd_alive(padapter)) - continue; -_next: - pcmd = r8712_dequeue_cmd(&pcmdpriv->cmd_queue); - if (!(pcmd)) { - r8712_unregister_cmd_alive(padapter); - continue; - } - pcmdbuf = (__le32 *)pcmdpriv->cmd_buf; - pdesc = (struct tx_desc *)pcmdbuf; - memset(pdesc, 0, TXDESC_SIZE); - pcmd = cmd_hdl_filter(padapter, pcmd); - if (pcmd) { /* if pcmd != NULL, cmd will be handled by f/w */ - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - u8 blnPending = 0; - u16 cmdcode = pcmd->cmdcode; - - pcmdpriv->cmd_issued_cnt++; - cmdsz = round_up(pcmd->cmdsz, 8); - wr_sz = TXDESC_SIZE + 8 + cmdsz; - pdesc->txdw0 |= cpu_to_le32((wr_sz - TXDESC_SIZE) & - 0x0000ffff); - if (pdvobj->ishighspeed) { - if ((wr_sz % 512) == 0) - blnPending = 1; - } else { - if ((wr_sz % 64) == 0) - blnPending = 1; - } - if (blnPending) { /* 32 bytes for TX Desc - 8 offset */ - pdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + - OFFSET_SZ + 8) << OFFSET_SHT) & - 0x00ff0000); - } else { - pdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + - OFFSET_SZ) << - OFFSET_SHT) & - 0x00ff0000); - } - pdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); - pdesc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) & - 0x00001f00); - pcmdbuf += (TXDESC_SIZE >> 2); - *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) | - (pcmd->cmdcode << 16) | - (pcmdpriv->cmd_seq << 24)); - pcmdbuf += 2; /* 8 bytes alignment */ - memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); - if (blnPending) - wr_sz += 8; /* Append 8 bytes */ - r8712_write_mem(padapter, RTL8712_DMA_H2CCMD, wr_sz, - (u8 *)pdesc); - pcmdpriv->cmd_seq++; - if (cmdcode == GEN_CMD_CODE(_CreateBss)) { - pcmd->res = H2C_SUCCESS; - pcmd_callback = cmd_callback[cmdcode].callback; - if (pcmd_callback) - pcmd_callback(padapter, pcmd); - continue; - } - if (cmdcode == GEN_CMD_CODE(_SetPwrMode)) { - if (padapter->pwrctrlpriv.bSleep) { - mutex_lock(pwctrl_lock); - r8712_set_rpwm(padapter, PS_STATE_S2); - mutex_unlock(pwctrl_lock); - } - } - r8712_free_cmd_obj(pcmd); - if (list_empty(&pcmdpriv->cmd_queue.queue)) { - r8712_unregister_cmd_alive(padapter); - continue; - } else { - goto _next; - } - } else { - goto _next; - } - flush_signals_thread(); - } - /* free all cmd_obj resources */ - do { - pcmd = r8712_dequeue_cmd(&pcmdpriv->cmd_queue); - if (!pcmd) - break; - r8712_free_cmd_obj(pcmd); - } while (1); - complete(&pcmdpriv->terminate_cmdthread_comp); - return 0; -} - -void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf) -{ - u8 evt_code, evt_seq; - u16 evt_sz; - void (*event_callback)(struct _adapter *dev, u8 *pbuf); - struct evt_priv *pevt_priv = &padapter->evtpriv; - - if (!peventbuf) - goto _abort_event_; - evt_sz = (u16)(le32_to_cpu(*peventbuf) & 0xffff); - evt_seq = (u8)((le32_to_cpu(*peventbuf) >> 24) & 0x7f); - evt_code = (u8)((le32_to_cpu(*peventbuf) >> 16) & 0xff); - /* checking event sequence... */ - if ((evt_seq & 0x7f) != pevt_priv->event_seq) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } - /* checking if event code is valid */ - if (evt_code >= MAX_C2HEVT) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } else if ((evt_code == GEN_EVT_CODE(_Survey)) && - (evt_sz > sizeof(struct wlan_bssid_ex))) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } - /* checking if event size match the event parm size */ - if ((wlanevents[evt_code].parmsize) && - (wlanevents[evt_code].parmsize != evt_sz)) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } else if ((evt_sz == 0) && (evt_code != GEN_EVT_CODE(_WPS_PBC))) { - pevt_priv->event_seq = ((evt_seq + 1) & 0x7f); - goto _abort_event_; - } - pevt_priv->event_seq++; /* update evt_seq */ - if (pevt_priv->event_seq > 127) - pevt_priv->event_seq = 0; - /* move to event content, 8 bytes alignment */ - peventbuf = peventbuf + 2; - event_callback = wlanevents[evt_code].event_callback; - if (event_callback) - event_callback(padapter, (u8 *)peventbuf); - pevt_priv->evt_done_cnt++; -_abort_event_: - return; -} diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h deleted file mode 100644 index a34d0dd023f3..000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmd.h +++ /dev/null @@ -1,231 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_CMD_H_ -#define __RTL8712_CMD_H_ - -#define CMD_HDR_SZ 8 - -u8 r8712_fw_cmd(struct _adapter *pAdapter, u32 cmd); -void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag); - -struct cmd_hdr { - u32 cmd_dw0; - u32 cmd_dw1; -}; - -enum rtl8712_h2c_cmd { - GEN_CMD_CODE(_Read_MACREG), /*0*/ - GEN_CMD_CODE(_Write_MACREG), - GEN_CMD_CODE(_Read_BBREG), - GEN_CMD_CODE(_Write_BBREG), - GEN_CMD_CODE(_Read_RFREG), - GEN_CMD_CODE(_Write_RFREG), /*5*/ - GEN_CMD_CODE(_Read_EEPROM), - GEN_CMD_CODE(_Write_EEPROM), - GEN_CMD_CODE(_Read_EFUSE), - GEN_CMD_CODE(_Write_EFUSE), - - GEN_CMD_CODE(_Read_CAM), /*10*/ - GEN_CMD_CODE(_Write_CAM), - GEN_CMD_CODE(_setBCNITV), - GEN_CMD_CODE(_setMBIDCFG), - GEN_CMD_CODE(_JoinBss), /*14*/ - GEN_CMD_CODE(_DisConnect), /*15*/ - GEN_CMD_CODE(_CreateBss), - GEN_CMD_CODE(_SetOpMode), - GEN_CMD_CODE(_SiteSurvey), /*18*/ - GEN_CMD_CODE(_SetAuth), - - GEN_CMD_CODE(_SetKey), /*20*/ - GEN_CMD_CODE(_SetStaKey), - GEN_CMD_CODE(_SetAssocSta), - GEN_CMD_CODE(_DelAssocSta), - GEN_CMD_CODE(_SetStaPwrState), - GEN_CMD_CODE(_SetBasicRate), /*25*/ - GEN_CMD_CODE(_GetBasicRate), - GEN_CMD_CODE(_SetDataRate), - GEN_CMD_CODE(_GetDataRate), - GEN_CMD_CODE(_SetPhyInfo), - - GEN_CMD_CODE(_GetPhyInfo), /*30*/ - GEN_CMD_CODE(_SetPhy), - GEN_CMD_CODE(_GetPhy), - GEN_CMD_CODE(_readRssi), - GEN_CMD_CODE(_readGain), - GEN_CMD_CODE(_SetAtim), /*35*/ - GEN_CMD_CODE(_SetPwrMode), - GEN_CMD_CODE(_JoinbssRpt), - GEN_CMD_CODE(_SetRaTable), - GEN_CMD_CODE(_GetRaTable), - - GEN_CMD_CODE(_GetCCXReport), /*40*/ - GEN_CMD_CODE(_GetDTMReport), - GEN_CMD_CODE(_GetTXRateStatistics), - GEN_CMD_CODE(_SetUsbSuspend), - GEN_CMD_CODE(_SetH2cLbk), - GEN_CMD_CODE(_AddBAReq), /*45*/ - - GEN_CMD_CODE(_SetChannel), /*46*/ -/* MP_OFFLOAD Start (47~54)*/ - GEN_CMD_CODE(_SetTxPower), - GEN_CMD_CODE(_SwitchAntenna), - GEN_CMD_CODE(_SetCrystalCap), - GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ - GEN_CMD_CODE(_SetSingleToneTx), - GEN_CMD_CODE(_SetCarrierSuppressionTx), - GEN_CMD_CODE(_SetContinuousTx), - GEN_CMD_CODE(_SwitchBandwidth), /*54*/ -/* MP_OFFLOAD End*/ - GEN_CMD_CODE(_TX_Beacon), /*55*/ - GEN_CMD_CODE(_SetPowerTracking), - GEN_CMD_CODE(_AMSDU_TO_AMPDU), /*57*/ - GEN_CMD_CODE(_SetMacAddress), /*58*/ - - GEN_CMD_CODE(_DisconnectCtrl), /*59*/ - GEN_CMD_CODE(_SetChannelPlan), /*60*/ - GEN_CMD_CODE(_DisconnectCtrlEx), /*61*/ - - /* To do, modify these h2c cmd, add or delete */ - GEN_CMD_CODE(_GetH2cLbk), - - /* WPS extra IE */ - GEN_CMD_CODE(_SetProbeReqExtraIE), - GEN_CMD_CODE(_SetAssocReqExtraIE), - GEN_CMD_CODE(_SetProbeRspExtraIE), - GEN_CMD_CODE(_SetAssocRspExtraIE), - - /* the following is driver will do */ - GEN_CMD_CODE(_GetCurDataRate), - - GEN_CMD_CODE(_GetTxRetrycnt), /* to record times that Tx retry to - * transmit packet after association - */ - GEN_CMD_CODE(_GetRxRetrycnt), /* to record total number of the - * received frame with ReTry bit set in - * the WLAN header - */ - - GEN_CMD_CODE(_GetBCNOKcnt), - GEN_CMD_CODE(_GetBCNERRcnt), - GEN_CMD_CODE(_GetCurTxPwrLevel), - - GEN_CMD_CODE(_SetDIG), - GEN_CMD_CODE(_SetRA), - GEN_CMD_CODE(_SetPT), - GEN_CMD_CODE(_ReadTSSI), - - MAX_H2CCMD -}; - -#define _GetBBReg_CMD_ _Read_BBREG_CMD_ -#define _SetBBReg_CMD_ _Write_BBREG_CMD_ -#define _GetRFReg_CMD_ _Read_RFREG_CMD_ -#define _SetRFReg_CMD_ _Write_RFREG_CMD_ -#define _DRV_INT_CMD_ (MAX_H2CCMD + 1) -#define _SetRFIntFs_CMD_ (MAX_H2CCMD + 2) - -#ifdef _RTL8712_CMD_C_ -static struct _cmd_callback cmd_callback[] = { - {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ - {GEN_CMD_CODE(_Write_MACREG), NULL}, - {GEN_CMD_CODE(_Read_BBREG), NULL}, - {GEN_CMD_CODE(_Write_BBREG), NULL}, - {GEN_CMD_CODE(_Read_RFREG), &r8712_getbbrfreg_cmdrsp_callback}, - {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ - {GEN_CMD_CODE(_Read_EEPROM), NULL}, - {GEN_CMD_CODE(_Write_EEPROM), NULL}, - {GEN_CMD_CODE(_Read_EFUSE), NULL}, - {GEN_CMD_CODE(_Write_EFUSE), NULL}, - - {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ - {GEN_CMD_CODE(_Write_CAM), NULL}, - {GEN_CMD_CODE(_setBCNITV), NULL}, - {GEN_CMD_CODE(_setMBIDCFG), NULL}, - {GEN_CMD_CODE(_JoinBss), &r8712_joinbss_cmd_callback}, /*14*/ - {GEN_CMD_CODE(_DisConnect), &r8712_disassoc_cmd_callback}, /*15*/ - {GEN_CMD_CODE(_CreateBss), &r8712_createbss_cmd_callback}, - {GEN_CMD_CODE(_SetOpMode), NULL}, - {GEN_CMD_CODE(_SiteSurvey), &r8712_survey_cmd_callback}, /*18*/ - {GEN_CMD_CODE(_SetAuth), NULL}, - - {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ - {GEN_CMD_CODE(_SetStaKey), &r8712_setstaKey_cmdrsp_callback}, - {GEN_CMD_CODE(_SetAssocSta), &r8712_setassocsta_cmdrsp_callback}, - {GEN_CMD_CODE(_DelAssocSta), NULL}, - {GEN_CMD_CODE(_SetStaPwrState), NULL}, - {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ - {GEN_CMD_CODE(_GetBasicRate), NULL}, - {GEN_CMD_CODE(_SetDataRate), NULL}, - {GEN_CMD_CODE(_GetDataRate), NULL}, - {GEN_CMD_CODE(_SetPhyInfo), NULL}, - - {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ - {GEN_CMD_CODE(_SetPhy), NULL}, - {GEN_CMD_CODE(_GetPhy), NULL}, - {GEN_CMD_CODE(_readRssi), NULL}, - {GEN_CMD_CODE(_readGain), NULL}, - {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ - {GEN_CMD_CODE(_SetPwrMode), NULL}, - {GEN_CMD_CODE(_JoinbssRpt), NULL}, - {GEN_CMD_CODE(_SetRaTable), NULL}, - {GEN_CMD_CODE(_GetRaTable), NULL}, - - {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ - {GEN_CMD_CODE(_GetDTMReport), NULL}, - {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, - {GEN_CMD_CODE(_SetUsbSuspend), NULL}, - {GEN_CMD_CODE(_SetH2cLbk), NULL}, - {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ - - {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ -/* MP_OFFLOAD Start (47~54)*/ - {GEN_CMD_CODE(_SetTxPower), NULL}, - {GEN_CMD_CODE(_SwitchAntenna), NULL}, - {GEN_CMD_CODE(_SetCrystalCap), NULL}, - {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ - {GEN_CMD_CODE(_SetSingleToneTx), NULL}, - {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, - {GEN_CMD_CODE(_SetContinuousTx), NULL}, - {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ -/* MP_OFFLOAD End*/ - {GEN_CMD_CODE(_TX_Beacon), NULL}, /*55*/ - {GEN_CMD_CODE(_SetPowerTracking), NULL}, - {GEN_CMD_CODE(_AMSDU_TO_AMPDU), NULL}, /*57*/ - {GEN_CMD_CODE(_SetMacAddress), NULL}, /*58*/ - - {GEN_CMD_CODE(_DisconnectCtrl), NULL}, /*59*/ - {GEN_CMD_CODE(_SetChannelPlan), NULL}, /*60*/ - {GEN_CMD_CODE(_DisconnectCtrlEx), NULL}, /*61*/ - - /* To do, modify these h2c cmd, add or delete */ - {GEN_CMD_CODE(_GetH2cLbk), NULL}, - - {_SetProbeReqExtraIE_CMD_, NULL}, - {_SetAssocReqExtraIE_CMD_, NULL}, - {_SetProbeRspExtraIE_CMD_, NULL}, - {_SetAssocRspExtraIE_CMD_, NULL}, - {_GetCurDataRate_CMD_, NULL}, - {_GetTxRetrycnt_CMD_, NULL}, - {_GetRxRetrycnt_CMD_, NULL}, - {_GetBCNOKcnt_CMD_, NULL}, - {_GetBCNERRcnt_CMD_, NULL}, - {_GetCurTxPwrLevel_CMD_, NULL}, - {_SetDIG_CMD_, NULL}, - {_SetRA_CMD_, NULL}, - {_SetPT_CMD_, NULL}, - {GEN_CMD_CODE(_ReadTSSI), &r8712_readtssi_cmdrsp_callback} -}; -#endif - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h deleted file mode 100644 index 68bdec07f51e..000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_CMDCTRL_BITDEF_H__ -#define __RTL8712_CMDCTRL_BITDEF_H__ - -/* - * 2. Command Control Registers (Offset: 0x0040 - 0x004F) - */ -/*--------------------------------------------------------------------------*/ -/* 8192S (CMD) command register bits (Offset 0x40, 16 bits)*/ -/*--------------------------------------------------------------------------*/ -#define _APSDOFF_STATUS BIT(15) -#define _APSDOFF BIT(14) -#define _BBRSTn BIT(13) /*Enable OFDM/CCK*/ -#define _BB_GLB_RSTn BIT(12) /*Enable BB*/ -#define _SCHEDULE_EN BIT(10) /*Enable MAC scheduler*/ -#define _MACRXEN BIT(9) -#define _MACTXEN BIT(8) -#define _DDMA_EN BIT(7) /*FW off load function enable*/ -#define _FW2HW_EN BIT(6) /*MAC every module reset */ -#define _RXDMA_EN BIT(5) -#define _TXDMA_EN BIT(4) -#define _HCI_RXDMA_EN BIT(3) -#define _HCI_TXDMA_EN BIT(2) - -/*TXPAUSE*/ -#define _STOPHCCA BIT(6) -#define _STOPHIGH BIT(5) -#define _STOPMGT BIT(4) -#define _STOPVO BIT(3) -#define _STOPVI BIT(2) -#define _STOPBE BIT(1) -#define _STOPBK BIT(0) - -/*TCR*/ -#define _DISCW BIT(20) -#define _ICV BIT(19) -#define _CFEND_FMT BIT(17) -#define _CRC BIT(16) -#define _FWRDY BIT(7) -#define _BASECHG BIT(6) -#define _IMEM_RDY BIT(5) -#define _DMEM_CODE_DONE BIT(4) -#define _EMEM_CHK_RPT BIT(3) -#define _EMEM_CODE_DONE BIT(2) -#define _IMEM_CHK_RPT BIT(1) -#define _IMEM_CODE_DONE BIT(0) - -#define _TXDMA_INIT_VALUE (_IMEM_CHK_RPT | _EMEM_CHK_RPT) - -/*RCR*/ -#define _ENMBID BIT(27) -#define _APP_PHYST_RXFF BIT(25) -#define _APP_PHYST_STAFF BIT(24) -#define _CBSSID BIT(23) -#define _APWRMGT BIT(22) -#define _ADD3 BIT(21) -#define _AMF BIT(20) -#define _ACF BIT(19) -#define _ADF BIT(18) -#define _APP_MIC BIT(17) -#define _APP_ICV BIT(16) -#define _RXFTH_MSK 0x0000E000 -#define _RXFTH_SHT 13 -#define _AICV BIT(12) -#define _RXPKTLMT_MSK 0x00000FC0 -#define _RXPKTLMT_SHT 6 -#define _ACRC32 BIT(5) -#define _AB BIT(3) -#define _AM BIT(2) -#define _APM BIT(1) -#define _AAP BIT(0) - -/*MSR*/ -#define _NETTYPE_MSK 0x03 -#define _NETTYPE_SHT 0 - -/*BT*/ -#define _BTMODE_MSK 0x06 -#define _BTMODE_SHT 1 -#define _ENBT BIT(0) - -/*MBIDCTRL*/ -#define _ENMBID_MODE BIT(15) -#define _BCNNO_MSK 0x7000 -#define _BCNNO_SHT 12 -#define _BCNSPACE_MSK 0x0FFF -#define _BCNSPACE_SHT 0 - -#endif /* __RTL8712_CMDCTRL_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h deleted file mode 100644 index fc67771c89b7..000000000000 --- a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_CMDCTRL_REGDEF_H__ -#define __RTL8712_CMDCTRL_REGDEF_H__ - -#define CR (RTL8712_CMDCTRL_ + 0x0000) -#define TXPAUSE (RTL8712_CMDCTRL_ + 0x0002) -#define TCR (RTL8712_CMDCTRL_ + 0x0004) -#define RCR (RTL8712_CMDCTRL_ + 0x0008) -#define MSR (RTL8712_CMDCTRL_ + 0x000C) -#define SYSF_CFG (RTL8712_CMDCTRL_ + 0x000D) -#define MBIDCTRL (RTL8712_CMDCTRL_ + 0x000E) - -#endif /* __RTL8712_CMDCTRL_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h deleted file mode 100644 index bb3863467f0d..000000000000 --- a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_DEBUGCTRL_BITDEF_H__ -#define __RTL8712_DEBUGCTRL_BITDEF_H__ - -/*BIST*/ -#define _BIST_RST BIT(0) - -/*LMS*/ -#define _LMS_MSK 0x03 - -/*WDG_CTRL*/ -#define _OVSEL_MSK 0x0600 -#define _OVSEL_SHT 9 -#define _WDGCLR BIT(8) -#define _WDGEN_MSK 0x00FF -#define _WDGEN_SHT 0 - -/*INTM*/ -#define _TXTIMER_MSK 0xF000 -#define _TXTIMER_SHT 12 -#define _TXNUM_MSK 0x0F00 -#define _TXNUM_SHT 8 -#define _RXTIMER_MSK 0x00F0 -#define _RXTIMER_SHT 4 -#define _RXNUM_MSK 0x000F -#define _RXNUM_SHT 0 - -/*FDLOCKTURN0*/ -/*FDLOCKTURN1*/ -#define _TURN1 BIT(0) - -/*FDLOCKFLAG0*/ -/*FDLOCKFLAG1*/ -#define _LOCKFLAG1_MSK 0x03 - -#endif /* __RTL8712_DEBUGCTRL_BITDEF_H__ */ diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h deleted file mode 100644 index 319220e9d53d..000000000000 --- a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_DEBUGCTRL_REGDEF_H__ -#define __RTL8712_DEBUGCTRL_REGDEF_H__ - -#define BIST (RTL8712_DEBUGCTRL_ + 0x00) -#define DBS (RTL8712_DEBUGCTRL_ + 0x04) -#define LMS (RTL8712_DEBUGCTRL_ + 0x05) -#define CPUINST (RTL8712_DEBUGCTRL_ + 0x08) -#define CPUCAUSE (RTL8712_DEBUGCTRL_ + 0x0C) -#define LBUS_ERR_ADDR (RTL8712_DEBUGCTRL_ + 0x10) -#define LBUS_ERR_CMD (RTL8712_DEBUGCTRL_ + 0x14) -#define LBUS_ERR_DATA_L (RTL8712_DEBUGCTRL_ + 0x18) -#define LBUS_ERR_DATA_H (RTL8712_DEBUGCTRL_ + 0x1C) -#define LBUS_EXCEPTION_ADDR (RTL8712_DEBUGCTRL_ + 0x20) -#define WDG_CTRL (RTL8712_DEBUGCTRL_ + 0x24) -#define INTMTU (RTL8712_DEBUGCTRL_ + 0x28) -#define INTM (RTL8712_DEBUGCTRL_ + 0x2A) -#define FDLOCKTURN0 (RTL8712_DEBUGCTRL_ + 0x2C) -#define FDLOCKTURN1 (RTL8712_DEBUGCTRL_ + 0x2D) -#define FDLOCKFLAG0 (RTL8712_DEBUGCTRL_ + 0x2E) -#define FDLOCKFLAG1 (RTL8712_DEBUGCTRL_ + 0x2F) -#define TRXPKTBUF_DBG_DATA (RTL8712_DEBUGCTRL_ + 0x30) -#define TRXPKTBUF_DBG_CTRL (RTL8712_DEBUGCTRL_ + 0x38) -#define DPLL_MON (RTL8712_DEBUGCTRL_ + 0x3A) - -#endif /* __RTL8712_DEBUGCTRL_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h deleted file mode 100644 index 9048d6a65296..000000000000 --- a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_EDCASETTING_BITDEF_H__ -#define __RTL8712_EDCASETTING_BITDEF_H__ - -/*EDCAPARAM*/ -#define _TXOPLIMIT_MSK 0xFFFF0000 -#define _TXOPLIMIT_SHT 16 -#define _ECWIN_MSK 0x0000FF00 -#define _ECWIN_SHT 8 -#define _AIFS_MSK 0x000000FF -#define _AIFS_SHT 0 - -/*BCNTCFG*/ -#define _BCNECW_MSK 0xFF00 -#define _BCNECW_SHT 8 -#define _BCNIFS_MSK 0x00FF -#define _BCNIFS_SHT 0 - -/*CWRR*/ -#define _CWRR_MSK 0x03FF - -/*ACMAVG*/ -#define _AVG_TIME_UP BIT(3) -#define _AVGPERIOD_MSK 0x03 - -/*ACMHWCTRL*/ -#define _VOQ_ACM_STATUS BIT(6) -#define _VIQ_ACM_STATUS BIT(5) -#define _BEQ_ACM_STATUS BIT(4) -#define _VOQ_ACM_EN BIT(3) -#define _VIQ_ACM_EN BIT(2) -#define _BEQ_ACM_EN BIT(1) -#define _ACMHWEN BIT(0) - -/*VO_ADMTIME*/ -#define _VO_ACM_RUT BIT(18) -#define _VO_ADMTIME_MSK 0x0003FFF - -/*VI_ADMTIME*/ -#define _VI_ACM_RUT BIT(18) -#define _VI_ADMTIME_MSK 0x0003FFF - -/*BE_ADMTIME*/ -#define _BE_ACM_RUT BIT(18) -#define _BE_ADMTIME_MSK 0x0003FFF - -/*Retry limit reg*/ -#define _SRL_MSK 0xFF00 -#define _SRL_SHT 8 -#define _LRL_MSK 0x00FF -#define _LRL_SHT 0 - -#endif /* __RTL8712_EDCASETTING_BITDEF_H__*/ diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h deleted file mode 100644 index 02ec9f3bba66..000000000000 --- a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_EDCASETTING_REGDEF_H__ -#define __RTL8712_EDCASETTING_REGDEF_H__ - -#define EDCA_VO_PARAM (RTL8712_EDCASETTING_ + 0x00) -#define EDCA_VI_PARAM (RTL8712_EDCASETTING_ + 0x04) -#define EDCA_BE_PARAM (RTL8712_EDCASETTING_ + 0x08) -#define EDCA_BK_PARAM (RTL8712_EDCASETTING_ + 0x0C) -#define BCNTCFG (RTL8712_EDCASETTING_ + 0x10) -#define CWRR (RTL8712_EDCASETTING_ + 0x12) -#define ACMAVG (RTL8712_EDCASETTING_ + 0x16) -#define ACMHWCTRL (RTL8712_EDCASETTING_ + 0x17) -#define VO_ADMTIME (RTL8712_EDCASETTING_ + 0x18) -#define VI_ADMTIME (RTL8712_EDCASETTING_ + 0x1C) -#define BE_ADMTIME (RTL8712_EDCASETTING_ + 0x20) -#define RL (RTL8712_EDCASETTING_ + 0x24) - -#endif /* __RTL8712_EDCASETTING_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c deleted file mode 100644 index c9400e40a1d6..000000000000 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ /dev/null @@ -1,564 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rtl8712_efuse.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_EFUSE_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl8712_efuse.h" - -/* reserve 3 bytes for HW stop read */ -static int efuse_available_max_size = EFUSE_MAX_SIZE - 3 /*0x1FD*/; - -static void efuse_reg_ctrl(struct _adapter *adapter, u8 bPowerOn) -{ - u8 tmpu8 = 0; - - if (bPowerOn) { - /* -----------------e-fuse pwr & clk reg ctrl --------------- - * Enable LDOE25 Macro Block - */ - tmpu8 = r8712_read8(adapter, EFUSE_TEST + 3); - tmpu8 |= 0x80; - r8712_write8(adapter, EFUSE_TEST + 3, tmpu8); - msleep(20); /* for some platform , need some delay time */ - /* Change Efuse Clock for write action to 40MHZ */ - r8712_write8(adapter, EFUSE_CLK_CTRL, 0x03); - msleep(20); /* for some platform , need some delay time */ - } else { - /* -----------------e-fuse pwr & clk reg ctrl ----------------- - * Disable LDOE25 Macro Block - */ - tmpu8 = r8712_read8(adapter, EFUSE_TEST + 3); - tmpu8 &= 0x7F; - r8712_write8(adapter, EFUSE_TEST + 3, tmpu8); - /* Change Efuse Clock for write action to 500K */ - r8712_write8(adapter, EFUSE_CLK_CTRL, 0x02); - } -} - -/* - * Before write E-Fuse, this function must be called. - */ -u8 r8712_efuse_reg_init(struct _adapter *adapter) -{ - return true; -} - -void r8712_efuse_reg_uninit(struct _adapter *adapter) -{ - efuse_reg_ctrl(adapter, false); -} - -static u8 efuse_one_byte_read(struct _adapter *adapter, u16 addr, u8 *data) -{ - u8 tmpidx = 0, bResult; - - /* -----------------e-fuse reg ctrl --------------------------------- */ - r8712_write8(adapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */ - r8712_write8(adapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | - (r8712_read8(adapter, EFUSE_CTRL + 2) & 0xFC)); - r8712_write8(adapter, EFUSE_CTRL + 3, 0x72); /* read cmd */ - /* wait for complete */ - while (!(0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) { - *data = r8712_read8(adapter, EFUSE_CTRL); - bResult = true; - } else { - *data = 0xff; - bResult = false; - } - return bResult; -} - -static u8 efuse_one_byte_write(struct _adapter *adapter, u16 addr, u8 data) -{ - u8 tmpidx = 0, bResult; - - /* -----------------e-fuse reg ctrl -------------------------------- */ - r8712_write8(adapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */ - r8712_write8(adapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | - (r8712_read8(adapter, EFUSE_CTRL + 2) & 0xFC)); - r8712_write8(adapter, EFUSE_CTRL, data); /* data */ - r8712_write8(adapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */ - /* wait for complete */ - while ((0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) - bResult = true; - else - bResult = false; - return bResult; -} - -static u8 efuse_one_byte_rw(struct _adapter *adapter, u8 bRead, u16 addr, - u8 *data) -{ - u8 tmpidx = 0, tmpv8 = 0, bResult; - - /* -----------------e-fuse reg ctrl --------------------------------- */ - r8712_write8(adapter, EFUSE_CTRL + 1, (u8)(addr & 0xFF)); /* address */ - tmpv8 = ((u8)((addr >> 8) & 0x03)) | - (r8712_read8(adapter, EFUSE_CTRL + 2) & 0xFC); - r8712_write8(adapter, EFUSE_CTRL + 2, tmpv8); - if (bRead) { - r8712_write8(adapter, EFUSE_CTRL + 3, 0x72); /* read cmd */ - while (!(0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) { - *data = r8712_read8(adapter, EFUSE_CTRL); - bResult = true; - } else { - *data = 0; - bResult = false; - } - } else { - r8712_write8(adapter, EFUSE_CTRL, *data); /* data */ - r8712_write8(adapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */ - while ((0x80 & r8712_read8(adapter, EFUSE_CTRL + 3)) && - (tmpidx < 100)) - tmpidx++; - if (tmpidx < 100) - bResult = true; - else - bResult = false; - } - return bResult; -} - -static u8 efuse_is_empty(struct _adapter *adapter, u8 *empty) -{ - u8 value, ret = true; - - /* read one byte to check if E-Fuse is empty */ - if (efuse_one_byte_rw(adapter, true, 0, &value)) { - if (value == 0xFF) - *empty = true; - else - *empty = false; - } else { - ret = false; - } - return ret; -} - -void r8712_efuse_change_max_size(struct _adapter *adapter) -{ - u16 pre_pg_data_saddr = 0x1FB; - u16 i; - u16 pre_pg_data_size = 5; - u8 pre_pg_data[5]; - - for (i = 0; i < pre_pg_data_size; i++) - efuse_one_byte_read(adapter, pre_pg_data_saddr + i, - &pre_pg_data[i]); - if ((pre_pg_data[0] == 0x03) && (pre_pg_data[1] == 0x00) && - (pre_pg_data[2] == 0x00) && (pre_pg_data[3] == 0x00) && - (pre_pg_data[4] == 0x0C)) - efuse_available_max_size -= pre_pg_data_size; -} - -int r8712_efuse_get_max_size(struct _adapter *adapter) -{ - return efuse_available_max_size; -} - -static u8 calculate_word_cnts(const u8 word_en) -{ - u8 word_cnts = 0; - u8 word_idx; - - for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++) - if (!(word_en & BIT(word_idx))) - word_cnts++; /* 0 : write enable */ - return word_cnts; -} - -static void pgpacket_copy_data(const u8 word_en, const u8 *sourdata, - u8 *targetdata) -{ - u8 tmpindex = 0; - u8 word_idx, byte_idx; - - for (word_idx = 0; word_idx < PGPKG_MAX_WORDS; word_idx++) { - if (!(word_en & BIT(word_idx))) { - byte_idx = word_idx * 2; - targetdata[byte_idx] = sourdata[tmpindex++]; - targetdata[byte_idx + 1] = sourdata[tmpindex++]; - } - } -} - -u16 r8712_efuse_get_current_size(struct _adapter *adapter) -{ - int bContinual = true; - u16 efuse_addr = 0; - u8 hworden = 0; - u8 efuse_data, word_cnts = 0; - - while (bContinual && efuse_one_byte_read(adapter, efuse_addr, - &efuse_data) && (efuse_addr < efuse_available_max_size)) { - if (efuse_data != 0xFF) { - hworden = efuse_data & 0x0F; - word_cnts = calculate_word_cnts(hworden); - /* read next header */ - efuse_addr = efuse_addr + (word_cnts * 2) + 1; - } else { - bContinual = false; - } - } - return efuse_addr; -} - -u8 r8712_efuse_pg_packet_read(struct _adapter *adapter, u8 offset, u8 *data) -{ - u8 hoffset = 0, hworden = 0, word_cnts = 0; - u16 efuse_addr = 0; - u8 efuse_data; - u8 tmpidx = 0; - u8 tmpdata[PGPKT_DATA_SIZE]; - u8 ret = true; - - if (!data) - return false; - if (offset > 0x0f) - return false; - memset(data, 0xFF, sizeof(u8) * PGPKT_DATA_SIZE); - while (efuse_addr < efuse_available_max_size) { - if (efuse_one_byte_read(adapter, efuse_addr, &efuse_data)) { - if (efuse_data == 0xFF) - break; - hoffset = (efuse_data >> 4) & 0x0F; - hworden = efuse_data & 0x0F; - word_cnts = calculate_word_cnts(hworden); - if (hoffset == offset) { - memset(tmpdata, 0xFF, PGPKT_DATA_SIZE); - for (tmpidx = 0; tmpidx < word_cnts * 2; - tmpidx++) { - if (efuse_one_byte_read(adapter, - efuse_addr + 1 + tmpidx, - &efuse_data)) { - tmpdata[tmpidx] = efuse_data; - } else { - ret = false; - } - } - pgpacket_copy_data(hworden, tmpdata, data); - } - efuse_addr += 1 + (word_cnts * 2); - } else { - ret = false; - break; - } - } - return ret; -} - -static u8 fix_header(struct _adapter *adapter, u8 header, u16 header_addr) -{ - struct PGPKT_STRUCT pkt; - u8 offset, word_en, value; - u16 addr; - int i; - u8 ret = true; - - pkt.offset = GET_EFUSE_OFFSET(header); - pkt.word_en = GET_EFUSE_WORD_EN(header); - addr = header_addr + 1 + calculate_word_cnts(pkt.word_en) * 2; - if (addr > efuse_available_max_size) - return false; - /* retrieve original data */ - addr = 0; - while (addr < header_addr) { - if (!efuse_one_byte_read(adapter, addr++, &value)) { - ret = false; - break; - } - offset = GET_EFUSE_OFFSET(value); - word_en = GET_EFUSE_WORD_EN(value); - if (pkt.offset != offset) { - addr += calculate_word_cnts(word_en) * 2; - continue; - } - for (i = 0; i < PGPKG_MAX_WORDS; i++) { - if (!(BIT(i) & word_en)) - continue; - if (BIT(i) & pkt.word_en) { - if (efuse_one_byte_read(adapter, - addr, - &value)) - pkt.data[i * 2] = value; - else - return false; - if (efuse_one_byte_read(adapter, - addr + 1, - &value)) - pkt.data[i * 2 + 1] = value; - else - return false; - } - addr += 2; - } - } - if (addr != header_addr) - return false; - addr++; - /* fill original data */ - for (i = 0; i < PGPKG_MAX_WORDS; i++) { - if (BIT(i) & pkt.word_en) { - efuse_one_byte_write(adapter, addr, pkt.data[i * 2]); - efuse_one_byte_write(adapter, addr + 1, - pkt.data[i * 2 + 1]); - /* additional check */ - if (!efuse_one_byte_read(adapter, addr, &value)) { - ret = false; - } else if (pkt.data[i * 2] != value) { - ret = false; - if (value == 0xFF) /* write again */ - efuse_one_byte_write(adapter, addr, - pkt.data[i * 2]); - } - if (!efuse_one_byte_read(adapter, addr + 1, &value)) { - ret = false; - } else if (pkt.data[i * 2 + 1] != value) { - ret = false; - if (value == 0xFF) /* write again */ - efuse_one_byte_write(adapter, addr + 1, - pkt.data[i * 2 + - 1]); - } - } - addr += 2; - } - return ret; -} - -u8 r8712_efuse_pg_packet_write(struct _adapter *adapter, const u8 offset, - const u8 word_en, const u8 *data) -{ - u8 pg_header = 0; - u16 efuse_addr = 0, curr_size = 0; - u8 efuse_data, target_word_cnts = 0; - int repeat_times; - int sub_repeat; - u8 bResult = true; - - /* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */ - efuse_data = r8712_read8(adapter, EFUSE_CLK_CTRL); - if (efuse_data != 0x03) - return false; - pg_header = MAKE_EFUSE_HEADER(offset, word_en); - target_word_cnts = calculate_word_cnts(word_en); - repeat_times = 0; - efuse_addr = 0; - while (efuse_addr < efuse_available_max_size) { - curr_size = r8712_efuse_get_current_size(adapter); - if ((curr_size + 1 + target_word_cnts * 2) > - efuse_available_max_size) - return false; /*target_word_cnts + pg header(1 byte)*/ - efuse_addr = curr_size; /* current size is also the last addr*/ - efuse_one_byte_write(adapter, efuse_addr, pg_header); /*hdr*/ - sub_repeat = 0; - /* check if what we read is what we write */ - while (!efuse_one_byte_read(adapter, efuse_addr, - &efuse_data)) { - if (++sub_repeat > _REPEAT_THRESHOLD_) { - bResult = false; /* continue to blind write */ - break; /* continue to blind write */ - } - } - if ((sub_repeat > _REPEAT_THRESHOLD_) || - (pg_header == efuse_data)) { - /* write header ok OR can't check header(creep) */ - u8 i; - - /* go to next address */ - efuse_addr++; - for (i = 0; i < target_word_cnts * 2; i++) { - efuse_one_byte_write(adapter, - efuse_addr + i, - *(data + i)); - if (!efuse_one_byte_read(adapter, - efuse_addr + i, - &efuse_data)) - bResult = false; - else if (*(data + i) != efuse_data) /* fail */ - bResult = false; - } - break; - } - /* write header fail */ - bResult = false; - if (efuse_data == 0xFF) - return bResult; /* nothing damaged. */ - /* call rescue procedure */ - if (!fix_header(adapter, efuse_data, efuse_addr)) - return false; /* rescue fail */ - - if (++repeat_times > _REPEAT_THRESHOLD_) /* fail */ - break; - /* otherwise, take another risk... */ - } - return bResult; -} - -u8 r8712_efuse_access(struct _adapter *adapter, u8 bRead, u16 start_addr, - u16 cnts, u8 *data) -{ - int i; - u8 res = true; - - if (start_addr > EFUSE_MAX_SIZE) - return false; - if (!bRead && ((start_addr + cnts) > - efuse_available_max_size)) - return false; - if (!bRead && !r8712_efuse_reg_init(adapter)) - return false; - /* -----------------e-fuse one byte read / write ---------------------*/ - for (i = 0; i < cnts; i++) { - if ((start_addr + i) > EFUSE_MAX_SIZE) { - res = false; - break; - } - res = efuse_one_byte_rw(adapter, bRead, start_addr + i, - data + i); - if (!bRead && !res) - break; - } - if (!bRead) - r8712_efuse_reg_uninit(adapter); - return res; -} - -u8 r8712_efuse_map_read(struct _adapter *adapter, u16 addr, u16 cnts, u8 *data) -{ - u8 offset, ret = true; - u8 pktdata[PGPKT_DATA_SIZE]; - int i, idx; - - if ((addr + cnts) > EFUSE_MAP_MAX_SIZE) - return false; - if (efuse_is_empty(adapter, &offset) && offset) { - for (i = 0; i < cnts; i++) - data[i] = 0xFF; - return ret; - } - offset = (addr >> 3) & 0xF; - ret = r8712_efuse_pg_packet_read(adapter, offset, pktdata); - i = addr & 0x7; /* pktdata index */ - idx = 0; /* data index */ - - do { - for (; i < PGPKT_DATA_SIZE; i++) { - data[idx++] = pktdata[i]; - if (idx == cnts) - return ret; - } - offset++; - if (!r8712_efuse_pg_packet_read(adapter, offset, pktdata)) - ret = false; - i = 0; - } while (1); - return ret; -} - -u8 r8712_efuse_map_write(struct _adapter *adapter, u16 addr, u16 cnts, - u8 *data) -{ - u8 offset, word_en, empty; - u8 pktdata[PGPKT_DATA_SIZE], newdata[PGPKT_DATA_SIZE]; - int i, j, idx; - - if ((addr + cnts) > EFUSE_MAP_MAX_SIZE) - return false; - /* check if E-Fuse Clock Enable and E-Fuse Clock is 40M */ - empty = r8712_read8(adapter, EFUSE_CLK_CTRL); - if (empty != 0x03) - return false; - if (efuse_is_empty(adapter, &empty)) { - if (empty) - memset(pktdata, 0xFF, PGPKT_DATA_SIZE); - } else { - return false; - } - offset = (addr >> 3) & 0xF; - if (!empty) - if (!r8712_efuse_pg_packet_read(adapter, offset, pktdata)) - return false; - word_en = 0xF; - memset(newdata, 0xFF, PGPKT_DATA_SIZE); - i = addr & 0x7; /* pktdata index */ - j = 0; /* newdata index */ - idx = 0; /* data index */ - - if (i & 0x1) { - /* odd start */ - if (data[idx] != pktdata[i]) { - word_en &= ~BIT(i >> 1); - newdata[j++] = pktdata[i - 1]; - newdata[j++] = data[idx]; - } - i++; - idx++; - } - do { - for (; i < PGPKT_DATA_SIZE; i += 2) { - if ((cnts - idx) == 1) { - if (data[idx] != pktdata[i]) { - word_en &= ~BIT(i >> 1); - newdata[j++] = data[idx]; - newdata[j++] = pktdata[1 + 1]; - } - idx++; - break; - } - - if ((data[idx] != pktdata[i]) || (data[idx + 1] != - pktdata[i + 1])) { - word_en &= ~BIT(i >> 1); - newdata[j++] = data[idx]; - newdata[j++] = data[idx + 1]; - } - idx += 2; - - if (idx == cnts) - break; - } - - if (word_en != 0xF) - if (!r8712_efuse_pg_packet_write(adapter, offset, - word_en, newdata)) - return false; - if (idx == cnts) - break; - offset++; - if (!empty) - if (!r8712_efuse_pg_packet_read(adapter, offset, - pktdata)) - return false; - i = 0; - j = 0; - word_en = 0xF; - memset(newdata, 0xFF, PGPKT_DATA_SIZE); - } while (1); - - return true; -} diff --git a/drivers/staging/rtl8712/rtl8712_efuse.h b/drivers/staging/rtl8712/rtl8712_efuse.h deleted file mode 100644 index 7a49740212eb..000000000000 --- a/drivers/staging/rtl8712/rtl8712_efuse.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __RTL8712_EFUSE_H__ -#define __RTL8712_EFUSE_H__ - -#include "osdep_service.h" - -#define _REPEAT_THRESHOLD_ 3 - -#define EFUSE_MAX_SIZE 512 -#define EFUSE_MAP_MAX_SIZE 128 - -#define PGPKG_MAX_WORDS 4 -#define PGPKT_DATA_SIZE 8 /* PGPKG_MAX_WORDS*2; BYTES sizeof(u8)*8*/ -#define MAX_PGPKT_SIZE 9 /* 1 + PGPKT_DATA_SIZE; header + 2 * 4 words (BYTES)*/ - -#define GET_EFUSE_OFFSET(header) ((header & 0xF0) >> 4) -#define GET_EFUSE_WORD_EN(header) (header & 0x0F) -#define MAKE_EFUSE_HEADER(offset, word_en) ((((offset) & 0x0F) << 4) | \ - ((word_en) & 0x0F)) -/*--------------------------------------------------------------------------*/ -struct PGPKT_STRUCT { - u8 offset; - u8 word_en; - u8 data[PGPKT_DATA_SIZE]; -}; - -/*--------------------------------------------------------------------------*/ -u8 r8712_efuse_reg_init(struct _adapter *padapter); -void r8712_efuse_reg_uninit(struct _adapter *padapter); -u16 r8712_efuse_get_current_size(struct _adapter *padapter); -int r8712_efuse_get_max_size(struct _adapter *padapter); -void r8712_efuse_change_max_size(struct _adapter *padapter); -u8 r8712_efuse_pg_packet_read(struct _adapter *padapter, - u8 offset, u8 *data); -u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, - const u8 offset, const u8 word_en, - const u8 *data); -u8 r8712_efuse_access(struct _adapter *padapter, u8 bRead, - u16 start_addr, u16 cnts, u8 *data); -u8 r8712_efuse_map_read(struct _adapter *padapter, u16 addr, - u16 cnts, u8 *data); -u8 r8712_efuse_map_write(struct _adapter *padapter, u16 addr, - u16 cnts, u8 *data); -#endif diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h deleted file mode 100644 index 0d3e5feadcc0..000000000000 --- a/drivers/staging/rtl8712/rtl8712_event.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL8712_EVENT_H_ -#define _RTL8712_EVENT_H_ - -void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf); -void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf); - -enum rtl8712_c2h_event { - GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/ - GEN_EVT_CODE(_Read_BBREG), - GEN_EVT_CODE(_Read_RFREG), - GEN_EVT_CODE(_Read_EEPROM), - GEN_EVT_CODE(_Read_EFUSE), - GEN_EVT_CODE(_Read_CAM), /*5*/ - GEN_EVT_CODE(_Get_BasicRate), - GEN_EVT_CODE(_Get_DataRate), - GEN_EVT_CODE(_Survey), /*8*/ - GEN_EVT_CODE(_SurveyDone), /*9*/ - - GEN_EVT_CODE(_JoinBss), /*10*/ - GEN_EVT_CODE(_AddSTA), - GEN_EVT_CODE(_DelSTA), - GEN_EVT_CODE(_AtimDone), - GEN_EVT_CODE(_TX_Report), - GEN_EVT_CODE(_CCX_Report), /*15*/ - GEN_EVT_CODE(_DTM_Report), - GEN_EVT_CODE(_TX_Rate_Statistics), - GEN_EVT_CODE(_C2HLBK), - GEN_EVT_CODE(_FWDBG), - GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ - GEN_EVT_CODE(_ADDBA), - GEN_EVT_CODE(_C2HBCN), - GEN_EVT_CODE(_ReportPwrState), /*filen: only for PCIE, USB*/ - GEN_EVT_CODE(_WPS_PBC), /*24*/ - GEN_EVT_CODE(_ADDBAReq_Report), /*25*/ - MAX_C2HEVT -}; - -#ifdef _RTL8712_CMD_C_ - -static struct fwevent wlanevents[] = { - {0, NULL}, /*0*/ - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, &r8712_survey_event_callback}, /*8*/ - {sizeof(struct surveydone_event), - &r8712_surveydone_event_callback}, /*9*/ - - {0, &r8712_joinbss_event_callback}, /*10*/ - {sizeof(struct stassoc_event), &r8712_stassoc_event_callback}, - {sizeof(struct stadel_event), &r8712_stadel_event_callback}, - {0, &r8712_atimdone_event_callback}, - {0, NULL}, - {0, NULL}, /*15*/ - {0, NULL}, - {0, NULL}, - {0, NULL}, - {0, NULL}, /*fwdbg_event_callback},*/ - {0, NULL}, /*20*/ - {0, NULL}, - {0, NULL}, - {0, &r8712_cpwm_event_callback}, - {0, &r8712_wpspbc_event_callback}, - {0, &r8712_got_addbareq_event_callback}, -}; - -#endif/*_RTL8712_CMD_C_*/ - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h deleted file mode 100644 index f09645fa1886..000000000000 --- a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_FIFOCTRL_BITDEF_H__ -#define __RTL8712_FIFOCTRL_BITDEF_H__ - -/*PBP*/ -#define _PSTX_MSK 0xF0 -#define _PSTX_SHT 4 -#define _PSRX_MSK 0x0F -#define _PSRX_SHT 0 - -/*TXFF_STATUS*/ -#define _TXSTATUS_OVF BIT(15) - -/*RXFF_STATUS*/ -#define _STATUSFF1_OVF BIT(7) -#define _STATUSFF1_EMPTY BIT(6) -#define _STATUSFF0_OVF BIT(5) -#define _STATUSFF0_EMPTY BIT(4) -#define _RXFF1_OVF BIT(3) -#define _RXFF1_EMPTY BIT(2) -#define _RXFF0_OVF BIT(1) -#define _RXFF0_EMPTY BIT(0) - -/*TXFF_EMPTY_TH*/ -#define _BKQ_EMPTY_TH_MSK 0x0F0000 -#define _BKQ_EMPTY_TH_SHT 16 -#define _BEQ_EMPTY_TH_MSK 0x00F000 -#define _BEQ_EMPTY_TH_SHT 12 -#define _VIQ_EMPTY_TH_MSK 0x000F00 -#define _VIQ_EMPTY_TH_SHT 8 -#define _VOQ_EMPTY_TH_MSK 0x0000F0 -#define _VOQ_EMPTY_TH_SHT 4 -#define _BMCQ_EMPTY_TH_MSK 0x00000F -#define _BMCQ_EMPTY_TH_SHT 0 - -/*SDIO_RX_BLKSZ*/ -#define _SDIO_RX_BLKSZ_MSK 0x07 - -/*RXDMA_CTRL*/ -#define _C2HFF_POLL BIT(4) -#define _RXPKT_POLL BIT(0) - -/*RXPKT_NUM*/ -#define _RXCMD_NUM_MSK 0xFF00 -#define _RXCMD_NUM_SHT 8 -#define _RXFF0_NUM_MSK 0x00FF -#define _RXFF0_NUM_SHT 0 - -/*FIFOPAGE2*/ -#define _PUB_AVAL_PG_MSK 0xFFFF0000 -#define _PUB_AVAL_PG_SHT 16 -#define _BCN_AVAL_PG_MSK 0x0000FFFF -#define _BCN_AVAL_PG_SHT 0 - -/*RX0PKTNUM*/ -#define _RXFF0_DEC_POLL BIT(15) -#define _RXFF0_PKT_DEC_NUM_MSK 0x3F00 -#define _RXFF0_PKT_DEC_NUM_SHT 8 -#define _RXFF0_PKTNUM_RPT_MSK 0x00FF -#define _RXFF0_PKTNUM_RPT_SHT 0 - -/*RX1PKTNUM*/ -#define _RXFF1_DEC_POLL BIT(15) -#define _RXFF1_PKT_DEC_NUM_MSK 0x3F00 -#define _RXFF1_PKT_DEC_NUM_SHT 8 -#define _RXFF1_PKTNUM_RPT_MSK 0x00FF -#define _RXFF1_PKTNUM_RPT_SHT 0 - -/*RXFLTMAP0*/ -#define _MGTFLT13EN BIT(13) -#define _MGTFLT12EN BIT(12) -#define _MGTFLT11EN BIT(11) -#define _MGTFLT10EN BIT(10) -#define _MGTFLT9EN BIT(9) -#define _MGTFLT8EN BIT(8) -#define _MGTFLT5EN BIT(5) -#define _MGTFLT4EN BIT(4) -#define _MGTFLT3EN BIT(3) -#define _MGTFLT2EN BIT(2) -#define _MGTFLT1EN BIT(1) -#define _MGTFLT0EN BIT(0) - -/*RXFLTMAP1*/ -#define _CTRLFLT15EN BIT(15) -#define _CTRLFLT14EN BIT(14) -#define _CTRLFLT13EN BIT(13) -#define _CTRLFLT12EN BIT(12) -#define _CTRLFLT11EN BIT(11) -#define _CTRLFLT10EN BIT(10) -#define _CTRLFLT9EN BIT(9) -#define _CTRLFLT8EN BIT(8) -#define _CTRLFLT7EN BIT(7) -#define _CTRLFLT6EN BIT(6) - -/*RXFLTMAP2*/ -#define _DATAFLT15EN BIT(15) -#define _DATAFLT14EN BIT(14) -#define _DATAFLT13EN BIT(13) -#define _DATAFLT12EN BIT(12) -#define _DATAFLT11EN BIT(11) -#define _DATAFLT10EN BIT(10) -#define _DATAFLT9EN BIT(9) -#define _DATAFLT8EN BIT(8) -#define _DATAFLT7EN BIT(7) -#define _DATAFLT6EN BIT(6) -#define _DATAFLT5EN BIT(5) -#define _DATAFLT4EN BIT(4) -#define _DATAFLT3EN BIT(3) -#define _DATAFLT2EN BIT(2) -#define _DATAFLT1EN BIT(1) -#define _DATAFLT0EN BIT(0) - -/*RXFLTMAP3*/ -#define _MESHAFLT1EN BIT(1) -#define _MESHAFLT0EN BIT(0) - -/*TXPKT_NUM_CTRL*/ -#define _TXPKTNUM_DEC BIT(8) -#define _TXPKTNUM_MSK 0x00FF -#define _TXPKTNUM_SHT 0 - -/*TXFF_PG_NUM*/ -#define _TXFF_PG_NUM_MSK 0x0FFF - -#endif /* __RTL8712_FIFOCTRL_BITDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h deleted file mode 100644 index 189fdeb16d7d..000000000000 --- a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_FIFOCTRL_REGDEF_H__ -#define __RTL8712_FIFOCTRL_REGDEF_H__ - -#define RQPN (RTL8712_FIFOCTRL_ + 0x00) -#define RXFF_BNDY (RTL8712_FIFOCTRL_ + 0x0C) -#define RXRPT_BNDY (RTL8712_FIFOCTRL_ + 0x10) -#define TXPKTBUF_PGBNDY (RTL8712_FIFOCTRL_ + 0x14) -#define PBP (RTL8712_FIFOCTRL_ + 0x15) -#define RX_DRVINFO_SZ (RTL8712_FIFOCTRL_ + 0x16) -#define TXFF_STATUS (RTL8712_FIFOCTRL_ + 0x17) -#define RXFF_STATUS (RTL8712_FIFOCTRL_ + 0x18) -#define TXFF_EMPTY_TH (RTL8712_FIFOCTRL_ + 0x19) -#define SDIO_RX_BLKSZ (RTL8712_FIFOCTRL_ + 0x1C) -#define RXDMA_RXCTRL (RTL8712_FIFOCTRL_ + 0x1D) -#define RXPKT_NUM (RTL8712_FIFOCTRL_ + 0x1E) -#define RXPKT_NUM_C2H (RTL8712_FIFOCTRL_ + 0x1F) -#define C2HCMD_UDT_SIZE (RTL8712_FIFOCTRL_ + 0x20) -#define C2HCMD_UDT_ADDR (RTL8712_FIFOCTRL_ + 0x22) -#define FIFOPAGE2 (RTL8712_FIFOCTRL_ + 0x24) -#define FIFOPAGE1 (RTL8712_FIFOCTRL_ + 0x28) -#define FW_RSVD_PG_CTRL (RTL8712_FIFOCTRL_ + 0x30) -#define TXRPTFF_RDPTR (RTL8712_FIFOCTRL_ + 0x40) -#define TXRPTFF_WTPTR (RTL8712_FIFOCTRL_ + 0x44) -#define C2HFF_RDPTR (RTL8712_FIFOCTRL_ + 0x48) -#define C2HFF_WTPTR (RTL8712_FIFOCTRL_ + 0x4C) -#define RXFF0_RDPTR (RTL8712_FIFOCTRL_ + 0x50) -#define RXFF0_WTPTR (RTL8712_FIFOCTRL_ + 0x54) -#define RXFF1_RDPTR (RTL8712_FIFOCTRL_ + 0x58) -#define RXFF1_WTPTR (RTL8712_FIFOCTRL_ + 0x5C) -#define RXRPT0FF_RDPTR (RTL8712_FIFOCTRL_ + 0x60) -#define RXRPT0FF_WTPTR (RTL8712_FIFOCTRL_ + 0x64) -#define RXRPT1FF_RDPTR (RTL8712_FIFOCTRL_ + 0x68) -#define RXRPT1FF_WTPTR (RTL8712_FIFOCTRL_ + 0x6C) -#define RX0PKTNUM (RTL8712_FIFOCTRL_ + 0x72) -#define RX1PKTNUM (RTL8712_FIFOCTRL_ + 0x74) -#define RXFLTMAP0 (RTL8712_FIFOCTRL_ + 0x76) -#define RXFLTMAP1 (RTL8712_FIFOCTRL_ + 0x78) -#define RXFLTMAP2 (RTL8712_FIFOCTRL_ + 0x7A) -#define RXFLTMAP3 (RTL8712_FIFOCTRL_ + 0x7c) -#define TBDA (RTL8712_FIFOCTRL_ + 0x84) -#define THPDA (RTL8712_FIFOCTRL_ + 0x88) -#define TCDA (RTL8712_FIFOCTRL_ + 0x8C) -#define TMDA (RTL8712_FIFOCTRL_ + 0x90) -#define HDA (RTL8712_FIFOCTRL_ + 0x94) -#define TVODA (RTL8712_FIFOCTRL_ + 0x98) -#define TVIDA (RTL8712_FIFOCTRL_ + 0x9C) -#define TBEDA (RTL8712_FIFOCTRL_ + 0xA0) -#define TBKDA (RTL8712_FIFOCTRL_ + 0xA4) -#define RCDA (RTL8712_FIFOCTRL_ + 0xA8) -#define RDSA (RTL8712_FIFOCTRL_ + 0xAC) -#define TXPKT_NUM_CTRL (RTL8712_FIFOCTRL_ + 0xB0) -#define TXQ_PGADD (RTL8712_FIFOCTRL_ + 0xB3) -#define TXFF_PG_NUM (RTL8712_FIFOCTRL_ + 0xB4) - -#endif /* __RTL8712_FIFOCTRL_REGDEF_H__ */ diff --git a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h deleted file mode 100644 index ee651fb3fde3..000000000000 --- a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_GP_BITDEF_H__ -#define __RTL8712_GP_BITDEF_H__ - -/*GPIO_CTRL*/ -#define _GPIO_MOD_MSK 0xFF000000 -#define _GPIO_MOD_SHT 24 -#define _GPIO_IO_SEL_MSK 0x00FF0000 -#define _GPIO_IO_SEL_SHT 16 -#define _GPIO_OUT_MSK 0x0000FF00 -#define _GPIO_OUT_SHT 8 -#define _GPIO_IN_MSK 0x000000FF -#define _GPIO_IN_SHT 0 - -/*SYS_PINMUX_CFG*/ -#define _GPIOSEL_MSK 0x0003 -#define _GPIOSEL_SHT 0 - -/*LED_CFG*/ -#define _LED1SV BIT(7) -#define _LED1CM_MSK 0x0070 -#define _LED1CM_SHT 4 -#define _LED0SV BIT(3) -#define _LED0CM_MSK 0x0007 -#define _LED0CM_SHT 0 - -/*PHY_REG*/ -#define _HST_RDRDY_SHT 0 -#define _HST_RDRDY_MSK 0xFF -#define _HST_RDRDY BIT(_HST_RDRDY_SHT) -#define _CPU_WTBUSY_SHT 1 -#define _CPU_WTBUSY_MSK 0xFF -#define _CPU_WTBUSY BIT(_CPU_WTBUSY_SHT) - -/* 11. General Purpose Registers (Offset: 0x02E0 - 0x02FF)*/ - -/* 8192S GPIO Config Setting (offset 0x2F1, 1 byte)*/ - -/*----------------------------------------------------------------------------*/ - -#define GPIOMUX_EN BIT(3) /* When this bit is set to "1", - * GPIO PINs will switch to MAC - * GPIO Function - */ -#define GPIOSEL_GPIO 0 /* UART or JTAG or pure GPIO*/ -#define GPIOSEL_PHYDBG 1 /* PHYDBG*/ -#define GPIOSEL_BT 2 /* BT_coex*/ -#define GPIOSEL_WLANDBG 3 /* WLANDBG*/ -#define GPIOSEL_GPIO_MASK (~(BIT(0) | BIT(1))) -/* HW Radio OFF switch (GPIO BIT) */ -#define HAL_8192S_HW_GPIO_OFF_BIT BIT(3) -#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7 -#define HAL_8192S_HW_GPIO_WPS_BIT BIT(4) - -#endif /*__RTL8712_GP_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_gp_regdef.h b/drivers/staging/rtl8712/rtl8712_gp_regdef.h deleted file mode 100644 index 892a7fb13923..000000000000 --- a/drivers/staging/rtl8712/rtl8712_gp_regdef.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_GP_REGDEF_H__ -#define __RTL8712_GP_REGDEF_H__ - -#define PSTIMER (RTL8712_GP_ + 0x00) -#define TIMER1 (RTL8712_GP_ + 0x04) -#define TIMER2 (RTL8712_GP_ + 0x08) -#define GPIO_CTRL (RTL8712_GP_ + 0x0C) -#define GPIO_IO_SEL (RTL8712_GP_ + 0x0E) -#define GPIO_INTCTRL (RTL8712_GP_ + 0x10) -#define MAC_PINMUX_CTRL (RTL8712_GP_ + 0x11) -#define LEDCFG (RTL8712_GP_ + 0x12) -#define PHY_REG_RPT (RTL8712_GP_ + 0x13) -#define PHY_REG_DATA (RTL8712_GP_ + 0x14) - -#endif /*__RTL8712_GP_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h deleted file mode 100644 index 66cc4645e2d1..000000000000 --- a/drivers/staging/rtl8712/rtl8712_hal.h +++ /dev/null @@ -1,142 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_HAL_H__ -#define __RTL8712_HAL_H__ - -enum _HW_VERSION { - RTL8712_FPGA, - RTL8712_1stCUT, /*A Cut (RTL8712_ASIC)*/ - RTL8712_2ndCUT, /*B Cut*/ - RTL8712_3rdCUT, /*C Cut*/ -}; - -enum _LOOPBACK_TYPE { - RTL8712_AIR_TRX = 0, - RTL8712_MAC_LBK, - RTL8712_BB_LBK, - RTL8712_MAC_FW_LBK = 4, - RTL8712_BB_FW_LBK = 8, -}; - -enum RTL871X_HCI_TYPE { - RTL8712_SDIO, - RTL8712_USB, -}; - -enum RTL8712_RF_CONFIG { - RTL8712_RF_1T1R, - RTL8712_RF_1T2R, - RTL8712_RF_2T2R -}; - -enum _RTL8712_HCI_TYPE_ { - RTL8712_HCI_TYPE_PCIE = 0x01, - RTL8712_HCI_TYPE_AP_PCIE = 0x81, - RTL8712_HCI_TYPE_USB = 0x02, - RTL8712_HCI_TYPE_92USB = 0x02, - RTL8712_HCI_TYPE_AP_USB = 0x82, - RTL8712_HCI_TYPE_72USB = 0x12, - RTL8712_HCI_TYPE_SDIO = 0x04, - RTL8712_HCI_TYPE_72SDIO = 0x14 -}; - -struct fw_priv { /*8-bytes alignment required*/ - /*--- long word 0 ----*/ - unsigned char signature_0; /*0x12: CE product, 0x92: IT product*/ - unsigned char signature_1; /*0x87: CE product, 0x81: IT product*/ - unsigned char hci_sel; /*0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP, - * 0x12: 72S-U, 03:SDIO - */ - unsigned char chip_version; /*the same value as register value*/ - unsigned char customer_ID_0; /*customer ID low byte*/ - unsigned char customer_ID_1; /*customer ID high byte*/ - unsigned char rf_config; /*0x11: 1T1R, 0x12: 1T2R, 0x92: 1T2R turbo, - * 0x22: 2T2R - */ - unsigned char usb_ep_num; /* 4: 4EP, 6: 6EP, 11: 11EP*/ - /*--- long word 1 ----*/ - unsigned char regulatory_class_0; /*regulatory class bit map 0*/ - unsigned char regulatory_class_1; /*regulatory class bit map 1*/ - unsigned char regulatory_class_2; /*regulatory class bit map 2*/ - unsigned char regulatory_class_3; /*regulatory class bit map 3*/ - unsigned char rfintfs; /* 0:SWSI, 1:HWSI, 2:HWPI*/ - unsigned char def_nettype; - unsigned char turbo_mode; - unsigned char low_power_mode;/* 0: normal mode, 1: low power mode*/ - /*--- long word 2 ----*/ - unsigned char lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/ - unsigned char mp_mode; /* 1: for MP use, 0: for normal driver */ - unsigned char vcs_type; /* 0:off 1:on 2:auto */ - unsigned char vcs_mode; /* 1:RTS/CTS 2:CTS to self */ - unsigned char rsvd022; - unsigned char rsvd023; - unsigned char rsvd024; - unsigned char rsvd025; - /*--- long word 3 ----*/ - unsigned char qos_en; /*1: QoS enable*/ - unsigned char bw_40MHz_en; /*1: 40MHz BW enable*/ - unsigned char AMSDU2AMPDU_en; /*1: 4181 convert AMSDU to AMPDU, - * 0: disable - */ - unsigned char AMPDU_en; /*1: 11n AMPDU enable*/ - unsigned char rate_control_offload; /*1: FW offloads,0: driver handles*/ - unsigned char aggregation_offload; /*1: FW offloads,0: driver handles*/ - unsigned char rsvd030; - unsigned char rsvd031; - /*--- long word 4 ----*/ - unsigned char beacon_offload; /* 1. FW offloads, 0: driver handles*/ - unsigned char MLME_offload; /* 2. FW offloads, 0: driver handles*/ - unsigned char hwpc_offload; /* 3. FW offloads, 0: driver handles*/ - unsigned char tcp_checksum_offload; /*4. FW offloads,0: driver handles*/ - unsigned char tcp_offload; /* 5. FW offloads, 0: driver handles*/ - unsigned char ps_control_offload; /* 6. FW offloads, 0: driver handles*/ - unsigned char WWLAN_offload; /* 7. FW offloads, 0: driver handles*/ - unsigned char rsvd040; - /*--- long word 5 ----*/ - unsigned char tcp_tx_frame_len_L; /*tcp tx packet length low byte*/ - unsigned char tcp_tx_frame_len_H; /*tcp tx packet length high byte*/ - unsigned char tcp_rx_frame_len_L; /*tcp rx packet length low byte*/ - unsigned char tcp_rx_frame_len_H; /*tcp rx packet length high byte*/ - unsigned char rsvd050; - unsigned char rsvd051; - unsigned char rsvd052; - unsigned char rsvd053; -}; - -struct fw_hdr {/*8-byte alignment required*/ - unsigned short signature; - unsigned short version; /* 0x8000 ~ 0x8FFF for FPGA version, - * 0x0000 ~ 0x7FFF for ASIC version, - */ - unsigned int dmem_size; /*define the size of boot loader*/ - unsigned int img_IMEM_size; /*define the size of FW in IMEM*/ - unsigned int img_SRAM_size; /*define the size of FW in SRAM*/ - unsigned int fw_priv_sz; /*define the size of DMEM variable*/ - unsigned short efuse_addr; - unsigned short h2ccnd_resp_addr; - unsigned int SVNRevision; - unsigned int release_time; /*Mon:Day:Hr:Min*/ - struct fw_priv fwpriv; -}; - -struct hal_priv { - /*Endpoint handles*/ - struct net_device *pipehdls_r8712[10]; - u8 (*hal_bus_init)(struct _adapter *adapter); -}; - -uint rtl8712_hal_init(struct _adapter *padapter); -int rtl871x_load_fw(struct _adapter *padapter); - -#endif diff --git a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h b/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h deleted file mode 100644 index e9732a1bcd7e..000000000000 --- a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_INTERRUPT_BITDEF_H__ -#define __RTL8712_INTERRUPT_BITDEF_H__ - -/*HIMR*/ -/*HISR*/ -#define _CPUERR BIT(29) -#define _ATIMEND BIT(28) -#define _TXBCNOK BIT(27) -#define _TXBCNERR BIT(26) -#define _BCNDMAINT4 BIT(25) -#define _BCNDMAINT3 BIT(24) -#define _BCNDMAINT2 BIT(23) -#define _BCNDMAINT1 BIT(22) -#define _BCNDOK4 BIT(21) -#define _BCNDOK3 BIT(20) -#define _BCNDOK2 BIT(19) -#define _BCNDOK1 BIT(18) -#define _TIMEOUT2 BIT(17) -#define _TIMEOUT1 BIT(16) -#define _TXFOVW BIT(15) -#define _PSTIMEOUT BIT(14) -#define _BCNDMAINT0 BIT(13) -#define _FOVW BIT(12) -#define _RDU BIT(11) -#define _RXCMDOK BIT(10) -#define _BCNDOK0 BIT(9) -#define _HIGHDOK BIT(8) -#define _COMDOK BIT(7) -#define _MGTDOK BIT(6) -#define _HCCADOK BIT(5) -#define _BKDOK BIT(4) -#define _BEDOK BIT(3) -#define _VIDOK BIT(2) -#define _VODOK BIT(1) -#define _RXOK BIT(0) - -#endif /*__RTL8712_INTERRUPT_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_io.c b/drivers/staging/rtl8712/rtl8712_io.c deleted file mode 100644 index 384cbdb05e19..000000000000 --- a/drivers/staging/rtl8712/rtl8712_io.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_io.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE . - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_IO_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_io.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -u8 r8712_read8(struct _adapter *adapter, u32 addr) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - return hdl->io_ops._read8(hdl, addr); -} - -u16 r8712_read16(struct _adapter *adapter, u32 addr) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - return hdl->io_ops._read16(hdl, addr); -} - -u32 r8712_read32(struct _adapter *adapter, u32 addr) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - return hdl->io_ops._read32(hdl, addr); -} - -void r8712_write8(struct _adapter *adapter, u32 addr, u8 val) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write8(hdl, addr, val); -} - -void r8712_write16(struct _adapter *adapter, u32 addr, u16 val) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write16(hdl, addr, val); -} - -void r8712_write32(struct _adapter *adapter, u32 addr, u32 val) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write32(hdl, addr, val); -} - -void r8712_read_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - if (adapter->driver_stopped || adapter->surprise_removed) - return; - - hdl->io_ops._read_mem(hdl, addr, cnt, pmem); -} - -void r8712_write_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write_mem(hdl, addr, cnt, pmem); -} - -void r8712_read_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - if (adapter->driver_stopped || adapter->surprise_removed) - return; - - hdl->io_ops._read_port(hdl, addr, cnt, pmem); -} - -void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem) -{ - struct intf_hdl *hdl = &adapter->pio_queue->intf; - - hdl->io_ops._write_port(hdl, addr, cnt, pmem); -} diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c deleted file mode 100644 index d5fc9026b036..000000000000 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ /dev/null @@ -1,1830 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_led.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#include "drv_types.h" - -/*=========================================================================== - * Constant. - *=========================================================================== - - * - * Default LED behavior. - */ -#define LED_BLINK_NORMAL_INTERVAL 100 -#define LED_BLINK_SLOWLY_INTERVAL 200 -#define LED_BLINK_LONG_INTERVAL 400 - -#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 -#define LED_BLINK_LINK_INTERVAL_ALPHA 500 -#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 -#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 -#define LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA 5000 - -/*=========================================================================== - * LED object. - *=========================================================================== - */ -enum _LED_STATE_871x { - LED_UNKNOWN = 0, - LED_STATE_ON = 1, - LED_STATE_OFF = 2, - LED_BLINK_NORMAL = 3, - LED_BLINK_SLOWLY = 4, - LED_POWER_ON_BLINK = 5, - LED_SCAN_BLINK = 6, /* LED is blinking during scanning period, - * the # of times to blink is depend on time - * for scanning. - */ - LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */ - LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer - * Server case - */ - LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */ - LED_TXRX_BLINK = 10, - LED_BLINK_WPS_STOP = 11, /*for ALPHA */ - LED_BLINK_WPS_STOP_OVERLAP = 12, /*for BELKIN */ -}; - -/*=========================================================================== - * Prototype of protected function. - *=========================================================================== - */ -static void BlinkTimerCallback(struct timer_list *t); - -static void BlinkWorkItemCallback(struct work_struct *work); -/*=========================================================================== - * LED_819xUsb routines. - *=========================================================================== - * - * - * - * Description: - * Initialize an LED_871x object. - */ -static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed, - enum LED_PIN_871x LedPin) -{ - pLed->padapter = padapter; - pLed->LedPin = LedPin; - pLed->CurrLedState = LED_STATE_OFF; - pLed->bLedOn = false; - pLed->bLedBlinkInProgress = false; - pLed->BlinkTimes = 0; - pLed->BlinkingLedState = LED_UNKNOWN; - timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0); - INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback); -} - -/* - * Description: - * DeInitialize an LED_871x object. - */ -static void DeInitLed871x(struct LED_871x *pLed) -{ - del_timer_sync(&pLed->BlinkTimer); - /* We should reset bLedBlinkInProgress if we cancel - * the LedControlTimer, - */ - pLed->bLedBlinkInProgress = false; -} - -/* - * Description: - * Turn on LED according to LedPin specified. - */ -static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed) -{ - u8 LedCfg; - - if (padapter->surprise_removed || padapter->driver_stopped) - return; - LedCfg = r8712_read8(padapter, LEDCFG); - switch (pLed->LedPin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - /* SW control led0 on.*/ - r8712_write8(padapter, LEDCFG, LedCfg & 0xf0); - break; - case LED_PIN_LED1: - /* SW control led1 on.*/ - r8712_write8(padapter, LEDCFG, LedCfg & 0x0f); - break; - default: - break; - } - pLed->bLedOn = true; -} - -/* - * Description: - * Turn off LED according to LedPin specified. - */ -static void SwLedOff(struct _adapter *padapter, struct LED_871x *pLed) -{ - u8 LedCfg; - - if (padapter->surprise_removed || padapter->driver_stopped) - return; - LedCfg = r8712_read8(padapter, LEDCFG); - switch (pLed->LedPin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - LedCfg &= 0xf0; /* Set to software control.*/ - r8712_write8(padapter, LEDCFG, (LedCfg | BIT(3))); - break; - case LED_PIN_LED1: - LedCfg &= 0x0f; /* Set to software control.*/ - r8712_write8(padapter, LEDCFG, (LedCfg | BIT(7))); - break; - default: - break; - } - pLed->bLedOn = false; -} - -/*=========================================================================== - * Interface to manipulate LED objects. - *=========================================================================== - * - * Description: - * Initialize all LED_871x objects. - */ -void r8712_InitSwLeds(struct _adapter *padapter) -{ - struct led_priv *pledpriv = &padapter->ledpriv; - - pledpriv->LedControlHandler = LedControl871x; - InitLed871x(padapter, &pledpriv->SwLed0, LED_PIN_LED0); - InitLed871x(padapter, &pledpriv->SwLed1, LED_PIN_LED1); -} - -/* Description: - * DeInitialize all LED_819xUsb objects. - */ -void r8712_DeInitSwLeds(struct _adapter *padapter) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - - DeInitLed871x(&ledpriv->SwLed0); - DeInitLed871x(&ledpriv->SwLed1); -} - -/* Description: - * Implementation of LED blinking behavior. - * It toggle off LED and schedule corresponding timer if necessary. - */ -static void SwLedBlink(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - /* Determine if we shall change LED state again. */ - pLed->BlinkTimes--; - switch (pLed->CurrLedState) { - case LED_BLINK_NORMAL: - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - case LED_BLINK_StartToBlink: - if (check_fwstate(pmlmepriv, _FW_LINKED) && - (pmlmepriv->fw_state & WIFI_STATION_STATE)) - bStopBlinking = true; - if (check_fwstate(pmlmepriv, _FW_LINKED) && - ((pmlmepriv->fw_state & WIFI_ADHOC_STATE) || - (pmlmepriv->fw_state & WIFI_ADHOC_MASTER_STATE))) - bStopBlinking = true; - else if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - case LED_BLINK_WPS: - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - break; - default: - bStopBlinking = true; - break; - } - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED) && - !pLed->bLedOn) - SwLedOn(padapter, pLed); - else if (check_fwstate(pmlmepriv, _FW_LINKED) && pLed->bLedOn) - SwLedOff(padapter, pLed); - pLed->BlinkTimes = 0; - pLed->bLedBlinkInProgress = false; - } else { - /* Assign LED state to toggle. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - - /* Schedule a timer to toggle LED state. */ - switch (pLed->CurrLedState) { - case LED_BLINK_NORMAL: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_BLINK_SLOWLY: - case LED_BLINK_StartToBlink: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - break; - case LED_BLINK_WPS: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LONG_INTERVAL)); - break; - default: - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - break; - } - } -} - -static void SwLedBlink1(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct eeprom_priv *peeprompriv = &padapter->eeprompriv; - struct LED_871x *pLed1 = &ledpriv->SwLed1; - u8 bStopBlinking = false; - - if (peeprompriv->CustomerID == RT_CID_819x_CAMEO) - pLed = &ledpriv->SwLed1; - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - if (peeprompriv->CustomerID == RT_CID_DEFAULT) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (!pLed1->bSWLedCtrl) { - SwLedOn(padapter, pLed1); - pLed1->bSWLedCtrl = true; - } else if (!pLed1->bLedOn) { - SwLedOn(padapter, pLed1); - } - } else { - if (!pLed1->bSWLedCtrl) { - SwLedOff(padapter, pLed1); - pLed1->bSWLedCtrl = true; - } else if (pLed1->bLedOn) { - SwLedOff(padapter, pLed1); - } - } - } - switch (pLed->CurrLedState) { - case LED_BLINK_SLOWLY: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_BLINK_NORMAL: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - break; - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - pLed->BlinkTimes = 0; - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - case LED_BLINK_WPS_STOP: /* WPS success */ - if (pLed->BlinkingLedState == LED_STATE_ON) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - bStopBlinking = false; - } else { - bStopBlinking = true; - } - if (bStopBlinking) { - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } - pLed->bLedWPSBlinkInProgress = false; - break; - default: - break; - } -} - -static void SwLedBlink2(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - SwLedOff(padapter, pLed); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - SwLedOff(padapter, pLed); - } - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - default: - break; - } -} - -static void SwLedBlink3(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - if (pLed->CurrLedState != LED_BLINK_WPS_STOP) - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedOn) - SwLedOff(padapter, pLed); - } - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - SwLedOn(padapter, pLed); - } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedOn) - SwLedOff(padapter, pLed); - } - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - case LED_BLINK_WPS_STOP: /*WPS success*/ - if (pLed->BlinkingLedState == LED_STATE_ON) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - bStopBlinking = false; - } else { - bStopBlinking = true; - } - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - SwLedOn(padapter, pLed); - pLed->bLedWPSBlinkInProgress = false; - } - break; - default: - break; - } -} - -static void SwLedBlink4(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - struct led_priv *ledpriv = &padapter->ledpriv; - struct LED_871x *pLed1 = &ledpriv->SwLed1; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - if (!pLed1->bLedWPSBlinkInProgress && - pLed1->BlinkingLedState == LED_UNKNOWN) { - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - SwLedOff(padapter, pLed1); - } - switch (pLed->CurrLedState) { - case LED_BLINK_SLOWLY: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_BLINK_StartToBlink: - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - break; - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - break; - case LED_BLINK_WPS_STOP: /*WPS authentication fail*/ - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_BLINK_WPS_STOP_OVERLAP: /*WPS session overlap */ - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - if (pLed->bLedOn) - pLed->BlinkTimes = 1; - else - bStopBlinking = true; - } - if (bStopBlinking) { - pLed->BlinkTimes = 10; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - break; - default: - break; - } -} - -static void SwLedBlink5(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_SCAN_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - pLed->bLedScanBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - default: - break; - } -} - -static void SwLedBlink6(struct LED_871x *pLed) -{ - struct _adapter *padapter = pLed->padapter; - u8 bStopBlinking = false; - - /* Change LED according to BlinkingLedState specified. */ - if (pLed->BlinkingLedState == LED_STATE_ON) - SwLedOn(padapter, pLed); - else - SwLedOff(padapter, pLed); - switch (pLed->CurrLedState) { - case LED_TXRX_BLINK: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) - bStopBlinking = true; - if (bStopBlinking) { - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (!pLed->bLedOn) - SwLedOn(padapter, pLed); - pLed->bLedBlinkInProgress = false; - } else { - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_BLINK_WPS: - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - break; - - default: - break; - } -} - -/* Description: - * Callback function of LED BlinkTimer, - * it just schedules to corresponding BlinkWorkItem. - */ -static void BlinkTimerCallback(struct timer_list *t) -{ - struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer); - - /* This fixed the crash problem on Fedora 12 when trying to do the - * insmod;ifconfig up;rmmod commands. - */ - if (pLed->padapter->surprise_removed || pLed->padapter->driver_stopped) - return; - schedule_work(&pLed->BlinkWorkItem); -} - -/* Description: - * Callback function of LED BlinkWorkItem. - * We dispatch actual LED blink action according to LedStrategy. - */ -static void BlinkWorkItemCallback(struct work_struct *work) -{ - struct LED_871x *pLed = container_of(work, struct LED_871x, - BlinkWorkItem); - struct led_priv *ledpriv = &pLed->padapter->ledpriv; - - switch (ledpriv->LedStrategy) { - case SW_LED_MODE0: - SwLedBlink(pLed); - break; - case SW_LED_MODE1: - SwLedBlink1(pLed); - break; - case SW_LED_MODE2: - SwLedBlink2(pLed); - break; - case SW_LED_MODE3: - SwLedBlink3(pLed); - break; - case SW_LED_MODE4: - SwLedBlink4(pLed); - break; - case SW_LED_MODE5: - SwLedBlink5(pLed); - break; - case SW_LED_MODE6: - SwLedBlink6(pLed); - break; - default: - SwLedBlink(pLed); - break; - } -} - -/*============================================================================ - * Default LED behavior. - *============================================================================ - * - * Description: - * Implement each led action for SW_LED_MODE0. - * This is default strategy. - */ - -static void SwLedControlMode1(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl; - - if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO) - pLed = &ledpriv->SwLed1; - switch (LedAction) { - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!pLed->bLedNoLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - break; - case LED_CTL_LINK: - if (!pLed->bLedLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_NORMAL; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA)); - } - break; - case LED_CTL_SITE_SURVEY: - if (psitesurveyctrl->traffic_busy && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_START_WPS: /*wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_STOP_WPS: - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) - del_timer(&pLed->BlinkTimer); - else - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - default: - break; - } -} - -static void SwLedControlMode2(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - - case LED_CTL_LINK: - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - - case LED_CTL_START_WPS: /*wait until xinpin finish*/ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - - case LED_CTL_STOP_WPS: - pLed->bLedWPSBlinkInProgress = false; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - - case LED_CTL_STOP_WPS_FAIL: - pLed->bLedWPSBlinkInProgress = false; - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - default: - break; - } -} - -static void SwLedControlMode3(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_LINK: - if (IS_LED_WPS_BLINKING(pLed)) - return; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_START_WPS: /* wait until xinpin finish */ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_STOP_WPS: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } else { - pLed->bLedWPSBlinkInProgress = true; - } - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (!IS_LED_BLINKING(pLed)) { - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - default: - break; - } -} - -static void SwLedControlMode4(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - struct LED_871x *pLed1 = &ledpriv->SwLed1; - - switch (LedAction) { - case LED_CTL_START_TO_LINK: - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer(&pLed1->BlinkTimer); - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - if (!pLed->bLedStartToLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - pLed->bLedStartToLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_StartToBlink; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - } - break; - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - /*LED1 settings*/ - if (LedAction == LED_CTL_LINK) { - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer(&pLed1->BlinkTimer); - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - } - if (!pLed->bLedNoLinkBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - } - break; - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; - else if (!pLed->bLedScanBlinkInProgress) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK || - IS_LED_WPS_BLINKING(pLed)) - return; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_START_WPS: /*wait until xinpin finish*/ - case LED_CTL_START_WPS_BOTTON: - if (pLed1->bLedWPSBlinkInProgress) { - pLed1->bLedWPSBlinkInProgress = false; - del_timer(&pLed1->BlinkTimer); - pLed1->BlinkingLedState = LED_STATE_OFF; - pLed1->CurrLedState = LED_STATE_OFF; - if (pLed1->bLedOn) - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - } - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) { - pLed->BlinkingLedState = LED_STATE_OFF; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL)); - } else { - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - } - } - break; - case LED_CTL_STOP_WPS: /*WPS connect success*/ - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - break; - case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/ - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - /*LED1 settings*/ - if (pLed1->bLedWPSBlinkInProgress) - del_timer(&pLed1->BlinkTimer); - else - pLed1->bLedWPSBlinkInProgress = true; - pLed1->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed1->bLedOn) - pLed1->BlinkingLedState = LED_STATE_OFF; - else - pLed1->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/ - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->bLedNoLinkBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_SLOWLY; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); - /*LED1 settings*/ - if (pLed1->bLedWPSBlinkInProgress) - del_timer(&pLed1->BlinkTimer); - else - pLed1->bLedWPSBlinkInProgress = true; - pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; - pLed1->BlinkTimes = 10; - if (pLed1->bLedOn) - pLed1->BlinkingLedState = LED_STATE_OFF; - else - pLed1->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL)); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedNoLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedNoLinkBlinkInProgress = false; - } - if (pLed->bLedLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedLinkBlinkInProgress = false; - } - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - if (pLed->bLedScanBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedScanBlinkInProgress = false; - } - if (pLed->bLedStartToLinkBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedStartToLinkBlinkInProgress = false; - } - if (pLed1->bLedWPSBlinkInProgress) { - del_timer(&pLed1->BlinkTimer); - pLed1->bLedWPSBlinkInProgress = false; - } - pLed1->BlinkingLedState = LED_UNKNOWN; - SwLedOff(padapter, pLed); - SwLedOff(padapter, pLed1); - break; - default: - break; - } -} - -static void SwLedControlMode5(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO) - pLed = &ledpriv->SwLed1; - - switch (LedAction) { - case LED_CTL_POWER_ON: - case LED_CTL_NO_LINK: - case LED_CTL_LINK: /* solid blue */ - if (pLed->CurrLedState == LED_SCAN_BLINK) - return; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - pLed->bLedBlinkInProgress = false; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_SITE_SURVEY: - if (pmlmepriv->sitesurveyctrl.traffic_busy && - check_fwstate(pmlmepriv, _FW_LINKED)) - ; /* dummy branch */ - else if (!pLed->bLedScanBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedScanBlinkInProgress = true; - pLed->CurrLedState = LED_SCAN_BLINK; - pLed->BlinkTimes = 24; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress) { - if (pLed->CurrLedState == LED_SCAN_BLINK) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - SwLedOff(padapter, pLed); - break; - default: - break; - } -} - -static void SwLedControlMode6(struct _adapter *padapter, - enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct LED_871x *pLed = &ledpriv->SwLed0; - - switch (LedAction) { - case LED_CTL_POWER_ON: - case LED_CTL_NO_LINK: - case LED_CTL_LINK: /*solid blue*/ - case LED_CTL_SITE_SURVEY: - if (IS_LED_WPS_BLINKING(pLed)) - return; - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - pLed->bLedBlinkInProgress = false; - mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (!pLed->bLedBlinkInProgress && - check_fwstate(pmlmepriv, _FW_LINKED)) { - if (IS_LED_WPS_BLINKING(pLed)) - return; - pLed->bLedBlinkInProgress = true; - pLed->CurrLedState = LED_TXRX_BLINK; - pLed->BlinkTimes = 2; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA)); - } - break; - case LED_CTL_START_WPS: /*wait until xinpin finish*/ - case LED_CTL_START_WPS_BOTTON: - if (!pLed->bLedWPSBlinkInProgress) { - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - if (pLed->bLedOn) - pLed->BlinkingLedState = LED_STATE_OFF; - else - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, jiffies + - msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA)); - } - break; - case LED_CTL_STOP_WPS_FAIL: - case LED_CTL_STOP_WPS: - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - pLed->CurrLedState = LED_STATE_ON; - pLed->BlinkingLedState = LED_STATE_ON; - mod_timer(&pLed->BlinkTimer, - jiffies + msecs_to_jiffies(0)); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = LED_STATE_OFF; - pLed->BlinkingLedState = LED_STATE_OFF; - if (pLed->bLedBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedBlinkInProgress = false; - } - if (pLed->bLedWPSBlinkInProgress) { - del_timer(&pLed->BlinkTimer); - pLed->bLedWPSBlinkInProgress = false; - } - SwLedOff(padapter, pLed); - break; - default: - break; - } -} - -/* Description: - * Dispatch LED action according to pHalData->LedStrategy. - */ -void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - - if (!ledpriv->bRegUseLed) - return; - switch (ledpriv->LedStrategy) { - case SW_LED_MODE0: - break; - case SW_LED_MODE1: - SwLedControlMode1(padapter, LedAction); - break; - case SW_LED_MODE2: - SwLedControlMode2(padapter, LedAction); - break; - case SW_LED_MODE3: - SwLedControlMode3(padapter, LedAction); - break; - case SW_LED_MODE4: - SwLedControlMode4(padapter, LedAction); - break; - case SW_LED_MODE5: - SwLedControlMode5(padapter, LedAction); - break; - case SW_LED_MODE6: - SwLedControlMode6(padapter, LedAction); - break; - default: - break; - } -} - -void r8712_flush_led_works(struct _adapter *padapter) -{ - struct led_priv *pledpriv = &padapter->ledpriv; - - flush_work(&pledpriv->SwLed0.BlinkWorkItem); - flush_work(&pledpriv->SwLed1.BlinkWorkItem); -} diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h deleted file mode 100644 index 46d758d3f3a4..000000000000 --- a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_MACSETTING_BITDEF_H__ -#define __RTL8712_MACSETTING_BITDEF_H__ - -/*MACID*/ -/*BSSID*/ - -/*HWVID*/ -#define _HWVID_MSK 0x0F - -/*MAR*/ -/*MBIDCANCONTENT*/ - -/*MBIDCANCFG*/ -#define _POOLING BIT(31) -#define _WRITE_EN BIT(16) -#define _CAM_ADDR_MSK 0x001F -#define _CAM_ADDR_SHT 0 - -/*BUILDTIME*/ -#define _BUILDTIME_MSK 0x3FFFFFFF - -/*BUILDUSER*/ - -#endif /* __RTL8712_MACSETTING_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h deleted file mode 100644 index 64740d99c252..000000000000 --- a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_MACSETTING_REGDEF_H__ -#define __RTL8712_MACSETTING_REGDEF_H__ - -#define MACID (RTL8712_MACIDSETTING_ + 0x0000) -#define BSSIDR (RTL8712_MACIDSETTING_ + 0x0008) -#define HWVID (RTL8712_MACIDSETTING_ + 0x000E) -#define MAR (RTL8712_MACIDSETTING_ + 0x0010) -#define MBIDCANCONTENT (RTL8712_MACIDSETTING_ + 0x0018) -#define MBIDCANCFG (RTL8712_MACIDSETTING_ + 0x0020) -#define BUILDTIME (RTL8712_MACIDSETTING_ + 0x0024) -#define BUILDUSER (RTL8712_MACIDSETTING_ + 0x0028) - -#endif /*__RTL8712_MACSETTING_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h b/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h deleted file mode 100644 index 53e0d6b440f3..000000000000 --- a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_POWERSAVE_BITDEF_H__ -#define __RTL8712_POWERSAVE_BITDEF_H__ - -/*WOWCTRL*/ -#define _UWF BIT(3) -#define _MAGIC BIT(2) -#define _WOW_EN BIT(1) -#define _PMEN BIT(0) - -/*PSSTATUS*/ -#define _PSSTATUS_SEL_MSK 0x0F - -/*PSSWITCH*/ -#define _PSSWITCH_ACT BIT(7) -#define _PSSWITCH_SEL_MSK 0x0F -#define _PSSWITCH_SEL_SHT 0 - -/*LPNAV_CTRL*/ -#define _LPNAV_EN BIT(31) -#define _LPNAV_EARLY_MSK 0x7FFF0000 -#define _LPNAV_EARLY_SHT 16 -#define _LPNAV_TH_MSK 0x0000FFFF -#define _LPNAV_TH_SHT 0 - -/*RPWM*/ -/*CPWM*/ -#define _TOGGLING BIT(7) -#define _WWLAN BIT(3) -#define _RPS_ST BIT(2) -#define _WLAN_TRX BIT(1) -#define _SYS_CLK BIT(0) - -#endif /* __RTL8712_POWERSAVE_BITDEF_H__*/ diff --git a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h b/drivers/staging/rtl8712/rtl8712_powersave_regdef.h deleted file mode 100644 index 1bcfde4b1c11..000000000000 --- a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_POWERSAVE_REGDEF_H__ -#define __RTL8712_POWERSAVE_REGDEF_H__ - -#define WOWCTRL (RTL8712_POWERSAVE_ + 0x00) -#define PSSTATUS (RTL8712_POWERSAVE_ + 0x01) -#define PSSWITCH (RTL8712_POWERSAVE_ + 0x02) -#define MIMOPS_WAITPERIOD (RTL8712_POWERSAVE_ + 0x03) -#define LPNAV_CTRL (RTL8712_POWERSAVE_ + 0x04) -#define WFM0 (RTL8712_POWERSAVE_ + 0x10) -#define WFM1 (RTL8712_POWERSAVE_ + 0x20) -#define WFM2 (RTL8712_POWERSAVE_ + 0x30) -#define WFM3 (RTL8712_POWERSAVE_ + 0x40) -#define WFM4 (RTL8712_POWERSAVE_ + 0x50) -#define WFM5 (RTL8712_POWERSAVE_ + 0x60) -#define WFCRC (RTL8712_POWERSAVE_ + 0x70) -#define RPWM (RTL8712_POWERSAVE_ + 0x7C) -#define CPWM (RTL8712_POWERSAVE_ + 0x7D) - -#endif /* __RTL8712_POWERSAVE_REGDEF_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h deleted file mode 100644 index 1de51c48f9c1..000000000000 --- a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_RATECTRL_BITDEF_H__ -#define __RTL8712_RATECTRL_BITDEF_H__ - -/*INIRTSMCS_SEL*/ -#define _INIRTSMCS_SEL_MSK 0x3F - -/* RRSR*/ -#define _RRSR_SHORT BIT(23) -#define _RRSR_RSC_MSK 0x600000 -#define _RRSR_RSC_SHT 21 -#define _RRSR_BITMAP_MSK 0x0FFFFF -#define _RRSR_BITMAP_SHT 0 - -/* AGGLEN_LMT_H*/ -#define _AGGLMT_MCS32_MSK 0xF0 -#define _AGGLMT_MCS32_SHT 4 -#define _AGGLMT_MCS15_SGI_MSK 0x0F -#define _AGGLMT_MCS15_SGI_SHT 0 - -/* DARFRC*/ -/* RARFRC*/ -/* MCS_TXAGC*/ -/* CCK_TXAGC*/ -#define _CCK_MSK 0xFF00 -#define _CCK_SHT 8 -#define _BARKER_MSK 0x00FF -#define _BARKER_SHT 0 - -#endif /* __RTL8712_RATECTRL_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h deleted file mode 100644 index 9ed5653f3f7f..000000000000 --- a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_RATECTRL_REGDEF_H__ -#define __RTL8712_RATECTRL_REGDEF_H__ - -#define INIMCS_SEL (RTL8712_RATECTRL_ + 0x00) -#define INIRTSMCS_SEL (RTL8712_RATECTRL_ + 0x20) -#define RRSR (RTL8712_RATECTRL_ + 0x21) -#define ARFR0 (RTL8712_RATECTRL_ + 0x24) -#define ARFR1 (RTL8712_RATECTRL_ + 0x28) -#define ARFR2 (RTL8712_RATECTRL_ + 0x2C) -#define ARFR3 (RTL8712_RATECTRL_ + 0x30) -#define ARFR4 (RTL8712_RATECTRL_ + 0x34) -#define ARFR5 (RTL8712_RATECTRL_ + 0x38) -#define ARFR6 (RTL8712_RATECTRL_ + 0x3C) -#define ARFR7 (RTL8712_RATECTRL_ + 0x40) -#define AGGLEN_LMT_H (RTL8712_RATECTRL_ + 0x47) -#define AGGLEN_LMT_L (RTL8712_RATECTRL_ + 0x48) -#define DARFRC (RTL8712_RATECTRL_ + 0x50) -#define RARFRC (RTL8712_RATECTRL_ + 0x58) -#define MCS_TXAGC0 (RTL8712_RATECTRL_ + 0x60) -#define MCS_TXAGC1 (RTL8712_RATECTRL_ + 0x61) -#define MCS_TXAGC2 (RTL8712_RATECTRL_ + 0x62) -#define MCS_TXAGC3 (RTL8712_RATECTRL_ + 0x63) -#define MCS_TXAGC4 (RTL8712_RATECTRL_ + 0x64) -#define MCS_TXAGC5 (RTL8712_RATECTRL_ + 0x65) -#define MCS_TXAGC6 (RTL8712_RATECTRL_ + 0x66) -#define MCS_TXAGC7 (RTL8712_RATECTRL_ + 0x67) -#define CCK_TXAGC (RTL8712_RATECTRL_ + 0x68) - -#endif /*__RTL8712_RATECTRL_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c deleted file mode 100644 index 7da014ab0723..000000000000 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ /dev/null @@ -1,1080 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_recv.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_RECV_C_ - -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" -#include "ethernet.h" -#include "usb_ops.h" -#include "wifi.h" - -static void recv_tasklet(struct tasklet_struct *t); - -int r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter) -{ - int i; - struct recv_buf *precvbuf; - addr_t tmpaddr = 0; - int alignment = 0; - struct sk_buff *pskb = NULL; - - /*init recv_buf*/ - _init_queue(&precvpriv->free_recv_buf_queue); - precvpriv->pallocated_recv_buf = - kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_ATOMIC); - if (!precvpriv->pallocated_recv_buf) - return -ENOMEM; - precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 - - ((addr_t)(precvpriv->pallocated_recv_buf) & 3); - precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - INIT_LIST_HEAD(&precvbuf->list); - spin_lock_init(&precvbuf->recvbuf_lock); - if (r8712_os_recvbuf_resource_alloc(padapter, precvbuf)) - break; - precvbuf->ref_cnt = 0; - precvbuf->adapter = padapter; - list_add_tail(&precvbuf->list, - &precvpriv->free_recv_buf_queue.queue); - precvbuf++; - } - precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; - tasklet_setup(&precvpriv->recv_tasklet, recv_tasklet); - skb_queue_head_init(&precvpriv->rx_skb_queue); - - skb_queue_head_init(&precvpriv->free_recv_skb_queue); - for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { - pskb = netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + - RECVBUFF_ALIGN_SZ); - if (pskb) { - tmpaddr = (addr_t)pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); - skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); - } - pskb = NULL; - } - return 0; -} - -void r8712_free_recv_priv(struct recv_priv *precvpriv) -{ - int i; - struct recv_buf *precvbuf; - struct _adapter *padapter = precvpriv->adapter; - - precvbuf = (struct recv_buf *)precvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - r8712_os_recvbuf_resource_free(padapter, precvbuf); - precvbuf++; - } - kfree(precvpriv->pallocated_recv_buf); - skb_queue_purge(&precvpriv->rx_skb_queue); - if (skb_queue_len(&precvpriv->rx_skb_queue)) - netdev_warn(padapter->pnetdev, "r8712u: rx_skb_queue not empty\n"); - skb_queue_purge(&precvpriv->free_recv_skb_queue); - if (skb_queue_len(&precvpriv->free_recv_skb_queue)) - netdev_warn(padapter->pnetdev, "r8712u: free_recv_skb_queue not empty %d\n", - skb_queue_len(&precvpriv->free_recv_skb_queue)); -} - -void r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf) -{ - precvbuf->transfer_len = 0; - precvbuf->len = 0; - precvbuf->ref_cnt = 0; - if (precvbuf->pbuf) { - precvbuf->pdata = precvbuf->pbuf; - precvbuf->phead = precvbuf->pbuf; - precvbuf->ptail = precvbuf->pbuf; - precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ; - } -} - -void r8712_free_recvframe(union recv_frame *precvframe, - struct __queue *pfree_recv_queue) -{ - unsigned long irqL; - struct _adapter *padapter = precvframe->u.hdr.adapter; - struct recv_priv *precvpriv = &padapter->recvpriv; - - if (precvframe->u.hdr.pkt) { - dev_kfree_skb_any(precvframe->u.hdr.pkt);/*free skb by driver*/ - precvframe->u.hdr.pkt = NULL; - } - spin_lock_irqsave(&pfree_recv_queue->lock, irqL); - list_del_init(&precvframe->u.hdr.list); - list_add_tail(&precvframe->u.hdr.list, &pfree_recv_queue->queue); - if (padapter) { - if (pfree_recv_queue == &precvpriv->free_recv_queue) - precvpriv->free_recvframe_cnt++; - } - spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL); -} - -static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib, - struct recv_stat *prxstat) -{ - u16 drvinfo_sz; - - drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; - drvinfo_sz <<= 3; - /*TODO: - * Offset 0 - */ - pattrib->bdecrypted = (le32_to_cpu(prxstat->rxdw0) & BIT(27)) == 0; - pattrib->crc_err = (le32_to_cpu(prxstat->rxdw0) & BIT(14)) != 0; - /*Offset 4*/ - /*Offset 8*/ - /*Offset 12*/ - if (le32_to_cpu(prxstat->rxdw3) & BIT(13)) { - pattrib->tcpchk_valid = 1; /* valid */ - if (le32_to_cpu(prxstat->rxdw3) & BIT(11)) - pattrib->tcp_chkrpt = 1; /* correct */ - else - pattrib->tcp_chkrpt = 0; /* incorrect */ - if (le32_to_cpu(prxstat->rxdw3) & BIT(12)) - pattrib->ip_chkrpt = 1; /* correct */ - else - pattrib->ip_chkrpt = 0; /* incorrect */ - } else { - pattrib->tcpchk_valid = 0; /* invalid */ - } - pattrib->mcs_rate = (u8)((le32_to_cpu(prxstat->rxdw3)) & 0x3f); - pattrib->htc = (u8)((le32_to_cpu(prxstat->rxdw3) >> 14) & 0x1); - /*Offset 16*/ - /*Offset 20*/ - /*phy_info*/ -} - -/*perform defrag*/ -static union recv_frame *recvframe_defrag(struct _adapter *adapter, - struct __queue *defrag_q) -{ - struct list_head *plist, *phead; - u8 wlanhdr_offset; - u8 curfragnum; - struct recv_frame_hdr *pfhdr, *pnfhdr; - union recv_frame *prframe, *pnextrframe; - struct __queue *pfree_recv_queue; - - pfree_recv_queue = &adapter->recvpriv.free_recv_queue; - phead = &defrag_q->queue; - plist = phead->next; - prframe = container_of(plist, union recv_frame, u.list); - list_del_init(&prframe->u.list); - pfhdr = &prframe->u.hdr; - curfragnum = 0; - if (curfragnum != pfhdr->attrib.frag_num) { - /*the first fragment number must be 0 - *free the whole queue - */ - r8712_free_recvframe(prframe, pfree_recv_queue); - r8712_free_recvframe_queue(defrag_q, pfree_recv_queue); - return NULL; - } - curfragnum++; - plist = &defrag_q->queue; - plist = plist->next; - while (!end_of_queue_search(phead, plist)) { - pnextrframe = container_of(plist, union recv_frame, u.list); - pnfhdr = &pnextrframe->u.hdr; - /*check the fragment sequence (2nd ~n fragment frame) */ - if (curfragnum != pnfhdr->attrib.frag_num) { - /* the fragment number must increase (after decache) - * release the defrag_q & prframe - */ - r8712_free_recvframe(prframe, pfree_recv_queue); - r8712_free_recvframe_queue(defrag_q, pfree_recv_queue); - return NULL; - } - curfragnum++; - /* copy the 2nd~n fragment frame's payload to the first fragment - * get the 2nd~last fragment frame's payload - */ - wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; - recvframe_pull(pnextrframe, wlanhdr_offset); - /* append to first fragment frame's tail (if privacy frame, - * pull the ICV) - */ - recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); - memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); - recvframe_put(prframe, pnfhdr->len); - pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; - plist = plist->next; - } - /* free the defrag_q queue and return the prframe */ - r8712_free_recvframe_queue(defrag_q, pfree_recv_queue); - return prframe; -} - -/* check if need to defrag, if needed queue the frame to defrag_q */ -union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter, - union recv_frame *precv_frame) -{ - u8 ismfrag; - u8 fragnum; - u8 *psta_addr; - struct recv_frame_hdr *pfhdr; - struct sta_info *psta; - struct sta_priv *pstapriv; - struct list_head *phead; - union recv_frame *prtnframe = NULL; - struct __queue *pfree_recv_queue, *pdefrag_q; - - pstapriv = &padapter->stapriv; - pfhdr = &precv_frame->u.hdr; - pfree_recv_queue = &padapter->recvpriv.free_recv_queue; - /* need to define struct of wlan header frame ctrl */ - ismfrag = pfhdr->attrib.mfrag; - fragnum = pfhdr->attrib.frag_num; - psta_addr = pfhdr->attrib.ta; - psta = r8712_get_stainfo(pstapriv, psta_addr); - if (!psta) - pdefrag_q = NULL; - else - pdefrag_q = &psta->sta_recvpriv.defrag_q; - - if ((ismfrag == 0) && (fragnum == 0)) - prtnframe = precv_frame;/*isn't a fragment frame*/ - if (ismfrag == 1) { - /* 0~(n-1) fragment frame - * enqueue to defraf_g - */ - if (pdefrag_q) { - if (fragnum == 0) { - /*the first fragment*/ - if (!list_empty(&pdefrag_q->queue)) { - /*free current defrag_q */ - r8712_free_recvframe_queue(pdefrag_q, - pfree_recv_queue); - } - } - /* Then enqueue the 0~(n-1) fragment to the defrag_q */ - phead = &pdefrag_q->queue; - list_add_tail(&pfhdr->list, phead); - prtnframe = NULL; - } else { - /* can't find this ta's defrag_queue, so free this - * recv_frame - */ - r8712_free_recvframe(precv_frame, pfree_recv_queue); - prtnframe = NULL; - } - } - if ((ismfrag == 0) && (fragnum != 0)) { - /* the last fragment frame - * enqueue the last fragment - */ - if (pdefrag_q) { - phead = &pdefrag_q->queue; - list_add_tail(&pfhdr->list, phead); - /*call recvframe_defrag to defrag*/ - precv_frame = recvframe_defrag(padapter, pdefrag_q); - prtnframe = precv_frame; - } else { - /* can't find this ta's defrag_queue, so free this - * recv_frame - */ - r8712_free_recvframe(precv_frame, pfree_recv_queue); - prtnframe = NULL; - } - } - if (prtnframe && (prtnframe->u.hdr.attrib.privacy)) { - /* after defrag we must check tkip mic code */ - if (r8712_recvframe_chkmic(padapter, prtnframe) == _FAIL) { - r8712_free_recvframe(prtnframe, pfree_recv_queue); - prtnframe = NULL; - } - } - return prtnframe; -} - -static void amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe) -{ - int a_len, padding_len; - u16 eth_type, nSubframe_Length; - u8 nr_subframes, i; - unsigned char *pdata; - struct rx_pkt_attrib *pattrib; - _pkt *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; - struct recv_priv *precvpriv = &padapter->recvpriv; - struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; - - nr_subframes = 0; - pattrib = &prframe->u.hdr.attrib; - recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen); - if (prframe->u.hdr.attrib.iv_len > 0) - recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len); - a_len = prframe->u.hdr.len; - pdata = prframe->u.hdr.rx_data; - while (a_len > ETH_HLEN) { - /* Offset 12 denote 2 mac address */ - nSubframe_Length = *((u16 *)(pdata + 12)); - /*==m==>change the length order*/ - nSubframe_Length = (nSubframe_Length >> 8) + - (nSubframe_Length << 8); - if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { - netdev_warn(padapter->pnetdev, "r8712u: nRemain_Length is %d and nSubframe_Length is: %d\n", - a_len, nSubframe_Length); - goto exit; - } - /* move the data point to data content */ - pdata += ETH_HLEN; - a_len -= ETH_HLEN; - /* Allocate new skb for releasing to upper layer */ - sub_skb = dev_alloc_skb(nSubframe_Length + 12); - if (!sub_skb) - break; - skb_reserve(sub_skb, 12); - skb_put_data(sub_skb, pdata, nSubframe_Length); - subframes[nr_subframes++] = sub_skb; - if (nr_subframes >= MAX_SUBFRAME_COUNT) { - netdev_warn(padapter->pnetdev, "r8712u: ParseSubframe(): Too many Subframes! Packets dropped!\n"); - break; - } - pdata += nSubframe_Length; - a_len -= nSubframe_Length; - if (a_len != 0) { - padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & 3); - if (padding_len == 4) - padding_len = 0; - if (a_len < padding_len) - goto exit; - pdata += padding_len; - a_len -= padding_len; - } - } - for (i = 0; i < nr_subframes; i++) { - sub_skb = subframes[i]; - /* convert hdr + possible LLC headers into Ethernet header */ - eth_type = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) && - eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || - !memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE))) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType - */ - skb_pull(sub_skb, SNAP_SIZE); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, - ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, - ETH_ALEN); - } else { - __be16 len; - /* Leave Ethernet header part of hdr and full payload */ - len = htons(sub_skb->len); - memcpy(skb_push(sub_skb, 2), &len, 2); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, - ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, - ETH_ALEN); - } - /* Indicate the packets to upper layer */ - if (sub_skb) { - sub_skb->protocol = - eth_type_trans(sub_skb, padapter->pnetdev); - sub_skb->dev = padapter->pnetdev; - if ((pattrib->tcpchk_valid == 1) && - (pattrib->tcp_chkrpt == 1)) { - sub_skb->ip_summed = CHECKSUM_UNNECESSARY; - } else { - sub_skb->ip_summed = CHECKSUM_NONE; - } - netif_rx(sub_skb); - } - } -exit: - prframe->u.hdr.len = 0; - r8712_free_recvframe(prframe, pfree_recv_queue); -} - -void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) -{ - __le32 voffset; - u8 *poffset; - u16 cmd_len, drvinfo_sz; - struct recv_stat *prxstat; - - poffset = prxcmdbuf; - voffset = *(__le32 *)poffset; - prxstat = prxcmdbuf; - drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; - drvinfo_sz <<= 3; - poffset += RXDESC_SIZE + drvinfo_sz; - do { - voffset = *(__le32 *)poffset; - cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff); - r8712_event_handle(padapter, (__le32 *)poffset); - poffset += (cmd_len + 8);/*8 bytes alignment*/ - } while (le32_to_cpu(voffset) & BIT(31)); -} - -static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, - u16 seq_num) -{ - u8 wsize = preorder_ctrl->wsize_b; - u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) % 4096; - - /* Rx Reorder initialize condition.*/ - if (preorder_ctrl->indicate_seq == 0xffff) - preorder_ctrl->indicate_seq = seq_num; - /* Drop out the packet which SeqNum is smaller than WinStart */ - if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) - return false; - /* - * Sliding window manipulation. Conditions includes: - * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 - * 2. Incoming SeqNum is larger than the WinEnd => Window shift N - */ - if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) - preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + - 1) % 4096; - else if (SN_LESS(wend, seq_num)) { - if (seq_num >= (wsize - 1)) - preorder_ctrl->indicate_seq = seq_num + 1 - wsize; - else - preorder_ctrl->indicate_seq = 4095 - (wsize - - (seq_num + 1)) + 1; - } - return true; -} - -static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, - union recv_frame *prframe) -{ - struct list_head *phead, *plist; - union recv_frame *pnextrframe; - struct rx_pkt_attrib *pnextattrib; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; - - phead = &ppending_recvframe_queue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - pnextrframe = container_of(plist, union recv_frame, u.list); - pnextattrib = &pnextrframe->u.hdr.attrib; - - if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) - return false; - - if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) - plist = plist->next; - else - break; - } - list_del_init(&prframe->u.hdr.list); - list_add_tail(&prframe->u.hdr.list, plist); - return true; -} - -int r8712_recv_indicatepkts_in_order(struct _adapter *padapter, - struct recv_reorder_ctrl *preorder_ctrl, - int bforced) -{ - struct list_head *phead, *plist; - union recv_frame *prframe; - struct rx_pkt_attrib *pattrib; - int bPktInBuf = false; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - - phead = &ppending_recvframe_queue->queue; - plist = phead->next; - /* Handling some condition for forced indicate case.*/ - if (bforced) { - if (list_empty(phead)) - return true; - - prframe = container_of(plist, union recv_frame, u.list); - pattrib = &prframe->u.hdr.attrib; - preorder_ctrl->indicate_seq = pattrib->seq_num; - } - /* Prepare indication list and indication. - * Check if there is any packet need indicate. - */ - while (!list_empty(phead)) { - prframe = container_of(plist, union recv_frame, u.list); - pattrib = &prframe->u.hdr.attrib; - if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) { - plist = plist->next; - list_del_init(&prframe->u.hdr.list); - if (SN_EQUAL(preorder_ctrl->indicate_seq, - pattrib->seq_num)) - preorder_ctrl->indicate_seq = - (preorder_ctrl->indicate_seq + 1) % 4096; - /*indicate this recv_frame*/ - if (!pattrib->amsdu) { - if (!padapter->driver_stopped && - !padapter->surprise_removed) { - /* indicate this recv_frame */ - r8712_recv_indicatepkt(padapter, - prframe); - } - } else if (pattrib->amsdu == 1) { - amsdu_to_msdu(padapter, prframe); - } - /* Update local variables. */ - bPktInBuf = false; - } else { - bPktInBuf = true; - break; - } - } - return bPktInBuf; -} - -static int recv_indicatepkt_reorder(struct _adapter *padapter, - union recv_frame *prframe) -{ - unsigned long irql; - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; - struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - - if (!pattrib->amsdu) { - /* s1. */ - r8712_wlanhdr_to_ethhdr(prframe); - if (pattrib->qos != 1) { - if (!padapter->driver_stopped && - !padapter->surprise_removed) { - r8712_recv_indicatepkt(padapter, prframe); - return 0; - } else { - return -EINVAL; - } - } - } - spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); - /*s2. check if winstart_b(indicate_seq) needs to be updated*/ - if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) - goto _err_exit; - /*s3. Insert all packet into Reorder Queue to maintain its ordering.*/ - if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) - goto _err_exit; - /*s4. - * Indication process. - * After Packet dropping and Sliding Window shifting as above, we can - * now just indicate the packets with the SeqNum smaller than latest - * WinStart and buffer other packets. - * - * For Rx Reorder condition: - * 1. All packets with SeqNum smaller than WinStart => Indicate - * 2. All packets with SeqNum larger than or equal to - * WinStart => Buffer it. - */ - if (r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) { - mod_timer(&preorder_ctrl->reordering_ctrl_timer, - jiffies + msecs_to_jiffies(REORDER_WAIT_TIME)); - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - } else { - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - del_timer(&preorder_ctrl->reordering_ctrl_timer); - } - return 0; -_err_exit: - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); - return -ENOMEM; -} - -void r8712_reordering_ctrl_timeout_handler(void *pcontext) -{ - unsigned long irql; - struct recv_reorder_ctrl *preorder_ctrl = pcontext; - struct _adapter *padapter = preorder_ctrl->padapter; - struct __queue *ppending_recvframe_queue = - &preorder_ctrl->pending_recvframe_queue; - - if (padapter->driver_stopped || padapter->surprise_removed) - return; - spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); - r8712_recv_indicatepkts_in_order(padapter, preorder_ctrl, true); - spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); -} - -static int r8712_process_recv_indicatepkts(struct _adapter *padapter, - union recv_frame *prframe) -{ - int retval = _SUCCESS; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - if (phtpriv->ht_option == 1) { /*B/G/N Mode*/ - if (recv_indicatepkt_reorder(padapter, prframe)) { - /* including perform A-MPDU Rx Ordering Buffer Control*/ - if (!padapter->driver_stopped && - !padapter->surprise_removed) - return _FAIL; - } - } else { /*B/G mode*/ - retval = r8712_wlanhdr_to_ethhdr(prframe); - if (retval) - return _FAIL; - if (!padapter->driver_stopped && !padapter->surprise_removed) { - /* indicate this recv_frame */ - r8712_recv_indicatepkt(padapter, prframe); - } else { - return _FAIL; - } - } - return retval; -} - -static u8 query_rx_pwr_percentage(s8 antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; -} - -static u8 evm_db2percentage(s8 value) -{ - /* - * -33dB~0dB to 0%~99% - */ - s8 ret_val = clamp(-value, 0, 33) * 3; - - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} - -s32 r8712_signal_scale_mapping(s32 cur_sig) -{ - s32 ret_sig; - - if (cur_sig >= 51 && cur_sig <= 100) - ret_sig = 100; - else if (cur_sig >= 41 && cur_sig <= 50) - ret_sig = 80 + ((cur_sig - 40) * 2); - else if (cur_sig >= 31 && cur_sig <= 40) - ret_sig = 66 + (cur_sig - 30); - else if (cur_sig >= 21 && cur_sig <= 30) - ret_sig = 54 + (cur_sig - 20); - else if (cur_sig >= 10 && cur_sig <= 20) - ret_sig = 42 + (((cur_sig - 10) * 2) / 3); - else if (cur_sig >= 5 && cur_sig <= 9) - ret_sig = 22 + (((cur_sig - 5) * 3) / 2); - else if (cur_sig >= 1 && cur_sig <= 4) - ret_sig = 6 + (((cur_sig - 1) * 3) / 2); - else - ret_sig = cur_sig; - return ret_sig; -} - -static s32 translate2dbm(struct _adapter *padapter, u8 signal_strength_idx) -{ - s32 signal_power; /* in dBm.*/ - /* Translate to dBm (x=0.5y-95).*/ - signal_power = (s32)((signal_strength_idx + 1) >> 1); - signal_power -= 95; - return signal_power; -} - -static void query_rx_phy_status(struct _adapter *padapter, - union recv_frame *prframe) -{ - u8 i, max_spatial_stream, evm; - struct recv_stat *prxstat = (struct recv_stat *)prframe->u.hdr.rx_head; - struct phy_stat *pphy_stat = (struct phy_stat *)(prxstat + 1); - u8 *pphy_head = (u8 *)(prxstat + 1); - s8 rx_pwr[4], rx_pwr_all; - u8 pwdb_all; - u32 rssi, total_rssi = 0; - u8 bcck_rate = 0, rf_rx_num = 0, cck_highpwr = 0; - struct phy_cck_rx_status *pcck_buf; - u8 sq; - - /* Record it for next packet processing*/ - bcck_rate = (prframe->u.hdr.attrib.mcs_rate <= 3 ? 1 : 0); - if (bcck_rate) { - u8 report; - - /* CCK Driver info Structure is not the same as OFDM packet.*/ - pcck_buf = (struct phy_cck_rx_status *)pphy_stat; - /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB calculated by hardware - * (for rate adaptive) - */ - if (!cck_highpwr) { - report = pcck_buf->cck_agc_rpt & 0xc0; - report >>= 6; - switch (report) { - /* Modify the RF RNA gain value to -40, -20, - * -2, 14 by Jenyu's suggestion - * Note: different RF with the different - * RNA gain. - */ - case 0x3: - rx_pwr_all = -40 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x2: - rx_pwr_all = -20 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x1: - rx_pwr_all = -2 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - case 0x0: - rx_pwr_all = 14 - (pcck_buf->cck_agc_rpt & - 0x3e); - break; - } - } else { - report = ((u8)(le32_to_cpu(pphy_stat->phydw1) >> 8)) & - 0x60; - report >>= 5; - switch (report) { - case 0x3: - rx_pwr_all = -40 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -20 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -2 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = 14 - ((pcck_buf->cck_agc_rpt & - 0x1f) << 1); - break; - } - } - pwdb_all = query_rx_pwr_percentage(rx_pwr_all); - /* CCK gain is smaller than OFDM/MCS gain,*/ - /* so we add gain diff by experiences, the val is 6 */ - pwdb_all += 6; - if (pwdb_all > 100) - pwdb_all = 100; - /* modify the offset to make the same gain index with OFDM.*/ - if (pwdb_all > 34 && pwdb_all <= 42) - pwdb_all -= 2; - else if (pwdb_all > 26 && pwdb_all <= 34) - pwdb_all -= 6; - else if (pwdb_all > 14 && pwdb_all <= 26) - pwdb_all -= 8; - else if (pwdb_all > 4 && pwdb_all <= 14) - pwdb_all -= 4; - /* - * (3) Get Signal Quality (EVM) - */ - if (pwdb_all > 40) { - sq = 100; - } else { - sq = pcck_buf->sq_rpt; - if (pcck_buf->sq_rpt > 64) - sq = 0; - else if (pcck_buf->sq_rpt < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - prframe->u.hdr.attrib.signal_qual = sq; - prframe->u.hdr.attrib.rx_mimo_signal_qual[0] = sq; - prframe->u.hdr.attrib.rx_mimo_signal_qual[1] = -1; - } else { - /* (1)Get RSSI for HT rate */ - for (i = 0; i < ((padapter->registrypriv.rf_config) & - 0x0f); i++) { - rf_rx_num++; - rx_pwr[i] = ((pphy_head[PHY_STAT_GAIN_TRSW_SHT + i] - & 0x3F) * 2) - 110; - /* Translate DBM to percentage. */ - rssi = query_rx_pwr_percentage(rx_pwr[i]); - total_rssi += rssi; - } - /* (2)PWDB, Average PWDB calculated by hardware (for - * rate adaptive) - */ - rx_pwr_all = (((pphy_head[PHY_STAT_PWDB_ALL_SHT]) >> 1) & 0x7f) - - 106; - pwdb_all = query_rx_pwr_percentage(rx_pwr_all); - - { - /* (3)EVM of HT rate */ - if (prframe->u.hdr.attrib.htc && - prframe->u.hdr.attrib.mcs_rate >= 20 && - prframe->u.hdr.attrib.mcs_rate <= 27) { - /* both spatial stream make sense */ - max_spatial_stream = 2; - } else { - /* only spatial stream 1 makes sense */ - max_spatial_stream = 1; - } - for (i = 0; i < max_spatial_stream; i++) { - evm = evm_db2percentage((pphy_head - [PHY_STAT_RXEVM_SHT + i]));/*dbm*/ - prframe->u.hdr.attrib.signal_qual = - (u8)(evm & 0xff); - prframe->u.hdr.attrib.rx_mimo_signal_qual[i] = - (u8)(evm & 0xff); - } - } - } - /* UI BSS List signal strength(in percentage), make it good looking, - * from 0~100. It is assigned to the BSS List in - * GetValueFromBeaconOrProbeRsp(). - */ - if (bcck_rate) { - prframe->u.hdr.attrib.signal_strength = - (u8)r8712_signal_scale_mapping(pwdb_all); - } else { - if (rf_rx_num != 0) - prframe->u.hdr.attrib.signal_strength = - (u8)(r8712_signal_scale_mapping(total_rssi /= - rf_rx_num)); - } -} - -static void process_link_qual(struct _adapter *padapter, - union recv_frame *prframe) -{ - u32 last_evm = 0, tmpVal; - struct rx_pkt_attrib *pattrib; - struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; - - if (!prframe || !padapter) - return; - pattrib = &prframe->u.hdr.attrib; - if (pattrib->signal_qual != 0) { - /* - * 1. Record the general EVM to the sliding window. - */ - if (sqd->total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) { - sqd->total_num = PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = sqd->elements[sqd->index]; - sqd->total_val -= last_evm; - } - sqd->total_val += pattrib->signal_qual; - sqd->elements[sqd->index++] = pattrib->signal_qual; - if (sqd->index >= PHY_LINKQUALITY_SLID_WIN_MAX) - sqd->index = 0; - - /* <1> Showed on UI for user, in percentage. */ - tmpVal = sqd->total_val / sqd->total_num; - padapter->recvpriv.signal = (u8)tmpVal; - } -} - -static void process_rssi(struct _adapter *padapter, union recv_frame *prframe) -{ - u32 last_rssi, tmp_val; - struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; - struct smooth_rssi_data *ssd = &padapter->recvpriv.signal_strength_data; - - if (ssd->total_num++ >= PHY_RSSI_SLID_WIN_MAX) { - ssd->total_num = PHY_RSSI_SLID_WIN_MAX; - last_rssi = ssd->elements[ssd->index]; - ssd->total_val -= last_rssi; - } - ssd->total_val += pattrib->signal_strength; - ssd->elements[ssd->index++] = pattrib->signal_strength; - if (ssd->index >= PHY_RSSI_SLID_WIN_MAX) - ssd->index = 0; - tmp_val = ssd->total_val / ssd->total_num; - padapter->recvpriv.rssi = (s8)translate2dbm(padapter, (u8)tmp_val); -} - -static void process_phy_info(struct _adapter *padapter, - union recv_frame *prframe) -{ - query_rx_phy_status(padapter, prframe); - process_rssi(padapter, prframe); - process_link_qual(padapter, prframe); -} - -int recv_func(struct _adapter *padapter, void *pcontext) -{ - struct rx_pkt_attrib *pattrib; - union recv_frame *prframe, *orig_prframe; - int retval = _SUCCESS; - struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - prframe = pcontext; - orig_prframe = prframe; - pattrib = &prframe->u.hdr.attrib; - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - if (pattrib->crc_err == 1) - padapter->mppriv.rx_crcerrpktcount++; - else - padapter->mppriv.rx_pktcount++; - if (!check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE)) { - /* free this recv_frame */ - r8712_free_recvframe(orig_prframe, pfree_recv_queue); - goto _exit_recv_func; - } - } - /* check the frame crtl field and decache */ - retval = r8712_validate_recv_frame(padapter, prframe); - if (retval != _SUCCESS) { - /* free this recv_frame */ - r8712_free_recvframe(orig_prframe, pfree_recv_queue); - goto _exit_recv_func; - } - process_phy_info(padapter, prframe); - prframe = r8712_decryptor(padapter, prframe); - if (!prframe) { - retval = _FAIL; - goto _exit_recv_func; - } - prframe = r8712_recvframe_chk_defrag(padapter, prframe); - if (!prframe) - goto _exit_recv_func; - prframe = r8712_portctrl(padapter, prframe); - if (!prframe) { - retval = _FAIL; - goto _exit_recv_func; - } - retval = r8712_process_recv_indicatepkts(padapter, prframe); - if (retval != _SUCCESS) { - r8712_free_recvframe(orig_prframe, pfree_recv_queue); - goto _exit_recv_func; - } -_exit_recv_func: - return retval; -} - -static void recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb) -{ - u8 *pbuf, shift_sz = 0; - u8 frag, mf; - uint pkt_len; - u32 transfer_len; - struct recv_stat *prxstat; - u16 pkt_cnt, drvinfo_sz, pkt_offset, tmp_len, alloc_sz; - struct __queue *pfree_recv_queue; - _pkt *pkt_copy = NULL; - union recv_frame *precvframe = NULL; - struct recv_priv *precvpriv = &padapter->recvpriv; - - pfree_recv_queue = &precvpriv->free_recv_queue; - pbuf = pskb->data; - prxstat = (struct recv_stat *)pbuf; - pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; - pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff; - transfer_len = pskb->len; - /* Test throughput with Netgear 3700 (No security) with Chariot 3T3R - * pairs. The packet count will be a big number so that the containing - * packet will effect the Rx reordering. - */ - if (transfer_len < pkt_len) { - /* In this case, it means the MAX_RECVBUF_SZ is too small to - * get the data from 8712u. - */ - return; - } - do { - prxstat = (struct recv_stat *)pbuf; - pkt_len = le32_to_cpu(prxstat->rxdw0) & 0x00003fff; - /* more fragment bit */ - mf = (le32_to_cpu(prxstat->rxdw1) >> 27) & 0x1; - /* ragmentation number */ - frag = (le32_to_cpu(prxstat->rxdw2) >> 12) & 0xf; - /* uint 2^3 = 8 bytes */ - drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16; - drvinfo_sz <<= 3; - if (pkt_len <= 0) - return; - /* Qos data, wireless lan header length is 26 */ - if ((le32_to_cpu(prxstat->rxdw0) >> 23) & 0x01) - shift_sz = 2; - precvframe = r8712_alloc_recvframe(pfree_recv_queue); - if (!precvframe) - return; - INIT_LIST_HEAD(&precvframe->u.hdr.list); - precvframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf*/ - precvframe->u.hdr.len = 0; - tmp_len = pkt_len + drvinfo_sz + RXDESC_SIZE; - pkt_offset = (u16)round_up(tmp_len, 128); - /* for first fragment packet, driver need allocate 1536 + - * drvinfo_sz + RXDESC_SIZE to defrag packet. - */ - if ((mf == 1) && (frag == 0)) - /*1658+6=1664, 1664 is 128 alignment.*/ - alloc_sz = max_t(u16, tmp_len, 1658); - else - alloc_sz = tmp_len; - /* 2 is for IP header 4 bytes alignment in QoS packet case. - * 4 is for skb->data 4 bytes alignment. - */ - alloc_sz += 6; - pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz); - if (!pkt_copy) - return; - - precvframe->u.hdr.pkt = pkt_copy; - skb_reserve(pkt_copy, 4 - ((addr_t)(pkt_copy->data) % 4)); - skb_reserve(pkt_copy, shift_sz); - memcpy(pkt_copy->data, pbuf, tmp_len); - precvframe->u.hdr.rx_head = pkt_copy->data; - precvframe->u.hdr.rx_data = pkt_copy->data; - precvframe->u.hdr.rx_tail = pkt_copy->data; - precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; - - recvframe_put(precvframe, tmp_len); - recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); - /* because the endian issue, driver avoid reference to the - * rxstat after calling update_recvframe_attrib_from_recvstat(); - */ - update_recvframe_attrib_from_recvstat(&precvframe->u.hdr.attrib, - prxstat); - r8712_recv_entry(precvframe); - transfer_len -= pkt_offset; - pbuf += pkt_offset; - pkt_cnt--; - precvframe = NULL; - pkt_copy = NULL; - } while ((transfer_len > 0) && pkt_cnt > 0); -} - -static void recv_tasklet(struct tasklet_struct *t) -{ - struct sk_buff *pskb; - struct _adapter *padapter = from_tasklet(padapter, t, - recvpriv.recv_tasklet); - struct recv_priv *precvpriv = &padapter->recvpriv; - - while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { - recvbuf2recvframe(padapter, pskb); - skb_reset_tail_pointer(pskb); - pskb->len = 0; - if (!skb_cloned(pskb)) - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); - else - consume_skb(pskb); - } -} diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h deleted file mode 100644 index f4d20b0efd4e..000000000000 --- a/drivers/staging/rtl8712/rtl8712_recv.h +++ /dev/null @@ -1,145 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL8712_RECV_H_ -#define _RTL8712_RECV_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -/* Realtek's v2.6.6 reduced this to 4. However, under heavy network and CPU - * loads, even 8 receive buffers might not be enough; cutting it to 4 seemed - * unwise. - */ -#define NR_RECVBUFF (8) - -#define NR_PREALLOC_RECV_SKB (8) -#define RXDESC_SIZE 24 -#define RXDESC_OFFSET RXDESC_SIZE -#define RECV_BLK_SZ 512 -#define RECV_BLK_CNT 16 -#define RECV_BLK_TH RECV_BLK_CNT -#define MAX_RECVBUF_SZ 9100 -#define RECVBUFF_ALIGN_SZ 512 -#define RSVD_ROOM_SZ (0) -/*These definition is used for Rx packet reordering.*/ -#define SN_LESS(a, b) (((a-b) & 0x800) != 0) -#define SN_EQUAL(a, b) (a == b) -#define REORDER_WAIT_TIME 30 /* (ms)*/ - -struct recv_stat { - __le32 rxdw0; - __le32 rxdw1; - __le32 rxdw2; - __le32 rxdw3; - __le32 rxdw4; - __le32 rxdw5; -}; - -struct phy_cck_rx_status { - /* For CCK rate descriptor. This is a unsigned 8:1 variable. - * LSB bit present 0.5. And MSB 7 bts present a signed value. - * Range from -64~+63.5. - */ - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}; - -struct phy_stat { - __le32 phydw0; - __le32 phydw1; - __le32 phydw2; - __le32 phydw3; - __le32 phydw4; - __le32 phydw5; - __le32 phydw6; - __le32 phydw7; -}; - -#define PHY_STAT_GAIN_TRSW_SHT 0 -#define PHY_STAT_PWDB_ALL_SHT 4 -#define PHY_STAT_CFOSHO_SHT 5 -#define PHY_STAT_CCK_AGC_RPT_SHT 5 -#define PHY_STAT_CFOTAIL_SHT 9 -#define PHY_STAT_RXEVM_SHT 13 -#define PHY_STAT_RXSNR_SHT 15 -#define PHY_STAT_PDSNR_SHT 19 -#define PHY_STAT_CSI_CURRENT_SHT 21 -#define PHY_STAT_CSI_TARGET_SHT 23 -#define PHY_STAT_SIGEVM_SHT 25 -#define PHY_STAT_MAX_EX_PWR_SHT 26 - -union recvstat { - struct recv_stat recv_stat; - unsigned int value[RXDESC_SIZE>>2]; -}; - -struct recv_buf { - struct list_head list; - spinlock_t recvbuf_lock; - u32 ref_cnt; - struct _adapter *adapter; - struct urb *purb; - _pkt *pskb; - u8 irp_pending; - u32 transfer_len; - uint len; - u8 *phead; - u8 *pdata; - u8 *ptail; - u8 *pend; - u8 *pbuf; - u8 *pallocated_buf; -}; - -/* - * head -----> - * data -----> - * payload - * tail -----> - * end -----> - * len = (unsigned int )(tail - data); - */ -struct recv_frame_hdr { - struct list_head list; - _pkt *pkt; - _pkt *pkt_newalloc; - struct _adapter *adapter; - u8 fragcnt; - struct rx_pkt_attrib attrib; - uint len; - u8 *rx_head; - u8 *rx_data; - u8 *rx_tail; - u8 *rx_end; - void *precvbuf; - struct sta_info *psta; - /*for A-MPDU Rx reordering buffer control*/ - struct recv_reorder_ctrl *preorder_ctrl; -}; - -union recv_frame { - union { - struct list_head list; - struct recv_frame_hdr hdr; - } u; -}; - -void r8712_init_recvbuf(struct _adapter *padapter, struct recv_buf *precvbuf); -void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf); -s32 r8712_signal_scale_mapping(s32 cur_sig); -void r8712_reordering_ctrl_timeout_handler(void *pcontext); - -#endif - diff --git a/drivers/staging/rtl8712/rtl8712_regdef.h b/drivers/staging/rtl8712/rtl8712_regdef.h deleted file mode 100644 index 28aec9aa539f..000000000000 --- a/drivers/staging/rtl8712/rtl8712_regdef.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_REGDEF_H__ -#define __RTL8712_REGDEF_H__ - -#include "rtl8712_syscfg_regdef.h" -#include "rtl8712_cmdctrl_regdef.h" -#include "rtl8712_macsetting_regdef.h" -#include "rtl8712_timectrl_regdef.h" -#include "rtl8712_fifoctrl_regdef.h" -#include "rtl8712_ratectrl_regdef.h" -#include "rtl8712_edcasetting_regdef.h" -#include "rtl8712_wmac_regdef.h" -#include "rtl8712_powersave_regdef.h" -#include "rtl8712_gp_regdef.h" -#include "rtl8712_debugctrl_regdef.h" - -#define HIMR (RTL8712_INTERRUPT_ + 0x08) - -#endif /* __RTL8712_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_security_bitdef.h b/drivers/staging/rtl8712/rtl8712_security_bitdef.h deleted file mode 100644 index 44275ef455a0..000000000000 --- a/drivers/staging/rtl8712/rtl8712_security_bitdef.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_SECURITY_BITDEF_H__ -#define __RTL8712_SECURITY_BITDEF_H__ - -/*CAMCMD*/ -#define _SECCAM_POLLING BIT(31) -#define _SECCAM_CLR BIT(30) -#define _SECCAM_WE BIT(16) -#define _SECCAM_ADR_MSK 0x000000FF -#define _SECCAM_ADR_SHT 0 - -/*CAMDBG*/ -#define _SECCAM_INFO BIT(31) -#define _SEC_KEYFOUND BIT(30) -#define _SEC_CONFIG_MSK 0x3F000000 -#define _SEC_CONFIG_SHT 24 -#define _SEC_KEYCONTENT_MSK 0x00FFFFFF -#define _SEC_KEYCONTENT_SHT 0 - -/*SECCFG*/ -#define _NOSKMC BIT(5) -#define _SKBYA2 BIT(4) -#define _RXDEC BIT(3) -#define _TXENC BIT(2) -#define _RXUSEDK BIT(1) -#define _TXUSEDK BIT(0) - -#endif /*__RTL8712_SECURITY_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_spec.h b/drivers/staging/rtl8712/rtl8712_spec.h deleted file mode 100644 index 613a410e5714..000000000000 --- a/drivers/staging/rtl8712/rtl8712_spec.h +++ /dev/null @@ -1,121 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_SPEC_H__ -#define __RTL8712_SPEC_H__ - -#define RTL8712_IOBASE_TXPKT 0x10200000 /*IOBASE_TXPKT*/ -#define RTL8712_IOBASE_RXPKT 0x10210000 /*IOBASE_RXPKT*/ -#define RTL8712_IOBASE_RXCMD 0x10220000 /*IOBASE_RXCMD*/ -#define RTL8712_IOBASE_TXSTATUS 0x10230000 /*IOBASE_TXSTATUS*/ -#define RTL8712_IOBASE_RXSTATUS 0x10240000 /*IOBASE_RXSTATUS*/ -#define RTL8712_IOBASE_IOREG 0x10250000 /*IOBASE_IOREG ADDR*/ -#define RTL8712_IOBASE_SCHEDULER 0x10260000 /*IOBASE_SCHEDULE*/ - -#define RTL8712_IOBASE_TRXDMA 0x10270000 /*IOBASE_TRXDMA*/ -#define RTL8712_IOBASE_TXLLT 0x10280000 /*IOBASE_TXLLT*/ -#define RTL8712_IOBASE_WMAC 0x10290000 /*IOBASE_WMAC*/ -#define RTL8712_IOBASE_FW2HW 0x102A0000 /*IOBASE_FW2HW*/ -#define RTL8712_IOBASE_ACCESS_PHYREG 0x102B0000 /*IOBASE_ACCESS_PHYREG*/ - -#define RTL8712_IOBASE_FF 0x10300000 /*IOBASE_FIFO 0x1031000~0x103AFFFF*/ - -/*IOREG Offset for 8712*/ -#define RTL8712_SYSCFG_ RTL8712_IOBASE_IOREG -#define RTL8712_CMDCTRL_ (RTL8712_IOBASE_IOREG + 0x40) -#define RTL8712_MACIDSETTING_ (RTL8712_IOBASE_IOREG + 0x50) -#define RTL8712_TIMECTRL_ (RTL8712_IOBASE_IOREG + 0x80) -#define RTL8712_FIFOCTRL_ (RTL8712_IOBASE_IOREG + 0xA0) -#define RTL8712_RATECTRL_ (RTL8712_IOBASE_IOREG + 0x160) -#define RTL8712_EDCASETTING_ (RTL8712_IOBASE_IOREG + 0x1D0) -#define RTL8712_WMAC_ (RTL8712_IOBASE_IOREG + 0x200) -#define RTL8712_SECURITY_ (RTL8712_IOBASE_IOREG + 0x240) -#define RTL8712_POWERSAVE_ (RTL8712_IOBASE_IOREG + 0x260) -#define RTL8712_GP_ (RTL8712_IOBASE_IOREG + 0x2E0) -#define RTL8712_INTERRUPT_ (RTL8712_IOBASE_IOREG + 0x300) -#define RTL8712_DEBUGCTRL_ (RTL8712_IOBASE_IOREG + 0x310) -#define RTL8712_OFFLOAD_ (RTL8712_IOBASE_IOREG + 0x2D0) - -/*FIFO for 8712*/ -#define RTL8712_DMA_BCNQ (RTL8712_IOBASE_FF + 0x10000) -#define RTL8712_DMA_MGTQ (RTL8712_IOBASE_FF + 0x20000) -#define RTL8712_DMA_BMCQ (RTL8712_IOBASE_FF + 0x30000) -#define RTL8712_DMA_VOQ (RTL8712_IOBASE_FF + 0x40000) -#define RTL8712_DMA_VIQ (RTL8712_IOBASE_FF + 0x50000) -#define RTL8712_DMA_BEQ (RTL8712_IOBASE_FF + 0x60000) -#define RTL8712_DMA_BKQ (RTL8712_IOBASE_FF + 0x70000) -#define RTL8712_DMA_RX0FF (RTL8712_IOBASE_FF + 0x80000) -#define RTL8712_DMA_H2CCMD (RTL8712_IOBASE_FF + 0x90000) -#define RTL8712_DMA_C2HCMD (RTL8712_IOBASE_FF + 0xA0000) - -/*------------------------------*/ - -/*BIT 16 15*/ -#define DID_SDIO_LOCAL 0 /* 0 0*/ -#define DID_WLAN_IOREG 1 /* 0 1*/ -#define DID_WLAN_FIFO 3 /* 1 1*/ -#define DID_UNDEFINE (-1) - -#define CMD_ADDR_MAPPING_SHIFT 2 /*SDIO CMD ADDR MAPPING, - *shift 2 bit for match - * offset[14:2] - */ - -/*Offset for SDIO LOCAL*/ -#define OFFSET_SDIO_LOCAL 0x0FFF - -/*Offset for WLAN IOREG*/ -#define OFFSET_WLAN_IOREG 0x0FFF - -/*Offset for WLAN FIFO*/ -#define OFFSET_TX_BCNQ 0x0300 -#define OFFSET_TX_HIQ 0x0310 -#define OFFSET_TX_CMDQ 0x0320 -#define OFFSET_TX_MGTQ 0x0330 -#define OFFSET_TX_HCCAQ 0x0340 -#define OFFSET_TX_VOQ 0x0350 -#define OFFSET_TX_VIQ 0x0360 -#define OFFSET_TX_BEQ 0x0370 -#define OFFSET_TX_BKQ 0x0380 -#define OFFSET_RX_RX0FFQ 0x0390 -#define OFFSET_RX_C2HFFQ 0x03A0 - -#define BK_QID_01 1 -#define BK_QID_02 2 -#define BE_QID_01 0 -#define BE_QID_02 3 -#define VI_QID_01 4 -#define VI_QID_02 5 -#define VO_QID_01 6 -#define VO_QID_02 7 -#define HCCA_QID_01 8 -#define HCCA_QID_02 9 -#define HCCA_QID_03 10 -#define HCCA_QID_04 11 -#define HCCA_QID_05 12 -#define HCCA_QID_06 13 -#define HCCA_QID_07 14 -#define HCCA_QID_08 15 -#define HI_QID 17 -#define CMD_QID 19 -#define MGT_QID 18 -#define BCN_QID 16 - -#include "rtl8712_regdef.h" - -#include "rtl8712_bitdef.h" - -#include "basic_types.h" - -#endif /* __RTL8712_SPEC_H__ */ - diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h deleted file mode 100644 index d92df3fbd2b1..000000000000 --- a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h +++ /dev/null @@ -1,163 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_SYSCFG_BITDEF_H__ -#define __RTL8712_SYSCFG_BITDEF_H__ - -/*SYS_PWR_CTRL*/ -/*SRCTRL0*/ -/*SRCTRL1*/ -/*SYS_CLKR*/ - -/*SYS_IOS_CTRL*/ -#define iso_LDR2RP_SHT 8 /* EE Loader to Retention Path*/ -#define iso_LDR2RP BIT(iso_LDR2RP_SHT) /* 1:isolation, 0:attach*/ - -/*SYS_CTRL*/ -#define FEN_DIO_SDIO_SHT 0 -#define FEN_DIO_SDIO BIT(FEN_DIO_SDIO_SHT) -#define FEN_SDIO_SHT 1 -#define FEN_SDIO BIT(FEN_SDIO_SHT) -#define FEN_USBA_SHT 2 -#define FEN_USBA BIT(FEN_USBA_SHT) -#define FEN_UPLL_SHT 3 -#define FEN_UPLL BIT(FEN_UPLL_SHT) -#define FEN_USBD_SHT 4 -#define FEN_USBD BIT(FEN_USBD_SHT) -#define FEN_DIO_PCIE_SHT 5 -#define FEN_DIO_PCIE BIT(FEN_DIO_PCIE_SHT) -#define FEN_PCIEA_SHT 6 -#define FEN_PCIEA BIT(FEN_PCIEA_SHT) -#define FEN_PPLL_SHT 7 -#define FEN_PPLL BIT(FEN_PPLL_SHT) -#define FEN_PCIED_SHT 8 -#define FEN_PCIED BIT(FEN_PCIED_SHT) -#define FEN_CPUEN_SHT 10 -#define FEN_CPUEN BIT(FEN_CPUEN_SHT) -#define FEN_DCORE_SHT 11 -#define FEN_DCORE BIT(FEN_DCORE_SHT) -#define FEN_ELDR_SHT 12 -#define FEN_ELDR BIT(FEN_ELDR_SHT) -#define PWC_DV2LDR_SHT 13 -#define PWC_DV2LDR BIT(PWC_DV2LDR_SHT) /* Loader Power Enable*/ - -/*=== SYS_CLKR ===*/ -#define SYS_CLKSEL_SHT 0 -#define SYS_CLKSEL BIT(SYS_CLKSEL_SHT) /* System Clock 80MHz*/ -#define PS_CLKSEL_SHT 1 -#define PS_CLKSEL BIT(PS_CLKSEL_SHT) /*System power save - * clock select. - */ -#define CPU_CLKSEL_SHT 2 -#define CPU_CLKSEL BIT(CPU_CLKSEL_SHT) /* System Clock select, - * 1: AFE source, - * 0: System clock(L-Bus) - */ -#define INT32K_EN_SHT 3 -#define INT32K_EN BIT(INT32K_EN_SHT) -#define MACSLP_SHT 4 -#define MACSLP BIT(MACSLP_SHT) -#define MAC_CLK_EN_SHT 11 -#define MAC_CLK_EN BIT(MAC_CLK_EN_SHT) /* MAC Clock Enable.*/ -#define SYS_CLK_EN_SHT 12 -#define SYS_CLK_EN BIT(SYS_CLK_EN_SHT) -#define RING_CLK_EN_SHT 13 -#define RING_CLK_EN BIT(RING_CLK_EN_SHT) -#define SWHW_SEL_SHT 14 -#define SWHW_SEL BIT(SWHW_SEL_SHT) /* Load done, - * control path switch. - */ -#define FWHW_SEL_SHT 15 -#define FWHW_SEL BIT(FWHW_SEL_SHT) /* Sleep exit, - * control path switch. - */ - -/*9346CR*/ -#define _VPDIDX_MSK 0xFF00 -#define _VPDIDX_SHT 8 -#define _EEM_MSK 0x00C0 -#define _EEM_SHT 6 -#define _EEM0 BIT(6) -#define _EEM1 BIT(7) -#define _EEPROM_EN BIT(5) -#define _9356SEL BIT(4) -#define _EECS BIT(3) -#define _EESK BIT(2) -#define _EEDI BIT(1) -#define _EEDO BIT(0) - -/*AFE_MISC*/ -#define AFE_MISC_USB_MBEN_SHT 7 -#define AFE_MISC_USB_MBEN BIT(AFE_MISC_USB_MBEN_SHT) -#define AFE_MISC_USB_BGEN_SHT 6 -#define AFE_MISC_USB_BGEN BIT(AFE_MISC_USB_BGEN_SHT) -#define AFE_MISC_LD12_VDAJ_SHT 4 -#define AFE_MISC_LD12_VDAJ_MSK 0X0030 -#define AFE_MISC_LD12_VDAJ BIT(AFE_MISC_LD12_VDAJ_SHT) -#define AFE_MISC_I32_EN_SHT 3 -#define AFE_MISC_I32_EN BIT(AFE_MISC_I32_EN_SHT) -#define AFE_MISC_E32_EN_SHT 2 -#define AFE_MISC_E32_EN BIT(AFE_MISC_E32_EN_SHT) -#define AFE_MISC_MBEN_SHT 1 -#define AFE_MISC_MBEN BIT(AFE_MISC_MBEN_SHT)/* Enable AFE Macro - * Block's Mbias. - */ -#define AFE_MISC_BGEN_SHT 0 -#define AFE_MISC_BGEN BIT(AFE_MISC_BGEN_SHT)/* Enable AFE Macro - * Block's Bandgap. - */ - -/*--------------------------------------------------------------------------*/ -/* SPS1_CTRL bits (Offset 0x18-1E, 56bits)*/ -/*--------------------------------------------------------------------------*/ -#define SPS1_SWEN BIT(1) /* Enable vsps18 SW Macro Block.*/ -#define SPS1_LDEN BIT(0) /* Enable VSPS12 LDO Macro block.*/ - -/*----------------------------------------------------------------------------*/ -/* LDOA15_CTRL bits (Offset 0x20, 8bits)*/ -/*----------------------------------------------------------------------------*/ -#define LDA15_EN BIT(0) /* Enable LDOA15 Macro Block*/ - -/*----------------------------------------------------------------------------*/ -/* 8192S LDOV12D_CTRL bit (Offset 0x21, 8bits)*/ -/*----------------------------------------------------------------------------*/ -#define LDV12_EN BIT(0) /* Enable LDOVD12 Macro Block*/ -#define LDV12_SDBY BIT(1) /* LDOVD12 standby mode*/ - -/*CLK_PS_CTRL*/ -#define _CLK_GATE_EN BIT(0) - -/* EFUSE_CTRL*/ -#define EF_FLAG BIT(31) /* Access Flag, Write:1; - * Read:0 - */ -#define EF_PGPD 0x70000000 /* E-fuse Program time*/ -#define EF_RDT 0x0F000000 /* E-fuse read time: in the - * unit of cycle time - */ -#define EF_PDN_EN BIT(19) /* EFuse Power down enable*/ -#define ALD_EN BIT(18) /* Autoload Enable*/ -#define EF_ADDR 0x0003FF00 /* Access Address*/ -#define EF_DATA 0x000000FF /* Access Data*/ - -/* EFUSE_TEST*/ -#define LDOE25_EN BIT(31) /* Enable LDOE25 Macro Block*/ - -/* EFUSE_CLK_CTRL*/ -#define EFUSE_CLK_EN BIT(1) /* E-Fuse Clock Enable*/ -#define EFUSE_CLK_SEL BIT(0) /* E-Fuse Clock Select, - * 0:500K, 1:40M - */ - -#endif /*__RTL8712_SYSCFG_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h deleted file mode 100644 index da5efcdedabe..000000000000 --- a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_SYSCFG_REGDEF_H__ -#define __RTL8712_SYSCFG_REGDEF_H__ - -#define SYS_ISO_CTRL (RTL8712_SYSCFG_ + 0x0000) -#define SYS_FUNC_EN (RTL8712_SYSCFG_ + 0x0002) -#define PMC_FSM (RTL8712_SYSCFG_ + 0x0004) -#define SYS_CLKR (RTL8712_SYSCFG_ + 0x0008) -#define EE_9346CR (RTL8712_SYSCFG_ + 0x000A) -#define EE_VPD (RTL8712_SYSCFG_ + 0x000C) -#define AFE_MISC (RTL8712_SYSCFG_ + 0x0010) -#define SPS0_CTRL (RTL8712_SYSCFG_ + 0x0011) -#define SPS1_CTRL (RTL8712_SYSCFG_ + 0x0018) -#define RF_CTRL (RTL8712_SYSCFG_ + 0x001F) -#define LDOA15_CTRL (RTL8712_SYSCFG_ + 0x0020) -#define LDOV12D_CTRL (RTL8712_SYSCFG_ + 0x0021) -#define LDOHCI12_CTRL (RTL8712_SYSCFG_ + 0x0022) -#define LDO_USB_CTRL (RTL8712_SYSCFG_ + 0x0023) -#define LPLDO_CTRL (RTL8712_SYSCFG_ + 0x0024) -#define AFE_XTAL_CTRL (RTL8712_SYSCFG_ + 0x0026) -#define AFE_PLL_CTRL (RTL8712_SYSCFG_ + 0x0028) -#define EFUSE_CTRL (RTL8712_SYSCFG_ + 0x0030) -#define EFUSE_TEST (RTL8712_SYSCFG_ + 0x0034) -#define PWR_DATA (RTL8712_SYSCFG_ + 0x0038) -#define DPS_TIMER (RTL8712_SYSCFG_ + 0x003C) -#define RCLK_MON (RTL8712_SYSCFG_ + 0x003E) -#define EFUSE_CLK_CTRL (RTL8712_SYSCFG_ + 0x02F8) - -#endif /*__RTL8712_SYSCFG_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h deleted file mode 100644 index d7bc9dd5cecd..000000000000 --- a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_TIMECTRL_BITDEF_H__ -#define __RTL8712_TIMECTRL_BITDEF_H__ - -/*TSFTR*/ -/*SLOT*/ -/*USTIME*/ - -/*TUBASE*/ -#define _TUBASE_MSK 0x07FF - -/*SIFS_CCK*/ -#define _SIFS_CCK_TRX_MSK 0xFF00 -#define _SIFS_CCK_TRX_SHT 0x8 -#define _SIFS_CCK_CTX_MSK 0x00FF -#define _SIFS_CCK_CTX_SHT 0 - -/*SIFS_OFDM*/ -#define _SIFS_OFDM_TRX_MSK 0xFF00 -#define _SIFS_OFDM_TRX_SHT 0x8 -#define _SIFS_OFDM_CTX_MSK 0x00FF -#define _SIFS_OFDM_CTX_SHT 0 - -/*PIFS*/ -/*ACKTO*/ -/*EIFS*/ -/*BCNITV*/ -/*ATIMWND*/ - -/*DRVERLYINT*/ -#define _ENSWBCN BIT(15) -#define _DRVERLY_TU_MSK 0x0FF0 -#define _DRVERLY_TU_SHT 4 -#define _DRVERLY_US_MSK 0x000F -#define _DRVERLY_US_SHT 0 - -/*BCNDMATIM*/ -#define _BCNDMATIM_MSK 0x03FF - -/*BCNERRTH*/ -/*MLT*/ - -#endif /* __RTL8712_TIMECTRL_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h deleted file mode 100644 index b51603f1b880..000000000000 --- a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL8712_TIMECTRL_REGDEF_H__ -#define __RTL8712_TIMECTRL_REGDEF_H__ - -#define TSFTR (RTL8712_TIMECTRL_ + 0x00) -#define USTIME (RTL8712_TIMECTRL_ + 0x08) -#define SLOT (RTL8712_TIMECTRL_ + 0x09) -#define TUBASE (RTL8712_TIMECTRL_ + 0x0A) -#define SIFS_CCK (RTL8712_TIMECTRL_ + 0x0C) -#define SIFS_OFDM (RTL8712_TIMECTRL_ + 0x0E) -#define PIFS (RTL8712_TIMECTRL_ + 0x10) -#define ACKTO (RTL8712_TIMECTRL_ + 0x11) -#define EIFS (RTL8712_TIMECTRL_ + 0x12) -#define BCNITV (RTL8712_TIMECTRL_ + 0x14) -#define ATIMWND (RTL8712_TIMECTRL_ + 0x16) -#define DRVERLYINT (RTL8712_TIMECTRL_ + 0x18) -#define BCNDMATIM (RTL8712_TIMECTRL_ + 0x1A) -#define BCNERRTH (RTL8712_TIMECTRL_ + 0x1C) -#define MLT (RTL8712_TIMECTRL_ + 0x1D) - -#endif /* __RTL8712_TIMECTRL_REGDEF_H__ */ diff --git a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h b/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h deleted file mode 100644 index ea164e482347..000000000000 --- a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_WMAC_BITDEF_H__ -#define __RTL8712_WMAC_BITDEF_H__ - -/*NAVCTRL*/ -#define _NAV_UPPER_EN BIT(18) -#define _NAV_MTO_EN BIT(17) -#define _NAV_UPPER BIT(16) -#define _NAV_MTO_MSK 0xFF00 -#define _NAV_MTO_SHT 8 -#define _RTSRST_MSK 0x00FF -#define _RTSRST_SHT 0 - -/*BWOPMODE*/ -#define _20MHZBW BIT(2) - -/*BACAMCMD*/ -#define _BACAM_POLL BIT(31) -#define _BACAM_RST BIT(17) -#define _BACAM_RW BIT(16) -#define _BACAM_ADDR_MSK 0x0000007F -#define _BACAM_ADDR_SHT 0 - -/*LBDLY*/ -#define _LBDLY_MSK 0x1F - -/*FWDLY*/ -#define _FWDLY_MSK 0x0F - -/*RXERR_RPT*/ -#define _RXERR_RPT_SEL_MSK 0xF0000000 -#define _RXERR_RPT_SEL_SHT 28 -#define _RPT_CNT_MSK 0x000FFFFF -#define _RPT_CNT_SHT 0 - -#endif /*__RTL8712_WMAC_BITDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h b/drivers/staging/rtl8712/rtl8712_wmac_regdef.h deleted file mode 100644 index dfe3e9fbed43..000000000000 --- a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_WMAC_REGDEF_H__ -#define __RTL8712_WMAC_REGDEF_H__ - -#define NAVCTRL (RTL8712_WMAC_ + 0x00) -#define BWOPMODE (RTL8712_WMAC_ + 0x03) -#define BACAMCMD (RTL8712_WMAC_ + 0x04) -#define BACAMCONTENT (RTL8712_WMAC_ + 0x08) -#define LBDLY (RTL8712_WMAC_ + 0x10) -#define FWDLY (RTL8712_WMAC_ + 0x11) -#define HWPC_RX_CTRL (RTL8712_WMAC_ + 0x18) -#define MQ (RTL8712_WMAC_ + 0x20) -#define MA (RTL8712_WMAC_ + 0x22) -#define MS (RTL8712_WMAC_ + 0x24) -#define CLM_RESULT (RTL8712_WMAC_ + 0x27) -#define NHM_RPI_CNT (RTL8712_WMAC_ + 0x28) -#define RXERR_RPT (RTL8712_WMAC_ + 0x30) -#define NAV_PROT_LEN (RTL8712_WMAC_ + 0x34) -#define CFEND_TH (RTL8712_WMAC_ + 0x36) -#define AMPDU_MIN_SPACE (RTL8712_WMAC_ + 0x37) -#define TXOP_STALL_CTRL (RTL8712_WMAC_ + 0x38) - -#endif /*__RTL8712_WMAC_REGDEF_H__*/ - diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c deleted file mode 100644 index 4cb01f590673..000000000000 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ /dev/null @@ -1,744 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl8712_xmit.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL8712_XMIT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wifi.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -static void dump_xframe(struct _adapter *padapter, - struct xmit_frame *pxmitframe); -static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz); - -sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag) -{ - phw_txqueue->ac_tag = ac_tag; - switch (ac_tag) { - case BE_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ; - break; - case BK_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_BKQ; - break; - case VI_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_VIQ; - break; - case VO_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_VOQ; - break; - case BMC_QUEUE_INX: - phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ; - break; - } - return _SUCCESS; -} - -int r8712_txframes_sta_ac_pending(struct _adapter *padapter, - struct pkt_attrib *pattrib) -{ - struct sta_info *psta; - struct tx_servq *ptxservq; - int priority = pattrib->priority; - - psta = pattrib->psta; - switch (priority) { - case 1: - case 2: - ptxservq = &psta->sta_xmitpriv.bk_q; - break; - case 4: - case 5: - ptxservq = &psta->sta_xmitpriv.vi_q; - break; - case 6: - case 7: - ptxservq = &psta->sta_xmitpriv.vo_q; - break; - case 0: - case 3: - default: - ptxservq = &psta->sta_xmitpriv.be_q; - break; - } - return ptxservq->qcnt; -} - -static u32 get_ff_hwaddr(struct xmit_frame *pxmitframe) -{ - u32 addr = 0; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct _adapter *padapter = pxmitframe->padapter; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - - if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { - addr = RTL8712_DMA_H2CCMD; - } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { - addr = RTL8712_DMA_MGTQ; - } else if (pdvobj->nr_endpoint == 6) { - switch (pattrib->priority) { - case 0: - case 3: - addr = RTL8712_DMA_BEQ; - break; - case 1: - case 2: - addr = RTL8712_DMA_BKQ; - break; - case 4: - case 5: - addr = RTL8712_DMA_VIQ; - break; - case 6: - case 7: - addr = RTL8712_DMA_VOQ; - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13: - addr = RTL8712_DMA_H2CCMD; - break; - default: - addr = RTL8712_DMA_BEQ; - break; - } - } else if (pdvobj->nr_endpoint == 4) { - switch (pattrib->qsel) { - case 0: - case 3: - case 1: - case 2: - addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/ - break; - case 4: - case 5: - case 6: - case 7: - addr = RTL8712_DMA_VOQ;/*RTL8712_EP_HI;*/ - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13: - addr = RTL8712_DMA_H2CCMD; - break; - default: - addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/ - break; - } - } - return addr; -} - -static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, - struct hw_xmit *phwxmit, - struct tx_servq *ptxservq, - struct __queue *pframe_queue) -{ - struct list_head *xmitframe_plist, *xmitframe_phead; - struct xmit_frame *pxmitframe = NULL; - - xmitframe_phead = &pframe_queue->queue; - xmitframe_plist = xmitframe_phead->next; - if (!end_of_queue_search(xmitframe_phead, xmitframe_plist)) { - pxmitframe = container_of(xmitframe_plist, - struct xmit_frame, list); - list_del_init(&pxmitframe->list); - ptxservq->qcnt--; - phwxmit->txcmdcnt++; - } - return pxmitframe; -} - -static struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv, - struct hw_xmit *phwxmit_i, sint entry) -{ - unsigned long irqL0; - struct list_head *sta_plist, *sta_phead; - struct hw_xmit *phwxmit; - struct tx_servq *ptxservq = NULL; - struct __queue *pframe_queue = NULL; - struct xmit_frame *pxmitframe = NULL; - int i, inx[4]; - int j, acirp_cnt[4]; - - /*entry indx: 0->vo, 1->vi, 2->be, 3->bk.*/ - inx[0] = 0; acirp_cnt[0] = pxmitpriv->voq_cnt; - inx[1] = 1; acirp_cnt[1] = pxmitpriv->viq_cnt; - inx[2] = 2; acirp_cnt[2] = pxmitpriv->beq_cnt; - inx[3] = 3; acirp_cnt[3] = pxmitpriv->bkq_cnt; - for (i = 0; i < 4; i++) { - for (j = i + 1; j < 4; j++) { - if (acirp_cnt[j] < acirp_cnt[i]) { - swap(acirp_cnt[i], acirp_cnt[j]); - swap(inx[i], inx[j]); - } - } - } - spin_lock_irqsave(&pxmitpriv->lock, irqL0); - for (i = 0; i < entry; i++) { - phwxmit = phwxmit_i + inx[i]; - sta_phead = &phwxmit->sta_queue->queue; - sta_plist = sta_phead->next; - while (!end_of_queue_search(sta_phead, sta_plist)) { - ptxservq = container_of(sta_plist, struct tx_servq, - tx_pending); - pframe_queue = &ptxservq->sta_pending; - pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, - ptxservq, pframe_queue); - if (pxmitframe) { - phwxmit->accnt--; - goto exit_dequeue_xframe_ex; - } - sta_plist = sta_plist->next; - /*Remove sta node when there are no pending packets.*/ - if (list_empty(&pframe_queue->queue)) { - /* must be done after sta_plist->next - * and before break - */ - list_del_init(&ptxservq->tx_pending); - } - } - } -exit_dequeue_xframe_ex: - spin_unlock_irqrestore(&pxmitpriv->lock, irqL0); - return pxmitframe; -} - -void r8712_do_queue_select(struct _adapter *padapter, - struct pkt_attrib *pattrib) -{ - unsigned int qsel = 0; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - - if (pdvobj->nr_endpoint == 6) { - qsel = (unsigned int)pattrib->priority; - } else if (pdvobj->nr_endpoint == 4) { - qsel = (unsigned int)pattrib->priority; - if (qsel == 0 || qsel == 3) - qsel = 3; - else if (qsel == 1 || qsel == 2) - qsel = 1; - else if (qsel == 4 || qsel == 5) - qsel = 5; - else if (qsel == 6 || qsel == 7) - qsel = 7; - else - qsel = 3; - } - pattrib->qsel = qsel; -} - -#ifdef CONFIG_R8712_TX_AGGR -void r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf) -{ - struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf; - - /* Fill up TxCmd Descriptor according as USB FW Tx Aaggregation info.*/ - /* dw0 */ - ptx_desc->txdw0 = cpu_to_le32(CMD_HDR_SZ & 0xffff); - ptx_desc->txdw0 |= - cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & - 0x00ff0000); - ptx_desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); - - /* dw1 */ - ptx_desc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) & 0x00001f00); -} - -void r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf) -{ - struct xmit_frame *pxmitframe = (struct xmit_frame *) - pxmitbuf->priv_data; - struct _adapter *padapter = pxmitframe->padapter; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *) - (pxmitbuf->pbuf + TXDESC_SIZE); - - /* Fill up Cmd Header for USB FW Tx Aggregation.*/ - /* dw0 */ - pcmd_hdr->cmd_dw0 = cpu_to_le32((GEN_CMD_CODE(_AMSDU_TO_AMPDU) << 16) | - (pcmdpriv->cmd_seq << 24)); - pcmdpriv->cmd_seq++; -} - -void r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - struct _adapter *padapter = pxmitframe->padapter; - struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf; - int last_txcmdsz = 0; - int padding_sz = 0; - - /* 802.3->802.11 converter */ - r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); - /* free skb struct */ - r8712_xmit_complete(padapter, pxmitframe); - if (pxmitframe->attrib.ether_type != 0x0806) { - if ((pxmitframe->attrib.ether_type != 0x888e) && - (pxmitframe->attrib.dhcp_pkt != 1)) { - r8712_issue_addbareq_cmd(padapter, - pxmitframe->attrib.priority); - } - } - pxmitframe->last[0] = 1; - update_txdesc(pxmitframe, (uint *)(pxmitframe->buf_addr), - pxmitframe->attrib.last_txcmdsz); - /*padding zero */ - last_txcmdsz = pxmitframe->attrib.last_txcmdsz; - padding_sz = (8 - (last_txcmdsz % 8)); - if ((last_txcmdsz % 8) != 0) { - int i; - - for (i = 0; i < padding_sz; i++) - *(pxmitframe->buf_addr + TXDESC_SIZE + last_txcmdsz + - i) = 0; - } - /* Add the new mpdu's length */ - ptx_desc->txdw0 = cpu_to_le32((ptx_desc->txdw0 & 0xffff0000) | - ((ptx_desc->txdw0 & 0x0000ffff) + - ((TXDESC_SIZE + last_txcmdsz + padding_sz) & - 0x0000ffff))); -} - -void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - /* linux complete context doesn't need to protect */ - pxmitframe->pxmitbuf = pxmitbuf; - pxmitbuf->priv_data = pxmitframe; - pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0]; - /* buffer addr assoc */ - pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE + CMD_HDR_SZ; - /*RTL8712_DMA_H2CCMD */ - r8712_construct_txaggr_cmd_desc(pxmitbuf); - r8712_construct_txaggr_cmd_hdr(pxmitbuf); - r8712_append_mpdu_unit(pxmitbuf, pxmitframe); - pxmitbuf->aggr_nr = 1; -} - -u16 r8712_xmitframe_aggr_next(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - pxmitframe->pxmitbuf = pxmitbuf; - pxmitbuf->priv_data = pxmitframe; - pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0]; - /* buffer addr assoc */ - pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE + - (((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff); - r8712_append_mpdu_unit(pxmitbuf, pxmitframe); - r8712_free_xmitframe_ex(&pxmitframe->padapter->xmitpriv, - pxmitframe); - pxmitbuf->aggr_nr++; - - return TXDESC_SIZE + - (((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff); -} - -void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe) -{ - struct _adapter *padapter = pxmitframe->padapter; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - struct tx_desc *ptxdesc = pxmitbuf->pbuf; - struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *) - (pxmitbuf->pbuf + TXDESC_SIZE); - u16 total_length = (u16)(ptxdesc->txdw0 & 0xffff); - - /* use 1st xmitframe as media */ - xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf); - pcmd_hdr->cmd_dw0 = cpu_to_le32(((total_length - CMD_HDR_SZ) & - 0x0000ffff) | (pcmd_hdr->cmd_dw0 & - 0xffff0000)); - - /* urb length in cmd_dw1 */ - pcmd_hdr->cmd_dw1 = cpu_to_le32((pxmitbuf->aggr_nr & 0xff) | - ((total_length + TXDESC_SIZE) << 16)); - pxmitframe->last[0] = 1; - pxmitframe->bpending[0] = false; - pxmitframe->mem_addr = pxmitbuf->pbuf; - - if ((pdvobj->ishighspeed && ((total_length + TXDESC_SIZE) % 0x200) == - 0) || ((!pdvobj->ishighspeed && ((total_length + TXDESC_SIZE) % - 0x40) == 0))) { - ptxdesc->txdw0 |= cpu_to_le32 - (((TXDESC_SIZE + OFFSET_SZ + 8) << OFFSET_SHT) & - 0x00ff0000); - /*32 bytes for TX Desc + 8 bytes pending*/ - } else { - ptxdesc->txdw0 |= cpu_to_le32 - (((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & - 0x00ff0000); - /*default = 32 bytes for TX Desc*/ - } - r8712_write_port(pxmitframe->padapter, RTL8712_DMA_H2CCMD, - total_length + TXDESC_SIZE, (u8 *)pxmitframe); -} - -#endif - -static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz) -{ - uint qsel; - struct _adapter *padapter = pxmitframe->padapter; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct tx_desc *ptxdesc = (struct tx_desc *)pmem; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; -#ifdef CONFIG_R8712_TX_AGGR - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; -#endif - u8 blnSetTxDescOffset; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - struct tx_desc txdesc_mp; - - memcpy(&txdesc_mp, ptxdesc, sizeof(struct tx_desc)); - memset(ptxdesc, 0, sizeof(struct tx_desc)); - /* offset 0 */ - ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff); - if (pdvobj->ishighspeed) { - if (((sz + TXDESC_SIZE) % 512) == 0) - blnSetTxDescOffset = 1; - else - blnSetTxDescOffset = 0; - } else { - if (((sz + TXDESC_SIZE) % 64) == 0) - blnSetTxDescOffset = 1; - else - blnSetTxDescOffset = 0; - } - if (blnSetTxDescOffset) { - /* 32 bytes for TX Desc + 8 bytes pending */ - ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ + 8) << - OFFSET_SHT) & 0x00ff0000); - } else { - /* default = 32 bytes for TX Desc */ - ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << - OFFSET_SHT) & 0x00ff0000); - } - ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); - if (pxmitframe->frame_tag == DATA_FRAMETAG) { - /* offset 4 */ - ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x1f); - -#ifdef CONFIG_R8712_TX_AGGR - /* dirty workaround, need to check if it is aggr cmd. */ - if ((u8 *)pmem != (u8 *)pxmitframe->pxmitbuf->pbuf) { - ptxdesc->txdw0 |= cpu_to_le32 - ((0x3 << TYPE_SHT) & TYPE_MSK); - qsel = (uint)(pattrib->qsel & 0x0000001f); - if (qsel == 2) - qsel = 0; - ptxdesc->txdw1 |= cpu_to_le32 - ((qsel << QSEL_SHT) & 0x00001f00); - ptxdesc->txdw2 = cpu_to_le32 - ((qsel << RTS_RC_SHT) & 0x001f0000); - ptxdesc->txdw6 |= cpu_to_le32 - ((0x5 << RSVD6_SHT) & RSVD6_MSK); - } else { - ptxdesc->txdw0 |= cpu_to_le32 - ((0x3 << TYPE_SHT) & TYPE_MSK); - ptxdesc->txdw1 |= cpu_to_le32 - ((0x13 << QSEL_SHT) & 0x00001f00); - qsel = (uint)(pattrib->qsel & 0x0000001f); - if (qsel == 2) - qsel = 0; - ptxdesc->txdw2 = cpu_to_le32 - ((qsel << RTS_RC_SHT) & 0x0001f000); - ptxdesc->txdw7 |= cpu_to_le32 - (pcmdpriv->cmd_seq << 24); - pcmdpriv->cmd_seq++; - } - pattrib->qsel = 0x13; -#else - qsel = (uint)(pattrib->qsel & 0x0000001f); - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); -#endif - if (!pqospriv->qos_option) - ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/*Non-QoS*/ - if ((pattrib->encrypt > 0) && !pattrib->bswenc) { - switch (pattrib->encrypt) { /*SEC_TYPE*/ - case _WEP40_: - case _WEP104_: - ptxdesc->txdw1 |= cpu_to_le32((0x01 << 22) & - 0x00c00000); - /*KEY_ID when WEP is used;*/ - ptxdesc->txdw1 |= - cpu_to_le32((psecuritypriv->PrivacyKeyIndex << 17) & - 0x00060000); - break; - case _TKIP_: - case _TKIP_WTMIC_: - ptxdesc->txdw1 |= cpu_to_le32((0x02 << 22) & - 0x00c00000); - break; - case _AES_: - ptxdesc->txdw1 |= cpu_to_le32((0x03 << 22) & - 0x00c00000); - break; - case _NO_PRIVACY_: - default: - break; - } - } - /*offset 8*/ - if (bmcst) - ptxdesc->txdw2 |= cpu_to_le32(BMC); - - /*offset 12*/ - /* f/w will increase the seqnum by itself, driver pass the - * correct priority to fw. - * fw will check the correct priority for increasing the - * seqnum per tid. about usb using 4-endpoint, qsel points out - * the correct mapping between AC&Endpoint, - * the purpose is that correct mapping lets the MAC release - * the AC Queue list correctly. - */ - ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) & - 0x0fff0000); - if ((pattrib->ether_type != 0x888e) && - (pattrib->ether_type != 0x0806) && - (pattrib->dhcp_pkt != 1)) { - /*Not EAP & ARP type data packet*/ - if (phtpriv->ht_option == 1) { /*B/G/N Mode*/ - if (!phtpriv->ampdu_enable) - ptxdesc->txdw2 |= cpu_to_le32(BK); - } - } else { - /* EAP data packet and ARP packet. - * Use the 1M data rate to send the EAP/ARP packet. - * This will maybe make the handshake smooth. - */ - /*driver uses data rate*/ - ptxdesc->txdw4 = cpu_to_le32(0x80000000); - ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/*1M*/ - } - if (pattrib->pctrl == 1) { /* mp tx packets */ - struct tx_desc *ptxdesc_mp; - - ptxdesc_mp = &txdesc_mp; - /* offset 8 */ - ptxdesc->txdw2 = ptxdesc_mp->txdw2; - if (bmcst) - ptxdesc->txdw2 |= cpu_to_le32(BMC); - ptxdesc->txdw2 |= cpu_to_le32(BK); - /* offset 16 */ - ptxdesc->txdw4 = ptxdesc_mp->txdw4; - /* offset 20 */ - ptxdesc->txdw5 = ptxdesc_mp->txdw5; - pattrib->pctrl = 0;/* reset to zero; */ - } - } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { - /* offset 4 */ - /* CAM_ID(MAC_ID), default=5; */ - ptxdesc->txdw1 |= cpu_to_le32((0x05) & 0x1f); - qsel = (uint)(pattrib->qsel & 0x0000001f); - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); - ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/* Non-QoS */ - /* offset 8 */ - if (bmcst) - ptxdesc->txdw2 |= cpu_to_le32(BMC); - /* offset 12 */ - /* f/w will increase the seqnum by itself, driver pass the - * correct priority to fw. - * fw will check the correct priority for increasing the seqnum - * per tid. about usb using 4-endpoint, qsel points out the - * correct mapping between AC&Endpoint, - * the purpose is that correct mapping let the MAC releases - * the AC Queue list correctly. - */ - ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) & - 0x0fff0000); - /* offset 16 */ - ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/ - /* offset 20 */ - ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/* gtest 1M */ - } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { - /* offset 4 */ - qsel = 0x13; - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); - } else { - /* offset 4 */ - qsel = (uint)(pattrib->priority & 0x0000001f); - ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); - /*offset 8*/ - /*offset 12*/ - ptxdesc->txdw3 = cpu_to_le32((pattrib->seqnum << SEQ_SHT) & - 0x0fff0000); - /*offset 16*/ - ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/ - /*offset 20*/ - ptxdesc->txdw5 = cpu_to_le32(0x001f9600);/*gtest*/ - } -} - -int r8712_xmitframe_complete(struct _adapter *padapter, - struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf) -{ - struct hw_xmit *phwxmits; - sint hwentry; - struct xmit_frame *pxmitframe = NULL; -#ifdef CONFIG_R8712_TX_AGGR - struct xmit_frame *p2ndxmitframe = NULL; -#else - int res = _SUCCESS; -#endif - - phwxmits = pxmitpriv->hwxmits; - hwentry = pxmitpriv->hwxmit_entry; - if (!pxmitbuf) { - pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv); - if (!pxmitbuf) - return false; -#ifdef CONFIG_R8712_TX_AGGR - pxmitbuf->aggr_nr = 0; -#endif - } - /* 1st frame dequeued */ - pxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry); - /* need to remember the 1st frame */ - if (pxmitframe) { - -#ifdef CONFIG_R8712_TX_AGGR - /* 1. dequeue 2nd frame - * 2. aggr if 2nd xframe is dequeued, else dump directly - */ - if (AGGR_NR_HIGH_BOUND > 1) - p2ndxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, - hwentry); - if (pxmitframe->frame_tag != DATA_FRAMETAG) { - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } - if (p2ndxmitframe) - if (p2ndxmitframe->frame_tag != DATA_FRAMETAG) { - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } - r8712_xmitframe_aggr_1st(pxmitbuf, pxmitframe); - if (p2ndxmitframe) { - u16 total_length; - - total_length = r8712_xmitframe_aggr_next( - pxmitbuf, p2ndxmitframe); - do { - p2ndxmitframe = dequeue_xframe_ex( - pxmitpriv, phwxmits, hwentry); - if (p2ndxmitframe) - total_length = - r8712_xmitframe_aggr_next( - pxmitbuf, - p2ndxmitframe); - else - break; - } while (total_length <= 0x1800 && - pxmitbuf->aggr_nr <= AGGR_NR_HIGH_BOUND); - } - if (pxmitbuf->aggr_nr > 0) - r8712_dump_aggr_xframe(pxmitbuf, pxmitframe); - -#else - - xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf); - if (pxmitframe->frame_tag == DATA_FRAMETAG) { - if (pxmitframe->attrib.priority <= 15) - res = r8712_xmitframe_coalesce(padapter, - pxmitframe->pkt, pxmitframe); - /* always return ndis_packet after - * r8712_xmitframe_coalesce - */ - r8712_xmit_complete(padapter, pxmitframe); - } - if (res == _SUCCESS) - dump_xframe(padapter, pxmitframe); - else - r8712_free_xmitframe_ex(pxmitpriv, pxmitframe); -#endif - - } else { /* pxmitframe == NULL && p2ndxmitframe == NULL */ - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - return false; - } - return true; -} - -static void dump_xframe(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - int t, sz, w_sz; - u8 *mem_addr; - u32 ff_hwaddr; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - if (pxmitframe->attrib.ether_type != 0x0806) { - if (pxmitframe->attrib.ether_type != 0x888e) - r8712_issue_addbareq_cmd(padapter, pattrib->priority); - } - mem_addr = pxmitframe->buf_addr; - for (t = 0; t < pattrib->nr_frags; t++) { - if (t != (pattrib->nr_frags - 1)) { - sz = pxmitpriv->frag_len; - sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : - pattrib->icv_len); - pxmitframe->last[t] = 0; - } else { - sz = pattrib->last_txcmdsz; - pxmitframe->last[t] = 1; - } - update_txdesc(pxmitframe, (uint *)mem_addr, sz); - w_sz = sz + TXDESC_SIZE; - pxmitframe->mem_addr = mem_addr; - pxmitframe->bpending[t] = false; - ff_hwaddr = get_ff_hwaddr(pxmitframe); -#ifdef CONFIG_R8712_TX_AGGR - r8712_write_port(padapter, RTL8712_DMA_H2CCMD, w_sz, - (unsigned char *)pxmitframe); -#else - r8712_write_port(padapter, ff_hwaddr, w_sz, - (unsigned char *)pxmitframe); -#endif - mem_addr += w_sz; - mem_addr = (u8 *)RND4(((addr_t)(mem_addr))); - } -} - -void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe) -{ - int res; - - res = r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); - pxmitframe->pkt = NULL; - if (res == _SUCCESS) - dump_xframe(padapter, pxmitframe); -} - -int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe) -{ - if (r8712_xmit_classifier(padapter, pxmitframe)) { - pxmitframe->pkt = NULL; - return _FAIL; - } - return _SUCCESS; -} diff --git a/drivers/staging/rtl8712/rtl8712_xmit.h b/drivers/staging/rtl8712/rtl8712_xmit.h deleted file mode 100644 index 5cd651a0de75..000000000000 --- a/drivers/staging/rtl8712/rtl8712_xmit.h +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL8712_XMIT_H_ -#define _RTL8712_XMIT_H_ - -#define HWXMIT_ENTRY 4 - -#define VO_QUEUE_INX 0 -#define VI_QUEUE_INX 1 -#define BE_QUEUE_INX 2 -#define BK_QUEUE_INX 3 -#define TS_QUEUE_INX 4 -#define MGT_QUEUE_INX 5 -#define BMC_QUEUE_INX 6 -#define BCN_QUEUE_INX 7 - -#define HW_QUEUE_ENTRY 8 - -#define TXDESC_SIZE 32 -#define TXDESC_OFFSET TXDESC_SIZE - -#define NR_AMSDU_XMITFRAME 8 -#define NR_TXAGG_XMITFRAME 8 - -#define MAX_AMSDU_XMITBUF_SZ 8704 -#define MAX_TXAGG_XMITBUF_SZ 16384 /*16k*/ - -#define tx_cmd tx_desc - -/* - *defined for TX DESC Operation - */ - -#define MAX_TID (15) - -/*OFFSET 0*/ -#define OFFSET_SZ (0) -#define OFFSET_SHT (16) -#define OWN BIT(31) -#define FSG BIT(27) -#define LSG BIT(26) -#define TYPE_SHT (24) -#define TYPE_MSK (0x03000000) - -/*OFFSET 4*/ -#define PKT_OFFSET_SZ (0) -#define QSEL_SHT (8) -#define HWPC BIT(31) - -/*OFFSET 8*/ -#define BMC BIT(7) -#define BK BIT(30) -#define AGG_EN BIT(29) -#define RTS_RC_SHT (16) - -/*OFFSET 12*/ -#define SEQ_SHT (16) - -/*OFFSET 16*/ -#define TXBW BIT(18) - -/*OFFSET 20*/ -#define DISFB BIT(15) -#define RSVD6_MSK (0x00E00000) -#define RSVD6_SHT (21) - -struct tx_desc { - /*DWORD 0*/ - __le32 txdw0; - __le32 txdw1; - __le32 txdw2; - __le32 txdw3; - __le32 txdw4; - __le32 txdw5; - __le32 txdw6; - __le32 txdw7; -}; - -union txdesc { - struct tx_desc txdesc; - unsigned int value[TXDESC_SIZE >> 2]; -}; - -int r8712_xmitframe_complete(struct _adapter *padapter, - struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf); -void r8712_do_queue_select(struct _adapter *padapter, - struct pkt_attrib *pattrib); - -#ifdef CONFIG_R8712_TX_AGGR -void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe); -void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf, - struct xmit_frame *pxmitframe); -#endif - -#endif diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c deleted file mode 100644 index 4be96df5a329..000000000000 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ /dev/null @@ -1,796 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_cmd.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_CMD_C_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" - -/* - * Caller and the r8712_cmd_thread can protect cmd_q by spin_lock. - * No irqsave is necessary. - */ - -int r8712_init_cmd_priv(struct cmd_priv *pcmdpriv) -{ - init_completion(&pcmdpriv->cmd_queue_comp); - init_completion(&pcmdpriv->terminate_cmdthread_comp); - - _init_queue(&(pcmdpriv->cmd_queue)); - - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - pcmdpriv->cmd_seq = 1; - pcmdpriv->cmd_allocated_buf = kmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, - GFP_ATOMIC); - if (!pcmdpriv->cmd_allocated_buf) - return -ENOMEM; - pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - - ((addr_t)(pcmdpriv->cmd_allocated_buf) & - (CMDBUFF_ALIGN_SZ - 1)); - pcmdpriv->rsp_allocated_buf = kmalloc(MAX_RSPSZ + 4, GFP_ATOMIC); - if (!pcmdpriv->rsp_allocated_buf) { - kfree(pcmdpriv->cmd_allocated_buf); - pcmdpriv->cmd_allocated_buf = NULL; - return -ENOMEM; - } - pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - - ((addr_t)(pcmdpriv->rsp_allocated_buf) & 3); - pcmdpriv->cmd_issued_cnt = 0; - pcmdpriv->cmd_done_cnt = 0; - pcmdpriv->rsp_cnt = 0; - return 0; -} - -int r8712_init_evt_priv(struct evt_priv *pevtpriv) -{ - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - pevtpriv->event_seq = 0; - pevtpriv->evt_allocated_buf = kmalloc(MAX_EVTSZ + 4, GFP_ATOMIC); - - if (!pevtpriv->evt_allocated_buf) - return -ENOMEM; - pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 - - ((addr_t)(pevtpriv->evt_allocated_buf) & 3); - pevtpriv->evt_done_cnt = 0; - return 0; -} - -void r8712_free_evt_priv(struct evt_priv *pevtpriv) -{ - kfree(pevtpriv->evt_allocated_buf); -} - -void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv) -{ - if (pcmdpriv) { - kfree(pcmdpriv->cmd_allocated_buf); - kfree(pcmdpriv->rsp_allocated_buf); - } -} - -/* - * Calling Context: - * - * r8712_enqueue_cmd can only be called between kernel thread, - * since only spin_lock is used. - * - * ISR/Call-Back functions can't call this sub-function. - * - */ - -void r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj) -{ - struct __queue *queue; - unsigned long irqL; - - if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag) - return; - if (!obj) - return; - queue = &pcmdpriv->cmd_queue; - spin_lock_irqsave(&queue->lock, irqL); - list_add_tail(&obj->list, &queue->queue); - spin_unlock_irqrestore(&queue->lock, irqL); - complete(&pcmdpriv->cmd_queue_comp); -} - -struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue) -{ - unsigned long irqL; - struct cmd_obj *obj; - - spin_lock_irqsave(&queue->lock, irqL); - obj = list_first_entry_or_null(&queue->queue, - struct cmd_obj, list); - if (obj) - list_del_init(&obj->list); - spin_unlock_irqrestore(&queue->lock, irqL); - return obj; -} - -void r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj) -{ - unsigned long irqL; - struct __queue *queue; - - if (!obj) - return; - if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag) - return; - queue = &pcmdpriv->cmd_queue; - spin_lock_irqsave(&queue->lock, irqL); - list_add_tail(&obj->list, &queue->queue); - spin_unlock_irqrestore(&queue->lock, irqL); - complete(&pcmdpriv->cmd_queue_comp); -} - -void r8712_free_cmd_obj(struct cmd_obj *pcmd) -{ - if ((pcmd->cmdcode != _JoinBss_CMD_) && - (pcmd->cmdcode != _CreateBss_CMD_)) - kfree(pcmd->parmbuf); - if (pcmd->rsp) { - if (pcmd->rspsz != 0) - kfree(pcmd->rsp); - } - kfree(pcmd); -} - -u8 r8712_sitesurvey_cmd(struct _adapter *padapter, - struct ndis_802_11_ssid *pssid) - __must_hold(&padapter->mlmepriv.lock) -{ - struct cmd_obj *ph2c; - struct sitesurvey_parm *psurveyPara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return _FAIL; - psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC); - if (!psurveyPara) { - kfree(ph2c); - return _FAIL; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, - GEN_CMD_CODE(_SiteSurvey)); - psurveyPara->bsslimit = cpu_to_le32(48); - psurveyPara->passive_mode = cpu_to_le32(pmlmepriv->passive_mode); - psurveyPara->ss_ssidlen = 0; - memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1); - if (pssid && pssid->SsidLength) { - int len = min_t(int, pssid->SsidLength, IW_ESSID_MAX_SIZE); - - memcpy(psurveyPara->ss_ssid, pssid->Ssid, len); - psurveyPara->ss_ssidlen = cpu_to_le32(len); - } - set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); - r8712_enqueue_cmd(pcmdpriv, ph2c); - mod_timer(&pmlmepriv->scan_to_timer, - jiffies + msecs_to_jiffies(SCANNING_TIMEOUT)); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_SITE_SURVEY); - complete(&padapter->rx_filter_ready); - return _SUCCESS; -} - -int r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset) -{ - struct cmd_obj *ph2c; - struct setdatarate_parm *pbsetdataratepara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); - if (!pbsetdataratepara) { - kfree(ph2c); - return -ENOMEM; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, - GEN_CMD_CODE(_SetDataRate)); - pbsetdataratepara->mac_id = 5; - memcpy(pbsetdataratepara->datarates, rateset, NumRates); - r8712_enqueue_cmd(pcmdpriv, ph2c); - return 0; -} - -void r8712_set_chplan_cmd(struct _adapter *padapter, int chplan) -{ - struct cmd_obj *ph2c; - struct SetChannelPlan_param *psetchplanpara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC); - if (!psetchplanpara) { - kfree(ph2c); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara, - GEN_CMD_CODE(_SetChannelPlan)); - psetchplanpara->ChannelPlan = chplan; - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -int r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val) -{ - struct cmd_obj *ph2c; - struct writeRF_parm *pwriterfparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC); - if (!pwriterfparm) { - kfree(ph2c); - return -ENOMEM; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); - pwriterfparm->offset = offset; - pwriterfparm->value = val; - r8712_enqueue_cmd(pcmdpriv, ph2c); - return 0; -} - -int r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval) -{ - struct cmd_obj *ph2c; - struct readRF_parm *prdrfparm; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC); - if (!prdrfparm) { - kfree(ph2c); - return -ENOMEM; - } - INIT_LIST_HEAD(&ph2c->list); - ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg); - ph2c->parmbuf = (unsigned char *)prdrfparm; - ph2c->cmdsz = sizeof(struct readRF_parm); - ph2c->rsp = pval; - ph2c->rspsz = sizeof(struct readRF_rsp); - prdrfparm->offset = offset; - r8712_enqueue_cmd(pcmdpriv, ph2c); - return 0; -} - -void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - kfree(pcmd->parmbuf); - kfree(pcmd); - padapter->mppriv.workparam.bcompleted = true; -} - -void r8712_readtssi_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - kfree(pcmd->parmbuf); - kfree(pcmd); - - padapter->mppriv.workparam.bcompleted = true; -} - -int r8712_createbss_cmd(struct _adapter *padapter) -{ - struct cmd_obj *pcmd; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct wlan_bssid_ex *pdev_network = - &padapter->registrypriv.dev_network; - - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - INIT_LIST_HEAD(&pcmd->list); - pcmd->cmdcode = _CreateBss_CMD_; - pcmd->parmbuf = (unsigned char *)pdev_network; - pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(pdev_network); - pcmd->rsp = NULL; - pcmd->rspsz = 0; - /* notes: translate IELength & Length after assign to cmdsz; */ - pdev_network->Length = pcmd->cmdsz; - pdev_network->IELength = pdev_network->IELength; - pdev_network->Ssid.SsidLength = pdev_network->Ssid.SsidLength; - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; -} - -int r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) -{ - struct wlan_bssid_ex *psecnetwork; - struct cmd_obj *pcmd; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct registry_priv *pregistrypriv = &padapter->registrypriv; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = - pnetwork->network.InfrastructureMode; - - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - - /* for hidden ap to set fw_state here */ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) != - true) { - switch (ndis_network_mode) { - case Ndis802_11IBSS: - pmlmepriv->fw_state |= WIFI_ADHOC_STATE; - break; - case Ndis802_11Infrastructure: - pmlmepriv->fw_state |= WIFI_STATION_STATE; - break; - case Ndis802_11APMode: - case Ndis802_11AutoUnknown: - case Ndis802_11InfrastructureMax: - break; - } - } - psecnetwork = &psecuritypriv->sec_bss; - memcpy(psecnetwork, &pnetwork->network, sizeof(*psecnetwork)); - psecuritypriv->authenticator_ie[0] = (unsigned char) - psecnetwork->IELength; - if ((psecnetwork->IELength - 12) < (256 - 1)) - memcpy(&psecuritypriv->authenticator_ie[1], - &psecnetwork->IEs[12], psecnetwork->IELength - 12); - else - memcpy(&psecuritypriv->authenticator_ie[1], - &psecnetwork->IEs[12], (256 - 1)); - psecnetwork->IELength = 0; - /* - * If the driver wants to use the bssid to create the connection. - * If not, we copy the connecting AP's MAC address to it so that - * the driver just has the bssid information for PMKIDList searching. - */ - if (!pmlmepriv->assoc_by_bssid) - ether_addr_copy(&pmlmepriv->assoc_bssid[0], - &pnetwork->network.MacAddress[0]); - psecnetwork->IELength = r8712_restruct_sec_ie(padapter, - &pnetwork->network.IEs[0], - &psecnetwork->IEs[0], - pnetwork->network.IELength); - pqospriv->qos_option = 0; - if (pregistrypriv->wmm_enable) { - u32 tmp_len; - - tmp_len = r8712_restruct_wmm_ie(padapter, - &pnetwork->network.IEs[0], - &psecnetwork->IEs[0], - pnetwork->network.IELength, - psecnetwork->IELength); - if (psecnetwork->IELength != tmp_len) { - psecnetwork->IELength = tmp_len; - pqospriv->qos_option = 1; /* WMM IE in beacon */ - } else { - pqospriv->qos_option = 0; /* no WMM IE in beacon */ - } - } - if (pregistrypriv->ht_enable) { - /* - * For WEP mode, we will use the bg mode to do the connection - * to avoid some IOT issues, especially for Realtek 8192u - * SoftAP. - */ - if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_) && - (padapter->securitypriv.PrivacyAlgrthm != _WEP104_)) { - /* restructure_ht_ie */ - r8712_restructure_ht_ie(padapter, - &pnetwork->network.IEs[0], - &psecnetwork->IEs[0], - pnetwork->network.IELength, - &psecnetwork->IELength); - } - } - psecuritypriv->supplicant_ie[0] = (u8)psecnetwork->IELength; - if (psecnetwork->IELength < 255) - memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], - psecnetwork->IELength); - else - memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], - 255); - /* get cmdsz before endian conversion */ - pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(psecnetwork); -#ifdef __BIG_ENDIAN - /* wlan_network endian conversion */ - psecnetwork->Length = cpu_to_le32(psecnetwork->Length); - psecnetwork->Ssid.SsidLength = cpu_to_le32( - psecnetwork->Ssid.SsidLength); - psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy); - psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi); - psecnetwork->NetworkTypeInUse = cpu_to_le32( - psecnetwork->NetworkTypeInUse); - psecnetwork->Configuration.ATIMWindow = cpu_to_le32( - psecnetwork->Configuration.ATIMWindow); - psecnetwork->Configuration.BeaconPeriod = cpu_to_le32( - psecnetwork->Configuration.BeaconPeriod); - psecnetwork->Configuration.DSConfig = cpu_to_le32( - psecnetwork->Configuration.DSConfig); - psecnetwork->Configuration.FHConfig.DwellTime = cpu_to_le32( - psecnetwork->Configuration.FHConfig.DwellTime); - psecnetwork->Configuration.FHConfig.HopPattern = cpu_to_le32( - psecnetwork->Configuration.FHConfig.HopPattern); - psecnetwork->Configuration.FHConfig.HopSet = cpu_to_le32( - psecnetwork->Configuration.FHConfig.HopSet); - psecnetwork->Configuration.FHConfig.Length = cpu_to_le32( - psecnetwork->Configuration.FHConfig.Length); - psecnetwork->Configuration.Length = cpu_to_le32( - psecnetwork->Configuration.Length); - psecnetwork->InfrastructureMode = cpu_to_le32( - psecnetwork->InfrastructureMode); - psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength); -#endif - INIT_LIST_HEAD(&pcmd->list); - pcmd->cmdcode = _JoinBss_CMD_; - pcmd->parmbuf = (unsigned char *)psecnetwork; - pcmd->rsp = NULL; - pcmd->rspsz = 0; - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; -} - -void r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */ -{ - struct cmd_obj *pdisconnect_cmd; - struct disconnect_parm *pdisconnect; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - pdisconnect_cmd = kmalloc(sizeof(*pdisconnect_cmd), GFP_ATOMIC); - if (!pdisconnect_cmd) - return; - pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC); - if (!pdisconnect) { - kfree(pdisconnect_cmd); - return; - } - init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect, - _DisConnect_CMD_); - r8712_enqueue_cmd(pcmdpriv, pdisconnect_cmd); -} - -void r8712_setopmode_cmd(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) -{ - struct cmd_obj *ph2c; - struct setopmode_parm *psetop; - - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC); - if (!psetop) { - kfree(ph2c); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); - psetop->mode = (u8)networktype; - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -void r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key) -{ - struct cmd_obj *ph2c; - struct set_stakey_parm *psetstakey_para; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct set_stakey_rsp *psetstakey_rsp = NULL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct sta_info *sta = (struct sta_info *)psta; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC); - if (!psetstakey_para) { - kfree(ph2c); - return; - } - psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC); - if (!psetstakey_rsp) { - kfree(ph2c); - kfree(psetstakey_para); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); - ph2c->rsp = (u8 *)psetstakey_rsp; - ph2c->rspsz = sizeof(struct set_stakey_rsp); - ether_addr_copy(psetstakey_para->addr, sta->hwaddr); - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - psetstakey_para->algorithm = (unsigned char) - psecuritypriv->PrivacyAlgrthm; - else - GET_ENCRY_ALGO(psecuritypriv, sta, - psetstakey_para->algorithm, false); - if (unicast_key) - memcpy(&psetstakey_para->key, &sta->x_UncstKey, 16); - else - memcpy(&psetstakey_para->key, - &psecuritypriv->XGrpKey[ - psecuritypriv->XGrpKeyid - 1]. skey, 16); - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -void r8712_setMacAddr_cmd(struct _adapter *padapter, const u8 *mac_addr) -{ - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_obj *ph2c; - struct SetMacAddr_param *psetMacAddr_para; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC); - if (!psetMacAddr_para) { - kfree(ph2c); - return; - } - init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para, - _SetMacAddress_CMD_); - ether_addr_copy(psetMacAddr_para->MacAddr, mac_addr); - r8712_enqueue_cmd(pcmdpriv, ph2c); -} - -void r8712_addbareq_cmd(struct _adapter *padapter, u8 tid) -{ - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - struct cmd_obj *ph2c; - struct addBaReq_parm *paddbareq_parm; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC); - if (!paddbareq_parm) { - kfree(ph2c); - return; - } - paddbareq_parm->tid = tid; - init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, - GEN_CMD_CODE(_AddBAReq)); - r8712_enqueue_cmd_ex(pcmdpriv, ph2c); -} - -void r8712_wdg_wk_cmd(struct _adapter *padapter) -{ - struct cmd_obj *ph2c; - struct drvint_cmd_parm *pdrvintcmd_param; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC); - if (!pdrvintcmd_param) { - kfree(ph2c); - return; - } - pdrvintcmd_param->i_cid = WDG_WK_CID; - pdrvintcmd_param->sz = 0; - pdrvintcmd_param->pbuf = NULL; - init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvintcmd_param, _DRV_INT_CMD_); - r8712_enqueue_cmd_ex(pcmdpriv, ph2c); -} - -void r8712_survey_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (pcmd->res != H2C_SUCCESS) - clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY); - r8712_free_cmd_obj(pcmd); -} - -void r8712_disassoc_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (pcmd->res != H2C_SUCCESS) { - spin_lock_irqsave(&pmlmepriv->lock, irqL); - set_fwstate(pmlmepriv, _FW_LINKED); - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return; - } - r8712_free_cmd_obj(pcmd); -} - -void r8712_joinbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (pcmd->res != H2C_SUCCESS) - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(1)); - r8712_free_cmd_obj(pcmd); -} - -void r8712_createbss_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - unsigned long irqL; - struct sta_info *psta = NULL; - struct wlan_network *pwlan = NULL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; - struct wlan_network *tgt_network = &(pmlmepriv->cur_network); - - if (pcmd->res != H2C_SUCCESS) - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(1)); - del_timer(&pmlmepriv->assoc_timer); -#ifdef __BIG_ENDIAN - /* endian_convert */ - pnetwork->Length = le32_to_cpu(pnetwork->Length); - pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); - pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); - pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); - pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); - pnetwork->Configuration.ATIMWindow = - le32_to_cpu(pnetwork->Configuration.ATIMWindow); - pnetwork->Configuration.DSConfig = - le32_to_cpu(pnetwork->Configuration.DSConfig); - pnetwork->Configuration.FHConfig.DwellTime = - le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); - pnetwork->Configuration.FHConfig.HopPattern = - le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); - pnetwork->Configuration.FHConfig.HopSet = - le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); - pnetwork->Configuration.FHConfig.Length = - le32_to_cpu(pnetwork->Configuration.FHConfig.Length); - pnetwork->Configuration.Length = - le32_to_cpu(pnetwork->Configuration.Length); - pnetwork->InfrastructureMode = - le32_to_cpu(pnetwork->InfrastructureMode); - pnetwork->IELength = le32_to_cpu(pnetwork->IELength); -#endif - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if ((pmlmepriv->fw_state) & WIFI_AP_STATE) { - psta = r8712_get_stainfo(&padapter->stapriv, - pnetwork->MacAddress); - if (!psta) { - psta = r8712_alloc_stainfo(&padapter->stapriv, - pnetwork->MacAddress); - if (!psta) - goto createbss_cmd_fail; - } - r8712_indicate_connect(padapter); - } else { - pwlan = _r8712_alloc_network(pmlmepriv); - if (!pwlan) { - pwlan = r8712_get_oldest_wlan_network( - &pmlmepriv->scanned_queue); - if (!pwlan) - goto createbss_cmd_fail; - pwlan->last_scanned = jiffies; - } else { - list_add_tail(&(pwlan->list), - &pmlmepriv->scanned_queue.queue); - } - pnetwork->Length = r8712_get_wlan_bssid_ex_sz(pnetwork); - memcpy(&(pwlan->network), pnetwork, pnetwork->Length); - pwlan->fixed = true; - memcpy(&tgt_network->network, pnetwork, - (r8712_get_wlan_bssid_ex_sz(pnetwork))); - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= _FW_UNDER_LINKING; - /* - * we will set _FW_LINKED when there is one more sat to - * join us (stassoc_event_callback) - */ - } -createbss_cmd_fail: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - r8712_free_cmd_obj(pcmd); -} - -void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *) - (pcmd->rsp); - struct sta_info *psta = r8712_get_stainfo(pstapriv, - psetstakey_rsp->addr); - - if (!psta) - goto exit; - psta->aid = psta->mac_id = psetstakey_rsp->keyid; /*CAM_ID(CAM_ENTRY)*/ -exit: - r8712_free_cmd_obj(pcmd); -} - -void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd) -{ - unsigned long irqL; - struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct set_assocsta_parm *passocsta_parm = - (struct set_assocsta_parm *)(pcmd->parmbuf); - struct set_assocsta_rsp *passocsta_rsp = - (struct set_assocsta_rsp *) (pcmd->rsp); - struct sta_info *psta = r8712_get_stainfo(pstapriv, - passocsta_parm->addr); - - if (!psta) - return; - psta->aid = psta->mac_id = passocsta_rsp->cam_id; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if ((check_fwstate(pmlmepriv, WIFI_MP_STATE)) && - (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) - pmlmepriv->fw_state ^= _FW_UNDER_LINKING; - set_fwstate(pmlmepriv, _FW_LINKED); - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - r8712_free_cmd_obj(pcmd); -} - -void r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, - u32 tryPktCnt, u32 tryPktInterval, u32 firstStageTO) -{ - struct cmd_obj *ph2c; - struct DisconnectCtrlEx_param *param; - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - - ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - param = kzalloc(sizeof(*param), GFP_ATOMIC); - if (!param) { - kfree(ph2c); - return; - } - - param->EnableDrvCtrl = (unsigned char)enableDrvCtrl; - param->TryPktCnt = (unsigned char)tryPktCnt; - param->TryPktInterval = (unsigned char)tryPktInterval; - param->FirstStageTO = (unsigned int)firstStageTO; - - init_h2fwcmd_w_parm_no_rsp(ph2c, param, - GEN_CMD_CODE(_DisconnectCtrlEx)); - r8712_enqueue_cmd(pcmdpriv, ph2c); -} diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h deleted file mode 100644 index 8453d8de8248..000000000000 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ /dev/null @@ -1,761 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_CMD_H_ -#define __RTL871X_CMD_H_ - -#include "wlan_bssdef.h" -#include "rtl871x_rf.h" -#define C2H_MEM_SZ (16*1024) - -#include "osdep_service.h" -#include "ieee80211.h" - -#define FREE_CMDOBJ_SZ 128 -#define MAX_CMDSZ 512 -#define MAX_RSPSZ 512 -#define MAX_EVTSZ 1024 -#define CMDBUFF_ALIGN_SZ 512 - -struct cmd_obj { - u16 cmdcode; - u8 res; - u8 *parmbuf; - u32 cmdsz; - u8 *rsp; - u32 rspsz; - struct list_head list; -}; - -struct cmd_priv { - struct completion cmd_queue_comp; - struct completion terminate_cmdthread_comp; - struct __queue cmd_queue; - u8 cmd_seq; - u8 *cmd_buf; /*shall be non-paged, and 4 bytes aligned*/ - u8 *cmd_allocated_buf; - u8 *rsp_buf; /*shall be non-paged, and 4 bytes aligned*/ - u8 *rsp_allocated_buf; - u32 cmd_issued_cnt; - u32 cmd_done_cnt; - u32 rsp_cnt; - struct _adapter *padapter; -}; - -struct evt_obj { - u16 evtcode; - u8 res; - u8 *parmbuf; - u32 evtsz; - struct list_head list; -}; - -struct evt_priv { - struct __queue evt_queue; - u8 event_seq; - u8 *evt_buf; /*shall be non-paged, and 4 bytes aligned*/ - u8 *evt_allocated_buf; - u32 evt_done_cnt; -}; - -#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ -do {\ - INIT_LIST_HEAD(&pcmd->list);\ - pcmd->cmdcode = code;\ - pcmd->parmbuf = (u8 *)(pparm);\ - pcmd->cmdsz = sizeof(*pparm);\ - pcmd->rsp = NULL;\ - pcmd->rspsz = 0;\ -} while (0) - -void r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); -void r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); -struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue); -void r8712_free_cmd_obj(struct cmd_obj *pcmd); -int r8712_cmd_thread(void *context); -int r8712_init_cmd_priv(struct cmd_priv *pcmdpriv); -void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv); -int r8712_init_evt_priv(struct evt_priv *pevtpriv); -void r8712_free_evt_priv(struct evt_priv *pevtpriv); - -enum rtl871x_drvint_cid { - NONE_WK_CID, - WDG_WK_CID, - MAX_WK_CID -}; - -enum RFINTFS { - SWSI, - HWSI, - HWPI, -}; - -/* - * Caller Mode: Infra, Ad-HoC(C) - * Notes: To enter USB suspend mode - * Command Mode - */ -struct usb_suspend_parm { - u32 action; /* 1: sleep, 0:resume */ -}; - -/* - * Caller Mode: Infra, Ad-HoC(C) - * Notes: To disconnect the current associated BSS - * Command Mode - */ -struct disconnect_parm { - u32 rsvd; -}; - -/* - * Caller Mode: AP, Ad-HoC, Infra - * Notes: To set the NIC mode of RTL8711 - * Command Mode - * The definition of mode: - * - * #define IW_MODE_AUTO 0 // Let the driver decides which AP to join - * #define IW_MODE_ADHOC 1 // Single cell network (Ad-Hoc Clients) - * #define IW_MODE_INFRA 2 // Multi cell network, roaming, .. - * #define IW_MODE_MASTER 3 // Synchronisation master or AP - * #define IW_MODE_REPEAT 4 // Wireless Repeater (forwarder) - * #define IW_MODE_SECOND 5 // Secondary master/repeater (backup) - * #define IW_MODE_MONITOR 6 // Passive monitor (listen only) - */ -struct setopmode_parm { - u8 mode; - u8 rsvd[3]; -}; - -/* - * Caller Mode: AP, Ad-HoC, Infra - * Notes: To ask RTL8711 performing site-survey - * Command-Event Mode - */ -struct sitesurvey_parm { - __le32 passive_mode; /*active: 1, passive: 0 */ - __le32 bsslimit; /* 1 ~ 48 */ - __le32 ss_ssidlen; - u8 ss_ssid[IW_ESSID_MAX_SIZE + 1]; -}; - -/* - * Caller Mode: Any - * Notes: To set the auth type of RTL8711. open/shared/802.1x - * Command Mode - */ -struct setauth_parm { - u8 mode; /*0: legacy open, 1: legacy shared 2: 802.1x*/ - u8 _1x; /*0: PSK, 1: TLS*/ - u8 rsvd[2]; -}; - -/* - * Caller Mode: Infra - * a. algorithm: wep40, wep104, tkip & aes - * b. keytype: grp key/unicast key - * c. key contents - * - * when shared key ==> keyid is the camid - * when 802.1x ==> keyid [0:1] ==> grp key - * when 802.1x ==> keyid > 2 ==> unicast key - */ -struct setkey_parm { - u8 algorithm; /* encryption algorithm, could be none, wep40, - * TKIP, CCMP, wep104 - */ - u8 keyid; - u8 grpkey; /* 1: this is the grpkey for 802.1x. - * 0: this is the unicast key for 802.1x - */ - u8 key[16]; /* this could be 40 or 104 */ -}; - -/* - * When in AP or Ad-Hoc mode, this is used to - * allocate an sw/hw entry for a newly associated sta. - * Command - * when shared key ==> algorithm/keyid - */ -struct set_stakey_parm { - u8 addr[ETH_ALEN]; - u8 algorithm; - u8 key[16]; -}; - -struct set_stakey_rsp { - u8 addr[ETH_ALEN]; - u8 keyid; - u8 rsvd; -}; - -struct SetMacAddr_param { - u8 MacAddr[ETH_ALEN]; -}; - -/* - * Caller Ad-Hoc/AP - * - * Command -Rsp(AID == CAMID) mode - * - * This is to force fw to add an sta_data entry per driver's request. - * - * FW will write an cam entry associated with it. - * - */ -struct set_assocsta_parm { - u8 addr[ETH_ALEN]; -}; - -struct set_assocsta_rsp { - u8 cam_id; - u8 rsvd[3]; -}; - -/* - * Caller Ad-Hoc/AP - * - * Command mode - * - * This is to force fw to del an sta_data entry per driver's request - * - * FW will invalidate the cam entry associated with it. - * - */ -struct del_assocsta_parm { - u8 addr[ETH_ALEN]; -}; - -/* - * Caller Mode: AP/Ad-HoC(M) - * - * Notes: To notify fw that given staid has changed its power state - * - * Command Mode - * - */ -struct setstapwrstate_parm { - u8 staid; - u8 status; - u8 hwaddr[6]; -}; - -/* - * Caller Mode: Any - * - * Notes: To setup the basic rate of RTL8711 - * - * Command Mode - * - */ -struct setbasicrate_parm { - u8 basicrates[NumRates]; -}; - -/* - * Caller Mode: Any - * - * Notes: To read the current basic rate - * - * Command-Rsp Mode - * - */ -struct getbasicrate_parm { - u32 rsvd; -}; - -struct getbasicrate_rsp { - u8 basicrates[NumRates]; -}; - -/* - * Caller Mode: Any - * - * Notes: To setup the data rate of RTL8711 - * - * Command Mode - * - */ -struct setdatarate_parm { - u8 mac_id; - u8 datarates[NumRates]; -}; - -enum _RT_CHANNEL_DOMAIN { - RT_CHANNEL_DOMAIN_FCC = 0, - RT_CHANNEL_DOMAIN_IC = 1, - RT_CHANNEL_DOMAIN_ETSI = 2, - RT_CHANNEL_DOMAIN_SPAIN = 3, - RT_CHANNEL_DOMAIN_FRANCE = 4, - RT_CHANNEL_DOMAIN_MKK = 5, - RT_CHANNEL_DOMAIN_MKK1 = 6, - RT_CHANNEL_DOMAIN_ISRAEL = 7, - RT_CHANNEL_DOMAIN_TELEC = 8, - - /* Be compatible with old channel plan. No good! */ - RT_CHANNEL_DOMAIN_MIC = 9, - RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 10, - RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 11, - RT_CHANNEL_DOMAIN_TELEC_NETGEAR = 12, - - RT_CHANNEL_DOMAIN_NCC = 13, - RT_CHANNEL_DOMAIN_5G = 14, - RT_CHANNEL_DOMAIN_5G_40M = 15, - /*===== Add new channel plan above this line===============*/ - RT_CHANNEL_DOMAIN_MAX, -}; - -struct SetChannelPlan_param { - enum _RT_CHANNEL_DOMAIN ChannelPlan; -}; - -/* - * Caller Mode: Any - * - * Notes: To read the current data rate - * - * Command-Rsp Mode - * - */ -struct getdatarate_parm { - u32 rsvd; - -}; - -struct getdatarate_rsp { - u8 datarates[NumRates]; -}; - -/* - * Caller Mode: Any - * AP: AP can use the info for the contents of beacon frame - * Infra: STA can use the info when sitesurveying - * Ad-HoC(M): Like AP - * Ad-HoC(C): Like STA - * - * - * Notes: To set the phy capability of the NIC - * - * Command Mode - * - */ - -/* - * Caller Mode: Any - * - * Notes: To set the channel/modem/band - * This command will be used when channel/modem/band is changed. - * - * Command Mode - * - */ -/* - * Caller Mode: Any - * - * Notes: To get the current setting of channel/modem/band - * - * Command-Rsp Mode - * - */ -struct getphy_rsp { - u8 rfchannel; - u8 modem; -}; - -struct readBB_parm { - u8 offset; -}; - -struct readBB_rsp { - u8 value; -}; - -struct readTSSI_parm { - u8 offset; -}; - -struct readTSSI_rsp { - u8 value; -}; - -struct writeBB_parm { - u8 offset; - u8 value; -}; - -struct writePTM_parm { - u8 type; -}; - -struct readRF_parm { - u8 offset; -}; - -struct readRF_rsp { - u32 value; -}; - -struct writeRF_parm { - u32 offset; - u32 value; -}; - -struct setrfintfs_parm { - u8 rfintfs; -}; - -struct getrfintfs_parm { - u8 rfintfs; -}; - -/* - * Notes: This command is used for H2C/C2H loopback testing - * - * mac[0] == 0 - * ==> CMD mode, return H2C_SUCCESS. - * The following condition must be true under CMD mode - * mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; - * s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; - * s2 == (b1 << 8 | b0); - * - * mac[0] == 1 - * ==> CMD_RSP mode, return H2C_SUCCESS_RSP - * - * The rsp layout shall be: - * rsp: parm: - * mac[0] = mac[5]; - * mac[1] = mac[4]; - * mac[2] = mac[3]; - * mac[3] = mac[2]; - * mac[4] = mac[1]; - * mac[5] = mac[0]; - * s0 = s1; - * s1 = swap16(s0); - * w0 = swap32(w1); - * b0 = b1 - * s2 = s0 + s1 - * b1 = b0 - * w1 = w0 - * - * mac[0] == 2 - * ==> CMD_EVENT mode, return H2C_SUCCESS - * The event layout shall be: - * event: parm: - * mac[0] = mac[5]; - * mac[1] = mac[4]; - * mac[2] = event's sequence number, starting from 1 to parm's marc[3] - * mac[3] = mac[2]; - * mac[4] = mac[1]; - * mac[5] = mac[0]; - * s0 = swap16(s0) - event.mac[2]; - * s1 = s1 + event.mac[2]; - * w0 = swap32(w0); - * b0 = b1 - * s2 = s0 + event.mac[2] - * b1 = b0 - * w1 = swap32(w1) - event.mac[2]; - * - * parm->mac[3] is the total event counts that host requested. - * - * - * event will be the same with the cmd's param. - * - */ - -/* CMD param Formart for DRV INTERNAL CMD HDL*/ -struct drvint_cmd_parm { - int i_cid; /*internal cmd id*/ - int sz; /* buf sz*/ - unsigned char *pbuf; -}; - -/*------------------- Below are used for RF/BB tuning ---------------------*/ - -struct setantenna_parm { - u8 tx_antset; - u8 rx_antset; - u8 tx_antenna; - u8 rx_antenna; -}; - -struct enrateadaptive_parm { - u32 en; -}; - -struct settxagctbl_parm { - u32 txagc[MAX_RATES_LENGTH]; -}; - -struct gettxagctbl_parm { - u32 rsvd; -}; - -struct gettxagctbl_rsp { - u32 txagc[MAX_RATES_LENGTH]; -}; - -struct setagcctrl_parm { - u32 agcctrl; /* 0: pure hw, 1: fw */ -}; - -struct setssup_parm { - u32 ss_ForceUp[MAX_RATES_LENGTH]; -}; - -struct getssup_parm { - u32 rsvd; -}; - -struct getssup_rsp { - u8 ss_ForceUp[MAX_RATES_LENGTH]; -}; - -struct setssdlevel_parm { - u8 ss_DLevel[MAX_RATES_LENGTH]; -}; - -struct getssdlevel_parm { - u32 rsvd; -}; - -struct getssdlevel_rsp { - u8 ss_DLevel[MAX_RATES_LENGTH]; -}; - -struct setssulevel_parm { - u8 ss_ULevel[MAX_RATES_LENGTH]; -}; - -struct getssulevel_parm { - u32 rsvd; -}; - -struct getssulevel_rsp { - u8 ss_ULevel[MAX_RATES_LENGTH]; -}; - -struct setcountjudge_parm { - u8 count_judge[MAX_RATES_LENGTH]; -}; - -struct getcountjudge_parm { - u32 rsvd; -}; - -struct getcountjudge_rsp { - u8 count_judge[MAX_RATES_LENGTH]; -}; - -struct setpwrmode_parm { - u8 mode; - u8 flag_low_traffic_en; - u8 flag_lpnav_en; - u8 flag_rf_low_snr_en; - u8 flag_dps_en; /* 1: dps, 0: 32k */ - u8 bcn_rx_en; - u8 bcn_pass_cnt; /* fw report one beacon information to - * driver when it receives bcn_pass_cnt - * beacons. - */ - u8 bcn_to; /* beacon TO (ms). ¡§=0¡¨ no limit.*/ - u16 bcn_itv; - u8 app_itv; /* only for VOIP mode. */ - u8 awake_bcn_itv; - u8 smart_ps; - u8 bcn_pass_time; /* unit: 100ms */ -}; - -struct setatim_parm { - u8 op; /*0: add, 1:del*/ - u8 txid; /* id of dest station.*/ -}; - -struct setratable_parm { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; -}; - -struct getratable_parm { - uint rsvd; -}; - -struct getratable_rsp { - u8 ss_ForceUp[NumRates]; - u8 ss_ULevel[NumRates]; - u8 ss_DLevel[NumRates]; - u8 count_judge[NumRates]; -}; - -/*to get TX,RX retry count*/ -struct gettxretrycnt_parm { - unsigned int rsvd; -}; - -struct gettxretrycnt_rsp { - unsigned long tx_retrycnt; -}; - -struct getrxretrycnt_parm { - unsigned int rsvd; -}; - -struct getrxretrycnt_rsp { - unsigned long rx_retrycnt; -}; - -/*to get BCNOK,BCNERR count*/ -struct getbcnokcnt_parm { - unsigned int rsvd; -}; - -struct getbcnokcnt_rsp { - unsigned long bcnokcnt; -}; - -struct getbcnerrcnt_parm { - unsigned int rsvd; -}; - -struct getbcnerrcnt_rsp { - unsigned long bcnerrcnt; -}; - -/* to get current TX power level*/ -struct getcurtxpwrlevel_parm { - unsigned int rsvd; -}; - -struct getcurtxpwrlevel_rsp { - unsigned short tx_power; -}; - -/*dynamic on/off DIG*/ -struct setdig_parm { - unsigned char dig_on; /* 1:on , 0:off */ -}; - -/*dynamic on/off RA*/ -struct setra_parm { - unsigned char ra_on; /* 1:on , 0:off */ -}; - -struct setprobereqextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct setassocreqextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct setproberspextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct setassocrspextraie_parm { - unsigned char e_id; - unsigned char ie_len; - unsigned char ie[]; -}; - -struct addBaReq_parm { - unsigned int tid; -}; - -/*H2C Handler index: 46 */ -struct SetChannel_parm { - u32 curr_ch; -}; - -/*H2C Handler index: 61 */ -struct DisconnectCtrlEx_param { - /* MAXTIME = (2 * FirstStageTO) + (TryPktCnt * TryPktInterval) */ - unsigned char EnableDrvCtrl; - unsigned char TryPktCnt; - unsigned char TryPktInterval; /* Unit: ms */ - unsigned char rsvd; - unsigned int FirstStageTO; /* Unit: ms */ -}; - -#define GEN_CMD_CODE(cmd) cmd ## _CMD_ - -/* - * Result: - * 0x00: success - * 0x01: success, and check Response. - * 0x02: cmd ignored due to duplicated sequence number - * 0x03: cmd dropped due to invalid cmd code - * 0x04: reserved. - */ - -#define H2C_RSP_OFFSET 512 -#define H2C_SUCCESS 0x00 -#define H2C_SUCCESS_RSP 0x01 -#define H2C_DUPLICATED 0x02 -#define H2C_DROPPED 0x03 -#define H2C_PARAMETERS_ERROR 0x04 -#define H2C_REJECTED 0x05 -#define H2C_CMD_OVERFLOW 0x06 -#define H2C_RESERVED 0x07 - -void r8712_setMacAddr_cmd(struct _adapter *padapter, const u8 *mac_addr); -u8 r8712_sitesurvey_cmd(struct _adapter *padapter, - struct ndis_802_11_ssid *pssid); -int r8712_createbss_cmd(struct _adapter *padapter); -void r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key); -int r8712_joinbss_cmd(struct _adapter *padapter, - struct wlan_network *pnetwork); -void r8712_disassoc_cmd(struct _adapter *padapter); -void r8712_setopmode_cmd(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); -int r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset); -void r8712_set_chplan_cmd(struct _adapter *padapter, int chplan); -int r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval); -int r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val); -void r8712_addbareq_cmd(struct _adapter *padapter, u8 tid); -void r8712_wdg_wk_cmd(struct _adapter *padapter); -void r8712_survey_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_disassoc_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_joinbss_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_createbss_cmd_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_readtssi_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter, - struct cmd_obj *pcmd); -void r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl, - u32 tryPktCnt, u32 tryPktInterval, u32 firstStageTO); - -struct _cmd_callback { - u32 cmd_code; - void (*callback)(struct _adapter *padapter, struct cmd_obj *cmd); -}; - -#include "rtl8712_cmd.h" - -#endif /* _CMD_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_debug.h b/drivers/staging/rtl8712/rtl871x_debug.h deleted file mode 100644 index 69c631af2a2a..000000000000 --- a/drivers/staging/rtl8712/rtl871x_debug.h +++ /dev/null @@ -1,130 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_DEBUG_H__ -#define __RTL871X_DEBUG_H__ - -#include "osdep_service.h" -#include "drv_types.h" - -#define _drv_emerg_ 1 -#define _drv_alert_ 2 -#define _drv_crit_ 3 -#define _drv_err_ 4 -#define _drv_warning_ 5 -#define _drv_notice_ 6 -#define _drv_info_ 7 -#define _drv_dump_ 8 -#define _drv_debug_ 9 - -#define _module_rtl871x_xmit_c_ BIT(0) -#define _module_xmit_osdep_c_ BIT(1) -#define _module_rtl871x_recv_c_ BIT(2) -#define _module_recv_osdep_c_ BIT(3) -#define _module_rtl871x_mlme_c_ BIT(4) -#define _module_mlme_osdep_c_ BIT(5) -#define _module_rtl871x_sta_mgt_c_ BIT(6) -#define _module_rtl871x_cmd_c_ BIT(7) -#define _module_cmd_osdep_c_ BIT(8) -#define _module_rtl871x_io_c_ BIT(9) -#define _module_io_osdep_c_ BIT(10) -#define _module_os_intfs_c_ BIT(11) -#define _module_rtl871x_security_c_ BIT(12) -#define _module_rtl871x_eeprom_c_ BIT(13) -#define _module_hal_init_c_ BIT(14) -#define _module_hci_hal_init_c_ BIT(15) -#define _module_rtl871x_ioctl_c_ BIT(16) -#define _module_rtl871x_ioctl_set_c_ BIT(17) -#define _module_rtl871x_pwrctrl_c_ BIT(19) -#define _module_hci_intfs_c_ BIT(20) -#define _module_hci_ops_c_ BIT(21) -#define _module_osdep_service_c_ BIT(22) -#define _module_rtl871x_mp_ioctl_c_ BIT(23) -#define _module_hci_ops_os_c_ BIT(24) -#define _module_rtl871x_ioctl_os_c BIT(25) -#define _module_rtl8712_cmd_c_ BIT(26) -#define _module_rtl871x_mp_c_ BIT(27) -#define _module_rtl8712_xmit_c_ BIT(28) -#define _module_rtl8712_efuse_c_ BIT(29) -#define _module_rtl8712_recv_c_ BIT(30) -#define _module_rtl8712_led_c_ BIT(31) - -#undef _MODULE_DEFINE_ - -#if defined _RTL871X_XMIT_C_ - #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_ -#elif defined _XMIT_OSDEP_C_ - #define _MODULE_DEFINE_ _module_xmit_osdep_c_ -#elif defined _RTL871X_RECV_C_ - #define _MODULE_DEFINE_ _module_rtl871x_recv_c_ -#elif defined _RECV_OSDEP_C_ - #define _MODULE_DEFINE_ _module_recv_osdep_c_ -#elif defined _RTL871X_MLME_C_ - #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_ -#elif defined _MLME_OSDEP_C_ - #define _MODULE_DEFINE_ _module_mlme_osdep_c_ -#elif defined _RTL871X_STA_MGT_C_ - #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_ -#elif defined _RTL871X_CMD_C_ - #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_ -#elif defined _CMD_OSDEP_C_ - #define _MODULE_DEFINE_ _module_cmd_osdep_c_ -#elif defined _RTL871X_IO_C_ - #define _MODULE_DEFINE_ _module_rtl871x_io_c_ -#elif defined _IO_OSDEP_C_ - #define _MODULE_DEFINE_ _module_io_osdep_c_ -#elif defined _OS_INTFS_C_ - #define _MODULE_DEFINE_ _module_os_intfs_c_ -#elif defined _RTL871X_SECURITY_C_ - #define _MODULE_DEFINE_ _module_rtl871x_security_c_ -#elif defined _RTL871X_EEPROM_C_ - #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_ -#elif defined _HAL_INIT_C_ - #define _MODULE_DEFINE_ _module_hal_init_c_ -#elif defined _HCI_HAL_INIT_C_ - #define _MODULE_DEFINE_ _module_hci_hal_init_c_ -#elif defined _RTL871X_IOCTL_C_ - #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_ -#elif defined _RTL871X_IOCTL_SET_C_ - #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_ -#elif defined _RTL871X_PWRCTRL_C_ - #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_ -#elif defined _HCI_INTF_C_ - #define _MODULE_DEFINE_ _module_hci_intfs_c_ -#elif defined _HCI_OPS_C_ - #define _MODULE_DEFINE_ _module_hci_ops_c_ -#elif defined _OSDEP_HCI_INTF_C_ - #define _MODULE_DEFINE_ _module_hci_intfs_c_ -#elif defined _OSDEP_SERVICE_C_ - #define _MODULE_DEFINE_ _module_osdep_service_c_ -#elif defined _RTL871X_MP_IOCTL_C_ - #define _MODULE_DEFINE_ _module_rtl871x_mp_ioctl_c_ -#elif defined _HCI_OPS_OS_C_ - #define _MODULE_DEFINE_ _module_hci_ops_os_c_ -#elif defined _RTL871X_IOCTL_LINUX_C_ - #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c -#elif defined _RTL871X_MP_C_ - #define _MODULE_DEFINE_ _module_rtl871x_mp_c_ -#elif defined _RTL8712_CMD_C_ - #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_ -#elif defined _RTL8712_XMIT_C_ - #define _MODULE_DEFINE_ _module_rtl8712_xmit_c_ -#elif defined _RTL8712_EFUSE_C_ - #define _MODULE_DEFINE_ _module_rtl8712_efuse_c_ -#elif defined _RTL8712_RECV_C_ - #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ -#else - #undef _MODULE_DEFINE_ -#endif - -#endif /*__RTL871X_DEBUG_H__*/ diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.c b/drivers/staging/rtl8712/rtl871x_eeprom.c deleted file mode 100644 index 221bf92e1b1c..000000000000 --- a/drivers/staging/rtl8712/rtl871x_eeprom.c +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_eeprom.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_EEPROM_C_ - -#include "osdep_service.h" -#include "drv_types.h" - -static void up_clk(struct _adapter *padapter, u16 *x) -{ - *x = *x | _EESK; - r8712_write8(padapter, EE_9346CR, (u8)*x); - udelay(CLOCK_RATE); -} - -static void down_clk(struct _adapter *padapter, u16 *x) -{ - *x = *x & ~_EESK; - r8712_write8(padapter, EE_9346CR, (u8)*x); - udelay(CLOCK_RATE); -} - -static void shift_out_bits(struct _adapter *padapter, u16 data, u16 count) -{ - u16 x, mask; - - if (padapter->surprise_removed) - goto out; - mask = 0x01 << (count - 1); - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDO | _EEDI); - do { - x &= ~_EEDI; - if (data & mask) - x |= _EEDI; - if (padapter->surprise_removed) - goto out; - r8712_write8(padapter, EE_9346CR, (u8)x); - udelay(CLOCK_RATE); - up_clk(padapter, &x); - down_clk(padapter, &x); - mask >>= 1; - } while (mask); - if (padapter->surprise_removed) - goto out; - x &= ~_EEDI; - r8712_write8(padapter, EE_9346CR, (u8)x); -out:; -} - -static u16 shift_in_bits(struct _adapter *padapter) -{ - u16 x, d = 0, i; - - if (padapter->surprise_removed) - goto out; - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDO | _EEDI); - d = 0; - for (i = 0; i < 16; i++) { - d <<= 1; - up_clk(padapter, &x); - if (padapter->surprise_removed) - goto out; - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDI); - if (x & _EEDO) - d |= 1; - down_clk(padapter, &x); - } -out: - return d; -} - -static void standby(struct _adapter *padapter) -{ - u8 x; - - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EECS | _EESK); - r8712_write8(padapter, EE_9346CR, x); - udelay(CLOCK_RATE); - x |= _EECS; - r8712_write8(padapter, EE_9346CR, x); - udelay(CLOCK_RATE); -} - -static u16 wait_eeprom_cmd_done(struct _adapter *padapter) -{ - u8 x; - u16 i; - - standby(padapter); - for (i = 0; i < 200; i++) { - x = r8712_read8(padapter, EE_9346CR); - if (x & _EEDO) - return true; - udelay(CLOCK_RATE); - } - return false; -} - -static void eeprom_clean(struct _adapter *padapter) -{ - u16 x; - - if (padapter->surprise_removed) - return; - x = r8712_read8(padapter, EE_9346CR); - if (padapter->surprise_removed) - return; - x &= ~(_EECS | _EEDI); - r8712_write8(padapter, EE_9346CR, (u8)x); - if (padapter->surprise_removed) - return; - up_clk(padapter, &x); - if (padapter->surprise_removed) - return; - down_clk(padapter, &x); -} - -void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data) -{ - u8 x; - u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; - - tmp8_ori = r8712_read8(padapter, 0x102502f1); - tmp8_new = tmp8_ori & 0xf7; - if (tmp8_ori != tmp8_new) - r8712_write8(padapter, 0x102502f1, tmp8_new); - tmp8_clk_ori = r8712_read8(padapter, 0x10250003); - tmp8_clk_new = tmp8_clk_ori | 0x20; - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_new); - x = r8712_read8(padapter, EE_9346CR); - x &= ~(_EEDI | _EEDO | _EESK | _EEM0); - x |= _EEM1 | _EECS; - r8712_write8(padapter, EE_9346CR, x); - shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5); - if (padapter->eeprom_address_size == 8) /*CF+ and SDIO*/ - shift_out_bits(padapter, 0, 6); - else /* USB */ - shift_out_bits(padapter, 0, 4); - standby(padapter); - /* Erase this particular word. Write the erase opcode and register - * number in that order. The opcode is 3bits in length; reg is 6 - * bits long. - */ - standby(padapter); - /* write the new word to the EEPROM - * send the write opcode the EEPORM - */ - shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3); - /* select which word in the EEPROM that we are writing to. */ - shift_out_bits(padapter, reg, padapter->eeprom_address_size); - /* write the data to the selected EEPROM word. */ - shift_out_bits(padapter, data, 16); - if (wait_eeprom_cmd_done(padapter)) { - standby(padapter); - shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5); - shift_out_bits(padapter, reg, 4); - eeprom_clean(padapter); - } - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_ori); - if (tmp8_new != tmp8_ori) - r8712_write8(padapter, 0x102502f1, tmp8_ori); -} - -u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg) /*ReadEEprom*/ -{ - u16 x; - u16 data = 0; - u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; - - tmp8_ori = r8712_read8(padapter, 0x102502f1); - tmp8_new = tmp8_ori & 0xf7; - if (tmp8_ori != tmp8_new) - r8712_write8(padapter, 0x102502f1, tmp8_new); - tmp8_clk_ori = r8712_read8(padapter, 0x10250003); - tmp8_clk_new = tmp8_clk_ori | 0x20; - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_new); - if (padapter->surprise_removed) - goto out; - /* select EEPROM, reset bits, set _EECS */ - x = r8712_read8(padapter, EE_9346CR); - if (padapter->surprise_removed) - goto out; - x &= ~(_EEDI | _EEDO | _EESK | _EEM0); - x |= _EEM1 | _EECS; - r8712_write8(padapter, EE_9346CR, (unsigned char)x); - /* write the read opcode and register number in that order - * The opcode is 3bits in length, reg is 6 bits long - */ - shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); - shift_out_bits(padapter, reg, padapter->eeprom_address_size); - /* Now read the data (16 bits) in from the selected EEPROM word */ - data = shift_in_bits(padapter); - eeprom_clean(padapter); -out: - if (tmp8_clk_new != tmp8_clk_ori) - r8712_write8(padapter, 0x10250003, tmp8_clk_ori); - if (tmp8_new != tmp8_ori) - r8712_write8(padapter, 0x102502f1, tmp8_ori); - return data; -} diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.h b/drivers/staging/rtl8712/rtl871x_eeprom.h deleted file mode 100644 index 7bdeb2aaa025..000000000000 --- a/drivers/staging/rtl8712/rtl871x_eeprom.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - ******************************************************************************/ -#ifndef __RTL871X_EEPROM_H__ -#define __RTL871X_EEPROM_H__ - -#include "osdep_service.h" - -#define RTL8712_EEPROM_ID 0x8712 -#define EEPROM_MAX_SIZE 256 -#define CLOCK_RATE 50 /*100us*/ - -/*- EEPROM opcodes*/ -#define EEPROM_READ_OPCODE 06 -#define EEPROM_WRITE_OPCODE 05 -#define EEPROM_ERASE_OPCODE 07 -#define EEPROM_EWEN_OPCODE 19 /* Erase/write enable*/ -#define EEPROM_EWDS_OPCODE 16 /* Erase/write disable*/ - -#define EEPROM_CID_DEFAULT 0x0 -#define EEPROM_CID_ALPHA 0x1 -#define EEPROM_CID_Senao 0x3 -#define EEPROM_CID_NetCore 0x5 -#define EEPROM_CID_CAMEO 0X8 -#define EEPROM_CID_SITECOM 0x9 -#define EEPROM_CID_COREGA 0xB -#define EEPROM_CID_EDIMAX_BELKIN 0xC -#define EEPROM_CID_SERCOMM_BELKIN 0xE -#define EEPROM_CID_CAMEO1 0xF -#define EEPROM_CID_WNC_COREGA 0x12 -#define EEPROM_CID_CLEVO 0x13 -#define EEPROM_CID_WHQL 0xFE - -enum RT_CUSTOMER_ID { - RT_CID_DEFAULT = 0, - RT_CID_8187_ALPHA0 = 1, - RT_CID_8187_SERCOMM_PS = 2, - RT_CID_8187_HW_LED = 3, - RT_CID_8187_NETGEAR = 4, - RT_CID_WHQL = 5, - RT_CID_819x_CAMEO = 6, - RT_CID_819x_RUNTOP = 7, - RT_CID_819x_Senao = 8, - RT_CID_TOSHIBA = 9, - RT_CID_819x_Netcore = 10, - RT_CID_Nettronix = 11, - RT_CID_DLINK = 12, - RT_CID_PRONET = 13, - RT_CID_COREGA = 14, - RT_CID_819x_ALPHA = 15, - RT_CID_819x_Sitecom = 16, - RT_CID_CCX = 17, - RT_CID_819x_Lenovo = 18, - RT_CID_819x_QMI = 19, - RT_CID_819x_Edimax_Belkin = 20, - RT_CID_819x_Sercomm_Belkin = 21, - RT_CID_819x_CAMEO1 = 22, - RT_CID_819x_MSI = 23, - RT_CID_819x_Acer = 24, - RT_CID_819x_AzWave_ASUS = 25, - RT_CID_819x_AzWave = 26, - RT_CID_819x_WNC_COREGA = 27, - RT_CID_819x_CLEVO = 28, -}; - -struct eeprom_priv { - u8 bautoload_fail_flag; - u8 bempty; - u8 sys_config; - u8 mac_addr[6]; - u8 config0; - u16 channel_plan; - u8 country_string[3]; - u8 tx_power_b[15]; - u8 tx_power_g[15]; - u8 tx_power_a[201]; - u8 efuse_eeprom_data[EEPROM_MAX_SIZE]; - enum RT_CUSTOMER_ID CustomerID; -}; - -void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data); -u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg); - -#endif /*__RTL871X_EEPROM_H__*/ - diff --git a/drivers/staging/rtl8712/rtl871x_event.h b/drivers/staging/rtl8712/rtl871x_event.h deleted file mode 100644 index 759a2d27d8f2..000000000000 --- a/drivers/staging/rtl8712/rtl871x_event.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871x_EVENT_H_ -#define _RTL871x_EVENT_H_ - -#include "osdep_service.h" - -#include "wlan_bssdef.h" -#include -#include - -/* - * Used to report a bss has been scanned - */ -struct survey_event { - struct wlan_bssid_ex bss; -}; - -/* - * Used to report that the requested site survey has been done. - * bss_cnt indicates the number of bss that has been reported. - */ -struct surveydone_event { - unsigned int bss_cnt; - -}; - -/* - * Used to report the link result of joinning the given bss - * join_res: - * -1: authentication fail - * -2: association fail - * > 0: TID - */ -struct joinbss_event { - struct wlan_network network; -}; - -/* - * Used to report a given STA has joinned the created BSS. - * It is used in AP/Ad-HoC(M) mode. - */ -struct stassoc_event { - unsigned char macaddr[6]; - unsigned char rsvd[2]; - __le32 cam_id; -}; - -struct stadel_event { - unsigned char macaddr[6]; - unsigned char rsvd[2]; -}; - -struct addba_event { - unsigned int tid; -}; - -#define GEN_EVT_CODE(event) event ## _EVT_ - -struct fwevent { - u32 parmsize; - void (*event_callback)(struct _adapter *dev, u8 *pbuf); -}; - -#define C2HEVENT_SZ 32 -struct event_node { - unsigned char *node; - unsigned char evt_code; - unsigned short evt_sz; - /*volatile*/ int *caller_ff_tail; - int caller_ff_sz; -}; - -struct c2hevent_queue { - /*volatile*/ int head; - /*volatile*/ int tail; - struct event_node nodes[C2HEVENT_SZ]; - unsigned char seq; -}; - -#define NETWORK_QUEUE_SZ 4 - -struct network_queue { - /*volatile*/ int head; - /*volatile*/ int tail; - struct wlan_bssid_ex networks[NETWORK_QUEUE_SZ]; -}; - -struct ADDBA_Req_Report_parm { - unsigned char MacAddress[ETH_ALEN]; - unsigned short StartSeqNum; - unsigned char tid; -}; - -#include "rtl8712_event.h" - -#endif /* _WLANEVENT_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_ht.h b/drivers/staging/rtl8712/rtl871x_ht.h deleted file mode 100644 index ebd78665775d..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ht.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_HT_H_ -#define _RTL871X_HT_H_ - -#include "osdep_service.h" -#include "wifi.h" - -struct ht_priv { - unsigned int ht_option; - unsigned int ampdu_enable;/*for enable Tx A-MPDU*/ - unsigned char baddbareq_issued[16]; - unsigned int tx_amsdu_enable;/*for enable Tx A-MSDU */ - unsigned int tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */ - unsigned int rx_ampdu_maxlen; /* for rx reordering ctrl win_sz, - * updated when join_callback. - */ - struct ieee80211_ht_cap ht_cap; -}; - -#endif /*_RTL871X_HT_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c deleted file mode 100644 index 6789a4c98564..000000000000 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_io.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -/* - * - * The purpose of rtl871x_io.c - * - * a. provides the API - * b. provides the protocol engine - * c. provides the software interface between caller and the hardware interface - * - * For r8712u, both sync/async operations are provided. - * - * Only sync read/write_mem operations are provided. - * - */ - -#define _RTL871X_IO_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_io.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -static uint _init_intf_hdl(struct _adapter *padapter, - struct intf_hdl *pintf_hdl) -{ - struct intf_priv *pintf_priv; - void (*set_intf_option)(u32 *poption) = NULL; - void (*set_intf_funs)(struct intf_hdl *pintf_hdl); - void (*set_intf_ops)(struct _io_ops *pops); - uint (*init_intf_priv)(struct intf_priv *pintfpriv); - - set_intf_option = &(r8712_usb_set_intf_option); - set_intf_funs = &(r8712_usb_set_intf_funs); - set_intf_ops = &r8712_usb_set_intf_ops; - init_intf_priv = &r8712_usb_init_intf_priv; - pintf_priv = pintf_hdl->pintfpriv = kmalloc(sizeof(struct intf_priv), - GFP_ATOMIC); - if (!pintf_priv) - goto _init_intf_hdl_fail; - pintf_hdl->adapter = (u8 *)padapter; - set_intf_option(&pintf_hdl->intf_option); - set_intf_funs(pintf_hdl); - set_intf_ops(&pintf_hdl->io_ops); - pintf_priv->intf_dev = (u8 *)&padapter->dvobjpriv; - if (init_intf_priv(pintf_priv) == _FAIL) - goto _init_intf_hdl_fail; - return _SUCCESS; -_init_intf_hdl_fail: - kfree(pintf_priv); - return _FAIL; -} - -static void _unload_intf_hdl(struct intf_priv *pintfpriv) -{ - void (*unload_intf_priv)(struct intf_priv *pintfpriv); - - unload_intf_priv = &r8712_usb_unload_intf_priv; - unload_intf_priv(pintfpriv); - kfree(pintfpriv); -} - -static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl) -{ - struct _adapter *adapter = (struct _adapter *)dev; - - pintfhdl->intf_option = 0; - pintfhdl->adapter = dev; - pintfhdl->intf_dev = (u8 *)&adapter->dvobjpriv; - if (!_init_intf_hdl(adapter, pintfhdl)) - goto register_intf_hdl_fail; - return _SUCCESS; -register_intf_hdl_fail: - return false; -} - -static void unregister_intf_hdl(struct intf_hdl *pintfhdl) -{ - _unload_intf_hdl(pintfhdl->pintfpriv); - memset((u8 *)pintfhdl, 0, sizeof(struct intf_hdl)); -} - -uint r8712_alloc_io_queue(struct _adapter *adapter) -{ - u32 i; - struct io_queue *pio_queue; - struct io_req *pio_req; - - pio_queue = kmalloc(sizeof(*pio_queue), GFP_ATOMIC); - if (!pio_queue) - goto alloc_io_queue_fail; - INIT_LIST_HEAD(&pio_queue->free_ioreqs); - INIT_LIST_HEAD(&pio_queue->processing); - INIT_LIST_HEAD(&pio_queue->pending); - spin_lock_init(&pio_queue->lock); - pio_queue->pallocated_free_ioreqs_buf = kzalloc(NUM_IOREQ * - (sizeof(struct io_req)) + 4, - GFP_ATOMIC); - if ((pio_queue->pallocated_free_ioreqs_buf) == NULL) - goto alloc_io_queue_fail; - pio_queue->free_ioreqs_buf = pio_queue->pallocated_free_ioreqs_buf + 4 - - ((addr_t)(pio_queue->pallocated_free_ioreqs_buf) - & 3); - pio_req = (struct io_req *)(pio_queue->free_ioreqs_buf); - for (i = 0; i < NUM_IOREQ; i++) { - INIT_LIST_HEAD(&pio_req->list); - list_add_tail(&pio_req->list, &pio_queue->free_ioreqs); - pio_req++; - } - if ((register_intf_hdl((u8 *)adapter, &pio_queue->intf)) == _FAIL) - goto alloc_io_queue_fail; - adapter->pio_queue = pio_queue; - return _SUCCESS; -alloc_io_queue_fail: - if (pio_queue) { - kfree(pio_queue->pallocated_free_ioreqs_buf); - kfree(pio_queue); - } - adapter->pio_queue = NULL; - return _FAIL; -} - -void r8712_free_io_queue(struct _adapter *adapter) -{ - struct io_queue *pio_queue = adapter->pio_queue; - - if (pio_queue) { - kfree(pio_queue->pallocated_free_ioreqs_buf); - adapter->pio_queue = NULL; - unregister_intf_hdl(&pio_queue->intf); - kfree(pio_queue); - } -} diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h deleted file mode 100644 index c5b12f74ebf8..000000000000 --- a/drivers/staging/rtl8712/rtl871x_io.h +++ /dev/null @@ -1,236 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_IO_H_ -#define _RTL871X_IO_H_ - -#include "osdep_service.h" -#include "osdep_intf.h" - -#define NUM_IOREQ 8 - -#define MAX_PROT_SZ (64-16) - -#define _IOREADY 0 -#define _IO_WAIT_COMPLETE 1 -#define _IO_WAIT_RSP 2 - -/* IO COMMAND TYPE */ -#define _IOSZ_MASK_ (0x7F) -#define _IO_WRITE_ BIT(7) -#define _IO_FIXED_ BIT(8) -#define _IO_BURST_ BIT(9) -#define _IO_BYTE_ BIT(10) -#define _IO_HW_ BIT(11) -#define _IO_WORD_ BIT(12) -#define _IO_SYNC_ BIT(13) -#define _IO_CMDMASK_ (0x1F80) - -/* - * For prompt mode accessing, caller shall free io_req - * Otherwise, io_handler will free io_req - */ -/* IO STATUS TYPE */ -#define _IO_ERR_ BIT(2) -#define _IO_SUCCESS_ BIT(1) -#define _IO_DONE_ BIT(0) -#define IO_RD32 (_IO_SYNC_ | _IO_WORD_) -#define IO_RD16 (_IO_SYNC_ | _IO_HW_) -#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_) -#define IO_RD32_ASYNC (_IO_WORD_) -#define IO_RD16_ASYNC (_IO_HW_) -#define IO_RD8_ASYNC (_IO_BYTE_) -#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_) -#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_) -#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_) -#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_) -#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_) -#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_) -/* - * Only Sync. burst accessing is provided. - */ -#define IO_WR_BURST(x) (IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | \ - ((x) & _IOSZ_MASK_)) -#define IO_RD_BURST(x) (_IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_)) -/*below is for the intf_option bit defition...*/ -#define _INTF_ASYNC_ BIT(0) /*support async io*/ -struct intf_priv; -struct intf_hdl; -struct io_queue; -struct _io_ops { - uint (*_sdbus_read_bytes_to_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf); - uint (*_sdbus_read_blocks_to_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf); - u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); - u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); - u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); - uint (*_sdbus_write_blocks_from_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf, - u8 async); - uint (*_sdbus_write_bytes_from_membuf)(struct intf_priv *pintfpriv, - u32 addr, u32 cnt, u8 *pbuf); - u8 (*_cmd52r)(struct intf_priv *pintfpriv, u32 addr); - void (*_cmd52w)(struct intf_priv *pintfpriv, u32 addr, u8 val8); - u8 (*_cmdfunc152r)(struct intf_priv *pintfpriv, u32 addr); - void (*_cmdfunc152w)(struct intf_priv *pintfpriv, u32 addr, u8 val8); - void (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); - void (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); - void (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); - void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); - void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); - void (*_sync_irp_protocol_rw)(struct io_queue *pio_q); - u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); - u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, - u8 *pmem); -}; - -struct io_req { - struct list_head list; - u32 addr; - /*volatile*/ u32 val; - u32 command; - u32 status; - u8 *pbuf; - void (*_async_io_callback)(struct _adapter *padapter, - struct io_req *pio_req, u8 *cnxt); - u8 *cnxt; -}; - -struct intf_hdl { - u32 intf_option; - u8 *adapter; - u8 *intf_dev; - struct intf_priv *pintfpriv; - void (*intf_hdl_init)(u8 *priv); - void (*intf_hdl_unload)(u8 *priv); - void (*intf_hdl_open)(u8 *priv); - void (*intf_hdl_close)(u8 *priv); - struct _io_ops io_ops; -}; - -struct reg_protocol_rd { -#ifdef __LITTLE_ENDIAN - /* DW1 */ - u32 NumOfTrans:4; - u32 Reserved1:4; - u32 Reserved2:24; - /* DW2 */ - u32 ByteCount:7; - u32 WriteEnable:1; /*0:read, 1:write*/ - u32 FixOrContinuous:1; /*0:continuous, 1: Fix*/ - u32 BurstMode:1; - u32 Byte1Access:1; - u32 Byte2Access:1; - u32 Byte4Access:1; - u32 Reserved3:3; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ -#else -/*DW1*/ - u32 Reserved1:4; - u32 NumOfTrans:4; - u32 Reserved2:24; - /*DW2*/ - u32 WriteEnable:1; - u32 ByteCount:7; - u32 Reserved3:3; - u32 Byte4Access:1; - u32 Byte2Access:1; - u32 Byte1Access:1; - u32 BurstMode:1; - u32 FixOrContinuous:1; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ -#endif -}; - -struct reg_protocol_wt { -#ifdef __LITTLE_ENDIAN - /*DW1*/ - u32 NumOfTrans:4; - u32 Reserved1:4; - u32 Reserved2:24; - /*DW2*/ - u32 ByteCount:7; - u32 WriteEnable:1; /*0:read, 1:write*/ - u32 FixOrContinuous:1; /*0:continuous, 1: Fix*/ - u32 BurstMode:1; - u32 Byte1Access:1; - u32 Byte2Access:1; - u32 Byte4Access:1; - u32 Reserved3:3; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ - u32 Value; -#else - /*DW1*/ - u32 Reserved1:4; - u32 NumOfTrans:4; - u32 Reserved2:24; - /*DW2*/ - u32 WriteEnable:1; - u32 ByteCount:7; - u32 Reserved3:3; - u32 Byte4Access:1; - u32 Byte2Access:1; - u32 Byte1Access:1; - u32 BurstMode:1; - u32 FixOrContinuous:1; - u32 Reserved4:16; - /*DW3*/ - u32 BusAddress; - /*DW4*/ - u32 Value; -#endif -}; - -/* - * Below is the data structure used by _io_handler - */ - -struct io_queue { - spinlock_t lock; - struct list_head free_ioreqs; - /*The io_req list that will be served in the single protocol r/w.*/ - struct list_head pending; - struct list_head processing; - u8 *free_ioreqs_buf; /* 4-byte aligned */ - u8 *pallocated_free_ioreqs_buf; - struct intf_hdl intf; -}; - -u8 r8712_read8(struct _adapter *adapter, u32 addr); -u16 r8712_read16(struct _adapter *adapter, u32 addr); -u32 r8712_read32(struct _adapter *adapter, u32 addr); -void r8712_read_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -void r8712_read_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -void r8712_write8(struct _adapter *adapter, u32 addr, u8 val); -void r8712_write16(struct _adapter *adapter, u32 addr, u16 val); -void r8712_write32(struct _adapter *adapter, u32 addr, u32 val); -void r8712_write_mem(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -void r8712_write_port(struct _adapter *adapter, u32 addr, u32 cnt, u8 *pmem); -/*ioreq */ -uint r8712_alloc_io_queue(struct _adapter *adapter); -void r8712_free_io_queue(struct _adapter *adapter); - -#endif /*_RTL871X_IO_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_ioctl.h b/drivers/staging/rtl8712/rtl871x_ioctl.h deleted file mode 100644 index d6332a8c7f4f..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IOCTL_H -#define __IOCTL_H - -#include "osdep_service.h" -#include "drv_types.h" - -#ifndef OID_802_11_CAPABILITY - #define OID_802_11_CAPABILITY 0x0d010122 -#endif - -#ifndef OID_802_11_PMKID - #define OID_802_11_PMKID 0x0d010123 -#endif - -/* For DDK-defined OIDs*/ -#define OID_NDIS_SEG1 0x00010100 -#define OID_NDIS_SEG2 0x00010200 -#define OID_NDIS_SEG3 0x00020100 -#define OID_NDIS_SEG4 0x01010100 -#define OID_NDIS_SEG5 0x01020100 -#define OID_NDIS_SEG6 0x01020200 -#define OID_NDIS_SEG7 0xFD010100 -#define OID_NDIS_SEG8 0x0D010100 -#define OID_NDIS_SEG9 0x0D010200 -#define OID_NDIS_SEG10 0x0D020200 -#define SZ_OID_NDIS_SEG1 23 -#define SZ_OID_NDIS_SEG2 3 -#define SZ_OID_NDIS_SEG3 6 -#define SZ_OID_NDIS_SEG4 6 -#define SZ_OID_NDIS_SEG5 4 -#define SZ_OID_NDIS_SEG6 8 -#define SZ_OID_NDIS_SEG7 7 -#define SZ_OID_NDIS_SEG8 36 -#define SZ_OID_NDIS_SEG9 24 -#define SZ_OID_NDIS_SEG10 19 - -/* For Realtek-defined OIDs*/ -#define OID_MP_SEG1 0xFF871100 -#define OID_MP_SEG2 0xFF818000 -#define OID_MP_SEG3 0xFF818700 -#define OID_MP_SEG4 0xFF011100 - -enum oid_type { - QUERY_OID, - SET_OID -}; - -struct oid_funs_node { - unsigned int oid_start; /*the starting number for OID*/ - unsigned int oid_end; /*the ending number for OID*/ - struct oid_obj_priv *node_array; - unsigned int array_sz; /*the size of node_array*/ - int query_counter; /*count the number of query hits for this segment*/ - int set_counter; /*count the number of set hits for this segment*/ -}; - -struct oid_par_priv { - void *adapter_context; - uint oid; - void *information_buf; - unsigned long information_buf_len; - unsigned long *bytes_rw; - unsigned long *bytes_needed; - enum oid_type type_of_oid; - unsigned int dbg; -}; - -struct oid_obj_priv { - unsigned char dbg; /* 0: without OID debug message - * 1: with OID debug message - */ - uint (*oidfuns)(struct oid_par_priv *poid_par_priv); -}; - -uint oid_null_function(struct oid_par_priv *poid_par_priv); - -extern struct iw_handler_def r871x_handlers_def; - -uint drv_query_info(struct net_device *MiniportAdapterContext, - uint Oid, - void *InformationBuffer, - u32 InformationBufferLength, - u32 *BytesWritten, - u32 *BytesNeeded); - -uint drv_set_info(struct net_device *MiniportAdapterContext, - uint Oid, - void *InformationBuffer, - u32 InformationBufferLength, - u32 *BytesRead, - u32 *BytesNeeded); - -#endif diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c deleted file mode 100644 index 36f6904d25ab..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ /dev/null @@ -1,2330 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_ioctl_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_IOCTL_LINUX_C_ -#define _RTL871X_MP_IOCTL_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wlan_bssdef.h" -#include "rtl871x_debug.h" -#include "wifi.h" -#include "rtl871x_mlme.h" -#include "rtl871x_ioctl.h" -#include "rtl871x_ioctl_set.h" -#include "rtl871x_mp_ioctl.h" -#include "mlme_osdep.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E) - -#define SCAN_ITEM_SIZE 768 -#define MAX_CUSTOM_LEN 64 -#define RATE_COUNT 4 - -static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, - 6000000, 9000000, 12000000, 18000000, - 24000000, 36000000, 48000000, 54000000}; - -static const long ieee80211_wlan_frequencies[] = { - 2412, 2417, 2422, 2427, - 2432, 2437, 2442, 2447, - 2452, 2457, 2462, 2467, - 2472, 2484 -}; - -void r8712_indicate_wx_assoc_event(struct _adapter *padapter) -{ - union iwreq_data wrqu; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, - ETH_ALEN); - wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); -} - -void r8712_indicate_wx_disassoc_event(struct _adapter *padapter) -{ - union iwreq_data wrqu; - - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - eth_zero_addr(wrqu.ap_addr.sa_data); - wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL); -} - -static inline void handle_pairwise_key(struct sta_info *psta, - struct ieee_param *param, - struct _adapter *padapter) -{ - /* pairwise key */ - memcpy(psta->x_UncstKey.skey, param->u.crypt.key, - (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len)); - if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */ - memcpy(psta->tkiptxmickey. skey, - ¶m->u.crypt.key[16], 8); - memcpy(psta->tkiprxmickey. skey, - ¶m->u.crypt.key[24], 8); - padapter->securitypriv. busetkipkey = false; - mod_timer(&padapter->securitypriv.tkip_timer, - jiffies + msecs_to_jiffies(50)); - } - r8712_setstakey_cmd(padapter, (unsigned char *)psta, true); -} - -static inline void handle_group_key(struct ieee_param *param, - struct _adapter *padapter) -{ - union Keytype *gk = padapter->securitypriv.XGrpKey; - union Keytype *gtk = padapter->securitypriv.XGrptxmickey; - union Keytype *grk = padapter->securitypriv.XGrprxmickey; - - if (param->u.crypt.idx > 0 && - param->u.crypt.idx < 3) { - /* group key idx is 1 or 2 */ - memcpy(gk[param->u.crypt.idx - 1].skey, - param->u.crypt.key, - (param->u.crypt.key_len > 16 ? 16 : - param->u.crypt.key_len)); - memcpy(gtk[param->u.crypt.idx - 1].skey, - ¶m->u.crypt.key[16], 8); - memcpy(grk[param->u.crypt.idx - 1].skey, - ¶m->u.crypt.key[24], 8); - padapter->securitypriv.binstallGrpkey = true; - r8712_set_key(padapter, &padapter->securitypriv, - param->u.crypt.idx); - if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) { - if (padapter->registrypriv.power_mgnt != - padapter->pwrctrlpriv.pwr_mode) - mod_timer(&padapter->mlmepriv.dhcp_timer, - jiffies + msecs_to_jiffies(60000)); - } - } -} - -static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info, - struct wlan_network *pnetwork, - struct iw_event *iwe, - char *start, char *stop) -{ - /* parsing WPA/WPA2 IE */ - u8 buf[MAX_WPA_IE_LEN]; - u8 wpa_ie[255], rsn_ie[255]; - u16 wpa_len = 0, rsn_len = 0; - int n, i; - - r8712_get_sec_ie(pnetwork->network.IEs, - pnetwork->network.IELength, rsn_ie, &rsn_len, - wpa_ie, &wpa_len); - if (wpa_len > 0) { - memset(buf, 0, MAX_WPA_IE_LEN); - n = sprintf(buf, "wpa_ie="); - for (i = 0; i < wpa_len; i++) { - n += scnprintf(buf + n, MAX_WPA_IE_LEN - n, - "%02x", wpa_ie[i]); - if (n == MAX_WPA_IE_LEN - 1) - break; - } - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVCUSTOM; - iwe->u.data.length = (u16)strlen(buf); - start = iwe_stream_add_point(info, start, stop, - iwe, buf); - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVGENIE; - iwe->u.data.length = (u16)wpa_len; - start = iwe_stream_add_point(info, start, stop, - iwe, wpa_ie); - } - if (rsn_len > 0) { - memset(buf, 0, MAX_WPA_IE_LEN); - n = sprintf(buf, "rsn_ie="); - for (i = 0; i < rsn_len; i++) { - n += scnprintf(buf + n, MAX_WPA_IE_LEN - n, - "%02x", rsn_ie[i]); - if (n == MAX_WPA_IE_LEN - 1) - break; - } - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVCUSTOM; - iwe->u.data.length = strlen(buf); - start = iwe_stream_add_point(info, start, stop, - iwe, buf); - memset(iwe, 0, sizeof(*iwe)); - iwe->cmd = IWEVGENIE; - iwe->u.data.length = rsn_len; - start = iwe_stream_add_point(info, start, stop, iwe, - rsn_ie); - } - - return start; -} - -static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info, - struct wlan_network *pnetwork, - struct iw_event *iwe, - char *start, char *stop) -{ - /* parsing WPS IE */ - u8 wps_ie[512]; - uint wps_ielen; - - if (r8712_get_wps_ie(pnetwork->network.IEs, - pnetwork->network.IELength, - wps_ie, &wps_ielen)) { - if (wps_ielen > 2) { - iwe->cmd = IWEVGENIE; - iwe->u.data.length = (u16)wps_ielen; - start = iwe_stream_add_point(info, start, stop, - iwe, wps_ie); - } - } - - return start; -} - -static char *translate_scan(struct _adapter *padapter, - struct iw_request_info *info, - struct wlan_network *pnetwork, - char *start, char *stop) -{ - struct iw_event iwe; - char *current_val; - s8 *p; - u32 i = 0, ht_ielen = 0; - u16 cap, ht_cap = false; - u8 rssi; - - if ((pnetwork->network.Configuration.DSConfig < 1) || - (pnetwork->network.Configuration.DSConfig > 14)) { - if (pnetwork->network.Configuration.DSConfig < 1) - pnetwork->network.Configuration.DSConfig = 1; - else - pnetwork->network.Configuration.DSConfig = 14; - } - /* AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); - /* Add the ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, - pnetwork->network.Ssid.Ssid); - /* parsing HT_CAP_IE */ - p = r8712_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY, - &ht_ielen, pnetwork->network.IELength - 12); - if (p && ht_ielen > 0) - ht_cap = true; - /* Add the protocol name */ - iwe.cmd = SIOCGIWNAME; - if (r8712_is_cckratesonly_included(pnetwork->network.rates)) { - if (ht_cap) - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn"); - else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b"); - } else if (r8712_is_cckrates_included(pnetwork->network.rates)) { - if (ht_cap) - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn"); - else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg"); - } else { - if (ht_cap) - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn"); - else - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g"); - } - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs), - 2); - le16_to_cpus(&cap); - if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_ESS)) { - if (cap & WLAN_CAPABILITY_ESS) - iwe.u.mode = (u32)IW_MODE_MASTER; - else - iwe.u.mode = (u32)IW_MODE_ADHOC; - start = iwe_stream_add_event(info, start, stop, &iwe, - IW_EV_UINT_LEN); - } - /* Add frequency/channel */ - iwe.cmd = SIOCGIWFREQ; - { - /* check legal index */ - u8 dsconfig = pnetwork->network.Configuration.DSConfig; - - if (dsconfig >= 1 && dsconfig <= sizeof( - ieee80211_wlan_frequencies) / sizeof(long)) - iwe.u.freq.m = - (s32)(ieee80211_wlan_frequencies - [dsconfig - 1] * 100000); - else - iwe.u.freq.m = 0; - } - iwe.u.freq.e = (s16)1; - iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig; - start = iwe_stream_add_event(info, start, stop, &iwe, - IW_EV_FREQ_LEN); - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (cap & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED | - IW_ENCODE_NOKEY); - else - iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED); - iwe.u.data.length = (u16)0; - start = iwe_stream_add_point(info, start, stop, &iwe, - pnetwork->network.Ssid.Ssid); - /*Add basic and extended rates */ - current_val = start + iwe_stream_lcp_len(info); - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = 0; - iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = 0; - i = 0; - while (pnetwork->network.rates[i] != 0) { - /* Bit rate given in 500 kb/s units */ - iwe.u.bitrate.value = (pnetwork->network.rates[i++] & - 0x7F) * 500000; - current_val = iwe_stream_add_value(info, start, current_val, - stop, &iwe, IW_EV_PARAM_LEN); - } - /* Check if we added any event */ - if ((current_val - start) > iwe_stream_lcp_len(info)) - start = current_val; - - start = translate_scan_wpa(info, pnetwork, &iwe, start, stop); - - start = translate_scan_wps(info, pnetwork, &iwe, start, stop); - - /* Add quality statistics */ - iwe.cmd = IWEVQUAL; - rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi); - /* we only update signal_level (signal strength) that is rssi. */ - iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | - IW_QUAL_NOISE_INVALID); - iwe.u.qual.level = rssi; /* signal strength */ - iwe.u.qual.qual = 0; /* signal quality */ - iwe.u.qual.noise = 0; /* noise level */ - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); - /* how to translate rssi to ?% */ - return start; -} - -static int wpa_set_auth_algs(struct net_device *dev, u32 value) -{ - struct _adapter *padapter = netdev_priv(dev); - int ret = 0; - - if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeAutoSwitch; - padapter->securitypriv.AuthAlgrthm = 3; - } else if (value & AUTH_ALG_SHARED_KEY) { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared; - padapter->securitypriv.AuthAlgrthm = 1; - } else if (value & AUTH_ALG_OPEN_SYSTEM) { - if (padapter->securitypriv.ndisauthtype < - Ndis802_11AuthModeWPAPSK) { - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeOpen; - padapter->securitypriv.AuthAlgrthm = 0; - } - } else { - ret = -EINVAL; - } - return ret; -} - -static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, - u32 param_len) -{ - int ret = 0; - u32 wep_key_idx, wep_key_len = 0; - struct NDIS_802_11_WEP *pwep = NULL; - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - param->u.crypt.err = 0; - param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) + - param->u.crypt.key_len) - return -EINVAL; - if (!is_broadcast_ether_addr(param->sta_addr)) - return -EINVAL; - - if (param->u.crypt.idx >= WEP_KEYS) { - /* for large key indices, set the default (0) */ - param->u.crypt.idx = 0; - } - if (strcmp(param->u.crypt.alg, "WEP") == 0) { - netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.PrivacyAlgrthm = _WEP40_; - padapter->securitypriv.XGrpPrivacy = _WEP40_; - wep_key_idx = param->u.crypt.idx; - wep_key_len = param->u.crypt.key_len; - if (wep_key_idx >= WEP_KEYS) - wep_key_idx = 0; - if (wep_key_len <= 0) - return -EINVAL; - - wep_key_len = wep_key_len <= 5 ? 5 : 13; - pwep = kzalloc(sizeof(*pwep), GFP_ATOMIC); - if (!pwep) - return -ENOMEM; - pwep->KeyLength = wep_key_len; - pwep->Length = wep_key_len + - offsetof(struct NDIS_802_11_WEP, KeyMaterial); - if (wep_key_len == 13) { - padapter->securitypriv.PrivacyAlgrthm = _WEP104_; - padapter->securitypriv.XGrpPrivacy = _WEP104_; - } - pwep->KeyIndex = wep_key_idx; - pwep->KeyIndex |= 0x80000000; - memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength); - if (param->u.crypt.set_tx) { - if (r8712_set_802_11_add_wep(padapter, pwep)) - ret = -EOPNOTSUPP; - } else { - /* don't update "psecuritypriv->PrivacyAlgrthm" and - * "psecuritypriv->PrivacyKeyIndex=keyid", but can - * r8712_set_key to fw/cam - */ - if (wep_key_idx >= WEP_KEYS) { - ret = -EOPNOTSUPP; - goto exit; - } - memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0], - pwep->KeyMaterial, - pwep->KeyLength); - psecuritypriv->DefKeylen[wep_key_idx] = - pwep->KeyLength; - r8712_set_key(padapter, psecuritypriv, wep_key_idx); - } - goto exit; - } - if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */ - struct sta_info *psta, *pbcmc_sta; - struct sta_priv *pstapriv = &padapter->stapriv; - struct security_priv *spriv = &padapter->securitypriv; - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | - WIFI_MP_STATE)) { /* sta mode */ - psta = r8712_get_stainfo(pstapriv, - get_bssid(pmlmepriv)); - if (psta) { - psta->ieee8021x_blocked = false; - if (spriv->ndisencryptstatus == - Ndis802_11Encryption2Enabled || - spriv->ndisencryptstatus == - Ndis802_11Encryption3Enabled) - psta->XPrivacy = spriv->PrivacyAlgrthm; - if (param->u.crypt.set_tx == 1) - handle_pairwise_key(psta, param, - padapter); - else /* group key */ - handle_group_key(param, padapter); - } - pbcmc_sta = r8712_get_bcmc_stainfo(padapter); - if (pbcmc_sta) { - pbcmc_sta->ieee8021x_blocked = false; - if (spriv->ndisencryptstatus == - Ndis802_11Encryption2Enabled || - spriv->ndisencryptstatus == - Ndis802_11Encryption3Enabled) - pbcmc_sta->XPrivacy = - spriv->PrivacyAlgrthm; - } - } - } -exit: - kfree(pwep); - return ret; -} - -static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie, - unsigned short ielen) -{ - u8 *buf = NULL; - int group_cipher = 0, pairwise_cipher = 0; - int ret = 0; - - if (ielen > MAX_WPA_IE_LEN || !pie) - return -EINVAL; - if (ielen) { - buf = kmemdup(pie, ielen, GFP_ATOMIC); - if (!buf) - return -ENOMEM; - if (ielen < RSN_HEADER_LEN) { - ret = -EINVAL; - goto exit; - } - if (r8712_parse_wpa_ie(buf, ielen, &group_cipher, - &pairwise_cipher) == 0) { - padapter->securitypriv.AuthAlgrthm = 2; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPAPSK; - } - if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher, - &pairwise_cipher) == 0) { - padapter->securitypriv.AuthAlgrthm = 2; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPA2PSK; - } - switch (group_cipher) { - case WPA_CIPHER_NONE: - padapter->securitypriv.XGrpPrivacy = - _NO_PRIVACY_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11EncryptionDisabled; - break; - case WPA_CIPHER_WEP40: - padapter->securitypriv.XGrpPrivacy = _WEP40_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - break; - case WPA_CIPHER_TKIP: - padapter->securitypriv.XGrpPrivacy = _TKIP_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption2Enabled; - break; - case WPA_CIPHER_CCMP: - padapter->securitypriv.XGrpPrivacy = _AES_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption3Enabled; - break; - case WPA_CIPHER_WEP104: - padapter->securitypriv.XGrpPrivacy = _WEP104_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - break; - } - switch (pairwise_cipher) { - case WPA_CIPHER_NONE: - padapter->securitypriv.PrivacyAlgrthm = - _NO_PRIVACY_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11EncryptionDisabled; - break; - case WPA_CIPHER_WEP40: - padapter->securitypriv.PrivacyAlgrthm = _WEP40_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - break; - case WPA_CIPHER_TKIP: - padapter->securitypriv.PrivacyAlgrthm = _TKIP_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption2Enabled; - break; - case WPA_CIPHER_CCMP: - padapter->securitypriv.PrivacyAlgrthm = _AES_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption3Enabled; - break; - case WPA_CIPHER_WEP104: - padapter->securitypriv.PrivacyAlgrthm = _WEP104_; - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - break; - } - padapter->securitypriv.wps_phase = false; - {/* set wps_ie */ - u16 cnt = 0; - u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; - - while (cnt < ielen) { - eid = buf[cnt]; - - if ((eid == WLAN_EID_VENDOR_SPECIFIC) && - (!memcmp(&buf[cnt + 2], wps_oui, 4))) { - netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n"); - padapter->securitypriv.wps_ie_len = - ((buf[cnt + 1] + 2) < - (MAX_WPA_IE_LEN << 2)) ? - (buf[cnt + 1] + 2) : - (MAX_WPA_IE_LEN << 2); - memcpy(padapter->securitypriv.wps_ie, - &buf[cnt], - padapter->securitypriv.wps_ie_len); - padapter->securitypriv.wps_phase = - true; - netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n"); - cnt += buf[cnt + 1] + 2; - break; - } - - cnt += buf[cnt + 1] + 2; - } - } - } -exit: - kfree(buf); - return ret; -} - -static int r8711_wx_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 ht_ielen = 0; - char *p; - u8 ht_cap = false; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - u8 *prates; - - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == - true) { - /* parsing HT_CAP_IE */ - p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, - &ht_ielen, pcur_bss->IELength - 12); - if (p && ht_ielen > 0) - ht_cap = true; - prates = pcur_bss->rates; - if (r8712_is_cckratesonly_included(prates)) { - if (ht_cap) - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11bn"); - else - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11b"); - } else if (r8712_is_cckrates_included(prates)) { - if (ht_cap) - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11bgn"); - else - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11bg"); - } else { - if (ht_cap) - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11gn"); - else - snprintf(wrqu->name, IFNAMSIZ, - "IEEE 802.11g"); - } - } else { - snprintf(wrqu->name, IFNAMSIZ, "unassociated"); - } - return 0; -} - -static const long frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, - 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, - 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, - 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805, - 5825 -}; - -static int r8711_wx_set_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_freq *fwrq = &wrqu->freq; - int rc = 0; - -/* If setting by frequency, convert to a channel */ - if ((fwrq->e == 1) && - (fwrq->m >= 241200000) && - (fwrq->m <= 248700000)) { - int f = fwrq->m / 100000; - int c = 0; - - while ((c < 14) && (f != frequency_list[c])) - c++; - fwrq->e = 0; - fwrq->m = c + 1; - } - /* Setting by channel number */ - if ((fwrq->m > 14) || (fwrq->e > 0)) { - rc = -EOPNOTSUPP; - } else { - int channel = fwrq->m; - - if ((channel < 1) || (channel > 14)) { - rc = -EINVAL; - } else { - /* Yes ! We can set it !!! */ - padapter->registrypriv.channel = channel; - } - } - return rc; -} - -static int r8711_wx_get_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - - if (!check_fwstate(pmlmepriv, _FW_LINKED)) - return -ENOLINK; - - wrqu->freq.m = ieee80211_wlan_frequencies[ - pcur_bss->Configuration.DSConfig - 1] * 100000; - wrqu->freq.e = 1; - wrqu->freq.i = pcur_bss->Configuration.DSConfig; - - return 0; -} - -static int r8711_wx_set_mode(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct _adapter *padapter = netdev_priv(dev); - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; - - switch (wrqu->mode) { - case IW_MODE_AUTO: - networkType = Ndis802_11AutoUnknown; - break; - case IW_MODE_ADHOC: - networkType = Ndis802_11IBSS; - break; - case IW_MODE_MASTER: - networkType = Ndis802_11APMode; - break; - case IW_MODE_INFRA: - networkType = Ndis802_11Infrastructure; - break; - default: - return -EINVAL; - } - if (Ndis802_11APMode == networkType) - r8712_setopmode_cmd(padapter, networkType); - else - r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown); - - r8712_set_802_11_infrastructure_mode(padapter, networkType); - return 0; -} - -static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - wrqu->mode = IW_MODE_INFRA; - else if (check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE)) - wrqu->mode = IW_MODE_ADHOC; - else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) - wrqu->mode = IW_MODE_MASTER; - else - wrqu->mode = IW_MODE_AUTO; - return 0; -} - -static int r871x_wx_set_pmkid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct iw_pmksa *pPMK = (struct iw_pmksa *) extra; - struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList; - u8 strZeroMacAddress[ETH_ALEN] = {0x00}; - u8 strIssueBssid[ETH_ALEN] = {0x00}; - u8 j, blInserted = false; - int intReturn = false; - -/* - * There are the BSSID information in the bssid.sa_data array. - * If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear - * all the PMKID information. If cmd is IW_PMKSA_ADD, it means the - * wpa_supplicant wants to add a PMKID/BSSID to driver. - * If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to - * remove a PMKID/BSSID from driver. - */ - if (!pPMK) - return -EINVAL; - memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN); - switch (pPMK->cmd) { - case IW_PMKSA_ADD: - if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN)) - return intReturn; - intReturn = true; - blInserted = false; - /* overwrite PMKID */ - for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { - /* BSSID is matched, the same AP => rewrite - * with new PMKID. - */ - netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n", - __func__); - memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); - pl[j].bUsed = true; - psecuritypriv->PMKIDIndex = j + 1; - blInserted = true; - break; - } - } - if (!blInserted) { - /* Find a new entry */ - netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n", - __func__, psecuritypriv->PMKIDIndex); - memcpy(pl[psecuritypriv->PMKIDIndex].Bssid, - strIssueBssid, ETH_ALEN); - memcpy(pl[psecuritypriv->PMKIDIndex].PMKID, - pPMK->pmkid, IW_PMKID_LEN); - pl[psecuritypriv->PMKIDIndex].bUsed = true; - psecuritypriv->PMKIDIndex++; - if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE) - psecuritypriv->PMKIDIndex = 0; - } - break; - case IW_PMKSA_REMOVE: - intReturn = true; - for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { - /* BSSID is matched, the same AP => Remove - * this PMKID information and reset it. - */ - eth_zero_addr(pl[j].Bssid); - pl[j].bUsed = false; - break; - } - } - break; - case IW_PMKSA_FLUSH: - memset(psecuritypriv->PMKIDList, 0, - sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - psecuritypriv->PMKIDIndex = 0; - intReturn = true; - break; - default: - netdev_info(dev, "r8712u: %s: unknown Command\n", __func__); - intReturn = false; - break; - } - return intReturn; -} - -static int r8711_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->sens.value = 0; - wrqu->sens.fixed = 0; /* no auto select */ - wrqu->sens.disabled = 1; - return 0; -} - -static int r8711_wx_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - u16 val; - int i; - - wrqu->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - /* Let's try to keep this struct in the same order as in - * linux/include/wireless.h - */ - - /* TODO: See what values we can set, and remove the ones we can't - * set, or fill them with some default data. - */ - /* ~5 Mb/s real (802.11b) */ - range->throughput = 5 * 1000 * 1000; - /* TODO: 8711 sensitivity ? */ - /* signal level threshold range */ - /* percent values between 0 and 100. */ - range->max_qual.qual = 100; - range->max_qual.level = 100; - range->max_qual.noise = 100; - range->max_qual.updated = 7; /* Updated all three */ - range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ - range->avg_qual.level = 0x100 - 78; - range->avg_qual.noise = 0; - range->avg_qual.updated = 7; /* Updated all three */ - range->num_bitrates = RATE_COUNT; - for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = rtl8180_rates[i]; - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - range->pm_capa = 0; - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; - range->num_channels = 14; - for (i = 0, val = 0; i < 14; i++) { - /* Include only legal frequencies for some countries */ - range->freq[val].i = i + 1; - range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; - range->freq[val].e = 1; - val++; - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - range->enc_capa = IW_ENC_CAPA_WPA | - IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | - IW_ENC_CAPA_CIPHER_CCMP; - return 0; -} - -static int r8711_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -static int r871x_wx_set_priv(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - int ret = 0, len = 0; - char *ext; - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *dwrq = (struct iw_point *)awrq; - - len = dwrq->length; - ext = strndup_user(dwrq->pointer, len); - if (IS_ERR(ext)) - return PTR_ERR(ext); - - if (!strcasecmp(ext, "RSSI")) { - /*Return received signal strength indicator in -db for */ - /* current AP */ - /* Rssi xx */ - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct wlan_network *pcur_network = &pmlmepriv->cur_network; - /*static u8 xxxx; */ - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - sprintf(ext, "%s rssi %d", - pcur_network->network.Ssid.Ssid, - /*(xxxx=xxxx+10) */ - ((padapter->recvpriv.fw_rssi) >> 1) - 95 - /*pcur_network->network.Rssi */ - ); - } else { - sprintf(ext, "OK"); - } - } else if (!strcasecmp(ext, "LINKSPEED")) { - /*Return link speed in MBPS */ - /*LinkSpeed xx */ - union iwreq_data wrqd; - int ret_inner; - int mbps; - - ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra); - if (ret_inner != 0) - mbps = 0; - else - mbps = wrqd.bitrate.value / 1000000; - sprintf(ext, "LINKSPEED %d", mbps); - } else if (!strcasecmp(ext, "MACADDR")) { - /*Return mac address of the station */ - /* Macaddr = xx:xx:xx:xx:xx:xx */ - sprintf(ext, "MACADDR = %pM", dev->dev_addr); - } else if (!strcasecmp(ext, "SCAN-ACTIVE")) { - /*Set scan type to active */ - /*OK if successful */ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - pmlmepriv->passive_mode = 1; - sprintf(ext, "OK"); - } else if (!strcasecmp(ext, "SCAN-PASSIVE")) { - /*Set scan type to passive */ - /*OK if successful */ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - pmlmepriv->passive_mode = 0; - sprintf(ext, "OK"); - } else if (!strncmp(ext, "DCE-E", 5)) { - /*Set scan type to passive */ - /*OK if successful */ - r8712_disconnectCtrlEx_cmd(padapter - , 1 /*u32 enableDrvCtrl */ - , 5 /*u32 tryPktCnt */ - , 100 /*u32 tryPktInterval */ - , 5000 /*u32 firstStageTO */ - ); - sprintf(ext, "OK"); - } else if (!strncmp(ext, "DCE-D", 5)) { - /*Set scan type to passive */ - /*OK if successfu */ - r8712_disconnectCtrlEx_cmd(padapter - , 0 /*u32 enableDrvCtrl */ - , 5 /*u32 tryPktCnt */ - , 100 /*u32 tryPktInterval */ - , 5000 /*u32 firstStageTO */ - ); - sprintf(ext, "OK"); - } else { - netdev_info(dev, "r8712u: %s: unknown Command %s.\n", - __func__, ext); - goto FREE_EXT; - } - if (copy_to_user(dwrq->pointer, ext, - min(dwrq->length, (__u16)(strlen(ext) + 1)))) - ret = -EFAULT; - -FREE_EXT: - kfree(ext); - return ret; -} - -/* set bssid flow - * s1. set_802_11_infrastructure_mode() - * s2. set_802_11_authentication_mode() - * s3. set_802_11_encryption_mode() - * s4. set_802_11_bssid() - * - * This function intends to handle the Set AP command, which specifies the - * MAC# of a preferred Access Point. - * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl. - * - * For this operation to succeed, there is no need for the interface to be up. - * - */ -static int r8711_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - int ret = -EINPROGRESS; - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct sockaddr *temp = (struct sockaddr *)awrq; - unsigned long irqL; - struct list_head *phead; - u8 *dst_bssid; - struct wlan_network *pnetwork = NULL; - enum NDIS_802_11_AUTHENTICATION_MODE authmode; - - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) - return -EBUSY; - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - return ret; - if (temp->sa_family != ARPHRD_ETHER) - return -EINVAL; - authmode = padapter->securitypriv.ndisauthtype; - spin_lock_irqsave(&queue->lock, irqL); - phead = &queue->queue; - pmlmepriv->pscanned = phead->next; - while (1) { - if (end_of_queue_search(phead, pmlmepriv->pscanned)) - break; - pnetwork = container_of(pmlmepriv->pscanned, - struct wlan_network, list); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - dst_bssid = pnetwork->network.MacAddress; - if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) { - r8712_set_802_11_infrastructure_mode(padapter, - pnetwork->network.InfrastructureMode); - break; - } - } - spin_unlock_irqrestore(&queue->lock, irqL); - if (!ret) { - if (!r8712_set_802_11_authentication_mode(padapter, authmode)) { - ret = -ENOMEM; - } else { - if (!r8712_set_802_11_bssid(padapter, temp->sa_data)) - ret = -1; - } - } - return ret; -} - -static int r8711_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - - wrqu->ap_addr.sa_family = ARPHRD_ETHER; - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE | - WIFI_AP_STATE)) - ether_addr_copy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress); - else - eth_zero_addr(wrqu->ap_addr.sa_data); - return 0; -} - -static int r871x_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct _adapter *padapter = netdev_priv(dev); - struct iw_mlme *mlme = (struct iw_mlme *) extra; - - if (!mlme) - return -1; - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - if (!r8712_set_802_11_disassociate(padapter)) - ret = -1; - break; - case IW_MLME_DISASSOC: - if (!r8712_set_802_11_disassociate(padapter)) - ret = -1; - break; - default: - return -EOPNOTSUPP; - } - return ret; -} - -/* - * - * This function intends to handle the Set Scan command. - * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl. - * - * For this operation to succeed, the interface is brought Up beforehand. - * - */ -static int r8711_wx_set_scan(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 status = true; - - if (padapter->driver_stopped) { - netdev_info(dev, "In %s: driver_stopped=%d\n", - __func__, padapter->driver_stopped); - return -1; - } - if (!padapter->bup) - return -ENETDOWN; - if (!padapter->hw_init_completed) - return -1; - if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) || - (pmlmepriv->sitesurveyctrl.traffic_busy)) - return 0; - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct ndis_802_11_ssid ssid; - unsigned long irqL; - u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE); - - memset((unsigned char *)&ssid, 0, - sizeof(struct ndis_802_11_ssid)); - memcpy(ssid.Ssid, req->essid, len); - ssid.SsidLength = len; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) || - (pmlmepriv->sitesurveyctrl.traffic_busy)) { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - status = false; - } else { - status = r8712_sitesurvey_cmd(padapter, &ssid); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - } - } else { - status = r8712_set_802_11_bssid_list_scan(padapter); - } - if (!status) - return -1; - return 0; -} - -static int r8711_wx_get_scan(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct wlan_network *pnetwork = NULL; - unsigned long irqL; - struct list_head *plist, *phead; - char *ev = extra; - char *stop = ev + wrqu->data.length; - u32 ret = 0, cnt = 0; - - if (padapter->driver_stopped) - return -EINVAL; - while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) { - msleep(30); - cnt++; - if (cnt > 100) - break; - } - spin_lock_irqsave(&queue->lock, irqL); - phead = &queue->queue; - plist = phead->next; - while (1) { - if (end_of_queue_search(phead, plist)) - break; - if ((stop - ev) < SCAN_ITEM_SIZE) { - ret = -E2BIG; - break; - } - pnetwork = container_of(plist, struct wlan_network, list); - ev = translate_scan(padapter, a, pnetwork, ev, stop); - plist = plist->next; - } - spin_unlock_irqrestore(&queue->lock, irqL); - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; - return ret; -} - -/* set ssid flow - * s1. set_802_11_infrastructure_mode() - * s2. set_802_11_authenticaion_mode() - * s3. set_802_11_encryption_mode() - * s4. set_802_11_ssid() - * - * This function intends to handle the Set ESSID command. - * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl. - * - * For this operation to succeed, there is no need for the interface to be Up. - * - */ -static int r8711_wx_set_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct wlan_network *pnetwork = NULL; - enum NDIS_802_11_AUTHENTICATION_MODE authmode; - struct ndis_802_11_ssid ndis_ssid; - u8 *dst_ssid, *src_ssid; - struct list_head *phead; - u32 len; - - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) - return -EBUSY; - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - return 0; - if (wrqu->essid.length > IW_ESSID_MAX_SIZE) - return -E2BIG; - authmode = padapter->securitypriv.ndisauthtype; - if (wrqu->essid.flags && wrqu->essid.length) { - len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? - wrqu->essid.length : IW_ESSID_MAX_SIZE; - memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid)); - ndis_ssid.SsidLength = len; - memcpy(ndis_ssid.Ssid, extra, len); - src_ssid = ndis_ssid.Ssid; - phead = &queue->queue; - pmlmepriv->pscanned = phead->next; - while (1) { - if (end_of_queue_search(phead, pmlmepriv->pscanned)) - break; - pnetwork = container_of(pmlmepriv->pscanned, - struct wlan_network, list); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - dst_ssid = pnetwork->network.Ssid.Ssid; - if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) - && (pnetwork->network.Ssid.SsidLength == - ndis_ssid.SsidLength)) { - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_STATE)) { - if (pnetwork->network. - InfrastructureMode - != - padapter->mlmepriv. - cur_network.network. - InfrastructureMode) - continue; - } - - r8712_set_802_11_infrastructure_mode( - padapter, - pnetwork->network.InfrastructureMode); - break; - } - } - r8712_set_802_11_authentication_mode(padapter, authmode); - r8712_set_802_11_ssid(padapter, &ndis_ssid); - } - return -EINPROGRESS; -} - -static int r8711_wx_get_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - u32 len, ret = 0; - - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { - len = pcur_bss->Ssid.SsidLength; - wrqu->essid.length = len; - memcpy(extra, pcur_bss->Ssid.Ssid, len); - wrqu->essid.flags = 1; - } else { - ret = -ENOLINK; - } - return ret; -} - -static int r8711_wx_set_rate(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 target_rate = wrqu->bitrate.value; - u32 fixed = wrqu->bitrate.fixed; - u32 ratevalue = 0; - u8 datarates[NumRates]; - u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff}; - int i; - - if (target_rate == -1) { - ratevalue = 11; - goto set_rate; - } - target_rate = target_rate / 100000; - switch (target_rate) { - case 10: - ratevalue = 0; - break; - case 20: - ratevalue = 1; - break; - case 55: - ratevalue = 2; - break; - case 60: - ratevalue = 3; - break; - case 90: - ratevalue = 4; - break; - case 110: - ratevalue = 5; - break; - case 120: - ratevalue = 6; - break; - case 180: - ratevalue = 7; - break; - case 240: - ratevalue = 8; - break; - case 360: - ratevalue = 9; - break; - case 480: - ratevalue = 10; - break; - case 540: - ratevalue = 11; - break; - default: - ratevalue = 11; - break; - } -set_rate: - for (i = 0; i < NumRates; i++) { - if (ratevalue == mpdatarate[i]) { - datarates[i] = mpdatarate[i]; - if (fixed == 0) - break; - } else { - datarates[i] = 0xff; - } - } - return r8712_setdatarate_cmd(padapter, datarates); -} - -static int r8711_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - struct ieee80211_ht_cap *pht_capie; - unsigned char rf_type = padapter->registrypriv.rf_config; - int i; - u8 *p; - u16 rate, max_rate = 0, ht_cap = false; - u32 ht_ielen = 0; - u8 bw_40MHz = 0, short_GI = 0; - u16 mcs_rate = 0; - - i = 0; - if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) - return -ENOLINK; - p = r8712_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, - pcur_bss->IELength - 12); - if (p && ht_ielen > 0) { - ht_cap = true; - pht_capie = (struct ieee80211_ht_cap *)(p + 2); - memcpy(&mcs_rate, &pht_capie->mcs, 2); - bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & - IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; - short_GI = (le16_to_cpu(pht_capie->cap_info) & - (IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; - } - while ((pcur_bss->rates[i] != 0) && - (pcur_bss->rates[i] != 0xFF)) { - rate = pcur_bss->rates[i] & 0x7F; - if (rate > max_rate) - max_rate = rate; - wrqu->bitrate.fixed = 0; /* no auto select */ - wrqu->bitrate.value = rate * 500000; - i++; - } - if (ht_cap) { - if (mcs_rate & 0x8000 /* MCS15 */ - && - rf_type == RTL8712_RF_2T2R) - max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : - ((short_GI) ? 144 : 130); - else /* default MCS7 */ - max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : - ((short_GI) ? 72 : 65); - max_rate *= 2; /* Mbps/2 */ - } - wrqu->bitrate.value = max_rate * 500000; - return 0; -} - -static int r8711_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - wrqu->rts.value = padapter->registrypriv.rts_thresh; - wrqu->rts.fixed = 0; /* no auto select */ - return 0; -} - -static int r8711_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - if (wrqu->frag.disabled) { - padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD; - } else { - if (wrqu->frag.value < MIN_FRAG_THRESHOLD || - wrqu->frag.value > MAX_FRAG_THRESHOLD) - return -EINVAL; - padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1; - } - return 0; -} - -static int r8711_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - wrqu->frag.value = padapter->xmitpriv.frag_len; - wrqu->frag.fixed = 0; /* no auto select */ - return 0; -} - -static int r8711_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->retry.value = 7; - wrqu->retry.fixed = 0; /* no auto select */ - wrqu->retry.disabled = 1; - return 0; -} - -static int r8711_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - u32 key; - u32 keyindex_provided; - struct NDIS_802_11_WEP wep; - enum NDIS_802_11_AUTHENTICATION_MODE authmode; - struct iw_point *erq = &wrqu->encoding; - struct _adapter *padapter = netdev_priv(dev); - - key = erq->flags & IW_ENCODE_INDEX; - memset(&wep, 0, sizeof(struct NDIS_802_11_WEP)); - if (erq->flags & IW_ENCODE_DISABLED) { - netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11EncryptionDisabled; - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - padapter->securitypriv.AuthAlgrthm = 0; /* open system */ - authmode = Ndis802_11AuthModeOpen; - padapter->securitypriv.ndisauthtype = authmode; - return 0; - } - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - keyindex_provided = 1; - } else { - keyindex_provided = 0; - key = padapter->securitypriv.PrivacyKeyIndex; - } - /* set authentication mode */ - if (erq->flags & IW_ENCODE_OPEN) { - netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.AuthAlgrthm = 0; /* open system */ - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - authmode = Ndis802_11AuthModeOpen; - padapter->securitypriv.ndisauthtype = authmode; - } else if (erq->flags & IW_ENCODE_RESTRICTED) { - netdev_info(dev, - "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__); - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.AuthAlgrthm = 1; /* shared system */ - padapter->securitypriv.PrivacyAlgrthm = _WEP40_; - padapter->securitypriv.XGrpPrivacy = _WEP40_; - authmode = Ndis802_11AuthModeShared; - padapter->securitypriv.ndisauthtype = authmode; - } else { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption1Enabled; - padapter->securitypriv.AuthAlgrthm = 0; /* open system */ - padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_; - authmode = Ndis802_11AuthModeOpen; - padapter->securitypriv.ndisauthtype = authmode; - } - wep.KeyIndex = key; - if (erq->length > 0) { - wep.KeyLength = erq->length <= 5 ? 5 : 13; - wep.Length = wep.KeyLength + - offsetof(struct NDIS_802_11_WEP, KeyMaterial); - } else { - wep.KeyLength = 0; - if (keyindex_provided == 1) { /* set key_id only, no given - * KeyMaterial(erq->length==0). - */ - padapter->securitypriv.PrivacyKeyIndex = key; - switch (padapter->securitypriv.DefKeylen[key]) { - case 5: - padapter->securitypriv.PrivacyAlgrthm = - _WEP40_; - break; - case 13: - padapter->securitypriv.PrivacyAlgrthm = - _WEP104_; - break; - default: - padapter->securitypriv.PrivacyAlgrthm = - _NO_PRIVACY_; - break; - } - return 0; - } - } - wep.KeyIndex |= 0x80000000; /* transmit key */ - memcpy(wep.KeyMaterial, keybuf, wep.KeyLength); - if (r8712_set_802_11_add_wep(padapter, &wep)) - return -EOPNOTSUPP; - return 0; -} - -static int r8711_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - uint key; - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *erq = &wrqu->encoding; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - union Keytype *dk = padapter->securitypriv.DefKey; - - if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - } - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - } else { - key = padapter->securitypriv.PrivacyKeyIndex; - } - erq->flags = key + 1; - switch (padapter->securitypriv.ndisencryptstatus) { - case Ndis802_11EncryptionNotSupported: - case Ndis802_11EncryptionDisabled: - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - break; - case Ndis802_11Encryption1Enabled: - erq->length = padapter->securitypriv.DefKeylen[key]; - if (erq->length) { - memcpy(keybuf, dk[key].skey, - padapter->securitypriv.DefKeylen[key]); - erq->flags |= IW_ENCODE_ENABLED; - if (padapter->securitypriv.ndisauthtype == - Ndis802_11AuthModeOpen) - erq->flags |= IW_ENCODE_OPEN; - else if (padapter->securitypriv.ndisauthtype == - Ndis802_11AuthModeShared) - erq->flags |= IW_ENCODE_RESTRICTED; - } else { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - } - break; - case Ndis802_11Encryption2Enabled: - case Ndis802_11Encryption3Enabled: - erq->length = 16; - erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | - IW_ENCODE_NOKEY); - break; - default: - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - break; - } - return 0; -} - -static int r8711_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wrqu->power.value = 0; - wrqu->power.fixed = 0; /* no auto select */ - wrqu->power.disabled = 1; - return 0; -} - -static int r871x_wx_set_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - - return r871x_set_wpa_ie(padapter, extra, wrqu->data.length); -} - -static int r871x_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_param *param = (struct iw_param *)&wrqu->param; - int paramid; - int paramval; - int ret = 0; - - paramid = param->flags & IW_AUTH_INDEX; - paramval = param->value; - switch (paramid) { - case IW_AUTH_WPA_VERSION: - break; - case IW_AUTH_CIPHER_PAIRWISE: - break; - case IW_AUTH_CIPHER_GROUP: - break; - case IW_AUTH_KEY_MGMT: - /* - * ??? does not use these parameters - */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - if (paramval) { - /* wpa_supplicant is enabling tkip countermeasure. */ - padapter->securitypriv.btkip_countermeasure = true; - } else { - /* wpa_supplicant is disabling tkip countermeasure. */ - padapter->securitypriv.btkip_countermeasure = false; - } - break; - case IW_AUTH_DROP_UNENCRYPTED: - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - if (padapter->securitypriv.ndisencryptstatus == - Ndis802_11Encryption1Enabled) { - /* it means init value, or using wep, - * ndisencryptstatus = - * Ndis802_11Encryption1Enabled, - * then it needn't reset it; - */ - break; - } - - if (paramval) { - padapter->securitypriv.ndisencryptstatus = - Ndis802_11EncryptionDisabled; - padapter->securitypriv.PrivacyAlgrthm = - _NO_PRIVACY_; - padapter->securitypriv.XGrpPrivacy = - _NO_PRIVACY_; - padapter->securitypriv.AuthAlgrthm = 0; - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeOpen; - } - break; - case IW_AUTH_80211_AUTH_ALG: - ret = wpa_set_auth_algs(dev, (u32)paramval); - break; - case IW_AUTH_WPA_ENABLED: - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; - case IW_AUTH_PRIVACY_INVOKED: - break; - default: - return -EOPNOTSUPP; - } - - return ret; -} - -static int r871x_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_point *pencoding = &wrqu->encoding; - struct iw_encode_ext *pext = (struct iw_encode_ext *)extra; - struct ieee_param *param = NULL; - char *alg_name; - u32 param_len; - int ret = 0; - - switch (pext->alg) { - case IW_ENCODE_ALG_NONE: - alg_name = "none"; - break; - case IW_ENCODE_ALG_WEP: - alg_name = "WEP"; - break; - case IW_ENCODE_ALG_TKIP: - alg_name = "TKIP"; - break; - case IW_ENCODE_ALG_CCMP: - alg_name = "CCMP"; - break; - default: - return -EINVAL; - } - - param_len = sizeof(struct ieee_param) + pext->key_len; - param = kzalloc(param_len, GFP_ATOMIC); - if (!param) - return -ENOMEM; - param->cmd = IEEE_CMD_SET_ENCRYPTION; - eth_broadcast_addr(param->sta_addr); - strscpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); - if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) - param->u.crypt.set_tx = 0; - if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - param->u.crypt.set_tx = 1; - param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1; - if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) - memcpy(param->u.crypt.seq, pext->rx_seq, 8); - if (pext->key_len) { - param->u.crypt.key_len = pext->key_len; - memcpy(param + 1, pext + 1, pext->key_len); - } - ret = wpa_set_encryption(dev, param, param_len); - kfree(param); - return ret; -} - -static int r871x_wx_get_nick(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - if (extra) { - wrqu->data.length = 8; - wrqu->data.flags = 1; - memcpy(extra, "rtl_wifi", 8); - } - return 0; -} - -static int r8711_wx_read32(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 addr; - u32 data32; - - get_user(addr, (u32 __user *)wrqu->data.pointer); - data32 = r8712_read32(padapter, addr); - put_user(data32, (u32 __user *)wrqu->data.pointer); - wrqu->data.length = (data32 & 0xffff0000) >> 16; - wrqu->data.flags = data32 & 0xffff; - get_user(addr, (u32 __user *)wrqu->data.pointer); - return 0; -} - -static int r8711_wx_write32(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct _adapter *padapter = netdev_priv(dev); - u32 addr; - u32 data32; - - get_user(addr, (u32 __user *)wrqu->data.pointer); - data32 = ((u32)wrqu->data.length << 16) | (u32)wrqu->data.flags; - r8712_write32(padapter, addr, data32); - return 0; -} - -static int dummy(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - return -EINVAL; -} - -static int r8711_drvext_hdl(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - return 0; -} - -static int r871x_mp_ioctl_hdl(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *p = &wrqu->data; - struct oid_par_priv oid_par; - struct mp_ioctl_handler *phandler; - struct mp_ioctl_param *poidparam; - unsigned long BytesRead, BytesWritten, BytesNeeded; - u8 *pparmbuf, bset; - u16 len; - uint status; - int ret = 0; - - if ((!p->length) || (!p->pointer)) - return -EINVAL; - - bset = (u8)(p->flags & 0xFFFF); - len = p->length; - pparmbuf = memdup_user(p->pointer, len); - if (IS_ERR(pparmbuf)) - return PTR_ERR(pparmbuf); - - poidparam = (struct mp_ioctl_param *)pparmbuf; - if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { - ret = -EINVAL; - goto _r871x_mp_ioctl_hdl_exit; - } - phandler = mp_ioctl_hdl + poidparam->subcode; - if ((phandler->paramsize != 0) && - (poidparam->len < phandler->paramsize)) { - ret = -EINVAL; - goto _r871x_mp_ioctl_hdl_exit; - } - if (phandler->oid == 0 && phandler->handler) { - status = phandler->handler(&oid_par); - } else if (phandler->handler) { - oid_par.adapter_context = padapter; - oid_par.oid = phandler->oid; - oid_par.information_buf = poidparam->data; - oid_par.information_buf_len = poidparam->len; - oid_par.dbg = 0; - BytesWritten = 0; - BytesNeeded = 0; - if (bset) { - oid_par.bytes_rw = &BytesRead; - oid_par.bytes_needed = &BytesNeeded; - oid_par.type_of_oid = SET_OID; - } else { - oid_par.bytes_rw = &BytesWritten; - oid_par.bytes_needed = &BytesNeeded; - oid_par.type_of_oid = QUERY_OID; - } - status = phandler->handler(&oid_par); - /* todo:check status, BytesNeeded, etc. */ - } else { - netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n", - __func__, poidparam->subcode, phandler->oid, - phandler->handler); - ret = -EFAULT; - goto _r871x_mp_ioctl_hdl_exit; - } - if (bset == 0x00) { /* query info */ - if (copy_to_user(p->pointer, pparmbuf, len)) - ret = -EFAULT; - } - if (status) { - ret = -EFAULT; - goto _r871x_mp_ioctl_hdl_exit; - } -_r871x_mp_ioctl_hdl_exit: - kfree(pparmbuf); - return ret; -} - -static int r871x_get_ap_info(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct iw_point *pdata = &wrqu->data; - struct wlan_network *pnetwork = NULL; - u32 cnt = 0, wpa_ielen; - unsigned long irqL; - struct list_head *plist, *phead; - unsigned char *pbuf; - u8 bssid[ETH_ALEN]; - char data[33]; - - if (padapter->driver_stopped || !pdata) - return -EINVAL; - while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) { - msleep(30); - cnt++; - if (cnt > 100) - break; - } - pdata->flags = 0; - if (pdata->length < 32) - return -EINVAL; - if (copy_from_user(data, pdata->pointer, 32)) - return -EINVAL; - data[32] = 0; - - spin_lock_irqsave(&pmlmepriv->scanned_queue.lock, irqL); - phead = &queue->queue; - plist = phead->next; - while (1) { - if (end_of_queue_search(phead, plist)) - break; - pnetwork = container_of(plist, struct wlan_network, list); - if (!mac_pton(data, bssid)) { - netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n", - (u8 *)data); - spin_unlock_irqrestore(&pmlmepriv->scanned_queue.lock, - irqL); - return -EINVAL; - } - netdev_info(dev, "r8712u: BSSID:%pM\n", bssid); - if (ether_addr_equal(bssid, pnetwork->network.MacAddress)) { - /* BSSID match, then check if supporting wpa/wpa2 */ - pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12], - &wpa_ielen, pnetwork->network.IELength - 12); - if (pbuf && (wpa_ielen > 0)) { - pdata->flags = 1; - break; - } - pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12], - &wpa_ielen, pnetwork->network.IELength - 12); - if (pbuf && (wpa_ielen > 0)) { - pdata->flags = 2; - break; - } - } - plist = plist->next; - } - spin_unlock_irqrestore(&pmlmepriv->scanned_queue.lock, irqL); - if (pdata->length >= 34) { - if (copy_to_user((u8 __user *)pdata->pointer + 32, - (u8 *)&pdata->flags, 1)) - return -EINVAL; - } - return 0; -} - -static int r871x_set_pid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *pdata = &wrqu->data; - - if (padapter->driver_stopped || !pdata) - return -EINVAL; - if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int))) - return -EINVAL; - return 0; -} - -static int r871x_set_chplan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *pdata = &wrqu->data; - int ch_plan = -1; - - if (padapter->driver_stopped || !pdata) { - ret = -EINVAL; - goto exit; - } - ch_plan = (int)*extra; - r8712_set_chplan_cmd(padapter, ch_plan); - -exit: - - return ret; -} - -static int r871x_wps_start(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_point *pdata = &wrqu->data; - u32 u32wps_start = 0; - - if (padapter->driver_stopped || !pdata) - return -EINVAL; - if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) - return -EFAULT; - if (u32wps_start == 0) - u32wps_start = *extra; - if (u32wps_start == 1) /* WPS Start */ - padapter->ledpriv.LedControlHandler(padapter, - LED_CTL_START_WPS); - else if (u32wps_start == 2) /* WPS Stop because of wps success */ - padapter->ledpriv.LedControlHandler(padapter, - LED_CTL_STOP_WPS); - else if (u32wps_start == 3) /* WPS Stop because of wps fail */ - padapter->ledpriv.LedControlHandler(padapter, - LED_CTL_STOP_WPS_FAIL); - return 0; -} - -static int wpa_set_param(struct net_device *dev, u8 name, u32 value) -{ - struct _adapter *padapter = netdev_priv(dev); - - switch (name) { - case IEEE_PARAM_WPA_ENABLED: - padapter->securitypriv.AuthAlgrthm = 2; /* 802.1x */ - switch ((value) & 0xff) { - case 1: /* WPA */ - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPAPSK; /* WPA_PSK */ - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption2Enabled; - break; - case 2: /* WPA2 */ - padapter->securitypriv.ndisauthtype = - Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */ - padapter->securitypriv.ndisencryptstatus = - Ndis802_11Encryption3Enabled; - break; - } - break; - case IEEE_PARAM_TKIP_COUNTERMEASURES: - break; - case IEEE_PARAM_DROP_UNENCRYPTED: - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - break; - case IEEE_PARAM_PRIVACY_INVOKED: - break; - case IEEE_PARAM_AUTH_ALGS: - return wpa_set_auth_algs(dev, value); - case IEEE_PARAM_IEEE_802_1X: - break; - case IEEE_PARAM_WPAX_SELECT: - /* added for WPA2 mixed mode */ - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -static int wpa_mlme(struct net_device *dev, u32 command, u32 reason) -{ - struct _adapter *padapter = netdev_priv(dev); - - switch (command) { - case IEEE_MLME_STA_DEAUTH: - if (!r8712_set_802_11_disassociate(padapter)) - return -1; - break; - case IEEE_MLME_STA_DISASSOC: - if (!r8712_set_802_11_disassociate(padapter)) - return -1; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) -{ - struct ieee_param *param; - int ret = 0; - struct _adapter *padapter = netdev_priv(dev); - - if (p->length < sizeof(struct ieee_param) || !p->pointer) - return -EINVAL; - param = memdup_user(p->pointer, p->length); - if (IS_ERR(param)) - return PTR_ERR(param); - switch (param->cmd) { - case IEEE_CMD_SET_WPA_PARAM: - ret = wpa_set_param(dev, param->u.wpa_param.name, - param->u.wpa_param.value); - break; - case IEEE_CMD_SET_WPA_IE: - ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data, - (u16)param->u.wpa_ie.len); - break; - case IEEE_CMD_SET_ENCRYPTION: - ret = wpa_set_encryption(dev, param, p->length); - break; - case IEEE_CMD_MLME: - ret = wpa_mlme(dev, param->u.mlme.command, - param->u.mlme.reason_code); - break; - default: - ret = -EOPNOTSUPP; - break; - } - if (ret == 0 && copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - kfree(param); - return ret; -} - -/* based on "driver_ipw" and for hostapd */ -int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct iwreq *wrq = (struct iwreq *)rq; - - switch (cmd) { - case RTL_IOCTL_WPA_SUPPLICANT: - return wpa_supplicant_ioctl(dev, &wrq->u.data); - default: - return -EOPNOTSUPP; - } - return 0; -} - -static iw_handler r8711_handlers[] = { - NULL, /* SIOCSIWCOMMIT */ - r8711_wx_get_name, /* SIOCGIWNAME */ - dummy, /* SIOCSIWNWID */ - dummy, /* SIOCGIWNWID */ - r8711_wx_set_freq, /* SIOCSIWFREQ */ - r8711_wx_get_freq, /* SIOCGIWFREQ */ - r8711_wx_set_mode, /* SIOCSIWMODE */ - r8711_wx_get_mode, /* SIOCGIWMODE */ - dummy, /* SIOCSIWSENS */ - r8711_wx_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - r8711_wx_get_range, /* SIOCGIWRANGE */ - r871x_wx_set_priv, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - dummy, /* SIOCSIWSPY */ - dummy, /* SIOCGIWSPY */ - NULL, /* SIOCGIWTHRSPY */ - NULL, /* SIOCWIWTHRSPY */ - r8711_wx_set_wap, /* SIOCSIWAP */ - r8711_wx_get_wap, /* SIOCGIWAP */ - r871x_wx_set_mlme, /* request MLME operation; - * uses struct iw_mlme - */ - dummy, /* SIOCGIWAPLIST -- deprecated */ - r8711_wx_set_scan, /* SIOCSIWSCAN */ - r8711_wx_get_scan, /* SIOCGIWSCAN */ - r8711_wx_set_essid, /* SIOCSIWESSID */ - r8711_wx_get_essid, /* SIOCGIWESSID */ - dummy, /* SIOCSIWNICKN */ - r871x_wx_get_nick, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - r8711_wx_set_rate, /* SIOCSIWRATE */ - r8711_wx_get_rate, /* SIOCGIWRATE */ - dummy, /* SIOCSIWRTS */ - r8711_wx_get_rts, /* SIOCGIWRTS */ - r8711_wx_set_frag, /* SIOCSIWFRAG */ - r8711_wx_get_frag, /* SIOCGIWFRAG */ - dummy, /* SIOCSIWTXPOW */ - dummy, /* SIOCGIWTXPOW */ - dummy, /* SIOCSIWRETRY */ - r8711_wx_get_retry, /* SIOCGIWRETRY */ - r8711_wx_set_enc, /* SIOCSIWENCODE */ - r8711_wx_get_enc, /* SIOCGIWENCODE */ - dummy, /* SIOCSIWPOWER */ - r8711_wx_get_power, /* SIOCGIWPOWER */ - NULL, /*---hole---*/ - NULL, /*---hole---*/ - r871x_wx_set_gen_ie, /* SIOCSIWGENIE */ - NULL, /* SIOCGIWGENIE */ - r871x_wx_set_auth, /* SIOCSIWAUTH */ - NULL, /* SIOCGIWAUTH */ - r871x_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ - NULL, /* SIOCGIWENCODEEXT */ - r871x_wx_set_pmkid, /* SIOCSIWPMKSA */ - NULL, /*---hole---*/ -}; - -static const struct iw_priv_args r8711_private_args[] = { - { - SIOCIWFIRSTPRIV + 0x0, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32" - }, - { - SIOCIWFIRSTPRIV + 0x1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32" - }, - { - SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext" - }, - { - SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl" - }, - { - SIOCIWFIRSTPRIV + 0x4, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo" - }, - { - SIOCIWFIRSTPRIV + 0x5, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid" - }, - { - SIOCIWFIRSTPRIV + 0x6, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start" - }, - { - SIOCIWFIRSTPRIV + 0x7, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan" - } -}; - -static iw_handler r8711_private_handler[] = { - r8711_wx_read32, - r8711_wx_write32, - r8711_drvext_hdl, - r871x_mp_ioctl_hdl, - r871x_get_ap_info, /*for MM DTV platform*/ - r871x_set_pid, - r871x_wps_start, - r871x_set_chplan -}; - -static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev) -{ - struct _adapter *padapter = netdev_priv(dev); - struct iw_statistics *piwstats = &padapter->iwstats; - int tmp_level = 0; - int tmp_qual = 0; - int tmp_noise = 0; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) { - piwstats->qual.qual = 0; - piwstats->qual.level = 0; - piwstats->qual.noise = 0; - } else { - /* show percentage, we need transfer dbm to original value. */ - tmp_level = padapter->recvpriv.fw_rssi; - tmp_qual = padapter->recvpriv.signal; - tmp_noise = padapter->recvpriv.noise; - piwstats->qual.level = tmp_level; - piwstats->qual.qual = tmp_qual; - piwstats->qual.noise = tmp_noise; - } - piwstats->qual.updated = IW_QUAL_ALL_UPDATED; - return &padapter->iwstats; -} - -struct iw_handler_def r871x_handlers_def = { - .standard = r8711_handlers, - .num_standard = ARRAY_SIZE(r8711_handlers), - .private = r8711_private_handler, - .private_args = (struct iw_priv_args *)r8711_private_args, - .num_private = ARRAY_SIZE(r8711_private_handler), - .num_private_args = sizeof(r8711_private_args) / - sizeof(struct iw_priv_args), - .get_wireless_stats = r871x_get_wireless_stats -}; diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c deleted file mode 100644 index 2b539335206a..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c +++ /dev/null @@ -1,519 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_ioctl_rtl.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_IOCTL_RTL_C_ - -#include -#include "osdep_service.h" -#include "drv_types.h" -#include "wlan_bssdef.h" -#include "wifi.h" -#include "rtl871x_ioctl.h" -#include "rtl871x_ioctl_set.h" -#include "rtl871x_ioctl_rtl.h" -#include "mp_custom_oid.h" -#include "rtl871x_mp.h" -#include "rtl871x_mp_ioctl.h" - -uint oid_rt_get_signal_quality_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_small_packet_crc_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_smallpacket_crcerr; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_middlepacket_crcerr; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_large_packet_crc_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_largepacket_crcerr; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_tx_retry_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_rx_retry_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_rx_total_packet_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_pkts + - padapter->recvpriv.rx_drop; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(uint *)poid_par_priv->information_buf = - padapter->recvpriv.rx_icv_err; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - u32 preamblemode = 0; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - if (padapter->registrypriv.preamble == PREAMBLE_LONG) - preamblemode = 0; - else if (padapter->registrypriv.preamble == PREAMBLE_AUTO) - preamblemode = 1; - else if (padapter->registrypriv.preamble == PREAMBLE_SHORT) - preamblemode = 2; - *(u32 *)poid_par_priv->information_buf = preamblemode; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_ap_ip_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_channelplan_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct eeprom_priv *peeprompriv = &padapter->eeprompriv; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - *(u16 *)poid_par_priv->information_buf = peeprompriv->channel_plan; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_channelplan_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct eeprom_priv *peeprompriv = &padapter->eeprompriv; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - peeprompriv->channel_plan = *(u16 *)poid_par_priv->information_buf; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_preamble_mode_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - u32 preamblemode = 0; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - preamblemode = *(u32 *)poid_par_priv->information_buf; - if (preamblemode == 0) - padapter->registrypriv.preamble = PREAMBLE_LONG; - else if (preamblemode == 1) - padapter->registrypriv.preamble = PREAMBLE_AUTO; - else if (preamblemode == 2) - padapter->registrypriv.preamble = PREAMBLE_SHORT; - *(u32 *)poid_par_priv->information_buf = preamblemode; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_bcn_intvl_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_dedicate_probe_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->xmitpriv.tx_bytes; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv - *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - padapter->recvpriv.rx_bytes; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_current_tx_power_level_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_channel_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct NDIS_802_11_CONFIGURATION *pnic_Config; - u32 channelnum; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (check_fwstate(pmlmepriv, _FW_LINKED) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) - pnic_Config = &pmlmepriv->cur_network.network.Configuration; - else - pnic_Config = &padapter->registrypriv.dev_network.Configuration; - channelnum = pnic_Config->DSConfig; - *(u32 *)poid_par_priv->information_buf = channelnum; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_key_mismatch_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_supported_wireless_mode_hdl(struct oid_par_priv - *poid_par_priv) -{ - u32 ulInfo = 0; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len >= sizeof(u32)) { - ulInfo |= 0x0100; /* WIRELESS_MODE_B */ - ulInfo |= 0x0200; /* WIRELESS_MODE_G */ - ulInfo |= 0x0400; /* WIRELESS_MODE_A */ - *(u32 *) poid_par_priv->information_buf = ulInfo; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_channel_list_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_scan_in_progress_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_forced_data_rate_hdl(struct oid_par_priv *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv - *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv - *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* - poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_supported_hdl(struct oid_par_priv *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_ap_set_passphrase_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* - poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - struct _adapter *Adapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */ - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len == - (sizeof(unsigned long) * 3)) { - if (r8712_setrfreg_cmd(Adapter, - *(unsigned char *)poid_par_priv->information_buf, - (unsigned long)(*((unsigned long *) - poid_par_priv->information_buf + 2)))) - status = RNDIS_STATUS_NOT_ACCEPTED; - } else { - status = RNDIS_STATUS_INVALID_LENGTH; - } - return status; -} - -uint oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv *poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - struct _adapter *Adapter = poid_par_priv->adapter_context; - - if (poid_par_priv->type_of_oid != SET_OID) /* QUERY_OID */ - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len == (sizeof(unsigned long) * - 3)) { - if (Adapter->mppriv.act_in_progress) { - status = RNDIS_STATUS_NOT_ACCEPTED; - } else { - /* init workparam */ - Adapter->mppriv.act_in_progress = true; - Adapter->mppriv.workparam.bcompleted = false; - Adapter->mppriv.workparam.act_type = MPT_READ_RF; - Adapter->mppriv.workparam.io_offset = *(unsigned long *) - poid_par_priv->information_buf; - Adapter->mppriv.workparam.io_value = 0xcccccccc; - - /* RegOffsetValue - The offset of RF register to read. - * RegDataWidth - The data width of RF register to read. - * RegDataValue - The value to read. - * RegOffsetValue = *((unsigned long *)InformationBuffer); - * RegDataWidth = *((unsigned long *)InformationBuffer+1); - * RegDataValue = *((unsigned long *)InformationBuffer+2); - */ - if (r8712_getrfreg_cmd(Adapter, - *(unsigned char *)poid_par_priv->information_buf, - (unsigned char *)&Adapter->mppriv.workparam.io_value - )) - status = RNDIS_STATUS_NOT_ACCEPTED; - } - } else { - status = RNDIS_STATUS_INVALID_LENGTH; - } - return status; -} - -enum _CONNECT_STATE_ { - CHECKINGSTATUS, - ASSOCIATED, - ADHOCMODE, - NOTASSOCIATED -}; - -uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *padapter = poid_par_priv->adapter_context; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - u32 ulInfo; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - /* nStatus==0 CheckingStatus - * nStatus==1 Associated - * nStatus==2 AdHocMode - * nStatus==3 NotAssociated - */ - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - ulInfo = CHECKINGSTATUS; - else if (check_fwstate(pmlmepriv, _FW_LINKED)) - ulInfo = ASSOCIATED; - else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) - ulInfo = ADHOCMODE; - else - ulInfo = NOTASSOCIATED; - *(u32 *)poid_par_priv->information_buf = ulInfo; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_default_key_id_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h b/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h deleted file mode 100644 index 7c0b880ac686..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_rtl.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_IOCTL_RTL_H -#define _RTL871X_IOCTL_RTL_H - -#include "osdep_service.h" -#include "drv_types.h" - -/*************** oid_rtl_seg_01_01 **************/ -uint oid_rt_get_signal_quality_hdl( - struct oid_par_priv *poid_par_priv);/*84*/ -uint oid_rt_get_small_packet_crc_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_middle_packet_crc_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_large_packet_crc_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_tx_retry_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_rx_retry_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_rx_total_packet_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_tx_beacon_ok_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_tx_beacon_err_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_rx_icv_err_hdl( - struct oid_par_priv *poid_par_priv);/*93*/ -uint oid_rt_set_encryption_algorithm_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_preamble_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_ap_ip_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_channelplan_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_channelplan_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_preamble_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_bcn_intvl_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_dedicate_probe_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_total_tx_bytes_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_total_rx_bytes_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_current_tx_power_level_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_enc_key_mismatch_count_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_enc_key_match_count_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_channel_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_hardware_radio_off_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_key_mismatch_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_supported_wireless_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_channel_list_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_scan_in_progress_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_forced_data_rate_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_wireless_mode_for_scan_list_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_bss_wireless_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_scan_with_magic_packet_hdl( - struct oid_par_priv *poid_par_priv); - -/************** oid_rtl_seg_01_03 section start **************/ -uint oid_rt_ap_get_associated_station_list_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_ap_switch_into_ap_mode_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_ap_supported_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_ap_set_passphrase_hdl( - struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_01_11 */ -uint oid_rt_pro_rf_write_registry_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_rf_read_registry_hdl( - struct oid_par_priv *poid_par_priv); -/*************** oid_rtl_seg_03_00 section start **************/ -uint oid_rt_get_connect_state_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_default_key_id_hdl( - struct oid_par_priv *poid_par_priv); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c deleted file mode 100644 index 34c9a52b4c42..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ /dev/null @@ -1,354 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_ioctl_set.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_IOCTL_SET_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_ioctl_set.h" -#include "usb_osintf.h" -#include "usb_ops.h" - -static u8 validate_ssid(struct ndis_802_11_ssid *ssid) -{ - u8 i; - - if (ssid->SsidLength > 32) - return false; - for (i = 0; i < ssid->SsidLength; i++) { - /* wifi, printable ascii code must be supported */ - if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) - return false; - } - return true; -} - -static u8 do_join(struct _adapter *padapter) -{ - struct list_head *plist, *phead; - u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct __queue *queue = &(pmlmepriv->scanned_queue); - int ret; - - phead = &queue->queue; - plist = phead->next; - pmlmepriv->cur_network.join_res = -2; - pmlmepriv->fw_state |= _FW_UNDER_LINKING; - pmlmepriv->pscanned = plist; - pmlmepriv->to_join = true; - - /* adhoc mode will start with an empty queue, but skip checking */ - if (!check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) && - list_empty(&queue->queue)) { - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= _FW_UNDER_LINKING; - /* when set_ssid/set_bssid for do_join(), but scanning queue - * is empty we try to issue sitesurvey firstly - */ - if (!pmlmepriv->sitesurveyctrl.traffic_busy) - r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); - return true; - } - - ret = r8712_select_and_join_from_scan(pmlmepriv); - if (!ret) { - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT)); - } else { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - /* submit r8712_createbss_cmd to change to an - * ADHOC_MASTER pmlmepriv->lock has been - * acquired by caller... - */ - struct wlan_bssid_ex *pdev_network = - &padapter->registrypriv.dev_network; - pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; - pibss = padapter->registrypriv.dev_network.MacAddress; - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network(padapter); - r8712_generate_random_ibss(pibss); - if (r8712_createbss_cmd(padapter)) - return false; - pmlmepriv->to_join = false; - } else { - /* can't associate ; reset under-linking */ - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - /* when set_ssid/set_bssid for do_join(), but - * there are no desired bss in scanning queue - * we try to issue sitesurvey first - */ - if (!pmlmepriv->sitesurveyctrl.traffic_busy) - r8712_sitesurvey_cmd(padapter, - &pmlmepriv->assoc_ssid); - } - } - return true; -} - -u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid) -{ - unsigned long irqL; - u8 status = true; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) { - status = false; - return status; - } - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | - _FW_UNDER_LINKING)) { - status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); - goto _Abort_Set_BSSID; - } - if (check_fwstate(pmlmepriv, - _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { - if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, - ETH_ALEN)) { - if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - /* driver is in - * WIFI_ADHOC_MASTER_STATE - */ - goto _Abort_Set_BSSID; - } else { - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, _FW_LINKED)) - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - if ((check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE))) { - _clr_fwstate_(pmlmepriv, - WIFI_ADHOC_MASTER_STATE); - set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); - } - } - } - memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); - pmlmepriv->assoc_by_bssid = true; - status = do_join(padapter); - goto done; -_Abort_Set_BSSID: -done: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return status; -} - -void r8712_set_802_11_ssid(struct _adapter *padapter, - struct ndis_802_11_ssid *ssid) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *pnetwork = &pmlmepriv->cur_network; - - if (!padapter->hw_init_completed) - return; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) { - check_fwstate(pmlmepriv, _FW_UNDER_LINKING); - goto _Abort_Set_SSID; - } - if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { - if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && - (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, - ssid->SsidLength))) { - if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - if (!r8712_is_same_ibss(padapter, - pnetwork)) { - /* if in WIFI_ADHOC_MASTER_STATE or - * WIFI_ADHOC_STATE, create bss or - * rejoin again - */ - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, - _FW_LINKED)) - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE)) { - _clr_fwstate_(pmlmepriv, - WIFI_ADHOC_MASTER_STATE); - set_fwstate(pmlmepriv, - WIFI_ADHOC_STATE); - } - } else { - /* driver is in - * WIFI_ADHOC_MASTER_STATE - */ - goto _Abort_Set_SSID; - } - } - } else { - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, _FW_LINKED)) - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_MASTER_STATE)) { - _clr_fwstate_(pmlmepriv, - WIFI_ADHOC_MASTER_STATE); - set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); - } - } - } - if (padapter->securitypriv.btkip_countermeasure) - goto _Abort_Set_SSID; - if (!validate_ssid(ssid)) - goto _Abort_Set_SSID; - memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); - pmlmepriv->assoc_by_bssid = false; - do_join(padapter); - goto done; -_Abort_Set_SSID: -done: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *cur_network = &pmlmepriv->cur_network; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = - &(cur_network->network.InfrastructureMode); - - if (*pold_state != networktype) { - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_LINKED) || - (*pold_state == Ndis802_11IBSS)) - r8712_disassoc_cmd(padapter); - if (check_fwstate(pmlmepriv, - _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) - r8712_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, _FW_LINKED) || - (*pold_state == Ndis802_11Infrastructure) || - (*pold_state == Ndis802_11IBSS)) { - /* will clr Linked_state before this function, - * we must have checked whether issue dis-assoc_cmd or - * not - */ - r8712_ind_disconnect(padapter); - } - *pold_state = networktype; - /* clear WIFI_STATION_STATE; WIFI_AP_STATE; WIFI_ADHOC_STATE; - * WIFI_ADHOC_MASTER_STATE - */ - _clr_fwstate_(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE | - WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE); - switch (networktype) { - case Ndis802_11IBSS: - set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); - break; - case Ndis802_11Infrastructure: - set_fwstate(pmlmepriv, WIFI_STATION_STATE); - break; - case Ndis802_11APMode: - set_fwstate(pmlmepriv, WIFI_AP_STATE); - break; - case Ndis802_11AutoUnknown: - case Ndis802_11InfrastructureMax: - break; - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - } -} - -u8 r8712_set_802_11_disassociate(struct _adapter *padapter) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - r8712_disassoc_cmd(padapter); - r8712_ind_disconnect(padapter); - r8712_free_assoc_resources(padapter); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return true; -} - -u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter) -{ - struct mlme_priv *pmlmepriv = NULL; - unsigned long irqL; - u8 ret = true; - - if (!padapter) - return false; - pmlmepriv = &padapter->mlmepriv; - if (!padapter->hw_init_completed) - return false; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) || - pmlmepriv->sitesurveyctrl.traffic_busy) { - /* Scan or linking is in progress, do nothing. */ - ret = (u8)check_fwstate(pmlmepriv, _FW_UNDER_SURVEY); - } else { - r8712_free_network_queue(padapter); - ret = r8712_sitesurvey_cmd(padapter, NULL); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return ret; -} - -u8 r8712_set_802_11_authentication_mode(struct _adapter *padapter, - enum NDIS_802_11_AUTHENTICATION_MODE authmode) -{ - struct security_priv *psecuritypriv = &padapter->securitypriv; - u8 ret; - - psecuritypriv->ndisauthtype = authmode; - if (psecuritypriv->ndisauthtype > 3) - psecuritypriv->AuthAlgrthm = 2; /* 802.1x */ - if (r8712_set_auth(padapter, psecuritypriv)) - ret = false; - else - ret = true; - return ret; -} - -int r8712_set_802_11_add_wep(struct _adapter *padapter, - struct NDIS_802_11_WEP *wep) -{ - sint keyid; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - keyid = wep->KeyIndex & 0x3fffffff; - if (keyid >= WEP_KEYS) - return -EINVAL; - switch (wep->KeyLength) { - case 5: - psecuritypriv->PrivacyAlgrthm = _WEP40_; - break; - case 13: - psecuritypriv->PrivacyAlgrthm = _WEP104_; - break; - default: - psecuritypriv->PrivacyAlgrthm = _NO_PRIVACY_; - break; - } - memcpy(psecuritypriv->DefKey[keyid].skey, &wep->KeyMaterial, - wep->KeyLength); - psecuritypriv->DefKeylen[keyid] = wep->KeyLength; - psecuritypriv->PrivacyKeyIndex = keyid; - return r8712_set_key(padapter, psecuritypriv, keyid); -} diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.h b/drivers/staging/rtl8712/rtl871x_ioctl_set.h deleted file mode 100644 index e2de820f61d9..000000000000 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __IOCTL_SET_H -#define __IOCTL_SET_H - -#include "drv_types.h" - -typedef u8 NDIS_802_11_PMKID_VALUE[16]; - -struct BSSIDInfo { - unsigned char BSSID[6]; - NDIS_802_11_PMKID_VALUE PMKID; -}; - -u8 r8712_set_802_11_authentication_mode(struct _adapter *pdapter, - enum NDIS_802_11_AUTHENTICATION_MODE authmode); - -u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid); - -int r8712_set_802_11_add_wep(struct _adapter *padapter, - struct NDIS_802_11_WEP *wep); - -u8 r8712_set_802_11_disassociate(struct _adapter *padapter); - -u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter); - -void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, - enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); - -void r8712_set_802_11_ssid(struct _adapter *padapter, - struct ndis_802_11_ssid *ssid); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_led.h b/drivers/staging/rtl8712/rtl871x_led.h deleted file mode 100644 index 2f0768132ad8..000000000000 --- a/drivers/staging/rtl8712/rtl871x_led.h +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL8712_LED_H -#define __RTL8712_LED_H - -#include "osdep_service.h" -#include "drv_types.h" - -/*=========================================================================== - * LED customization. - *=========================================================================== - */ -enum LED_CTL_MODE { - LED_CTL_POWER_ON = 1, - LED_CTL_LINK = 2, - LED_CTL_NO_LINK = 3, - LED_CTL_TX = 4, - LED_CTL_RX = 5, - LED_CTL_SITE_SURVEY = 6, - LED_CTL_POWER_OFF = 7, - LED_CTL_START_TO_LINK = 8, - LED_CTL_START_WPS = 9, - LED_CTL_STOP_WPS = 10, - LED_CTL_START_WPS_BOTTON = 11, - LED_CTL_STOP_WPS_FAIL = 12, - LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, -}; - -#define IS_LED_WPS_BLINKING(_LED_871x) \ - (((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS \ - || ((struct LED_871x *)_LED_871x)->CurrLedState == LED_BLINK_WPS_STOP \ - || ((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress) - -#define IS_LED_BLINKING(_LED_871x) \ - (((struct LED_871x *)_LED_871x)->bLedWPSBlinkInProgress \ - || ((struct LED_871x *)_LED_871x)->bLedScanBlinkInProgress) - -enum LED_PIN_871x { - LED_PIN_GPIO0, - LED_PIN_LED0, - LED_PIN_LED1 -}; - -/*=========================================================================== - * LED customization. - *=========================================================================== - */ -enum LED_STRATEGY_871x { - SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */ - SW_LED_MODE1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */ - SW_LED_MODE2, /* SW control 1 LED via GPIO0, - * custom for AzWave 8187 minicard. - */ - SW_LED_MODE3, /* SW control 1 LED via GPIO0, - * customized for Sercomm Printer Server case. - */ - SW_LED_MODE4, /*for Edimax / Belkin*/ - SW_LED_MODE5, /*for Sercomm / Belkin*/ - SW_LED_MODE6, /*for WNC / Corega*/ - HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different - * control modes, see MAC.CONFIG1 for details.) - */ -}; - -struct LED_871x { - struct _adapter *padapter; - enum LED_PIN_871x LedPin; /* Implementation for this SW led. */ - u32 CurrLedState; /* Current LED state. */ - u8 bLedOn; /* true if LED is ON */ - u8 bSWLedCtrl; - u8 bLedBlinkInProgress; /*true if blinking */ - u8 bLedNoLinkBlinkInProgress; - u8 bLedLinkBlinkInProgress; - u8 bLedStartToLinkBlinkInProgress; - u8 bLedScanBlinkInProgress; - u8 bLedWPSBlinkInProgress; - u32 BlinkTimes; /* No. times to toggle for blink.*/ - u32 BlinkingLedState; /* Next state for blinking, - * either LED_ON or OFF. - */ - - struct timer_list BlinkTimer; /* Timer object for led blinking.*/ - struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer */ -}; - -struct led_priv { - /* add for led control */ - struct LED_871x SwLed0; - struct LED_871x SwLed1; - enum LED_STRATEGY_871x LedStrategy; - u8 bRegUseLed; - void (*LedControlHandler)(struct _adapter *padapter, - enum LED_CTL_MODE LedAction); - /* add for led control */ -}; - -/*=========================================================================== - * Interface to manipulate LED objects. - *=========================================================================== - */ -void r8712_InitSwLeds(struct _adapter *padapter); -void r8712_DeInitSwLeds(struct _adapter *padapter); -void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction); -void r8712_flush_led_works(struct _adapter *padapter); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c deleted file mode 100644 index fccfa0915a02..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ /dev/null @@ -1,1710 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_mlme.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_MLME_C_ - -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "xmit_osdep.h" -#include "mlme_osdep.h" -#include "sta_info.h" -#include "wifi.h" -#include "wlan_bssdef.h" - -static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len); - -int r8712_init_mlme_priv(struct _adapter *padapter) -{ - sint i; - u8 *pbuf; - struct wlan_network *pnetwork; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); - pmlmepriv->nic_hdl = (u8 *)padapter; - pmlmepriv->pscanned = NULL; - pmlmepriv->fw_state = 0; - pmlmepriv->cur_network.network.InfrastructureMode = - Ndis802_11AutoUnknown; - /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/ - pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */ - spin_lock_init(&(pmlmepriv->lock)); - spin_lock_init(&(pmlmepriv->lock2)); - _init_queue(&(pmlmepriv->free_bss_pool)); - _init_queue(&(pmlmepriv->scanned_queue)); - set_scanned_network_val(pmlmepriv, 0); - memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid)); - pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network), - GFP_ATOMIC); - if (!pbuf) - return -ENOMEM; - pmlmepriv->free_bss_buf = pbuf; - pnetwork = (struct wlan_network *)pbuf; - for (i = 0; i < MAX_BSS_CNT; i++) { - INIT_LIST_HEAD(&(pnetwork->list)); - list_add_tail(&(pnetwork->list), - &(pmlmepriv->free_bss_pool.queue)); - pnetwork++; - } - pmlmepriv->sitesurveyctrl.last_rx_pkts = 0; - pmlmepriv->sitesurveyctrl.last_tx_pkts = 0; - pmlmepriv->sitesurveyctrl.traffic_busy = false; - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - r8712_init_mlme_timer(padapter); - return 0; -} - -struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv) -{ - unsigned long irqL; - struct wlan_network *pnetwork; - struct __queue *free_queue = &pmlmepriv->free_bss_pool; - - spin_lock_irqsave(&free_queue->lock, irqL); - pnetwork = list_first_entry_or_null(&free_queue->queue, - struct wlan_network, list); - if (pnetwork) { - list_del_init(&pnetwork->list); - pnetwork->last_scanned = jiffies; - pmlmepriv->num_of_scanned++; - } - spin_unlock_irqrestore(&free_queue->lock, irqL); - return pnetwork; -} - -static void _free_network(struct mlme_priv *pmlmepriv, - struct wlan_network *pnetwork) -{ - u32 curr_time, delta_time; - unsigned long irqL; - struct __queue *free_queue = &(pmlmepriv->free_bss_pool); - - if (!pnetwork) - return; - if (pnetwork->fixed) - return; - curr_time = jiffies; - delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ; - if (delta_time < SCANQUEUE_LIFETIME) - return; - spin_lock_irqsave(&free_queue->lock, irqL); - list_del_init(&pnetwork->list); - list_add_tail(&pnetwork->list, &free_queue->queue); - pmlmepriv->num_of_scanned--; - spin_unlock_irqrestore(&free_queue->lock, irqL); -} - -static void free_network_nolock(struct mlme_priv *pmlmepriv, - struct wlan_network *pnetwork) -{ - struct __queue *free_queue = &pmlmepriv->free_bss_pool; - - if (!pnetwork) - return; - if (pnetwork->fixed) - return; - list_del_init(&pnetwork->list); - list_add_tail(&pnetwork->list, &free_queue->queue); - pmlmepriv->num_of_scanned--; -} - -/* return the wlan_network with the matching addr - * Shall be called under atomic context... - * to avoid possible racing condition... - */ -static struct wlan_network *r8712_find_network(struct __queue *scanned_queue, - u8 *addr) -{ - unsigned long irqL; - struct list_head *phead, *plist; - struct wlan_network *pnetwork = NULL; - - if (is_zero_ether_addr(addr)) - return NULL; - spin_lock_irqsave(&scanned_queue->lock, irqL); - phead = &scanned_queue->queue; - list_for_each(plist, phead) { - pnetwork = list_entry(plist, struct wlan_network, list); - if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN)) - break; - } - if (plist == phead) - pnetwork = NULL; - spin_unlock_irqrestore(&scanned_queue->lock, irqL); - return pnetwork; -} - -void r8712_free_network_queue(struct _adapter *padapter) -{ - unsigned long irqL; - struct list_head *phead, *plist; - struct wlan_network *pnetwork; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *scanned_queue = &pmlmepriv->scanned_queue; - - spin_lock_irqsave(&scanned_queue->lock, irqL); - phead = &scanned_queue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - pnetwork = container_of(plist, struct wlan_network, list); - plist = plist->next; - _free_network(pmlmepriv, pnetwork); - } - spin_unlock_irqrestore(&scanned_queue->lock, irqL); -} - -sint r8712_if_up(struct _adapter *padapter) -{ - sint res; - - if (padapter->driver_stopped || padapter->surprise_removed || - !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) { - res = false; - } else { - res = true; - } - return res; -} - -void r8712_generate_random_ibss(u8 *pibss) -{ - u32 curtime = jiffies; - - pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */ - pibss[1] = 0x11; - pibss[2] = 0x87; - pibss[3] = (u8)(curtime & 0xff); - pibss[4] = (u8)((curtime >> 8) & 0xff); - pibss[5] = (u8)((curtime >> 16) & 0xff); -} - -uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss) -{ - return sizeof(*bss) + bss->IELength - MAX_IE_SZ; -} - -u8 *r8712_get_capability_from_ie(u8 *ie) -{ - return ie + 8 + 2; -} - -void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv) -{ - kfree(pmlmepriv->free_bss_buf); -} - -static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv) -{ - return _r8712_alloc_network(pmlmepriv); -} - -int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork) -{ - int ret = true; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && - (pnetwork->network.Privacy == cpu_to_le32(0))) - ret = false; - else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) && - (pnetwork->network.Privacy == cpu_to_le32(1))) - ret = false; - else - ret = true; - return ret; - -} - -static int is_same_network(struct wlan_bssid_ex *src, - struct wlan_bssid_ex *dst) -{ - u16 s_cap, d_cap; - - memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2); - memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2); - return (src->Ssid.SsidLength == dst->Ssid.SsidLength) && - (src->Configuration.DSConfig == - dst->Configuration.DSConfig) && - ((!memcmp(src->MacAddress, dst->MacAddress, - ETH_ALEN))) && - ((!memcmp(src->Ssid.Ssid, - dst->Ssid.Ssid, - src->Ssid.SsidLength))) && - ((s_cap & WLAN_CAPABILITY_IBSS) == - (d_cap & WLAN_CAPABILITY_IBSS)) && - ((s_cap & WLAN_CAPABILITY_ESS) == - (d_cap & WLAN_CAPABILITY_ESS)); - -} - -struct wlan_network *r8712_get_oldest_wlan_network( - struct __queue *scanned_queue) -{ - struct list_head *plist, *phead; - struct wlan_network *pwlan = NULL; - struct wlan_network *oldest = NULL; - - phead = &scanned_queue->queue; - plist = phead->next; - while (1) { - if (end_of_queue_search(phead, plist)) - break; - pwlan = container_of(plist, struct wlan_network, list); - if (!pwlan->fixed) { - if (!oldest || - time_after((unsigned long)oldest->last_scanned, - (unsigned long)pwlan->last_scanned)) - oldest = pwlan; - } - plist = plist->next; - } - return oldest; -} - -static void update_network(struct wlan_bssid_ex *dst, - struct wlan_bssid_ex *src, - struct _adapter *padapter) -{ - u32 last_evm = 0, tmpVal; - struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; - - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && - is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { - if (padapter->recvpriv.signal_qual_data.total_num++ >= - PHY_LINKQUALITY_SLID_WIN_MAX) { - padapter->recvpriv.signal_qual_data.total_num = - PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = sqd->elements[sqd->index]; - padapter->recvpriv.signal_qual_data.total_val -= - last_evm; - } - padapter->recvpriv.signal_qual_data.total_val += src->Rssi; - - sqd->elements[sqd->index++] = src->Rssi; - if (padapter->recvpriv.signal_qual_data.index >= - PHY_LINKQUALITY_SLID_WIN_MAX) - padapter->recvpriv.signal_qual_data.index = 0; - /* <1> Showed on UI for user, in percentage. */ - tmpVal = padapter->recvpriv.signal_qual_data.total_val / - padapter->recvpriv.signal_qual_data.total_num; - padapter->recvpriv.signal = (u8)tmpVal; - - src->Rssi = padapter->recvpriv.signal; - } else { - src->Rssi = (src->Rssi + dst->Rssi) / 2; - } - memcpy((u8 *)dst, (u8 *)src, r8712_get_wlan_bssid_ex_sz(src)); -} - -static void update_current_network(struct _adapter *adapter, - struct wlan_bssid_ex *pnetwork) -{ - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) { - update_network(&(pmlmepriv->cur_network.network), - pnetwork, adapter); - r8712_update_protection(adapter, - (pmlmepriv->cur_network.network.IEs) + - sizeof(struct NDIS_802_11_FIXED_IEs), - pmlmepriv->cur_network.network.IELength); - } -} - -/* Caller must hold pmlmepriv->lock first */ -static void update_scanned_network(struct _adapter *adapter, - struct wlan_bssid_ex *target) -{ - struct list_head *plist, *phead; - - u32 bssid_ex_sz; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; - struct wlan_network *pnetwork = NULL; - struct wlan_network *oldest = NULL; - - phead = &queue->queue; - plist = phead->next; - - while (1) { - if (end_of_queue_search(phead, plist)) - break; - - pnetwork = container_of(plist, struct wlan_network, list); - if (is_same_network(&pnetwork->network, target)) - break; - if ((oldest == ((struct wlan_network *)0)) || - time_after((unsigned long)oldest->last_scanned, - (unsigned long)pnetwork->last_scanned)) - oldest = pnetwork; - - plist = plist->next; - } - - /* If we didn't find a match, then get a new network slot to initialize - * with this beacon's information - */ - if (end_of_queue_search(phead, plist)) { - if (list_empty(&pmlmepriv->free_bss_pool.queue)) { - /* If there are no more slots, expire the oldest */ - pnetwork = oldest; - target->Rssi = (pnetwork->network.Rssi + - target->Rssi) / 2; - memcpy(&pnetwork->network, target, - r8712_get_wlan_bssid_ex_sz(target)); - pnetwork->last_scanned = jiffies; - } else { - /* Otherwise just pull from the free list */ - /* update scan_time */ - pnetwork = alloc_network(pmlmepriv); - if (!pnetwork) - return; - bssid_ex_sz = r8712_get_wlan_bssid_ex_sz(target); - target->Length = bssid_ex_sz; - memcpy(&pnetwork->network, target, bssid_ex_sz); - list_add_tail(&pnetwork->list, &queue->queue); - } - } else { - /* we have an entry and we are going to update it. But - * this entry may be already expired. In this case we - * do the same as we found a new net and call the new_net - * handler - */ - update_network(&pnetwork->network, target, adapter); - pnetwork->last_scanned = jiffies; - } -} - -static void rtl8711_add_network(struct _adapter *adapter, - struct wlan_bssid_ex *pnetwork) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv); - struct __queue *queue = &pmlmepriv->scanned_queue; - - spin_lock_irqsave(&queue->lock, irqL); - update_current_network(adapter, pnetwork); - update_scanned_network(adapter, pnetwork); - spin_unlock_irqrestore(&queue->lock, irqL); -} - -/*select the desired network based on the capability of the (i)bss. - * check items: (1) security - * (2) network_type - * (3) WMM - * (4) HT - * (5) others - */ -static int is_desired_network(struct _adapter *adapter, - struct wlan_network *pnetwork) -{ - u8 wps_ie[512]; - uint wps_ielen; - int bselected = true; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - if (psecuritypriv->wps_phase) { - if (r8712_get_wps_ie(pnetwork->network.IEs, - pnetwork->network.IELength, wps_ie, - &wps_ielen)) - return true; - return false; - } - if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) && - (pnetwork->network.Privacy == 0)) - bselected = false; - if (check_fwstate(&adapter->mlmepriv, WIFI_ADHOC_STATE)) { - if (pnetwork->network.InfrastructureMode != - adapter->mlmepriv.cur_network.network.InfrastructureMode) - bselected = false; - } - return bselected; -} - -/* TODO: Perry : For Power Management */ -void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf) -{ -} - -void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long flags; - u32 len; - struct wlan_bssid_ex *pnetwork; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - pnetwork = (struct wlan_bssid_ex *)pbuf; -#ifdef __BIG_ENDIAN - /* endian_convert */ - pnetwork->Length = le32_to_cpu(pnetwork->Length); - pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength); - pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); - pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); - pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); - pnetwork->Configuration.ATIMWindow = - le32_to_cpu(pnetwork->Configuration.ATIMWindow); - pnetwork->Configuration.BeaconPeriod = - le32_to_cpu(pnetwork->Configuration.BeaconPeriod); - pnetwork->Configuration.DSConfig = - le32_to_cpu(pnetwork->Configuration.DSConfig); - pnetwork->Configuration.FHConfig.DwellTime = - le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); - pnetwork->Configuration.FHConfig.HopPattern = - le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); - pnetwork->Configuration.FHConfig.HopSet = - le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); - pnetwork->Configuration.FHConfig.Length = - le32_to_cpu(pnetwork->Configuration.FHConfig.Length); - pnetwork->Configuration.Length = - le32_to_cpu(pnetwork->Configuration.Length); - pnetwork->InfrastructureMode = - le32_to_cpu(pnetwork->InfrastructureMode); - pnetwork->IELength = le32_to_cpu(pnetwork->IELength); -#endif - len = r8712_get_wlan_bssid_ex_sz(pnetwork); - if (len > sizeof(struct wlan_bssid_ex)) - return; - spin_lock_irqsave(&pmlmepriv->lock2, flags); - /* update IBSS_network 's timestamp */ - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress), - pnetwork->MacAddress, ETH_ALEN)) { - struct wlan_network *ibss_wlan = NULL; - - memcpy(pmlmepriv->cur_network.network.IEs, - pnetwork->IEs, 8); - ibss_wlan = r8712_find_network( - &pmlmepriv->scanned_queue, - pnetwork->MacAddress); - if (ibss_wlan) { - memcpy(ibss_wlan->network.IEs, - pnetwork->IEs, 8); - goto exit; - } - } - } - /* lock pmlmepriv->lock when you accessing network_q */ - if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - if (pnetwork->Ssid.Ssid[0] != 0) { - rtl8711_add_network(adapter, pnetwork); - } else { - pnetwork->Ssid.SsidLength = 8; - memcpy(pnetwork->Ssid.Ssid, "", 8); - rtl8711_add_network(adapter, pnetwork); - } - } -exit: - spin_unlock_irqrestore(&pmlmepriv->lock2, flags); -} - -void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) { - del_timer(&pmlmepriv->scan_to_timer); - - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); - } - - if (pmlmepriv->to_join) { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - if (!check_fwstate(pmlmepriv, _FW_LINKED)) { - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); - - if (!r8712_select_and_join_from_scan(pmlmepriv)) { - mod_timer(&pmlmepriv->assoc_timer, jiffies + - msecs_to_jiffies(MAX_JOIN_TIMEOUT)); - } else { - struct wlan_bssid_ex *pdev_network = - &(adapter->registrypriv.dev_network); - u8 *pibss = - adapter->registrypriv.dev_network.MacAddress; - pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct - ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network - (adapter); - r8712_generate_random_ibss(pibss); - pmlmepriv->fw_state = - WIFI_ADHOC_MASTER_STATE; - pmlmepriv->to_join = false; - } - } - } else { - pmlmepriv->to_join = false; - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); - if (!r8712_select_and_join_from_scan(pmlmepriv)) - mod_timer(&pmlmepriv->assoc_timer, jiffies + - msecs_to_jiffies(MAX_JOIN_TIMEOUT)); - else - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - } - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -/* - *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock - */ -void r8712_free_assoc_resources(struct _adapter *adapter) -{ - unsigned long irqL; - struct wlan_network *pwlan = NULL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct sta_priv *pstapriv = &adapter->stapriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - - pwlan = r8712_find_network(&pmlmepriv->scanned_queue, - tgt_network->network.MacAddress); - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { - struct sta_info *psta; - - psta = r8712_get_stainfo(&adapter->stapriv, - tgt_network->network.MacAddress); - - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - r8712_free_stainfo(adapter, psta); - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); - } - - if (check_fwstate(pmlmepriv, - WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) - r8712_free_all_stainfo(adapter); - if (pwlan) - pwlan->fixed = false; - - if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) && - (adapter->stapriv.asoc_sta_count == 1))) - free_network_nolock(pmlmepriv, pwlan); -} - -/* - * r8712_indicate_connect: the caller has to lock pmlmepriv->lock - */ -void r8712_indicate_connect(struct _adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - pmlmepriv->to_join = false; - set_fwstate(pmlmepriv, _FW_LINKED); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK); - r8712_os_indicate_connect(padapter); - if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) - mod_timer(&pmlmepriv->dhcp_timer, - jiffies + msecs_to_jiffies(60000)); -} - -/* - * r8712_ind_disconnect: the caller has to lock pmlmepriv->lock - */ -void r8712_ind_disconnect(struct _adapter *padapter) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - _clr_fwstate_(pmlmepriv, _FW_LINKED); - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK); - r8712_os_indicate_disconnect(padapter); - } - if (padapter->pwrctrlpriv.pwr_mode != - padapter->registrypriv.power_mgnt) { - del_timer(&pmlmepriv->dhcp_timer); - r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt, - padapter->registrypriv.smart_ps); - } -} - -/*Notes: - *pnetwork : returns from r8712_joinbss_event_callback - *ptarget_wlan: found from scanned_queue - *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if - * "ptarget_sta" & "ptarget_wlan" exist. - *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check - * if "ptarget_wlan" exist. - *if join_res > 0, update "cur_network->network" from - * "pnetwork->network" if (ptarget_wlan !=NULL). - */ -void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL = 0, irqL2; - struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct wlan_network *cur_network = &pmlmepriv->cur_network; - struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL; - unsigned int the_same_macaddr = false; - struct wlan_network *pnetwork; - - if (sizeof(struct list_head) == 4 * sizeof(u32)) { - pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC); - if (!pnetwork) - return; - memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8, - sizeof(struct wlan_network) - 16); - } else { - pnetwork = (struct wlan_network *)pbuf; - } - -#ifdef __BIG_ENDIAN - /* endian_convert */ - pnetwork->join_res = le32_to_cpu(pnetwork->join_res); - pnetwork->network_type = le32_to_cpu(pnetwork->network_type); - pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length); - pnetwork->network.Ssid.SsidLength = - le32_to_cpu(pnetwork->network.Ssid.SsidLength); - pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy); - pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi); - pnetwork->network.NetworkTypeInUse = - le32_to_cpu(pnetwork->network.NetworkTypeInUse); - pnetwork->network.Configuration.ATIMWindow = - le32_to_cpu(pnetwork->network.Configuration.ATIMWindow); - pnetwork->network.Configuration.BeaconPeriod = - le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod); - pnetwork->network.Configuration.DSConfig = - le32_to_cpu(pnetwork->network.Configuration.DSConfig); - pnetwork->network.Configuration.FHConfig.DwellTime = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime); - pnetwork->network.Configuration.FHConfig.HopPattern = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern); - pnetwork->network.Configuration.FHConfig.HopSet = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet); - pnetwork->network.Configuration.FHConfig.Length = - le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length); - pnetwork->network.Configuration.Length = - le32_to_cpu(pnetwork->network.Configuration.Length); - pnetwork->network.InfrastructureMode = - le32_to_cpu(pnetwork->network.InfrastructureMode); - pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength); -#endif - - the_same_macaddr = !memcmp(pnetwork->network.MacAddress, - cur_network->network.MacAddress, ETH_ALEN); - pnetwork->network.Length = - r8712_get_wlan_bssid_ex_sz(&pnetwork->network); - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) - goto ignore_joinbss_callback; - if (pnetwork->join_res > 0) { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - /*s1. find ptarget_wlan*/ - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (the_same_macaddr) { - ptarget_wlan = - r8712_find_network(&pmlmepriv->scanned_queue, - cur_network->network.MacAddress); - } else { - pcur_wlan = - r8712_find_network(&pmlmepriv->scanned_queue, - cur_network->network.MacAddress); - if (pcur_wlan) - pcur_wlan->fixed = false; - - pcur_sta = r8712_get_stainfo(pstapriv, - cur_network->network.MacAddress); - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL2); - r8712_free_stainfo(adapter, pcur_sta); - spin_unlock_irqrestore(&(pstapriv->sta_hash_lock), irqL2); - - ptarget_wlan = - r8712_find_network(&pmlmepriv->scanned_queue, - pnetwork->network.MacAddress); - if (ptarget_wlan) - ptarget_wlan->fixed = true; - } - } else { - ptarget_wlan = r8712_find_network(&pmlmepriv->scanned_queue, - pnetwork->network.MacAddress); - if (ptarget_wlan) - ptarget_wlan->fixed = true; - } - - if (!ptarget_wlan) { - if (check_fwstate(pmlmepriv, - _FW_UNDER_LINKING)) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - goto ignore_joinbss_callback; - } - - /*s2. find ptarget_sta & update ptarget_sta*/ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - if (the_same_macaddr) { - ptarget_sta = - r8712_get_stainfo(pstapriv, - pnetwork->network.MacAddress); - if (!ptarget_sta) - ptarget_sta = - r8712_alloc_stainfo(pstapriv, - pnetwork->network.MacAddress); - } else { - ptarget_sta = - r8712_alloc_stainfo(pstapriv, - pnetwork->network.MacAddress); - } - if (ptarget_sta) /*update ptarget_sta*/ { - ptarget_sta->aid = pnetwork->join_res; - ptarget_sta->qos_option = 1; - ptarget_sta->mac_id = 5; - if (adapter->securitypriv.AuthAlgrthm == 2) { - adapter->securitypriv.binstallGrpkey = false; - adapter->securitypriv.busetkipkey = false; - adapter->securitypriv.bgrpkey_handshake = false; - ptarget_sta->ieee8021x_blocked = true; - ptarget_sta->XPrivacy = - adapter->securitypriv.PrivacyAlgrthm; - memset((u8 *)&ptarget_sta->x_UncstKey, - 0, - sizeof(union Keytype)); - memset((u8 *)&ptarget_sta->tkiprxmickey, - 0, - sizeof(union Keytype)); - memset((u8 *)&ptarget_sta->tkiptxmickey, - 0, - sizeof(union Keytype)); - memset((u8 *)&ptarget_sta->txpn, - 0, - sizeof(union pn48)); - memset((u8 *)&ptarget_sta->rxpn, - 0, - sizeof(union pn48)); - } - } else { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - goto ignore_joinbss_callback; - } - } - - /*s3. update cur_network & indicate connect*/ - memcpy(&cur_network->network, &pnetwork->network, - pnetwork->network.Length); - cur_network->aid = pnetwork->join_res; - /*update fw_state will clr _FW_UNDER_LINKING*/ - switch (pnetwork->network.InfrastructureMode) { - case Ndis802_11Infrastructure: - pmlmepriv->fw_state = WIFI_STATION_STATE; - break; - case Ndis802_11IBSS: - pmlmepriv->fw_state = WIFI_ADHOC_STATE; - break; - default: - pmlmepriv->fw_state = WIFI_NULL_STATE; - break; - } - r8712_update_protection(adapter, - (cur_network->network.IEs) + - sizeof(struct NDIS_802_11_FIXED_IEs), - (cur_network->network.IELength)); - /*TODO: update HT_Capability*/ - update_ht_cap(adapter, cur_network->network.IEs, - cur_network->network.IELength); - /*indicate connect*/ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - r8712_indicate_connect(adapter); - del_timer(&pmlmepriv->assoc_timer); - } else { - goto ignore_joinbss_callback; - } - } else { - if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(1)); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - } - } -ignore_joinbss_callback: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - if (sizeof(struct list_head) == 4 * sizeof(u32)) - kfree(pnetwork); -} - -void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL; - struct sta_info *psta; - struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); - struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf; - - /* to do: */ - if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr)) - return; - psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (psta) { - /*the sta have been in sta_info_queue => do nothing - *(between drv has received this event before and - * fw have not yet to set key to CAM_ENTRY) - */ - return; - } - - psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (!psta) - return; - /* to do : init sta_info variable */ - psta->qos_option = 0; - psta->mac_id = le32_to_cpu(pstassoc->cam_id); - /* psta->aid = (uint)pstassoc->cam_id; */ - - if (adapter->securitypriv.AuthAlgrthm == 2) - psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm; - psta->ieee8021x_blocked = false; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - if (adapter->stapriv.asoc_sta_count == 2) { - /* a sta + bc/mc_stainfo (not Ibss_stainfo) */ - r8712_indicate_connect(adapter); - } - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - unsigned long irqL, irqL2; - struct sta_info *psta; - struct wlan_network *pwlan = NULL; - struct wlan_bssid_ex *pdev_network = NULL; - u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct stadel_event *pstadel = (struct stadel_event *)pbuf; - struct sta_priv *pstapriv = &adapter->stapriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - - spin_lock_irqsave(&pmlmepriv->lock, irqL2); - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - r8712_ind_disconnect(adapter); - r8712_free_assoc_resources(adapter); - } - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | - WIFI_ADHOC_STATE)) { - psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr); - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - r8712_free_stainfo(adapter, psta); - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); - if (adapter->stapriv.asoc_sta_count == 1) { - /*a sta + bc/mc_stainfo (not Ibss_stainfo) */ - pwlan = r8712_find_network(&pmlmepriv->scanned_queue, - tgt_network->network.MacAddress); - if (pwlan) { - pwlan->fixed = false; - free_network_nolock(pmlmepriv, pwlan); - } - /*re-create ibss*/ - pdev_network = &(adapter->registrypriv.dev_network); - pibss = adapter->registrypriv.dev_network.MacAddress; - memcpy(pdev_network, &tgt_network->network, - r8712_get_wlan_bssid_ex_sz(&tgt_network->network)); - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network(adapter); - r8712_generate_random_ibss(pibss); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE); - set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE); - } - } - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL2); -} - -void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - struct reportpwrstate_parm *preportpwrstate = - (struct reportpwrstate_parm *)pbuf; - - preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80); - r8712_cpwm_int_hdl(adapter, preportpwrstate); -} - -/* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send - * the ADDBA req frame with start seq control = 0 to wifi client after - * the WPA handshake and the seqence number of following data packet - * will be 0. In this case, the Rx reorder sequence is not longer than 0 - * and the WiFi client will drop the data with seq number 0. - * So, the 8712 firmware has to inform driver with receiving the - * ADDBA-Req frame so that the driver can reset the - * sequence value of Rx reorder control. - */ -void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - struct ADDBA_Req_Report_parm *pAddbareq_pram = - (struct ADDBA_Req_Report_parm *)pbuf; - struct sta_info *psta; - struct sta_priv *pstapriv = &adapter->stapriv; - struct recv_reorder_ctrl *precvreorder_ctrl = NULL; - - psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress); - if (psta) { - precvreorder_ctrl = - &psta->recvreorder_ctrl[pAddbareq_pram->tid]; - /* set the indicate_seq to 0xffff so that the rx reorder - * can store any following data packet. - */ - precvreorder_ctrl->indicate_seq = 0xffff; - } -} - -void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf) -{ - if (!adapter->securitypriv.wps_hw_pbc_pressed) - adapter->securitypriv.wps_hw_pbc_pressed = true; -} - -void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter) -{ - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl; - struct registry_priv *pregistrypriv = &adapter->registrypriv; - u64 current_tx_pkts; - uint current_rx_pkts; - - current_tx_pkts = (adapter->xmitpriv.tx_pkts) - - (psitesurveyctrl->last_tx_pkts); - current_rx_pkts = (adapter->recvpriv.rx_pkts) - - (psitesurveyctrl->last_rx_pkts); - psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts; - psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts; - if ((current_tx_pkts > pregistrypriv->busy_thresh) || - (current_rx_pkts > pregistrypriv->busy_thresh)) - psitesurveyctrl->traffic_busy = true; - else - psitesurveyctrl->traffic_busy = false; -} - -void _r8712_join_timeout_handler(struct _adapter *adapter) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - if (adapter->driver_stopped || adapter->surprise_removed) - return; - spin_lock_irqsave(&pmlmepriv->lock, irqL); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - pmlmepriv->to_join = false; - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - r8712_os_indicate_disconnect(adapter); - _clr_fwstate_(pmlmepriv, _FW_LINKED); - } - if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) { - r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, - adapter->registrypriv.smart_ps); - } - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_scan_timeout_handler (struct _adapter *adapter) -{ - unsigned long irqL; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); - pmlmepriv->to_join = false; /* scan fail, so clear to_join flag */ - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void _r8712_dhcp_timeout_handler (struct _adapter *adapter) -{ - if (adapter->driver_stopped || adapter->surprise_removed) - return; - if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) - r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt, - adapter->registrypriv.smart_ps); -} - -int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) -{ - struct list_head *phead; - unsigned char *dst_ssid, *src_ssid; - struct _adapter *adapter; - struct __queue *queue = NULL; - struct wlan_network *pnetwork = NULL; - struct wlan_network *pnetwork_max_rssi = NULL; - - adapter = (struct _adapter *)pmlmepriv->nic_hdl; - queue = &pmlmepriv->scanned_queue; - phead = &queue->queue; - pmlmepriv->pscanned = phead->next; - while (1) { - if (end_of_queue_search(phead, pmlmepriv->pscanned)) { - if (pmlmepriv->assoc_by_rssi && pnetwork_max_rssi) { - pnetwork = pnetwork_max_rssi; - goto ask_for_joinbss; - } - return -EINVAL; - } - pnetwork = container_of(pmlmepriv->pscanned, - struct wlan_network, list); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - if (pmlmepriv->assoc_by_bssid) { - dst_ssid = pnetwork->network.MacAddress; - src_ssid = pmlmepriv->assoc_bssid; - if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - if (is_same_network(&pmlmepriv->cur_network.network, - &pnetwork->network)) { - _clr_fwstate_(pmlmepriv, - _FW_UNDER_LINKING); - /*r8712_indicate_connect again*/ - r8712_indicate_connect(adapter); - return 2; - } - r8712_disassoc_cmd(adapter); - r8712_ind_disconnect(adapter); - r8712_free_assoc_resources(adapter); - } - goto ask_for_joinbss; - } - } else if (pmlmepriv->assoc_ssid.SsidLength == 0) { - goto ask_for_joinbss; - } - dst_ssid = pnetwork->network.Ssid.Ssid; - src_ssid = pmlmepriv->assoc_ssid.Ssid; - if ((pnetwork->network.Ssid.SsidLength == - pmlmepriv->assoc_ssid.SsidLength) && - (!memcmp(dst_ssid, src_ssid, - pmlmepriv->assoc_ssid.SsidLength))) { - if (pmlmepriv->assoc_by_rssi) { - /* if the ssid is the same, select the bss - * which has the max rssi - */ - if (pnetwork_max_rssi) { - if (pnetwork->network.Rssi > - pnetwork_max_rssi->network.Rssi) - pnetwork_max_rssi = pnetwork; - } else { - pnetwork_max_rssi = pnetwork; - } - } else if (is_desired_network(adapter, pnetwork)) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - r8712_disassoc_cmd(adapter); - r8712_free_assoc_resources(adapter); - } - goto ask_for_joinbss; - } - } - } - -ask_for_joinbss: - return r8712_joinbss_cmd(adapter, pnetwork); -} - -int r8712_set_auth(struct _adapter *adapter, - struct security_priv *psecuritypriv) -{ - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - struct cmd_obj *pcmd; - struct setauth_parm *psetauthparm; - - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - - psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC); - if (!psetauthparm) { - kfree(pcmd); - return -ENOMEM; - } - psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm; - pcmd->cmdcode = _SetAuth_CMD_; - pcmd->parmbuf = (unsigned char *)psetauthparm; - pcmd->cmdsz = sizeof(struct setauth_parm); - pcmd->rsp = NULL; - pcmd->rspsz = 0; - INIT_LIST_HEAD(&pcmd->list); - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; -} - -int r8712_set_key(struct _adapter *adapter, - struct security_priv *psecuritypriv, - sint keyid) -{ - struct cmd_priv *pcmdpriv = &adapter->cmdpriv; - struct cmd_obj *pcmd; - struct setkey_parm *psetkeyparm; - u8 keylen; - int ret; - - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return -ENOMEM; - psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC); - if (!psetkeyparm) { - ret = -ENOMEM; - goto err_free_cmd; - } - if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */ - psetkeyparm->algorithm = - (u8)psecuritypriv->XGrpPrivacy; - } else { /* WEP */ - psetkeyparm->algorithm = - (u8)psecuritypriv->PrivacyAlgrthm; - } - psetkeyparm->keyid = (u8)keyid; - - switch (psetkeyparm->algorithm) { - case _WEP40_: - keylen = 5; - memcpy(psetkeyparm->key, - psecuritypriv->DefKey[keyid].skey, keylen); - break; - case _WEP104_: - keylen = 13; - memcpy(psetkeyparm->key, - psecuritypriv->DefKey[keyid].skey, keylen); - break; - case _TKIP_: - if (keyid < 1 || keyid > 2) { - ret = -EINVAL; - goto err_free_parm; - } - keylen = 16; - memcpy(psetkeyparm->key, - &psecuritypriv->XGrpKey[keyid - 1], keylen); - psetkeyparm->grpkey = 1; - break; - case _AES_: - if (keyid < 1 || keyid > 2) { - ret = -EINVAL; - goto err_free_parm; - } - keylen = 16; - memcpy(psetkeyparm->key, - &psecuritypriv->XGrpKey[keyid - 1], keylen); - psetkeyparm->grpkey = 1; - break; - default: - ret = -EINVAL; - goto err_free_parm; - } - pcmd->cmdcode = _SetKey_CMD_; - pcmd->parmbuf = (u8 *)psetkeyparm; - pcmd->cmdsz = (sizeof(struct setkey_parm)); - pcmd->rsp = NULL; - pcmd->rspsz = 0; - INIT_LIST_HEAD(&pcmd->list); - r8712_enqueue_cmd(pcmdpriv, pcmd); - return 0; - -err_free_parm: - kfree(psetkeyparm); -err_free_cmd: - kfree(pcmd); - return ret; -} - -/* adjust IEs for r8712_joinbss_cmd in WMM */ -int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie, - uint in_len, uint initial_out_len) -{ - unsigned int ielength = 0; - unsigned int i, j; - - i = 12; /* after the fixed IE */ - while (i < in_len) { - ielength = initial_out_len; - if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && - in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && - in_ie[i + 5] == 0x02 && i + 5 < in_len) { - /*WMM element ID and OUI*/ - for (j = i; j < i + 9; j++) { - out_ie[ielength] = in_ie[j]; - ielength++; - } - out_ie[initial_out_len + 1] = 0x07; - out_ie[initial_out_len + 6] = 0x00; - out_ie[initial_out_len + 8] = 0x00; - break; - } - i += (in_ie[i + 1] + 2); /* to the next IE element */ - } - return ielength; -} - -/* - * Ported from 8185: IsInPreAuthKeyList(). - * - * Search by BSSID, - * Return Value: - * -1 :if there is no pre-auth key in the table - * >=0 :if there is pre-auth key, and return the entry id - */ -static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid) -{ - struct security_priv *p = &Adapter->securitypriv; - int i; - - for (i = 0; i < NUM_PMKID_CACHE; i++) - if (p->PMKIDList[i].bUsed && !memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN)) - return i; - return -1; -} - -sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, - u8 *out_ie, uint in_len) -{ - u8 authmode = 0, match; - u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255]; - u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01}; - uint ielength, cnt, remove_cnt; - int iEntry; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - struct security_priv *psecuritypriv = &adapter->securitypriv; - uint ndisauthmode = psecuritypriv->ndisauthtype; - uint ndissecuritytype = psecuritypriv->ndisencryptstatus; - - if ((ndisauthmode == Ndis802_11AuthModeWPA) || - (ndisauthmode == Ndis802_11AuthModeWPAPSK)) { - authmode = _WPA_IE_ID_; - uncst_oui[0] = 0x0; - uncst_oui[1] = 0x50; - uncst_oui[2] = 0xf2; - } - if ((ndisauthmode == Ndis802_11AuthModeWPA2) || - (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) { - authmode = _WPA2_IE_ID_; - uncst_oui[0] = 0x0; - uncst_oui[1] = 0x0f; - uncst_oui[2] = 0xac; - } - switch (ndissecuritytype) { - case Ndis802_11Encryption1Enabled: - case Ndis802_11Encryption1KeyAbsent: - uncst_oui[3] = 0x1; - break; - case Ndis802_11Encryption2Enabled: - case Ndis802_11Encryption2KeyAbsent: - uncst_oui[3] = 0x2; - break; - case Ndis802_11Encryption3Enabled: - case Ndis802_11Encryption3KeyAbsent: - uncst_oui[3] = 0x4; - break; - default: - break; - } - /*Search required WPA or WPA2 IE and copy to sec_ie[] */ - cnt = 12; - match = false; - while (cnt < in_len) { - if (in_ie[cnt] == authmode) { - if ((authmode == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) { - memcpy(&sec_ie[0], &in_ie[cnt], - in_ie[cnt + 1] + 2); - match = true; - break; - } - if (authmode == _WPA2_IE_ID_) { - memcpy(&sec_ie[0], &in_ie[cnt], - in_ie[cnt + 1] + 2); - match = true; - break; - } - if (((authmode == _WPA_IE_ID_) && - (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) || - (authmode == _WPA2_IE_ID_)) - memcpy(&bkup_ie[0], &in_ie[cnt], - in_ie[cnt + 1] + 2); - } - cnt += in_ie[cnt + 1] + 2; /*get next*/ - } - /*restruct WPA IE or WPA2 IE in sec_ie[] */ - if (match) { - if (sec_ie[0] == _WPA_IE_ID_) { - /* parsing SSN IE to select required encryption - * algorithm, and set the bc/mc encryption algorithm - */ - while (true) { - /*check wpa_oui tag*/ - if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) { - match = false; - break; - } - if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) { - /*IE Ver error*/ - match = false; - break; - } - if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) { - /* get bc/mc encryption type (group - * key type) - */ - switch (sec_ie[11]) { - case 0x0: /*none*/ - psecuritypriv->XGrpPrivacy = - _NO_PRIVACY_; - break; - case 0x1: /*WEP_40*/ - psecuritypriv->XGrpPrivacy = - _WEP40_; - break; - case 0x2: /*TKIP*/ - psecuritypriv->XGrpPrivacy = - _TKIP_; - break; - case 0x3: /*AESCCMP*/ - case 0x4: - psecuritypriv->XGrpPrivacy = - _AES_; - break; - case 0x5: /*WEP_104*/ - psecuritypriv->XGrpPrivacy = - _WEP104_; - break; - } - } else { - match = false; - break; - } - if (sec_ie[12] == 0x01) { - /*check the unicast encryption type*/ - if (memcmp(&sec_ie[14], - &uncst_oui[0], 4)) { - match = false; - break; - - } /*else the uncst_oui is match*/ - } else { /*mixed mode, unicast_enc_type > 1*/ - /*select the uncst_oui and remove - * the other uncst_oui - */ - cnt = sec_ie[12]; - remove_cnt = (cnt - 1) * 4; - sec_ie[12] = 0x01; - memcpy(&sec_ie[14], &uncst_oui[0], 4); - /*remove the other unicast suit*/ - memcpy(&sec_ie[18], - &sec_ie[18 + remove_cnt], - sec_ie[1] - 18 + 2 - - remove_cnt); - sec_ie[1] = sec_ie[1] - remove_cnt; - } - break; - } - } - if (authmode == _WPA2_IE_ID_) { - /* parsing RSN IE to select required encryption - * algorithm, and set the bc/mc encryption algorithm - */ - while (true) { - if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) { - /*IE Ver error*/ - match = false; - break; - } - if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) { - /*get bc/mc encryption type*/ - switch (sec_ie[7]) { - case 0x1: /*WEP_40*/ - psecuritypriv->XGrpPrivacy = - _WEP40_; - break; - case 0x2: /*TKIP*/ - psecuritypriv->XGrpPrivacy = - _TKIP_; - break; - case 0x4: /*AESWRAP*/ - psecuritypriv->XGrpPrivacy = - _AES_; - break; - case 0x5: /*WEP_104*/ - psecuritypriv->XGrpPrivacy = - _WEP104_; - break; - default: /*one*/ - psecuritypriv->XGrpPrivacy = - _NO_PRIVACY_; - break; - } - } else { - match = false; - break; - } - if (sec_ie[8] == 0x01) { - /*check the unicast encryption type*/ - if (memcmp(&sec_ie[10], - &uncst_oui[0], 4)) { - match = false; - break; - } /*else the uncst_oui is match*/ - } else { /*mixed mode, unicast_enc_type > 1*/ - /*select the uncst_oui and remove the - * other uncst_oui - */ - cnt = sec_ie[8]; - remove_cnt = (cnt - 1) * 4; - sec_ie[8] = 0x01; - memcpy(&sec_ie[10], &uncst_oui[0], 4); - /*remove the other unicast suit*/ - memcpy(&sec_ie[14], - &sec_ie[14 + remove_cnt], - (sec_ie[1] - 14 + 2 - - remove_cnt)); - sec_ie[1] = sec_ie[1] - remove_cnt; - } - break; - } - } - } - if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) { - /*copy fixed ie*/ - memcpy(out_ie, in_ie, 12); - ielength = 12; - /*copy RSN or SSN*/ - if (match) { - memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2); - ielength += sec_ie[1] + 2; - if (authmode == _WPA2_IE_ID_) { - /*the Pre-Authentication bit should be zero*/ - out_ie[ielength - 1] = 0; - out_ie[ielength - 2] = 0; - } - r8712_report_sec_ie(adapter, authmode, sec_ie); - } - } else { - /*copy fixed ie only*/ - memcpy(out_ie, in_ie, 12); - ielength = 12; - if (psecuritypriv->wps_phase) { - memcpy(out_ie + ielength, psecuritypriv->wps_ie, - psecuritypriv->wps_ie_len); - ielength += psecuritypriv->wps_ie_len; - } - } - iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid); - if (iEntry < 0) - return ielength; - if (authmode == _WPA2_IE_ID_) { - out_ie[ielength] = 1; - ielength++; - out_ie[ielength] = 0; /*PMKID count = 0x0100*/ - ielength++; - memcpy(&out_ie[ielength], - &psecuritypriv->PMKIDList[iEntry].PMKID, 16); - ielength += 16; - out_ie[13] += 18;/*PMKID length = 2+16*/ - } - return ielength; -} - -void r8712_init_registrypriv_dev_network(struct _adapter *adapter) -{ - struct registry_priv *pregistrypriv = &adapter->registrypriv; - struct eeprom_priv *peepriv = &adapter->eeprompriv; - struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; - u8 *myhwaddr = myid(peepriv); - - memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN); - memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, - sizeof(struct ndis_802_11_ssid)); - pdev_network->Configuration.Length = - sizeof(struct NDIS_802_11_CONFIGURATION); - pdev_network->Configuration.BeaconPeriod = 100; - pdev_network->Configuration.FHConfig.Length = 0; - pdev_network->Configuration.FHConfig.HopPattern = 0; - pdev_network->Configuration.FHConfig.HopSet = 0; - pdev_network->Configuration.FHConfig.DwellTime = 0; -} - -void r8712_update_registrypriv_dev_network(struct _adapter *adapter) -{ - int sz = 0; - struct registry_priv *pregistrypriv = &adapter->registrypriv; - struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; - struct security_priv *psecuritypriv = &adapter->securitypriv; - struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; - - pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm - > 0 ? 1 : 0); /* adhoc no 802.1x */ - pdev_network->Rssi = 0; - switch (pregistrypriv->wireless_mode) { - case WIRELESS_11B: - pdev_network->NetworkTypeInUse = Ndis802_11DS; - break; - case WIRELESS_11G: - case WIRELESS_11BG: - pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; - break; - case WIRELESS_11A: - pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; - break; - default: - /* TODO */ - break; - } - pdev_network->Configuration.DSConfig = pregistrypriv->channel; - if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) - pdev_network->Configuration.ATIMWindow = 3; - pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode; - /* 1. Supported rates - * 2. IE - */ - sz = r8712_generate_ie(pregistrypriv); - pdev_network->IELength = sz; - pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network); -} - -/*the function is at passive_level*/ -void r8712_joinbss_reset(struct _adapter *padapter) -{ - int i; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - /* todo: if you want to do something io/reg/hw setting before join_bss, - * please add code here - */ - phtpriv->ampdu_enable = false;/*reset to disabled*/ - for (i = 0; i < 16; i++) - phtpriv->baddbareq_issued[i] = false;/*reset it*/ - if (phtpriv->ht_option) { - /* validate usb rx aggregation */ - r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/ - } else { - /* invalidate usb rx aggregation */ - /* TH=1 => means that invalidate usb rx aggregation */ - r8712_write8(padapter, 0x102500D9, 1); - } -} - -/*the function is >= passive_level*/ -unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, - u8 *out_ie, uint in_len, uint *pout_len) -{ - u32 ielen, out_len; - unsigned char *p; - struct ieee80211_ht_cap ht_capie; - unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - phtpriv->ht_option = 0; - p = r8712_get_ie(in_ie + 12, WLAN_EID_HT_CAPABILITY, &ielen, in_len - 12); - if (p && (ielen > 0)) { - if (pqospriv->qos_option == 0) { - out_len = *pout_len; - r8712_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC, - _WMM_IE_Length_, WMM_IE, pout_len); - pqospriv->qos_option = 1; - } - out_len = *pout_len; - memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap)); - ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_TX_STBC | - IEEE80211_HT_CAP_MAX_AMSDU | - IEEE80211_HT_CAP_DSSSCCK40); - ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR & - 0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00); - r8712_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY, - sizeof(struct ieee80211_ht_cap), - (unsigned char *)&ht_capie, pout_len); - phtpriv->ht_option = 1; - } - return phtpriv->ht_option; -} - -/* the function is > passive_level (in critical_section) */ -static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) -{ - u8 *p, max_ampdu_sz; - int i; - uint len; - struct sta_info *bmc_sta, *psta; - struct ieee80211_ht_cap *pht_capie; - struct recv_reorder_ctrl *preorder_ctrl; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - struct registry_priv *pregistrypriv = &padapter->registrypriv; - struct wlan_network *pcur_network = &(pmlmepriv->cur_network); - - if (!phtpriv->ht_option) - return; - /* maybe needs check if ap supports rx ampdu. */ - if (!phtpriv->ampdu_enable && - (pregistrypriv->ampdu_enable == 1)) - phtpriv->ampdu_enable = true; - /*check Max Rx A-MPDU Size*/ - len = 0; - p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), - WLAN_EID_HT_CAPABILITY, - &len, ie_len - - sizeof(struct NDIS_802_11_FIXED_IEs)); - if (p && len > 0) { - pht_capie = (struct ieee80211_ht_cap *)(p + 2); - max_ampdu_sz = (pht_capie->ampdu_params_info & - IEEE80211_HT_AMPDU_PARM_FACTOR); - /* max_ampdu_sz (kbytes); */ - max_ampdu_sz = 1 << (max_ampdu_sz + 3); - phtpriv->rx_ampdu_maxlen = max_ampdu_sz; - } - /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info - * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl - * wstart_b(indicate_seq) to default value=0xffff - * todo: check if AP can send A-MPDU packets - */ - bmc_sta = r8712_get_bcmc_stainfo(padapter); - if (bmc_sta) { - for (i = 0; i < 16; i++) { - preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - } - } - psta = r8712_get_stainfo(&padapter->stapriv, - pcur_network->network.MacAddress); - if (psta) { - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - } - } - len = 0; - p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs), - WLAN_EID_HT_OPERATION, &len, - ie_len - sizeof(struct NDIS_802_11_FIXED_IEs)); -} - -void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority) -{ - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ht_priv *phtpriv = &pmlmepriv->htpriv; - - if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) { - if (!phtpriv->baddbareq_issued[priority]) { - r8712_addbareq_cmd(padapter, (u8)priority); - phtpriv->baddbareq_issued[priority] = true; - } - } -} diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h deleted file mode 100644 index d7d25f240111..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ /dev/null @@ -1,205 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_MLME_H_ -#define __RTL871X_MLME_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wlan_bssdef.h" - -#define MAX_BSS_CNT 64 -#define MAX_JOIN_TIMEOUT 6000 - -#define SCANNING_TIMEOUT 4500 - -#define SCANQUEUE_LIFETIME 20 /* unit:sec */ - -#define WIFI_NULL_STATE 0x00000000 -#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state...*/ -#define WIFI_REASOC_STATE 0x00000002 -#define WIFI_SLEEP_STATE 0x00000004 -#define WIFI_STATION_STATE 0x00000008 -#define WIFI_AP_STATE 0x00000010 -#define WIFI_ADHOC_STATE 0x00000020 -#define WIFI_ADHOC_MASTER_STATE 0x00000040 -#define WIFI_UNDER_LINKING 0x00000080 -#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station - * is under site surveying - */ -#define WIFI_MP_STATE 0x00010000 -#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in cont. tx background*/ -#define WIFI_MP_CTX_ST 0x00040000 /* in cont. tx with - * single-tone - */ -#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in cont, tx - * background due - * to out of skb - */ -#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx*/ -#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in cont, tx with carrier - * suppression - */ -#define WIFI_MP_LPBK_STATE 0x00400000 - -#define _FW_UNDER_LINKING WIFI_UNDER_LINKING -#define _FW_LINKED WIFI_ASOC_STATE -#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR - -/* - * there are several "locks" in mlme_priv, - * since mlme_priv is a shared resource between many threads, - * like ISR/Call-Back functions, the OID handlers, and even timer functions. - * Each _queue has its own locks, already. - * Other items are protected by mlme_priv.lock. - * To avoid possible dead lock, any thread trying to modify mlme_priv - * SHALL not lock up more than one lock at a time! - */ - -#define traffic_threshold 10 -#define traffic_scan_period 500 - -struct sitesurvey_ctrl { - u64 last_tx_pkts; - uint last_rx_pkts; - sint traffic_busy; - struct timer_list sitesurvey_ctrl_timer; -}; - -struct mlme_priv { - spinlock_t lock; - spinlock_t lock2; - sint fw_state; /*shall we protect this variable? */ - u8 to_join; /*flag*/ - u8 *nic_hdl; - struct list_head *pscanned; - struct __queue free_bss_pool; - struct __queue scanned_queue; - u8 *free_bss_buf; - unsigned long num_of_scanned; - u8 passive_mode; /*add for Android's SCAN-ACTIVE/SCAN-PASSIVE */ - struct ndis_802_11_ssid assoc_ssid; - u8 assoc_bssid[6]; - struct wlan_network cur_network; - struct sitesurvey_ctrl sitesurveyctrl; - struct timer_list assoc_timer; - uint assoc_by_bssid; - uint assoc_by_rssi; - struct timer_list scan_to_timer; /* driver handles scan_timeout.*/ - struct timer_list dhcp_timer; /* set dhcp to if driver in ps mode.*/ - struct qos_priv qospriv; - struct ht_priv htpriv; - struct timer_list wdg_timer; /*watchdog periodic timer*/ -}; - -static inline u8 *get_bssid(struct mlme_priv *pmlmepriv) -{ - return pmlmepriv->cur_network.network.MacAddress; -} - -static inline u8 check_fwstate(struct mlme_priv *pmlmepriv, sint state) -{ - if (pmlmepriv->fw_state & state) - return true; - return false; -} - -static inline sint get_fwstate(struct mlme_priv *pmlmepriv) -{ - return pmlmepriv->fw_state; -} - -/* - * No Limit on the calling context, - * therefore set it to be the critical section... - * - * ### NOTE:#### (!!!!) - * TAKE CARE BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock - */ -static inline void set_fwstate(struct mlme_priv *pmlmepriv, sint state) -{ - pmlmepriv->fw_state |= state; -} - -static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) -{ - pmlmepriv->fw_state &= ~state; -} - -/* - * No Limit on the calling context, - * therefore set it to be the critical section... - */ -static inline void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) -{ - unsigned long irqL; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, state)) - pmlmepriv->fw_state ^= state; - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, - sint val) -{ - unsigned long irqL; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - pmlmepriv->num_of_scanned = val; - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); -} - -void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf); -void r8712_free_network_queue(struct _adapter *adapter); -int r8712_init_mlme_priv(struct _adapter *adapter); -void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv); -int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv); -int r8712_set_key(struct _adapter *adapter, - struct security_priv *psecuritypriv, sint keyid); -int r8712_set_auth(struct _adapter *adapter, - struct security_priv *psecuritypriv); -uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss); -void r8712_generate_random_ibss(u8 *pibss); -u8 *r8712_get_capability_from_ie(u8 *ie); -struct wlan_network *r8712_get_oldest_wlan_network( - struct __queue *scanned_queue); -void r8712_free_assoc_resources(struct _adapter *adapter); -void r8712_ind_disconnect(struct _adapter *adapter); -void r8712_indicate_connect(struct _adapter *adapter); -int r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie, - u8 *out_ie, uint in_len); -int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, - u8 *out_ie, uint in_len, uint initial_out_len); -void r8712_init_registrypriv_dev_network(struct _adapter *adapter); -void r8712_update_registrypriv_dev_network(struct _adapter *adapter); -void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter); -void _r8712_join_timeout_handler(struct _adapter *adapter); -void r8712_scan_timeout_handler(struct _adapter *adapter); -void _r8712_dhcp_timeout_handler(struct _adapter *adapter); -struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv); -sint r8712_if_up(struct _adapter *padapter); -void r8712_joinbss_reset(struct _adapter *padapter); -unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie, - u8 *out_ie, uint in_len, uint *pout_len); -void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority); -int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork); - -#endif /*__RTL871X_MLME_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c deleted file mode 100644 index 099c512c8519..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ /dev/null @@ -1,724 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#define _RTL871X_MP_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "rtl871x_mp_phy_regdef.h" -#include "rtl8712_cmd.h" - -static void _init_mp_priv_(struct mp_priv *pmp_priv) -{ - pmp_priv->mode = _LOOPBOOK_MODE_; - pmp_priv->curr_ch = 1; - pmp_priv->curr_modem = MIXED_PHY; - pmp_priv->curr_rateidx = 0; - pmp_priv->curr_txpoweridx = 0x14; - pmp_priv->antenna_tx = ANTENNA_A; - pmp_priv->antenna_rx = ANTENNA_AB; - pmp_priv->check_mp_pkt = 0; - pmp_priv->tx_pktcount = 0; - pmp_priv->rx_pktcount = 0; - pmp_priv->rx_crcerrpktcount = 0; -} - -static int init_mp_priv(struct mp_priv *pmp_priv) -{ - int i; - struct mp_xmit_frame *pmp_xmitframe; - - _init_mp_priv_(pmp_priv); - _init_queue(&pmp_priv->free_mp_xmitqueue); - pmp_priv->pallocated_mp_xmitframe_buf = NULL; - pmp_priv->pallocated_mp_xmitframe_buf = kmalloc(NR_MP_XMITFRAME * - sizeof(struct mp_xmit_frame) + 4, - GFP_ATOMIC); - if (!pmp_priv->pallocated_mp_xmitframe_buf) - return -ENOMEM; - - pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + - 4 - - ((addr_t)(pmp_priv->pallocated_mp_xmitframe_buf) & 3); - pmp_xmitframe = (struct mp_xmit_frame *)pmp_priv->pmp_xmtframe_buf; - for (i = 0; i < NR_MP_XMITFRAME; i++) { - INIT_LIST_HEAD(&(pmp_xmitframe->list)); - list_add_tail(&(pmp_xmitframe->list), - &(pmp_priv->free_mp_xmitqueue.queue)); - pmp_xmitframe->pkt = NULL; - pmp_xmitframe->frame_tag = MP_FRAMETAG; - pmp_xmitframe->padapter = pmp_priv->papdater; - pmp_xmitframe++; - } - pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME; - return 0; -} - -static int free_mp_priv(struct mp_priv *pmp_priv) -{ - kfree(pmp_priv->pallocated_mp_xmitframe_buf); - return 0; -} - -void mp871xinit(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - - pmppriv->papdater = padapter; - init_mp_priv(pmppriv); -} - -void mp871xdeinit(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - - free_mp_priv(pmppriv); -} - -/* - * Special for bb and rf reg read/write - */ -static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd) -{ - u32 cmd32 = 0, val32 = 0; - u8 iocmd_class = iocmd.cmdclass; - u16 iocmd_value = iocmd.value; - u8 iocmd_idx = iocmd.index; - - cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx; - if (r8712_fw_cmd(pAdapter, cmd32)) - r8712_fw_cmd_data(pAdapter, &val32, 1); - else - val32 = 0; - return val32; -} - -static u8 fw_iocmd_write(struct _adapter *pAdapter, - struct IOCMD_STRUCT iocmd, u32 value) -{ - u32 cmd32 = 0; - u8 iocmd_class = iocmd.cmdclass; - u32 iocmd_value = iocmd.value; - u8 iocmd_idx = iocmd.index; - - r8712_fw_cmd_data(pAdapter, &value, 0); - msleep(100); - cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx; - return r8712_fw_cmd(pAdapter, cmd32); -} - -/* offset : 0X800~0XFFF */ -u32 r8712_bb_reg_read(struct _adapter *pAdapter, u16 offset) -{ - u8 shift = offset & 0x0003; /* 4 byte access */ - u16 bb_addr = offset & 0x0FFC; /* 4 byte access */ - u32 bb_val = 0; - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = bb_addr; - iocmd.index = IOCMD_BB_READ_IDX; - bb_val = fw_iocmd_read(pAdapter, iocmd); - if (shift != 0) { - u32 bb_val2 = 0; - - bb_val >>= (shift * 8); - iocmd.value += 4; - bb_val2 = fw_iocmd_read(pAdapter, iocmd); - bb_val2 <<= ((4 - shift) * 8); - bb_val |= bb_val2; - } - return bb_val; -} - -/* offset : 0X800~0XFFF */ -u8 r8712_bb_reg_write(struct _adapter *pAdapter, u16 offset, u32 value) -{ - u8 shift = offset & 0x0003; /* 4 byte access */ - u16 bb_addr = offset & 0x0FFC; /* 4 byte access */ - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = bb_addr; - iocmd.index = IOCMD_BB_WRITE_IDX; - if (shift != 0) { - u32 oldValue = 0; - u32 newValue = value; - - oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); - oldValue &= (0xFFFFFFFF >> ((4 - shift) * 8)); - value = oldValue | (newValue << (shift * 8)); - if (!fw_iocmd_write(pAdapter, iocmd, value)) - return false; - iocmd.value += 4; - oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); - oldValue &= (0xFFFFFFFF << (shift * 8)); - value = oldValue | (newValue >> ((4 - shift) * 8)); - } - return fw_iocmd_write(pAdapter, iocmd, value); -} - -/* offset : 0x00 ~ 0xFF */ -u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset) -{ - u16 rf_addr = (path << 8) | offset; - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = rf_addr; - iocmd.index = IOCMD_RF_READ_IDX; - return fw_iocmd_read(pAdapter, iocmd); -} - -u8 r8712_rf_reg_write(struct _adapter *pAdapter, u8 path, u8 offset, u32 value) -{ - u16 rf_addr = (path << 8) | offset; - struct IOCMD_STRUCT iocmd; - - iocmd.cmdclass = IOCMD_CLASS_BB_RF; - iocmd.value = rf_addr; - iocmd.index = IOCMD_RF_WRIT_IDX; - return fw_iocmd_write(pAdapter, iocmd, value); -} - -static u32 bitshift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) - if (((bitmask >> i) & 0x1) == 1) - break; - return i; -} - -static u32 get_bb_reg(struct _adapter *pAdapter, u16 offset, u32 bitmask) -{ - u32 org_value, bit_shift; - - org_value = r8712_bb_reg_read(pAdapter, offset); - bit_shift = bitshift(bitmask); - return (org_value & bitmask) >> bit_shift; -} - -static u8 set_bb_reg(struct _adapter *pAdapter, - u16 offset, - u32 bitmask, - u32 value) -{ - u32 org_value, bit_shift, new_value; - - if (bitmask != bMaskDWord) { - org_value = r8712_bb_reg_read(pAdapter, offset); - bit_shift = bitshift(bitmask); - new_value = (org_value & (~bitmask)) | (value << bit_shift); - } else { - new_value = value; - } - return r8712_bb_reg_write(pAdapter, offset, new_value); -} - -static u32 get_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, - u32 bitmask) -{ - u32 org_value, bit_shift; - - org_value = r8712_rf_reg_read(pAdapter, path, offset); - bit_shift = bitshift(bitmask); - return (org_value & bitmask) >> bit_shift; -} - -static u8 set_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, u32 bitmask, - u32 value) -{ - u32 org_value, bit_shift, new_value; - - if (bitmask != bMaskDWord) { - org_value = r8712_rf_reg_read(pAdapter, path, offset); - bit_shift = bitshift(bitmask); - new_value = (org_value & (~bitmask)) | (value << bit_shift); - } else { - new_value = value; - } - return r8712_rf_reg_write(pAdapter, path, offset, new_value); -} - -/* - * SetChannel - * Description - * Use H2C command to change channel, - * not only modify rf register, but also other setting need to be done. - */ -void r8712_SetChannel(struct _adapter *pAdapter) -{ - struct cmd_priv *pcmdpriv = &pAdapter->cmdpriv; - struct cmd_obj *pcmd = NULL; - struct SetChannel_parm *pparm = NULL; - u16 code = GEN_CMD_CODE(_SetChannel); - - pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); - if (!pcmd) - return; - pparm = kmalloc(sizeof(*pparm), GFP_ATOMIC); - if (!pparm) { - kfree(pcmd); - return; - } - pparm->curr_ch = pAdapter->mppriv.curr_ch; - init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code); - r8712_enqueue_cmd(pcmdpriv, pcmd); -} - -static void SetCCKTxPower(struct _adapter *pAdapter, u8 TxPower) -{ - u16 TxAGC = 0; - - TxAGC = TxPower; - set_bb_reg(pAdapter, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); -} - -static void SetOFDMTxPower(struct _adapter *pAdapter, u8 TxPower) -{ - u32 TxAGC = 0; - - TxAGC |= ((TxPower << 24) | (TxPower << 16) | (TxPower << 8) | - TxPower); - set_bb_reg(pAdapter, rTxAGC_Rate18_06, bTxAGCRate18_06, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Rate54_24, bTxAGCRate54_24, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs03_Mcs00, bTxAGCRateMCS3_MCS0, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs07_Mcs04, bTxAGCRateMCS7_MCS4, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs11_Mcs08, bTxAGCRateMCS11_MCS8, TxAGC); - set_bb_reg(pAdapter, rTxAGC_Mcs15_Mcs12, bTxAGCRateMCS15_MCS12, TxAGC); -} - -void r8712_SetTxPower(struct _adapter *pAdapter) -{ - u8 TxPower = pAdapter->mppriv.curr_txpoweridx; - - SetCCKTxPower(pAdapter, TxPower); - SetOFDMTxPower(pAdapter, TxPower); -} - -void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset) -{ - u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D, tmpAGC; - - TxAGCOffset_B = ulTxAGCOffset & 0x000000ff; - TxAGCOffset_C = (ulTxAGCOffset & 0x0000ff00) >> 8; - TxAGCOffset_D = (ulTxAGCOffset & 0x00ff0000) >> 16; - tmpAGC = TxAGCOffset_D << 8 | TxAGCOffset_C << 4 | TxAGCOffset_B; - set_bb_reg(pAdapter, rFPGA0_TxGainStage, - (bXBTxAGC | bXCTxAGC | bXDTxAGC), tmpAGC); -} - -void r8712_SetDataRate(struct _adapter *pAdapter) -{ - u8 path = RF_PATH_A; - u8 offset = RF_SYN_G2; - u32 value; - - value = (pAdapter->mppriv.curr_rateidx < 4) ? 0x4440 : 0xF200; - r8712_rf_reg_write(pAdapter, path, offset, value); -} - -void r8712_SwitchBandwidth(struct _adapter *pAdapter) -{ - /* 3 1.Set MAC register : BWOPMODE bit2:1 20MhzBW */ - u8 regBwOpMode = 0; - u8 Bandwidth = pAdapter->mppriv.curr_bandwidth; - - regBwOpMode = r8712_read8(pAdapter, 0x10250203); - if (Bandwidth == HT_CHANNEL_WIDTH_20) - regBwOpMode |= BIT(2); - else - regBwOpMode &= ~(BIT(2)); - r8712_write8(pAdapter, 0x10250203, regBwOpMode); - /* 3 2.Set PHY related register */ - switch (Bandwidth) { - /* 20 MHz channel*/ - case HT_CHANNEL_WIDTH_20: - set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x0); - set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x0); - /* Use PHY_REG.txt default value. Do not need to change. - * Correct the tx power for CCK rate in 40M. - * It is set in Tx descriptor for 8192x series - */ - set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x58); - break; - /* 40 MHz channel*/ - case HT_CHANNEL_WIDTH_40: - set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x1); - set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x1); - /* Use PHY_REG.txt default value. Do not need to change. - * Correct the tx power for CCK rate in 40M. - * Set Control channel to upper or lower. These settings are - * required only for 40MHz - */ - set_bb_reg(pAdapter, rCCK0_System, bCCKSideBand, - (HAL_PRIME_CHNL_OFFSET_DONT_CARE >> 1)); - set_bb_reg(pAdapter, rOFDM1_LSTF, 0xC00, - HAL_PRIME_CHNL_OFFSET_DONT_CARE); - set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x18); - break; - default: - break; - } - - /* 3 3.Set RF related register */ - switch (Bandwidth) { - case HT_CHANNEL_WIDTH_20: - set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW, - BIT(10) | BIT(11), 0x01); - break; - case HT_CHANNEL_WIDTH_40: - set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW, - BIT(10) | BIT(11), 0x00); - break; - default: - break; - } -} - -/*------------------------------Define structure----------------------------*/ -struct R_ANTENNA_SELECT_OFDM { - u32 r_tx_antenna:4; - u32 r_ant_l:4; - u32 r_ant_non_ht:4; - u32 r_ant_ht1:4; - u32 r_ant_ht2:4; - u32 r_ant_ht_s1:4; - u32 r_ant_non_ht_s1:4; - u32 OFDM_TXSC:2; - u32 Reserved:2; -}; - -struct R_ANTENNA_SELECT_CCK { - u8 r_cckrx_enable_2:2; - u8 r_cckrx_enable:2; - u8 r_ccktx_enable:4; -}; - -void r8712_SwitchAntenna(struct _adapter *pAdapter) -{ - u32 ofdm_tx_en_val = 0, ofdm_tx_ant_sel_val = 0; - u8 ofdm_rx_ant_sel_val = 0; - u8 cck_ant_select_val = 0; - u32 cck_ant_sel_val = 0; - struct R_ANTENNA_SELECT_CCK *p_cck_txrx; - - p_cck_txrx = (struct R_ANTENNA_SELECT_CCK *)&cck_ant_select_val; - - switch (pAdapter->mppriv.antenna_tx) { - case ANTENNA_A: - /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/ - set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); - set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); - ofdm_tx_en_val = 0x3; - ofdm_tx_ant_sel_val = 0x11111111;/* Power save */ - p_cck_txrx->r_ccktx_enable = 0x8; - break; - case ANTENNA_B: - set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); - set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); - ofdm_tx_en_val = 0x3; - ofdm_tx_ant_sel_val = 0x22222222;/* Power save */ - p_cck_txrx->r_ccktx_enable = 0x4; - break; - case ANTENNA_AB: /* For 8192S */ - set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); - set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); - ofdm_tx_en_val = 0x3; - ofdm_tx_ant_sel_val = 0x3321333; /* Disable Power save */ - p_cck_txrx->r_ccktx_enable = 0xC; - break; - default: - break; - } - /*OFDM Tx*/ - set_bb_reg(pAdapter, rFPGA1_TxInfo, 0xffffffff, ofdm_tx_ant_sel_val); - /*OFDM Tx*/ - set_bb_reg(pAdapter, rFPGA0_TxInfo, 0x0000000f, ofdm_tx_en_val); - switch (pAdapter->mppriv.antenna_rx) { - case ANTENNA_A: - ofdm_rx_ant_sel_val = 0x1; /* A */ - p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */ - p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */ - break; - case ANTENNA_B: - ofdm_rx_ant_sel_val = 0x2; /* B */ - p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */ - p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */ - break; - case ANTENNA_AB: - ofdm_rx_ant_sel_val = 0x3; /* AB */ - p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */ - p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */ - break; - default: - break; - } - /*OFDM Rx*/ - set_bb_reg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, - ofdm_rx_ant_sel_val); - /*OFDM Rx*/ - set_bb_reg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, - ofdm_rx_ant_sel_val); - - cck_ant_sel_val = cck_ant_select_val; - /*CCK TxRx*/ - set_bb_reg(pAdapter, rCCK0_AFESetting, bMaskByte3, cck_ant_sel_val); -} - -static void TriggerRFThermalMeter(struct _adapter *pAdapter) -{ - /* 0x24: RF Reg[6:5] */ - set_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); -} - -static u32 ReadRFThermalMeter(struct _adapter *pAdapter) -{ - /* 0x24: RF Reg[4:0] */ - return get_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, 0x1F); -} - -void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value) -{ - TriggerRFThermalMeter(pAdapter); - msleep(1000); - *value = ReadRFThermalMeter(pAdapter); -} - -void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart) -{ - if (bStart) { /* Start Single Carrier. */ - /* 1. if OFDM block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) - /*set OFDM block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); - /* 2. set CCK test mode off, set to CCK normal mode */ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); - /* 3. turn on scramble setting */ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - /* 4. Turn On Single Carrier Tx and off the other test modes. */ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - } else { /* Stop Single Carrier.*/ - /* Turn off all test modes.*/ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - msleep(20); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } -} - -void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart) -{ - u8 rfPath; - - switch (pAdapter->mppriv.antenna_tx) { - case ANTENNA_B: - rfPath = RF_PATH_B; - break; - case ANTENNA_A: - default: - rfPath = RF_PATH_A; - break; - } - if (bStart) { /* Start Single Tone.*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bDisable); - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bDisable); - set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask, - 0xd4000); - msleep(100); - /* PAD all on.*/ - set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x2001f); - msleep(100); - } else { /* Stop Single Tone.*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable); - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); - set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask, - 0x54000); - msleep(100); - /* PAD all on.*/ - set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x30000); - msleep(100); - } -} - -void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart) -{ - if (bStart) { /* Start Carrier Suppression.*/ - if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) { - /* 1. if CCK block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) { - /*set CCK block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, - bEnable); - } - /* Turn Off All Test Mode */ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, - bDisable); - /*transmit mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); - /*turn off scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, - bDisable); - /*Set CCK Tx Test Rate*/ - /*Set FTxRate to 1Mbps*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); - } - } else { /* Stop Carrier Suppression. */ - if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) { - /*normal mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); - /*turn on scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, - bEnable); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } - } -} - -static void SetCCKContinuousTx(struct _adapter *pAdapter, u8 bStart) -{ - u32 cckrate; - - if (bStart) { - /* 1. if CCK block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) { - /*set CCK block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable); - } - /* Turn Off All Test Mode */ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - /*Set CCK Tx Test Rate*/ - cckrate = pAdapter->mppriv.curr_rateidx; - set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); - /*transmit mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); - /*turn on scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - } else { - /*normal mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); - /*turn on scramble setting*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } -} /* mpt_StartCckContTx */ - -static void SetOFDMContinuousTx(struct _adapter *pAdapter, u8 bStart) -{ - if (bStart) { - /* 1. if OFDM block on? */ - if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) { - /*set OFDM block on*/ - set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); - } - /* 2. set CCK test mode off, set to CCK normal mode*/ - set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); - /* 3. turn on scramble setting */ - set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); - /* 4. Turn On Continue Tx and turn off the other test modes.*/ - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - } else { - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, - bDisable); - set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); - msleep(20); - /*BB Reset*/ - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); - set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); - } -} /* mpt_StartOfdmContTx */ - -void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart) -{ - /* ADC turn off [bit24-21] adc port0 ~ port1 */ - if (bStart) { - r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA, - r8712_bb_reg_read(pAdapter, - rRx_Wait_CCCA) & 0xFE1FFFFF); - msleep(100); - } - if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) - SetCCKContinuousTx(pAdapter, bStart); - else if ((pAdapter->mppriv.curr_rateidx >= MPT_RATE_6M) && - (pAdapter->mppriv.curr_rateidx <= MPT_RATE_MCS15)) - SetOFDMContinuousTx(pAdapter, bStart); - /* ADC turn on [bit24-21] adc port0 ~ port1 */ - if (!bStart) - r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA, - r8712_bb_reg_read(pAdapter, - rRx_Wait_CCCA) | 0x01E00000); -} - -void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter) -{ - u32 i, phyrx_set = 0; - - for (i = OFDM_PPDU_BIT; i <= HT_MPDU_FAIL_BIT; i++) { - phyrx_set = 0; - phyrx_set |= (i << 28); /*select*/ - phyrx_set |= 0x08000000; /* set counter to zero*/ - r8712_write32(pAdapter, RXERR_RPT, phyrx_set); - } -} - -static u32 GetPhyRxPktCounts(struct _adapter *pAdapter, u32 selbit) -{ - /*selection*/ - u32 phyrx_set = 0; - u32 SelectBit; - - SelectBit = selbit << 28; - phyrx_set |= (SelectBit & 0xF0000000); - r8712_write32(pAdapter, RXERR_RPT, phyrx_set); - /*Read packet count*/ - return r8712_read32(pAdapter, RXERR_RPT) & RPTMaxCount; -} - -u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter) -{ - u32 OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_OK_BIT); - u32 CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_OK_BIT); - u32 HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_OK_BIT); - - return OFDM_cnt + CCK_cnt + HT_cnt; -} - -u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter) -{ - u32 OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_FAIL_BIT); - u32 CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_FAIL_BIT); - u32 HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_FAIL_BIT); - - return OFDM_cnt + CCK_cnt + HT_cnt; -} diff --git a/drivers/staging/rtl8712/rtl871x_mp.h b/drivers/staging/rtl8712/rtl871x_mp.h deleted file mode 100644 index 0a60b1e6ccaf..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp.h +++ /dev/null @@ -1,275 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_MP_H_ -#define __RTL871X_MP_H_ - -#define MPT_NOOP 0 -#define MPT_READ_MAC_1BYTE 1 -#define MPT_READ_MAC_2BYTE 2 -#define MPT_READ_MAC_4BYTE 3 -#define MPT_WRITE_MAC_1BYTE 4 -#define MPT_WRITE_MAC_2BYTE 5 -#define MPT_WRITE_MAC_4BYTE 6 -#define MPT_READ_BB_CCK 7 -#define MPT_WRITE_BB_CCK 8 -#define MPT_READ_BB_OFDM 9 -#define MPT_WRITE_BB_OFDM 10 -#define MPT_READ_RF 11 -#define MPT_WRITE_RF 12 -#define MPT_READ_EEPROM_1BYTE 13 -#define MPT_WRITE_EEPROM_1BYTE 14 -#define MPT_READ_EEPROM_2BYTE 15 -#define MPT_WRITE_EEPROM_2BYTE 16 -#define MPT_SET_CSTHRESHOLD 21 -#define MPT_SET_INITGAIN 22 -#define MPT_SWITCH_BAND 23 -#define MPT_SWITCH_CHANNEL 24 -#define MPT_SET_DATARATE 25 -#define MPT_SWITCH_ANTENNA 26 -#define MPT_SET_TX_POWER 27 -#define MPT_SET_CONT_TX 28 -#define MPT_SET_SINGLE_CARRIER 29 -#define MPT_SET_CARRIER_SUPPRESSION 30 -#define MPT_GET_RATE_TABLE 31 -#define MPT_READ_TSSI 32 -#define MPT_GET_THERMAL_METER 33 -#define MAX_MP_XMITBUF_SZ 2048 -#define NR_MP_XMITFRAME 8 - -struct mp_xmit_frame { - struct list_head list; - struct pkt_attrib attrib; - _pkt *pkt; - int frame_tag; - struct _adapter *padapter; - u8 *mem_addr; - u16 sz[8]; - struct urb *pxmit_urb[8]; - u8 bpending[8]; - u8 last[8]; -}; - -struct mp_wiparam { - u32 bcompleted; - u32 act_type; - u32 io_offset; - u32 io_value; -}; - -struct mp_priv { - struct _adapter *papdater; - /*OID cmd handler*/ - struct mp_wiparam workparam; - u8 act_in_progress; - /*Tx Section*/ - u8 TID; - u32 tx_pktcount; - /*Rx Section*/ - u32 rx_pktcount; - u32 rx_crcerrpktcount; - u32 rx_pktloss; - struct recv_stat rxstat; - /*RF/BB relative*/ - u32 curr_ch; - u32 curr_rateidx; - u8 curr_bandwidth; - u8 curr_modem; - u8 curr_txpoweridx; - u32 curr_crystalcap; - u16 antenna_tx; - u16 antenna_rx; - u8 curr_rfpath; - u8 check_mp_pkt; - uint ForcedDataRate; - struct wlan_network mp_network; - unsigned char network_macaddr[6]; - /*Testing Flag*/ - u32 mode;/*0 for normal type packet, - * 1 for loopback packet (16bytes TXCMD) - */ - sint prev_fw_state; - u8 *pallocated_mp_xmitframe_buf; - u8 *pmp_xmtframe_buf; - struct __queue free_mp_xmitqueue; - u32 free_mp_xmitframe_cnt; -}; - -struct IOCMD_STRUCT { - u8 cmdclass; - u16 value; - u8 index; -}; - -struct rf_reg_param { - u32 path; - u32 offset; - u32 value; -}; - -struct bb_reg_param { - u32 offset; - u32 value; -}; - -/* ======================================================================= */ - -#define LOWER true -#define RAISE false -#define IOCMD_CTRL_REG 0x10250370 -#define IOCMD_DATA_REG 0x10250374 -#define IOCMD_GET_THERMAL_METER 0xFD000028 -#define IOCMD_CLASS_BB_RF 0xF0 -#define IOCMD_BB_READ_IDX 0x00 -#define IOCMD_BB_WRITE_IDX 0x01 -#define IOCMD_RF_READ_IDX 0x02 -#define IOCMD_RF_WRIT_IDX 0x03 -#define BB_REG_BASE_ADDR 0x800 -#define RF_PATH_A 0 -#define RF_PATH_B 1 -#define RF_PATH_C 2 -#define RF_PATH_D 3 -#define MAX_RF_PATH_NUMS 2 -#define _2MAC_MODE_ 0 -#define _LOOPBOOK_MODE_ 1 - -/* MP set force data rate base on the definition. */ -enum { - /* CCK rate. */ - MPT_RATE_1M, /* 0 */ - MPT_RATE_2M, - MPT_RATE_55M, - MPT_RATE_11M, /* 3 */ - - /* OFDM rate. */ - MPT_RATE_6M, /* 4 */ - MPT_RATE_9M, - MPT_RATE_12M, - MPT_RATE_18M, - MPT_RATE_24M, - MPT_RATE_36M, - MPT_RATE_48M, - MPT_RATE_54M, /* 11 */ - - /* HT rate. */ - MPT_RATE_MCS0, /* 12 */ - MPT_RATE_MCS1, - MPT_RATE_MCS2, - MPT_RATE_MCS3, - MPT_RATE_MCS4, - MPT_RATE_MCS5, - MPT_RATE_MCS6, - MPT_RATE_MCS7, /* 19 */ - MPT_RATE_MCS8, - MPT_RATE_MCS9, - MPT_RATE_MCS10, - MPT_RATE_MCS11, - MPT_RATE_MCS12, - MPT_RATE_MCS13, - MPT_RATE_MCS14, - MPT_RATE_MCS15, /* 27 */ - MPT_RATE_LAST -}; - -/* Represent Channel Width in HT Capabilities */ -enum HT_CHANNEL_WIDTH { - HT_CHANNEL_WIDTH_20 = 0, - HT_CHANNEL_WIDTH_40 = 1, -}; - -#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */ - -enum POWER_MODE { - POWER_LOW = 0, - POWER_NORMAL -}; - -#define RX_PKT_BROADCAST 1 -#define RX_PKT_DEST_ADDR 2 -#define RX_PKT_PHY_MATCH 3 - -#define RPTMaxCount 0x000FFFFF - -/* parameter 1 : BitMask - * bit 0 : OFDM PPDU - * bit 1 : OFDM False Alarm - * bit 2 : OFDM MPDU OK - * bit 3 : OFDM MPDU Fail - * bit 4 : CCK PPDU - * bit 5 : CCK False Alarm - * bit 6 : CCK MPDU ok - * bit 7 : CCK MPDU fail - * bit 8 : HT PPDU counter - * bit 9 : HT false alarm - * bit 10 : HT MPDU total - * bit 11 : HT MPDU OK - * bit 12 : HT MPDU fail - * bit 15 : RX full drop - */ -enum RXPHY_BITMASK { - OFDM_PPDU_BIT = 0, - OFDM_MPDU_OK_BIT, - OFDM_MPDU_FAIL_BIT, - CCK_PPDU_BIT, - CCK_MPDU_OK_BIT, - CCK_MPDU_FAIL_BIT, - HT_PPDU_BIT, - HT_MPDU_BIT, - HT_MPDU_OK_BIT, - HT_MPDU_FAIL_BIT, -}; - -enum ENCRY_CTRL_STATE { - HW_CONTROL, /*hw encryption& decryption*/ - SW_CONTROL, /*sw encryption& decryption*/ - HW_ENCRY_SW_DECRY, /*hw encryption & sw decryption*/ - SW_ENCRY_HW_DECRY /*sw encryption & hw decryption*/ -}; - -/* Bandwidth Offset */ -#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 -#define HAL_PRIME_CHNL_OFFSET_UPPER 2 -/*=======================================================================*/ -void mp871xinit(struct _adapter *padapter); -void mp871xdeinit(struct _adapter *padapter); -u32 r8712_bb_reg_read(struct _adapter *Adapter, u16 offset); -u8 r8712_bb_reg_write(struct _adapter *Adapter, u16 offset, u32 value); -u32 r8712_rf_reg_read(struct _adapter *Adapter, u8 path, u8 offset); -u8 r8712_rf_reg_write(struct _adapter *Adapter, u8 path, - u8 offset, u32 value); -u32 r8712_get_bb_reg(struct _adapter *Adapter, u16 offset, u32 bitmask); -u8 r8712_set_bb_reg(struct _adapter *Adapter, u16 offset, - u32 bitmask, u32 value); -u32 r8712_get_rf_reg(struct _adapter *Adapter, u8 path, u8 offset, - u32 bitmask); -u8 r8712_set_rf_reg(struct _adapter *Adapter, u8 path, u8 offset, - u32 bitmask, u32 value); - -void r8712_SetChannel(struct _adapter *pAdapter); -void r8712_SetTxPower(struct _adapter *pAdapte); -void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset); -void r8712_SetDataRate(struct _adapter *pAdapter); -void r8712_SwitchBandwidth(struct _adapter *pAdapter); -void r8712_SwitchAntenna(struct _adapter *pAdapter); -void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value); -void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart); -void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart); -void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart); -void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart); -void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter); -u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter); -u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter); - -#endif /*__RTL871X_MP_H_*/ - diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c deleted file mode 100644 index 26fa09b45c90..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ /dev/null @@ -1,883 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_mp_ioctl.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#include -#include "osdep_service.h" -#include "drv_types.h" -#include "mlme_osdep.h" -#include "rtl871x_mp.h" -#include "rtl871x_mp_ioctl.h" - -uint oid_null_function(struct oid_par_priv *poid_par_priv) -{ - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid == SET_OID) { - if (poid_par_priv->information_buf_len >= sizeof(u8)) - Adapter->registrypriv.wireless_mode = - *(u8 *)poid_par_priv->information_buf; - else - status = RNDIS_STATUS_INVALID_LENGTH; - } else if (poid_par_priv->type_of_oid == QUERY_OID) { - if (poid_par_priv->information_buf_len >= sizeof(u8)) { - *(u8 *)poid_par_priv->information_buf = - Adapter->registrypriv.wireless_mode; - *poid_par_priv->bytes_rw = - poid_par_priv->information_buf_len; - } else { - status = RNDIS_STATUS_INVALID_LENGTH; - } - } else { - status = RNDIS_STATUS_NOT_ACCEPTED; - } - return status; -} - -uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct bb_reg_param *pbbreg; - u16 offset; - u32 value; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); - offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/ - if (offset < BB_REG_BASE_ADDR) - offset |= BB_REG_BASE_ADDR; - value = pbbreg->value; - r8712_bb_reg_write(Adapter, offset, value); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct bb_reg_param *pbbreg; - u16 offset; - u32 value; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf); - offset = (u16)(pbbreg->offset) & 0xFFF; /*0ffset :0x800~0xfff*/ - if (offset < BB_REG_BASE_ADDR) - offset |= BB_REG_BASE_ADDR; - value = r8712_bb_reg_read(Adapter, offset); - pbbreg->value = value; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct rf_reg_param *pbbreg; - u8 path; - u8 offset; - u32 value; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); - path = (u8)pbbreg->path; - if (path > RF_PATH_B) - return RNDIS_STATUS_NOT_ACCEPTED; - offset = (u8)pbbreg->offset; - value = pbbreg->value; - r8712_rf_reg_write(Adapter, path, offset, value); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - struct rf_reg_param *pbbreg; - u8 path; - u8 offset; - u32 value; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param)) - return RNDIS_STATUS_INVALID_LENGTH; - pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf); - path = (u8)pbbreg->path; - if (path > RF_PATH_B) /* 1T2R path_a /path_b */ - return RNDIS_STATUS_NOT_ACCEPTED; - offset = (u8)pbbreg->offset; - value = r8712_rf_reg_read(Adapter, path, offset); - pbbreg->value = value; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -/*This function initializes the DUT to the MP test mode*/ -static int mp_start_test(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - struct wlan_bssid_ex *bssid; - struct sta_info *psta; - unsigned long length; - unsigned long irqL; - int res = 0; - - bssid = kzalloc(sizeof(*bssid), GFP_KERNEL); - if (!bssid) - return -ENOMEM; - - /* 3 1. initialize a new struct wlan_bssid_ex */ - memcpy(bssid->MacAddress, pmppriv->network_macaddr, ETH_ALEN); - bssid->Ssid.SsidLength = 16; - memcpy(bssid->Ssid.Ssid, (unsigned char *)"mp_pseudo_adhoc", - bssid->Ssid.SsidLength); - bssid->InfrastructureMode = Ndis802_11IBSS; - bssid->NetworkTypeInUse = Ndis802_11DS; - bssid->IELength = 0; - length = r8712_get_wlan_bssid_ex_sz(bssid); - if (length % 4) { - /*round up to multiple of 4 bytes.*/ - bssid->Length = ((length >> 2) + 1) << 2; - } else { - bssid->Length = length; - } - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - goto end_of_mp_start_test; - /*init mp_start_test status*/ - pmppriv->prev_fw_state = get_fwstate(pmlmepriv); - pmlmepriv->fw_state = WIFI_MP_STATE; - if (pmppriv->mode == _LOOPBOOK_MODE_) - set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/ - set_fwstate(pmlmepriv, _FW_UNDER_LINKING); - /* 3 2. create a new psta for mp driver */ - /* clear psta in the cur_network, if any */ - psta = r8712_get_stainfo(&padapter->stapriv, - tgt_network->network.MacAddress); - if (psta) - r8712_free_stainfo(padapter, psta); - psta = r8712_alloc_stainfo(&padapter->stapriv, bssid->MacAddress); - if (!psta) { - res = -ENOMEM; - goto end_of_mp_start_test; - } - /* 3 3. join pseudo AdHoc */ - tgt_network->join_res = 1; - tgt_network->aid = psta->aid = 1; - memcpy(&tgt_network->network, bssid, length); - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); - r8712_os_indicate_connect(padapter); - /* Set to LINKED STATE for MP TRX Testing */ - set_fwstate(pmlmepriv, _FW_LINKED); -end_of_mp_start_test: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - kfree(bssid); - return res; -} - -/*This function change the DUT from the MP test mode into normal mode */ -static int mp_stop_test(struct _adapter *padapter) -{ - struct mp_priv *pmppriv = &padapter->mppriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network *tgt_network = &pmlmepriv->cur_network; - struct sta_info *psta; - unsigned long irqL; - - spin_lock_irqsave(&pmlmepriv->lock, irqL); - if (!check_fwstate(pmlmepriv, WIFI_MP_STATE)) - goto end_of_mp_stop_test; - /* 3 1. disconnect pseudo AdHoc */ - r8712_os_indicate_disconnect(padapter); - /* 3 2. clear psta used in mp test mode. */ - psta = r8712_get_stainfo(&padapter->stapriv, - tgt_network->network.MacAddress); - if (psta) - r8712_free_stainfo(padapter, psta); - /* 3 3. return to normal state (default:station mode) */ - pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE;*/ - /*flush the cur_network*/ - memset(tgt_network, 0, sizeof(struct wlan_network)); -end_of_mp_stop_test: - spin_unlock_irqrestore(&pmlmepriv->lock, irqL); - return _SUCCESS; -} - -uint oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 ratevalue; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - ratevalue = *((u32 *)poid_par_priv->information_buf); - if (ratevalue >= MPT_RATE_LAST) - return RNDIS_STATUS_INVALID_DATA; - Adapter->mppriv.curr_rateidx = ratevalue; - r8712_SetDataRate(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - u32 mode; - u8 val8; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - mode = *((u32 *)poid_par_priv->information_buf); - Adapter->mppriv.mode = mode;/* 1 for loopback*/ - if (mp_start_test(Adapter)) - status = RNDIS_STATUS_NOT_ACCEPTED; - r8712_write8(Adapter, MSR, 1); /* Link in ad hoc network, 0x1025004C */ - r8712_write8(Adapter, RCR, 0); /* RCR : disable all pkt, 0x10250048 */ - /* RCR disable Check BSSID, 0x1025004a */ - r8712_write8(Adapter, RCR + 2, 0x57); - /* disable RX filter map , mgt frames will put in RX FIFO 0 */ - r8712_write16(Adapter, RXFLTMAP0, 0x0); - val8 = r8712_read8(Adapter, EE_9346CR); - if (!(val8 & _9356SEL)) { /*boot from EFUSE*/ - r8712_efuse_reg_init(Adapter); - r8712_efuse_change_max_size(Adapter); - r8712_efuse_reg_uninit(Adapter); - } - return status; -} - -uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (mp_stop_test(Adapter) == _FAIL) - return RNDIS_STATUS_NOT_ACCEPTED; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 Channel; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - Channel = *((u32 *)poid_par_priv->information_buf); - if (Channel > 14) - return RNDIS_STATUS_NOT_ACCEPTED; - Adapter->mppriv.curr_ch = Channel; - r8712_SetChannel(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 antenna; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - antenna = *((u32 *)poid_par_priv->information_buf); - Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16); - Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF); - r8712_SwitchAntenna(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 tx_pwr_idx; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - tx_pwr_idx = *((u32 *)poid_par_priv->information_buf); - if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE) - return RNDIS_STATUS_NOT_ACCEPTED; - Adapter->mppriv.curr_txpoweridx = (u8)tx_pwr_idx; - r8712_SetTxPower(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len == sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.tx_pktcount; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len == sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.rx_pktcount; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len == sizeof(u32)) { - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.rx_crcerrpktcount; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - Adapter->mppriv.tx_pktcount = 0; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len == sizeof(u32)) { - Adapter->mppriv.rx_pktcount = 0; - Adapter->mppriv.rx_crcerrpktcount = 0; - } else { - return RNDIS_STATUS_INVALID_LENGTH; - } - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - r8712_ResetPhyRxPktCount(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(u32 *)poid_par_priv->information_buf = - r8712_GetPhyRxPktReceived(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len != sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(u32 *)poid_par_priv->information_buf = - r8712_GetPhyRxPktCRC32Error(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - Adapter->mppriv.curr_modem = *((u8 *)poid_par_priv->information_buf); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetContinuousTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetSingleCarrierTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetCarrierSuppressionTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bStartTest; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - bStartTest = *((u32 *)poid_par_priv->information_buf); - r8712_SetSingleToneTx(Adapter, (u8)bStartTest); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - struct mp_rw_reg *RegRWStruct; - u16 offset; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; - if ((RegRWStruct->offset >= 0x10250800) && - (RegRWStruct->offset <= 0x10250FFF)) { - /*baseband register*/ - /*0ffset :0x800~0xfff*/ - offset = (u16)(RegRWStruct->offset) & 0xFFF; - RegRWStruct->value = r8712_bb_reg_read(Adapter, offset); - } else { - switch (RegRWStruct->width) { - case 1: - RegRWStruct->value = r8712_read8(Adapter, - RegRWStruct->offset); - break; - case 2: - RegRWStruct->value = r8712_read16(Adapter, - RegRWStruct->offset); - break; - case 4: - RegRWStruct->value = r8712_read32(Adapter, - RegRWStruct->offset); - break; - default: - status = RNDIS_STATUS_NOT_ACCEPTED; - break; - } - } - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return status; -} - -uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - struct mp_rw_reg *RegRWStruct; - u16 offset; - u32 value; - u32 oldValue = 0; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf; - if ((RegRWStruct->offset >= 0x10250800) && - (RegRWStruct->offset <= 0x10250FFF)) { - /*baseband register*/ - offset = (u16)(RegRWStruct->offset) & 0xFFF; - value = RegRWStruct->value; - switch (RegRWStruct->width) { - case 1: - oldValue = r8712_bb_reg_read(Adapter, offset); - oldValue &= 0xFFFFFF00; - value &= 0x000000FF; - value |= oldValue; - break; - case 2: - oldValue = r8712_bb_reg_read(Adapter, offset); - oldValue &= 0xFFFF0000; - value &= 0x0000FFFF; - value |= oldValue; - break; - } - r8712_bb_reg_write(Adapter, offset, value); - } else { - switch (RegRWStruct->width) { - case 1: - r8712_write8(Adapter, RegRWStruct->offset, - (unsigned char)RegRWStruct->value); - break; - case 2: - r8712_write16(Adapter, RegRWStruct->offset, - (unsigned short)RegRWStruct->value); - break; - case 4: - r8712_write32(Adapter, RegRWStruct->offset, - (unsigned int)RegRWStruct->value); - break; - default: - status = RNDIS_STATUS_NOT_ACCEPTED; - break; - } - } - return status; -} - -uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (Adapter->mppriv.act_in_progress) - return RNDIS_STATUS_NOT_ACCEPTED; - - if (poid_par_priv->information_buf_len < sizeof(u8)) - return RNDIS_STATUS_INVALID_LENGTH; - /*init workparam*/ - Adapter->mppriv.act_in_progress = true; - Adapter->mppriv.workparam.bcompleted = false; - Adapter->mppriv.workparam.act_type = MPT_GET_THERMAL_METER; - Adapter->mppriv.workparam.io_offset = 0; - Adapter->mppriv.workparam.io_value = 0xFFFFFFFF; - r8712_GetThermalMeter(Adapter, &Adapter->mppriv.workparam.io_value); - Adapter->mppriv.workparam.bcompleted = true; - Adapter->mppriv.act_in_progress = false; - *(u32 *)poid_par_priv->information_buf = - Adapter->mppriv.workparam.io_value; - *poid_par_priv->bytes_rw = sizeof(u32); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - uint status = RNDIS_STATUS_SUCCESS; - - struct EFUSE_ACCESS_STRUCT *pefuse; - u8 *data; - u16 addr = 0, cnts = 0; - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < - sizeof(struct EFUSE_ACCESS_STRUCT)) - return RNDIS_STATUS_INVALID_LENGTH; - pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf; - addr = pefuse->start_addr; - cnts = pefuse->cnts; - data = pefuse->data; - memset(data, 0xFF, cnts); - if ((addr > 511) || (cnts < 1) || (cnts > 512) || (addr + cnts) > - EFUSE_MAX_SIZE) - return RNDIS_STATUS_NOT_ACCEPTED; - if (!r8712_efuse_access(Adapter, true, addr, cnts, data)) - status = RNDIS_STATUS_FAILURE; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return status; -} - -/*------------------------------------------------------------------------*/ -uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - uint status = RNDIS_STATUS_SUCCESS; - - struct EFUSE_ACCESS_STRUCT *pefuse; - u8 *data; - u16 addr = 0, cnts = 0; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - - pefuse = (struct EFUSE_ACCESS_STRUCT *)poid_par_priv->information_buf; - addr = pefuse->start_addr; - cnts = pefuse->cnts; - data = pefuse->data; - - if ((addr > 511) || (cnts < 1) || (cnts > 512) || - (addr + cnts) > r8712_efuse_get_max_size(Adapter)) - return RNDIS_STATUS_NOT_ACCEPTED; - if (!r8712_efuse_access(Adapter, false, addr, cnts, data)) - status = RNDIS_STATUS_FAILURE; - return status; -} - -/*----------------------------------------------------------------------*/ - -uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(int)) - return RNDIS_STATUS_INVALID_LENGTH; - r8712_efuse_reg_init(Adapter); - *(int *)poid_par_priv->information_buf = - r8712_efuse_get_current_size(Adapter); - r8712_efuse_reg_uninit(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(int *)poid_par_priv->information_buf = - r8712_efuse_get_max_size(Adapter); - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv) -{ - uint status = RNDIS_STATUS_SUCCESS; - - if (poid_par_priv->type_of_oid == QUERY_OID) - status = oid_rt_pro_read_efuse_hdl(poid_par_priv); - else - status = oid_rt_pro_write_efuse_hdl(poid_par_priv); - return status; -} - -uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - uint status = RNDIS_STATUS_SUCCESS; - u8 *data; - - *poid_par_priv->bytes_rw = 0; - if (poid_par_priv->information_buf_len < EFUSE_MAP_MAX_SIZE) - return RNDIS_STATUS_INVALID_LENGTH; - data = (u8 *)poid_par_priv->information_buf; - if (poid_par_priv->type_of_oid == QUERY_OID) { - if (r8712_efuse_map_read(Adapter, 0, EFUSE_MAP_MAX_SIZE, data)) - *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE; - else - status = RNDIS_STATUS_FAILURE; - } else { - /* SET_OID */ - if (r8712_efuse_reg_init(Adapter)) { - if (r8712_efuse_map_write(Adapter, 0, - EFUSE_MAP_MAX_SIZE, data)) - *poid_par_priv->bytes_rw = EFUSE_MAP_MAX_SIZE; - else - status = RNDIS_STATUS_FAILURE; - r8712_efuse_reg_uninit(Adapter); - } else { - status = RNDIS_STATUS_FAILURE; - } - } - return status; -} - -uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u32 bandwidth; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - bandwidth = *((u32 *)poid_par_priv->information_buf);/*4*/ - if (bandwidth != HT_CHANNEL_WIDTH_20) - bandwidth = HT_CHANNEL_WIDTH_40; - Adapter->mppriv.curr_bandwidth = (u8)bandwidth; - r8712_SwitchBandwidth(Adapter); - return RNDIS_STATUS_SUCCESS; -} - -uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - u8 rx_pkt_type; - u32 rcr_val32; - - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u8)) - return RNDIS_STATUS_INVALID_LENGTH; - rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/*4*/ - rcr_val32 = r8712_read32(Adapter, RCR);/*RCR = 0x10250048*/ - rcr_val32 &= ~(RCR_CBSSID | RCR_AB | RCR_AM | RCR_APM | RCR_AAP); - switch (rx_pkt_type) { - case RX_PKT_BROADCAST: - rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32); - break; - case RX_PKT_DEST_ADDR: - rcr_val32 |= (RCR_AB | RCR_AM | RCR_APM | RCR_AAP | RCR_ACRC32); - break; - case RX_PKT_PHY_MATCH: - rcr_val32 |= (RCR_APM | RCR_ACRC32); - break; - default: - rcr_val32 &= ~(RCR_AAP | - RCR_APM | - RCR_AM | - RCR_AB | - RCR_ACRC32); - break; - } - if (rx_pkt_type == RX_PKT_DEST_ADDR) - Adapter->mppriv.check_mp_pkt = 1; - else - Adapter->mppriv.check_mp_pkt = 0; - r8712_write32(Adapter, RCR, rcr_val32); - return RNDIS_STATUS_SUCCESS; -} - -/*--------------------------------------------------------------------------*/ -/*Linux*/ -unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv) -{ - return _SUCCESS; -} - -/*-------------------------------------------------------------------------*/ -uint oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv) -{ - if (poid_par_priv->type_of_oid != SET_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - /*CALL the power_down function*/ - return RNDIS_STATUS_SUCCESS; -} - -/*-------------------------------------------------------------------------- */ -uint oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv) -{ - struct _adapter *Adapter = (struct _adapter *) - (poid_par_priv->adapter_context); - - if (poid_par_priv->type_of_oid != QUERY_OID) - return RNDIS_STATUS_NOT_ACCEPTED; - if (poid_par_priv->information_buf_len < sizeof(u32)) - return RNDIS_STATUS_INVALID_LENGTH; - *(int *)poid_par_priv->information_buf = - Adapter->registrypriv.low_power ? POWER_LOW : POWER_NORMAL; - *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len; - return RNDIS_STATUS_SUCCESS; -} diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h deleted file mode 100644 index aa4d5ce471f2..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h +++ /dev/null @@ -1,328 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_MP_IOCTL_H -#define _RTL871X_MP_IOCTL_H - -#include "osdep_service.h" -#include "drv_types.h" -#include "mp_custom_oid.h" -#include "rtl871x_ioctl.h" -#include "rtl871x_ioctl_rtl.h" -#include "rtl8712_efuse.h" - -#define TESTFWCMDNUMBER 1000000 -#define TEST_H2CINT_WAIT_TIME 500 -#define TEST_C2HINT_WAIT_TIME 500 -#define HCI_TEST_SYSCFG_HWMASK 1 -#define _BUSCLK_40M (4 << 2) - -struct CFG_DBG_MSG_STRUCT { - u32 DebugLevel; - u32 DebugComponent_H32; - u32 DebugComponent_L32; -}; - -struct mp_rw_reg { - uint offset; - uint width; - u32 value; -}; - -/* for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM */ -struct eeprom_rw_param { - uint offset; - u16 value; -}; - -struct EFUSE_ACCESS_STRUCT { - u16 start_addr; - u16 cnts; - u8 data[]; -}; - -struct burst_rw_reg { - uint offset; - uint len; - u8 Data[256]; -}; - -struct usb_vendor_req { - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; - u8 u8Dir;/*0:OUT, 1:IN */ - u8 u8InData; -}; - -struct DR_VARIABLE_STRUCT { - u8 offset; - u32 variable; -}; - -/* oid_rtl_seg_87_11_00 */ -uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_80_00 */ -uint oid_rt_pro_set_data_rate_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_channel_direct_call_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_antenna_bb_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_tx_power_control_hdl( - struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_80_20 */ -uint oid_rt_pro_query_tx_packet_sent_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_query_rx_packet_received_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_query_rx_packet_crc32_error_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_reset_tx_packet_sent_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_reset_rx_packet_received_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_continuous_tx_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_single_carrier_tx_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_carrier_suppression_tx_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_set_single_tone_tx_hdl( - struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_87 */ -uint oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv); -/* oid_rtl_seg_81_85 */ -uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_get_efuse_current_size_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv); -uint oid_rt_get_thermal_meter_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_reset_phy_rx_packet_count_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_phy_rx_packet_received_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_phy_rx_packet_crc32_error_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_set_power_down_hdl( - struct oid_par_priv *poid_par_priv); -uint oid_rt_get_power_mode_hdl( - struct oid_par_priv *poid_par_priv); -#ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */ -/* This ifdef _MUST_ be left in!! */ - -#else /* _RTL871X_MP_IOCTL_C_ */ -extern struct oid_obj_priv oid_rtl_seg_81_87[5]; -extern struct oid_obj_priv oid_rtl_seg_87_11_00[32]; -extern struct oid_obj_priv oid_rtl_seg_87_11_20[5]; -extern struct oid_obj_priv oid_rtl_seg_87_11_50[2]; -extern struct oid_obj_priv oid_rtl_seg_87_11_80[1]; -extern struct oid_obj_priv oid_rtl_seg_87_11_B0[1]; -extern struct oid_obj_priv oid_rtl_seg_87_11_F0[16]; -extern struct oid_obj_priv oid_rtl_seg_87_12_00[32]; - -#endif /* _RTL871X_MP_IOCTL_C_ */ - -enum MP_MODE { - MP_START_MODE, - MP_STOP_MODE, - MP_ERR_MODE -}; - -struct rwreg_param { - unsigned int offset; - unsigned int width; - unsigned int value; -}; - -struct bbreg_param { - unsigned int offset; - unsigned int phymask; - unsigned int value; -}; - -struct txpower_param { - unsigned int pwr_index; -}; - -struct datarate_param { - unsigned int rate_index; -}; - -struct rfintfs_parm { - unsigned int rfintfs; -}; - -struct mp_xmit_packet { - unsigned int len; -}; - -struct psmode_param { - unsigned int ps_mode; - unsigned int smart_ps; -}; - -struct mp_ioctl_handler { - unsigned int paramsize; - unsigned int (*handler)(struct oid_par_priv *poid_par_priv); - unsigned int oid; -}; - -struct mp_ioctl_param { - unsigned int subcode; - unsigned int len; - unsigned char data[]; -}; - -#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_ - -enum RTL871X_MP_IOCTL_SUBCODE { - GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/ - GEN_MP_IOCTL_SUBCODE(MP_STOP), /*1*/ - GEN_MP_IOCTL_SUBCODE(READ_REG), /*2*/ - GEN_MP_IOCTL_SUBCODE(WRITE_REG), - GEN_MP_IOCTL_SUBCODE(SET_CHANNEL), /*4*/ - GEN_MP_IOCTL_SUBCODE(SET_TXPOWER), /*5*/ - GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*6*/ - GEN_MP_IOCTL_SUBCODE(READ_BB_REG), /*7*/ - GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), - GEN_MP_IOCTL_SUBCODE(READ_RF_REG), /*9*/ - GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG), - GEN_MP_IOCTL_SUBCODE(SET_RF_INTFS), - GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET), /*12*/ - GEN_MP_IOCTL_SUBCODE(PS_STATE), /*13*/ - GEN_MP_IOCTL_SUBCODE(READ16_EEPROM), /*14*/ - GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM), /*15*/ - GEN_MP_IOCTL_SUBCODE(SET_PTM), /*16*/ - GEN_MP_IOCTL_SUBCODE(READ_TSSI), /*17*/ - GEN_MP_IOCTL_SUBCODE(CNTU_TX), /*18*/ - GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH), /*19*/ - GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE), /*20*/ - GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT), /*21*/ - GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*22*/ - GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR), /*23*/ - GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*24*/ - GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER), /*25*/ - GEN_MP_IOCTL_SUBCODE(GET_POWER_MODE), /*26*/ - GEN_MP_IOCTL_SUBCODE(EFUSE), /*27*/ - GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*28*/ - GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE), /*29*/ - GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE), /*30*/ - GEN_MP_IOCTL_SUBCODE(SC_TX), /*31*/ - GEN_MP_IOCTL_SUBCODE(CS_TX), /*32*/ - GEN_MP_IOCTL_SUBCODE(ST_TX), /*33*/ - GEN_MP_IOCTL_SUBCODE(SET_ANTENNA), /*34*/ - MAX_MP_IOCTL_SUBCODE, -}; - -unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv); - -#ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */ -/* This ifdef _MUST_ be left in!! */ - -static struct mp_ioctl_handler mp_ioctl_hdl[] = { - {sizeof(u32), oid_rt_pro_start_test_hdl, - OID_RT_PRO_START_TEST},/*0*/ - {sizeof(u32), oid_rt_pro_stop_test_hdl, - OID_RT_PRO_STOP_TEST},/*1*/ - {sizeof(struct rwreg_param), - oid_rt_pro_read_register_hdl, - OID_RT_PRO_READ_REGISTER},/*2*/ - {sizeof(struct rwreg_param), - oid_rt_pro_write_register_hdl, - OID_RT_PRO_WRITE_REGISTER}, - {sizeof(u32), - oid_rt_pro_set_channel_direct_call_hdl, - OID_RT_PRO_SET_CHANNEL_DIRECT_CALL}, - {sizeof(struct txpower_param), - oid_rt_pro_set_tx_power_control_hdl, - OID_RT_PRO_SET_TX_POWER_CONTROL}, - {sizeof(u32), - oid_rt_pro_set_data_rate_hdl, - OID_RT_PRO_SET_DATA_RATE}, - {sizeof(struct bb_reg_param), - oid_rt_pro_read_bb_reg_hdl, - OID_RT_PRO_READ_BB_REG},/*7*/ - {sizeof(struct bb_reg_param), - oid_rt_pro_write_bb_reg_hdl, - OID_RT_PRO_WRITE_BB_REG}, - {sizeof(struct rwreg_param), - oid_rt_pro_read_rf_reg_hdl, - OID_RT_PRO_RF_READ_REGISTRY},/*9*/ - {sizeof(struct rwreg_param), - oid_rt_pro_write_rf_reg_hdl, - OID_RT_PRO_RF_WRITE_REGISTRY}, - {sizeof(struct rfintfs_parm), NULL, 0}, - {0, mp_ioctl_xmit_packet_hdl, 0},/*12*/ - {sizeof(struct psmode_param), NULL, 0},/*13*/ - {sizeof(struct eeprom_rw_param), NULL, 0},/*14*/ - {sizeof(struct eeprom_rw_param), NULL, 0},/*15*/ - {sizeof(unsigned char), NULL, 0},/*16*/ - {sizeof(u32), NULL, 0},/*17*/ - {sizeof(u32), oid_rt_pro_set_continuous_tx_hdl, - OID_RT_PRO_SET_CONTINUOUS_TX},/*18*/ - {sizeof(u32), oid_rt_set_bandwidth_hdl, - OID_RT_SET_BANDWIDTH},/*19*/ - {sizeof(u32), oid_rt_set_rx_packet_type_hdl, - OID_RT_SET_RX_PACKET_TYPE},/*20*/ - {0, oid_rt_reset_phy_rx_packet_count_hdl, - OID_RT_RESET_PHY_RX_PACKET_COUNT},/*21*/ - {sizeof(u32), oid_rt_get_phy_rx_packet_received_hdl, - OID_RT_GET_PHY_RX_PACKET_RECEIVED},/*22*/ - {sizeof(u32), oid_rt_get_phy_rx_packet_crc32_error_hdl, - OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR},/*23*/ - {sizeof(unsigned char), oid_rt_set_power_down_hdl, - OID_RT_SET_POWER_DOWN},/*24*/ - {sizeof(u32), oid_rt_get_thermal_meter_hdl, - OID_RT_PRO_GET_THERMAL_METER},/*25*/ - {sizeof(u32), oid_rt_get_power_mode_hdl, - OID_RT_GET_POWER_MODE},/*26*/ - {sizeof(struct EFUSE_ACCESS_STRUCT), - oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE},/*27*/ - {EFUSE_MAP_MAX_SIZE, oid_rt_pro_efuse_map_hdl, - OID_RT_PRO_EFUSE_MAP},/*28*/ - {sizeof(u32), oid_rt_get_efuse_max_size_hdl, - OID_RT_GET_EFUSE_MAX_SIZE},/*29*/ - {sizeof(u32), oid_rt_get_efuse_current_size_hdl, - OID_RT_GET_EFUSE_CURRENT_SIZE},/*30*/ - {sizeof(u32), oid_rt_pro_set_single_carrier_tx_hdl, - OID_RT_PRO_SET_SINGLE_CARRIER_TX},/*31*/ - {sizeof(u32), oid_rt_pro_set_carrier_suppression_tx_hdl, - OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX},/*32*/ - {sizeof(u32), oid_rt_pro_set_single_tone_tx_hdl, - OID_RT_PRO_SET_SINGLE_TONE_TX},/*33*/ - {sizeof(u32), oid_rt_pro_set_antenna_bb_hdl, - OID_RT_PRO_SET_ANTENNA_BB},/*34*/ -}; - -#else /* _RTL871X_MP_IOCTL_C_ */ -extern struct mp_ioctl_handler mp_ioctl_hdl[]; -#endif /* _RTL871X_MP_IOCTL_C_ */ - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h deleted file mode 100644 index a08c5d2f59e3..000000000000 --- a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h +++ /dev/null @@ -1,1034 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/***************************************************************************** - * Copyright(c) 2008, RealTEK Technology Inc. All Right Reserved. - * - * Module: __INC_HAL8192SPHYREG_H - * - * - * Note: 1. Define PMAC/BB register map - * 2. Define RF register map - * 3. PMAC/BB register bit mask. - * 4. RF reg bit mask. - * 5. Other BB/RF relative definition. - * - * - * Export: Constants, macro, functions(API), global variables(None). - * - * Abbrev: - * - * History: - * Data Who Remark - * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. - * 2. Reorganize code architecture. - * 09/25/2008 MH 1. Add RL6052 register definition - * - *****************************************************************************/ -#ifndef __RTL871X_MP_PHY_REGDEF_H -#define __RTL871X_MP_PHY_REGDEF_H - -/*--------------------------Define Parameters-------------------------------*/ - -/*============================================================ - * 8192S Register offset definition - *============================================================ - * - * - * BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF - * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF - * 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 - * 3. RF register 0x00-2E - * 4. Bit Mask for BB/RF register - * 5. Other definition for BB/RF R/W - * - * 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF - * 1. Page1(0x100) - */ -#define rPMAC_Reset 0x100 -#define rPMAC_TxStart 0x104 -#define rPMAC_TxLegacySIG 0x108 -#define rPMAC_TxHTSIG1 0x10c -#define rPMAC_TxHTSIG2 0x110 -#define rPMAC_PHYDebug 0x114 -#define rPMAC_TxPacketNum 0x118 -#define rPMAC_TxIdle 0x11c -#define rPMAC_TxMACHeader0 0x120 -#define rPMAC_TxMACHeader1 0x124 -#define rPMAC_TxMACHeader2 0x128 -#define rPMAC_TxMACHeader3 0x12c -#define rPMAC_TxMACHeader4 0x130 -#define rPMAC_TxMACHeader5 0x134 -#define rPMAC_TxDataType 0x138 -#define rPMAC_TxRandomSeed 0x13c -#define rPMAC_CCKPLCPPreamble 0x140 -#define rPMAC_CCKPLCPHeader 0x144 -#define rPMAC_CCKCRC16 0x148 -#define rPMAC_OFDMRxCRC32OK 0x170 -#define rPMAC_OFDMRxCRC32Er 0x174 -#define rPMAC_OFDMRxParityEr 0x178 -#define rPMAC_OFDMRxCRC8Er 0x17c -#define rPMAC_CCKCRxRC16Er 0x180 -#define rPMAC_CCKCRxRC32Er 0x184 -#define rPMAC_CCKCRxRC32OK 0x188 -#define rPMAC_TxStatus 0x18c - -/* - * 2. Page2(0x200) - * - * The following two definition are only used for USB interface. - *#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. - *#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. - * - * - * 3. Page8(0x800) - */ -#define rFPGA0_RFMOD 0x800 /*RF mode & CCK TxSC RF - * BW Setting?? - */ -#define rFPGA0_TxInfo 0x804 /* Status report?? */ -#define rFPGA0_PSDFunction 0x808 -#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */ -#define rFPGA0_RFTiming1 0x810 /* Useless now */ -#define rFPGA0_RFTiming2 0x814 -#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */ -#define rFPGA0_XA_HSSIParameter2 0x824 -#define rFPGA0_XB_HSSIParameter1 0x828 -#define rFPGA0_XB_HSSIParameter2 0x82c -#define rFPGA0_XC_HSSIParameter1 0x830 -#define rFPGA0_XC_HSSIParameter2 0x834 -#define rFPGA0_XD_HSSIParameter1 0x838 -#define rFPGA0_XD_HSSIParameter2 0x83c -#define rFPGA0_XA_LSSIParameter 0x840 -#define rFPGA0_XB_LSSIParameter 0x844 -#define rFPGA0_XC_LSSIParameter 0x848 -#define rFPGA0_XD_LSSIParameter 0x84c - -#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */ -#define rFPGA0_RFSleepUpParameter 0x854 - -#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */ -#define rFPGA0_XCD_SwitchControl 0x85c - -#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */ -#define rFPGA0_XB_RFInterfaceOE 0x864 -#define rFPGA0_XC_RFInterfaceOE 0x868 -#define rFPGA0_XD_RFInterfaceOE 0x86c -#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Interface Software Ctrl */ -#define rFPGA0_XCD_RFInterfaceSW 0x874 - -#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */ -#define rFPGA0_XCD_RFParameter 0x87c - -#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting - * RF-R/W protection - * for parameter4?? - */ -#define rFPGA0_AnalogParameter2 0x884 -#define rFPGA0_AnalogParameter3 0x888 /* Useless now */ -#define rFPGA0_AnalogParameter4 0x88c - -#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */ -#define rFPGA0_XB_LSSIReadBack 0x8a4 -#define rFPGA0_XC_LSSIReadBack 0x8a8 -#define rFPGA0_XD_LSSIReadBack 0x8ac - -#define rFPGA0_PSDReport 0x8b4 /* Useless now */ -#define rFPGA0_XAB_RFInterfaceRB 0x8e0 /* Useless now */ -#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */ - -/* - * 4. Page9(0x900) - */ -#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC */ - -#define rFPGA1_TxBlock 0x904 /* Useless now */ -#define rFPGA1_DebugSelect 0x908 /* Useless now */ -#define rFPGA1_TxInfo 0x90c /* Useless now */ - -/* - * 5. PageA(0xA00) - * - * Set Control channel to upper or lower. - * These settings are required only for 40MHz - */ -#define rCCK0_System 0xa00 - -#define rCCK0_AFESetting 0xa04 /* Disable init gain now */ -#define rCCK0_CCA 0xa08 /* Disable init gain now */ - -#define rCCK0_RxAGC1 0xa0c -/* AGC default value, saturation level - * Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. - * Not the same as 90 series - */ -#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ - -#define rCCK0_RxHP 0xa14 - -#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel - * estimation threshold - */ -#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ - -#define rCCK0_TxFilter1 0xa20 -#define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ -#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f - * channel report - */ -#define rCCK0_TRSSIReport 0xa50 -#define rCCK0_RxReport 0xa54 /* 0xa57 */ -#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ -#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ - -/* - * 6. PageC(0xC00) - */ -#define rOFDM0_LSTF 0xc00 -#define rOFDM0_TRxPathEnable 0xc04 -#define rOFDM0_TRMuxPar 0xc08 -#define rOFDM0_TRSWIsolation 0xc0c - -/*RxIQ DC offset, Rx digital filter, DC notch filter */ -#define rOFDM0_XARxAFE 0xc10 -#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ -#define rOFDM0_XBRxAFE 0xc18 -#define rOFDM0_XBRxIQImbalance 0xc1c -#define rOFDM0_XCRxAFE 0xc20 -#define rOFDM0_XCRxIQImbalance 0xc24 -#define rOFDM0_XDRxAFE 0xc28 -#define rOFDM0_XDRxIQImbalance 0xc2c - -#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune - * init gain - */ -#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */ -#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */ -#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & - * Short-GI - */ - -#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ -#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ -#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ -#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ - -#define rOFDM0_XAAGCCore1 0xc50 /* DIG */ -#define rOFDM0_XAAGCCore2 0xc54 -#define rOFDM0_XBAGCCore1 0xc58 -#define rOFDM0_XBAGCCore2 0xc5c -#define rOFDM0_XCAGCCore1 0xc60 -#define rOFDM0_XCAGCCore2 0xc64 -#define rOFDM0_XDAGCCore1 0xc68 -#define rOFDM0_XDAGCCore2 0xc6c -#define rOFDM0_AGCParameter1 0xc70 -#define rOFDM0_AGCParameter2 0xc74 -#define rOFDM0_AGCRSSITable 0xc78 -#define rOFDM0_HTSTFAGC 0xc7c - -#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */ -#define rOFDM0_XATxAFE 0xc84 -#define rOFDM0_XBTxIQImbalance 0xc88 -#define rOFDM0_XBTxAFE 0xc8c -#define rOFDM0_XCTxIQImbalance 0xc90 -#define rOFDM0_XCTxAFE 0xc94 -#define rOFDM0_XDTxIQImbalance 0xc98 -#define rOFDM0_XDTxAFE 0xc9c - -#define rOFDM0_RxHPParameter 0xce0 -#define rOFDM0_TxPseudoNoiseWgt 0xce4 -#define rOFDM0_FrameSync 0xcf0 -#define rOFDM0_DFSReport 0xcf4 -#define rOFDM0_TxCoeff1 0xca4 -#define rOFDM0_TxCoeff2 0xca8 -#define rOFDM0_TxCoeff3 0xcac -#define rOFDM0_TxCoeff4 0xcb0 -#define rOFDM0_TxCoeff5 0xcb4 -#define rOFDM0_TxCoeff6 0xcb8 - -/* - * 7. PageD(0xD00) - */ -#define rOFDM1_LSTF 0xd00 -#define rOFDM1_TRxPathEnable 0xd04 - -#define rOFDM1_CFO 0xd08 /* No setting now */ -#define rOFDM1_CSI1 0xd10 -#define rOFDM1_SBD 0xd14 -#define rOFDM1_CSI2 0xd18 -#define rOFDM1_CFOTracking 0xd2c -#define rOFDM1_TRxMesaure1 0xd34 -#define rOFDM1_IntfDet 0xd3c -#define rOFDM1_PseudoNoiseStateAB 0xd50 -#define rOFDM1_PseudoNoiseStateCD 0xd54 -#define rOFDM1_RxPseudoNoiseWgt 0xd58 - -#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ -#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ -#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ -#define rOFDM_ShortCFOAB 0xdac /* No setting now */ -#define rOFDM_ShortCFOCD 0xdb0 -#define rOFDM_LongCFOAB 0xdb4 -#define rOFDM_LongCFOCD 0xdb8 -#define rOFDM_TailCFOAB 0xdbc -#define rOFDM_TailCFOCD 0xdc0 -#define rOFDM_PWMeasure1 0xdc4 -#define rOFDM_PWMeasure2 0xdc8 -#define rOFDM_BWReport 0xdcc -#define rOFDM_AGCReport 0xdd0 -#define rOFDM_RxSNR 0xdd4 -#define rOFDM_RxEVMCSI 0xdd8 -#define rOFDM_SIGReport 0xddc - -/* - * 8. PageE(0xE00) - */ -#define rTxAGC_Rate18_06 0xe00 -#define rTxAGC_Rate54_24 0xe04 -#define rTxAGC_CCK_Mcs32 0xe08 -#define rTxAGC_Mcs03_Mcs00 0xe10 -#define rTxAGC_Mcs07_Mcs04 0xe14 -#define rTxAGC_Mcs11_Mcs08 0xe18 -#define rTxAGC_Mcs15_Mcs12 0xe1c - -/* Analog- control in RX_WAIT_CCA : REG: EE0 - * [Analog- Power & Control Register] - */ -#define rRx_Wait_CCCA 0xe70 -#define rAnapar_Ctrl_BB 0xee0 - -/* - * 7. RF Register 0x00-0x2E (RF 8256) - * RF-0222D 0x00-3F - * - * Zebra1 - */ -#define rZebra1_HSSIEnable 0x0 /* Useless now */ -#define rZebra1_TRxEnable1 0x1 -#define rZebra1_TRxEnable2 0x2 -#define rZebra1_AGC 0x4 -#define rZebra1_ChargePump 0x5 -#define rZebra1_Channel 0x7 /* RF channel switch */ -#define rZebra1_TxGain 0x8 /* Useless now */ -#define rZebra1_TxLPF 0x9 -#define rZebra1_RxLPF 0xb -#define rZebra1_RxHPFCorner 0xc - -/* Zebra4 */ -#define rGlobalCtrl 0 /* Useless now */ -#define rRTL8256_TxLPF 19 -#define rRTL8256_RxLPF 11 - -/* RTL8258 */ -#define rRTL8258_TxLPF 0x11 /* Useless now */ -#define rRTL8258_RxLPF 0x13 -#define rRTL8258_RSSILPF 0xa - -/* RL6052 Register definition */ -#define RF_AC 0x00 -#define RF_IQADJ_G1 0x01 -#define RF_IQADJ_G2 0x02 -#define RF_POW_TRSW 0x05 - -#define RF_GAIN_RX 0x06 -#define RF_GAIN_TX 0x07 - -#define RF_TXM_IDAC 0x08 -#define RF_BS_IQGEN 0x0F - -#define RF_MODE1 0x10 -#define RF_MODE2 0x11 - -#define RF_RX_AGC_HP 0x12 -#define RF_TX_AGC 0x13 -#define RF_BIAS 0x14 -#define RF_IPA 0x15 -#define RF_POW_ABILITY 0x17 -#define RF_MODE_AG 0x18 -#define rRfChannel 0x18 /* RF channel and BW switch */ -#define RF_CHNLBW 0x18 /* RF channel and BW switch */ -#define RF_TOP 0x19 -#define RF_RX_G1 0x1A -#define RF_RX_G2 0x1B -#define RF_RX_BB2 0x1C -#define RF_RX_BB1 0x1D - -#define RF_RCK1 0x1E -#define RF_RCK2 0x1F - -#define RF_TX_G1 0x20 -#define RF_TX_G2 0x21 -#define RF_TX_G3 0x22 - -#define RF_TX_BB1 0x23 -#define RF_T_METER 0x24 - -#define RF_SYN_G1 0x25 /* RF TX Power control */ -#define RF_SYN_G2 0x26 /* RF TX Power control */ -#define RF_SYN_G3 0x27 /* RF TX Power control */ -#define RF_SYN_G4 0x28 /* RF TX Power control */ -#define RF_SYN_G5 0x29 /* RF TX Power control */ -#define RF_SYN_G6 0x2A /* RF TX Power control */ -#define RF_SYN_G7 0x2B /* RF TX Power control */ -#define RF_SYN_G8 0x2C /* RF TX Power control */ - -#define RF_RCK_OS 0x30 /* RF TX PA control */ - -#define RF_TXPA_G1 0x31 /* RF TX PA control */ -#define RF_TXPA_G2 0x32 /* RF TX PA control */ -#define RF_TXPA_G3 0x33 /* RF TX PA control */ - -/* - * Bit Mask - * - * 1. Page1(0x100) - */ -#define bBBResetB 0x100 /* Useless now? */ -#define bGlobalResetB 0x200 -#define bOFDMTxStart 0x4 -#define bCCKTxStart 0x8 -#define bCRC32Debug 0x100 -#define bPMACLoopback 0x10 -#define bTxLSIG 0xffffff -#define bOFDMTxRate 0xf -#define bOFDMTxReserved 0x10 -#define bOFDMTxLength 0x1ffe0 -#define bOFDMTxParity 0x20000 -#define bTxHTSIG1 0xffffff -#define bTxHTMCSRate 0x7f -#define bTxHTBW 0x80 -#define bTxHTLength 0xffff00 -#define bTxHTSIG2 0xffffff -#define bTxHTSmoothing 0x1 -#define bTxHTSounding 0x2 -#define bTxHTReserved 0x4 -#define bTxHTAggreation 0x8 -#define bTxHTSTBC 0x30 -#define bTxHTAdvanceCoding 0x40 -#define bTxHTShortGI 0x80 -#define bTxHTNumberHT_LTF 0x300 -#define bTxHTCRC8 0x3fc00 -#define bCounterReset 0x10000 -#define bNumOfOFDMTx 0xffff -#define bNumOfCCKTx 0xffff0000 -#define bTxIdleInterval 0xffff -#define bOFDMService 0xffff0000 -#define bTxMACHeader 0xffffffff -#define bTxDataInit 0xff -#define bTxHTMode 0x100 -#define bTxDataType 0x30000 -#define bTxRandomSeed 0xffffffff -#define bCCKTxPreamble 0x1 -#define bCCKTxSFD 0xffff0000 -#define bCCKTxSIG 0xff -#define bCCKTxService 0xff00 -#define bCCKLengthExt 0x8000 -#define bCCKTxLength 0xffff0000 -#define bCCKTxCRC16 0xffff -#define bCCKTxStatus 0x1 -#define bOFDMTxStatus 0x2 -#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && \ - (_Offset <= 0xfff)) - -/* 2. Page8(0x800) */ -#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */ -#define bJapanMode 0x2 -#define bCCKTxSC 0x30 -#define bCCKEn 0x1000000 -#define bOFDMEn 0x2000000 - -#define bOFDMRxADCPhase 0x10000 /* Useless now */ -#define bOFDMTxDACPhase 0x40000 -#define bXATxAGC 0x3f -#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */ -#define bXCTxAGC 0xf000 -#define bXDTxAGC 0xf0000 - -#define bPAStart 0xf0000000 /* Useless now */ -#define bTRStart 0x00f00000 -#define bRFStart 0x0000f000 -#define bBBStart 0x000000f0 -#define bBBCCKStart 0x0000000f -#define bPAEnd 0xf /* Reg0x814 */ -#define bTREnd 0x0f000000 -#define bRFEnd 0x000f0000 -#define bCCAMask 0x000000f0 /* T2R */ -#define bR2RCCAMask 0x00000f00 -#define bHSSI_R2TDelay 0xf8000000 -#define bHSSI_T2RDelay 0xf80000 -#define bContTxHSSI 0x400 /* change gain at continue Tx */ -#define bIGFromCCK 0x200 -#define bAGCAddress 0x3f -#define bRxHPTx 0x7000 -#define bRxHPT2R 0x38000 -#define bRxHPCCKIni 0xc0000 -#define bAGCTxCode 0xc00000 -#define bAGCRxCode 0x300000 -#define b3WireDataLength 0x800 /* Reg 0x820~84f rFPGA0_XA_HSSIParm1 */ -#define b3WireAddressLength 0x400 -#define b3WireRFPowerDown 0x1 /* Useless now */ -#define b5GPAPEPolarity 0x40000000 -#define b2GPAPEPolarity 0x80000000 -#define bRFSW_TxDefaultAnt 0x3 -#define bRFSW_TxOptionAnt 0x30 -#define bRFSW_RxDefaultAnt 0x300 -#define bRFSW_RxOptionAnt 0x3000 -#define bRFSI_3WireData 0x1 -#define bRFSI_3WireClock 0x2 -#define bRFSI_3WireLoad 0x4 -#define bRFSI_3WireRW 0x8 -#define bRFSI_3Wire 0xf -#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */ -#define bRFSI_TRSW 0x20 /* Useless now */ -#define bRFSI_TRSWB 0x40 -#define bRFSI_ANTSW 0x100 -#define bRFSI_ANTSWB 0x200 -#define bRFSI_PAPE 0x400 -#define bRFSI_PAPE5G 0x800 -#define bBandSelect 0x1 -#define bHTSIG2_GI 0x80 -#define bHTSIG2_Smoothing 0x01 -#define bHTSIG2_Sounding 0x02 -#define bHTSIG2_Aggreaton 0x08 -#define bHTSIG2_STBC 0x30 -#define bHTSIG2_AdvCoding 0x40 -#define bHTSIG2_NumOfHTLTF 0x300 -#define bHTSIG2_CRC8 0x3fc -#define bHTSIG1_MCS 0x7f -#define bHTSIG1_BandWidth 0x80 -#define bHTSIG1_HTLength 0xffff -#define bLSIG_Rate 0xf -#define bLSIG_Reserved 0x10 -#define bLSIG_Length 0x1fffe -#define bLSIG_Parity 0x20 -#define bCCKRxPhase 0x4 -#define bLSSIReadAddress 0x7f800000 /* T65 RF */ -#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ -#define bLSSIReadBackData 0xfffff /* T65 RF */ -#define bLSSIReadOKFlag 0x1000 /* Useless now */ -#define bCCKSampleRate 0x8 /*0: 44MHz, 1:88MHz*/ -#define bRegulator0Standby 0x1 -#define bRegulatorPLLStandby 0x2 -#define bRegulator1Standby 0x4 -#define bPLLPowerUp 0x8 -#define bDPLLPowerUp 0x10 -#define bDA10PowerUp 0x20 -#define bAD7PowerUp 0x200 -#define bDA6PowerUp 0x2000 -#define bXtalPowerUp 0x4000 -#define b40MDClkPowerUP 0x8000 -#define bDA6DebugMode 0x20000 -#define bDA6Swing 0x380000 - -/* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */ -#define bADClkPhase 0x4000000 - -#define b80MClkDelay 0x18000000 /* Useless */ -#define bAFEWatchDogEnable 0x20000000 - -/* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */ -#define bXtalCap01 0xc0000000 -#define bXtalCap23 0x3 -#define bXtalCap92x 0x0f000000 -#define bXtalCap 0x0f000000 -#define bIntDifClkEnable 0x400 /* Useless */ -#define bExtSigClkEnable 0x800 -#define bBandgapMbiasPowerUp 0x10000 -#define bAD11SHGain 0xc0000 -#define bAD11InputRange 0x700000 -#define bAD11OPCurrent 0x3800000 -#define bIPathLoopback 0x4000000 -#define bQPathLoopback 0x8000000 -#define bAFELoopback 0x10000000 -#define bDA10Swing 0x7e0 -#define bDA10Reverse 0x800 -#define bDAClkSource 0x1000 -#define bAD7InputRange 0x6000 -#define bAD7Gain 0x38000 -#define bAD7OutputCMMode 0x40000 -#define bAD7InputCMMode 0x380000 -#define bAD7Current 0xc00000 -#define bRegulatorAdjust 0x7000000 -#define bAD11PowerUpAtTx 0x1 -#define bDA10PSAtTx 0x10 -#define bAD11PowerUpAtRx 0x100 -#define bDA10PSAtRx 0x1000 -#define bCCKRxAGCFormat 0x200 -#define bPSDFFTSamplepPoint 0xc000 -#define bPSDAverageNum 0x3000 -#define bIQPathControl 0xc00 -#define bPSDFreq 0x3ff -#define bPSDAntennaPath 0x30 -#define bPSDIQSwitch 0x40 -#define bPSDRxTrigger 0x400000 -#define bPSDTxTrigger 0x80000000 -#define bPSDSineToneScale 0x7f000000 -#define bPSDReport 0xffff - -/* 3. Page9(0x900) */ -#define bOFDMTxSC 0x30000000 /* Useless */ -#define bCCKTxOn 0x1 -#define bOFDMTxOn 0x2 -#define bDebugPage 0xfff /* reset debug page and HWord, LWord */ -#define bDebugItem 0xff /* reset debug page and LWord */ -#define bAntL 0x10 -#define bAntNonHT 0x100 -#define bAntHT1 0x1000 -#define bAntHT2 0x10000 -#define bAntHT1S1 0x100000 -#define bAntNonHTS1 0x1000000 - -/* 4. PageA(0xA00) */ -#define bCCKBBMode 0x3 /* Useless */ -#define bCCKTxPowerSaving 0x80 -#define bCCKRxPowerSaving 0x40 - -#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 switch*/ -#define bCCKScramble 0x8 /* Useless */ -#define bCCKAntDiversity 0x8000 -#define bCCKCarrierRecovery 0x4000 -#define bCCKTxRate 0x3000 -#define bCCKDCCancel 0x0800 -#define bCCKISICancel 0x0400 -#define bCCKMatchFilter 0x0200 -#define bCCKEqualizer 0x0100 -#define bCCKPreambleDetect 0x800000 -#define bCCKFastFalseCCA 0x400000 -#define bCCKChEstStart 0x300000 -#define bCCKCCACount 0x080000 -#define bCCKcs_lim 0x070000 -#define bCCKBistMode 0x80000000 -#define bCCKCCAMask 0x40000000 -#define bCCKTxDACPhase 0x4 -#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ -#define bCCKr_cp_mode0 0x0100 -#define bCCKTxDCOffset 0xf0 -#define bCCKRxDCOffset 0xf -#define bCCKCCAMode 0xc000 -#define bCCKFalseCS_lim 0x3f00 -#define bCCKCS_ratio 0xc00000 -#define bCCKCorgBit_sel 0x300000 -#define bCCKPD_lim 0x0f0000 -#define bCCKNewCCA 0x80000000 -#define bCCKRxHPofIG 0x8000 -#define bCCKRxIG 0x7f00 -#define bCCKLNAPolarity 0x800000 -#define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 /* CCK Rx initial gain polarity */ -#define bCCKRxAGCSatLevel 0x1f000000 -#define bCCKRxAGCSatCount 0xe0 -#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ -#define bCCKFixedRxAGC 0x8000 -#define bCCKAntennaPolarity 0x2000 -#define bCCKTxFilterType 0x0c00 -#define bCCKRxAGCReportType 0x0300 -#define bCCKRxDAGCEn 0x80000000 -#define bCCKRxDAGCPeriod 0x20000000 -#define bCCKRxDAGCSatLevel 0x1f000000 -#define bCCKTimingRecovery 0x800000 -#define bCCKTxC0 0x3f0000 -#define bCCKTxC1 0x3f000000 -#define bCCKTxC2 0x3f -#define bCCKTxC3 0x3f00 -#define bCCKTxC4 0x3f0000 -#define bCCKTxC5 0x3f000000 -#define bCCKTxC6 0x3f -#define bCCKTxC7 0x3f00 -#define bCCKDebugPort 0xff0000 -#define bCCKDACDebug 0x0f000000 -#define bCCKFalseAlarmEnable 0x8000 -#define bCCKFalseAlarmRead 0x4000 -#define bCCKTRSSI 0x7f -#define bCCKRxAGCReport 0xfe -#define bCCKRxReport_AntSel 0x80000000 -#define bCCKRxReport_MFOff 0x40000000 -#define bCCKRxRxReport_SQLoss 0x20000000 -#define bCCKRxReport_Pktloss 0x10000000 -#define bCCKRxReport_Lockedbit 0x08000000 -#define bCCKRxReport_RateError 0x04000000 -#define bCCKRxReport_RxRate 0x03000000 -#define bCCKRxFACounterLower 0xff -#define bCCKRxFACounterUpper 0xff000000 -#define bCCKRxHPAGCStart 0xe000 -#define bCCKRxHPAGCFinal 0x1c00 -#define bCCKRxFalseAlarmEnable 0x8000 -#define bCCKFACounterFreeze 0x4000 -#define bCCKTxPathSel 0x10000000 -#define bCCKDefaultRxPath 0xc000000 -#define bCCKOptionRxPath 0x3000000 - -/* 5. PageC(0xC00) */ -#define bNumOfSTF 0x3 /* Useless */ -#define bShift_L 0xc0 -#define bGI_TH 0xc -#define bRxPathA 0x1 -#define bRxPathB 0x2 -#define bRxPathC 0x4 -#define bRxPathD 0x8 -#define bTxPathA 0x1 -#define bTxPathB 0x2 -#define bTxPathC 0x4 -#define bTxPathD 0x8 -#define bTRSSIFreq 0x200 -#define bADCBackoff 0x3000 -#define bDFIRBackoff 0xc000 -#define bTRSSILatchPhase 0x10000 -#define bRxIDCOffset 0xff -#define bRxQDCOffset 0xff00 -#define bRxDFIRMode 0x1800000 -#define bRxDCNFType 0xe000000 -#define bRXIQImb_A 0x3ff -#define bRXIQImb_B 0xfc00 -#define bRXIQImb_C 0x3f0000 -#define bRXIQImb_D 0xffc00000 -#define bDC_dc_Notch 0x60000 -#define bRxNBINotch 0x1f000000 -#define bPD_TH 0xf -#define bPD_TH_Opt2 0xc000 -#define bPWED_TH 0x700 -#define bIfMF_Win_L 0x800 -#define bPD_Option 0x1000 -#define bMF_Win_L 0xe000 -#define bBW_Search_L 0x30000 -#define bwin_enh_L 0xc0000 -#define bBW_TH 0x700000 -#define bED_TH2 0x3800000 -#define bBW_option 0x4000000 -#define bRatio_TH 0x18000000 -#define bWindow_L 0xe0000000 -#define bSBD_Option 0x1 -#define bFrame_TH 0x1c -#define bFS_Option 0x60 -#define bDC_Slope_check 0x80 -#define bFGuard_Counter_DC_L 0xe00 -#define bFrame_Weight_Short 0x7000 -#define bSub_Tune 0xe00000 -#define bFrame_DC_Length 0xe000000 -#define bSBD_start_offset 0x30000000 -#define bFrame_TH_2 0x7 -#define bFrame_GI2_TH 0x38 -#define bGI2_Sync_en 0x40 -#define bSarch_Short_Early 0x300 -#define bSarch_Short_Late 0xc00 -#define bSarch_GI2_Late 0x70000 -#define bCFOAntSum 0x1 -#define bCFOAcc 0x2 -#define bCFOStartOffset 0xc -#define bCFOLookBack 0x70 -#define bCFOSumWeight 0x80 -#define bDAGCEnable 0x10000 -#define bTXIQImb_A 0x3ff -#define bTXIQImb_B 0xfc00 -#define bTXIQImb_C 0x3f0000 -#define bTXIQImb_D 0xffc00000 -#define bTxIDCOffset 0xff -#define bTxQDCOffset 0xff00 -#define bTxDFIRMode 0x10000 -#define bTxPesudoNoiseOn 0x4000000 -#define bTxPesudoNoise_A 0xff -#define bTxPesudoNoise_B 0xff00 -#define bTxPesudoNoise_C 0xff0000 -#define bTxPesudoNoise_D 0xff000000 -#define bCCADropOption 0x20000 -#define bCCADropThres 0xfff00000 -#define bEDCCA_H 0xf -#define bEDCCA_L 0xf0 -#define bLambda_ED 0x300 -#define bRxInitialGain 0x7f -#define bRxAntDivEn 0x80 -#define bRxAGCAddressForLNA 0x7f00 -#define bRxHighPowerFlow 0x8000 -#define bRxAGCFreezeThres 0xc0000 -#define bRxFreezeStep_AGC1 0x300000 -#define bRxFreezeStep_AGC2 0xc00000 -#define bRxFreezeStep_AGC3 0x3000000 -#define bRxFreezeStep_AGC0 0xc000000 -#define bRxRssi_Cmp_En 0x10000000 -#define bRxQuickAGCEn 0x20000000 -#define bRxAGCFreezeThresMode 0x40000000 -#define bRxOverFlowCheckType 0x80000000 -#define bRxAGCShift 0x7f -#define bTRSW_Tri_Only 0x80 -#define bPowerThres 0x300 -#define bRxAGCEn 0x1 -#define bRxAGCTogetherEn 0x2 -#define bRxAGCMin 0x4 -#define bRxHP_Ini 0x7 -#define bRxHP_TRLNA 0x70 -#define bRxHP_RSSI 0x700 -#define bRxHP_BBP1 0x7000 -#define bRxHP_BBP2 0x70000 -#define bRxHP_BBP3 0x700000 -#define bRSSI_H 0x7f0000 /* the threshold for high power */ -#define bRSSI_Gen 0x7f000000 /* the threshold for ant divers */ -#define bRxSettle_TRSW 0x7 -#define bRxSettle_LNA 0x38 -#define bRxSettle_RSSI 0x1c0 -#define bRxSettle_BBP 0xe00 -#define bRxSettle_RxHP 0x7000 -#define bRxSettle_AntSW_RSSI 0x38000 -#define bRxSettle_AntSW 0xc0000 -#define bRxProcessTime_DAGC 0x300000 -#define bRxSettle_HSSI 0x400000 -#define bRxProcessTime_BBPPW 0x800000 -#define bRxAntennaPowerShift 0x3000000 -#define bRSSITableSelect 0xc000000 -#define bRxHP_Final 0x7000000 -#define bRxHTSettle_BBP 0x7 -#define bRxHTSettle_HSSI 0x8 -#define bRxHTSettle_RxHP 0x70 -#define bRxHTSettle_BBPPW 0x80 -#define bRxHTSettle_Idle 0x300 -#define bRxHTSettle_Reserved 0x1c00 -#define bRxHTRxHPEn 0x8000 -#define bRxHTAGCFreezeThres 0x30000 -#define bRxHTAGCTogetherEn 0x40000 -#define bRxHTAGCMin 0x80000 -#define bRxHTAGCEn 0x100000 -#define bRxHTDAGCEn 0x200000 -#define bRxHTRxHP_BBP 0x1c00000 -#define bRxHTRxHP_Final 0xe0000000 -#define bRxPWRatioTH 0x3 -#define bRxPWRatioEn 0x4 -#define bRxMFHold 0x3800 -#define bRxPD_Delay_TH1 0x38 -#define bRxPD_Delay_TH2 0x1c0 -#define bRxPD_DC_COUNT_MAX 0x600 -#define bRxPD_Delay_TH 0x8000 -#define bRxProcess_Delay 0xf0000 -#define bRxSearchrange_GI2_Early 0x700000 -#define bRxFrame_Guard_Counter_L 0x3800000 -#define bRxSGI_Guard_L 0xc000000 -#define bRxSGI_Search_L 0x30000000 -#define bRxSGI_TH 0xc0000000 -#define bDFSCnt0 0xff -#define bDFSCnt1 0xff00 -#define bDFSFlag 0xf0000 -#define bMFWeightSum 0x300000 -#define bMinIdxTH 0x7f000000 -#define bDAFormat 0x40000 -#define bTxChEmuEnable 0x01000000 -#define bTRSWIsolation_A 0x7f -#define bTRSWIsolation_B 0x7f00 -#define bTRSWIsolation_C 0x7f0000 -#define bTRSWIsolation_D 0x7f000000 -#define bExtLNAGain 0x7c00 - -/* 6. PageE(0xE00) */ -#define bSTBCEn 0x4 /* Useless */ -#define bAntennaMapping 0x10 -#define bNss 0x20 -#define bCFOAntSumD 0x200 -#define bPHYCounterReset 0x8000000 -#define bCFOReportGet 0x4000000 -#define bOFDMContinueTx 0x10000000 -#define bOFDMSingleCarrier 0x20000000 -#define bOFDMSingleTone 0x40000000 -#define bHTDetect 0x100 -#define bCFOEn 0x10000 -#define bCFOValue 0xfff00000 -#define bSigTone_Re 0x3f -#define bSigTone_Im 0x7f00 -#define bCounter_CCA 0xffff -#define bCounter_ParityFail 0xffff0000 -#define bCounter_RateIllegal 0xffff -#define bCounter_CRC8Fail 0xffff0000 -#define bCounter_MCSNoSupport 0xffff -#define bCounter_FastSync 0xffff -#define bShortCFO 0xfff -#define bShortCFOTLength 12 /* total */ -#define bShortCFOFLength 11 /* fraction */ -#define bLongCFO 0x7ff -#define bLongCFOTLength 11 -#define bLongCFOFLength 11 -#define bTailCFO 0x1fff -#define bTailCFOTLength 13 -#define bTailCFOFLength 12 -#define bmax_en_pwdB 0xffff -#define bCC_power_dB 0xffff0000 -#define bnoise_pwdB 0xffff -#define bPowerMeasTLength 10 -#define bPowerMeasFLength 3 -#define bRx_HT_BW 0x1 -#define bRxSC 0x6 -#define bRx_HT 0x8 -#define bNB_intf_det_on 0x1 -#define bIntf_win_len_cfg 0x30 -#define bNB_Intf_TH_cfg 0x1c0 -#define bRFGain 0x3f -#define bTableSel 0x40 -#define bTRSW 0x80 -#define bRxSNR_A 0xff -#define bRxSNR_B 0xff00 -#define bRxSNR_C 0xff0000 -#define bRxSNR_D 0xff000000 -#define bSNREVMTLength 8 -#define bSNREVMFLength 1 -#define bCSI1st 0xff -#define bCSI2nd 0xff00 -#define bRxEVM1st 0xff0000 -#define bRxEVM2nd 0xff000000 -#define bSIGEVM 0xff -#define bPWDB 0xff00 -#define bSGIEN 0x10000 - -#define bSFactorQAM1 0xf /* Useless */ -#define bSFactorQAM2 0xf0 -#define bSFactorQAM3 0xf00 -#define bSFactorQAM4 0xf000 -#define bSFactorQAM5 0xf0000 -#define bSFactorQAM6 0xf0000 -#define bSFactorQAM7 0xf00000 -#define bSFactorQAM8 0xf000000 -#define bSFactorQAM9 0xf0000000 -#define bCSIScheme 0x100000 - -#define bNoiseLvlTopSet 0x3 /* Useless */ -#define bChSmooth 0x4 -#define bChSmoothCfg1 0x38 -#define bChSmoothCfg2 0x1c0 -#define bChSmoothCfg3 0xe00 -#define bChSmoothCfg4 0x7000 -#define bMRCMode 0x800000 -#define bTHEVMCfg 0x7000000 - -#define bLoopFitType 0x1 /* Useless */ -#define bUpdCFO 0x40 -#define bUpdCFOOffData 0x80 -#define bAdvUpdCFO 0x100 -#define bAdvTimeCtrl 0x800 -#define bUpdClko 0x1000 -#define bFC 0x6000 -#define bTrackingMode 0x8000 -#define bPhCmpEnable 0x10000 -#define bUpdClkoLTF 0x20000 -#define bComChCFO 0x40000 -#define bCSIEstiMode 0x80000 -#define bAdvUpdEqz 0x100000 -#define bUChCfg 0x7000000 -#define bUpdEqz 0x8000000 - -#define bTxAGCRate18_06 0x7f7f7f7f /* Useless */ -#define bTxAGCRate54_24 0x7f7f7f7f -#define bTxAGCRateMCS32 0x7f -#define bTxAGCRateCCK 0x7f00 -#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f -#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f -#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f -#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f - -/* Rx Pseduo noise */ -#define bRxPesudoNoiseOn 0x20000000 /* Useless */ -#define bRxPesudoNoise_A 0xff -#define bRxPesudoNoise_B 0xff00 -#define bRxPesudoNoise_C 0xff0000 -#define bRxPesudoNoise_D 0xff000000 -#define bPesudoNoiseState_A 0xffff -#define bPesudoNoiseState_B 0xffff0000 -#define bPesudoNoiseState_C 0xffff -#define bPesudoNoiseState_D 0xffff0000 - -/* 7. RF Register - * Zebra1 - */ -#define bZebra1_HSSIEnable 0x8 /* Useless */ -#define bZebra1_TRxControl 0xc00 -#define bZebra1_TRxGainSetting 0x07f -#define bZebra1_RxCorner 0xc00 -#define bZebra1_TxChargePump 0x38 -#define bZebra1_RxChargePump 0x7 -#define bZebra1_ChannelNum 0xf80 -#define bZebra1_TxLPFBW 0x400 -#define bZebra1_RxLPFBW 0x600 - -/*Zebra4 */ -#define bRTL8256RegModeCtrl1 0x100 /* Useless */ -#define bRTL8256RegModeCtrl0 0x40 -#define bRTL8256_TxLPFBW 0x18 -#define bRTL8256_RxLPFBW 0x600 - -/* RTL8258 */ -#define bRTL8258_TxLPFBW 0xc /* Useless */ -#define bRTL8258_RxLPFBW 0xc00 -#define bRTL8258_RSSILPFBW 0xc0 - -/* - * Other Definition - */ - -/* byte endable for sb_write */ -#define bByte0 0x1 /* Useless */ -#define bByte1 0x2 -#define bByte2 0x4 -#define bByte3 0x8 -#define bWord0 0x3 -#define bWord1 0xc -#define bDWord 0xf - -/* for PutRegsetting & GetRegSetting BitMask */ -#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */ -#define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 -#define bMaskByte3 0xff000000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff -#define bMaskDWord 0xffffffff - -/* for PutRFRegsetting & GetRFRegSetting BitMask */ -#define bRFRegOffsetMask 0xfffff -#define bEnable 0x1 /* Useless */ -#define bDisable 0x0 - -#define LeftAntenna 0x0 /* Useless */ -#define RightAntenna 0x1 - -#define tCheckTxStatus 500 /* 500ms Useless */ -#define tUpdateRxCounter 100 /* 100ms */ - -#define rateCCK 0 /* Useless */ -#define rateOFDM 1 -#define rateHT 2 - -/* define Register-End */ -#define bPMAC_End 0x1ff /* Useless */ -#define bFPGAPHY0_End 0x8ff -#define bFPGAPHY1_End 0x9ff -#define bCCKPHY0_End 0xaff -#define bOFDMPHY0_End 0xcff -#define bOFDMPHY1_End 0xdff - -#define bPMACControl 0x0 /* Useless */ -#define bWMACControl 0x1 -#define bWNICControl 0x2 - -#define ANTENNA_A 0x1 /* Useless */ -#define ANTENNA_B 0x2 -#define ANTENNA_AB 0x3 /* ANTENNA_A |ANTENNA_B */ - -#define ANTENNA_C 0x4 -#define ANTENNA_D 0x8 - -/* accept all physical address */ -#define RCR_AAP BIT(0) -#define RCR_APM BIT(1) /* accept physical match */ -#define RCR_AM BIT(2) /* accept multicast */ -#define RCR_AB BIT(3) /* accept broadcast */ -#define RCR_ACRC32 BIT(5) /* accept error packet */ -#define RCR_9356SEL BIT(6) -#define RCR_AICV BIT(12) /* Accept ICV error packet */ -#define RCR_RXFTH0 (BIT(13)|BIT(14)|BIT(15)) /* Rx FIFO threshold */ -#define RCR_ADF BIT(18) /* Accept Data(frame type) frame */ -#define RCR_ACF BIT(19) /* Accept control frame */ -#define RCR_AMF BIT(20) /* Accept management frame */ -#define RCR_ADD3 BIT(21) -#define RCR_APWRMGT BIT(22) /* Accept power management packet */ -#define RCR_CBSSID BIT(23) /* Accept BSSID match packet */ -#define RCR_ENMARP BIT(28) /* enable mac auto reset phy */ -#define RCR_EnCS1 BIT(29) /* enable carrier sense method 1 */ -#define RCR_EnCS2 BIT(30) /* enable carrier sense method 2 */ -/* Rx Early mode is performed for packet size greater than 1536 */ -#define RCR_OnlyErlPkt BIT(31) - -/*--------------------------Define Parameters-------------------------------*/ - -#endif /*__INC_HAL8192SPHYREG_H */ - diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c deleted file mode 100644 index cd6d9ff0bebc..000000000000 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_pwrctrl.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_PWRCTRL_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" - -#define RTL8712_SDIO_LOCAL_BASE 0X10100000 -#define SDIO_HCPWM (RTL8712_SDIO_LOCAL_BASE + 0x0081) - -void r8712_set_rpwm(struct _adapter *padapter, u8 val8) -{ - u8 rpwm; - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - if (pwrpriv->rpwm == val8) { - if (pwrpriv->rpwm_retry == 0) - return; - } - if (padapter->driver_stopped || padapter->surprise_removed) - return; - rpwm = val8 | pwrpriv->tog; - switch (val8) { - case PS_STATE_S1: - pwrpriv->cpwm = val8; - break; - case PS_STATE_S2:/* only for USB normal powersave mode use, - * temp mark some code. - */ - case PS_STATE_S3: - case PS_STATE_S4: - pwrpriv->cpwm = val8; - break; - default: - break; - } - pwrpriv->rpwm_retry = 0; - pwrpriv->rpwm = val8; - r8712_write8(padapter, 0x1025FE58, rpwm); - pwrpriv->tog += 0x80; -} - -void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, uint smart_ps) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - if (ps_mode > PM_Card_Disable) - return; - /* if driver is in active state, we dont need set smart_ps.*/ - if (ps_mode == PS_MODE_ACTIVE) - smart_ps = 0; - if ((pwrpriv->pwr_mode != ps_mode) || (pwrpriv->smart_ps != smart_ps)) { - if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) - pwrpriv->bSleep = true; - else - pwrpriv->bSleep = false; - pwrpriv->pwr_mode = ps_mode; - pwrpriv->smart_ps = smart_ps; - schedule_work(&pwrpriv->SetPSModeWorkItem); - } -} - -/* - * Caller:ISR handler... - * - * This will be called when CPWM interrupt is up. - * - * using to update cpwn of drv; and drv will make a decision to up or - * down pwr level - */ -void r8712_cpwm_int_hdl(struct _adapter *padapter, - struct reportpwrstate_parm *preportpwrstate) -{ - struct pwrctrl_priv *pwrpriv = &(padapter->pwrctrlpriv); - struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); - - if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80)) - return; - del_timer(&padapter->pwrctrlpriv.rpwm_check_timer); - mutex_lock(&pwrpriv->mutex_lock); - pwrpriv->cpwm = (preportpwrstate->state) & 0xf; - if (pwrpriv->cpwm >= PS_STATE_S2) { - if (pwrpriv->alives & CMD_ALIVE) - complete(&(pcmdpriv->cmd_queue_comp)); - } - pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80; - mutex_unlock(&pwrpriv->mutex_lock); -} - -static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, uint tag) -{ - pwrctrl->alives |= tag; -} - -static inline void unregister_task_alive(struct pwrctrl_priv *pwrctrl, uint tag) -{ - if (pwrctrl->alives & tag) - pwrctrl->alives ^= tag; -} - -static void _rpwm_check_handler (struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - if (padapter->driver_stopped || padapter->surprise_removed) - return; - if (pwrpriv->cpwm != pwrpriv->rpwm) - schedule_work(&pwrpriv->rpwm_workitem); -} - -static void SetPSModeWorkItemCallback(struct work_struct *work) -{ - struct pwrctrl_priv *pwrpriv = container_of(work, - struct pwrctrl_priv, SetPSModeWorkItem); - struct _adapter *padapter = container_of(pwrpriv, - struct _adapter, pwrctrlpriv); - if (!pwrpriv->bSleep) { - mutex_lock(&pwrpriv->mutex_lock); - if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) - r8712_set_rpwm(padapter, PS_STATE_S4); - mutex_unlock(&pwrpriv->mutex_lock); - } -} - -static void rpwm_workitem_callback(struct work_struct *work) -{ - struct pwrctrl_priv *pwrpriv = container_of(work, - struct pwrctrl_priv, rpwm_workitem); - struct _adapter *padapter = container_of(pwrpriv, - struct _adapter, pwrctrlpriv); - if (pwrpriv->cpwm != pwrpriv->rpwm) { - mutex_lock(&pwrpriv->mutex_lock); - r8712_read8(padapter, SDIO_HCPWM); - pwrpriv->rpwm_retry = 1; - r8712_set_rpwm(padapter, pwrpriv->rpwm); - mutex_unlock(&pwrpriv->mutex_lock); - } -} - -static void rpwm_check_handler (struct timer_list *t) -{ - struct _adapter *adapter = - from_timer(adapter, t, pwrctrlpriv.rpwm_check_timer); - - _rpwm_check_handler(adapter); -} - -void r8712_init_pwrctrl_priv(struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; - - memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv)); - mutex_init(&pwrctrlpriv->mutex_lock); - pwrctrlpriv->cpwm = PS_STATE_S4; - pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; - pwrctrlpriv->smart_ps = 0; - pwrctrlpriv->tog = 0x80; -/* clear RPWM to ensure driver and fw back to initial state. */ - r8712_write8(padapter, 0x1025FE58, 0); - INIT_WORK(&pwrctrlpriv->SetPSModeWorkItem, SetPSModeWorkItemCallback); - INIT_WORK(&pwrctrlpriv->rpwm_workitem, rpwm_workitem_callback); - timer_setup(&pwrctrlpriv->rpwm_check_timer, rpwm_check_handler, 0); -} - -/* - * Caller: r8712_cmd_thread - * Check if the fw_pwrstate is okay for issuing cmd. - * If not (cpwm should be is less than P2 state), then the sub-routine - * will raise the cpwm to be greater than or equal to P2. - * Calling Context: Passive - * Return Value: - * 0: r8712_cmd_thread can issue cmds to firmware afterwards. - * -EINVAL: r8712_cmd_thread can not do anything. - */ -int r8712_register_cmd_alive(struct _adapter *padapter) -{ - int res = 0; - struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; - - mutex_lock(&pwrctrl->mutex_lock); - register_task_alive(pwrctrl, CMD_ALIVE); - if (pwrctrl->cpwm < PS_STATE_S2) { - r8712_set_rpwm(padapter, PS_STATE_S3); - res = -EINVAL; - } - mutex_unlock(&pwrctrl->mutex_lock); - return res; -} - -/* - * Caller: ISR - * If ISR's txdone, - * No more pkts for TX, - * Then driver shall call this fun. to power down firmware again. - */ -void r8712_unregister_cmd_alive(struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; - - mutex_lock(&pwrctrl->mutex_lock); - unregister_task_alive(pwrctrl, CMD_ALIVE); - if ((pwrctrl->cpwm > PS_STATE_S2) && - (pwrctrl->pwr_mode > PS_MODE_ACTIVE)) { - if ((pwrctrl->alives == 0) && - (check_fwstate(&padapter->mlmepriv, - _FW_UNDER_LINKING) != true)) { - r8712_set_rpwm(padapter, PS_STATE_S0); - } - } - mutex_unlock(&pwrctrl->mutex_lock); -} - -void r8712_flush_rwctrl_works(struct _adapter *padapter) -{ - struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv; - - flush_work(&pwrctrl->SetPSModeWorkItem); - flush_work(&pwrctrl->rpwm_workitem); -} diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h deleted file mode 100644 index b35b9c7920eb..000000000000 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_PWRCTRL_H_ -#define __RTL871X_PWRCTRL_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define CMD_ALIVE BIT(2) - -enum Power_Mgnt { - PS_MODE_ACTIVE = 0, - PS_MODE_MIN, - PS_MODE_MAX, - PS_MODE_DTIM, - PS_MODE_VOIP, - PS_MODE_UAPSD_WMM, - PS_MODE_UAPSD, - PS_MODE_IBSS, - PS_MODE_WWLAN, - PM_Radio_Off, - PM_Card_Disable, - PS_MODE_NUM -}; - -/* - * BIT[2:0] = HW state - * BIT[3] = Protocol PS state, 0: register active state, - * 1: register sleep state - * BIT[4] = sub-state - */ - -#define PS_DPS BIT(0) -#define PS_LCLK (PS_DPS) -#define PS_RF_OFF BIT(1) -#define PS_ALL_ON BIT(2) -#define PS_ST_ACTIVE BIT(3) -#define PS_LP BIT(4) /* low performance */ - -#define PS_STATE_MASK (0x0F) -#define PS_STATE_HW_MASK (0x07) -#define PS_SEQ_MASK (0xc0) - -#define PS_STATE(x) (PS_STATE_MASK & (x)) -#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) -#define PS_SEQ(x) (PS_SEQ_MASK & (x)) - -#define PS_STATE_S0 (PS_DPS) -#define PS_STATE_S1 (PS_LCLK) -#define PS_STATE_S2 (PS_RF_OFF) -#define PS_STATE_S3 (PS_ALL_ON) -#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) - -#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) -#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) -#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) - -struct reportpwrstate_parm { - unsigned char mode; - unsigned char state; /* the CPWM value */ - unsigned short rsvd; -}; - -struct pwrctrl_priv { - struct mutex mutex_lock; - /*volatile*/ u8 rpwm; /* requested power state for fw */ - /* fw current power state. updated when 1. read from HCPWM or - * 2. driver lowers power level - */ - /*volatile*/ u8 cpwm; - /*volatile*/ u8 tog; /* toggling */ - /*volatile*/ u8 cpwm_tog; /* toggling */ - /*volatile*/ u8 tgt_rpwm; /* wanted power state */ - uint pwr_mode; - uint smart_ps; - uint alives; - uint ImrContent; /* used to store original imr. */ - uint bSleep; /* sleep -> active is different from active -> sleep. */ - - struct work_struct SetPSModeWorkItem; - struct work_struct rpwm_workitem; - struct timer_list rpwm_check_timer; - u8 rpwm_retry; - uint bSetPSModeWorkItemInProgress; - - spinlock_t pnp_pwr_mgnt_lock; - s32 pnp_current_pwr_state; - u8 pnp_bstop_trx; - u8 pnp_wwirp_pending; -}; - -void r8712_init_pwrctrl_priv(struct _adapter *adapter); -int r8712_register_cmd_alive(struct _adapter *padapter); -void r8712_unregister_cmd_alive(struct _adapter *padapter); -void r8712_cpwm_int_hdl(struct _adapter *padapter, - struct reportpwrstate_parm *preportpwrstate); -void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, - uint smart_ps); -void r8712_set_rpwm(struct _adapter *padapter, u8 val8); -void r8712_flush_rwctrl_works(struct _adapter *padapter); - -#endif /* __RTL871X_PWRCTRL_H_ */ diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c deleted file mode 100644 index 8a3566214af7..000000000000 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ /dev/null @@ -1,671 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_recv.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_RECV_C_ - -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "mlme_osdep.h" -#include "ethernet.h" -#include "usb_ops.h" -#include "wifi.h" - -static const u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; - -/* Datagram Delivery Protocol */ -static const u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; - -void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) -{ - memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); - spin_lock_init(&psta_recvpriv->lock); - _init_queue(&psta_recvpriv->defrag_q); -} - -int _r8712_init_recv_priv(struct recv_priv *precvpriv, - struct _adapter *padapter) -{ - int ret; - sint i; - union recv_frame *precvframe; - - memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); - spin_lock_init(&precvpriv->lock); - _init_queue(&precvpriv->free_recv_queue); - _init_queue(&precvpriv->recv_pending_queue); - precvpriv->adapter = padapter; - precvpriv->free_recvframe_cnt = NR_RECVFRAME; - precvpriv->pallocated_frame_buf = kzalloc(NR_RECVFRAME * - sizeof(union recv_frame) + RXFRAME_ALIGN_SZ, - GFP_ATOMIC); - if (!precvpriv->pallocated_frame_buf) - return -ENOMEM; - precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + - RXFRAME_ALIGN_SZ - - ((addr_t)(precvpriv->pallocated_frame_buf) & - (RXFRAME_ALIGN_SZ - 1)); - precvframe = (union recv_frame *)precvpriv->precv_frame_buf; - for (i = 0; i < NR_RECVFRAME; i++) { - INIT_LIST_HEAD(&(precvframe->u.list)); - list_add_tail(&(precvframe->u.list), - &(precvpriv->free_recv_queue.queue)); - r8712_os_recv_resource_alloc(padapter, precvframe); - precvframe->u.hdr.adapter = padapter; - precvframe++; - } - precvpriv->rx_pending_cnt = 1; - ret = r8712_init_recv_priv(precvpriv, padapter); - if (ret) - kfree(precvpriv->pallocated_frame_buf); - - return ret; -} - -void _r8712_free_recv_priv(struct recv_priv *precvpriv) -{ - kfree(precvpriv->pallocated_frame_buf); - r8712_free_recv_priv(precvpriv); -} - -union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue) -{ - unsigned long irqL; - union recv_frame *precvframe; - struct _adapter *padapter; - struct recv_priv *precvpriv; - - spin_lock_irqsave(&pfree_recv_queue->lock, irqL); - precvframe = list_first_entry_or_null(&pfree_recv_queue->queue, - union recv_frame, u.hdr.list); - if (precvframe) { - list_del_init(&precvframe->u.hdr.list); - padapter = precvframe->u.hdr.adapter; - if (padapter) { - precvpriv = &padapter->recvpriv; - if (pfree_recv_queue == &precvpriv->free_recv_queue) - precvpriv->free_recvframe_cnt--; - } - } - spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL); - return precvframe; -} - -/* - * caller : defrag; recvframe_chk_defrag in recv_thread (passive) - * pframequeue: defrag_queue : will be accessed in recv_thread (passive) - * using spin_lock to protect - */ -void r8712_free_recvframe_queue(struct __queue *pframequeue, - struct __queue *pfree_recv_queue) -{ - union recv_frame *precvframe; - struct list_head *plist, *phead; - - spin_lock(&pframequeue->lock); - phead = &pframequeue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - precvframe = container_of(plist, union recv_frame, u.list); - plist = plist->next; - r8712_free_recvframe(precvframe, pfree_recv_queue); - } - spin_unlock(&pframequeue->lock); -} - -sint r8712_recvframe_chkmic(struct _adapter *adapter, - union recv_frame *precvframe) -{ - sint i, res = _SUCCESS; - u32 datalen; - u8 miccode[8]; - u8 bmic_err = false; - u8 *pframe, *payload, *pframemic; - u8 *mickey, idx, *iv; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); - if (prxattrib->encrypt == _TKIP_) { - /* calculate mic code */ - if (stainfo) { - if (is_multicast_ether_addr(prxattrib->ra)) { - iv = precvframe->u.hdr.rx_data + - prxattrib->hdrlen; - idx = iv[3]; - mickey = &psecuritypriv->XGrprxmickey[(((idx >> - 6) & 0x3)) - 1].skey[0]; - if (!psecuritypriv->binstallGrpkey) - return _FAIL; - } else { - mickey = &stainfo->tkiprxmickey.skey[0]; - } - /*icv_len included the mic code*/ - datalen = precvframe->u.hdr.len - prxattrib->hdrlen - - prxattrib->iv_len - prxattrib->icv_len - 8; - pframe = precvframe->u.hdr.rx_data; - payload = pframe + prxattrib->hdrlen + - prxattrib->iv_len; - seccalctkipmic(mickey, pframe, payload, datalen, - &miccode[0], - (unsigned char)prxattrib->priority); - pframemic = payload + datalen; - bmic_err = false; - for (i = 0; i < 8; i++) { - if (miccode[i] != *(pframemic + i)) - bmic_err = true; - } - if (bmic_err) { - if (prxattrib->bdecrypted) - r8712_handle_tkip_mic_err(adapter, - (u8)is_multicast_ether_addr(prxattrib->ra)); - res = _FAIL; - } else { - /* mic checked ok */ - if (!psecuritypriv->bcheck_grpkey && - is_multicast_ether_addr(prxattrib->ra)) - psecuritypriv->bcheck_grpkey = true; - } - recvframe_pull_tail(precvframe, 8); - } - } - return res; -} - -/* decrypt and set the ivlen,icvlen of the recv_frame */ -union recv_frame *r8712_decryptor(struct _adapter *padapter, - union recv_frame *precv_frame) -{ - struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - union recv_frame *return_packet = precv_frame; - - if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || - psecuritypriv->sw_decrypt)) { - psecuritypriv->hw_decrypted = false; - switch (prxattrib->encrypt) { - case _WEP40_: - case _WEP104_: - r8712_wep_decrypt(padapter, (u8 *)precv_frame); - break; - case _TKIP_: - r8712_tkip_decrypt(padapter, (u8 *)precv_frame); - break; - case _AES_: - r8712_aes_decrypt(padapter, (u8 *)precv_frame); - break; - default: - break; - } - } else if (prxattrib->bdecrypted == 1) { - psecuritypriv->hw_decrypted = true; - } - return return_packet; -} - -/*###set the security information in the recv_frame */ -union recv_frame *r8712_portctrl(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - u8 *psta_addr, *ptr; - uint auth_alg; - struct recv_frame_hdr *pfhdr; - struct sta_info *psta; - struct sta_priv *pstapriv; - union recv_frame *prtnframe; - u16 ether_type; - - pstapriv = &adapter->stapriv; - ptr = precv_frame->u.hdr.rx_data; - pfhdr = &precv_frame->u.hdr; - psta_addr = pfhdr->attrib.ta; - psta = r8712_get_stainfo(pstapriv, psta_addr); - auth_alg = adapter->securitypriv.AuthAlgrthm; - if (auth_alg == 2) { - /* get ether_type */ - ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; - ether_type = get_unaligned_be16(ptr); - - if (psta && psta->ieee8021x_blocked) { - /* blocked - * only accept EAPOL frame - */ - if (ether_type == 0x888e) { - prtnframe = precv_frame; - } else { - /*free this frame*/ - r8712_free_recvframe(precv_frame, - &adapter->recvpriv.free_recv_queue); - prtnframe = NULL; - } - } else { - /* allowed - * check decryption status, and decrypt the - * frame if needed - */ - prtnframe = precv_frame; - /* check is the EAPOL frame or not (Rekey) */ - if (ether_type == 0x888e) { - /* check Rekey */ - prtnframe = precv_frame; - } - } - } else { - prtnframe = precv_frame; - } - return prtnframe; -} - -static sint recv_decache(union recv_frame *precv_frame, u8 bretry, - struct stainfo_rxcache *prxcache) -{ - sint tid = precv_frame->u.hdr.attrib.priority; - u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) | - (precv_frame->u.hdr.attrib.frag_num & 0xf); - - if (tid > 15) - return _FAIL; - if (seq_ctrl == prxcache->tid_rxseq[tid]) - return _FAIL; - prxcache->tid_rxseq[tid] = seq_ctrl; - return _SUCCESS; -} - -static sint sta2sta_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta) -{ - u8 *ptr = precv_frame->u.hdr.rx_data; - sint ret = _SUCCESS; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *mybssid = get_bssid(pmlmepriv); - u8 *myhwaddr = myid(&adapter->eeprompriv); - u8 *sta_addr = NULL; - bool bmcast = is_multicast_ether_addr(pattrib->dst); - - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - /* filter packets that SA is myself or multicast or broadcast */ - if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) - return _FAIL; - if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) - return _FAIL; - if (is_zero_ether_addr(pattrib->bssid) || - is_zero_ether_addr(mybssid) || - (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) - return _FAIL; - sta_addr = pattrib->src; - } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - /* For Station mode, sa and bssid should always be BSSID, - * and DA is my mac-address - */ - if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) - return _FAIL; - sta_addr = pattrib->bssid; - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - if (bmcast) { - /* For AP mode, if DA == MCAST, then BSSID should - * be also MCAST - */ - if (!is_multicast_ether_addr(pattrib->bssid)) - return _FAIL; - } else { /* not mc-frame */ - /* For AP mode, if DA is non-MCAST, then it must be - * BSSID, and bssid == BSSID - */ - if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) - return _FAIL; - sta_addr = pattrib->src; - } - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); - memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - sta_addr = mybssid; - } else { - ret = _FAIL; - } - if (bmcast) - *psta = r8712_get_bcmc_stainfo(adapter); - else - *psta = r8712_get_stainfo(pstapriv, sta_addr); /* get ap_info */ - if (!*psta) { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - adapter->mppriv.rx_pktloss++; - return _FAIL; - } - return ret; -} - -static sint ap2sta_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta) -{ - u8 *ptr = precv_frame->u.hdr.rx_data; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - u8 *mybssid = get_bssid(pmlmepriv); - u8 *myhwaddr = myid(&adapter->eeprompriv); - bool bmcast = is_multicast_ether_addr(pattrib->dst); - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && - check_fwstate(pmlmepriv, _FW_LINKED)) { - /* if NULL-frame, drop packet */ - if ((GetFrameSubType(ptr)) == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC)) - return _FAIL; - /* drop QoS-SubType Data, including QoS NULL, - * excluding QoS-Data - */ - if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == - WIFI_QOS_DATA_TYPE) { - if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6))) - return _FAIL; - } - - /* filter packets that SA is myself or multicast or broadcast */ - if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) - return _FAIL; - - /* da should be for me */ - if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) - return _FAIL; - /* check BSSID */ - if (is_zero_ether_addr(pattrib->bssid) || - is_zero_ether_addr(mybssid) || - (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) - return _FAIL; - if (bmcast) - *psta = r8712_get_bcmc_stainfo(adapter); - else - *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); - if (!*psta) - return _FAIL; - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && - check_fwstate(pmlmepriv, _FW_LINKED)) { - memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); - memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - memcpy(pattrib->bssid, mybssid, ETH_ALEN); - *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); - if (!*psta) - return _FAIL; - } else { - return _FAIL; - } - return _SUCCESS; -} - -static sint sta2ap_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame, - struct sta_info **psta) -{ - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct sta_priv *pstapriv = &adapter->stapriv; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - unsigned char *mybssid = get_bssid(pmlmepriv); - - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - /* For AP mode, if DA is non-MCAST, then it must be BSSID, - * and bssid == BSSID - * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR - */ - if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) - return _FAIL; - *psta = r8712_get_stainfo(pstapriv, pattrib->src); - if (!*psta) - return _FAIL; - } - return _SUCCESS; -} - -static sint validate_recv_ctrl_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - return _FAIL; -} - -static sint validate_recv_mgnt_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - return _FAIL; -} - -static sint validate_recv_data_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - int res; - u8 bretry; - u8 *psa, *pda, *pbssid; - struct sta_info *psta = NULL; - u8 *ptr = precv_frame->u.hdr.rx_data; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - struct security_priv *psecuritypriv = &adapter->securitypriv; - - bretry = GetRetry(ptr); - pda = ieee80211_get_DA((struct ieee80211_hdr *)ptr); - psa = ieee80211_get_SA((struct ieee80211_hdr *)ptr); - pbssid = get_hdr_bssid(ptr); - if (!pbssid) - return _FAIL; - memcpy(pattrib->dst, pda, ETH_ALEN); - memcpy(pattrib->src, psa, ETH_ALEN); - memcpy(pattrib->bssid, pbssid, ETH_ALEN); - switch (pattrib->to_fr_ds) { - case 0: - memcpy(pattrib->ra, pda, ETH_ALEN); - memcpy(pattrib->ta, psa, ETH_ALEN); - res = sta2sta_data_frame(adapter, precv_frame, &psta); - break; - case 1: - memcpy(pattrib->ra, pda, ETH_ALEN); - memcpy(pattrib->ta, pbssid, ETH_ALEN); - res = ap2sta_data_frame(adapter, precv_frame, &psta); - break; - case 2: - memcpy(pattrib->ra, pbssid, ETH_ALEN); - memcpy(pattrib->ta, psa, ETH_ALEN); - res = sta2ap_data_frame(adapter, precv_frame, &psta); - break; - case 3: - memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); - memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); - return _FAIL; - default: - return _FAIL; - } - if (res == _FAIL) - return _FAIL; - if (!psta) - return _FAIL; - precv_frame->u.hdr.psta = psta; - pattrib->amsdu = 0; - /* parsing QC field */ - if (pattrib->qos == 1) { - pattrib->priority = GetPriority((ptr + 24)); - pattrib->ack_policy = GetAckpolicy((ptr + 24)); - pattrib->amsdu = GetAMsdu((ptr + 24)); - pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; - } else { - pattrib->priority = 0; - pattrib->hdrlen = (pattrib->to_fr_ds == 3) ? 30 : 24; - } - - if (pattrib->order)/*HT-CTRL 11n*/ - pattrib->hdrlen += 4; - precv_frame->u.hdr.preorder_ctrl = - &psta->recvreorder_ctrl[pattrib->priority]; - - /* decache, drop duplicate recv packets */ - if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == - _FAIL) - return _FAIL; - - if (pattrib->privacy) { - GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, - is_multicast_ether_addr(pattrib->ra)); - SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, - pattrib->encrypt); - } else { - pattrib->encrypt = 0; - pattrib->iv_len = pattrib->icv_len = 0; - } - return _SUCCESS; -} - -sint r8712_validate_recv_frame(struct _adapter *adapter, - union recv_frame *precv_frame) -{ - /*shall check frame subtype, to / from ds, da, bssid */ - /*then call check if rx seq/frag. duplicated.*/ - - u8 type; - u8 subtype; - sint retval = _SUCCESS; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; - - u8 *ptr = precv_frame->u.hdr.rx_data; - u8 ver = (unsigned char)(*ptr) & 0x3; - - /*add version chk*/ - if (ver != 0) - return _FAIL; - type = GetFrameType(ptr); - subtype = GetFrameSubType(ptr); /*bit(7)~bit(2)*/ - pattrib->to_fr_ds = get_tofr_ds(ptr); - pattrib->frag_num = GetFragNum(ptr); - pattrib->seq_num = GetSequence(ptr); - pattrib->pw_save = GetPwrMgt(ptr); - pattrib->mfrag = GetMFrag(ptr); - pattrib->mdata = GetMData(ptr); - pattrib->privacy = GetPrivacy(ptr); - pattrib->order = GetOrder(ptr); - switch (type) { - case IEEE80211_FTYPE_MGMT: - retval = validate_recv_mgnt_frame(adapter, precv_frame); - break; - case IEEE80211_FTYPE_CTL: - retval = validate_recv_ctrl_frame(adapter, precv_frame); - break; - case IEEE80211_FTYPE_DATA: - pattrib->qos = (subtype & BIT(7)) ? 1 : 0; - retval = validate_recv_data_frame(adapter, precv_frame); - break; - default: - return _FAIL; - } - return retval; -} - -int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) -{ - /*remove the wlanhdr and add the eth_hdr*/ - sint rmv_len; - u16 len; - u8 bsnaphdr; - u8 *psnap_type; - struct ieee80211_snap_hdr *psnap; - struct _adapter *adapter = precvframe->u.hdr.adapter; - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - u8 *ptr = precvframe->u.hdr.rx_data; /*point to frame_ctrl field*/ - struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; - - if (pattrib->encrypt) - recvframe_pull_tail(precvframe, pattrib->icv_len); - psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + - pattrib->iv_len); - psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; - /* convert hdr + possible LLC headers into Ethernet header */ - if ((!memcmp(psnap, (void *)rfc1042_header, SNAP_SIZE) && - (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_IPX, 2)) && - (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) || - !memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType - */ - bsnaphdr = true; - } else { - /* Leave Ethernet header part of hdr and full payload */ - bsnaphdr = false; - } - rmv_len = pattrib->hdrlen + pattrib->iv_len + - (bsnaphdr ? SNAP_SIZE : 0); - len = precvframe->u.hdr.len - rmv_len; - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - ptr += rmv_len; - *ptr = 0x87; - *(ptr + 1) = 0x12; - /* append rx status for mp test packets */ - ptr = recvframe_pull(precvframe, (rmv_len - - sizeof(struct ethhdr) + 2) - 24); - if (!ptr) - return -ENOMEM; - memcpy(ptr, get_rxmem(precvframe), 24); - ptr += 24; - } else { - ptr = recvframe_pull(precvframe, (rmv_len - - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - if (!ptr) - return -ENOMEM; - } - - memcpy(ptr, pattrib->dst, ETH_ALEN); - memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); - if (!bsnaphdr) { - __be16 be_tmp = htons(len); - - memcpy(ptr + 12, &be_tmp, 2); - } - return 0; -} - -void r8712_recv_entry(union recv_frame *precvframe) -{ - struct _adapter *padapter; - struct recv_priv *precvpriv; - - s32 ret = _SUCCESS; - - padapter = precvframe->u.hdr.adapter; - precvpriv = &(padapter->recvpriv); - - padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX); - - ret = recv_func(padapter, precvframe); - if (ret == _FAIL) - goto _recv_entry_drop; - precvpriv->rx_pkts++; - precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail - - precvframe->u.hdr.rx_data); - return; -_recv_entry_drop: - precvpriv->rx_drop++; - padapter->mppriv.rx_pktloss = precvpriv->rx_drop; -} diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h deleted file mode 100644 index 0760bccbf389..000000000000 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _RTL871X_RECV_H_ -#define _RTL871X_RECV_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define NR_RECVFRAME 256 - -#define RXFRAME_ALIGN 8 -#define RXFRAME_ALIGN_SZ (1 << RXFRAME_ALIGN) - -#define MAX_SUBFRAME_COUNT 64 - -/* for Rx reordering buffer control */ -struct recv_reorder_ctrl { - struct _adapter *padapter; - u16 indicate_seq; /* =wstart_b, init_value=0xffff */ - u16 wend_b; - u8 wsize_b; - struct __queue pending_recvframe_queue; - struct timer_list reordering_ctrl_timer; -}; - -struct stainfo_rxcache { - u16 tid_rxseq[16]; -}; - -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_LINKQUALITY_SLID_WIN_MAX 20 - -struct smooth_rssi_data { - u32 elements[100]; /* array to store values */ - u32 index; /* index to current array to store */ - u32 total_num; /* num of valid elements */ - u32 total_val; /* sum of valid elements */ -}; - -struct rx_pkt_attrib { - u8 amsdu; - u8 order; - u8 qos; - u8 to_fr_ds; - u8 frag_num; - u16 seq_num; - u8 pw_save; - u8 mfrag; - u8 mdata; - u8 privacy; /* in frame_ctrl field */ - u8 bdecrypted; - int hdrlen; /* the WLAN Header Len */ - int encrypt; /* 0 no encrypt. != 0 encrypt algorithm */ - int iv_len; - int icv_len; - int priority; - int ack_policy; - u8 crc_err; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 ta[ETH_ALEN]; - u8 ra[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - u8 tcpchk_valid; /* 0: invalid, 1: valid */ - u8 ip_chkrpt; /* 0: incorrect, 1: correct */ - u8 tcp_chkrpt; /* 0: incorrect, 1: correct */ - u8 signal_qual; - s8 rx_mimo_signal_qual[2]; - u8 mcs_rate; - u8 htc; - u8 signal_strength; -}; - -/* - * accesser of recv_priv: recv_entry(dispatch / passive level); - * recv_thread(passive) ; returnpkt(dispatch) - * ; halt(passive) ; - * - * using enter_critical section to protect - */ -struct recv_priv { - spinlock_t lock; - struct __queue free_recv_queue; - struct __queue recv_pending_queue; - u8 *pallocated_frame_buf; - u8 *precv_frame_buf; - uint free_recvframe_cnt; - struct _adapter *adapter; - uint rx_bytes; - uint rx_pkts; - uint rx_drop; - uint rx_icv_err; - uint rx_largepacket_crcerr; - uint rx_smallpacket_crcerr; - uint rx_middlepacket_crcerr; - u8 rx_pending_cnt; - uint ff_hwaddr; - struct tasklet_struct recv_tasklet; - struct sk_buff_head free_recv_skb_queue; - struct sk_buff_head rx_skb_queue; - u8 *pallocated_recv_buf; - u8 *precv_buf; /* 4 alignment */ - struct __queue free_recv_buf_queue; - u32 free_recv_buf_queue_cnt; - /* For the phy information */ - s8 rssi; - u8 signal; - u8 noise; - u8 fw_rssi; - struct smooth_rssi_data signal_qual_data; - struct smooth_rssi_data signal_strength_data; -}; - -struct sta_recv_priv { - spinlock_t lock; - sint option; - struct __queue defrag_q; /* keeping the fragment frame until defrag */ - struct stainfo_rxcache rxcache; - uint sta_rx_bytes; - uint sta_rx_pkts; - uint sta_rx_fail; -}; - -#include "rtl8712_recv.h" - -/* get a free recv_frame from pfree_recv_queue */ -union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue); -void r8712_free_recvframe(union recv_frame *precvframe, - struct __queue *pfree_recv_queue); -void r8712_free_recvframe_queue(struct __queue *pframequeue, - struct __queue *pfree_recv_queue); -int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe); -int recv_func(struct _adapter *padapter, void *pcontext); - -static inline u8 *get_rxmem(union recv_frame *precvframe) -{ - /* always return rx_head... */ - if (!precvframe) - return NULL; - return precvframe->u.hdr.rx_head; -} - -static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz) -{ - /* used for extract sz bytes from rx_data, update rx_data and return - * the updated rx_data to the caller - */ - if (!precvframe) - return NULL; - precvframe->u.hdr.rx_data += sz; - if (precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) { - precvframe->u.hdr.rx_data -= sz; - return NULL; - } - precvframe->u.hdr.len -= sz; - return precvframe->u.hdr.rx_data; -} - -static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz) -{ - /* used for append sz bytes from ptr to rx_tail, update rx_tail and - * return the updated rx_tail to the caller - * after putting, rx_tail must be still larger than rx_end. - */ - if (!precvframe) - return NULL; - precvframe->u.hdr.rx_tail += sz; - if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) { - precvframe->u.hdr.rx_tail -= sz; - return NULL; - } - precvframe->u.hdr.len += sz; - return precvframe->u.hdr.rx_tail; -} - -static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) -{ - /* rmv data from rx_tail (by yitsen) - * used for extract sz bytes from rx_end, update rx_end and return the - * updated rx_end to the caller - * after pulling, rx_end must be still larger than rx_data. - */ - if (!precvframe) - return NULL; - precvframe->u.hdr.rx_tail -= sz; - if (precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) { - precvframe->u.hdr.rx_tail += sz; - return NULL; - } - precvframe->u.hdr.len -= sz; - return precvframe->u.hdr.rx_tail; -} - -struct sta_info; - -void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); -sint r8712_recvframe_chkmic(struct _adapter *adapter, - union recv_frame *precvframe); -union recv_frame *r8712_decryptor(struct _adapter *adapter, - union recv_frame *precv_frame); -union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *adapter, - union recv_frame *precv_frame); -int r8712_validate_recv_frame(struct _adapter *adapter, - union recv_frame *precv_frame); -union recv_frame *r8712_portctrl(struct _adapter *adapter, - union recv_frame *precv_frame); - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_rf.h b/drivers/staging/rtl8712/rtl871x_rf.h deleted file mode 100644 index 7d98921a48fa..000000000000 --- a/drivers/staging/rtl8712/rtl871x_rf.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_RF_H_ -#define __RTL871X_RF_H_ - -#include "rtl871x_cmd.h" -#include "rtl871x_mp_phy_regdef.h" - -#define OFDM_PHY 1 -#define MIXED_PHY 2 -#define CCK_PHY 3 -#define NumRates (13) -#define RTL8711_RF_MAX_SENS 6 -#define RTL8711_RF_DEF_SENS 4 -#define NUM_CHANNELS 15 - -struct regulatory_class { - u32 starting_freq; /*MHz, */ - u8 channel_set[NUM_CHANNELS]; - u8 channel_cck_power[NUM_CHANNELS]; /*dbm*/ - u8 channel_ofdm_power[NUM_CHANNELS];/*dbm*/ - u8 txpower_limit; /*dbm*/ - u8 channel_spacing; /*MHz*/ - u8 modem; -}; - -enum _REG_PREAMBLE_MODE { - PREAMBLE_LONG = 1, - PREAMBLE_AUTO = 2, - PREAMBLE_SHORT = 3, -}; - -enum { - RTL8712_RFC_1T = 0x10, - RTL8712_RFC_2T = 0x20, - RTL8712_RFC_1R = 0x01, - RTL8712_RFC_2R = 0x02, - RTL8712_RFC_1T1R = 0x11, - RTL8712_RFC_1T2R = 0x12, - RTL8712_RFC_TURBO = 0x92, - RTL8712_RFC_2T2R = 0x22 -}; - -#endif /*__RTL871X_RF_H_*/ diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c deleted file mode 100644 index e46a5dbc7b65..000000000000 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ /dev/null @@ -1,1386 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_security.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_SECURITY_C_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" - -/* =====WEP related===== */ - -struct arc4context { - u32 x; - u32 y; - u8 state[256]; -}; - -static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len) -{ - u32 t, u; - u32 keyindex; - u32 stateindex; - u8 *state; - u32 counter; - - state = parc4ctx->state; - parc4ctx->x = 0; - parc4ctx->y = 0; - for (counter = 0; counter < 256; counter++) - state[counter] = (u8)counter; - keyindex = 0; - stateindex = 0; - for (counter = 0; counter < 256; counter++) { - t = state[counter]; - stateindex = (stateindex + key[keyindex] + t) & 0xff; - u = state[stateindex]; - state[stateindex] = (u8)t; - state[counter] = (u8)u; - if (++keyindex >= key_len) - keyindex = 0; - } -} - -static u32 arcfour_byte(struct arc4context *parc4ctx) -{ - u32 x; - u32 y; - u32 sx, sy; - u8 *state; - - state = parc4ctx->state; - x = (parc4ctx->x + 1) & 0xff; - sx = state[x]; - y = (sx + parc4ctx->y) & 0xff; - sy = state[y]; - parc4ctx->x = x; - parc4ctx->y = y; - state[y] = (u8)sx; - state[x] = (u8)sy; - return state[(sx + sy) & 0xff]; -} - -static void arcfour_encrypt(struct arc4context *parc4ctx, - u8 *dest, u8 *src, u32 len) -{ - u32 i; - - for (i = 0; i < len; i++) - dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx); -} - -static sint bcrc32initialized; -static u32 crc32_table[256]; - -static u8 crc32_reverseBit(u8 data) -{ - return ((u8)(data << 7) & 0x80) | ((data << 5) & 0x40) | ((data << 3) - & 0x20) | ((data << 1) & 0x10) | ((data >> 1) & 0x08) | - ((data >> 3) & 0x04) | ((data >> 5) & 0x02) | ((data >> 7) & - 0x01); -} - -static void crc32_init(void) -{ - sint i, j; - u32 c; - u8 *p = (u8 *)&c, *p1; - u8 k; - - if (bcrc32initialized == 1) - return; - - for (i = 0; i < 256; ++i) { - k = crc32_reverseBit((u8)i); - for (c = ((u32)k) << 24, j = 8; j > 0; --j) - c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY_BE : (c << 1); - p1 = (u8 *)&crc32_table[i]; - p1[0] = crc32_reverseBit(p[3]); - p1[1] = crc32_reverseBit(p[2]); - p1[2] = crc32_reverseBit(p[1]); - p1[3] = crc32_reverseBit(p[0]); - } - bcrc32initialized = 1; -} - -static u32 getcrc32(u8 *buf, u32 len) -{ - u8 *p; - u32 crc; - - if (!bcrc32initialized) - crc32_init(); - crc = 0xffffffff; /* preload shift register, per CRC-32 spec */ - for (p = buf; len > 0; ++p, --len) - crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8); - return ~crc; /* transmit complement, per CRC-32 spec */ -} - -/* - * Need to consider the fragment situation - */ -void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) -{ /* exclude ICV */ - unsigned char crc[4]; - struct arc4context mycontext; - u32 curfragnum, length, keylength, pki; - u8 *pframe, *payload, *iv; /*,*wepkey*/ - u8 wepkey[16]; - struct pkt_attrib *pattrib = &((struct xmit_frame *) - pxmitframe)->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) - return; - pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; - /*start to encrypt each fragment*/ - if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) { - pki = psecuritypriv->PrivacyKeyIndex; - keylength = psecuritypriv->DefKeylen[pki]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - iv = pframe + pattrib->hdrlen; - memcpy(&wepkey[0], iv, 3); - memcpy(&wepkey[3], &psecuritypriv->DefKey[ - psecuritypriv->PrivacyKeyIndex].skey[0], - keylength); - payload = pframe + pattrib->iv_len + pattrib->hdrlen; - if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32(getcrc32( - payload, length)); - arcfour_init(&mycontext, wepkey, 3 + keylength); - arcfour_encrypt(&mycontext, payload, payload, - length); - arcfour_encrypt(&mycontext, payload + length, - crc, 4); - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32(getcrc32( - payload, length)); - arcfour_init(&mycontext, wepkey, 3 + keylength); - arcfour_encrypt(&mycontext, payload, payload, - length); - arcfour_encrypt(&mycontext, payload + length, - crc, 4); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((addr_t)(pframe)); - } - } - } -} - -void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe) -{ - /* exclude ICV */ - u8 crc[4]; - struct arc4context mycontext; - u32 length, keylength; - u8 *pframe, *payload, *iv, wepkey[16]; - u8 keyindex; - struct rx_pkt_attrib *prxattrib = &(((union recv_frame *) - precvframe)->u.hdr.attrib); - struct security_priv *psecuritypriv = &padapter->securitypriv; - - pframe = (unsigned char *)((union recv_frame *)precvframe)-> - u.hdr.rx_data; - /* start to decrypt recvframe */ - if ((prxattrib->encrypt == _WEP40_) || (prxattrib->encrypt == - _WEP104_)) { - iv = pframe + prxattrib->hdrlen; - keyindex = (iv[3] & 0x3); - keylength = psecuritypriv->DefKeylen[keyindex]; - memcpy(&wepkey[0], iv, 3); - memcpy(&wepkey[3], &psecuritypriv->DefKey[ - psecuritypriv->PrivacyKeyIndex].skey[0], - keylength); - length = ((union recv_frame *)precvframe)-> - u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len; - payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; - /* decrypt payload include icv */ - arcfour_init(&mycontext, wepkey, 3 + keylength); - arcfour_encrypt(&mycontext, payload, payload, length); - /* calculate icv and compare the icv */ - *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4)); - } -} - -/* 3 =====TKIP related===== */ - -static u32 secmicgetuint32(u8 *p) -/* Convert from Byte[] to Us4Byte32 in a portable way */ -{ - s32 i; - u32 res = 0; - - for (i = 0; i < 4; i++) - res |= ((u32)(*p++)) << (8 * i); - return res; -} - -static void secmicputuint32(u8 *p, u32 val) -/* Convert from Us4Byte32 to Byte[] in a portable way */ -{ - long i; - - for (i = 0; i < 4; i++) { - *p++ = (u8)(val & 0xff); - val >>= 8; - } -} - -static void secmicclear(struct mic_data *pmicdata) -{ -/* Reset the state to the empty message. */ - pmicdata->L = pmicdata->K0; - pmicdata->R = pmicdata->K1; - pmicdata->nBytesInM = 0; - pmicdata->M = 0; -} - -void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key) -{ - /* Set the key */ - pmicdata->K0 = secmicgetuint32(key); - pmicdata->K1 = secmicgetuint32(key + 4); - /* and reset the message */ - secmicclear(pmicdata); -} - -static void secmicappendbyte(struct mic_data *pmicdata, u8 b) -{ - /* Append the byte to our word-sized buffer */ - pmicdata->M |= ((u32)b) << (8 * pmicdata->nBytesInM); - pmicdata->nBytesInM++; - /* Process the word if it is full. */ - if (pmicdata->nBytesInM >= 4) { - pmicdata->L ^= pmicdata->M; - pmicdata->R ^= ROL32(pmicdata->L, 17); - pmicdata->L += pmicdata->R; - pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | - ((pmicdata->L & 0x00ff00ff) << 8); - pmicdata->L += pmicdata->R; - pmicdata->R ^= ROL32(pmicdata->L, 3); - pmicdata->L += pmicdata->R; - pmicdata->R ^= ROR32(pmicdata->L, 2); - pmicdata->L += pmicdata->R; - /* Clear the buffer */ - pmicdata->M = 0; - pmicdata->nBytesInM = 0; - } -} - -void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nbytes) -{ - /* This is simple */ - while (nbytes > 0) { - secmicappendbyte(pmicdata, *src++); - nbytes--; - } -} - -void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst) -{ - /* Append the minimum padding */ - secmicappendbyte(pmicdata, 0x5a); - secmicappendbyte(pmicdata, 0); - secmicappendbyte(pmicdata, 0); - secmicappendbyte(pmicdata, 0); - secmicappendbyte(pmicdata, 0); - /* and then zeroes until the length is a multiple of 4 */ - while (pmicdata->nBytesInM != 0) - secmicappendbyte(pmicdata, 0); - /* The appendByte function has already computed the result. */ - secmicputuint32(dst, pmicdata->L); - secmicputuint32(dst + 4, pmicdata->R); - /* Reset to the empty message. */ - secmicclear(pmicdata); -} - -void seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_code, - u8 pri) -{ - - struct mic_data micdata; - u8 priority[4] = {0x0, 0x0, 0x0, 0x0}; - - r8712_secmicsetkey(&micdata, key); - priority[0] = pri; - /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ - if (header[1] & 1) { /* ToDS==1 */ - r8712_secmicappend(&micdata, &header[16], 6); /* DA */ - if (header[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, &header[24], 6); - else - r8712_secmicappend(&micdata, &header[10], 6); - } else { /* ToDS==0 */ - r8712_secmicappend(&micdata, &header[4], 6); /* DA */ - if (header[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, &header[16], 6); - else - r8712_secmicappend(&micdata, &header[10], 6); - } - r8712_secmicappend(&micdata, &priority[0], 4); - r8712_secmicappend(&micdata, data, data_len); - r8712_secgetmic(&micdata, mic_code); -} - -/* macros for extraction/creation of unsigned char/unsigned short values */ -#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15)) -#define Lo8(v16) ((u8)((v16) & 0x00FF)) -#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF)) -#define Lo16(v32) ((u16)((v32) & 0xFFFF)) -#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF)) -#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8)) - -/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */ -#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)]) - -/* S-box lookup: 16 bits --> 16 bits */ -#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)]) - -/* fixed algorithm "parameters" */ -#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */ -#define TA_SIZE 6 /* 48-bit transmitter address */ -#define TK_SIZE 16 /* 128-bit temporal key */ -#define P1K_SIZE 10 /* 80-bit Phase1 key */ -#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */ - -/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */ -static const unsigned short Sbox1[2][256] = {/* Sbox for hash (can be in ROM) */ - { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, - }, - { /* second half is unsigned char-reversed version of first! */ - 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491, - 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC, - 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB, - 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B, - 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83, - 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A, - 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F, - 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA, - 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B, - 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713, - 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6, - 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85, - 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411, - 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B, - 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1, - 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF, - 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E, - 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6, - 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B, - 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD, - 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8, - 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2, - 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049, - 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810, - 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197, - 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F, - 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C, - 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927, - 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733, - 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5, - 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0, - 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C, - } -}; - -/* - ********************************************************************** - * Routine: Phase 1 -- generate P1K, given TA, TK, IV32 - * - * Inputs: - * tk[] = temporal key [128 bits] - * ta[] = transmitter's MAC address [ 48 bits] - * iv32 = upper 32 bits of IV [ 32 bits] - * Output: - * p1k[] = Phase 1 key [ 80 bits] - * - * Note: - * This function only needs to be called every 2**16 packets, - * although in theory it could be called every packet. - * - ********************************************************************** - */ -static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32) -{ - sint i; - - /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */ - p1k[0] = Lo16(iv32); - p1k[1] = Hi16(iv32); - p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */ - p1k[3] = Mk16(ta[3], ta[2]); - p1k[4] = Mk16(ta[5], ta[4]); - /* Now compute an unbalanced Feistel cipher with 80-bit block */ - /* size on the 80-bit block P1K[], using the 128-bit key TK[] */ - for (i = 0; i < PHASE1_LOOP_CNT; i++) { /* Each add is mod 2**16 */ - p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0)); - p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2)); - p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4)); - p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6)); - p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0)); - p1k[4] += (unsigned short)i; /* avoid "slide attacks" */ - } -} - -/* - ********************************************************************** - * Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16 - * - * Inputs: - * tk[] = Temporal key [128 bits] - * p1k[] = Phase 1 output key [ 80 bits] - * iv16 = low 16 bits of IV counter [ 16 bits] - * Output: - * rc4key[] = the key used to encrypt the packet [128 bits] - * - * Note: - * The value {TA,IV32,IV16} for Phase1/Phase2 must be unique - * across all packets using the same key TK value. Then, for a - * given value of TK[], this TKIP48 construction guarantees that - * the final RC4KEY value is unique across all packets. - * - * Suggested implementation optimization: if PPK[] is "overlaid" - * appropriately on RC4KEY[], there is no need for the final - * for loop below that copies the PPK[] result into RC4KEY[]. - * - ********************************************************************** - */ -static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16) -{ - sint i; - u16 PPK[6]; /* temporary key for mixing */ - - /* Note: all adds in the PPK[] equations below are mod 2**16 */ - for (i = 0; i < 5; i++) - PPK[i] = p1k[i]; /* first, copy P1K to PPK */ - PPK[5] = p1k[4] + iv16; /* next, add in IV16 */ - /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */ - PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */ - PPK[1] += _S_(PPK[0] ^ TK16(1)); - PPK[2] += _S_(PPK[1] ^ TK16(2)); - PPK[3] += _S_(PPK[2] ^ TK16(3)); - PPK[4] += _S_(PPK[3] ^ TK16(4)); - PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */ - /* Final sweep: bijective, "linear". Rotates kill LSB correlations */ - PPK[0] += RotR1(PPK[5] ^ TK16(6)); - PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */ - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - /* Note: At this point, for a given key TK[0..15], the 96-bit output */ - /* value PPK[0..5] is guaranteed to be unique, as a function */ - /* of the 96-bit "input" value {TA,IV32,IV16}. That is, P1K */ - /* is now a keyed permutation of {TA,IV32,IV16}. */ - /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */ - rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */ - rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */ - rc4key[2] = Lo8(iv16); - rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1); - /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */ - for (i = 0; i < 6; i++) { - rc4key[4 + 2 * i] = Lo8(PPK[i]); - rc4key[5 + 2 * i] = Hi8(PPK[i]); - } -} - -/*The hlen isn't include the IV*/ -u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) -{ /* exclude ICV */ - u16 pnl; - u32 pnh; - u8 rc4key[16]; - u8 ttkey[16]; - u8 crc[4]; - struct arc4context mycontext; - u32 curfragnum, length; - - u8 *pframe, *payload, *iv, *prwskey; - union pn48 txpn; - struct sta_info *stainfo; - struct pkt_attrib *pattrib = &((struct xmit_frame *)pxmitframe)->attrib; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u32 res = _SUCCESS; - - if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) - return _FAIL; - - pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; - /* 4 start to encrypt each fragment */ - if (pattrib->encrypt == _TKIP_) { - if (pattrib->psta) - stainfo = pattrib->psta; - else - stainfo = r8712_get_stainfo(&padapter->stapriv, - &pattrib->ra[0]); - if (stainfo) { - prwskey = &stainfo->x_UncstKey.skey[0]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - iv = pframe + pattrib->hdrlen; - payload = pframe + pattrib->iv_len + - pattrib->hdrlen; - GET_TKIP_PN(iv, txpn); - pnl = (u16)(txpn.val); - pnh = (u32)(txpn.val >> 16); - phase1((u16 *)&ttkey[0], prwskey, - &pattrib->ta[0], pnh); - phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], - pnl); - if ((curfragnum + 1) == pattrib->nr_frags) { - /* 4 the last fragment */ - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32( - getcrc32(payload, length)); - arcfour_init(&mycontext, rc4key, 16); - arcfour_encrypt(&mycontext, payload, - payload, length); - arcfour_encrypt(&mycontext, payload + - length, crc, 4); - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - *((__le32 *)crc) = cpu_to_le32(getcrc32( - payload, length)); - arcfour_init(&mycontext, rc4key, 16); - arcfour_encrypt(&mycontext, payload, - payload, length); - arcfour_encrypt(&mycontext, - payload + length, crc, - 4); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((addr_t)(pframe)); - } - } - } else { - res = _FAIL; - } - } - return res; -} - -/* The hlen doesn't include the IV */ -void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe) -{ /* exclude ICV */ - u16 pnl; - u32 pnh; - u8 rc4key[16]; - u8 ttkey[16]; - u8 crc[4]; - struct arc4context mycontext; - u32 length; - u8 *pframe, *payload, *iv, *prwskey, idx = 0; - union pn48 txpn; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &((union recv_frame *) - precvframe)->u.hdr.attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - pframe = (unsigned char *)((union recv_frame *) - precvframe)->u.hdr.rx_data; - /* 4 start to decrypt recvframe */ - if (prxattrib->encrypt == _TKIP_) { - stainfo = r8712_get_stainfo(&padapter->stapriv, - &prxattrib->ta[0]); - if (stainfo) { - iv = pframe + prxattrib->hdrlen; - payload = pframe + prxattrib->iv_len + - prxattrib->hdrlen; - length = ((union recv_frame *)precvframe)-> - u.hdr.len - prxattrib->hdrlen - - prxattrib->iv_len; - if (is_multicast_ether_addr(prxattrib->ra)) { - idx = iv[3]; - prwskey = &psecuritypriv->XGrpKey[ - ((idx >> 6) & 0x3) - 1].skey[0]; - if (!psecuritypriv->binstallGrpkey) - return; - } else { - prwskey = &stainfo->x_UncstKey.skey[0]; - } - GET_TKIP_PN(iv, txpn); - pnl = (u16)(txpn.val); - pnh = (u32)(txpn.val >> 16); - phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], - pnh); - phase2(&rc4key[0], prwskey, (unsigned short *) - &ttkey[0], pnl); - /* 4 decrypt payload include icv */ - arcfour_init(&mycontext, rc4key, 16); - arcfour_encrypt(&mycontext, payload, payload, length); - *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, - length - 4)); - } - } -} - -/* 3 =====AES related===== */ - -#define MAX_MSG_SIZE 2048 -/*****************************/ -/******** SBOX Table *********/ -/*****************************/ - -static const u8 sbox_table[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -/****************************************/ -/* aes128k128d() */ -/* Performs a 128 bit AES encrypt with */ -/* 128 bit data. */ -/****************************************/ -static void xor_128(u8 *a, u8 *b, u8 *out) -{ - sint i; - - for (i = 0; i < 16; i++) - out[i] = a[i] ^ b[i]; -} - -static void xor_32(u8 *a, u8 *b, u8 *out) -{ - sint i; - - for (i = 0; i < 4; i++) - out[i] = a[i] ^ b[i]; -} - -static u8 sbox(u8 a) -{ - return sbox_table[(sint)a]; -} - -static void next_key(u8 *key, sint round) -{ - u8 rcon; - u8 sbox_key[4]; - static const u8 rcon_table[12] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x36, 0x36 - }; - - sbox_key[0] = sbox(key[13]); - sbox_key[1] = sbox(key[14]); - sbox_key[2] = sbox(key[15]); - sbox_key[3] = sbox(key[12]); - rcon = rcon_table[round]; - xor_32(&key[0], sbox_key, &key[0]); - key[0] = key[0] ^ rcon; - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -static void byte_sub(u8 *in, u8 *out) -{ - sint i; - - for (i = 0; i < 16; i++) - out[i] = sbox(in[i]); -} - -static void shift_row(u8 *in, u8 *out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -static void mix_column(u8 *in, u8 *out) -{ - sint i; - u8 add1b[4]; - u8 add1bf7[4]; - u8 rotl[4]; - u8 swap_halves[4]; - u8 andf7[4]; - u8 rotr[4]; - u8 temp[4]; - u8 tempb[4]; - - for (i = 0; i < 4; i++) { - if ((in[i] & 0x80) == 0x80) - add1b[i] = 0x1b; - else - add1b[i] = 0x00; - } - swap_halves[0] = in[2]; /* Swap halves */ - swap_halves[1] = in[3]; - swap_halves[2] = in[0]; - swap_halves[3] = in[1]; - rotl[0] = in[3]; /* Rotate left 8 bits */ - rotl[1] = in[0]; - rotl[2] = in[1]; - rotl[3] = in[2]; - andf7[0] = in[0] & 0x7f; - andf7[1] = in[1] & 0x7f; - andf7[2] = in[2] & 0x7f; - andf7[3] = in[3] & 0x7f; - for (i = 3; i > 0; i--) { /* logical shift left 1 bit */ - andf7[i] = andf7[i] << 1; - if ((andf7[i - 1] & 0x80) == 0x80) - andf7[i] = (andf7[i] | 0x01); - } - andf7[0] = andf7[0] << 1; - andf7[0] = andf7[0] & 0xfe; - xor_32(add1b, andf7, add1bf7); - xor_32(in, add1bf7, rotr); - temp[0] = rotr[0]; /* Rotate right 8 bits */ - rotr[0] = rotr[1]; - rotr[1] = rotr[2]; - rotr[2] = rotr[3]; - rotr[3] = temp[0]; - xor_32(add1bf7, rotr, temp); - xor_32(swap_halves, rotl, tempb); - xor_32(temp, tempb, out); -} - -static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext) -{ - sint round; - sint i; - u8 intermediatea[16]; - u8 intermediateb[16]; - u8 round_key[16]; - - for (i = 0; i < 16; i++) - round_key[i] = key[i]; - for (round = 0; round < 11; round++) { - if (round == 0) { - xor_128(round_key, data, ciphertext); - next_key(round_key, round); - } else if (round == 10) { - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - xor_128(intermediateb, round_key, ciphertext); - } else { /* 1 - 9 */ - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - mix_column(&intermediateb[0], &intermediatea[0]); - mix_column(&intermediateb[4], &intermediatea[4]); - mix_column(&intermediateb[8], &intermediatea[8]); - mix_column(&intermediateb[12], &intermediatea[12]); - xor_128(intermediatea, round_key, ciphertext); - next_key(round_key, round); - } - } -} - -/************************************************/ -/* construct_mic_iv() */ -/* Builds the MIC IV from header fields and PN */ -/************************************************/ -static void construct_mic_iv(u8 *mic_iv, sint qc_exists, sint a4_exists, - u8 *mpdu, uint payload_length, u8 *pn_vector) -{ - sint i; - - mic_iv[0] = 0x59; - if (qc_exists && a4_exists) - mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ - if (qc_exists && !a4_exists) - mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ - if (!qc_exists) - mic_iv[1] = 0x00; - for (i = 2; i < 8; i++) - mic_iv[i] = mpdu[i + 8]; - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ - mic_iv[14] = (unsigned char)(payload_length / 256); - mic_iv[15] = (unsigned char)(payload_length % 256); -} - -/************************************************/ -/* construct_mic_header1() */ -/* Builds the first MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu) -{ - mic_header1[0] = (u8)((header_length - 2) / 256); - mic_header1[1] = (u8)((header_length - 2) % 256); - mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ - /* Mute retry, more data and pwr mgt bits */ - mic_header1[3] = mpdu[1] & 0xc7; - mic_header1[4] = mpdu[4]; /* A1 */ - mic_header1[5] = mpdu[5]; - mic_header1[6] = mpdu[6]; - mic_header1[7] = mpdu[7]; - mic_header1[8] = mpdu[8]; - mic_header1[9] = mpdu[9]; - mic_header1[10] = mpdu[10]; /* A2 */ - mic_header1[11] = mpdu[11]; - mic_header1[12] = mpdu[12]; - mic_header1[13] = mpdu[13]; - mic_header1[14] = mpdu[14]; - mic_header1[15] = mpdu[15]; -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists, - sint qc_exists) -{ - sint i; - - for (i = 0; i < 16; i++) - mic_header2[i] = 0x00; - mic_header2[0] = mpdu[16]; /* A3 */ - mic_header2[1] = mpdu[17]; - mic_header2[2] = mpdu[18]; - mic_header2[3] = mpdu[19]; - mic_header2[4] = mpdu[20]; - mic_header2[5] = mpdu[21]; - mic_header2[6] = 0x00; - mic_header2[7] = 0x00; /* mpdu[23]; */ - if (!qc_exists && a4_exists) - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - if (qc_exists && !a4_exists) { - mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ - mic_header2[9] = mpdu[25] & 0x00; - } - if (qc_exists && a4_exists) { - for (i = 0; i < 6; i++) - mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ - mic_header2[14] = mpdu[30] & 0x0f; - mic_header2[15] = mpdu[31] & 0x00; - } -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ -static void construct_ctr_preload(u8 *ctr_preload, - sint a4_exists, sint qc_exists, - u8 *mpdu, u8 *pn_vector, sint c) -{ - sint i; - - for (i = 0; i < 16; i++) - ctr_preload[i] = 0x00; - i = 0; - ctr_preload[0] = 0x01; /* flag */ - if (qc_exists && a4_exists) - ctr_preload[1] = mpdu[30] & 0x0f; - if (qc_exists && !a4_exists) - ctr_preload[1] = mpdu[24] & 0x0f; - for (i = 2; i < 8; i++) - ctr_preload[i] = mpdu[i + 8]; - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[13 - i]; - ctr_preload[14] = (unsigned char)(c / 256); /* Ctr */ - ctr_preload[15] = (unsigned char)(c % 256); -} - -/************************************/ -/* bitwise_xor() */ -/* A 128 bit, bitwise exclusive or */ -/************************************/ -static void bitwise_xor(u8 *ina, u8 *inb, u8 *out) -{ - sint i; - - for (i = 0; i < 16; i++) - out[i] = ina[i] ^ inb[i]; -} - -static void aes_cipher(u8 *key, uint hdrlen, - u8 *pframe, uint plen) -{ - uint qc_exists, a4_exists, i, j, payload_remainder; - uint num_blocks, payload_index; - - u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; - - /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; - u8 mic[8]; - u16 frtype = GetFrameType(pframe); - u16 frsubtype = GetFrameSubType(pframe); - - frsubtype >>= 4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) - a4_exists = 0; - else - a4_exists = 1; - - if ((frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACK)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFPOLL)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACKPOLL))) { - qc_exists = 1; - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - } else if ((frsubtype == 0x08) || - (frsubtype == 0x09) || - (frsubtype == 0x0a) || - (frsubtype == 0x0b)) { - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - qc_exists = 1; - } else { - qc_exists = 0; - } - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector); - construct_mic_header1(mic_header1, hdrlen, pframe); - construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists); - payload_remainder = plen % 16; - num_blocks = plen / 16; - /* Find start of payload */ - payload_index = hdrlen + 8; - /* Calculate MIC */ - aes128k128d(key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - for (i = 0; i < num_blocks; i++) { - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - payload_index += 16; - aes128k128d(key, chain_buffer, aes_out); - } - /* Add on the final payload block if it needs padding */ - if (payload_remainder > 0) { - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index++]; - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - } - for (j = 0; j < 8; j++) - mic[j] = aes_out[j]; - /* Insert MIC into payload */ - for (j = 0; j < 8; j++) - pframe[payload_index + j] = mic[j]; - payload_index = hdrlen + 8; - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - pframe[payload_index++] = chain_buffer[j]; - } - if (payload_remainder > 0) { /* If short final block, then pad it,*/ - /* encrypt and copy unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, num_blocks + 1); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - pframe[payload_index++] = chain_buffer[j]; - } - /* Encrypt the MIC */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, 0); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < 8; j++) - padded_buffer[j] = pframe[j + hdrlen + 8 + plen]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < 8; j++) - pframe[payload_index++] = chain_buffer[j]; -} - -u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) -{ /* exclude ICV */ - /* Intermediate Buffers */ - sint curfragnum, length; - u8 *pframe, *prwskey; - struct sta_info *stainfo; - struct pkt_attrib *pattrib = &((struct xmit_frame *) - pxmitframe)->attrib; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u32 res = _SUCCESS; - - if (((struct xmit_frame *)pxmitframe)->buf_addr == NULL) - return _FAIL; - pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; - /* 4 start to encrypt each fragment */ - if (pattrib->encrypt == _AES_) { - if (pattrib->psta) - stainfo = pattrib->psta; - else - stainfo = r8712_get_stainfo(&padapter->stapriv, - &pattrib->ra[0]); - if (stainfo) { - prwskey = &stainfo->x_UncstKey.skey[0]; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - aes_cipher(prwskey, pattrib->hdrlen, - pframe, length); - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - - pattrib->iv_len - - pattrib->icv_len; - aes_cipher(prwskey, pattrib->hdrlen, - pframe, length); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((addr_t)(pframe)); - } - } - } else { - res = _FAIL; - } - } - return res; -} - -static void aes_decipher(u8 *key, uint hdrlen, - u8 *pframe, uint plen) -{ - static u8 message[MAX_MSG_SIZE]; - uint qc_exists, a4_exists, i, j, payload_remainder; - uint num_blocks, payload_index; - u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; - /* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; - u8 mic[8]; - uint frtype = GetFrameType(pframe); - uint frsubtype = GetFrameSubType(pframe); - - frsubtype >>= 4; - memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - /* start to decrypt the payload */ - /*(plen including llc, payload and mic) */ - num_blocks = (plen - 8) / 16; - payload_remainder = (plen - 8) % 16; - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) - a4_exists = 0; - else - a4_exists = 1; - if ((frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACK)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFPOLL)) || - (frtype == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA_CFACKPOLL))) { - qc_exists = 1; - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - } else if ((frsubtype == 0x08) || - (frsubtype == 0x09) || - (frsubtype == 0x0a) || - (frsubtype == 0x0b)) { - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - qc_exists = 1; - } else { - qc_exists = 0; - } - /* now, decrypt pframe with hdrlen offset and plen long */ - payload_index = hdrlen + 8; /* 8 is for extiv */ - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &pframe[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - pframe[payload_index++] = chain_buffer[j]; - } - if (payload_remainder > 0) { /* If short final block, pad it,*/ - /* encrypt it and copy the unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - pframe, pn_vector, num_blocks + 1); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = pframe[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - pframe[payload_index++] = chain_buffer[j]; - } - /* start to calculate the mic */ - memcpy((void *)message, pframe, (hdrlen + plen + 8)); - pn_vector[0] = pframe[hdrlen]; - pn_vector[1] = pframe[hdrlen + 1]; - pn_vector[2] = pframe[hdrlen + 4]; - pn_vector[3] = pframe[hdrlen + 5]; - pn_vector[4] = pframe[hdrlen + 6]; - pn_vector[5] = pframe[hdrlen + 7]; - construct_mic_iv(mic_iv, qc_exists, a4_exists, message, plen - 8, - pn_vector); - construct_mic_header1(mic_header1, hdrlen, message); - construct_mic_header2(mic_header2, message, a4_exists, qc_exists); - payload_remainder = (plen - 8) % 16; - num_blocks = (plen - 8) / 16; - /* Find start of payload */ - payload_index = hdrlen + 8; - /* Calculate MIC */ - aes128k128d(key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - for (i = 0; i < num_blocks; i++) { - bitwise_xor(aes_out, &message[payload_index], chain_buffer); - payload_index += 16; - aes128k128d(key, chain_buffer, aes_out); - } - /* Add on the final payload block if it needs padding */ - if (payload_remainder > 0) { - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = message[payload_index++]; - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(key, chain_buffer, aes_out); - } - for (j = 0; j < 8; j++) - mic[j] = aes_out[j]; - /* Insert MIC into payload */ - for (j = 0; j < 8; j++) - message[payload_index + j] = mic[j]; - payload_index = hdrlen + 8; - for (i = 0; i < num_blocks; i++) { - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - message, pn_vector, i + 1); - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, &message[payload_index], chain_buffer); - for (j = 0; j < 16; j++) - message[payload_index++] = chain_buffer[j]; - } - if (payload_remainder > 0) { /* If short final block, pad it,*/ - /* encrypt and copy unpadded part back */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, - message, pn_vector, num_blocks + 1); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < payload_remainder; j++) - padded_buffer[j] = message[payload_index + j]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < payload_remainder; j++) - message[payload_index++] = chain_buffer[j]; - } - /* Encrypt the MIC */ - construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message, - pn_vector, 0); - for (j = 0; j < 16; j++) - padded_buffer[j] = 0x00; - for (j = 0; j < 8; j++) - padded_buffer[j] = message[j + hdrlen + plen]; - aes128k128d(key, ctr_preload, aes_out); - bitwise_xor(aes_out, padded_buffer, chain_buffer); - for (j = 0; j < 8; j++) - message[payload_index++] = chain_buffer[j]; - /* compare the mic */ -} - -void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) -{ /* exclude ICV */ - /* Intermediate Buffers */ - sint length; - u8 *pframe, *prwskey, *iv, idx; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &((union recv_frame *) - precvframe)->u.hdr.attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - - pframe = (unsigned char *)((union recv_frame *)precvframe)-> - u.hdr.rx_data; - /* 4 start to encrypt each fragment */ - if (prxattrib->encrypt == _AES_) { - stainfo = r8712_get_stainfo(&padapter->stapriv, - &prxattrib->ta[0]); - if (stainfo) { - if (is_multicast_ether_addr(prxattrib->ra)) { - iv = pframe + prxattrib->hdrlen; - idx = iv[3]; - prwskey = &psecuritypriv->XGrpKey[ - ((idx >> 6) & 0x3) - 1].skey[0]; - if (!psecuritypriv->binstallGrpkey) - return; - - } else { - prwskey = &stainfo->x_UncstKey.skey[0]; - } - length = ((union recv_frame *)precvframe)-> - u.hdr.len - prxattrib->hdrlen - - prxattrib->iv_len; - aes_decipher(prwskey, prxattrib->hdrlen, pframe, - length); - } - } -} - -void r8712_use_tkipkey_handler(struct timer_list *t) -{ - struct _adapter *padapter = - from_timer(padapter, t, securitypriv.tkip_timer); - - padapter->securitypriv.busetkipkey = true; -} diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h deleted file mode 100644 index 8461b7f05359..000000000000 --- a/drivers/staging/rtl8712/rtl871x_security.h +++ /dev/null @@ -1,218 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __RTL871X_SECURITY_H_ -#define __RTL871X_SECURITY_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -#define _NO_PRIVACY_ 0x0 -#define _WEP40_ 0x1 -#define _TKIP_ 0x2 -#define _TKIP_WTMIC_ 0x3 -#define _AES_ 0x4 -#define _WEP104_ 0x5 - -#define _WPA_IE_ID_ 0xdd -#define _WPA2_IE_ID_ 0x30 - -#ifndef Ndis802_11AuthModeWPA2 -#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) -#endif - -#ifndef Ndis802_11AuthModeWPA2PSK -#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) -#endif - -union pn48 { - u64 val; -#if defined(__BIG_ENDIAN) - struct { - u8 TSC7; - u8 TSC6; - u8 TSC5; - u8 TSC4; - u8 TSC3; - u8 TSC2; - u8 TSC1; - u8 TSC0; - } _byte_; -#else - struct { - u8 TSC0; - u8 TSC1; - u8 TSC2; - u8 TSC3; - u8 TSC4; - u8 TSC5; - u8 TSC6; - u8 TSC7; - } _byte_; -#endif -}; - -union Keytype { - u8 skey[16]; - u32 lkey[4]; -}; - -struct RT_PMKID_LIST { - u8 bUsed; - u8 Bssid[6]; - u8 PMKID[16]; - u8 SsidBuf[33]; - u8 *ssid_octet; - u16 ssid_length; -}; - -struct security_priv { - u32 AuthAlgrthm; /* 802.11 auth, could be open, shared, - * 8021x and authswitch - */ - u32 PrivacyAlgrthm; /* This specify the privacy for shared - * auth. algorithm. - */ - u32 PrivacyKeyIndex; /* this is only valid for legendary - * wep, 0~3 for key id. - */ - union Keytype DefKey[4]; /* this is only valid for def. key */ - u32 DefKeylen[4]; - u32 XGrpPrivacy; /* This specify the privacy algthm. - * used for Grp key - */ - u32 XGrpKeyid; /* key id used for Grp Key */ - union Keytype XGrpKey[2]; /* 802.1x Group Key, for - * inx0 and inx1 - */ - union Keytype XGrptxmickey[2]; - union Keytype XGrprxmickey[2]; - union pn48 Grptxpn; /* PN48 used for Grp Key xmit. */ - union pn48 Grprxpn; /* PN48 used for Grp Key recv. */ - u8 wps_hw_pbc_pressed;/*for hw pbc pressed*/ - u8 wps_phase;/*for wps*/ - u8 wps_ie[MAX_WPA_IE_LEN << 2]; - int wps_ie_len; - u8 binstallGrpkey; - u8 busetkipkey; - struct timer_list tkip_timer; - u8 bcheck_grpkey; - u8 bgrpkey_handshake; - s32 sw_encrypt; /* from registry_priv */ - s32 sw_decrypt; /* from registry_priv */ - s32 hw_decrypted; /* if the rx packets is hw_decrypted==false, - * it means the hw has not been ready. - */ - u32 ndisauthtype; /* keeps the auth_type & enc_status from upper - * layer ioctl(wpa_supplicant or wzc) - */ - u32 ndisencryptstatus; - struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */ - struct NDIS_802_11_WEP ndiswep; - u8 assoc_info[600]; - u8 szofcapability[256]; /* for wpa2 usage */ - u8 oidassociation[512]; /* for wpa/wpa2 usage */ - u8 authenticator_ie[256]; /* store ap security information element */ - u8 supplicant_ie[256]; /* store sta security information element */ - /* for tkip countermeasure */ - u32 last_mic_err_time; - u8 btkip_countermeasure; - u8 btkip_wait_report; - u32 btkip_countermeasure_time; - /*------------------------------------------------------------------- - * For WPA2 Pre-Authentication. - *------------------------------------------------------------------ - **/ - struct RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE]; - u8 PMKIDIndex; -}; - -#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst) \ -do { \ - switch (psecuritypriv->AuthAlgrthm) { \ - case 0: \ - case 1: \ - case 3: \ - encry_algo = (u8)psecuritypriv->PrivacyAlgrthm; \ - break; \ - case 2: \ - if (bmcst) \ - encry_algo = (u8)psecuritypriv->XGrpPrivacy; \ - else \ - encry_algo = (u8)psta->XPrivacy; \ - break; \ - } \ -} while (0) -#define SET_ICE_IV_LEN(iv_len, icv_len, encrypt)\ -do {\ - switch (encrypt) { \ - case _WEP40_: \ - case _WEP104_: \ - iv_len = 4; \ - icv_len = 4; \ - break; \ - case _TKIP_: \ - iv_len = 8; \ - icv_len = 4; \ - break; \ - case _AES_: \ - iv_len = 8; \ - icv_len = 8; \ - break; \ - default: \ - iv_len = 0; \ - icv_len = 0; \ - break; \ - } \ -} while (0) -#define GET_TKIP_PN(iv, txpn) \ -do {\ - txpn._byte_.TSC0 = iv[2];\ - txpn._byte_.TSC1 = iv[0];\ - txpn._byte_.TSC2 = iv[4];\ - txpn._byte_.TSC3 = iv[5];\ - txpn._byte_.TSC4 = iv[6];\ - txpn._byte_.TSC5 = iv[7];\ -} while (0) - -#define ROL32(A, n) (((A) << (n)) | (((A) >> (32 - (n))) & ((1UL << (n)) - 1))) -#define ROR32(A, n) ROL32((A), 32 - (n)) - -struct mic_data { - u32 K0, K1; /* Key */ - u32 L, R; /* Current state */ - u32 M; /* Message accumulator (single word) */ - u32 nBytesInM; /* # bytes in M */ -}; - -void seccalctkipmic( - u8 *key, - u8 *header, - u8 *data, - u32 data_len, - u8 *Miccode, - u8 priority); - -void r8712_secmicsetkey(struct mic_data *pmicdata, u8 *key); -void r8712_secmicappend(struct mic_data *pmicdata, u8 *src, u32 nBytes); -void r8712_secgetmic(struct mic_data *pmicdata, u8 *dst); -u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe); -u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe); -void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe); -void r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe); -void r8712_use_tkipkey_handler(struct timer_list *t); - -#endif /*__RTL871X_SECURITY_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c deleted file mode 100644 index 2c806a0105bf..000000000000 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ /dev/null @@ -1,263 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_sta_mgt.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_STA_MGT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "xmit_osdep.h" -#include "sta_info.h" - -static void _init_stainfo(struct sta_info *psta) -{ - memset((u8 *)psta, 0, sizeof(struct sta_info)); - spin_lock_init(&psta->lock); - INIT_LIST_HEAD(&psta->list); - INIT_LIST_HEAD(&psta->hash_list); - _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); - _r8712_init_sta_recv_priv(&psta->sta_recvpriv); - INIT_LIST_HEAD(&psta->asoc_list); - INIT_LIST_HEAD(&psta->auth_list); -} - -int _r8712_init_sta_priv(struct sta_priv *pstapriv) -{ - struct sta_info *psta; - s32 i; - - pstapriv->pallocated_stainfo_buf = kmalloc(sizeof(struct sta_info) * - NUM_STA + 4, GFP_ATOMIC); - if (!pstapriv->pallocated_stainfo_buf) - return -ENOMEM; - pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 - - ((addr_t)(pstapriv->pallocated_stainfo_buf) & 3); - _init_queue(&pstapriv->free_sta_queue); - spin_lock_init(&pstapriv->sta_hash_lock); - pstapriv->asoc_sta_count = 0; - _init_queue(&pstapriv->sleep_q); - _init_queue(&pstapriv->wakeup_q); - psta = (struct sta_info *)(pstapriv->pstainfo_buf); - for (i = 0; i < NUM_STA; i++) { - _init_stainfo(psta); - INIT_LIST_HEAD(&(pstapriv->sta_hash[i])); - list_add_tail(&psta->list, &pstapriv->free_sta_queue.queue); - psta++; - } - INIT_LIST_HEAD(&pstapriv->asoc_list); - INIT_LIST_HEAD(&pstapriv->auth_list); - return 0; -} - -/* this function is used to free the memory of lock || sema for all stainfos */ -static void mfree_all_stainfo(struct sta_priv *pstapriv) -{ - unsigned long irqL; - struct list_head *plist, *phead; - - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - phead = &pstapriv->free_sta_queue.queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) - plist = plist->next; - - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); -} - -void _r8712_free_sta_priv(struct sta_priv *pstapriv) -{ - if (pstapriv) { - /* be done before free sta_hash_lock */ - mfree_all_stainfo(pstapriv); - kfree(pstapriv->pallocated_stainfo_buf); - } -} - -struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) -{ - s32 index; - struct list_head *phash_list; - struct sta_info *psta; - struct __queue *pfree_sta_queue; - struct recv_reorder_ctrl *preorder_ctrl; - int i = 0; - u16 wRxSeqInitialValue = 0xffff; - unsigned long flags; - - pfree_sta_queue = &pstapriv->free_sta_queue; - spin_lock_irqsave(&pfree_sta_queue->lock, flags); - psta = list_first_entry_or_null(&pfree_sta_queue->queue, - struct sta_info, list); - if (psta) { - list_del_init(&psta->list); - _init_stainfo(psta); - memcpy(psta->hwaddr, hwaddr, ETH_ALEN); - index = wifi_mac_hash(hwaddr); - if (index >= NUM_STA) { - psta = NULL; - goto exit; - } - phash_list = &pstapriv->sta_hash[index]; - list_add_tail(&psta->hash_list, phash_list); - pstapriv->asoc_sta_count++; - -/* For the SMC router, the sequence number of first packet of WPS handshake - * will be 0. In this case, this packet will be dropped by recv_decache function - * if we use the 0x00 as the default value for tid_rxseq variable. So, we - * initialize the tid_rxseq variable as the 0xffff. - */ - for (i = 0; i < 16; i++) - memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], - &wRxSeqInitialValue, 2); - /* for A-MPDU Rx reordering buffer control */ - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - preorder_ctrl->padapter = pstapriv->padapter; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - preorder_ctrl->wsize_b = 64; - _init_queue(&preorder_ctrl->pending_recvframe_queue); - r8712_init_recv_timer(preorder_ctrl); - } - } -exit: - spin_unlock_irqrestore(&pfree_sta_queue->lock, flags); - return psta; -} - -/* using pstapriv->sta_hash_lock to protect */ -void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta) -{ - int i; - unsigned long irqL0; - struct __queue *pfree_sta_queue; - struct recv_reorder_ctrl *preorder_ctrl; - struct sta_xmit_priv *pstaxmitpriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct sta_priv *pstapriv = &padapter->stapriv; - - if (!psta) - return; - pfree_sta_queue = &pstapriv->free_sta_queue; - pstaxmitpriv = &psta->sta_xmitpriv; - spin_lock_irqsave(&(pxmitpriv->vo_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); - list_del_init(&(pstaxmitpriv->vo_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->vo_pending.lock), irqL0); - spin_lock_irqsave(&(pxmitpriv->vi_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); - list_del_init(&(pstaxmitpriv->vi_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->vi_pending.lock), irqL0); - spin_lock_irqsave(&(pxmitpriv->bk_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); - list_del_init(&(pstaxmitpriv->bk_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->bk_pending.lock), irqL0); - spin_lock_irqsave(&(pxmitpriv->be_pending.lock), irqL0); - r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending); - list_del_init(&(pstaxmitpriv->be_q.tx_pending)); - spin_unlock_irqrestore(&(pxmitpriv->be_pending.lock), irqL0); - list_del_init(&psta->hash_list); - pstapriv->asoc_sta_count--; - /* re-init sta_info; 20061114 */ - _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); - _r8712_init_sta_recv_priv(&psta->sta_recvpriv); - /* for A-MPDU Rx reordering buffer control, - * cancel reordering_ctrl_timer - */ - for (i = 0; i < 16; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - del_timer(&preorder_ctrl->reordering_ctrl_timer); - } - spin_lock(&(pfree_sta_queue->lock)); - /* insert into free_sta_queue; 20061114 */ - list_add_tail(&psta->list, &pfree_sta_queue->queue); - spin_unlock(&(pfree_sta_queue->lock)); -} - -/* free all stainfo which in sta_hash[all] */ -void r8712_free_all_stainfo(struct _adapter *padapter) -{ - unsigned long irqL; - struct list_head *plist, *phead; - s32 index; - struct sta_info *psta = NULL; - struct sta_priv *pstapriv = &padapter->stapriv; - struct sta_info *pbcmc_stainfo = r8712_get_bcmc_stainfo(padapter); - - if (pstapriv->asoc_sta_count == 1) - return; - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - for (index = 0; index < NUM_STA; index++) { - phead = &(pstapriv->sta_hash[index]); - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - psta = container_of(plist, - struct sta_info, hash_list); - plist = plist->next; - if (pbcmc_stainfo != psta) - r8712_free_stainfo(padapter, psta); - } - } - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); -} - -/* any station allocated can be searched by hash list */ -struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) -{ - unsigned long irqL; - struct list_head *plist, *phead; - struct sta_info *psta = NULL; - u32 index; - - if (!hwaddr) - return NULL; - index = wifi_mac_hash(hwaddr); - spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); - phead = &(pstapriv->sta_hash[index]); - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - psta = container_of(plist, struct sta_info, hash_list); - if ((!memcmp(psta->hwaddr, hwaddr, ETH_ALEN))) { - /* if found the matched address */ - break; - } - psta = NULL; - plist = plist->next; - } - spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); - return psta; -} - -void r8712_init_bcmc_stainfo(struct _adapter *padapter) -{ - unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - struct sta_priv *pstapriv = &padapter->stapriv; - - r8712_alloc_stainfo(pstapriv, bcast_addr); -} - -struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter) -{ - struct sta_priv *pstapriv = &padapter->stapriv; - u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - return r8712_get_stainfo(pstapriv, bc_addr); -} - -u8 r8712_access_ctrl(struct wlan_acl_pool *pacl_list, u8 *mac_addr) -{ - return true; -} diff --git a/drivers/staging/rtl8712/rtl871x_wlan_sme.h b/drivers/staging/rtl8712/rtl871x_wlan_sme.h deleted file mode 100644 index 97ea1451426c..000000000000 --- a/drivers/staging/rtl8712/rtl871x_wlan_sme.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_WLAN_SME_H_ -#define _RTL871X_WLAN_SME_H_ - -#define MSR_APMODE 0x0C -#define MSR_STAMODE 0x08 -#define MSR_ADHOCMODE 0x04 -#define MSR_NOLINKMODE 0x00 -#define _1M_RATE_ 0 -#define _2M_RATE_ 1 -#define _5M_RATE_ 2 -#define _11M_RATE_ 3 -#define _6M_RATE_ 4 -#define _9M_RATE_ 5 -#define _12M_RATE_ 6 -#define _18M_RATE_ 7 -#define _24M_RATE_ 8 -#define _36M_RATE_ 9 -#define _48M_RATE_ 10 -#define _54M_RATE_ 11 - -#endif - diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c deleted file mode 100644 index 6353dbe554d3..000000000000 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ /dev/null @@ -1,1059 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * rtl871x_xmit.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _RTL871X_XMIT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -#include -#include - -static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8}; -static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00}; -static void init_hwxmits(struct hw_xmit *phwxmit, sint entry); -static void alloc_hwxmits(struct _adapter *padapter); -static void free_hwxmits(struct _adapter *padapter); - -static void _init_txservq(struct tx_servq *ptxservq) -{ - INIT_LIST_HEAD(&ptxservq->tx_pending); - _init_queue(&ptxservq->sta_pending); - ptxservq->qcnt = 0; -} - -void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv) -{ - memset((unsigned char *)psta_xmitpriv, 0, - sizeof(struct sta_xmit_priv)); - spin_lock_init(&psta_xmitpriv->lock); - _init_txservq(&psta_xmitpriv->be_q); - _init_txservq(&psta_xmitpriv->bk_q); - _init_txservq(&psta_xmitpriv->vi_q); - _init_txservq(&psta_xmitpriv->vo_q); - INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz); - INIT_LIST_HEAD(&psta_xmitpriv->apsd); -} - -int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, - struct _adapter *padapter) -{ - sint i; - struct xmit_buf *pxmitbuf; - struct xmit_frame *pxframe; - int j; - - memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); - spin_lock_init(&pxmitpriv->lock); - /* - *Please insert all the queue initialization using _init_queue below - */ - pxmitpriv->adapter = padapter; - _init_queue(&pxmitpriv->be_pending); - _init_queue(&pxmitpriv->bk_pending); - _init_queue(&pxmitpriv->vi_pending); - _init_queue(&pxmitpriv->vo_pending); - _init_queue(&pxmitpriv->bm_pending); - _init_queue(&pxmitpriv->legacy_dz_queue); - _init_queue(&pxmitpriv->apsd_queue); - _init_queue(&pxmitpriv->free_xmit_queue); - /* - * Please allocate memory with sz = (struct xmit_frame) * NR_XMITFRAME, - * and initialize free_xmit_frame below. - * Please also apply free_txobj to link_up all the xmit_frames... - */ - pxmitpriv->pallocated_frame_buf = - kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4, - GFP_ATOMIC); - if (!pxmitpriv->pallocated_frame_buf) { - pxmitpriv->pxmit_frame_buf = NULL; - return -ENOMEM; - } - pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - - ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3); - pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf; - for (i = 0; i < NR_XMITFRAME; i++) { - INIT_LIST_HEAD(&(pxframe->list)); - pxframe->padapter = padapter; - pxframe->frame_tag = DATA_FRAMETAG; - pxframe->pkt = NULL; - pxframe->buf_addr = NULL; - pxframe->pxmitbuf = NULL; - list_add_tail(&(pxframe->list), - &(pxmitpriv->free_xmit_queue.queue)); - pxframe++; - } - pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME; - /* - * init xmit hw_txqueue - */ - _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX); - _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX); - pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; - pxmitpriv->txirp_cnt = 1; - /*per AC pending irp*/ - pxmitpriv->beq_cnt = 0; - pxmitpriv->bkq_cnt = 0; - pxmitpriv->viq_cnt = 0; - pxmitpriv->voq_cnt = 0; - /*init xmit_buf*/ - _init_queue(&pxmitpriv->free_xmitbuf_queue); - _init_queue(&pxmitpriv->pending_xmitbuf_queue); - pxmitpriv->pallocated_xmitbuf = - kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC); - if (!pxmitpriv->pallocated_xmitbuf) - goto clean_up_frame_buf; - pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - - ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3); - pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; - for (i = 0; i < NR_XMITBUFF; i++) { - INIT_LIST_HEAD(&pxmitbuf->list); - pxmitbuf->pallocated_buf = - kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC); - if (!pxmitbuf->pallocated_buf) { - j = 0; - goto clean_up_alloc_buf; - } - pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ - - ((addr_t) (pxmitbuf->pallocated_buf) & - (XMITBUF_ALIGN_SZ - 1)); - if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) { - j = 1; - goto clean_up_alloc_buf; - } - list_add_tail(&pxmitbuf->list, - &(pxmitpriv->free_xmitbuf_queue.queue)); - pxmitbuf++; - } - pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; - INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter); - alloc_hwxmits(padapter); - init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh); - return 0; - -clean_up_alloc_buf: - if (j) { - /* failure happened in r8712_xmit_resource_alloc() - * delete extra pxmitbuf->pallocated_buf - */ - kfree(pxmitbuf->pallocated_buf); - } - for (j = 0; j < i; j++) { - int k; - - pxmitbuf--; /* reset pointer */ - kfree(pxmitbuf->pallocated_buf); - for (k = 0; k < 8; k++) /* delete xmit urb's */ - usb_free_urb(pxmitbuf->pxmit_urb[k]); - } - kfree(pxmitpriv->pallocated_xmitbuf); - pxmitpriv->pallocated_xmitbuf = NULL; -clean_up_frame_buf: - kfree(pxmitpriv->pallocated_frame_buf); - pxmitpriv->pallocated_frame_buf = NULL; - return -ENOMEM; -} - -void _free_xmit_priv(struct xmit_priv *pxmitpriv) -{ - int i; - struct _adapter *padapter = pxmitpriv->adapter; - struct xmit_frame *pxmitframe = (struct xmit_frame *) - pxmitpriv->pxmit_frame_buf; - struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; - - if (!pxmitpriv->pxmit_frame_buf) - return; - for (i = 0; i < NR_XMITFRAME; i++) { - r8712_xmit_complete(padapter, pxmitframe); - pxmitframe++; - } - for (i = 0; i < NR_XMITBUFF; i++) { - r8712_xmit_resource_free(padapter, pxmitbuf); - kfree(pxmitbuf->pallocated_buf); - pxmitbuf++; - } - kfree(pxmitpriv->pallocated_frame_buf); - kfree(pxmitpriv->pallocated_xmitbuf); - free_hwxmits(padapter); -} - -int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, - struct pkt_attrib *pattrib) -{ - struct pkt_file pktfile; - struct sta_info *psta = NULL; - struct ethhdr etherhdr; - - struct tx_cmd txdesc; - - bool bmcast; - struct sta_priv *pstapriv = &padapter->stapriv; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - - _r8712_open_pktfile(pkt, &pktfile); - - _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN); - - pattrib->ether_type = ntohs(etherhdr.h_proto); - - /* - * If driver xmit ARP packet, driver can set ps mode to initial - * setting. It stands for getting DHCP or fix IP. - */ - if (pattrib->ether_type == 0x0806) { - if (padapter->pwrctrlpriv.pwr_mode != - padapter->registrypriv.power_mgnt) { - del_timer_sync(&pmlmepriv->dhcp_timer); - r8712_set_ps_mode(padapter, - padapter->registrypriv.power_mgnt, - padapter->registrypriv.smart_ps); - } - } - - memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN); - memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN); - pattrib->pctrl = 0; - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - /*firstly, filter packet not belongs to mp*/ - if (pattrib->ether_type != 0x8712) - return -EINVAL; - /* for mp storing the txcmd per packet, - * according to the info of txcmd to update pattrib - */ - /*get MP_TXDESC_SIZE bytes txcmd per packet*/ - _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE); - memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); - memcpy(pattrib->ta, pattrib->src, ETH_ALEN); - pattrib->pctrl = 1; - } - /* r8712_xmitframe_coalesce() overwrite this!*/ - pattrib->pktlen = pktfile.pkt_len; - if (pattrib->ether_type == ETH_P_IP) { - /* The following is for DHCP and ARP packet, we use cck1M to - * tx these packets and let LPS awake some time - * to prevent DHCP protocol fail - */ - u8 tmp[24]; - - _r8712_pktfile_read(&pktfile, &tmp[0], 24); - pattrib->dhcp_pkt = 0; - if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/ - if (pattrib->ether_type == ETH_P_IP) {/* IP header*/ - if (((tmp[21] == 68) && (tmp[23] == 67)) || - ((tmp[21] == 67) && (tmp[23] == 68))) { - /* 68 : UDP BOOTP client - * 67 : UDP BOOTP server - * Use low rate to send DHCP packet. - */ - pattrib->dhcp_pkt = 1; - } - } - } - } - bmcast = is_multicast_ether_addr(pattrib->ra); - /* get sta_info*/ - if (bmcast) { - psta = r8712_get_bcmc_stainfo(padapter); - pattrib->mac_id = 4; - } else { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - psta = r8712_get_stainfo(pstapriv, - get_bssid(pmlmepriv)); - pattrib->mac_id = 5; - } else { - psta = r8712_get_stainfo(pstapriv, pattrib->ra); - if (!psta) /* drop the pkt */ - return -ENOMEM; - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - pattrib->mac_id = 5; - else - pattrib->mac_id = psta->mac_id; - } - } - - if (psta) { - pattrib->psta = psta; - } else { - /* if we cannot get psta => drrp the pkt */ - return -ENOMEM; - } - - pattrib->ack_policy = 0; - /* get ether_hdr_len */ - pattrib->pkt_hdrlen = ETH_HLEN; - - if (pqospriv->qos_option) { - r8712_set_qos(&pktfile, pattrib); - } else { - pattrib->hdrlen = WLAN_HDR_A3_LEN; - pattrib->subtype = IEEE80211_FTYPE_DATA; - pattrib->priority = 0; - } - if (psta->ieee8021x_blocked) { - pattrib->encrypt = 0; - if ((pattrib->ether_type != 0x888e) && - !check_fwstate(pmlmepriv, WIFI_MP_STATE)) - return -EINVAL; - } else { - GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); - } - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - pattrib->iv_len = 4; - pattrib->icv_len = 4; - break; - case _TKIP_: - pattrib->iv_len = 8; - pattrib->icv_len = 4; - if (padapter->securitypriv.busetkipkey == _FAIL) - return -EINVAL; - break; - case _AES_: - pattrib->iv_len = 8; - pattrib->icv_len = 8; - break; - default: - pattrib->iv_len = 0; - pattrib->icv_len = 0; - break; - } - - if (pattrib->encrypt && - (padapter->securitypriv.sw_encrypt || - !psecuritypriv->hw_decrypted)) - pattrib->bswenc = true; - else - pattrib->bswenc = false; - /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite - * some settings above. - */ - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - pattrib->priority = - (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f; - return 0; -} - -static int xmitframe_addmic(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - u32 curfragnum, length; - u8 *pframe, *payload, mic[8]; - struct mic_data micdata; - struct sta_info *stainfo; - struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv); - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct security_priv *psecpriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u8 priority[4] = {}; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (pattrib->psta) - stainfo = pattrib->psta; - else - stainfo = r8712_get_stainfo(&padapter->stapriv, - &pattrib->ra[0]); - if (pattrib->encrypt == _TKIP_) { - /*encode mic code*/ - if (stainfo) { - u8 null_key[16] = {}; - - pframe = pxmitframe->buf_addr + TXDESC_OFFSET; - if (bmcst) { - if (!memcmp(psecpriv->XGrptxmickey - [psecpriv->XGrpKeyid].skey, - null_key, 16)) - return -ENOMEM; - /*start to calculate the mic code*/ - r8712_secmicsetkey(&micdata, - psecpriv->XGrptxmickey - [psecpriv->XGrpKeyid].skey); - } else { - if (!memcmp(&stainfo->tkiptxmickey.skey[0], - null_key, 16)) - return -ENOMEM; - /* start to calculate the mic code */ - r8712_secmicsetkey(&micdata, - &stainfo->tkiptxmickey.skey[0]); - } - if (pframe[1] & 1) { /* ToDS==1 */ - r8712_secmicappend(&micdata, - &pframe[16], 6); /*DA*/ - if (pframe[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, - &pframe[24], 6); - else - r8712_secmicappend(&micdata, - &pframe[10], 6); - } else { /* ToDS==0 */ - r8712_secmicappend(&micdata, - &pframe[4], 6); /* DA */ - if (pframe[1] & 2) /* From Ds==1 */ - r8712_secmicappend(&micdata, - &pframe[16], 6); - else - r8712_secmicappend(&micdata, - &pframe[10], 6); - } - if (pqospriv->qos_option == 1) - priority[0] = (u8)pxmitframe->attrib.priority; - r8712_secmicappend(&micdata, &priority[0], 4); - payload = pframe; - for (curfragnum = 0; curfragnum < pattrib->nr_frags; - curfragnum++) { - payload = (u8 *)RND4((addr_t)(payload)); - payload += pattrib->hdrlen + pattrib->iv_len; - if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - - pattrib->hdrlen - - pattrib->iv_len - - ((psecpriv->sw_encrypt) - ? pattrib->icv_len : 0); - r8712_secmicappend(&micdata, payload, - length); - payload = payload + length; - } else { - length = pxmitpriv->frag_len - - pattrib->hdrlen - pattrib->iv_len - - ((psecpriv->sw_encrypt) ? - pattrib->icv_len : 0); - r8712_secmicappend(&micdata, payload, - length); - payload = payload + length + - pattrib->icv_len; - } - } - r8712_secgetmic(&micdata, &(mic[0])); - /* add mic code and add the mic code length in - * last_txcmdsz - */ - memcpy(payload, &(mic[0]), 8); - pattrib->last_txcmdsz += 8; - payload = payload - pattrib->last_txcmdsz + 8; - } - } - return 0; -} - -static sint xmitframe_swencrypt(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - if (pattrib->bswenc) { - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - r8712_wep_encrypt(padapter, (u8 *)pxmitframe); - break; - case _TKIP_: - r8712_tkip_encrypt(padapter, (u8 *)pxmitframe); - break; - case _AES_: - r8712_aes_encrypt(padapter, (u8 *)pxmitframe); - break; - default: - break; - } - } - return _SUCCESS; -} - -static int make_wlanhdr(struct _adapter *padapter, u8 *hdr, - struct pkt_attrib *pattrib) -{ - u16 *qc; - - struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - __le16 *fctrl = &pwlanhdr->frame_control; - u8 *bssid; - - memset(hdr, 0, WLANHDR_OFFSET); - SetFrameSubType(fctrl, pattrib->subtype); - if (!(pattrib->subtype & IEEE80211_FTYPE_DATA)) - return 0; - - bssid = get_bssid(pmlmepriv); - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { - /* to_ds = 1, fr_ds = 0; */ - SetToDs(fctrl); - ether_addr_copy(pwlanhdr->addr1, bssid); - ether_addr_copy(pwlanhdr->addr2, pattrib->src); - ether_addr_copy(pwlanhdr->addr3, pattrib->dst); - } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - /* to_ds = 0, fr_ds = 1; */ - SetFrDs(fctrl); - ether_addr_copy(pwlanhdr->addr1, pattrib->dst); - ether_addr_copy(pwlanhdr->addr2, bssid); - ether_addr_copy(pwlanhdr->addr3, pattrib->src); - } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { - ether_addr_copy(pwlanhdr->addr1, pattrib->dst); - ether_addr_copy(pwlanhdr->addr2, pattrib->src); - ether_addr_copy(pwlanhdr->addr3, bssid); - } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - ether_addr_copy(pwlanhdr->addr1, pattrib->dst); - ether_addr_copy(pwlanhdr->addr2, pattrib->src); - ether_addr_copy(pwlanhdr->addr3, bssid); - } else { - return -EINVAL; - } - - if (pattrib->encrypt) - SetPrivacy(fctrl); - if (pqospriv->qos_option) { - qc = (unsigned short *)(hdr + pattrib->hdrlen - 2); - if (pattrib->priority) - SetPriority(qc, pattrib->priority); - SetAckpolicy(qc, pattrib->ack_policy); - } - /* TODO: fill HT Control Field */ - /* Update Seq Num will be handled by f/w */ - { - struct sta_info *psta; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (pattrib->psta) - psta = pattrib->psta; - else if (bmcst) - psta = r8712_get_bcmc_stainfo(padapter); - else - psta = r8712_get_stainfo(&padapter->stapriv, - pattrib->ra); - - if (psta) { - u16 *txtid = psta->sta_xmitpriv.txseq_tid; - - txtid[pattrib->priority]++; - txtid[pattrib->priority] &= 0xFFF; - pattrib->seqnum = txtid[pattrib->priority]; - SetSeqNum(hdr, pattrib->seqnum); - } - } - - return 0; -} - -static sint r8712_put_snap(u8 *data, u16 h_proto) -{ - struct ieee80211_snap_hdr *snap; - const u8 *oui; - - snap = (struct ieee80211_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); - return SNAP_SIZE + sizeof(u16); -} - -/* - * This sub-routine will perform all the following: - * 1. remove 802.3 header. - * 2. create wlan_header, based on the info in pxmitframe - * 3. append sta's iv/ext-iv - * 4. append LLC - * 5. move frag chunk from pframe to pxmitframe->mem - * 6. apply sw-encrypt, if necessary. - */ -sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, - struct xmit_frame *pxmitframe) -{ - struct pkt_file pktfile; - - sint frg_len, mpdu_len, llc_sz; - u32 mem_sz; - u8 frg_inx; - addr_t addr; - u8 *pframe, *mem_start, *ptxdesc; - struct sta_info *psta; - struct security_priv *psecpriv = &padapter->securitypriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - u8 *pbuf_start; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (!pattrib->psta) - return _FAIL; - psta = pattrib->psta; - if (!pxmitframe->buf_addr) - return _FAIL; - pbuf_start = pxmitframe->buf_addr; - ptxdesc = pbuf_start; - mem_start = pbuf_start + TXDESC_OFFSET; - if (make_wlanhdr(padapter, mem_start, pattrib)) - return _FAIL; - _r8712_open_pktfile(pkt, &pktfile); - _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen); - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { - /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */ - if (pattrib->ether_type == 0x8712) { - /* take care - update_txdesc overwrite this */ - _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE); - } - } - pattrib->pktlen = pktfile.pkt_len; - frg_inx = 0; - frg_len = pxmitpriv->frag_len - 4; - while (1) { - llc_sz = 0; - mpdu_len = frg_len; - pframe = mem_start; - SetMFrag(mem_start); - pframe += pattrib->hdrlen; - mpdu_len -= pattrib->hdrlen; - /* adding icv, if necessary...*/ - if (pattrib->iv_len) { - if (psta) { - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - WEP_IV(pattrib->iv, psta->txpn, - (u8)psecpriv->PrivacyKeyIndex); - break; - case _TKIP_: - if (bmcst) - TKIP_IV(pattrib->iv, - psta->txpn, - (u8)psecpriv->XGrpKeyid); - else - TKIP_IV(pattrib->iv, psta->txpn, - 0); - break; - case _AES_: - if (bmcst) - AES_IV(pattrib->iv, psta->txpn, - (u8)psecpriv->XGrpKeyid); - else - AES_IV(pattrib->iv, psta->txpn, - 0); - break; - } - } - memcpy(pframe, pattrib->iv, pattrib->iv_len); - pframe += pattrib->iv_len; - mpdu_len -= pattrib->iv_len; - } - if (frg_inx == 0) { - llc_sz = r8712_put_snap(pframe, pattrib->ether_type); - pframe += llc_sz; - mpdu_len -= llc_sz; - } - if ((pattrib->icv_len > 0) && (pattrib->bswenc)) - mpdu_len -= pattrib->icv_len; - if (bmcst) - mem_sz = _r8712_pktfile_read(&pktfile, pframe, - pattrib->pktlen); - else - mem_sz = _r8712_pktfile_read(&pktfile, pframe, - mpdu_len); - pframe += mem_sz; - if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { - memcpy(pframe, pattrib->icv, pattrib->icv_len); - pframe += pattrib->icv_len; - } - frg_inx++; - if (bmcst || r8712_endofpktfile(&pktfile)) { - pattrib->nr_frags = frg_inx; - pattrib->last_txcmdsz = pattrib->hdrlen + - pattrib->iv_len + - ((pattrib->nr_frags == 1) ? - llc_sz : 0) + - ((pattrib->bswenc) ? - pattrib->icv_len : 0) + mem_sz; - ClearMFrag(mem_start); - break; - } - addr = (addr_t)(pframe); - mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET; - memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen); - } - - if (xmitframe_addmic(padapter, pxmitframe)) - return _FAIL; - xmitframe_swencrypt(padapter, pxmitframe); - return _SUCCESS; -} - -void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len) -{ - uint protection; - u8 *perp; - uint erp_len; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct registry_priv *pregistrypriv = &padapter->registrypriv; - - switch (pxmitpriv->vcs_setting) { - case DISABLE_VCS: - pxmitpriv->vcs = NONE_VCS; - break; - case ENABLE_VCS: - break; - case AUTO_VCS: - default: - perp = r8712_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len); - if (!perp) { - pxmitpriv->vcs = NONE_VCS; - } else { - protection = (*(perp + 2)) & BIT(1); - if (protection) { - if (pregistrypriv->vcs_type == RTS_CTS) - pxmitpriv->vcs = RTS_CTS; - else - pxmitpriv->vcs = CTS_TO_SELF; - } else { - pxmitpriv->vcs = NONE_VCS; - } - } - break; - } -} - -struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv) -{ - unsigned long irqL; - struct xmit_buf *pxmitbuf; - struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; - - spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); - pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue, - struct xmit_buf, list); - if (pxmitbuf) { - list_del_init(&pxmitbuf->list); - pxmitpriv->free_xmitbuf_cnt--; - } - spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); - return pxmitbuf; -} - -void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) -{ - unsigned long irqL; - struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; - - if (!pxmitbuf) - return; - spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); - list_del_init(&pxmitbuf->list); - list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue); - pxmitpriv->free_xmitbuf_cnt++; - spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); -} - -/* - * Calling context: - * 1. OS_TXENTRY - * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack) - * - * If we turn on USE_RXTHREAD, then, no need for critical section. - * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... - * - * Must be very very cautious... - * - */ -struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv) -{ - /* - * Please remember to use all the osdep_service api, - * and lock/unlock or _enter/_exit critical to protect - * pfree_xmit_queue - */ - unsigned long irqL; - struct xmit_frame *pxframe; - struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; - - spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); - pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue, - struct xmit_frame, list); - if (pxframe) { - list_del_init(&pxframe->list); - pxmitpriv->free_xmitframe_cnt--; - pxframe->buf_addr = NULL; - pxframe->pxmitbuf = NULL; - pxframe->attrib.psta = NULL; - pxframe->pkt = NULL; - } - spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL); - return pxframe; -} - -void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe) -{ - unsigned long irqL; - struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; - struct _adapter *padapter = pxmitpriv->adapter; - - if (!pxmitframe) - return; - spin_lock_irqsave(&pfree_xmit_queue->lock, irqL); - list_del_init(&pxmitframe->list); - if (pxmitframe->pkt) - pxmitframe->pkt = NULL; - list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue); - pxmitpriv->free_xmitframe_cnt++; - spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL); - if (netif_queue_stopped(padapter->pnetdev)) - netif_wake_queue(padapter->pnetdev); -} - -void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe) -{ - if (!pxmitframe) - return; - if (pxmitframe->frame_tag == DATA_FRAMETAG) - r8712_free_xmitframe(pxmitpriv, pxmitframe); -} - -void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv, - struct __queue *pframequeue) -{ - unsigned long irqL; - struct list_head *plist, *phead; - struct xmit_frame *pxmitframe; - - spin_lock_irqsave(&(pframequeue->lock), irqL); - phead = &pframequeue->queue; - plist = phead->next; - while (!end_of_queue_search(phead, plist)) { - pxmitframe = container_of(plist, struct xmit_frame, list); - plist = plist->next; - r8712_free_xmitframe(pxmitpriv, pxmitframe); - } - spin_unlock_irqrestore(&(pframequeue->lock), irqL); -} - -static inline struct tx_servq *get_sta_pending(struct _adapter *padapter, - struct __queue **ppstapending, - struct sta_info *psta, sint up) -{ - struct tx_servq *ptxservq; - struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; - - switch (up) { - case 1: - case 2: - ptxservq = &(psta->sta_xmitpriv.bk_q); - *ppstapending = &padapter->xmitpriv.bk_pending; - (phwxmits + 3)->accnt++; - break; - case 4: - case 5: - ptxservq = &(psta->sta_xmitpriv.vi_q); - *ppstapending = &padapter->xmitpriv.vi_pending; - (phwxmits + 1)->accnt++; - break; - case 6: - case 7: - ptxservq = &(psta->sta_xmitpriv.vo_q); - *ppstapending = &padapter->xmitpriv.vo_pending; - (phwxmits + 0)->accnt++; - break; - case 0: - case 3: - default: - ptxservq = &(psta->sta_xmitpriv.be_q); - *ppstapending = &padapter->xmitpriv.be_pending; - (phwxmits + 2)->accnt++; - break; - } - return ptxservq; -} - -/* - * Will enqueue pxmitframe to the proper queue, and indicate it - * to xx_pending list..... - */ -int r8712_xmit_classifier(struct _adapter *padapter, - struct xmit_frame *pxmitframe) -{ - unsigned long irqL0; - struct __queue *pstapending; - struct sta_info *psta; - struct tx_servq *ptxservq; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - bool bmcst = is_multicast_ether_addr(pattrib->ra); - - if (pattrib->psta) { - psta = pattrib->psta; - } else { - if (bmcst) { - psta = r8712_get_bcmc_stainfo(padapter); - } else { - if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) - psta = r8712_get_stainfo(pstapriv, - get_bssid(pmlmepriv)); - else - psta = r8712_get_stainfo(pstapriv, pattrib->ra); - } - } - if (!psta) - return -EINVAL; - ptxservq = get_sta_pending(padapter, &pstapending, - psta, pattrib->priority); - spin_lock_irqsave(&pstapending->lock, irqL0); - if (list_empty(&ptxservq->tx_pending)) - list_add_tail(&ptxservq->tx_pending, &pstapending->queue); - list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue); - ptxservq->qcnt++; - spin_unlock_irqrestore(&pstapending->lock, irqL0); - return 0; -} - -static void alloc_hwxmits(struct _adapter *padapter) -{ - struct hw_xmit *hwxmits; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; - pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry, - sizeof(struct hw_xmit), GFP_ATOMIC); - if (!pxmitpriv->hwxmits) - return; - hwxmits = pxmitpriv->hwxmits; - if (pxmitpriv->hwxmit_entry == 5) { - pxmitpriv->bmc_txqueue.head = 0; - hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; - hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; - pxmitpriv->vo_txqueue.head = 0; - hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; - hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; - pxmitpriv->vi_txqueue.head = 0; - hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; - hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; - pxmitpriv->bk_txqueue.head = 0; - hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; - pxmitpriv->be_txqueue.head = 0; - hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; - hwxmits[4] .sta_queue = &pxmitpriv->be_pending; - } else if (pxmitpriv->hwxmit_entry == 4) { - pxmitpriv->vo_txqueue.head = 0; - hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; - hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; - pxmitpriv->vi_txqueue.head = 0; - hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; - hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; - pxmitpriv->be_txqueue.head = 0; - hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; - hwxmits[2] .sta_queue = &pxmitpriv->be_pending; - pxmitpriv->bk_txqueue.head = 0; - hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; - hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; - } -} - -static void free_hwxmits(struct _adapter *padapter) -{ - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - kfree(pxmitpriv->hwxmits); -} - -static void init_hwxmits(struct hw_xmit *phwxmit, sint entry) -{ - sint i; - - for (i = 0; i < entry; i++, phwxmit++) { - spin_lock_init(&phwxmit->xmit_lock); - INIT_LIST_HEAD(&phwxmit->pending); - phwxmit->txcmdcnt = 0; - phwxmit->accnt = 0; - } -} - -void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe, - struct xmit_buf *pxmitbuf) -{ - /* pxmitbuf attach to pxmitframe */ - pxmitframe->pxmitbuf = pxmitbuf; - /* urb and irp connection */ - pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0]; - /* buffer addr assoc */ - pxmitframe->buf_addr = pxmitbuf->pbuf; - /* pxmitframe attach to pxmitbuf */ - pxmitbuf->priv_data = pxmitframe; -} - -/* - * tx_action == 0 == no frames to transmit - * tx_action > 0 ==> we have frames to transmit - * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough - * to transmit 1 frame. - */ - -int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe) -{ - unsigned long irqL; - int ret; - struct xmit_buf *pxmitbuf = NULL; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - r8712_do_queue_select(padapter, pattrib); - spin_lock_irqsave(&pxmitpriv->lock, irqL); - if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) { - ret = false; - r8712_xmit_enqueue(padapter, pxmitframe); - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - return ret; - } - pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv); - if (!pxmitbuf) { /*enqueue packet*/ - ret = false; - r8712_xmit_enqueue(padapter, pxmitframe); - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - } else { /*dump packet directly*/ - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - ret = true; - xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf); - r8712_xmit_direct(padapter, pxmitframe); - } - return ret; -} diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h deleted file mode 100644 index cdcbc87a3cad..000000000000 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ /dev/null @@ -1,288 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _RTL871X_XMIT_H_ -#define _RTL871X_XMIT_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "xmit_osdep.h" - -#ifdef CONFIG_R8712_TX_AGGR -#define MAX_XMITBUF_SZ (16384) -#else -#define MAX_XMITBUF_SZ (2048) -#endif - -#define NR_XMITBUFF (4) - -#ifdef CONFIG_R8712_TX_AGGR -#define AGGR_NR_HIGH_BOUND (4) /*(8) */ -#define AGGR_NR_LOW_BOUND (2) -#endif - -#define XMITBUF_ALIGN_SZ 512 -#define TX_GUARD_BAND 5 -#define MAX_NUMBLKS (1) - -/* Fixed the Big Endian bug when using the software driver encryption.*/ -#define WEP_IV(pattrib_iv, txpn, keyidx)\ -do { \ - pattrib_iv[0] = txpn._byte_.TSC0;\ - pattrib_iv[1] = txpn._byte_.TSC1;\ - pattrib_iv[2] = txpn._byte_.TSC2;\ - pattrib_iv[3] = ((keyidx & 0x3) << 6);\ - txpn.val = (txpn.val == 0xffffff) ? 0 : (txpn.val + 1);\ -} while (0) - -/* Fixed the Big Endian bug when doing the Tx. - * The Linksys WRH54G will check this. - */ -#define TKIP_IV(pattrib_iv, txpn, keyidx)\ -do { \ - pattrib_iv[0] = txpn._byte_.TSC1;\ - pattrib_iv[1] = (txpn._byte_.TSC1 | 0x20) & 0x7f;\ - pattrib_iv[2] = txpn._byte_.TSC0;\ - pattrib_iv[3] = BIT(5) | ((keyidx & 0x3) << 6);\ - pattrib_iv[4] = txpn._byte_.TSC2;\ - pattrib_iv[5] = txpn._byte_.TSC3;\ - pattrib_iv[6] = txpn._byte_.TSC4;\ - pattrib_iv[7] = txpn._byte_.TSC5;\ - txpn.val = txpn.val == 0xffffffffffffULL ? 0 : \ - (txpn.val + 1);\ -} while (0) - -#define AES_IV(pattrib_iv, txpn, keyidx)\ -do { \ - pattrib_iv[0] = txpn._byte_.TSC0;\ - pattrib_iv[1] = txpn._byte_.TSC1;\ - pattrib_iv[2] = 0;\ - pattrib_iv[3] = BIT(5) | ((keyidx & 0x3) << 6);\ - pattrib_iv[4] = txpn._byte_.TSC2;\ - pattrib_iv[5] = txpn._byte_.TSC3;\ - pattrib_iv[6] = txpn._byte_.TSC4;\ - pattrib_iv[7] = txpn._byte_.TSC5;\ - txpn.val = txpn.val == 0xffffffffffffULL ? 0 : \ - (txpn.val + 1);\ -} while (0) - -struct hw_xmit { - spinlock_t xmit_lock; - struct list_head pending; - struct __queue *sta_queue; - struct hw_txqueue *phwtxqueue; - sint txcmdcnt; - int accnt; -}; - -struct pkt_attrib { - u8 type; - u8 subtype; - u8 bswenc; - u8 dhcp_pkt; - - u16 seqnum; - u16 ether_type; - u16 pktlen; /* the original 802.3 pkt raw_data len - * (not include ether_hdr data) - */ - u16 last_txcmdsz; - - u8 pkt_hdrlen; /*the original 802.3 pkt header len*/ - u8 hdrlen; /*the WLAN Header Len*/ - u8 nr_frags; - u8 ack_policy; - u8 mac_id; - u8 vcs_mode; /*virtual carrier sense method*/ - u8 pctrl;/*per packet txdesc control enable*/ - u8 qsel; - - u8 priority; - u8 encrypt; /* when 0 indicate no encrypt. when non-zero, - * indicate the encrypt algorithm - */ - u8 iv_len; - u8 icv_len; - unsigned char iv[8]; - unsigned char icv[8]; - u8 dst[ETH_ALEN] __aligned(2); /* for ether_addr_copy */ - u8 src[ETH_ALEN]; - u8 ta[ETH_ALEN]; - u8 ra[ETH_ALEN]; - struct sta_info *psta; -}; - -#define WLANHDR_OFFSET 64 -#define DATA_FRAMETAG 0x01 -#define L2_FRAMETAG 0x02 -#define MGNT_FRAMETAG 0x03 -#define AMSDU_FRAMETAG 0x04 -#define EII_FRAMETAG 0x05 -#define IEEE8023_FRAMETAG 0x06 -#define MP_FRAMETAG 0x07 -#define TXAGG_FRAMETAG 0x08 - -struct xmit_buf { - struct list_head list; - - u8 *pallocated_buf; - u8 *pbuf; - void *priv_data; - struct urb *pxmit_urb[8]; - u32 aggr_nr; -}; - -struct xmit_frame { - struct list_head list; - struct pkt_attrib attrib; - _pkt *pkt; - int frame_tag; - struct _adapter *padapter; - u8 *buf_addr; - struct xmit_buf *pxmitbuf; - u8 *mem_addr; - u16 sz[8]; - struct urb *pxmit_urb[8]; - u8 bpending[8]; - u8 last[8]; -}; - -struct tx_servq { - struct list_head tx_pending; - struct __queue sta_pending; - int qcnt; -}; - -struct sta_xmit_priv { - spinlock_t lock; - sint option; - sint apsd_setting; /* When bit mask is on, the associated edca - * queue supports APSD. - */ - struct tx_servq be_q; /* priority == 0,3 */ - struct tx_servq bk_q; /* priority == 1,2*/ - struct tx_servq vi_q; /*priority == 4,5*/ - struct tx_servq vo_q; /*priority == 6,7*/ - struct list_head legacy_dz; - struct list_head apsd; - u16 txseq_tid[16]; - uint sta_tx_bytes; - u64 sta_tx_pkts; - uint sta_tx_fail; -}; - -struct hw_txqueue { - sint head; - sint tail; - sint free_sz; /* in units of 64 bytes */ - sint free_cmdsz; - sint txsz[8]; - uint ff_hwaddr; - uint cmd_hwaddr; - sint ac_tag; -}; - -struct xmit_priv { - spinlock_t lock; - struct __queue be_pending; - struct __queue bk_pending; - struct __queue vi_pending; - struct __queue vo_pending; - struct __queue bm_pending; - struct __queue legacy_dz_queue; - struct __queue apsd_queue; - u8 *pallocated_frame_buf; - u8 *pxmit_frame_buf; - uint free_xmitframe_cnt; - uint mapping_addr; - uint pkt_sz; - struct __queue free_xmit_queue; - struct hw_txqueue be_txqueue; - struct hw_txqueue bk_txqueue; - struct hw_txqueue vi_txqueue; - struct hw_txqueue vo_txqueue; - struct hw_txqueue bmc_txqueue; - uint frag_len; - struct _adapter *adapter; - u8 vcs_setting; - u8 vcs; - u8 vcs_type; - u16 rts_thresh; - uint tx_bytes; - u64 tx_pkts; - uint tx_drop; - struct hw_xmit *hwxmits; - u8 hwxmit_entry; - u8 txirp_cnt; - struct tasklet_struct xmit_tasklet; - struct work_struct xmit_pipe4_reset_wi; - struct work_struct xmit_pipe6_reset_wi; - struct work_struct xmit_piped_reset_wi; - /*per AC pending irp*/ - int beq_cnt; - int bkq_cnt; - int viq_cnt; - int voq_cnt; - struct __queue free_amsdu_xmit_queue; - u8 *pallocated_amsdu_frame_buf; - u8 *pxmit_amsdu_frame_buf; - uint free_amsdu_xmitframe_cnt; - struct __queue free_txagg_xmit_queue; - u8 *pallocated_txagg_frame_buf; - u8 *pxmit_txagg_frame_buf; - uint free_txagg_xmitframe_cnt; - int cmdseq; - struct __queue free_xmitbuf_queue; - struct __queue pending_xmitbuf_queue; - u8 *pallocated_xmitbuf; - u8 *pxmitbuf; - uint free_xmitbuf_cnt; -}; - -void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, - struct xmit_buf *pxmitbuf); -struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv); -void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len); -struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv); -void r8712_free_xmitframe(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe); -void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv, - struct __queue *pframequeue); -int r8712_xmit_classifier(struct _adapter *padapter, - struct xmit_frame *pxmitframe); -sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt, - struct xmit_frame *pxmitframe); -sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag); -void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); -int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt, - struct pkt_attrib *pattrib); -int r8712_txframes_sta_ac_pending(struct _adapter *padapter, - struct pkt_attrib *pattrib); -int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, - struct _adapter *padapter); -void _free_xmit_priv(struct xmit_priv *pxmitpriv); -void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv, - struct xmit_frame *pxmitframe); -int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe); -int r8712_xmit_enqueue(struct _adapter *padapter, - struct xmit_frame *pxmitframe); -void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe); -void r8712_xmit_bh(struct tasklet_struct *t); - -void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe, - struct xmit_buf *pxmitbuf); - -#include "rtl8712_xmit.h" - -#endif /*_RTL871X_XMIT_H_*/ - diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h deleted file mode 100644 index 6286c622475e..000000000000 --- a/drivers/staging/rtl8712/sta_info.h +++ /dev/null @@ -1,132 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __STA_INFO_H_ -#define __STA_INFO_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "wifi.h" - -#define NUM_STA 32 -#define NUM_ACL 64 - -/* if mode ==0, then the sta is allowed once the addr is hit. - * if mode ==1, then the sta is rejected once the addr is non-hit. - */ -struct wlan_acl_node { - struct list_head list; - u8 addr[ETH_ALEN]; - u8 mode; -}; - -struct wlan_acl_pool { - struct wlan_acl_node aclnode[NUM_ACL]; -}; - -struct stainfo_stats { - uint rx_pkts; - uint rx_bytes; - u64 tx_pkts; - uint tx_bytes; -}; - -struct sta_info { - spinlock_t lock; - struct list_head list; /*free_sta_queue*/ - struct list_head hash_list; /*sta_hash*/ - struct sta_xmit_priv sta_xmitpriv; - struct sta_recv_priv sta_recvpriv; - uint state; - uint aid; - uint mac_id; - uint qos_option; - u8 hwaddr[ETH_ALEN]; - uint ieee8021x_blocked; /*0: allowed, 1:blocked */ - uint XPrivacy; /*aes, tkip...*/ - union Keytype tkiptxmickey; - union Keytype tkiprxmickey; - union Keytype x_UncstKey; - union pn48 txpn; /* PN48 used for Unicast xmit.*/ - union pn48 rxpn; /* PN48 used for Unicast recv.*/ - u8 bssrateset[16]; - uint bssratelen; - s32 rssi; - s32 signal_quality; - struct stainfo_stats sta_stats; - /*for A-MPDU Rx reordering buffer control */ - struct recv_reorder_ctrl recvreorder_ctrl[16]; - struct ht_priv htpriv; - /* Notes: - * STA_Mode: - * curr_network(mlme_priv/security_priv/qos/ht) - * + sta_info: (STA & AP) CAP/INFO - * scan_q: AP CAP/INFO - * AP_Mode: - * curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO - * sta_info: (AP & STA) CAP/INFO - */ - struct list_head asoc_list; - struct list_head auth_list; - unsigned int expire_to; - unsigned int auth_seq; - unsigned int authalg; - unsigned char chg_txt[128]; - unsigned int tx_ra_bitmap; -}; - -struct sta_priv { - u8 *pallocated_stainfo_buf; - u8 *pstainfo_buf; - struct __queue free_sta_queue; - spinlock_t sta_hash_lock; - struct list_head sta_hash[NUM_STA]; - int asoc_sta_count; - struct __queue sleep_q; - struct __queue wakeup_q; - struct _adapter *padapter; - struct list_head asoc_list; - struct list_head auth_list; - unsigned int auth_to; /* sec, time to expire in authenticating. */ - unsigned int assoc_to; /* sec, time to expire before associating. */ - unsigned int expire_to; /* sec , time to expire after associated. */ -}; - -static inline u32 wifi_mac_hash(u8 *mac) -{ - u32 x; - - x = mac[0]; - x = (x << 2) ^ mac[1]; - x = (x << 2) ^ mac[2]; - x = (x << 2) ^ mac[3]; - x = (x << 2) ^ mac[4]; - x = (x << 2) ^ mac[5]; - x ^= x >> 8; - x = x & (NUM_STA - 1); - return x; -} - -int _r8712_init_sta_priv(struct sta_priv *pstapriv); -void _r8712_free_sta_priv(struct sta_priv *pstapriv); -struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, - u8 *hwaddr); -void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta); -void r8712_free_all_stainfo(struct _adapter *padapter); -struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); -void r8712_init_bcmc_stainfo(struct _adapter *padapter); -struct sta_info *r8712_get_bcmc_stainfo(struct _adapter *padapter); -u8 r8712_access_ctrl(struct wlan_acl_pool *pacl_list, u8 *mac_addr); - -#endif /* _STA_INFO_H_ */ - diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c deleted file mode 100644 index 313c569748e9..000000000000 --- a/drivers/staging/rtl8712/usb_halinit.c +++ /dev/null @@ -1,307 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_halinit.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_HAL_INIT_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "usb_ops.h" -#include "usb_osintf.h" - -u8 r8712_usb_hal_bus_init(struct _adapter *adapter) -{ - u8 val8 = 0; - u8 ret = _SUCCESS; - int PollingCnt = 20; - struct registry_priv *registrypriv = &adapter->registrypriv; - - if (registrypriv->chip_version == RTL8712_FPGA) { - val8 = 0x01; - /* switch to 80M clock */ - r8712_write8(adapter, SYS_CLKR, val8); - val8 = r8712_read8(adapter, SPS1_CTRL); - val8 = val8 | 0x01; - /* enable VSPS12 LDO Macro block */ - r8712_write8(adapter, SPS1_CTRL, val8); - val8 = r8712_read8(adapter, AFE_MISC); - val8 = val8 | 0x01; - /* Enable AFE Macro Block's Bandgap */ - r8712_write8(adapter, AFE_MISC, val8); - val8 = r8712_read8(adapter, LDOA15_CTRL); - val8 = val8 | 0x01; - /* enable LDOA15 block */ - r8712_write8(adapter, LDOA15_CTRL, val8); - val8 = r8712_read8(adapter, SPS1_CTRL); - val8 = val8 | 0x02; - /* Enable VSPS12_SW Macro Block */ - r8712_write8(adapter, SPS1_CTRL, val8); - val8 = r8712_read8(adapter, AFE_MISC); - val8 = val8 | 0x02; - /* Enable AFE Macro Block's Mbias */ - r8712_write8(adapter, AFE_MISC, val8); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - val8 = val8 | 0x08; - /* isolate PCIe Analog 1.2V to PCIe 3.3V and PCIE Digital */ - r8712_write8(adapter, SYS_ISO_CTRL + 1, val8); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - val8 = val8 & 0xEF; - /* attach AFE PLL to MACTOP/BB/PCIe Digital */ - r8712_write8(adapter, SYS_ISO_CTRL + 1, val8); - val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1); - val8 = val8 & 0xFB; - /* enable AFE clock */ - r8712_write8(adapter, AFE_XTAL_CTRL + 1, val8); - val8 = r8712_read8(adapter, AFE_PLL_CTRL); - val8 = val8 | 0x01; - /* Enable AFE PLL Macro Block */ - r8712_write8(adapter, AFE_PLL_CTRL, val8); - val8 = 0xEE; - /* release isolation AFE PLL & MD */ - r8712_write8(adapter, SYS_ISO_CTRL, val8); - val8 = r8712_read8(adapter, SYS_CLKR + 1); - val8 = val8 | 0x08; - /* enable MAC clock */ - r8712_write8(adapter, SYS_CLKR + 1, val8); - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - val8 = val8 | 0x08; - /* enable Core digital and enable IOREG R/W */ - r8712_write8(adapter, SYS_FUNC_EN + 1, val8); - val8 = val8 | 0x80; - /* enable REG_EN */ - r8712_write8(adapter, SYS_FUNC_EN + 1, val8); - val8 = r8712_read8(adapter, SYS_CLKR + 1); - val8 = (val8 | 0x80) & 0xBF; - /* switch the control path */ - r8712_write8(adapter, SYS_CLKR + 1, val8); - val8 = 0xFC; - r8712_write8(adapter, CR, val8); - val8 = 0x37; - r8712_write8(adapter, CR + 1, val8); - /* reduce EndPoint & init it */ - r8712_write8(adapter, 0x102500ab, r8712_read8(adapter, - 0x102500ab) | BIT(6) | BIT(7)); - /* consideration of power consumption - init */ - r8712_write8(adapter, 0x10250008, r8712_read8(adapter, - 0x10250008) & 0xfffffffb); - } else if (registrypriv->chip_version == RTL8712_1stCUT) { - /* Initialization for power on sequence, */ - r8712_write8(adapter, SPS0_CTRL + 1, 0x53); - r8712_write8(adapter, SPS0_CTRL, 0x57); - /* Enable AFE Macro Block's Bandgap and Enable AFE Macro - * Block's Mbias - */ - val8 = r8712_read8(adapter, AFE_MISC); - r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN | - AFE_MISC_MBEN)); - /* Enable LDOA15 block */ - val8 = r8712_read8(adapter, LDOA15_CTRL); - r8712_write8(adapter, LDOA15_CTRL, (val8 | LDA15_EN)); - val8 = r8712_read8(adapter, SPS1_CTRL); - r8712_write8(adapter, SPS1_CTRL, (val8 | SPS1_LDEN)); - msleep(20); - /* Enable Switch Regulator Block */ - val8 = r8712_read8(adapter, SPS1_CTRL); - r8712_write8(adapter, SPS1_CTRL, (val8 | SPS1_SWEN)); - r8712_write32(adapter, SPS1_CTRL, 0x00a7b267); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 | 0x08)); - /* Engineer Packet CP test Enable */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x20)); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 & 0x6F)); - /* Enable AFE clock */ - val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1); - r8712_write8(adapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb)); - /* Enable AFE PLL Macro Block */ - val8 = r8712_read8(adapter, AFE_PLL_CTRL); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11)); - /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ - val8 = r8712_read8(adapter, SYS_ISO_CTRL); - r8712_write8(adapter, SYS_ISO_CTRL, (val8 & 0xEE)); - /* Switch to 40M clock */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, val8 & (~SYS_CLKSEL)); - /* SSC Disable */ - val8 = r8712_read8(adapter, SYS_CLKR); - /* Enable MAC clock */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x18)); - /* Revised POS, */ - r8712_write8(adapter, PMC_FSM, 0x02); - /* Enable Core digital and enable IOREG R/W */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x08)); - /* Enable REG_EN */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x80)); - /* Switch the control path to FW */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF); - r8712_write8(adapter, CR, 0xFC); - r8712_write8(adapter, CR + 1, 0x37); - /* Fix the RX FIFO issue(usb error), */ - val8 = r8712_read8(adapter, 0x1025FE5c); - r8712_write8(adapter, 0x1025FE5c, (val8 | BIT(7))); - val8 = r8712_read8(adapter, 0x102500ab); - r8712_write8(adapter, 0x102500ab, (val8 | BIT(6) | BIT(7))); - /* For power save, used this in the bit file after 970621 */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, val8 & (~CPU_CLKSEL)); - } else if (registrypriv->chip_version == RTL8712_2ndCUT || - registrypriv->chip_version == RTL8712_3rdCUT) { - /* Initialization for power on sequence, - * E-Fuse leakage prevention sequence - */ - r8712_write8(adapter, 0x37, 0xb0); - msleep(20); - r8712_write8(adapter, 0x37, 0x30); - /* Set control path switch to HW control and reset Digital Core, - * CPU Core and MAC I/O to solve FW download fail when system - * from resume sate. - */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - if (val8 & 0x80) { - val8 &= 0x3f; - r8712_write8(adapter, SYS_CLKR + 1, val8); - } - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - val8 &= 0x73; - r8712_write8(adapter, SYS_FUNC_EN + 1, val8); - msleep(20); - /* Revised POS, */ - /* Enable AFE Macro Block's Bandgap and Enable AFE Macro - * Block's Mbias - */ - r8712_write8(adapter, SPS0_CTRL + 1, 0x53); - r8712_write8(adapter, SPS0_CTRL, 0x57); - val8 = r8712_read8(adapter, AFE_MISC); - /*Bandgap*/ - r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN)); - r8712_write8(adapter, AFE_MISC, (val8 | AFE_MISC_BGEN | - AFE_MISC_MBEN | AFE_MISC_I32_EN)); - /* Enable PLL Power (LDOA15V) */ - val8 = r8712_read8(adapter, LDOA15_CTRL); - r8712_write8(adapter, LDOA15_CTRL, (val8 | LDA15_EN)); - /* Enable LDOV12D block */ - val8 = r8712_read8(adapter, LDOV12D_CTRL); - r8712_write8(adapter, LDOV12D_CTRL, (val8 | LDV12_EN)); - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 | 0x08)); - /* Engineer Packet CP test Enable */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x20)); - /* Support 64k IMEM */ - val8 = r8712_read8(adapter, SYS_ISO_CTRL + 1); - r8712_write8(adapter, SYS_ISO_CTRL + 1, (val8 & 0x68)); - /* Enable AFE clock */ - val8 = r8712_read8(adapter, AFE_XTAL_CTRL + 1); - r8712_write8(adapter, AFE_XTAL_CTRL + 1, (val8 & 0xfb)); - /* Enable AFE PLL Macro Block */ - val8 = r8712_read8(adapter, AFE_PLL_CTRL); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11)); - /* Some sample will download fw failure. The clock will be - * stable with 500 us delay after reset the PLL - * TODO: When usleep is added to kernel, change next 3 - * udelay(500) to usleep(500) - */ - udelay(500); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x51)); - udelay(500); - r8712_write8(adapter, AFE_PLL_CTRL, (val8 | 0x11)); - udelay(500); - /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ - val8 = r8712_read8(adapter, SYS_ISO_CTRL); - r8712_write8(adapter, SYS_ISO_CTRL, (val8 & 0xEE)); - /* Switch to 40M clock */ - r8712_write8(adapter, SYS_CLKR, 0x00); - /* CPU Clock and 80M Clock SSC Disable to overcome FW download - * fail timing issue. - */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, (val8 | 0xa0)); - /* Enable MAC clock */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x18)); - /* Revised POS, */ - r8712_write8(adapter, PMC_FSM, 0x02); - /* Enable Core digital and enable IOREG R/W */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x08)); - /* Enable REG_EN */ - val8 = r8712_read8(adapter, SYS_FUNC_EN + 1); - r8712_write8(adapter, SYS_FUNC_EN + 1, (val8 | 0x80)); - /* Switch the control path to FW */ - val8 = r8712_read8(adapter, SYS_CLKR + 1); - r8712_write8(adapter, SYS_CLKR + 1, (val8 | 0x80) & 0xBF); - r8712_write8(adapter, CR, 0xFC); - r8712_write8(adapter, CR + 1, 0x37); - /* Fix the RX FIFO issue(usb error), 970410 */ - val8 = r8712_read8(adapter, 0x1025FE5c); - r8712_write8(adapter, 0x1025FE5c, (val8 | BIT(7))); - /* For power save, used this in the bit file after 970621 */ - val8 = r8712_read8(adapter, SYS_CLKR); - r8712_write8(adapter, SYS_CLKR, val8 & (~CPU_CLKSEL)); - /* Revised for 8051 ROM code wrong operation. */ - r8712_write8(adapter, 0x1025fe1c, 0x80); - /* To make sure that TxDMA can ready to download FW. - * We should reset TxDMA if IMEM RPT was not ready. - */ - do { - val8 = r8712_read8(adapter, TCR); - if ((val8 & _TXDMA_INIT_VALUE) == _TXDMA_INIT_VALUE) - break; - udelay(5); /* PlatformStallExecution(5); */ - } while (PollingCnt--); /* Delay 1ms */ - - if (PollingCnt <= 0) { - val8 = r8712_read8(adapter, CR); - r8712_write8(adapter, CR, val8 & (~_TXDMA_EN)); - udelay(2); /* PlatformStallExecution(2); */ - /* Reset TxDMA */ - r8712_write8(adapter, CR, val8 | _TXDMA_EN); - } - } else { - ret = _FAIL; - } - return ret; -} - -unsigned int r8712_usb_inirp_init(struct _adapter *adapter) -{ - u8 i; - struct recv_buf *recvbuf; - struct intf_hdl *intfhdl = &adapter->pio_queue->intf; - struct recv_priv *recvpriv = &(adapter->recvpriv); - - recvpriv->ff_hwaddr = RTL8712_DMA_RX0FF; /* mapping rx fifo address */ - /* issue Rx irp to receive data */ - recvbuf = (struct recv_buf *)recvpriv->precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - if (r8712_usb_read_port(intfhdl, recvpriv->ff_hwaddr, 0, - (unsigned char *)recvbuf) == false) - return _FAIL; - recvbuf++; - recvpriv->free_recv_buf_queue_cnt--; - } - return _SUCCESS; -} - -unsigned int r8712_usb_inirp_deinit(struct _adapter *adapter) -{ - r8712_usb_read_port_cancel(adapter); - return _SUCCESS; -} diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c deleted file mode 100644 index df05213f922f..000000000000 --- a/drivers/staging/rtl8712/usb_intf.c +++ /dev/null @@ -1,638 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_intf.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_INTF_C_ - -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "recv_osdep.h" -#include "xmit_osdep.h" -#include "rtl8712_efuse.h" -#include "usb_ops.h" -#include "usb_osintf.h" - -static struct usb_interface *pintf; - -static int r871xu_drv_init(struct usb_interface *pusb_intf, - const struct usb_device_id *pdid); - -static void r871xu_dev_remove(struct usb_interface *pusb_intf); - -static const struct usb_device_id rtl871x_usb_id_tbl[] = { -/* RTL8188SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8171)}, - {USB_DEVICE(0x0bda, 0x8173)}, - {USB_DEVICE(0x0bda, 0x8712)}, - {USB_DEVICE(0x0bda, 0x8713)}, - {USB_DEVICE(0x0bda, 0xC512)}, - /* Abocom */ - {USB_DEVICE(0x07B8, 0x8188)}, - /* ASUS */ - {USB_DEVICE(0x0B05, 0x1786)}, - {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ - /* Belkin */ - {USB_DEVICE(0x050D, 0x945A)}, - /* ISY IWL - Belkin clone */ - {USB_DEVICE(0x050D, 0x11F1)}, - /* Corega */ - {USB_DEVICE(0x07AA, 0x0047)}, - /* D-Link */ - {USB_DEVICE(0x2001, 0x3306)}, - {USB_DEVICE(0x07D1, 0x3306)}, /* 11n mode disable */ - /* Edimax */ - {USB_DEVICE(0x7392, 0x7611)}, - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9603)}, - /* Hawking */ - {USB_DEVICE(0x0E66, 0x0016)}, - /* Hercules */ - {USB_DEVICE(0x06F8, 0xE034)}, - {USB_DEVICE(0x06F8, 0xE032)}, - /* Logitec */ - {USB_DEVICE(0x0789, 0x0167)}, - /* PCI */ - {USB_DEVICE(0x2019, 0xAB28)}, - {USB_DEVICE(0x2019, 0xED16)}, - /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x0057)}, - {USB_DEVICE(0x0DF6, 0x0045)}, - {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ - {USB_DEVICE(0x0DF6, 0x004B)}, - {USB_DEVICE(0x0DF6, 0x005B)}, - {USB_DEVICE(0x0DF6, 0x005D)}, - {USB_DEVICE(0x0DF6, 0x0063)}, - /* Sweex */ - {USB_DEVICE(0x177F, 0x0154)}, - /* Thinkware */ - {USB_DEVICE(0x0BDA, 0x5077)}, - /* Toshiba */ - {USB_DEVICE(0x1690, 0x0752)}, - /* - */ - {USB_DEVICE(0x20F4, 0x646B)}, - {USB_DEVICE(0x083A, 0xC512)}, - {USB_DEVICE(0x25D4, 0x4CA1)}, - {USB_DEVICE(0x25D4, 0x4CAB)}, - -/* RTL8191SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8172)}, - {USB_DEVICE(0x0BDA, 0x8192)}, - /* Amigo */ - {USB_DEVICE(0x0EB0, 0x9061)}, - /* ASUS/EKB */ - {USB_DEVICE(0x13D3, 0x3323)}, - {USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3342)}, - /* ASUS/EKBLenovo */ - {USB_DEVICE(0x13D3, 0x3333)}, - {USB_DEVICE(0x13D3, 0x3334)}, - {USB_DEVICE(0x13D3, 0x3335)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3336)}, /* 11n mode disable */ - /* ASUS/Media BOX */ - {USB_DEVICE(0x13D3, 0x3309)}, - /* Belkin */ - {USB_DEVICE(0x050D, 0x815F)}, - /* D-Link */ - {USB_DEVICE(0x07D1, 0x3302)}, - {USB_DEVICE(0x07D1, 0x3300)}, - {USB_DEVICE(0x07D1, 0x3303)}, - /* Edimax */ - {USB_DEVICE(0x7392, 0x7612)}, - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9605)}, - /* Guillemot */ - {USB_DEVICE(0x06F8, 0xE031)}, - /* Hawking */ - {USB_DEVICE(0x0E66, 0x0015)}, - /* Mediao */ - {USB_DEVICE(0x13D3, 0x3306)}, - /* PCI */ - {USB_DEVICE(0x2019, 0xED18)}, - {USB_DEVICE(0x2019, 0x4901)}, - /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x0058)}, - {USB_DEVICE(0x0DF6, 0x0049)}, - {USB_DEVICE(0x0DF6, 0x004C)}, - {USB_DEVICE(0x0DF6, 0x006C)}, - {USB_DEVICE(0x0DF6, 0x0064)}, - /* Skyworth */ - {USB_DEVICE(0x14b2, 0x3300)}, - {USB_DEVICE(0x14b2, 0x3301)}, - {USB_DEVICE(0x14B2, 0x3302)}, - /* - */ - {USB_DEVICE(0x04F2, 0xAFF2)}, - {USB_DEVICE(0x04F2, 0xAFF5)}, - {USB_DEVICE(0x04F2, 0xAFF6)}, - {USB_DEVICE(0x13D3, 0x3339)}, - {USB_DEVICE(0x13D3, 0x3340)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3341)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3310)}, - {USB_DEVICE(0x13D3, 0x3325)}, - -/* RTL8192SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8174)}, - /* Belkin */ - {USB_DEVICE(0x050D, 0x845A)}, - /* Corega */ - {USB_DEVICE(0x07AA, 0x0051)}, - /* Edimax */ - {USB_DEVICE(0x7392, 0x7622)}, - /* NEC */ - {USB_DEVICE(0x0409, 0x02B6)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl); - -static struct specific_device_id specific_device_id_tbl[] = { - {.idVendor = 0x0b05, .idProduct = 0x1791, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x0df6, .idProduct = 0x0059, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3306, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13D3, .idProduct = 0x3311, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3335, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3336, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3340, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3341, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {} -}; - -struct drv_priv { - struct usb_driver r871xu_drv; - int drv_registered; -}; - -#ifdef CONFIG_PM -static int r871x_suspend(struct usb_interface *pusb_intf, pm_message_t state) -{ - struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct _adapter *padapter = netdev_priv(pnetdev); - - netdev_info(pnetdev, "Suspending...\n"); - padapter->suspended = true; - rtl871x_intf_stop(padapter); - if (pnetdev->netdev_ops->ndo_stop) - pnetdev->netdev_ops->ndo_stop(pnetdev); - mdelay(10); - netif_device_detach(pnetdev); - return 0; -} - -static void rtl871x_intf_resume(struct _adapter *padapter) -{ - if (padapter->dvobjpriv.inirp_init) - padapter->dvobjpriv.inirp_init(padapter); -} - -static int r871x_resume(struct usb_interface *pusb_intf) -{ - struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct _adapter *padapter = netdev_priv(pnetdev); - - netdev_info(pnetdev, "Resuming...\n"); - netif_device_attach(pnetdev); - if (pnetdev->netdev_ops->ndo_open) - pnetdev->netdev_ops->ndo_open(pnetdev); - padapter->suspended = false; - rtl871x_intf_resume(padapter); - return 0; -} -#endif - -static struct drv_priv drvpriv = { - .r871xu_drv.name = "r8712u", - .r871xu_drv.id_table = rtl871x_usb_id_tbl, - .r871xu_drv.probe = r871xu_drv_init, - .r871xu_drv.disconnect = r871xu_dev_remove, -#ifdef CONFIG_PM - .r871xu_drv.suspend = r871x_suspend, - .r871xu_drv.resume = r871x_resume, -#endif -}; - -static uint r8712_usb_dvobj_init(struct _adapter *padapter) -{ - uint status = _SUCCESS; - struct usb_host_interface *phost_iface; - struct usb_interface_descriptor *piface_desc; - struct dvobj_priv *pdvobjpriv = &padapter->dvobjpriv; - struct usb_device *pusbd = pdvobjpriv->pusbdev; - - pdvobjpriv->padapter = padapter; - padapter->eeprom_address_size = 6; - phost_iface = pintf->cur_altsetting; - piface_desc = &phost_iface->desc; - pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints; - if (pusbd->speed == USB_SPEED_HIGH) { - pdvobjpriv->ishighspeed = true; - dev_info(&pusbd->dev, "r8712u: USB_SPEED_HIGH with %d endpoints\n", - pdvobjpriv->nr_endpoint); - } else { - pdvobjpriv->ishighspeed = false; - dev_info(&pusbd->dev, "r8712u: USB_SPEED_LOW with %d endpoints\n", - pdvobjpriv->nr_endpoint); - } - if ((r8712_alloc_io_queue(padapter)) == _FAIL) - status = _FAIL; - return status; -} - -static void r8712_usb_dvobj_deinit(struct _adapter *padapter) -{ - r8712_free_io_queue(padapter); -} - -void rtl871x_intf_stop(struct _adapter *padapter) -{ - /*disable_hw_interrupt*/ - if (!padapter->surprise_removed) { - /*device still exists, so driver can do i/o operation - * TODO: - */ - } - - /* cancel in irp */ - if (padapter->dvobjpriv.inirp_deinit) - padapter->dvobjpriv.inirp_deinit(padapter); - /* cancel out irp */ - r8712_usb_write_port_cancel(padapter); - /* TODO:cancel other irps */ -} - -void r871x_dev_unload(struct _adapter *padapter) -{ - if (padapter->bup) { - /*s1.*/ - padapter->driver_stopped = true; - - /*s3.*/ - rtl871x_intf_stop(padapter); - - /*s4.*/ - r8712_stop_drv_threads(padapter); - - /*s5.*/ - if (!padapter->surprise_removed) { - padapter->hw_init_completed = false; - rtl8712_hal_deinit(padapter); - } - - padapter->bup = false; - } -} - -static void disable_ht_for_spec_devid(const struct usb_device_id *pdid, - struct _adapter *padapter) -{ - u16 vid, pid; - u32 flags; - int i; - int num = ARRAY_SIZE(specific_device_id_tbl); - - for (i = 0; i < num; i++) { - vid = specific_device_id_tbl[i].idVendor; - pid = specific_device_id_tbl[i].idProduct; - flags = specific_device_id_tbl[i].flags; - - if ((pdid->idVendor == vid) && (pdid->idProduct == pid) && - (flags & SPEC_DEV_ID_DISABLE_HT)) { - padapter->registrypriv.ht_enable = 0; - padapter->registrypriv.cbw40_enable = 0; - padapter->registrypriv.ampdu_enable = 0; - } - } -} - -static const struct device_type wlan_type = { - .name = "wlan", -}; - -/* - * drv_init() - a device potentially for us - * - * notes: drv_init() is called when the bus driver has located a card for us - * to support. We accept the new device by returning 0. - */ -static int r871xu_drv_init(struct usb_interface *pusb_intf, - const struct usb_device_id *pdid) -{ - uint status; - struct _adapter *padapter = NULL; - struct dvobj_priv *pdvobjpriv; - struct net_device *pnetdev; - struct usb_device *udev; - - /* In this probe function, O.S. will provide the usb interface pointer - * to driver. We have to increase the reference count of the usb device - * structure by using the usb_get_dev function. - */ - udev = interface_to_usbdev(pusb_intf); - usb_get_dev(udev); - pintf = pusb_intf; - /* step 1. */ - pnetdev = r8712_init_netdev(); - if (!pnetdev) - goto put_dev; - padapter = netdev_priv(pnetdev); - disable_ht_for_spec_devid(pdid, padapter); - pdvobjpriv = &padapter->dvobjpriv; - pdvobjpriv->padapter = padapter; - padapter->dvobjpriv.pusbdev = udev; - padapter->pusb_intf = pusb_intf; - usb_set_intfdata(pusb_intf, pnetdev); - SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); - pnetdev->dev.type = &wlan_type; - /* step 2. */ - padapter->dvobj_init = r8712_usb_dvobj_init; - padapter->dvobj_deinit = r8712_usb_dvobj_deinit; - padapter->halpriv.hal_bus_init = r8712_usb_hal_bus_init; - padapter->dvobjpriv.inirp_init = r8712_usb_inirp_init; - padapter->dvobjpriv.inirp_deinit = r8712_usb_inirp_deinit; - /* step 3. - * initialize the dvobj_priv - */ - - status = padapter->dvobj_init(padapter); - if (status != _SUCCESS) - goto free_netdev; - - /* step 4. */ - status = r8712_init_drv_sw(padapter); - if (status) - goto dvobj_deinit; - /* step 5. read efuse/eeprom data and get mac_addr */ - { - int i, offset; - u8 mac[6]; - u8 tmpU1b, AutoloadFail, eeprom_CustomerID; - u8 *pdata = padapter->eeprompriv.efuse_eeprom_data; - - tmpU1b = r8712_read8(padapter, EE_9346CR);/*CR9346*/ - - /* To check system boot selection.*/ - dev_info(&udev->dev, "r8712u: Boot from %s: Autoload %s\n", - (tmpU1b & _9356SEL) ? "EEPROM" : "EFUSE", - (tmpU1b & _EEPROM_EN) ? "OK" : "Failed"); - - /* To check autoload success or not.*/ - if (tmpU1b & _EEPROM_EN) { - AutoloadFail = true; - /* The following operations prevent Efuse leakage by - * turning on 2.5V. - */ - tmpU1b = r8712_read8(padapter, EFUSE_TEST + 3); - r8712_write8(padapter, EFUSE_TEST + 3, tmpU1b | 0x80); - msleep(20); - r8712_write8(padapter, EFUSE_TEST + 3, - (tmpU1b & (~BIT(7)))); - - /* Retrieve Chip version. - * Recognize IC version by Reg0x4 BIT15. - */ - tmpU1b = (u8)((r8712_read32(padapter, PMC_FSM) >> 15) & - 0x1F); - if (tmpU1b == 0x3) - padapter->registrypriv.chip_version = - RTL8712_3rdCUT; - else - padapter->registrypriv.chip_version = - (tmpU1b >> 1) + 1; - switch (padapter->registrypriv.chip_version) { - case RTL8712_1stCUT: - case RTL8712_2ndCUT: - case RTL8712_3rdCUT: - break; - default: - padapter->registrypriv.chip_version = - RTL8712_2ndCUT; - break; - } - - for (i = 0, offset = 0; i < 128; i += 8, offset++) - r8712_efuse_pg_packet_read(padapter, offset, - &pdata[i]); - - if (!r8712_initmac || !mac_pton(r8712_initmac, mac)) { - /* Use the mac address stored in the Efuse - * offset = 0x12 for usb in efuse - */ - ether_addr_copy(mac, &pdata[0x12]); - } - eeprom_CustomerID = pdata[0x52]; - switch (eeprom_CustomerID) { - case EEPROM_CID_ALPHA: - padapter->eeprompriv.CustomerID = - RT_CID_819x_ALPHA; - break; - case EEPROM_CID_CAMEO: - padapter->eeprompriv.CustomerID = - RT_CID_819x_CAMEO; - break; - case EEPROM_CID_SITECOM: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Sitecom; - break; - case EEPROM_CID_COREGA: - padapter->eeprompriv.CustomerID = - RT_CID_COREGA; - break; - case EEPROM_CID_Senao: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Senao; - break; - case EEPROM_CID_EDIMAX_BELKIN: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Edimax_Belkin; - break; - case EEPROM_CID_SERCOMM_BELKIN: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Sercomm_Belkin; - break; - case EEPROM_CID_WNC_COREGA: - padapter->eeprompriv.CustomerID = - RT_CID_819x_WNC_COREGA; - break; - case EEPROM_CID_WHQL: - break; - case EEPROM_CID_NetCore: - padapter->eeprompriv.CustomerID = - RT_CID_819x_Netcore; - break; - case EEPROM_CID_CAMEO1: - padapter->eeprompriv.CustomerID = - RT_CID_819x_CAMEO1; - break; - case EEPROM_CID_CLEVO: - padapter->eeprompriv.CustomerID = - RT_CID_819x_CLEVO; - break; - default: - padapter->eeprompriv.CustomerID = - RT_CID_DEFAULT; - break; - } - dev_info(&udev->dev, "r8712u: CustomerID = 0x%.4x\n", - padapter->eeprompriv.CustomerID); - /* Led mode */ - switch (padapter->eeprompriv.CustomerID) { - case RT_CID_DEFAULT: - case RT_CID_819x_ALPHA: - case RT_CID_819x_CAMEO: - padapter->ledpriv.LedStrategy = SW_LED_MODE1; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_Sitecom: - padapter->ledpriv.LedStrategy = SW_LED_MODE2; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_COREGA: - case RT_CID_819x_Senao: - padapter->ledpriv.LedStrategy = SW_LED_MODE3; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_Edimax_Belkin: - padapter->ledpriv.LedStrategy = SW_LED_MODE4; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_Sercomm_Belkin: - padapter->ledpriv.LedStrategy = SW_LED_MODE5; - padapter->ledpriv.bRegUseLed = true; - break; - case RT_CID_819x_WNC_COREGA: - padapter->ledpriv.LedStrategy = SW_LED_MODE6; - padapter->ledpriv.bRegUseLed = true; - break; - default: - padapter->ledpriv.LedStrategy = SW_LED_MODE0; - padapter->ledpriv.bRegUseLed = false; - break; - } - } else { - AutoloadFail = false; - } - if ((!AutoloadFail) || - ((mac[0] == 0xff) && (mac[1] == 0xff) && - (mac[2] == 0xff) && (mac[3] == 0xff) && - (mac[4] == 0xff) && (mac[5] == 0xff)) || - ((mac[0] == 0x00) && (mac[1] == 0x00) && - (mac[2] == 0x00) && (mac[3] == 0x00) && - (mac[4] == 0x00) && (mac[5] == 0x00))) { - mac[0] = 0x00; - mac[1] = 0xe0; - mac[2] = 0x4c; - mac[3] = 0x87; - mac[4] = 0x00; - mac[5] = 0x00; - } - if (r8712_initmac) { - /* Make sure the user did not select a multicast - * address by setting bit 1 of first octet. - */ - mac[0] &= 0xFE; - dev_info(&udev->dev, - "r8712u: MAC Address from user = %pM\n", mac); - } else { - dev_info(&udev->dev, - "r8712u: MAC Address from efuse = %pM\n", mac); - } - eth_hw_addr_set(pnetdev, mac); - } - /* step 6. Load the firmware asynchronously */ - if (rtl871x_load_fw(padapter)) - goto deinit_drv_sw; - init_completion(&padapter->rx_filter_ready); - return 0; - -deinit_drv_sw: - r8712_free_drv_sw(padapter); -dvobj_deinit: - padapter->dvobj_deinit(padapter); -free_netdev: - free_netdev(pnetdev); -put_dev: - usb_put_dev(udev); - usb_set_intfdata(pusb_intf, NULL); - return -ENODEV; -} - -/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove() - * => how to recognize both - */ -static void r871xu_dev_remove(struct usb_interface *pusb_intf) -{ - struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct usb_device *udev = interface_to_usbdev(pusb_intf); - struct _adapter *padapter = netdev_priv(pnetdev); - - /* never exit with a firmware callback pending */ - wait_for_completion(&padapter->rtl8712_fw_ready); - if (pnetdev->reg_state != NETREG_UNINITIALIZED) - unregister_netdev(pnetdev); /* will call netdev_close() */ - usb_set_intfdata(pusb_intf, NULL); - release_firmware(padapter->fw); - if (drvpriv.drv_registered) - padapter->surprise_removed = true; - r8712_flush_rwctrl_works(padapter); - r8712_flush_led_works(padapter); - udelay(1); - /* Stop driver mlme relation timer */ - r8712_stop_drv_timers(padapter); - r871x_dev_unload(padapter); - if (padapter->dvobj_deinit) - padapter->dvobj_deinit(padapter); - r8712_free_drv_sw(padapter); - free_netdev(pnetdev); - - /* decrease the reference count of the usb device structure - * when disconnect - */ - usb_put_dev(udev); - - /* If we didn't unplug usb dongle and remove/insert module, driver - * fails on sitesurvey for the first time when device is up. - * Reset usb port for sitesurvey fail issue. - */ - if (udev->state != USB_STATE_NOTATTACHED) - usb_reset_device(udev); -} - -static int __init r8712u_drv_entry(void) -{ - drvpriv.drv_registered = true; - return usb_register(&drvpriv.r871xu_drv); -} - -static void __exit r8712u_drv_halt(void) -{ - drvpriv.drv_registered = false; - usb_deregister(&drvpriv.r871xu_drv); -} - -module_init(r8712u_drv_entry); -module_exit(r8712u_drv_halt); diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c deleted file mode 100644 index af9966d03979..000000000000 --- a/drivers/staging/rtl8712/usb_ops.c +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_ops.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_OPS_C_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" -#include "usb_ops.h" -#include "recv_osdep.h" - -static u8 usb_read8(struct intf_hdl *intfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - int status; - __le32 data = 0; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x01; /* read_in */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 1; - status = r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, - &data, len, requesttype); - if (status < 0) - return 0; - return (u8)(le32_to_cpu(data) & 0x0ff); -} - -static u16 usb_read16(struct intf_hdl *intfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - int status; - __le32 data = 0; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x01; /* read_in */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 2; - status = r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, - &data, len, requesttype); - if (status < 0) - return 0; - return (u16)(le32_to_cpu(data) & 0xffff); -} - -static u32 usb_read32(struct intf_hdl *intfhdl, u32 addr) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - int status; - __le32 data = 0; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x01; /* read_in */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 4; - status = r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, - &data, len, requesttype); - if (status < 0) - return 0; - return le32_to_cpu(data); -} - -static void usb_write8(struct intf_hdl *intfhdl, u32 addr, u8 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - __le32 data; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x00; /* write_out */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 1; - data = cpu_to_le32((u32)val & 0x000000ff); - r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, &data, len, - requesttype); -} - -static void usb_write16(struct intf_hdl *intfhdl, u32 addr, u16 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - __le32 data; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x00; /* write_out */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 2; - data = cpu_to_le32((u32)val & 0x0000ffff); - r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, &data, len, - requesttype); -} - -static void usb_write32(struct intf_hdl *intfhdl, u32 addr, u32 val) -{ - u8 request; - u8 requesttype; - u16 wvalue; - u16 index; - u16 len; - __le32 data; - struct intf_priv *intfpriv = intfhdl->pintfpriv; - - request = 0x05; - requesttype = 0x00; /* write_out */ - index = 0; - wvalue = (u16)(addr & 0x0000ffff); - len = 4; - data = cpu_to_le32(val); - r8712_usbctrl_vendorreq(intfpriv, request, wvalue, index, &data, len, - requesttype); -} - -void r8712_usb_set_intf_option(u32 *option) -{ - *option = ((*option) | _INTF_ASYNC_); -} - -static void usb_intf_hdl_init(u8 *priv) -{ -} - -static void usb_intf_hdl_unload(u8 *priv) -{ -} - -static void usb_intf_hdl_open(u8 *priv) -{ -} - -static void usb_intf_hdl_close(u8 *priv) -{ -} - -void r8712_usb_set_intf_funs(struct intf_hdl *intfhdl) -{ - intfhdl->intf_hdl_init = usb_intf_hdl_init; - intfhdl->intf_hdl_unload = usb_intf_hdl_unload; - intfhdl->intf_hdl_open = usb_intf_hdl_open; - intfhdl->intf_hdl_close = usb_intf_hdl_close; -} - -void r8712_usb_set_intf_ops(struct _io_ops *ops) -{ - memset((u8 *)ops, 0, sizeof(struct _io_ops)); - ops->_read8 = usb_read8; - ops->_read16 = usb_read16; - ops->_read32 = usb_read32; - ops->_read_port = r8712_usb_read_port; - ops->_write8 = usb_write8; - ops->_write16 = usb_write16; - ops->_write32 = usb_write32; - ops->_write_mem = r8712_usb_write_mem; - ops->_write_port = r8712_usb_write_port; -} diff --git a/drivers/staging/rtl8712/usb_ops.h b/drivers/staging/rtl8712/usb_ops.h deleted file mode 100644 index 7a6b619b73fa..000000000000 --- a/drivers/staging/rtl8712/usb_ops.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __USB_OPS_H_ -#define __USB_OPS_H_ - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" - -void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, - u32 cnt, u8 *wmem); -u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr, - u32 cnt, u8 *wmem); -u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, - u32 cnt, u8 *rmem); -void r8712_usb_set_intf_option(u32 *poption); -void r8712_usb_set_intf_funs(struct intf_hdl *pintf_hdl); -uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv); -void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv); -void r8712_usb_set_intf_ops(struct _io_ops *pops); -void r8712_usb_read_port_cancel(struct _adapter *padapter); -void r8712_usb_write_port_cancel(struct _adapter *padapter); -int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, - u16 index, void *pdata, u16 len, u8 requesttype); - -#endif - diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c deleted file mode 100644 index b2181e1e2d38..000000000000 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ /dev/null @@ -1,515 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * usb_ops_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _HCI_OPS_OS_C_ - -#include - -#include "osdep_service.h" -#include "drv_types.h" -#include "osdep_intf.h" -#include "usb_ops.h" - -#define RTL871X_VENQT_READ 0xc0 -#define RTL871X_VENQT_WRITE 0x40 - -struct zero_bulkout_context { - void *pbuf; - void *purb; - void *pirp; - void *padapter; -}; - -uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv) -{ - pintfpriv->piorw_urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!pintfpriv->piorw_urb) - return _FAIL; - init_completion(&pintfpriv->io_retevt_comp); - return _SUCCESS; -} - -void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv) -{ - if (pintfpriv->piorw_urb) { - usb_kill_urb(pintfpriv->piorw_urb); - usb_free_urb(pintfpriv->piorw_urb); - } -} - -static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) -{ - unsigned int pipe = 0; - struct usb_device *pusbd = pdvobj->pusbdev; - - if (pdvobj->nr_endpoint == 11) { - switch (addr) { - case RTL8712_DMA_BKQ: - pipe = usb_sndbulkpipe(pusbd, 0x07); - break; - case RTL8712_DMA_BEQ: - pipe = usb_sndbulkpipe(pusbd, 0x06); - break; - case RTL8712_DMA_VIQ: - pipe = usb_sndbulkpipe(pusbd, 0x05); - break; - case RTL8712_DMA_VOQ: - pipe = usb_sndbulkpipe(pusbd, 0x04); - break; - case RTL8712_DMA_BCNQ: - pipe = usb_sndbulkpipe(pusbd, 0x0a); - break; - case RTL8712_DMA_BMCQ: /* HI Queue */ - pipe = usb_sndbulkpipe(pusbd, 0x0b); - break; - case RTL8712_DMA_MGTQ: - pipe = usb_sndbulkpipe(pusbd, 0x0c); - break; - case RTL8712_DMA_RX0FF: - pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ - break; - case RTL8712_DMA_C2HCMD: - pipe = usb_rcvbulkpipe(pusbd, 0x09); /* in */ - break; - case RTL8712_DMA_H2CCMD: - pipe = usb_sndbulkpipe(pusbd, 0x0d); - break; - } - } else if (pdvobj->nr_endpoint == 6) { - switch (addr) { - case RTL8712_DMA_BKQ: - pipe = usb_sndbulkpipe(pusbd, 0x07); - break; - case RTL8712_DMA_BEQ: - pipe = usb_sndbulkpipe(pusbd, 0x06); - break; - case RTL8712_DMA_VIQ: - pipe = usb_sndbulkpipe(pusbd, 0x05); - break; - case RTL8712_DMA_VOQ: - pipe = usb_sndbulkpipe(pusbd, 0x04); - break; - case RTL8712_DMA_RX0FF: - case RTL8712_DMA_C2HCMD: - pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ - break; - case RTL8712_DMA_H2CCMD: - case RTL8712_DMA_BCNQ: - case RTL8712_DMA_BMCQ: - case RTL8712_DMA_MGTQ: - pipe = usb_sndbulkpipe(pusbd, 0x0d); - break; - } - } else if (pdvobj->nr_endpoint == 4) { - switch (addr) { - case RTL8712_DMA_BEQ: - pipe = usb_sndbulkpipe(pusbd, 0x06); - break; - case RTL8712_DMA_VOQ: - pipe = usb_sndbulkpipe(pusbd, 0x04); - break; - case RTL8712_DMA_RX0FF: - case RTL8712_DMA_C2HCMD: - pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ - break; - case RTL8712_DMA_H2CCMD: - case RTL8712_DMA_BCNQ: - case RTL8712_DMA_BMCQ: - case RTL8712_DMA_MGTQ: - pipe = usb_sndbulkpipe(pusbd, 0x0d); - break; - } - } else { - pipe = 0; - } - return pipe; -} - -static void usb_write_mem_complete(struct urb *purb) -{ - struct io_queue *pio_q = (struct io_queue *)purb->context; - struct intf_hdl *pintf = &(pio_q->intf); - struct intf_priv *pintfpriv = pintf->pintfpriv; - struct _adapter *padapter = (struct _adapter *)pintf->adapter; - - if (purb->status != 0) { - if (purb->status == (-ESHUTDOWN)) - padapter->driver_stopped = true; - else - padapter->surprise_removed = true; - } - complete(&pintfpriv->io_retevt_comp); -} - -void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) -{ - unsigned int pipe; - struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; - struct intf_priv *pintfpriv = pintfhdl->pintfpriv; - struct io_queue *pio_queue = padapter->pio_queue; - struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; - struct usb_device *pusbd = pdvobj->pusbdev; - struct urb *piorw_urb = pintfpriv->piorw_urb; - - if ((padapter->driver_stopped) || (padapter->surprise_removed) || - (padapter->pwrctrlpriv.pnp_bstop_trx)) - return; - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - if (pipe == 0) - return; - usb_fill_bulk_urb(piorw_urb, pusbd, pipe, - wmem, cnt, usb_write_mem_complete, - pio_queue); - usb_submit_urb(piorw_urb, GFP_ATOMIC); - wait_for_completion_interruptible(&pintfpriv->io_retevt_comp); -} - -static void r8712_usb_read_port_complete(struct urb *purb) -{ - uint isevt; - __le32 *pbuf; - struct recv_buf *precvbuf = (struct recv_buf *)purb->context; - struct _adapter *padapter = (struct _adapter *)precvbuf->adapter; - struct recv_priv *precvpriv = &padapter->recvpriv; - - if (padapter->surprise_removed || padapter->driver_stopped) - return; - if (purb->status == 0) { /* SUCCESS */ - if ((purb->actual_length > (MAX_RECVBUF_SZ)) || - (purb->actual_length < RXDESC_SIZE)) { - r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, - (unsigned char *)precvbuf); - } else { - _pkt *pskb = precvbuf->pskb; - - precvbuf->transfer_len = purb->actual_length; - pbuf = (__le32 *)precvbuf->pbuf; - isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff; - if ((isevt & 0x1ff) == 0x1ff) { - r8712_rxcmd_event_hdl(padapter, pbuf); - skb_queue_tail(&precvpriv->rx_skb_queue, pskb); - r8712_read_port(padapter, precvpriv->ff_hwaddr, - 0, (unsigned char *)precvbuf); - } else { - skb_put(pskb, purb->actual_length); - skb_queue_tail(&precvpriv->rx_skb_queue, pskb); - tasklet_hi_schedule(&precvpriv->recv_tasklet); - r8712_read_port(padapter, precvpriv->ff_hwaddr, - 0, (unsigned char *)precvbuf); - } - } - } else { - switch (purb->status) { - case -EINVAL: - case -EPIPE: - case -ENODEV: - case -ESHUTDOWN: - padapter->driver_stopped = true; - break; - case -ENOENT: - if (!padapter->suspended) { - padapter->driver_stopped = true; - break; - } - fallthrough; - case -EPROTO: - r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, - (unsigned char *)precvbuf); - break; - case -EINPROGRESS: - netdev_err(padapter->pnetdev, "ERROR: URB IS IN PROGRESS!\n"); - break; - default: - break; - } - } -} - -u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) -{ - unsigned int pipe; - int err; - u32 tmpaddr = 0; - int alignment = 0; - u32 ret = _SUCCESS; - struct urb *purb = NULL; - struct recv_buf *precvbuf = (struct recv_buf *)rmem; - struct intf_priv *pintfpriv = pintfhdl->pintfpriv; - struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; - struct _adapter *adapter = pdvobj->padapter; - struct recv_priv *precvpriv = &adapter->recvpriv; - struct usb_device *pusbd = pdvobj->pusbdev; - - if (adapter->driver_stopped || adapter->surprise_removed || - adapter->pwrctrlpriv.pnp_bstop_trx || !precvbuf) - return _FAIL; - r8712_init_recvbuf(adapter, precvbuf); - /* Try to use skb from the free queue */ - precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); - - if (!precvbuf->pskb) { - precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, - MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - if (!precvbuf->pskb) - return _FAIL; - tmpaddr = (addr_t)precvbuf->pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); - skb_reserve(precvbuf->pskb, - (RECVBUFF_ALIGN_SZ - alignment)); - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - } else { /* skb is reused */ - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - precvbuf->pbuf = precvbuf->pskb->data; - } - purb = precvbuf->purb; - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - usb_fill_bulk_urb(purb, pusbd, pipe, - precvbuf->pbuf, MAX_RECVBUF_SZ, - r8712_usb_read_port_complete, - precvbuf); - err = usb_submit_urb(purb, GFP_ATOMIC); - if ((err) && (err != (-EPERM))) - ret = _FAIL; - return ret; -} - -void r8712_usb_read_port_cancel(struct _adapter *padapter) -{ - int i; - struct recv_buf *precvbuf; - - precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; - for (i = 0; i < NR_RECVBUFF; i++) { - if (precvbuf->purb) - usb_kill_urb(precvbuf->purb); - precvbuf++; - } -} - -void r8712_xmit_bh(struct tasklet_struct *t) -{ - int ret = false; - struct _adapter *padapter = from_tasklet(padapter, t, - xmitpriv.xmit_tasklet); - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - if (padapter->driver_stopped || - padapter->surprise_removed) { - netdev_err(padapter->pnetdev, "xmit_bh => driver_stopped or surprise_removed\n"); - return; - } - ret = r8712_xmitframe_complete(padapter, pxmitpriv, NULL); - if (!ret) - return; - tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); -} - -static void usb_write_port_complete(struct urb *purb) -{ - int i; - struct xmit_frame *pxmitframe = (struct xmit_frame *)purb->context; - struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; - struct _adapter *padapter = pxmitframe->padapter; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - switch (pattrib->priority) { - case 1: - case 2: - pxmitpriv->bkq_cnt--; - break; - case 4: - case 5: - pxmitpriv->viq_cnt--; - break; - case 6: - case 7: - pxmitpriv->voq_cnt--; - break; - case 0: - case 3: - default: - pxmitpriv->beq_cnt--; - break; - } - pxmitpriv->txirp_cnt--; - for (i = 0; i < 8; i++) { - if (purb == pxmitframe->pxmit_urb[i]) { - pxmitframe->bpending[i] = false; - break; - } - } - if (padapter->surprise_removed) - return; - switch (purb->status) { - case 0: - break; - default: - netdev_warn(padapter->pnetdev, - "r8712u: pipe error: (%d)\n", purb->status); - break; - } - /* not to consider tx fragment */ - r8712_free_xmitframe_ex(pxmitpriv, pxmitframe); - r8712_free_xmitbuf(pxmitpriv, pxmitbuf); - tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); -} - -u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) -{ - unsigned long irqL; - int i, status; - unsigned int pipe; - u32 ret, bwritezero; - struct urb *purb = NULL; - struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; - struct dvobj_priv *pdvobj = &padapter->dvobjpriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct xmit_frame *pxmitframe = (struct xmit_frame *)wmem; - struct usb_device *pusbd = pdvobj->pusbdev; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - if ((padapter->driver_stopped) || (padapter->surprise_removed) || - (padapter->pwrctrlpriv.pnp_bstop_trx)) - return _FAIL; - for (i = 0; i < 8; i++) { - if (!pxmitframe->bpending[i]) { - spin_lock_irqsave(&pxmitpriv->lock, irqL); - pxmitpriv->txirp_cnt++; - pxmitframe->bpending[i] = true; - switch (pattrib->priority) { - case 1: - case 2: - pxmitpriv->bkq_cnt++; - break; - case 4: - case 5: - pxmitpriv->viq_cnt++; - break; - case 6: - case 7: - pxmitpriv->voq_cnt++; - break; - case 0: - case 3: - default: - pxmitpriv->beq_cnt++; - break; - } - spin_unlock_irqrestore(&pxmitpriv->lock, irqL); - pxmitframe->sz[i] = (u16)cnt; - purb = pxmitframe->pxmit_urb[i]; - break; - } - } - bwritezero = false; - if (pdvobj->ishighspeed) { - if (cnt > 0 && cnt % 512 == 0) - bwritezero = true; - } else { - if (cnt > 0 && cnt % 64 == 0) - bwritezero = true; - } - /* translate DMA FIFO addr to pipehandle */ - pipe = ffaddr2pipehdl(pdvobj, addr); - if (pxmitpriv->free_xmitbuf_cnt % NR_XMITBUFF == 0) - purb->transfer_flags &= (~URB_NO_INTERRUPT); - else - purb->transfer_flags |= URB_NO_INTERRUPT; - if (bwritezero) - cnt += 8; - usb_fill_bulk_urb(purb, pusbd, pipe, - pxmitframe->mem_addr, - cnt, usb_write_port_complete, - pxmitframe); /* context is xmit_frame */ - status = usb_submit_urb(purb, GFP_ATOMIC); - if (!status) - ret = _SUCCESS; - else - ret = _FAIL; - return ret; -} - -void r8712_usb_write_port_cancel(struct _adapter *padapter) -{ - int i, j; - struct xmit_buf *pxmitbuf = (struct xmit_buf *) - padapter->xmitpriv.pxmitbuf; - - for (i = 0; i < NR_XMITBUFF; i++) { - for (j = 0; j < 8; j++) { - if (pxmitbuf->pxmit_urb[j]) - usb_kill_urb(pxmitbuf->pxmit_urb[j]); - } - pxmitbuf++; - } -} - -int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, - u16 index, void *pdata, u16 len, u8 requesttype) -{ - unsigned int pipe; - int status; - u8 reqtype; - struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *) - pintfpriv->intf_dev; - struct usb_device *udev = pdvobjpriv->pusbdev; - /* For mstar platform, mstar suggests the address for USB IO - * should be 16 bytes alignment. Trying to fix it here. - */ - u8 *palloc_buf, *pIo_buf; - - palloc_buf = kmalloc((u32)len + 16, GFP_ATOMIC); - if (!palloc_buf) - return -ENOMEM; - pIo_buf = palloc_buf + 16 - ((addr_t)(palloc_buf) & 0x0f); - if (requesttype == 0x01) { - pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ - reqtype = RTL871X_VENQT_READ; - } else { - pipe = usb_sndctrlpipe(udev, 0); /* write_out */ - reqtype = RTL871X_VENQT_WRITE; - memcpy(pIo_buf, pdata, len); - } - status = usb_control_msg(udev, pipe, request, reqtype, value, index, - pIo_buf, len, 500); - if (status < 0) - goto free; - if (status != len) { - status = -EREMOTEIO; - goto free; - } - /* Success this control transfer. */ - if (requesttype == 0x01) { - /* For Control read transfer, we have to copy the read - * data from pIo_buf to pdata. - */ - memcpy(pdata, pIo_buf, status); - } - -free: - kfree(palloc_buf); - return status; -} diff --git a/drivers/staging/rtl8712/usb_osintf.h b/drivers/staging/rtl8712/usb_osintf.h deleted file mode 100644 index 2e512b4a564c..000000000000 --- a/drivers/staging/rtl8712/usb_osintf.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __USB_OSINTF_H -#define __USB_OSINTF_H - -#include "osdep_service.h" -#include "drv_types.h" - -extern char *r8712_initmac; - -unsigned int r8712_usb_inirp_init(struct _adapter *padapter); -unsigned int r8712_usb_inirp_deinit(struct _adapter *padapter); -uint rtl871x_hal_init(struct _adapter *padapter); -uint rtl8712_hal_deinit(struct _adapter *padapter); - -void rtl871x_intf_stop(struct _adapter *padapter); -void r871x_dev_unload(struct _adapter *padapter); -void r8712_stop_drv_threads(struct _adapter *padapter); -void r8712_stop_drv_timers(struct _adapter *padapter); -int r8712_init_drv_sw(struct _adapter *padapter); -void r8712_free_drv_sw(struct _adapter *padapter); -struct net_device *r8712_init_netdev(void); - -#endif diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h deleted file mode 100644 index 498e6dec7e67..000000000000 --- a/drivers/staging/rtl8712/wifi.h +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef _WIFI_H_ -#define _WIFI_H_ - -#include -#include - -#define WLAN_HDR_A3_LEN 24 -#define WLAN_HDR_A3_QOS_LEN 26 - -enum WIFI_FRAME_TYPE { - WIFI_QOS_DATA_TYPE = (BIT(7) | BIT(3)), /*!< QoS Data */ -}; - -#define SetToDs(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_TODS); \ -}) - -#define GetToDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0) - -#define ClearToDs(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_TODS)); \ -}) - -#define SetFrDs(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_FROMDS); \ -}) - -#define GetFrDs(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0) - -#define ClearFrDs(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_FROMDS)); \ -}) - -static inline unsigned char get_tofr_ds(unsigned char *pframe) -{ - return ((GetToDs(pframe) << 1) | GetFrDs(pframe)); -} - -#define SetMFrag(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); \ -}) - -#define GetMFrag(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0) - -#define ClearMFrag(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)); \ -}) - -#define SetRetry(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_RETRY); \ -}) - -#define GetRetry(pbuf) (((*(__le16 *)(pbuf)) & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0) - -#define ClearRetry(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_RETRY)); \ -}) - -#define SetPwrMgt(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PM); \ -}) - -#define GetPwrMgt(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_PM)) != 0) - -#define ClearPwrMgt(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_PM)); \ -}) - -#define SetMData(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); \ -}) - -#define GetMData(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0) - -#define ClearMData(pbuf) ({ \ - *(__le16 *)(pbuf) &= (~cpu_to_le16(IEEE80211_FCTL_MOREDATA)); \ -}) - -#define SetPrivacy(pbuf) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); \ -}) - -#define GetPrivacy(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0) - -#define GetOrder(pbuf) (((*(__le16 *)(pbuf)) & \ - cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0) - -#define GetFrameType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \ - (BIT(3) | BIT(2))) - -#define SetFrameType(pbuf, type) \ - do { \ - *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(3) | \ - BIT(2))); \ - *(__le16 *)(pbuf) |= cpu_to_le16(type); \ - } while (0) - -#define GetFrameSubType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \ - (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | \ - BIT(2))) - -#define SetFrameSubType(pbuf, type) \ - do { \ - *(__le16 *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | \ - BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ - *(__le16 *)(pbuf) |= cpu_to_le16(type); \ - } while (0) - -#define GetSequence(pbuf) (le16_to_cpu(*(__le16 *)\ - ((addr_t)(pbuf) + 22)) >> 4) - -#define GetFragNum(pbuf) (le16_to_cpu(*(__le16 *)((addr_t)\ - (pbuf) + 22)) & 0x0f) - -#define SetSeqNum(pbuf, num) ({ \ - *(__le16 *)((addr_t)(pbuf) + 22) = \ - cpu_to_le16((le16_to_cpu(*(__le16 *)((addr_t)(pbuf) + 22)) & \ - 0x000f) | (0xfff0 & (num << 4))); \ -}) - -#define SetPriority(pbuf, tid) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16(tid & 0xf); \ -}) - -#define GetPriority(pbuf) ((le16_to_cpu(*(__le16 *)(pbuf))) & 0xf) - -#define SetAckpolicy(pbuf, ack) ({ \ - *(__le16 *)(pbuf) |= cpu_to_le16((ack & 3) << 5); \ -}) - -#define GetAckpolicy(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 5) & 0x3) - -#define GetAMsdu(pbuf) (((le16_to_cpu(*(__le16 *)pbuf)) >> 7) & 0x1) - -#define GetAddr1Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 4)) - -#define GetAddr2Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 10)) - -#define GetAddr3Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 16)) - -#define GetAddr4Ptr(pbuf) ((unsigned char *)((addr_t)(pbuf) + 24)) - -static inline unsigned char *get_hdr_bssid(unsigned char *pframe) -{ - unsigned char *sa; - unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); - - switch (to_fr_ds) { - case 0x00: /* ToDs=0, FromDs=0 */ - sa = GetAddr3Ptr(pframe); - break; - case 0x01: /* ToDs=0, FromDs=1 */ - sa = GetAddr2Ptr(pframe); - break; - case 0x02: /* ToDs=1, FromDs=0 */ - sa = GetAddr1Ptr(pframe); - break; - default: /* ToDs=1, FromDs=1 */ - sa = NULL; - break; - } - return sa; -} - -/* --------------------------------------------------------------------------- - * Below is the fixed elements... - * --------------------------------------------------------------------------- - */ -#define _BEACON_ITERVAL_ 2 -#define _CAPABILITY_ 2 -#define _TIMESTAMP_ 8 - -/*----------------------------------------------------------------------------- - * Below is the definition for WMM - *------------------------------------------------------------------------------ - */ -#define _WMM_IE_Length_ 7 /* for WMM STA */ - -#endif /* _WIFI_H_ */ - diff --git a/drivers/staging/rtl8712/wlan_bssdef.h b/drivers/staging/rtl8712/wlan_bssdef.h deleted file mode 100644 index ec3749813728..000000000000 --- a/drivers/staging/rtl8712/wlan_bssdef.h +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __WLAN_BSSDEF_H__ -#define __WLAN_BSSDEF_H__ - -#define MAX_IE_SZ 768 - -#define NDIS_802_11_LENGTH_SSID 32 -#define NDIS_802_11_LENGTH_RATES 8 -#define NDIS_802_11_LENGTH_RATES_EX 16 - -struct ndis_802_11_ssid { - u32 SsidLength; - u8 Ssid[32]; -}; - -enum NDIS_802_11_NETWORK_TYPE { - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11NetworkTypeMax /* not a real type, defined as an upper bound*/ -}; - -struct NDIS_802_11_CONFIGURATION_FH { - u32 Length; /* Length of structure */ - u32 HopPattern; /* As defined by 802.11, MSB set */ - u32 HopSet; /* to one if non-802.11 */ - u32 DwellTime; /* units are Kusec */ -}; - -/* - * FW will only save the channel number in DSConfig. - * ODI Handler will convert the channel number to freq. number. - */ -struct NDIS_802_11_CONFIGURATION { - u32 Length; /* Length of structure */ - u32 BeaconPeriod; /* units are Kusec */ - u32 ATIMWindow; /* units are Kusec */ - u32 DSConfig; /* Frequency, units are kHz */ - struct NDIS_802_11_CONFIGURATION_FH FHConfig; -}; - -enum NDIS_802_11_NETWORK_INFRASTRUCTURE { - Ndis802_11IBSS, - Ndis802_11Infrastructure, - Ndis802_11AutoUnknown, - Ndis802_11InfrastructureMax, /*Not a real value,defined as upper bound*/ - Ndis802_11APMode -}; - -struct NDIS_802_11_FIXED_IEs { - u8 Timestamp[8]; - u16 BeaconInterval; - u16 Capabilities; -}; - -struct wlan_bssid_ex { - u32 Length; - unsigned char MacAddress[6]; - u8 Reserved[2]; - struct ndis_802_11_ssid Ssid; - __le32 Privacy; - s32 Rssi; - enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - struct NDIS_802_11_CONFIGURATION Configuration; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; - u8 rates[NDIS_802_11_LENGTH_RATES_EX]; - /* number of content bytes in EIs, which varies */ - u32 IELength; - /*(timestamp, beacon interval, and capability information) */ - u8 IEs[MAX_IE_SZ]; -}; - -enum NDIS_802_11_AUTHENTICATION_MODE { - Ndis802_11AuthModeOpen, - Ndis802_11AuthModeShared, - Ndis802_11AuthModeAutoSwitch, - Ndis802_11AuthModeWPA, - Ndis802_11AuthModeWPAPSK, - Ndis802_11AuthModeWPANone, - Ndis802_11AuthModeMax /* Not a real mode, defined as upper bound */ -}; - -enum { - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent -}; - -#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 -#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 -#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 - -#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 -#define NDIS_802_11_AI_RESFI_STATUSCODE 2 -#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 - -struct NDIS_802_11_AI_REQFI { - u16 Capabilities; - u16 ListenInterval; - unsigned char CurrentAPAddress[6]; -}; - -struct NDIS_802_11_AI_RESFI { - u16 Capabilities; - u16 StatusCode; - u16 AssociationId; -}; - -struct NDIS_802_11_ASSOCIATION_INFORMATION { - u32 Length; - u16 AvailableRequestFixedIEs; - struct NDIS_802_11_AI_REQFI RequestFixedIEs; - u32 RequestIELength; - u32 OffsetRequestIEs; - u16 AvailableResponseFixedIEs; - struct NDIS_802_11_AI_RESFI ResponseFixedIEs; - u32 ResponseIELength; - u32 OffsetResponseIEs; -}; - -/* Key mapping keys require a BSSID*/ -struct NDIS_802_11_KEY { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - u32 KeyLength; /* length of key in bytes */ - unsigned char BSSID[6]; - unsigned long long KeyRSC; - u8 KeyMaterial[32]; /* variable length */ -}; - -struct NDIS_802_11_REMOVE_KEY { - u32 Length; /* Length of this structure */ - u32 KeyIndex; - unsigned char BSSID[6]; -}; - -struct NDIS_802_11_WEP { - u32 Length; /* Length of this structure */ - u32 KeyIndex; /* 0 is the per-client key, - * 1-N are the global keys - */ - u32 KeyLength; /* length of key in bytes */ - u8 KeyMaterial[16]; /* variable length depending on above field */ -}; - -/* mask for authentication/integrity fields */ -#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f -#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 -#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 -#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E - -/* MIC check time, 60 seconds. */ -#define MIC_CHECK_TIME 60000000 - -#ifndef Ndis802_11APMode -#define Ndis802_11APMode (Ndis802_11InfrastructureMax + 1) -#endif - -struct wlan_network { - struct list_head list; - int network_type; /*refer to ieee80211.h for WIRELESS_11A/B/G */ - int fixed; /* set to fixed when not to be removed asi - * site-surveying - */ - unsigned int last_scanned; /*timestamp for the network */ - int aid; /*will only be valid when a BSS is joined. */ - int join_res; - struct wlan_bssid_ex network; /*must be the last item */ -}; - -enum VRTL_CARRIER_SENSE { - DISABLE_VCS, - ENABLE_VCS, - AUTO_VCS -}; - -enum VCS_TYPE { - NONE_VCS, - RTS_CTS, - CTS_TO_SELF -}; - -#define PWR_CAM 0 -#define PWR_MINPS 1 -#define PWR_MAXPS 2 -#define PWR_UAPSD 3 -#define PWR_VOIP 4 - -enum UAPSD_MAX_SP { - NO_LIMIT, - TWO_MSDU, - FOUR_MSDU, - SIX_MSDU -}; - -#define NUM_PRE_AUTH_KEY 16 -#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY - -#endif /* #ifndef WLAN_BSSDEF_H_ */ - diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c deleted file mode 100644 index ceb6b590b310..000000000000 --- a/drivers/staging/rtl8712/xmit_linux.c +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/****************************************************************************** - * xmit_linux.c - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192SU - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ - -#define _XMIT_OSDEP_C_ - -#include -#include -#include -#include - -#include "osdep_service.h" -#include "drv_types.h" - -#include "wifi.h" -#include "mlme_osdep.h" -#include "xmit_osdep.h" -#include "osdep_intf.h" - -static uint remainder_len(struct pkt_file *pfile) -{ - return (uint)(pfile->buf_len - ((addr_t)(pfile->cur_addr) - - (addr_t)(pfile->buf_start))); -} - -void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile) -{ - pfile->pkt = pktptr; - pfile->cur_addr = pfile->buf_start = pktptr->data; - pfile->pkt_len = pfile->buf_len = pktptr->len; - pfile->cur_buffer = pfile->buf_start; -} - -uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) -{ - uint len; - - len = remainder_len(pfile); - len = (rlen > len) ? len : rlen; - if (rmem) - skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, - rmem, len); - pfile->cur_addr += len; - pfile->pkt_len -= len; - return len; -} - -sint r8712_endofpktfile(struct pkt_file *pfile) -{ - return (pfile->pkt_len == 0); -} - -void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) -{ - struct ethhdr etherhdr; - struct iphdr ip_hdr; - u16 user_priority = 0; - - _r8712_open_pktfile(ppktfile->pkt, ppktfile); - _r8712_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN); - - /* get user_priority from IP hdr*/ - if (pattrib->ether_type == 0x0800) { - _r8712_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); - /*user_priority = (ntohs(ip_hdr.tos) >> 5) & 0x3 ;*/ - user_priority = ip_hdr.tos >> 5; - } else { - /* "When priority processing of data frames is supported, - * a STA's SME should send EAPOL-Key frames at the highest - * priority." - */ - - if (pattrib->ether_type == 0x888e) - user_priority = 7; - } - pattrib->priority = user_priority; - pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; - pattrib->subtype = WIFI_QOS_DATA_TYPE; -} - -void r8712_SetFilter(struct work_struct *work) -{ - struct _adapter *adapter = container_of(work, struct _adapter, - wk_filter_rx_ff0); - u8 oldvalue = 0x00, newvalue = 0x00; - - oldvalue = r8712_read8(adapter, 0x117); - newvalue = oldvalue & 0xfe; - r8712_write8(adapter, 0x117, newvalue); - - wait_for_completion(&adapter->rx_filter_ready); - r8712_write8(adapter, 0x117, oldvalue); -} - -int r8712_xmit_resource_alloc(struct _adapter *padapter, - struct xmit_buf *pxmitbuf) -{ - int i; - - for (i = 0; i < 8; i++) { - pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!pxmitbuf->pxmit_urb[i]) { - int k; - - for (k = i - 1; k >= 0; k--) { - /* handle allocation errors part way through loop */ - usb_free_urb(pxmitbuf->pxmit_urb[k]); - } - netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n"); - return -ENOMEM; - } - kmemleak_not_leak(pxmitbuf->pxmit_urb[i]); - } - return 0; -} - -void r8712_xmit_resource_free(struct _adapter *padapter, - struct xmit_buf *pxmitbuf) -{ - int i; - - for (i = 0; i < 8; i++) { - if (pxmitbuf->pxmit_urb[i]) { - usb_kill_urb(pxmitbuf->pxmit_urb[i]); - usb_free_urb(pxmitbuf->pxmit_urb[i]); - } - } -} - -void r8712_xmit_complete(struct _adapter *padapter, struct xmit_frame *pxframe) -{ - if (pxframe->pkt) - dev_kfree_skb_any(pxframe->pkt); - pxframe->pkt = NULL; -} - -netdev_tx_t r8712_xmit_entry(_pkt *pkt, struct net_device *netdev) -{ - struct xmit_frame *xmitframe = NULL; - struct _adapter *adapter = netdev_priv(netdev); - struct xmit_priv *xmitpriv = &(adapter->xmitpriv); - - if (!r8712_if_up(adapter)) - goto _xmit_entry_drop; - - xmitframe = r8712_alloc_xmitframe(xmitpriv); - if (!xmitframe) - goto _xmit_entry_drop; - - if (r8712_update_attrib(adapter, pkt, &xmitframe->attrib)) - goto _xmit_entry_drop; - - adapter->ledpriv.LedControlHandler(adapter, LED_CTL_TX); - xmitframe->pkt = pkt; - if (r8712_pre_xmit(adapter, xmitframe)) { - /*dump xmitframe directly or drop xframe*/ - dev_kfree_skb_any(pkt); - xmitframe->pkt = NULL; - } - xmitpriv->tx_pkts++; - xmitpriv->tx_bytes += xmitframe->attrib.last_txcmdsz; - return NETDEV_TX_OK; -_xmit_entry_drop: - if (xmitframe) - r8712_free_xmitframe(xmitpriv, xmitframe); - xmitpriv->tx_drop++; - dev_kfree_skb_any(pkt); - return NETDEV_TX_OK; -} diff --git a/drivers/staging/rtl8712/xmit_osdep.h b/drivers/staging/rtl8712/xmit_osdep.h deleted file mode 100644 index 1ad42658c883..000000000000 --- a/drivers/staging/rtl8712/xmit_osdep.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE - * Larry Finger - * - ******************************************************************************/ -#ifndef __XMIT_OSDEP_H_ -#define __XMIT_OSDEP_H_ - -#include "osdep_service.h" -#include "drv_types.h" - -struct pkt_file { - _pkt *pkt; - u32 pkt_len; /*the remainder length of the open_file*/ - _buffer *cur_buffer; - u8 *buf_start; - u8 *cur_addr; - u32 buf_len; -}; - -#define NR_XMITFRAME 256 - -struct xmit_priv; -struct pkt_attrib; -struct sta_xmit_priv; -struct xmit_frame; -struct xmit_buf; - -netdev_tx_t r8712_xmit_entry(_pkt *pkt, struct net_device *pnetdev); -void r8712_SetFilter(struct work_struct *work); -int r8712_xmit_resource_alloc(struct _adapter *padapter, - struct xmit_buf *pxmitbuf); -void r8712_xmit_resource_free(struct _adapter *padapter, - struct xmit_buf *pxmitbuf); - -void r8712_set_qos(struct pkt_file *ppktfile, - struct pkt_attrib *pattrib); -void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile); -uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen); -sint r8712_endofpktfile(struct pkt_file *pfile); -void r8712_xmit_complete(struct _adapter *padapter, - struct xmit_frame *pxframe); - -#endif -- Gitee From 5aeb8ccbabc696c2890c1576474f8f5470c38dc8 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Fri, 28 Nov 2025 02:28:11 +0800 Subject: [PATCH 0171/1449] selftests: mptcp: join: properly kill background tasks ANBZ: #35228 commit b77075c08d7e0af0aeef80b7c17536188b8c9bd0 stable. commit 852b644acbce1529307a4bb283752c4e77b5cda7 upstream. The 'run_tests' function is executed in the background, but killing its associated PID would not kill the children tasks running in the background. To properly kill all background tasks, 'kill -- -PID' could be used, but this requires kill from procps-ng. Instead, all children tasks are listed using 'ps', and 'kill' is called with all PIDs of this group. Fixes: 31ee4ad86afd ("selftests: mptcp: join: stop transfer when check is done (part 1)") Cc: stable@vger.kernel.org Fixes: 04b57c9e096a ("selftests: mptcp: join: stop transfer when check is done (part 2)") Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251110-net-mptcp-sft-join-unstable-v1-6-a4332c714e10@kernel.org Signed-off-by: Jakub Kicinski [ Conflicts in mptcp_join.sh, because commit e3b47e460b4b ("selftests: mptcp: userspace pm remove initial subflow") and commit b9fb176081fb ("selftests: mptcp: userspace pm send RM_ADDR for ID 0") are not in this version. They introduced new subtests that got modified by this patch. That's OK, no need to modify them if they are not there: the conflicts can be dropped. ] Signed-off-by: Matthieu Baerts (NGI0) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../testing/selftests/net/mptcp/mptcp_join.sh | 14 ++++++------- .../testing/selftests/net/mptcp/mptcp_lib.sh | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index ef16edce4759..2c025c73e19f 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -3679,7 +3679,7 @@ userspace_tests() chk_mptcp_info subflows 0 subflows 0 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm create destroy subflow @@ -3707,7 +3707,7 @@ userspace_tests() chk_mptcp_info subflows 0 subflows 0 chk_subflows_total 1 1 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi # userspace pm create id 0 subflow @@ -3728,7 +3728,7 @@ userspace_tests() chk_mptcp_info subflows 1 subflows 1 chk_subflows_total 2 2 kill_events_pids - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi } @@ -3758,7 +3758,7 @@ endpoint_tests() pm_nl_add_endpoint $ns2 10.0.2.2 flags signal pm_nl_check_endpoint "modif is allowed" \ $ns2 10.0.2.2 id 1 flags signal - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid fi if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT && @@ -3813,7 +3813,7 @@ endpoint_tests() chk_mptcp_info subflows 3 subflows 3 done - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid kill_events_pids chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1 @@ -3886,7 +3886,7 @@ endpoint_tests() wait_mpj $ns2 chk_subflow_nr "after re-re-add ID 0" 3 chk_mptcp_info subflows 3 subflows 3 - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid kill_events_pids chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1 @@ -3933,7 +3933,7 @@ endpoint_tests() wait_mpj $ns2 pm_nl_add_endpoint $ns1 10.0.3.1 id 2 flags signal wait_mpj $ns2 - mptcp_lib_kill_wait $tests_pid + mptcp_lib_kill_group_wait $tests_pid chk_join_nr 2 2 2 chk_add_nr 2 2 diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh index 919f4f1018eb..8b3bd063f7be 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh @@ -242,6 +242,27 @@ mptcp_lib_kill_wait() { wait "${1}" 2>/dev/null } +# $1: PID +mptcp_lib_pid_list_children() { + local curr="${1}" + # evoke 'ps' only once + local pids="${2:-"$(ps o pid,ppid)"}" + + echo "${curr}" + + local pid + for pid in $(echo "${pids}" | awk "\$2 == ${curr} { print \$1 }"); do + mptcp_lib_pid_list_children "${pid}" "${pids}" + done +} + +# $1: PID +mptcp_lib_kill_group_wait() { + # Some users might not have procps-ng: cannot use "kill -- -PID" + mptcp_lib_pid_list_children "${1}" | xargs -r kill &>/dev/null + wait "${1}" 2>/dev/null +} + # $1: IP address mptcp_lib_is_v6() { [ -z "${1##*:*}" ] -- Gitee From 9a787a93fb469ca705d45d0b9126c8dc71baef4d Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Fri, 28 Nov 2025 02:27:42 +0800 Subject: [PATCH 0172/1449] mptcp: fix duplicate reset on fastclose ANBZ: #35228 commit 3a13454fd098ed51e733958488f8ec62859a9ed8 stable. commit ae155060247be8dcae3802a95bd1bdf93ab3215d upstream. The CI reports sporadic failures of the fastclose self-tests. The root cause is a duplicate reset, not carrying the relevant MPTCP option. In the failing scenario the bad reset is received by the peer before the fastclose one, preventing the reception of the latter. Indeed there is window of opportunity at fastclose time for the following race: mptcp_do_fastclose __mptcp_close_ssk __tcp_close() tcp_set_state() [1] tcp_send_active_reset() [2] After [1] the stack will send reset to in-flight data reaching the now closed port. Such reset may race with [2]. Address the issue explicitly sending a single reset on fastclose before explicitly moving the subflow to close status. Fixes: d21f83485518 ("mptcp: use fastclose on more edge scenarios") Cc: stable@vger.kernel.org Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/596 Signed-off-by: Paolo Abeni Reviewed-by: Geliang Tang Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-6-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski [ No conflicts, but tcp_send_active_reset() doesn't take a 3rd argument (sk_rst_reason) in this version, see commit 5691276b39da ("rstreason: prepare for active reset"). This argument is only helpful for tracing, it is fine to drop it. ] Signed-off-by: Matthieu Baerts (NGI0) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 90e0a9e8e014..816cf39dfa1e 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2431,7 +2431,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) /* flags for __mptcp_close_ssk() */ #define MPTCP_CF_PUSH BIT(1) -#define MPTCP_CF_FASTCLOSE BIT(2) /* be sure to send a reset only if the caller asked for it, also * clean completely the subflow status when the subflow reaches @@ -2442,7 +2441,7 @@ static void __mptcp_subflow_disconnect(struct sock *ssk, unsigned int flags) { if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || - (flags & MPTCP_CF_FASTCLOSE)) { + subflow->send_fastclose) { /* The MPTCP code never wait on the subflow sockets, TCP-level * disconnect should never fail */ @@ -2489,14 +2488,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); - if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { - /* be sure to force the tcp_close path - * to generate the egress reset - */ - ssk->sk_lingertime = 0; - sock_set_flag(ssk, SOCK_LINGER); - subflow->send_fastclose = 1; - } + if (subflow->send_fastclose && ssk->sk_state != TCP_CLOSE) + tcp_set_state(ssk, TCP_CLOSE); need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); if (!dispose_it) { @@ -2809,9 +2802,25 @@ static void mptcp_do_fastclose(struct sock *sk) struct mptcp_sock *msk = mptcp_sk(sk); mptcp_set_state(sk, TCP_CLOSE); - mptcp_for_each_subflow_safe(msk, subflow, tmp) - __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), - subflow, MPTCP_CF_FASTCLOSE); + + /* Explicitly send the fastclose reset as need */ + if (__mptcp_check_fallback(msk)) + return; + + mptcp_for_each_subflow_safe(msk, subflow, tmp) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + + lock_sock(ssk); + + /* Some subflow socket states don't allow/need a reset.*/ + if ((1 << ssk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + goto unlock; + + subflow->send_fastclose = 1; + tcp_send_active_reset(ssk, ssk->sk_allocation); +unlock: + release_sock(ssk); + } } static void mptcp_worker(struct work_struct *work) -- Gitee From ce000095d3233a618adff924d88ba327b102c7be Mon Sep 17 00:00:00 2001 From: Sean Heelan Date: Fri, 28 Nov 2025 00:23:37 +0800 Subject: [PATCH 0173/1449] ksmbd: fix use-after-free in session logoff ANBZ: #35228 commit 70ad6455139e26e85f48f95d0e21f351c1909342 stable. commit 2fc9feff45d92a92cd5f96487655d5be23fb7e2b upstream. The sess->user object can currently be in use by another thread, for example if another connection has sent a session setup request to bind to the session being free'd. The handler for that connection could be in the smb2_sess_setup function which makes use of sess->user. Signed-off-by: Sean Heelan Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Nazar Kalashnikov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 362c50efbcbb..413340d317c4 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2255,10 +2255,6 @@ int smb2_session_logoff(struct ksmbd_work *work) sess->state = SMB2_SESSION_EXPIRED; up_write(&conn->session_lock); - if (sess->user) { - ksmbd_free_user(sess->user); - sess->user = NULL; - } ksmbd_all_conn_set_status(sess_id, KSMBD_SESS_NEED_SETUP); rsp->StructureSize = cpu_to_le16(4); -- Gitee From 077edb87db9644fdd7674a986b392e062b18fd54 Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Wed, 3 Dec 2025 03:26:37 +0800 Subject: [PATCH 0174/1449] net: dsa: microchip: Fix symetry in ksz_ptp_msg_irq_{setup/free}() ANBZ: #35228 commit 3b5a6115d6ea45df1ea65dc9b832b23db5d593ba stable. commit d0b8fec8ae50525b57139393d0bb1f446e82ff7e upstream. The IRQ numbers created through irq_create_mapping() are only assigned to ptpmsg_irq[n].num at the end of the IRQ setup. So if an error occurs between their creation and their assignment (for instance during the request_threaded_irq() step), we enter the error path and fail to release the newly created virtual IRQs because they aren't yet assigned to ptpmsg_irq[n].num. Move the mapping creation to ksz_ptp_msg_irq_setup() to ensure symetry with what's released by ksz_ptp_msg_irq_free(). In the error path, move the irq_dispose_mapping to the out_ptp_msg label so it will be called only on created IRQs. Cc: stable@vger.kernel.org Fixes: cc13ab18b201 ("net: dsa: microchip: ptp: enable interrupt for timestamping") Reviewed-by: Andrew Lunn Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20251120-ksz-fix-v6-5-891f80ae7f8f@bootlin.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/microchip/ksz_ptp.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c index dca0c5124457..3783d20d673b 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.c +++ b/drivers/net/dsa/microchip/ksz_ptp.c @@ -1099,19 +1099,19 @@ static int ksz_ptp_msg_irq_setup(struct ksz_port *port, u8 n) static const char * const name[] = {"pdresp-msg", "xdreq-msg", "sync-msg"}; const struct ksz_dev_ops *ops = port->ksz_dev->dev_ops; + struct ksz_irq *ptpirq = &port->ptpirq; struct ksz_ptp_irq *ptpmsg_irq; ptpmsg_irq = &port->ptpmsg_irq[n]; + ptpmsg_irq->num = irq_create_mapping(ptpirq->domain, n); + if (!ptpmsg_irq->num) + return -EINVAL; ptpmsg_irq->port = port; ptpmsg_irq->ts_reg = ops->get_port_addr(port->num, ts_reg[n]); snprintf(ptpmsg_irq->name, sizeof(ptpmsg_irq->name), name[n]); - ptpmsg_irq->num = irq_find_mapping(port->ptpirq.domain, n); - if (ptpmsg_irq->num < 0) - return ptpmsg_irq->num; - return request_threaded_irq(ptpmsg_irq->num, NULL, ksz_ptp_msg_thread_fn, IRQF_ONESHOT, ptpmsg_irq->name, ptpmsg_irq); @@ -1141,9 +1141,6 @@ int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p) if (!ptpirq->domain) return -ENOMEM; - for (irq = 0; irq < ptpirq->nirqs; irq++) - irq_create_mapping(ptpirq->domain, irq); - ptpirq->irq_num = irq_find_mapping(port->pirq.domain, PORT_SRC_PTP_INT); if (!ptpirq->irq_num) { ret = -EINVAL; @@ -1165,12 +1162,11 @@ int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p) out_ptp_msg: free_irq(ptpirq->irq_num, ptpirq); - while (irq--) + while (irq--) { free_irq(port->ptpmsg_irq[irq].num, &port->ptpmsg_irq[irq]); -out: - for (irq = 0; irq < ptpirq->nirqs; irq++) irq_dispose_mapping(port->ptpmsg_irq[irq].num); - + } +out: irq_domain_remove(ptpirq->domain); return ret; -- Gitee From efdcb3426486a293b25efaab7589e3d93507af00 Mon Sep 17 00:00:00 2001 From: "Bastien Curutchet (Schneider Electric)" Date: Wed, 3 Dec 2025 04:15:07 +0800 Subject: [PATCH 0175/1449] net: dsa: microchip: Free previously initialized ports on init failures ANBZ: #35228 commit e7e8e9b1a1b1c8d4803fdb90354d4db04f05d210 stable. commit 0f80e21bf6229637e193248fbd284c0ec44bc0fd upstream. If a port interrupt setup fails after at least one port has already been successfully initialized, the gotos miss some resource releasing: - the already initialized PTP IRQs aren't released - the already initialized port IRQs aren't released if the failure occurs in ksz_pirq_setup(). Merge 'out_girq' and 'out_ptpirq' into a single 'port_release' label. Behind this label, use the reverse loop to release all IRQ resources for all initialized ports. Jump in the middle of the reverse loop if an error occurs in ksz_ptp_irq_setup() to only release the port IRQ of the current iteration. Cc: stable@vger.kernel.org Fixes: c9cd961c0d43 ("net: dsa: microchip: lan937x: add interrupt support for port phy link") Signed-off-by: Bastien Curutchet (Schneider Electric) Link: https://patch.msgid.link/20251120-ksz-fix-v6-4-891f80ae7f8f@bootlin.com Signed-off-by: Paolo Abeni [ replaced dsa_switch_for_each_user_port_continue_reverse() macro with dsa_switch_for_each_port_continue_reverse() plus manual dsa_port_is_user() check ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/microchip/ksz_common.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index a3c5a174e302..651b81b278b2 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -2163,18 +2163,18 @@ static int ksz_setup(struct dsa_switch *ds) dsa_switch_for_each_user_port(dp, dev->ds) { ret = ksz_pirq_setup(dev, dp->index); if (ret) - goto out_girq; + goto port_release; ret = ksz_ptp_irq_setup(ds, dp->index); if (ret) - goto out_pirq; + goto pirq_release; } } ret = ksz_ptp_clock_register(ds); if (ret) { dev_err(dev->dev, "Failed to register PTP clock: %d\n", ret); - goto out_ptpirq; + goto port_release; } ret = ksz_mdio_register(dev); @@ -2191,17 +2191,17 @@ static int ksz_setup(struct dsa_switch *ds) out_ptp_clock_unregister: ksz_ptp_clock_unregister(ds); -out_ptpirq: - if (dev->irq > 0) - dsa_switch_for_each_user_port(dp, dev->ds) +port_release: + if (dev->irq > 0) { + dsa_switch_for_each_port_continue_reverse(dp, dev->ds) { + if (!dsa_port_is_user(dp)) + continue; ksz_ptp_irq_free(ds, dp->index); -out_pirq: - if (dev->irq > 0) - dsa_switch_for_each_user_port(dp, dev->ds) +pirq_release: ksz_irq_free(&dev->ports[dp->index].pirq); -out_girq: - if (dev->irq > 0) + } ksz_irq_free(&dev->girq); + } return ret; } -- Gitee From bd0028b128a89dc9c3ba4d1dcdfe9347ba779f1d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 3 Dec 2025 19:23:18 +0800 Subject: [PATCH 0176/1449] HID: core: Harden s32ton() against conversion to 0 bits ANBZ: #35228 commit 810189546cb6c8f36443ed091d91f1f5d2fc2ec7 stable. commit a6b87bfc2ab5bccb7ad953693c85d9062aef3fdd upstream. Testing by the syzbot fuzzer showed that the HID core gets a shift-out-of-bounds exception when it tries to convert a 32-bit quantity to a 0-bit quantity. Ideally this should never occur, but there are buggy devices and some might have a report field with size set to zero; we shouldn't reject the report or the device just because of that. Instead, harden the s32ton() routine so that it returns a reasonable result instead of crashing when it is called with the number of bits set to 0 -- the same as what snto32() does. Signed-off-by: Alan Stern Reported-by: syzbot+b63d677d63bcac06cf90@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-usb/68753a08.050a0220.33d347.0008.GAE@google.com/ Tested-by: syzbot+b63d677d63bcac06cf90@syzkaller.appspotmail.com Fixes: dde5845a529f ("[PATCH] Generic HID layer - code split") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/613a66cd-4309-4bce-a4f7-2905f9bce0c9@rowland.harvard.edu Signed-off-by: Benjamin Tissoires [ s32ton() was moved by c653ffc28340 ("HID: stop exporting hid_snto32()"). Minor context change fixed. ] Signed-off-by: Wenshan Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 266cd56dec50..d8fda282d049 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1351,7 +1351,12 @@ EXPORT_SYMBOL_GPL(hid_snto32); static u32 s32ton(__s32 value, unsigned n) { - s32 a = value >> (n - 1); + s32 a; + + if (!value || !n) + return 0; + + a = value >> (n - 1); if (a && a != -1) return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; return value & ((1 << n) - 1); -- Gitee From 11ed065aa43d09d657a4f8ced468ced11b4bfc8e Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Wed, 30 Jul 2025 05:11:53 +0800 Subject: [PATCH 0177/1449] Revert "xfrm: destroy xfrm_state synchronously on net exit path" ANBZ: #35228 commit 88ed2012b8c72f2edc9782d42940c7dccdab25b6 stable. commit 2a198bbec6913ae1c90ec963750003c6213668c7 upstream. [Backport Note] We modify nbl_dev_notify_ipsec_hard_expire() to use xfrm_state_put(). This reverts commit f75a2804da391571563c4b6b29e7797787332673. With all states (whether user or kern) removed from the hashtables during deletion, there's no need for synchronous destruction of states. xfrm6_tunnel states still need to have been destroyed (which will be the case when its last user is deleted (not destroyed)) so that xfrm6_tunnel_free_spi removes it from the per-netns hashtable before the netns is destroyed. This has the benefit of skipping one synchronize_rcu per state (in __xfrm_state_destroy(sync=true)) when we exit a netns. Signed-off-by: Sabrina Dubroca Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../nebula-matrix/nbl/nbl_core/nbl_dev.c | 2 +- include/net/xfrm.h | 12 +++------- net/ipv6/xfrm6_tunnel.c | 2 +- net/key/af_key.c | 2 +- net/xfrm/xfrm_state.c | 23 ++++++++----------- net/xfrm/xfrm_user.c | 2 +- 6 files changed, 16 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c index 35417cc6482a..1f018aae5d76 100644 --- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c +++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c @@ -154,7 +154,7 @@ static __maybe_unused void nbl_dev_notify_ipsec_hard_expire(void *priv, u16 src_ if (x) { x->km.state = XFRM_STATE_EXPIRED; hrtimer_start(&x->mtimer, 0, HRTIMER_MODE_REL_SOFT); - xfrm_state_put_sync(x); + xfrm_state_put(x); } #endif } diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ca20cddf71fd..f8e1d3c5dd3b 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -811,7 +811,7 @@ static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) xfrm_pol_put(pols[i]); } -void __xfrm_state_destroy(struct xfrm_state *, bool); +void __xfrm_state_destroy(struct xfrm_state *); static inline void __xfrm_state_put(struct xfrm_state *x) { @@ -821,13 +821,7 @@ static inline void __xfrm_state_put(struct xfrm_state *x) static inline void xfrm_state_put(struct xfrm_state *x) { if (refcount_dec_and_test(&x->refcnt)) - __xfrm_state_destroy(x, false); -} - -static inline void xfrm_state_put_sync(struct xfrm_state *x) -{ - if (refcount_dec_and_test(&x->refcnt)) - __xfrm_state_destroy(x, true); + __xfrm_state_destroy(x); } static inline void xfrm_state_hold(struct xfrm_state *x) @@ -1663,7 +1657,7 @@ struct xfrmk_spdinfo { struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq); int xfrm_state_delete(struct xfrm_state *x); -int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync); +int xfrm_state_flush(struct net *net, u8 proto, bool task_valid); int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid); int xfrm_dev_policy_flush(struct net *net, struct net_device *dev, bool task_valid); diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 1702b4de1c1e..3645ab427e12 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -334,7 +334,7 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net) struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); unsigned int i; - xfrm_state_flush(net, 0, false, true); + xfrm_state_flush(net, IPSEC_PROTO_ANY, false); xfrm_flush_gc(); for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) diff --git a/net/key/af_key.c b/net/key/af_key.c index d68d01804dc7..6c4448908afe 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -1765,7 +1765,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, const struct sadb_m if (proto == 0) return -EINVAL; - err = xfrm_state_flush(net, proto, true, false); + err = xfrm_state_flush(net, proto, true); err2 = unicast_flush_resp(sk, hdr); if (err || err2) { if (err == -ESRCH) /* empty table - go quietly */ diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 7c8aeec4fe27..b0e2958342ad 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -521,7 +521,7 @@ void xfrm_state_free(struct xfrm_state *x) } EXPORT_SYMBOL(xfrm_state_free); -static void ___xfrm_state_destroy(struct xfrm_state *x) +static void xfrm_state_gc_destroy(struct xfrm_state *x) { hrtimer_cancel(&x->mtimer); del_timer_sync(&x->rtimer); @@ -559,7 +559,7 @@ static void xfrm_state_gc_task(struct work_struct *work) synchronize_rcu(); hlist_for_each_entry_safe(x, tmp, &gc_list, gclist) - ___xfrm_state_destroy(x); + xfrm_state_gc_destroy(x); } static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me) @@ -720,19 +720,14 @@ void xfrm_dev_state_free(struct xfrm_state *x) } #endif -void __xfrm_state_destroy(struct xfrm_state *x, bool sync) +void __xfrm_state_destroy(struct xfrm_state *x) { WARN_ON(x->km.state != XFRM_STATE_DEAD); - if (sync) { - synchronize_rcu(); - ___xfrm_state_destroy(x); - } else { - spin_lock_bh(&xfrm_state_gc_lock); - hlist_add_head(&x->gclist, &xfrm_state_gc_list); - spin_unlock_bh(&xfrm_state_gc_lock); - schedule_work(&xfrm_state_gc_work); - } + spin_lock_bh(&xfrm_state_gc_lock); + hlist_add_head(&x->gclist, &xfrm_state_gc_list); + spin_unlock_bh(&xfrm_state_gc_lock); + schedule_work(&xfrm_state_gc_work); } EXPORT_SYMBOL(__xfrm_state_destroy); @@ -840,7 +835,7 @@ xfrm_dev_state_flush_secctx_check(struct net *net, struct net_device *dev, bool } #endif -int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync) +int xfrm_state_flush(struct net *net, u8 proto, bool task_valid) { int i, err = 0, cnt = 0; @@ -2986,7 +2981,7 @@ void xfrm_state_fini(struct net *net) unsigned int sz; flush_work(&net->xfrm.state_hash_work); - xfrm_state_flush(net, 0, false, true); + xfrm_state_flush(net, IPSEC_PROTO_ANY, false); flush_work(&xfrm_state_gc_work); WARN_ON(!list_empty(&net->xfrm.state_all)); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 1d91b42e7997..5b3ab4532aec 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2380,7 +2380,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, struct xfrm_usersa_flush *p = nlmsg_data(nlh); int err; - err = xfrm_state_flush(net, p->proto, true, false); + err = xfrm_state_flush(net, p->proto, true); if (err) { if (err == -ESRCH) /* empty table */ return 0; -- Gitee From 9ed7948628832c8d55bdd9dbaa174f98b35c587a Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Fri, 5 Dec 2025 06:43:27 +0800 Subject: [PATCH 0178/1449] xfrm: also call xfrm_state_delete_tunnel at destroy time for states that were never added ANBZ: #35228 commit 763e5c351206c1e4d910db4a1159053f6263689c stable. commit 10deb69864840ccf96b00ac2ab3a2055c0c04721 upstream. In commit b441cf3f8c4b ("xfrm: delete x->tunnel as we delete x"), I missed the case where state creation fails between full initialization (->init_state has been called) and being inserted on the lists. In this situation, ->init_state has been called, so for IPcomp tunnels, the fallback tunnel has been created and added onto the lists, but the user state never gets added, because we fail before that. The user state doesn't go through __xfrm_state_delete, so we don't call xfrm_state_delete_tunnel for those states, and we end up leaking the FB tunnel. There are several codepaths affected by this: the add/update paths, in both net/key and xfrm, and the migrate code (xfrm_migrate, xfrm_state_migrate). A "proper" rollback of the init_state work would probably be doable in the add/update code, but for migrate it gets more complicated as multiple states may be involved. At some point, the new (not-inserted) state will be destroyed, so call xfrm_state_delete_tunnel during xfrm_state_gc_destroy. Most states will have their fallback tunnel cleaned up during __xfrm_state_delete, which solves the issue that b441cf3f8c4b (and other patches before it) aimed at. All states (including FB tunnels) will be removed from the lists once xfrm_state_fini has called flush_work(&xfrm_state_gc_work). Reported-by: syzbot+999eb23467f83f9bf9bf@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=999eb23467f83f9bf9bf Fixes: b441cf3f8c4b ("xfrm: delete x->tunnel as we delete x") Signed-off-by: Sabrina Dubroca Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/xfrm/xfrm_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index b0e2958342ad..3d806492e1de 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -521,6 +521,7 @@ void xfrm_state_free(struct xfrm_state *x) } EXPORT_SYMBOL(xfrm_state_free); +static void xfrm_state_delete_tunnel(struct xfrm_state *x); static void xfrm_state_gc_destroy(struct xfrm_state *x) { hrtimer_cancel(&x->mtimer); @@ -535,6 +536,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) kfree(x->preplay_esn); if (x->type_offload) xfrm_put_type_offload(x->type_offload); + xfrm_state_delete_tunnel(x); if (x->type) { x->type->destructor(x); xfrm_put_type(x->type); @@ -731,7 +733,6 @@ void __xfrm_state_destroy(struct xfrm_state *x) } EXPORT_SYMBOL(__xfrm_state_destroy); -static void xfrm_state_delete_tunnel(struct xfrm_state *x); int __xfrm_state_delete(struct xfrm_state *x) { struct net *net = xs_net(x); -- Gitee From d55351900232f878c3f54af35c357245ac9d0ea7 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Mon, 4 Aug 2025 17:05:43 +0800 Subject: [PATCH 0179/1449] xfrm: flush all states in xfrm_state_fini ANBZ: #35228 commit 25f34fd5214458829d491b97ff26a8d2570774fc stable. commit 42e42562c9cfcdacf000f1b42284a4fad24f8546 upstream. While reverting commit f75a2804da39 ("xfrm: destroy xfrm_state synchronously on net exit path"), I incorrectly changed xfrm_state_flush's "proto" argument back to IPSEC_PROTO_ANY. This reverts some of the changes in commit dbb2483b2a46 ("xfrm: clean up xfrm protocol checks"), and leads to some states not being removed when we exit the netns. Pass 0 instead of IPSEC_PROTO_ANY from both xfrm_state_fini xfrm6_tunnel_net_exit, so that xfrm_state_flush deletes all states. Fixes: 2a198bbec691 ("Revert "xfrm: destroy xfrm_state synchronously on net exit path"") Reported-by: syzbot+6641a61fe0e2e89ae8c5@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6641a61fe0e2e89ae8c5 Tested-by: syzbot+6641a61fe0e2e89ae8c5@syzkaller.appspotmail.com Signed-off-by: Sabrina Dubroca Reviewed-by: Simon Horman Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/xfrm6_tunnel.c | 2 +- net/xfrm/xfrm_state.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 3645ab427e12..775ae1171ef8 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -334,7 +334,7 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net) struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); unsigned int i; - xfrm_state_flush(net, IPSEC_PROTO_ANY, false); + xfrm_state_flush(net, 0, false); xfrm_flush_gc(); for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 3d806492e1de..5396fe6b90c6 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2982,7 +2982,7 @@ void xfrm_state_fini(struct net *net) unsigned int sz; flush_work(&net->xfrm.state_hash_work); - xfrm_state_flush(net, IPSEC_PROTO_ANY, false); + xfrm_state_flush(net, 0, false); flush_work(&xfrm_state_gc_work); WARN_ON(!list_empty(&net->xfrm.state_all)); -- Gitee From 127559f3bcde07e97eb236c9cd53f41ba9a897ce Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Sun, 4 Feb 2024 23:07:26 +0800 Subject: [PATCH 0180/1449] leds: spi-byte: Use devm_led_classdev_register_ext() ANBZ: #35228 commit 732fe5cbd6ad58cd37a746c7b57018fb0c9dc083 stable. commit ccc35ff2fd2911986b716a87fe65e03fac2312c9 upstream. Use extended classdev registration to generate generic device names from color and function enums instead of reading only the label from the device tree. Signed-off-by: Stefan Kalscheuer Link: https://lore.kernel.org/r/20240204150726.29783-1-stefan@stklcode.de Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/leds/leds-spi-byte.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c index afe9bff7c7c1..b04cf502e603 100644 --- a/drivers/leds/leds-spi-byte.c +++ b/drivers/leds/leds-spi-byte.c @@ -83,7 +83,7 @@ static int spi_byte_probe(struct spi_device *spi) struct device_node *child; struct device *dev = &spi->dev; struct spi_byte_led *led; - const char *name = "leds-spi-byte::"; + struct led_init_data init_data = {}; const char *state; int ret; @@ -96,12 +96,9 @@ static int spi_byte_probe(struct spi_device *spi) if (!led) return -ENOMEM; - of_property_read_string(child, "label", &name); - strscpy(led->name, name, sizeof(led->name)); led->spi = spi; mutex_init(&led->mutex); led->cdef = device_get_match_data(dev); - led->ldev.name = led->name; led->ldev.brightness = LED_OFF; led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value; led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking; @@ -121,7 +118,11 @@ static int spi_byte_probe(struct spi_device *spi) spi_byte_brightness_set_blocking(&led->ldev, led->ldev.brightness); - ret = devm_led_classdev_register(&spi->dev, &led->ldev); + init_data.fwnode = of_fwnode_handle(child); + init_data.devicename = "leds-spi-byte"; + init_data.default_label = ":"; + + ret = devm_led_classdev_register_ext(&spi->dev, &led->ldev, &init_data); if (ret) { of_node_put(child); mutex_destroy(&led->mutex); -- Gitee From e3e0b6dd80072ba452bdd432a58bdf680834a6e1 Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Wed, 22 Oct 2025 11:43:35 +0800 Subject: [PATCH 0181/1449] Documentation: process: Also mention Sasha Levin as stable tree maintainer ANBZ: #35228 commit 46c73ff89d73de579632c905e5b8f512ea8ee0f8 stable. commit ba2457109d5b47a90fe565b39524f7225fc23e60 upstream. Sasha has also maintaining stable branch in conjunction with Greg since cb5d21946d2a2f ("MAINTAINERS: Add Sasha as a stable branch maintainer"). Mention him in 2.Process.rst. Cc: stable@vger.kernel.org Signed-off-by: Bagas Sanjaya Reviewed-by: Randy Dunlap Acked-by: Greg Kroah-Hartman Signed-off-by: Jonathan Corbet Message-ID: <20251022034336.22839-1-bagasdotme@gmail.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/process/2.Process.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/process/2.Process.rst b/Documentation/process/2.Process.rst index 613a01da4717..90045a4f8c70 100644 --- a/Documentation/process/2.Process.rst +++ b/Documentation/process/2.Process.rst @@ -104,8 +104,10 @@ kernels go out with a handful of known regressions though, hopefully, none of them are serious. Once a stable release is made, its ongoing maintenance is passed off to the -"stable team," currently Greg Kroah-Hartman. The stable team will release -occasional updates to the stable release using the 5.x.y numbering scheme. +"stable team," currently consists of Greg Kroah-Hartman and Sasha Levin. The +stable team will release occasional updates to the stable release using the +5.x.y numbering scheme. + To be considered for an update release, a patch must (1) fix a significant bug, and (2) already be merged into the mainline for the next development kernel. Kernels will typically receive stable updates for a little more -- Gitee From 0e14a304f8832f73054e2220100c54ece6f9dd97 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Sat, 25 Oct 2025 15:26:57 +0800 Subject: [PATCH 0182/1449] jbd2: avoid bug_on in jbd2_journal_get_create_access() when file system corrupted ANBZ: #35228 commit b4f8eabf6d991bd41fabcdf9302c4b3eab590cf4 stable. commit 986835bf4d11032bba4ab8414d18fce038c61bb4 upstream. There's issue when file system corrupted: ------------[ cut here ]------------ kernel BUG at fs/jbd2/transaction.c:1289! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 5 UID: 0 PID: 2031 Comm: mkdir Not tainted 6.18.0-rc1-next RIP: 0010:jbd2_journal_get_create_access+0x3b6/0x4d0 RSP: 0018:ffff888117aafa30 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffff88811a86b000 RCX: ffffffff89a63534 RDX: 1ffff110200ec602 RSI: 0000000000000004 RDI: ffff888100763010 RBP: ffff888100763000 R08: 0000000000000001 R09: ffff888100763028 R10: 0000000000000003 R11: 0000000000000000 R12: 0000000000000000 R13: ffff88812c432000 R14: ffff88812c608000 R15: ffff888120bfc000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f91d6970c99 CR3: 00000001159c4000 CR4: 00000000000006f0 Call Trace: __ext4_journal_get_create_access+0x42/0x170 ext4_getblk+0x319/0x6f0 ext4_bread+0x11/0x100 ext4_append+0x1e6/0x4a0 ext4_init_new_dir+0x145/0x1d0 ext4_mkdir+0x326/0x920 vfs_mkdir+0x45c/0x740 do_mkdirat+0x234/0x2f0 __x64_sys_mkdir+0xd6/0x120 do_syscall_64+0x5f/0xfa0 entry_SYSCALL_64_after_hwframe+0x76/0x7e The above issue occurs with us in errors=continue mode when accompanied by storage failures. There have been many inconsistencies in the file system data. In the case of file system data inconsistency, for example, if the block bitmap of a referenced block is not set, it can lead to the situation where a block being committed is allocated and used again. As a result, the following condition will not be satisfied then trigger BUG_ON. Of course, it is entirely possible to construct a problematic image that can trigger this BUG_ON through specific operations. In fact, I have constructed such an image and easily reproduced this issue. Therefore, J_ASSERT() holds true only under ideal conditions, but it may not necessarily be satisfied in exceptional scenarios. Using J_ASSERT() directly in abnormal situations would cause the system to crash, which is clearly not what we want. So here we directly trigger a JBD abort instead of immediately invoking BUG_ON. Fixes: 470decc613ab ("[PATCH] jbd2: initial copy of files from jbd") Signed-off-by: Ye Bin Reviewed-by: Jan Kara Message-ID: <20251025072657.307851-1-yebin@huaweicloud.com> Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/jbd2/transaction.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 4b37ad2ad8de..e6f507c3a685 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1287,14 +1287,23 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) * committing transaction's lists, but it HAS to be in Forget state in * that case: the transaction must have deleted the buffer for it to be * reused here. + * In the case of file system data inconsistency, for example, if the + * block bitmap of a referenced block is not set, it can lead to the + * situation where a block being committed is allocated and used again. + * As a result, the following condition will not be satisfied, so here + * we directly trigger a JBD abort instead of immediately invoking + * bugon. */ spin_lock(&jh->b_state_lock); - J_ASSERT_JH(jh, (jh->b_transaction == transaction || - jh->b_transaction == NULL || - (jh->b_transaction == journal->j_committing_transaction && - jh->b_jlist == BJ_Forget))); + if (!(jh->b_transaction == transaction || jh->b_transaction == NULL || + (jh->b_transaction == journal->j_committing_transaction && + jh->b_jlist == BJ_Forget)) || jh->b_next_transaction != NULL) { + err = -EROFS; + spin_unlock(&jh->b_state_lock); + jbd2_journal_abort(journal, err); + goto out; + } - J_ASSERT_JH(jh, jh->b_next_transaction == NULL); J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); if (jh->b_transaction == NULL) { -- Gitee From 749c8ae3b1a96f73858bb0e6195ec45f555ad391 Mon Sep 17 00:00:00 2001 From: Deepanshu Kartikey Date: Mon, 20 Oct 2025 14:09:36 +0800 Subject: [PATCH 0183/1449] ext4: refresh inline data size before write operations ANBZ: #35228 commit 1687a055a555347b002f406676a1aaae4668f242 stable. commit 892e1cf17555735e9d021ab036c36bc7b58b0e3b upstream. The cached ei->i_inline_size can become stale between the initial size check and when ext4_update_inline_data()/ext4_create_inline_data() use it. Although ext4_get_max_inline_size() reads the correct value at the time of the check, concurrent xattr operations can modify i_inline_size before ext4_write_lock_xattr() is acquired. This causes ext4_update_inline_data() and ext4_create_inline_data() to work with stale capacity values, leading to a BUG_ON() crash in ext4_write_inline_data(): kernel BUG at fs/ext4/inline.c:1331! BUG_ON(pos + len > EXT4_I(inode)->i_inline_size); The race window: 1. ext4_get_max_inline_size() reads i_inline_size = 60 (correct) 2. Size check passes for 50-byte write 3. [Another thread adds xattr, i_inline_size changes to 40] 4. ext4_write_lock_xattr() acquires lock 5. ext4_update_inline_data() uses stale i_inline_size = 60 6. Attempts to write 50 bytes but only 40 bytes actually available 7. BUG_ON() triggers Fix this by recalculating i_inline_size via ext4_find_inline_data_nolock() immediately after acquiring xattr_sem. This ensures ext4_update_inline_data() and ext4_create_inline_data() work with current values that are protected from concurrent modifications. This is similar to commit a54c4613dac1 ("ext4: fix race writing to an inline_data file while its xattrs are changing") which fixed i_inline_off staleness. This patch addresses the related i_inline_size staleness issue. Reported-by: syzbot+f3185be57d7e8dda32b8@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=f3185be57d7e8dda32b8 Cc: stable@kernel.org Signed-off-by: Deepanshu Kartikey Message-ID: <20251020060936.474314-1-kartikey406@gmail.com> Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/inline.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 2ae65a246abd..6ed3361cace2 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -413,7 +413,12 @@ static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode, return -ENOSPC; ext4_write_lock_xattr(inode, &no_expand); - + /* + * ei->i_inline_size may have changed since the initial check + * if other xattrs were added. Recalculate to ensure + * ext4_update_inline_data() validates against current capacity. + */ + (void) ext4_find_inline_data_nolock(inode); if (ei->i_inline_off) ret = ext4_update_inline_data(handle, inode, len); else -- Gitee From 472b5400b9773cf8bf05de26b153b1811c525d47 Mon Sep 17 00:00:00 2001 From: Qianchang Zhao Date: Wed, 26 Nov 2025 11:24:18 +0800 Subject: [PATCH 0184/1449] ksmbd: ipc: fix use-after-free in ipc_msg_send_request ANBZ: #35228 commit 708a620b471a14466f1f52c90bf3f65ebdb31460 stable. commit 1fab1fa091f5aa97265648b53ea031deedd26235 upstream. ipc_msg_send_request() waits for a generic netlink reply using an ipc_msg_table_entry on the stack. The generic netlink handler (handle_generic_event()/handle_response()) fills entry->response under ipc_msg_table_lock, but ipc_msg_send_request() used to validate and free entry->response without holding the same lock. Under high concurrency this allows a race where handle_response() is copying data into entry->response while ipc_msg_send_request() has just freed it, leading to a slab-use-after-free reported by KASAN in handle_generic_event(): BUG: KASAN: slab-use-after-free in handle_generic_event+0x3c4/0x5f0 [ksmbd] Write of size 12 at addr ffff888198ee6e20 by task pool/109349 ... Freed by task: kvfree ipc_msg_send_request [ksmbd] ksmbd_rpc_open -> ksmbd_session_rpc_open [ksmbd] Fix by: - Taking ipc_msg_table_lock in ipc_msg_send_request() while validating entry->response, freeing it when invalid, and removing the entry from ipc_msg_table. - Returning the final entry->response pointer to the caller only after the hash entry is removed under the lock. - Returning NULL in the error path, preserving the original API semantics. This makes all accesses to entry->response consistent with handle_response(), which already updates and fills the response buffer under ipc_msg_table_lock, and closes the race that allowed the UAF. Cc: stable@vger.kernel.org Reported-by: Qianchang Zhao Reported-by: Zhitong Liu Signed-off-by: Qianchang Zhao Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/transport_ipc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c index 36e1e52c30a0..a5b90d0b9f2d 100644 --- a/fs/smb/server/transport_ipc.c +++ b/fs/smb/server/transport_ipc.c @@ -520,12 +520,16 @@ static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle up_write(&ipc_msg_table_lock); ret = ipc_msg_send(msg); - if (ret) + if (ret) { + down_write(&ipc_msg_table_lock); goto out; + } ret = wait_event_interruptible_timeout(entry.wait, entry.response != NULL, IPC_WAIT_TIMEOUT); + + down_write(&ipc_msg_table_lock); if (entry.response) { ret = ipc_validate_msg(&entry); if (ret) { @@ -534,7 +538,6 @@ static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle } } out: - down_write(&ipc_msg_table_lock); hash_del(&entry.ipc_table_hlist); up_write(&ipc_msg_table_lock); return entry.response; -- Gitee From 6458115fe70ffdeb84e8389cdebd3d5f017675fa Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 19 Sep 2025 17:12:38 +0800 Subject: [PATCH 0185/1449] locking/spinlock/debug: Fix data-race in do_raw_write_lock ANBZ: #35228 commit 39d2ef113416f1a4205b03fb0aa2e428d1412c77 stable. commit c14ecb555c3ee80eeb030a4e46d00e679537f03a upstream. KCSAN reports: BUG: KCSAN: data-race in do_raw_write_lock / do_raw_write_lock write (marked) to 0xffff800009cf504c of 4 bytes by task 1102 on cpu 1: do_raw_write_lock+0x120/0x204 _raw_write_lock_irq do_exit call_usermodehelper_exec_async ret_from_fork read to 0xffff800009cf504c of 4 bytes by task 1103 on cpu 0: do_raw_write_lock+0x88/0x204 _raw_write_lock_irq do_exit call_usermodehelper_exec_async ret_from_fork value changed: 0xffffffff -> 0x00000001 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 1103 Comm: kworker/u4:1 6.1.111 Commit 1a365e822372 ("locking/spinlock/debug: Fix various data races") has adressed most of these races, but seems to be not consistent/not complete. >From do_raw_write_lock() only debug_write_lock_after() part has been converted to WRITE_ONCE(), but not debug_write_lock_before() part. Do it now. Fixes: 1a365e822372 ("locking/spinlock/debug: Fix various data races") Reported-by: Adrian Freihofer Signed-off-by: Alexander Sverdlin Signed-off-by: Boqun Feng Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Paul E. McKenney Acked-by: Waiman Long Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/locking/spinlock_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c index 14235671a1a7..dae38b6cfe4c 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c @@ -183,8 +183,8 @@ void do_raw_read_unlock(rwlock_t *lock) static inline void debug_write_lock_before(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); - RWLOCK_BUG_ON(lock->owner == current, lock, "recursion"); - RWLOCK_BUG_ON(lock->owner_cpu == raw_smp_processor_id(), + RWLOCK_BUG_ON(READ_ONCE(lock->owner) == current, lock, "recursion"); + RWLOCK_BUG_ON(READ_ONCE(lock->owner_cpu) == raw_smp_processor_id(), lock, "cpu recursion"); } -- Gitee From aaa70b035e303b2ded154d3d16c820a68feb75a8 Mon Sep 17 00:00:00 2001 From: Alexey Nepomnyashih Date: Tue, 4 Nov 2025 17:33:25 +0800 Subject: [PATCH 0186/1449] ext4: add i_data_sem protection in ext4_destroy_inline_data_nolock() ANBZ: #35228 commit 144c48da33a01d92995aeccd8208eb47d2a8e659 stable. commit 0cd8feea8777f8d9b9a862b89c688b049a5c8475 upstream. Fix a race between inline data destruction and block mapping. The function ext4_destroy_inline_data_nolock() changes the inode data layout by clearing EXT4_INODE_INLINE_DATA and setting EXT4_INODE_EXTENTS. At the same time, another thread may execute ext4_map_blocks(), which tests EXT4_INODE_EXTENTS to decide whether to call ext4_ext_map_blocks() or ext4_ind_map_blocks(). Without i_data_sem protection, ext4_ind_map_blocks() may receive inode with EXT4_INODE_EXTENTS flag and triggering assert. kernel BUG at fs/ext4/indirect.c:546! EXT4-fs (loop2): unmounting filesystem. invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:ext4_ind_map_blocks.cold+0x2b/0x5a fs/ext4/indirect.c:546 Call Trace: ext4_map_blocks+0xb9b/0x16f0 fs/ext4/inode.c:681 _ext4_get_block+0x242/0x590 fs/ext4/inode.c:822 ext4_block_write_begin+0x48b/0x12c0 fs/ext4/inode.c:1124 ext4_write_begin+0x598/0xef0 fs/ext4/inode.c:1255 ext4_da_write_begin+0x21e/0x9c0 fs/ext4/inode.c:3000 generic_perform_write+0x259/0x5d0 mm/filemap.c:3846 ext4_buffered_write_iter+0x15b/0x470 fs/ext4/file.c:285 ext4_file_write_iter+0x8e0/0x17f0 fs/ext4/file.c:679 call_write_iter include/linux/fs.h:2271 [inline] do_iter_readv_writev+0x212/0x3c0 fs/read_write.c:735 do_iter_write+0x186/0x710 fs/read_write.c:861 vfs_iter_write+0x70/0xa0 fs/read_write.c:902 iter_file_splice_write+0x73b/0xc90 fs/splice.c:685 do_splice_from fs/splice.c:763 [inline] direct_splice_actor+0x10f/0x170 fs/splice.c:950 splice_direct_to_actor+0x33a/0xa10 fs/splice.c:896 do_splice_direct+0x1a9/0x280 fs/splice.c:1002 do_sendfile+0xb13/0x12c0 fs/read_write.c:1255 __do_sys_sendfile64 fs/read_write.c:1323 [inline] __se_sys_sendfile64 fs/read_write.c:1309 [inline] __x64_sys_sendfile64+0x1cf/0x210 fs/read_write.c:1309 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 Fixes: c755e251357a ("ext4: fix deadlock between inline_data and ext4_expand_extra_isize_ea()") Cc: stable@vger.kernel.org # v4.11+ Signed-off-by: Alexey Nepomnyashih Message-ID: <20251104093326.697381-1-sdl@nppct.ru> Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/inline.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 6ed3361cace2..f560e2526b02 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -446,9 +446,13 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle, if (!ei->i_inline_off) return 0; + down_write(&ei->i_data_sem); + error = ext4_get_inode_loc(inode, &is.iloc); - if (error) + if (error) { + up_write(&ei->i_data_sem); return error; + } error = ext4_xattr_ibody_find(inode, &i, &is); if (error) @@ -487,6 +491,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle, brelse(is.iloc.bh); if (error == -ENODATA) error = 0; + up_write(&ei->i_data_sem); return error; } -- Gitee From b42a41816ecf4b5fd881d81e6cdd0a7da87f5ebb Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Thu, 23 Oct 2025 22:14:56 +0800 Subject: [PATCH 0187/1449] comedi: pcl818: fix null-ptr-deref in pcl818_ai_cancel() ANBZ: #35228 commit 88d99ca5adbd01ff088f5fb2ddeba5755e085e52 stable. commit a51f025b5038abd3d22eed2ede4cd46793d89565 upstream. Syzbot identified an issue [1] in pcl818_ai_cancel(), which stems from the fact that in case of early device detach via pcl818_detach(), subdevice dev->read_subdev may not have initialized its pointer to &struct comedi_async as intended. Thus, any such dereferencing of &s->async->cmd will lead to general protection fault and kernel crash. Mitigate this problem by removing a call to pcl818_ai_cancel() from pcl818_detach() altogether. This way, if the subdevice setups its support for async commands, everything async-related will be handled via subdevice's own ->cancel() function in comedi_device_detach_locked() even before pcl818_detach(). If no support for asynchronous commands is provided, there is no need to cancel anything either. [1] Syzbot crash: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] CPU: 1 UID: 0 PID: 6050 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025 RIP: 0010:pcl818_ai_cancel+0x69/0x3f0 drivers/comedi/drivers/pcl818.c:762 ... Call Trace: pcl818_detach+0x66/0xd0 drivers/comedi/drivers/pcl818.c:1115 comedi_device_detach_locked+0x178/0x750 drivers/comedi/drivers.c:207 do_devconfig_ioctl drivers/comedi/comedi_fops.c:848 [inline] comedi_unlocked_ioctl+0xcde/0x1020 drivers/comedi/comedi_fops.c:2178 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] ... Reported-by: syzbot+fce5d9d5bd067d6fbe9b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=fce5d9d5bd067d6fbe9b Fixes: 00aba6e7b565 ("staging: comedi: pcl818: remove 'neverending_ai' from private data") Cc: stable Signed-off-by: Nikita Zhandarovich Reviewed-by: Ian Abbott Link: https://patch.msgid.link/20251023141457.398685-1-n.zhandarovich@fintech.ru Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/comedi/drivers/pcl818.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/comedi/drivers/pcl818.c b/drivers/comedi/drivers/pcl818.c index 29e503de8267..c5b60616967e 100644 --- a/drivers/comedi/drivers/pcl818.c +++ b/drivers/comedi/drivers/pcl818.c @@ -1111,10 +1111,9 @@ static void pcl818_detach(struct comedi_device *dev) { struct pcl818_private *devpriv = dev->private; - if (devpriv) { - pcl818_ai_cancel(dev, dev->read_subdev); + if (devpriv) pcl818_reset(dev); - } + pcl818_free_dma(dev); comedi_legacy_detach(dev); } -- Gitee From 9044de4545f5e2237c003d1e5f1c6c3d48b464ca Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Wed, 5 Nov 2025 01:55:26 +0800 Subject: [PATCH 0188/1449] KVM: SVM: Don't skip unrelated instruction if INT3/INTO is replaced ANBZ: #35228 commit 152289a51107ef45bbfe9b4aeeaa584a503042b5 stable. commit 4da3768e1820cf15cced390242d8789aed34f54d upstream. When re-injecting a soft interrupt from an INT3, INT0, or (select) INTn instruction, discard the exception and retry the instruction if the code stream is changed (e.g. by a different vCPU) between when the CPU executes the instruction and when KVM decodes the instruction to get the next RIP. As effectively predicted by commit 6ef88d6e36c2 ("KVM: SVM: Re-inject INT3/INTO instead of retrying the instruction"), failure to verify that the correct INTn instruction was decoded can effectively clobber guest state due to decoding the wrong instruction and thus specifying the wrong next RIP. The bug most often manifests as "Oops: int3" panics on static branch checks in Linux guests. Enabling or disabling a static branch in Linux uses the kernel's "text poke" code patching mechanism. To modify code while other CPUs may be executing that code, Linux (temporarily) replaces the first byte of the original instruction with an int3 (opcode 0xcc), then patches in the new code stream except for the first byte, and finally replaces the int3 with the first byte of the new code stream. If a CPU hits the int3, i.e. executes the code while it's being modified, then the guest kernel must look up the RIP to determine how to handle the #BP, e.g. by emulating the new instruction. If the RIP is incorrect, then this lookup fails and the guest kernel panics. The bug reproduces almost instantly by hacking the guest kernel to repeatedly check a static branch[1] while running a drgn script[2] on the host to constantly swap out the memory containing the guest's TSS. [1]: https://gist.github.com/osandov/44d17c51c28c0ac998ea0334edf90b5a [2]: https://gist.github.com/osandov/10e45e45afa29b11e0c7209247afc00b Fixes: 6ef88d6e36c2 ("KVM: SVM: Re-inject INT3/INTO instead of retrying the instruction") Cc: stable@vger.kernel.org Co-developed-by: Sean Christopherson Signed-off-by: Omar Sandoval Link: https://patch.msgid.link/1cc6dcdf36e3add7ee7c8d90ad58414eeb6c3d34.1762278762.git.osandov@fb.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/include/asm/kvm_host.h | 9 +++++++++ arch/x86/kvm/svm/svm.c | 24 +++++++++++++----------- arch/x86/kvm/x86.c | 21 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 06865907772f..346e0c317a6e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1974,6 +1974,11 @@ u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); * the gfn, i.e. retrying the instruction will hit a * !PRESENT fault, which results in a new shadow page * and sends KVM back to square one. + * + * EMULTYPE_SKIP_SOFT_INT - Set in combination with EMULTYPE_SKIP to only skip + * an instruction if it could generate a given software + * interrupt, which must be encoded via + * EMULTYPE_SET_SOFT_INT_VECTOR(). */ #define EMULTYPE_NO_DECODE (1 << 0) #define EMULTYPE_TRAP_UD (1 << 1) @@ -1984,6 +1989,10 @@ u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu); #define EMULTYPE_PF (1 << 6) #define EMULTYPE_COMPLETE_USER_EXIT (1 << 7) #define EMULTYPE_WRITE_PF_TO_SP (1 << 8) +#define EMULTYPE_SKIP_SOFT_INT (1 << 9) + +#define EMULTYPE_SET_SOFT_INT_VECTOR(v) ((u32)((v) & 0xff) << 16) +#define EMULTYPE_GET_SOFT_INT_VECTOR(e) (((e) >> 16) & 0xff) int kvm_emulate_instruction(struct kvm_vcpu *vcpu, int emulation_type); int kvm_emulate_instruction_from_buffer(struct kvm_vcpu *vcpu, diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 96f0d371d937..8e31d0ed5460 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -384,6 +384,7 @@ static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, void *insn, int insn_len); static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, + int emul_type, bool commit_side_effects) { struct vcpu_svm *svm = to_svm(vcpu); @@ -413,7 +414,7 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, if (unlikely(!commit_side_effects)) old_rflags = svm->vmcb->save.rflags; - if (!kvm_emulate_instruction(vcpu, EMULTYPE_SKIP)) + if (!kvm_emulate_instruction(vcpu, emul_type)) return 0; if (unlikely(!commit_side_effects)) @@ -431,11 +432,13 @@ static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, static int svm_skip_emulated_instruction(struct kvm_vcpu *vcpu) { - return __svm_skip_emulated_instruction(vcpu, true); + return __svm_skip_emulated_instruction(vcpu, EMULTYPE_SKIP, true); } -static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu) +static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu, u8 vector) { + const int emul_type = EMULTYPE_SKIP | EMULTYPE_SKIP_SOFT_INT | + EMULTYPE_SET_SOFT_INT_VECTOR(vector); unsigned long rip, old_rip = kvm_rip_read(vcpu); struct vcpu_svm *svm = to_svm(vcpu); @@ -451,7 +454,7 @@ static int svm_update_soft_interrupt_rip(struct kvm_vcpu *vcpu) * in use, the skip must not commit any side effects such as clearing * the interrupt shadow or RFLAGS.RF. */ - if (!__svm_skip_emulated_instruction(vcpu, !nrips)) + if (!__svm_skip_emulated_instruction(vcpu, emul_type, !nrips)) return -EIO; rip = kvm_rip_read(vcpu); @@ -487,7 +490,7 @@ static void svm_inject_exception(struct kvm_vcpu *vcpu) kvm_deliver_exception_payload(vcpu, ex); if (kvm_exception_is_soft(ex->vector) && - svm_update_soft_interrupt_rip(vcpu)) + svm_update_soft_interrupt_rip(vcpu, ex->vector)) return; svm->vmcb->control.event_inj = ex->vector @@ -3702,11 +3705,12 @@ static bool svm_set_vnmi_pending(struct kvm_vcpu *vcpu) static void svm_inject_irq(struct kvm_vcpu *vcpu, bool reinjected) { + struct kvm_queued_interrupt *intr = &vcpu->arch.interrupt; struct vcpu_svm *svm = to_svm(vcpu); u32 type; - if (vcpu->arch.interrupt.soft) { - if (svm_update_soft_interrupt_rip(vcpu)) + if (intr->soft) { + if (svm_update_soft_interrupt_rip(vcpu, intr->nr)) return; type = SVM_EVTINJ_TYPE_SOFT; @@ -3714,12 +3718,10 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu, bool reinjected) type = SVM_EVTINJ_TYPE_INTR; } - trace_kvm_inj_virq(vcpu->arch.interrupt.nr, - vcpu->arch.interrupt.soft, reinjected); + trace_kvm_inj_virq(intr->nr, intr->soft, reinjected); ++vcpu->stat.irq_injections; - svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr | - SVM_EVTINJ_VALID | type; + svm->vmcb->control.event_inj = intr->nr | SVM_EVTINJ_VALID | type; } void svm_complete_interrupt_delivery(struct kvm_vcpu *vcpu, int delivery_mode, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5c44ac253491..3d3e26e1f5b2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8936,6 +8936,23 @@ static bool is_vmware_backdoor_opcode(struct x86_emulate_ctxt *ctxt) return false; } +static bool is_soft_int_instruction(struct x86_emulate_ctxt *ctxt, + int emulation_type) +{ + u8 vector = EMULTYPE_GET_SOFT_INT_VECTOR(emulation_type); + + switch (ctxt->b) { + case 0xcc: + return vector == BP_VECTOR; + case 0xcd: + return vector == ctxt->src.val; + case 0xce: + return vector == OF_VECTOR; + default: + return false; + } +} + /* * Decode an instruction for emulation. The caller is responsible for handling * code breakpoints. Note, manually detecting code breakpoints is unnecessary @@ -9026,6 +9043,10 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, * injecting single-step #DBs. */ if (emulation_type & EMULTYPE_SKIP) { + if (emulation_type & EMULTYPE_SKIP_SOFT_INT && + !is_soft_int_instruction(ctxt, emulation_type)) + return 0; + if (ctxt->mode != X86EMUL_MODE_PROT64) ctxt->eip = (u32)ctxt->_eip; else -- Gitee From a3d28e827a91ac717c6ce1c9e21a0fbcff8e6e9d Mon Sep 17 00:00:00 2001 From: Slark Xiao Date: Tue, 18 Nov 2025 14:45:28 +0800 Subject: [PATCH 0189/1449] USB: serial: option: add Foxconn T99W760 ANBZ: #35228 commit 85e8739c5ce78d664cac7cc55d91c95fcb0e0c33 stable. commit 7970b4969c4c99bcdaf105f9f39c6d2021f6d244 upstream. T99W760 is designed based on Qualcomm SDX35 (5G redcap) chip. There are three serial ports to be enumerated: Modem, NMEA and Diag. test evidence as below: T: Bus=03 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 4 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e123 Rev=05.15 S: Manufacturer=QCOM S: Product=SDXBAAGHA-IDP _SN:39A8D3E4 S: SerialNumber=39a8d3e4 C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms 0&1: MBIM, 2:Modem, 3:GNSS(non-serial port), 4: NMEA, 5:Diag Signed-off-by: Slark Xiao Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8cc4ed4857cd..58a8bde1e032 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2376,6 +2376,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe0f0, 0xff), /* Foxconn T99W373 MBIM */ .driver_info = RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe123, 0xff), /* Foxconn T99W760 MBIM */ + .driver_info = RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe145, 0xff), /* Foxconn T99W651 RNDIS */ .driver_info = RSVD(5) | RSVD(6) }, { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe15f, 0xff), /* Foxconn T99W709 */ -- Gitee From e8bef0e5cda44668d274e4c70822929e1ebea56f Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Wed, 26 Nov 2025 22:26:39 +0800 Subject: [PATCH 0190/1449] USB: serial: option: add Telit Cinterion FE910C04 new compositions ANBZ: #35228 commit 63d6bf5b19bfb0bc480bfbbb7fef26300e008080 stable. commit c908039a29aa70870871f4848125b3d743f929bf upstream. Add the following Telit Cinterion new compositions: 0x10c1: RNDIS + tty (AT/NMEA) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c1 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10c2: MBIM + tty (AT/NMEA) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c2 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10c3: ECM + tty (AT/NMEA) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c3 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10c5: RNDIS + tty (AT) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c5 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10c6: MBIM + tty (AT) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 11 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c6 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10c9: MBIM + tty (AT) + tty (diag) + DPL (Data Packet Logging) + adb T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 13 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c9 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 6 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10cb: RNDIS + tty (AT) + tty (diag) + DPL (Data Packet Logging) + adb T: Bus=01 Lev=01 Prnt=01 Port=09 Cnt=01 Dev#= 9 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10cb Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 6 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Cc: stable@vger.kernel.org Signed-off-by: Fabio Porcedda Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/option.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 58a8bde1e032..2da03fd58b00 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1433,10 +1433,24 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b3, 0xff, 0xff, 0x60) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c0, 0xff), /* Telit FE910C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c1, 0xff), /* Telit FE910C04 (RNDIS) */ + .driver_info = NCTRL(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c2, 0xff), /* Telit FE910C04 (MBIM) */ + .driver_info = NCTRL(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c3, 0xff), /* Telit FE910C04 (ECM) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c4, 0xff), /* Telit FE910C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c5, 0xff), /* Telit FE910C04 (RNDIS) */ + .driver_info = NCTRL(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c6, 0xff), /* Telit FE910C04 (MBIM) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c9, 0xff), /* Telit FE910C04 (MBIM) */ + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10cb, 0xff), /* Telit FE910C04 (RNDIS) */ + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x30), /* Telit FN990B (rmnet) */ .driver_info = NCTRL(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x40) }, -- Gitee From 07cb18faafac415e301b1d2660f7dc94d4eda17e Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Wed, 26 Nov 2025 22:26:40 +0800 Subject: [PATCH 0191/1449] USB: serial: option: move Telit 0x10c7 composition in the right place ANBZ: #35228 commit 510db76553c987dff33c2730debac317eaa16fe0 stable. commit 072f2c49572547f4b0776fe2da6b8f61e4b34699 upstream. Move Telit 0x10c7 composition right after 0x10c6 composition and before 0x10c8 composition. Signed-off-by: Fabio Porcedda Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/option.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2da03fd58b00..2dfbf62d934a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1445,6 +1445,9 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c6, 0xff), /* Telit FE910C04 (MBIM) */ .driver_info = NCTRL(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x30), /* Telit FE910C04 (ECM) */ + .driver_info = NCTRL(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x40) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c9, 0xff), /* Telit FE910C04 (MBIM) */ @@ -1455,9 +1458,6 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x60) }, - { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x30), /* Telit FE910C04 (ECM) */ - .driver_info = NCTRL(4) }, - { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x30), /* Telit FN990B (MBIM) */ .driver_info = NCTRL(6) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x40) }, -- Gitee From f29e2c860665a509d1566f91994f70bb6bac08de Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 10 Nov 2025 19:12:05 +0800 Subject: [PATCH 0192/1449] USB: serial: ftdi_sio: match on interface number for jtag ANBZ: #35228 commit 53a633786718578ff4f12a1d9737192da093d531 stable. commit 4e31a5d0a9ee672f708fc993c1d5520643f769fd upstream. Some FTDI devices have the first port reserved for JTAG and have been using a dedicated quirk to prevent binding to it. As can be inferred directly or indirectly from the commit messages, almost all of these devices are dual port devices which means that the more recently added macro for matching on interface number can be used instead (and some such devices do so already). This avoids probing interfaces that will never be bound and cleans up the match table somewhat. Note that the JTAG quirk is kept for quad port devices, which would otherwise require three match entries. Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/ftdi_sio.c | 72 ++++++++++++----------------------- 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2bc5d21ef6b9..53f36762de9b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -628,10 +628,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLXM_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_TIAO_UMPA_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_NT_ORIONLXM_PID, 1) }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLX_PLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORION_IO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONMX_PID) }, @@ -842,24 +840,17 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) }, - { USB_DEVICE(FTDI_VID, CYBER_CORTEX_AV_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, CYBER_CORTEX_AV_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_H_PID, 1) }, - { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FIC_VID, FIC_NEO1973_DEBUG_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_OOCDLINK_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_TURTELIZER_PID, 1) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) }, { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, @@ -901,17 +892,14 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(ATMEL_VID, STK541_PID) }, { USB_DEVICE(DE_VID, STB_PID) }, { USB_DEVICE(DE_VID, WHT_PID) }, - { USB_DEVICE(ADI_VID, ADI_GNICE_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(ADI_VID, ADI_GNICE_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(ADI_VID, ADI_GNICEPLUS_PID, 1) }, { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, USB_CLASS_VENDOR_SPEC, USB_SUBCLASS_VENDOR_SPEC, 0x00) }, { USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) }, { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, - { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(MARVELL_VID, MARVELL_SHEEVAPLUG_PID, 1) }, { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, { USB_DEVICE(FTDI_VID, PI_C865_PID) }, @@ -934,10 +922,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(PI_VID, PI_1016_PID) }, { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, - { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, MARVELL_OPENRD_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, TI_XDS100V2_PID, 1) }, { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, @@ -946,18 +932,14 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, { USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) }, { USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) }, - { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, XVERVE_SIGNALYZER_ST_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID, 1) }, { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, { USB_DEVICE(FTDI_VID, ACCESIO_COM4SM_PID) }, - { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(IONICS_VID, IONICS_PLUGCOMPUTER_PID, 1) }, { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) }, @@ -972,15 +954,12 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, { USB_DEVICE(FTDI_VID, FTDI_FHE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, - { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(ST_VID, ST_STMCLT_2232_PID, 1) }, { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID), .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, - { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID, 1) }, { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) }, /* Crucible Devices */ { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, @@ -1055,8 +1034,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, - { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(TI_VID, TI_CC3200_LAUNCHPAD_PID, 1) }, { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, { USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) }, @@ -1076,10 +1054,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, { USB_DEVICE_INTERFACE_NUMBER(UBLOX_VID, UBLOX_EVK_M101_PID, 2) }, /* FreeCalypso USB adapters */ - { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID, 1) }, + { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID, 1) }, /* GMC devices */ { USB_DEVICE(GMC_VID, GMC_Z216C_PID) }, /* Altera USB Blaster 3 */ -- Gitee From c586d48bdd20ee7b57687e15f73d52d91d810fe3 Mon Sep 17 00:00:00 2001 From: Magne Bruno Date: Tue, 11 Nov 2025 00:24:56 +0800 Subject: [PATCH 0193/1449] serial: add support of CPCI cards ANBZ: #35228 commit 5a8c2136dc5ea62ab284f6c5b5a016f978a5ea24 stable. commit 0e5a99e0e5f50353b86939ff6e424800d769c818 upstream. Addi-Data GmbH is manufacturing multi-serial ports cards supporting CompactPCI (known as CPCI). Those cards are identified with different DeviceIds. Those cards integrating standard UARTs work the same way as PCI/PCIe models already supported in the serial driver. Signed-off-by: Magne Bruno Link: https://patch.msgid.link/20251110162456.341029-1-magne.bruno@addi-data.com Cc: stable Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/tty/serial/8250/8250_pci.c | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 0b38fada4144..18fddd65c010 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1971,6 +1971,11 @@ pci_moxa_setup(struct serial_private *priv, #define PCI_DEVICE_ID_MOXA_CP138E_A 0x1381 #define PCI_DEVICE_ID_MOXA_CP168EL_A 0x1683 +#define PCI_DEVICE_ID_ADDIDATA_CPCI7500 0x7003 +#define PCI_DEVICE_ID_ADDIDATA_CPCI7500_NG 0x7024 +#define PCI_DEVICE_ID_ADDIDATA_CPCI7420_NG 0x7025 +#define PCI_DEVICE_ID_ADDIDATA_CPCI7300_NG 0x7026 + /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 @@ -5868,6 +5873,38 @@ static const struct pci_device_id serial_pci_tbl[] = { 0, pbn_ADDIDATA_PCIe_8_3906250 }, + { PCI_VENDOR_ID_ADDIDATA, + PCI_DEVICE_ID_ADDIDATA_CPCI7500, + PCI_ANY_ID, + PCI_ANY_ID, + 0, + 0, + pbn_b0_4_115200 }, + + { PCI_VENDOR_ID_ADDIDATA, + PCI_DEVICE_ID_ADDIDATA_CPCI7500_NG, + PCI_ANY_ID, + PCI_ANY_ID, + 0, + 0, + pbn_b0_4_115200 }, + + { PCI_VENDOR_ID_ADDIDATA, + PCI_DEVICE_ID_ADDIDATA_CPCI7420_NG, + PCI_ANY_ID, + PCI_ANY_ID, + 0, + 0, + pbn_b0_2_115200 }, + + { PCI_VENDOR_ID_ADDIDATA, + PCI_DEVICE_ID_ADDIDATA_CPCI7300_NG, + PCI_ANY_ID, + PCI_ANY_ID, + 0, + 0, + pbn_b0_1_115200 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, PCI_VENDOR_ID_IBM, 0x0299, 0, 0, pbn_b0_bt_2_115200 }, -- Gitee From 1c6f5fc80dd1abbf66dca27d78f3f9bd936a1109 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 22 Oct 2025 23:26:33 +0800 Subject: [PATCH 0194/1449] USB: serial: belkin_sa: fix TIOCMBIS and TIOCMBIC ANBZ: #35228 commit cae7aa183ca4bbf700168cbd59ba539d69268875 stable. commit b6e0b3016187446ddef9edac03cd9d544ac63f11 upstream. Asserting or deasserting a modem control line using TIOCMBIS or TIOCMBIC should not deassert any lines that are not in the mask. Fix this long-standing regression dating back to 2003 when the tiocmset() callback was introduced. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/belkin_sa.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index cf47ee4ae5d3..114f9bb5391e 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -436,7 +436,7 @@ static int belkin_sa_tiocmset(struct tty_struct *tty, struct belkin_sa_private *priv = usb_get_serial_port_data(port); unsigned long control_state; unsigned long flags; - int retval; + int retval = 0; int rts = 0; int dtr = 0; @@ -453,26 +453,32 @@ static int belkin_sa_tiocmset(struct tty_struct *tty, } if (clear & TIOCM_RTS) { control_state &= ~TIOCM_RTS; - rts = 0; + rts = 1; } if (clear & TIOCM_DTR) { control_state &= ~TIOCM_DTR; - dtr = 0; + dtr = 1; } priv->control_state = control_state; spin_unlock_irqrestore(&priv->lock, flags); - retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, rts); - if (retval < 0) { - dev_err(&port->dev, "Set RTS error %d\n", retval); - goto exit; + if (rts) { + retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, + !!(control_state & TIOCM_RTS)); + if (retval < 0) { + dev_err(&port->dev, "Set RTS error %d\n", retval); + goto exit; + } } - retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, dtr); - if (retval < 0) { - dev_err(&port->dev, "Set DTR error %d\n", retval); - goto exit; + if (dtr) { + retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, + !!(control_state & TIOCM_DTR)); + if (retval < 0) { + dev_err(&port->dev, "Set DTR error %d\n", retval); + goto exit; + } } exit: return retval; -- Gitee From b6897b743c41ba53cc605f5973b260c1e6bc8eaa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 22 Oct 2025 23:26:34 +0800 Subject: [PATCH 0195/1449] USB: serial: kobil_sct: fix TIOCMBIS and TIOCMBIC ANBZ: #35228 commit 3915997ad777febded109fd321a9e47174ef7e2e stable. commit d432df758f92c4c28aac409bc807fd1716167577 upstream. Asserting or deasserting a modem control line using TIOCMBIS or TIOCMBIC should not deassert any lines that are not in the mask. Fix this long-standing issue dating back to 2003 when the support for these ioctls was added with the introduction of the tiocmset() callback. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/kobil_sct.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 5e775f68fcb8..d57e2cedc9fa 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -420,7 +420,7 @@ static int kobil_tiocmset(struct tty_struct *tty, struct usb_serial_port *port = tty->driver_data; struct device *dev = &port->dev; struct kobil_private *priv; - int result; + int result = 0; int dtr = 0; int rts = 0; @@ -437,12 +437,12 @@ static int kobil_tiocmset(struct tty_struct *tty, if (set & TIOCM_DTR) dtr = 1; if (clear & TIOCM_RTS) - rts = 0; + rts = 1; if (clear & TIOCM_DTR) - dtr = 0; + dtr = 1; - if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { - if (dtr != 0) + if (dtr && priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) { + if (set & TIOCM_DTR) dev_dbg(dev, "%s - Setting DTR\n", __func__); else dev_dbg(dev, "%s - Clearing DTR\n", __func__); @@ -450,13 +450,13 @@ static int kobil_tiocmset(struct tty_struct *tty, usb_sndctrlpipe(port->serial->dev, 0), SUSBCRequest_SetStatusLinesOrQueues, USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR), + ((set & TIOCM_DTR) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR), 0, NULL, 0, KOBIL_TIMEOUT); - } else { - if (rts != 0) + } else if (rts) { + if (set & TIOCM_RTS) dev_dbg(dev, "%s - Setting RTS\n", __func__); else dev_dbg(dev, "%s - Clearing RTS\n", __func__); @@ -464,7 +464,7 @@ static int kobil_tiocmset(struct tty_struct *tty, usb_sndctrlpipe(port->serial->dev, 0), SUSBCRequest_SetStatusLinesOrQueues, USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, - ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS), + ((set & TIOCM_RTS) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS), 0, NULL, 0, -- Gitee From cda2c080994686304d4529b1e4db5258ee5594df Mon Sep 17 00:00:00 2001 From: Song Liu Date: Tue, 28 Oct 2025 01:50:22 +0800 Subject: [PATCH 0196/1449] ftrace: bpf: Fix IPMODIFY + DIRECT in modify_ftrace_direct() ANBZ: #35228 commit 27b2a8f45ed1231aaa39bc9b5ffe05a9ed37b34d stable. commit 3e9a18e1c3e931abecf501cbb23d28d69f85bb56 upstream. ftrace_hash_ipmodify_enable() checks IPMODIFY and DIRECT ftrace_ops on the same kernel function. When needed, ftrace_hash_ipmodify_enable() calls ops->ops_func() to prepare the direct ftrace (BPF trampoline) to share the same function as the IPMODIFY ftrace (livepatch). ftrace_hash_ipmodify_enable() is called in register_ftrace_direct() path, but not called in modify_ftrace_direct() path. As a result, the following operations will break livepatch: 1. Load livepatch to a kernel function; 2. Attach fentry program to the kernel function; 3. Attach fexit program to the kernel function. After 3, the kernel function being used will not be the livepatched version, but the original version. Fix this by adding __ftrace_hash_update_ipmodify() to __modify_ftrace_direct() and adjust some logic around the call. Signed-off-by: Song Liu Reviewed-by: Jiri Olsa Link: https://lore.kernel.org/r/20251027175023.1521602-3-song@kernel.org Signed-off-by: Alexei Starovoitov Acked-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/trace/ftrace.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 60e7bcb450b8..a5ba522d1a53 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1937,7 +1937,8 @@ static void ftrace_hash_rec_enable_modify(struct ftrace_ops *ops, */ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, struct ftrace_hash *old_hash, - struct ftrace_hash *new_hash) + struct ftrace_hash *new_hash, + bool update_target) { struct ftrace_page *pg; struct dyn_ftrace *rec, *end = NULL; @@ -1972,10 +1973,13 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, if (rec->flags & FTRACE_FL_DISABLED) continue; - /* We need to update only differences of filter_hash */ + /* + * Unless we are updating the target of a direct function, + * we only need to update differences of filter_hash + */ in_old = !!ftrace_lookup_ip(old_hash, rec->ip); in_new = !!ftrace_lookup_ip(new_hash, rec->ip); - if (in_old == in_new) + if (!update_target && (in_old == in_new)) continue; if (in_new) { @@ -1986,7 +1990,16 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, if (is_ipmodify) goto rollback; - FTRACE_WARN_ON(rec->flags & FTRACE_FL_DIRECT); + /* + * If this is called by __modify_ftrace_direct() + * then it is only changing where the direct + * pointer is jumping to, and the record already + * points to a direct trampoline. If it isn't, + * then it is a bug to update ipmodify on a direct + * caller. + */ + FTRACE_WARN_ON(!update_target && + (rec->flags & FTRACE_FL_DIRECT)); /* * Another ops with IPMODIFY is already @@ -2043,7 +2056,7 @@ static int ftrace_hash_ipmodify_enable(struct ftrace_ops *ops) if (ftrace_hash_empty(hash)) hash = NULL; - return __ftrace_hash_update_ipmodify(ops, EMPTY_HASH, hash); + return __ftrace_hash_update_ipmodify(ops, EMPTY_HASH, hash, false); } /* Disabling always succeeds */ @@ -2054,7 +2067,7 @@ static void ftrace_hash_ipmodify_disable(struct ftrace_ops *ops) if (ftrace_hash_empty(hash)) hash = NULL; - __ftrace_hash_update_ipmodify(ops, hash, EMPTY_HASH); + __ftrace_hash_update_ipmodify(ops, hash, EMPTY_HASH, false); } static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, @@ -2068,7 +2081,7 @@ static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, if (ftrace_hash_empty(new_hash)) new_hash = NULL; - return __ftrace_hash_update_ipmodify(ops, old_hash, new_hash); + return __ftrace_hash_update_ipmodify(ops, old_hash, new_hash, false); } static void print_ip_ins(const char *fmt, const unsigned char *p) @@ -5531,7 +5544,7 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_direct); static int __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) { - struct ftrace_hash *hash; + struct ftrace_hash *hash = ops->func_hash->filter_hash; struct ftrace_func_entry *entry, *iter; static struct ftrace_ops tmp_ops = { .func = ftrace_stub, @@ -5551,13 +5564,21 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) if (err) return err; + /* + * Call __ftrace_hash_update_ipmodify() here, so that we can call + * ops->ops_func for the ops. This is needed because the above + * register_ftrace_function_nolock() worked on tmp_ops. + */ + err = __ftrace_hash_update_ipmodify(ops, hash, hash, true); + if (err) + goto out; + /* * Now the ftrace_ops_list_func() is called to do the direct callers. * We can safely change the direct functions attached to each entry. */ mutex_lock(&ftrace_lock); - hash = ops->func_hash->filter_hash; size = 1 << hash->size_bits; for (i = 0; i < size; i++) { hlist_for_each_entry(iter, &hash->buckets[i], hlist) { @@ -5572,6 +5593,7 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) mutex_unlock(&ftrace_lock); +out: /* Removing the tmp_ops will add the updated direct callers to the functions */ unregister_ftrace_function(&tmp_ops); -- Gitee From 858104d0fc002710b9e53bc115f2a80cc5dd50d0 Mon Sep 17 00:00:00 2001 From: Alvaro Gamez Machado Date: Thu, 6 Nov 2025 21:45:35 +0800 Subject: [PATCH 0197/1449] spi: xilinx: increase number of retries before declaring stall ANBZ: #35228 commit 5f061d0ed9062560203d54c61d86dd53cffdc18a stable. commit 939edfaa10f1d22e6af6a84bf4bd96dc49c67302 upstream. SPI devices using a (relative) slow frequency need a larger time. For instance, microblaze running at 83.25MHz and performing a 3 bytes transaction using a 10MHz/16 = 625kHz needed this stall value increased to at least 20. The SPI device is quite slow, but also is the microblaze, so set this value to 32 to give it even more margin. Signed-off-by: Alvaro Gamez Machado Reviewed-by: Ricardo Ribalda Link: https://patch.msgid.link/20251106134545.31942-1-alvaro.gamez@hazent.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-xilinx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 8e6e3876aa9a..b5405d9974ba 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -299,7 +299,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) /* Read out all the data from the Rx FIFO */ rx_words = n_words; - stalled = 10; + stalled = 32; while (rx_words) { if (rx_words == n_words && !(stalled--) && !(sr & XSPI_SR_TX_EMPTY_MASK) && -- Gitee From 4a9ff5891af2651bbd9e3ffd93db9f98ba2bbf98 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Fri, 24 Oct 2025 13:53:20 +0800 Subject: [PATCH 0198/1449] spi: imx: keep dma request disabled before dma transfer setup ANBZ: #35228 commit 88edfeca040cbb533e4d9a40b6ff533605c3ca5d stable. commit 86d57d9c07d54e8cb385ffe800930816ccdba0c1 upstream. Since sdma hardware configure postpone to transfer phase, have to disable dma request before dma transfer setup because there is a hardware limitation on sdma event enable(ENBLn) as below: "It is thus essential for the Arm platform to program them before any DMA request is triggered to the SDMA, otherwise an unpredictable combination of channels may be started." Signed-off-by: Carlos Song Signed-off-by: Robin Gong Link: https://patch.msgid.link/20251024055320.408482-1-carlos.song@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-imx.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index da4442954375..76f8747c2943 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -503,9 +503,15 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx) { u32 reg; - reg = readl(spi_imx->base + MX51_ECSPI_CTRL); - reg |= MX51_ECSPI_CTRL_XCH; - writel(reg, spi_imx->base + MX51_ECSPI_CTRL); + if (spi_imx->usedma) { + reg = readl(spi_imx->base + MX51_ECSPI_DMA); + reg |= MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN; + writel(reg, spi_imx->base + MX51_ECSPI_DMA); + } else { + reg = readl(spi_imx->base + MX51_ECSPI_CTRL); + reg |= MX51_ECSPI_CTRL_XCH; + writel(reg, spi_imx->base + MX51_ECSPI_CTRL); + } } static void mx51_ecspi_disable(struct spi_imx_data *spi_imx) @@ -699,7 +705,6 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx) writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) | MX51_ECSPI_DMA_TX_WML(tx_wml) | MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) | - MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN | MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA); } @@ -1458,6 +1463,8 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, reinit_completion(&spi_imx->dma_tx_completion); dma_async_issue_pending(controller->dma_tx); + spi_imx->devtype_data->trigger(spi_imx); + transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len); /* Wait SDMA to finish the data transfer.*/ -- Gitee From 3fd74ef56d23b1ce52ae431103e82f49d5695c20 Mon Sep 17 00:00:00 2001 From: Ian Forbes Date: Fri, 31 Oct 2025 03:36:40 +0800 Subject: [PATCH 0199/1449] drm/vmwgfx: Use kref in vmw_bo_dirty ANBZ: #35228 commit d6c24a5e6cdc264722338ea64254780673a3050f stable. commit c1962742ffff7e245f935903a4658eb6f94f6058 upstream. Rather than using an ad hoc reference count use kref which is atomic and has underflow warnings. Signed-off-by: Ian Forbes Signed-off-by: Zack Rusin Link: https://patch.msgid.link/20251030193640.153697-1-ian.forbes@broadcom.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index 74ff2812d66a..de2498749e27 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -51,22 +51,22 @@ enum vmw_bo_dirty_method { /** * struct vmw_bo_dirty - Dirty information for buffer objects + * @ref_count: Reference count for this structure. Must be first member! * @start: First currently dirty bit * @end: Last currently dirty bit + 1 * @method: The currently used dirty method * @change_count: Number of consecutive method change triggers - * @ref_count: Reference count for this structure * @bitmap_size: The size of the bitmap in bits. Typically equal to the * nuber of pages in the bo. * @bitmap: A bitmap where each bit represents a page. A set bit means a * dirty page. */ struct vmw_bo_dirty { + struct kref ref_count; unsigned long start; unsigned long end; enum vmw_bo_dirty_method method; unsigned int change_count; - unsigned int ref_count; unsigned long bitmap_size; unsigned long bitmap[]; }; @@ -235,7 +235,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo) int ret; if (dirty) { - dirty->ref_count++; + kref_get(&dirty->ref_count); return 0; } @@ -249,7 +249,7 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo) dirty->bitmap_size = num_pages; dirty->start = dirty->bitmap_size; dirty->end = 0; - dirty->ref_count = 1; + kref_init(&dirty->ref_count); if (num_pages < PAGE_SIZE / sizeof(pte_t)) { dirty->method = VMW_BO_DIRTY_PAGETABLE; } else { @@ -288,10 +288,8 @@ void vmw_bo_dirty_release(struct vmw_bo *vbo) { struct vmw_bo_dirty *dirty = vbo->dirty; - if (dirty && --dirty->ref_count == 0) { - kvfree(dirty); + if (dirty && kref_put(&dirty->ref_count, (void *)kvfree)) vbo->dirty = NULL; - } } /** -- Gitee From 0f69f0513b803a06c192217e060020c55b7f7c2a Mon Sep 17 00:00:00 2001 From: Max Chou Date: Wed, 5 Nov 2025 20:02:04 +0800 Subject: [PATCH 0200/1449] Bluetooth: btrtl: Avoid loading the config file on security chips ANBZ: #35228 commit 2b37f5b27f1303954577eccd331f9f328696ab11 stable. commit cd8dbd9ef600435439bb0e70af0a1d9e2193aecb upstream. For chips with security enabled, it's only possible to load firmware with a valid signature pattern. If key_id is not zero, it indicates a security chip, and the driver will not load the config file. - Example log for a security chip. Bluetooth: hci0: RTL: examining hci_ver=0c hci_rev=000a lmp_ver=0c lmp_subver=8922 Bluetooth: hci0: RTL: rom_version status=0 version=1 Bluetooth: hci0: RTL: btrtl_initialize: key id 1 Bluetooth: hci0: RTL: loading rtl_bt/rtl8922au_fw.bin Bluetooth: hci0: RTL: cfg_sz 0, total sz 71301 Bluetooth: hci0: RTL: fw version 0x41c0c905 - Example log for a normal chip. Bluetooth: hci0: RTL: examining hci_ver=0c hci_rev=000a lmp_ver=0c lmp_subver=8922 Bluetooth: hci0: RTL: rom_version status=0 version=1 Bluetooth: hci0: RTL: btrtl_initialize: key id 0 Bluetooth: hci0: RTL: loading rtl_bt/rtl8922au_fw.bin Bluetooth: hci0: RTL: loading rtl_bt/rtl8922au_config.bin Bluetooth: hci0: RTL: cfg_sz 6, total sz 71307 Bluetooth: hci0: RTL: fw version 0x41c0c905 Tested-by: Hilda Wu Signed-off-by: Nial Ni Signed-off-by: Max Chou Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bluetooth/btrtl.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 24dae5440c03..3d995790a507 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -49,7 +49,7 @@ #define RTL_CHIP_SUBVER (&(struct rtl_vendor_cmd) {{0x10, 0x38, 0x04, 0x28, 0x80}}) #define RTL_CHIP_REV (&(struct rtl_vendor_cmd) {{0x10, 0x3A, 0x04, 0x28, 0x80}}) -#define RTL_SEC_PROJ (&(struct rtl_vendor_cmd) {{0x10, 0xA4, 0x0D, 0x00, 0xb0}}) +#define RTL_SEC_PROJ (&(struct rtl_vendor_cmd) {{0x10, 0xA4, 0xAD, 0x00, 0xb0}}) #define RTL_PATCH_SNIPPETS 0x01 #define RTL_PATCH_DUMMY_HEADER 0x02 @@ -513,7 +513,6 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, { struct rtl_epatch_header_v2 *hdr; int rc; - u8 reg_val[2]; u8 key_id; u32 num_sections; struct rtl_section *section; @@ -528,14 +527,7 @@ static int rtlbt_parse_firmware_v2(struct hci_dev *hdev, .len = btrtl_dev->fw_len - 7, /* Cut the tail */ }; - rc = btrtl_vendor_read_reg16(hdev, RTL_SEC_PROJ, reg_val); - if (rc < 0) - return -EIO; - key_id = reg_val[0]; - - rtl_dev_dbg(hdev, "%s: key id %u", __func__, key_id); - - btrtl_dev->key_id = key_id; + key_id = btrtl_dev->key_id; hdr = rtl_iov_pull_data(&iov, sizeof(*hdr)); if (!hdr) @@ -1049,6 +1041,8 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, u16 hci_rev, lmp_subver; u8 hci_ver, lmp_ver, chip_type = 0; int ret; + int rc; + u8 key_id; u8 reg_val[2]; btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); @@ -1159,6 +1153,14 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, goto err_free; } + rc = btrtl_vendor_read_reg16(hdev, RTL_SEC_PROJ, reg_val); + if (rc < 0) + goto err_free; + + key_id = reg_val[0]; + btrtl_dev->key_id = key_id; + rtl_dev_info(hdev, "%s: key id %u", __func__, key_id); + btrtl_dev->fw_len = -EIO; if (lmp_subver == RTL_ROM_LMP_8852A && hci_rev == 0x000c) { snprintf(fw_name, sizeof(fw_name), "%s_v2.bin", @@ -1181,7 +1183,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, goto err_free; } - if (btrtl_dev->ic_info->cfg_name) { + if (btrtl_dev->ic_info->cfg_name && !btrtl_dev->key_id) { if (postfix) { snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin", btrtl_dev->ic_info->cfg_name, postfix); -- Gitee From 8e30220552b5f8c8dfcdcefc88f66b172ab3a960 Mon Sep 17 00:00:00 2001 From: Yiqi Sun Date: Tue, 11 Nov 2025 15:05:39 +0800 Subject: [PATCH 0201/1449] smb: fix invalid username check in smb3_fs_context_parse_param() ANBZ: #35228 commit 727197a77874e98f7ebd3b2d92d7c494a50ac15c stable. commit ed6612165b74f09db00ef0abaf9831895ab28b7f upstream. Since the maximum return value of strnlen(..., CIFS_MAX_USERNAME_LEN) is CIFS_MAX_USERNAME_LEN, length check in smb3_fs_context_parse_param() is always FALSE and invalid. Fix the comparison in if statement. Signed-off-by: Yiqi Sun Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/fs_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index a64c0b0dbec7..6358f2483c86 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -1386,7 +1386,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, break; } - if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) > + if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) == CIFS_MAX_USERNAME_LEN) { pr_warn("username too long\n"); goto cifs_parse_mount_err; -- Gitee From 437833b4a55668419abb9831e3a27cd10401dc3e Mon Sep 17 00:00:00 2001 From: Lushih Hsieh Date: Fri, 14 Nov 2025 13:20:53 +0800 Subject: [PATCH 0202/1449] ALSA: usb-audio: Add native DSD quirks for PureAudio DAC series ANBZ: #35228 commit 4943ed83f80e19f9b197441d9c0b3718c16a820e stable. commit 21a9ab5b90b3716a631d559e62818029b4e7f5b7 upstream. The PureAudio APA DAC and Lotus DAC5 series are USB Audio 2.0 Class devices that support native Direct Stream Digital (DSD) playback via specific vendor protocols. Without these quirks, the devices may only function in standard PCM mode, or fail to correctly report their DSD format capabilities to the ALSA framework, preventing native DSD playback under Linux. This commit adds new quirk entries for the mentioned DAC models based on their respective Vendor/Product IDs (VID:PID), for example: 0x16d0:0x0ab1 (APA DAC), 0x16d0:0xeca1 (DAC5 series), etc. The quirk ensures correct DSD format handling by setting the required SNDRV_PCM_FMTBIT_DSD_U32_BE format bit and defining the DSD-specific Audio Class 2.0 (AC2.0) endpoint configurations. This allows the ALSA DSD API to correctly address the device for high-bitrate DSD streams, bypassing the need for DoP (DSD over PCM). Test on APA DAC and Lotus DAC5 SE under Arch Linux. Tested-by: Lushih Hsieh Signed-off-by: Lushih Hsieh Link: https://patch.msgid.link/20251114052053.54989-1-bruce@mail.kh.edu.tw Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 68238e62020b..44274f39d693 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1922,6 +1922,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */ case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ + case USB_ID(0x16d0, 0x0ab1): /* PureAudio APA DAC */ + case USB_ID(0x16d0, 0xeca1): /* PureAudio Lotus DAC5, DAC5 SE, DAC5 Pro */ case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */ case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */ case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */ @@ -2189,6 +2191,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_IGNORE_CLOCK_SOURCE), DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */ QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x16d0, 0x0ab1, /* PureAudio APA DAC */ + QUIRK_FLAG_DSD_RAW), + DEVICE_FLG(0x16d0, 0xeca1, /* PureAudio Lotus DAC5, DAC5 SE and DAC5 Pro */ + QUIRK_FLAG_DSD_RAW), DEVICE_FLG(0x17aa, 0x1046, /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */ QUIRK_FLAG_DISABLE_AUTOSUSPEND), DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ -- Gitee From 669b4facb1d3d081bcab2eba6531209f758c14b8 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Thu, 23 Oct 2025 21:25:49 +0800 Subject: [PATCH 0203/1449] bfs: Reconstruct file type when loading from disk ANBZ: #35228 commit a9f626396bfe66f49b743601e862767928237cc0 stable. commit 34ab4c75588c07cca12884f2bf6b0347c7a13872 upstream. syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when the S_IFMT bits of the 32bits "mode" field loaded from disk are corrupted or when the 32bits "attributes" field loaded from disk are corrupted. A documentation says that BFS uses only lower 9 bits of the "mode" field. But I can't find an explicit explanation that the unused upper 23 bits (especially, the S_IFMT bits) are initialized with 0. Therefore, ignore the S_IFMT bits of the "mode" field loaded from disk. Also, verify that the value of the "attributes" field loaded from disk is either BFS_VREG or BFS_VDIR (because BFS supports only regular files and the root directory). Reported-by: syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d Signed-off-by: Tetsuo Handa Link: https://patch.msgid.link/fabce673-d5b9-4038-8287-0fd65d80203b@I-love.SAKURA.ne.jp Reviewed-by: Tigran Aivazian Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/bfs/inode.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index e6a76ae9eb44..42805e3dbdae 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -60,7 +60,19 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK; di = (struct bfs_inode *)bh->b_data + off; - inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode); + /* + * https://martin.hinner.info/fs/bfs/bfs-structure.html explains that + * BFS in SCO UnixWare environment used only lower 9 bits of di->i_mode + * value. This means that, although bfs_write_inode() saves whole + * inode->i_mode bits (which include S_IFMT bits and S_IS{UID,GID,VTX} + * bits), middle 7 bits of di->i_mode value can be garbage when these + * bits were not saved by bfs_write_inode(). + * Since we can't tell whether middle 7 bits are garbage, use only + * lower 12 bits (i.e. tolerate S_IS{UID,GID,VTX} bits possibly being + * garbage) and reconstruct S_IFMT bits for Linux environment from + * di->i_vtype value. + */ + inode->i_mode = 0x00000FFF & le32_to_cpu(di->i_mode); if (le32_to_cpu(di->i_vtype) == BFS_VDIR) { inode->i_mode |= S_IFDIR; inode->i_op = &bfs_dir_inops; @@ -70,6 +82,11 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) inode->i_op = &bfs_file_inops; inode->i_fop = &bfs_file_operations; inode->i_mapping->a_ops = &bfs_aops; + } else { + brelse(bh); + printf("Unknown vtype=%u %s:%08lx\n", + le32_to_cpu(di->i_vtype), inode->i_sb->s_id, ino); + goto error; } BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); -- Gitee From ff3d5a0df0bb6e7b1cad99feec2f9f5a22553b92 Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Fri, 31 Oct 2025 00:06:25 +0800 Subject: [PATCH 0204/1449] HID: hid-input: Extend Elan ignore battery quirk to USB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 37786f27ee0ed4b05fd387d28003db41e3837e8f stable. commit 534ca75e8e3b713514b3f2da85dab96831cf5b2a upstream. USB Elan devices have the same problem as the I2C ones with a fake battery device showing up. Reviewed-by: Hans de Goede Reported-by: André Barata Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220722 Signed-off-by: Mario Limonciello (AMD) Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-input.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index f073d5621050..fa3efe9701c9 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -386,10 +386,11 @@ static const struct hid_device_id hid_battery_quirks[] = { { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM), HID_BATTERY_QUIRK_AVOID_QUERY }, /* - * Elan I2C-HID touchscreens seem to all report a non present battery, - * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C-HID devices. + * Elan HID touchscreens seem to all report a non present battery, + * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices. */ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, {} }; -- Gitee From 6520109ccc7c671184c3d9763da6c0ffcad08242 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 5 Nov 2025 06:48:30 +0800 Subject: [PATCH 0205/1449] nvme: fix admin request_queue lifetime ANBZ: #35228 commit a505f0ba36ab24176c300d7ff56aff85c2977e6c stable. commit 03b3bcd319b3ab5182bc9aaa0421351572c78ac0 upstream. The namespaces can access the controller's admin request_queue, and stale references on the namespaces may exist after tearing down the controller. Ensure the admin request_queue is active by moving the controller's 'put' to after all controller references have been released to ensure no one is can access the request_queue. This fixes a reported use-after-free bug: BUG: KASAN: slab-use-after-free in blk_queue_enter+0x41c/0x4a0 Read of size 8 at addr ffff88c0a53819f8 by task nvme/3287 CPU: 67 UID: 0 PID: 3287 Comm: nvme Tainted: G E 6.13.2-ga1582f1a031e #15 Tainted: [E]=UNSIGNED_MODULE Hardware name: Jabil /EGS 2S MB1, BIOS 1.00 06/18/2025 Call Trace: dump_stack_lvl+0x4f/0x60 print_report+0xc4/0x620 ? _raw_spin_lock_irqsave+0x70/0xb0 ? _raw_read_unlock_irqrestore+0x30/0x30 ? blk_queue_enter+0x41c/0x4a0 kasan_report+0xab/0xe0 ? blk_queue_enter+0x41c/0x4a0 blk_queue_enter+0x41c/0x4a0 ? __irq_work_queue_local+0x75/0x1d0 ? blk_queue_start_drain+0x70/0x70 ? irq_work_queue+0x18/0x20 ? vprintk_emit.part.0+0x1cc/0x350 ? wake_up_klogd_work_func+0x60/0x60 blk_mq_alloc_request+0x2b7/0x6b0 ? __blk_mq_alloc_requests+0x1060/0x1060 ? __switch_to+0x5b7/0x1060 nvme_submit_user_cmd+0xa9/0x330 nvme_user_cmd.isra.0+0x240/0x3f0 ? force_sigsegv+0xe0/0xe0 ? nvme_user_cmd64+0x400/0x400 ? vfs_fileattr_set+0x9b0/0x9b0 ? cgroup_update_frozen_flag+0x24/0x1c0 ? cgroup_leave_frozen+0x204/0x330 ? nvme_ioctl+0x7c/0x2c0 blkdev_ioctl+0x1a8/0x4d0 ? blkdev_common_ioctl+0x1930/0x1930 ? fdget+0x54/0x380 __x64_sys_ioctl+0x129/0x190 do_syscall_64+0x5b/0x160 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7f765f703b0b Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d dd 52 0f 00 f7 d8 64 89 01 48 RSP: 002b:00007ffe2cefe808 EFLAGS: 00000202 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007ffe2cefe860 RCX: 00007f765f703b0b RDX: 00007ffe2cefe860 RSI: 00000000c0484e41 RDI: 0000000000000003 RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000 R10: 00007f765f611d50 R11: 0000000000000202 R12: 0000000000000003 R13: 00000000c0484e41 R14: 0000000000000001 R15: 00007ffe2cefea60 Reported-by: Casey Chen Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Reviewed-by: Ming Lei Reviewed-by: Chaitanya Kulkarni Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 72c15de35a64..b8e3f186dfdb 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4315,7 +4315,6 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set); void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl) { blk_mq_destroy_queue(ctrl->admin_q); - blk_put_queue(ctrl->admin_q); if (ctrl->ops->flags & NVME_F_FABRICS) { blk_mq_destroy_queue(ctrl->fabrics_q); blk_put_queue(ctrl->fabrics_q); @@ -4460,6 +4459,8 @@ static void nvme_free_ctrl(struct device *dev) container_of(dev, struct nvme_ctrl, ctrl_device); struct nvme_subsystem *subsys = ctrl->subsys; + if (ctrl->admin_q) + blk_put_queue(ctrl->admin_q); if (!subsys || ctrl->instance != subsys->instance) ida_free(&nvme_instance_ida, ctrl->instance); -- Gitee From 3b397c890d971ad045f7c7f9b5c4f93afaa39c2b Mon Sep 17 00:00:00 2001 From: Praveen Talari Date: Mon, 10 Nov 2025 18:10:41 +0800 Subject: [PATCH 0206/1449] pinctrl: qcom: msm: Fix deadlock in pinmux configuration ANBZ: #35228 commit fc59674bb41f236600a0a875ff4bceaa96d02d11 stable. commit 1c2e70397b4125022dba80f6111271a37fb36bae upstream. Replace disable_irq() with disable_irq_nosync() in msm_pinmux_set_mux() to prevent deadlock when wakeup IRQ is triggered on the same GPIO being reconfigured. The issue occurs when a wakeup IRQ is triggered on a GPIO and the IRQ handler attempts to reconfigure the same GPIO's pinmux. In this scenario, msm_pinmux_set_mux() calls disable_irq() which waits for the currently running IRQ handler to complete, creating a circular dependency that results in deadlock. Using disable_irq_nosync() avoids waiting for the IRQ handler to complete, preventing the deadlock condition while still properly disabling the interrupt during pinmux reconfiguration. Suggested-by: Prasad Sodagudi Signed-off-by: Praveen Talari Reviewed-by: Bjorn Andersson Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/qcom/pinctrl-msm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 13dc8bc1d0cf..688f3d01f4af 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -214,7 +214,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, */ if (d && i != gpio_func && !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux)) - disable_irq(irq); + disable_irq_nosync(irq); raw_spin_lock_irqsave(&pctrl->lock, flags); -- Gitee From 9bb9e3b62c491cc3449f7fc7b1ee640a2923a28f Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Mon, 17 Nov 2025 23:59:38 +0800 Subject: [PATCH 0207/1449] platform/x86: acer-wmi: Ignore backlight event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d046f04f223d6589cc35b5ce848856f13401b28a stable. commit 444a9256f8d106e08a6bc2dc8ef28a8699e4b3ba upstream. On the Acer Nitro AN515-58, the event 4 - 0 is send by the ACPI firmware when the backlight up/down keys are pressed. Ignore this event to avoid spamming the kernel log with error messages, as the acpi-video driver already handles brightness up/down events. Reported-by: Bugaddr Closes: https://bugaddr.tech/posts/2025-11-16-debugging-the-acer-nitro-5-an515-58-fn-f10-keyboard-backlight-bug-on-linux/#wmi-interface-issues Tested-by: Bugaddr Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20251117155938.3030-1-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/acer-wmi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 868faccfb862..e7a43f824272 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -86,6 +86,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); enum acer_wmi_event_ids { WMID_HOTKEY_EVENT = 0x1, + WMID_BACKLIGHT_EVENT = 0x4, WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, WMID_GAMING_TURBO_KEY_EVENT = 0x7, WMID_AC_EVENT = 0x8, @@ -1992,6 +1993,9 @@ static void acer_wmi_notify(u32 value, void *context) sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); } break; + case WMID_BACKLIGHT_EVENT: + /* Already handled by acpi-video */ + break; case WMID_ACCEL_OR_KBD_DOCK_EVENT: acer_gsensor_event(); acer_kbd_dock_event(&return_value); -- Gitee From b8a3d3e6876598ca04b17452dab3a4191f9db8e5 Mon Sep 17 00:00:00 2001 From: April Grimoire Date: Thu, 23 Oct 2025 00:37:26 +0800 Subject: [PATCH 0208/1449] HID: apple: Add SONiX AK870 PRO to non_apple_keyboards quirk list ANBZ: #35228 commit db78f96e150a5926dfdf49c714fd214c719eb4b8 stable. commit 743c81cdc98fd4fef62a89eb70efff994112c2d9 upstream. SONiX AK870 PRO keyboard pretends to be an apple keyboard by VID:PID, rendering function keys not treated properly. Despite being a SONiX USB DEVICE, it uses a different name, so adding it to the list. Signed-off-by: April Grimoire Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-apple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 7cf17c671da4..2b8021628d3c 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -341,6 +341,7 @@ static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { static const struct apple_non_apple_keyboard non_apple_keyboards[] = { { "SONiX USB DEVICE" }, + { "SONiX AK870 PRO" }, { "Keychron" }, { "AONE" }, { "GANSS" }, -- Gitee From 1e948f055187a3efd8d4feba1dedfb5d80aad9e1 Mon Sep 17 00:00:00 2001 From: Jia Ston Date: Wed, 29 Oct 2025 13:18:38 +0800 Subject: [PATCH 0209/1449] platform/x86: huawei-wmi: add keys for HONOR models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit f42f958c4f42d10b2d260dbbc4ae8a27652eb638 stable. commit 5c72329716d0858621021193330594d5d26bf44d upstream. HONOR MagicBook X16/X14 models produced in 2025 cannot use the Print Screen and YOYO keys properly, with the system reporting them as unknown key presses (codes: 0x028b and 0x028e). To resolve this, a key_entry is added for both the HONOR Print Screen key and the HONOR YOYO key, ensuring they function correctly on these models. Signed-off-by: Ston Jia Link: https://patch.msgid.link/20251029051804.220111-1-ston.jia@outlook.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/huawei-wmi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 0ef1c46b617b..29ef391d3305 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -81,6 +81,10 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_KEY, 0x289, { KEY_WLAN } }, // Huawei |M| key { KE_KEY, 0x28a, { KEY_CONFIG } }, + // HONOR YOYO key + { KE_KEY, 0x28b, { KEY_NOTIFICATION_CENTER } }, + // HONOR print screen + { KE_KEY, 0x28e, { KEY_PRINT } }, // Keyboard backlit { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, -- Gitee From 69048f38a9b7a379b288585e6e05c10246f27942 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis Date: Wed, 8 Oct 2025 21:50:57 +0800 Subject: [PATCH 0210/1449] platform/x86/amd: pmc: Add Lenovo Legion Go 2 to pmc quirk list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 919a9f1422e305bd3eff5ceeb9112d917ec94936 stable. commit f945afe01c6768dcfed7868c671a26e1164c2284 upstream. The Lenovo Legion Go 2 takes a long time to resume from suspend. This is due to it having an nvme resume handler that interferes with IOMMU mappings. It is a common issue with older Lenovo laptops. Adding it to that quirk list fixes this issue. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4618 Suggested-by: Mario Limonciello Signed-off-by: Antheas Kapenekakis Reviewed-by: Mario Limonciello (AMD) Link: https://patch.msgid.link/20251008135057.731928-1-lkml@antheas.dev Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/amd/pmc/pmc-quirks.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c index 9fd2829ee2ab..271cbeaa59af 100644 --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c @@ -198,6 +198,23 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "82ND"), } }, + /* https://gitlab.freedesktop.org/drm/amd/-/issues/4618 */ + { + .ident = "Lenovo Legion Go 2", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83N0"), + } + }, + { + .ident = "Lenovo Legion Go 2", + .driver_data = &quirk_s2idle_bug, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83N1"), + } + }, /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */ { .ident = "HP Laptop 15s-eq2xxx", -- Gitee From ba0e9f8202b7cb564ce7f569cac8c3920309f303 Mon Sep 17 00:00:00 2001 From: Antheas Kapenekakis Date: Fri, 24 Oct 2025 23:21:51 +0800 Subject: [PATCH 0211/1449] platform/x86/amd/pmc: Add spurious_8042 to Xbox Ally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e7915f55ab15198bfacdcf2dd92a95837d31e9fb stable. commit c0ddc54016636dd8dedfaf1a3b482a95058e1db2 upstream. The Xbox Ally features a Van Gogh SoC that has spurious interrupts during resume. We get the following logs: atkbd_receive_byte: 20 callbacks suppressed atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly. So, add the spurious_8042 quirk for it. It does not have a keyboard, so this does not result in any functional loss. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4659 Signed-off-by: Antheas Kapenekakis Reviewed-by: Mario Limonciello (AMD) Link: https://patch.msgid.link/20251024152152.3981721-3-lkml@antheas.dev Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/amd/pmc/pmc-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c index 271cbeaa59af..a5031339dac8 100644 --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c @@ -116,6 +116,14 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), } }, + { + .ident = "ROG Xbox Ally RC73YA", + .driver_data = &quirk_spurious_8042, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "RC73YA"), + } + }, /* https://bugzilla.kernel.org/show_bug.cgi?id=218024 */ { .ident = "V14 G4 AMN", -- Gitee From 3ad5026bfa0d88f757c7707f2caf9f0f47c8b7a2 Mon Sep 17 00:00:00 2001 From: Naoki Ueki Date: Mon, 3 Nov 2025 20:16:45 +0800 Subject: [PATCH 0212/1449] HID: elecom: Add support for ELECOM M-XT3URBK (018F) ANBZ: #35228 commit e9b3a97e852a480b63698d6109f0d6a174e6b04b stable. commit cdcbb8e8d10f656642380ee13516290437b52b36 upstream. The ELECOM M-XT3URBK trackball has an additional device ID (0x018F), which shares the same report descriptor as the existing device (0x00FB). However, the driver does not currently recognize this new ID, resulting in only five buttons being functional. This patch adds the new device ID so that all six buttons work properly. Signed-off-by: Naoki Ueki Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-elecom.c | 6 ++++-- drivers/hid/hid-ids.h | 3 ++- drivers/hid/hid-quirks.c | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index 4fa45ee77503..f76fec79e890 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c @@ -75,7 +75,8 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, */ mouse_button_fixup(hdev, rdesc, *rsize, 20, 28, 22, 14, 8); break; - case USB_DEVICE_ID_ELECOM_M_XT3URBK: + case USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB: + case USB_DEVICE_ID_ELECOM_M_XT3URBK_018F: case USB_DEVICE_ID_ELECOM_M_XT3DRBK: case USB_DEVICE_ID_ELECOM_M_XT4DRBK: /* @@ -117,7 +118,8 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, static const struct hid_device_id elecom_devices[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6a538dca21a9..ca9c70c8f3cf 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -439,7 +439,8 @@ #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 #define USB_DEVICE_ID_ELECOM_M_XGL20DLBK 0x00e6 -#define USB_DEVICE_ID_ELECOM_M_XT3URBK 0x00fb +#define USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB 0x00fb +#define USB_DEVICE_ID_ELECOM_M_XT3URBK_018F 0x018f #define USB_DEVICE_ID_ELECOM_M_XT3DRBK 0x00fc #define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd #define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index fa946666969b..2da21415e676 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -405,7 +405,8 @@ static const struct hid_device_id hid_have_special_driver[] = { #if IS_ENABLED(CONFIG_HID_ELECOM) { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) }, -- Gitee From 15f3014661fd84bbbcb72226bedbc0028222c366 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 22 Nov 2025 01:29:02 +0800 Subject: [PATCH 0213/1449] samples: work around glibc redefining some of our defines wrong ANBZ: #35228 commit 2f5e6805246cda81b2c999499b7aedb996baf1db stable. commit a48f822908982353c3256e35a089e9e7d0d61580 upstream. Apparently as of version 2.42, glibc headers define AT_RENAME_NOREPLACE and some of the other flags for renameat2() and friends in . Which would all be fine, except for inexplicable reasons glibc decided to define them _differently_ from the kernel definitions, which then makes some of our sample code that includes both kernel headers and user space headers unhappy, because the compiler will (correctly) complain about redefining things. Now, mixing kernel headers and user space headers is always a somewhat iffy proposition due to namespacing issues, but it's kind of inevitable in our sample and selftest code. And this is just glibc being stupid. Those defines come from the kernel, glibc is exposing the kernel interfaces, and glibc shouldn't make up some random new expressions for these values. It's not like glibc headers changed the actual result values, but they arbitrarily just decided to use a different expression to describe those values. The kernel just does #define AT_RENAME_NOREPLACE 0x0001 while glibc does # define RENAME_NOREPLACE (1 << 0) # define AT_RENAME_NOREPLACE RENAME_NOREPLACE instead. Same value in the end, but very different macro definition. For absolutely no reason. This has since been fixed in the glibc development tree, so eventually we'll end up with the canonical expressions and no clashes. But in the meantime the broken headers are in the glibc-2.42 release and have made it out into distributions. Do a minimal work-around to make the samples build cleanly by just undefining the affected macros in between the user space header include and the kernel header includes. Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- samples/vfs/test-statx.c | 6 ++++++ samples/watch_queue/watch_test.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/samples/vfs/test-statx.c b/samples/vfs/test-statx.c index 49c7a46cee07..424a6fa15723 100644 --- a/samples/vfs/test-statx.c +++ b/samples/vfs/test-statx.c @@ -19,6 +19,12 @@ #include #include #include + +// Work around glibc header silliness +#undef AT_RENAME_NOREPLACE +#undef AT_RENAME_EXCHANGE +#undef AT_RENAME_WHITEOUT + #include #include #define statx foo diff --git a/samples/watch_queue/watch_test.c b/samples/watch_queue/watch_test.c index 8c6cb57d5cfc..24cf7d7a1972 100644 --- a/samples/watch_queue/watch_test.c +++ b/samples/watch_queue/watch_test.c @@ -16,6 +16,12 @@ #include #include #include + +// Work around glibc header silliness +#undef AT_RENAME_NOREPLACE +#undef AT_RENAME_EXCHANGE +#undef AT_RENAME_WHITEOUT + #include #include #include -- Gitee From 0342a25b0a80f783a17276479ba0c95e4b41c245 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Mon, 29 Sep 2025 11:57:19 +0800 Subject: [PATCH 0214/1449] wifi: rtw88: Add USB ID 2001:3329 for D-Link AC13U rev. A1 ANBZ: #35228 commit 24cb00b9804c092af655696f71d80aa21f0dc271 stable. commit b377dcd9a286a6f81922ae442cd1c743bc4a2b35 upstream. Add USB ID 2001:3329 for D-Link AC13U rev. A1 which is a RTL8812CU-based Wi-Fi adapter. Compile tested only. Cc: stable@vger.kernel.org # 6.6.x Signed-off-by: Zenm Chen Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250929035719.6172-2-zenmchen@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/realtek/rtw88/rtw8822cu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822cu.c b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c index af28ca09d41f..cfb16ab68793 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822cu.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822cu.c @@ -21,6 +21,8 @@ static const struct usb_device_id rtw_8822cu_id_table[] = { .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3329, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* D-Link AC13U rev. A1 */ {}, }; MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table); -- Gitee From e6d96194c0886c56016adafd033e51780f5e5e7e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 23 Oct 2025 20:31:41 +0800 Subject: [PATCH 0215/1449] comedi: c6xdigio: Fix invalid PNP driver unregistration ANBZ: #35228 commit 72b3627b0d3b819de49b29c2c8cb1c64d54536b9 stable. commit 72262330f7b3ad2130e800cecf02adcce3c32c77 upstream. The Comedi low-level driver "c6xdigio" seems to be for a parallel port connected device. When the Comedi core calls the driver's Comedi "attach" handler `c6xdigio_attach()` to configure a Comedi to use this driver, it tries to enable the parallel port PNP resources by registering a PNP driver with `pnp_register_driver()`, but ignores the return value. (The `struct pnp_driver` it uses has only the `name` and `id_table` members filled in.) The driver's Comedi "detach" handler `c6xdigio_detach()` unconditionally unregisters the PNP driver with `pnp_unregister_driver()`. It is possible for `c6xdigio_attach()` to return an error before it calls `pnp_register_driver()` and it is possible for the call to `pnp_register_driver()` to return an error (that is ignored). In both cases, the driver should not be calling `pnp_unregister_driver()` as it does in `c6xdigio_detach()`. (Note that `c6xdigio_detach()` will be called by the Comedi core if `c6xdigio_attach()` returns an error, or if the Comedi core decides to detach the Comedi device from the driver for some other reason.) The unconditional call to `pnp_unregister_driver()` without a previous successful call to `pnp_register_driver()` will cause `driver_unregister()` to issue a warning "Unexpected driver unregister!". This was detected by Syzbot [1]. Also, the PNP driver registration and unregistration should be done at module init and exit time, respectively, not when attaching or detaching Comedi devices to the driver. (There might be more than one Comedi device being attached to the driver, although that is unlikely.) Change the driver to do the PNP driver registration at module init time, and the unregistration at module exit time. Since `c6xdigio_detach()` now only calls `comedi_legacy_detach()`, remove the function and change the Comedi driver "detach" handler to `comedi_legacy_detach`. ------------------------------------------- [1] Syzbot sample crash report: Unexpected driver unregister! WARNING: CPU: 0 PID: 5970 at drivers/base/driver.c:273 driver_unregister drivers/base/driver.c:273 [inline] WARNING: CPU: 0 PID: 5970 at drivers/base/driver.c:273 driver_unregister+0x90/0xb0 drivers/base/driver.c:270 Modules linked in: CPU: 0 UID: 0 PID: 5970 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025 RIP: 0010:driver_unregister drivers/base/driver.c:273 [inline] RIP: 0010:driver_unregister+0x90/0xb0 drivers/base/driver.c:270 Code: 48 89 ef e8 c2 e6 82 fc 48 89 df e8 3a 93 ff ff 5b 5d e9 c3 6d d9 fb e8 be 6d d9 fb 90 48 c7 c7 e0 f8 1f 8c e8 51 a2 97 fb 90 <0f> 0b 90 90 5b 5d e9 a5 6d d9 fb e8 e0 f4 41 fc eb 94 e8 d9 f4 41 RSP: 0018:ffffc9000373f9a0 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffffffff8ff24720 RCX: ffffffff817b6ee8 RDX: ffff88807c932480 RSI: ffffffff817b6ef5 RDI: 0000000000000001 RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffffffff8ff24660 R13: dffffc0000000000 R14: 0000000000000000 R15: ffff88814cca0000 FS: 000055556dab1500(0000) GS:ffff8881249d9000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055f77f285cd0 CR3: 000000007d871000 CR4: 00000000003526f0 Call Trace: comedi_device_detach_locked+0x12f/0xa50 drivers/comedi/drivers.c:207 comedi_device_detach+0x67/0xb0 drivers/comedi/drivers.c:215 comedi_device_attach+0x43d/0x900 drivers/comedi/drivers.c:1011 do_devconfig_ioctl+0x1b1/0x710 drivers/comedi/comedi_fops.c:872 comedi_unlocked_ioctl+0x165d/0x2f00 drivers/comedi/comedi_fops.c:2178 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl fs/ioctl.c:583 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fc05798eec9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffcf8184238 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007fc057be5fa0 RCX: 00007fc05798eec9 RDX: 0000200000000080 RSI: 0000000040946400 RDI: 0000000000000003 RBP: 00007fc057a11f91 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fc057be5fa0 R14: 00007fc057be5fa0 R15: 0000000000000003 ------------------------------------------- Reported-by: syzbot+6616bba359cec7a1def1@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6616bba359cec7a1def1 Fixes: 2c89e159cd2f ("Staging: comedi: add c6xdigio driver") Cc: stable Signed-off-by: Ian Abbott Link: https://patch.msgid.link/20251023123141.6537-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/comedi/drivers/c6xdigio.c | 46 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/comedi/drivers/c6xdigio.c b/drivers/comedi/drivers/c6xdigio.c index 14b90d1c64dc..8a38d97d463b 100644 --- a/drivers/comedi/drivers/c6xdigio.c +++ b/drivers/comedi/drivers/c6xdigio.c @@ -249,9 +249,6 @@ static int c6xdigio_attach(struct comedi_device *dev, if (ret) return ret; - /* Make sure that PnP ports get activated */ - pnp_register_driver(&c6xdigio_pnp_driver); - s = &dev->subdevices[0]; /* pwm output subdevice */ s->type = COMEDI_SUBD_PWM; @@ -278,19 +275,46 @@ static int c6xdigio_attach(struct comedi_device *dev, return 0; } -static void c6xdigio_detach(struct comedi_device *dev) -{ - comedi_legacy_detach(dev); - pnp_unregister_driver(&c6xdigio_pnp_driver); -} - static struct comedi_driver c6xdigio_driver = { .driver_name = "c6xdigio", .module = THIS_MODULE, .attach = c6xdigio_attach, - .detach = c6xdigio_detach, + .detach = comedi_legacy_detach, }; -module_comedi_driver(c6xdigio_driver); + +static bool c6xdigio_pnp_registered = false; + +static int __init c6xdigio_module_init(void) +{ + int ret; + + ret = comedi_driver_register(&c6xdigio_driver); + if (ret) + return ret; + + if (IS_ENABLED(CONFIG_PNP)) { + /* Try to activate the PnP ports */ + ret = pnp_register_driver(&c6xdigio_pnp_driver); + if (ret) { + pr_warn("failed to register pnp driver - err %d\n", + ret); + ret = 0; /* ignore the error. */ + } else { + c6xdigio_pnp_registered = true; + } + } + + return 0; +} +module_init(c6xdigio_module_init); + +static void __exit c6xdigio_module_exit(void) +{ + if (c6xdigio_pnp_registered) + pnp_unregister_driver(&c6xdigio_pnp_driver); + comedi_driver_unregister(&c6xdigio_driver); +} +module_exit(c6xdigio_module_exit); MODULE_AUTHOR("Comedi https://www.comedi.org"); MODULE_DESCRIPTION("Comedi driver for the C6x_DIGIO DSP daughter card"); -- Gitee From 824e8463e9ac59fe5eee9077d1094917ff5b78ce Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Thu, 23 Oct 2025 21:22:04 +0800 Subject: [PATCH 0216/1449] comedi: multiq3: sanitize config options in multiq3_attach() ANBZ: #35228 commit 049f14557450351750f929ebfff36d849511e132 stable. commit f24c6e3a39fa355dabfb684c9ca82db579534e72 upstream. Syzbot identified an issue [1] in multiq3_attach() that induces a task timeout due to open() or COMEDI_DEVCONFIG ioctl operations, specifically, in the case of multiq3 driver. This problem arose when syzkaller managed to craft weird configuration options used to specify the number of channels in encoder subdevice. If a particularly great number is passed to s->n_chan in multiq3_attach() via it->options[2], then multiple calls to multiq3_encoder_reset() at the end of driver-specific attach() method will be running for minutes, thus blocking tasks and affected devices as well. While this issue is most likely not too dangerous for real-life devices, it still makes sense to sanitize configuration inputs. Enable a sensible limit on the number of encoder chips (4 chips max, each with 2 channels) to stop this behaviour from manifesting. [1] Syzbot crash: INFO: task syz.2.19:6067 blocked for more than 143 seconds. ... Call Trace: context_switch kernel/sched/core.c:5254 [inline] __schedule+0x17c4/0x4d60 kernel/sched/core.c:6862 __schedule_loop kernel/sched/core.c:6944 [inline] schedule+0x165/0x360 kernel/sched/core.c:6959 schedule_preempt_disabled+0x13/0x30 kernel/sched/core.c:7016 __mutex_lock_common kernel/locking/mutex.c:676 [inline] __mutex_lock+0x7e6/0x1350 kernel/locking/mutex.c:760 comedi_open+0xc0/0x590 drivers/comedi/comedi_fops.c:2868 chrdev_open+0x4cc/0x5e0 fs/char_dev.c:414 do_dentry_open+0x953/0x13f0 fs/open.c:965 vfs_open+0x3b/0x340 fs/open.c:1097 ... Reported-by: syzbot+7811bb68a317954a0347@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=7811bb68a317954a0347 Fixes: 77e01cdbad51 ("Staging: comedi: add multiq3 driver") Cc: stable Signed-off-by: Nikita Zhandarovich Reviewed-by: Ian Abbott Link: https://patch.msgid.link/20251023132205.395753-1-n.zhandarovich@fintech.ru Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/comedi/drivers/multiq3.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/comedi/drivers/multiq3.c b/drivers/comedi/drivers/multiq3.c index 07ff5383da99..ac369e9a262d 100644 --- a/drivers/comedi/drivers/multiq3.c +++ b/drivers/comedi/drivers/multiq3.c @@ -67,6 +67,11 @@ #define MULTIQ3_TRSFRCNTR_OL 0x10 /* xfer CNTR to OL (x and y) */ #define MULTIQ3_EFLAG_RESET 0x06 /* reset E bit of flag reg */ +/* + * Limit on the number of optional encoder channels + */ +#define MULTIQ3_MAX_ENC_CHANS 8 + static void multiq3_set_ctrl(struct comedi_device *dev, unsigned int bits) { /* @@ -312,6 +317,10 @@ static int multiq3_attach(struct comedi_device *dev, s->insn_read = multiq3_encoder_insn_read; s->insn_config = multiq3_encoder_insn_config; + /* sanity check for number of encoder channels */ + if (s->n_chan > MULTIQ3_MAX_ENC_CHANS) + s->n_chan = MULTIQ3_MAX_ENC_CHANS; + for (i = 0; i < s->n_chan; i++) multiq3_encoder_reset(dev, i); -- Gitee From 6d6b23198262daf3b8b1af642b9030a0ece4cef4 Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Thu, 23 Oct 2025 21:22:32 +0800 Subject: [PATCH 0217/1449] comedi: check device's attached status in compat ioctls ANBZ: #35228 commit b975f91de5f8f63cf490f0393775cc795f8b0557 stable. commit 0de7d9cd07a2671fa6089173bccc0b2afe6b93ee upstream. Syzbot identified an issue [1] that crashes kernel, seemingly due to unexistent callback dev->get_valid_routes(). By all means, this should not occur as said callback must always be set to get_zero_valid_routes() in __comedi_device_postconfig(). As the crash seems to appear exclusively in i386 kernels, at least, judging from [1] reports, the blame lies with compat versions of standard IOCTL handlers. Several of them are modified and do not use comedi_unlocked_ioctl(). While functionality of these ioctls essentially copy their original versions, they do not have required sanity check for device's attached status. This, in turn, leads to a possibility of calling select IOCTLs on a device that has not been properly setup, even via COMEDI_DEVCONFIG. Doing so on unconfigured devices means that several crucial steps are missed, for instance, specifying dev->get_valid_routes() callback. Fix this somewhat crudely by ensuring device's attached status before performing any ioctls, improving logic consistency between modern and compat functions. [1] Syzbot report: BUG: kernel NULL pointer dereference, address: 0000000000000000 ... CR2: ffffffffffffffd6 CR3: 000000006c717000 CR4: 0000000000352ef0 Call Trace: get_valid_routes drivers/comedi/comedi_fops.c:1322 [inline] parse_insn+0x78c/0x1970 drivers/comedi/comedi_fops.c:1401 do_insnlist_ioctl+0x272/0x700 drivers/comedi/comedi_fops.c:1594 compat_insnlist drivers/comedi/comedi_fops.c:3208 [inline] comedi_compat_ioctl+0x810/0x990 drivers/comedi/comedi_fops.c:3273 __do_compat_sys_ioctl fs/ioctl.c:695 [inline] __se_compat_sys_ioctl fs/ioctl.c:638 [inline] __ia32_compat_sys_ioctl+0x242/0x370 fs/ioctl.c:638 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline] ... Reported-by: syzbot+ab8008c24e84adee93ff@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ab8008c24e84adee93ff Fixes: 3fbfd2223a27 ("comedi: get rid of compat_alloc_user_space() mess in COMEDI_CHANINFO compat") Cc: stable Reviewed-by: Ian Abbott Signed-off-by: Nikita Zhandarovich Link: https://patch.msgid.link/20251023132234.395794-1-n.zhandarovich@fintech.ru Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/comedi/comedi_fops.c | 42 ++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c index 1f12f7ea3dc4..bb4fbfa80c82 100644 --- a/drivers/comedi/comedi_fops.c +++ b/drivers/comedi/comedi_fops.c @@ -2971,7 +2971,12 @@ static int compat_chaninfo(struct file *file, unsigned long arg) chaninfo.rangelist = compat_ptr(chaninfo32.rangelist); mutex_lock(&dev->mutex); - err = do_chaninfo_ioctl(dev, &chaninfo); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + err = -ENODEV; + } else { + err = do_chaninfo_ioctl(dev, &chaninfo); + } mutex_unlock(&dev->mutex); return err; } @@ -2992,7 +2997,12 @@ static int compat_rangeinfo(struct file *file, unsigned long arg) rangeinfo.range_ptr = compat_ptr(rangeinfo32.range_ptr); mutex_lock(&dev->mutex); - err = do_rangeinfo_ioctl(dev, &rangeinfo); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + err = -ENODEV; + } else { + err = do_rangeinfo_ioctl(dev, &rangeinfo); + } mutex_unlock(&dev->mutex); return err; } @@ -3068,7 +3078,12 @@ static int compat_cmd(struct file *file, unsigned long arg) return rc; mutex_lock(&dev->mutex); - rc = do_cmd_ioctl(dev, &cmd, ©, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_cmd_ioctl(dev, &cmd, ©, file); + } mutex_unlock(&dev->mutex); if (copy) { /* Special case: copy cmd back to user. */ @@ -3093,7 +3108,12 @@ static int compat_cmdtest(struct file *file, unsigned long arg) return rc; mutex_lock(&dev->mutex); - rc = do_cmdtest_ioctl(dev, &cmd, ©, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_cmdtest_ioctl(dev, &cmd, ©, file); + } mutex_unlock(&dev->mutex); if (copy) { err = put_compat_cmd(compat_ptr(arg), &cmd); @@ -3153,7 +3173,12 @@ static int compat_insnlist(struct file *file, unsigned long arg) } mutex_lock(&dev->mutex); - rc = do_insnlist_ioctl(dev, insns, insnlist32.n_insns, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_insnlist_ioctl(dev, insns, insnlist32.n_insns, file); + } mutex_unlock(&dev->mutex); kfree(insns); return rc; @@ -3172,7 +3197,12 @@ static int compat_insn(struct file *file, unsigned long arg) return rc; mutex_lock(&dev->mutex); - rc = do_insn_ioctl(dev, &insn, file); + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + rc = -ENODEV; + } else { + rc = do_insn_ioctl(dev, &insn, file); + } mutex_unlock(&dev->mutex); return rc; } -- Gitee From 50614b2aa0457ba9a02f072f7d98b0c004ab75e0 Mon Sep 17 00:00:00 2001 From: Navaneeth K Date: Fri, 21 Nov 2025 00:23:52 +0800 Subject: [PATCH 0218/1449] staging: rtl8723bs: fix out-of-bounds read in rtw_get_ie() parser ANBZ: #35228 commit 30c558447e90935f0de61be181bbcedf75952e00 stable. commit 154828bf9559b9c8421fc2f0d7f7f76b3683aaed upstream. The Information Element (IE) parser rtw_get_ie() trusted the length byte of each IE without validating that the IE body (len bytes after the 2-byte header) fits inside the remaining frame buffer. A malformed frame can advertise an IE length larger than the available data, causing the parser to increment its pointer beyond the buffer end. This results in out-of-bounds reads or, depending on the pattern, an infinite loop. Fix by validating that (offset + 2 + len) does not exceed the limit before accepting the IE or advancing to the next element. This prevents OOB reads and ensures the parser terminates safely on malformed frames. Signed-off-by: Navaneeth K Cc: stable Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index 30e7457a9c31..54849235a149 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -139,22 +139,24 @@ u8 *rtw_get_ie(u8 *pbuf, signed int index, signed int *len, signed int limit) signed int tmp, i; u8 *p; - if (limit < 1) + if (limit < 2) return NULL; p = pbuf; i = 0; *len = 0; - while (1) { + while (i + 2 <= limit) { + tmp = *(p + 1); + if (i + 2 + tmp > limit) + break; + if (*p == index) { - *len = *(p + 1); + *len = tmp; return p; } - tmp = *(p + 1); + p += (tmp + 2); i += (tmp + 2); - if (i >= limit) - break; } return NULL; } -- Gitee From 77fa5ac7a88012683dad203bc5d3d6bf638af3de Mon Sep 17 00:00:00 2001 From: Navaneeth K Date: Fri, 21 Nov 2025 00:33:08 +0800 Subject: [PATCH 0219/1449] staging: rtl8723bs: fix stack buffer overflow in OnAssocReq IE parsing ANBZ: #35228 commit 34620eb602aa432f090b2b784ee5c5070fb16cf9 stable. commit 6ef0e1c10455927867cac8f0ed6b49f328f8cf95 upstream. The Supported Rates IE length from an incoming Association Request frame was used directly as the memcpy() length when copying into a fixed-size 16-byte stack buffer (supportRate). A malicious station can advertise an IE length larger than 16 bytes, causing a stack buffer overflow. Clamp ie_len to the buffer size before copying the Supported Rates IE, and correct the bounds check when merging Extended Supported Rates to prevent a second potential overflow. This prevents kernel stack corruption triggered by malformed association requests. Signed-off-by: Navaneeth K Cc: stable Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 985683767a40..7b9d32b44b5b 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -1034,6 +1034,9 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) status = WLAN_STATUS_CHALLENGE_FAIL; goto OnAssocReqFail; } else { + if (ie_len > sizeof(supportRate)) + ie_len = sizeof(supportRate); + memcpy(supportRate, p+2, ie_len); supportRateNum = ie_len; @@ -1041,7 +1044,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) pkt_len - WLAN_HDR_A3_LEN - ie_offset); if (p) { - if (supportRateNum <= sizeof(supportRate)) { + if (supportRateNum + ie_len <= sizeof(supportRate)) { memcpy(supportRate+supportRateNum, p+2, ie_len); supportRateNum += ie_len; } -- Gitee From 695696b7cdf6b29ffcaa68632f618d85f27fbda8 Mon Sep 17 00:00:00 2001 From: Navaneeth K Date: Fri, 21 Nov 2025 00:35:20 +0800 Subject: [PATCH 0220/1449] staging: rtl8723bs: fix out-of-bounds read in OnBeacon ESR IE parsing ANBZ: #35228 commit c173ce97d3f0f0c0fefa39139d6d04ba60b5db22 stable. commit 502ddcc405b69fa92e0add6c1714d654504f6fd7 upstream. The Extended Supported Rates (ESR) IE handling in OnBeacon accessed *(p + 1 + ielen) and *(p + 2 + ielen) without verifying that these offsets lie within the received frame buffer. A malformed beacon with an ESR IE positioned at the end of the buffer could cause an out-of-bounds read, potentially triggering a kernel panic. Add a boundary check to ensure that the ESR IE body and the subsequent bytes are within the limits of the frame before attempting to access them. This prevents OOB reads caused by malformed beacon frames. Signed-off-by: Navaneeth K Cc: stable Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 7b9d32b44b5b..cde0a9b0498d 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -580,9 +580,11 @@ unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame) p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_); if (p && ielen > 0) { - if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) - /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */ - *(p + 1) = ielen - 1; + if (p + 2 + ielen < pframe + len) { + if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) + /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */ + *(p + 1) = ielen - 1; + } } if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { -- Gitee From 69524bf87690d20222c0968e67120f66e0e24784 Mon Sep 17 00:00:00 2001 From: Konstantin Andreev Date: Tue, 17 Jun 2025 05:32:16 +0800 Subject: [PATCH 0221/1449] smack: fix bug: unprivileged task can create labels ANBZ: #35228 commit f8fd5491100f920847a3338d5fba22db19c72773 stable. commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 upstream. If an unprivileged task is allowed to relabel itself (/smack/relabel-self is not empty), it can freely create new labels by writing their names into own /proc/PID/attr/smack/current This occurs because do_setattr() imports the provided label in advance, before checking "relabel-self" list. This change ensures that the "relabel-self" list is checked before importing the label. Fixes: 38416e53936e ("Smack: limited capability for changing process label") Signed-off-by: Konstantin Andreev Signed-off-by: Casey Schaufler Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 6b559d04463f..e6f19ff952dc 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3680,8 +3680,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size) struct task_smack *tsp = smack_cred(current_cred()); struct cred *new; struct smack_known *skp; - struct smack_known_list_elem *sklep; - int rc; + char *labelstr; + int rc = 0; if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) return -EPERM; @@ -3692,28 +3692,41 @@ static int smack_setprocattr(const char *name, void *value, size_t size) if (strcmp(name, "current") != 0) return -EINVAL; - skp = smk_import_entry(value, size); - if (IS_ERR(skp)) - return PTR_ERR(skp); + labelstr = smk_parse_smack(value, size); + if (IS_ERR(labelstr)) + return PTR_ERR(labelstr); /* * No process is ever allowed the web ("@") label * and the star ("*") label. */ - if (skp == &smack_known_web || skp == &smack_known_star) - return -EINVAL; + if (labelstr[1] == '\0' /* '@', '*' */) { + const char c = labelstr[0]; + + if (c == *smack_known_web.smk_known || + c == *smack_known_star.smk_known) { + rc = -EPERM; + goto free_labelstr; + } + } if (!smack_privileged(CAP_MAC_ADMIN)) { - rc = -EPERM; + const struct smack_known_list_elem *sklep; list_for_each_entry(sklep, &tsp->smk_relabel, list) - if (sklep->smk_label == skp) { - rc = 0; - break; - } - if (rc) - return rc; + if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) + goto free_labelstr; + rc = -EPERM; } +free_labelstr: + kfree(labelstr); + if (rc) + return -EPERM; + + skp = smk_import_entry(value, size); + if (IS_ERR(skp)) + return PTR_ERR(skp); + new = prepare_creds(); if (new == NULL) return -ENOMEM; -- Gitee From 93d7670a0b907cea081240793f5565edec422693 Mon Sep 17 00:00:00 2001 From: Mainak Sen Date: Mon, 7 Jul 2025 17:17:39 +0800 Subject: [PATCH 0222/1449] gpu: host1x: Fix race in syncpt alloc/free ANBZ: #35228 commit 6245cce711e2cdb2cc75c0bb8632952e36f8c972 stable. commit c7d393267c497502fa737607f435f05dfe6e3d9b upstream. Fix race condition between host1x_syncpt_alloc() and host1x_syncpt_put() by using kref_put_mutex() instead of kref_put() + manual mutex locking. This ensures no thread can acquire the syncpt_mutex after the refcount drops to zero but before syncpt_release acquires it. This prevents races where syncpoints could be allocated while still being cleaned up from a previous release. Remove explicit mutex locking in syncpt_release as kref_put_mutex() handles this atomically. Signed-off-by: Mainak Sen Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/host1x/syncpt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c index f63d14a57a1d..acc7d82e0585 100644 --- a/drivers/gpu/host1x/syncpt.c +++ b/drivers/gpu/host1x/syncpt.c @@ -345,8 +345,6 @@ static void syncpt_release(struct kref *ref) sp->locked = false; - mutex_lock(&sp->host->syncpt_mutex); - host1x_syncpt_base_free(sp->base); kfree(sp->name); sp->base = NULL; @@ -369,7 +367,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) if (!sp) return; - kref_put(&sp->ref, syncpt_release); + kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); } EXPORT_SYMBOL(host1x_syncpt_put); -- Gitee From de3d9172b5dc06f3024673c0b9630887affbffcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 11 Sep 2025 00:39:57 +0800 Subject: [PATCH 0223/1449] drm/panel: visionox-rm69299: Don't clear all mode flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 2f97ed8e88a3d70b0ed916d2f3032cfe3e332ff5 stable. commit 39144b611e9cd4f5814f4098c891b545dd70c536 upstream. Don't clear all mode flags. We only want to maek sure we use HS mode during unprepare. Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") Reviewed-by: Neil Armstrong Signed-off-by: Guido Günther Reviewed-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c index 6e946e5a036e..fa784b9998eb 100644 --- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c +++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c @@ -64,7 +64,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) struct visionox_rm69299 *ctx = panel_to_ctx(panel); int ret; - ctx->dsi->mode_flags = 0; + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); if (ret < 0) -- Gitee From 47caa689ff1f50b91d0c376df4a11b87c9bb4cde Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Fri, 26 Sep 2025 23:26:27 +0800 Subject: [PATCH 0224/1449] drm/vgem-fence: Fix potential deadlock on release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9dc3c78d21e16f5af1a9c3d11b4bd5276f891fe0 stable. commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f upstream. A timer that expires a vgem fence automatically in 10 seconds is now released with timer_delete_sync() from fence->ops.release() called on last dma_fence_put(). In some scenarios, it can run in IRQ context, which is not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while working on new IGT subtests syncobj_timeline@stress-* as user space replacements of some problematic test cases of a dma-fence-chain selftest [1]. [117.004338] ================================ [117.004340] WARNING: inconsistent lock state [117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U [117.004346] -------------------------------- [117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. [117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: [117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 [117.004361] {HARDIRQ-ON-W} state was registered at: [117.004363] lock_acquire+0xc4/0x2e0 [117.004366] call_timer_fn+0x80/0x2a0 [117.004368] __run_timers+0x231/0x310 [117.004370] run_timer_softirq+0x76/0xe0 [117.004372] handle_softirqs+0xd4/0x4d0 [117.004375] __irq_exit_rcu+0x13f/0x160 [117.004377] irq_exit_rcu+0xe/0x20 [117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 [117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 [117.004385] cpuidle_enter_state+0x12b/0x8a0 [117.004388] cpuidle_enter+0x2e/0x50 [117.004393] call_cpuidle+0x22/0x60 [117.004395] do_idle+0x1fd/0x260 [117.004398] cpu_startup_entry+0x29/0x30 [117.004401] start_secondary+0x12d/0x160 [117.004404] common_startup_64+0x13e/0x141 [117.004407] irq event stamp: 2282669 [117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 [117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 [117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 [117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 [117.004426] other info that might help us debug this: [117.004429] Possible unsafe locking scenario: [117.004432] CPU0 [117.004433] ---- [117.004434] lock((&fence->timer)); [117.004436] [117.004438] lock((&fence->timer)); [117.004440] *** DEADLOCK *** [117.004443] 1 lock held by swapper/0/0: [117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 [117.004450] stack backtrace: [117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) [117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER [117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 [117.004456] Call Trace: [117.004456] [117.004457] dump_stack_lvl+0x91/0xf0 [117.004460] dump_stack+0x10/0x20 [117.004461] print_usage_bug.part.0+0x260/0x360 [117.004463] mark_lock+0x76e/0x9c0 [117.004465] ? register_lock_class+0x48/0x4a0 [117.004467] __lock_acquire+0xbc3/0x2860 [117.004469] lock_acquire+0xc4/0x2e0 [117.004470] ? __timer_delete_sync+0x4b/0x190 [117.004472] ? __timer_delete_sync+0x4b/0x190 [117.004473] __timer_delete_sync+0x68/0x190 [117.004474] ? __timer_delete_sync+0x4b/0x190 [117.004475] timer_delete_sync+0x10/0x20 [117.004476] vgem_fence_release+0x19/0x30 [vgem] [117.004478] dma_fence_release+0xc1/0x3b0 [117.004480] ? dma_fence_release+0xa1/0x3b0 [117.004481] dma_fence_chain_release+0xe7/0x130 [117.004483] dma_fence_release+0xc1/0x3b0 [117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 [117.004485] dma_fence_chain_irq_work+0x59/0x80 [117.004487] irq_work_single+0x75/0xa0 [117.004490] irq_work_run_list+0x33/0x60 [117.004491] irq_work_run+0x18/0x40 [117.004493] __sysvec_irq_work+0x35/0x170 [117.004494] sysvec_irq_work+0x47/0xc0 [117.004496] asm_sysvec_irq_work+0x1b/0x20 [117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 [117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 [117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 [117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 [117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 [117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 [117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 [117.004506] dma_fence_signal+0x49/0xb0 [117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] [117.004508] vgem_fence_timeout+0x12/0x20 [vgem] [117.004509] call_timer_fn+0xa1/0x2a0 [117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] [117.004513] __run_timers+0x231/0x310 [117.004514] ? tmigr_handle_remote+0x2ac/0x560 [117.004517] timer_expire_remote+0x46/0x70 [117.004518] tmigr_handle_remote+0x433/0x560 [117.004520] ? __run_timers+0x239/0x310 [117.004521] ? run_timer_softirq+0x21/0xe0 [117.004522] ? lock_release+0xce/0x2a0 [117.004524] run_timer_softirq+0xcf/0xe0 [117.004525] handle_softirqs+0xd4/0x4d0 [117.004526] __irq_exit_rcu+0x13f/0x160 [117.004527] irq_exit_rcu+0xe/0x20 [117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 [117.004529] [117.004529] [117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 [117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 [117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 [117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 [117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 [117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 [117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 [117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b [117.004537] ? cpuidle_enter_state+0x125/0x8a0 [117.004538] ? sched_clock_noinstr+0x9/0x10 [117.004540] cpuidle_enter+0x2e/0x50 [117.004542] call_cpuidle+0x22/0x60 [117.004542] do_idle+0x1fd/0x260 [117.004544] cpu_startup_entry+0x29/0x30 [117.004546] rest_init+0x104/0x200 [117.004548] start_kernel+0x93d/0xbd0 [117.004550] ? load_ucode_intel_bsp+0x2a/0x90 [117.004551] ? sme_unmap_bootdata+0x14/0x80 [117.004554] x86_64_start_reservations+0x18/0x30 [117.004555] x86_64_start_kernel+0xfd/0x150 [117.004556] ? soft_restart_cpu+0x14/0x14 [117.004558] common_startup_64+0x13e/0x141 [117.004560] [117.004565] ------------[ cut here ]------------ [117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 [117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 [117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 [117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) [117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER [117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 [117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 [117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c [117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 [117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 [117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 [117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb [117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 [117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 [117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 [117.004826] PKRU: 55555554 [117.004827] Call Trace: [117.004829] [117.004831] timer_delete_sync+0x10/0x20 [117.004833] vgem_fence_release+0x19/0x30 [vgem] [117.004836] dma_fence_release+0xc1/0x3b0 [117.004838] ? dma_fence_release+0xa1/0x3b0 [117.004841] dma_fence_chain_release+0xe7/0x130 [117.004844] dma_fence_release+0xc1/0x3b0 [117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 [117.004850] dma_fence_chain_irq_work+0x59/0x80 [117.004853] irq_work_single+0x75/0xa0 [117.004857] irq_work_run_list+0x33/0x60 [117.004860] irq_work_run+0x18/0x40 [117.004863] __sysvec_irq_work+0x35/0x170 [117.004865] sysvec_irq_work+0x47/0xc0 [117.004868] asm_sysvec_irq_work+0x1b/0x20 [117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 [117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 [117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 [117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 [117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 [117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 [117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 [117.004897] dma_fence_signal+0x49/0xb0 [117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] [117.004902] vgem_fence_timeout+0x12/0x20 [vgem] [117.004904] call_timer_fn+0xa1/0x2a0 [117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] [117.004910] __run_timers+0x231/0x310 [117.004913] ? tmigr_handle_remote+0x2ac/0x560 [117.004917] timer_expire_remote+0x46/0x70 [117.004919] tmigr_handle_remote+0x433/0x560 [117.004923] ? __run_timers+0x239/0x310 [117.004925] ? run_timer_softirq+0x21/0xe0 [117.004928] ? lock_release+0xce/0x2a0 [117.004931] run_timer_softirq+0xcf/0xe0 [117.004933] handle_softirqs+0xd4/0x4d0 [117.004936] __irq_exit_rcu+0x13f/0x160 [117.004938] irq_exit_rcu+0xe/0x20 [117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 [117.004943] [117.004944] [117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 [117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 [117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 [117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 [117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 [117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 [117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 [117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b [117.004978] ? cpuidle_enter_state+0x125/0x8a0 [117.004981] ? sched_clock_noinstr+0x9/0x10 [117.004985] cpuidle_enter+0x2e/0x50 [117.004989] call_cpuidle+0x22/0x60 [117.004991] do_idle+0x1fd/0x260 [117.005001] cpu_startup_entry+0x29/0x30 [117.005004] rest_init+0x104/0x200 [117.005008] start_kernel+0x93d/0xbd0 [117.005011] ? load_ucode_intel_bsp+0x2a/0x90 [117.005014] ? sme_unmap_bootdata+0x14/0x80 [117.005017] x86_64_start_reservations+0x18/0x30 [117.005020] x86_64_start_kernel+0xfd/0x150 [117.005023] ? soft_restart_cpu+0x14/0x14 [117.005026] common_startup_64+0x13e/0x141 [117.005030] [117.005032] irq event stamp: 2282669 [117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 [117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 [117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 [117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 [117.005051] ---[ end trace 0000000000000000 ]--- Make the timer IRQ safe. [1] https://patchwork.freedesktop.org/series/154987/#rev2 Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") Signed-off-by: Janusz Krzysztofik Reviewed-by: Christian König Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com Signed-off-by: Maarten Lankhorst Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/vgem/vgem_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c index 5298d995faa7..97b8cdf5c54f 100644 --- a/drivers/gpu/drm/vgem/vgem_fence.c +++ b/drivers/gpu/drm/vgem/vgem_fence.c @@ -79,7 +79,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, dma_fence_context_alloc(1), 1); - timer_setup(&fence->timer, vgem_fence_timeout, 0); + timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); /* We force the fence to expire within 10s to prevent driver hangs */ mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); -- Gitee From 511013bd88615ba55dfcb9db3fd18faefcd4ad9c Mon Sep 17 00:00:00 2001 From: Seungjin Bae Date: Mon, 29 Sep 2025 02:56:11 +0800 Subject: [PATCH 0225/1449] USB: Fix descriptor count when handling invalid MBIM extended descriptor ANBZ: #35228 commit 094b1827d2f7640d8f035367575992b1019e3b85 stable. commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe upstream. In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE descriptor was using 'break' upon detecting an invalid length. This was incorrect because 'break' only exits the switch statement, causing the code to fall through to cnt++, thus incorrectly incrementing the count of parsed descriptors for a descriptor that was actually invalid and being discarded. This patch changes 'break' to 'goto next_desc;' to ensure that the logic skips the counter increment and correctly proceeds to the next descriptor in the buffer. This maintains an accurate count of only the successfully parsed descriptors. Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") Signed-off-by: Seungjin Bae Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/core/message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 077dfe48d01c..5a5dfbf995e3 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -2428,7 +2428,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, break; case USB_CDC_MBIM_EXTENDED_TYPE: if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) - break; + goto next_desc; hdr->usb_cdc_mbim_extended_desc = (struct usb_cdc_mbim_extended_desc *)buffer; break; -- Gitee From 53456c9ae8c211281586268b2c7593d6a8ef78c7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 18 Sep 2025 11:04:43 +0800 Subject: [PATCH 0226/1449] clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle callback ANBZ: #35228 commit 2ba9e39f1aedb6d54569ca186a074d0f1240c727 stable. commit 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab upstream. R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page 583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) indicate after reset has been asserted by writing a matching reset bit into register SRCR, it is mandatory to wait 1ms. This 1ms delay is documented on R-Car V4H and V4M, it is currently unclear whether S4 is affected as well. This patch does apply the extra delay on R-Car S4 as well. Fix the reset driver to respect the additional delay when toggling resets. Drivers which use separate reset_control_(de)assert() must assure matching delay in their driver code. Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") Signed-off-by: Marek Vasut Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index cb80d1bf6c7c..55ac571c7388 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -612,8 +612,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, /* Reset module */ writel(bitmask, priv->base + priv->reset_regs[reg]); - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. + * On older SoCs, delay after SRCR has been written is 35us + * (one cycle of the RCLK clock @ ca. 32 kHz). + */ + if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) + usleep_range(1000, 2000); + else + usleep_range(35, 1000); /* Release module from reset state */ writel(bitmask, priv->base + priv->reset_clear_regs[reg]); -- Gitee From a47f1454a8ad057d216e2d4595fcfe30e5589e83 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 12 Sep 2023 12:51:31 +0800 Subject: [PATCH 0227/1449] clk: renesas: rzg2l: Simplify the logic in rzg2l_mod_clock_endisable() ANBZ: #35228 commit 73fcc27a9795cac90b524231268e2c8a80b972f4 stable. commit becf4a771a12b52dc5b3d2b089598d5603f3bbec upstream. The bitmask << 16 is anyway set on both branches of if thus move it before the if and set the lower bits of registers only in case clock is enabled. Signed-off-by: Claudiu Beznea Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230912045157.177966-12-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Geert Uytterhoeven Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/rzg2l-cpg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 77eefb6ee453..0b3b6097b33a 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -992,10 +992,9 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) enable ? "ON" : "OFF"); spin_lock_irqsave(&priv->rmw_lock, flags); + value = bitmask << 16; if (enable) - value = (bitmask << 16) | bitmask; - else - value = bitmask << 16; + value |= bitmask; writel(value, priv->base + CLK_ON_R(reg)); spin_unlock_irqrestore(&priv->rmw_lock, flags); -- Gitee From f009ced5e4e32172b8d90deabe813dfc329ec56a Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 29 Sep 2023 13:38:53 +0800 Subject: [PATCH 0228/1449] clk: renesas: rzg2l: Remove critical area ANBZ: #35228 commit 3cf222e052ca9d3a2971681036400712da899c13 stable. commit 5f710e3bc5987373737470f98798bbd49134a2e0 upstream. The spinlock in rzg2l_mod_clock_endisable() is intended to protect RMW-accesses to the hardware register. There is no need to protect instructions that set temporary variables which will be written afterwards to a hardware register. With this only one write to one clock register is executed thus locking/unlocking rmw_lock is removed. Signed-off-by: Claudiu Beznea Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230929053915.1530607-7-claudiu.beznea@bp.renesas.com Signed-off-by: Geert Uytterhoeven Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/rzg2l-cpg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 0b3b6097b33a..b7fa4c7eb801 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -978,7 +978,6 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) struct rzg2l_cpg_priv *priv = clock->priv; unsigned int reg = clock->off; struct device *dev = priv->dev; - unsigned long flags; u32 bitmask = BIT(clock->bit); u32 value; int error; @@ -990,14 +989,12 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, enable ? "ON" : "OFF"); - spin_lock_irqsave(&priv->rmw_lock, flags); value = bitmask << 16; if (enable) value |= bitmask; - writel(value, priv->base + CLK_ON_R(reg)); - spin_unlock_irqrestore(&priv->rmw_lock, flags); + writel(value, priv->base + CLK_ON_R(reg)); if (!enable) return 0; -- Gitee From b016792feb8fbef3aff2f73d40ff28aedd7fd870 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 10 Oct 2023 21:26:56 +0800 Subject: [PATCH 0229/1449] clk: renesas: rzg2l: Use %x format specifier to print CLK_ON_R() ANBZ: #35228 commit d349d7dc324348d599341c701d4b791300b6923f stable. commit fd627207aaa782c1fd4224076b56a03a1059f516 upstream. Use the %x format specifier to print CLK_ON_R(). This makes debugging easier as the value printed will be hexadecimal like in the hardware manual. Along with it add "0x" in front of the printed value. Signed-off-by: Claudiu Beznea Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20231010132701.1658737-2-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Geert Uytterhoeven Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index b7fa4c7eb801..ab71f9cd250b 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -987,7 +987,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) return 0; } - dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, + dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, enable ? "ON" : "OFF"); value = bitmask << 16; -- Gitee From 726fdffe96a3e212e331b9b9c37144952a46949f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 28 Apr 2025 19:45:55 +0800 Subject: [PATCH 0230/1449] clk: renesas: Use str_on_off() helper ANBZ: #35228 commit 224a0d7c8449d6361e93a4abf5cb074c8305ed3b stable. commit aff664cc8cbc5c28e5aa57dc4201c34497f3c871 upstream. Use the str_on_off() helper instead of open-coding the same operation. Note that this does change the case of the flags, which doesn't matter much for debug messages. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/622f8554dcb815c8fc73511a1a118c1724570fa9.1745840497.git.geert+renesas@glider.be Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++- drivers/clk/renesas/rzg2l-cpg.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 55ac571c7388..908bb9517cc1 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -200,7 +201,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) int error; dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, - enable ? "ON" : "OFF"); + str_on_off(enable)); spin_lock_irqsave(&priv->rmw_lock, flags); if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index ab71f9cd250b..4bba49215c71 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -988,7 +989,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) } dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, - enable ? "ON" : "OFF"); + str_on_off(enable)); value = bitmask << 16; if (enable) -- Gitee From 61ec0d4d9cecafa07fa405955d000fb49d104dc5 Mon Sep 17 00:00:00 2001 From: Thierry Bultel Date: Thu, 15 May 2025 22:18:19 +0800 Subject: [PATCH 0231/1449] clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register ANBZ: #35228 commit e8c7304992933fbbd9e7e44ed597afeaebc38ec3 stable. commit 3d37ca1482c36975255f29911a529f84f1bc34a9 upstream. In a subsequent patch, the registration callback will need more parameters from cpg_mssr_priv (like another base address with clock controllers with double register block, and also, notifiers and rmw_lock). Instead of adding more parameters, move the needed parameters to a public sub-struct. Instead moving clks to this structure, which would have implied to add an allocation (and cleanup) for it, keep the way the allocation is done and just have a copy of the pointer in the public structure. Reviewed-by: Geert Uytterhoeven Signed-off-by: Thierry Bultel Link: https://lore.kernel.org/20250515141828.43444-5-thierry.bultel.yh@bp.renesas.com Signed-off-by: Geert Uytterhoeven Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/r7s9210-cpg-mssr.c | 7 +- drivers/clk/renesas/r8a77970-cpg-mssr.c | 8 +- drivers/clk/renesas/rcar-gen2-cpg.c | 5 +- drivers/clk/renesas/rcar-gen2-cpg.h | 3 +- drivers/clk/renesas/rcar-gen3-cpg.c | 6 +- drivers/clk/renesas/rcar-gen3-cpg.h | 3 +- drivers/clk/renesas/rcar-gen4-cpg.c | 6 +- drivers/clk/renesas/rcar-gen4-cpg.h | 3 +- drivers/clk/renesas/renesas-cpg-mssr.c | 98 ++++++++++++------------- drivers/clk/renesas/renesas-cpg-mssr.h | 20 ++++- 10 files changed, 88 insertions(+), 71 deletions(-) diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index a85227c248f3..733244687daa 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk, static struct clk * __init rza2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { - struct clk *parent; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; unsigned int mult = 1; unsigned int div = 1; + struct clk *parent; parent = clks[core->parent]; if (IS_ERR(parent)) diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index 7e90e94c4b68..0c568a113c3f 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -222,10 +222,11 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev) static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { const struct clk_div_table *table; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; const struct clk *parent; unsigned int shift; @@ -239,8 +240,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, shift = 4; break; default: - return rcar_gen3_cpg_clk_register(dev, core, info, clks, base, - notifiers); + return rcar_gen3_cpg_clk_register(dev, core, info, pub); } parent = clks[core->parent]; diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index edae874fa2b6..1a59a71eede2 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -274,10 +274,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { const struct clk_div_table *table = NULL; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; const struct clk *parent; const char *parent_name; unsigned int mult = 1; diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h index bdcd4a38d48d..3d4b127fdeaf 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.h +++ b/drivers/clk/renesas/rcar-gen2-cpg.h @@ -32,8 +32,7 @@ struct rcar_gen2_cpg_pll_config { struct clk *rcar_gen2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + struct cpg_mssr_pub *pub); int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config, unsigned int pll0_div, u32 mode); diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index d0129a650941..47d52e2c996e 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -346,9 +346,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { + struct raw_notifier_head *notifiers = &pub->notifiers; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; const struct clk *parent; unsigned int mult = 1; unsigned int div = 1; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index bfdc649bdf12..d15a5d1df71c 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -81,8 +81,7 @@ struct rcar_gen3_cpg_pll_config { struct clk *rcar_gen3_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + struct cpg_mssr_pub *pub); int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, unsigned int clk_extalr, u32 mode); diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c index c68d8b987054..b7bc3e6860c7 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.c +++ b/drivers/clk/renesas/rcar-gen4-cpg.c @@ -330,9 +330,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = { struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers) + struct cpg_mssr_pub *pub) { + struct raw_notifier_head *notifiers = &pub->notifiers; + void __iomem *base = pub->base0; + struct clk **clks = pub->clks; const struct clk *parent; unsigned int mult = 1; unsigned int div = 1; diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h index 006537e29e4e..f479c30a30e8 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.h +++ b/drivers/clk/renesas/rcar-gen4-cpg.h @@ -72,8 +72,7 @@ struct rcar_gen4_cpg_pll_config { struct clk *rcar_gen4_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + struct cpg_mssr_pub *pub); int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config, unsigned int clk_extalr, u32 mode); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 908bb9517cc1..c66b5e735928 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -127,16 +127,14 @@ static const u16 srstclr_for_gen4[] = { * struct cpg_mssr_priv - Clock Pulse Generator / Module Standby * and Software Reset Private Data * + * @pub: Data passed to clock registration callback * @rcdev: Optional reset controller entity * @dev: CPG/MSSR device - * @base: CPG/MSSR register block base address * @reg_layout: CPG/MSSR register layout - * @rmw_lock: protects RMW register accesses * @np: Device node in DT for this CPG/MSSR module * @num_core_clks: Number of Core Clocks in clks[] * @num_mod_clks: Number of Module Clocks in clks[] * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @notifiers: Notifier chain to save/restore clock state for system resume * @status_regs: Pointer to status registers array * @control_regs: Pointer to control registers array * @reset_regs: Pointer to reset registers array @@ -146,20 +144,18 @@ static const u16 srstclr_for_gen4[] = { * @clks: Array containing all Core and Module Clocks */ struct cpg_mssr_priv { + struct cpg_mssr_pub pub; #ifdef CONFIG_RESET_CONTROLLER struct reset_controller_dev rcdev; #endif struct device *dev; - void __iomem *base; enum clk_reg_layout reg_layout; - spinlock_t rmw_lock; struct device_node *np; unsigned int num_core_clks; unsigned int num_mod_clks; unsigned int last_dt_core_clk; - struct raw_notifier_head notifiers; const u16 *status_regs; const u16 *control_regs; const u16 *reset_regs; @@ -202,38 +198,39 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, str_on_off(enable)); - spin_lock_irqsave(&priv->rmw_lock, flags); + spin_lock_irqsave(&priv->pub.rmw_lock, flags); if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { - value = readb(priv->base + priv->control_regs[reg]); + value = readb(priv->pub.base0 + priv->control_regs[reg]); if (enable) value &= ~bitmask; else value |= bitmask; - writeb(value, priv->base + priv->control_regs[reg]); + writeb(value, priv->pub.base0 + priv->control_regs[reg]); /* dummy read to ensure write has completed */ - readb(priv->base + priv->control_regs[reg]); - barrier_data(priv->base + priv->control_regs[reg]); + readb(priv->pub.base0 + priv->control_regs[reg]); + barrier_data(priv->pub.base0 + priv->control_regs[reg]); + } else { - value = readl(priv->base + priv->control_regs[reg]); + value = readl(priv->pub.base0 + priv->control_regs[reg]); if (enable) value &= ~bitmask; else value |= bitmask; - writel(value, priv->base + priv->control_regs[reg]); + writel(value, priv->pub.base0 + priv->control_regs[reg]); } - spin_unlock_irqrestore(&priv->rmw_lock, flags); + spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) return 0; - error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], + error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], value, !(value & bitmask), 0, 10); if (error) dev_err(dev, "Failed to enable SMSTP %p[%d]\n", - priv->base + priv->control_regs[reg], bit); + priv->pub.base0 + priv->control_regs[reg], bit); return error; } @@ -252,12 +249,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) { struct mstp_clock *clock = to_mstp_clock(hw); struct cpg_mssr_priv *priv = clock->priv; + unsigned int reg = clock->index / 32; u32 value; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) - value = readb(priv->base + priv->control_regs[clock->index / 32]); + value = readb(priv->pub.base0 + priv->control_regs[reg]); else - value = readl(priv->base + priv->status_regs[clock->index / 32]); + value = readl(priv->pub.base0 + priv->status_regs[reg]); return !(value & BIT(clock->index % 32)); } @@ -349,7 +347,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, case CLK_TYPE_DIV6P1: case CLK_TYPE_DIV6_RO: WARN_DEBUG(core->parent >= priv->num_core_clks); - parent = priv->clks[core->parent]; + parent = priv->pub.clks[core->parent]; if (IS_ERR(parent)) { clk = parent; goto fail; @@ -359,12 +357,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, if (core->type == CLK_TYPE_DIV6_RO) /* Multiply with the DIV6 register value */ - div *= (readl(priv->base + core->offset) & 0x3f) + 1; + div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1; if (core->type == CLK_TYPE_DIV6P1) { clk = cpg_div6_register(core->name, 1, &parent_name, - priv->base + core->offset, - &priv->notifiers); + priv->pub.base0 + core->offset, + &priv->pub.notifiers); } else { clk = clk_register_fixed_factor(NULL, core->name, parent_name, 0, @@ -380,8 +378,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, default: if (info->cpg_clk_register) clk = info->cpg_clk_register(dev, core, info, - priv->clks, priv->base, - &priv->notifiers); + &priv->pub); else dev_err(dev, "%s has unsupported core clock type %u\n", core->name, core->type); @@ -392,7 +389,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, goto fail; dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; + priv->pub.clks[id] = clk; return; fail: @@ -415,14 +412,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, WARN_DEBUG(id < priv->num_core_clks); WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT); if (!mod->name) { /* Skip NULLified clock */ return; } - parent = priv->clks[mod->parent]; + parent = priv->pub.clks[mod->parent]; if (IS_ERR(parent)) { clk = parent; goto fail; @@ -611,7 +608,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); /* Reset module */ - writel(bitmask, priv->base + priv->reset_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); /* * On R-Car Gen4, delay after SRCR has been written is 1ms. @@ -624,7 +621,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, usleep_range(35, 1000); /* Release module from reset state */ - writel(bitmask, priv->base + priv->reset_clear_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); return 0; } @@ -638,7 +635,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); - writel(bitmask, priv->base + priv->reset_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); return 0; } @@ -652,7 +649,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); - writel(bitmask, priv->base + priv->reset_clear_regs[reg]); + writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); return 0; } @@ -664,7 +661,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev, unsigned int bit = id % 32; u32 bitmask = BIT(bit); - return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask); + return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); } static const struct reset_control_ops cpg_mssr_reset_ops = { @@ -885,12 +882,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev) if (priv->smstpcr_saved[reg].mask) priv->smstpcr_saved[reg].val = priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? - readb(priv->base + priv->control_regs[reg]) : - readl(priv->base + priv->control_regs[reg]); + readb(priv->pub.base0 + priv->control_regs[reg]) : + readl(priv->pub.base0 + priv->control_regs[reg]); } /* Save core clocks */ - raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL); + raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL); return 0; } @@ -907,7 +904,7 @@ static int cpg_mssr_resume_noirq(struct device *dev) return 0; /* Restore core clocks */ - raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL); + raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL); /* Restore module clocks */ for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { @@ -916,29 +913,29 @@ static int cpg_mssr_resume_noirq(struct device *dev) continue; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) - oldval = readb(priv->base + priv->control_regs[reg]); + oldval = readb(priv->pub.base0 + priv->control_regs[reg]); else - oldval = readl(priv->base + priv->control_regs[reg]); + oldval = readl(priv->pub.base0 + priv->control_regs[reg]); newval = oldval & ~mask; newval |= priv->smstpcr_saved[reg].val & mask; if (newval == oldval) continue; if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { - writeb(newval, priv->base + priv->control_regs[reg]); + writeb(newval, priv->pub.base0 + priv->control_regs[reg]); /* dummy read to ensure write has completed */ - readb(priv->base + priv->control_regs[reg]); - barrier_data(priv->base + priv->control_regs[reg]); + readb(priv->pub.base0 + priv->control_regs[reg]); + barrier_data(priv->pub.base0 + priv->control_regs[reg]); continue; } else - writel(newval, priv->base + priv->control_regs[reg]); + writel(newval, priv->pub.base0 + priv->control_regs[reg]); /* Wait until enabled clocks are really enabled */ mask &= ~priv->smstpcr_saved[reg].val; if (!mask) continue; - error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], + error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], oldval, !(oldval & mask), 0, 10); if (error) dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg, @@ -976,12 +973,13 @@ static int __init cpg_mssr_common_init(struct device *dev, if (!priv) return -ENOMEM; + priv->pub.clks = priv->clks; priv->np = np; priv->dev = dev; - spin_lock_init(&priv->rmw_lock); + spin_lock_init(&priv->pub.rmw_lock); - priv->base = of_iomap(np, 0); - if (!priv->base) { + priv->pub.base0 = of_iomap(np, 0); + if (!priv->pub.base0) { error = -ENOMEM; goto out_err; } @@ -989,7 +987,7 @@ static int __init cpg_mssr_common_init(struct device *dev, priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; - RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); + RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers); priv->reg_layout = info->reg_layout; if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) { priv->status_regs = mstpsr; @@ -1009,7 +1007,7 @@ static int __init cpg_mssr_common_init(struct device *dev, } for (i = 0; i < nclks; i++) - priv->clks[i] = ERR_PTR(-ENOENT); + priv->pub.clks[i] = ERR_PTR(-ENOENT); error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); if (error) @@ -1020,8 +1018,8 @@ static int __init cpg_mssr_common_init(struct device *dev, return 0; out_err: - if (priv->base) - iounmap(priv->base); + if (priv->pub.base0) + iounmap(priv->pub.base0); kfree(priv); return error; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 80c5b462924a..0a7b0b328d82 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -8,6 +8,8 @@ #ifndef __CLK_RENESAS_CPG_MSSR_H__ #define __CLK_RENESAS_CPG_MSSR_H__ +#include + /* * Definitions of CPG Core Clocks * @@ -29,6 +31,21 @@ struct cpg_core_clk { unsigned int offset; }; +/** + * struct cpg_mssr_pub - data shared with device-specific clk registration code + * + * @base0: CPG/MSSR register block base0 address + * @notifiers: Notifier chain to save/restore clock state for system resume + * @rmw_lock: protects RMW register accesses + * @clks: pointer to clocks + */ +struct cpg_mssr_pub { + void __iomem *base0; + struct raw_notifier_head notifiers; + spinlock_t rmw_lock; + struct clk **clks; +}; + enum clk_types { /* Generic */ CLK_TYPE_IN, /* External Clock Input */ @@ -153,8 +170,7 @@ struct cpg_mssr_info { struct clk *(*cpg_clk_register)(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base, - struct raw_notifier_head *notifiers); + struct cpg_mssr_pub *pub); }; extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; -- Gitee From 5cc5d08a2241f5ce8edbd796d7e30757b4529f13 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 23 Sep 2025 00:20:38 +0800 Subject: [PATCH 0232/1449] clk: renesas: cpg-mssr: Read back reset registers to assure values latched ANBZ: #35228 commit c9a86c677b48a905743552ac84b8d465a19c9c34 stable. commit b91401af6c00ffab003698bfabd4c166df30748b upstream. On R-Car V4H, the PCIEC controller DBI read would generate an SError in case the controller reset is released by writing SRSTCLR register first, and immediately afterward reading some PCIEC controller DBI register. The issue triggers in rcar_gen4_pcie_additional_common_init() on dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). The reset controller which contains the SRSTCLR register and the PCIEC controller which contains the DBI register share the same root access bus, but the bus then splits into separate segments before reaching each IP. Even if the SRSTCLR write access was posted on the bus before the DBI read access, it seems the DBI read access may reach the PCIEC controller before the SRSTCLR write completed, and trigger the SError. Mitigate the issue by adding a dummy SRSTCLR read, which assures the SRSTCLR write completes fully and is latched into the reset controller, before the PCIEC DBI read access can occur. Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") Reviewed-by: Wolfram Sang Tested-by: Geert Uytterhoeven Signed-off-by: Marek Vasut Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/renesas-cpg-mssr.c | 46 ++++++++++++-------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index c66b5e735928..0f558d94750f 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -597,18 +597,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) -static int cpg_mssr_reset(struct reset_controller_dev *rcdev, - unsigned long id) +static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, + const char *func, bool set, unsigned long id) { struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); unsigned int reg = id / 32; unsigned int bit = id % 32; + const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; u32 bitmask = BIT(bit); - dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); + if (func) + dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); + + writel(bitmask, priv->pub.base0 + off); + readl(priv->pub.base0 + off); + barrier_data(priv->pub.base0 + off); + + return 0; +} + +static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); /* Reset module */ - writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + cpg_mssr_reset_operate(rcdev, "reset", true, id); /* * On R-Car Gen4, delay after SRCR has been written is 1ms. @@ -621,36 +635,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, usleep_range(35, 1000); /* Release module from reset state */ - writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); - - return 0; + return cpg_mssr_reset_operate(rcdev, NULL, false, id); } static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) { - struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); - unsigned int reg = id / 32; - unsigned int bit = id % 32; - u32 bitmask = BIT(bit); - - dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); - - writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); - return 0; + return cpg_mssr_reset_operate(rcdev, "assert", true, id); } static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, unsigned long id) { - struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); - unsigned int reg = id / 32; - unsigned int bit = id % 32; - u32 bitmask = BIT(bit); - - dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); - - writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); - return 0; + return cpg_mssr_reset_operate(rcdev, "deassert", false, id); } static int cpg_mssr_status(struct reset_controller_dev *rcdev, -- Gitee From 51542917028e1eb7abb641ead12b17431e17f856 Mon Sep 17 00:00:00 2001 From: Mavroudis Chatzilazaridis Date: Fri, 3 Oct 2025 03:30:58 +0800 Subject: [PATCH 0233/1449] HID: logitech-hidpp: Do not assume FAP in hidpp_send_message_sync() ANBZ: #35228 commit c5f56b7faa80fb675242a788b4bdc6987479d77e stable. commit aba7963544d47d82cdf36602a6678a093af0299d upstream. Currently, hidpp_send_message_sync() retries sending the message when the device returns a busy error code, specifically HIDPP20_ERROR_BUSY, which has a different meaning under RAP. This ends up being a problem because this function is used for both FAP and RAP messages. This issue is not noticeable on older receivers with unreachable devices since they return HIDPP_ERROR_RESOURCE_ERROR (0x09), which is not equal to HIDPP20_ERROR_BUSY (0x08). However, newer receivers return HIDPP_ERROR_UNKNOWN_DEVICE (0x08) which happens to equal to HIDPP20_ERROR_BUSY, causing unnecessary retries when the device is not actually busy. This is resolved by checking if the error response is FAP or RAP and picking the respective ERROR_BUSY code. Fixes: 60165ab774cb ("HID: logitech-hidpp: rework one more time the retries attempts") Signed-off-by: Mavroudis Chatzilazaridis Tested-by: Stuart Hayhurst Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-logitech-hidpp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 3a2c1e48aba2..5a2fe703cf57 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -351,10 +351,15 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, do { ret = __do_hidpp_send_message_sync(hidpp, message, response); - if (ret != HIDPP20_ERROR_BUSY) + if (response->report_id == REPORT_ID_HIDPP_SHORT && + ret != HIDPP_ERROR_BUSY) + break; + if ((response->report_id == REPORT_ID_HIDPP_LONG || + response->report_id == REPORT_ID_HIDPP_VERY_LONG) && + ret != HIDPP20_ERROR_BUSY) break; - dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret); + dbg_hid("%s:got busy hidpp error %02X, retrying\n", __func__, ret); } while (--max_retries); mutex_unlock(&hidpp->send_mutex); -- Gitee From 364a66d82a12c1c14f52e7c6551ab21119176ad6 Mon Sep 17 00:00:00 2001 From: Dylan Hatch Date: Tue, 23 Sep 2025 08:49:41 +0800 Subject: [PATCH 0234/1449] objtool: Fix standalone --hacks=jump_label ANBZ: #35228 commit fe6ff6e24ae80577b7ddf5a51587cdf1a4691996 stable. commit be8374a5ba7cbab6b97df94b4ffe0b92f5c8a6d2 upstream. The objtool command line 'objtool --hacks=jump_label foo.o' on its own should be expected to rewrite jump labels to NOPs. This means the add_special_section_alts() code path needs to run when only this option is provided. This is mainly relevant in certain debugging situations, but could potentially also fix kernel builds in which objtool is run with --hacks=jump_label but without --orc, --stackval, --uaccess, or --hacks=noinstr. Fixes: de6fbcedf5ab ("objtool: Read special sections with alts only when specific options are selected") Signed-off-by: Dylan Hatch Signed-off-by: Josh Poimboeuf Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/objtool/check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 93700717f76f..70dc60883daa 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2636,7 +2636,8 @@ static int decode_sections(struct objtool_file *file) * Must be before add_jump_destinations(), which depends on 'func' * being set for alternatives, to enable proper sibling call detection. */ - if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { + if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr || + opts.hack_jump_label) { ret = add_special_section_alts(file); if (ret) return ret; -- Gitee From d63675dbae39b595c5c5a617a173673ff5536ad4 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Thu, 18 Sep 2025 00:03:27 +0800 Subject: [PATCH 0235/1449] objtool: Fix weak symbol detection ANBZ: #35228 commit a8fdcac66666cabe80266d5b5f1e33e9c462ec10 stable. commit 72567c630d32bc31f671977f78228c80937ed80e upstream. find_symbol_hole_containing() fails to find a symbol hole (aka stripped weak symbol) if its section has no symbols before the hole. This breaks weak symbol detection if -ffunction-sections is enabled. Fix that by allowing the interval tree to contain section symbols, which are always at offset zero for a given section. Fixes a bunch of (-ffunction-sections) warnings like: vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") Acked-by: Petr Mladek Tested-by: Joe Lawrence Signed-off-by: Josh Poimboeuf Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/objtool/elf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 081befa4674b..797507a90251 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -110,7 +110,7 @@ struct symbol_hole { }; /* - * Find !section symbol where @offset is after it. + * Find the last symbol before @offset. */ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) { @@ -121,8 +121,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) return -1; if (sh->key >= s->offset + s->len) { - if (s->type != STT_SECTION) - sh->sym = s; + sh->sym = s; return 1; } @@ -410,7 +409,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) sym->len = sym->sym.st_size; __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { - if (iter->offset == sym->offset && iter->type == sym->type) + if (iter->offset == sym->offset && iter->type == sym->type && + iter->len == sym->len) iter->alias = sym; } -- Gitee From 5108c6847f45547dbe0abee1dfdfa204ac3d13a1 Mon Sep 17 00:00:00 2001 From: Fernand Sieber Date: Thu, 18 Sep 2025 23:05:28 +0800 Subject: [PATCH 0236/1449] sched/fair: Forfeit vruntime on yield ANBZ: #35228 commit b0515a899ad1e0c8079098b7690ac640df1c754b stable. commit 79104becf42baeeb4a3f2b106f954b9fc7c10a3c upstream. If a task yields, the scheduler may decide to pick it again. The task in turn may decide to yield immediately or shortly after, leading to a tight loop of yields. If there's another runnable task as this point, the deadline will be increased by the slice at each loop. This can cause the deadline to runaway pretty quickly, and subsequent elevated run delays later on as the task doesn't get picked again. The reason the scheduler can pick the same task again and again despite its deadline increasing is because it may be the only eligible task at that point. Fix this by making the task forfeiting its remaining vruntime and pushing the deadline one slice ahead. This implements yield behavior more authentically. We limit the forfeiting to eligible tasks. This is because core scheduling prefers running ineligible tasks rather than force idling. As such, without the condition, we can end up on a yield loop which makes the vruntime increase rapidly, leading to anomalous run delays later down the line. Fixes: 147f3efaa24182 ("sched/fair: Implement an EEVDF-like scheduling policy") Signed-off-by: Fernand Sieber Signed-off-by: Peter Zijlstra (Intel) Link: https://lore.kernel.org/r/20250401123622.584018-1-sieberf@amazon.com Link: https://lore.kernel.org/r/20250911095113.203439-1-sieberf@amazon.com Link: https://lore.kernel.org/r/20250916140228.452231-1-sieberf@amazon.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/sched/fair.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c1842d6916d6..b331320d88b3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10635,7 +10635,19 @@ static void yield_task_fair(struct rq *rq) */ rq_clock_skip_update(rq); - se->deadline += calc_delta_fair(se->slice, se); + /* + * Forfeit the remaining vruntime, only if the entity is eligible. This + * condition is necessary because in core scheduling we prefer to run + * ineligible tasks rather than force idling. If this happens we may + * end up in a loop where the core scheduler picks the yielding task, + * which yields immediately again; without the condition the vruntime + * ends up quickly running away. + */ + if (entity_eligible(cfs_rq, se)) { + se->vruntime = se->deadline; + se->deadline += calc_delta_fair(se->slice, se); + update_min_vruntime(cfs_rq); + } } static bool yield_to_task_fair(struct rq *rq, struct task_struct *p) -- Gitee From a9329c92ea242aabb1de2075365a2468981c636d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Oct 2025 17:46:03 +0800 Subject: [PATCH 0237/1449] irqchip/irq-bcm7038-l1: Fix section mismatch ANBZ: #35228 commit f00b32894c5188a696a2beaf850b19d23f62a40b stable. commit e9db5332caaf4789ae3bafe72f61ad8e6e0c2d81 upstream. Platform drivers can be probed after their init sections have been discarded so the irqchip init callback must not live in init. Fixes: c057c799e379 ("irqchip/irq-bcm7038-l1: Switch to IRQCHIP_PLATFORM_DRIVER") Signed-off-by: Johan Hovold Signed-off-by: Thomas Gleixner Reviewed-by: Florian Fainelli Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/irq-bcm7038-l1.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index 24ca1d656adc..51d38a92ec20 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c @@ -219,9 +219,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, } #endif -static int __init bcm7038_l1_init_one(struct device_node *dn, - unsigned int idx, - struct bcm7038_l1_chip *intc) +static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, + struct bcm7038_l1_chip *intc) { struct resource res; resource_size_t sz; @@ -395,8 +394,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { .map = bcm7038_l1_map, }; -static int __init bcm7038_l1_of_init(struct device_node *dn, - struct device_node *parent) +static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) { struct bcm7038_l1_chip *intc; int idx, ret; -- Gitee From 1a715b428955f2b368e26551463acd1ec0795d09 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Oct 2025 17:46:04 +0800 Subject: [PATCH 0238/1449] irqchip/irq-bcm7120-l2: Fix section mismatch ANBZ: #35228 commit 7a57553d212394ce7b745f429014ec28d9645685 stable. commit bfc0c5beab1fde843677923cf008f41d583c980a upstream. Platform drivers can be probed after their init sections have been discarded so the irqchip init callbacks must not live in init. Fixes: 3ac268d5ed22 ("irqchip/irq-bcm7120-l2: Switch to IRQCHIP_PLATFORM_DRIVER") Signed-off-by: Johan Hovold Signed-off-by: Thomas Gleixner Reviewed-by: Florian Fainelli Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/irq-bcm7120-l2.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 1e9dab6e0d86..bb6e56629e53 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -147,8 +147,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, return 0; } -static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, - struct bcm7120_l2_intc_data *data) +static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data) { int ret; @@ -181,8 +180,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, return 0; } -static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, - struct bcm7120_l2_intc_data *data) +static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data) { unsigned int gc_idx; @@ -212,10 +210,9 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, return 0; } -static int __init bcm7120_l2_intc_probe(struct device_node *dn, - struct device_node *parent, +static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, int (*iomap_regs_fn)(struct device_node *, - struct bcm7120_l2_intc_data *), + struct bcm7120_l2_intc_data *), const char *intc_name) { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; @@ -343,15 +340,13 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, return ret; } -static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, - struct device_node *parent) +static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) { return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, "BCM7120 L2"); } -static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, - struct device_node *parent) +static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) { return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, "BCM3380 L2"); -- Gitee From b6b7c1978d2842ab735da871bf2708892c9b6ee9 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Oct 2025 17:46:05 +0800 Subject: [PATCH 0239/1449] irqchip/irq-brcmstb-l2: Fix section mismatch ANBZ: #35228 commit 1fbdca7341d98aa20e89eca510213ec62b9bcfb2 stable. commit bbe1775924478e95372c2f896064ab6446000713 upstream. Platform drivers can be probed after their init sections have been discarded so the irqchip init callbacks must not live in init. Fixes: 51d9db5c8fbb ("irqchip/irq-brcmstb-l2: Switch to IRQCHIP_PLATFORM_DRIVER") Signed-off-by: Johan Hovold Signed-off-by: Thomas Gleixner Reviewed-by: Florian Fainelli Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/irq-brcmstb-l2.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index 2b0b3175cea0..23a470868459 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -157,10 +157,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) irq_gc_unlock_irqrestore(gc, flags); } -static int __init brcmstb_l2_intc_of_init(struct device_node *np, - struct device_node *parent, - const struct brcmstb_intc_init_params - *init_params) +static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, + const struct brcmstb_intc_init_params *init_params) { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; unsigned int set = 0; @@ -276,14 +274,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, return ret; } -static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, - struct device_node *parent) +static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) { return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); } -static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, - struct device_node *parent) +static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) { return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); } -- Gitee From ae34e2eca4312253e3b13f1d29d7c10b95bed31f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Oct 2025 17:46:06 +0800 Subject: [PATCH 0240/1449] irqchip/imx-mu-msi: Fix section mismatch ANBZ: #35228 commit c696fb981d7d03da1ec5a47bae9c50ddaddd99e9 stable. commit 64acfd8e680ff8992c101fe19aadb112ce551072 upstream. Platform drivers can be probed after their init sections have been discarded so the irqchip init callbacks must not live in init. Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") Signed-off-by: Johan Hovold Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/irq-imx-mu-msi.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c index e4a5e478fb4e..8d42548c153e 100644 --- a/drivers/irqchip/irq-imx-mu-msi.c +++ b/drivers/irqchip/irq-imx-mu-msi.c @@ -297,9 +297,8 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { }, }; -static int __init imx_mu_of_init(struct device_node *dn, - struct device_node *parent, - const struct imx_mu_dcfg *cfg) +static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, + const struct imx_mu_dcfg *cfg) { struct platform_device *pdev = of_find_device_by_node(dn); struct device_link *pd_link_a; @@ -417,20 +416,17 @@ static const struct dev_pm_ops imx_mu_pm_ops = { imx_mu_runtime_resume, NULL) }; -static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, - struct device_node *parent) +static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) { return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); } -static int __init imx_mu_imx6sx_of_init(struct device_node *dn, - struct device_node *parent) +static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) { return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); } -static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, - struct device_node *parent) +static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) { return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); } -- Gitee From 4f9a55086549bd5f59eb70fdb5126dabbba0b17d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 13 Oct 2025 17:46:09 +0800 Subject: [PATCH 0241/1449] irqchip/qcom-irq-combiner: Fix section mismatch ANBZ: #35228 commit 2629742ccd3ac5233dd3a0d2a922057fa44cf6bc stable. commit 9b685058ca936752285c5520d351b828312ac965 upstream. Platform drivers can be probed after their init sections have been discarded so the probe callback must not live in init. Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") Signed-off-by: Johan Hovold Signed-off-by: Thomas Gleixner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/qcom-irq-combiner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c index 18e696dc7f4d..9308088773be 100644 --- a/drivers/irqchip/qcom-irq-combiner.c +++ b/drivers/irqchip/qcom-irq-combiner.c @@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) return 0; } -static int __init combiner_probe(struct platform_device *pdev) +static int combiner_probe(struct platform_device *pdev) { struct combiner *combiner; int nregs; -- Gitee From 41e015039534415ba91462d5812c53eb0f708c27 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 24 Sep 2025 18:20:17 +0800 Subject: [PATCH 0242/1449] crypto: authenc - Correctly pass EINPROGRESS back up to the caller ANBZ: #35228 commit 3f8878c15753d10856b32b126417a288e5b3e603 stable. commit 96feb73def02d175850daa0e7c2c90c876681b5c upstream. When authenc is invoked with MAY_BACKLOG, it needs to pass EINPROGRESS notifications back up to the caller when the underlying algorithm returns EBUSY synchronously. However, if the EBUSY comes from the second part of an authenc call, i.e., it is asynchronous, both the EBUSY and the subsequent EINPROGRESS notification must not be passed to the caller. Implement this by passing a mask to the function that starts the second half of authenc and using it to determine whether EBUSY and EINPROGRESS should be passed to the caller. This was a deficiency in the original implementation of authenc because it was not expected to be used with MAY_BACKLOG. Reported-by: Ingo Franzki Reported-by: Mikulas Patocka Fixes: 180ce7e81030 ("crypto: authenc - Add EINPROGRESS check") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- crypto/authenc.c | 75 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/crypto/authenc.c b/crypto/authenc.c index 04ae8834b0c0..ae4614edc9cf 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -37,7 +37,7 @@ struct authenc_request_ctx { static void authenc_request_complete(struct aead_request *req, int err) { - if (err != -EINPROGRESS) + if (err != -EINPROGRESS && err != -EBUSY) aead_request_complete(req, err); } @@ -107,27 +107,42 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, return err; } -static void authenc_geniv_ahash_done(void *data, int err) +static void authenc_geniv_ahash_finish(struct aead_request *req) { - struct aead_request *req = data; struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct aead_instance *inst = aead_alg_instance(authenc); struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); - if (err) - goto out; - scatterwalk_map_and_copy(ahreq->result, req->dst, req->assoclen + req->cryptlen, crypto_aead_authsize(authenc), 1); +} -out: +static void authenc_geniv_ahash_done(void *data, int err) +{ + struct aead_request *req = data; + + if (!err) + authenc_geniv_ahash_finish(req); aead_request_complete(req, err); } -static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) +/* + * Used when the ahash request was invoked in the async callback context + * of the previous skcipher request. Eat any EINPROGRESS notifications. + */ +static void authenc_geniv_ahash_done2(void *data, int err) +{ + struct aead_request *req = data; + + if (!err) + authenc_geniv_ahash_finish(req); + authenc_request_complete(req, err); +} + +static int crypto_authenc_genicv(struct aead_request *req, unsigned int mask) { struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct aead_instance *inst = aead_alg_instance(authenc); @@ -136,6 +151,7 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) struct crypto_ahash *auth = ctx->auth; struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); + unsigned int flags = aead_request_flags(req) & ~mask; u8 *hash = areq_ctx->tail; int err; @@ -146,7 +162,8 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) ahash_request_set_crypt(ahreq, req->dst, hash, req->assoclen + req->cryptlen); ahash_request_set_callback(ahreq, flags, - authenc_geniv_ahash_done, req); + mask ? authenc_geniv_ahash_done2 : + authenc_geniv_ahash_done, req); err = crypto_ahash_digest(ahreq); if (err) @@ -162,12 +179,11 @@ static void crypto_authenc_encrypt_done(void *data, int err) { struct aead_request *areq = data; - if (err) - goto out; - - err = crypto_authenc_genicv(areq, 0); - -out: + if (err) { + aead_request_complete(areq, err); + return; + } + err = crypto_authenc_genicv(areq, CRYPTO_TFM_REQ_MAY_SLEEP); authenc_request_complete(areq, err); } @@ -202,11 +218,18 @@ static int crypto_authenc_encrypt(struct aead_request *req) if (err) return err; - return crypto_authenc_genicv(req, aead_request_flags(req)); + return crypto_authenc_genicv(req, 0); +} + +static void authenc_decrypt_tail_done(void *data, int err) +{ + struct aead_request *req = data; + + authenc_request_complete(req, err); } static int crypto_authenc_decrypt_tail(struct aead_request *req, - unsigned int flags) + unsigned int mask) { struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct aead_instance *inst = aead_alg_instance(authenc); @@ -217,6 +240,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, struct skcipher_request *skreq = (void *)(areq_ctx->tail + ictx->reqoff); unsigned int authsize = crypto_aead_authsize(authenc); + unsigned int flags = aead_request_flags(req) & ~mask; u8 *ihash = ahreq->result + authsize; struct scatterlist *src, *dst; @@ -233,7 +257,9 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, skcipher_request_set_tfm(skreq, ctx->enc); skcipher_request_set_callback(skreq, flags, - req->base.complete, req->base.data); + mask ? authenc_decrypt_tail_done : + req->base.complete, + mask ? req : req->base.data); skcipher_request_set_crypt(skreq, src, dst, req->cryptlen - authsize, req->iv); @@ -244,12 +270,11 @@ static void authenc_verify_ahash_done(void *data, int err) { struct aead_request *req = data; - if (err) - goto out; - - err = crypto_authenc_decrypt_tail(req, 0); - -out: + if (err) { + aead_request_complete(req, err); + return; + } + err = crypto_authenc_decrypt_tail(req, CRYPTO_TFM_REQ_MAY_SLEEP); authenc_request_complete(req, err); } @@ -279,7 +304,7 @@ static int crypto_authenc_decrypt(struct aead_request *req) if (err) return err; - return crypto_authenc_decrypt_tail(req, aead_request_flags(req)); + return crypto_authenc_decrypt_tail(req, 0); } static int crypto_authenc_init_tfm(struct crypto_aead *tfm) -- Gitee From 0091c85786c488567c7f194db814226a0a0e39ee Mon Sep 17 00:00:00 2001 From: Raphael Pinsonneault-Thibeault Date: Mon, 13 Oct 2025 04:16:34 +0800 Subject: [PATCH 0243/1449] ntfs3: fix uninit memory after failed mi_read in mi_format_new MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 8bf729b96303bb862d7c6dc05edcf51274ae04cf stable. commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 upstream. Fix a KMSAN un-init bug found by syzkaller. ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be uptodate. We do not bring the buffer uptodate before setting it as uptodate. If the buffer were to not be uptodate, it could mean adding a buffer with un-init data to the mi record. Attempting to load that record will trigger KMSAN. Avoid this by setting the buffer as uptodate, if it’s not already, by overwriting it. Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") Signed-off-by: Raphael Pinsonneault-Thibeault Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/fsntfs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c index e19b13db4f91..446079b0866d 100644 --- a/fs/ntfs3/fsntfs.c +++ b/fs/ntfs3/fsntfs.c @@ -1369,7 +1369,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, } if (buffer_locked(bh)) __wait_on_buffer(bh); - set_buffer_uptodate(bh); + + lock_buffer(bh); + if (!buffer_uptodate(bh)) + { + memset(bh->b_data, 0, blocksize); + set_buffer_uptodate(bh); + } + unlock_buffer(bh); } else { bh = ntfs_bread(sb, block); if (!bh) { -- Gitee From 01beba1b0f2988c8a1c03919bf2baffe791c4dd6 Mon Sep 17 00:00:00 2001 From: Sidharth Seela Date: Tue, 23 Sep 2025 14:40:16 +0800 Subject: [PATCH 0244/1449] ntfs3: Fix uninit buffer allocated by __getname() ANBZ: #35228 commit dcb5e3cd96b77d52bb65988e4c914636a6d4fdd9 stable. commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 upstream. Fix uninit errors caused after buffer allocation given to 'de'; by initializing the buffer with zeroes. The fix was found by using KMSAN. Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") Signed-off-by: Sidharth Seela Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index ba365983422d..bb3459c2ae02 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -1720,6 +1720,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) de = __getname(); if (!de) return -ENOMEM; + memset(de, 0, PATH_MAX); /* Mark rw ntfs as dirty. It will be cleared at umount. */ ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); -- Gitee From 768527c6689439796ebc2f645151b4d822d56789 Mon Sep 17 00:00:00 2001 From: Xuanqiang Luo Date: Wed, 15 Oct 2025 10:02:34 +0800 Subject: [PATCH 0245/1449] rculist: Add hlist_nulls_replace_rcu() and hlist_nulls_replace_init_rcu() ANBZ: #35228 commit ad12d25edbbeda64f9d44fce230ad351e2544e3f stable. commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 upstream. Add two functions to atomically replace RCU-protected hlist_nulls entries. Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as mentioned in the patch below: commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for rculist_nulls") commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for hlist_nulls") Reviewed-by: Kuniyuki Iwashima Reviewed-by: Frederic Weisbecker Reviewed-by: Eric Dumazet Signed-off-by: Xuanqiang Luo Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev Signed-off-by: Jakub Kicinski Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h index 89186c499dd4..c26cb83ca071 100644 --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) #define hlist_nulls_next_rcu(node) \ (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) +/** + * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. + * @node: element of the list. + */ +#define hlist_nulls_pprev_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) + /** * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization * @n: the element to delete from the hash list. @@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); } +/** + * hlist_nulls_replace_rcu - replace an old entry by a new one + * @old: the element to be replaced + * @new: the new element to insert + * + * Description: + * Replace the old entry with the new one in a RCU-protected hlist_nulls, while + * permitting racing traversals. + * + * The caller must take whatever precautions are necessary (such as holding + * appropriate locks) to avoid racing with another list-mutation primitive, such + * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same + * list. However, it is perfectly legal to run concurrently with the _rcu + * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). + */ +static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, + struct hlist_nulls_node *new) +{ + struct hlist_nulls_node *next = old->next; + + WRITE_ONCE(new->next, next); + WRITE_ONCE(new->pprev, old->pprev); + rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); + if (!is_a_nulls(next)) + WRITE_ONCE(next->pprev, &new->next); +} + +/** + * hlist_nulls_replace_init_rcu - replace an old entry by a new one and + * initialize the old + * @old: the element to be replaced + * @new: the new element to insert + * + * Description: + * Replace the old entry with the new one in a RCU-protected hlist_nulls, while + * permitting racing traversals, and reinitialize the old entry. + * + * Note: @old must be hashed. + * + * The caller must take whatever precautions are necessary (such as holding + * appropriate locks) to avoid racing with another list-mutation primitive, such + * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same + * list. However, it is perfectly legal to run concurrently with the _rcu + * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). + */ +static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, + struct hlist_nulls_node *new) +{ + hlist_nulls_replace_rcu(old, new); + WRITE_ONCE(old->pprev, NULL); +} + /** * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type * @tpos: the type * to use as a loop cursor. -- Gitee From 006d89a6d65a875f29e97ba688e73d0d77a9bfe3 Mon Sep 17 00:00:00 2001 From: Xuanqiang Luo Date: Wed, 15 Oct 2025 10:02:35 +0800 Subject: [PATCH 0246/1449] inet: Avoid ehash lookup race in inet_ehash_insert() ANBZ: #35228 commit 23b2b6af8dc67ce1446a97e506d3508bdfc12070 stable. commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc upstream. Since ehash lookups are lockless, if one CPU performs a lookup while another concurrently deletes and inserts (removing reqsk and inserting sk), the lookup may fail to find the socket, an RST may be sent. The call trace map is drawn as follows: CPU 0 CPU 1 ----- ----- inet_ehash_insert() spin_lock() sk_nulls_del_node_init_rcu(osk) __inet_lookup_established() (lookup failed) __sk_nulls_add_node_rcu(sk, list) spin_unlock() As both deletion and insertion operate on the same ehash chain, this patch introduces a new sk_nulls_replace_node_init_rcu() helper functions to implement atomic replacement. Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") Reviewed-by: Kuniyuki Iwashima Reviewed-by: Jiayuan Chen Signed-off-by: Xuanqiang Luo Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/sock.h | 13 +++++++++++++ net/ipv4/inet_hashtables.c | 8 ++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 70e1c1e378c1..2201e70741c9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -833,6 +833,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) return rc; } +static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, + struct sock *new) +{ + if (sk_hashed(old)) { + hlist_nulls_replace_init_rcu(&old->sk_nulls_node, + &new->sk_nulls_node); + __sock_put(old); + return true; + } + + return false; +} + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) { hlist_add_head(&sk->sk_node, list); diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 60e81f6b1c6d..7292f7017625 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -676,8 +676,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) spin_lock(lock); if (osk) { WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); - ret = sk_nulls_del_node_init_rcu(osk); - } else if (found_dup_sk) { + ret = sk_nulls_replace_node_init_rcu(osk, sk); + goto unlock; + } + + if (found_dup_sk) { *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); if (*found_dup_sk) ret = false; @@ -686,6 +689,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) if (ret) __sk_nulls_add_node_rcu(sk, list); +unlock: spin_unlock(lock); return ret; -- Gitee From 94e91dacb439107f67598ce906ea6737db1e9c26 Mon Sep 17 00:00:00 2001 From: Francesco Lavra Date: Sat, 18 Oct 2025 00:42:54 +0800 Subject: [PATCH 0247/1449] iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member ANBZ: #35228 commit cf5cd55287a121503cfa09d62756db3607de988a stable. commit c6d702f2b77194b62fb2098c63bb7f2a87da142d upstream. The `odr` field in struct st_lsm6dsx_sensor contains a data rate value expressed in mHz, not in Hz. Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") Signed-off-by: Francesco Lavra Acked-by: Lorenzo Bianconi Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 35325d2e1ce6..33b5c660103e 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -381,7 +381,7 @@ enum st_lsm6dsx_fifo_mode { * @id: Sensor identifier. * @hw: Pointer to instance of struct st_lsm6dsx_hw. * @gain: Configured sensor sensitivity. - * @odr: Output data rate of the sensor [Hz]. + * @odr: Output data rate of the sensor [mHz]. * @samples_to_discard: Number of samples to discard for filters settling time. * @watermark: Sensor watermark level. * @decimator: Sensor decimation factor. -- Gitee From 40ef42f6f27c1d6d33deef68b92191e3352b5412 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 18 Sep 2025 23:44:45 +0800 Subject: [PATCH 0248/1449] arm64: dts: freescale: imx8mp-venice-gw7905-2x: remove duplicate usdhc1 props ANBZ: #35228 commit d553d5e13edbccaa70ac34781cde32b46ae31829 stable. commit 8b7e58ab4a02601a0e86e9f9701d4612038d8b29 upstream. Remove the un-intended duplicate properties from usdhc1. Fixes: 0d5b288c2110e ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") Signed-off-by: Tim Harvey Reviewed-by: Peng Fan Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi index 560c68e4da6d..f541360cb554 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi @@ -401,9 +401,6 @@ &usdhc1 { bus-width = <4>; non-removable; status = "okay"; - bus-width = <4>; - non-removable; - status = "okay"; }; /* eMMC */ -- Gitee From 119944d67e3bc4ecfe1534c5e33a718fcb331e7a Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 18 Sep 2025 23:44:49 +0800 Subject: [PATCH 0249/1449] arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl ANBZ: #35228 commit e2060f8513b5241b7318b1ace863e1e1e9190cd0 stable. commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 upstream. The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the unused pinctrl_usdhc1 iomux node. Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") Signed-off-by: Tim Harvey Reviewed-by: Peng Fan Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi index 570992a52b75..7263bbf0f052 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi @@ -337,17 +337,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 >; }; - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 - MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 - MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 - MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 - MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 - MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 - >; - }; - pinctrl_usdhc2: usdhc2grp { fsl,pins = < MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 -- Gitee From d2d4c4b24de71bef6bc3a9675bde9166325abe85 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 18 Sep 2025 23:44:50 +0800 Subject: [PATCH 0250/1449] arm64: dts: imx8mp-venice-gw702x: remove off-board uart ANBZ: #35228 commit 5db023188615944daebe73c398da9b15a8f2cc38 stable. commit effe98060f70eb96e142f656e750d6af275ceac3 upstream. UART1 and UART3 go to a connector for use on a baseboard and as such are defined in the baseboard device-trees. Remove them from the gw702x SOM device-tree. Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") Signed-off-by: Tim Harvey Reviewed-by: Peng Fan Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../dts/freescale/imx8mp-venice-gw702x.dtsi | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi index f541360cb554..ac5b3a8ce729 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi @@ -373,13 +373,6 @@ &i2c3 { status = "okay"; }; -/* off-board header */ -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; - status = "okay"; -}; - /* console */ &uart2 { pinctrl-names = "default"; @@ -387,13 +380,6 @@ &uart2 { status = "okay"; }; -/* off-board header */ -&uart3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; - status = "okay"; -}; - /* off-board */ &usdhc1 { pinctrl-names = "default"; @@ -496,13 +482,6 @@ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c2 >; }; - pinctrl_uart1: uart1grp { - fsl,pins = < - MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 - MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 - >; - }; - pinctrl_uart2: uart2grp { fsl,pins = < MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 @@ -510,13 +489,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 >; }; - pinctrl_uart3: uart3grp { - fsl,pins = < - MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 - MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 - >; - }; - pinctrl_usdhc1: usdhc1grp { fsl,pins = < MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 -- Gitee From bdd532c2b1b6654e3a9997364800fc3c899a9554 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Thu, 18 Sep 2025 23:44:51 +0800 Subject: [PATCH 0251/1449] arm64: dts: imx8mp-venice-gw702x: remove off-board sdhc1 ANBZ: #35228 commit 631786221875346cfd6d30b24f182e92838d0a6f stable. commit 9db04b310ef99b546e4240c55842e81b06b78579 upstream. SDHC1 on the GW702x SOM routes to a connector for use on a baseboard and as such are defined in the baseboard device-trees. Remove it from the gw702x SOM device-tree. Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") Signed-off-by: Tim Harvey Reviewed-by: Peng Fan Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../dts/freescale/imx8mp-venice-gw702x.dtsi | 20 ------------------- .../dts/freescale/imx8mp-venice-gw72xx.dtsi | 11 ---------- 2 files changed, 31 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi index ac5b3a8ce729..de21faeafd09 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi @@ -380,15 +380,6 @@ &uart2 { status = "okay"; }; -/* off-board */ -&usdhc1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; - bus-width = <4>; - non-removable; - status = "okay"; -}; - /* eMMC */ &usdhc3 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; @@ -489,17 +480,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 >; }; - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 - MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 - MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 - MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 - MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 - MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 - >; - }; - pinctrl_usdhc3: usdhc3grp { fsl,pins = < MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi index f3bab22d5e68..fc1ee675c88d 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi @@ -310,17 +310,6 @@ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 >; }; - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 - MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 - MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 - MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 - MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 - MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 - >; - }; - pinctrl_usdhc2: usdhc2grp { fsl,pins = < MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 -- Gitee From 9d198a4fde467050e3e89a7314da7e29d1d0412f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 3 Oct 2025 16:35:34 +0800 Subject: [PATCH 0252/1449] PCI: rcar-gen2: Drop ARM dependency from PCI_RCAR_GEN2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 433e72bf0f4ec45406796451741476ea09abbc0e stable. commit d312742f686582e6457070bcfd24bee8acfdf213 upstream. Since the reliance on ARM-specific struct pci_sys_data was removed, this driver can be compile-tested on other architectures. While at it, make the help text a bit more generic, as some members of the R-Car Gen2 family have a different number of internal PCI controllers. Fixes: 4a957563fe0231e0 ("PCI: rcar-gen2: Convert to use modern host bridge probe functions") Suggested-by: Ilpo Jarvinen Signed-off-by: Geert Uytterhoeven Signed-off-by: Manivannan Sadhasivam [bhelgaas: add rcar-gen2 to subject] Signed-off-by: Bjorn Helgaas Reviewed-by: Ilpo Järvinen Link: https://patch.msgid.link/00f75d6732eacce93f04ffaeedc415d2db714cd6.1759480426.git.geert+renesas@glider.be Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/controller/Kconfig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 2a2a3ccd66ad..ab780887a821 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -257,12 +257,11 @@ config PCIE_RCAR_EP config PCI_RCAR_GEN2 bool "Renesas R-Car Gen2 Internal PCI controller" - depends on ARCH_RENESAS || COMPILE_TEST - depends on ARM + depends on (ARCH_RENESAS && ARM) || COMPILE_TEST help Say Y here if you want internal PCI support on R-Car Gen2 SoC. - There are 3 internal PCI controllers available with a single - built-in EHCI/OHCI host controller present on each one. + Each internal PCI controller contains a single built-in EHCI/OHCI + host controller. config PCIE_ROCKCHIP bool -- Gitee From 007a5e7a2239ac037e0d61e94def7e3bd045aefe Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Wed, 15 Oct 2025 14:40:20 +0800 Subject: [PATCH 0253/1449] uio: uio_fsl_elbc_gpcm:: Add null pointer check to uio_fsl_elbc_gpcm_probe ANBZ: #35228 commit 285dadbb3cb0316f2d094b02b67e4a7cf54b0acf stable. commit d48fb15e6ad142e0577428a8c5028136e10c7b3d upstream. devm_kasprintf() returns a pointer to dynamically allocated memory which can be NULL upon failure. Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") Signed-off-by: Li Qiang Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c index 82dda799f327..a433bc84313f 100644 --- a/drivers/uio/uio_fsl_elbc_gpcm.c +++ b/drivers/uio/uio_fsl_elbc_gpcm.c @@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) /* set all UIO data */ info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); + if (!info->mem[0].name) { + ret = -ENODEV; + goto out_err3; + } + info->mem[0].addr = res.start; info->mem[0].size = resource_size(&res); info->mem[0].memtype = UIO_MEM_PHYS; @@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) out_err2: if (priv->shutdown) priv->shutdown(info, true); + +out_err3: iounmap(info->mem[0].internal_addr); return ret; } -- Gitee From 52e6ffee79285ae567862b46a9d5c6e07033560e Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 22 Oct 2025 07:44:46 +0800 Subject: [PATCH 0254/1449] clk: qcom: camcc-sm6350: Specify Titan GDSC power domain as a parent to other ANBZ: #35228 commit 77197835a735f73f8cb264d5ca2c83fb677ad5e2 stable. commit a76ce61d7225934b0a52c8172a8cd944002a8c6f upstream. When a consumer turns on/off a power domain dependent on another power domain in hardware, the parent power domain shall be turned on/off by the power domain provider as well, and to get it the power domain hardware hierarchy shall be described in the CAMCC driver. Establish the power domain hierarchy with a Titan GDSC set as a parent of all other GDSC power domains provided by the SM6350 camera clock controller to enforce a correct sequence of enabling and disabling power domains by the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS IP and its driver. Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") Reviewed-by: Konrad Dybcio Reviewed-by: Imran Shaik Reviewed-by: Bryan O'Donoghue Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20251021234450.2271279-3-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/qcom/camcc-sm6350.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index eca36bd3ba5c..79131e1699b8 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -1692,6 +1692,8 @@ static struct clk_branch camcc_sys_tmr_clk = { }, }; +static struct gdsc titan_top_gdsc; + static struct gdsc bps_gdsc = { .gdscr = 0x6004, .en_rest_wait_val = 0x2, @@ -1701,6 +1703,7 @@ static struct gdsc bps_gdsc = { .name = "bps_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = VOTABLE, }; @@ -1713,6 +1716,7 @@ static struct gdsc ipe_0_gdsc = { .name = "ipe_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, .flags = VOTABLE, }; @@ -1725,6 +1729,7 @@ static struct gdsc ife_0_gdsc = { .name = "ife_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc ife_1_gdsc = { @@ -1736,6 +1741,7 @@ static struct gdsc ife_1_gdsc = { .name = "ife_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc ife_2_gdsc = { @@ -1747,6 +1753,7 @@ static struct gdsc ife_2_gdsc = { .name = "ife_2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .parent = &titan_top_gdsc.pd, }; static struct gdsc titan_top_gdsc = { -- Gitee From fd3ceb0b631b3fe1f6905ed6da2c5fc3596fcf8b Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 22 Oct 2025 02:08:54 +0800 Subject: [PATCH 0255/1449] clk: qcom: camcc-sm6350: Fix PLL config of PLL2 ANBZ: #35228 commit 4a1535593fffe29e32ae1949bc452ce22620f9ac stable. commit ab0e13141d679fdffdd3463a272c5c1b10be1794 upstream. The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the parameters that are provided in the vendor driver. Instead the upstream configuration should provide the final user_ctl value that is written to the USER_CTL register. Fix the config so that the PLL is configured correctly, and fixes CAMCC_MCLK* being stuck off. Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") Suggested-by: Taniya Das Signed-off-by: Luca Weiss Reviewed-by: Abel Vesa Reviewed-by: Taniya Das Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-1-8c1d8aff4afc@fairphone.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/qcom/camcc-sm6350.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index 79131e1699b8..83cee6994d16 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -144,15 +144,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { static const struct alpha_pll_config camcc_pll2_config = { .l = 0x64, .alpha = 0x0, - .post_div_val = 0x3 << 8, - .post_div_mask = 0x3 << 8, - .aux_output_mask = BIT(1), - .main_output_mask = BIT(0), - .early_output_mask = BIT(3), .config_ctl_val = 0x20000800, .config_ctl_hi_val = 0x400003d2, .test_ctl_val = 0x04000400, .test_ctl_hi_val = 0x00004000, + .user_ctl_val = 0x0000030b, }; static struct clk_alpha_pll camcc_pll2 = { -- Gitee From aff95e5f14db2e1897fb9e7ff4e95379b6273c42 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 13 Oct 2025 19:40:10 +0800 Subject: [PATCH 0256/1449] crypto: asymmetric_keys - prevent overflow in asymmetric_key_generate_id ANBZ: #35228 commit 5b8ac617c8dab5cad3c4dc8d84d0987808a0f99c stable. commit df0845cf447ae1556c3440b8b155de0926cbaa56 upstream. Use check_add_overflow() to guard against potential integer overflows when adding the binary blob lengths and the size of an asymmetric_key_id structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a possible buffer overflow when copying data from potentially malicious X.509 certificate fields that can be arbitrarily large, such as ASN.1 INTEGER serial numbers, issuer names, etc. Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") Signed-off-by: Thorsten Blum Reviewed-by: Lukas Wunner Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 43af5fa510c0..7859b0692b42 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -151,12 +152,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, size_t len_2) { struct asymmetric_key_id *kid; - - kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, - GFP_KERNEL); + size_t kid_sz; + size_t len; + + if (check_add_overflow(len_1, len_2, &len)) + return ERR_PTR(-EOVERFLOW); + if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) + return ERR_PTR(-EOVERFLOW); + kid = kmalloc(kid_sz, GFP_KERNEL); if (!kid) return ERR_PTR(-ENOMEM); - kid->len = len_1 + len_2; + kid->len = len; memcpy(kid->data, val_1, len_1); memcpy(kid->data + len_1, val_2, len_2); return kid; -- Gitee From 3b3ad7c2b001d7b7f5443816be33802318fb07f4 Mon Sep 17 00:00:00 2001 From: nieweiqiang Date: Sat, 18 Oct 2025 19:27:39 +0800 Subject: [PATCH 0257/1449] crypto: hisilicon/qm - restore original qos values ANBZ: #35228 commit 9484379c88e1404e52879e9c459c672c61905af3 stable. commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 upstream. When the new qos valus setting fails, restore to the original qos values. Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") Signed-off-by: nieweiqiang Signed-off-by: Chenghai Huang Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index a2c6b28f4b84..2c0ca68914e2 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -3555,6 +3555,7 @@ static int qm_clear_vft_config(struct hisi_qm *qm) static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) { struct device *dev = &qm->pdev->dev; + struct qm_shaper_factor t_factor; u32 ir = qos * QM_QOS_RATE; int ret, total_vfs, i; @@ -3562,6 +3563,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) if (fun_index > total_vfs) return -EINVAL; + memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); qm->factor[fun_index].func_qos = qos; ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); @@ -3575,11 +3577,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); if (ret) { dev_err(dev, "type: %d, failed to set shaper vft!\n", i); - return -EINVAL; + goto back_func_qos; } } return 0; + +back_func_qos: + memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); + for (i--; i >= ALG_TYPE_0; i--) { + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) + dev_err(dev, "failed to restore shaper vft during rollback!\n"); + } + + return -EINVAL; } static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) -- Gitee From 7a87aeb565f466fde2fa90af43c423e92cbc862d Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Fri, 17 Oct 2025 09:49:00 +0800 Subject: [PATCH 0258/1449] wifi: ath11k: fix peer HE MCS assignment ANBZ: #35228 commit 4304bd7a334e981f189b9973056a58f84cc2b482 stable. commit 4a013ca2d490c73c40588d62712ffaa432046a04 upstream. In ath11k_wmi_send_peer_assoc_cmd(), peer's transmit MCS is sent to firmware as receive MCS while peer's receive MCS sent as transmit MCS, which goes against firmwire's definition. While connecting to a misbehaved AP that advertises 0xffff (meaning not supported) for 160 MHz transmit MCS map, firmware crashes due to 0xffff is assigned to he_mcs->rx_mcs_set field. Ext Tag: HE Capabilities [...] Supported HE-MCS and NSS Set [...] Rx and Tx MCS Maps 160 MHz [...] Tx HE-MCS Map 160 MHz: 0xffff Swap the assignment to fix this issue. As the HE rate control mask is meant to limit our own transmit MCS, it needs to go via he_mcs->rx_mcs_set field. With the aforementioned swapping done, change is needed as well to apply it to the peer's receive MCS. Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Fixes: 61fe43e7216d ("ath11k: add support for setting fixed HE rate/gi/ltf") Signed-off-by: Baochen Qiang Reviewed-by: Vasanthakumar Thiagarajan Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-2-da40825c1783@oss.qualcomm.com Signed-off-by: Jeff Johnson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2921be9bd530..0937d725d4d0 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2424,10 +2424,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, he_tx_mcs = v; } v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); - v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; arg->peer_he_mcs_count++; @@ -2437,10 +2437,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, default: v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); + v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); - v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; arg->peer_he_mcs_count++; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 16687223bdcb..f491aeb22a88 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -2044,8 +2044,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, FIELD_PREP(WMI_TLV_LEN, sizeof(*he_mcs) - TLV_HDR_SIZE); - he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; - he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; + /* firmware interprets mcs->rx_mcs_set field as peer's + * RX capability + */ + he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; + he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; ptr += sizeof(*he_mcs); } -- Gitee From 5088cdd9ef1bfe8376180803b14287d2cf7e1565 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 20 Oct 2025 22:17:54 +0800 Subject: [PATCH 0259/1449] s390/smp: Fix fallback CPU detection ANBZ: #35228 commit 772ded5a84e0a414e13203d6b28f65659b7cbe74 stable. commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 upstream. In case SCLP CPU detection does not work a fallback mechanism using SIGP is in place. Since a cleanup this does not work correctly anymore: new CPUs are only considered if their type matches the boot CPU. Before the cleanup the information if a CPU type should be considered was also part of a structure generated by the fallback mechanism and indicated that a CPU type should not be considered when adding CPUs. Since the rework a global SCLP state is used instead. If the global SCLP state indicates that the CPU type should be considered and the fallback mechanism is used, there may be a mismatch with CPU types if CPUs are added. This can lead to a system with only a single CPU even tough there are many more CPUs. Address this by simply copying the boot cpu type into the generated data structure from the fallback mechanism. Reported-by: Alexander Egorenkov Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") Reviewed-by: Mete Durlu Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/s390/kernel/smp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index c63be2efd689..1970c9077597 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -759,6 +759,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) continue; info->core[info->configured].core_id = address >> smp_cpu_mt_shift; + info->core[info->configured].type = boot_core_type; info->configured++; } info->combined = info->configured; -- Gitee From 436c95dd1454debb6f7470d8b56140debe1a7f72 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 24 Oct 2025 18:24:33 +0800 Subject: [PATCH 0260/1449] s390/ap: Don't leak debug feature files if AP instructions are not available ANBZ: #35228 commit bb04d3610f0803f7c2cb0b9a9ee38c02908ec3f2 stable. commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 upstream. If no AP instructions are available the AP bus module leaks registered debug feature files. Change function call order to fix this. Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") Reviewed-by: Harald Freudenberger Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/s390/crypto/ap_bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 93351452184a..97cbf233a543 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -2235,15 +2235,15 @@ static int __init ap_module_init(void) { int rc; - rc = ap_debug_init(); - if (rc) - return rc; - if (!ap_instructions_available()) { pr_warn("The hardware system does not support AP instructions\n"); return -ENODEV; } + rc = ap_debug_init(); + if (rc) + return rc; + /* init ap_queue hashtable */ hash_init(ap_queues); -- Gitee From 41de263cf6cc7e16b11cbb534e6f2bfc0df45746 Mon Sep 17 00:00:00 2001 From: Randolph Sapp Date: Sat, 20 Sep 2025 03:33:42 +0800 Subject: [PATCH 0261/1449] arm64: dts: ti: k3-am62p: Fix memory ranges for GPU ANBZ: #35228 commit abdbffb6a0878bc36aee4627ec2a651274783b90 stable. commit 76546090b1726118cd6fb3db7159fc2a3fdda8a0 upstream. Update the memory region listed in the k3-am62p.dtsi for the BXS-4-64 GPU to match the Main Memory Map described in the TRM [1]. [1] https://www.ti.com/lit/ug/spruj83b/spruj83b.pdf Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs") Signed-off-by: Randolph Sapp Reviewed-by: Michael Walle Link: https://patch.msgid.link/20250919193341.707660-2-rs@ti.com Signed-off-by: Vignesh Raghavendra Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi index dc0a8e94e9ac..0e0241e746fb 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi @@ -59,7 +59,7 @@ cbass_main: bus@f0000 { <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */ <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */ <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ - <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */ + <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */ <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */ <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */ -- Gitee From 956fe0c0ff1fd997c16cb2aa1c30bc85ac098880 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:24 +0800 Subject: [PATCH 0262/1449] firmware: imx: scu-irq: fix OF node leak in ANBZ: #35228 commit a649992b7eb33f84c052a786f1f3c543363c61f4 stable. commit ee67247843a2b62d1473cfa4df300e69b5190ccf upstream. imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), but does not release the OF node reference. Add a of_node_put() call to release the reference. Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/imx/imx-scu-irq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index 6125cccc9ba7..f2b902e95b73 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -226,8 +226,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); if (!of_parse_phandle_with_args(dev->of_node, "mboxes", - "#mbox-cells", 0, &spec)) + "#mbox-cells", 0, &spec)) { i = of_alias_get_id(spec.np, "mu"); + of_node_put(spec.np); + } /* use mu1 as general mu irq channel if failed */ if (i < 0) -- Gitee From faaadaebbbaf806f6c027808c940741300821874 Mon Sep 17 00:00:00 2001 From: Gergo Koteles Date: Sat, 27 Sep 2025 19:20:28 +0800 Subject: [PATCH 0263/1449] arm64: dts: qcom: sdm845-oneplus: Correct gpio used for slider ANBZ: #35228 commit 32d9c68af13344caa16652433f9ee8bd063edba1 stable. commit d7ec7d34237498fab7a6afed8da4b7139b0e387c upstream. The previous GPIO numbers were wrong. Update them to the correct ones and fix the label. Fixes: 288ef8a42612 ("arm64: dts: sdm845: add oneplus6/6t devices") Signed-off-by: Gergo Koteles Signed-off-by: David Heidelberg Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250927-slider-correct-v1-1-fb8cc7fdcedf@ixit.cz Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi index 9322b92a1e68..bccc52e01da3 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi @@ -780,8 +780,8 @@ hall_sensor_default: hall-sensor-default-state { bias-disable; }; - tri_state_key_default: tri-state-key-default-state { - pins = "gpio40", "gpio42", "gpio26"; + alert_slider_default: alert-slider-default-state { + pins = "gpio126", "gpio52", "gpio24"; function = "gpio"; drive-strength = <2>; bias-disable; -- Gitee From d6e0dd313655020e74c2a0bbef9f62b4e6a76372 Mon Sep 17 00:00:00 2001 From: Horatiu Vultur Date: Fri, 24 Oct 2025 03:13:50 +0800 Subject: [PATCH 0264/1449] phy: mscc: Fix PTP for VSC8574 and VSC8572 ANBZ: #35228 commit 85ede044f43d98ee6a53872afbeab2220b8773f3 stable. commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 upstream. The PTP initialization is two-step. First part are the function vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which initialize the locks, queues, creates the PTP device. The second part is the function vsc8584_ptp_init() at config_init() time which initialize PTP in the HW. For VSC8574 and VSC8572, the PTP initialization is incomplete. It is missing the first part but it makes the second part. Meaning that the ptp_clock_register() is never called. There is no crash without the first part when enabling PTP but this is unexpected because some PHys have PTP functionality exposed by the driver and some don't even though they share the same PTP clock PTP. Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") Reviewed-by: Maxime Chevallier Signed-off-by: Horatiu Vultur Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/mscc/mscc_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index 3a932b30f435..0a4aa8e08827 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -2595,7 +2595,7 @@ static struct phy_driver vsc85xx_driver[] = { .suspend = &genphy_suspend, .resume = &genphy_resume, .remove = &vsc85xx_remove, - .probe = &vsc8574_probe, + .probe = &vsc8584_probe, .set_wol = &vsc85xx_wol_set, .get_wol = &vsc85xx_wol_get, .get_tunable = &vsc85xx_get_tunable, @@ -2616,12 +2616,12 @@ static struct phy_driver vsc85xx_driver[] = { .config_aneg = &vsc85xx_config_aneg, .aneg_done = &genphy_aneg_done, .read_status = &vsc85xx_read_status, - .handle_interrupt = vsc85xx_handle_interrupt, + .handle_interrupt = vsc8584_handle_interrupt, .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, .remove = &vsc85xx_remove, - .probe = &vsc8574_probe, + .probe = &vsc8584_probe, .set_wol = &vsc85xx_wol_set, .get_wol = &vsc85xx_wol_get, .get_tunable = &vsc85xx_get_tunable, -- Gitee From c6a2f1808b9289e6ce519e3688146b4c45fa333d Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 24 Oct 2025 07:16:50 +0800 Subject: [PATCH 0265/1449] sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). ANBZ: #35228 commit 8f2602a83f669e5a955f59a4caa832896b9018b8 stable. commit 622e8838a29845316668ec2e7648428878df7f9a upstream. SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() returns 0 after successfully allocating sctp_sk(sk)->ep. OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). The code seems to expect that the socket is always exposed to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but there is a path where the assumption is not true. In sctp_accept(), sctp_sock_migrate() could fail after sctp_init_sock(). Then, sk_common_release() does not call inet_release() nor sctp_close(). Instead, it calls sk->sk_prot->destroy(). Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to sctp_destroy_sock(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Kuniyuki Iwashima Acked-by: Xin Long Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sctp/socket.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index adc04e88f349..852c4f66eab5 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1553,8 +1553,6 @@ static void sctp_close(struct sock *sk, long timeout) spin_unlock_bh(&net->sctp.addr_wq_lock); sock_put(sk); - - SCTP_DBG_OBJCNT_DEC(sock); } /* Handle EPIPE error. */ @@ -5106,9 +5104,12 @@ static void sctp_destroy_sock(struct sock *sk) sp->do_auto_asconf = 0; list_del(&sp->auto_asconf_list); } + sctp_endpoint_free(sp->ep); + sk_sockets_allocated_dec(sk); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + SCTP_DBG_OBJCNT_DEC(sock); } /* Triggered when there are no references on the socket anymore */ -- Gitee From beac50716438752f9dd4df276678a5897bc8888b Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Tue, 28 Oct 2025 05:52:03 +0800 Subject: [PATCH 0266/1449] RDMA/rxe: Fix null deref on srq->rq.queue after resize failure ANBZ: #35228 commit 58aca869babd48cb9c3d6ee9e1452c4b9f5266a6 stable. commit 503a5e4690ae14c18570141bc0dcf7501a8419b0 upstream. A NULL pointer dereference can occur in rxe_srq_chk_attr() when ibv_modify_srq() is invoked twice in succession under certain error conditions. The first call may fail in rxe_queue_resize(), which leads rxe_srq_from_attr() to set srq->rq.queue = NULL. The second call then triggers a crash (null deref) when accessing srq->rq.queue->buf->index_mask. Call Trace: rxe_modify_srq+0x170/0x480 [rdma_rxe] ? __pfx_rxe_modify_srq+0x10/0x10 [rdma_rxe] ? uverbs_try_lock_object+0x4f/0xa0 [ib_uverbs] ? rdma_lookup_get_uobject+0x1f0/0x380 [ib_uverbs] ib_uverbs_modify_srq+0x204/0x290 [ib_uverbs] ? __pfx_ib_uverbs_modify_srq+0x10/0x10 [ib_uverbs] ? tryinc_node_nr_active+0xe6/0x150 ? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x2c0/0x470 [ib_uverbs] ? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] ? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] ib_uverbs_run_method+0x55a/0x6e0 [ib_uverbs] ? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] ib_uverbs_cmd_verbs+0x54d/0x800 [ib_uverbs] ? __pfx_ib_uverbs_cmd_verbs+0x10/0x10 [ib_uverbs] ? __pfx___raw_spin_lock_irqsave+0x10/0x10 ? __pfx_do_vfs_ioctl+0x10/0x10 ? ioctl_has_perm.constprop.0.isra.0+0x2c7/0x4c0 ? __pfx_ioctl_has_perm.constprop.0.isra.0+0x10/0x10 ib_uverbs_ioctl+0x13e/0x220 [ib_uverbs] ? __pfx_ib_uverbs_ioctl+0x10/0x10 [ib_uverbs] __x64_sys_ioctl+0x138/0x1c0 do_syscall_64+0x82/0x250 ? fdget_pos+0x58/0x4c0 ? ksys_write+0xf3/0x1c0 ? __pfx_ksys_write+0x10/0x10 ? do_syscall_64+0xc8/0x250 ? __pfx_vm_mmap_pgoff+0x10/0x10 ? fget+0x173/0x230 ? fput+0x2a/0x80 ? ksys_mmap_pgoff+0x224/0x4c0 ? do_syscall_64+0xc8/0x250 ? do_user_addr_fault+0x37b/0xfe0 ? clear_bhb_loop+0x50/0xa0 ? clear_bhb_loop+0x50/0xa0 ? clear_bhb_loop+0x50/0xa0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fixes: 8700e3e7c485 ("Soft RoCE driver") Tested-by: Liu Yi Signed-off-by: Zhu Yanjun Link: https://patch.msgid.link/20251027215203.1321-1-yanjun.zhu@linux.dev Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/sw/rxe/rxe_srq.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c index 3661cb627d28..2a234f26ac10 100644 --- a/drivers/infiniband/sw/rxe/rxe_srq.c +++ b/drivers/infiniband/sw/rxe/rxe_srq.c @@ -171,7 +171,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, udata, mi, &srq->rq.producer_lock, &srq->rq.consumer_lock); if (err) - goto err_free; + return err; srq->rq.max_wr = attr->max_wr; } @@ -180,11 +180,6 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, srq->limit = attr->srq_limit; return 0; - -err_free: - rxe_queue_cleanup(q); - srq->rq.queue = NULL; - return err; } void rxe_srq_cleanup(struct rxe_pool_elem *elem) -- Gitee From cad968a6c9410d1fac31a84ca548f0dd3ad02257 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 29 Sep 2025 17:36:02 +0800 Subject: [PATCH 0267/1449] ARM: dts: renesas: gose: Remove superfluous port property ANBZ: #35228 commit eb8ac04f1036b687e1414410a4c3bf8df8ff5c9c stable. commit 00df14f34615630f92f97c9d6790bd9d25c4242d upstream. 'bus-width' is defined for the corresponding vin input port already. No need to declare it in the output port again. Fixes: arch/arm/boot/dts/renesas/r8a7793-gose.dtb: composite-in@20 (adi,adv7180cp): ports:port@3:endpoint: Unevaluated properties are not allowed ('bus-width' was unexpected) from schema $id: http://devicetree.org/schemas/media/i2c/adi,adv7180.yaml# Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20250929093616.17679-2-wsa+renesas@sang-engineering.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/renesas/r8a7793-gose.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts index 9358fc7d0e9f..e92de3ab33b5 100644 --- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts +++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts @@ -355,7 +355,6 @@ adv7180_in: endpoint { port@3 { reg = <3>; adv7180_out: endpoint { - bus-width = <8>; remote-endpoint = <&vin1ep>; }; }; -- Gitee From 57eea08a7ba02743781b5bbf9621edf2cf9f7bfc Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 7 Oct 2025 18:46:25 +0800 Subject: [PATCH 0268/1449] ARM: dts: renesas: r9a06g032-rzn1d400-db: Drop invalid #cells properties ANBZ: #35228 commit 4a493d02ff463ce9d088dcf4ca1bd07ba300e9cb stable. commit ca7fffb6e92a7c93604ea2bae0e1c89b20750937 upstream. The 'ethernet-ports' node in the SoC DTSI handles them already. Fixes: arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dtb: switch@44050000 (renesas,r9a06g032-a5psw): Unevaluated properties are not allowed ('#address-cells', '#size-cells' were unexpected) from schema $id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml# Fixes: 5b6d7c3c5861ad4a ("ARM: dts: r9a06g032-rzn1d400-db: Add switch description") Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251007104624.19786-2-wsa+renesas@sang-engineering.com Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts index 31cdca3e623c..5fa7acce4714 100644 --- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts @@ -126,8 +126,6 @@ &rtc0 { &switch { status = "okay"; - #address-cells = <1>; - #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pins_eth3>, <&pins_eth4>, <&pins_mdio1>; -- Gitee From 481ef99892de7442d8d8f5d1a7593e91d7a32e6b Mon Sep 17 00:00:00 2001 From: Aryan Srivastava Date: Fri, 24 Oct 2025 08:19:41 +0800 Subject: [PATCH 0269/1449] Revert "mtd: rawnand: marvell: fix layouts" ANBZ: #35228 commit 9ce7cbd355ae1793cf33d8050f2fbbe6bf88a69e stable. commit fbd72cb463fdea3a0c900dd5d6e813cdebc3a73c upstream. This reverts commit e6a30d0c48a1e8a68f1cc413bee65302ab03ddfb. This change resulted in the 8bit ECC layouts having the incorrect amount of read/write chunks, the last spare bytes chunk would always be missed. Fixes: e6a30d0c48a1 ("mtd: rawnand: marvell: fix layouts") Signed-off-by: Aryan Srivastava Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/nand/raw/marvell_nand.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 93d8c6da555b..b841a81cb128 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -290,13 +290,16 @@ static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = { MARVELL_LAYOUT( 2048, 512, 4, 1, 1, 2048, 32, 30, 0, 0, 0), MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,32, 30), MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,64, 30), - MARVELL_LAYOUT( 2048, 512, 16, 4, 4, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 2048, 512, 12, 3, 2, 704, 0, 30,640, 0, 30), + MARVELL_LAYOUT( 2048, 512, 16, 5, 4, 512, 0, 30, 0, 32, 30), MARVELL_LAYOUT( 4096, 512, 4, 2, 2, 2048, 32, 30, 0, 0, 0), - MARVELL_LAYOUT( 4096, 512, 8, 4, 4, 1024, 0, 30, 0, 64, 30), - MARVELL_LAYOUT( 4096, 512, 16, 8, 8, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 4096, 512, 8, 5, 4, 1024, 0, 30, 0, 64, 30), + MARVELL_LAYOUT( 4096, 512, 12, 6, 5, 704, 0, 30,576, 32, 30), + MARVELL_LAYOUT( 4096, 512, 16, 9, 8, 512, 0, 30, 0, 32, 30), MARVELL_LAYOUT( 8192, 512, 4, 4, 4, 2048, 0, 30, 0, 0, 0), - MARVELL_LAYOUT( 8192, 512, 8, 8, 8, 1024, 0, 30, 0, 160, 30), - MARVELL_LAYOUT( 8192, 512, 16, 16, 16, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 8192, 512, 8, 9, 8, 1024, 0, 30, 0, 160, 30), + MARVELL_LAYOUT( 8192, 512, 12, 12, 11, 704, 0, 30,448, 64, 30), + MARVELL_LAYOUT( 8192, 512, 16, 17, 16, 512, 0, 30, 0, 32, 30), }; /** -- Gitee From 8cc2c767b811ce0188b404a5f9ed012dbf1b3356 Mon Sep 17 00:00:00 2001 From: Aryan Srivastava Date: Fri, 24 Oct 2025 08:19:42 +0800 Subject: [PATCH 0270/1449] mtd: nand: relax ECC parameter validation check ANBZ: #35228 commit 4e6526697dcb92f89afe7e0aa7a1c4a5acb65308 stable. commit 050553c683f21eebd7d1020df9b2ec852e2a9e4e upstream. Due to the custom handling and layouts of certain nand controllers this validity check will always fail for certain layouts. The check inherently depends on even chunk sizing and this is not always the case. Modify the check to only print a warning, instead of failing to init the attached NAND. This allows various 8 bit and 12 ECC strength layouts to be used. Fixes: 68c18dae6888 ("mtd: rawnand: marvell: add missing layouts") Signed-off-by: Aryan Srivastava Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/nand/raw/nand_base.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 7c3e3d70be8b..fe0b298f8425 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -6450,11 +6450,14 @@ static int nand_scan_tail(struct nand_chip *chip) ecc->steps = mtd->writesize / ecc->size; if (!base->ecc.ctx.nsteps) base->ecc.ctx.nsteps = ecc->steps; - if (ecc->steps * ecc->size != mtd->writesize) { - WARN(1, "Invalid ECC parameters\n"); - ret = -EINVAL; - goto err_nand_manuf_cleanup; - } + + /* + * Validity check: Warn if ECC parameters are not compatible with page size. + * Due to the custom handling of ECC blocks in certain controllers the check + * may result in an expected failure. + */ + if (ecc->steps * ecc->size != mtd->writesize) + pr_warn("ECC parameters may be invalid in reference to underlying NAND chip\n"); if (!ecc->total) { ecc->total = ecc->steps * ecc->bytes; -- Gitee From aae67c52aa13ed52e64a068f2cd956822d4f5c60 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 28 Oct 2025 17:47:47 +0800 Subject: [PATCH 0271/1449] mtd: rawnand: lpc32xx_slc: fix GPIO descriptor leak on probe error and remove ANBZ: #35228 commit 1d733fcbfe61c41a8a0f42342bdf59c963965814 stable. commit cdf44f1add4ec9ee80569d5a43e6e9bba0d74c7a upstream. The driver calls gpiod_get_optional() in the probe function but never calls gpiod_put() in the remove function or in the probe error path. This leads to a GPIO descriptor resource leak. The lpc32xx_mlc.c driver in the same directory handles this correctly by calling gpiod_put() on both paths. Add gpiod_put() in the remove function and in the probe error path to fix the resource leak. Fixes: 6b923db2867c ("mtd: rawnand: lpc32xx_slc: switch to using gpiod API") Signed-off-by: Haotian Zhang Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/nand/raw/lpc32xx_slc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c index 1c5fa855b9f2..8abad092b058 100644 --- a/drivers/mtd/nand/raw/lpc32xx_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c @@ -933,6 +933,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) dma_release_channel(host->dma_chan); enable_wp: lpc32xx_wp_enable(host); + gpiod_put(host->wp_gpio); return res; } @@ -958,6 +959,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev) writel(tmp, SLC_CTRL(host->io_base)); lpc32xx_wp_enable(host); + gpiod_put(host->wp_gpio); } static int lpc32xx_nand_resume(struct platform_device *pdev) -- Gitee From edd7628d5ebe31bf150af3d1261ed4c04914fa49 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 22 Sep 2025 21:47:00 +0800 Subject: [PATCH 0272/1449] task_work: Fix NMI race condition ANBZ: #35228 commit b2a39b1a3cde5e49b5b646ae3829d683cd51b69b stable. commit ef1ea98c8fffe227e5319215d84a53fa2a4bcebc upstream. __schedule() // disable irqs task_work_add(current, work, TWA_NMI_CURRENT); // current = next; // enable irqs task_work_set_notify_irq() test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); // wrong task! // original task skips task work on its next return to user (or exit!) Fixes: 466e4d801cd4 ("task_work: Add TWA_NMI_CURRENT as an additional notify mode.") Reported-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Steven Rostedt (Google) Link: https://patch.msgid.link/20250924080118.425949403@infradead.org Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/task_work.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/task_work.c b/kernel/task_work.c index c969f1f26be5..48ab6275e6e7 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -9,7 +9,12 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ #ifdef CONFIG_IRQ_WORK static void task_work_set_notify_irq(struct irq_work *entry) { - test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); + /* + * no-op IPI + * + * TWA_NMI_CURRENT will already have set the TIF flag, all + * this interrupt does it tickle the return-to-user path. + */ } static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = IRQ_WORK_INIT_HARD(task_work_set_notify_irq); @@ -98,6 +103,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, break; #ifdef CONFIG_IRQ_WORK case TWA_NMI_CURRENT: + set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); break; #endif -- Gitee From f96488df37a484267d88d09071230dd57f1da992 Mon Sep 17 00:00:00 2001 From: Tengda Wu Date: Thu, 23 Oct 2025 17:06:32 +0800 Subject: [PATCH 0273/1449] x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() ANBZ: #35228 commit 2d3e5c1e76e9a9e9267b3038964cb589bf050db5 stable. commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 upstream. When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), KASAN may report false-positive out-of-bounds access: BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 Call Trace: dump_stack_lvl print_address_description.constprop.0 print_report __show_regs show_trace_log_lvl sched_show_task show_state_filter sysrq_handle_showstate __handle_sysrq write_sysrq_trigger proc_reg_write vfs_write ksys_write do_syscall_64 entry_SYSCALL_64_after_hwframe The issue occurs as follows: Task A (walk other tasks' stacks) Task B (running) 1. echo t > /proc/sysrq-trigger show_trace_log_lvl regs = unwind_get_entry_regs() show_regs_if_on_stack(regs) 2. The stack value pointed by `regs` keeps changing, and so are the tags in its KASAN shadow region. __show_regs(regs) regs->ax, regs->bx, ... 3. hit KASAN redzones, OOB When task A walks task B's stack without suspending it, the continuous changes in task B's stack (and corresponding KASAN shadow tags) may cause task A to hit KASAN redzones when accessing obsolete values on the stack, resulting in false positive reports. Simply stopping the task before unwinding is not a viable fix, as it would alter the state intended to inspect. This is especially true for diagnosing misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide the root cause by changing the call stack. Therefore, fix this by disabling KASAN checks during asynchronous stack unwinding, which is identified when the unwinding task does not match the current task (task != current). [ bp: Align arguments on function's opening brace. ] Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") Signed-off-by: Tengda Wu Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Andrey Ryabinin Acked-by: Josh Poimboeuf Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 52dc5839d1e8..0667d947d82b 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -183,8 +183,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, * in false positive reports. Disable instrumentation to avoid those. */ __no_kmsan_checks -static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, const char *log_lvl) +static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, const char *log_lvl) { struct unwind_state state; struct stack_info stack_info = {0}; @@ -305,6 +305,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, } } +static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, const char *log_lvl) +{ + /* + * Disable KASAN to avoid false positives during walking another + * task's stacks, as values on these stacks may change concurrently + * with task execution. + */ + bool disable_kasan = task && task != current; + + if (disable_kasan) + kasan_disable_current(); + + __show_trace_log_lvl(task, regs, stack, log_lvl); + + if (disable_kasan) + kasan_enable_current(); +} + void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) { -- Gitee From effdb21fee1e5e78470ee80f80c2c9ed7d7cc815 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 24 Sep 2025 22:20:50 +0800 Subject: [PATCH 0274/1449] tools/nolibc/stdio: let perror work when NOLIBC_IGNORE_ERRNO is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 6135d225cca7dc04031145207cd1c39d7117cd4e stable. commit c485ca3aff2442adea4c08ceb5183e671ebed22a upstream. There is no errno variable when NOLIBC_IGNORE_ERRNO is defined. As such, simply print the message with "unknown error" rather than the integer value of errno. Fixes: acab7bcdb1bc ("tools/nolibc/stdio: add perror() to report the errno value") Signed-off-by: Benjamin Berg Signed-off-by: Thomas Weißschuh Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/include/nolibc/stdio.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index d7ef43973916..faa6cc6c667d 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -351,7 +351,11 @@ int printf(const char *fmt, ...) static __attribute__((unused)) void perror(const char *msg) { +#ifdef NOLIBC_IGNORE_ERRNO + fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); +#else fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); +#endif } static __attribute__((unused)) -- Gitee From 4cf0edc18aa48cff7b1f771a05fb0b4cbd664bfe Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 29 Oct 2025 10:27:33 +0800 Subject: [PATCH 0275/1449] soc: qcom: smem: fix hwspinlock resource leak in probe error paths ANBZ: #35228 commit ea954e50d312a080ca2b8676c1e082aeb95371b3 stable. commit dc5db35073a19f6d3c30bea367b551c1a784ef8f upstream. The hwspinlock acquired via hwspin_lock_request_specific() is not released on several error paths. This results in resource leakage when probe fails. Switch to devm_hwspin_lock_request_specific() to automatically handle cleanup on probe failure. Remove the manual hwspin_lock_free() in qcom_smem_remove() as devm handles it automatically. Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") Signed-off-by: Haotian Zhang Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/soc/qcom/smem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index aead7dd482ea..5217ff0a434f 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -1164,7 +1164,7 @@ static int qcom_smem_probe(struct platform_device *pdev) return hwlock_id; } - smem->hwlock = hwspin_lock_request_specific(hwlock_id); + smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); if (!smem->hwlock) return -ENXIO; @@ -1217,7 +1217,6 @@ static int qcom_smem_remove(struct platform_device *pdev) { platform_device_unregister(__smem->socinfo); - hwspin_lock_free(__smem->hwlock); __smem = NULL; return 0; -- Gitee From d7bb37c1c7b059f5f09de0e89b8e3927485551fe Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 29 Oct 2025 09:42:52 +0800 Subject: [PATCH 0276/1449] pinctrl: stm32: fix hwspinlock resource leak in probe function ANBZ: #35228 commit 5f133ebe68366fbd94b34b00c9cf30776915e193 stable. commit 002679f79ed605e543fbace465557317cd307c9a upstream. In stm32_pctl_probe(), hwspin_lock_request_specific() is called to request a hwspinlock, but the acquired lock is not freed on multiple error paths after this call. This causes resource leakage when the function fails to initialize properly. Use devm_hwspin_lock_request_specific() instead of hwspin_lock_request_specific() to automatically manage the hwspinlock resource lifecycle. Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") Signed-off-by: Haotian Zhang Reviewed-by: Antonio Borneo Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 67c2791ee246..ac96523e07b8 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1550,7 +1550,7 @@ int stm32_pctl_probe(struct platform_device *pdev) if (hwlock_id == -EPROBE_DEFER) return hwlock_id; } else { - pctl->hwlock = hwspin_lock_request_specific(hwlock_id); + pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); } spin_lock_init(&pctl->irqmux_lock); -- Gitee From 5d5ffb14e3ecd9b7a4aa634a97aac6f82f61cb23 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 21 Sep 2023 13:56:53 +0800 Subject: [PATCH 0277/1449] i3c: master: Inherit DMA masks and parameters from parent device ANBZ: #35228 commit 4fc6af9d9e6d1f502cd3f08595021d15da597498 stable. commit 0c35691551387e060e6ae7a6652b4101270c73cf upstream. Copy the DMA masks and parameters for an I3C master device from parent device so that the master device has them set for the DMA buffer and mapping API. Signed-off-by: Jarkko Nikula Link: https://lore.kernel.org/r/20230921055704.1087277-2-jarkko.nikula@linux.intel.com Signed-off-by: Alexandre Belloni Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/i3c/master.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index b6995e767850..29e591bcc064 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -2775,6 +2775,10 @@ int i3c_master_register(struct i3c_master_controller *master, device_initialize(&master->dev); dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + master->dev.dma_mask = parent->dma_mask; + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ret = of_populate_i3c_bus(master); if (ret) goto err_put_dev; -- Gitee From 93d626070bd8c6500b4084a842e05b92ad758862 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 16 Oct 2025 22:38:13 +0800 Subject: [PATCH 0278/1449] i3c: fix refcount inconsistency in i3c_master_register ANBZ: #35228 commit 82a09b9965ed7a4743fe41a142254f0d0ccb63a0 stable. commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 upstream. In `i3c_master_register`, a possible refcount inconsistency has been identified, causing possible resource leak. Function `of_node_get` increases the refcount of `parent->of_node`. If function `i3c_bus_init` fails, the function returns immediately without a corresponding decrease, resulting in an inconsistent refcounter. Move call i3c_bus_init() after device_initialize() to let callback i3c_masterdev_release() release of_node. Reported-by: Shuhao Fu Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") Signed-off-by: Frank Li Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/i3c/master.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 29e591bcc064..060f70e4d52d 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -2768,10 +2768,6 @@ int i3c_master_register(struct i3c_master_controller *master, INIT_LIST_HEAD(&master->boardinfo.i2c); INIT_LIST_HEAD(&master->boardinfo.i3c); - ret = i3c_bus_init(i3cbus, master->dev.of_node); - if (ret) - return ret; - device_initialize(&master->dev); dev_set_name(&master->dev, "i3c-%d", i3cbus->id); @@ -2779,6 +2775,10 @@ int i3c_master_register(struct i3c_master_controller *master, master->dev.coherent_dma_mask = parent->coherent_dma_mask; master->dev.dma_parms = parent->dma_parms; + ret = i3c_bus_init(i3cbus, master->dev.of_node); + if (ret) + goto err_put_dev; + ret = of_populate_i3c_bus(master); if (ret) goto err_put_dev; -- Gitee From 78fb2d7b34aa0f2b2941ba97abafbbd8e23c4d91 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Mon, 27 Oct 2025 11:47:15 +0800 Subject: [PATCH 0279/1449] i3c: master: svc: Prevent incomplete IBI transaction ANBZ: #35228 commit bbd0544921015fcdb50131991949aff8a566eac3 stable. commit 3a36273e5a07dda0ccec193800f3b78c3c0380af upstream. If no free IBI slot is available, svc_i3c_master_handle_ibi returns immediately. This causes the STOP condition to be missed because the EmitStop request is sent when the transfer is not complete. To resolve this, svc_i3c_master_handle_ibi must wait for the transfer to complete before returning. Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") Signed-off-by: Stanley Chu Reviewed-by: Frank Li Reviewed-by: Miquel Raynal Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index 277884b5e1ca..3222b8f56a92 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -358,21 +358,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, int ret, val; u8 *buf; - slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); - if (!slot) - return -ENOSPC; - - slot->len = 0; - buf = slot->data; - + /* + * Wait for transfer to complete before returning. Otherwise, the EmitStop + * request might be sent when the transfer is not complete. + */ ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); if (ret) { dev_err(master->dev, "Timeout when polling for COMPLETE\n"); - i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); return ret; } + slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); + if (!slot) { + dev_dbg(master->dev, "No free ibi slot, drop the data\n"); + writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); + return -ENOSPC; + } + + slot->len = 0; + buf = slot->data; + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && slot->len < SVC_I3C_FIFO_SIZE) { mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); -- Gitee From 0176e11036a308a5e52de6cfe5ab98b0738f1035 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 2 Oct 2025 16:53:00 +0800 Subject: [PATCH 0280/1449] interconnect: qcom: msm8996: add missing link to SLAVE_USB_HS ANBZ: #35228 commit 7bfe9e5e31e35a604614a6cce64538758f5aa645 stable. commit 8cf9b43f6b4d90e19a9341edefdd46842d4adb55 upstream. >From the initial submission the interconnect driver missed the link from SNOC_PNOC to the USB 2 configuration space. Add missing link in order to let the platform configure and utilize this path. Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-1-a36a05d1f869@oss.qualcomm.com Signed-off-by: Georgi Djakov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/interconnect/qcom/msm8996.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index 88683dfa468f..84811fe32782 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -550,6 +550,7 @@ static struct qcom_icc_node mas_venus_vmem = { static const u16 mas_snoc_pnoc_links[] = { MSM8996_SLAVE_BLSP_1, MSM8996_SLAVE_BLSP_2, + MSM8996_SLAVE_USB_HS, MSM8996_SLAVE_SDCC_1, MSM8996_SLAVE_SDCC_2, MSM8996_SLAVE_SDCC_4, -- Gitee From 37fd4a458cf0aa7d26738288efc6dbf46d7d0bc6 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 2 Oct 2025 16:53:01 +0800 Subject: [PATCH 0281/1449] arm64: dts: qcom: msm8996: add interconnect paths to USB2 controller ANBZ: #35228 commit 92087be48b6da1458da481de844c30d3416c3928 stable. commit 242f7558e7bf54cb63c06506f7b0630dd67d45a4 upstream. Add the missing interconnects to the USB2 host. The Fixes tag points to the commit which broke probing of the USB host on that platform. Fixes: 130733a10079 ("interconnect: qcom: msm8996: Promote to core_initcall") Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-2-a36a05d1f869@oss.qualcomm.com Signed-off-by: Georgi Djakov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 70ef8c83e7b9..473d72d2c7b1 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -3432,6 +3432,9 @@ usb2: usb@76f8800 { <&gcc GCC_USB20_MASTER_CLK>; assigned-clock-rates = <19200000>, <60000000>; + interconnects = <&pnoc MASTER_USB_HS &bimc SLAVE_EBI_CH0>, + <&bimc MASTER_AMPSS_M0 &pnoc SLAVE_USB_HS>; + interconnect-names = "usb-ddr", "apps-usb"; power-domains = <&gcc USB30_GDSC>; qcom,select-utmi-as-pipe-clk; status = "disabled"; -- Gitee From 80d437a1a83b05ae1c71900bea1d81673f003674 Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Fri, 10 Oct 2025 23:14:47 +0800 Subject: [PATCH 0282/1449] interconnect: debugfs: Fix incorrect error handling for NULL path ANBZ: #35228 commit 23411ba96edc6a571d37ac9dbe7ba836d411dd9c stable. commit 6bfe104fd0f94d0248af22c256ce725ee087157b upstream. The icc_commit_set() function, used by the debugfs interface, checks the validity of the global cur_path pointer using IS_ERR_OR_NULL(). However, in the specific case where cur_path is NULL, while IS_ERR_OR_NULL(NULL) correctly evaluates to true, the subsequent call to PTR_ERR(NULL) returns 0. This causes the function to return a success code (0) instead of an error, misleading the user into believing their bandwidth request was successfully committed when, in fact, no operation was performed. Fix this by adding an explicit check to return -EINVAL if cur_path is NULL. This prevents silent failures and ensures that an invalid operational sequence is immediately and clearly reported as an error. Fixes: 770c69f037c1 ("interconnect: Add debugfs test client") Signed-off-by: Kuan-Wei Chiu Link: https://lore.kernel.org/r/20251010151447.2289779-1-visitorckw@gmail.com Signed-off-by: Georgi Djakov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/interconnect/debugfs-client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c index bc3fd8a7b9eb..778deeb4a7e8 100644 --- a/drivers/interconnect/debugfs-client.c +++ b/drivers/interconnect/debugfs-client.c @@ -117,7 +117,12 @@ static int icc_commit_set(void *data, u64 val) mutex_lock(&debugfs_lock); - if (IS_ERR_OR_NULL(cur_path)) { + if (!cur_path) { + ret = -EINVAL; + goto out; + } + + if (IS_ERR(cur_path)) { ret = PTR_ERR(cur_path); goto out; } -- Gitee From 2411e45f765234d292b245c572ba5db89df6ca37 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 7 Dec 2023 09:16:53 +0800 Subject: [PATCH 0283/1449] perf maps: Add maps__load_first() ANBZ: #35228 commit 9dd3998165eae0f434736b1355d5d033202a85ee stable. commit e77b0236cd0cd1572c6a9b25097b207eab799e74 upstream. Avoid bpf_lock_contention_read touching the internal maps data structure by adding a helper function. As access is done directly on the map in maps, hold the read lock to stop it being removed. Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Athira Rajeev Cc: Changbin Du Cc: Colin Ian King Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: German Gomez Cc: Guilherme Amadio Cc: Huacai Chen Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: K Prateek Nayak Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Li Dong Cc: Liam Howlett Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miguel Ojeda Cc: Ming Wang Cc: Namhyung Kim Cc: Nick Terrell Cc: Paolo Bonzini Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sandipan Das Cc: Sean Christopherson Cc: Steinar H. Gunderson Cc: Vincent Whitchurch Cc: Wenyu Liu Cc: Yang Jihong Link: https://lore.kernel.org/r/20231207011722.1220634-20-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo Stable-dep-of: 553d18c98a89 ("perf lock contention: Load kernel map before lookup") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/perf/util/bpf_lock_contention.c | 2 +- tools/perf/util/maps.c | 13 +++++++++++++ tools/perf/util/maps.h | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index e7dddf0127bc..a73f39540a3d 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -285,7 +285,7 @@ int lock_contention_read(struct lock_contention *con) } /* make sure it loads the kernel map */ - map__load(maps__first(machine->kmaps)->map); + maps__load_first(machine->kmaps); prev_key = NULL; while (!bpf_map_get_next_key(fd, prev_key, &key)) { diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 9a011aed4b75..9c7618b7d5e9 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -713,3 +713,16 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) } return err; } + +void maps__load_first(struct maps *maps) +{ + struct map_rb_node *first; + + down_read(maps__lock(maps)); + + first = maps__first(maps); + if (first) + map__load(first->map); + + up_read(maps__lock(maps)); +} diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index a689149be8c4..d9f65f9e6d09 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -145,4 +145,6 @@ void __maps__sort_by_name(struct maps *maps); void maps__fixup_end(struct maps *maps); +void maps__load_first(struct maps *maps); + #endif // __PERF_MAPS_H -- Gitee From 4d6ddb5dbc8b435635a602bd168ada6811911ac0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 30 Oct 2025 12:01:39 +0800 Subject: [PATCH 0284/1449] perf lock contention: Load kernel map before lookup ANBZ: #35228 commit 4dc555120afc1fb15123885f6c15b2de38340500 stable. commit 553d18c98a896094b99a01765b9698b204183d49 upstream. On some machines, it caused troubles when it tried to find kernel symbols. I think it's because kernel modules and kallsyms are messed up during load and split. Basically we want to make sure the kernel map is loaded and the code has it in the lock_contention_read(). But recently we added more lookups in the lock_contention_prepare() which is called before _read(). Also the kernel map (kallsyms) may not be the first one in the group like on ARM. Let's use machine__kernel_map() rather than just loading the first map. Reviewed-by: Ian Rogers Fixes: 688d2e8de231c54e ("perf lock contention: Add -l/--lock-addr option") Signed-off-by: Namhyung Kim Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/perf/util/bpf_lock_contention.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index a73f39540a3d..aa4c7baf20f5 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -24,6 +24,9 @@ int lock_contention_prepare(struct lock_contention *con) struct evlist *evlist = con->evlist; struct target *target = con->target; + /* make sure it loads the kernel map before lookup */ + map__load(machine__kernel_map(con->machine)); + skel = lock_contention_bpf__open(); if (!skel) { pr_err("Failed to open lock-contention BPF skeleton\n"); @@ -284,9 +287,6 @@ int lock_contention_read(struct lock_contention *con) bpf_prog_test_run_opts(prog_fd, &opts); } - /* make sure it loads the kernel map */ - maps__load_first(machine->kmaps); - prev_key = NULL; while (!bpf_map_get_next_key(fd, prev_key, &key)) { s64 ls_key; -- Gitee From 0123ccdc6c9b5415f3df94a5e189418fd2e5bc3c Mon Sep 17 00:00:00 2001 From: Ivan Abramov Date: Wed, 8 Oct 2025 20:07:11 +0800 Subject: [PATCH 0285/1449] power: supply: cw2015: Check devm_delayed_work_autocancel() return code ANBZ: #35228 commit 1f309df6378582898d7bfd270e9277373f993640 stable. commit 92ec7e7b86ec0aff9cd7db64d9dce50a0ea7c542 upstream. Since devm_delayed_work_autocancel() may fail, add return code check and exit cw_bat_probe() on error. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 0cb172a4918e ("power: supply: cw2015: Use device managed API to simplify the code") Signed-off-by: Ivan Abramov Link: https://patch.msgid.link/20251008120711.556021-1-i.abramov@mt-integration.ru Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/power/supply/cw2015_battery.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c index 434e3233c9f8..f777665cf068 100644 --- a/drivers/power/supply/cw2015_battery.c +++ b/drivers/power/supply/cw2015_battery.c @@ -702,7 +702,13 @@ static int cw_bat_probe(struct i2c_client *client) if (!cw_bat->battery_workqueue) return -ENOMEM; - devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); + ret = devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); + if (ret) { + dev_err_probe(&client->dev, ret, + "Failed to register delayed work\n"); + return ret; + } + queue_delayed_work(cw_bat->battery_workqueue, &cw_bat->battery_delay_work, msecs_to_jiffies(10)); return 0; -- Gitee From 586f6de0e3a89542438a75996a0a14e11a708098 Mon Sep 17 00:00:00 2001 From: Ivan Abramov Date: Thu, 9 Oct 2025 22:47:24 +0800 Subject: [PATCH 0286/1449] power: supply: rt9467: Return error on failure in rt9467_set_value_from_ranges() ANBZ: #35228 commit 5e9308f3539ba78bb7a30cfd7590b9c62beb3060 stable. commit 8b27fe2d8d2380118c343629175385ff587e2fe4 upstream. The return value of rt9467_set_value_from_ranges() when setting AICL VTH is not checked, even though it may fail. Log error and return from rt9467_run_aicl() on fail. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") Signed-off-by: Ivan Abramov Link: https://patch.msgid.link/20251009144725.562278-1-i.abramov@mt-integration.ru Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/power/supply/rt9467-charger.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c index fdfdc83ab045..1462d630e399 100644 --- a/drivers/power/supply/rt9467-charger.c +++ b/drivers/power/supply/rt9467-charger.c @@ -588,6 +588,10 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) aicl_vth = mivr_vth + RT9467_AICLVTH_GAP_uV; ret = rt9467_set_value_from_ranges(data, F_AICL_VTH, RT9467_RANGE_AICL_VTH, aicl_vth); + if (ret) { + dev_err(data->dev, "Failed to set AICL VTH\n"); + return ret; + } /* Trigger AICL function */ ret = regmap_field_write(data->rm_field[F_AICL_MEAS], 1); -- Gitee From f7e56ba65380f29efcd59ed92342566ca12ff4b7 Mon Sep 17 00:00:00 2001 From: Murad Masimov Date: Thu, 9 Oct 2025 22:53:08 +0800 Subject: [PATCH 0287/1449] power: supply: rt9467: Prevent using uninitialized local variable in rt9467_set_value_from_ranges() ANBZ: #35228 commit 0fcbaf9e99dc1d16b4893d29fc5107565e901eda stable. commit 15aca30cc6c69806054b896a2ccf7577239cb878 upstream. There is a typo in rt9467_set_value_from_ranges() that can cause leaving local variable sel with an undefined value which is then used in regmap_field_write(). Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") Signed-off-by: Murad Masimov Link: https://patch.msgid.link/20251009145308.1830893-1-m.masimov@mt-integration.ru Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/power/supply/rt9467-charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c index 1462d630e399..1e1659326751 100644 --- a/drivers/power/supply/rt9467-charger.c +++ b/drivers/power/supply/rt9467-charger.c @@ -376,7 +376,7 @@ static int rt9467_set_value_from_ranges(struct rt9467_chg_data *data, if (rsel == RT9467_RANGE_VMIVR) { ret = linear_range_get_selector_high(range, value, &sel, &found); if (ret) - value = range->max_sel; + sel = range->max_sel; } else { linear_range_get_selector_within(range, value, &sel); } -- Gitee From 40d031ddd11315221e103cb27be0a1e28227dee9 Mon Sep 17 00:00:00 2001 From: Ivan Abramov Date: Fri, 10 Oct 2025 01:05:52 +0800 Subject: [PATCH 0288/1449] power: supply: wm831x: Check wm831x_set_bits() return value ANBZ: #35228 commit ea3bdf099e6e23d7f072b79b343d9828616c5cbe stable. commit ea14bae6df18942bccb467fcf5ff33ca677b8253 upstream. Since wm831x_set_bits() may return error, log failure and exit from wm831x_usb_limit_change() in such case. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") Signed-off-by: Ivan Abramov Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/power/supply/wm831x_power.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c index 82e31066c746..bbae77982d08 100644 --- a/drivers/power/supply/wm831x_power.c +++ b/drivers/power/supply/wm831x_power.c @@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, struct wm831x_power, usb_notify); unsigned int i, best; + int ret; /* Find the highest supported limit */ best = 0; @@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, dev_dbg(wm831x_power->wm831x->dev, "Limiting USB current to %umA", wm831x_usb_limits[best]); - wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, - WM831X_USB_ILIM_MASK, best); + ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, + WM831X_USB_ILIM_MASK, best); + if (ret < 0) { + dev_err(wm831x_power->wm831x->dev, + "Failed to set USB current limit: %d\n", ret); + return ret; + } return 0; } -- Gitee From 23c7bdc66aba104e3b8f75129b890ce5642bbc10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahelenia=20Ziemia=C5=84ska?= Date: Fri, 17 Oct 2025 06:05:18 +0800 Subject: [PATCH 0289/1449] power: supply: apm_power: only unset own apm_get_power_status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4eee4a5b9b2e06c1f2144812700a73ebacce26e7 stable. commit bd44ea12919ac4e83c9f3997240fe58266aa8799 upstream. Mirroring drivers/macintosh/apm_emu.c, this means that modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power leaves $anotherdriver's apm_get_power_status instead of deleting it. Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") Signed-off-by: Ahelenia Ziemiańska Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/power/supply/apm_power.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c index 9d1a7fbcaed4..50b963694559 100644 --- a/drivers/power/supply/apm_power.c +++ b/drivers/power/supply/apm_power.c @@ -365,7 +365,8 @@ static int __init apm_battery_init(void) static void __exit apm_battery_exit(void) { - apm_get_power_status = NULL; + if (apm_get_power_status == apm_battery_apm_get_power_status) + apm_get_power_status = NULL; } module_init(apm_battery_init); -- Gitee From 7c161da70db0820f3150bcf829bfa84341dba6a6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 28 Oct 2025 02:46:38 +0800 Subject: [PATCH 0290/1449] scsi: target: Do not write NUL characters into ASCII configfs output ANBZ: #35228 commit 3b8431f15cdd02a9d9586e1430b18a89ef99336d stable. commit c03b55f235e283cae49c88b9602fd11096b92eba upstream. NUL characters are not allowed in ASCII configfs output. Hence this patch. Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") Signed-off-by: Bart Van Assche Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/target/target_core_configfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index eddcfd09c05b..6ec98dfd1f31 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -2736,7 +2736,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", config_item_name(&hba->hba_group.cg_item), config_item_name(&dev->dev_group.cg_item)); - cur_len++; /* Extra byte for NULL terminator */ if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { pr_warn("Ran out of lu_gp_show_attr" -- Gitee From c32f09a0c912631f95bf6a25bbc23ae79dd02542 Mon Sep 17 00:00:00 2001 From: Tingmao Wang Date: Mon, 3 Nov 2025 07:56:30 +0800 Subject: [PATCH 0291/1449] fs/9p: Don't open remote file with APPEND mode when writeback cache is used ANBZ: #35228 commit 577d1ef1849959af6e81a0ea570dbd8ccb292ad1 stable. commit a63dd8fd137933551bfd9aeeeaa942f04c7aad65 upstream. When page cache is used, writebacks are done on a page granularity, and it is expected that the underlying filesystem (such as v9fs) should respect the write position. However, currently v9fs will passthrough O_APPEND to the server even on cached mode. This causes data corruption if a sync or fstat gets between two writes to the same file. This patch removes the APPEND flag from the open request we send to the server when writeback caching is involved. I believe keeping server-side APPEND is probably fine for uncached mode (even if two fds are opened, one without O_APPEND and one with it, this should still be fine since they would use separate fid for the writes). Signed-off-by: Tingmao Wang Fixes: 4eb3117888a9 ("fs/9p: Rework cache modes and add new options to Documentation") Message-ID: <20251102235631.8724-1-m@maowtm.org> Signed-off-by: Dominique Martinet Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/9p/vfs_file.c | 11 ++++++++--- fs/9p/vfs_inode.c | 3 +-- fs/9p/vfs_inode_dotl.c | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 8566ddad49ad..655e7bf602f1 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -43,14 +43,18 @@ int v9fs_file_open(struct inode *inode, struct file *file) struct v9fs_session_info *v9ses; struct p9_fid *fid; int omode; + int o_append; p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); v9ses = v9fs_inode2v9ses(inode); - if (v9fs_proto_dotl(v9ses)) + if (v9fs_proto_dotl(v9ses)) { omode = v9fs_open_to_dotl_flags(file->f_flags); - else + o_append = P9_DOTL_APPEND; + } else { omode = v9fs_uflags2omode(file->f_flags, v9fs_proto_dotu(v9ses)); + o_append = P9_OAPPEND; + } fid = file->private_data; if (!fid) { fid = v9fs_fid_clone(file_dentry(file)); @@ -58,9 +62,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) return PTR_ERR(fid); if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) { - int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; + int writeback_omode = (omode & ~(P9_OWRITE | o_append)) | P9_ORDWR; p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); + err = p9_client_open(fid, writeback_omode); if (err < 0) { p9_debug(P9_DEBUG_CACHE, "could not open O_RDWR, disabling caches\n"); diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index aba0625de48a..e084caf467d1 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -824,7 +824,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses)); if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { - p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; + p9_omode = (p9_omode & ~(P9_OWRITE | P9_OAPPEND)) | P9_ORDWR; p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, creating w/ O_RDWR\n"); } @@ -1458,4 +1458,3 @@ static const struct inode_operations v9fs_symlink_inode_operations = { .getattr = v9fs_vfs_getattr, .setattr = v9fs_vfs_setattr, }; - diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 91bcee2ab3c4..96e791c2b7b4 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -288,7 +288,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, } if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { - p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; + p9_omode = (p9_omode & ~(P9_OWRITE | P9_DOTL_APPEND)) | P9_ORDWR; p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, creating w/ O_RDWR\n"); } -- Gitee From b3961f14f9bd1d35bf5810cf1ff9708e5f7b04b4 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Tue, 7 Oct 2025 18:38:51 +0800 Subject: [PATCH 0292/1449] ARM: dts: am335x-netcom-plus-2xx: add missing GPIO labels ANBZ: #35228 commit 2470624c4a2124e85a89662826b0c7555c78c954 stable. commit d0c4b1723c419a18cb434903c7754954ecb51d35 upstream. Fixes: 8e9d75fd2ec2 ("ARM: dts: am335x-netcom: add GPIO names for NetCom Plus 2-port devices") Signed-off-by: Yegor Yefremov Link: https://lore.kernel.org/r/20251007103851.3765678-1-yegorslists@googlemail.com Signed-off-by: Kevin Hilman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts index 76751a324ad7..441d4696b94d 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts @@ -222,10 +222,10 @@ &gpio3 { "ModeA1", "ModeA2", "ModeA3", - "NC", - "NC", - "NC", - "NC", + "ModeB0", + "ModeB1", + "ModeB2", + "ModeB3", "NC", "NC", "NC", -- Gitee From d04625ff6aa701f82823325c192ef83d6a18def8 Mon Sep 17 00:00:00 2001 From: Jihed Chaibi Date: Mon, 15 Sep 2025 03:25:15 +0800 Subject: [PATCH 0293/1449] ARM: dts: omap3: beagle-xm: Correct obsolete TWL4030 power compatible ANBZ: #35228 commit 4c1dd8da53860d5580b7250516a93ff21890f759 stable. commit f7f3bc18300a230e0f1bfb17fc8889435c1e47f5 upstream. The "ti,twl4030-power-beagleboard-xm" compatible string is obsolete and is not supported by any in-kernel driver. Currently, the kernel falls back to the second entry, "ti,twl4030-power-idle-osc-off", to bind a driver to this node. Make this fallback explicit by removing the obsolete board-specific compatible. This preserves the existing functionality while making the DTS compliant with the new, stricter 'ti,twl.yaml' binding. Fixes: 9188883fd66e9 ("ARM: dts: Enable twl4030 off-idle configuration for selected omaps") Signed-off-by: Jihed Chaibi Link: https://lore.kernel.org/r/20250914192516.164629-3-jihed.chaibi.dev@gmail.com Signed-off-by: Kevin Hilman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts index 08ee0f8ea68f..71b39a923d37 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts @@ -291,7 +291,7 @@ codec { }; twl_power: power { - compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; + compatible = "ti,twl4030-power-idle-osc-off"; ti,use_poweroff; }; }; -- Gitee From a298f66cce90bb2b653665a1378961d1e8b88e10 Mon Sep 17 00:00:00 2001 From: Jihed Chaibi Date: Mon, 15 Sep 2025 03:25:16 +0800 Subject: [PATCH 0294/1449] ARM: dts: omap3: n900: Correct obsolete TWL4030 power compatible ANBZ: #35228 commit 182b0cc9c6d5b1f971d4a5308bca284352f88d18 stable. commit 3862123e9b56663c7a3e4a308e6e65bffe44f646 upstream. The "ti,twl4030-power-n900" compatible string is obsolete and is not supported by any in-kernel driver. Currently, the kernel falls back to the second entry, "ti,twl4030-power-idle-osc-off", to bind a driver to this node. Make this fallback explicit by removing the obsolete board-specific compatible. This preserves the existing functionality while making the DTS compliant with the new, stricter 'ti,twl.yaml' binding. Fixes: daebabd578647 ("mfd: twl4030-power: Fix PM idle pin configuration to not conflict with regulators") Signed-off-by: Jihed Chaibi Link: https://lore.kernel.org/r/20250914192516.164629-4-jihed.chaibi.dev@gmail.com Signed-off-by: Kevin Hilman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/ti/omap/omap3-n900.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts index 036e472b77be..98f259dbcb0d 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts @@ -508,7 +508,7 @@ twl_audio: audio { }; twl_power: power { - compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off"; + compatible = "ti,twl4030-power-idle-osc-off"; ti,use_poweroff; }; }; -- Gitee From 95043fceda61985f46c0bcced6be50cbabadac22 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 3 Nov 2025 22:09:22 +0800 Subject: [PATCH 0295/1449] x86/boot: Fix page table access in 5-level to 4-level paging transition ANBZ: #35228 commit 6f16ed9c84013ab4333386a684221596f4ddd8bd stable. commit eb2266312507d7b757859e2227aa5c4ba6280ebe upstream. When transitioning from 5-level to 4-level paging, the existing code incorrectly accesses page table entries by directly dereferencing CR3 and applying PAGE_MASK. This approach has several issues: - __native_read_cr3() returns the raw CR3 register value, which on x86_64 includes not just the physical address but also flags. Bits above the physical address width of the system i.e. above __PHYSICAL_MASK_SHIFT) are also not masked. - The PGD entry is masked by PAGE_SIZE which doesn't take into account the higher bits such as _PAGE_BIT_NOPTISHADOW. Replace this with proper accessor functions: - native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out of CR3 (like SME or LAM bits). All remaining bits are real address bits or reserved and must be 0. - mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above the max physical address are reserved and must be 0. Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline") Reported-by: Michael van der Westhuizen Reported-by: Tobias Fleig Co-developed-by: Kiryl Shutsemau Signed-off-by: Kiryl Shutsemau Signed-off-by: Usama Arif Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Ard Biesheuvel Acked-by: Dave Hansen Link: https://lore.kernel.org/r/a482fd68-ce54-472d-8df1-33d6ac9f6bb5@intel.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index 15354673d3aa..dc21b0d89d66 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -2,6 +2,7 @@ #include "misc.h" #include #include +#include #include #include "pgtable.h" #include "../string.h" @@ -175,9 +176,10 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) * For 4- to 5-level paging transition, set up current CR3 as * the first and the only entry in a new top-level page table. */ - *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; + *trampoline_32bit = native_read_cr3_pa() | _PAGE_TABLE_NOENC; } else { - unsigned long src; + u64 *new_cr3; + pgd_t *pgdp; /* * For 5- to 4-level paging transition, copy page table pointed @@ -187,8 +189,9 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) * We cannot just point to the page table from trampoline as it * may be above 4G. */ - src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; - memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); + pgdp = (pgd_t *)native_read_cr3_pa(); + new_cr3 = (u64 *)(native_pgd_val(pgdp[0]) & PTE_PFN_MASK); + memcpy(trampoline_32bit, new_cr3, PAGE_SIZE); } toggle_la57(trampoline_32bit); -- Gitee From cdecca4cde8fbe01895e563e26e4f2083d11555c Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 3 Nov 2025 22:09:23 +0800 Subject: [PATCH 0296/1449] efi/libstub: Fix page table access in 5-level to 4-level paging transition ANBZ: #35228 commit e4d11160a77d5d7db92215aa74d273c2d258324e stable. commit 84361123413efc84b06f3441c6c827b95d902732 upstream. When transitioning from 5-level to 4-level paging, the existing code incorrectly accesses page table entries by directly dereferencing CR3 and applying PAGE_MASK. This approach has several issues: - __native_read_cr3() returns the raw CR3 register value, which on x86_64 includes not just the physical address but also flags Bits above the physical address width of the system (i.e. above __PHYSICAL_MASK_SHIFT) are also not masked. - The pgd value is masked by PAGE_SIZE which doesn't take into account the higher bits such as _PAGE_BIT_NOPTISHADOW. Replace this with proper accessor functions: - native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out of CR3 (like SME or LAM bits). All remaining bits are real address bits or reserved and must be 0. - mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above the max physical address are reserved and must be 0. Fixes: cb1c9e02b0c1 ("x86/efistub: Perform 4/5 level paging switch from the stub") Reported-by: Michael van der Westhuizen Reported-by: Tobias Fleig Co-developed-by: Kiryl Shutsemau Signed-off-by: Kiryl Shutsemau Signed-off-by: Usama Arif Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Ard Biesheuvel Link: https://patch.msgid.link/20251103141002.2280812-3-usamaarif642@gmail.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c index 479dd445acdc..267b1c531254 100644 --- a/drivers/firmware/efi/libstub/x86-5lvl.c +++ b/drivers/firmware/efi/libstub/x86-5lvl.c @@ -66,7 +66,7 @@ void efi_5level_switch(void) bool have_la57 = native_read_cr4() & X86_CR4_LA57; bool need_toggle = want_la57 ^ have_la57; u64 *pgt = (void *)la57_toggle + PAGE_SIZE; - u64 *cr3 = (u64 *)__native_read_cr3(); + pgd_t *cr3 = (pgd_t *)native_read_cr3_pa(); u64 *new_cr3; if (!la57_toggle || !need_toggle) @@ -82,7 +82,7 @@ void efi_5level_switch(void) new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; } else { /* take the new root table pointer from the current entry #0 */ - new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); + new_cr3 = (u64 *)(native_pgd_val(cr3[0]) & PTE_PFN_MASK); /* copy the new root table if it is not 32-bit addressable */ if ((u64)new_cr3 > U32_MAX) -- Gitee From 96151a93df30efac3043e03e056d0e9db70e1161 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Fri, 10 Oct 2025 09:17:36 +0800 Subject: [PATCH 0297/1449] mfd: da9055: Fix missing regmap_del_irq_chip() in error path ANBZ: #35228 commit b5ed17a409094440a5467843d8ed0e3c8dab1264 stable. commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 upstream. When da9055_device_init() fails after regmap_add_irq_chip() succeeds but mfd_add_devices() fails, the error handling path only calls mfd_remove_devices() but forgets to call regmap_del_irq_chip(). This results in a resource leak. Fix this by adding regmap_del_irq_chip() to the error path so that resources are released properly. Fixes: 2896434cf272 ("mfd: DA9055 core driver") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mfd/da9055-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c index 768302e05baa..bdf6401d32d7 100644 --- a/drivers/mfd/da9055-core.c +++ b/drivers/mfd/da9055-core.c @@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) err: mfd_remove_devices(da9055->dev); + regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); return ret; } -- Gitee From d4d781f80a14caf6ee738edfed87ee43babd2504 Mon Sep 17 00:00:00 2001 From: Zhang Yi Date: Mon, 13 Oct 2025 09:51:17 +0800 Subject: [PATCH 0298/1449] ext4: correct the checking of quota files before moving extents ANBZ: #35228 commit 22b62f223c074d332bcc6089ae70c1638f6efa15 stable. commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 upstream. The move extent operation should return -EOPNOTSUPP if any of the inodes is a quota inode, rather than requiring both to be quota inodes. Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") Signed-off-by: Zhang Yi Reviewed-by: Jan Kara Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/move_extent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 91a8578af0bd..c967e03b7d88 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -483,7 +483,7 @@ mext_check_arguments(struct inode *orig_inode, return -ETXTBSY; } - if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { + if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", orig_inode->i_ino, donor_inode->i_ino); return -EOPNOTSUPP; -- Gitee From 81472d3a721d0967babb520fd2cf27d7e080211a Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sat, 8 Nov 2025 01:10:08 +0800 Subject: [PATCH 0299/1449] regulator: core: disable supply if enabling main regulator fails ANBZ: #35228 commit e432944735edb63ad7dfd37deb4b754c78f24ec4 stable. commit fb1ebb10468da414d57153ddebaab29c38ef1a78 upstream. For 'always-on' and 'boot-on' regulators, the set_machine_constraints() may enable supply before enabling the main regulator, however if the latter fails, the function returns with an error but the supply remains enabled. When this happens, the regulator_register() function continues on the error path where it puts the supply regulator. Since enabling the supply is not balanced with a disable call, a warning similar to the following gets issued from _regulator_put(): [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 [ 1.603908] Modules linked in: [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) [ 1.603945] Workqueue: async async_run_entry_fn [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 1.603967] pc : _regulator_put+0x8c/0xa0 [ 1.603976] lr : _regulator_put+0x7c/0xa0 ... [ 1.604140] Call trace: [ 1.604145] _regulator_put+0x8c/0xa0 (P) [ 1.604156] regulator_register+0x2ec/0xbf0 [ 1.604166] devm_regulator_register+0x60/0xb0 [ 1.604178] rpm_reg_probe+0x120/0x208 [ 1.604187] platform_probe+0x64/0xa8 ... In order to avoid this, change the set_machine_constraints() function to disable the supply if enabling the main regulator fails. Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") Signed-off-by: Gabor Juhos Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/regulator/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1d49612eeb7e..465f4f870162 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1653,6 +1653,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) * and we have control then make sure it is enabled. */ if (rdev->constraints->always_on || rdev->constraints->boot_on) { + bool supply_enabled = false; + /* If we want to enable this regulator, make sure that we know * the supplying regulator. */ @@ -1672,11 +1674,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) rdev->supply = NULL; return ret; } + supply_enabled = true; } ret = _regulator_do_enable(rdev); if (ret < 0 && ret != -EINVAL) { rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); + if (supply_enabled) + regulator_disable(rdev->supply); return ret; } -- Gitee From 8334b68cd91f2e1d1d1bdf7a7bb74f1830589bfb Mon Sep 17 00:00:00 2001 From: Zheng Qixing Date: Sat, 8 Nov 2025 15:02:02 +0800 Subject: [PATCH 0300/1449] nbd: defer config put in recv_work ANBZ: #35228 commit 1ba2ced2bbdf7e64a30c3e88c70ea8bc208d1509 stable. commit 9517b82d8d422d426a988b213fdd45c6b417b86d upstream. There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and NBD_CMD_RECONFIGURE: nbd_genl_connect // conf_ref=2 (connect and recv_work A) nbd_open // conf_ref=3 recv_work A done // conf_ref=2 NBD_CLEAR_SOCK // conf_ref=1 nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) close nbd // conf_ref=1 recv_work B config_put // conf_ref=0 atomic_dec(&config->recv_threads); -> UAF Or only running NBD_CLEAR_SOCK: nbd_genl_connect // conf_ref=2 nbd_open // conf_ref=3 NBD_CLEAR_SOCK // conf_ref=2 close nbd nbd_release config_put // conf_ref=1 recv_work config_put // conf_ref=0 atomic_dec(&config->recv_threads); -> UAF Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the waiter") moved nbd_config_put() to run before waking up the waiter in recv_work, in order to ensure that nbd_start_device_ioctl() would not be woken up while nbd->task_recv was still uncleared. However, in nbd_start_device_ioctl(), after being woken up it explicitly calls flush_workqueue() to make sure all current works are finished. Therefore, there is no need to move the config put ahead of the wakeup. Move nbd_config_put() to the end of recv_work, so that the reference is held for the whole lifetime of the worker thread. This makes sure the config cannot be freed while recv_work is still running, even if clear + reconfigure interleave. In addition, we don't need to worry about recv_work dropping the last nbd_put (which causes deadlock): path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): connect // nbd_refs=1 (trigger recv_work) open nbd // nbd_refs=2 NBD_CLEAR_SOCK close nbd nbd_release nbd_disconnect_and_put flush_workqueue // recv_work done nbd_config_put nbd_put // nbd_refs=1 nbd_put // nbd_refs=0 queue_work path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): connect // nbd_refs=2 (trigger recv_work) open nbd // nbd_refs=3 NBD_CLEAR_SOCK // conf_refs=2 close nbd nbd_release nbd_config_put // conf_refs=1 nbd_put // nbd_refs=2 recv_work done // conf_refs=0, nbd_refs=1 rmmod // nbd_refs=0 Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") Signed-off-by: Zheng Qixing Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 27a05b1521f6..9e190d220e98 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -912,9 +912,9 @@ static void recv_work(struct work_struct *work) nbd_mark_nsock_dead(nbd, nsock, 1); mutex_unlock(&nsock->tx_lock); - nbd_config_put(nbd); atomic_dec(&config->recv_threads); wake_up(&config->recv_wq); + nbd_config_put(nbd); kfree(args); } -- Gitee From c6426f2a07debaa80874695a3053a9043d0f40c2 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 4 Nov 2025 17:48:47 +0800 Subject: [PATCH 0301/1449] scsi: stex: Fix reboot_notifier leak in probe error path ANBZ: #35228 commit 1867723a98c869d7feddc6a141fe4e244ca01350 stable. commit 20da637eb545b04753e20c675cfe97b04c7b600b upstream. In stex_probe(), register_reboot_notifier() is called at the beginning, but if any subsequent initialization step fails, the function returns without unregistering the notifier, resulting in a resource leak. Add unregister_reboot_notifier() in the out_disable error path to ensure proper cleanup on all failure paths. Fixes: 61b745fa63db ("scsi: stex: Add S6 support") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/stex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 8ffb75be99bc..879b090fb39e 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -1846,6 +1846,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) out_scsi_host_put: scsi_host_put(host); out_disable: + unregister_reboot_notifier(&stex_notifier); pci_disable_device(pdev); return err; -- Gitee From fb8f2b5f262dc20346146b703b591ff56a0eaf1d Mon Sep 17 00:00:00 2001 From: Mike McGowen Date: Fri, 7 Nov 2025 00:38:20 +0800 Subject: [PATCH 0302/1449] scsi: smartpqi: Fix device resources accessed after device removal ANBZ: #35228 commit 6d2390653d82cad0e1ba2676e536dd99678f6ef1 stable. commit b518e86d1a70a88f6592a7c396cf1b93493d1aab upstream. Correct possible race conditions during device removal. Previously, a scheduled work item to reset a LUN could still execute after the device was removed, leading to use-after-free and other resource access issues. This race condition occurs because the abort handler may schedule a LUN reset concurrently with device removal via sdev_destroy(), leading to use-after-free and improper access to freed resources. - Check in the device reset handler if the device is still present in the controller's SCSI device list before running; if not, the reset is skipped. - Cancel any pending TMF work that has not started in sdev_destroy(). - Ensure device freeing in sdev_destroy() is done while holding the LUN reset mutex to avoid races with ongoing resets. Fixes: 2d80f4054f7f ("scsi: smartpqi: Update deleting a LUN via sysfs") Reviewed-by: Scott Teel Reviewed-by: Scott Benesh Signed-off-by: Mike McGowen Signed-off-by: Don Brace Link: https://patch.msgid.link/20251106163823.786828-3-don.brace@microchip.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/smartpqi/smartpqi_init.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 0af2d366c85f..0cdeb7aa5502 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6366,10 +6366,22 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) { + unsigned long flags; int rc; mutex_lock(&ctrl_info->lun_reset_mutex); + spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); + if (pqi_find_scsi_dev(ctrl_info, device->bus, device->target, device->lun) == NULL) { + dev_warn(&ctrl_info->pci_dev->dev, + "skipping reset of scsi %d:%d:%d:%u, device has been removed\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); + spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); + mutex_unlock(&ctrl_info->lun_reset_mutex); + return 0; + } + spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); + dev_err(&ctrl_info->pci_dev->dev, "resetting scsi %d:%d:%d:%u SCSI cmd at %p due to cmd opcode 0x%02x\n", ctrl_info->scsi_host->host_no, device->bus, device->target, lun, scmd, scsi_opcode); @@ -6549,7 +6561,9 @@ static void pqi_slave_destroy(struct scsi_device *sdev) { struct pqi_ctrl_info *ctrl_info; struct pqi_scsi_dev *device; + struct pqi_tmf_work *tmf_work; int mutex_acquired; + unsigned int lun; unsigned long flags; ctrl_info = shost_to_hba(sdev->host); @@ -6576,8 +6590,13 @@ static void pqi_slave_destroy(struct scsi_device *sdev) mutex_unlock(&ctrl_info->scan_mutex); + for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) + cancel_work_sync(&tmf_work->work_struct); + + mutex_lock(&ctrl_info->lun_reset_mutex); pqi_dev_info(ctrl_info, "removed", device); pqi_free_device(device); + mutex_unlock(&ctrl_info->lun_reset_mutex); } static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) -- Gitee From a90829a7414fc1948534f0c002cbd27bb77aad03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 20 Sep 2024 23:34:33 +0800 Subject: [PATCH 0303/1449] staging: most: i2c: Drop explicit initialization of struct i2c_device_id::driver_data to 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit bb0f288a2c4ba9be3df3dc7b59d0785813bc4ef1 stable. commit b5b7a2c92332b6f799e81f256aed6a93a0e037fd upstream. These drivers don't use the driver_data member of struct i2c_device_id, so don't explicitly initialize this member. This prepares putting driver_data in an anonymous union which requires either no initialization or named designators. But it's also a nice cleanup on its own. While touching the initializer, also remove the comma after the sentinel entry. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20240920153430.503212-15-u.kleine-koenig@baylibre.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 495df2da6944 ("staging: most: remove broken i2c driver") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/staging/most/i2c/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c index ce869280a056..184b2dd11fc3 100644 --- a/drivers/staging/most/i2c/i2c.c +++ b/drivers/staging/most/i2c/i2c.c @@ -352,8 +352,8 @@ static void i2c_remove(struct i2c_client *client) } static const struct i2c_device_id i2c_id[] = { - { "most_i2c", 0 }, - { }, /* Terminating entry */ + { "most_i2c" }, + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(i2c, i2c_id); -- Gitee From 9ed3f3d3af9328ac02fa47bd235a8e6dca2d4d35 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 29 Oct 2025 17:34:42 +0800 Subject: [PATCH 0304/1449] staging: most: remove broken i2c driver ANBZ: #35228 commit 6cbba922934805f86eece6ba7010b7201962695d stable. commit 495df2da6944477d282d5cc0c13174d06e25b310 upstream. The MOST I2C driver has been completely broken for five years without anyone noticing so remove the driver from staging. Specifically, commit 723de0f9171e ("staging: most: remove device from interface structure") started requiring drivers to set the interface device pointer before registration, but the I2C driver was never updated which results in a NULL pointer dereference if anyone ever tries to probe it. Fixes: 723de0f9171e ("staging: most: remove device from interface structure") Cc: Christian Gromm Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251029093442.29256-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/staging/most/Kconfig | 2 - drivers/staging/most/Makefile | 1 - drivers/staging/most/i2c/Kconfig | 13 -- drivers/staging/most/i2c/Makefile | 4 - drivers/staging/most/i2c/i2c.c | 374 ------------------------------ 5 files changed, 394 deletions(-) delete mode 100644 drivers/staging/most/i2c/Kconfig delete mode 100644 drivers/staging/most/i2c/Makefile delete mode 100644 drivers/staging/most/i2c/i2c.c diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig index 6f420cbcdcff..e89658df6f12 100644 --- a/drivers/staging/most/Kconfig +++ b/drivers/staging/most/Kconfig @@ -24,6 +24,4 @@ source "drivers/staging/most/video/Kconfig" source "drivers/staging/most/dim2/Kconfig" -source "drivers/staging/most/i2c/Kconfig" - endif diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile index 8b3fc5a7af51..e45084df7803 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -3,4 +3,3 @@ obj-$(CONFIG_MOST_NET) += net/ obj-$(CONFIG_MOST_VIDEO) += video/ obj-$(CONFIG_MOST_DIM2) += dim2/ -obj-$(CONFIG_MOST_I2C) += i2c/ diff --git a/drivers/staging/most/i2c/Kconfig b/drivers/staging/most/i2c/Kconfig deleted file mode 100644 index ff64283cbad1..000000000000 --- a/drivers/staging/most/i2c/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# MOST I2C configuration -# - -config MOST_I2C - tristate "I2C" - depends on I2C - help - Say Y here if you want to connect via I2C to network transceiver. - - To compile this driver as a module, choose M here: the - module will be called most_i2c. diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile deleted file mode 100644 index 71099dd0f85b..000000000000 --- a/drivers/staging/most/i2c/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MOST_I2C) += most_i2c.o - -most_i2c-objs := i2c.o diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c deleted file mode 100644 index 184b2dd11fc3..000000000000 --- a/drivers/staging/most/i2c/i2c.c +++ /dev/null @@ -1,374 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * i2c.c - Hardware Dependent Module for I2C Interface - * - * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include - -enum { CH_RX, CH_TX, NUM_CHANNELS }; - -#define MAX_BUFFERS_CONTROL 32 -#define MAX_BUF_SIZE_CONTROL 256 - -/** - * list_first_mbo - get the first mbo from a list - * @ptr: the list head to take the mbo from. - */ -#define list_first_mbo(ptr) \ - list_first_entry(ptr, struct mbo, list) - -static unsigned int polling_rate; -module_param(polling_rate, uint, 0644); -MODULE_PARM_DESC(polling_rate, "Polling rate [Hz]. Default = 0 (use IRQ)"); - -struct hdm_i2c { - struct most_interface most_iface; - struct most_channel_capability capabilities[NUM_CHANNELS]; - struct i2c_client *client; - struct rx { - struct delayed_work dwork; - struct list_head list; - bool int_disabled; - unsigned int delay; - } rx; - char name[64]; -}; - -static inline struct hdm_i2c *to_hdm(struct most_interface *iface) -{ - return container_of(iface, struct hdm_i2c, most_iface); -} - -static irqreturn_t most_irq_handler(int, void *); -static void pending_rx_work(struct work_struct *); - -/** - * configure_channel - called from MOST core to configure a channel - * @most_iface: interface the channel belongs to - * @ch_idx: channel to be configured - * @channel_config: structure that holds the configuration information - * - * Return 0 on success, negative on failure. - * - * Receives configuration information from MOST core and initialize the - * corresponding channel. - */ -static int configure_channel(struct most_interface *most_iface, - int ch_idx, - struct most_channel_config *channel_config) -{ - int ret; - struct hdm_i2c *dev = to_hdm(most_iface); - unsigned int delay, pr; - - BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); - - if (channel_config->data_type != MOST_CH_CONTROL) { - pr_err("bad data type for channel %d\n", ch_idx); - return -EPERM; - } - - if (channel_config->direction != dev->capabilities[ch_idx].direction) { - pr_err("bad direction for channel %d\n", ch_idx); - return -EPERM; - } - - if (channel_config->direction == MOST_CH_RX) { - if (!polling_rate) { - if (dev->client->irq <= 0) { - pr_err("bad irq: %d\n", dev->client->irq); - return -ENOENT; - } - dev->rx.int_disabled = false; - ret = request_irq(dev->client->irq, most_irq_handler, 0, - dev->client->name, dev); - if (ret) { - pr_err("request_irq(%d) failed: %d\n", - dev->client->irq, ret); - return ret; - } - } else { - delay = msecs_to_jiffies(MSEC_PER_SEC / polling_rate); - dev->rx.delay = delay ? delay : 1; - pr = MSEC_PER_SEC / jiffies_to_msecs(dev->rx.delay); - pr_info("polling rate is %u Hz\n", pr); - } - } - - return 0; -} - -/** - * enqueue - called from MOST core to enqueue a buffer for data transfer - * @most_iface: intended interface - * @ch_idx: ID of the channel the buffer is intended for - * @mbo: pointer to the buffer object - * - * Return 0 on success, negative on failure. - * - * Transmit the data over I2C if it is a "write" request or push the buffer into - * list if it is an "read" request - */ -static int enqueue(struct most_interface *most_iface, - int ch_idx, struct mbo *mbo) -{ - struct hdm_i2c *dev = to_hdm(most_iface); - int ret; - - BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); - - if (ch_idx == CH_RX) { - /* RX */ - if (!polling_rate) - disable_irq(dev->client->irq); - cancel_delayed_work_sync(&dev->rx.dwork); - list_add_tail(&mbo->list, &dev->rx.list); - if (dev->rx.int_disabled || polling_rate) - pending_rx_work(&dev->rx.dwork.work); - if (!polling_rate) - enable_irq(dev->client->irq); - } else { - /* TX */ - ret = i2c_master_send(dev->client, mbo->virt_address, - mbo->buffer_length); - if (ret <= 0) { - mbo->processed_length = 0; - mbo->status = MBO_E_INVAL; - } else { - mbo->processed_length = mbo->buffer_length; - mbo->status = MBO_SUCCESS; - } - mbo->complete(mbo); - } - - return 0; -} - -/** - * poison_channel - called from MOST core to poison buffers of a channel - * @most_iface: pointer to the interface the channel to be poisoned belongs to - * @ch_idx: corresponding channel ID - * - * Return 0 on success, negative on failure. - * - * If channel direction is RX, complete the buffers in list with - * status MBO_E_CLOSE - */ -static int poison_channel(struct most_interface *most_iface, - int ch_idx) -{ - struct hdm_i2c *dev = to_hdm(most_iface); - struct mbo *mbo; - - BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); - - if (ch_idx == CH_RX) { - if (!polling_rate) - free_irq(dev->client->irq, dev); - cancel_delayed_work_sync(&dev->rx.dwork); - - while (!list_empty(&dev->rx.list)) { - mbo = list_first_mbo(&dev->rx.list); - list_del(&mbo->list); - - mbo->processed_length = 0; - mbo->status = MBO_E_CLOSE; - mbo->complete(mbo); - } - } - - return 0; -} - -static void do_rx_work(struct hdm_i2c *dev) -{ - struct mbo *mbo; - unsigned char msg[MAX_BUF_SIZE_CONTROL]; - int ret; - u16 pml, data_size; - - /* Read PML (2 bytes) */ - ret = i2c_master_recv(dev->client, msg, 2); - if (ret <= 0) { - pr_err("Failed to receive PML\n"); - return; - } - - pml = (msg[0] << 8) | msg[1]; - if (!pml) - return; - - data_size = pml + 2; - - /* Read the whole message, including PML */ - ret = i2c_master_recv(dev->client, msg, data_size); - if (ret <= 0) { - pr_err("Failed to receive a Port Message\n"); - return; - } - - mbo = list_first_mbo(&dev->rx.list); - list_del(&mbo->list); - - mbo->processed_length = min(data_size, mbo->buffer_length); - memcpy(mbo->virt_address, msg, mbo->processed_length); - mbo->status = MBO_SUCCESS; - mbo->complete(mbo); -} - -/** - * pending_rx_work - Read pending messages through I2C - * @work: definition of this work item - * - * Invoked by the Interrupt Service Routine, most_irq_handler() - */ -static void pending_rx_work(struct work_struct *work) -{ - struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work); - - if (list_empty(&dev->rx.list)) - return; - - do_rx_work(dev); - - if (polling_rate) { - schedule_delayed_work(&dev->rx.dwork, dev->rx.delay); - } else { - dev->rx.int_disabled = false; - enable_irq(dev->client->irq); - } -} - -/* - * most_irq_handler - Interrupt Service Routine - * @irq: irq number - * @_dev: private data - * - * Schedules a delayed work - * - * By default the interrupt line behavior is Active Low. Once an interrupt is - * generated by the device, until driver clears the interrupt (by reading - * the PMP message), device keeps the interrupt line in low state. Since i2c - * read is done in work queue, the interrupt line must be disabled temporarily - * to avoid ISR being called repeatedly. Re-enable the interrupt in workqueue, - * after reading the message. - * - * Note: If we use the interrupt line in Falling edge mode, there is a - * possibility to miss interrupts when ISR is getting executed. - * - */ -static irqreturn_t most_irq_handler(int irq, void *_dev) -{ - struct hdm_i2c *dev = _dev; - - disable_irq_nosync(irq); - dev->rx.int_disabled = true; - schedule_delayed_work(&dev->rx.dwork, 0); - - return IRQ_HANDLED; -} - -/* - * i2c_probe - i2c probe handler - * @client: i2c client device structure - * @id: i2c client device id - * - * Return 0 on success, negative on failure. - * - * Register the i2c client device as a MOST interface - */ -static int i2c_probe(struct i2c_client *client) -{ - struct hdm_i2c *dev; - int ret, i; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - /* ID format: i2c--
*/ - snprintf(dev->name, sizeof(dev->name), "i2c-%d-%04x", - client->adapter->nr, client->addr); - - for (i = 0; i < NUM_CHANNELS; i++) { - dev->capabilities[i].data_type = MOST_CH_CONTROL; - dev->capabilities[i].num_buffers_packet = MAX_BUFFERS_CONTROL; - dev->capabilities[i].buffer_size_packet = MAX_BUF_SIZE_CONTROL; - } - dev->capabilities[CH_RX].direction = MOST_CH_RX; - dev->capabilities[CH_RX].name_suffix = "rx"; - dev->capabilities[CH_TX].direction = MOST_CH_TX; - dev->capabilities[CH_TX].name_suffix = "tx"; - - dev->most_iface.interface = ITYPE_I2C; - dev->most_iface.description = dev->name; - dev->most_iface.num_channels = NUM_CHANNELS; - dev->most_iface.channel_vector = dev->capabilities; - dev->most_iface.configure = configure_channel; - dev->most_iface.enqueue = enqueue; - dev->most_iface.poison_channel = poison_channel; - - INIT_LIST_HEAD(&dev->rx.list); - - INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work); - - dev->client = client; - i2c_set_clientdata(client, dev); - - ret = most_register_interface(&dev->most_iface); - if (ret) { - pr_err("Failed to register i2c as a MOST interface\n"); - kfree(dev); - return ret; - } - - return 0; -} - -/* - * i2c_remove - i2c remove handler - * @client: i2c client device structure - * - * Return 0 on success. - * - * Unregister the i2c client device as a MOST interface - */ -static void i2c_remove(struct i2c_client *client) -{ - struct hdm_i2c *dev = i2c_get_clientdata(client); - - most_deregister_interface(&dev->most_iface); - kfree(dev); -} - -static const struct i2c_device_id i2c_id[] = { - { "most_i2c" }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(i2c, i2c_id); - -static struct i2c_driver i2c_driver = { - .driver = { - .name = "hdm_i2c", - }, - .probe = i2c_probe, - .remove = i2c_remove, - .id_table = i2c_id, -}; - -module_i2c_driver(i2c_driver); - -MODULE_AUTHOR("Andrey Shvetsov "); -MODULE_DESCRIPTION("I2C Hardware Dependent Module"); -MODULE_LICENSE("GPL"); -- Gitee From 399ec9ea3c93b66a31f726f51178fecbcefa9003 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Sat, 1 Nov 2025 12:29:40 +0800 Subject: [PATCH 0305/1449] dt-bindings: PCI: amlogic: Fix the register name of the DBI region ANBZ: #35228 commit 841ccb2df19b4e9f43351e58921689f9d0b45bf8 stable. commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 upstream. Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must have region for DWC controllers as it has the Root Port and controller specific registers, while ELBI has optional registers. Hence, fix the binding. Though this is an ABI break, this change is needed to accurately describe the PCI memory map. Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") Signed-off-by: Manivannan Sadhasivam Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml index a5bd90bc0712..9c3b8e65c42a 100644 --- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml @@ -36,13 +36,13 @@ properties: reg: items: - - description: External local bus interface registers + - description: Data Bus Interface registers - description: Meson designed configuration registers - description: PCIe configuration space reg-names: items: - - const: elbi + - const: dbi - const: cfg - const: config @@ -113,7 +113,7 @@ examples: pcie: pcie@f9800000 { compatible = "amlogic,axg-pcie", "snps,dw-pcie"; reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; - reg-names = "elbi", "cfg", "config"; + reg-names = "dbi", "cfg", "config"; interrupts = ; clocks = <&pclk>, <&clk_port>, <&clk_phy>; clock-names = "pclk", "port", "general"; -- Gitee From 0660b734c16b22abf65137893860b633f7930a72 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Mon, 10 Nov 2025 08:51:58 +0800 Subject: [PATCH 0306/1449] RDMA/rtrs: server: Fix error handling in get_or_create_srv ANBZ: #35228 commit d76abca880453f165c1dc0e19ceab2cef6b72487 stable. commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 upstream. After device_initialize() is called, use put_device() to release the device according to kernel device management rules. While direct kfree() work in this case, using put_device() is more correct. Found by code review. Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") Signed-off-by: Ma Ke Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn Acked-by: Jack Wang Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index 84d1654148d7..5dbf315630c1 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -1443,7 +1443,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, kfree(srv->chunks); err_free_srv: - kfree(srv); + put_device(&srv->dev); return ERR_PTR(-ENOMEM); } -- Gitee From bdaf41fafe8256e8d3953b062d00295d2bc4359e Mon Sep 17 00:00:00 2001 From: Jihed Chaibi Date: Tue, 16 Sep 2025 06:46:11 +0800 Subject: [PATCH 0307/1449] ARM: dts: stm32: stm32mp157c-phycore: Fix STMPE811 touchscreen node properties ANBZ: #35228 commit 86322d5110aee5acb93fbed370d4316dd9c2cb79 stable. commit e40b061cd379f4897e705d17cf1b4572ad0f3963 upstream. Move st,adc-freq, st,mod-12b, st,ref-sel, and st,sample-time properties from the touchscreen subnode to the parent touch@44 node. These properties are defined in the st,stmpe.yaml schema for the parent node, not the touchscreen subnode, resolving the validation error about unevaluated properties. Fixes: 27538a18a4fcc ("ARM: dts: stm32: add STM32MP1-based Phytec SoM") Signed-off-by: Jihed Chaibi Link: https://lore.kernel.org/r/20250915224611.169980-1-jihed.chaibi.dev@gmail.com Signed-off-by: Alexandre Torgue Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi index 4e8b2d2b30c7..7dfe1fbfbfed 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +++ b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi @@ -185,13 +185,13 @@ touch@44 { interrupt-parent = <&gpioi>; vio-supply = <&v3v3>; vcc-supply = <&v3v3>; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; touchscreen { compatible = "st,stmpe-ts"; - st,sample-time = <4>; - st,mod-12b = <1>; - st,ref-sel = <0>; - st,adc-freq = <1>; st,ave-ctrl = <1>; st,touch-det-delay = <2>; st,settling = <2>; -- Gitee From ac6ffb4f4fd8654b5d68b8429be5ce36e0448459 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Tue, 16 Sep 2025 13:50:13 +0800 Subject: [PATCH 0308/1449] ntfs3: init run lock for extend inode ANBZ: #35228 commit 907bf69c6b6ce5d038eec7a599d67b45b62624bc stable. commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 upstream. After setting the inode mode of $Extend to a regular file, executing the truncate system call will enter the do_truncate() routine, causing the run_lock uninitialized error reported by syzbot. Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to a regular file, the do_truncate() routine would not be entered. Add the run_lock initialization when loading $Extend. syzbot reported: INFO: trying to register non-static key. Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index bb3459c2ae02..3da73f716dda 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -465,6 +465,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, /* Records in $Extend are not a files or general directories. */ inode->i_op = &ntfs_file_inode_operations; mode = S_IFREG; + init_rwsem(&ni->file.run_lock); } else { err = -EINVAL; goto out; -- Gitee From 581ec1c28635fb93971b9f3347ca51bf9f84436b Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Sat, 8 Nov 2025 07:05:17 +0800 Subject: [PATCH 0309/1449] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() ANBZ: #35228 commit ef2bbc11b82b72e5672ffcd310ff298e2d1dfc8a stable. commit d794b499f948801f54d67ddbc34a6eac5a6d150a upstream. The function ufshcd_read_string_desc() was duplicating memory starting from the beginning of struct uc_string_id, which included the length and type fields. As a result, the allocated buffer contained unwanted metadata in addition to the string itself. The correct behavior is to duplicate only the Unicode character array in the structure. Update the code so that only the actual string content is copied into the new buffer. Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") Reviewed-by: Avri Altman Reviewed-by: Bart Van Assche Signed-off-by: Bean Huo Link: https://patch.msgid.link/20251107230518.4060231-3-beanhuo@iokpp.de Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ufs/core/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 01a7c1720ce1..9d6a47abe4bc 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3738,7 +3738,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, str[ret++] = '\0'; } else { - str = kmemdup(uc_str, uc_str->len, GFP_KERNEL); + str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); if (!str) { ret = -ENOMEM; goto out; -- Gitee From b52793774949437f3af3378025d3cf5915fb9724 Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Fri, 7 Nov 2025 13:11:45 +0530 Subject: [PATCH 0310/1449] cpufreq/amd-pstate: Call cppc_set_auto_sel() only for online CPUs ANBZ: #35228 commit a68afb6d6540b8f9f3f5baf4513df478e0b15f16 stable. commit bb31fef0d03ed17d587b40e3458786be408fb9df upstream. amd_pstate_change_mode_without_dvr_change() calls cppc_set_auto_sel() for all the present CPUs. However, this callpath eventually calls cppc_set_reg_val() which accesses the per-cpu cpc_desc_ptr object. This object is initialized only for online CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() --> acpi_cppc_processor_probe(). Hence, restrict calling cppc_set_auto_sel() to only the online CPUs. Fixes: 3ca7bc818d8c ("cpufreq: amd-pstate: Add guided mode control support via sysfs") Suggested-by: Mario Limonciello (AMD) (kernel.org) Signed-off-by: Gautham R. Shenoy Signed-off-by: Mario Limonciello (AMD) Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- drivers/cpufreq/amd-pstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index d4ac7b23d639..02b5fdc0e855 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -1282,7 +1282,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode) if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE) return 0; - for_each_present_cpu(cpu) { + for_each_online_cpu(cpu) { cppc_set_auto_sel(cpu, (cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1); } -- Gitee From 6a0940724642741df020ddb5dd2a667c91355b90 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 12 Sep 2025 16:37:34 +0800 Subject: [PATCH 0311/1449] powerpc/32: Fix unpaired stwcx. on interrupt exit ANBZ: #35228 commit d5720e4045affca827a96b65920af5f3f4bbd186 stable. commit 10e1c77c3636d815db802ceef588522c2d2d947c upstream. Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") erroneouly copied to powerpc/32 the logic from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is always 0 on powerpc/32. Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] Avoid unpaired stwcx. on some processors") which is based on CPU_FTR_NEED_PAIRED_STWCX feature. Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") Signed-off-by: Christophe Leroy Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/kernel/entry_32.S | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 7eda33a24bb4..ba1670311bb0 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -269,10 +269,9 @@ interrupt_return: mtspr SPRN_SRR1,r12 BEGIN_FTR_SECTION + lwarx r0,0,r1 +END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) stwcx. r0,0,r1 /* to clear the reservation */ -FTR_SECTION_ELSE - lwarx r0,0,r1 -ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) lwz r3,_CCR(r1) lwz r4,_LINK(r1) @@ -315,10 +314,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) mtspr SPRN_SRR1,r12 BEGIN_FTR_SECTION + lwarx r0,0,r1 +END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) stwcx. r0,0,r1 /* to clear the reservation */ -FTR_SECTION_ELSE - lwarx r0,0,r1 -ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) lwz r3,_LINK(r1) lwz r4,_CTR(r1) -- Gitee From bff36501230bf0de2f6e838658491898ef684a76 Mon Sep 17 00:00:00 2001 From: Long Li Date: Tue, 19 Aug 2025 17:10:35 +0800 Subject: [PATCH 0312/1449] macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse ANBZ: #35228 commit 61abf8c3162d155b4fd0fb251f08557093363a0a stable. commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f upstream. The following warning appears when running syzkaller, and this issue also exists in the mainline code. ------------[ cut here ]------------ list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 Modules linked in: CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:__list_add_valid_or_report+0xf7/0x130 RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 80000000 Call Trace: input_register_handler+0xb3/0x210 mac_hid_start_emulation+0x1c5/0x290 mac_hid_toggle_emumouse+0x20a/0x240 proc_sys_call_handler+0x4c2/0x6e0 new_sync_write+0x1b1/0x2d0 vfs_write+0x709/0x950 ksys_write+0x12a/0x250 do_syscall_64+0x5a/0x110 entry_SYSCALL_64_after_hwframe+0x78/0xe2 The WARNING occurs when two processes concurrently write to the mac-hid emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). Both processes read old_val=0, then both try to register the input handler, leading to a double list_add of the same handler. CPU0 CPU1 ------------------------- ------------------------- vfs_write() //write 1 vfs_write() //write 1 proc_sys_write() proc_sys_write() mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() old_val = *valp // old_val=0 old_val = *valp // old_val=0 mutex_lock_killable() proc_dointvec() // *valp=1 mac_hid_start_emulation() input_register_handler() mutex_unlock() mutex_lock_killable() proc_dointvec() mac_hid_start_emulation() input_register_handler() //Trigger Warning mutex_unlock() Fix this by moving the old_val read inside the mutex lock region. Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") Signed-off-by: Long Li Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/macintosh/mac_hid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index d8c4d5664145..44e332ee99d3 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -186,13 +186,14 @@ static int mac_hid_toggle_emumouse(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { int *valp = table->data; - int old_val = *valp; + int old_val; int rc; rc = mutex_lock_killable(&mac_hid_emumouse_mutex); if (rc) return rc; + old_val = *valp; rc = proc_dointvec(table, write, buffer, lenp, ppos); if (rc == 0 && write && *valp != old_val) { -- Gitee From bb7ea526c4ed9260a5c5c5782f88efb330d5a3f5 Mon Sep 17 00:00:00 2001 From: Abdun Nihaal Date: Tue, 11 Nov 2025 01:53:15 +0800 Subject: [PATCH 0313/1449] wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() ANBZ: #35228 commit cbfcd8ee53c2a62e3579745dc2c18a73437cb296 stable. commit 5e88e864118c20e63a1571d0ff0a152e5d684959 upstream. In one of the error paths, the memory allocated for skb_rx is not freed. Fix that by freeing it before returning. Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") Signed-off-by: Abdun Nihaal Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c index 3b4ded2ac801..37232ee22037 100644 --- a/drivers/net/wireless/st/cw1200/bh.c +++ b/drivers/net/wireless/st/cw1200/bh.c @@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, if (wsm_id & 0x0400) { int rc = wsm_release_tx_buffer(priv, 1); - if (WARN_ON(rc < 0)) + if (WARN_ON(rc < 0)) { + dev_kfree_skb(skb_rx); return rc; - else if (rc > 0) + } else if (rc > 0) { *tx = 1; + } } /* cw1200_wsm_rx takes care on SKB livetime */ -- Gitee From 47aed6476303f2a56edb3f533160b539e3e102ec Mon Sep 17 00:00:00 2001 From: Zheng Qixing Date: Mon, 10 Nov 2025 20:49:20 +0800 Subject: [PATCH 0314/1449] nbd: defer config unlock in nbd_genl_connect ANBZ: #35228 commit 2e5e0665a594f076ef2b9439447bae8be293d09d stable. commit 1649714b930f9ea6233ce0810ba885999da3b5d4 upstream. There is one use-after-free warning when running NBD_CMD_CONNECT and NBD_CLEAR_SOCK: nbd_genl_connect nbd_alloc_and_init_config // config_refs=1 nbd_start_device // config_refs=2 set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 recv_work done // config_refs=2 NBD_CLEAR_SOCK // config_refs=1 close nbd // config_refs=0 refcount_inc -> uaf ------------[ cut here ]------------ refcount_t: addition on 0; use-after-free. WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 nbd_genl_connect+0x16d0/0x1ab0 genl_family_rcv_msg_doit+0x1f3/0x310 genl_rcv_msg+0x44a/0x790 The issue can be easily reproduced by adding a small delay before refcount_inc(&nbd->config_refs) in nbd_genl_connect(): mutex_unlock(&nbd->config_lock); if (!ret) { set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + printk("before sleep\n"); + mdelay(5 * 1000); + printk("after sleep\n"); refcount_inc(&nbd->config_refs); nbd_connect_reply(info, nbd->index); } Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") Signed-off-by: Zheng Qixing Reviewed-by: Yu Kuai Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/nbd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 9e190d220e98..8b7f306ec976 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -2147,12 +2147,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) ret = nbd_start_device(nbd); out: - mutex_unlock(&nbd->config_lock); if (!ret) { set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); refcount_inc(&nbd->config_refs); nbd_connect_reply(info, nbd->index); } + mutex_unlock(&nbd->config_lock); + nbd_config_put(nbd); if (put_dev) nbd_put(nbd); -- Gitee From ae29975d5600d3f7a1a33451ccc677cef8142eb3 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Wed, 12 Nov 2025 02:58:38 +0800 Subject: [PATCH 0315/1449] coresight: etm4x: Correct polling IDLE bit ANBZ: #35228 commit 60f664206be297229598cd068f014a8fdbef1e9c stable. commit 4dc4e22f9536341255f5de6047977a80ff47eaef upstream. Since commit 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR"), the code has incorrectly been polling the PMSTABLE bit instead of the IDLE bit. This commit corrects the typo. Fixes: 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR") Reviewed-by: Yeoreum Yun Reviewed-by: Mike Leach Tested-by: James Clark Signed-off-by: Leo Yan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-4-f55553b6c8b3@arm.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index b808effca173..63ddd81e9d1a 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1844,7 +1844,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) state->trcpdcr = etm4x_read32(csa, TRCPDCR); /* wait for TRCSTATR.IDLE to go up */ - if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { + if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) { dev_err(etm_dev, "timeout while waiting for Idle Trace Status\n"); etm4_os_unlock(drvdata); -- Gitee From a5449e111c864267a2455d8f94bd003fb05d26fd Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Wed, 2 Apr 2025 02:07:02 +0800 Subject: [PATCH 0316/1449] coresight: etm4x: Extract the trace unit controlling ANBZ: #35228 commit 289d9a2a98ba60db9ff877403a6dfa1287cd4077 stable. commit 40f682ae5086366d51e29e66eb8a344501245d0d upstream. The trace unit is controlled in the ETM hardware enabling and disabling. The sequential changes for support AUX pause and resume will reuse the same operations. Extract the operations in the etm4_{enable|disable}_trace_unit() functions. A minor improvement in etm4_enable_trace_unit() is for returning the timeout error to callers. Signed-off-by: Leo Yan Reviewed-by: Mike Leach Reviewed-by: James Clark Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20250401180708.385396-2-leo.yan@arm.com Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../coresight/coresight-etm4x-core.c | 103 +++++++++++------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 63ddd81e9d1a..8c13d885fd26 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -422,6 +422,44 @@ static int etm4x_wait_status(struct csdev_access *csa, int pos, int val) return coresight_timeout(csa, TRCSTATR, pos, val); } +static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) +{ + struct coresight_device *csdev = drvdata->csdev; + struct device *etm_dev = &csdev->dev; + struct csdev_access *csa = &csdev->access; + + /* + * ETE mandates that the TRCRSR is written to before + * enabling it. + */ + if (etm4x_is_ete(drvdata)) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + + /* Synchronize the register updates for sysreg access */ + if (!csa->io_mem) + isb(); + + /* wait for TRCSTATR.IDLE to go back down to '0' */ + if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + return -ETIME; + } + + /* + * As recommended by section 4.3.7 ("Synchronization when using the + * memory-mapped interface") of ARM IHI 0064D + */ + dsb(sy); + isb(); + + return 0; +} + static int etm4_enable_hw(struct etmv4_drvdata *drvdata) { int i, rc; @@ -531,33 +569,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); } - /* - * ETE mandates that the TRCRSR is written to before - * enabling it. - */ - if (etm4x_is_ete(drvdata)) - etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); - - etm4x_allow_trace(drvdata); - /* Enable the trace unit */ - etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); - - /* Synchronize the register updates for sysreg access */ - if (!csa->io_mem) - isb(); - - /* wait for TRCSTATR.IDLE to go back down to '0' */ - if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) - dev_err(etm_dev, - "timeout while waiting for Idle Trace Status\n"); - - /* - * As recommended by section 4.3.7 ("Synchronization when using the - * memory-mapped interface") of ARM IHI 0064D - */ - dsb(sy); - isb(); - + rc = etm4_enable_trace_unit(drvdata); done: etm4_cs_lock(drvdata, csa); @@ -889,25 +901,12 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, return ret; } -static void etm4_disable_hw(void *info) +static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) { u32 control; - struct etmv4_drvdata *drvdata = info; - struct etmv4_config *config = &drvdata->config; struct coresight_device *csdev = drvdata->csdev; struct device *etm_dev = &csdev->dev; struct csdev_access *csa = &csdev->access; - int i; - - etm4_cs_unlock(drvdata, csa); - etm4_disable_arch_specific(drvdata); - - if (!drvdata->skip_power_up) { - /* power can be removed from the trace unit now */ - control = etm4x_relaxed_read32(csa, TRCPDCR); - control &= ~TRCPDCR_PU; - etm4x_relaxed_write32(csa, control, TRCPDCR); - } control = etm4x_relaxed_read32(csa, TRCPRGCTLR); @@ -948,6 +947,28 @@ static void etm4_disable_hw(void *info) * of ARM IHI 0064H.b. */ isb(); +} + +static void etm4_disable_hw(void *info) +{ + u32 control; + struct etmv4_drvdata *drvdata = info; + struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct csdev_access *csa = &csdev->access; + int i; + + etm4_cs_unlock(drvdata, csa); + etm4_disable_arch_specific(drvdata); + + if (!drvdata->skip_power_up) { + /* power can be removed from the trace unit now */ + control = etm4x_relaxed_read32(csa, TRCPDCR); + control &= ~TRCPDCR_PU; + etm4x_relaxed_write32(csa, control, TRCPDCR); + } + + etm4_disable_trace_unit(drvdata); /* read the status of the single shot comparators */ for (i = 0; i < drvdata->nr_ss_cmp; i++) { -- Gitee From e6b622891771d6977336e5b89b9f13b89cab9b8b Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Wed, 12 Nov 2025 02:58:39 +0800 Subject: [PATCH 0317/1449] coresight: etm4x: Add context synchronization before enabling trace ANBZ: #35228 commit bb5f23ae16be11a05649a064268426715917e148 stable. commit 64eb04ae545294e105ad91714dc3167a0b660731 upstream. According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a Context synchronization event is required before enabling the trace unit. An ISB is added to meet this requirement, particularly for guarding the operations in the flow: etm4x_allow_trace() `> kvm_tracing_set_el1_configuration() `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) Improved the barrier comments to provide more accurate information. Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") Reviewed-by: Mike Leach Reviewed-by: Yeoreun Yun Tested-by: James Clark Signed-off-by: Leo Yan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 8c13d885fd26..4f2abd5ce985 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -436,10 +436,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); etm4x_allow_trace(drvdata); + + /* + * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), + * execute a Context synchronization event to guarantee the trace unit + * will observe the new values of the System registers. + */ + if (!csa->io_mem) + isb(); + /* Enable the trace unit */ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); - /* Synchronize the register updates for sysreg access */ + /* + * As recommended by section 4.3.7 ("Synchronization when using system + * instructions to progrom the trace unit") of ARM IHI 0064H.b, the + * self-hosted trace analyzer must perform a Context synchronization + * event between writing to the TRCPRGCTLR and reading the TRCSTATR. + */ if (!csa->io_mem) isb(); @@ -919,11 +933,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) */ etm4x_prohibit_trace(drvdata); /* - * Make sure everything completes before disabling, as recommended - * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, - * SSTATUS") of ARM IHI 0064D + * Prevent being speculative at the point of disabling the trace unit, + * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control + * Register, SSTATUS") of ARM IHI 0064D */ dsb(sy); + /* + * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), + * execute a Context synchronization event to guarantee no new + * program-flow trace is generated. + */ isb(); /* Trace synchronization barrier, is a nop if not supported */ tsb_csync(); -- Gitee From 45d70830b7148a975723322ea07e1bbc190a1eff Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Thu, 30 Oct 2025 14:16:03 +0800 Subject: [PATCH 0318/1449] clk: renesas: r9a06g032: Fix memory leak in error path ANBZ: #35228 commit 43e2c9203d0f987519ebd018643162be382c1f04 stable. commit f8def051bbcf8677f64701e9699bf6d11e2780cd upstream. The current code uses of_iomap() to map registers but never calls iounmap() on any error path after the mapping. This causes a memory leak when probe fails after successful ioremap, for example when of_clk_add_provider() or r9a06g032_add_clk_domain() fails. Replace of_iomap() with devm_of_iomap() to automatically unmap the region on probe failure. Update the error check accordingly to use IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") Signed-off-by: Haotian Zhang Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 55db63c7041a..cdc820b7e6ea 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -1316,9 +1316,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) if (IS_ERR(mclk)) return PTR_ERR(mclk); - clocks->reg = of_iomap(np, 0); - if (WARN_ON(!clocks->reg)) - return -ENOMEM; + clocks->reg = devm_of_iomap(dev, np, 0, NULL); + if (IS_ERR(clocks->reg)) + return PTR_ERR(clocks->reg); r9a06g032_init_h2mode(clocks); -- Gitee From e1b3ecfb71de8a9ecc6fd6c6b881a76086feb1a8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 10 Nov 2025 21:21:18 +0800 Subject: [PATCH 0319/1449] lib/vsprintf: Check pointer before dereferencing in time_and_date() ANBZ: #35228 commit 7c8a7d87af9d39268ae33dc316c67945ebbe1348 stable. commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f upstream. The pointer may be invalid when gets to the printf(). In particular the time_and_date() dereferencing it in some cases without checking. Move the check from rtc_str() to time_and_date() to cover all cases. Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") Signed-off-by: Andy Shevchenko Reviewed-by: Petr Mladek Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com Signed-off-by: Petr Mladek Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- lib/vsprintf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index f4ab2750cfc1..fc5ffc1b1690 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1859,9 +1859,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, bool found = true; int count = 2; - if (check_pointer(&buf, end, tm, spec)) - return buf; - switch (fmt[count]) { case 'd': have_t = false; @@ -1927,6 +1924,9 @@ static noinline_for_stack char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, const char *fmt) { + if (check_pointer(&buf, end, ptr, spec)) + return buf; + switch (fmt[1]) { case 'R': return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); -- Gitee From 8f5e87c6528cdc7d48b800979b9177ee92ae0b3f Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 9 Oct 2025 18:23:49 +0800 Subject: [PATCH 0320/1449] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() ANBZ: #35228 commit bcb94288d95cfc52f4d7cead260f4db54c8c741a stable. commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d upstream. In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just to avoid crashing the whole kernel due to a filesystem corruption. Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru Signed-off-by: Dmitry Antipov Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ocfs2/move_extents.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 2f34074f0078..d97ec93ff4c2 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, rec = &el->l_recs[index]; - BUG_ON(ext_flags != rec->e_flags); + if (ext_flags != rec->e_flags) { + ret = ocfs2_error(inode->i_sb, + "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", + (unsigned long long)ino, index, rec->e_flags, cpos); + goto out; + } + /* * after moving/defraging to new location, the extent is not going * to be refcounted anymore. -- Gitee From d56b3c7eccf0afb0207f1c68ed87a3e8e37ced81 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 11 Nov 2025 15:50:00 +0800 Subject: [PATCH 0321/1449] ACPI: property: Fix fwnode refcount leak in acpi_fwnode_graph_parse_endpoint() ANBZ: #35228 commit 39c754efb3e1a827a2f222e8ff694da619cf5603 stable. commit 593ee49222a0d751062fd9a5e4a963ade4ec028a upstream. acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the parent fwnode but returns without calling fwnode_handle_put() on it. This potentially leads to a fwnode refcount leak and prevents the parent node from being released properly. Call fwnode_handle_put() on the parent fwnode before returning to prevent the leak from occurring. Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") Signed-off-by: Haotian Zhang Reviewed-by: Sakari Ailus [ rjw: Changelog edits ] Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/property.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index d02b332744e6..1b8f3958b0ed 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -1622,6 +1622,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + fwnode_handle_put(port_fwnode); return 0; } -- Gitee From 093689caf9aaba14bc45eab0491b66f8df08a83e Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 29 Oct 2025 11:25:55 +0800 Subject: [PATCH 0322/1449] scsi: sim710: Fix resource leak by adding missing ioport_unmap() calls ANBZ: #35228 commit 796037ca2faba445a565fb6e577e4b35d50e7780 stable. commit acd194d9b5bac419e04968ffa44351afabb50bac upstream. The driver calls ioport_map() to map I/O ports in sim710_probe_common() but never calls ioport_unmap() to release the mapping. This causes resource leaks in both the error path when request_irq() fails and in the normal device removal path via sim710_device_remove(). Add ioport_unmap() calls in the out_release error path and in sim710_device_remove(). Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/sim710.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index e519df68d603..70c75ab1453a 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, out_put_host: scsi_host_put(host); out_release: + ioport_unmap(hostdata->base); release_region(base_addr, 64); out_free: kfree(hostdata); @@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) scsi_remove_host(host); NCR_700_release(host); + ioport_unmap(hostdata->base); kfree(hostdata); free_irq(host->irq, host); release_region(host->base, 64); -- Gitee From 16ecf015e2f98ba6821530a2db5683fc9d3e5c8b Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Fri, 31 Oct 2025 10:16:20 +0800 Subject: [PATCH 0323/1449] leds: netxbig: Fix GPIO descriptor leak in error paths ANBZ: #35228 commit df38a4843ab5892e09911ae46f303d725889a5cf stable. commit 03865dd8af52eb16c38062df2ed30a91b604780e upstream. The function netxbig_gpio_ext_get() acquires GPIO descriptors but fails to release them when errors occur mid-way through initialization. The cleanup callback registered by devm_add_action_or_reset() only runs on success, leaving acquired GPIOs leaked on error paths. Add goto-based error handling to release all acquired GPIOs before returning errors. Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") Suggested-by: Markus Elfring Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 6692de0af68f..ea0801b9cb01 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, if (!addr) return -ENOMEM; + gpio_ext->addr = addr; + gpio_ext->num_addr = 0; + /* * We cannot use devm_ managed resources with these GPIO descriptors * since they are associated with the "GPIO extension device" which @@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) - return PTR_ERR(gpiod); + goto err_set_code; gpiod_set_consumer_name(gpiod, "GPIO extension addr"); addr[i] = gpiod; + gpio_ext->num_addr++; } - gpio_ext->addr = addr; - gpio_ext->num_addr = num_addr; ret = gpiod_count(gpio_ext_dev, "data"); if (ret < 0) { dev_err(dev, "Failed to count GPIOs in DT property data-gpios\n"); - return ret; + goto err_free_addr; } num_data = ret; data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; + if (!data) { + ret = -ENOMEM; + goto err_free_addr; + } + + gpio_ext->data = data; + gpio_ext->num_data = 0; for (i = 0; i < num_data; i++) { gpiod = gpiod_get_index(gpio_ext_dev, "data", i, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) - return PTR_ERR(gpiod); + goto err_free_data; gpiod_set_consumer_name(gpiod, "GPIO extension data"); data[i] = gpiod; + gpio_ext->num_data++; } - gpio_ext->data = data; - gpio_ext->num_data = num_data; gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(gpiod)) { dev_err(dev, "Failed to get GPIO from DT property enable-gpio\n"); - return PTR_ERR(gpiod); + goto err_free_data; } gpiod_set_consumer_name(gpiod, "GPIO extension enable"); gpio_ext->enable = gpiod; return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); + +err_free_data: + for (i = 0; i < gpio_ext->num_data; i++) + gpiod_put(gpio_ext->data[i]); +err_set_code: + ret = PTR_ERR(gpiod); +err_free_addr: + for (i = 0; i < gpio_ext->num_addr; i++) + gpiod_put(gpio_ext->addr[i]); + return ret; } static int netxbig_leds_get_of_pdata(struct device *dev, -- Gitee From a1147d55fcdd876197a5d488fe5bd5006345b954 Mon Sep 17 00:00:00 2001 From: Leon Hwang Date: Wed, 5 Nov 2025 23:14:06 +0800 Subject: [PATCH 0324/1449] bpf: Free special fields when update [lru_,]percpu_hash maps ANBZ: #35228 commit 994d6303ed0b84cbc795bb5becf7ed6de40d3f3c stable. commit 6af6e49a76c9af7d42eb923703e7648cb2bf401a upstream. As [lru_,]percpu_hash maps support BPF_KPTR_{REF,PERCPU}, missing calls to 'bpf_obj_free_fields()' in 'pcpu_copy_value()' could cause the memory referenced by BPF_KPTR_{REF,PERCPU} fields to be held until the map gets freed. Fix this by calling 'bpf_obj_free_fields()' after 'copy_map_value[,_long]()' in 'pcpu_copy_value()'. Fixes: 65334e64a493 ("bpf: Support kptrs in percpu hashmap and percpu LRU hashmap") Signed-off-by: Leon Hwang Acked-by: Yonghong Song Link: https://lore.kernel.org/r/20251105151407.12723-2-leon.hwang@linux.dev Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/bpf/hashtab.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 8a3eadf17f78..8bac6ae1204d 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -957,15 +957,21 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, void *value, bool onallcpus) { + void *ptr; + if (!onallcpus) { /* copy true value_size bytes */ - copy_map_value(&htab->map, this_cpu_ptr(pptr), value); + ptr = this_cpu_ptr(pptr); + copy_map_value(&htab->map, ptr, value); + bpf_obj_free_fields(htab->map.record, ptr); } else { u32 size = round_up(htab->map.value_size, 8); int off = 0, cpu; for_each_possible_cpu(cpu) { - copy_map_value_long(&htab->map, per_cpu_ptr(pptr, cpu), value + off); + ptr = per_cpu_ptr(pptr, cpu); + copy_map_value_long(&htab->map, ptr, value + off); + bpf_obj_free_fields(htab->map.record, ptr); off += size; } } -- Gitee From fb95f0d204cf720b56ef238a4a77106eb2b233a0 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Wed, 29 Oct 2025 16:04:51 +0800 Subject: [PATCH 0325/1449] PCI: keystone: Exit ks_pcie_probe() for invalid mode ANBZ: #35228 commit 3800c97efff28eb72c5fd452cc0ce9689939de32 stable. commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f upstream. Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", the PCIe Controller is configured accordingly. However, when the mode is neither of them, an error message is displayed, but the driver probe succeeds. Since this "invalid" mode is not associated with a functional PCIe Controller, the probe should fail. Fix the behavior by exiting "ks_pcie_probe()" with the return value of "-EINVAL" in addition to displaying the existing error message when the mode is invalid. Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") Signed-off-by: Siddharth Vadapalli Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/controller/dwc/pci-keystone.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 9055ce34c636..7dcb9a9f385e 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -1341,6 +1341,8 @@ static int ks_pcie_probe(struct platform_device *pdev) break; default: dev_err(dev, "INVALID device type %d\n", mode); + ret = -EINVAL; + goto err_get_sync; } ks_pcie_enable_error_irq(ks_pcie); -- Gitee From 05cb66d018ac27f8534628b717901490ac6691e8 Mon Sep 17 00:00:00 2001 From: FUKAUMI Naoki Date: Wed, 12 Nov 2025 11:51:29 +0800 Subject: [PATCH 0326/1449] arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK 5A ANBZ: #35228 commit 6b73166d3b4ba1adfaee3f25bc7e71e991c90e17 stable. commit 92e6e0b0e595afdda6296c760551ad3ffe9d5231 upstream. The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected to the i2c0 bus, [1] so move the eeprom node from the i2c2 bus to the i2c0 bus. [1] Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19 Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") Signed-off-by: FUKAUMI Naoki Link: https://patch.msgid.link/20251112035133.28753-2-naoki@radxa.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts index 68763714f7f7..f60243e2b3c3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts @@ -184,6 +184,12 @@ regulator-state-mem { regulator-off-in-suspend; }; }; + + eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; + }; }; &i2c2 { @@ -205,12 +211,6 @@ regulator-state-mem { regulator-off-in-suspend; }; }; - - eeprom: eeprom@50 { - compatible = "belling,bl24c16a", "atmel,24c16"; - reg = <0x50>; - pagesize = <16>; - }; }; &i2c3 { -- Gitee From ae4f6e65a3ac66237aa469653ed906ca7b42a07e Mon Sep 17 00:00:00 2001 From: FUKAUMI Naoki Date: Wed, 12 Nov 2025 11:51:30 +0800 Subject: [PATCH 0327/1449] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A ANBZ: #35228 commit f5391a065c158e707b9a18592a75b9ab4c44f406 stable. commit 3069ff1930aa71e125874c780ffaa6caeda5800a upstream. The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor. [1] Describe this supply. [1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.4, p.19 Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") Signed-off-by: FUKAUMI Naoki Link: https://patch.msgid.link/20251112035133.28753-3-naoki@radxa.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts index f60243e2b3c3..cd8bd50b3577 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts @@ -189,6 +189,7 @@ eeprom: eeprom@50 { compatible = "belling,bl24c16a", "atmel,24c16"; reg = <0x50>; pagesize = <16>; + vcc-supply = <&vcc_3v3_pmu>; }; }; @@ -518,7 +519,7 @@ regulator-state-mem { }; }; - vcc_3v3_s3: dcdc-reg8 { + vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 { regulator-name = "vcc_3v3_s3"; regulator-always-on; regulator-boot-on; -- Gitee From 2ef1a32ad2c9f4357c1b1bcd6ba1019857cd94e1 Mon Sep 17 00:00:00 2001 From: Rene Rebe Date: Fri, 14 Nov 2025 22:30:33 +0800 Subject: [PATCH 0328/1449] ps3disk: use memcpy_{from,to}_bvec index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit bf8f8528b7621c493c60113e7e3929783e3df157 stable. commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db upstream. With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting ps3disk to new bvec helpers, incrementing the offset was accidently lost, corrupting consecutive buffers. Restore index for non-corrupted data transfers. Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) Signed-off-by: René Rebe Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/ps3disk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 36d7b36c60c7..79d3779e1c7a 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, struct bio_vec bvec; rq_for_each_segment(bvec, req, iter) { + dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", + __func__, __LINE__, bio_sectors(iter.bio), + iter.bio->bi_iter.bi_sector); if (gather) memcpy_from_bvec(dev->bounce_buf + offset, &bvec); else memcpy_to_bvec(&bvec, dev->bounce_buf + offset); + offset += bvec.bv_len; } } -- Gitee From 98bbfc66339d328da7003939b27c13f4eab7b68f Mon Sep 17 00:00:00 2001 From: Menglong Dong Date: Mon, 10 Nov 2025 20:07:05 +0800 Subject: [PATCH 0329/1449] bpf: Handle return value of ftrace_set_filter_ip in register_fentry ANBZ: #35228 commit edcb09848a322247f5797d65ad3b763dd42e84d1 stable. commit fea3f5e83c5cd80a76d97343023a2f2e6bd862bf upstream. The error that returned by ftrace_set_filter_ip() in register_fentry() is not handled properly. Just fix it. Fixes: 00963a2e75a8 ("bpf: Support bpf_trampoline on functions with IPMODIFY (e.g. livepatch)") Signed-off-by: Menglong Dong Acked-by: Song Liu Link: https://lore.kernel.org/r/20251110120705.1553694-1-dongml2@chinatelecom.cn Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/bpf/trampoline.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 521a32636d75..a8ed4cbfc868 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -216,7 +216,9 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr) } if (tr->func.ftrace_managed) { - ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); + ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); + if (ret) + return ret; ret = register_ftrace_direct(tr->fops, (long)new_addr); } else { ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr); -- Gitee From 2d147cdc5b2a3fd50fbefc62b578e530bff391e1 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Fri, 14 Nov 2025 01:11:53 +0800 Subject: [PATCH 0330/1449] selftests/bpf: Fix failure paths in send_signal test ANBZ: #35228 commit 67d295d202e2b2e630a5f2cd1943e079013a7515 stable. commit c13339039891dbdfa6c1972f0483bd07f610b776 upstream. When test_send_signal_kern__open_and_load() fails parent closes the pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child continues and enters infinite loop, while parent is stuck in wait(NULL). Other error paths have similar issue, so kill the child before waiting on it. The bug was discovered while compiling all of selftests with -O1 instead of -O2 which caused progs/test_send_signal_kern.c to fail to load. Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") Signed-off-by: Alexei Starovoitov Signed-off-by: Andrii Nakryiko Acked-by: Eduard Zingerman Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 9adcda7f1fed..61c903500014 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -145,6 +145,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, skel_open_load_failure: close(pipe_c2p[0]); close(pipe_p2c[1]); + /* + * Child is either about to exit cleanly or stuck in case of errors. + * Nudge it to exit. + */ + kill(pid, SIGKILL); wait(NULL); } -- Gitee From ccab0e343f31d6d4c13688ec1f6fa25fe31cb7b8 Mon Sep 17 00:00:00 2001 From: Martin KaFai Lau Date: Thu, 13 Nov 2025 07:23:30 +0800 Subject: [PATCH 0331/1449] bpf: Check skb->transport_header is set in bpf_skb_check_mtu ANBZ: #35228 commit 97b876fa88322625228792cf7a5fd77531815a80 stable. commit d946f3c98328171fa50ddb908593cf833587f725 upstream. The bpf_skb_check_mtu helper needs to use skb->transport_header when the BPF_MTU_CHK_SEGS flag is used: bpf_skb_check_mtu(skb, ifindex, &mtu_len, 0, BPF_MTU_CHK_SEGS) The transport_header is not always set. There is a WARN_ON_ONCE report when CONFIG_DEBUG_NET is enabled + skb->gso_size is set + bpf_prog_test_run is used: WARNING: CPU: 1 PID: 2216 at ./include/linux/skbuff.h:3071 skb_gso_validate_network_len bpf_skb_check_mtu bpf_prog_3920e25740a41171_tc_chk_segs_flag # A test in the next patch bpf_test_run bpf_prog_test_run_skb For a normal ingress skb (not test_run), skb_reset_transport_header is performed but there is plan to avoid setting it as described in commit 2170a1f09148 ("net: no longer reset transport_header in __netif_receive_skb_core()"). This patch fixes the bpf helper by checking skb_transport_header_was_set(). The check is done just before skb->transport_header is used, to avoid breaking the existing bpf prog. The WARN_ON_ONCE is limited to bpf_prog_test_run, so targeting bpf-next. Fixes: 34b2021cc616 ("bpf: Add BPF-helper for MTU checking") Cc: Jesper Dangaard Brouer Reported-by: Kaiyan Mei Reported-by: Yinhao Hu Signed-off-by: Martin KaFai Lau Link: https://lore.kernel.org/r/20251112232331.1566074-1-martin.lau@linux.dev Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/filter.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 23ae2052fd40..f68f91ab9a1f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6295,9 +6295,12 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, */ if (skb_is_gso(skb)) { ret = BPF_MTU_CHK_RET_SUCCESS; - if (flags & BPF_MTU_CHK_SEGS && - !skb_gso_validate_network_len(skb, mtu)) - ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; + if (flags & BPF_MTU_CHK_SEGS) { + if (!skb_transport_header_was_set(skb)) + return -EINVAL; + if (!skb_gso_validate_network_len(skb, mtu)) + ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; + } } out: *mtu_len = mtu; -- Gitee From 216de3b0a35ee3b0b1f9a72147789b2b97a47137 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Thu, 13 Nov 2025 10:30:32 +0800 Subject: [PATCH 0332/1449] watchdog: wdat_wdt: Fix ACPI table leak in probe function ANBZ: #35228 commit 0592410b31f11f97fb525aa957bbece9abb6fc6d stable. commit 25c0b472eab8379683d4eef681185c104bed8ffd upstream. wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but never calls acpi_put_table() on any paths. This causes a permanent ACPI table memory leak. Add a single cleanup path which calls acpi_put_table() to ensure the ACPI table is always released. Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") Suggested-by: Guenter Roeck Signed-off-by: Haotian Zhang Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c index 0ba99bed59fc..02fbe05c37a0 100644 --- a/drivers/watchdog/wdat_wdt.c +++ b/drivers/watchdog/wdat_wdt.c @@ -326,19 +326,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) return -ENODEV; wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); - if (!wdat) - return -ENOMEM; + if (!wdat) { + ret = -ENOMEM; + goto out_put_table; + } regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), GFP_KERNEL); - if (!regs) - return -ENOMEM; + if (!regs) { + ret = -ENOMEM; + goto out_put_table; + } /* WDAT specification wants to have >= 1ms period */ - if (tbl->timer_period < 1) - return -EINVAL; - if (tbl->min_count > tbl->max_count) - return -EINVAL; + if (tbl->timer_period < 1) { + ret = -EINVAL; + goto out_put_table; + } + if (tbl->min_count > tbl->max_count) { + ret = -EINVAL; + goto out_put_table; + } wdat->period = tbl->timer_period; wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000); @@ -355,15 +363,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) res = &pdev->resource[i]; if (resource_type(res) == IORESOURCE_MEM) { reg = devm_ioremap_resource(dev, res); - if (IS_ERR(reg)) - return PTR_ERR(reg); + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + goto out_put_table; + } } else if (resource_type(res) == IORESOURCE_IO) { reg = devm_ioport_map(dev, res->start, 1); - if (!reg) - return -ENOMEM; + if (!reg) { + ret = -ENOMEM; + goto out_put_table; + } } else { dev_err(dev, "Unsupported resource\n"); - return -EINVAL; + ret = -EINVAL; + goto out_put_table; } regs[i] = reg; @@ -385,8 +398,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) } instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); - if (!instr) - return -ENOMEM; + if (!instr) { + ret = -ENOMEM; + goto out_put_table; + } INIT_LIST_HEAD(&instr->node); instr->entry = entries[i]; @@ -417,7 +432,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) if (!instr->reg) { dev_err(dev, "I/O resource not found\n"); - return -EINVAL; + ret = -EINVAL; + goto out_put_table; } instructions = wdat->instructions[action]; @@ -425,8 +441,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) instructions = devm_kzalloc(dev, sizeof(*instructions), GFP_KERNEL); - if (!instructions) - return -ENOMEM; + if (!instructions) { + ret = -ENOMEM; + goto out_put_table; + } INIT_LIST_HEAD(instructions); wdat->instructions[action] = instructions; @@ -443,7 +461,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) ret = wdat_wdt_enable_reboot(wdat); if (ret) - return ret; + goto out_put_table; platform_set_drvdata(pdev, wdat); @@ -460,12 +478,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); if (ret) - return ret; + goto out_put_table; watchdog_set_nowayout(&wdat->wdd, nowayout); watchdog_stop_on_reboot(&wdat->wdd); watchdog_stop_on_unregister(&wdat->wdd); - return devm_watchdog_register_device(dev, &wdat->wdd); + ret = devm_watchdog_register_device(dev, &wdat->wdd); + +out_put_table: + acpi_put_table((struct acpi_table_header *)tbl); + return ret; } static int wdat_wdt_suspend_noirq(struct device *dev) -- Gitee From 28903652dc0672190e9604a84d74f90df4020150 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 5 Nov 2025 16:42:20 +0800 Subject: [PATCH 0333/1449] watchdog: starfive: Fix resource leak in probe error path ANBZ: #35228 commit 74f25cec6e260983ebba647f9f8a9f561df3d865 stable. commit 5bcc5786a0cfa9249ccbe539833040a6285d0de3 upstream. If pm_runtime_put_sync() fails after watchdog_register_device() succeeds, the probe function jumps to err_exit without unregistering the watchdog device. This leaves the watchdog registered in the subsystem while the driver fails to load, resulting in a resource leak. Add a new error label err_unregister_wdt to properly unregister the watchdog device. Fixes: 8bc22a2f1bf0 ("watchdog: starfive: Check pm_runtime_enabled() before decrementing usage counter") Signed-off-by: Haotian Zhang Reviewed-by: Wim Van Sebroeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/watchdog/starfive-wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index e4b344db3803..0606142ffc5e 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -498,12 +498,14 @@ static int starfive_wdt_probe(struct platform_device *pdev) if (pm_runtime_enabled(&pdev->dev)) { ret = pm_runtime_put_sync(&pdev->dev); if (ret) - goto err_exit; + goto err_unregister_wdt; } } return 0; +err_unregister_wdt: + watchdog_unregister_device(&wdt->wdd); err_exit: starfive_wdt_disable_clock(wdt); pm_runtime_disable(&pdev->dev); -- Gitee From 7092ee5e582062f9fd76058a72e14f22840f2fb8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Oct 2025 06:13:48 +0800 Subject: [PATCH 0334/1449] tracefs: fix a leak in eventfs_create_events_dir() ANBZ: #35228 commit 07a0310292011a1dde9ad93250203783b6b58b70 stable. commit 798a401660a151633cb171738a72a8f1efb9b0b4 upstream. If we have LOCKDOWN_TRACEFS, the function bails out - *after* having locked the parent directory and without bothering to undo that. Just check it before tracefs_start_creating()... Fixes: e24709454c45 "tracefs/eventfs: Add missing lockdown checks" Acked-by: Steven Rostedt (Google) Signed-off-by: Al Viro Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/tracefs/event_inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 73a08db3b7a8..4190e6155044 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -827,7 +827,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry const struct eventfs_entry *entries, int size, void *data) { - struct dentry *dentry = tracefs_start_creating(name, parent); + struct dentry *dentry; struct eventfs_root_inode *rei; struct eventfs_inode *ei; struct tracefs_inode *ti; @@ -838,6 +838,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry if (security_locked_down(LOCKDOWN_TRACEFS)) return NULL; + dentry = tracefs_start_creating(name, parent); if (IS_ERR(dentry)) return ERR_CAST(dentry); -- Gitee From b9fc51d9b24e601bf2c24e6db1c291d2e63e1fe8 Mon Sep 17 00:00:00 2001 From: Sergey Bashirov Date: Fri, 3 Oct 2025 17:11:03 +0800 Subject: [PATCH 0335/1449] NFSD/blocklayout: Fix minlength check in proc_layoutget ANBZ: #35228 commit 9f7ab3fbadf300462a72c1301525c90fa04fa20f stable. commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 upstream. The extent returned by the file system may have a smaller offset than the segment offset requested by the client. In this case, the minimum segment length must be checked against the requested range. Otherwise, the client may not be able to continue the read/write operation. Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/blocklayout.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 59f119cce3dc..3a9415fd7754 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, { struct nfsd4_layout_seg *seg = &args->lg_seg; struct super_block *sb = inode->i_sb; + u64 length; u32 block_size = i_blocksize(inode); struct pnfs_block_extent *bex; struct iomap iomap; @@ -53,7 +54,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, goto out_error; } - if (iomap.length < args->lg_minlength) { + length = iomap.offset + iomap.length - seg->offset; + if (length < args->lg_minlength) { dprintk("pnfsd: extent smaller than minlength\n"); goto out_layoutunavailable; } -- Gitee From 99841489efb18846034248e383eb3dedeba19886 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 14 Nov 2025 04:40:50 +0800 Subject: [PATCH 0336/1449] drm/msm/a2xx: stop over-complaining about the legacy firmware ANBZ: #35228 commit 5ed033c5413393876a02f86205c5588abb42d9af stable. commit a3a22373fce576560757f5616eb48dbf85891d9c upstream. If the rootfs have a legacy A200 firmware, currently the driver will complain each time the hw is reinited (which can happen a lot). E.g. with GL testsuite the hw is reinited after each test, spamming the console. Make sure that the message is printed only once: when we detect the firmware that doesn't support protection. Fixes: 302295070d3c ("drm/msm/a2xx: support loading legacy (iMX) firmware") Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/688098/ Signed-off-by: Rob Clark Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 0d8133f3174b..535c89ce5d62 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -234,7 +234,7 @@ static int a2xx_hw_init(struct msm_gpu *gpu) * word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225). * Older firmware files, which lack protection support, have 0 instead. */ - if (ptr[1] == 0) { + if (ptr[1] == 0 && !a2xx_gpu->protection_disabled) { dev_warn(gpu->dev->dev, "Legacy firmware detected, disabling protection support\n"); a2xx_gpu->protection_disabled = true; -- Gitee From b3e7a9ef5125452ef00dd564d57e78263be3dbcb Mon Sep 17 00:00:00 2001 From: Abdun Nihaal Date: Fri, 14 Nov 2025 17:45:26 +0800 Subject: [PATCH 0337/1449] wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() ANBZ: #35228 commit bf8513dfa31ea015c9cf415796dca2113d293840 stable. commit 9b5b9c042b30befc5b37e4539ace95af70843473 upstream. In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA allocations in a loop. When an allocation fails, the previously successful allocations are not freed on exit. Fix that by jumping to err_free_rings label on error, which calls rtl8180_free_rx_ring() to free the allocations. Remove the free of rx_ring in rtl8180_init_rx_ring() error path, and set the freed priv->rx_buf entry to null, to avoid double free. Fixes: f653211197f3 ("Add rtl8180 wireless driver") Signed-off-by: Abdun Nihaal Reviewed-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c index f6c25a52b69a..fa8d8e216bd0 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c @@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) dma_addr_t *mapping; entry = priv->rx_ring + priv->rx_ring_sz*i; if (!skb) { - dma_free_coherent(&priv->pdev->dev, - priv->rx_ring_sz * 32, - priv->rx_ring, priv->rx_ring_dma); wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); return -ENOMEM; } @@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) if (dma_mapping_error(&priv->pdev->dev, *mapping)) { kfree_skb(skb); - dma_free_coherent(&priv->pdev->dev, - priv->rx_ring_sz * 32, - priv->rx_ring, priv->rx_ring_dma); + priv->rx_buf[i] = NULL; wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); return -ENOMEM; } @@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) ret = rtl8180_init_rx_ring(dev); if (ret) - return ret; + goto err_free_rings; for (i = 0; i < (dev->queues + 1); i++) if ((ret = rtl8180_init_tx_ring(dev, i, 16))) -- Gitee From a775f73618c2ba18bee03234fa5e7556c018d63d Mon Sep 17 00:00:00 2001 From: Jose Fernandez Date: Tue, 2 Apr 2024 11:40:10 +0800 Subject: [PATCH 0338/1449] bpf: Improve program stats run-time calculation ANBZ: #35228 commit c8201d1353c507e8ebb6e2db736d721b3295361d stable. commit ce09cbdd988887662546a1175bcfdfc6c8fdd150 upstream. This patch improves the run-time calculation for program stats by capturing the duration as soon as possible after the program returns. Previously, the duration included u64_stats_t operations. While the instrumentation overhead is part of the total time spent when stats are enabled, distinguishing between the program's native execution time and the time spent due to instrumentation is crucial for accurate performance analysis. By making this change, the patch facilitates more precise optimization of BPF programs, enabling users to understand their performance in environments without stats enabled. I used a virtualized environment to measure the run-time over one minute for a basic raw_tracepoint/sys_enter program, which just increments a local counter. Although the virtualization introduced some performance degradation that could affect the results, I observed approximately a 16% decrease in average run-time reported by stats with this change (310 -> 260 nsec). Signed-off-by: Jose Fernandez Signed-off-by: Daniel Borkmann Acked-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20240402034010.25060-1-josef@netflix.com Stable-dep-of: 7dc211c1159d ("bpf: Fix invalid prog->stats access when update_effective_progs fails") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/filter.h | 6 ++++-- kernel/bpf/trampoline.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 896554f3c416..d1ed58a631b7 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -602,14 +602,16 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, cant_migrate(); if (static_branch_unlikely(&bpf_stats_enabled_key)) { struct bpf_prog_stats *stats; - u64 start = sched_clock(); + u64 duration, start = sched_clock(); unsigned long flags; ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + + duration = sched_clock() - start; stats = this_cpu_ptr(prog->stats); flags = u64_stats_update_begin_irqsave(&stats->syncp); u64_stats_inc(&stats->cnt); - u64_stats_add(&stats->nsecs, sched_clock() - start); + u64_stats_add(&stats->nsecs, duration); u64_stats_update_end_irqrestore(&stats->syncp, flags); } else { ret = dfunc(ctx, prog->insnsi, prog->bpf_func); diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index a8ed4cbfc868..0e41ec662f75 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -870,12 +870,13 @@ static void notrace update_prog_stats(struct bpf_prog *prog, * Hence check that 'start' is valid. */ start > NO_START_TIME) { + u64 duration = sched_clock() - start; unsigned long flags; stats = this_cpu_ptr(prog->stats); flags = u64_stats_update_begin_irqsave(&stats->syncp); u64_stats_inc(&stats->cnt); - u64_stats_add(&stats->nsecs, sched_clock() - start); + u64_stats_add(&stats->nsecs, duration); u64_stats_update_end_irqrestore(&stats->syncp, flags); } } -- Gitee From 99f0746042a72a67f0353db430b608e7a846bb03 Mon Sep 17 00:00:00 2001 From: Pu Lehui Date: Sat, 15 Nov 2025 18:23:43 +0800 Subject: [PATCH 0339/1449] bpf: Fix invalid prog->stats access when update_effective_progs fails ANBZ: #35228 commit bf2c990b012100610c0f1ec5c4ea434da2d080c2 stable. commit 7dc211c1159d991db609bdf4b0fb9033c04adcbc upstream. Syzkaller triggers an invalid memory access issue following fault injection in update_effective_progs. The issue can be described as follows: __cgroup_bpf_detach update_effective_progs compute_effective_progs bpf_prog_array_alloc <-- fault inject purge_effective_progs /* change to dummy_bpf_prog */ array->items[index] = &dummy_bpf_prog.prog ---softirq start--- __do_softirq ... __cgroup_bpf_run_filter_skb __bpf_prog_run_save_cb bpf_prog_run stats = this_cpu_ptr(prog->stats) /* invalid memory access */ flags = u64_stats_update_begin_irqsave(&stats->syncp) ---softirq end--- static_branch_dec(&cgroup_bpf_enabled_key[atype]) The reason is that fault injection caused update_effective_progs to fail and then changed the original prog into dummy_bpf_prog.prog in purge_effective_progs. Then a softirq came, and accessing the members of dummy_bpf_prog.prog in the softirq triggers invalid mem access. To fix it, skip updating stats when stats is NULL. Fixes: 492ecee892c2 ("bpf: enable program stats") Signed-off-by: Pu Lehui Link: https://lore.kernel.org/r/20251115102343.2200727-1-pulehui@huaweicloud.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/filter.h | 12 +++++++----- kernel/bpf/syscall.c | 3 +++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index d1ed58a631b7..af6a89b76c8f 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -608,11 +608,13 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, ret = dfunc(ctx, prog->insnsi, prog->bpf_func); duration = sched_clock() - start; - stats = this_cpu_ptr(prog->stats); - flags = u64_stats_update_begin_irqsave(&stats->syncp); - u64_stats_inc(&stats->cnt); - u64_stats_add(&stats->nsecs, duration); - u64_stats_update_end_irqrestore(&stats->syncp, flags); + if (likely(prog->stats)) { + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); + u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } } else { ret = dfunc(ctx, prog->insnsi, prog->bpf_func); } diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 34459d36181b..0154968c9f68 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2226,6 +2226,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) struct bpf_prog_stats *stats; unsigned int flags; + if (unlikely(!prog->stats)) + return; + stats = this_cpu_ptr(prog->stats); flags = u64_stats_update_begin_irqsave(&stats->syncp); u64_stats_inc(&stats->misses); -- Gitee From bc11232ba1e52f738a6d9733c43cc95675becabd Mon Sep 17 00:00:00 2001 From: "Ritesh Harjani (IBM)" Date: Thu, 30 Oct 2025 22:57:27 +0800 Subject: [PATCH 0340/1449] powerpc/64s/hash: Restrict stress_hpt_struct memblock region to within RMA limit ANBZ: #35228 commit e95d7d5821f636925dd9a1b088e8afff9b915964 stable. commit 17b45ccf09882e0c808ad2cf62acdc90ad968746 upstream. When HV=0 & IR/DR=0, the Hash MMU is said to be in Virtual Real Addressing Mode during early boot. During this, we should ensure that memory region allocations for stress_hpt_struct should happen from within RMA region as otherwise the boot might get stuck while doing memset of this region. History behind why do we have RMA region limitation is better explained in these 2 patches [1] & [2]. This patch ensures that memset to stress_hpt_struct during early boot does not cross ppc64_rma_size boundary. [1]: https://lore.kernel.org/all/20190710052018.14628-1-sjitindarsingh@gmail.com/ [2]: https://lore.kernel.org/all/87wp54usvj.fsf@linux.vnet.ibm.com/ Fixes: 6b34a099faa12 ("powerpc/64s/hash: add stress_hpt kernel boot option to increase hash faults") Signed-off-by: Ritesh Harjani (IBM) Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/ada1173933ea7617a994d6ee3e54ced8797339fc.1761834163.git.ritesh.list@gmail.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/mm/book3s64/hash_utils.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index ad2afa08e62e..4f09d295e518 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -1032,11 +1032,14 @@ static void __init htab_initialize(void) unsigned long table; unsigned long pteg_count; unsigned long prot; - phys_addr_t base = 0, size = 0, end; + phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; u64 i; DBG(" -> htab_initialize()\n"); + if (firmware_has_feature(FW_FEATURE_LPAR)) + limit = ppc64_rma_size; + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { mmu_kernel_ssize = MMU_SEGSIZE_1T; mmu_highuser_ssize = MMU_SEGSIZE_1T; @@ -1052,7 +1055,7 @@ static void __init htab_initialize(void) // Too early to use nr_cpu_ids, so use NR_CPUS tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, __alignof__(struct stress_hpt_struct), - 0, MEMBLOCK_ALLOC_ANYWHERE); + MEMBLOCK_LOW_LIMIT, limit); memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); stress_hpt_struct = __va(tmp); @@ -1086,7 +1089,6 @@ static void __init htab_initialize(void) mmu_hash_ops.hpte_clear_all(); #endif } else { - unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; #ifdef CONFIG_PPC_CELL /* @@ -1102,7 +1104,7 @@ static void __init htab_initialize(void) table = memblock_phys_alloc_range(htab_size_bytes, htab_size_bytes, - 0, limit); + MEMBLOCK_LOW_LIMIT, limit); if (!table) panic("ERROR: Failed to allocate %pa bytes below %pa\n", &htab_size_bytes, &limit); -- Gitee From c9af0c076da54629b8ec033bea3f4f09eb5666cd Mon Sep 17 00:00:00 2001 From: "Ritesh Harjani (IBM)" Date: Thu, 30 Oct 2025 22:57:28 +0800 Subject: [PATCH 0341/1449] powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE format ANBZ: #35228 commit 800153219f0443ee2d5bb96afd93deb32caec537 stable. commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 upstream. HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping kernel hash page tables, nothing gets printed on powernv P9+. This patch utilizes the helpers added in the patch tagged as fixes, to convert new format to old format and dump the hptes. This fix is only needed for native_find() (powernv), since pseries continues to work fine with the old format. Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") Signed-off-by: Ritesh Harjani (IBM) Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c index 9a601587836b..ee5e1dfe7932 100644 --- a/arch/powerpc/mm/ptdump/hashpagetable.c +++ b/arch/powerpc/mm/ptdump/hashpagetable.c @@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 vpn = hpt_vpn(ea, vsid, ssize); hash = hpt_hash(vpn, shift, ssize); want_v = hpte_encode_avpn(vpn, psize, ssize); + if (cpu_has_feature(CPU_FTR_ARCH_300)) + want_v = hpte_old_to_new_v(want_v); /* to check in the secondary hash table, we invert the hash */ if (!primary) @@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 /* HPTE matches */ *v = be64_to_cpu(hptep->v); *r = be64_to_cpu(hptep->r); + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + *v = hpte_new_to_old_v(*v, *r); + *r = hpte_new_to_old_r(*r); + } return 0; } ++hpte_group; -- Gitee From 8388e35f7ca47b502e33ce11076239dbf09674dc Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Tue, 11 Nov 2025 19:13:56 +0800 Subject: [PATCH 0342/1449] fs/ntfs3: out1 also needs to put mi ANBZ: #35228 commit ba125e8f8d113def65327b6dea05c164b09c463c stable. commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 upstream. After ntfs_look_free_mft() executes successfully, all subsequent code that fails to execute must put mi. Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") Signed-off-by: Edward Adam Davis Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/frecord.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index 5c45fec832b0..6ff10042a15f 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -1067,9 +1067,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, out2: ni_remove_mi(ni, mi); - mi_put(mi); out1: + mi_put(mi); ntfs_mark_rec_free(sbi, rno, is_mft); out: -- Gitee From 18c02586dbbf0d295c3be08eeab583189a9e80e0 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Tue, 11 Nov 2025 19:05:42 +0800 Subject: [PATCH 0343/1449] fs/ntfs3: Prevent memory leaks in add sub record ANBZ: #35228 commit 9068cfff4caba1f75f94ac46d45325ded9f913dc stable. commit ccc4e86d1c24260c18ae94541198c3711c140da6 upstream. If a rb node with the same ino already exists in the rb tree, the newly alloced mft_inode in ni_add_subrecord() will not have its memory cleaned up, which leads to the memory leak issue reported by syzbot. The best option to avoid this issue is to put the newly alloced mft node when a rb node with the same ino already exists in the rb tree and return the rb node found in the rb tree to the parent layer. syzbot reported: BUG: memory leak unreferenced object 0xffff888110bef280 (size 128): backtrace (crc 126a088f): ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 BUG: memory leak unreferenced object 0xffff888109093400 (size 1024): backtrace (crc 7197c55e): mi_init+0x2b/0x50 fs/ntfs3/record.c:105 mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/frecord.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index 6ff10042a15f..18e41faef8e6 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -378,8 +378,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) mi_get_ref(&ni->mi, &m->mrec->parent_ref); - ni_add_mi(ni, m); - *mi = m; + *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); + if (*mi != m) + mi_put(m); + return true; } -- Gitee From 2c1d74ca967fd9a4b03f3c0f38febe24cdf60baa Mon Sep 17 00:00:00 2001 From: Jay Liu Date: Sun, 21 Sep 2025 13:53:05 +0800 Subject: [PATCH 0344/1449] drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue ANBZ: #35228 commit d258ebe7059ac419528705addafa96fcb645f876 stable. commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 upstream. if matrixbit is 11, The range of color matrix is from 0 to (BIT(12) - 1). Values from 0 to (BIT(11) - 1) represent positive numbers, values from BIT(11) to (BIT(12) - 1) represent negative numbers. For example, -1 need converted to 8191. so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, and set int_bits to 2. Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Jay Liu Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c index 4234ff7485e8..2126cb95ae92 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c @@ -80,27 +80,6 @@ void mtk_ccorr_stop(struct device *dev) writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); } -/* Converts a DRM S31.32 value to the HW S1.n format. */ -static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) -{ - u16 r; - - /* Sign bit. */ - r = in & BIT_ULL(63) ? BIT(n + 1) : 0; - - if ((in & GENMASK_ULL(62, 33)) > 0) { - /* identity value 0x100000000 -> 0x400(mt8183), */ - /* identity value 0x100000000 -> 0x800(mt8192), */ - /* if bigger this, set it to max 0x7ff. */ - r |= GENMASK(n, 0); - } else { - /* take the n+1 most important bits. */ - r |= (in >> (32 - n)) & GENMASK(n, 0); - } - - return r; -} - void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) { struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); @@ -119,7 +98,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) input = ctm->matrix; for (i = 0; i < ARRAY_SIZE(coeffs); i++) - coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); + coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); -- Gitee From 179c19198c37872154d036d4356f497cc2b81852 Mon Sep 17 00:00:00 2001 From: Kui-Feng Lee Date: Fri, 9 Feb 2024 06:06:51 +0800 Subject: [PATCH 0345/1449] net/ipv6: Remove expired routes with a separated list of routes. ANBZ: #35228 commit bd12abe294c7738421bdfbc486f1909d02db30e9 stable. commit 5eb902b8e7193cdcb33242af0a56502e6b5206e9 upstream. FIB6 GC walks trees of fib6_tables to remove expired routes. Walking a tree can be expensive if the number of routes in a table is big, even if most of them are permanent. Checking routes in a separated list of routes having expiration will avoid this potential issue. Reviewed-by: David Ahern Signed-off-by: Kui-Feng Lee Signed-off-by: David S. Miller Stable-dep-of: f72514b3c569 ("ipv6: clear RA flags when adding a static route") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/ip6_fib.h | 46 ++++++++++++++++++++++++++++++++- net/ipv6/addrconf.c | 41 ++++++++++++++++++++++++----- net/ipv6/ip6_fib.c | 60 +++++++++++++++++++++++++++++++++++++++---- net/ipv6/ndisc.c | 10 +++++++- net/ipv6/route.c | 13 ++++++++-- 5 files changed, 154 insertions(+), 16 deletions(-) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index e2e9c7109efb..888fa6b85434 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -181,6 +181,9 @@ struct fib6_info { refcount_t fib6_ref; unsigned long expires; + + struct hlist_node gc_link; + struct dst_metrics *fib6_metrics; #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] @@ -256,12 +259,18 @@ static inline bool fib6_requires_src(const struct fib6_info *rt) return rt->fib6_src.plen > 0; } +/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever + * been added to a table before. + */ static inline void fib6_clean_expires(struct fib6_info *f6i) { f6i->fib6_flags &= ~RTF_EXPIRES; f6i->expires = 0; } +/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever + * been added to a table before. + */ static inline void fib6_set_expires(struct fib6_info *f6i, unsigned long expires) { @@ -342,8 +351,10 @@ static inline bool fib6_info_hold_safe(struct fib6_info *f6i) static inline void fib6_info_release(struct fib6_info *f6i) { - if (f6i && refcount_dec_and_test(&f6i->fib6_ref)) + if (f6i && refcount_dec_and_test(&f6i->fib6_ref)) { + DEBUG_NET_WARN_ON_ONCE(!hlist_unhashed(&f6i->gc_link)); call_rcu(&f6i->rcu, fib6_info_destroy_rcu); + } } enum fib6_walk_state { @@ -397,6 +408,7 @@ struct fib6_table { struct inet_peer_base tb6_peers; unsigned int flags; unsigned int fib_seq; + struct hlist_head tb6_gc_hlist; /* GC candidates */ #define RT6_TABLE_HAS_DFLT_ROUTER BIT(0) }; @@ -513,6 +525,38 @@ void fib6_gc_cleanup(void); int fib6_init(void); +/* Add the route to the gc list if it is not already there + * + * The callers should hold f6i->fib6_table->tb6_lock. + */ +static inline void fib6_add_gc_list(struct fib6_info *f6i) +{ + /* If fib6_node is null, the f6i is not in (or removed from) the + * table. + * + * There is a gap between finding the f6i from the table and + * calling this function without the protection of the tb6_lock. + * This check makes sure the f6i is not added to the gc list when + * it is not on the table. + */ + if (!rcu_dereference_protected(f6i->fib6_node, + lockdep_is_held(&f6i->fib6_table->tb6_lock))) + return; + + if (hlist_unhashed(&f6i->gc_link)) + hlist_add_head(&f6i->gc_link, &f6i->fib6_table->tb6_gc_hlist); +} + +/* Remove the route from the gc list if it is on the list. + * + * The callers should hold f6i->fib6_table->tb6_lock. + */ +static inline void fib6_remove_gc_list(struct fib6_info *f6i) +{ + if (!hlist_unhashed(&f6i->gc_link)) + hlist_del_init(&f6i->gc_link); +} + struct ipv6_route_iter { struct seq_net_private p; struct fib6_walker w; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 0e49ee83533b..b606d77fe7fc 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1268,6 +1268,7 @@ static void cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_rt, bool del_peer) { + struct fib6_table *table; struct fib6_info *f6i; f6i = addrconf_get_prefix_route(del_peer ? &ifp->peer_addr : &ifp->addr, @@ -1277,8 +1278,15 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, if (del_rt) ip6_del_rt(dev_net(ifp->idev->dev), f6i, false); else { - if (!(f6i->fib6_flags & RTF_EXPIRES)) + if (!(f6i->fib6_flags & RTF_EXPIRES)) { + table = f6i->fib6_table; + spin_lock_bh(&table->tb6_lock); + fib6_set_expires(f6i, expires); + fib6_add_gc_list(f6i); + + spin_unlock_bh(&table->tb6_lock); + } fib6_info_release(f6i); } } @@ -2736,6 +2744,7 @@ EXPORT_SYMBOL_GPL(addrconf_prefix_rcv_add_addr); void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) { struct prefix_info *pinfo; + struct fib6_table *table; __u32 valid_lft; __u32 prefered_lft; int addr_type, err; @@ -2812,11 +2821,20 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) if (valid_lft == 0) { ip6_del_rt(net, rt, false); rt = NULL; - } else if (addrconf_finite_timeout(rt_expires)) { - /* not infinity */ - fib6_set_expires(rt, jiffies + rt_expires); } else { - fib6_clean_expires(rt); + table = rt->fib6_table; + spin_lock_bh(&table->tb6_lock); + + if (addrconf_finite_timeout(rt_expires)) { + /* not infinity */ + fib6_set_expires(rt, jiffies + rt_expires); + fib6_add_gc_list(rt); + } else { + fib6_clean_expires(rt); + fib6_remove_gc_list(rt); + } + + spin_unlock_bh(&table->tb6_lock); } } else if (valid_lft) { clock_t expires = 0; @@ -4770,6 +4788,7 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, u32 flags, bool modify_peer) { + struct fib6_table *table; struct fib6_info *f6i; u32 prio; @@ -4790,10 +4809,18 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, ifp->rt_priority, ifp->idev->dev, expires, flags, GFP_KERNEL); } else { - if (!expires) + table = f6i->fib6_table; + spin_lock_bh(&table->tb6_lock); + + if (!expires) { fib6_clean_expires(f6i); - else + fib6_remove_gc_list(f6i); + } else { fib6_set_expires(f6i, expires); + fib6_add_gc_list(f6i); + } + + spin_unlock_bh(&table->tb6_lock); fib6_info_release(f6i); } diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index c44136cbbaa1..ab84e2dd682f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -160,6 +160,8 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh) INIT_LIST_HEAD(&f6i->fib6_siblings); refcount_set(&f6i->fib6_ref, 1); + INIT_HLIST_NODE(&f6i->gc_link); + return f6i; } @@ -246,6 +248,7 @@ static struct fib6_table *fib6_alloc_table(struct net *net, u32 id) net->ipv6.fib6_null_entry); table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; inet_peer_base_init(&table->tb6_peers); + INIT_HLIST_HEAD(&table->tb6_gc_hlist); } return table; @@ -1063,6 +1066,9 @@ static void fib6_purge_rt(struct fib6_info *rt, struct fib6_node *fn, lockdep_is_held(&table->tb6_lock)); } } + + fib6_clean_expires(rt); + fib6_remove_gc_list(rt); } /* @@ -1123,10 +1129,13 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, WRITE_ONCE(rt->fib6_nsiblings, 0); if (!(iter->fib6_flags & RTF_EXPIRES)) return -EEXIST; - if (!(rt->fib6_flags & RTF_EXPIRES)) + if (!(rt->fib6_flags & RTF_EXPIRES)) { fib6_clean_expires(iter); - else + fib6_remove_gc_list(iter); + } else { fib6_set_expires(iter, rt->expires); + fib6_add_gc_list(iter); + } if (rt->fib6_pmtu) fib6_metric_set(iter, RTAX_MTU, @@ -1491,6 +1500,10 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt, if (rt->nh) list_add(&rt->nh_list, &rt->nh->f6i_list); __fib6_update_sernum_upto_root(rt, fib6_new_sernum(info->nl_net)); + + if (rt->fib6_flags & RTF_EXPIRES) + fib6_add_gc_list(rt); + fib6_start_gc(info->nl_net, rt); } @@ -2294,9 +2307,8 @@ static void fib6_flush_trees(struct net *net) * Garbage collection */ -static int fib6_age(struct fib6_info *rt, void *arg) +static int fib6_age(struct fib6_info *rt, struct fib6_gc_args *gc_args) { - struct fib6_gc_args *gc_args = arg; unsigned long now = jiffies; /* @@ -2321,6 +2333,42 @@ static int fib6_age(struct fib6_info *rt, void *arg) return 0; } +static void fib6_gc_table(struct net *net, + struct fib6_table *tb6, + struct fib6_gc_args *gc_args) +{ + struct fib6_info *rt; + struct hlist_node *n; + struct nl_info info = { + .nl_net = net, + .skip_notify = false, + }; + + hlist_for_each_entry_safe(rt, n, &tb6->tb6_gc_hlist, gc_link) + if (fib6_age(rt, gc_args) == -1) + fib6_del(rt, &info); +} + +static void fib6_gc_all(struct net *net, struct fib6_gc_args *gc_args) +{ + struct fib6_table *table; + struct hlist_head *head; + unsigned int h; + + rcu_read_lock(); + for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { + head = &net->ipv6.fib_table_hash[h]; + hlist_for_each_entry_rcu(table, head, tb6_hlist) { + spin_lock_bh(&table->tb6_lock); + + fib6_gc_table(net, table, gc_args); + + spin_unlock_bh(&table->tb6_lock); + } + } + rcu_read_unlock(); +} + void fib6_run_gc(unsigned long expires, struct net *net, bool force) { struct fib6_gc_args gc_args; @@ -2336,7 +2384,7 @@ void fib6_run_gc(unsigned long expires, struct net *net, bool force) net->ipv6.sysctl.ip6_rt_gc_interval; gc_args.more = 0; - fib6_clean_all(net, fib6_age, &gc_args); + fib6_gc_all(net, &gc_args); now = jiffies; net->ipv6.ip6_rt_last_gc = now; @@ -2396,6 +2444,7 @@ static int __net_init fib6_net_init(struct net *net) net->ipv6.fib6_main_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; inet_peer_base_init(&net->ipv6.fib6_main_tbl->tb6_peers); + INIT_HLIST_HEAD(&net->ipv6.fib6_main_tbl->tb6_gc_hlist); #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl), @@ -2408,6 +2457,7 @@ static int __net_init fib6_net_init(struct net *net) net->ipv6.fib6_local_tbl->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; inet_peer_base_init(&net->ipv6.fib6_local_tbl->tb6_peers); + INIT_HLIST_HEAD(&net->ipv6.fib6_local_tbl->tb6_gc_hlist); #endif fib6_tables_init(net); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 8d853971f2f6..d8e5e2833ede 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1241,6 +1241,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) struct ndisc_options ndopts; struct fib6_info *rt = NULL; struct inet6_dev *in6_dev; + struct fib6_table *table; u32 defrtr_usr_metric; unsigned int pref = 0; __u32 old_if_flags; @@ -1413,8 +1414,15 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) inet6_rt_notify(RTM_NEWROUTE, rt, &nlinfo, NLM_F_REPLACE); } - if (rt) + if (rt) { + table = rt->fib6_table; + spin_lock_bh(&table->tb6_lock); + fib6_set_expires(rt, jiffies + (HZ * lifetime)); + fib6_add_gc_list(rt); + + spin_unlock_bh(&table->tb6_lock); + } if (in6_dev->cnf.accept_ra_min_hop_limit < 256 && ra_msg->icmph.icmp6_hop_limit) { if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b56a31bb7909..23ab5b22cb3f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -974,6 +974,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, struct net *net = dev_net(dev); struct route_info *rinfo = (struct route_info *) opt; struct in6_addr prefix_buf, *prefix; + struct fib6_table *table; unsigned int pref; unsigned long lifetime; struct fib6_info *rt; @@ -1032,10 +1033,18 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, (rt->fib6_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); if (rt) { - if (!addrconf_finite_timeout(lifetime)) + table = rt->fib6_table; + spin_lock_bh(&table->tb6_lock); + + if (!addrconf_finite_timeout(lifetime)) { fib6_clean_expires(rt); - else + fib6_remove_gc_list(rt); + } else { fib6_set_expires(rt, jiffies + HZ * lifetime); + fib6_add_gc_list(rt); + } + + spin_unlock_bh(&table->tb6_lock); fib6_info_release(rt); } -- Gitee From 96189918d1400cba07e6dc2674cbcfc2e027c0c9 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Sat, 15 Nov 2025 17:59:38 +0800 Subject: [PATCH 0346/1449] ipv6: clear RA flags when adding a static route ANBZ: #35228 commit cb2b0caa8ca93cbe39177516669bf699c74f7041 stable. commit f72514b3c5698e4b900b25345e09f9ed33123de6 upstream. When an IPv6 Router Advertisement (RA) is received for a prefix, the kernel creates the corresponding on-link route with flags RTF_ADDRCONF and RTF_PREFIX_RT configured and RTF_EXPIRES if lifetime is set. If later a user configures a static IPv6 address on the same prefix the kernel clears the RTF_EXPIRES flag but it doesn't clear the RTF_ADDRCONF and RTF_PREFIX_RT. When the next RA for that prefix is received, the kernel sees the route as RA-learned and wrongly configures back the lifetime. This is problematic because if the route expires, the static address won't have the corresponding on-link route. This fix clears the RTF_ADDRCONF and RTF_PREFIX_RT flags preventing that the lifetime is configured when the next RA arrives. If the static address is deleted, the route becomes RA-learned again. Fixes: 14ef37b6d00e ("ipv6: fix route lookup in addrconf_prefix_rcv()") Reported-by: Garri Djavadyan Closes: https://lore.kernel.org/netdev/ba807d39aca5b4dcf395cc11dca61a130a52cfd3.camel@gmail.com/ Signed-off-by: Fernando Fernandez Mancera Reviewed-by: David Ahern Link: https://patch.msgid.link/20251115095939.6967-1-fmancera@suse.de Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/ip6_fib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ab84e2dd682f..646ff1276aff 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1136,6 +1136,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, fib6_set_expires(iter, rt->expires); fib6_add_gc_list(iter); } + if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT))) { + iter->fib6_flags &= ~RTF_ADDRCONF; + iter->fib6_flags &= ~RTF_PREFIX_RT; + } if (rt->fib6_pmtu) fib6_metric_set(iter, RTAX_MTU, -- Gitee From 4311f4f2bc4d137fa5f4913b95d173560139bbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 19 Nov 2025 01:43:02 +0800 Subject: [PATCH 0347/1449] pwm: bcm2835: Make sure the channel is enabled after pwm_request() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 6b4cd95bd7463bc57c49942645a6efe2c0a0240e stable. commit cda323dbda76600bf9761970d58517648f0de67d upstream. The .free callback cleared among others the enable bit PWENx in the control register. When the PWM is requested later again this bit isn't restored but the core assumes the PWM is enabled and thus skips a request to configure the same state as before. To fix that don't touch the hardware configuration in .free(). For symmetry also drop .request() and configure the mode completely in .apply(). Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") Signed-off-by: Uwe Kleine-König Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com Signed-off-by: Uwe Kleine-König Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c index bdfc2a5ec0d6..5a51ba9b26d9 100644 --- a/drivers/pwm/pwm-bcm2835.c +++ b/drivers/pwm/pwm-bcm2835.c @@ -35,29 +35,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) return container_of(chip, struct bcm2835_pwm, chip); } -static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); - u32 value; - - value = readl(pc->base + PWM_CONTROL); - value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); - value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); - writel(value, pc->base + PWM_CONTROL); - - return 0; -} - -static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); - u32 value; - - value = readl(pc->base + PWM_CONTROL); - value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); - writel(value, pc->base + PWM_CONTROL); -} - static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { @@ -109,6 +86,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, /* set polarity */ val = readl(pc->base + PWM_CONTROL); + val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); + val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); + if (state->polarity == PWM_POLARITY_NORMAL) val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); else @@ -126,8 +106,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, } static const struct pwm_ops bcm2835_pwm_ops = { - .request = bcm2835_pwm_request, - .free = bcm2835_pwm_free, .apply = bcm2835_pwm_apply, .owner = THIS_MODULE, }; -- Gitee From 812ff81f97e2b9fdb8d30385851b23c030e20d67 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Thu, 13 Nov 2025 23:12:46 +0800 Subject: [PATCH 0348/1449] scsi: qla2xxx: Fix improper freeing of purex item ANBZ: #35228 commit 4bccd506a1f1ab01d1f45b2a3effff6bedc73cf9 stable. commit 78b1a242fe612a755f2158fd206ee6bb577d18ca upstream. In qla2xxx_process_purls_iocb(), an item is allocated via qla27xx_copy_multiple_pkt(), which internally calls qla24xx_alloc_purex_item(). The qla24xx_alloc_purex_item() function may return a pre-allocated item from a per-adapter pool for small allocations, instead of dynamically allocating memory with kzalloc(). An error handling path in qla2xxx_process_purls_iocb() incorrectly uses kfree() to release the item. If the item was from the pre-allocated pool, calling kfree() on it is a bug that can lead to memory corruption. Fix this by using the correct deallocation function, qla24xx_free_purex_item(), which properly handles both dynamically allocated and pre-allocated items. Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe") Signed-off-by: Zilin Guan Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 080670cb2aa5..38cb3281c635 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -1293,7 +1293,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) a.reason = FCNVME_RJT_RC_LOGIC; a.explanation = FCNVME_RJT_EXP_NONE; xmt_reject = true; - kfree(item); + qla24xx_free_purex_item(item); goto out; } -- Gitee From d7fb1645ec51c2cc8760a96593b1ab617d1895f6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Sep 2023 23:25:09 +0800 Subject: [PATCH 0349/1449] wifi: mac80211: remove RX_DROP_UNUSABLE ANBZ: #35228 commit 7fce2c2ce8815843fbf80f16b0fc92a05887b373 stable. commit dccc9aa7ee84a9bed7a4840608829eba66f84cb9 upstream. Convert all instances of RX_DROP_UNUSABLE to indicate a better reason, and then remove RX_DROP_UNUSABLE. Signed-off-by: Johannes Berg Stable-dep-of: 353cda30d30e ("wifi: mac80211: fix CMAC functions not handling errors") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/drop.h | 33 +++++++++++++++++++++++++++- net/mac80211/rx.c | 52 ++++++++++++++++++++++----------------------- net/mac80211/wep.c | 9 ++++---- net/mac80211/wpa.c | 42 ++++++++++++++++++------------------ 4 files changed, 84 insertions(+), 52 deletions(-) diff --git a/net/mac80211/drop.h b/net/mac80211/drop.h index 1570fac8411f..725a07a5b614 100644 --- a/net/mac80211/drop.h +++ b/net/mac80211/drop.h @@ -21,6 +21,38 @@ typedef unsigned int __bitwise ieee80211_rx_result; R(RX_DROP_U_MIC_FAIL) \ R(RX_DROP_U_REPLAY) \ R(RX_DROP_U_BAD_MMIE) \ + R(RX_DROP_U_DUP) \ + R(RX_DROP_U_SPURIOUS) \ + R(RX_DROP_U_DECRYPT_FAIL) \ + R(RX_DROP_U_NO_KEY_ID) \ + R(RX_DROP_U_BAD_CIPHER) \ + R(RX_DROP_U_OOM) \ + R(RX_DROP_U_NONSEQ_PN) \ + R(RX_DROP_U_BAD_KEY_COLOR) \ + R(RX_DROP_U_BAD_4ADDR) \ + R(RX_DROP_U_BAD_AMSDU) \ + R(RX_DROP_U_BAD_AMSDU_CIPHER) \ + R(RX_DROP_U_INVALID_8023) \ + R(RX_DROP_U_RUNT_ACTION) \ + R(RX_DROP_U_UNPROT_ACTION) \ + R(RX_DROP_U_ACTION_UNKNOWN_SRC) \ + R(RX_DROP_U_REJECTED_ACTION_RESPONSE) \ + R(RX_DROP_U_EXPECT_DEFRAG_PROT) \ + R(RX_DROP_U_WEP_DEC_FAIL) \ + R(RX_DROP_U_NO_IV) \ + R(RX_DROP_U_NO_ICV) \ + R(RX_DROP_U_AP_RX_GROUPCAST) \ + R(RX_DROP_U_SHORT_MMIC) \ + R(RX_DROP_U_MMIC_FAIL) \ + R(RX_DROP_U_SHORT_TKIP) \ + R(RX_DROP_U_TKIP_FAIL) \ + R(RX_DROP_U_SHORT_CCMP) \ + R(RX_DROP_U_SHORT_CCMP_MIC) \ + R(RX_DROP_U_SHORT_GCMP) \ + R(RX_DROP_U_SHORT_GCMP_MIC) \ + R(RX_DROP_U_SHORT_CMAC) \ + R(RX_DROP_U_SHORT_CMAC256) \ + R(RX_DROP_U_SHORT_GMAC) \ /* this line for the trailing \ - add before this */ /* having two enums allows for checking ieee80211_rx_result use with sparse */ @@ -46,7 +78,6 @@ enum mac80211_drop_reason { RX_CONTINUE = (__force ieee80211_rx_result)___RX_CONTINUE, RX_QUEUED = (__force ieee80211_rx_result)___RX_QUEUED, RX_DROP_MONITOR = (__force ieee80211_rx_result)___RX_DROP_MONITOR, - RX_DROP_UNUSABLE = (__force ieee80211_rx_result)___RX_DROP_UNUSABLE, #define DEF(x) x = (__force ieee80211_rx_result)___ ## x, MAC80211_DROP_REASONS_MONITOR(DEF) MAC80211_DROP_REASONS_UNUSABLE(DEF) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e6a0a65d4d43..d27303b9f3a9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1436,7 +1436,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) rx->sta->last_seq_ctrl[rx->seqno_idx] == hdr->seq_ctrl)) { I802_DEBUG_INC(rx->local->dot11FrameDuplicateCount); rx->link_sta->rx_stats.num_duplicates++; - return RX_DROP_UNUSABLE; + return RX_DROP_U_DUP; } else if (!(status->flag & RX_FLAG_AMSDU_MORE)) { rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; } @@ -1490,7 +1490,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) cfg80211_rx_spurious_frame(rx->sdata->dev, hdr->addr2, GFP_ATOMIC)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SPURIOUS; return RX_DROP_MONITOR; } @@ -1883,7 +1883,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; int keyidx; - ieee80211_rx_result result = RX_DROP_UNUSABLE; + ieee80211_rx_result result = RX_DROP_U_DECRYPT_FAIL; struct ieee80211_key *sta_ptk = NULL; struct ieee80211_key *ptk_idx = NULL; int mmie_keyidx = -1; @@ -1933,7 +1933,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) keyid = ieee80211_get_keyid(rx->skb); if (unlikely(keyid < 0)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_NO_KEY_ID; ptk_idx = rcu_dereference(rx->sta->ptk[keyid]); } @@ -2038,7 +2038,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) keyidx = ieee80211_get_keyid(rx->skb); if (unlikely(keyidx < 0)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_NO_KEY_ID; /* check per-station GTK first, if multicast packet */ if (is_multicast_ether_addr(hdr->addr1) && rx->link_sta) @@ -2104,7 +2104,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) result = ieee80211_crypto_gcmp_decrypt(rx); break; default: - result = RX_DROP_UNUSABLE; + result = RX_DROP_U_BAD_CIPHER; } /* the hdr variable is invalid after the decrypt handlers */ @@ -2249,7 +2249,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) I802_DEBUG_INC(rx->local->rx_handlers_fragments); if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; /* * skb_linearize() might change the skb->data and @@ -2312,11 +2312,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; if (!requires_sequential_pn(rx, fc)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_NONSEQ_PN; /* Prevent mixed key and fragment cache attacks */ if (entry->key_color != rx->key->color) - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_KEY_COLOR; memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { @@ -2327,7 +2327,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) rpn = rx->ccm_gcm.pn; if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_REPLAY; memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); } else if (entry->is_protected && (!rx->key || @@ -2338,11 +2338,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) * if for TKIP Michael MIC should protect us, and WEP is a * lost cause anyway. */ - return RX_DROP_UNUSABLE; + return RX_DROP_U_EXPECT_DEFRAG_PROT; } else if (entry->is_protected && rx->key && entry->key_color != rx->key->color && (status->flag & RX_FLAG_DECRYPTED)) { - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_KEY_COLOR; } skb_pull(rx->skb, ieee80211_hdrlen(fc)); @@ -2361,7 +2361,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) GFP_ATOMIC))) { I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); __skb_queue_purge(&entry->skb_list); - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; } } while ((skb = __skb_dequeue(&entry->skb_list))) { @@ -2910,10 +2910,10 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta skb = NULL; if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; if (skb_linearize(fwd_skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; } fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); @@ -3010,7 +3010,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) rx->sdata->vif.addr, rx->sdata->vif.type, data_offset, true)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_AMSDU; if (rx->sta->amsdu_mesh_control < 0) { s8 valid = -1; @@ -3085,21 +3085,21 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) switch (rx->sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: if (!rx->sdata->u.vlan.sta) - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_4ADDR; break; case NL80211_IFTYPE_STATION: if (!rx->sdata->u.mgd.use_4addr) - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_4ADDR; break; case NL80211_IFTYPE_MESH_POINT: break; default: - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_4ADDR; } } if (is_multicast_ether_addr(hdr->addr1) || !rx->sta) - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_AMSDU; if (rx->key) { /* @@ -3112,7 +3112,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_TKIP: - return RX_DROP_UNUSABLE; + return RX_DROP_U_BAD_AMSDU_CIPHER; default: break; } @@ -3154,7 +3154,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) err = __ieee80211_data_to_8023(rx, &port_control); if (unlikely(err)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_INVALID_8023; res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); if (res != RX_CONTINUE) @@ -3386,7 +3386,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) /* drop too small action frames */ if (ieee80211_is_action(mgmt->frame_control) && rx->skb->len < IEEE80211_MIN_ACTION_SIZE) - return RX_DROP_UNUSABLE; + return RX_DROP_U_RUNT_ACTION; if (rx->sdata->vif.type == NL80211_IFTYPE_AP && ieee80211_is_beacon(mgmt->frame_control) && @@ -3408,7 +3408,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) } if (ieee80211_drop_unencrypted_mgmt(rx)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_UNPROT_ACTION; return RX_CONTINUE; } @@ -3480,7 +3480,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC && mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED && mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) - return RX_DROP_UNUSABLE; + return RX_DROP_U_ACTION_UNKNOWN_SRC; switch (mgmt->u.action.category) { case WLAN_CATEGORY_HT: @@ -3885,7 +3885,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) - return RX_DROP_UNUSABLE; + return RX_DROP_U_REJECTED_ACTION_RESPONSE; nskb = skb_copy_expand(rx->skb, local->hw.extra_tx_headroom, 0, GFP_ATOMIC); diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9a6e11d7b4db..5c01e121481a 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -3,6 +3,7 @@ * Software WEP encryption implementation * Copyright 2002, Jouni Malinen * Copyright 2003, Instant802 Networks, Inc. + * Copyright (C) 2023 Intel Corporation */ #include @@ -250,18 +251,18 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) if (!(status->flag & RX_FLAG_DECRYPTED)) { if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_WEP_DEC_FAIL; } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + IEEE80211_WEP_IV_LEN)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_NO_IV; ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); /* remove ICV */ if (!(status->flag & RX_FLAG_ICV_STRIPPED) && pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_NO_ICV; } return RX_CONTINUE; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 2d8e38b3bcb5..94dae7cb6dbd 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -3,7 +3,7 @@ * Copyright 2002-2004, Instant802 Networks, Inc. * Copyright 2008, Jouni Malinen * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation */ #include @@ -142,7 +142,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) * group keys and only the AP is sending real multicast * frames in the BSS. */ - return RX_DROP_UNUSABLE; + return RX_DROP_U_AP_RX_GROUPCAST; } if (status->flag & RX_FLAG_MMIC_ERROR) @@ -150,10 +150,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) hdrlen = ieee80211_hdrlen(hdr->frame_control); if (skb->len < hdrlen + MICHAEL_MIC_LEN) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_MMIC; if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; hdr = (void *)skb->data; data = skb->data + hdrlen; @@ -188,7 +188,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) NL80211_KEYTYPE_PAIRWISE, rx->key ? rx->key->conf.keyidx : -1, NULL, GFP_ATOMIC); - return RX_DROP_UNUSABLE; + return RX_DROP_U_MMIC_FAIL; } static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) @@ -276,11 +276,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) return RX_CONTINUE; if (!rx->sta || skb->len - hdrlen < 12) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_TKIP; /* it may be possible to optimize this a bit more */ if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; hdr = (void *)skb->data; /* @@ -298,7 +298,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) &rx->tkip.iv32, &rx->tkip.iv16); if (res != TKIP_DECRYPT_OK) - return RX_DROP_UNUSABLE; + return RX_DROP_U_TKIP_FAIL; /* Trim ICV */ if (!(status->flag & RX_FLAG_ICV_STRIPPED)) @@ -523,12 +523,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, if (status->flag & RX_FLAG_DECRYPTED) { if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_CCMP; if (status->flag & RX_FLAG_MIC_STRIPPED) mic_len = 0; } else { if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; } /* reload hdr - skb might have been reallocated */ @@ -536,7 +536,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len; if (!rx->sta || data_len < 0) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_CCMP; if (!(status->flag & RX_FLAG_PN_VALIDATED)) { int res; @@ -574,7 +574,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, /* Remove CCMP header and MIC */ if (pskb_trim(skb, skb->len - mic_len)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_CCMP_MIC; memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen); skb_pull(skb, IEEE80211_CCMP_HDR_LEN); @@ -719,12 +719,12 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) if (status->flag & RX_FLAG_DECRYPTED) { if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_GCMP; if (status->flag & RX_FLAG_MIC_STRIPPED) mic_len = 0; } else { if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; } /* reload hdr - skb might have been reallocated */ @@ -732,7 +732,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len; if (!rx->sta || data_len < 0) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_GCMP; if (!(status->flag & RX_FLAG_PN_VALIDATED)) { int res; @@ -771,7 +771,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) /* Remove GCMP header and MIC */ if (pskb_trim(skb, skb->len - mic_len)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_GCMP_MIC; memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen); skb_pull(skb, IEEE80211_GCMP_HDR_LEN); @@ -924,7 +924,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) /* management frames are already linear */ if (skb->len < 24 + sizeof(*mmie)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_CMAC; mmie = (struct ieee80211_mmie *) (skb->data + skb->len - sizeof(*mmie)); @@ -974,13 +974,13 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) /* management frames are already linear */ if (skb->len < 24 + sizeof(*mmie)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_CMAC256; mmie = (struct ieee80211_mmie_16 *) (skb->data + skb->len - sizeof(*mmie)); if (mmie->element_id != WLAN_EID_MMIE || mmie->length != sizeof(*mmie) - 2) - return RX_DROP_UNUSABLE; /* Invalid MMIE */ + return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */ bip_ipn_swap(ipn, mmie->sequence_number); @@ -1073,7 +1073,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) /* management frames are already linear */ if (skb->len < 24 + sizeof(*mmie)) - return RX_DROP_UNUSABLE; + return RX_DROP_U_SHORT_GMAC; mmie = (struct ieee80211_mmie_16 *) (skb->data + skb->len - sizeof(*mmie)); @@ -1097,7 +1097,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC); if (!mic) - return RX_DROP_UNUSABLE; + return RX_DROP_U_OOM; if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, skb->data + 24, skb->len - 24, mic) < 0 || -- Gitee From ac182b79f9d7a6944f5506a55cc41f4942e93e1f Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Thu, 13 Nov 2025 22:05:07 +0800 Subject: [PATCH 0350/1449] wifi: mac80211: fix CMAC functions not handling errors ANBZ: #35228 commit 19eda47ce3f1493436e36d24a361a5b17bc77bf6 stable. commit 353cda30d30e5dc7cacf8de5d2546724708ae3bb upstream. The called hash functions could fail thus we should check return values. Fixes: 26717828b75d ("mac80211: aes-cmac: switch to shash CMAC driver") Signed-off-by: Chien Wong Link: https://patch.msgid.link/20251113140511.48658-2-m@xv97.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/aes_cmac.c | 63 +++++++++++++++++++++++++++++------------ net/mac80211/aes_cmac.h | 8 +++--- net/mac80211/wpa.c | 20 +++++++------ 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index 48c04f89de20..65989c7dfc68 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c @@ -22,50 +22,77 @@ static const u8 zero[CMAC_TLEN_256]; -void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic) +int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic) { + int err; SHASH_DESC_ON_STACK(desc, tfm); u8 out[AES_BLOCK_SIZE]; const __le16 *fc; desc->tfm = tfm; - crypto_shash_init(desc); - crypto_shash_update(desc, aad, AAD_LEN); + err = crypto_shash_init(desc); + if (err) + return err; + err = crypto_shash_update(desc, aad, AAD_LEN); + if (err) + return err; fc = (const __le16 *)aad; if (ieee80211_is_beacon(*fc)) { /* mask Timestamp field to zero */ - crypto_shash_update(desc, zero, 8); - crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); + err = crypto_shash_update(desc, zero, 8); + if (err) + return err; + err = crypto_shash_update(desc, data + 8, + data_len - 8 - CMAC_TLEN); + if (err) + return err; } else { - crypto_shash_update(desc, data, data_len - CMAC_TLEN); + err = crypto_shash_update(desc, data, + data_len - CMAC_TLEN); + if (err) + return err; } - crypto_shash_finup(desc, zero, CMAC_TLEN, out); - + err = crypto_shash_finup(desc, zero, CMAC_TLEN, out); + if (err) + return err; memcpy(mic, out, CMAC_TLEN); + + return 0; } -void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic) +int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic) { + int err; SHASH_DESC_ON_STACK(desc, tfm); const __le16 *fc; desc->tfm = tfm; - crypto_shash_init(desc); - crypto_shash_update(desc, aad, AAD_LEN); + err = crypto_shash_init(desc); + if (err) + return err; + err = crypto_shash_update(desc, aad, AAD_LEN); + if (err) + return err; fc = (const __le16 *)aad; if (ieee80211_is_beacon(*fc)) { /* mask Timestamp field to zero */ - crypto_shash_update(desc, zero, 8); - crypto_shash_update(desc, data + 8, - data_len - 8 - CMAC_TLEN_256); + err = crypto_shash_update(desc, zero, 8); + if (err) + return err; + err = crypto_shash_update(desc, data + 8, + data_len - 8 - CMAC_TLEN_256); + if (err) + return err; } else { - crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); + err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); + if (err) + return err; } - crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); + return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); } struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h index 76817446fb83..f74150542142 100644 --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h @@ -11,10 +11,10 @@ struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], size_t key_len); -void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic); -void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic); +int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic); +int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic); void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); #endif /* AES_CMAC_H */ diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 94dae7cb6dbd..6223014e480c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -859,8 +859,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) /* * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */ - ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, - skb->data + 24, skb->len - 24, mmie->mic); + if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, + skb->data + 24, skb->len - 24, mmie->mic)) + return TX_DROP; return TX_CONTINUE; } @@ -902,8 +903,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */ - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, - skb->data + 24, skb->len - 24, mmie->mic); + if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, + skb->data + 24, skb->len - 24, mmie->mic)) + return TX_DROP; return TX_CONTINUE; } @@ -942,8 +944,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) if (!(status->flag & RX_FLAG_DECRYPTED)) { /* hardware didn't decrypt/verify MIC */ bip_aad(skb, aad); - ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, - skb->data + 24, skb->len - 24, mic); + if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, + skb->data + 24, skb->len - 24, mic)) + return RX_DROP_U_DECRYPT_FAIL; if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { key->u.aes_cmac.icverrors++; return RX_DROP_U_MIC_FAIL; @@ -992,8 +995,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) if (!(status->flag & RX_FLAG_DECRYPTED)) { /* hardware didn't decrypt/verify MIC */ bip_aad(skb, aad); - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, - skb->data + 24, skb->len - 24, mic); + if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, + skb->data + 24, skb->len - 24, mic)) + return RX_DROP_U_DECRYPT_FAIL; if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { key->u.aes_cmac.icverrors++; return RX_DROP_U_MIC_FAIL; -- Gitee From ec59d5d332085fb8b3fd099345fcfcbb069b2e5b Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 18 Nov 2025 20:15:00 +0800 Subject: [PATCH 0351/1449] mfd: mt6397-irq: Fix missing irq_domain_remove() in error path ANBZ: #35228 commit eb09da83e409b3305d199e15cadad527e188ea45 stable. commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 upstream. If devm_request_threaded_irq() fails after irq_domain_create_linear() succeeds in mt6397_irq_init(), the function returns without removing the created IRQ domain, leading to a resource leak. Call irq_domain_remove() in the error path after a successful irq_domain_create_linear() to properly release the IRQ domain. Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mfd/mt6397-irq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c index 886745b5b607..1e83f7c7ce14 100644 --- a/drivers/mfd/mt6397-irq.c +++ b/drivers/mfd/mt6397-irq.c @@ -208,6 +208,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) if (ret) { dev_err(chip->dev, "failed to register irq=%d; err: %d\n", chip->irq, ret); + irq_domain_remove(chip->irq_domain); return ret; } -- Gitee From 3f21cac16023f87955f38925e29f5f3936b48d64 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 18 Nov 2025 20:14:27 +0800 Subject: [PATCH 0352/1449] mfd: mt6358-irq: Fix missing irq_domain_remove() in error path ANBZ: #35228 commit c23e0dfb05f16956789e9c92359e12d0fe907335 stable. commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c upstream. If devm_request_threaded_irq() fails after irq_domain_add_linear() succeeds in mt6358_irq_init(), the function returns without removing the created IRQ domain, leading to a resource leak. Call irq_domain_remove() in the error path after a successful irq_domain_add_linear() to properly release the IRQ domain. Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mfd/mt6358-irq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c index 49830b526ee8..10a0952615a1 100644 --- a/drivers/mfd/mt6358-irq.c +++ b/drivers/mfd/mt6358-irq.c @@ -286,6 +286,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) if (ret) { dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", chip->irq, ret); + irq_domain_remove(chip->irq_domain); return ret; } -- Gitee From cb374d69eade609f4abd94a5cbe7df1c2da9f1c1 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 23 Oct 2025 21:58:05 +0800 Subject: [PATCH 0353/1449] phy: renesas: rcar-gen3-usb2: Fix an error handling path in rcar_gen3_phy_usb2_probe() ANBZ: #35228 commit 8d946fccf5b4df7b9d570055df002d3c3dafb2f1 stable. commit 662bb179d3381c7c069e44bb177396bcaee31cc8 upstream. If an error occurs after the reset_control_deassert(), reset_control_assert() must be called, as already done in the remove function. Use devm_add_action_or_reset() to add the missing call and simplify the .remove() function accordingly. While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore. [claudiu.beznea: removed "struct reset_control *rstc = data;" from rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc] Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus") Signed-off-by: Christophe JAILLET Reviewed-by: Biju Das Reviewed-by: Geert Uytterhoeven Tested-by: Wolfram Sang Signed-off-by: Claudiu Beznea Link: https://patch.msgid.link/20251023135810.1688415-3-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 9a6391361a0b..89a9693c9f57 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -117,7 +117,6 @@ struct rcar_gen3_chan { struct extcon_dev *extcon; struct rcar_gen3_phy rphys[NUM_OF_PHYS]; struct regulator *vbus; - struct reset_control *rstc; struct work_struct work; spinlock_t lock; /* protects access to hardware and driver data structure. */ enum usb_dr_mode dr_mode; @@ -658,21 +657,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) return candidate; } +static void rcar_gen3_reset_assert(void *data) +{ + reset_control_assert(data); +} + static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) { struct device *dev = channel->dev; + struct reset_control *rstc; int ret; u32 val; - channel->rstc = devm_reset_control_array_get_shared(dev); - if (IS_ERR(channel->rstc)) - return PTR_ERR(channel->rstc); + rstc = devm_reset_control_array_get_shared(dev); + if (IS_ERR(rstc)) + return PTR_ERR(rstc); ret = pm_runtime_resume_and_get(dev); if (ret) return ret; - ret = reset_control_deassert(channel->rstc); + ret = reset_control_deassert(rstc); + if (ret) + goto rpm_put; + + ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, rstc); if (ret) goto rpm_put; @@ -814,7 +823,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) if (channel->is_otg_channel) device_remove_file(&pdev->dev, &dev_attr_role); - reset_control_assert(channel->rstc); pm_runtime_disable(&pdev->dev); }; -- Gitee From 92a8b6d8c094e7380548a63103a5ef02cb423399 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Wed, 19 Nov 2025 20:47:36 +0800 Subject: [PATCH 0354/1449] net: phy: adin1100: Fix software power-down ready condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 49dc43b25d3457e974a6c7e97d9484a12d65fbba stable. commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 upstream. Value CRSM_SFT_PD written to Software Power-Down Control Register (CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for confirmation powerdown has been reached. The condition could have only worked when disabling powerdown (both 0x00), but never when enabling it (0x01 != 0x02). Result is a timeout, like so: $ ifdown eth0 macb f802c000.ethernet eth0: Link is Down ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 Fixes: 7eaf9132996a ("net: phy: adin1100: Add initial support for ADIN1100 industrial PHY") Signed-off-by: Alexander Dahl Reviewed-by: Russell King (Oracle) Acked-by: Nuno Sá Link: https://patch.msgid.link/20251119124737.280939-2-ada@thorsis.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/adin1100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c index 7619d6185801..2f47b7020e12 100644 --- a/drivers/net/phy/adin1100.c +++ b/drivers/net/phy/adin1100.c @@ -148,7 +148,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en) return ret; return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ADIN_CRSM_STAT, ret, - (ret & ADIN_CRSM_SFT_PD_RDY) == val, + !!(ret & ADIN_CRSM_SFT_PD_RDY) == en, 1000, 30000, true); } -- Gitee From 70023c66f6057cf3d937d82aa3b17f314605bea9 Mon Sep 17 00:00:00 2001 From: Chen Ridong Date: Fri, 14 Nov 2025 10:08:47 +0800 Subject: [PATCH 0355/1449] cpuset: Treat cpusets in attaching as populated ANBZ: #35228 commit 06a5e91764ed8ce85ee211cf7b07248c9fd2aec1 stable. commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 upstream. Currently, the check for whether a partition is populated does not account for tasks in the cpuset of attaching. This is a corner case that can leave a task stuck in a partition with no effective CPUs. The race condition occurs as follows: cpu0 cpu1 //cpuset A with cpu N migrate task p to A cpuset_can_attach // with effective cpus // check ok // cpuset_mutex is not held // clear cpuset.cpus.exclusive // making effective cpus empty update_exclusive_cpumask // tasks_nocpu_error check ok // empty effective cpus, partition valid cpuset_attach ... // task p stays in A, with non-effective cpus. To fix this issue, this patch introduces cs_is_populated, which considers tasks in the attaching cpuset. This new helper is used in validate_change and partition_is_populated. Fixes: e2d59900d936 ("cgroup/cpuset: Allow no-task partition to have empty cpuset.cpus.effective") Signed-off-by: Chen Ridong Reviewed-by: Waiman Long Signed-off-by: Tejun Heo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index af88e3286a19..8c0bbbc1e1e4 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -454,6 +454,15 @@ static inline bool is_in_v2_mode(void) (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); } +static inline bool cpuset_is_populated(struct cpuset *cs) +{ + lockdep_assert_held(&cpuset_mutex); + + /* Cpusets in the process of attaching should be considered as populated */ + return cgroup_is_populated(cs->css.cgroup) || + cs->attach_in_progress; +} + /** * partition_is_populated - check if partition has tasks * @cs: partition root to be checked @@ -466,21 +475,31 @@ static inline bool is_in_v2_mode(void) static inline bool partition_is_populated(struct cpuset *cs, struct cpuset *excluded_child) { - struct cgroup_subsys_state *css; - struct cpuset *child; + struct cpuset *cp; + struct cgroup_subsys_state *pos_css; - if (cs->css.cgroup->nr_populated_csets) + /* + * We cannot call cs_is_populated(cs) directly, as + * nr_populated_domain_children may include populated + * csets from descendants that are partitions. + */ + if (cs->css.cgroup->nr_populated_csets || + cs->attach_in_progress) return true; if (!excluded_child && !cs->nr_subparts_cpus) return cgroup_is_populated(cs->css.cgroup); rcu_read_lock(); - cpuset_for_each_child(child, css, cs) { - if (child == excluded_child) + cpuset_for_each_descendant_pre(cp, pos_css, cs) { + if (cp == cs || cp == excluded_child) continue; - if (is_partition_valid(child)) + + if (is_partition_valid(cp)) { + pos_css = css_rightmost_descendant(pos_css); continue; - if (cgroup_is_populated(child->css.cgroup)) { + } + + if (cpuset_is_populated(cp)) { rcu_read_unlock(); return true; } @@ -752,7 +771,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) * be changed to have empty cpus_allowed or mems_allowed. */ ret = -ENOSPC; - if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) { + if (cpuset_is_populated(cur)) { if (!cpumask_empty(cur->cpus_allowed) && cpumask_empty(trial->cpus_allowed)) goto out; -- Gitee From 86f974a45f594c323c3015715549378b3392e485 Mon Sep 17 00:00:00 2001 From: Seungjin Bae Date: Tue, 18 Nov 2025 09:32:59 +0800 Subject: [PATCH 0356/1449] wifi: rtl818x: rtl8187: Fix potential buffer underflow in rtl8187_rx_cb() ANBZ: #35228 commit dc153401fb26c1640a2b279c47b65e1c416af276 stable. commit b647d2574e4583c2e3b0ab35568f60c88e910840 upstream. The rtl8187_rx_cb() calculates the rx descriptor header address by subtracting its size from the skb tail pointer. However, it does not validate if the received packet (skb->len from urb->actual_length) is large enough to contain this header. If a truncated packet is received, this will lead to a buffer underflow, reading memory before the start of the skb data area, and causing a kernel panic. Add length checks for both rtl8187 and rtl8187b descriptor headers before attempting to access them, dropping the packet cleanly if the check fails. Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") Signed-off-by: Seungjin Bae Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c index f6528469022b..70df4c0b939c 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c @@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) spin_unlock_irqrestore(&priv->rx_queue.lock, f); skb_put(skb, urb->actual_length); - if (unlikely(urb->status)) { - dev_kfree_skb_irq(skb); - return; - } + if (unlikely(urb->status)) + goto free_skb; if (!priv->is_rtl8187b) { - struct rtl8187_rx_hdr *hdr = - (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + struct rtl8187_rx_hdr *hdr; + + if (skb->len < sizeof(struct rtl8187_rx_hdr)) + goto free_skb; + + hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); flags = le32_to_cpu(hdr->flags); /* As with the RTL8187B below, the AGC is used to calculate * signal strength. In this case, the scaling @@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) rx_status.antenna = (hdr->signal >> 7) & 1; rx_status.mactime = le64_to_cpu(hdr->mac_time); } else { - struct rtl8187b_rx_hdr *hdr = - (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + struct rtl8187b_rx_hdr *hdr; + + if (skb->len < sizeof(struct rtl8187b_rx_hdr)) + goto free_skb; + + hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); /* The Realtek datasheet for the RTL8187B shows that the RX * header contains the following quantities: signal quality, * RSSI, AGC, the received power in dB, and the measured SNR. @@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) skb_unlink(skb, &priv->rx_queue); dev_kfree_skb_irq(skb); } + return; + +free_skb: + dev_kfree_skb_irq(skb); + return; } static int rtl8187_init_urbs(struct ieee80211_hw *dev) -- Gitee From dcce577f922130609e64a52852889ccd4b1466ae Mon Sep 17 00:00:00 2001 From: Zhao Yipeng Date: Thu, 20 Nov 2025 15:18:05 +0800 Subject: [PATCH 0357/1449] ima: Handle error code returned by ima_filter_rule_match() ANBZ: #35228 commit cca3e7df3c0f99542033657ba850b9a6d27f8784 stable. commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 upstream. In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to the rule being NULL, the function incorrectly skips the 'if (!rc)' check and sets 'result = true'. The LSM rule is considered a match, causing extra files to be measured by IMA. This issue can be reproduced in the following scenario: After unloading the SELinux policy module via 'semodule -d', if an IMA measurement is triggered before ima_lsm_rules is updated, in ima_match_rules(), the first call to ima_filter_rule_match() returns -ESTALE. This causes the code to enter the 'if (rc == -ESTALE && !rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In ima_lsm_copy_rule(), since the SELinux module has been removed, the rule becomes NULL, and the second call to ima_filter_rule_match() returns -ENOENT. This bypasses the 'if (!rc)' check and results in a false match. Call trace: selinux_audit_rule_match+0x310/0x3b8 security_audit_rule_match+0x60/0xa0 ima_match_rules+0x2e4/0x4a0 ima_match_policy+0x9c/0x1e8 ima_get_action+0x48/0x60 process_measurement+0xf8/0xa98 ima_bprm_check+0x98/0xd8 security_bprm_check+0x5c/0x78 search_binary_handler+0x6c/0x318 exec_binprm+0x58/0x1b8 bprm_execve+0xb8/0x130 do_execveat_common.isra.0+0x1a8/0x258 __arm64_sys_execve+0x48/0x68 invoke_syscall+0x50/0x128 el0_svc_common.constprop.0+0xc8/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x44/0x200 el0t_64_sync_handler+0x100/0x130 el0t_64_sync+0x3c8/0x3d0 Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error codes like -ENOENT do not bypass the check and accidentally result in a successful match. Fixes: 4af4662fa4a9d ("integrity: IMA policy") Signed-off-by: Zhao Yipeng Reviewed-by: Roberto Sassu Signed-off-by: Mimi Zohar Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- security/integrity/ima/ima_policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index f3f46c6186c0..afbf963cb748 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -672,7 +672,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, goto retry; } } - if (!rc) { + if (rc <= 0) { result = false; goto out; } -- Gitee From 594f95ba6fbd97aba8391c6cce1663694f7c6b93 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 30 Oct 2025 17:39:06 +0800 Subject: [PATCH 0358/1449] usb: chaoskey: fix locking for O_NONBLOCK ANBZ: #35228 commit b90c743a0a32b62345d539ac40dddfad751cce37 stable. commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de upstream. A failure to take a lock with O_NONBLOCK needs to result in -EAGAIN. Change it. Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") Signed-off-by: Oliver Neukum Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index 225863321dc4..45cff32656c6 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -444,9 +444,19 @@ static ssize_t chaoskey_read(struct file *file, goto bail; mutex_unlock(&dev->rng_lock); - result = mutex_lock_interruptible(&dev->lock); - if (result) - goto bail; + if (file->f_flags & O_NONBLOCK) { + result = mutex_trylock(&dev->lock); + if (result == 0) { + result = -EAGAIN; + goto bail; + } else { + result = 0; + } + } else { + result = mutex_lock_interruptible(&dev->lock); + if (result) + goto bail; + } if (dev->valid == dev->used) { result = _chaoskey_fill(dev); if (result < 0) { -- Gitee From 826a11ab78abebb848b58d16f3f1208a88794c74 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sun, 29 Jun 2025 17:46:55 +0800 Subject: [PATCH 0359/1449] usb: dwc2: disable platform lowlevel hw resources during shutdown ANBZ: #35228 commit 7e993b9d6d246924eb49d7dcb6906398a11720be stable. commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 upstream. On some SoC platforms, in shutdown stage, most components' power is cut off, but there's still power supply to the so called always-on domain, so if the dwc2's regulator is from the always-on domain, we need to explicitly disable it to save power. Disable platform lowlevel hw resources such as phy, clock and regulators etc. in device shutdown hook to reduce non-necessary power consumption when the platform enters shutdown stage. Signed-off-by: Jisheng Zhang Acked-by: Minas Harutyunyan Link: https://lore.kernel.org/r/20250629094655.747-1-jszhang@kernel.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc2/platform.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index c1b7209b9483..79ce88b5f07d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -371,6 +371,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev) dwc2_disable_global_interrupts(hsotg); synchronize_irq(hsotg->irq); + + if (hsotg->ll_hw_enabled) + dwc2_lowlevel_hw_disable(hsotg); } /** -- Gitee From c0e5134db15f5c4e93ec6e013da324131edcbeb1 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Tue, 4 Nov 2025 08:25:02 +0800 Subject: [PATCH 0360/1449] usb: dwc2: fix hang during shutdown if set as peripheral ANBZ: #35228 commit bac021bf0733fe9c380646da73f6dddd82d6cfac stable. commit b6ebcfdcac40a27953f052e4269ce75a18825ffc upstream. dwc2 on most platforms needs phy controller, clock and power supply. All of them must be enabled/activated to properly operate. If dwc2 is configured as peripheral mode, then all the above three hardware resources are disabled at the end of the probe: /* Gadget code manages lowlevel hw on its own */ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) dwc2_lowlevel_hw_disable(hsotg); But dwc2_driver_shutdown() tries to disable the interrupts on HW IP level. This would result in hang during shutdown if dwc2 is configured as peripheral mode. Fix this hang by only disable and sync irq when lowlevel hw is enabled. Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") Signed-off-by: Jisheng Zhang Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc2/platform.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 79ce88b5f07d..fad6f68f86bd 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -369,11 +369,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); - dwc2_disable_global_interrupts(hsotg); - synchronize_irq(hsotg->irq); - - if (hsotg->ll_hw_enabled) + if (hsotg->ll_hw_enabled) { + dwc2_disable_global_interrupts(hsotg); + synchronize_irq(hsotg->irq); dwc2_lowlevel_hw_disable(hsotg); + } } /** -- Gitee From b4dab6ddb22c4af6f2d48c53f37eb82f15f1a6bf Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Tue, 4 Nov 2025 08:25:03 +0800 Subject: [PATCH 0361/1449] usb: dwc2: fix hang during suspend if set as peripheral ANBZ: #35228 commit b6943283343b9b15da942393d1b58e342983bb9b stable. commit 2b94b054ac4974ad2f89f7f7461840c851933adb upstream. dwc2 on most platforms needs phy controller, clock and power supply. All of them must be enabled/activated to properly operate. If dwc2 is configured as peripheral mode, then all the above three hardware resources are disabled at the end of the probe: /* Gadget code manages lowlevel hw on its own */ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) dwc2_lowlevel_hw_disable(hsotg); But the dwc2_suspend() tries to read the dwc2's reg to check whether is_device_mode or not, this would result in hang during suspend if dwc2 is configured as peripheral mode. Fix this hang by bypassing suspend/resume if lowlevel hw isn't enabled. Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") Signed-off-by: Jisheng Zhang Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc2/platform.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index fad6f68f86bd..e80982c817d7 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -649,9 +649,13 @@ static int dwc2_driver_probe(struct platform_device *dev) static int __maybe_unused dwc2_suspend(struct device *dev) { struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); - bool is_device_mode = dwc2_is_device_mode(dwc2); + bool is_device_mode; int ret = 0; + if (!dwc2->ll_hw_enabled) + return 0; + + is_device_mode = dwc2_is_device_mode(dwc2); if (is_device_mode) dwc2_hsotg_suspend(dwc2); @@ -702,6 +706,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; + if (!dwc2->ll_hw_enabled) + return 0; + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { ret = __dwc2_lowlevel_hw_enable(dwc2); if (ret) -- Gitee From 7afd781b9790b16204513a84f4acfa6e4bd1ea16 Mon Sep 17 00:00:00 2001 From: Gopi Krishna Menon Date: Wed, 29 Oct 2025 00:56:57 +0800 Subject: [PATCH 0362/1449] usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE ANBZ: #35228 commit 3915c76df201644f88347878e6342af93bbae9f5 stable. commit a5160af78be7fcf3ade6caab0a14e349560c96d7 upstream. The previous commit removed the PAGE_SIZE limit on transfer length of raw_io buffer in order to avoid any problems with emulating USB devices whose full configuration descriptor exceeds PAGE_SIZE in length. However this also removes the upperbound on user supplied length, allowing very large values to be passed to the allocator. syzbot on fuzzing the transfer length with very large value (1.81GB) results in kmalloc() to fall back to the page allocator, which triggers a kernel warning as the page allocator cannot handle allocations more than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. Since there is no limit imposed on the size of buffer for both control and non control transfers, cap the raw_io transfer length to KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to prevent any warnings from the page allocator. Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ Signed-off-by: Gopi Krishna Menon Reviewed-by: Andrey Konovalov Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index 2deab4a6030d..8aa1a8408ae3 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -39,6 +39,7 @@ MODULE_LICENSE("GPL"); static DEFINE_IDA(driver_id_numbers); #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 +#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE #define RAW_EVENT_QUEUE_SIZE 16 @@ -620,6 +621,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, return ERR_PTR(-EINVAL); if (!usb_raw_io_flags_valid(io->flags)) return ERR_PTR(-EINVAL); + if (io->length > USB_RAW_IO_LENGTH_MAX) + return ERR_PTR(-EINVAL); if (get_from_user) data = memdup_user(ptr + sizeof(*io), io->length); else { -- Gitee From 171f6c1426905b1a59ec070d2acb31f6f41c087c Mon Sep 17 00:00:00 2001 From: Matt Bobrowski Date: Thu, 20 Nov 2025 22:20:59 +0800 Subject: [PATCH 0363/1449] selftests/bpf: skip test_perf_branches_hw() on unsupported platforms ANBZ: #35228 commit e5343f28814d81ff0488afece0274813e40dd5ba stable. commit 27746aaf1b20172f0859546c4a3e82eca459f680 upstream. Gracefully skip the test_perf_branches_hw subtest on platforms that do not support LBR or require specialized perf event attributes to enable branch sampling. For example, AMD's Milan (Zen 3) supports BRS rather than traditional LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the generic setup used within this test. Notably, it also probably doesn't hold much value to special case perf event configurations for selected micro architectures. Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") Signed-off-by: Matt Bobrowski Acked-by: Song Liu Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c index bc24f83339d6..06c7986131d9 100644 --- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c +++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c @@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); /* - * Some setups don't support branch records (virtual machines, !x86), - * so skip test in this case. + * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen + * 3 which only supports BRS), so skip test in this case. */ if (pfd < 0) { - if (errno == ENOENT || errno == EOPNOTSUPP) { + if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", __func__); test__skip(); -- Gitee From 98a627e4a373c04c051ee1c1ad38e09c793a4a67 Mon Sep 17 00:00:00 2001 From: Matt Bobrowski Date: Wed, 19 Nov 2025 22:35:40 +0800 Subject: [PATCH 0364/1449] selftests/bpf: Improve reliability of test_perf_branches_no_hw() ANBZ: #35228 commit 6a17f898a8bf91281c202c687b52f7fb957e0e47 stable. commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 upstream. Currently, test_perf_branches_no_hw() relies on the busy loop within test_perf_branches_common() being slow enough to allow at least one perf event sample tick to occur before starting to tear down the backing perf event BPF program. With a relatively small fixed iteration count of 1,000,000, this is not guaranteed on modern fast CPUs, resulting in the test run to subsequently fail with the following: bpf_testmod.ko is already unloaded. Loading bpf_testmod.ko... Successfully loaded bpf_testmod.ko. test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_good_sample:PASS:output not valid 0 nsec check_good_sample:PASS:read_branches_size 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_size 0 nsec test_perf_branches_no_hw:PASS:perf_event_open 0 nsec test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_bad_sample:FAIL:output not valid no valid sample from prog Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED Successfully unloaded bpf_testmod.ko. On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 million increments of a volatile integer can take significantly less than 1 millisecond. If the spin loop and detachment of the perf event BPF program elapses before the first 1 ms sampling interval elapses, the perf event will never end up firing. Fix this by bumping the loop iteration counter a little within test_perf_branches_common(), along with ensuring adding another loop termination condition which is directly influenced by the backing perf event BPF program executing. Notably, a concious decision was made to not adjust the sample_freq value as that is just not a reliable way to go about fixing the problem. It effectively still leaves the race window open. Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") Signed-off-by: Matt Bobrowski Reviewed-by: Jiri Olsa Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- .../selftests/bpf/progs/test_perf_branches.c | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c index 06c7986131d9..0a7ef770c487 100644 --- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c +++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c @@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) int pbe_size = sizeof(struct perf_branch_entry); int duration = 0; + if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", + "checked sample validity before prog run")) + return; + if (CHECK(!skel->bss->valid, "output not valid", "no valid sample from prog")) return; @@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) int written_stack = skel->bss->written_stack_out; int duration = 0; + if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", + "checked sample validity before prog run")) + return; + if (CHECK(!skel->bss->valid, "output not valid", "no valid sample from prog")) return; @@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) goto out_destroy; - /* spin the loop for a while (random high number) */ - for (i = 0; i < 1000000; ++i) + + /* Spin the loop for a while by using a high iteration count, and by + * checking whether the specific run count marker has been explicitly + * incremented at least once by the backing perf_event BPF program. + */ + for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) ++j; test_perf_branches__detach(skel); diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c index a1ccc831c882..05ac9410cd68 100644 --- a/tools/testing/selftests/bpf/progs/test_perf_branches.c +++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c @@ -8,6 +8,7 @@ #include int valid = 0; +int run_cnt = 0; int required_size_out = 0; int written_stack_out = 0; int written_global_out = 0; @@ -24,6 +25,8 @@ int perf_branches(void *ctx) __u64 entries[4 * 3] = {0}; int required_size, written_stack, written_global; + ++run_cnt; + /* write to stack */ written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); /* ignore spurious events */ -- Gitee From 8677066236a1b0ddf43f90acb6aa2d1cc406c2c2 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 10 Nov 2025 14:54:38 +0800 Subject: [PATCH 0365/1449] crypto: starfive - Correctly handle return of sg_nents_for_len ANBZ: #35228 commit 6cd14414394b4f3d6e1ed64b8241d1fcc2271820 stable. commit e9eb52037a529fbb307c290e9951a62dd728b03d upstream. The return value of sg_nents_for_len was assigned to an unsigned long in starfive_hash_digest, causing negative error codes to be converted to large positive integers. Add error checking for sg_nents_for_len and return immediately on failure to prevent potential buffer overflows. Fixes: 7883d1b28a2b ("crypto: starfive - Add hash and HMAC support") Signed-off-by: Haotian Zhang Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/starfive/jh7110-hash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/starfive/jh7110-hash.c b/drivers/crypto/starfive/jh7110-hash.c index cc7650198d70..e973e73f866b 100644 --- a/drivers/crypto/starfive/jh7110-hash.c +++ b/drivers/crypto/starfive/jh7110-hash.c @@ -358,6 +358,7 @@ static int starfive_hash_digest(struct ahash_request *req) struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); struct starfive_cryp_dev *cryp = ctx->cryp; + int sg_len; memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); @@ -366,7 +367,10 @@ static int starfive_hash_digest(struct ahash_request *req) rctx->in_sg = req->src; rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); rctx->digsize = crypto_ahash_digestsize(tfm); - rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); + sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); + if (sg_len < 0) + return sg_len; + rctx->in_sg_len = sg_len; ctx->rctx = rctx; if (starfive_hash_check_aligned(rctx->in_sg, rctx->total, rctx->blksize)) -- Gitee From c27aac83d42ae6ebad0f8570335f01144973bd60 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 10 Nov 2025 15:20:41 +0800 Subject: [PATCH 0366/1449] crypto: ccree - Correctly handle return of sg_nents_for_len ANBZ: #35228 commit 76ae0cc396736c4e729616fd6442d4e74f60bb57 stable. commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c upstream. Fix error handling in cc_map_hash_request_update where sg_nents_for_len return value was assigned to u32, converting negative errors to large positive values before passing to sg_copy_to_buffer. Check sg_nents_for_len return value and propagate errors before assigning to areq_ctx->in_nents. Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") Signed-off-by: Haotian Zhang Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c index bcca55bff910..286e0d4b8f95 100644 --- a/drivers/crypto/ccree/cc_buffer_mgr.c +++ b/drivers/crypto/ccree/cc_buffer_mgr.c @@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, int rc = 0; u32 dummy = 0; u32 mapped_nents = 0; + int sg_nents; dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); @@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, if (total_in_len < block_size) { dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); - areq_ctx->in_nents = sg_nents_for_len(src, nbytes); + sg_nents = sg_nents_for_len(src, nbytes); + if (sg_nents < 0) + return sg_nents; + areq_ctx->in_nents = sg_nents; sg_copy_to_buffer(src, areq_ctx->in_nents, &curr_buff[*curr_buff_cnt], nbytes); *curr_buff_cnt += nbytes; -- Gitee From 33c6f1794add6a92266bc42e1a08abe0752f1d96 Mon Sep 17 00:00:00 2001 From: Fangyu Yu Date: Fri, 21 Nov 2025 21:35:43 +0800 Subject: [PATCH 0367/1449] RISC-V: KVM: Fix guest page fault within HLV* instructions ANBZ: #35228 commit e3e1c7416be8a902fcffc9749935e9bab369656e stable. commit 974555d6e417974e63444266e495a06d06c23af5 upstream. When executing HLV* instructions at the HS mode, a guest page fault may occur when a g-stage page table migration between triggering the virtual instruction exception and executing the HLV* instruction. This may be a corner case, and one simpler way to handle this is to re-execute the instruction where the virtual instruction exception occurred, and the guest page fault will be automatically handled. Fixes: b91f0e4cb8a3 ("RISC-V: KVM: Factor-out instruction emulation into separate sources") Signed-off-by: Fangyu Yu Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20251121133543.46822-1-fangyu.yu@linux.alibaba.com Signed-off-by: Anup Patel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index 97dec18e6989..3dbd6a09d482 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -424,6 +424,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, return (rc <= 0) ? rc : 1; } +static bool is_load_guest_page_fault(unsigned long scause) +{ + /** + * If a g-stage page fault occurs, the direct approach + * is to let the g-stage page fault handler handle it + * naturally, however, calling the g-stage page fault + * handler here seems rather strange. + * Considering this is a corner case, we can directly + * return to the guest and re-execute the same PC, this + * will trigger a g-stage page fault again and then the + * regular g-stage page fault handler will populate + * g-stage page table. + */ + return (scause == EXC_LOAD_GUEST_PAGE_FAULT); +} + /** * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap * @@ -449,6 +465,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ct->sepc, &utrap); if (utrap.scause) { + if (is_load_guest_page_fault(utrap.scause)) + return 1; utrap.sepc = ct->sepc; kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); return 1; @@ -504,6 +522,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, &utrap); if (utrap.scause) { + if (is_load_guest_page_fault(utrap.scause)) + return 1; /* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc; kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); @@ -630,6 +650,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, &utrap); if (utrap.scause) { + if (is_load_guest_page_fault(utrap.scause)) + return 1; /* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc; kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); -- Gitee From 04d76632617194e0927af32fe6943b2b951d02c2 Mon Sep 17 00:00:00 2001 From: Selvin Xavier Date: Thu, 20 Nov 2025 15:36:54 +0800 Subject: [PATCH 0368/1449] RDMA/bnxt_re: Fix the inline size for GenP7 devices ANBZ: #35228 commit ccc585db618c7823c8f83d8f756398c2020a4da0 stable. commit 6afe40ff484a1155b71158b911c65299496e35c3 upstream. Inline size supported by the device is based on the number of SGEs supported by the adapter. Change the inline size calculation based on that. Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") Reviewed-by: Kashyap Desai Signed-off-by: Kalesh AP Signed-off-by: Selvin Xavier Link: https://patch.msgid.link/1763624215-10382-1-git-send-email-selvin.xavier@broadcom.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c index 74c3f6b26c4d..0b713c1821c3 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c @@ -161,7 +161,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1; attr->max_srq_sges = sb->max_srq_sge; attr->max_pkey = 1; - attr->max_inline_data = le32_to_cpu(sb->max_inline_data); + attr->max_inline_data = attr->max_qp_sges * sizeof(struct sq_sge); if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) attr->l2_db_size = (sb->l2_db_space_size + 1) * (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); -- Gitee From aaec7d3c71e467e27b7f5fbcfefbdb6f8965870b Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Thu, 13 Nov 2025 14:24:15 +0800 Subject: [PATCH 0369/1449] mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() ANBZ: #35228 commit 1c3c234af9407256ed670c8752923a672eea4225 stable. commit 53d1548612670aa8b5d89745116cc33d9d172863 upstream. In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function returns an error without freeing sskb, leading to a memory leak. Fix this by calling dev_kfree_skb() on sskb in the error handling path to ensure it is properly released. Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") Signed-off-by: Zilin Guan Acked-by: Lorenzo Bianconi Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn Signed-off-by: Felix Fietkau Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index e92040616a1f..94adb22f8570 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -870,8 +870,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, WTBL_RESET_AND_SET, NULL, &wskb); - if (IS_ERR(wtbl_hdr)) + if (IS_ERR(wtbl_hdr)) { + dev_kfree_skb(sskb); return PTR_ERR(wtbl_hdr); + } if (enable) { mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, -- Gitee From 5051fd195ba8bc89bf7c5b522d0b1509e8a30d63 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Sat, 15 Nov 2025 02:58:13 +0800 Subject: [PATCH 0370/1449] firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc ANBZ: #35228 commit d6ce96e10e4d00200f1dc411ea00f3eeda6789de stable. commit 377441d53a2df61b105e823b335010cd4f1a6e56 upstream. Fix this warning that was generated from "make htmldocs": WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs' not described in 'stratix10_svc' Fixes: e6281c26674e ("firmware: stratix10-svc: Add support for FCS") Reported-by: Stephen Rothwell Closes: https://lore.kernel.org/linux-next/20251106145941.37920e97@canb.auug.org.au/ Signed-off-by: Dinh Nguyen Link: https://patch.msgid.link/20251114185815.358423-1-dinguyen@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/stratix10-svc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 766ced12345c..a133ac5fb037 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -52,6 +52,7 @@ struct stratix10_svc_chan; /** * struct stratix10_svc - svc private data * @stratix10_svc_rsu: pointer to stratix10 RSU device + * @intel_svc_fcs: pointer to the FCS device */ struct stratix10_svc { struct platform_device *stratix10_svc_rsu; -- Gitee From 97710d82ac02c7ce596a06bf4bc03cc69c061ee4 Mon Sep 17 00:00:00 2001 From: Jianglei Nie Date: Thu, 13 Nov 2025 03:22:07 +0800 Subject: [PATCH 0371/1449] staging: fbtft: core: fix potential memory leak in fbtft_probe_common() ANBZ: #35228 commit 3cfa3d4b155a0ae79e2e05415dacd9451cfe7a13 stable. commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 upstream. fbtft_probe_common() allocates a memory chunk for "info" with fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the function returns without releasing the "info", which will lead to a memory leak. Fix it by calling fbtft_framebuffer_release() when "display->buswidth == 0" is true. Fixes: c296d5f9957c ("staging: fbtft: core support") Signed-off-by: Jianglei Nie Signed-off-by: Andy Shevchenko Acked-by: Abdun Nihaal Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/staging/fbtft/fbtft-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index dce721f440c5..5dfe2d7a73e3 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -1225,8 +1225,8 @@ int fbtft_probe_common(struct fbtft_display *display, par->pdev = pdev; if (display->buswidth == 0) { - dev_err(dev, "buswidth is not set\n"); - return -EINVAL; + ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); + goto out_release; } /* write register functions */ -- Gitee From b3d6a9894dc2f639a33fa76692c635f1f289cbac Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 13 Nov 2025 20:52:45 +0800 Subject: [PATCH 0372/1449] btrfs: fix leaf leak in an error path in btrfs_del_items() ANBZ: #35228 commit 5928832a90c192ed78d011684d8417a0e6a8b06d stable. commit e7dd1182fcedee7c6097c9f49eba8de94a4364e3 upstream. If the call to btrfs_del_leaf() fails we return without decrementing the extra ref we took on the leaf, therefore leaking it. Fix this by ensuring we drop the ref count before returning the error. Fixes: 751a27615dda ("btrfs: do not BUG_ON() on tree mod log failures at btrfs_del_ptr()") Reviewed-by: Qu Wenruo Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/ctree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 31b1b448efc2..a26c6e9d562d 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -4743,9 +4743,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (btrfs_header_nritems(leaf) == 0) { path->slots[1] = slot; ret = btrfs_del_leaf(trans, root, path, leaf); + free_extent_buffer(leaf); if (ret < 0) return ret; - free_extent_buffer(leaf); ret = 0; } else { /* if we're still in the path, make sure -- Gitee From aab6f7030e8c428d253af78c3a528416dbd44fa0 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 14 Nov 2025 20:09:00 +0800 Subject: [PATCH 0373/1449] PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition ANBZ: #35228 commit 96c56c5ff4e4aa88e3c1a897a382d37ff250e1df stable. commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 upstream. As per DesignWare Cores PCI Express Controller Databook, section 5.50, SII: Debug Signals, cxpl_debug_info[63:0]: [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the dedicated smlh_ltssm_state output. The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") Signed-off-by: Shawn Lin [mani: reworded description] Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/controller/dwc/pcie-designware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 74d500819e92..b6ce6b7b23b7 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -92,7 +92,7 @@ #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) #define PCIE_PORT_DEBUG0 0x728 -#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f +#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f #define PORT_LOGIC_LTSSM_STATE_L0 0x11 #define PCIE_PORT_DEBUG1 0x72C #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) -- Gitee From 91883c1d431580f48ff377d6a13a8e5d154a62b0 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Fri, 14 Nov 2025 07:03:22 +0800 Subject: [PATCH 0374/1449] drm/nouveau: restrict the flush page to a 32-bit address ANBZ: #35228 commit 7e50ce619ec68cd69255ed66ff05aab19bf5282d stable. commit 04d98b3452331fa53ec3b698b66273af6ef73288 upstream. The flush page DMA address is stored in a special register that is not associated with the GPU's standard DMA range. For example, on Turing, the GPU's MMU can handle 47-bit addresses, but the flush page address register is limited to 40 bits. At the point during device initialization when the flush page is allocated, the DMA mask is still at its default of 32 bits. So even though it's unlikely that the flush page could exist above a 40-bit address, the dma_map_page() call could fail, e.g. if IOMMU is disabled and the address is above 32 bits. The simplest way to achieve all constraints is to allocate the page in the DMA32 zone. Since the flush page is literally just a page, this is an acceptable limitation. The alternative is to temporarily set the DMA mask to 40 (or 52 for Hopper and later) bits, but that could have unforseen side effects. In situations where the flush page is allocated above 32 bits and IOMMU is disabled, you will get an error like this: nouveau 0000:65:00.0: DMA addr 0x0000000107c56000+4096 overflow (mask ffffffff, bus limit 0). Fixes: 5728d064190e ("drm/nouveau/fb: handle sysmem flush page from common code") Signed-off-by: Timur Tabi Reviewed-by: Lyude Paul Signed-off-by: Lyude Paul Link: https://patch.msgid.link/20251113230323.1271726-1-ttabi@nvidia.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index 8a286a9349ac..7ce1b65e2c1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -279,7 +279,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, mutex_init(&fb->tags.mutex); if (func->sysmem.flush_page_init) { - fb->sysmem.flush_page = alloc_page(GFP_KERNEL | __GFP_ZERO); + fb->sysmem.flush_page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); if (!fb->sysmem.flush_page) return -ENOMEM; -- Gitee From 7bbba2488371fa3d35651b6e706d3c036843e39c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 6 Feb 2025 14:40:04 +0800 Subject: [PATCH 0375/1449] iomap: factor out a iomap_dio_done helper ANBZ: #35228 commit 4ae9ff07bc2be46dbc72e44effe2c2751a937ee9 stable. commit ae2f33a519af3730cacd1c787ebe1f7475df5ba8 upstream. Split out the struct iomap-dio level final completion from iomap_dio_bio_end_io into a helper to clean up the code and make it reusable. Signed-off-by: Christoph Hellwig Link: https://lore.kernel.org/r/20250206064035.2323428-7-hch@lst.de Reviewed-by: "Darrick J. Wong" Signed-off-by: Christian Brauner Stable-dep-of: ddb4873286e0 ("iomap: always run error completions in user context") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/iomap/direct-io.c | 76 ++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index bcd3f8cf5ea4..1b0f06e7e58d 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -156,43 +156,31 @@ static inline void iomap_dio_set_error(struct iomap_dio *dio, int ret) cmpxchg(&dio->error, 0, ret); } -void iomap_dio_bio_end_io(struct bio *bio) +/* + * Called when dio->ref reaches zero from an I/O completion. + */ +static void iomap_dio_done(struct iomap_dio *dio) { - struct iomap_dio *dio = bio->bi_private; - bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); struct kiocb *iocb = dio->iocb; - if (bio->bi_status) - iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); - if (!atomic_dec_and_test(&dio->ref)) - goto release_bio; - - /* - * Synchronous dio, task itself will handle any completion work - * that needs after IO. All we need to do is wake the task. - */ if (dio->wait_for_completion) { + /* + * Synchronous I/O, task itself will handle any completion work + * that needs after IO. All we need to do is wake the task. + */ struct task_struct *waiter = dio->submit.waiter; WRITE_ONCE(dio->submit.waiter, NULL); blk_wake_io_task(waiter); - goto release_bio; - } - - /* - * Flagged with IOMAP_DIO_INLINE_COMP, we can complete it inline - */ - if (dio->flags & IOMAP_DIO_INLINE_COMP) { + } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { WRITE_ONCE(iocb->private, NULL); iomap_dio_complete_work(&dio->aio.work); - goto release_bio; - } - - /* - * If this dio is flagged with IOMAP_DIO_CALLER_COMP, then schedule - * our completion that way to avoid an async punt to a workqueue. - */ - if (dio->flags & IOMAP_DIO_CALLER_COMP) { + } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { + /* + * If this dio is flagged with IOMAP_DIO_CALLER_COMP, then + * schedule our completion that way to avoid an async punt to a + * workqueue. + */ /* only polled IO cares about private cleared */ iocb->private = dio; iocb->dio_complete = iomap_dio_deferred_complete; @@ -210,19 +198,31 @@ void iomap_dio_bio_end_io(struct bio *bio) * issuer. */ iocb->ki_complete(iocb, 0); - goto release_bio; + } else { + struct inode *inode = file_inode(iocb->ki_filp); + + /* + * Async DIO completion that requires filesystem level + * completion work gets punted to a work queue to complete as + * the operation may require more IO to be issued to finalise + * filesystem metadata changes or guarantee data integrity. + */ + INIT_WORK(&dio->aio.work, iomap_dio_complete_work); + queue_work(inode->i_sb->s_dio_done_wq, &dio->aio.work); } +} + +void iomap_dio_bio_end_io(struct bio *bio) +{ + struct iomap_dio *dio = bio->bi_private; + bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); + + if (bio->bi_status) + iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); + + if (atomic_dec_and_test(&dio->ref)) + iomap_dio_done(dio); - /* - * Async DIO completion that requires filesystem level completion work - * gets punted to a work queue to complete as the operation may require - * more IO to be issued to finalise filesystem metadata changes or - * guarantee data integrity. - */ - INIT_WORK(&dio->aio.work, iomap_dio_complete_work); - queue_work(file_inode(iocb->ki_filp)->i_sb->s_dio_done_wq, - &dio->aio.work); -release_bio: if (should_dirty) { bio_check_pages_dirty(bio); } else { -- Gitee From 9fb86c3b9014edeec8f01f42053050733984a4df Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 14 Nov 2025 01:06:27 +0800 Subject: [PATCH 0376/1449] iomap: always run error completions in user context ANBZ: #35228 commit e3676761efb20564297250f000cbbd2187de2601 stable. commit ddb4873286e03e193c5a3bebb5fc6fa820e9ee3a upstream. At least zonefs expects error completions to be able to sleep. Because error completions aren't performance critical, just defer them to workqueue context unconditionally. Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system") Signed-off-by: Christoph Hellwig Link: https://patch.msgid.link/20251113170633.1453259-3-hch@lst.de Reviewed-by: Jan Kara Reviewed-by: Chaitanya Kulkarni Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/iomap/direct-io.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index 1b0f06e7e58d..8158ab18e1ae 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -172,7 +172,18 @@ static void iomap_dio_done(struct iomap_dio *dio) WRITE_ONCE(dio->submit.waiter, NULL); blk_wake_io_task(waiter); - } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { + return; + } + + /* + * Always run error completions in user context. These are not + * performance critical and some code relies on taking sleeping locks + * for error handling. + */ + if (dio->error) + dio->flags &= ~IOMAP_DIO_INLINE_COMP; + + if (dio->flags & IOMAP_DIO_INLINE_COMP) { WRITE_ONCE(iocb->private, NULL); iomap_dio_complete_work(&dio->aio.work); } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { -- Gitee From f4073c30dd44cb9c2aa8ecc28fed1337ec959c63 Mon Sep 17 00:00:00 2001 From: Ria Thomas Date: Mon, 24 Nov 2025 20:56:37 +0800 Subject: [PATCH 0377/1449] wifi: ieee80211: correct FILS status codes ANBZ: #35228 commit 26fa6991683fc7ae3d3712cb89efa326bbce2131 stable. commit 24d4da5c2565313c2ad3c43449937a9351a64407 upstream. The FILS status codes are set to 108/109, but the IEEE 802.11-2020 spec defines them as 112/113. Update the enum so it matches the specification and keeps the kernel consistent with standard values. Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") Signed-off-by: Ria Thomas Reviewed-by: Jeff Johnson Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/ieee80211.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 0ff10007eb1a..38e3e81b880f 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -3297,8 +3297,8 @@ enum ieee80211_statuscode { WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, /* 802.11ai */ - WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, - WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, + WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, + WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, WLAN_STATUS_SAE_PK = 127, }; -- Gitee From abf3d3dabeddf6fe1847382e308c5a6ce6ebbca0 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Tue, 20 May 2025 04:19:11 +0800 Subject: [PATCH 0378/1449] backlight: led-bl: Add devlink to supplier LEDs ANBZ: #35228 commit 30cbe4b642745a9488a0f0d78be43afe69d7555c stable. commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d upstream. LED Backlight is a consumer of one or multiple LED class devices, but devlink is currently unable to create correct supplier-producer links when the supplier is a class device. It creates instead a link where the supplier is the parent of the expected device. One consequence is that removal order is not correctly enforced. Issues happen for example with the following sections in a device tree overlay: // An LED driver chip pca9632@62 { compatible = "nxp,pca9632"; reg = <0x62>; // ... addon_led_pwm: led-pwm@3 { reg = <3>; label = "addon:led:pwm"; }; }; backlight-addon { compatible = "led-backlight"; leds = <&addon_led_pwm>; brightness-levels = <255>; default-brightness-level = <255>; }; In this example, the devlink should be created between the backlight-addon (consumer) and the pca9632@62 (supplier). Instead it is created between the backlight-addon (consumer) and the parent of the pca9632@62, which is typically the I2C bus adapter. On removal of the above overlay, the LED driver can be removed before the backlight device, resulting in: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 ... Call trace: led_put+0xe0/0x140 devm_led_release+0x6c/0x98 Another way to reproduce the bug without any device tree overlays is unbinding the LED class device (pca9632@62) before unbinding the consumer (backlight-addon): echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind Fix by adding a devlink between the consuming led-backlight device and the supplying LED device, as other drivers and subsystems do as well. Fixes: ae232e45acf9 ("backlight: add led-backlight driver") Signed-off-by: Luca Ceresoli Reviewed-by: Daniel Thompson (RISCstar) Reviewed-by: Herve Codina Tested-by: Alexander Sverdlin Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/backlight/led_bl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c index 0e53e427a91d..9089d17200ec 100644 --- a/drivers/video/backlight/led_bl.c +++ b/drivers/video/backlight/led_bl.c @@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) return PTR_ERR(priv->bl_dev); } + for (i = 0; i < priv->nb_leds; i++) { + struct device_link *link; + + link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, + DL_FLAG_AUTOREMOVE_CONSUMER); + if (!link) { + dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", + dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); + backlight_device_unregister(priv->bl_dev); + return -EINVAL; + } + } + for (i = 0; i < priv->nb_leds; i++) { mutex_lock(&priv->leds[i]->led_access); led_sysfs_disable(priv->leds[i]); -- Gitee From 3f1087353fca024c867cce6785bd63cc1d611fb9 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 11 Nov 2025 14:09:16 +0800 Subject: [PATCH 0379/1449] backlight: lp855x: Fix lp855x.h kernel-doc warnings ANBZ: #35228 commit 136ff909dfb90931292bd6dd41ea8a88d1d296fa stable. commit 2d45db63260c6ae3cf007361e04a1c41bd265084 upstream. Add a missing struct short description and a missing leading " *" to lp855x.h to avoid kernel-doc warnings: Warning: include/linux/platform_data/lp855x.h:126 missing initial short description on line: * struct lp855x_platform_data Warning: include/linux/platform_data/lp855x.h:131 bad line: Only valid when mode is PWM_BASED. Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") Signed-off-by: Randy Dunlap Reviewed-by: Daniel Thompson (RISCstar) Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org Signed-off-by: Lee Jones Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/platform_data/lp855x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h index ab222dd05bbc..3b4a891acefe 100644 --- a/include/linux/platform_data/lp855x.h +++ b/include/linux/platform_data/lp855x.h @@ -124,12 +124,12 @@ struct lp855x_rom_data { }; /** - * struct lp855x_platform_data + * struct lp855x_platform_data - lp855 platform-specific data * @name : Backlight driver name. If it is not defined, default name is set. * @device_control : value of DEVICE CONTROL register * @initial_brightness : initial value of backlight brightness * @period_ns : platform specific pwm period value. unit is nano. - Only valid when mode is PWM_BASED. + * Only valid when mode is PWM_BASED. * @size_program : total size of lp855x_rom_data * @rom_data : list of new eeprom/eprom registers */ -- Gitee From 6947107e292da91aa16bcb4c94b6a66bb3c31a29 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 21 Aug 2025 16:33:53 +0800 Subject: [PATCH 0380/1449] iommu/arm-smmu-qcom: Enable use of all SMR groups when running bare-metal ANBZ: #35228 commit 599632e08859db6b0939653ac38dc3cb727f65cf stable. commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c upstream. Some platforms (e.g. SC8280XP and X1E) support more than 128 stream matching groups. This is more than what is defined as maximum by the ARM SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") disabled use of the additional groups because they don't exhibit the same behavior as the architecture supported ones. It seems like this is just another quirk of the hypervisor: When running bare-metal without the hypervisor, the additional groups appear to behave just like all others. The boot firmware uses some of the additional groups, so ignoring them in this situation leads to stream match conflicts whenever we allocate a new SMR group for the same SID. The workaround exists primarily because the bypass quirk detection fails when using a S2CR register from the additional matching groups, so let's perform the test with the last reliable S2CR (127) and then limit the number of SMR groups only if we detect that we are running below the hypervisor (because of the bypass quirk). Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") Signed-off-by: Stephan Gerhold Signed-off-by: Will Deacon Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c index 0c35a235ab6d..1a72d067e584 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -299,17 +299,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) /* * Some platforms support more than the Arm SMMU architected maximum of - * 128 stream matching groups. For unknown reasons, the additional - * groups don't exhibit the same behavior as the architected registers, - * so limit the groups to 128 until the behavior is fixed for the other - * groups. + * 128 stream matching groups. The additional registers appear to have + * the same behavior as the architected registers in the hardware. + * However, on some firmware versions, the hypervisor does not + * correctly trap and emulate accesses to the additional registers, + * resulting in unexpected behavior. + * + * If there are more than 128 groups, use the last reliable group to + * detect if we need to apply the bypass quirk. */ - if (smmu->num_mapping_groups > 128) { - dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); - smmu->num_mapping_groups = 128; - } - - last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + if (smmu->num_mapping_groups > 128) + last_s2cr = ARM_SMMU_GR0_S2CR(127); + else + last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); /* * With some firmware versions writes to S2CR of type FAULT are @@ -332,6 +334,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); + + if (smmu->num_mapping_groups > 128) { + dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); + smmu->num_mapping_groups = 128; + } } for (i = 0; i < smmu->num_mapping_groups; i++) { -- Gitee From 50321a759bfb7b3b5998afaf5f30ae60ac74ac8a Mon Sep 17 00:00:00 2001 From: Krzysztof Czurylo Date: Tue, 25 Nov 2025 10:53:42 +0800 Subject: [PATCH 0381/1449] RDMA/irdma: Fix data race in irdma_sc_ccq_arm ANBZ: #35228 commit 444de2316b098ce57a11a8c9bae1b3b29e520165 stable. commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 upstream. Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: irdma_sc_ccq_arm+0x36/0xd0 [irdma] irdma_cqp_ce_handler+0x300/0x310 [irdma] cqp_compl_worker+0x2a/0x40 [irdma] process_one_work+0x402/0x7e0 worker_thread+0xb3/0x6d0 kthread+0x178/0x1a0 ret_from_fork+0x2c/0x50 write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: irdma_sc_ccq_arm+0x7e/0xd0 [irdma] irdma_cqp_ce_handler+0x300/0x310 [irdma] irdma_wait_event+0xd4/0x3e0 [irdma] irdma_handle_cqp_op+0xa5/0x220 [irdma] irdma_hw_flush_wqes+0xb1/0x300 [irdma] irdma_flush_wqes+0x22e/0x3a0 [irdma] irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] irdma_disconnect_worker+0x35/0x50 [irdma] process_one_work+0x402/0x7e0 worker_thread+0xb3/0x6d0 kthread+0x178/0x1a0 ret_from_fork+0x2c/0x50 value changed: 0x0000000000024000 -> 0x0000000000034000 Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") Signed-off-by: Krzysztof Czurylo Signed-off-by: Tatyana Nikolova Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/irdma/ctrl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c index 8a6200e55c54..ebbece4f09a2 100644 --- a/drivers/infiniband/hw/irdma/ctrl.c +++ b/drivers/infiniband/hw/irdma/ctrl.c @@ -3316,11 +3316,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) */ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) { + unsigned long flags; u64 temp_val; u16 sw_cq_sel; u8 arm_next_se; u8 arm_seq_num; + spin_lock_irqsave(&ccq->dev->cqp_lock, flags); get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); @@ -3331,6 +3333,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); + spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); dma_wmb(); /* make sure shadow area is updated before arming */ -- Gitee From 69954d1ceddb50cbfcb18d907c88e64b9dc99e18 Mon Sep 17 00:00:00 2001 From: Krzysztof Czurylo Date: Tue, 25 Nov 2025 10:53:43 +0800 Subject: [PATCH 0382/1449] RDMA/irdma: Fix data race in irdma_free_pble ANBZ: #35228 commit 8c7b21f374948089d9688bb5fe8509838faee8e7 stable. commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 upstream. Protects pble_rsrc counters with mutex to prevent data race. Fixes the following data race in irdma_free_pble reported by KCSAN: BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: irdma_free_pble+0x3b/0xb0 [irdma] irdma_dereg_mr+0x108/0x110 [irdma] ib_dereg_mr_user+0x74/0x160 [ib_core] uverbs_free_mr+0x26/0x30 [ib_uverbs] destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] uobj_destroy+0x61/0xb0 [ib_uverbs] ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] __x64_sys_ioctl+0xc9/0x100 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: irdma_free_pble+0x23/0xb0 [irdma] irdma_dereg_mr+0x108/0x110 [irdma] ib_dereg_mr_user+0x74/0x160 [ib_core] uverbs_free_mr+0x26/0x30 [ib_uverbs] destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] uobj_destroy+0x61/0xb0 [ib_uverbs] ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] __x64_sys_ioctl+0xc9/0x100 do_syscall_64+0x44/0xa0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 value changed: 0x0000000000005a62 -> 0x0000000000005a68 Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") Signed-off-by: Krzysztof Czurylo Signed-off-by: Tatyana Nikolova Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/irdma/pble.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c index fa096557adc8..c7bcdc1bf931 100644 --- a/drivers/infiniband/hw/irdma/pble.c +++ b/drivers/infiniband/hw/irdma/pble.c @@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, struct irdma_pble_alloc *palloc) { - pble_rsrc->freedpbles += palloc->total_cnt; - if (palloc->level == PBLE_LEVEL_2) free_lvl2(pble_rsrc, palloc); else irdma_prm_return_pbles(&pble_rsrc->pinfo, &palloc->level1.chunkinfo); + + mutex_lock(&pble_rsrc->pble_mutex_lock); + pble_rsrc->freedpbles += palloc->total_cnt; pble_rsrc->stats_alloc_freed++; + mutex_unlock(&pble_rsrc->pble_mutex_lock); } -- Gitee From 7de0d03a1a161f480b96825ae18971eae940c105 Mon Sep 17 00:00:00 2001 From: Sindhu Devale Date: Wed, 4 Oct 2023 23:13:06 +0800 Subject: [PATCH 0383/1449] RDMA/irdma: Add support to re-register a memory region ANBZ: #35228 commit 715fdb3b30541cc8180b7cdc6aa9f8c307afdf25 stable. commit 5ac388db27c443dadfbb0b8b23fa7ccf429d901a upstream. Add support for reregister MR verb API by doing a de-register followed by a register MR with the new attributes. Reuse resources like iwmr handle and HW stag where possible. Signed-off-by: Sindhu Devale Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20231004151306.228-1-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky Stable-dep-of: 71d3bdae5eab ("RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/irdma/verbs.c | 232 ++++++++++++++++++++++------ drivers/infiniband/hw/irdma/verbs.h | 2 + 2 files changed, 191 insertions(+), 43 deletions(-) diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index 29540b2b2373..aece20f10591 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -2661,8 +2661,11 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, cqp_info->in.u.alloc_stag.scratch = (uintptr_t)cqp_request; status = irdma_handle_cqp_op(iwdev->rf, cqp_request); irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + if (status) + return status; - return status; + iwmr->is_hwreg = 1; + return 0; } /** @@ -2828,14 +2831,18 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, ret = irdma_handle_cqp_op(iwdev->rf, cqp_request); irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + if (!ret) + iwmr->is_hwreg = 1; + return ret; } -static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access) +static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access, + bool create_stag) { struct irdma_device *iwdev = to_iwdev(iwmr->ibmr.device); struct irdma_pbl *iwpbl = &iwmr->iwpbl; - u32 stag; + u32 stag = 0; u8 lvl; int err; @@ -2854,15 +2861,18 @@ static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access) } } - stag = irdma_create_stag(iwdev); - if (!stag) { - err = -ENOMEM; - goto free_pble; + if (create_stag) { + stag = irdma_create_stag(iwdev); + if (!stag) { + err = -ENOMEM; + goto free_pble; + } + + iwmr->stag = stag; + iwmr->ibmr.rkey = stag; + iwmr->ibmr.lkey = stag; } - iwmr->stag = stag; - iwmr->ibmr.rkey = stag; - iwmr->ibmr.lkey = stag; err = irdma_hwreg_mr(iwdev, iwmr, access); if (err) goto err_hwreg; @@ -2870,7 +2880,8 @@ static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access) return 0; err_hwreg: - irdma_free_stag(iwdev, stag); + if (stag) + irdma_free_stag(iwdev, stag); free_pble: if (iwpbl->pble_alloc.level != PBLE_LEVEL_0 && iwpbl->pbl_allocated) @@ -3050,7 +3061,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, goto error; break; case IRDMA_MEMREG_TYPE_MEM: - err = irdma_reg_user_mr_type_mem(iwmr, access); + err = irdma_reg_user_mr_type_mem(iwmr, access, true); if (err) goto error; @@ -3094,7 +3105,7 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start, goto err_release; } - err = irdma_reg_user_mr_type_mem(iwmr, access); + err = irdma_reg_user_mr_type_mem(iwmr, access, true); if (err) goto err_iwmr; @@ -3109,6 +3120,161 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start, return ERR_PTR(err); } +static int irdma_hwdereg_mr(struct ib_mr *ib_mr) +{ + struct irdma_device *iwdev = to_iwdev(ib_mr->device); + struct irdma_mr *iwmr = to_iwmr(ib_mr); + struct irdma_pd *iwpd = to_iwpd(ib_mr->pd); + struct irdma_dealloc_stag_info *info; + struct irdma_pbl *iwpbl = &iwmr->iwpbl; + struct irdma_cqp_request *cqp_request; + struct cqp_cmds_info *cqp_info; + int status; + + /* Skip HW MR de-register when it is already de-registered + * during an MR re-reregister and the re-registration fails + */ + if (!iwmr->is_hwreg) + return 0; + + cqp_request = irdma_alloc_and_get_cqp_request(&iwdev->rf->cqp, true); + if (!cqp_request) + return -ENOMEM; + + cqp_info = &cqp_request->info; + info = &cqp_info->in.u.dealloc_stag.info; + memset(info, 0, sizeof(*info)); + info->pd_id = iwpd->sc_pd.pd_id; + info->stag_idx = ib_mr->rkey >> IRDMA_CQPSQ_STAG_IDX_S; + info->mr = true; + if (iwpbl->pbl_allocated) + info->dealloc_pbl = true; + + cqp_info->cqp_cmd = IRDMA_OP_DEALLOC_STAG; + cqp_info->post_sq = 1; + cqp_info->in.u.dealloc_stag.dev = &iwdev->rf->sc_dev; + cqp_info->in.u.dealloc_stag.scratch = (uintptr_t)cqp_request; + status = irdma_handle_cqp_op(iwdev->rf, cqp_request); + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + if (status) + return status; + + iwmr->is_hwreg = 0; + return 0; +} + +/* + * irdma_rereg_mr_trans - Re-register a user MR for a change translation. + * @iwmr: ptr of iwmr + * @start: virtual start address + * @len: length of mr + * @virt: virtual address + * + * Re-register a user memory region when a change translation is requested. + * Re-register a new region while reusing the stag from the original registration. + */ +static int irdma_rereg_mr_trans(struct irdma_mr *iwmr, u64 start, u64 len, + u64 virt) +{ + struct irdma_device *iwdev = to_iwdev(iwmr->ibmr.device); + struct irdma_pbl *iwpbl = &iwmr->iwpbl; + struct ib_pd *pd = iwmr->ibmr.pd; + struct ib_umem *region; + int err; + + region = ib_umem_get(pd->device, start, len, iwmr->access); + if (IS_ERR(region)) + return PTR_ERR(region); + + iwmr->region = region; + iwmr->ibmr.iova = virt; + iwmr->ibmr.pd = pd; + iwmr->page_size = ib_umem_find_best_pgsz(region, + iwdev->rf->sc_dev.hw_attrs.page_size_cap, + virt); + if (unlikely(!iwmr->page_size)) { + err = -EOPNOTSUPP; + goto err; + } + + iwmr->len = region->length; + iwpbl->user_base = virt; + iwmr->page_cnt = ib_umem_num_dma_blocks(region, iwmr->page_size); + + err = irdma_reg_user_mr_type_mem(iwmr, iwmr->access, false); + if (err) + goto err; + + return 0; + +err: + ib_umem_release(region); + return err; +} + +/* + * irdma_rereg_user_mr - Re-Register a user memory region(MR) + * @ibmr: ib mem to access iwarp mr pointer + * @flags: bit mask to indicate which of the attr's of MR modified + * @start: virtual start address + * @len: length of mr + * @virt: virtual address + * @new_access: bit mask of access flags + * @new_pd: ptr of pd + * @udata: user data + * + * Return: + * NULL - Success, existing MR updated + * ERR_PTR - error occurred + */ +static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, + u64 start, u64 len, u64 virt, + int new_access, struct ib_pd *new_pd, + struct ib_udata *udata) +{ + struct irdma_device *iwdev = to_iwdev(ib_mr->device); + struct irdma_mr *iwmr = to_iwmr(ib_mr); + struct irdma_pbl *iwpbl = &iwmr->iwpbl; + int ret; + + if (len > iwdev->rf->sc_dev.hw_attrs.max_mr_size) + return ERR_PTR(-EINVAL); + + if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS)) + return ERR_PTR(-EOPNOTSUPP); + + ret = irdma_hwdereg_mr(ib_mr); + if (ret) + return ERR_PTR(ret); + + if (flags & IB_MR_REREG_ACCESS) + iwmr->access = new_access; + + if (flags & IB_MR_REREG_PD) { + iwmr->ibmr.pd = new_pd; + iwmr->ibmr.device = new_pd->device; + } + + if (flags & IB_MR_REREG_TRANS) { + if (iwpbl->pbl_allocated) { + irdma_free_pble(iwdev->rf->pble_rsrc, + &iwpbl->pble_alloc); + iwpbl->pbl_allocated = false; + } + if (iwmr->region) { + ib_umem_release(iwmr->region); + iwmr->region = NULL; + } + + ret = irdma_rereg_mr_trans(iwmr, start, len, virt); + } else + ret = irdma_hwreg_mr(iwdev, iwmr, iwmr->access); + if (ret) + return ERR_PTR(ret); + + return NULL; +} + /** * irdma_reg_phys_mr - register kernel physical memory * @pd: ibpd pointer @@ -3216,16 +3382,10 @@ static void irdma_del_memlist(struct irdma_mr *iwmr, */ static int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata) { - struct ib_pd *ibpd = ib_mr->pd; - struct irdma_pd *iwpd = to_iwpd(ibpd); struct irdma_mr *iwmr = to_iwmr(ib_mr); struct irdma_device *iwdev = to_iwdev(ib_mr->device); - struct irdma_dealloc_stag_info *info; struct irdma_pbl *iwpbl = &iwmr->iwpbl; - struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc; - struct irdma_cqp_request *cqp_request; - struct cqp_cmds_info *cqp_info; - int status; + int ret; if (iwmr->type != IRDMA_MEMREG_TYPE_MEM) { if (iwmr->region) { @@ -3239,33 +3399,18 @@ static int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata) goto done; } - cqp_request = irdma_alloc_and_get_cqp_request(&iwdev->rf->cqp, true); - if (!cqp_request) - return -ENOMEM; - - cqp_info = &cqp_request->info; - info = &cqp_info->in.u.dealloc_stag.info; - memset(info, 0, sizeof(*info)); - info->pd_id = iwpd->sc_pd.pd_id; - info->stag_idx = ib_mr->rkey >> IRDMA_CQPSQ_STAG_IDX_S; - info->mr = true; - if (iwpbl->pbl_allocated) - info->dealloc_pbl = true; - - cqp_info->cqp_cmd = IRDMA_OP_DEALLOC_STAG; - cqp_info->post_sq = 1; - cqp_info->in.u.dealloc_stag.dev = &iwdev->rf->sc_dev; - cqp_info->in.u.dealloc_stag.scratch = (uintptr_t)cqp_request; - status = irdma_handle_cqp_op(iwdev->rf, cqp_request); - irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); - if (status) - return status; + ret = irdma_hwdereg_mr(ib_mr); + if (ret) + return ret; irdma_free_stag(iwdev, iwmr->stag); done: if (iwpbl->pbl_allocated) - irdma_free_pble(iwdev->rf->pble_rsrc, palloc); - ib_umem_release(iwmr->region); + irdma_free_pble(iwdev->rf->pble_rsrc, &iwpbl->pble_alloc); + + if (iwmr->region) + ib_umem_release(iwmr->region); + kfree(iwmr); return 0; @@ -4595,6 +4740,7 @@ static const struct ib_device_ops irdma_dev_ops = { .query_qp = irdma_query_qp, .reg_user_mr = irdma_reg_user_mr, .reg_user_mr_dmabuf = irdma_reg_user_mr_dmabuf, + .rereg_user_mr = irdma_rereg_user_mr, .req_notify_cq = irdma_req_notify_cq, .resize_cq = irdma_resize_cq, INIT_RDMA_OBJ_SIZE(ib_pd, irdma_pd, ibpd), diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h index bb9ab945938e..533b4597c407 100644 --- a/drivers/infiniband/hw/irdma/verbs.h +++ b/drivers/infiniband/hw/irdma/verbs.h @@ -100,6 +100,8 @@ struct irdma_mr { struct ib_mw ibmw; }; struct ib_umem *region; + int access; + u8 is_hwreg; u16 type; u32 page_cnt; u64 page_size; -- Gitee From 1c53c8a04bced05e3685f30b311737f8823c3715 Mon Sep 17 00:00:00 2001 From: Jacob Moroni Date: Tue, 25 Nov 2025 10:53:47 +0800 Subject: [PATCH 0384/1449] RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY ANBZ: #35228 commit aaf2a6097116d3162a2a1b0ede49a68913470ffa stable. commit 71d3bdae5eab21cf8991a6f3cd914caa31d5a51f upstream. The HW disables bounds checking for MRs with a length of zero, so the driver will only allow a zero length MR if the "all_memory" flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY is set for the PD. This means that the "get_dma_mr" method will currently fail unless the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue because the "get_dma_mr" method is only ever invoked if the device does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY is set, and so far, all IRDMA HW supports the local DMA lkey. However, some new HW does not support the local DMA lkey, so the "get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY being set. To support HW that does not allow the local DMA lkey, the logic has been changed to pass an explicit flag to indicate when a dma_mr is being created so that the zero length will be allowed. Also, the "all_memory" flag has been forced to false for normal MR allocation since these MRs are never supposed to provide global unsafe rkey semantics anyway; only the MR created with "get_dma_mr" should support this. Fixes: bb6d73d9add6 ("RDMA/irdma: Prevent zero-length STAG registration") Signed-off-by: Jacob Moroni Signed-off-by: Tatyana Nikolova Link: https://patch.msgid.link/20251125025350.180-7-tatyana.e.nikolova@intel.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/irdma/cm.c | 2 +- drivers/infiniband/hw/irdma/main.h | 2 +- drivers/infiniband/hw/irdma/verbs.c | 15 ++++++++------- drivers/infiniband/hw/irdma/verbs.h | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c index 1916daa8c332..b3f14816251b 100644 --- a/drivers/infiniband/hw/irdma/cm.c +++ b/drivers/infiniband/hw/irdma/cm.c @@ -3708,7 +3708,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) iwpd = iwqp->iwpd; tagged_offset = (uintptr_t)iwqp->ietf_mem.va; ibmr = irdma_reg_phys_mr(&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len, - IB_ACCESS_LOCAL_WRITE, &tagged_offset); + IB_ACCESS_LOCAL_WRITE, &tagged_offset, false); if (IS_ERR(ibmr)) { ret = -ENOMEM; goto error; diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h index cbf0db72e108..28963e19d955 100644 --- a/drivers/infiniband/hw/irdma/main.h +++ b/drivers/infiniband/hw/irdma/main.h @@ -535,7 +535,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src); u16 irdma_get_vlan_ipv4(u32 *addr); void irdma_get_vlan_mac_ipv6(u32 *addr, u16 *vlan_id, u8 *mac); struct ib_mr *irdma_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size, - int acc, u64 *iova_start); + int acc, u64 *iova_start, bool dma_mr); int irdma_upload_qp_context(struct irdma_qp *iwqp, bool freeze, bool raw); void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq); int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd, diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index aece20f10591..b52e0716d23f 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -2653,7 +2653,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S; info->pd_id = iwpd->sc_pd.pd_id; info->total_len = iwmr->len; - info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; info->remote_access = true; cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG; cqp_info->post_sq = 1; @@ -2664,7 +2663,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, if (status) return status; - iwmr->is_hwreg = 1; + iwmr->is_hwreg = true; return 0; } @@ -2805,7 +2804,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, stag_info->total_len = iwmr->len; stag_info->access_rights = irdma_get_mr_access(access); stag_info->pd_id = iwpd->sc_pd.pd_id; - stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; + stag_info->all_memory = iwmr->dma_mr; if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED) stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED; else @@ -2832,7 +2831,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); if (!ret) - iwmr->is_hwreg = 1; + iwmr->is_hwreg = true; return ret; } @@ -3159,7 +3158,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr) if (status) return status; - iwmr->is_hwreg = 0; + iwmr->is_hwreg = false; return 0; } @@ -3282,9 +3281,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, * @size: size of memory to register * @access: Access rights * @iova_start: start of virtual address for physical buffers + * @dma_mr: Flag indicating whether this region is a PD DMA MR */ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access, - u64 *iova_start) + u64 *iova_start, bool dma_mr) { struct irdma_device *iwdev = to_iwdev(pd->device); struct irdma_pbl *iwpbl; @@ -3301,6 +3301,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access iwpbl = &iwmr->iwpbl; iwpbl->iwmr = iwmr; iwmr->type = IRDMA_MEMREG_TYPE_MEM; + iwmr->dma_mr = dma_mr; iwpbl->user_base = *iova_start; stag = irdma_create_stag(iwdev); if (!stag) { @@ -3339,7 +3340,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc) { u64 kva = 0; - return irdma_reg_phys_mr(pd, 0, 0, acc, &kva); + return irdma_reg_phys_mr(pd, 0, 0, acc, &kva, true); } /** diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h index 533b4597c407..97abd45a5cee 100644 --- a/drivers/infiniband/hw/irdma/verbs.h +++ b/drivers/infiniband/hw/irdma/verbs.h @@ -101,7 +101,8 @@ struct irdma_mr { }; struct ib_umem *region; int access; - u8 is_hwreg; + bool is_hwreg:1; + bool dma_mr:1; u16 type; u32 page_cnt; u64 page_size; -- Gitee From a66589e3c4cd98750679ec940b5e584d04906e37 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 26 Nov 2025 14:45:09 +0800 Subject: [PATCH 0385/1449] ASoC: fsl_xcvr: clear the channel status control memory ANBZ: #35228 commit 6dca0f3f61ab747b2e4aecee55372ec5bc2e7e34 stable. commit 73b97d46dde64fa184d47865d4a532d818c3a007 upstream. memset_io() writes memory byte by byte with __raw_writeb() on the arm platform if the size is word. but XCVR data RAM memory can't be accessed with byte address, so with memset_io() the channel status control memory is not really cleared, use writel_relaxed() instead. Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/fsl/fsl_xcvr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 1d7791c7fb4e..90a0a24c05d8 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1195,7 +1195,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) bitrev32(val); } /* clear CS control register */ - memset_io(reg_ctrl, 0, sizeof(val)); + writel_relaxed(0, reg_ctrl); } } else { regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, -- Gitee From 114a7e3ab1ddf0e61213cecc450ba7541bd63d90 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 31 Oct 2025 21:02:25 +0800 Subject: [PATCH 0386/1449] drm/amd/display: Fix logical vs bitwise bug in get_embedded_panel_info_v2_1() ANBZ: #35228 commit e84690a05e4797b995729b09cca35c7c67a4fe8c stable. commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 upstream. The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 then the last bit is always 1 so this code always sets .H_SYNC_POLARITY and .V_SYNC_POLARITY to true. This code is instead intended to check if the ATOM_HSYNC_POLARITY or ATOM_VSYNC_POLARITY flags are set and reverse the result. In other words, it's supposed to be a logical negate instead of a bitwise negate. Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") Signed-off-by: Dan Carpenter Reviewed-by: Alex Hung Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 384ddb28e6f6..c0a705888cb5 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -1477,10 +1477,10 @@ static enum bp_result get_embedded_panel_info_v2_1( /* not provided by VBIOS */ info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; - info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo - & ATOM_HSYNC_POLARITY); - info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo - & ATOM_VSYNC_POLARITY); + info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & + ATOM_HSYNC_POLARITY); + info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & + ATOM_VSYNC_POLARITY); /* not provided by VBIOS */ info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; -- Gitee From f42df4c2ec626ba6bc1180b65d4216c5eb018980 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Thu, 27 Nov 2025 00:26:02 +0800 Subject: [PATCH 0387/1449] hwmon: sy7636a: Fix regulator_enable resource leak on error path ANBZ: #35228 commit 1968f2ab4188f2828d780d793d2753e889e0bc95 stable. commit 2f88425ef590b7fcc2324334b342e048edc144a9 upstream. In sy7636a_sensor_probe(), regulator_enable() is called but if devm_hwmon_device_register_with_info() fails, the function returns without calling regulator_disable(), leaving the regulator enabled and leaking the reference count. Switch to devm_regulator_get_enable() to automatically manage the regulator resource. Fixes: de34a4053250 ("hwmon: sy7636a: Add temperature driver for sy7636a") Suggested-by: Guenter Roeck Signed-off-by: Haotian Zhang Link: https://lore.kernel.org/r/20251126162602.2086-1-vulab@iscas.ac.cn Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/sy7636a-hwmon.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c index a12fc0ce70e7..d51daaf63d63 100644 --- a/drivers/hwmon/sy7636a-hwmon.c +++ b/drivers/hwmon/sy7636a-hwmon.c @@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = { static int sy7636a_sensor_probe(struct platform_device *pdev) { struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); - struct regulator *regulator; struct device *hwmon_dev; int err; if (!regmap) return -EPROBE_DEFER; - regulator = devm_regulator_get(&pdev->dev, "vcom"); - if (IS_ERR(regulator)) - return PTR_ERR(regulator); - - err = regulator_enable(regulator); + err = devm_regulator_get_enable(&pdev->dev, "vcom"); if (err) return err; -- Gitee From dfbd98b99fdb222dfb0cde34de65f02eb1018002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Wed, 26 Nov 2025 23:55:13 +0800 Subject: [PATCH 0388/1449] ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit c242024efd1b95f2a2874261fbd29536c9784fed stable. commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 upstream. On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace and equivalent Gigabyte, amd-pstate does not initialize when the x2apic is enabled in the BIOS. Kernel debug messages include: [ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. [ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 [ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled I tracked this down to map_x2apic_id() checking device_declaration passed in via the type argument of acpi_get_phys_id() via map_madt_entry() while map_lapic_id() does not. It appears these BIOSes use Processor statements for declaring the CPUs in the ACPI namespace instead of processor device objects (which should have been used). CPU declarations via Processor statements were deprecated in ACPI 6.0 that was released 10 years ago. They should not be used any more in any contemporary platform firmware. I tried to contact Asus support multiple times, but never received a reply nor did any BIOS update ever change this. Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with CPUs declared via Processor statements for IDs less than 255, which is consistent with ACPI 5.0 that still allowed Processor statements to be used for declaring CPUs. Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") Signed-off-by: René Rebe [ rjw: Changelog edits ] Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/processor_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 7dd6dbaa98c3..dea60d694343 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) return -ENODEV; - if (device_declaration && (apic->uid == acpi_id)) { + if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { *apic_id = apic->local_apic_id; return 0; } -- Gitee From 87d2adfd992994786a35e6afb88e22681fb27d1b Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 9 Oct 2023 17:33:17 +0800 Subject: [PATCH 0389/1449] ublk: make sure io cmd handled in submitter task context ANBZ: #35228 commit 84ea891dc897532822651ca15d59ddd87c6790fb stable. commit 3421c7f68bba52281bbb38bc76c18dc03cb689e4 upstream. In well-done ublk server implementation, ublk io command won't be linked into any link chain. Meantime they are always handled in no-wait style, so basically io cmd is always handled in submitter task context. However, the server may set IOSQE_ASYNC, or io command is linked to one chain mistakenly, then we may still run into io-wq context and ctx->uring_lock isn't held. So in case of IO_URING_F_UNLOCKED, schedule this command by io_uring_cmd_complete_in_task to force running it in submitter task. Then ublk_ch_uring_cmd_local() is guaranteed to run with context uring_lock held, and we needn't to worry about sync among submission code path any more. Signed-off-by: Ming Lei Link: https://lore.kernel.org/r/20231009093324.957829-3-ming.lei@redhat.com Signed-off-by: Jens Axboe Stable-dep-of: c6a45ee7607d ("ublk: prevent invalid access with DEBUG") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/ublk_drv.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index ec6d7a08104d..6419f304fa5e 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1857,7 +1857,8 @@ static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, return NULL; } -static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) +static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, + unsigned int issue_flags) { /* * Not necessary for async retry, but let's keep it simple and always @@ -1871,9 +1872,28 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) .addr = READ_ONCE(ub_src->addr) }; + WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED); + return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd); } +static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd, + unsigned int issue_flags) +{ + ublk_ch_uring_cmd_local(cmd, issue_flags); +} + +static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) +{ + /* well-implemented server won't run into unlocked */ + if (unlikely(issue_flags & IO_URING_F_UNLOCKED)) { + io_uring_cmd_complete_in_task(cmd, ublk_ch_uring_cmd_cb); + return -EIOCBQUEUED; + } + + return ublk_ch_uring_cmd_local(cmd, issue_flags); +} + static inline bool ublk_check_ubuf_dir(const struct request *req, int ubuf_dir) { -- Gitee From ddeaa06f4cad6a9d037e673a56f13fe7fe461436 Mon Sep 17 00:00:00 2001 From: Caleb Sander Mateos Date: Wed, 26 Feb 2025 05:24:55 +0800 Subject: [PATCH 0390/1449] ublk: complete command synchronously on error ANBZ: #35228 commit 0a0a51092c1c0332d33713088864919549447b35 stable. commit 603f9be21c1894e462416e3324962d6c9c2b95f8 upstream. In case of an error, ublk's ->uring_cmd() functions currently return -EIOCBQUEUED and immediately call io_uring_cmd_done(). -EIOCBQUEUED and io_uring_cmd_done() are intended for asynchronous completions. For synchronous completions, the ->uring_cmd() function can just return the negative return code directly. This skips io_uring_cmd_del_cancelable(), and deferring the completion to task work. So return the error code directly from __ublk_ch_uring_cmd() and ublk_ctrl_uring_cmd(). Update ublk_ch_uring_cmd_cb(), which currently ignores the return value from __ublk_ch_uring_cmd(), to call io_uring_cmd_done() for synchronous completions. Signed-off-by: Caleb Sander Mateos Reviewed-by: Ming Lei Reviewed-by: Keith Busch Link: https://lore.kernel.org/r/20250225212456.2902549-1-csander@purestorage.com Signed-off-by: Jens Axboe Stable-dep-of: c6a45ee7607d ("ublk: prevent invalid access with DEBUG") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/ublk_drv.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 6419f304fa5e..88d566f0ffa6 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1821,10 +1821,9 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, return -EIOCBQUEUED; out: - io_uring_cmd_done(cmd, ret, 0, issue_flags); pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", __func__, cmd_op, tag, ret, io->flags); - return -EIOCBQUEUED; + return ret; } static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, @@ -1880,7 +1879,10 @@ static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd, unsigned int issue_flags) { - ublk_ch_uring_cmd_local(cmd, issue_flags); + int ret = ublk_ch_uring_cmd_local(cmd, issue_flags); + + if (ret != -EIOCBQUEUED) + io_uring_cmd_done(cmd, ret, 0, issue_flags); } static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) @@ -2948,10 +2950,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, if (ub) ublk_put_device(ub); out: - io_uring_cmd_done(cmd, ret, 0, issue_flags); pr_devel("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n", __func__, ret, cmd->cmd_op, header->dev_id, header->queue_id); - return -EIOCBQUEUED; + return ret; } static const struct file_operations ublk_ctl_fops = { -- Gitee From 7ad0a49f7028aa9dc18df6d8d09ffbbc40fc45fc Mon Sep 17 00:00:00 2001 From: Kevin Brodsky Date: Wed, 26 Nov 2025 20:48:35 +0800 Subject: [PATCH 0391/1449] ublk: prevent invalid access with DEBUG ANBZ: #35228 commit db5deba07f53a7f3c212fbe1bfe35cdca5769bc2 stable. commit c6a45ee7607de3a350008630f4369b1b5ac80884 upstream. ublk_ch_uring_cmd_local() may jump to the out label before initialising the io pointer. This will cause trouble if DEBUG is defined, because the pr_devel() call dereferences io. Clang reports: drivers/block/ublk_drv.c:2403:6: error: variable 'io' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] 2403 | if (tag >= ub->dev_info.queue_depth) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/block/ublk_drv.c:2492:32: note: uninitialized use occurs here 2492 | __func__, cmd_op, tag, ret, io->flags); | Fix this by initialising io to NULL and checking it before dereferencing it. Signed-off-by: Kevin Brodsky Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") Reviewed-by: Caleb Sander Mateos Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/ublk_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 88d566f0ffa6..563b2a94d4c3 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1709,7 +1709,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, { struct ublk_device *ub = cmd->file->private_data; struct ublk_queue *ubq; - struct ublk_io *io; + struct ublk_io *io = NULL; u32 cmd_op = cmd->cmd_op; unsigned tag = ub_cmd->tag; int ret = -EINVAL; @@ -1822,7 +1822,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, out: pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", - __func__, cmd_op, tag, ret, io->flags); + __func__, cmd_op, tag, ret, io ? io->flags : 0); return ret; } -- Gitee From cebd0636eb02ef8ec13e382f1a9482832d486f81 Mon Sep 17 00:00:00 2001 From: Kemeng Shi Date: Fri, 5 Jan 2024 17:20:54 +0800 Subject: [PATCH 0392/1449] ext4: remove unused return value of __mb_check_buddy ANBZ: #35228 commit 0adc8de19be01f2fa8ec3904f29ab0134a567588 stable. commit 133de5a0d8f8e32b34feaa8beae7a189482f1856 upstream. Remove unused return value of __mb_check_buddy. Signed-off-by: Kemeng Shi Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20240105092102.496631-2-shikemeng@huaweicloud.com Signed-off-by: Theodore Ts'o Stable-dep-of: d9ee3ff810f1 ("ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/mballoc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 3445f0af07b9..2960ddb7cf42 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -681,7 +681,7 @@ do { \ } \ } while (0) -static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, +static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, const char *function, int line) { struct super_block *sb = e4b->bd_sb; @@ -700,7 +700,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, void *buddy2; if (e4b->bd_info->bb_check_counter++ % 10) - return 0; + return; while (order > 1) { buddy = mb_find_buddy(e4b, order, &max); @@ -762,7 +762,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, grp = ext4_get_group_info(sb, e4b->bd_group); if (!grp) - return NULL; + return; list_for_each(cur, &grp->bb_prealloc_list) { ext4_group_t groupnr; struct ext4_prealloc_space *pa; @@ -772,7 +772,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, for (i = 0; i < pa->pa_len; i++) MB_CHECK_ASSERT(mb_test_bit(k + i, buddy)); } - return 0; } #undef MB_CHECK_ASSERT #define mb_check_buddy(e4b) __mb_check_buddy(e4b, \ -- Gitee From 19e2236ef22c618c383690565b5244eb9f47b3e4 Mon Sep 17 00:00:00 2001 From: Yongjian Sun Date: Thu, 6 Nov 2025 14:06:14 +0800 Subject: [PATCH 0393/1449] ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation ANBZ: #35228 commit 55b273382c528899874e4b75a9324d8905068442 stable. commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 upstream. When the MB_CHECK_ASSERT macro is enabled, we found that the current validation logic in __mb_check_buddy has a gap in detecting certain invalid buddy states, particularly related to order-0 (bitmap) bits. The original logic consists of three steps: 1. Validates higher-order buddies: if a higher-order bit is set, at most one of the two corresponding lower-order bits may be free; if a higher-order bit is clear, both lower-order bits must be allocated (and their bitmap bits must be 0). 2. For any set bit in order-0, ensures all corresponding higher-order bits are not free. 3. Verifies that all preallocated blocks (pa) in the group have pa_pstart within bounds and their bitmap bits marked as allocated. However, this approach fails to properly validate cases where order-0 bits are incorrectly cleared (0), allowing some invalid configurations to pass: corrupt integral order 3 1 1 order 2 1 1 1 1 order 1 1 1 1 1 1 1 1 1 order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Here we get two adjacent free blocks at order-0 with inconsistent higher-order state, and the right one shows the correct scenario. The root cause is insufficient validation of order-0 zero bits. To fix this and improve completeness without significant performance cost, we refine the logic: 1. Maintain the top-down higher-order validation, but we no longer check the cases where the higher-order bit is 0, as this case will be covered in step 2. 2. Enhance order-0 checking by examining pairs of bits: - If either bit in a pair is set (1), all corresponding higher-order bits must not be free. - If both bits are clear (0), then exactly one of the corresponding higher-order bits must be free 3. Keep the preallocation (pa) validation unchanged. This change closes the validation gap, ensuring illegal buddy states involving order-0 are correctly detected, while removing redundant checks and maintaining efficiency. Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") Suggested-by: Jan Kara Signed-off-by: Yongjian Sun Reviewed-by: Baokun Li Reviewed-by: Jan Kara Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 2960ddb7cf42..8a8b54e640bc 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -681,6 +681,24 @@ do { \ } \ } while (0) +/* + * Perform buddy integrity check with the following steps: + * + * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): + * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), + * at most one of the two corresponding lower-order bits may be clear (free). + * + * 2. Order-0 (bitmap) validation, performed on bit pairs: + * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits + * must not be free (0). + * - If both bits in a pair are clear (0, free), then exactly one of the corresponding + * higher-order bits must be free (0). + * + * 3. Preallocation (pa) list validation: + * For each preallocated block (pa) in the group: + * - Verify that pa_pstart falls within the bounds of this block group. + * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). + */ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, const char *function, int line) { @@ -722,15 +740,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, continue; } - /* both bits in buddy2 must be 1 */ - MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); - MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); - - for (j = 0; j < (1 << order); j++) { - k = (i * (1 << order)) + j; - MB_CHECK_ASSERT( - !mb_test_bit(k, e4b->bd_bitmap)); - } count++; } MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); @@ -746,15 +755,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, fragments++; fstart = i; } - continue; + } else { + fstart = -1; } - fstart = -1; - /* check used bits only */ - for (j = 0; j < e4b->bd_blkbits + 1; j++) { - buddy2 = mb_find_buddy(e4b, j, &max2); - k = i >> j; - MB_CHECK_ASSERT(k < max2); - MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); + if (!(i & 1)) { + int in_use, zero_bit_count = 0; + + in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); + for (j = 1; j < e4b->bd_blkbits + 2; j++) { + buddy2 = mb_find_buddy(e4b, j, &max2); + k = i >> j; + MB_CHECK_ASSERT(k < max2); + if (!mb_test_bit(k, buddy2)) + zero_bit_count++; + } + MB_CHECK_ASSERT(zero_bit_count == !in_use); } } MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); -- Gitee From 61cac1ac38b2bc2aa7ba73d0b2db6e67011c7132 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Thu, 2 Oct 2025 03:16:50 +0800 Subject: [PATCH 0394/1449] virtio_vdpa: fix misleading return in void function ANBZ: #35228 commit 22b11e8f0b8f09022b23fa10134bfad57fdab1fe stable. commit e40b6abe0b1247d43bc61942aa7534fca7209e44 upstream. virtio_vdpa_set_status() is declared as returning void, but it used "return vdpa_set_status()" Since vdpa_set_status() also returns void, the return statement is unnecessary and misleading. Remove it. Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") Signed-off-by: Alok Tiwari Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/virtio/virtio_vdpa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c index 06ce6d8c2e00..6855cc22ea96 100644 --- a/drivers/virtio/virtio_vdpa.c +++ b/drivers/virtio/virtio_vdpa.c @@ -93,7 +93,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) { struct vdpa_device *vdpa = vd_get_vdpa(vdev); - return vdpa_set_status(vdpa, status); + vdpa_set_status(vdpa, status); } static void virtio_vdpa_reset(struct virtio_device *vdev) -- Gitee From b28b3440943f3619c65581a943ce1b0416ad88ec Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 13 Nov 2025 17:34:31 +0800 Subject: [PATCH 0395/1449] virtio: fix typo in virtio_device_ready() comment ANBZ: #35228 commit 83dc689e138b364e89c106a8d9f28343c73d534f stable. commit 361173f95ae4b726ebbbf0bd594274f5576c4abc upstream. "coherenct" -> "coherent" Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") Message-Id: Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 2b3438de2c4d..84a9fd21df3e 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -288,7 +288,7 @@ void virtio_device_ready(struct virtio_device *dev) * specific set_status() method. * * A well behaved device will only notify a virtqueue after - * DRIVER_OK, this means the device should "see" the coherenct + * DRIVER_OK, this means the device should "see" the coherent * memory write that set vq->broken as false which is done by * the driver when it sees DRIVER_OK, then the following * driver's vring_interrupt() will see vq->broken as false so -- Gitee From ff7250d56c275b9d8005049da6154dd5a3c61f4a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 13 Nov 2025 17:34:34 +0800 Subject: [PATCH 0396/1449] virtio: fix whitespace in virtio_config_ops ANBZ: #35228 commit 1c7d1ef95abf21c6e9578b25fed8503394307745 stable. commit 7831791e77a1cd29528d4dc336ce14466aef5ba6 upstream. The finalize_features documentation uses a tab between words. Use space instead. Fixes: d16c0cd27331 ("docs: driver-api: virtio: virtio on Linux") Message-Id: <39d7685c82848dc6a876d175e33a1407f6ab3fc1.1763026134.git.mst@redhat.com> Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 84a9fd21df3e..f106d3177476 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -71,7 +71,7 @@ typedef void vq_callback_t(struct virtqueue *); * vdev: the virtio_device * This sends the driver feature bits to the device: it can change * the dev->feature bits if it wants. - * Note that despite the name this can be called any number of + * Note that despite the name this can be called any number of * times. * Returns 0 on success or error status * @bus_name: return the bus name associated with the device (optional) -- Gitee From 022b493c7434b5cf1ab5666f70cefdc5f069adf6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 13 Nov 2025 17:34:43 +0800 Subject: [PATCH 0397/1449] virtio: fix virtqueue_set_affinity() docs ANBZ: #35228 commit c1947cecdd5cb216e7382c238f3d5329a8ba5641 stable. commit 43236d8bbafff94b423afecc4a692dd90602d426 upstream. Rewrite the comment for better grammar and clarity. Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") Message-Id: Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/virtio_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index f106d3177476..7528255068fd 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -310,7 +310,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) * @vq: the virtqueue * @cpu_mask: the cpu mask * - * Pay attention the function are best-effort: the affinity hint may not be set + * Note that this function is best-effort: the affinity hint may not be set * due to config support, irq type and sharing. * */ -- Gitee From 75e247a2361300182fa2d76d009c21f03ae2d105 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Sun, 19 Oct 2025 01:46:46 +0800 Subject: [PATCH 0398/1449] vdpa/pds: use %pe for ERR_PTR() in event handler registration ANBZ: #35228 commit 84b3ea5ba85c315f9651e789054d05606a44f18a stable. commit 731ca4a4cc52fd5c5ae309edcfd2d7e54ece3321 upstream. Use %pe instead of %ps when printing ERR_PTR() values. %ps is intended for string pointers, while %pe correctly prints symbolic error names for error pointers returned via ERR_PTR(). This shows the returned error value more clearly. Fixes: 67f27b8b3a34 ("pds_vdpa: subscribe to the pds_core events") Signed-off-by: Alok Tiwari Reviewed-by: Brett Creeley Signed-off-by: Michael S. Tsirkin Message-Id: <20251018174705.1511982-1-alok.a.tiwari@oracle.com> Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/vdpa/pds/vdpa_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vdpa/pds/vdpa_dev.c b/drivers/vdpa/pds/vdpa_dev.c index 25c0fe5ec3d5..744739a708b2 100644 --- a/drivers/vdpa/pds/vdpa_dev.c +++ b/drivers/vdpa/pds/vdpa_dev.c @@ -51,7 +51,7 @@ static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv) err = pdsc_register_notify(nb); if (err) { nb->notifier_call = NULL; - dev_err(dev, "failed to register pds event handler: %ps\n", + dev_err(dev, "failed to register pds event handler: %pe\n", ERR_PTR(err)); return -EINVAL; } -- Gitee From c6bce1fec623197a85adc8cc5cfc8bb645fc1d53 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 26 Nov 2025 17:55:20 +0800 Subject: [PATCH 0399/1449] ASoC: Intel: catpt: Fix error path in hw_params() ANBZ: #35228 commit 886c8f5af8a9cab7576e5d0f19d907e5ce9395bd stable. commit 86a5b621be658fc8fe594ca6db317d64de30cce1 upstream. Do not leave any resources hanging on the DSP side if applying user settings fails. Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") Signed-off-by: Cezary Rojewski Reviewed-by: Andy Shevchenko Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/intel/catpt/pcm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index f1a5cb825ff1..10d1c15857bf 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, return CATPT_IPC_ERROR(ret); ret = catpt_dai_apply_usettings(dai, stream); - if (ret) + if (ret) { + catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); return ret; + } stream->allocated = true; return 0; -- Gitee From 262bdd652a9e8bc4161856d0e84496f6fa855274 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 26 Nov 2025 18:26:15 +0800 Subject: [PATCH 0400/1449] ARM: dts: samsung: universal_c210: turn off SDIO WLAN chip during system suspend ANBZ: #35228 commit 83a9770432f560f846e1149cd932e348ffb38d7c stable. commit 97aee67e2406ea381408915e606c5f86448f3949 upstream. Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning. Fixes: f1b0ffaa686f ("ARM: dts: exynos: Enable WLAN support for the UniversalC210 board") Signed-off-by: Marek Szyprowski Link: https://patch.msgid.link/20251126102618.3103517-2-m.szyprowski@samsung.com Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts index bdc30f8cf748..91490693432b 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts @@ -610,6 +610,7 @@ &sdhci_3 { #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&ldo5_reg>; -- Gitee From cd35de85432bc5a0f103c1d9e6bead99281f7297 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 26 Nov 2025 18:26:16 +0800 Subject: [PATCH 0401/1449] ARM: dts: samsung: exynos4210-i9100: turn off SDIO WLAN chip during system suspend ANBZ: #35228 commit 3ff05c6af301de795b1e1961254458a9db7e5999 stable. commit 863d69923bdb6f414d0a3f504f1dfaeacbc00b09 upstream. Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning. Fixes: 8620cc2f99b7 ("ARM: dts: exynos: Add devicetree file for the Galaxy S2") Signed-off-by: Marek Szyprowski Link: https://patch.msgid.link/20251126102618.3103517-3-m.szyprowski@samsung.com Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/samsung/exynos4210-i9100.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts index a076a1dfe41f..d7adf2bd8f87 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts @@ -815,6 +815,7 @@ &sdhci_3 { #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&vtf_reg>; -- Gitee From 5cf8915fe050410e8dd61e32e6b4166dcd99c399 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 26 Nov 2025 18:26:17 +0800 Subject: [PATCH 0402/1449] ARM: dts: samsung: exynos4210-trats: turn off SDIO WLAN chip during system suspend ANBZ: #35228 commit 7236e72a91ee5ee28b270ab87f6fdc979b6ed417 stable. commit 97cc9c346b2c9cde075b9420fc172137d2427711 upstream. Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning. Fixes: a19f6efc01df ("ARM: dts: exynos: Enable WLAN support for the Trats board") Signed-off-by: Marek Szyprowski Link: https://patch.msgid.link/20251126102618.3103517-4-m.szyprowski@samsung.com Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/samsung/exynos4210-trats.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts index 95e0e01b6ff6..6bd902cb8f4a 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts @@ -518,6 +518,7 @@ &sdhci_3 { #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; vmmc-supply = <&tflash_reg>; -- Gitee From 812bb95100136bdec1a3b9a5c3d54ab8ff2be93f Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 26 Nov 2025 18:26:18 +0800 Subject: [PATCH 0403/1449] ARM: dts: samsung: exynos4412-midas: turn off SDIO WLAN chip during system suspend ANBZ: #35228 commit 6338e278de4a92b41108e7bdbb6cba20fb0f31bb stable. commit 2ff147fdfa99b8cbb8c2833e685fde7c42580ae6 upstream. Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board requires it") changed default behavior of the BRCMFMAC driver, which now keeps SDIO card powered during system suspend to enable optional support for WOWL. This feature is not supported by the legacy Exynos4 based boards and leads to WLAN disfunction after system suspend/resume cycle. Fix this by annotating SDIO host used by WLAN chip with 'cap-power-off-card' property, which should have been there from the beginning. Fixes: f77cbb9a3e5d ("ARM: dts: exynos: Add bcm4334 device node to Trats2") Signed-off-by: Marek Szyprowski Link: https://patch.msgid.link/20251126102618.3103517-5-m.szyprowski@samsung.com Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/samsung/exynos4412-midas.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi index 7daf25865551..a77e57645f21 100644 --- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi @@ -1440,6 +1440,7 @@ &sdhci_3 { #address-cells = <1>; #size-cells = <0>; non-removable; + cap-power-off-card; bus-width = <4>; mmc-pwrseq = <&wlan_pwrseq>; -- Gitee From cbd2780baf24649ba2d2ae969ee47768aa6f0e8e Mon Sep 17 00:00:00 2001 From: sparkhuang Date: Thu, 27 Nov 2025 10:57:16 +0800 Subject: [PATCH 0404/1449] regulator: core: Protect regulator_supply_alias_list with regulator_list_mutex ANBZ: #35228 commit 09811a83b214cc15521e0d818e43ae9043e9a28d stable. commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d upstream. regulator_supply_alias_list was accessed without any locking in regulator_supply_alias(), regulator_register_supply_alias(), and regulator_unregister_supply_alias(). Concurrent registration, unregistration and lookups can race, leading to: 1 use-after-free if an alias entry is removed while being read, 2 duplicate entries when two threads register the same alias, 3 inconsistent alias mappings observed by consumers. Protect all traversals, insertions and deletions on regulator_supply_alias_list with the existing regulator_list_mutex. Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") Signed-off-by: sparkhuang Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/regulator/core.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 465f4f870162..23cdf220ca7d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1970,6 +1970,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) { struct regulator_supply_alias *map; + mutex_lock(®ulator_list_mutex); map = regulator_find_supply_alias(*dev, *supply); if (map) { dev_dbg(*dev, "Mapping supply %s to %s,%s\n", @@ -1978,6 +1979,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) *dev = map->alias_dev; *supply = map->alias_supply; } + mutex_unlock(®ulator_list_mutex); } static int regulator_match(struct device *dev, const void *data) @@ -2456,22 +2458,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, const char *alias_id) { struct regulator_supply_alias *map; + struct regulator_supply_alias *new_map; - map = regulator_find_supply_alias(dev, id); - if (map) - return -EEXIST; - - map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); - if (!map) + new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); + if (!new_map) return -ENOMEM; - map->src_dev = dev; - map->src_supply = id; - map->alias_dev = alias_dev; - map->alias_supply = alias_id; - - list_add(&map->list, ®ulator_supply_alias_list); + mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + mutex_unlock(®ulator_list_mutex); + kfree(new_map); + return -EEXIST; + } + new_map->src_dev = dev; + new_map->src_supply = id; + new_map->alias_dev = alias_dev; + new_map->alias_supply = alias_id; + list_add(&new_map->list, ®ulator_supply_alias_list); + mutex_unlock(®ulator_list_mutex); pr_info("Adding alias for supply %s,%s -> %s,%s\n", id, dev_name(dev), alias_id, dev_name(alias_dev)); @@ -2491,11 +2497,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) { struct regulator_supply_alias *map; + mutex_lock(®ulator_list_mutex); map = regulator_find_supply_alias(dev, id); if (map) { list_del(&map->list); kfree(map); } + mutex_unlock(®ulator_list_mutex); } EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); -- Gitee From de45e2a63b3799e4cb5d4efe0614934b3a4a2d32 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 13 Sep 2023 00:53:10 +0800 Subject: [PATCH 0405/1449] resource: Reuse for_each_resource() macro ANBZ: #35228 commit 9bf08dab70417fd8cf5c4c405996903167d172eb stable. commit 441f0dd8fa035a2c7cfe972047bb905d3be05c1b upstream. We have a few places where for_each_resource() is open coded. Replace that by the macro. This makes code easier to read and understand. With this, compile r_next() only for CONFIG_PROC_FS=y. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230912165312.402422-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/resource.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index 6506839f8a81..79fba72cb7d2 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -77,13 +77,6 @@ static struct resource *next_resource_skip_children(struct resource *p) (_p) = (_skip_children) ? next_resource_skip_children(_p) : \ next_resource(_p)) -static void *r_next(struct seq_file *m, void *v, loff_t *pos) -{ - struct resource *p = v; - (*pos)++; - return (void *)next_resource(p); -} - #ifdef CONFIG_PROC_FS enum { MAX_IORES_LEVEL = 5 }; @@ -91,14 +84,26 @@ enum { MAX_IORES_LEVEL = 5 }; static void *r_start(struct seq_file *m, loff_t *pos) __acquires(resource_lock) { - struct resource *p = pde_data(file_inode(m->file)); - loff_t l = 0; + struct resource *root = pde_data(file_inode(m->file)); + struct resource *p; + loff_t l = *pos; + read_lock(&resource_lock); - for (p = p->child; p && l < *pos; p = r_next(m, p, &l)) - ; + for_each_resource(root, p, false) { + if (l-- == 0) + break; + } + return p; } +static void *r_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct resource *p = v; + (*pos)++; + return (void *)next_resource(p); +} + static void r_stop(struct seq_file *m, void *v) __releases(resource_lock) { @@ -336,7 +341,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, read_lock(&resource_lock); - for (p = iomem_resource.child; p; p = next_resource(p)) { + for_each_resource(&iomem_resource, p, false) { /* If we passed the resource we are looking for, stop */ if (p->start > end) { p = NULL; @@ -1684,13 +1689,12 @@ __setup("reserve=", reserve_setup); */ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) { - struct resource *p = &iomem_resource; resource_size_t end = addr + size - 1; + struct resource *p; int err = 0; - loff_t l; read_lock(&resource_lock); - for (p = p->child; p ; p = r_next(NULL, p, &l)) { + for_each_resource(&iomem_resource, p, false) { /* * We can probably skip the resources without * IORESOURCE_IO attribute? -- Gitee From 17a77900dc513a7c150a213d3c5ed981a3481529 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 25 Sep 2024 23:43:34 +0800 Subject: [PATCH 0406/1449] resource: replace open coded resource_intersection() ANBZ: #35228 commit 7c5527d188573863330d1e43631fb4d61bd974e3 stable. commit 5c1edea773c98707fbb23d1df168bcff52f61e4b upstream. Patch series "resource: A couple of cleanups". A couple of ad-hoc cleanups since there was a recent development of the code in question. No functional changes intended. This patch (of 2): __region_intersects() uses open coded resource_intersection(). Replace it with existing API which also make more clear what we are checking. Link: https://lkml.kernel.org/r/20240925154355.1170859-1-andriy.shevchenko@linux.intel.com Link: https://lkml.kernel.org/r/20240925154355.1170859-2-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Cc: Rasmus Villemoes Signed-off-by: Andrew Morton Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/resource.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index 79fba72cb7d2..dcc3b564c053 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -498,17 +498,16 @@ static int __region_intersects(struct resource *parent, resource_size_t start, size_t size, unsigned long flags, unsigned long desc) { - resource_size_t ostart, oend; int type = 0; int other = 0; struct resource *p, *dp; + struct resource res, o; bool is_type, covered; - struct resource res; res.start = start; res.end = start + size - 1; for (p = parent->child; p ; p = p->sibling) { - if (!resource_overlaps(p, &res)) + if (!resource_intersection(p, &res, &o)) continue; is_type = (p->flags & flags) == flags && (desc == IORES_DESC_NONE || desc == p->desc); @@ -529,8 +528,6 @@ static int __region_intersects(struct resource *parent, resource_size_t start, * |-- "System RAM" --||-- "CXL Window 0a" --| */ covered = false; - ostart = max(res.start, p->start); - oend = min(res.end, p->end); for_each_resource(p, dp, false) { if (!resource_overlaps(dp, &res)) continue; @@ -539,17 +536,17 @@ static int __region_intersects(struct resource *parent, resource_size_t start, if (is_type) { type++; /* - * Range from 'ostart' to 'dp->start' + * Range from 'o.start' to 'dp->start' * isn't covered by matched resource. */ - if (dp->start > ostart) + if (dp->start > o.start) break; - if (dp->end >= oend) { + if (dp->end >= o.end) { covered = true; break; } /* Remove covered range */ - ostart = max(ostart, dp->end + 1); + o.start = max(o.start, dp->end + 1); } } if (!covered) -- Gitee From 6e1b21b0f626f3752516559c1d5a4e7bc9cde24a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 25 Sep 2024 23:43:35 +0800 Subject: [PATCH 0407/1449] resource: introduce is_type_match() helper and use it ANBZ: #35228 commit 14f860fb0873c4907db0b0a8d23feef31c74dad2 stable. commit ba1eccc114ffc62c4495a5e15659190fa2c42308 upstream. There are already a couple of places where we may replace a few lines of code by calling a helper, which increases readability while deduplicating the code. Introduce is_type_match() helper and use it. Link: https://lkml.kernel.org/r/20240925154355.1170859-3-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Cc: Rasmus Villemoes Signed-off-by: Andrew Morton Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/resource.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index dcc3b564c053..67410132b40e 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -310,6 +310,11 @@ int release_resource(struct resource *old) EXPORT_SYMBOL(release_resource); +static bool is_type_match(struct resource *p, unsigned long flags, unsigned long desc) +{ + return (p->flags & flags) == flags && (desc == IORES_DESC_NONE || desc == p->desc); +} + /** * find_next_iomem_res - Finds the lowest iomem resource that covers part of * [@start..@end]. @@ -352,13 +357,9 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, if (p->end < start) continue; - if ((p->flags & flags) != flags) - continue; - if ((desc != IORES_DESC_NONE) && (desc != p->desc)) - continue; - /* Found a match, break */ - break; + if (is_type_match(p, flags, desc)) + break; } if (p) { @@ -501,7 +502,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, int type = 0; int other = 0; struct resource *p, *dp; struct resource res, o; - bool is_type, covered; + bool covered; res.start = start; res.end = start + size - 1; @@ -509,9 +510,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, for (p = parent->child; p ; p = p->sibling) { if (!resource_intersection(p, &res, &o)) continue; - is_type = (p->flags & flags) == flags && - (desc == IORES_DESC_NONE || desc == p->desc); - if (is_type) { + if (is_type_match(p, flags, desc)) { type++; continue; } @@ -531,9 +530,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, for_each_resource(p, dp, false) { if (!resource_overlaps(dp, &res)) continue; - is_type = (dp->flags & flags) == flags && - (desc == IORES_DESC_NONE || desc == dp->desc); - if (is_type) { + if (is_type_match(dp, flags, desc)) { type++; /* * Range from 'o.start' to 'dp->start' -- Gitee From 66eda40d97da0d6cf1d60600da788a203e3528eb Mon Sep 17 00:00:00 2001 From: Ilias Stamatis Date: Tue, 25 Nov 2025 00:53:49 +0800 Subject: [PATCH 0408/1449] Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit c327ca1b2de52a6f3ad16fb4d6fb2a0d39233140 stable. commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 upstream. Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") removed an optimization introduced by commit 756398750e11 ("resource: avoid unnecessary lookups in find_next_iomem_res()"). That was not called out in the message of the first commit explicitly so it's not entirely clear whether removing the optimization happened inadvertently or not. As the original commit message of the optimization explains there is no point considering the children of a subtree in find_next_iomem_res() if the top level range does not match. Reinstating the optimization results in performance improvements in systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem in such platforms takes 700-1500μs without the optimisation and 10-50μs with the optimisation. Note that even though commit 97523a4edb7b removed the 'sibling_only' parameter from next_resource(), newer kernels have basically reinstated it under the name 'skip_children'. Link: https://lore.kernel.org/all/20251124165349.3377826-1-ilstam@amazon.com/T/#u Fixes: 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") Signed-off-by: Ilias Stamatis Acked-by: David Hildenbrand (Red Hat) Cc: Andriy Shevchenko Cc: Baoquan He Cc: "Huang, Ying" Cc: Nadav Amit Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/resource.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/resource.c b/kernel/resource.c index 67410132b40e..dca8581eb399 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -336,6 +336,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, unsigned long flags, unsigned long desc, struct resource *res) { + /* Skip children until we find a top level range that matches */ + bool skip_children = true; struct resource *p; if (!res) @@ -346,7 +348,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, read_lock(&resource_lock); - for_each_resource(&iomem_resource, p, false) { + for_each_resource(&iomem_resource, p, skip_children) { /* If we passed the resource we are looking for, stop */ if (p->start > end) { p = NULL; @@ -357,6 +359,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, if (p->end < start) continue; + /* + * We found a top level range that matches what we are looking + * for. Time to start checking children too. + */ + skip_children = false; + /* Found a match, break */ if (is_type_match(p, flags, desc)) break; -- Gitee From a17e646b3b4818d2bf99e110fd006b92503e5f2b Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 28 Nov 2025 07:26:22 +0800 Subject: [PATCH 0409/1449] netfilter: flowtable: check for maximum number of encapsulations in bridge vlan ANBZ: #35228 commit 11b01b8ef1b118b078af54f2dcb8547e62eac3cd stable. commit 634f3853cc98d73bdec8918010ee29b06981583e upstream. Add a sanity check to skip path discovery if the maximum number of encapsulation is reached. While at it, check for underflow too. Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nft_flow_offload.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c index 1894032a7971..75dddcaa9aa3 100644 --- a/net/netfilter/nft_flow_offload.c +++ b/net/netfilter/nft_flow_offload.c @@ -140,12 +140,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, info->ingress_vlans |= BIT(info->num_encaps - 1); break; case DEV_PATH_BR_VLAN_TAG: + if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { + info->indev = NULL; + break; + } info->encap[info->num_encaps].id = path->bridge.vlan_id; info->encap[info->num_encaps].proto = path->bridge.vlan_proto; info->num_encaps++; break; case DEV_PATH_BR_VLAN_UNTAG: - info->num_encaps--; + if (WARN_ON_ONCE(info->num_encaps-- == 0)) { + info->indev = NULL; + break; + } break; case DEV_PATH_BR_VLAN_KEEP: break; -- Gitee From 1552baa85849381254b56272ce3d8bb8ffe30c03 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Fri, 21 Nov 2025 08:14:30 +0800 Subject: [PATCH 0410/1449] netfilter: nf_conncount: rework API to use sk_buff directly ANBZ: #35228 commit da9f247fb5efcd5a2730cdc989291b383c439e10 stable. commit be102eb6a0e7c03db00e50540622f4e43b2d2844 upstream. When using nf_conncount infrastructure for non-confirmed connections a duplicated track is possible due to an optimization introduced since commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). In order to fix this introduce a new conncount API that receives directly an sk_buff struct. It fetches the tuple and zone and the corresponding ct from it. It comes with both existing conncount variants nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove the old API and adjust all the users to use the new one. This way, for each sk_buff struct it is possible to check if there is a ct present and already confirmed. If so, skip the add operation. Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/netfilter/nf_conntrack_count.h | 17 +- net/netfilter/nf_conncount.c | 177 ++++++++++++++------- net/netfilter/nft_connlimit.c | 21 +-- net/netfilter/xt_connlimit.c | 14 +- net/openvswitch/conntrack.c | 16 +- 5 files changed, 142 insertions(+), 103 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h index e227d997fc71..115bb7e572f7 100644 --- a/include/net/netfilter/nf_conntrack_count.h +++ b/include/net/netfilter/nf_conntrack_count.h @@ -20,15 +20,14 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family void nf_conncount_destroy(struct net *net, unsigned int family, struct nf_conncount_data *data); -unsigned int nf_conncount_count(struct net *net, - struct nf_conncount_data *data, - const u32 *key, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone); - -int nf_conncount_add(struct net *net, struct nf_conncount_list *list, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone); +unsigned int nf_conncount_count_skb(struct net *net, + const struct sk_buff *skb, + u16 l3num, + struct nf_conncount_data *data, + const u32 *key); + +int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, + u16 l3num, struct nf_conncount_list *list); void nf_conncount_list_init(struct nf_conncount_list *list); diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index 6156c0751056..7a8a6f72ff19 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, return ERR_PTR(-EAGAIN); } +static bool get_ct_or_tuple_from_skb(struct net *net, + const struct sk_buff *skb, + u16 l3num, + struct nf_conn **ct, + struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone **zone, + bool *refcounted) +{ + const struct nf_conntrack_tuple_hash *h; + enum ip_conntrack_info ctinfo; + struct nf_conn *found_ct; + + found_ct = nf_ct_get(skb, &ctinfo); + if (found_ct && !nf_ct_is_template(found_ct)) { + *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + *zone = nf_ct_zone(found_ct); + *ct = found_ct; + return true; + } + + if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) + return false; + + if (found_ct) + *zone = nf_ct_zone(found_ct); + + h = nf_conntrack_find_get(net, *zone, tuple); + if (!h) + return true; + + found_ct = nf_ct_tuplehash_to_ctrack(h); + *refcounted = true; + *ct = found_ct; + + return true; +} + static int __nf_conncount_add(struct net *net, - struct nf_conncount_list *list, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone) + const struct sk_buff *skb, + u16 l3num, + struct nf_conncount_list *list) { + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; const struct nf_conntrack_tuple_hash *found; struct nf_conncount_tuple *conn, *conn_n; + struct nf_conntrack_tuple tuple; + struct nf_conn *ct = NULL; struct nf_conn *found_ct; unsigned int collect = 0; + bool refcounted = false; + + if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) + return -ENOENT; + + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); + return 0; + } if ((u32)jiffies == list->last_gc) goto add_new_node; @@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, if (IS_ERR(found)) { /* Not found, but might be about to be confirmed */ if (PTR_ERR(found) == -EAGAIN) { - if (nf_ct_tuple_equal(&conn->tuple, tuple) && + if (nf_ct_tuple_equal(&conn->tuple, &tuple) && nf_ct_zone_id(&conn->zone, conn->zone.dir) == nf_ct_zone_id(zone, zone->dir)) - return 0; /* already exists */ + goto out_put; /* already exists */ } else { collect++; } @@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, found_ct = nf_ct_tuplehash_to_ctrack(found); - if (nf_ct_tuple_equal(&conn->tuple, tuple) && + if (nf_ct_tuple_equal(&conn->tuple, &tuple) && nf_ct_zone_equal(found_ct, zone, zone->dir)) { /* * We should not see tuples twice unless someone hooks @@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, * Attempt to avoid a re-add in this case. */ nf_ct_put(found_ct); - return 0; + goto out_put; } else if (already_closed(found_ct)) { /* * we do not care about connections which are @@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, if (conn == NULL) return -ENOMEM; - conn->tuple = *tuple; + conn->tuple = tuple; conn->zone = *zone; conn->cpu = raw_smp_processor_id(); conn->jiffies32 = (u32)jiffies; list_add_tail(&conn->node, &list->head); list->count++; list->last_gc = (u32)jiffies; + +out_put: + if (refcounted) + nf_ct_put(ct); return 0; } -int nf_conncount_add(struct net *net, - struct nf_conncount_list *list, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone) +int nf_conncount_add_skb(struct net *net, + const struct sk_buff *skb, + u16 l3num, + struct nf_conncount_list *list) { int ret; /* check the saved connections */ spin_lock_bh(&list->list_lock); - ret = __nf_conncount_add(net, list, tuple, zone); + ret = __nf_conncount_add(net, skb, l3num, list); spin_unlock_bh(&list->list_lock); return ret; } -EXPORT_SYMBOL_GPL(nf_conncount_add); +EXPORT_SYMBOL_GPL(nf_conncount_add_skb); void nf_conncount_list_init(struct nf_conncount_list *list) { @@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) static unsigned int insert_tree(struct net *net, + const struct sk_buff *skb, + u16 l3num, struct nf_conncount_data *data, struct rb_root *root, unsigned int hash, - const u32 *key, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone) + const u32 *key) { struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + bool do_gc = true, refcounted = false; + unsigned int count = 0, gc_count = 0; struct rb_node **rbnode, *parent; - struct nf_conncount_rb *rbconn; + struct nf_conntrack_tuple tuple; struct nf_conncount_tuple *conn; - unsigned int count = 0, gc_count = 0; - bool do_gc = true; + struct nf_conncount_rb *rbconn; + struct nf_conn *ct = NULL; spin_lock_bh(&nf_conncount_locks[hash]); restart: @@ -340,7 +397,7 @@ insert_tree(struct net *net, } else { int ret; - ret = nf_conncount_add(net, &rbconn->list, tuple, zone); + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); if (ret) count = 0; /* hotdrop */ else @@ -364,30 +421,35 @@ insert_tree(struct net *net, goto restart; } - /* expected case: match, insert new node */ - rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); - if (rbconn == NULL) - goto out_unlock; + if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { + /* expected case: match, insert new node */ + rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); + if (rbconn == NULL) + goto out_unlock; - conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); - if (conn == NULL) { - kmem_cache_free(conncount_rb_cachep, rbconn); - goto out_unlock; - } + conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); + if (conn == NULL) { + kmem_cache_free(conncount_rb_cachep, rbconn); + goto out_unlock; + } - conn->tuple = *tuple; - conn->zone = *zone; - conn->cpu = raw_smp_processor_id(); - conn->jiffies32 = (u32)jiffies; - memcpy(rbconn->key, key, sizeof(u32) * data->keylen); + conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + memcpy(rbconn->key, key, sizeof(u32) * data->keylen); + + nf_conncount_list_init(&rbconn->list); + list_add(&conn->node, &rbconn->list.head); + count = 1; + rbconn->list.count = count; - nf_conncount_list_init(&rbconn->list); - list_add(&conn->node, &rbconn->list.head); - count = 1; - rbconn->list.count = count; + rb_link_node_rcu(&rbconn->node, parent, rbnode); + rb_insert_color(&rbconn->node, root); - rb_link_node_rcu(&rbconn->node, parent, rbnode); - rb_insert_color(&rbconn->node, root); + if (refcounted) + nf_ct_put(ct); + } out_unlock: spin_unlock_bh(&nf_conncount_locks[hash]); return count; @@ -395,10 +457,10 @@ insert_tree(struct net *net, static unsigned int count_tree(struct net *net, + const struct sk_buff *skb, + u16 l3num, struct nf_conncount_data *data, - const u32 *key, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone) + const u32 *key) { struct rb_root *root; struct rb_node *parent; @@ -422,7 +484,7 @@ count_tree(struct net *net, } else { int ret; - if (!tuple) { + if (!skb) { nf_conncount_gc_list(net, &rbconn->list); return rbconn->list.count; } @@ -437,7 +499,7 @@ count_tree(struct net *net, } /* same source network -> be counted! */ - ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); spin_unlock_bh(&rbconn->list.list_lock); if (ret) return 0; /* hotdrop */ @@ -446,10 +508,10 @@ count_tree(struct net *net, } } - if (!tuple) + if (!skb) return 0; - return insert_tree(net, data, root, hash, key, tuple, zone); + return insert_tree(net, skb, l3num, data, root, hash, key); } static void tree_gc_worker(struct work_struct *work) @@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) } /* Count and return number of conntrack entries in 'net' with particular 'key'. - * If 'tuple' is not null, insert it into the accounting data structure. - * Call with RCU read lock. + * If 'skb' is not null, insert the corresponding tuple into the accounting + * data structure. Call with RCU read lock. */ -unsigned int nf_conncount_count(struct net *net, - struct nf_conncount_data *data, - const u32 *key, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone) +unsigned int nf_conncount_count_skb(struct net *net, + const struct sk_buff *skb, + u16 l3num, + struct nf_conncount_data *data, + const u32 *key) { - return count_tree(net, data, key, tuple, zone); + return count_tree(net, skb, l3num, data, key); + } -EXPORT_SYMBOL_GPL(nf_conncount_count); +EXPORT_SYMBOL_GPL(nf_conncount_count_skb); struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, unsigned int keylen) diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c index 92b984fa8175..d998e27713ac 100644 --- a/net/netfilter/nft_connlimit.c +++ b/net/netfilter/nft_connlimit.c @@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, const struct nft_pktinfo *pkt, const struct nft_set_ext *ext) { - const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; - const struct nf_conntrack_tuple *tuple_ptr; - struct nf_conntrack_tuple tuple; - enum ip_conntrack_info ctinfo; - const struct nf_conn *ct; unsigned int count; + int err; - tuple_ptr = &tuple; - - ct = nf_ct_get(pkt->skb, &ctinfo); - if (ct != NULL) { - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - zone = nf_ct_zone(ct); - } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), - nft_pf(pkt), nft_net(pkt), &tuple)) { - regs->verdict.code = NF_DROP; - return; - } - - if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { regs->verdict.code = NF_DROP; return; } diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index d1d0fa6c8061..b3e4be6e1e43 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = xt_net(par); const struct xt_connlimit_info *info = par->matchinfo; - struct nf_conntrack_tuple tuple; - const struct nf_conntrack_tuple *tuple_ptr = &tuple; const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; enum ip_conntrack_info ctinfo; const struct nf_conn *ct; @@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) u32 key[5]; ct = nf_ct_get(skb, &ctinfo); - if (ct != NULL) { - tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + if (ct) zone = nf_ct_zone(ct); - } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), - xt_family(par), net, &tuple)) { - goto hotdrop; - } if (xt_family(par) == NFPROTO_IPV6) { const struct ipv6hdr *iph = ipv6_hdr(skb); @@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) key[1] = zone->id; } - connections = nf_conncount_count(net, info->data, key, tuple_ptr, - zone); + connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); if (connections == 0) - /* kmalloc failed, drop it entirely */ + /* kmalloc failed or tuple couldn't be found, drop it entirely */ goto hotdrop; return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 3b980bf2770b..32485b367737 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -904,8 +904,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) } static int ovs_ct_check_limit(struct net *net, - const struct ovs_conntrack_info *info, - const struct nf_conntrack_tuple *tuple) + const struct sk_buff *skb, + const struct ovs_conntrack_info *info) { struct ovs_net *ovs_net = net_generic(net, ovs_net_id); const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; @@ -918,8 +918,9 @@ static int ovs_ct_check_limit(struct net *net, if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) return 0; - connections = nf_conncount_count(net, ct_limit_info->data, - &conncount_key, tuple, &info->zone); + connections = nf_conncount_count_skb(net, skb, info->family, + ct_limit_info->data, + &conncount_key); if (connections > per_zone_limit) return -ENOMEM; @@ -948,8 +949,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) if (static_branch_unlikely(&ovs_ct_limit_enabled)) { if (!nf_ct_is_confirmed(ct)) { - err = ovs_ct_check_limit(net, info, - &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + err = ovs_ct_check_limit(net, skb, info); if (err) { net_warn_ratelimited("openvswitch: zone: %u " "exceeds conntrack limit\n", @@ -1744,8 +1744,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, zone_limit.limit = limit; nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); - zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, - &ct_zone); + zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, + &conncount_key); return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); } -- Gitee From 7dc5d1d4d0d3e5898976fb9860a2a6a152b5be1c Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Fri, 21 Nov 2025 08:14:32 +0800 Subject: [PATCH 0411/1449] netfilter: nft_connlimit: update the count if add was skipped ANBZ: #35228 commit 8286c02fe9100330475331253fc590f047963f90 stable. commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e upstream. Connlimit expression can be used for all kind of packets and not only for packets with connection state new. See this ruleset as example: table ip filter { chain input { type filter hook input priority filter; policy accept; tcp dport 22 ct count over 4 counter } } Currently, if the connection count goes over the limit the counter will count the packets. When a connection is closed, the connection count won't decrement as it should because it is only updated for new connections due to an optimization on __nf_conncount_add() that prevents updating the list if the connection is duplicated. To solve this problem, check whether the connection was skipped and if so, update the list. Adjust count_tree() too so the same fix is applied for xt_connlimit. Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_conncount.c | 12 ++++++++---- net/netfilter/nft_connlimit.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index 7a8a6f72ff19..97b631a81484 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, if (ct && nf_ct_is_confirmed(ct)) { if (refcounted) nf_ct_put(ct); - return 0; + return -EEXIST; } if ((u32)jiffies == list->last_gc) @@ -398,7 +398,7 @@ insert_tree(struct net *net, int ret; ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); - if (ret) + if (ret && ret != -EEXIST) count = 0; /* hotdrop */ else count = rbconn->list.count; @@ -501,10 +501,14 @@ count_tree(struct net *net, /* same source network -> be counted! */ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); spin_unlock_bh(&rbconn->list.list_lock); - if (ret) + if (ret && ret != -EEXIST) { return 0; /* hotdrop */ - else + } else { + /* -EEXIST means add was skipped, update the list */ + if (ret == -EEXIST) + nf_conncount_gc_list(net, &rbconn->list); return rbconn->list.count; + } } } diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c index d998e27713ac..83a7d5769396 100644 --- a/net/netfilter/nft_connlimit.c +++ b/net/netfilter/nft_connlimit.c @@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); if (err) { - regs->verdict.code = NF_DROP; - return; + if (err == -EEXIST) { + /* Call gc to update the list count if any connection has + * been closed already. This is useful for softlimit + * connections like limiting bandwidth based on a number + * of open connections. + */ + nf_conncount_gc_list(nft_net(pkt), priv->list); + } else { + regs->verdict.code = NF_DROP; + return; + } } count = priv->list->count; -- Gitee From 716dcf8cda804bf8926dc06d81bda8db22372662 Mon Sep 17 00:00:00 2001 From: Alexey Kodanev Date: Wed, 26 Nov 2025 18:43:27 +0800 Subject: [PATCH 0412/1449] net: stmmac: fix rx limit check in stmmac_rx_zc() ANBZ: #35228 commit 660936cb51550d504fa155b291753394ca2bc8fb stable. commit 8048168df56e225c94e50b04cb7b0514135d7a1c upstream. The extra "count >= limit" check in stmmac_rx_zc() is redundant and has no effect because the value of "count" doesn't change after the while condition at this point. However, it can change after "read_again:" label: while (count < limit) { ... if (count >= limit) break; read_again: ... /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ if (likely(status & rx_not_ls)) { xsk_buff_free(buf->xdp); buf->xdp = NULL; dirty++; count++; goto read_again; } ... This patch addresses the same issue previously resolved in stmmac_rx() by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). The fix is the same: move the check after the label to ensure that it bounds the goto loop. Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") Signed-off-by: Alexey Kodanev Reviewed-by: Russell King (Oracle) Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 7323b11c3c33..abb38af68ed6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5158,10 +5158,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) len = 0; } +read_again: if (count >= limit) break; -read_again: buf1_len = 0; entry = next_entry; buf = &rx_q->buf_pool[entry]; -- Gitee From 2a0b25fbd94278887105b64dc2cc18374533e0ef Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 24 Nov 2025 00:35:51 +0800 Subject: [PATCH 0413/1449] mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors ANBZ: #35228 commit d29034c70f15aa0ad7617e4188084101ff582482 stable. commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 upstream. devm_pm_runtime_enable() can fail due to memory allocation failures. The current code ignores its return value and proceeds with pm_runtime_resume_and_get(), which may operate on incorrectly initialized runtime PM state. Check the return value of devm_pm_runtime_enable() and return the error code if it fails. Fixes: 6a2277a0ebe7 ("mtd: rawnand: renesas: Use runtime PM instead of the raw clock API") Signed-off-by: Haotian Zhang Reviewed-by: Geert Uytterhoeven Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c index a9e79f0acbe2..46af7666b3c9 100644 --- a/drivers/mtd/nand/raw/renesas-nand-controller.c +++ b/drivers/mtd/nand/raw/renesas-nand-controller.c @@ -1342,7 +1342,10 @@ static int rnandc_probe(struct platform_device *pdev) if (IS_ERR(rnandc->regs)) return PTR_ERR(rnandc->regs); - devm_pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; -- Gitee From 688e0f9488a02bbbbda217e49ab2699c0639c338 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 16 Jan 2024 10:02:01 +0800 Subject: [PATCH 0414/1449] selftests: bonding: add missing build configs ANBZ: #35228 commit 12364ab3a790c3d2da6473d59ceb3bda7025d5e2 stable. commit 03fb8565c880d57952d9b4ba0b36468bae52b554 upstream. bonding tests also try to create bridge, veth and dummy interfaces. These are not currently listed in config. Fixes: bbb774d921e2 ("net: Add tests for bonding and team address list management") Fixes: c078290a2b76 ("selftests: include bonding tests into the kselftest infra") Acked-by: Muhammad Usama Anjum Link: https://lore.kernel.org/r/20240116020201.1883023-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/drivers/net/bonding/config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config index 70638fa50b2c..f85b16fc5128 100644 --- a/tools/testing/selftests/drivers/net/bonding/config +++ b/tools/testing/selftests/drivers/net/bonding/config @@ -1,2 +1,5 @@ CONFIG_BONDING=y +CONFIG_BRIDGE=y +CONFIG_DUMMY=y CONFIG_MACVLAN=y +CONFIG_VETH=y -- Gitee From 2adac3dfe2af2b1ee561e4ebef640409ec9c8337 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Tue, 16 Jan 2024 23:49:26 +0800 Subject: [PATCH 0415/1449] selftests: bonding: Add more missing config options ANBZ: #35228 commit 194788280708276deb128f656c0bdb6b81010be1 stable. commit dd2d40acdbb2b9e6bcddd5424b0e00c1760ecf26 upstream. As a followup to commit 03fb8565c880 ("selftests: bonding: add missing build configs"), add more networking-specific config options which are needed for bonding tests. For testing, I used the minimal config generated by virtme-ng and I added the options in the config file. All bonding tests passed. Fixes: bbb774d921e2 ("net: Add tests for bonding and team address list management") # for ipv6 Fixes: 6cbe791c0f4e ("kselftest: bonding: add num_grat_arp test") # for tc options Fixes: 222c94ec0ad4 ("selftests: bonding: add tests for ether type changes") # for nlmon Suggested-by: Jakub Kicinski Signed-off-by: Benjamin Poirier Link: https://lore.kernel.org/r/20240116154926.202164-1-bpoirier@nvidia.com Signed-off-by: Paolo Abeni Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/drivers/net/bonding/config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config index f85b16fc5128..899d7fb6ea8e 100644 --- a/tools/testing/selftests/drivers/net/bonding/config +++ b/tools/testing/selftests/drivers/net/bonding/config @@ -1,5 +1,10 @@ CONFIG_BONDING=y CONFIG_BRIDGE=y CONFIG_DUMMY=y +CONFIG_IPV6=y CONFIG_MACVLAN=y +CONFIG_NET_ACT_GACT=y +CONFIG_NET_CLS_FLOWER=y +CONFIG_NET_SCH_INGRESS=y +CONFIG_NLMON=y CONFIG_VETH=y -- Gitee From 745aaab6f1ab51392697a0515e6f18f8cd1c5b9a Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Thu, 9 Jan 2025 11:28:19 +0800 Subject: [PATCH 0416/1449] selftests: bonding: add ipvlan over bond testing ANBZ: #35228 commit 4035ea8f02fdbf36e27f3e21594427fb2ae3524a stable. commit 08ac69b24507ab06871c18adc421c9d4f1008c61 upstream. This rework bond_macvlan.sh into bond_macvlan_ipvlan.sh We only test bridge mode for macvlan and l2 mode ]# ./bond_macvlan_ipvlan.sh TEST: active-backup/macvlan_bridge: IPv4: client->server [ OK ] ... TEST: active-backup/ipvlan_l2: IPv4: client->server [ OK ] ... TEST: balance-tlb/macvlan_bridge: IPv4: client->server [ OK ] ... TEST: balance-tlb/ipvlan_l2: IPv4: client->server [ OK ] ... TEST: balance-alb/macvlan_bridge: IPv4: client->server [ OK ] ... TEST: balance-alb/ipvlan_l2: IPv4: client->server [ OK ] ... Signed-off-by: Etienne Champetier Link: https://patch.msgid.link/20250109032819.326528-3-champetier.etienne@gmail.com Signed-off-by: Jakub Kicinski Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../selftests/drivers/net/bonding/Makefile | 2 +- .../drivers/net/bonding/bond_macvlan.sh | 99 ------------------- .../net/bonding/bond_macvlan_ipvlan.sh | 96 ++++++++++++++++++ .../selftests/drivers/net/bonding/config | 1 + 4 files changed, 98 insertions(+), 100 deletions(-) delete mode 100755 tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh create mode 100755 tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile index 8a72bb7de70f..770aa7345aac 100644 --- a/tools/testing/selftests/drivers/net/bonding/Makefile +++ b/tools/testing/selftests/drivers/net/bonding/Makefile @@ -10,7 +10,7 @@ TEST_PROGS := \ mode-2-recovery-updelay.sh \ bond_options.sh \ bond-eth-type-change.sh \ - bond_macvlan.sh + bond_macvlan_ipvlan.sh TEST_FILES := \ lag_lib.sh \ diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh deleted file mode 100755 index b609fb6231f4..000000000000 --- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 -# -# Test macvlan over balance-alb - -lib_dir=$(dirname "$0") -source ${lib_dir}/bond_topo_2d1c.sh - -m1_ns="m1-$(mktemp -u XXXXXX)" -m2_ns="m1-$(mktemp -u XXXXXX)" -m1_ip4="192.0.2.11" -m1_ip6="2001:db8::11" -m2_ip4="192.0.2.12" -m2_ip6="2001:db8::12" - -cleanup() -{ - ip -n ${m1_ns} link del macv0 - ip netns del ${m1_ns} - ip -n ${m2_ns} link del macv0 - ip netns del ${m2_ns} - - client_destroy - server_destroy - gateway_destroy -} - -check_connection() -{ - local ns=${1} - local target=${2} - local message=${3:-"macvlan_over_bond"} - RET=0 - - - ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null - check_err $? "ping failed" - log_test "$mode: $message" -} - -macvlan_over_bond() -{ - local param="$1" - RET=0 - - # setup new bond mode - bond_reset "${param}" - - ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge - ip -n ${s_ns} link set macv0 netns ${m1_ns} - ip -n ${m1_ns} link set dev macv0 up - ip -n ${m1_ns} addr add ${m1_ip4}/24 dev macv0 - ip -n ${m1_ns} addr add ${m1_ip6}/24 dev macv0 - - ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge - ip -n ${s_ns} link set macv0 netns ${m2_ns} - ip -n ${m2_ns} link set dev macv0 up - ip -n ${m2_ns} addr add ${m2_ip4}/24 dev macv0 - ip -n ${m2_ns} addr add ${m2_ip6}/24 dev macv0 - - sleep 2 - - check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server" - check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server" - check_connection "${c_ns}" "${m1_ip4}" "IPv4: client->macvlan_1" - check_connection "${c_ns}" "${m1_ip6}" "IPv6: client->macvlan_1" - check_connection "${c_ns}" "${m2_ip4}" "IPv4: client->macvlan_2" - check_connection "${c_ns}" "${m2_ip6}" "IPv6: client->macvlan_2" - check_connection "${m1_ns}" "${m2_ip4}" "IPv4: macvlan_1->macvlan_2" - check_connection "${m1_ns}" "${m2_ip6}" "IPv6: macvlan_1->macvlan_2" - - - sleep 5 - - check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client" - check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client" - check_connection "${m1_ns}" "${c_ip4}" "IPv4: macvlan_1->client" - check_connection "${m1_ns}" "${c_ip6}" "IPv6: macvlan_1->client" - check_connection "${m2_ns}" "${c_ip4}" "IPv4: macvlan_2->client" - check_connection "${m2_ns}" "${c_ip6}" "IPv6: macvlan_2->client" - check_connection "${m2_ns}" "${m1_ip4}" "IPv4: macvlan_2->macvlan_2" - check_connection "${m2_ns}" "${m1_ip6}" "IPv6: macvlan_2->macvlan_2" - - ip -n ${c_ns} neigh flush dev eth0 -} - -trap cleanup EXIT - -setup_prepare -ip netns add ${m1_ns} -ip netns add ${m2_ns} - -modes="active-backup balance-tlb balance-alb" - -for mode in $modes; do - macvlan_over_bond "mode $mode" -done - -exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh new file mode 100755 index 000000000000..c4711272fe45 --- /dev/null +++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test macvlan/ipvlan over bond + +lib_dir=$(dirname "$0") +source ${lib_dir}/bond_topo_2d1c.sh + +xvlan1_ns="xvlan1-$(mktemp -u XXXXXX)" +xvlan2_ns="xvlan2-$(mktemp -u XXXXXX)" +xvlan1_ip4="192.0.2.11" +xvlan1_ip6="2001:db8::11" +xvlan2_ip4="192.0.2.12" +xvlan2_ip6="2001:db8::12" + +cleanup() +{ + client_destroy + server_destroy + gateway_destroy + + ip netns del ${xvlan1_ns} + ip netns del ${xvlan2_ns} +} + +check_connection() +{ + local ns=${1} + local target=${2} + local message=${3} + RET=0 + + ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null + check_err $? "ping failed" + log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" +} + +xvlan_over_bond() +{ + local param="$1" + local xvlan_type="$2" + local xvlan_mode="$3" + RET=0 + + # setup new bond mode + bond_reset "${param}" + + ip -n ${s_ns} link add link bond0 name ${xvlan_type}0 type ${xvlan_type} mode ${xvlan_mode} + ip -n ${s_ns} link set ${xvlan_type}0 netns ${xvlan1_ns} + ip -n ${xvlan1_ns} link set dev ${xvlan_type}0 up + ip -n ${xvlan1_ns} addr add ${xvlan1_ip4}/24 dev ${xvlan_type}0 + ip -n ${xvlan1_ns} addr add ${xvlan1_ip6}/24 dev ${xvlan_type}0 + + ip -n ${s_ns} link add link bond0 name ${xvlan_type}0 type ${xvlan_type} mode ${xvlan_mode} + ip -n ${s_ns} link set ${xvlan_type}0 netns ${xvlan2_ns} + ip -n ${xvlan2_ns} link set dev ${xvlan_type}0 up + ip -n ${xvlan2_ns} addr add ${xvlan2_ip4}/24 dev ${xvlan_type}0 + ip -n ${xvlan2_ns} addr add ${xvlan2_ip6}/24 dev ${xvlan_type}0 + + sleep 2 + + check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server" + check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server" + check_connection "${c_ns}" "${xvlan1_ip4}" "IPv4: client->${xvlan_type}_1" + check_connection "${c_ns}" "${xvlan1_ip6}" "IPv6: client->${xvlan_type}_1" + check_connection "${c_ns}" "${xvlan2_ip4}" "IPv4: client->${xvlan_type}_2" + check_connection "${c_ns}" "${xvlan2_ip6}" "IPv6: client->${xvlan_type}_2" + check_connection "${xvlan1_ns}" "${xvlan2_ip4}" "IPv4: ${xvlan_type}_1->${xvlan_type}_2" + check_connection "${xvlan1_ns}" "${xvlan2_ip6}" "IPv6: ${xvlan_type}_1->${xvlan_type}_2" + + check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client" + check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client" + check_connection "${xvlan1_ns}" "${c_ip4}" "IPv4: ${xvlan_type}_1->client" + check_connection "${xvlan1_ns}" "${c_ip6}" "IPv6: ${xvlan_type}_1->client" + check_connection "${xvlan2_ns}" "${c_ip4}" "IPv4: ${xvlan_type}_2->client" + check_connection "${xvlan2_ns}" "${c_ip6}" "IPv6: ${xvlan_type}_2->client" + check_connection "${xvlan2_ns}" "${xvlan1_ip4}" "IPv4: ${xvlan_type}_2->${xvlan_type}_1" + check_connection "${xvlan2_ns}" "${xvlan1_ip6}" "IPv6: ${xvlan_type}_2->${xvlan_type}_1" + + ip -n ${c_ns} neigh flush dev eth0 +} + +trap cleanup EXIT + +setup_prepare +ip netns add ${xvlan1_ns} +ip netns add ${xvlan2_ns} + +bond_modes="active-backup balance-tlb balance-alb" + +for bond_mode in ${bond_modes}; do + xvlan_over_bond "mode ${bond_mode}" macvlan bridge + xvlan_over_bond "mode ${bond_mode}" ipvlan l2 +done + +exit $EXIT_STATUS diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config index 899d7fb6ea8e..dad4e5fda4db 100644 --- a/tools/testing/selftests/drivers/net/bonding/config +++ b/tools/testing/selftests/drivers/net/bonding/config @@ -3,6 +3,7 @@ CONFIG_BRIDGE=y CONFIG_DUMMY=y CONFIG_IPV6=y CONFIG_MACVLAN=y +CONFIG_IPVLAN=y CONFIG_NET_ACT_GACT=y CONFIG_NET_CLS_FLOWER=y CONFIG_NET_SCH_INGRESS=y -- Gitee From 2fb83781ffb93590271557547085b3a71c44c5d3 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Thu, 27 Nov 2025 22:33:10 +0800 Subject: [PATCH 0417/1449] selftests: bonding: add delay before each xvlan_over_bond connectivity check ANBZ: #35228 commit c44e376a533efbd534edb156ffaf1aa8a38edf69 stable. commit 2c28ee720ad14f58eb88a97ec3efe7c5c315ea5d upstream. Jakub reported increased flakiness in bond_macvlan_ipvlan.sh on regular kernel, while the tests consistently pass on a debug kernel. This suggests a timing-sensitive issue. To mitigate this, introduce a short sleep before each xvlan_over_bond connectivity check. The delay helps ensure neighbor and route cache have fully converged before verifying connectivity. The sleep interval is kept minimal since check_connection() is invoked nearly 100 times during the test. Fixes: 246af950b940 ("selftests: bonding: add macvlan over bond testing") Reported-by: Jakub Kicinski Closes: https://lore.kernel.org/netdev/20251114082014.750edfad@kernel.org Signed-off-by: Hangbin Liu Link: https://patch.msgid.link/20251127143310.47740-1-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh index c4711272fe45..559f300f965a 100755 --- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh @@ -30,6 +30,7 @@ check_connection() local message=${3} RET=0 + sleep 0.25 ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null check_err $? "ping failed" log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" -- Gitee From d2c3964c1c83ee99a266e877faa5219d1923b65b Mon Sep 17 00:00:00 2001 From: Ivan Stepchenko Date: Fri, 21 Nov 2025 19:54:46 +0800 Subject: [PATCH 0418/1449] mtd: lpddr_cmds: fix signed shifts in lpddr_cmds ANBZ: #35228 commit d31af068650cbcc74ca4120f7a9ce025c1eb07c1 stable. commit c909fec69f84b39e63876c69b9df2c178c6b76ba upstream. There are several places where a value of type 'int' is shifted by lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and might reach 31 when QINFO reports a 2 GiB size - the maximum supported by LPDDR(1) compliant chips. This may cause unexpected sign-extensions when casting the integer value to the type of 'unsigned long'. Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before shifting so the computation is performed at the destination width. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") Signed-off-by: Ivan Stepchenko Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index 3c3939bc2dad..2a2318230936 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) mutex_init(&shared[i].lock); for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { *chip = lpddr->chips[i]; - chip->start += j << lpddr->chipshift; + chip->start += (unsigned long)j << lpddr->chipshift; chip->oldstate = chip->state = FL_READY; chip->priv = &shared[i]; /* those should be reset too since @@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, break; if ((len + ofs - 1) >> lpddr->chipshift) - thislen = (1<chipshift) - ofs; + thislen = (1UL << lpddr->chipshift) - ofs; else thislen = len; /* get the chip */ @@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, len -= thislen; ofs = 0; - last_end += 1 << lpddr->chipshift; + last_end += 1UL << lpddr->chipshift; chipnum++; chip = &lpddr->chips[chipnum]; } @@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) break; if ((len + ofs - 1) >> lpddr->chipshift) - thislen = (1<chipshift) - ofs; + thislen = (1UL << lpddr->chipshift) - ofs; else thislen = len; -- Gitee From b9eb3a1d8bebeb50f9d6631425de5c196900ad17 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Sat, 29 Nov 2025 09:32:05 +0800 Subject: [PATCH 0419/1449] remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs ANBZ: #35228 commit 61f371ade3b68dbb46e2d90882af993f73b489b5 stable. commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 upstream. The "qcom,halt-regs" consists of a phandle reference followed by the three offsets within syscon for halt registers. Thus, we need to request 4 integers from of_property_read_variable_u32_array(), with the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns -EOVERFLOW, causing .probe() to fail. Increase MAX_HALT_REG to 4, and update the indexes accordingly. Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") Signed-off-by: Alexandru Gagniuc Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c index cff1fa07d1de..f80d701225a1 100644 --- a/drivers/remoteproc/qcom_q6v5_wcss.c +++ b/drivers/remoteproc/qcom_q6v5_wcss.c @@ -85,7 +85,7 @@ #define TCSR_WCSS_CLK_MASK 0x1F #define TCSR_WCSS_CLK_ENABLE 0x14 -#define MAX_HALT_REG 3 +#define MAX_HALT_REG 4 enum { WCSS_IPQ8074, WCSS_QCS404, @@ -863,9 +863,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, return -EINVAL; } - wcss->halt_q6 = halt_reg[0]; - wcss->halt_wcss = halt_reg[1]; - wcss->halt_nc = halt_reg[2]; + wcss->halt_q6 = halt_reg[1]; + wcss->halt_wcss = halt_reg[2]; + wcss->halt_nc = halt_reg[3]; return 0; } -- Gitee From 3e4192f69ee4d49ae8ab6bc04c4968f127db4908 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Mon, 17 Nov 2025 16:55:57 +0800 Subject: [PATCH 0420/1449] md/raid5: fix IO hang when array is broken with IO inflight ANBZ: #35228 commit fe78b35d19aeb7778aaf95ef539b061e6aaf30ae stable. commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e upstream. Following test can cause IO hang: mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none sleep 5 echo 1 > /sys/block/sda/device/delete echo 1 > /sys/block/sdb/device/delete echo 1 > /sys/block/sdc/device/delete echo 1 > /sys/block/sdd/device/delete dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct Root cause: 1) all disks removed, however all rdevs in the array is still in sync, IO will be issued normally. 2) IO failure from sda, and set badblocks failed, sda will be faulty and MD_SB_CHANGING_PENDING will be set. 3) error recovery try to recover this IO from other disks, IO will be issued to sdb, sdc, and sdd. 4) IO failure from sdb, and set badblocks failed again, now array is broken and will become read-only. 5) IO failure from sdc and sdd, however, stripe can't be handled anymore because MD_SB_CHANGING_PENDING is set: handle_stripe handle_stripe if (test_bit MD_SB_CHANGING_PENDING) set_bit STRIPE_HANDLE goto finish // skip handling failed stripe release_stripe if (test_bit STRIPE_HANDLE) list_add_tail conf->hand_list 6) later raid5d can't handle failed stripe as well: raid5d md_check_recovery md_update_sb if (!md_is_rdwr()) // can't clear pending bit return if (test_bit MD_SB_CHANGING_PENDING) break; // can't handle failed stripe Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, fix this problem by skip this checking for read-only array. Link: https://lore.kernel.org/linux-raid/20251117085557.770572-3-yukuai@fnnas.com Fixes: d87f064f5874 ("md: never update metadata when array is read-only.") Signed-off-by: Yu Kuai Reviewed-by: Li Nan Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/raid5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 8a0edb429b13..33314182352d 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5002,7 +5002,8 @@ static void handle_stripe(struct stripe_head *sh) goto finish; if (s.handle_bad_blocks || - test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags)) { + (md_is_rdwr(conf->mddev) && + test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags))) { set_bit(STRIPE_HANDLE, &sh->state); goto finish; } @@ -6829,7 +6830,8 @@ static void raid5d(struct md_thread *thread) int batch_size, released; unsigned int offset; - if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + if (md_is_rdwr(mddev) && + test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) break; released = release_stripe_list(conf, conf->temp_inactive_list); -- Gitee From afff28e2434a617eaeda93c753a0b71b13f903b7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 27 Nov 2025 21:53:25 +0800 Subject: [PATCH 0421/1449] clk: keystone: fix compile testing ANBZ: #35228 commit 84a7efd23b7816d756d28e1353bda960ca938209 stable. commit b276445e98fe28609688fb85b89a81b803910e63 upstream. Some keystone clock drivers can be selected when COMPILE_TEST is enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk driver support") they are never actually built. Enable compile testing by allowing the build system to process the keystone drivers. Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") Signed-off-by: Johan Hovold Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index acac827d906a..95c11a3ff642 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -95,8 +95,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ obj-y += imx/ obj-y += ingenic/ -obj-$(CONFIG_ARCH_K3) += keystone/ -obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ +obj-y += keystone/ obj-y += mediatek/ obj-$(CONFIG_ARCH_MESON) += meson/ obj-y += microchip/ -- Gitee From 3593451f11ebfba50cad703ad920ad37e59de937 Mon Sep 17 00:00:00 2001 From: Xiang Mei Date: Fri, 28 Nov 2025 08:14:14 +0800 Subject: [PATCH 0422/1449] net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d01f0e072dadb02fe10f436b940dd957aff0d7d4 stable. commit 9fefc78f7f02d71810776fdeb119a05a946a27cc upstream. In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes that the parent qdisc will enqueue the current packet. However, this assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent qdisc stops enqueuing current packet, leaving the tree qlen/backlog accounting inconsistent. This mismatch can lead to a NULL dereference (e.g., when the parent Qdisc is qfq_qdisc). This patch computes the qlen/backlog delta in a more robust way by observing the difference before and after the series of cake_drop() calls, and then compensates the qdisc tree accounting if cake_enqueue() returns NET_XMIT_CN. To ensure correct compensation when ACK thinning is enabled, a new variable is introduced to keep qlen unchanged. Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") Signed-off-by: Xiang Mei Reviewed-by: Toke Høiland-Jørgensen Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index 85984c91cf51..14e06f474b6c 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -1609,7 +1609,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) __qdisc_drop(skb, to_free); sch->q.qlen--; - qdisc_tree_reduce_backlog(sch, 1, len); cake_heapify(q, 0); @@ -1755,14 +1754,14 @@ static void cake_reconfigure(struct Qdisc *sch); static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) { + u32 idx, tin, prev_qlen, prev_backlog, drop_id; struct cake_sched_data *q = qdisc_priv(sch); - int len = qdisc_pkt_len(skb); - int ret; + int len = qdisc_pkt_len(skb), ret; struct sk_buff *ack = NULL; ktime_t now = ktime_get(); struct cake_tin_data *b; struct cake_flow *flow; - u32 idx, tin; + bool same_flow = false; /* choose flow to insert into */ idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); @@ -1835,6 +1834,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, consume_skb(skb); } else { /* not splitting */ + int ack_pkt_len = 0; + cobalt_set_enqueue_time(skb, now); get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); flow_queue_add(flow, skb); @@ -1845,13 +1846,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, if (ack) { b->ack_drops++; sch->qstats.drops++; - b->bytes += qdisc_pkt_len(ack); - len -= qdisc_pkt_len(ack); + ack_pkt_len = qdisc_pkt_len(ack); + b->bytes += ack_pkt_len; q->buffer_used += skb->truesize - ack->truesize; if (q->rate_flags & CAKE_FLAG_INGRESS) cake_advance_shaper(q, b, ack, now, true); - qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); + qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); consume_skb(ack); } else { sch->q.qlen++; @@ -1860,11 +1861,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, /* stats */ b->packets++; - b->bytes += len; - b->backlogs[idx] += len; - b->tin_backlog += len; - sch->qstats.backlog += len; - q->avg_window_bytes += len; + b->bytes += len - ack_pkt_len; + b->backlogs[idx] += len - ack_pkt_len; + b->tin_backlog += len - ack_pkt_len; + sch->qstats.backlog += len - ack_pkt_len; + q->avg_window_bytes += len - ack_pkt_len; } if (q->overflow_timeout) @@ -1939,24 +1940,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, if (q->buffer_used > q->buffer_max_used) q->buffer_max_used = q->buffer_used; - if (q->buffer_used > q->buffer_limit) { - bool same_flow = false; - u32 dropped = 0; - u32 drop_id; + if (q->buffer_used <= q->buffer_limit) + return NET_XMIT_SUCCESS; - while (q->buffer_used > q->buffer_limit) { - dropped++; - drop_id = cake_drop(sch, to_free); + prev_qlen = sch->q.qlen; + prev_backlog = sch->qstats.backlog; - if ((drop_id >> 16) == tin && - (drop_id & 0xFFFF) == idx) - same_flow = true; - } - b->drop_overlimit += dropped; + while (q->buffer_used > q->buffer_limit) { + drop_id = cake_drop(sch, to_free); + if ((drop_id >> 16) == tin && + (drop_id & 0xFFFF) == idx) + same_flow = true; + } + + prev_qlen -= sch->q.qlen; + prev_backlog -= sch->qstats.backlog; + b->drop_overlimit += prev_qlen; - if (same_flow) - return NET_XMIT_CN; + if (same_flow) { + qdisc_tree_reduce_backlog(sch, prev_qlen - 1, + prev_backlog - len); + return NET_XMIT_CN; } + qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); return NET_XMIT_SUCCESS; } -- Gitee From 7c1a38641ce38ac2bd23c287eb964aa65cf799aa Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 3 Dec 2025 07:57:15 +0800 Subject: [PATCH 0423/1449] perf tools: Fix split kallsyms DSO counting ANBZ: #35228 commit 7438b1d70bf2d743c6d975e25865ea436b1e3a7a stable. commit ad0b9c4865b98dc37f4d606d26b1c19808796805 upstream. It's counted twice as it's increased after calling maps__insert(). I guess we want to increase it only after it's added properly. Reviewed-by: Ian Rogers Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") Signed-off-by: Namhyung Kim Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/perf/util/symbol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index ea24f21aafc3..18556b7a7656 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -905,11 +905,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, if (dso->kernel == DSO_SPACE__KERNEL_GUEST) snprintf(dso_name, sizeof(dso_name), "[guest.kernel].%d", - kernel_range++); + kernel_range); else snprintf(dso_name, sizeof(dso_name), "[kernel].%d", - kernel_range++); + kernel_range); ndso = dso__new(dso_name); if (ndso == NULL) -- Gitee From 08975c6e3b1d1998a6ab43ae04c55c007ca7e9bd Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 19 Mar 2024 19:06:34 +0800 Subject: [PATCH 0424/1449] pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling ANBZ: #35228 commit de0711dbfb5c32c070f3b5bdadfd508bcf74e354 stable. commit b5fe46efc147516a908d2d31bf40eb858ab76d51 upstream. The pinctrl-single driver handles pin_config_set by looking up the requested setting in a DT-defined lookup table, which defines what bits correspond to each setting. There is no way to add PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead code to disable the bias by applying the disable values of both the pullup and pulldown entries in the table. However, this code is inside the table-lookup loop, so it would only execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, which can never exist, so this code never runs. This commit lifts the offending code out of the loop, so it just executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, skippipng the table lookup loop. This also introduces a new `param` variable to make the code slightly more readable. This bug seems to have existed when this code was first merged in commit 9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in the lookup table, but that was removed, which is probably how this bug was introduced. Signed-off-by: Matthijs Kooijman Reviewed-by: Haojian Zhuang Reviewed-by: Tony Lindgren Message-ID: <20240319110633.230329-1-matthijs@stdin.nl> Signed-off-by: Linus Walleij Stable-dep-of: 61d1bb53547d ("pinctrl: single: Fix incorrect type for error return variable") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 7684039be10c..5c6d5add6eca 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -556,21 +556,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned offset = 0, shift = 0, i, data, ret; u32 arg; int j; + enum pin_config_param param; ret = pcs_get_function(pctldev, pin, &func); if (ret) return ret; for (j = 0; j < num_configs; j++) { + param = pinconf_to_config_param(configs[j]); + + /* BIAS_DISABLE has no entry in the func->conf table */ + if (param == PIN_CONFIG_BIAS_DISABLE) { + /* This just disables all bias entries */ + pcs_pinconf_clear_bias(pctldev, pin); + continue; + } + for (i = 0; i < func->nconfs; i++) { - if (pinconf_to_config_param(configs[j]) - != func->conf[i].param) + if (param != func->conf[i].param) continue; offset = pin * (pcs->width / BITS_PER_BYTE); data = pcs->read(pcs->base + offset); arg = pinconf_to_config_argument(configs[j]); - switch (func->conf[i].param) { + switch (param) { /* 2 parameters */ case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_DRIVE_STRENGTH: @@ -582,9 +591,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, data |= (arg << shift) & func->conf[i].mask; break; /* 4 parameters */ - case PIN_CONFIG_BIAS_DISABLE: - pcs_pinconf_clear_bias(pctldev, pin); - break; case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_UP: if (arg) { -- Gitee From 78a029687043c18f26c71406b9deae844a351b1c Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 3 Dec 2025 14:13:47 +0800 Subject: [PATCH 0425/1449] pinctrl: single: Fix incorrect type for error return variable ANBZ: #35228 commit ae836bfac958231ce68577fedfd4a8d16d7d825e stable. commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 upstream. pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, but assign it the return values of pcs_get_function() that may return negative error codes. This causes negative error codes to be converted to large positive values. Change ret from unsigned int to int in both functions. Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") Signed-off-by: Haotian Zhang Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/pinctrl-single.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 5c6d5add6eca..2ee0ee3b6ed1 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -489,7 +489,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); struct pcs_function *func; enum pin_config_param param; - unsigned offset = 0, data = 0, i, j, ret; + unsigned offset = 0, data = 0, i, j; + int ret; ret = pcs_get_function(pctldev, pin, &func); if (ret) @@ -553,9 +554,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, { struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); struct pcs_function *func; - unsigned offset = 0, shift = 0, i, data, ret; + unsigned offset = 0, shift = 0, i, data; u32 arg; - int j; + int j, ret; enum pin_config_param param; ret = pcs_get_function(pctldev, pin, &func); -- Gitee From ba9eee47a71e038f2547a83f5a09cef10ebe07a3 Mon Sep 17 00:00:00 2001 From: Abdun Nihaal Date: Wed, 3 Dec 2025 11:55:44 +0800 Subject: [PATCH 0426/1449] fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() ANBZ: #35228 commit a888905f28743a2a873f4392fc7cca8050232b14 stable. commit 164312662ae9764b83b84d97afb25c42eb2be473 upstream. The page allocated for vmem using __get_free_pages() is not freed on the error paths after it. Fix that by adding a corresponding __free_pages() call to the error path. Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") Signed-off-by: Abdun Nihaal Signed-off-by: Helge Deller Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/fbdev/ssd1307fb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 1a4f90ea7d5a..bf8ec4861b45 100644 --- a/drivers/video/fbdev/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -688,7 +688,7 @@ static int ssd1307fb_probe(struct i2c_client *client) if (!ssd1307fb_defio) { dev_err(dev, "Couldn't allocate deferred io.\n"); ret = -ENOMEM; - goto fb_alloc_error; + goto fb_defio_error; } ssd1307fb_defio->delay = HZ / refreshrate; @@ -766,6 +766,8 @@ static int ssd1307fb_probe(struct i2c_client *client) regulator_disable(par->vbat_reg); reset_oled_error: fb_deferred_io_cleanup(info); +fb_defio_error: + __free_pages(vmem, get_order(vmem_size)); fb_alloc_error: framebuffer_release(info); return ret; -- Gitee From c2d2db5d7305ceb4795d26c2f1fafe8a698a5cfe Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Wed, 3 Dec 2025 06:30:53 +0800 Subject: [PATCH 0427/1449] 9p: fix cache/debug options printing in v9fs_show_options ANBZ: #35228 commit f1fe47f592d3ff19bf203084b4b47aee70e3f08f stable. commit f0445613314f474c1a0ec6fa8a5cd153a618f1b6 upstream. commit 4eb3117888a92 changed the cache= option to accept either string shortcuts or bitfield values. It also changed /proc/mounts to emit the option as the hexadecimal numeric value rather than the shortcut string. However, by printing "cache=%x" without the leading 0x, shortcuts such as "cache=loose" will emit "cache=f" and 'f' is not a string that is parseable by kstrtoint(), so remounting may fail if a remount with "cache=f" is attempted. debug=%x has had the same problem since options have been displayed in c4fac9100456 ("9p: Implement show_options") Fix these by adding the 0x prefix to the hexadecimal value shown in /proc/mounts. Fixes: 4eb3117888a92 ("fs/9p: Rework cache modes and add new options to Documentation") Signed-off-by: Eric Sandeen Message-ID: <54b93378-dcf1-4b04-922d-c8b4393da299@redhat.com> [Dominique: use %#x at Al Viro's suggestion, also handle debug] Tested-by: Remi Pommarel Signed-off-by: Dominique Martinet Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/9p/v9fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index be61810cb779..159a2aae849b 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -101,7 +101,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) struct v9fs_session_info *v9ses = root->d_sb->s_fs_info; if (v9ses->debug) - seq_printf(m, ",debug=%x", v9ses->debug); + seq_printf(m, ",debug=%#x", v9ses->debug); if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID)) seq_printf(m, ",dfltuid=%u", from_kuid_munged(&init_user_ns, v9ses->dfltuid)); @@ -117,7 +117,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) if (v9ses->nodev) seq_puts(m, ",nodevmap"); if (v9ses->cache) - seq_printf(m, ",cache=%x", v9ses->cache); + seq_printf(m, ",cache=%#x", v9ses->cache); #ifdef CONFIG_9P_FSCACHE if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE)) seq_printf(m, ",cachetag=%s", v9ses->cachetag); -- Gitee From ee2a83d8c2952c5d7f32375189d5707ecb464967 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 18 Nov 2025 04:28:17 +0800 Subject: [PATCH 0428/1449] NFS: Avoid changing nlink when file removes and attribute updates race ANBZ: #35228 commit 796318ae388f8dc537e698164f5b97f3d02d3d88 stable. commit bd4928ec799b31c492eb63f9f4a0c1e0bb4bb3f7 upstream. If a file removal races with another operation that updates its attributes, then skip the change to nlink, and just mark the attributes as being stale. Reported-by: Aiden Lambert Fixes: 59a707b0d42e ("NFS: Ensure we revalidate the inode correctly after remove or rename") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/dir.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 385baf871800..70f55df9e4f9 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1901,13 +1901,15 @@ static int nfs_dentry_delete(const struct dentry *dentry) } /* Ensure that we revalidate inode->i_nlink */ -static void nfs_drop_nlink(struct inode *inode) +static void nfs_drop_nlink(struct inode *inode, unsigned long gencount) { + struct nfs_inode *nfsi = NFS_I(inode); + spin_lock(&inode->i_lock); /* drop the inode if we're reasonably sure this is the last link */ - if (inode->i_nlink > 0) + if (inode->i_nlink > 0 && gencount == nfsi->attr_gencount) drop_nlink(inode); - NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); + nfsi->attr_gencount = nfs_inc_attr_generation_counter(); nfs_set_cache_invalid( inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | NFS_INO_INVALID_NLINK); @@ -1921,8 +1923,9 @@ static void nfs_drop_nlink(struct inode *inode) static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) { if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { + unsigned long gencount = READ_ONCE(NFS_I(inode)->attr_gencount); nfs_complete_unlink(dentry, inode); - nfs_drop_nlink(inode); + nfs_drop_nlink(inode, gencount); } iput(inode); } @@ -2475,9 +2478,11 @@ static int nfs_safe_remove(struct dentry *dentry) trace_nfs_remove_enter(dir, dentry); if (inode != NULL) { + unsigned long gencount = READ_ONCE(NFS_I(inode)->attr_gencount); + error = NFS_PROTO(dir)->remove(dir, dentry); if (error == 0) - nfs_drop_nlink(inode); + nfs_drop_nlink(inode, gencount); } else error = NFS_PROTO(dir)->remove(dir, dentry); if (error == -ENOENT) @@ -2682,6 +2687,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, { struct inode *old_inode = d_inode(old_dentry); struct inode *new_inode = d_inode(new_dentry); + unsigned long new_gencount = 0; struct dentry *dentry = NULL; struct rpc_task *task; bool must_unblock = false; @@ -2734,6 +2740,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, } else { block_revalidate(new_dentry); must_unblock = true; + new_gencount = NFS_I(new_inode)->attr_gencount; spin_unlock(&new_dentry->d_lock); } @@ -2773,7 +2780,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, new_dir, new_dentry, error); if (!error) { if (new_inode != NULL) - nfs_drop_nlink(new_inode); + nfs_drop_nlink(new_inode, new_gencount); /* * The d_move() should be here instead of in an async RPC completion * handler because we need the proper locks to move the dentry. If -- Gitee From e42c0f8276094cd8ca603e14237156f251985905 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Tue, 11 Nov 2025 21:11:22 +0800 Subject: [PATCH 0429/1449] fs/nls: Fix utf16 to utf8 conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 29e8d9b274c9b465934c590301ed162377002ded stable. commit 25524b6190295577e4918c689644451365e6466d upstream. Currently the function responsible for converting between utf16 and utf8 strings will ignore any characters that cannot be converted. This however also includes multi-byte characters that do not fit into the provided string buffer. This can cause problems if such a multi-byte character is followed by a single-byte character. In such a case the multi-byte character might be ignored when the provided string buffer is too small, but the single-byte character might fit and is thus still copied into the resulting string. Fix this by stop filling the provided string buffer once a character does not fit. In order to be able to do this extend utf32_to_utf8() to return useful errno codes instead of -1. Fixes: 74675a58507e ("NLS: update handling of Unicode") Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20251111131125.3379-2-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nls/nls_base.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index a026dbd3593f..7eacded3c17d 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -94,7 +94,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout) l = u; if (l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR) - return -1; + return -EILSEQ; nc = 0; for (t = utf8_table; t->cmask && maxout; t++, maxout--) { @@ -110,7 +110,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout) return nc; } } - return -1; + return -EOVERFLOW; } EXPORT_SYMBOL(utf32_to_utf8); @@ -217,8 +217,16 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian, inlen--; } size = utf32_to_utf8(u, op, maxout); - if (size == -1) { - /* Ignore character and move on */ + if (size < 0) { + if (size == -EILSEQ) { + /* Ignore character and move on */ + continue; + } + /* + * Stop filling the buffer with data once a character + * does not fit anymore. + */ + break; } else { op += size; maxout -= size; -- Gitee From 9301a1345761f4f5c537e6ecc2368c79a41d128e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 19 Nov 2025 21:36:16 +0800 Subject: [PATCH 0430/1449] NFS: Initialise verifiers for visible dentries in readdir and lookup ANBZ: #35228 commit 991609c4a7b1a75dcfe8024aa4fe96def71ca29f stable. commit 9bd545539b233725a3416801f7c374bff0327d6e upstream. Ensure that the verifiers are initialised before calling d_splice_alias() in both nfs_prime_dcache() and nfs_lookup(). Reported-by: Michael Stoler Fixes: a1147b8281bd ("NFS: Fix up directory verifier races") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 70f55df9e4f9..d47e908ef411 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -785,16 +785,17 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry, goto out; } + nfs_set_verifier(dentry, dir_verifier); inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); alias = d_splice_alias(inode, dentry); d_lookup_done(dentry); if (alias) { if (IS_ERR(alias)) goto out; + nfs_set_verifier(alias, dir_verifier); dput(dentry); dentry = alias; } - nfs_set_verifier(dentry, dir_verifier); trace_nfs_readdir_lookup(d_inode(parent), dentry, 0); out: dput(dentry); @@ -2000,13 +2001,14 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in nfs_lookup_advise_force_readdirplus(dir, flags); no_entry: + nfs_set_verifier(dentry, dir_verifier); res = d_splice_alias(inode, dentry); if (res != NULL) { if (IS_ERR(res)) goto out; + nfs_set_verifier(res, dir_verifier); dentry = res; } - nfs_set_verifier(dentry, dir_verifier); out: trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res)); nfs_free_fattr(fattr); -- Gitee From ac584224a159f67a136f2a6befa300d36c268ff9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 19 Nov 2025 21:39:50 +0800 Subject: [PATCH 0431/1449] NFS: Initialise verifiers for visible dentries in nfs_atomic_open() ANBZ: #35228 commit b8045ad0d53a0204a9519702c59b0591ece5d0df stable. commit 518c32a1bc4f8df1a8442ee8cdfea3e2fcff20a0 upstream. Ensure that the verifiers are initialised before calling d_splice_alias() in nfs_atomic_open(). Reported-by: Michael Stoler Fixes: 809fd143de88 ("NFSv4: Ensure nfs_atomic_open set the dentry verifier on ENOENT") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d47e908ef411..32e922a20d0d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -2149,12 +2149,12 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, d_drop(dentry); switch (err) { case -ENOENT: - d_splice_alias(NULL, dentry); if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE)) dir_verifier = inode_peek_iversion_raw(dir); else dir_verifier = nfs_save_change_attribute(dir); nfs_set_verifier(dentry, dir_verifier); + d_splice_alias(NULL, dentry); break; case -EISDIR: case -ENOTDIR: -- Gitee From b7a430f82cea66b50e90a91d7a7500210dda8a2a Mon Sep 17 00:00:00 2001 From: Jonathan Curley Date: Thu, 13 Nov 2025 02:02:42 +0800 Subject: [PATCH 0432/1449] NFSv4/pNFS: Clear NFS_INO_LAYOUTCOMMIT in pnfs_mark_layout_stateid_invalid ANBZ: #35228 commit f718f9ea6094843b8c059b073af49ad61e9f49bb stable. commit e0f8058f2cb56de0b7572f51cd563ca5debce746 upstream. Fixes a crash when layout is null during this call stack: write_inode -> nfs4_write_inode -> pnfs_layoutcommit_inode pnfs_set_layoutcommit relies on the lseg refcount to keep the layout around. Need to clear NFS_INO_LAYOUTCOMMIT otherwise we might attempt to reference a null layout. Fixes: fe1cf9469d7bc ("pNFS: Clear all layout segment state in pnfs_mark_layout_stateid_invalid") Signed-off-by: Jonathan Curley Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/pnfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index b40c20bd364b..0737d9a15d86 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -465,6 +465,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg, *next; set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); + clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(lo->plh_inode)->flags); list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) pnfs_clear_lseg_state(lseg, lseg_list); pnfs_clear_layoutreturn_info(lo); -- Gitee From a5c1463bfd63e88100c892103eabbb6bbabf5f2f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 29 Nov 2025 02:39:07 +0800 Subject: [PATCH 0433/1449] Revert "nfs: ignore SB_RDONLY when remounting nfs" ANBZ: #35228 commit b2ed74f8ccd2a3b9a9ca0f53267f56cdf86fecfa stable. commit 400fa37afbb11a601c204b72af0f0e5bc2db695c upstream. This reverts commit 80c4de6ab44c14e910117a02f2f8241ffc6ec54a. Silently ignoring the "ro" and "rw" mount options causes user confusion, and regressions. Reported-by: Alkis Georgopoulos Cc: Li Lingfeng Fixes: 80c4de6ab44c ("nfs: ignore SB_RDONLY when remounting nfs") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/super.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 9c02e6b14108..fcdfc1e58036 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1025,16 +1025,6 @@ int nfs_reconfigure(struct fs_context *fc) sync_filesystem(sb); - /* - * The SB_RDONLY flag has been removed from the superblock during - * mounts to prevent interference between different filesystems. - * Similarly, it is also necessary to ignore the SB_RDONLY flag - * during reconfiguration; otherwise, it may also result in the - * creation of redundant superblocks when mounting a directory with - * different rw and ro flags multiple times. - */ - fc->sb_flags_mask &= ~SB_RDONLY; - /* * Userspace mount programs that send binary options generally send * them populated with default values. We have no way to know which -- Gitee From a7adbcdca47af4e135aa6826bf38b0e8d98da28c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 29 Nov 2025 02:39:38 +0800 Subject: [PATCH 0434/1449] Revert "nfs: clear SB_RDONLY before getting superblock" ANBZ: #35228 commit 350e69eb93eff60c585f84fe531699037fd5fc33 stable. commit d216b698d44e33417ad4cc796cb04ccddbb8c0ee upstream. This reverts commit 8cd9b785943c57a136536250da80ba1eb6f8eb18. Silently ignoring the "ro" and "rw" mount options causes user confusion, and regressions. Reported-by: Alkis Georgopoulos Cc: Li Lingfeng Fixes: 8cd9b785943c ("nfs: clear SB_RDONLY before getting superblock") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/super.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index fcdfc1e58036..868c53f914c6 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1282,17 +1282,8 @@ int nfs_get_tree_common(struct fs_context *fc) if (IS_ERR(server)) return PTR_ERR(server); - /* - * When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a - * superblock among each filesystem that mounts sub-directories - * belonging to a single exported root path. - * To prevent interference between different filesystems, the - * SB_RDONLY flag should be removed from the superblock. - */ if (server->flags & NFS_MOUNT_UNSHARED) compare_super = NULL; - else - fc->sb_flags &= ~SB_RDONLY; /* -o noac implies -o sync */ if (server->flags & NFS_MOUNT_NOAC) -- Gitee From 80c71b130ae0b419a7ebbec1faca84e9ed21a938 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 29 Nov 2025 02:39:45 +0800 Subject: [PATCH 0435/1449] Revert "nfs: ignore SB_RDONLY when mounting nfs" ANBZ: #35228 commit e04647b63cfd9a1c7bb1bd0329e5e1268078b88d stable. commit d4a26d34f1946142f9d32e540490e4926ae9a46b upstream. This reverts commit 52cb7f8f177878b4f22397b9c4d2c8f743766be3. Silently ignoring the "ro" and "rw" mount options causes user confusion, and regressions. Reported-by: Alkis Georgopoulos Cc: Li Lingfeng Fixes: 52cb7f8f1778 ("nfs: ignore SB_RDONLY when mounting nfs") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index bde81e0abf0a..161c8fffbc1d 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -12,7 +12,7 @@ #include #include -#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) +#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) extern const struct export_operations nfs_export_ops; -- Gitee From 649ca2f25809e22ce45a5c4d8fa2f027d2ec383f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 29 Nov 2025 03:22:44 +0800 Subject: [PATCH 0436/1449] NFS: Automounted filesystems should inherit ro,noexec,nodev,sync flags ANBZ: #35228 commit dce10c59211e5cd763a62ea01e79b82a629811e3 stable. commit 8675c69816e4276b979ff475ee5fac4688f80125 upstream. When a filesystem is being automounted, it needs to preserve the user-set superblock mount options, such as the "ro" flag. Reported-by: Li Lingfeng Link: https://lore.kernel.org/all/20240604112636.236517-3-lilingfeng@huaweicloud.com/ Fixes: f2aedb713c28 ("NFS: Add fs_context support.") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/namespace.c | 6 ++++++ fs/nfs/super.c | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index e7494cdd957e..40d7163bca87 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -149,6 +149,7 @@ struct vfsmount *nfs_d_automount(struct path *path) struct vfsmount *mnt = ERR_PTR(-ENOMEM); struct nfs_server *server = NFS_SB(path->dentry->d_sb); struct nfs_client *client = server->nfs_client; + unsigned long s_flags = path->dentry->d_sb->s_flags; int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout); int ret; @@ -174,6 +175,11 @@ struct vfsmount *nfs_d_automount(struct path *path) fc->net_ns = get_net(client->cl_net); } + /* Inherit the flags covered by NFS_SB_MASK */ + fc->sb_flags_mask |= NFS_SB_MASK; + fc->sb_flags &= ~NFS_SB_MASK; + fc->sb_flags |= s_flags & NFS_SB_MASK; + /* for submounts we want the same server; referrals will reassign */ memcpy(&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen); ctx->nfs_server.addrlen = client->cl_addrlen; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 868c53f914c6..f5682889d347 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1289,10 +1289,6 @@ int nfs_get_tree_common(struct fs_context *fc) if (server->flags & NFS_MOUNT_NOAC) fc->sb_flags |= SB_SYNCHRONOUS; - if (ctx->clone_data.sb) - if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS) - fc->sb_flags |= SB_SYNCHRONOUS; - /* Get a superblock - note that we may end up sharing one that already exists */ fc->s_fs_info = server; s = sget_fc(fc, compare_super, nfs_set_super); -- Gitee From 51c5d17a2c6f71f021ec20e0caa397e3ec4cfca3 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 29 May 2025 18:45:45 +0800 Subject: [PATCH 0437/1449] Expand the type of nfs_fattr->valid ANBZ: #35228 commit 52cfde819a961f821d509e8fd97f9a55d05a192d stable. commit ce60ab3964782df9ba34f0a64c0bc766dd508bde upstream. We need to be able to track more than 32 attributes per inode. Signed-off-by: Trond Myklebust Signed-off-by: Lance Shelton Signed-off-by: Benjamin Coddington Reviewed-by: Jeff Layton Link: https://lore.kernel.org/r/1e3405fca54efd0be7c91c1da77917b94f5dfcc4.1748515333.git.bcodding@redhat.com Signed-off-by: Trond Myklebust Stable-dep-of: 2b092175f5e3 ("NFS: Fix inheritance of the block sizes when automounting") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/inode.c | 2 +- include/linux/nfs_fs_sb.h | 2 +- include/linux/nfs_xdr.h | 54 +++++++++++++++++++-------------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 5cd5e4226db3..0d7facfdafb9 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2086,7 +2086,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) bool attr_changed = false; bool have_delegation; - dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n", + dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%llx)\n", __func__, inode->i_sb->s_id, inode->i_ino, nfs_display_fhandle_hash(NFS_FH(inode)), atomic_read(&inode->i_count), fattr->valid); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 374b1b208bd8..ac2d720a164f 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -157,8 +157,8 @@ struct nfs_server { #define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000 #define NFS_MOUNT_SHUTDOWN 0x08000000 - unsigned int fattr_valid; /* Valid attributes */ unsigned int caps; /* server capabilities */ + __u64 fattr_valid; /* Valid attributes */ unsigned int rsize; /* read size */ unsigned int rpages; /* read size (in pages) */ unsigned int wsize; /* write size */ diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 12bbb5c63664..e2a99bf46cdf 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -45,7 +45,7 @@ struct nfs4_threshold { }; struct nfs_fattr { - unsigned int valid; /* which fields are valid */ + __u64 valid; /* which fields are valid */ umode_t mode; __u32 nlink; kuid_t uid; @@ -80,32 +80,32 @@ struct nfs_fattr { struct nfs4_label *label; }; -#define NFS_ATTR_FATTR_TYPE (1U << 0) -#define NFS_ATTR_FATTR_MODE (1U << 1) -#define NFS_ATTR_FATTR_NLINK (1U << 2) -#define NFS_ATTR_FATTR_OWNER (1U << 3) -#define NFS_ATTR_FATTR_GROUP (1U << 4) -#define NFS_ATTR_FATTR_RDEV (1U << 5) -#define NFS_ATTR_FATTR_SIZE (1U << 6) -#define NFS_ATTR_FATTR_PRESIZE (1U << 7) -#define NFS_ATTR_FATTR_BLOCKS_USED (1U << 8) -#define NFS_ATTR_FATTR_SPACE_USED (1U << 9) -#define NFS_ATTR_FATTR_FSID (1U << 10) -#define NFS_ATTR_FATTR_FILEID (1U << 11) -#define NFS_ATTR_FATTR_ATIME (1U << 12) -#define NFS_ATTR_FATTR_MTIME (1U << 13) -#define NFS_ATTR_FATTR_CTIME (1U << 14) -#define NFS_ATTR_FATTR_PREMTIME (1U << 15) -#define NFS_ATTR_FATTR_PRECTIME (1U << 16) -#define NFS_ATTR_FATTR_CHANGE (1U << 17) -#define NFS_ATTR_FATTR_PRECHANGE (1U << 18) -#define NFS_ATTR_FATTR_V4_LOCATIONS (1U << 19) -#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 20) -#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 21) -#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22) -#define NFS_ATTR_FATTR_OWNER_NAME (1U << 23) -#define NFS_ATTR_FATTR_GROUP_NAME (1U << 24) -#define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25) +#define NFS_ATTR_FATTR_TYPE BIT_ULL(0) +#define NFS_ATTR_FATTR_MODE BIT_ULL(1) +#define NFS_ATTR_FATTR_NLINK BIT_ULL(2) +#define NFS_ATTR_FATTR_OWNER BIT_ULL(3) +#define NFS_ATTR_FATTR_GROUP BIT_ULL(4) +#define NFS_ATTR_FATTR_RDEV BIT_ULL(5) +#define NFS_ATTR_FATTR_SIZE BIT_ULL(6) +#define NFS_ATTR_FATTR_PRESIZE BIT_ULL(7) +#define NFS_ATTR_FATTR_BLOCKS_USED BIT_ULL(8) +#define NFS_ATTR_FATTR_SPACE_USED BIT_ULL(9) +#define NFS_ATTR_FATTR_FSID BIT_ULL(10) +#define NFS_ATTR_FATTR_FILEID BIT_ULL(11) +#define NFS_ATTR_FATTR_ATIME BIT_ULL(12) +#define NFS_ATTR_FATTR_MTIME BIT_ULL(13) +#define NFS_ATTR_FATTR_CTIME BIT_ULL(14) +#define NFS_ATTR_FATTR_PREMTIME BIT_ULL(15) +#define NFS_ATTR_FATTR_PRECTIME BIT_ULL(16) +#define NFS_ATTR_FATTR_CHANGE BIT_ULL(17) +#define NFS_ATTR_FATTR_PRECHANGE BIT_ULL(18) +#define NFS_ATTR_FATTR_V4_LOCATIONS BIT_ULL(19) +#define NFS_ATTR_FATTR_V4_REFERRAL BIT_ULL(20) +#define NFS_ATTR_FATTR_MOUNTPOINT BIT_ULL(21) +#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID BIT_ULL(22) +#define NFS_ATTR_FATTR_OWNER_NAME BIT_ULL(23) +#define NFS_ATTR_FATTR_GROUP_NAME BIT_ULL(24) +#define NFS_ATTR_FATTR_V4_SECURITY_LABEL BIT_ULL(25) #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | NFS_ATTR_FATTR_MODE \ -- Gitee From cc051923442a8c21dbfbd805e66b433eca8d78bc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 29 Nov 2025 05:06:41 +0800 Subject: [PATCH 0438/1449] NFS: Fix inheritance of the block sizes when automounting ANBZ: #35228 commit a98719b6af3e7945f2430536906f0a9a381668cc stable. commit 2b092175f5e301cdaa935093edfef2be9defb6df upstream. Only inherit the block sizes that were actually specified as mount parameters for the parent mount. Fixes: 62a55d088cd8 ("NFS: Additional refactoring for fs_context conversion") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/client.c | 21 +++++++++++++++++---- fs/nfs/internal.h | 1 - fs/nfs/namespace.c | 5 ++++- fs/nfs/nfs4client.c | 18 ++++++++++++++---- fs/nfs/super.c | 10 +++------- include/linux/nfs_fs_sb.h | 5 +++++ 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 1bcdaee7e856..de4922ce4ac7 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -759,10 +759,18 @@ static int nfs_init_server(struct nfs_server *server, server->fattr_valid = NFS_ATTR_FATTR_V4; } - if (ctx->rsize) + if (ctx->bsize) { + server->bsize = ctx->bsize; + server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE; + } + if (ctx->rsize) { server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto); - if (ctx->wsize) + server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE; + } + if (ctx->wsize) { server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto); + server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE; + } server->acregmin = ctx->acregmin * HZ; server->acregmax = ctx->acregmax * HZ; @@ -954,8 +962,13 @@ EXPORT_SYMBOL_GPL(nfs_probe_server); void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) { target->flags = source->flags; - target->rsize = source->rsize; - target->wsize = source->wsize; + target->automount_inherit = source->automount_inherit; + if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE) + target->bsize = source->bsize; + if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_RSIZE) + target->rsize = source->rsize; + if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_WSIZE) + target->wsize = source->wsize; target->acregmin = source->acregmin; target->acregmax = source->acregmax; target->acdirmin = source->acdirmin; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 161c8fffbc1d..3d5ae22ed3a8 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -150,7 +150,6 @@ struct nfs_fs_context { struct super_block *sb; struct dentry *dentry; struct nfs_fattr *fattr; - unsigned int inherited_bsize; } clone_data; }; diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 40d7163bca87..923b5c1eb47e 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -190,6 +190,10 @@ struct vfsmount *nfs_d_automount(struct path *path) ctx->nfs_mod = client->cl_nfs_mod; __module_get(ctx->nfs_mod->owner); + /* Inherit block sizes if they were specified as mount parameters */ + if (server->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE) + ctx->bsize = server->bsize; + ret = client->rpc_ops->submount(fc, server); if (ret < 0) { mnt = ERR_PTR(ret); @@ -290,7 +294,6 @@ int nfs_do_submount(struct fs_context *fc) return -ENOMEM; ctx->internal = true; - ctx->clone_data.inherited_bsize = ctx->clone_data.sb->s_blocksize_bits; p = nfs_devname(dentry, buffer, 4096); if (IS_ERR(p)) { diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index b14688da814d..3f31d05e87ae 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -1176,10 +1176,20 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) if (error < 0) return error; - if (ctx->rsize) - server->rsize = nfs_io_size(ctx->rsize, server->nfs_client->cl_proto); - if (ctx->wsize) - server->wsize = nfs_io_size(ctx->wsize, server->nfs_client->cl_proto); + if (ctx->bsize) { + server->bsize = ctx->bsize; + server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE; + } + if (ctx->rsize) { + server->rsize = + nfs_io_size(ctx->rsize, server->nfs_client->cl_proto); + server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE; + } + if (ctx->wsize) { + server->wsize = + nfs_io_size(ctx->wsize, server->nfs_client->cl_proto); + server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE; + } server->acregmin = ctx->acregmin * HZ; server->acregmax = ctx->acregmax * HZ; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f5682889d347..437634e57b5b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1065,8 +1065,9 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx) sb->s_blocksize = 0; sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr; sb->s_op = server->nfs_client->cl_nfs_mod->sops; - if (ctx->bsize) - sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits); + if (server->bsize) + sb->s_blocksize = + nfs_block_size(server->bsize, &sb->s_blocksize_bits); switch (server->nfs_client->rpc_ops->version) { case 2: @@ -1312,13 +1313,8 @@ int nfs_get_tree_common(struct fs_context *fc) } if (!s->s_root) { - unsigned bsize = ctx->clone_data.inherited_bsize; /* initial superblock/root creation */ nfs_fill_super(s, ctx); - if (bsize) { - s->s_blocksize_bits = bsize; - s->s_blocksize = 1U << bsize; - } error = nfs_get_cache_cookie(s, ctx); if (error < 0) goto error_splat_super; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index ac2d720a164f..4ca77c50e489 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -157,6 +157,11 @@ struct nfs_server { #define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000 #define NFS_MOUNT_SHUTDOWN 0x08000000 + unsigned int automount_inherit; /* Properties inherited by automount */ +#define NFS_AUTOMOUNT_INHERIT_BSIZE 0x0001 +#define NFS_AUTOMOUNT_INHERIT_RSIZE 0x0002 +#define NFS_AUTOMOUNT_INHERIT_WSIZE 0x0004 + unsigned int caps; /* server capabilities */ __u64 fattr_valid; /* Valid attributes */ unsigned int rsize; /* read size */ -- Gitee From 78a2b7f351f34e1dd5a03050f8ff91a9fa953b88 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Sat, 29 Nov 2025 19:15:35 +0800 Subject: [PATCH 0439/1449] fs/nls: Fix inconsistency between utf8_to_utf32() and utf32_to_utf8() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4543d9ccd99e77a7697a52be73c0d297ccf6628e stable. commit c36f9d7b2869a003a2f7d6ff2c6bac9e62fd7d68 upstream. After commit 25524b619029 ("fs/nls: Fix utf16 to utf8 conversion"), the return values of utf8_to_utf32() and utf32_to_utf8() are inconsistent when encountering an error: utf8_to_utf32() returns -1, while utf32_to_utf8() returns errno codes. Fix this inconsistency by modifying utf8_to_utf32() to return errno codes as well. Fixes: 25524b619029 ("fs/nls: Fix utf16 to utf8 conversion") Suggested-by: Andy Shevchenko Reviewed-by: Andy Shevchenko Signed-off-by: Armin Wolf Link: https://patch.msgid.link/20251129111535.8984-1-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nls/nls_base.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 7eacded3c17d..f072eb6b563f 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -67,19 +67,22 @@ int utf8_to_utf32(const u8 *s, int inlen, unicode_t *pu) l &= t->lmask; if (l < t->lval || l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR) - return -1; + return -EILSEQ; + *pu = (unicode_t) l; return nc; } if (inlen <= nc) - return -1; + return -EOVERFLOW; + s++; c = (*s ^ 0x80) & 0xFF; if (c & 0xC0) - return -1; + return -EILSEQ; + l = (l << 6) | c; } - return -1; + return -EILSEQ; } EXPORT_SYMBOL(utf8_to_utf32); -- Gitee From ad28cf72b82a2659ae502c651556e2c6fcb52ed7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 29 Nov 2025 18:13:08 +0800 Subject: [PATCH 0440/1449] platform/x86: asus-wmi: use brightness_set_blocking() for kbd led MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 1edf1b4467d39b4bd1686672f25591ff6025e28e stable. commit ccb61a328321ba3f8567e350664c9ca7a42b6c70 upstream. kbd_led_set() can sleep, and so may not be used as the brightness_set() callback. Otherwise using this led with a trigger leads to system hangs accompanied by: BUG: scheduling while atomic: acpi_fakekeyd/2588/0x00000003 CPU: 4 UID: 0 PID: 2588 Comm: acpi_fakekeyd Not tainted 6.17.9+deb14-amd64 #1 PREEMPT(lazy) Debian 6.17.9-1 Hardware name: ASUSTeK COMPUTER INC. ASUS EXPERTBOOK B9403CVAR/B9403CVAR, BIOS B9403CVAR.311 12/24/2024 Call Trace: [...] schedule_timeout+0xbd/0x100 __down_common+0x175/0x290 down_timeout+0x67/0x70 acpi_os_wait_semaphore+0x57/0x90 [...] asus_wmi_evaluate_method3+0x87/0x190 [asus_wmi] led_trigger_event+0x3f/0x60 [...] Fixes: 9fe44fc98ce4 ("platform/x86: asus-wmi: Simplify the keyboard brightness updating process") Signed-off-by: Anton Khirnov Reviewed-by: Andy Shevchenko Reviewed-by: Denis Benato Link: https://patch.msgid.link/20251129101307.18085-3-anton@khirnov.net Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/asus-wmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 2c894ea8aa81..b56be64fcc63 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -1405,14 +1405,14 @@ static void do_kbd_led_set(struct led_classdev *led_cdev, int value) kbd_led_update(asus); } -static void kbd_led_set(struct led_classdev *led_cdev, - enum led_brightness value) +static int kbd_led_set(struct led_classdev *led_cdev, enum led_brightness value) { /* Prevent disabling keyboard backlight on module unregister */ if (led_cdev->flags & LED_UNREGISTERING) - return; + return 0; do_kbd_led_set(led_cdev, value); + return 0; } static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value) @@ -1565,7 +1565,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus) asus->kbd_led_wk = led_val; asus->kbd_led.name = "asus::kbd_backlight"; asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED; - asus->kbd_led.brightness_set = kbd_led_set; + asus->kbd_led.brightness_set_blocking = kbd_led_set; asus->kbd_led.brightness_get = kbd_led_get; asus->kbd_led.max_brightness = 3; -- Gitee From 0e23b6af54c479bb8fdb1c748ccd16436e5e32b8 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 2 Dec 2025 18:16:42 +0800 Subject: [PATCH 0441/1449] ASoC: bcm: bcm63xx-pcm-whistler: Check return value of of_dma_configure() ANBZ: #35228 commit 5fd617128b57eaf879936bbd1bcbcd7cd436c614 stable. commit 0ebbd45c33d0049ebf5a22c1434567f0c420b333 upstream. bcm63xx_soc_pcm_new() does not check the return value of of_dma_configure(), which may fail with -EPROBE_DEFER or other errors, allowing PCM setup to continue with incomplete DMA configuration. Add error checking for of_dma_configure() and return on failure. Fixes: 88eb404ccc3e ("ASoC: brcm: Add DSL/PON SoC audio driver") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251202101642.492-1-vulab@iscas.ac.cn Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/bcm/bcm63xx-pcm-whistler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/bcm/bcm63xx-pcm-whistler.c b/sound/soc/bcm/bcm63xx-pcm-whistler.c index 2c600b017524..760cb1887090 100644 --- a/sound/soc/bcm/bcm63xx-pcm-whistler.c +++ b/sound/soc/bcm/bcm63xx-pcm-whistler.c @@ -354,7 +354,9 @@ static int bcm63xx_soc_pcm_new(struct snd_soc_component *component, i2s_priv = dev_get_drvdata(asoc_rtd_to_cpu(rtd, 0)->dev); - of_dma_configure(pcm->card->dev, pcm->card->dev->of_node, 1); + ret = of_dma_configure(pcm->card->dev, pcm->card->dev->of_node, 1); + if (ret) + return ret; ret = dma_coerce_mask_and_coherent(pcm->card->dev, DMA_BIT_MASK(32)); if (ret) -- Gitee From 2dcc09fa52dd0adc4a1faa03807c984bb622e85d Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 3 Dec 2025 18:05:28 +0800 Subject: [PATCH 0442/1449] ASoC: ak4458: Disable regulator when error happens ANBZ: #35228 commit 8465515b8689f0a51ad753320fcb58615409569b stable. commit ae585fabb9713a43e358cf606451386757225c95 upstream. Disable regulator in runtime resume when error happens to balance the reference count of regulator. Fixes: 7e3096e8f823 ("ASoC: ak4458: Add regulator support") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20251203100529.3841203-2-shengjiu.wang@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/ak4458.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c index 77678f85ad94..ec8771158ab2 100644 --- a/sound/soc/codecs/ak4458.c +++ b/sound/soc/codecs/ak4458.c @@ -681,7 +681,15 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev) regcache_cache_only(ak4458->regmap, false); regcache_mark_dirty(ak4458->regmap); - return regcache_sync(ak4458->regmap); + ret = regcache_sync(ak4458->regmap); + if (ret) + goto err; + + return 0; +err: + regcache_cache_only(ak4458->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(ak4458->supplies), ak4458->supplies); + return ret; } #endif /* CONFIG_PM */ -- Gitee From 54045d72acc4ea43267d4205b9cb61287128194e Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 3 Dec 2025 18:05:29 +0800 Subject: [PATCH 0443/1449] ASoC: ak5558: Disable regulator when error happens ANBZ: #35228 commit 5e3230f9f6441abd4434544d4ff1169c72596654 stable. commit 1f8f726a2a29c28f65b30880335a1610c5e63594 upstream. Disable regulator in runtime resume when error happens to balance the reference count of regulator. Fixes: 2ff6d5a108c6 ("ASoC: ak5558: Add regulator support") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20251203100529.3841203-3-shengjiu.wang@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/ak5558.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c index 442e2cb42df4..aeec8dabfe3f 100644 --- a/sound/soc/codecs/ak5558.c +++ b/sound/soc/codecs/ak5558.c @@ -372,7 +372,15 @@ static int __maybe_unused ak5558_runtime_resume(struct device *dev) regcache_cache_only(ak5558->regmap, false); regcache_mark_dirty(ak5558->regmap); - return regcache_sync(ak5558->regmap); + ret = regcache_sync(ak5558->regmap); + if (ret) + goto err; + + return 0; +err: + regcache_cache_only(ak5558->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(ak5558->supplies), ak5558->supplies); + return ret; } static const struct dev_pm_ops ak5558_pm = { -- Gitee From 281ea917ea0758d72b028c4b5624dce12ed0098c Mon Sep 17 00:00:00 2001 From: Cong Zhang Date: Wed, 3 Dec 2025 11:34:21 +0800 Subject: [PATCH 0444/1449] blk-mq: Abort suspend when wakeup events are pending ANBZ: #35228 commit 94f146df56fb3ca0b831c6f60825478c218363f2 stable. commit c196bf43d706592d8801a7513603765080e495fb upstream. During system suspend, wakeup capable IRQs for block device can be delayed, which can cause blk_mq_hctx_notify_offline() to hang indefinitely while waiting for pending request to complete. Skip the request waiting loop and abort suspend when wakeup events are pending to prevent the deadlock. Fixes: bf0beec0607d ("blk-mq: drain I/O when all CPUs in a hctx are offline") Signed-off-by: Cong Zhang Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- block/blk-mq.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 68f546b24b8c..7cc9244f570f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -3613,6 +3614,7 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) { struct blk_mq_hw_ctx *hctx = hlist_entry_safe(node, struct blk_mq_hw_ctx, cpuhp_online); + int ret = 0; if (!cpumask_test_cpu(cpu, hctx->cpumask) || !blk_mq_last_cpu_in_hctx(cpu, hctx)) @@ -3634,12 +3636,24 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) * frozen and there are no requests. */ if (percpu_ref_tryget(&hctx->queue->q_usage_counter)) { - while (blk_mq_hctx_has_requests(hctx)) + while (blk_mq_hctx_has_requests(hctx)) { + /* + * The wakeup capable IRQ handler of block device is + * not called during suspend. Skip the loop by checking + * pm_wakeup_pending to prevent the deadlock and improve + * suspend latency. + */ + if (pm_wakeup_pending()) { + clear_bit(BLK_MQ_S_INACTIVE, &hctx->state); + ret = -EBUSY; + break; + } msleep(5); + } percpu_ref_put(&hctx->queue->q_usage_counter); } - return 0; + return ret; } static int blk_mq_hctx_notify_online(unsigned int cpu, struct hlist_node *node) -- Gitee From 960560b1d39668324c71132155de01cc4c9c6b46 Mon Sep 17 00:00:00 2001 From: shechenglong Date: Wed, 3 Dec 2025 23:17:49 +0800 Subject: [PATCH 0445/1449] block: fix comment for op_is_zone_mgmt() to include RESET_ALL ANBZ: #35228 commit 27d20907debf81ac2ad7a955001dda8312d261b3 stable. commit 8a32282175c964eb15638e8dfe199fc13c060f67 upstream. REQ_OP_ZONE_RESET_ALL is a zone management request, and op_is_zone_mgmt() has returned true for it. Update the comment to remove the misleading exception note so the documentation matches the implementation. Fixes: 12a1c9353c47 ("block: fix op_is_zone_mgmt() to handle REQ_OP_ZONE_RESET_ALL") Signed-off-by: shechenglong Reviewed-by: Damien Le Moal Reviewed-by: Johannes Thumshirn Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/blk_types.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index e4c753b403a4..700d1f30d1ae 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -566,10 +566,7 @@ static inline bool op_is_discard(blk_opf_t op) } /* - * Check if a bio or request operation is a zone management operation, with - * the exception of REQ_OP_ZONE_RESET_ALL which is treated as a special case - * due to its different handling in the block layer and device response in - * case of command failure. + * Check if a bio or request operation is a zone management operation. */ static inline bool op_is_zone_mgmt(enum req_op op) { -- Gitee From 4ec8c10b60c96a2a26034754d08654157ec5a352 Mon Sep 17 00:00:00 2001 From: Israel Rukshin Date: Sun, 23 Nov 2025 22:46:48 +0800 Subject: [PATCH 0446/1449] nvme-auth: use kvfree() for memory allocated with kvcalloc() ANBZ: #35228 commit 1e59c7587bb08f003159cd3612596536744c3db3 stable. commit bb9f4cca7c031de6f0e85f7ba24abf0172829f85 upstream. Memory allocated by kvcalloc() may come from vmalloc or kmalloc, so use kvfree() instead of kfree() for proper deallocation. Fixes: aa36d711e945 ("nvme-auth: convert dhchap_auth_list to an array") Signed-off-by: Israel Rukshin Reviewed-by: Max Gurtovoy Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c index 811541ce206b..f1b0a8e7af89 100644 --- a/drivers/nvme/host/auth.c +++ b/drivers/nvme/host/auth.c @@ -997,7 +997,7 @@ void nvme_auth_free(struct nvme_ctrl *ctrl) if (ctrl->dhchap_ctxs) { for (i = 0; i < ctrl_max_dhchaps(ctrl); i++) nvme_auth_free_dhchap(&ctrl->dhchap_ctxs[i]); - kfree(ctrl->dhchap_ctxs); + kvfree(ctrl->dhchap_ctxs); } if (ctrl->host_key) { nvme_auth_free_key(ctrl->host_key); -- Gitee From 105dfa65396470d54bb9c00572aecabd71bc13d6 Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Wed, 3 Dec 2025 12:27:03 +0800 Subject: [PATCH 0447/1449] ALSA: firewire-motu: fix buffer overflow in hwdep read for DSP events ANBZ: #35228 commit ddd32ec66bc4eb6969fe835e4cc1c0706c6348fe stable. commit 210d77cca3d0494ed30a5c628b20c1d95fa04fb1 upstream. The DSP event handling code in hwdep_read() could write more bytes to the user buffer than requested, when a user provides a buffer smaller than the event header size (8 bytes). Fix by using min_t() to clamp the copy size, This ensures we never copy more than the user requested. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model") Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB78810656377E79E58350D951AFD9A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/firewire/motu/motu-hwdep.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c index a220ac0c8eb8..28885c8004ae 100644 --- a/sound/firewire/motu/motu-hwdep.c +++ b/sound/firewire/motu/motu-hwdep.c @@ -83,10 +83,11 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, event.motu_register_dsp_change.type = SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE; event.motu_register_dsp_change.count = (consumed - sizeof(event.motu_register_dsp_change)) / 4; - if (copy_to_user(buf, &event, sizeof(event.motu_register_dsp_change))) + if (copy_to_user(buf, &event, + min_t(long, count, sizeof(event.motu_register_dsp_change)))) return -EFAULT; - count = consumed; + count = min_t(long, count, consumed); } else { spin_unlock_irq(&motu->lock); -- Gitee From c806c9f96725c32741391e07229ba825bb6d3c12 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 2 Dec 2025 23:28:10 +0800 Subject: [PATCH 0448/1449] dma/pool: eliminate alloc_pages warning in atomic_pool_expand ANBZ: #35228 commit 74f2a6b2cff8da57d9e4e6867bc97c76203df50d stable. commit 463d439becb81383f3a5a5d840800131f265a09c upstream. atomic_pool_expand iteratively tries the allocation while decrementing the page order. There is no need to issue a warning if an attempted allocation fails. Signed-off-by: Dave Kleikamp Reviewed-by: Robin Murphy Fixes: d7e673ec2c8e ("dma-pool: Only allocate from CMA when in same memory zone") [mszyprow: fixed typo] Signed-off-by: Marek Szyprowski Link: https://lore.kernel.org/r/20251202152810.142370-1-dave.kleikamp@oracle.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/dma/pool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index 6b0be9598a97..b3b9c7ec5fc5 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -93,7 +93,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, page = dma_alloc_from_contiguous(NULL, 1 << order, order, false); if (!page) - page = alloc_pages(gfp, order); + page = alloc_pages(gfp | __GFP_NOWARN, order); } while (!page && order-- > 0); if (!page) goto out; -- Gitee From 991dff95ef849599e9e05b30dc745d7333368049 Mon Sep 17 00:00:00 2001 From: Andres J Rosa Date: Thu, 4 Dec 2025 00:25:01 +0800 Subject: [PATCH 0449/1449] ALSA: uapi: Fix typo in asound.h comment ANBZ: #35228 commit 5ef0faed120a01d9563431b267f9f4c9db833ad6 stable. commit 9a97857db0c5655b8932f86b5d18bb959079b0ee upstream. Fix 'level-shit' to 'level-shift' in struct snd_cea_861_aud_if comment. Fixes: 7ba1c40b536e ("ALSA: Add definitions for CEA-861 Audio InfoFrames") Signed-off-by: Andres J Rosa Link: https://patch.msgid.link/20251203162509.1822-1-andyrosa@gmail.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/uapi/sound/asound.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index f9939da41122..10966a9250cd 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -60,7 +60,7 @@ struct snd_cea_861_aud_if { unsigned char db2_sf_ss; /* sample frequency and size */ unsigned char db3; /* not used, all zeros */ unsigned char db4_ca; /* channel allocation code */ - unsigned char db5_dminh_lsv; /* downmix inhibit & level-shit values */ + unsigned char db5_dminh_lsv; /* downmix inhibit & level-shift values */ }; /**************************************************************************** -- Gitee From af67cf7e57781c7eab69d9e281ffee1c3dde7904 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 26 Nov 2025 16:06:25 +0800 Subject: [PATCH 0450/1449] rtc: gamecube: Check the return value of ioremap() ANBZ: #35228 commit 2e09c882a66ed46ac04a661a7bfd913e5dbe254f stable. commit d1220e47e4bd2be8b84bc158f4dea44f2f88b226 upstream. The function ioremap() in gamecube_rtc_read_offset_from_sram() can fail and return NULL, which is dereferenced without checking, leading to a NULL pointer dereference. Add a check for the return value of ioremap() and return -ENOMEM on failure. Fixes: 86559400b3ef ("rtc: gamecube: Add a RTC driver for the GameCube, Wii and Wii U") Signed-off-by: Haotian Zhang Reviewed-by: Link Mauve Link: https://patch.msgid.link/20251126080625.1752-1-vulab@iscas.ac.cn Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/rtc/rtc-gamecube.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/rtc/rtc-gamecube.c b/drivers/rtc/rtc-gamecube.c index c828bc8e05b9..045d5d45ab4b 100644 --- a/drivers/rtc/rtc-gamecube.c +++ b/drivers/rtc/rtc-gamecube.c @@ -242,6 +242,10 @@ static int gamecube_rtc_read_offset_from_sram(struct priv *d) } hw_srnprot = ioremap(res.start, resource_size(&res)); + if (!hw_srnprot) { + pr_err("failed to ioremap hw_srnprot\n"); + return -ENOMEM; + } old = ioread32be(hw_srnprot); /* TODO: figure out why we use this magic constant. I obtained it by -- Gitee From a787a85123a039f46e800af4173a3463a72062da Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Tue, 9 Dec 2025 13:16:41 +0800 Subject: [PATCH 0451/1449] ALSA: firewire-motu: add bounds check in put_user loop for DSP events ANBZ: #35228 commit 6d4f17782ce4facf3197e79707df411ee3d7b30a stable. commit 298e753880b6ea99ac30df34959a7a03b0878eed upstream. In the DSP event handling code, a put_user() loop copies event data. When the user buffer size is not aligned to 4 bytes, it could overwrite beyond the buffer boundary. Fix by adding a bounds check before put_user(). Suggested-by: Takashi Iwai Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model") Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB788112C72AF8A1C8C448B4B8AFA3A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/firewire/motu/motu-hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c index 28885c8004ae..8519a9f9ce2c 100644 --- a/sound/firewire/motu/motu-hwdep.c +++ b/sound/firewire/motu/motu-hwdep.c @@ -75,7 +75,7 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, while (consumed < count && snd_motu_register_dsp_message_parser_copy_event(motu, &ev)) { ptr = (u32 __user *)(buf + consumed); - if (put_user(ev, ptr)) + if (consumed + sizeof(ev) > count || put_user(ev, ptr)) return -EFAULT; consumed += sizeof(ev); } -- Gitee From 40d820c6cac786ba27c775d2ca0908cde19ac784 Mon Sep 17 00:00:00 2001 From: Liyuan Pang Date: Tue, 9 Dec 2025 10:19:45 +0800 Subject: [PATCH 0452/1449] ARM: 9464/1: fix input-only operand modification in load_unaligned_zeropad() ANBZ: #35228 commit fd7e7353a5ba215bdf35655a07b72a297f2201d0 stable. commit edb924a7211c9aa7a4a415e03caee4d875e46b8e upstream. In the inline assembly inside load_unaligned_zeropad(), the "addr" is constrained as input-only operand. The compiler assumes that on exit from the asm statement these operands contain the same values as they had before executing the statement, but when kernel page fault happened, the assembly fixup code "bic %2 %2, #0x3" modify the value of "addr", which may lead to an unexpected behavior. Use a temporary variable "tmp" to handle it, instead of modifying the input-only operand, just like what arm64's load_unaligned_zeropad() does. Fixes: b9a50f74905a ("ARM: 7450/1: dcache: select DCACHE_WORD_ACCESS for little-endian ARMv6+ CPUs") Co-developed-by: Xie Yuanbin Signed-off-by: Xie Yuanbin Signed-off-by: Liyuan Pang Signed-off-by: Russell King (Oracle) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/include/asm/word-at-a-time.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h index 352ab213520d..2e6d0b4349f4 100644 --- a/arch/arm/include/asm/word-at-a-time.h +++ b/arch/arm/include/asm/word-at-a-time.h @@ -66,7 +66,7 @@ static inline unsigned long find_zero(unsigned long mask) */ static inline unsigned long load_unaligned_zeropad(const void *addr) { - unsigned long ret, offset; + unsigned long ret, tmp; /* Load word from unaligned pointer addr */ asm( @@ -74,9 +74,9 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) "2:\n" " .pushsection .text.fixup,\"ax\"\n" " .align 2\n" - "3: and %1, %2, #0x3\n" - " bic %2, %2, #0x3\n" - " ldr %0, [%2]\n" + "3: bic %1, %2, #0x3\n" + " ldr %0, [%1]\n" + " and %1, %2, #0x3\n" " lsl %1, %1, #0x3\n" #ifndef __ARMEB__ " lsr %0, %0, %1\n" @@ -89,7 +89,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) " .align 3\n" " .long 1b, 3b\n" " .popsection" - : "=&r" (ret), "=&r" (offset) + : "=&r" (ret), "=&r" (tmp) : "r" (addr), "Qo" (*(unsigned long *)addr)); return ret; -- Gitee From db54045554187a11ac20416a9f90c41e14168a17 Mon Sep 17 00:00:00 2001 From: Mohamed Khalfella Date: Sat, 6 Dec 2025 05:17:02 +0800 Subject: [PATCH 0453/1449] block: Use RCU in blk_mq_[un]quiesce_tagset() instead of set->tag_list_lock ANBZ: #35228 commit ca8764c0ea1fb825f17f19704af55e9e02c9f768 stable. commit 59e25ef2b413c72da6686d431e7759302cfccafa upstream. blk_mq_{add,del}_queue_tag_set() functions add and remove queues from tagset, the functions make sure that tagset and queues are marked as shared when two or more queues are attached to the same tagset. Initially a tagset starts as unshared and when the number of added queues reaches two, blk_mq_add_queue_tag_set() marks it as shared along with all the queues attached to it. When the number of attached queues drops to 1 blk_mq_del_queue_tag_set() need to mark both the tagset and the remaining queues as unshared. Both functions need to freeze current queues in tagset before setting on unsetting BLK_MQ_F_TAG_QUEUE_SHARED flag. While doing so, both functions hold set->tag_list_lock mutex, which makes sense as we do not want queues to be added or deleted in the process. This used to work fine until commit 98d81f0df70c ("nvme: use blk_mq_[un]quiesce_tagset") made the nvme driver quiesce tagset instead of quiscing individual queues. blk_mq_quiesce_tagset() does the job and quiesce the queues in set->tag_list while holding set->tag_list_lock also. This results in deadlock between two threads with these stacktraces: __schedule+0x47c/0xbb0 ? timerqueue_add+0x66/0xb0 schedule+0x1c/0xa0 schedule_preempt_disabled+0xa/0x10 __mutex_lock.constprop.0+0x271/0x600 blk_mq_quiesce_tagset+0x25/0xc0 nvme_dev_disable+0x9c/0x250 nvme_timeout+0x1fc/0x520 blk_mq_handle_expired+0x5c/0x90 bt_iter+0x7e/0x90 blk_mq_queue_tag_busy_iter+0x27e/0x550 ? __blk_mq_complete_request_remote+0x10/0x10 ? __blk_mq_complete_request_remote+0x10/0x10 ? __call_rcu_common.constprop.0+0x1c0/0x210 blk_mq_timeout_work+0x12d/0x170 process_one_work+0x12e/0x2d0 worker_thread+0x288/0x3a0 ? rescuer_thread+0x480/0x480 kthread+0xb8/0xe0 ? kthread_park+0x80/0x80 ret_from_fork+0x2d/0x50 ? kthread_park+0x80/0x80 ret_from_fork_asm+0x11/0x20 __schedule+0x47c/0xbb0 ? xas_find+0x161/0x1a0 schedule+0x1c/0xa0 blk_mq_freeze_queue_wait+0x3d/0x70 ? destroy_sched_domains_rcu+0x30/0x30 blk_mq_update_tag_set_shared+0x44/0x80 blk_mq_exit_queue+0x141/0x150 del_gendisk+0x25a/0x2d0 nvme_ns_remove+0xc9/0x170 nvme_remove_namespaces+0xc7/0x100 nvme_remove+0x62/0x150 pci_device_remove+0x23/0x60 device_release_driver_internal+0x159/0x200 unbind_store+0x99/0xa0 kernfs_fop_write_iter+0x112/0x1e0 vfs_write+0x2b1/0x3d0 ksys_write+0x4e/0xb0 do_syscall_64+0x5b/0x160 entry_SYSCALL_64_after_hwframe+0x4b/0x53 The top stacktrace is showing nvme_timeout() called to handle nvme command timeout. timeout handler is trying to disable the controller and as a first step, it needs to blk_mq_quiesce_tagset() to tell blk-mq not to call queue callback handlers. The thread is stuck waiting for set->tag_list_lock as it tries to walk the queues in set->tag_list. The lock is held by the second thread in the bottom stack which is waiting for one of queues to be frozen. The queue usage counter will drop to zero after nvme_timeout() finishes, and this will not happen because the thread will wait for this mutex forever. Given that [un]quiescing queue is an operation that does not need to sleep, update blk_mq_[un]quiesce_tagset() to use RCU instead of taking set->tag_list_lock, update blk_mq_{add,del}_queue_tag_set() to use RCU safe list operations. Also, delete INIT_LIST_HEAD(&q->tag_set_list) in blk_mq_del_queue_tag_set() because we can not re-initialize it while the list is being traversed under RCU. The deleted queue will not be added/deleted to/from a tagset and it will be freed in blk_free_queue() after the end of RCU grace period. Signed-off-by: Mohamed Khalfella Fixes: 98d81f0df70c ("nvme: use blk_mq_[un]quiesce_tagset") Reviewed-by: Ming Lei Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- block/blk-mq.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 7cc9244f570f..103da8441ecf 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -309,12 +309,12 @@ void blk_mq_quiesce_tagset(struct blk_mq_tag_set *set) { struct request_queue *q; - mutex_lock(&set->tag_list_lock); - list_for_each_entry(q, &set->tag_list, tag_set_list) { + rcu_read_lock(); + list_for_each_entry_rcu(q, &set->tag_list, tag_set_list) { if (!blk_queue_skip_tagset_quiesce(q)) blk_mq_quiesce_queue_nowait(q); } - mutex_unlock(&set->tag_list_lock); + rcu_read_unlock(); blk_mq_wait_quiesce_done(set); } @@ -324,12 +324,12 @@ void blk_mq_unquiesce_tagset(struct blk_mq_tag_set *set) { struct request_queue *q; - mutex_lock(&set->tag_list_lock); - list_for_each_entry(q, &set->tag_list, tag_set_list) { + rcu_read_lock(); + list_for_each_entry_rcu(q, &set->tag_list, tag_set_list) { if (!blk_queue_skip_tagset_quiesce(q)) blk_mq_unquiesce_queue(q); } - mutex_unlock(&set->tag_list_lock); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(blk_mq_unquiesce_tagset); @@ -4182,7 +4182,7 @@ static void blk_mq_del_queue_tag_set(struct request_queue *q) struct blk_mq_tag_set *set = q->tag_set; mutex_lock(&set->tag_list_lock); - list_del(&q->tag_set_list); + list_del_rcu(&q->tag_set_list); if (list_is_singular(&set->tag_list)) { /* just transitioned to unshared */ set->flags &= ~BLK_MQ_F_TAG_QUEUE_SHARED; @@ -4190,7 +4190,6 @@ static void blk_mq_del_queue_tag_set(struct request_queue *q) blk_mq_update_tag_set_shared(set, false); } mutex_unlock(&set->tag_list_lock); - INIT_LIST_HEAD(&q->tag_set_list); } static void blk_mq_add_queue_tag_set(struct blk_mq_tag_set *set, @@ -4209,7 +4208,7 @@ static void blk_mq_add_queue_tag_set(struct blk_mq_tag_set *set, } if (set->flags & BLK_MQ_F_TAG_QUEUE_SHARED) queue_set_hctx_shared(q, true); - list_add_tail(&q->tag_set_list, &set->tag_list); + list_add_tail_rcu(&q->tag_set_list, &set->tag_list); mutex_unlock(&set->tag_list_lock); } -- Gitee From 841f0509c148511328ff013808c39246960c57ca Mon Sep 17 00:00:00 2001 From: Alexey Simakov Date: Wed, 3 Dec 2025 01:18:38 +0800 Subject: [PATCH 0454/1449] dm-raid: fix possible NULL dereference with undefined raid type ANBZ: #35228 commit 448092910421ff3ea2ac33e0771e3d196744e91f stable. commit 2f6cfd6d7cb165a7af8877b838a9f6aab4159324 upstream. rs->raid_type is assigned from get_raid_type_by_ll(), which may return NULL. This NULL value could be dereferenced later in the condition 'if (!(rs_is_raid10(rs) && rt_is_raid0(rs->raid_type)))'. Add a fail-fast check to return early with an error if raid_type is NULL, similar to other uses of this function. Found by Linux Verification Center (linuxtesting.org) with Svace. Fixes: 33e53f06850f ("dm raid: introduce extended superblock and new raid types to support takeover/reshaping") Signed-off-by: Alexey Simakov Signed-off-by: Mikulas Patocka Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/dm-raid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index f23edd79df45..0c4ab6865182 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -2259,6 +2259,8 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) mddev->reshape_position = le64_to_cpu(sb->reshape_position); rs->raid_type = get_raid_type_by_ll(mddev->level, mddev->layout); + if (!rs->raid_type) + return -EINVAL; } } else { -- Gitee From d42afd2c97bd912b779c4e1854cf313451e0f237 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 1 Dec 2025 15:41:03 +0800 Subject: [PATCH 0455/1449] dm log-writes: Add missing set_freezable() for freezable kthread ANBZ: #35228 commit 99bc41d7d7962b4124ac00d6d2c90b9f0dcc8568 stable. commit ab08f9c8b363297cafaf45475b08f78bf19b88ef upstream. The log_writes_kthread() calls try_to_freeze() but lacks set_freezable(), rendering the freeze attempt ineffective since kernel threads are non-freezable by default. This prevents proper thread suspension during system suspend/hibernate. Add set_freezable() to explicitly mark the thread as freezable. Fixes: 0e9cebe72459 ("dm: add log writes target") Signed-off-by: Haotian Zhang Reviewed-by: Benjamin Marzinski Signed-off-by: Mikulas Patocka Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/dm-log-writes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c index f17a6cf2284e..dabfc856443a 100644 --- a/drivers/md/dm-log-writes.c +++ b/drivers/md/dm-log-writes.c @@ -432,6 +432,7 @@ static int log_writes_kthread(void *arg) struct log_writes_c *lc = arg; sector_t sector = 0; + set_freezable(); while (!kthread_should_stop()) { bool super = false; bool logging_enabled; -- Gitee From 54114f3457184fc3dbe7a266bb10b7dc08b3f55e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Aug 2025 00:52:54 +0800 Subject: [PATCH 0456/1449] efi/cper: Add a new helper function to print bitmasks ANBZ: #35228 commit b930724424b797385da25d294fc9ed991a70183f stable. commit a976d790f49499ccaa0f991788ad8ebf92e7fd5c upstream. Add a helper function to print a string with names associated to each bit field. A typical example is: const char * const bits[] = { "bit 3 name", "bit 4 name", "bit 5 name", }; char str[120]; unsigned int bitmask = BIT(3) | BIT(5); #define MASK GENMASK(5,3) cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask), bits, ARRAY_SIZE(bits)); The above code fills string "str" with "bit 3 name|bit 5 name". Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab Acked-by: Borislav Petkov (AMD) Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/efi/cper.c | 60 +++++++++++++++++++++++++++++++++++++ include/linux/cper.h | 2 ++ 2 files changed, 62 insertions(+) diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 81cb85b5a9fa..e23396473c46 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -12,6 +12,7 @@ * Specification version 2.4. */ +#include #include #include #include @@ -106,6 +107,65 @@ void cper_print_bits(const char *pfx, unsigned int bits, printk("%s\n", buf); } +/** + * cper_bits_to_str - return a string for set bits + * @buf: buffer to store the output string + * @buf_size: size of the output string buffer + * @bits: bit mask + * @strs: string array, indexed by bit position + * @strs_size: size of the string array: @strs + * + * Add to @buf the bitmask in hexadecimal. Then, for each set bit in @bits, + * add the corresponding string describing the bit in @strs to @buf. + * + * A typical example is:: + * + * const char * const bits[] = { + * "bit 3 name", + * "bit 4 name", + * "bit 5 name", + * }; + * char str[120]; + * unsigned int bitmask = BIT(3) | BIT(5); + * #define MASK GENMASK(5,3) + * + * cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask), + * bits, ARRAY_SIZE(bits)); + * + * The above code fills the string ``str`` with ``bit 3 name|bit 5 name``. + * + * Return: number of bytes stored or an error code if lower than zero. + */ +int cper_bits_to_str(char *buf, int buf_size, unsigned long bits, + const char * const strs[], unsigned int strs_size) +{ + int len = buf_size; + char *str = buf; + int i, size; + + *buf = '\0'; + + for_each_set_bit(i, &bits, strs_size) { + if (!(bits & BIT_ULL(i))) + continue; + + if (*buf && len > 0) { + *str = '|'; + len--; + str++; + } + + size = strscpy(str, strs[i], len); + if (size < 0) + return size; + + len -= size; + str += size; + } + return len - buf_size; +} +EXPORT_SYMBOL_GPL(cper_bits_to_str); + static const char * const proc_type_strs[] = { "IA32/X64", "IA64", diff --git a/include/linux/cper.h b/include/linux/cper.h index 9af9b87ca138..f0c238a21692 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -584,6 +584,8 @@ const char *cper_mem_err_type_str(unsigned int); const char *cper_mem_err_status_str(u64 status); void cper_print_bits(const char *prefix, unsigned int bits, const char * const strs[], unsigned int strs_size); +int cper_bits_to_str(char *buf, int buf_size, unsigned long bits, + const char * const strs[], unsigned int strs_size); void cper_mem_err_pack(const struct cper_sec_mem_err *, struct cper_mem_err_compact *); const char *cper_mem_err_unpack(struct trace_seq *, -- Gitee From 59af651ac192dcf1c97de5bd1466115daf437742 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Aug 2025 00:52:53 +0800 Subject: [PATCH 0457/1449] efi/cper: Adjust infopfx size to accept an extra space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit f5a28c4ee058fe157dd655abe61a7b2a3363603b stable. commit 8ad2c72e21efb3dc76c5b14089fa7984cdd87898 upstream. Compiling with W=1 with werror enabled produces an error: drivers/firmware/efi/cper-arm.c: In function ‘cper_print_proc_arm’: drivers/firmware/efi/cper-arm.c:298:64: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] 298 | snprintf(infopfx, sizeof(infopfx), "%s ", newpfx); | ^ drivers/firmware/efi/cper-arm.c:298:25: note: ‘snprintf’ output between 2 and 65 bytes into a destination of size 64 298 | snprintf(infopfx, sizeof(infopfx), "%s ", newpfx); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As the logic there adds an space at the end of infopx buffer. Add an extra space to avoid such warning. Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Jonathan Cameron Acked-by: Borislav Petkov (AMD) Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/efi/cper-arm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/cper-arm.c b/drivers/firmware/efi/cper-arm.c index fa9c1c3bf168..eb7ee6af55f2 100644 --- a/drivers/firmware/efi/cper-arm.c +++ b/drivers/firmware/efi/cper-arm.c @@ -240,7 +240,7 @@ void cper_print_proc_arm(const char *pfx, int i, len, max_ctx_type; struct cper_arm_err_info *err_info; struct cper_arm_ctx_info *ctx_info; - char newpfx[64], infopfx[64]; + char newpfx[64], infopfx[ARRAY_SIZE(newpfx) + 1]; printk("%sMIDR: 0x%016llx\n", pfx, proc->midr); -- Gitee From 10de0c9bf1e6f409c61fd31ed904ed6802c268cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 15 Aug 2025 00:52:55 +0800 Subject: [PATCH 0458/1449] efi/cper: align ARM CPER type with UEFI 2.9A/2.10 specs ANBZ: #35228 commit 94a4c58d7195c360f6719506931bbe3186ae91f4 stable. commit 96b010536ee020e716d28d9b359a4bcd18800aeb upstream. Up to UEFI spec 2.9, the type byte of CPER struct for ARM processor was defined simply as: Type at byte offset 4: - Cache error - TLB Error - Bus Error - Micro-architectural Error All other values are reserved Yet, there was no information about how this would be encoded. Spec 2.9A errata corrected it by defining: - Bit 1 - Cache Error - Bit 2 - TLB Error - Bit 3 - Bus Error - Bit 4 - Micro-architectural Error All other values are reserved That actually aligns with the values already defined on older versions at N.2.4.1. Generic Processor Error Section. Spec 2.10 also preserve the same encoding as 2.9A. Adjust CPER and GHES handling code for both generic and ARM processors to properly handle UEFI 2.9A and 2.10 encoding. Link: https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#arm-processor-error-information Signed-off-by: Mauro Carvalho Chehab Reviewed-by: Jonathan Cameron Acked-by: Borislav Petkov (AMD) Signed-off-by: Ard Biesheuvel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/apei/ghes.c | 16 +++++++---- drivers/firmware/efi/cper-arm.c | 50 ++++++++++++++++----------------- include/linux/cper.h | 10 +++---- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index a294efc36dd4..b507eef6d1f9 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -570,6 +571,7 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, { struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); int flags = sync ? MF_ACTION_REQUIRED : 0; + char error_type[120]; bool queued = false; int sec_sev, i; char *p; @@ -583,9 +585,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, p = (char *)(err + 1); for (i = 0; i < err->err_info_num; i++) { struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p; - bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR); + bool is_cache = err_info->type & CPER_ARM_CACHE_ERROR; bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR); - const char *error_type = "unknown error"; /* * The field (err_info->error_info & BIT(26)) is fixed to set to @@ -599,12 +600,15 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, continue; } - if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs)) - error_type = cper_proc_error_type_strs[err_info->type]; + cper_bits_to_str(error_type, sizeof(error_type), + FIELD_GET(CPER_ARM_ERR_TYPE_MASK, err_info->type), + cper_proc_error_type_strs, + ARRAY_SIZE(cper_proc_error_type_strs)); pr_warn_ratelimited(FW_WARN GHES_PFX - "Unhandled processor error type: %s\n", - error_type); + "Unhandled processor error type 0x%02x: %s%s\n", + err_info->type, error_type, + (err_info->type & ~CPER_ARM_ERR_TYPE_MASK) ? " with reserved bit(s)" : ""); p += err_info->length; } diff --git a/drivers/firmware/efi/cper-arm.c b/drivers/firmware/efi/cper-arm.c index eb7ee6af55f2..52d18490b59e 100644 --- a/drivers/firmware/efi/cper-arm.c +++ b/drivers/firmware/efi/cper-arm.c @@ -93,15 +93,11 @@ static void cper_print_arm_err_info(const char *pfx, u32 type, bool proc_context_corrupt, corrected, precise_pc, restartable_pc; bool time_out, access_mode; - /* If the type is unknown, bail. */ - if (type > CPER_ARM_MAX_TYPE) - return; - /* * Vendor type errors have error information values that are vendor * specific. */ - if (type == CPER_ARM_VENDOR_ERROR) + if (type & CPER_ARM_VENDOR_ERROR) return; if (error_info & CPER_ARM_ERR_VALID_TRANSACTION_TYPE) { @@ -116,43 +112,38 @@ static void cper_print_arm_err_info(const char *pfx, u32 type, if (error_info & CPER_ARM_ERR_VALID_OPERATION_TYPE) { op_type = ((error_info >> CPER_ARM_ERR_OPERATION_SHIFT) & CPER_ARM_ERR_OPERATION_MASK); - switch (type) { - case CPER_ARM_CACHE_ERROR: + if (type & CPER_ARM_CACHE_ERROR) { if (op_type < ARRAY_SIZE(arm_cache_err_op_strs)) { - printk("%soperation type: %s\n", pfx, + printk("%scache error, operation type: %s\n", pfx, arm_cache_err_op_strs[op_type]); } - break; - case CPER_ARM_TLB_ERROR: + } + if (type & CPER_ARM_TLB_ERROR) { if (op_type < ARRAY_SIZE(arm_tlb_err_op_strs)) { - printk("%soperation type: %s\n", pfx, + printk("%sTLB error, operation type: %s\n", pfx, arm_tlb_err_op_strs[op_type]); } - break; - case CPER_ARM_BUS_ERROR: + } + if (type & CPER_ARM_BUS_ERROR) { if (op_type < ARRAY_SIZE(arm_bus_err_op_strs)) { - printk("%soperation type: %s\n", pfx, + printk("%sbus error, operation type: %s\n", pfx, arm_bus_err_op_strs[op_type]); } - break; } } if (error_info & CPER_ARM_ERR_VALID_LEVEL) { level = ((error_info >> CPER_ARM_ERR_LEVEL_SHIFT) & CPER_ARM_ERR_LEVEL_MASK); - switch (type) { - case CPER_ARM_CACHE_ERROR: + if (type & CPER_ARM_CACHE_ERROR) printk("%scache level: %d\n", pfx, level); - break; - case CPER_ARM_TLB_ERROR: + + if (type & CPER_ARM_TLB_ERROR) printk("%sTLB level: %d\n", pfx, level); - break; - case CPER_ARM_BUS_ERROR: + + if (type & CPER_ARM_BUS_ERROR) printk("%saffinity level at which the bus error occurred: %d\n", pfx, level); - break; - } } if (error_info & CPER_ARM_ERR_VALID_PROC_CONTEXT_CORRUPT) { @@ -241,6 +232,7 @@ void cper_print_proc_arm(const char *pfx, struct cper_arm_err_info *err_info; struct cper_arm_ctx_info *ctx_info; char newpfx[64], infopfx[ARRAY_SIZE(newpfx) + 1]; + char error_type[120]; printk("%sMIDR: 0x%016llx\n", pfx, proc->midr); @@ -289,9 +281,15 @@ void cper_print_proc_arm(const char *pfx, newpfx); } - printk("%serror_type: %d, %s\n", newpfx, err_info->type, - err_info->type < ARRAY_SIZE(cper_proc_error_type_strs) ? - cper_proc_error_type_strs[err_info->type] : "unknown"); + cper_bits_to_str(error_type, sizeof(error_type), + FIELD_GET(CPER_ARM_ERR_TYPE_MASK, err_info->type), + cper_proc_error_type_strs, + ARRAY_SIZE(cper_proc_error_type_strs)); + + printk("%serror_type: 0x%02x: %s%s\n", newpfx, err_info->type, + error_type, + (err_info->type & ~CPER_ARM_ERR_TYPE_MASK) ? " with reserved bit(s)" : ""); + if (err_info->validation_bits & CPER_ARM_INFO_VALID_ERR_INFO) { printk("%serror_info: 0x%016llx\n", newpfx, err_info->error_info); diff --git a/include/linux/cper.h b/include/linux/cper.h index f0c238a21692..17a93a7780bb 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -293,11 +293,11 @@ enum { #define CPER_ARM_INFO_FLAGS_PROPAGATED BIT(2) #define CPER_ARM_INFO_FLAGS_OVERFLOW BIT(3) -#define CPER_ARM_CACHE_ERROR 0 -#define CPER_ARM_TLB_ERROR 1 -#define CPER_ARM_BUS_ERROR 2 -#define CPER_ARM_VENDOR_ERROR 3 -#define CPER_ARM_MAX_TYPE CPER_ARM_VENDOR_ERROR +#define CPER_ARM_ERR_TYPE_MASK GENMASK(4,1) +#define CPER_ARM_CACHE_ERROR BIT(1) +#define CPER_ARM_TLB_ERROR BIT(2) +#define CPER_ARM_BUS_ERROR BIT(3) +#define CPER_ARM_VENDOR_ERROR BIT(4) #define CPER_ARM_ERR_VALID_TRANSACTION_TYPE BIT(0) #define CPER_ARM_ERR_VALID_OPERATION_TYPE BIT(1) -- Gitee From b3e9f81e6f063a440006cd6fa8e1d01aaec943f0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 9 Dec 2025 14:54:16 +0800 Subject: [PATCH 0459/1449] irqchip/mchp-eic: Fix error code in mchp_eic_domain_alloc() ANBZ: #35228 commit c21c606ad398eeb86a0f3aaff9ba4f2665e286c6 stable. commit 7dbc0d40d8347bd9de55c904f59ea44bcc8dedb7 upstream. If irq_domain_translate_twocell() sets "hwirq" to >= MCHP_EIC_NIRQ (2) then it results in an out of bounds access. The code checks for invalid values, but doesn't set the error code. Return -EINVAL in that case, instead of returning success. Fixes: 00fa3461c86d ("irqchip/mchp-eic: Add support for the Microchip EIC") Signed-off-by: Dan Carpenter Signed-off-by: Thomas Gleixner Reviewed-by: Claudiu Beznea Link: https://patch.msgid.link/aTfHmOz6IBpTIPU5@stanley.mountain Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/irq-mchp-eic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c index 5dcd94c000a2..8a5baa0987a4 100644 --- a/drivers/irqchip/irq-mchp-eic.c +++ b/drivers/irqchip/irq-mchp-eic.c @@ -166,7 +166,7 @@ static int mchp_eic_domain_alloc(struct irq_domain *domain, unsigned int virq, ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type); if (ret || hwirq >= MCHP_EIC_NIRQ) - return ret; + return ret ?: -EINVAL; switch (type) { case IRQ_TYPE_EDGE_RISING: -- Gitee From f604dfe08444c2af306657ebc103f9ee35236870 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 5 Dec 2025 14:51:59 +0800 Subject: [PATCH 0460/1449] ocfs2: fix memory leak in ocfs2_merge_rec_left() ANBZ: #35228 commit 8d9d121e3799d2e2f393d6b1e855679b6cc67afc stable. commit 2214ec4bf89d0fd27717322d3983a2f3b469c7f3 upstream. In 'ocfs2_merge_rec_left()', do not reset 'left_path' to NULL after move, thus allowing 'ocfs2_free_path()' to free it before return. Link: https://lkml.kernel.org/r/20251205065159.392749-1-dmantipov@yandex.ru Fixes: 677b975282e4 ("ocfs2: Add support for cross extent block") Signed-off-by: Dmitry Antipov Reported-by: syzbot+cfc7cab3bb6eaa7c4de2@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=cfc7cab3bb6eaa7c4de2 Reviewed-by: Heming Zhao Acked-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ocfs2/alloc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index e6191249169e..af40f0da3a95 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -3647,7 +3647,6 @@ static int ocfs2_merge_rec_left(struct ocfs2_path *right_path, * So we use the new rightmost path. */ ocfs2_mv_path(right_path, left_path); - left_path = NULL; } else ocfs2_complete_edge_insert(handle, left_path, right_path, subtree_index); -- Gitee From 5e2b3a98e124bf0add84b9c0ed119b31e4032912 Mon Sep 17 00:00:00 2001 From: Thangaraj Samynathan Date: Tue, 15 Apr 2025 12:45:09 +0800 Subject: [PATCH 0461/1449] net: lan743x: Allocate rings outside ZONE_DMA ANBZ: #35228 commit 7c0b3edb6c77655ff1284a2946e3aa1c6c407f73 stable. commit 8a8f3f4991761a70834fe6719d09e9fd338a766e upstream. The driver allocates ring elements using GFP_DMA flags. There is no dependency from LAN743x hardware on memory allocation should be in DMA_ZONE. Hence modifying the flags to use only GFP_ATOMIC. This is consistent with other callers of lan743x_rx_init_ring_element(). Reported-by: Zhang, Liyin(CN) Signed-off-by: Thangaraj Samynathan Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250415044509.6695-1-thangaraj.s@microchip.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/microchip/lan743x_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index 781440d5756f..8910928b3849 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -2633,8 +2633,7 @@ static int lan743x_rx_process_buffer(struct lan743x_rx *rx) /* save existing skb, allocate new skb and map to dma */ skb = buffer_info->skb; - if (lan743x_rx_init_ring_element(rx, rx->last_head, - GFP_ATOMIC | GFP_DMA)) { + if (lan743x_rx_init_ring_element(rx, rx->last_head, GFP_ATOMIC)) { /* failed to allocate next skb. * Memory is very low. * Drop this packet and reuse buffer. -- Gitee From 7dc92492f7ccab1ca31000b111fcdd73e7783e5c Mon Sep 17 00:00:00 2001 From: Haotien Hsu Date: Thu, 27 Nov 2025 11:35:40 +0800 Subject: [PATCH 0462/1449] usb: gadget: tegra-xudc: Always reinitialize data toggle when clear halt ANBZ: #35228 commit 4ef659d1f2e111f4238c7b63315e072b9cf282db stable. commit 2585973c7f9ee31d21e5848c996fab2521fd383d upstream. The driver previously skipped handling ClearFeature(ENDPOINT_HALT) when the endpoint was already not halted. This prevented the controller from resetting the data sequence number and reinitializing the endpoint state. According to USB 3.2 specification Rev. 1.1, section 9.4.5, ClearFeature(ENDPOINT_HALT) must always reset the data sequence and set the stream state machine to Disabled, regardless of whether the endpoint was halted. Remove the early return so that ClearFeature(ENDPOINT_HALT) always resets the endpoint sequence state as required by the specification. Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller") Cc: stable Signed-off-by: Haotien Hsu Signed-off-by: Wayne Chang Link: https://patch.msgid.link/20251127033540.2287517-1-waynec@nvidia.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/udc/tegra-xudc.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 9bb54da8a6ae..3a14b6b72d8c 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -1554,12 +1554,6 @@ static int __tegra_xudc_ep_set_halt(struct tegra_xudc_ep *ep, bool halt) return -ENOTSUPP; } - if (!!(xudc_readl(xudc, EP_HALT) & BIT(ep->index)) == halt) { - dev_dbg(xudc->dev, "EP %u already %s\n", ep->index, - halt ? "halted" : "not halted"); - return 0; - } - if (halt) { ep_halt(xudc, ep->index); } else { -- Gitee From 25eb5c5033bdba7d2e3466b8270e5cff8ef08291 Mon Sep 17 00:00:00 2001 From: Diogo Ivo Date: Sat, 22 Nov 2025 02:16:36 +0800 Subject: [PATCH 0463/1449] usb: phy: Initialize struct usb_phy list_head ANBZ: #35228 commit dbf2d472323d9a6bde7c31c277068f32a67f1686 stable. commit c69ff68b097b0f53333114f1b2c3dc128f389596 upstream. As part of the registration of a new 'struct usb_phy' with the USB PHY core via either usb_add_phy(struct usb_phy *x, ...) or usb_add_phy_dev(struct usb_phy *x) these functions call list_add_tail(&x->head, phy_list) in order for the new instance x to be stored in phy_list, a static list kept internally by the core. After 7d21114dc6a2 ("usb: phy: Introduce one extcon device into usb phy") when executing either of the registration functions above it is possible that usb_add_extcon() fails, leading to either function returning before the call to list_add_tail(), leaving x->head uninitialized. Then, when a driver tries to undo the failed registration by calling usb_remove_phy(struct usb_phy *x) there will be an unconditional call to list_del(&x->head) acting on an uninitialized variable, and thus a possible NULL pointer dereference. Fix this by initializing x->head before usb_add_extcon() has a chance to fail. Note that this was not needed before 7d21114dc6a2 since list_add_phy() was executed unconditionally and it guaranteed that x->head was initialized. Fixes: 7d21114dc6a2 ("usb: phy: Introduce one extcon device into usb phy") Cc: stable Signed-off-by: Diogo Ivo Link: https://patch.msgid.link/20251121-diogo-smaug_typec-v2-1-5c37c1169d57@tecnico.ulisboa.pt Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/phy/phy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 5f6d711e7a8b..31fb5121b7e5 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -672,6 +672,8 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) return -EINVAL; } + INIT_LIST_HEAD(&x->head); + usb_charger_init(x); ret = usb_add_extcon(x); if (ret) @@ -722,6 +724,8 @@ int usb_add_phy_dev(struct usb_phy *x) return -EINVAL; } + INIT_LIST_HEAD(&x->head); + usb_charger_init(x); ret = usb_add_extcon(x); if (ret) -- Gitee From 23bec4b6da0ff58af2a79541096aada2b072fde1 Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Fri, 28 Nov 2025 12:06:31 +0800 Subject: [PATCH 0464/1449] ALSA: dice: fix buffer overflow in detect_stream_formats() ANBZ: #35228 commit dea3ed2c16f99f46f97b1a090bf80ecdd6972ce0 stable. commit 324f3e03e8a85931ce0880654e3c3eb38b0f0bba upstream. The function detect_stream_formats() reads the stream_count value directly from a FireWire device without validating it. This can lead to out-of-bounds writes when a malicious device provides a stream_count value greater than MAX_STREAMS. Fix by applying the same validation to both TX and RX stream counts in detect_stream_formats(). Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 58579c056c1c ("ALSA: dice: use extended protocol to detect available stream formats") Cc: stable@vger.kernel.org Reviewed-by: Takashi Sakamoto Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB7881B043FC68B4C0DA40B73DAFDCA@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/firewire/dice/dice-extension.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/firewire/dice/dice-extension.c b/sound/firewire/dice/dice-extension.c index 02f4a8318e38..48bfb3ad93ce 100644 --- a/sound/firewire/dice/dice-extension.c +++ b/sound/firewire/dice/dice-extension.c @@ -116,7 +116,7 @@ static int detect_stream_formats(struct snd_dice *dice, u64 section_addr) break; base_offset += EXT_APP_STREAM_ENTRIES; - stream_count = be32_to_cpu(reg[0]); + stream_count = min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS); err = read_stream_entries(dice, section_addr, base_offset, stream_count, mode, dice->tx_pcm_chs, @@ -125,7 +125,7 @@ static int detect_stream_formats(struct snd_dice *dice, u64 section_addr) break; base_offset += stream_count * EXT_APP_STREAM_ENTRY_SIZE; - stream_count = be32_to_cpu(reg[1]); + stream_count = min_t(unsigned int, be32_to_cpu(reg[1]), MAX_STREAMS); err = read_stream_entries(dice, section_addr, base_offset, stream_count, mode, dice->rx_pcm_chs, -- Gitee From fa6408ed081e2d13d65071dc16d8936e5e3e00f4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 27 Nov 2024 03:28:27 +0800 Subject: [PATCH 0465/1449] ipv6: avoid possible NULL deref in modify_prefix_route() ANBZ: #35228 commit 90f7d995b861fd77ae4885cc58e26a6a4e5ccdb9 stable. commit a747e02430dfb3657141f99aa6b09331283fa493 upstream. syzbot found a NULL deref [1] in modify_prefix_route(), caused by one fib6_info without a fib6_table pointer set. This can happen for net->ipv6.fib6_null_entry [1] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037] CPU: 1 UID: 0 PID: 5837 Comm: syz-executor888 Not tainted 6.12.0-syzkaller-09567-g7eef7e306d3c #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 RIP: 0010:__lock_acquire+0xe4/0x3c40 kernel/locking/lockdep.c:5089 Code: 08 84 d2 0f 85 15 14 00 00 44 8b 0d ca 98 f5 0e 45 85 c9 0f 84 b4 0e 00 00 48 b8 00 00 00 00 00 fc ff df 4c 89 e2 48 c1 ea 03 <80> 3c 02 00 0f 85 96 2c 00 00 49 8b 04 24 48 3d a0 07 7f 93 0f 84 RSP: 0018:ffffc900035d7268 EFLAGS: 00010006 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000006 RSI: 1ffff920006bae5f RDI: 0000000000000030 RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000001 R10: ffffffff90608e17 R11: 0000000000000001 R12: 0000000000000030 R13: ffff888036334880 R14: 0000000000000000 R15: 0000000000000000 FS: 0000555579e90380(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffc59cc4278 CR3: 0000000072b54000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5849 __raw_spin_lock_bh include/linux/spinlock_api_smp.h:126 [inline] _raw_spin_lock_bh+0x33/0x40 kernel/locking/spinlock.c:178 spin_lock_bh include/linux/spinlock.h:356 [inline] modify_prefix_route+0x30b/0x8b0 net/ipv6/addrconf.c:4831 inet6_addr_modify net/ipv6/addrconf.c:4923 [inline] inet6_rtm_newaddr+0x12c7/0x1ab0 net/ipv6/addrconf.c:5055 rtnetlink_rcv_msg+0x3c7/0xea0 net/core/rtnetlink.c:6920 netlink_rcv_skb+0x16b/0x440 net/netlink/af_netlink.c:2541 netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline] netlink_unicast+0x53c/0x7f0 net/netlink/af_netlink.c:1347 netlink_sendmsg+0x8b8/0xd70 net/netlink/af_netlink.c:1891 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg net/socket.c:726 [inline] ____sys_sendmsg+0xaaf/0xc90 net/socket.c:2583 ___sys_sendmsg+0x135/0x1e0 net/socket.c:2637 __sys_sendmsg+0x16e/0x220 net/socket.c:2669 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fd1dcef8b79 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 c1 17 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc59cc4378 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fd1dcef8b79 RDX: 0000000000040040 RSI: 0000000020000140 RDI: 0000000000000004 RBP: 00000000000113fd R08: 0000000000000006 R09: 0000000000000006 R10: 0000000000000006 R11: 0000000000000246 R12: 00007ffc59cc438c R13: 431bde82d7b634db R14: 0000000000000001 R15: 0000000000000001 Fixes: 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.") Reported-by: syzbot+1de74b0794c40c8eb300@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/67461f7f.050a0220.1286eb.0021.GAE@google.com/T/#u Signed-off-by: Eric Dumazet CC: Kui-Feng Lee Cc: David Ahern Reviewed-by: David Ahern Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/addrconf.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b606d77fe7fc..2737bb4751e4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4784,7 +4784,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, ifm->ifa_prefixlen, extack); } -static int modify_prefix_route(struct inet6_ifaddr *ifp, +static int modify_prefix_route(struct net *net, struct inet6_ifaddr *ifp, unsigned long expires, u32 flags, bool modify_peer) { @@ -4808,7 +4808,9 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, ifp->prefix_len, ifp->rt_priority, ifp->idev->dev, expires, flags, GFP_KERNEL); - } else { + return 0; + } + if (f6i != net->ipv6.fib6_null_entry) { table = f6i->fib6_table; spin_lock_bh(&table->tb6_lock); @@ -4821,9 +4823,8 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, } spin_unlock_bh(&table->tb6_lock); - - fib6_info_release(f6i); } + fib6_info_release(f6i); return 0; } @@ -4902,7 +4903,7 @@ static int inet6_addr_modify(struct net *net, struct inet6_ifaddr *ifp, int rc = -ENOENT; if (had_prefixroute) - rc = modify_prefix_route(ifp, expires, flags, false); + rc = modify_prefix_route(net, ifp, expires, flags, false); /* prefix route could have been deleted; if so restore it */ if (rc == -ENOENT) { @@ -4912,7 +4913,7 @@ static int inet6_addr_modify(struct net *net, struct inet6_ifaddr *ifp, } if (had_prefixroute && !ipv6_addr_any(&ifp->peer_addr)) - rc = modify_prefix_route(ifp, expires, flags, true); + rc = modify_prefix_route(net, ifp, expires, flags, true); if (rc == -ENOENT && !ipv6_addr_any(&ifp->peer_addr)) { addrconf_prefix_route(&ifp->peer_addr, ifp->prefix_len, -- Gitee From c1983160b950832d3fcd63adc80478b5d080ce67 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Wed, 9 Apr 2025 01:46:17 +0800 Subject: [PATCH 0466/1449] ipv6: add exception routes to GC list in rt6_insert_exception ANBZ: #35228 commit e5daff089b9283fa68cb38493dd65879c9b502a1 stable. commit cfe82469a00f0c0983bf4652de3a2972637dfc56 upstream. Commit 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.") introduced a separated list for managing route expiration via the GC timer. However, it missed adding exception routes (created by ip6_rt_update_pmtu() and rt6_do_redirect()) to this GC list. As a result, these exceptions were never considered for expiration and removal, leading to stale entries persisting in the routing table. This patch fixes the issue by calling fib6_add_gc_list() in rt6_insert_exception(), ensuring that exception routes are properly tracked and garbage collected when expired. Fixes: 5eb902b8e719 ("net/ipv6: Remove expired routes with a separated list of routes.") Reported-by: Jianlin Shi Signed-off-by: Xin Long Reviewed-by: David Ahern Link: https://patch.msgid.link/837e7506ffb63f47faa2b05d9b85481aad28e1a4.1744134377.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/route.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 23ab5b22cb3f..7d072ee660d6 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1775,6 +1775,7 @@ static int rt6_insert_exception(struct rt6_info *nrt, if (!err) { spin_lock_bh(&f6i->fib6_table->tb6_lock); fib6_update_sernum(net, f6i); + fib6_add_gc_list(f6i); spin_unlock_bh(&f6i->fib6_table->tb6_lock); fib6_force_start_gc(net); } -- Gitee From 54124611d668bd986f965c3f8b003c1fefd71fbf Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 4 Dec 2025 01:02:00 +0800 Subject: [PATCH 0467/1449] btrfs: do not skip logging new dentries when logging a new name ANBZ: #35228 commit 54ac15426326e5a2fe2d12d3a26e3a44317d81c4 stable. commit 5630f7557de61264ccb4f031d4734a1a97eaed16 upstream. When we are logging a directory and the log context indicates that we are logging a new name for some other file (that is or was inside that directory), we skip logging the inodes for new dentries in the directory. This is ok most of the time, but if after the rename or link operation that triggered the logging of that directory, we have an explicit fsync of that directory without the directory inode being evicted and reloaded, we end up never logging the inodes for the new dentries that we found during the new name logging, as the next directory fsync will only process dentries that were added after the last time we logged the directory (we are doing an incremental directory logging). So make sure we always log new dentries for a directory even if we are in a context of logging a new name. We started skipping logging inodes for new dentries as of commit c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name exists") and it was fine back then, because when logging a directory we always iterated over all the directory entries (for leaves changed in the current transaction) so a subsequent fsync would always log anything that was previously skipped while logging a directory when logging a new name (with btrfs_log_new_name()). But later support for incrementally logging a directory was added in commit dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory"), to avoid checking all dir items every time we log a directory, so the check to skip dentry logging added in the first commit should have been removed when the incremental support for logging a directory was added. A test case for fstests will follow soon. Reported-by: Vyacheslav Kovalevsky Link: https://lore.kernel.org/linux-btrfs/84c4e713-85d6-42b9-8dcf-0722ed26cb05@gmail.com/ Fixes: dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory") Reviewed-by: Boris Burkov Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/tree-log.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 256116a6e07c..ca01f2daac6e 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5526,14 +5526,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, struct btrfs_inode *curr_inode = start_inode; int ret = 0; - /* - * If we are logging a new name, as part of a link or rename operation, - * don't bother logging new dentries, as we just want to log the names - * of an inode and that any new parents exist. - */ - if (ctx->logging_new_name) - return 0; - path = btrfs_alloc_path(); if (!path) return -ENOMEM; -- Gitee From 368410971a7790f0dcadd70826aa87f37ec754fb Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 25 Nov 2025 16:19:56 +0800 Subject: [PATCH 0468/1449] btrfs: fix a potential path leak in print_data_reloc_error() ANBZ: #35228 commit beeed972ab48752c0f1f8b587d55d05df2b1ca21 stable. commit 313ef70a9f0f637a09d9ef45222f5bdcf30a354b upstream. Inside print_data_reloc_error(), if extent_from_logical() failed we return immediately. However there are the following cases where extent_from_logical() can return error but still holds a path: - btrfs_search_slot() returned 0 - No backref item found in extent tree - No flags_ret provided This is not possible in this call site though. So for the above two cases, we can return without releasing the path, causing extent buffer leaks. Fixes: b9a9a85059cd ("btrfs: output affected files when relocation fails") Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 17a389089b75..d9b2bf868de7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -266,6 +266,7 @@ static void print_data_reloc_error(const struct btrfs_inode *inode, u64 file_off if (ret < 0) { btrfs_err_rl(fs_info, "failed to lookup extent item for logical %llu: %d", logical, ret); + btrfs_release_path(&path); return; } eb = path.nodes[0]; -- Gitee From 31f559a5cd17b883f55b0b38e3a81161488a9935 Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Thu, 4 Dec 2025 20:59:16 +0800 Subject: [PATCH 0469/1449] bpf, arm64: Do not audit capability check in do_jit() ANBZ: #35228 commit f64105c91557a9bb70350c953314ec4c3f964584 stable. commit 189e5deb944a6f9c7992355d60bffd8ec2e54a9c upstream. Analogically to the x86 commit 881a9c9cb785 ("bpf: Do not audit capability check in do_jit()"), change the capable() call to ns_capable_noaudit() in order to avoid spurious SELinux denials in audit log. The commit log from that commit applies here as well: """ The failure of this check only results in a security mitigation being applied, slightly affecting performance of the compiled BPF program. It doesn't result in a failed syscall, an thus auditing a failed LSM permission check for it is unwanted. For example with SELinux, it causes a denial to be reported for confined processes running as root, which tends to be flagged as a problem to be fixed in the policy. Yet dontauditing or allowing CAP_SYS_ADMIN to the domain may not be desirable, as it would allow/silence also other checks - either going against the principle of least privilege or making debugging potentially harder. Fix it by changing it from capable() to ns_capable_noaudit(), which instructs the LSMs to not audit the resulting denials. """ Fixes: f300769ead03 ("arm64: bpf: Only mitigate cBPF programs loaded by unprivileged users") Signed-off-by: Ondrej Mosnacek Link: https://lore.kernel.org/r/20251204125916.441021-1-omosnace@redhat.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/net/bpf_jit_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 77c4b243aea7..ef5be7dd6d05 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -666,7 +666,7 @@ static void __maybe_unused build_bhb_mitigation(struct jit_ctx *ctx) arm64_get_spectre_v2_state() == SPECTRE_VULNERABLE) return; - if (capable(CAP_SYS_ADMIN)) + if (ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) return; if (supports_clearbhb(SCOPE_SYSTEM)) { -- Gitee From 0376d0667c4496b40c8017dceafbdcd53c4cee11 Mon Sep 17 00:00:00 2001 From: Deepanshu Kartikey Date: Wed, 10 Dec 2025 21:28:07 +0800 Subject: [PATCH 0470/1449] btrfs: fix memory leak of fs_devices in degraded seed device path ANBZ: #35228 commit c0c0951b9cd4f4440f3d9f17a806122b045bf1f5 stable. commit b57f2ddd28737db6ff0e9da8467f0ab9d707e997 upstream. In open_seed_devices(), when find_fsid() fails and we're in DEGRADED mode, a new fs_devices is allocated via alloc_fs_devices() but is never added to the seed_list before returning. This contrasts with the normal path where fs_devices is properly added via list_add(). If any error occurs later in read_one_dev() or btrfs_read_chunk_tree(), the cleanup code iterates seed_list to free seed devices, but this orphaned fs_devices is never found and never freed, causing a memory leak. Any devices allocated via add_missing_dev() and attached to this fs_devices are also leaked. Fix this by adding the newly allocated fs_devices to seed_list in the degraded path, consistent with the normal path. Fixes: 5f37583569442 ("Btrfs: move the missing device to its own fs device list") Reported-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=eadd98df8bceb15d7fed Tested-by: syzbot+eadd98df8bceb15d7fed@syzkaller.appspotmail.com Reviewed-by: Qu Wenruo Signed-off-by: Deepanshu Kartikey Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/volumes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1eb543602ff1..8207b0b4c43a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -6966,6 +6966,7 @@ static struct btrfs_fs_devices *open_seed_devices(struct btrfs_fs_info *fs_info, fs_devices->seeding = true; fs_devices->opened = 1; + list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list); return fs_devices; } -- Gitee From ea18c098ae5615001e3134b056ab2d4a8034f08f Mon Sep 17 00:00:00 2001 From: Joanne Koong Date: Tue, 23 Sep 2025 02:00:42 +0800 Subject: [PATCH 0471/1449] iomap: adjust read range correctly for non-block-aligned positions ANBZ: #35228 commit 82b60ffbb532d919959702768dca04c3c0500ae5 stable. commit 7aa6bc3e8766990824f66ca76c19596ce10daf3e upstream. iomap_adjust_read_range() assumes that the position and length passed in are block-aligned. This is not always the case however, as shown in the syzbot generated case for erofs. This causes too many bytes to be skipped for uptodate blocks, which results in returning the incorrect position and length to read in. If all the blocks are uptodate, this underflows length and returns a position beyond the folio. Fix the calculation to also take into account the block offset when calculating how many bytes can be skipped for uptodate blocks. Signed-off-by: Joanne Koong Tested-by: syzbot@syzkaller.appspotmail.com Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/iomap/buffered-io.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index cdfe3bb03ebe..5b63d1e9e6ab 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -250,17 +250,24 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, * to avoid reading in already uptodate ranges. */ if (ifs) { - unsigned int i; + unsigned int i, blocks_skipped; /* move forward for each leading block marked uptodate */ - for (i = first; i <= last; i++) { + for (i = first; i <= last; i++) if (!ifs_block_is_uptodate(ifs, i)) break; - *pos += block_size; - poff += block_size; - plen -= block_size; - first++; + + blocks_skipped = i - first; + if (blocks_skipped) { + unsigned long block_offset = *pos & (block_size - 1); + unsigned bytes_skipped = + (blocks_skipped << block_bits) - block_offset; + + *pos += bytes_skipped; + poff += bytes_skipped; + plen -= bytes_skipped; } + first = i; /* truncate len if we find any trailing uptodate block(s) */ while (++i <= last) { -- Gitee From c4a23b6e1db04e8e1fdb44c5e7f915102059f90d Mon Sep 17 00:00:00 2001 From: Joanne Koong Date: Wed, 12 Nov 2025 03:36:51 +0800 Subject: [PATCH 0472/1449] iomap: account for unaligned end offsets when truncating read range ANBZ: #35228 commit 011e356fe41e2d72a68468fec00ca70dd9b61769 stable. commit 9d875e0eef8ec15b6b1da0cb9a0f8ed13efee89e upstream. The end position to start truncating from may be at an offset into a block, which under the current logic would result in overtruncation. Adjust the calculation to account for unaligned end offsets. Signed-off-by: Joanne Koong Link: https://patch.msgid.link/20251111193658.3495942-3-joannelkoong@gmail.com Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/iomap/buffered-io.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 5b63d1e9e6ab..e8dd07fb0886 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -227,6 +227,22 @@ static void ifs_free(struct folio *folio) kfree(ifs); } +/* + * Calculate how many bytes to truncate based off the number of blocks to + * truncate and the end position to start truncating from. + */ +static size_t iomap_bytes_to_truncate(loff_t end_pos, unsigned block_bits, + unsigned blocks_truncated) +{ + unsigned block_size = 1 << block_bits; + unsigned block_offset = end_pos & (block_size - 1); + + if (!block_offset) + return blocks_truncated << block_bits; + + return ((blocks_truncated - 1) << block_bits) + block_offset; +} + /* * Calculate the range inside the folio that we actually need to read. */ @@ -272,7 +288,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, /* truncate len if we find any trailing uptodate block(s) */ while (++i <= last) { if (ifs_block_is_uptodate(ifs, i)) { - plen -= (last - i + 1) * block_size; + plen -= iomap_bytes_to_truncate(*pos + plen, + block_bits, last - i + 1); last = i - 1; break; } @@ -288,7 +305,8 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, unsigned end = offset_in_folio(folio, isize - 1) >> block_bits; if (first <= end && last > end) - plen -= (last - end) * block_size; + plen -= iomap_bytes_to_truncate(*pos + plen, block_bits, + last - end); } *offp = poff; -- Gitee From 74d13527b97e491bf91f9f7f67b692ec7409dee4 Mon Sep 17 00:00:00 2001 From: George Kennedy Date: Tue, 8 Oct 2024 21:00:53 +0800 Subject: [PATCH 0473/1449] perf/x86/amd: Check event before enable to avoid GPF ANBZ: #35228 commit 6e41d9ec8d7cc3f01b9ba785e05f0ebef8b3b37f stable. commit 866cf36bfee4fba6a492d2dcc5133f857e3446b0 upstream. On AMD machines cpuc->events[idx] can become NULL in a subtle race condition with NMI->throttle->x86_pmu_stop(). Check event for NULL in amd_pmu_enable_all() before enable to avoid a GPF. This appears to be an AMD only issue. Syzkaller reported a GPF in amd_pmu_enable_all. INFO: NMI handler (perf_event_nmi_handler) took too long to run: 13.143 msecs Oops: general protection fault, probably for non-canonical address 0xdffffc0000000034: 0000 PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x00000000000001a0-0x00000000000001a7] CPU: 0 UID: 0 PID: 328415 Comm: repro_36674776 Not tainted 6.12.0-rc1-syzk RIP: 0010:x86_pmu_enable_event (arch/x86/events/perf_event.h:1195 arch/x86/events/core.c:1430) RSP: 0018:ffff888118009d60 EFLAGS: 00010012 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000034 RSI: 0000000000000000 RDI: 00000000000001a0 RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002 R13: ffff88811802a440 R14: ffff88811802a240 R15: ffff8881132d8601 FS: 00007f097dfaa700(0000) GS:ffff888118000000(0000) GS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000200001c0 CR3: 0000000103d56000 CR4: 00000000000006f0 Call Trace: amd_pmu_enable_all (arch/x86/events/amd/core.c:760 (discriminator 2)) x86_pmu_enable (arch/x86/events/core.c:1360) event_sched_out (kernel/events/core.c:1191 kernel/events/core.c:1186 kernel/events/core.c:2346) __perf_remove_from_context (kernel/events/core.c:2435) event_function (kernel/events/core.c:259) remote_function (kernel/events/core.c:92 (discriminator 1) kernel/events/core.c:72 (discriminator 1)) __flush_smp_call_function_queue (./arch/x86/include/asm/jump_label.h:27 ./include/linux/jump_label.h:207 ./include/trace/events/csd.h:64 kernel/smp.c:135 kernel/smp.c:540) __sysvec_call_function_single (./arch/x86/include/asm/jump_label.h:27 ./include/linux/jump_label.h:207 ./arch/x86/include/asm/trace/irq_vectors.h:99 arch/x86/kernel/smp.c:272) sysvec_call_function_single (arch/x86/kernel/smp.c:266 (discriminator 47) arch/x86/kernel/smp.c:266 (discriminator 47)) Reported-by: syzkaller Signed-off-by: George Kennedy Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/events/amd/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 5046ca723285..5c93241b4262 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -763,7 +763,12 @@ static void amd_pmu_enable_all(int added) if (!test_bit(idx, cpuc->active_mask)) continue; - amd_pmu_enable_event(cpuc->events[idx]); + /* + * FIXME: cpuc->events[idx] can become NULL in a subtle race + * condition with NMI->throttle->x86_pmu_stop(). + */ + if (cpuc->events[idx]) + amd_pmu_enable_event(cpuc->events[idx]); } } -- Gitee From 0845f8b8cade92b2a94a6a27f5ee88001846013d Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Fri, 15 Aug 2025 09:22:36 +0800 Subject: [PATCH 0474/1449] sched/deadline: only set free_cpus for online runqueues ANBZ: #35228 commit 91e448e69aca4bb0ba2e998eb3e555644db7322b stable. commit 382748c05e58a9f1935f5a653c352422375566ea upstream. Commit 16b269436b72 ("sched/deadline: Modify cpudl::free_cpus to reflect rd->online") introduced the cpudl_set/clear_freecpu functions to allow the cpu_dl::free_cpus mask to be manipulated by the deadline scheduler class rq_on/offline callbacks so the mask would also reflect this state. Commit 9659e1eeee28 ("sched/deadline: Remove cpu_active_mask from cpudl_find()") removed the check of the cpu_active_mask to save some processing on the premise that the cpudl::free_cpus mask already reflected the runqueue online state. Unfortunately, there are cases where it is possible for the cpudl_clear function to set the free_cpus bit for a CPU when the deadline runqueue is offline. When this occurs while a CPU is connected to the default root domain the flag may retain the bad state after the CPU has been unplugged. Later, a different CPU that is transitioning through the default root domain may push a deadline task to the powered down CPU when cpudl_find sees its free_cpus bit is set. If this happens the task will not have the opportunity to run. One example is outlined here: https://lore.kernel.org/lkml/20250110233010.2339521-1-opendmb@gmail.com Another occurs when the last deadline task is migrated from a CPU that has an offlined runqueue. The dequeue_task member of the deadline scheduler class will eventually call cpudl_clear and set the free_cpus bit for the CPU. This commit modifies the cpudl_clear function to be aware of the online state of the deadline runqueue so that the free_cpus mask can be updated appropriately. It is no longer necessary to manage the mask outside of the cpudl_set/clear functions so the cpudl_set/clear_freecpu functions are removed. In addition, since the free_cpus mask is now only updated under the cpudl lock the code was changed to use the non-atomic __cpumask functions. Signed-off-by: Doug Berger Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/sched/cpudeadline.c | 34 +++++++++------------------------- kernel/sched/cpudeadline.h | 4 +--- kernel/sched/deadline.c | 8 ++++---- 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c index 95baa12a1029..59d7b4f48c08 100644 --- a/kernel/sched/cpudeadline.c +++ b/kernel/sched/cpudeadline.c @@ -165,12 +165,13 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, * cpudl_clear - remove a CPU from the cpudl max-heap * @cp: the cpudl max-heap context * @cpu: the target CPU + * @online: the online state of the deadline runqueue * * Notes: assumes cpu_rq(cpu)->lock is locked * * Returns: (void) */ -void cpudl_clear(struct cpudl *cp, int cpu) +void cpudl_clear(struct cpudl *cp, int cpu, bool online) { int old_idx, new_cpu; unsigned long flags; @@ -183,7 +184,7 @@ void cpudl_clear(struct cpudl *cp, int cpu) if (old_idx == IDX_INVALID) { /* * Nothing to remove if old_idx was invalid. - * This could happen if a rq_offline_dl is + * This could happen if rq_online_dl or rq_offline_dl is * called for a CPU without -dl tasks running. */ } else { @@ -194,9 +195,12 @@ void cpudl_clear(struct cpudl *cp, int cpu) cp->elements[new_cpu].idx = old_idx; cp->elements[cpu].idx = IDX_INVALID; cpudl_heapify(cp, old_idx); - - cpumask_set_cpu(cpu, cp->free_cpus); } + if (likely(online)) + __cpumask_set_cpu(cpu, cp->free_cpus); + else + __cpumask_clear_cpu(cpu, cp->free_cpus); + raw_spin_unlock_irqrestore(&cp->lock, flags); } @@ -227,7 +231,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) cp->elements[new_idx].cpu = cpu; cp->elements[cpu].idx = new_idx; cpudl_heapify_up(cp, new_idx); - cpumask_clear_cpu(cpu, cp->free_cpus); + __cpumask_clear_cpu(cpu, cp->free_cpus); } else { cp->elements[old_idx].dl = dl; cpudl_heapify(cp, old_idx); @@ -236,26 +240,6 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl) raw_spin_unlock_irqrestore(&cp->lock, flags); } -/* - * cpudl_set_freecpu - Set the cpudl.free_cpus - * @cp: the cpudl max-heap context - * @cpu: rd attached CPU - */ -void cpudl_set_freecpu(struct cpudl *cp, int cpu) -{ - cpumask_set_cpu(cpu, cp->free_cpus); -} - -/* - * cpudl_clear_freecpu - Clear the cpudl.free_cpus - * @cp: the cpudl max-heap context - * @cpu: rd attached CPU - */ -void cpudl_clear_freecpu(struct cpudl *cp, int cpu) -{ - cpumask_clear_cpu(cpu, cp->free_cpus); -} - /* * cpudl_init - initialize the cpudl structure * @cp: the cpudl max-heap context diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h index aad1c1c3e19a..70b46dabe292 100644 --- a/kernel/sched/cpudeadline.h +++ b/kernel/sched/cpudeadline.h @@ -23,9 +23,7 @@ struct cpudl { #ifdef CONFIG_SMP int cpudl_find(struct cpudl *cp, struct task_struct *p, struct cpumask *later_mask); void cpudl_set(struct cpudl *cp, int cpu, u64 dl); -void cpudl_clear(struct cpudl *cp, int cpu); +void cpudl_clear(struct cpudl *cp, int cpu, bool online); int cpudl_init(struct cpudl *cp); -void cpudl_set_freecpu(struct cpudl *cp, int cpu); -void cpudl_clear_freecpu(struct cpudl *cp, int cpu); void cpudl_cleanup(struct cpudl *cp); #endif /* CONFIG_SMP */ diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index b8c6e066b547..f18c065f2ec1 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1469,7 +1469,7 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline) if (!dl_rq->dl_nr_running) { dl_rq->earliest_dl.curr = 0; dl_rq->earliest_dl.next = 0; - cpudl_clear(&rq->rd->cpudl, rq->cpu); + cpudl_clear(&rq->rd->cpudl, rq->cpu, rq->online); cpupri_set(&rq->rd->cpupri, rq->cpu, rq->rt.highest_prio.curr); } else { struct rb_node *leftmost = rb_first_cached(&dl_rq->root); @@ -2541,9 +2541,10 @@ static void rq_online_dl(struct rq *rq) if (rq->dl.overloaded) dl_set_overload(rq); - cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu); if (rq->dl.dl_nr_running > 0) cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr); + else + cpudl_clear(&rq->rd->cpudl, rq->cpu, true); } /* Assumes rq->lock is held */ @@ -2552,8 +2553,7 @@ static void rq_offline_dl(struct rq *rq) if (rq->dl.overloaded) dl_clear_overload(rq); - cpudl_clear(&rq->rd->cpudl, rq->cpu); - cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu); + cpudl_clear(&rq->rd->cpudl, rq->cpu, false); } void __init init_sched_dl_class(void) -- Gitee From 5ec778dcb5480cfd5087ab5f95352f30fcb568dc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 7 Nov 2025 17:01:20 +0100 Subject: [PATCH 0475/1449] sched/fair: Revert max_newidle_lb_cost bump ANBZ: #35228 commit 6c074ccf77056dddeb9d698df44082ff8ed42020 stable. commit d206fbad9328ddb68ebabd7cf7413392acd38081 upstream. Many people reported regressions on their database workloads due to: 155213a2aed4 ("sched/fair: Bump sd->max_newidle_lb_cost when newidle balance fails") For instance Adam Li reported a 6% regression on SpecJBB. Conversely this will regress schbench again; on my machine from 2.22 Mrps/s down to 2.04 Mrps/s. Reported-by: Joseph Salisbury Reported-by: Adam Li Reported-by: Dietmar Eggemann Reported-by: Hazem Mohamed Abuelfotoh Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Dietmar Eggemann Tested-by: Dietmar Eggemann Tested-by: Chris Mason Link: https://lkml.kernel.org/r/20250626144017.1510594-2-clm@fb.com Link: https://lkml.kernel.org/r/006c9df2-b691-47f1-82e6-e233c3f91faf@oracle.com Link: https://patch.msgid.link/20251107161739.406147760@infradead.org Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- kernel/sched/fair.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index b331320d88b3..87a54c42c1bc 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -13832,14 +13832,8 @@ static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) /* * Track max cost of a domain to make sure to not delay the * next wakeup on the CPU. - * - * sched_balance_newidle() bumps the cost whenever newidle - * balance fails, and we don't want things to grow out of - * control. Use the sysctl_sched_migration_cost as the upper - * limit, plus a litle extra to avoid off by ones. */ - sd->max_newidle_lb_cost = - min(cost, sysctl_sched_migration_cost + 200); + sd->max_newidle_lb_cost = cost; sd->last_decay_max_lb_cost = jiffies; } else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) { /* @@ -14539,17 +14533,10 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) t1 = sched_clock_cpu(this_cpu); domain_cost = t1 - t0; + update_newidle_cost(sd, domain_cost); + curr_cost += domain_cost; t0 = t1; - - /* - * Failing newidle means it is not effective; - * bump the cost so we end up doing less of it. - */ - if (!pulled_task) - domain_cost = (3 * sd->max_newidle_lb_cost) / 2; - - update_newidle_cost(sd, domain_cost); } /* We wanna pull non-idle tasks to idle task only cpu. */ -- Gitee From c3616f6c2044fa27e4fc516a1d76b974bc920bed Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 31 Oct 2025 19:04:24 +0800 Subject: [PATCH 0476/1449] x86/ptrace: Always inline trivial accessors ANBZ: #35228 commit 30917f8d43838a44757fb9b89d3895fbd8130cc7 stable. commit 1fe4002cf7f23d70c79bda429ca2a9423ebcfdfa upstream. A KASAN build bloats these single load/store helpers such that it fails to inline them: vmlinux.o: error: objtool: irqentry_exit+0x5e8: call to instruction_pointer_set() with UACCESS enabled Make sure the compiler isn't allowed to do stupid. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Link: https://patch.msgid.link/20251031105435.GU4068168@noisy.programming.kicks-ass.net Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/include/asm/ptrace.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 5a83fbd9bc0b..eb5b1e2aa700 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -187,12 +187,12 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code); -static inline unsigned long regs_return_value(struct pt_regs *regs) +static __always_inline unsigned long regs_return_value(struct pt_regs *regs) { return regs->ax; } -static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) +static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) { regs->ax = rc; } @@ -277,34 +277,34 @@ static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) } #endif -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs) { return regs->sp; } -static inline unsigned long instruction_pointer(struct pt_regs *regs) +static __always_inline unsigned long instruction_pointer(struct pt_regs *regs) { return regs->ip; } -static inline void instruction_pointer_set(struct pt_regs *regs, - unsigned long val) +static __always_inline +void instruction_pointer_set(struct pt_regs *regs, unsigned long val) { regs->ip = val; } -static inline unsigned long frame_pointer(struct pt_regs *regs) +static __always_inline unsigned long frame_pointer(struct pt_regs *regs) { return regs->bp; } -static inline unsigned long user_stack_pointer(struct pt_regs *regs) +static __always_inline unsigned long user_stack_pointer(struct pt_regs *regs) { return regs->sp; } -static inline void user_stack_pointer_set(struct pt_regs *regs, - unsigned long val) +static __always_inline +void user_stack_pointer_set(struct pt_regs *regs, unsigned long val) { regs->sp = val; } -- Gitee From 8d55dd72659c9520b48c08a1f9ecd0976ff47be4 Mon Sep 17 00:00:00 2001 From: Cryolitia PukNgae Date: Tue, 25 Nov 2025 16:14:38 +0800 Subject: [PATCH 0477/1449] ACPICA: Avoid walking the Namespace if start_node is NULL ANBZ: #35228 commit 1bc34293dfbd266c29875206849b4f8e8177e6df stable. commit 9d6c58dae8f6590c746ac5d0012ffe14a77539f0 upstream. Although commit 0c9992315e73 ("ACPICA: Avoid walking the ACPI Namespace if it is not there") fixed the situation when both start_node and acpi_gbl_root_node are NULL, the Linux kernel mainline now still crashed on Honor Magicbook 14 Pro [1]. That happens due to the access to the member of parent_node in acpi_ns_get_next_node(). The NULL pointer dereference will always happen, no matter whether or not the start_node is equal to ACPI_ROOT_OBJECT, so move the check of start_node being NULL out of the if block. Unfortunately, all the attempts to contact Honor have failed, they refused to provide any technical support for Linux. The bad DSDT table's dump could be found on GitHub [2]. DMI: HONOR FMB-P/FMB-P-PCB, BIOS 1.13 05/08/2025 Link: https://github.com/acpica/acpica/commit/1c1b57b9eba4554cb132ee658dd942c0210ed20d Link: https://gist.github.com/Cryolitia/a860ffc97437dcd2cd988371d5b73ed7 [1] Link: https://github.com/denis-bb/honor-fmb-p-dsdt [2] Signed-off-by: Cryolitia PukNgae Reviewed-by: WangYuli [ rjw: Subject adjustment, changelog edits ] Link: https://patch.msgid.link/20251125-acpica-v1-1-99e63b1b25f8@linux.dev Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/acpica/nswalk.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index eee396a77bae..1b000ccbf8e1 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -169,9 +169,12 @@ acpi_ns_walk_namespace(acpi_object_type type, if (start_node == ACPI_ROOT_OBJECT) { start_node = acpi_gbl_root_node; - if (!start_node) { - return_ACPI_STATUS(AE_NO_NAMESPACE); - } + } + + /* Avoid walking the namespace if the StartNode is NULL */ + + if (!start_node) { + return_ACPI_STATUS(AE_NO_NAMESPACE); } /* Null child means "get first node" */ -- Gitee From 9429439f95060c1b3d88fc9bc3365e90c9693152 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 1 Oct 2025 18:43:19 +0800 Subject: [PATCH 0478/1449] ACPI: property: Use ACPI functions in acpi_graph_get_next_endpoint() only ANBZ: #35228 commit ce2bdfc4af3fdc8407259d1441b1cd898d08b9d1 stable. commit 5d010473cdeaabf6a2d3a9e2aed2186c1b73c213 upstream. Calling fwnode_get_next_child_node() in ACPI implementation of the fwnode property API is somewhat problematic as the latter is used in the impelementation of the former. Instead of using fwnode_get_next_child_node() in acpi_graph_get_next_endpoint(), call acpi_get_next_subnode() directly instead. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/20251001104320.1272752-3-sakari.ailus@linux.intel.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/property.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 1b8f3958b0ed..6bb85c12b5a0 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -1370,7 +1370,7 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( if (!prev) { do { - port = fwnode_get_next_child_node(fwnode, port); + port = acpi_get_next_subnode(fwnode, port); /* * The names of the port nodes begin with "port@" * followed by the number of the port node and they also @@ -1388,13 +1388,13 @@ static struct fwnode_handle *acpi_graph_get_next_endpoint( if (!port) return NULL; - endpoint = fwnode_get_next_child_node(port, prev); + endpoint = acpi_get_next_subnode(port, prev); while (!endpoint) { - port = fwnode_get_next_child_node(fwnode, port); + port = acpi_get_next_subnode(fwnode, port); if (!port) break; if (is_acpi_graph_node(port, "port")) - endpoint = fwnode_get_next_child_node(port, NULL); + endpoint = acpi_get_next_subnode(port, NULL); } /* -- Gitee From 793b6b707806eb2643b5ac2aaba49eccb69d5997 Mon Sep 17 00:00:00 2001 From: Hal Feng Date: Thu, 16 Oct 2025 16:00:48 +0800 Subject: [PATCH 0479/1449] cpufreq: dt-platdev: Add JH7110S SOC to the allowlist ANBZ: #35228 commit 9ba782fbe66a243e39c9465b22b5f60dbf643a3d stable. commit 6e7970cab51d01b8f7c56f120486c571c22e1b80 upstream. Add the compatible strings for supporting the generic cpufreq driver on the StarFive JH7110S SoC. Signed-off-by: Hal Feng Reviewed-by: Heinrich Schuchardt Signed-off-by: Viresh Kumar Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index c58c1defd745..8b53388280d7 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -87,6 +87,7 @@ static const struct of_device_id allowlist[] __initconst = { { .compatible = "st-ericsson,u9540", }, { .compatible = "starfive,jh7110", }, + { .compatible = "starfive,jh7110s", }, { .compatible = "ti,omap2", }, { .compatible = "ti,omap4", }, -- Gitee From 4bb435dbc23e9f74d146a6f39bf6fef7e3e0f5e7 Mon Sep 17 00:00:00 2001 From: Shuhao Fu Date: Mon, 6 Oct 2025 03:31:17 +0800 Subject: [PATCH 0480/1449] cpufreq: s5pv210: fix refcount leak ANBZ: #35228 commit ae7ead58d949084945c19602d958a2a1ad59217b stable. commit 2de5cb96060a1664880d65b120e59485a73588a8 upstream. In function `s5pv210_cpu_init`, a possible refcount inconsistency has been identified, causing a resource leak. Why it is a bug: 1. For every clk_get, there should be a matching clk_put on every successive error handling path. 2. After calling `clk_get(dmc1_clk)`, variable `dmc1_clk` will not be freed even if any error happens. How it is fixed: For every failed path, an extra goto label is added to ensure `dmc1_clk` will be freed regardlessly. Signed-off-by: Shuhao Fu Signed-off-by: Viresh Kumar Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/cpufreq/s5pv210-cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 76c888ed8d16..d2fa42beae9c 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -518,7 +518,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) { ret = -EINVAL; - goto out_dmc1; + goto out; } /* @@ -530,7 +530,7 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { pr_err("CPUFreq doesn't support this memory type\n"); ret = -EINVAL; - goto out_dmc1; + goto out; } /* Find current refresh counter and frequency each DMC */ @@ -544,6 +544,8 @@ static int s5pv210_cpu_init(struct cpufreq_policy *policy) cpufreq_generic_init(policy, s5pv210_freq_table, 40000); return 0; +out: + clk_put(dmc1_clk); out_dmc1: clk_put(dmc0_clk); out_dmc0: -- Gitee From 4eb0fd2649e9b73f24d200089f4bbe59ba4fdfb4 Mon Sep 17 00:00:00 2001 From: Aboorva Devarajan Date: Mon, 6 Oct 2025 09:39:54 +0800 Subject: [PATCH 0481/1449] cpuidle: menu: Use residency threshold in polling state override decisions ANBZ: #35228 commit e71e8079adfe79ba598cfaecaf0d7797761c533d stable. commit 07d815701274d156ad8c7c088a52e01642156fb8 upstream. On virtualized PowerPC (pseries) systems, where only one polling state (Snooze) and one deep state (CEDE) are available, selecting CEDE when the predicted idle duration is less than the target residency of CEDE state can hurt performance. In such cases, the entry/exit overhead of CEDE outweighs the power savings, leading to unnecessary state transitions and higher latency. Menu governor currently contains a special-case rule that prioritizes the first non-polling state over polling, even when its target residency is much longer than the predicted idle duration. On PowerPC/pseries, where the gap between the polling state (Snooze) and the first non-polling state (CEDE) is large, this behavior causes performance regressions. Refine that special case by adding an extra requirement: the first non-polling state can only be chosen if its target residency is below the defined RESIDENCY_THRESHOLD_NS. If this condition is not satisfied, polling is allowed instead, avoiding suboptimal non-polling state entries. This change is limited to the single special-case rule for the first non-polling state. The general non-polling state selection logic in the menu governor remains unchanged. Performance improvement observed with pgbench on PowerPC (pseries) system: +---------------------------+------------+------------+------------+ | Metric | Baseline | Patched | Change (%) | +---------------------------+------------+------------+------------+ | Transactions/sec (TPS) | 495,210 | 536,982 | +8.45% | | Avg latency (ms) | 0.163 | 0.150 | -7.98% | +---------------------------+------------+------------+------------+ CPUIdle state usage: +--------------+--------------+-------------+ | Metric | Baseline | Patched | +--------------+--------------+-------------+ | Total usage | 12,735,820 | 13,918,442 | | Above usage | 11,401,520 | 1,598,210 | | Below usage | 20,145 | 702,395 | +--------------+--------------+-------------+ Above/Total and Below/Total usage percentages: +------------------------+-----------+---------+ | Metric | Baseline | Patched | +------------------------+-----------+---------+ | Above % (Above/Total) | 89.56% | 11.49% | | Below % (Below/Total) | 0.16% | 5.05% | | Total cpuidle miss (%) | 89.72% | 16.54% | +------------------------+-----------+---------+ The results indicate that restricting CEDE selection to cases where its residency matches the predicted idle time reduces mispredictions, lowers unnecessary state transitions, and improves overall throughput. Reviewed-by: Christian Loehle Signed-off-by: Aboorva Devarajan [ rjw: Changelog edits, rebase ] Link: https://patch.msgid.link/20251006013954.17972-1-aboorvad@linux.ibm.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/cpuidle/governors/menu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 8c591dde6102..27010eee6d1b 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -354,12 +354,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, } /* - * Use a physical idle state, not busy polling, unless a timer - * is going to trigger soon enough or the exit latency of the - * idle state in question is greater than the predicted idle - * duration. + * Use a physical idle state instead of busy polling so long as + * its target residency is below the residency threshold, its + * exit latency is not greater than the predicted idle duration, + * and the next timer doesn't expire soon. */ if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && + s->target_residency_ns < RESIDENCY_THRESHOLD_NS && s->target_residency_ns <= data->next_timer_ns && s->exit_latency_ns <= predicted_ns) { predicted_ns = s->target_residency_ns; -- Gitee From 69c489ef34821f3ad6f4cd006d9fbfcb7d4ba812 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Tue, 14 Oct 2025 01:30:19 +0800 Subject: [PATCH 0482/1449] livepatch: Match old_sympos 0 and 1 in klp_find_func() ANBZ: #35228 commit fefb29d64e7b2dd16feed60ca05676e525125ac6 stable. commit 139560e8b973402140cafeb68c656c1374bd4c20 upstream. When there is only one function of the same name, old_sympos of 0 and 1 are logically identical. Match them in klp_find_func(). This is to avoid a corner case with different toolchain behavior. In this specific issue, two versions of kpatch-build were used to build livepatch for the same kernel. One assigns old_sympos == 0 for unique local functions, the other assigns old_sympos == 1 for unique local functions. Both versions work fine by themselves. (PS: This behavior change was introduced in a downstream version of kpatch-build. This change does not exist in upstream kpatch-build.) However, during livepatch upgrade (with the replace flag set) from a patch built with one version of kpatch-build to the same fix built with the other version of kpatch-build, livepatching fails with errors like: [ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' ... [ 14.219466] Call Trace: [ 14.219468] [ 14.219469] dump_stack_lvl+0x47/0x60 [ 14.219474] sysfs_warn_dup.cold+0x17/0x27 [ 14.219476] sysfs_create_dir_ns+0x95/0xb0 [ 14.219479] kobject_add_internal+0x9e/0x260 [ 14.219483] kobject_add+0x68/0x80 [ 14.219485] ? kstrdup+0x3c/0xa0 [ 14.219486] klp_enable_patch+0x320/0x830 [ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] [ 14.219491] ? 0xffffffffa05eb000 [ 14.219492] do_one_initcall+0x2e/0x190 [ 14.219494] do_init_module+0x67/0x270 [ 14.219496] init_module_from_file+0x75/0xa0 [ 14.219499] idempotent_init_module+0x15a/0x240 [ 14.219501] __x64_sys_finit_module+0x61/0xc0 [ 14.219503] do_syscall_64+0x5b/0x160 [ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 14.219507] RIP: 0033:0x7f545a4bd96d ... [ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with -EEXIST, don't try to register things with the same name ... This happens because klp_find_func() thinks somefunc with old_sympos==0 is not the same as somefunc with old_sympos==1, and klp_add_object_nops adds another xxx/func,1 to the list of functions to patch. Signed-off-by: Song Liu Acked-by: Josh Poimboeuf [pmladek@suse.com: Fixed some typos.] Reviewed-by: Petr Mladek Tested-by: Petr Mladek Signed-off-by: Petr Mladek Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/livepatch/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index c9a9827fd9d8..06646995bac6 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -90,8 +90,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj, struct klp_func *func; klp_for_each_func(obj, func) { + /* + * Besides identical old_sympos, also consider old_sympos + * of 0 and 1 are identical. + */ if ((strcmp(old_func->old_name, func->old_name) == 0) && - (old_func->old_sympos == func->old_sympos)) { + ((old_func->old_sympos == func->old_sympos) || + (old_func->old_sympos == 0 && func->old_sympos == 1) || + (old_func->old_sympos == 1 && func->old_sympos == 0))) { return func; } } -- Gitee From 0019bd91a1d25ba44667c79fc9eefba307571816 Mon Sep 17 00:00:00 2001 From: Konstantin Komarov Date: Mon, 1 Sep 2025 16:48:48 +0800 Subject: [PATCH 0483/1449] fs/ntfs3: Support timestamps prior to epoch ANBZ: #35228 commit f5c2a7cb2f007304eed7fafc119b28530de09d4e stable. commit 5180138604323895b5c291eca6aa7c20be494ade upstream. Before it used an unsigned 64-bit type, which prevented proper handling of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to support pre-epoch timestamps. The issue was caught by xfstests. Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/ntfs_fs.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index e4d6427849f8..ff07a09580dc 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -991,11 +991,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) */ static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) { - u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + s32 t32; + /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ + s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; - // WARNING: do_div changes its first argument(!) - ts->tv_nsec = do_div(t, _100ns2seconds) * 100; - ts->tv_sec = t; + ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); + ts->tv_nsec = t32 * 100; } static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb) -- Gitee From 01aa88b8b999f110394c5b70e9d33aa194ab5982 Mon Sep 17 00:00:00 2001 From: Mikhail Malyshev Date: Thu, 16 Oct 2025 00:34:52 +0800 Subject: [PATCH 0484/1449] kbuild: Use objtree for module signing key path ANBZ: #35228 commit fb9e2f99ac100a20ccd8d35727559afdce906208 stable. commit af61da281f52aba0c5b090bafb3a31c5739850ff upstream. When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, module signing fails because the private key path uses $(srctree) while the public key path uses $(objtree). Since signing keys are generated in the build directory during kernel compilation, both paths should use $(objtree) for consistency. This causes SSL errors like: SSL error:02001002:system library:fopen:No such file or directory sign-file: /kernel-src/certs/signing_key.pem The issue occurs because: - sig-key uses: $(srctree)/certs/signing_key.pem (source tree) - cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree) But both keys are generated in $(objtree) during the build. This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for external modules") which fixed the scripts path and public key path, but missed the private key path inconsistency. Fixes out-of-tree module signing for configurations with separate source and build directories (e.g., O=/kernel-out). Signed-off-by: Mikhail Malyshev Reviewed-by: Nathan Chancellor Tested-by: Nicolas Schier Link: https://patch.msgid.link/20251015163452.3754286-1-mike.malyshev@gmail.com Signed-off-by: Nicolas Schier Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 0afd75472679..3e8b069a04ff 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -96,7 +96,7 @@ endif # Don't stop modules_install even if we can't sign external modules. # ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) -sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) +sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) else sig-key := $(CONFIG_MODULE_SIG_KEY) endif -- Gitee From 78b838f46a03de6eaeaebf1e346e262496d27b8c Mon Sep 17 00:00:00 2001 From: Pedro Demarchi Gomes Date: Fri, 3 Oct 2025 23:38:50 +0800 Subject: [PATCH 0485/1449] ntfs: set dummy blocksize to read boot_block when mounting ANBZ: #35228 commit 44a38eb4f7876513db5a1bccde74de9bc4389d43 stable. commit d1693a7d5a38acf6424235a6070bcf5b186a360d upstream. When mounting, sb->s_blocksize is used to read the boot_block without being defined or validated. Set a dummy blocksize before attempting to read the boot_block. The issue can be triggered with the following syz reproducer: mkdirat(0xffffffffffffff9c, &(0x7f0000000080)='./file1\x00', 0x0) r4 = openat$nullb(0xffffffffffffff9c, &(0x7f0000000040), 0x121403, 0x0) ioctl$FS_IOC_SETFLAGS(r4, 0x40081271, &(0x7f0000000980)=0x4000) mount(&(0x7f0000000140)=@nullb, &(0x7f0000000040)='./cgroup\x00', &(0x7f0000000000)='ntfs3\x00', 0x2208004, 0x0) syz_clone(0x88200200, 0x0, 0x0, 0x0, 0x0, 0x0) Here, the ioctl sets the bdev block size to 16384. During mount, get_tree_bdev_flags() calls sb_set_blocksize(sb, block_size(bdev)), but since block_size(bdev) > PAGE_SIZE, sb_set_blocksize() leaves sb->s_blocksize at zero. Later, ntfs_init_from_boot() attempts to read the boot_block while sb->s_blocksize is still zero, which triggers the bug. Reported-by: syzbot+f4f84b57a01d6b8364ad@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f4f84b57a01d6b8364ad Signed-off-by: Pedro Demarchi Gomes [almaz.alexandrovich@paragon-software.com: changed comment style, added return value handling] Signed-off-by: Konstantin Komarov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/super.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c index c14b55cdea85..0b96d0f995c6 100644 --- a/fs/ntfs3/super.c +++ b/fs/ntfs3/super.c @@ -885,6 +885,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size, sbi->volume.blocks = dev_size >> PAGE_SHIFT; + /* Set dummy blocksize to read boot_block. */ + if (!sb_min_blocksize(sb, PAGE_SIZE)) { + return -EINVAL; + } + read_boot: bh = ntfs_bread(sb, boot_block); if (!bh) -- Gitee From 0c7e2e6b370d0991df06734a24d414911433d5a8 Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Sat, 1 Nov 2025 08:12:30 +0800 Subject: [PATCH 0486/1449] hfsplus: fix volume corruption issue for generic/070 ANBZ: #35228 commit 6348bea92f4fb11bffdee61c0725ff4153f9f85c stable. commit ed490f36f439b877393c12a2113601e4145a5a56 upstream. The xfstests' test-case generic/070 leaves HFS+ volume in corrupted state: sudo ./check generic/070 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent (see xfstests-dev/results//generic/070.full for details) Ran: generic/070 Failures: generic/070 Failed 1 of 1 tests sudo fsck.hfsplus -d /dev/loop50 ** /dev/loop50 Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking non-journaled HFS Plus Volume. The volume name is test ** Checking extents overflow file. Unused node is not erased (node = 1) ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 CBTStat = 0x0000 CatStat = 0x00000000 ** Repairing volume. ** Rechecking volume. ** Checking non-journaled HFS Plus Volume. The volume name is test ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. ** The volume test was repaired successfully. It is possible to see that fsck.hfsplus detected not erased and unused node for the case of extents overflow file. The HFS+ logic has special method that defines if the node should be erased: bool hfs_bnode_need_zeroout(struct hfs_btree *tree) { struct super_block *sb = tree->inode->i_sb; struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); return tree->cnid == HFSPLUS_CAT_CNID && volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; } However, it is possible to see that this method works only for the case of catalog file. But debugging of the issue has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been requested for the extents overflow file too: catalog file kernel: hfsplus: node 4, num_recs 0, flags 0x10 kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800 extents overflow file kernel: hfsplus: node 1, num_recs 0, flags 0x10 kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800 This patch modifies the hfs_bnode_need_zeroout() by checking only volume_attr but not the b-tree ID because node zeroing can be requested for all HFS+ b-tree types. sudo ./check generic/070 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/070 33s ... 34s Ran: generic/070 Passed all 1 tests Signed-off-by: Viacheslav Dubeyko cc: John Paul Adrian Glaubitz cc: Yangtao Li cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/hfsplus/bnode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 407d5152eb41..aa095e6fb20e 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes); - return tree->cnid == HFSPLUS_CAT_CNID && - volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; } -- Gitee From 09b2855ac06a5670913055b47dd78b808bfd9997 Mon Sep 17 00:00:00 2001 From: Yang Chenzhi Date: Fri, 29 Aug 2025 17:39:12 +0800 Subject: [PATCH 0487/1449] hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create ANBZ: #35228 commit b9d1c6bb5f19460074ce9862cb80be86b5fb0a50 stable. commit 152af114287851583cf7e0abc10129941f19466a upstream. When sync() and link() are called concurrently, both threads may enter hfs_bnode_find() without finding the node in the hash table and proceed to create it. Thread A: hfsplus_write_inode() -> hfsplus_write_system_inode() -> hfs_btree_write() -> hfs_bnode_find(tree, 0) -> __hfs_bnode_create(tree, 0) Thread B: hfsplus_create_cat() -> hfs_brec_insert() -> hfs_bnode_split() -> hfs_bmap_alloc() -> hfs_bnode_find(tree, 0) -> __hfs_bnode_create(tree, 0) In this case, thread A creates the bnode, sets refcnt=1, and hashes it. Thread B also tries to create the same bnode, notices it has already been inserted, drops its own instance, and uses the hashed one without getting the node. ``` node2 = hfs_bnode_findhash(tree, cnid); if (!node2) { <- Thread A hash = hfs_bnode_hash(cnid); node->next_hash = tree->node_hash[hash]; tree->node_hash[hash] = node; tree->node_hash_cnt++; } else { <- Thread B spin_unlock(&tree->hash_lock); kfree(node); wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags)); return node2; } ``` However, hfs_bnode_find() requires each call to take a reference. Here both threads end up setting refcnt=1. When they later put the node, this triggers: BUG_ON(!atomic_read(&node->refcnt)) In this scenario, Thread B in fact finds the node in the hash table rather than creating a new one, and thus must take a reference. Fix this by calling hfs_bnode_get() when reusing a bnode newly created by another thread to ensure the refcount is updated correctly. A similar bug was fixed in HFS long ago in commit a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") but the same issue remained in HFS+ until now. Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com Signed-off-by: Yang Chenzhi Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/hfsplus/bnode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index aa095e6fb20e..c0089849be50 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) tree->node_hash[hash] = node; tree->node_hash_cnt++; } else { + hfs_bnode_get(node2); spin_unlock(&tree->hash_lock); kfree(node); wait_event(node2->lock_wq, -- Gitee From 9d852ab6b77f7bd1ffb5a8ff9150c5c13e99e6ea Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sat, 15 Nov 2025 17:18:54 +0800 Subject: [PATCH 0488/1449] hfsplus: Verify inode mode when loading from disk ANBZ: #35228 commit 05ec9af3cc430683c97f76027e1c55ac6fd25c59 stable. commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 upstream. syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted. According to [1], the permissions field was treated as reserved in Mac OS 8 and 9. According to [2], the reserved field was explicitly initialized with 0, and that field must remain 0 as long as reserved. Therefore, when the "mode" field is not 0 (i.e. no longer reserved), the file must be S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0. Reported-by: syzbot Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlusPermissions [1] Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#ReservedAndPadFields [2] Signed-off-by: Tetsuo Handa Reviewed-by: Viacheslav Dubeyko Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA.ne.jp Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index f5f37d15681e..e7ba9077b263 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -184,13 +184,29 @@ const struct dentry_operations hfsplus_dentry_operations = { .d_compare = hfsplus_compare_dentry, }; -static void hfsplus_get_perms(struct inode *inode, - struct hfsplus_perm *perms, int dir) +static int hfsplus_get_perms(struct inode *inode, + struct hfsplus_perm *perms, int dir) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); u16 mode; mode = be16_to_cpu(perms->mode); + if (dir) { + if (mode && !S_ISDIR(mode)) + goto bad_type; + } else if (mode) { + switch (mode & S_IFMT) { + case S_IFREG: + case S_IFLNK: + case S_IFCHR: + case S_IFBLK: + case S_IFIFO: + case S_IFSOCK: + break; + default: + goto bad_type; + } + } i_uid_write(inode, be32_to_cpu(perms->owner)); if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) @@ -216,6 +232,10 @@ static void hfsplus_get_perms(struct inode *inode, inode->i_flags |= S_APPEND; else inode->i_flags &= ~S_APPEND; + return 0; +bad_type: + pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); + return -EIO; } static int hfsplus_file_open(struct inode *inode, struct file *file) @@ -520,7 +540,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) } hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, sizeof(struct hfsplus_cat_folder)); - hfsplus_get_perms(inode, &folder->permissions, 1); + res = hfsplus_get_perms(inode, &folder->permissions, 1); + if (res) + goto out; set_nlink(inode, 1); inode->i_size = 2 + be32_to_cpu(folder->valence); inode->i_atime = hfsp_mt2ut(folder->access_date); @@ -548,7 +570,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? &file->rsrc_fork : &file->data_fork); - hfsplus_get_perms(inode, &file->permissions, 0); + res = hfsplus_get_perms(inode, &file->permissions, 0); + if (res) + goto out; set_nlink(inode, 1); if (S_ISREG(inode->i_mode)) { if (file->permissions.dev) -- Gitee From 90e3d222b8ba2f9f8cdd54b2c8937811ae135d31 Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Thu, 13 Nov 2025 07:25:23 +0800 Subject: [PATCH 0489/1449] hfsplus: fix volume corruption issue for generic/073 ANBZ: #35228 commit 857e7a2d5a94c9d97da52137a069a62eae42d4a5 stable. commit 24e17a29cf7537f0947f26a50f85319abd723c6c upstream. The xfstests' test-case generic/073 leaves HFS+ volume in corrupted state: sudo ./check generic/073 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent (see XFSTESTS-2/xfstests-dev/results//generic/073.full for details) Ran: generic/073 Failures: generic/073 Failed 1 of 1 tests sudo fsck.hfsplus -d /dev/loop51 ** /dev/loop51 Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. Invalid directory item count (It should be 1 instead of 0) ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 CBTStat = 0x0000 CatStat = 0x00004000 ** Repairing volume. ** Rechecking volume. ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. ** The volume untitled was repaired successfully. The test is doing these steps on final phase: mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ logic decrements the number of entries in testdir_1 and increments number of entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not for testdir_2. As a result, this is the reason why fsck.hfsplus detects the volume corruption afterwards. This patch fixes the issue by means of adding the hfsplus_cat_write_inode() call for old_dir and new_dir in hfsplus_rename() after the successful ending of hfsplus_rename_cat(). This method makes modification of in-core inode objects for old_dir and new_dir but it doesn't save these modifications in Catalog File's entries. It was expected that hfsplus_write_inode() will save these modifications afterwards. However, because generic/073 does fsync only for testdir_1 and foo then testdir_2 modification hasn't beed saved into Catalog File's entry and it was flushed without this modification. And it was detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog File all modified entries and correct state of Catalog File will be flushed during hfsplus_file_fsync() call. Finally, it makes fsck.hfsplus happy. sudo ./check generic/073 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/073 32s ... 32s Ran: generic/073 Passed all 1 tests Signed-off-by: Viacheslav Dubeyko cc: John Paul Adrian Glaubitz cc: Yangtao Li cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/hfsplus/dir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index f5c4b3e31a1c..33154c720a4e 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -552,8 +552,13 @@ static int hfsplus_rename(struct mnt_idmap *idmap, res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); - if (!res) + if (!res) { new_dentry->d_fsdata = old_dentry->d_fsdata; + + res = hfsplus_cat_write_inode(old_dir); + if (!res) + res = hfsplus_cat_write_inode(new_dir); + } return res; } -- Gitee From a835d68a7f3ec587f13fc12b81c76a37e555f4b3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 3 Nov 2025 18:03:14 +0800 Subject: [PATCH 0490/1449] wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet ANBZ: #35228 commit 935284aaf233ca41445b2eafbfe7a18e2b28bd79 stable. commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 upstream. The Acer A1 840 tablet contains quite generic names in the sys_vendor and product_name DMI strings, without this patch brcmfmac will try to load: brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit too generic. Add a DMI quirk so that a unique and clearly identifiable nvram file name is used on the Acer A1 840 tablet. Acked-by: Arend van Spriel Signed-off-by: Hans de Goede Link: https://patch.msgid.link/20251103100314.353826-1-hansg@kernel.org Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c index c3a602197662..abe7f6501e5e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c @@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" }; +static const struct brcmf_dmi_data acer_a1_840_data = { + BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" +}; + /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. */ @@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&acepc_t8_data, }, + { + /* Acer Iconia One 8 A1-840 (non FHD version) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), + /* Above strings are too generic also match BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), + }, + .driver_data = (void *)&acer_a1_840_data, + }, { /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ .matches = { -- Gitee From d5aeace6319b6bb1902899a12a38eeb3e2a4f47c Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 3 Nov 2025 10:21:09 +0800 Subject: [PATCH 0491/1449] btrfs: scrub: always update btrfs_scrub_progress::last_physical ANBZ: #35228 commit 58d3e00853e48de086f2ae467b039324809e86ea stable. commit 54df8b80cc63aa0f22c4590cad11542731ed43ff upstream. [BUG] When a scrub failed immediately without any byte scrubbed, the returned btrfs_scrub_progress::last_physical will always be 0, even if there is a non-zero @start passed into btrfs_scrub_dev() for resume cases. This will reset the progress and make later scrub resume start from the beginning. [CAUSE] The function btrfs_scrub_dev() accepts a @progress parameter to copy its updated progress to the caller, there are cases where we either don't touch progress::last_physical at all or copy 0 into last_physical: - last_physical not updated at all If some error happened before scrubbing any super block or chunk, we will not copy the progress, leaving the @last_physical untouched. E.g. failed to allocate @sctx, scrubbing a missing device or even there is already a running scrub and so on. All those cases won't touch @progress at all, resulting the last_physical untouched and will be left as 0 for most cases. - Error out before scrubbing any bytes In those case we allocated @sctx, and sctx->stat.last_physical is all zero (initialized by kvzalloc()). Unfortunately some critical errors happened during scrub_enumerate_chunks() or scrub_supers() before any stripe is really scrubbed. In that case although we will copy sctx->stat back to @progress, since no byte is really scrubbed, last_physical will be overwritten to 0. [FIX] Make sure the parameter @progress always has its @last_physical member updated to @start parameter inside btrfs_scrub_dev(). At the very beginning of the function, set @progress->last_physical to @start, so that even if we error out without doing progress copying, last_physical is still at @start. Then after we got @sctx allocated, set sctx->stat.last_physical to @start, this will make sure even if we didn't get any byte scrubbed, at the progress copying stage the @last_physical is not left as zero. This should resolve the resume progress reset problem. Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/scrub.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index a69dce114c5b..3338e2e7a9a0 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -2858,6 +2858,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, unsigned int nofs_flag; bool need_commit = false; + /* Set the basic fallback @last_physical before we got a sctx. */ + if (progress) + progress->last_physical = start; + if (btrfs_fs_closing(fs_info)) return -EAGAIN; @@ -2876,6 +2880,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, sctx = scrub_setup_ctx(fs_info, is_dev_replace); if (IS_ERR(sctx)) return PTR_ERR(sctx); + sctx->stat.last_physical = start; ret = scrub_workers_get(fs_info); if (ret) -- Gitee From e478d3a767433a6de319e3ae15312e7296a70f20 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 19 Nov 2025 20:14:24 +0800 Subject: [PATCH 0492/1449] gfs2: fix remote evict for read-only filesystems ANBZ: #35228 commit 11860cf9cc876ddfa4f5a89bbfc7147e71bf0651 stable. commit 64c10ed9274bc46416f502afea48b4ae11279669 upstream. When a node tries to delete an inode, it first requests exclusive access to the iopen glock. This triggers demote requests on all remote nodes currently holding the iopen glock. To satisfy those requests, the remote nodes evict the inode in question, or they poke the corresponding inode glock to signal that the inode is still in active use. This behavior doesn't depend on whether or not a filesystem is read-only, so remove the incorrect read-only check. Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/gfs2/glops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 1c854d4e2d49..4a169c60bce6 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -640,8 +640,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) struct gfs2_inode *ip = gl->gl_object; struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; - if (!remote || sb_rdonly(sdp->sd_vfs) || - test_bit(SDF_KILL, &sdp->sd_flags)) + if (!remote || test_bit(SDF_KILL, &sdp->sd_flags)) return; if (gl->gl_demote_state == LM_ST_UNLOCKED && -- Gitee From ab339650a6cb8ab40f25bd8ba1e336d3ae5e6c8d Mon Sep 17 00:00:00 2001 From: ChenXiaoSong Date: Fri, 17 Oct 2025 18:46:10 +0800 Subject: [PATCH 0493/1449] smb/server: fix return value of smb2_ioctl() ANBZ: #35228 commit c4d7795fa55e897e16dcb2faa37c01a8216f19bd stable. commit 269df046c1e15ab34fa26fd90db9381f022a0963 upstream. __process_request() will not print error messages if smb2_ioctl() always returns 0. Fix this by returning the correct value at the end of function. Signed-off-by: ChenXiaoSong Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 413340d317c4..c05feb93d41a 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -8096,7 +8096,7 @@ int smb2_ioctl(struct ksmbd_work *work) id = req->VolatileFileId; if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { - rsp->hdr.Status = STATUS_NOT_SUPPORTED; + ret = -EOPNOTSUPP; goto out; } @@ -8116,8 +8116,9 @@ int smb2_ioctl(struct ksmbd_work *work) case FSCTL_DFS_GET_REFERRALS: case FSCTL_DFS_GET_REFERRALS_EX: /* Not support DFS yet */ + ret = -EOPNOTSUPP; rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; - goto out; + goto out2; case FSCTL_CREATE_OR_GET_OBJECT_ID: { struct file_object_buf_type1_ioctl_rsp *obj_buf; @@ -8407,8 +8408,10 @@ int smb2_ioctl(struct ksmbd_work *work) rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL; else if (ret < 0 || rsp->hdr.Status == 0) rsp->hdr.Status = STATUS_INVALID_PARAMETER; + +out2: smb2_set_err_rsp(work); - return 0; + return ret; } /** -- Gitee From fa806b398923e74334cdb3cc11a596a8816ec89c Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 18 Nov 2025 08:05:46 +0800 Subject: [PATCH 0494/1449] ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency ANBZ: #35228 commit d64977495e44855f2b28d8ce56107c963a7a50e4 stable. commit b39a1833cc4a2755b02603eec3a71a85e9dff926 upstream. Under high concurrency, A tree-connection object (tcon) is freed on a disconnect path while another path still holds a reference and later executes *_put()/write on it. Reported-by: Qianchang Zhao Reported-by: Zhitong Liu Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- fs/smb/server/mgmt/tree_connect.h | 1 - fs/smb/server/smb2pdu.c | 3 --- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c index 94a52a75014a..9bde1b58f9c4 100644 --- a/fs/smb/server/mgmt/tree_connect.c +++ b/fs/smb/server/mgmt/tree_connect.c @@ -77,7 +77,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) tree_conn->t_state = TREE_NEW; status.tree_conn = tree_conn; atomic_set(&tree_conn->refcount, 1); - init_waitqueue_head(&tree_conn->refcount_q); ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, GFP_KERNEL)); @@ -99,14 +98,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) { - /* - * Checking waitqueue to releasing tree connect on - * tree disconnect. waitqueue_active is safe because it - * uses atomic operation for condition. - */ - if (!atomic_dec_return(&tcon->refcount) && - waitqueue_active(&tcon->refcount_q)) - wake_up(&tcon->refcount_q); + if (atomic_dec_and_test(&tcon->refcount)) + kfree(tcon); } int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, @@ -118,14 +111,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, xa_erase(&sess->tree_conns, tree_conn->id); write_unlock(&sess->tree_conns_lock); - if (!atomic_dec_and_test(&tree_conn->refcount)) - wait_event(tree_conn->refcount_q, - atomic_read(&tree_conn->refcount) == 0); - ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); ksmbd_release_tree_conn_id(sess, tree_conn->id); ksmbd_share_config_put(tree_conn->share_conf); - kfree(tree_conn); + if (atomic_dec_and_test(&tree_conn->refcount)) + kfree(tree_conn); return ret; } diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h index a42cdd051041..f0023d86716f 100644 --- a/fs/smb/server/mgmt/tree_connect.h +++ b/fs/smb/server/mgmt/tree_connect.h @@ -33,7 +33,6 @@ struct ksmbd_tree_connect { int maximal_access; bool posix_extensions; atomic_t refcount; - wait_queue_head_t refcount_q; unsigned int t_state; }; diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index c05feb93d41a..958d6edd512c 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2183,7 +2183,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) goto err_out; } - WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); tcon->t_state = TREE_DISCONNECTED; write_unlock(&sess->tree_conns_lock); @@ -2193,8 +2192,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) goto err_out; } - work->tcon = NULL; - rsp->StructureSize = cpu_to_le16(4); err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_disconnect_rsp)); -- Gitee From 795878f5445a55b0eb374b08a7d47aa26e651e8e Mon Sep 17 00:00:00 2001 From: Qianchang Zhao Date: Mon, 24 Nov 2025 15:05:09 +0800 Subject: [PATCH 0495/1449] ksmbd: vfs: fix race on m_flags in vfs_cache ANBZ: #35228 commit 5adad9727a815c26013b0d41cfee92ffa7d4037c stable. commit 991f8a79db99b14c48d20d2052c82d65b9186cad upstream. ksmbd maintains delete-on-close and pending-delete state in ksmbd_inode->m_flags. In vfs_cache.c this field is accessed under inconsistent locking: some paths read and modify m_flags under ci->m_lock while others do so without taking the lock at all. Examples: - ksmbd_query_inode_status() and __ksmbd_inode_close() use ci->m_lock when checking or updating m_flags. - ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), ksmbd_clear_inode_pending_delete() and ksmbd_fd_set_delete_on_close() used to read and modify m_flags without ci->m_lock. This creates a potential data race on m_flags when multiple threads open, close and delete the same file concurrently. In the worst case delete-on-close and pending-delete bits can be lost or observed in an inconsistent state, leading to confusing delete semantics (files that stay on disk after delete-on-close, or files that disappear while still in use). Fix it by: - Making ksmbd_query_inode_status() look at m_flags under ci->m_lock after dropping inode_hash_lock. - Adding ci->m_lock protection to all helpers that read or modify m_flags (ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), ksmbd_clear_inode_pending_delete(), ksmbd_fd_set_delete_on_close()). - Keeping the existing ci->m_lock protection in __ksmbd_inode_close(), and moving the actual unlink/xattr removal outside the lock. This unifies the locking around m_flags and removes the data race while preserving the existing delete-on-close behaviour. Reported-by: Qianchang Zhao Reported-by: Zhitong Liu Signed-off-by: Qianchang Zhao Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/vfs_cache.c | 88 +++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index 002f0864abee..2fcb7ca33a63 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -105,40 +105,62 @@ int ksmbd_query_inode_status(struct dentry *dentry) read_lock(&inode_hash_lock); ci = __ksmbd_inode_lookup(dentry); - if (ci) { - ret = KSMBD_INODE_STATUS_OK; - if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) - ret = KSMBD_INODE_STATUS_PENDING_DELETE; - atomic_dec(&ci->m_count); - } read_unlock(&inode_hash_lock); + if (!ci) + return ret; + + down_read(&ci->m_lock); + if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) + ret = KSMBD_INODE_STATUS_PENDING_DELETE; + else + ret = KSMBD_INODE_STATUS_OK; + up_read(&ci->m_lock); + + atomic_dec(&ci->m_count); return ret; } bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) { - return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); + struct ksmbd_inode *ci = fp->f_ci; + int ret; + + down_read(&ci->m_lock); + ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); + up_read(&ci->m_lock); + + return ret; } void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) { - fp->f_ci->m_flags |= S_DEL_PENDING; + struct ksmbd_inode *ci = fp->f_ci; + + down_write(&ci->m_lock); + ci->m_flags |= S_DEL_PENDING; + up_write(&ci->m_lock); } void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp) { - fp->f_ci->m_flags &= ~S_DEL_PENDING; + struct ksmbd_inode *ci = fp->f_ci; + + down_write(&ci->m_lock); + ci->m_flags &= ~S_DEL_PENDING; + up_write(&ci->m_lock); } void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, int file_info) { - if (ksmbd_stream_fd(fp)) { - fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM; - return; - } + struct ksmbd_inode *ci = fp->f_ci; - fp->f_ci->m_flags |= S_DEL_ON_CLS; + down_write(&ci->m_lock); + if (ksmbd_stream_fd(fp)) + ci->m_flags |= S_DEL_ON_CLS_STREAM; + else + ci->m_flags |= S_DEL_ON_CLS; + up_write(&ci->m_lock); } static void ksmbd_inode_hash(struct ksmbd_inode *ci) @@ -250,27 +272,41 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) struct file *filp; filp = fp->filp; - if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { - ci->m_flags &= ~S_DEL_ON_CLS_STREAM; - err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), - &filp->f_path, - fp->stream.name, - true); - if (err) - pr_err("remove xattr failed : %s\n", - fp->stream.name); + + if (ksmbd_stream_fd(fp)) { + bool remove_stream_xattr = false; + + down_write(&ci->m_lock); + if (ci->m_flags & S_DEL_ON_CLS_STREAM) { + ci->m_flags &= ~S_DEL_ON_CLS_STREAM; + remove_stream_xattr = true; + } + up_write(&ci->m_lock); + + if (remove_stream_xattr) { + err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), + &filp->f_path, + fp->stream.name, + true); + if (err) + pr_err("remove xattr failed : %s\n", + fp->stream.name); + } } if (atomic_dec_and_test(&ci->m_count)) { + bool do_unlink = false; + down_write(&ci->m_lock); if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); - up_write(&ci->m_lock); - ksmbd_vfs_unlink(filp); - down_write(&ci->m_lock); + do_unlink = true; } up_write(&ci->m_lock); + if (do_unlink) + ksmbd_vfs_unlink(filp); + ksmbd_inode_free(ci); } } -- Gitee From 74f5f2bc1a96f72d869712b1cd5b427b3e208bbb Mon Sep 17 00:00:00 2001 From: Chingbin Li Date: Mon, 6 Oct 2025 16:46:47 +0800 Subject: [PATCH 0496/1449] Bluetooth: btusb: Add new VID/PID 2b89/6275 for RTL8761BUV ANBZ: #35228 commit 6d9a87ecf31ffbbc6fc1ed661a3ddd7118c34cbe stable. commit 8dbbb5423c0802ec21266765de80fd491868fab1 upstream. Add VID 2b89 & PID 6275 for Realtek RTL8761BUV USB Bluetooth chip. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2b89 ProdID=6275 Rev= 2.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00E04C239987 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Chingbin Li Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f632b6d63cfb..5a629034428b 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -735,6 +735,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2b89, 0x6275), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Additional Realtek 8821AE Bluetooth devices */ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, -- Gitee From 52df09e5f2a27e03c0f614e3402cccb4b133a436 Mon Sep 17 00:00:00 2001 From: Gongwei Li Date: Wed, 19 Nov 2025 15:33:38 +0800 Subject: [PATCH 0497/1449] Bluetooth: btusb: Add new VID/PID 13d3/3533 for RTL8821CE ANBZ: #35228 commit 96a60775dbb1a515b9449cc67c04f0d6215cc987 stable. commit 525459da4bd62a81142fea3f3d52188ceb4d8907 upstream. Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3533 Rev= 1.10 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Gongwei Li Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 5a629034428b..96b1e64377c6 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -498,6 +498,8 @@ static const struct usb_device_id quirks_table[] = { /* Realtek 8821CE Bluetooth devices */ { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | -- Gitee From bcf9689dcd16c51788fc6e6fcf78164ba2aa139e Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Mon, 1 Dec 2025 05:19:52 +0800 Subject: [PATCH 0498/1449] gfs2: Fix use of bio_chain ANBZ: #35228 commit ab794ec9f3745f5bfdd9a13897b8650bd2daa206 stable. commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 upstream. In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. The result is leaked bios and incorrect synchronization (only the last bio will actually be waited for). This code is only used during mount and filesystem thaw, so the bug normally won't be noticeable. Reported-by: Stephen Zhang Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/gfs2/lops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 483f69807062..b25b741e3c96 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -492,7 +492,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); bio_clone_blkg_association(new, prev); new->bi_iter.bi_sector = bio_end_sector(prev); - bio_chain(new, prev); + bio_chain(prev, new); submit_bio(prev); return new; } -- Gitee From 129011454a185985d3a96e2789c3cc24566066b1 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Fri, 28 Nov 2025 10:59:15 +0800 Subject: [PATCH 0499/1449] net: fec: ERR007885 Workaround for XDP TX path ANBZ: #35228 commit 0e26e3ef8e5c02fe569773252784a47ab3d2bf43 stable. commit e8e032cd24dda7cceaa27bc2eb627f82843f0466 upstream. The ERR007885 will lead to a TDAR race condition for mutliQ when the driver sets TDAR and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles). And it will cause the udma_tx and udma_tx_arbiter state machines to hang. Therefore, the commit 53bb20d1faba ("net: fec: add variable reg_desc_active to speed things up") and the commit a179aad12bad ("net: fec: ERR007885 Workaround for conventional TX") have added the workaround to fix the potential issue for the conventional TX path. Similarly, the XDP TX path should also have the potential hang issue, so add the workaround for XDP TX path. Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support") Signed-off-by: Wei Fang Link: https://patch.msgid.link/20251128025915.2486943-1-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/fec_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ee0306ab9771..7efe4e81cf32 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3935,7 +3935,12 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep, txq->bd.cur = bdp; /* Trigger transmission start */ - writel(0, txq->bd.reg_desc_active); + if (!(fep->quirks & FEC_QUIRK_ERR007885) || + !readl(txq->bd.reg_desc_active) || + !readl(txq->bd.reg_desc_active) || + !readl(txq->bd.reg_desc_active) || + !readl(txq->bd.reg_desc_active)) + writel(0, txq->bd.reg_desc_active); return 0; } -- Gitee From 6553cea74faabced49b7276a4980255fb7aa8bf0 Mon Sep 17 00:00:00 2001 From: Wang Liang Date: Sat, 29 Nov 2025 12:13:15 +0800 Subject: [PATCH 0500/1449] netrom: Fix memory leak in nr_sendmsg() ANBZ: #35228 commit 156a0f6341dce634a825db49ca20b48b1ae9bcc1 stable. commit 613d12dd794e078be8ff3cf6b62a6b9acf7f4619 upstream. syzbot reported a memory leak [1]. When function sock_alloc_send_skb() return NULL in nr_output(), the original skb is not freed, which was allocated in nr_sendmsg(). Fix this by freeing it before return. [1] BUG: memory leak unreferenced object 0xffff888129f35500 (size 240): comm "syz.0.17", pid 6119, jiffies 4294944652 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 10 52 28 81 88 ff ff ..........R(.... backtrace (crc 1456a3e4): kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline] slab_post_alloc_hook mm/slub.c:4983 [inline] slab_alloc_node mm/slub.c:5288 [inline] kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5340 __alloc_skb+0x203/0x240 net/core/skbuff.c:660 alloc_skb include/linux/skbuff.h:1383 [inline] alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671 sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965 sock_alloc_send_skb include/net/sock.h:1859 [inline] nr_sendmsg+0x287/0x450 net/netrom/af_netrom.c:1105 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg net/socket.c:742 [inline] sock_write_iter+0x293/0x2a0 net/socket.c:1195 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x45d/0x710 fs/read_write.c:686 ksys_write+0x143/0x170 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Reported-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=d7abc36bbbb6d7d40b58 Tested-by: syzbot+d7abc36bbbb6d7d40b58@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Wang Liang Link: https://patch.msgid.link/20251129041315.1550766-1-wangliang74@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netrom/nr_out.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c index 5e531394a724..2b3cbceb0b52 100644 --- a/net/netrom/nr_out.c +++ b/net/netrom/nr_out.c @@ -43,8 +43,10 @@ void nr_output(struct sock *sk, struct sk_buff *skb) frontlen = skb_headroom(skb); while (skb->len > 0) { - if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) + if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) { + kfree_skb(skb); return; + } skb_reserve(skbn, frontlen); -- Gitee From e4d3ee0d613fd626a9642622107a67cb7e00ff1e Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Fri, 28 Nov 2025 23:19:19 +0800 Subject: [PATCH 0501/1449] net/sched: ets: Always remove class from active list before deleting in ets_qdisc_change ANBZ: #35228 commit 9987cda315c08f63a02423fa2f9a1f6602c861a0 stable. commit ce052b9402e461a9aded599f5b47e76bc727f7de upstream. zdi-disclosures@trendmicro.com says: The vulnerability is a race condition between `ets_qdisc_dequeue` and `ets_qdisc_change`. It leads to UAF on `struct Qdisc` object. Attacker requires the capability to create new user and network namespace in order to trigger the bug. See my additional commentary at the end of the analysis. Analysis: static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) { ... // (1) this lock is preventing .change handler (`ets_qdisc_change`) //to race with .dequeue handler (`ets_qdisc_dequeue`) sch_tree_lock(sch); for (i = nbands; i < oldbands; i++) { if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) list_del_init(&q->classes[i].alist); qdisc_purge_queue(q->classes[i].qdisc); } WRITE_ONCE(q->nbands, nbands); for (i = nstrict; i < q->nstrict; i++) { if (q->classes[i].qdisc->q.qlen) { // (2) the class is added to the q->active list_add_tail(&q->classes[i].alist, &q->active); q->classes[i].deficit = quanta[i]; } } WRITE_ONCE(q->nstrict, nstrict); memcpy(q->prio2band, priomap, sizeof(priomap)); for (i = 0; i < q->nbands; i++) WRITE_ONCE(q->classes[i].quantum, quanta[i]); for (i = oldbands; i < q->nbands; i++) { q->classes[i].qdisc = queues[i]; if (q->classes[i].qdisc != &noop_qdisc) qdisc_hash_add(q->classes[i].qdisc, true); } // (3) the qdisc is unlocked, now dequeue can be called in parallel // to the rest of .change handler sch_tree_unlock(sch); ets_offload_change(sch); for (i = q->nbands; i < oldbands; i++) { // (4) we're reducing the refcount for our class's qdisc and // freeing it qdisc_put(q->classes[i].qdisc); // (5) If we call .dequeue between (4) and (5), we will have // a strong UAF and we can control RIP q->classes[i].qdisc = NULL; WRITE_ONCE(q->classes[i].quantum, 0); q->classes[i].deficit = 0; gnet_stats_basic_sync_init(&q->classes[i].bstats); memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats)); } return 0; } Comment: This happens because some of the classes have their qdiscs assigned to NULL, but remain in the active list. This commit fixes this issue by always removing the class from the active list before deleting and freeing its associated qdisc Reproducer Steps (trimmed version of what was sent by zdi-disclosures@trendmicro.com) ``` DEV="${DEV:-lo}" ROOT_HANDLE="${ROOT_HANDLE:-1:}" BAND2_HANDLE="${BAND2_HANDLE:-20:}" # child under 1:2 PING_BYTES="${PING_BYTES:-48}" PING_COUNT="${PING_COUNT:-200000}" PING_DST="${PING_DST:-127.0.0.1}" SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}" SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}" SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}" cleanup() { tc qdisc del dev "$DEV" root 2>/dev/null } trap cleanup EXIT ip link set "$DEV" up tc qdisc del dev "$DEV" root 2>/dev/null || true tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2 tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \ tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT" tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2 tc -s qdisc ls dev $DEV ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \ >/dev/null 2>&1 & tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0 tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2 tc -s qdisc ls dev $DEV tc qdisc del dev "$DEV" parent 1:2 || true tc -s qdisc ls dev $DEV tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 1 strict 1 ``` KASAN report ``` ================================================================== BUG: KASAN: slab-use-after-free in ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481 Read of size 8 at addr ffff8880502fc018 by task ping/12308 > CPU: 0 UID: 0 PID: 12308 Comm: ping Not tainted 6.18.0-rc4-dirty #1 PREEMPT(full) Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: __dump_stack kernel/lib/dump_stack.c:94 dump_stack_lvl+0x100/0x190 kernel/lib/dump_stack.c:120 print_address_description kernel/mm/kasan/report.c:378 print_report+0x156/0x4c9 kernel/mm/kasan/report.c:482 kasan_report+0xdf/0x110 kernel/mm/kasan/report.c:595 ets_qdisc_dequeue+0x1071/0x11b0 kernel/net/sched/sch_ets.c:481 dequeue_skb kernel/net/sched/sch_generic.c:294 qdisc_restart kernel/net/sched/sch_generic.c:399 __qdisc_run+0x1c9/0x1b00 kernel/net/sched/sch_generic.c:417 __dev_xmit_skb kernel/net/core/dev.c:4221 __dev_queue_xmit+0x2848/0x4410 kernel/net/core/dev.c:4729 dev_queue_xmit kernel/./include/linux/netdevice.h:3365 [...] Allocated by task 17115: kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56 kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77 poison_kmalloc_redzone kernel/mm/kasan/common.c:400 __kasan_kmalloc+0xaa/0xb0 kernel/mm/kasan/common.c:417 kasan_kmalloc kernel/./include/linux/kasan.h:262 __do_kmalloc_node kernel/mm/slub.c:5642 __kmalloc_node_noprof+0x34e/0x990 kernel/mm/slub.c:5648 kmalloc_node_noprof kernel/./include/linux/slab.h:987 qdisc_alloc+0xb8/0xc30 kernel/net/sched/sch_generic.c:950 qdisc_create_dflt+0x93/0x490 kernel/net/sched/sch_generic.c:1012 ets_class_graft+0x4fd/0x800 kernel/net/sched/sch_ets.c:261 qdisc_graft+0x3e4/0x1780 kernel/net/sched/sch_api.c:1196 [...] Freed by task 9905: kasan_save_stack+0x30/0x50 kernel/mm/kasan/common.c:56 kasan_save_track+0x14/0x30 kernel/mm/kasan/common.c:77 __kasan_save_free_info+0x3b/0x70 kernel/mm/kasan/generic.c:587 kasan_save_free_info kernel/mm/kasan/kasan.h:406 poison_slab_object kernel/mm/kasan/common.c:252 __kasan_slab_free+0x5f/0x80 kernel/mm/kasan/common.c:284 kasan_slab_free kernel/./include/linux/kasan.h:234 slab_free_hook kernel/mm/slub.c:2539 slab_free kernel/mm/slub.c:6630 kfree+0x144/0x700 kernel/mm/slub.c:6837 rcu_do_batch kernel/kernel/rcu/tree.c:2605 rcu_core+0x7c0/0x1500 kernel/kernel/rcu/tree.c:2861 handle_softirqs+0x1ea/0x8a0 kernel/kernel/softirq.c:622 __do_softirq kernel/kernel/softirq.c:656 [...] Commentary: 1. Maher Azzouzi working with Trend Micro Zero Day Initiative was reported as the person who found the issue. I requested to get a proper email to add to the reported-by tag but got no response. For this reason i will credit the person i exchanged emails with i.e zdi-disclosures@trendmicro.com 2. Neither i nor Victor who did a much more thorough testing was able to reproduce a UAF with the PoC or other approaches we tried. We were both able to reproduce a null ptr deref. After exchange with zdi-disclosures@trendmicro.com they sent a small change to be made to the code to add an extra delay which was able to simulate the UAF. i.e, this: qdisc_put(q->classes[i].qdisc); mdelay(90); q->classes[i].qdisc = NULL; I was informed by Thomas Gleixner(tglx@linutronix.de) that adding delays was acceptable approach for demonstrating the bug, quote: "Adding such delays is common exploit validation practice" The equivalent delay could happen "by virt scheduling the vCPU out, SMIs, NMIs, PREEMPT_RT enabled kernel" 3. I asked the OP to test and report back but got no response and after a few days gave up and proceeded to submit this fix. Fixes: de6d25924c2a ("net/sched: sch_ets: don't peek at classes beyond 'nbands'") Reported-by: zdi-disclosures@trendmicro.com Tested-by: Victor Nogueira Signed-off-by: Jamal Hadi Salim Reviewed-by: Davide Caratti Link: https://patch.msgid.link/20251128151919.576920-1-jhs@mojatatu.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_ets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c index 9873f4ae90c3..b732d09ede99 100644 --- a/net/sched/sch_ets.c +++ b/net/sched/sch_ets.c @@ -652,7 +652,7 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, sch_tree_lock(sch); for (i = nbands; i < oldbands; i++) { - if (i >= q->nstrict && q->classes[i].qdisc->q.qlen) + if (cl_is_active(&q->classes[i])) list_del_init(&q->classes[i].alist); qdisc_purge_queue(q->classes[i].qdisc); } -- Gitee From ac38e5890b87b0bcefdd0a8fbfa94d0768473a4d Mon Sep 17 00:00:00 2001 From: Dmitry Skorodumov Date: Tue, 2 Dec 2025 18:39:03 +0800 Subject: [PATCH 0502/1449] ipvlan: Ignore PACKET_LOOPBACK in handle_mode_l2() ANBZ: #35228 commit 17aefe815462c35bcfc87a75cf02a958ae43035b stable. commit 0c57ff008a11f24f7f05fa760222692a00465fec upstream. Packets with pkt_type == PACKET_LOOPBACK are captured by handle_frame() function, but they don't have L2 header. We should not process them in handle_mode_l2(). This doesn't affect old L2 functionality, since handling was anyway incorrect. Handle them the same way as in br_handle_frame(): just pass the skb. To observe invalid behaviour, just start "ping -b" on bcast address of port-interface. Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") Signed-off-by: Dmitry Skorodumov Link: https://patch.msgid.link/20251202103906.4087675-1-skorodumov.dmitry@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ipvlan/ipvlan_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index ca62188a317a..83bd65a22770 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -737,6 +737,9 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb, struct ethhdr *eth = eth_hdr(skb); rx_handler_result_t ret = RX_HANDLER_PASS; + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + return RX_HANDLER_PASS; + if (is_multicast_ether_addr(eth->h_dest)) { if (ipvlan_external_frame(skb, port)) { struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); -- Gitee From bb93a9913c552f38ef9e1c605dc1a0d464900b3b Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 3 Dec 2025 01:44:11 +0800 Subject: [PATCH 0503/1449] mlxsw: spectrum_router: Fix possible neighbour reference count leak ANBZ: #35228 commit 5a182635fef36bee55e3450d41805b6ca395578d stable. commit b6b638bda240395dff49a87403b2e32493e56d2a upstream. mlxsw_sp_router_schedule_work() takes a reference on a neighbour, expecting a work item to release it later on. However, we might fail to schedule the work item, in which case the neighbour reference count will be leaked. Fix by taking the reference just before scheduling the work item. Note that mlxsw_sp_router_schedule_work() can receive a NULL neighbour pointer, but neigh_clone() handles that correctly. Spotted during code review, did not actually observe the reference count leak. Fixes: 151b89f6025a ("mlxsw: spectrum_router: Reuse work neighbor initialization in work scheduler") Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: Petr Machata Reviewed-by: Simon Horman Link: https://patch.msgid.link/ec2934ae4aca187a8d8c9329a08ce93cca411378.1764695650.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 0534b10e29c5..f5c34218ba85 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -2857,6 +2857,11 @@ static int mlxsw_sp_router_schedule_work(struct net *net, if (!net_work) return NOTIFY_BAD; + /* Take a reference to ensure the neighbour won't be destructed until + * we drop the reference in the work item. + */ + neigh_clone(n); + INIT_WORK(&net_work->work, cb); net_work->mlxsw_sp = router->mlxsw_sp; net_work->n = n; @@ -2880,11 +2885,6 @@ static int mlxsw_sp_router_schedule_neigh_work(struct mlxsw_sp_router *router, struct net *net; net = neigh_parms_net(n->parms); - - /* Take a reference to ensure the neighbour won't be destructed until we - * drop the reference in delayed work. - */ - neigh_clone(n); return mlxsw_sp_router_schedule_work(net, router, n, mlxsw_sp_router_neigh_event_work); } -- Gitee From 7260621d31ed1894918489e90535509658a303aa Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 3 Dec 2025 01:44:12 +0800 Subject: [PATCH 0504/1449] mlxsw: spectrum_router: Fix neighbour use-after-free ANBZ: #35228 commit 4a3c569005f42ab5e5b2ad637132a33bf102cc08 stable. commit 8b0e69763ef948fb872a7767df4be665d18f5fd4 upstream. We sometimes observe use-after-free when dereferencing a neighbour [1]. The problem seems to be that the driver stores a pointer to the neighbour, but without holding a reference on it. A reference is only taken when the neighbour is used by a nexthop. Fix by simplifying the reference counting scheme. Always take a reference when storing a neighbour pointer in a neighbour entry. Avoid taking a referencing when the neighbour is used by a nexthop as the neighbour entry associated with the nexthop already holds a reference. Tested by running the test that uncovered the problem over 300 times. Without this patch the problem was reproduced after a handful of iterations. [1] BUG: KASAN: slab-use-after-free in mlxsw_sp_neigh_entry_update+0x2d4/0x310 Read of size 8 at addr ffff88817f8e3420 by task ip/3929 CPU: 3 UID: 0 PID: 3929 Comm: ip Not tainted 6.18.0-rc4-virtme-g36b21a067510 #3 PREEMPT(full) Hardware name: Nvidia SN5600/VMOD0013, BIOS 5.13 05/31/2023 Call Trace: dump_stack_lvl+0x6f/0xa0 print_address_description.constprop.0+0x6e/0x300 print_report+0xfc/0x1fb kasan_report+0xe4/0x110 mlxsw_sp_neigh_entry_update+0x2d4/0x310 mlxsw_sp_router_rif_gone_sync+0x35f/0x510 mlxsw_sp_rif_destroy+0x1ea/0x730 mlxsw_sp_inetaddr_port_vlan_event+0xa1/0x1b0 __mlxsw_sp_inetaddr_lag_event+0xcc/0x130 __mlxsw_sp_inetaddr_event+0xf5/0x3c0 mlxsw_sp_router_netdevice_event+0x1015/0x1580 notifier_call_chain+0xcc/0x150 call_netdevice_notifiers_info+0x7e/0x100 __netdev_upper_dev_unlink+0x10b/0x210 netdev_upper_dev_unlink+0x79/0xa0 vrf_del_slave+0x18/0x50 do_set_master+0x146/0x7d0 do_setlink.isra.0+0x9a0/0x2880 rtnl_newlink+0x637/0xb20 rtnetlink_rcv_msg+0x6fe/0xb90 netlink_rcv_skb+0x123/0x380 netlink_unicast+0x4a3/0x770 netlink_sendmsg+0x75b/0xc90 __sock_sendmsg+0xbe/0x160 ____sys_sendmsg+0x5b2/0x7d0 ___sys_sendmsg+0xfd/0x180 __sys_sendmsg+0x124/0x1c0 do_syscall_64+0xbb/0xfd0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 [...] Allocated by task 109: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x7b/0x90 __kmalloc_noprof+0x2c1/0x790 neigh_alloc+0x6af/0x8f0 ___neigh_create+0x63/0xe90 mlxsw_sp_nexthop_neigh_init+0x430/0x7e0 mlxsw_sp_nexthop_type_init+0x212/0x960 mlxsw_sp_nexthop6_group_info_init.constprop.0+0x81f/0x1280 mlxsw_sp_nexthop6_group_get+0x392/0x6a0 mlxsw_sp_fib6_entry_create+0x46a/0xfd0 mlxsw_sp_router_fib6_replace+0x1ed/0x5f0 mlxsw_sp_router_fib6_event_work+0x10a/0x2a0 process_one_work+0xd57/0x1390 worker_thread+0x4d6/0xd40 kthread+0x355/0x5b0 ret_from_fork+0x1d4/0x270 ret_from_fork_asm+0x11/0x20 Freed by task 154: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x43/0x70 kmem_cache_free_bulk.part.0+0x1eb/0x5e0 kvfree_rcu_bulk+0x1f2/0x260 kfree_rcu_work+0x130/0x1b0 process_one_work+0xd57/0x1390 worker_thread+0x4d6/0xd40 kthread+0x355/0x5b0 ret_from_fork+0x1d4/0x270 ret_from_fork_asm+0x11/0x20 Last potentially related work creation: kasan_save_stack+0x30/0x50 kasan_record_aux_stack+0x8c/0xa0 kvfree_call_rcu+0x93/0x5b0 mlxsw_sp_router_neigh_event_work+0x67d/0x860 process_one_work+0xd57/0x1390 worker_thread+0x4d6/0xd40 kthread+0x355/0x5b0 ret_from_fork+0x1d4/0x270 ret_from_fork_asm+0x11/0x20 Fixes: 6cf3c971dc84 ("mlxsw: spectrum_router: Add private neigh table") Signed-off-by: Ido Schimmel Reviewed-by: Petr Machata Signed-off-by: Petr Machata Reviewed-by: Simon Horman Link: https://patch.msgid.link/92d75e21d95d163a41b5cea67a15cd33f547cba6.1764695650.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../ethernet/mellanox/mlxsw/spectrum_router.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index f5c34218ba85..4cd79473ace5 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -2264,6 +2264,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n, if (!neigh_entry) return NULL; + neigh_hold(n); neigh_entry->key.n = n; neigh_entry->rif = rif; INIT_LIST_HEAD(&neigh_entry->nexthop_list); @@ -2273,6 +2274,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n, static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry) { + neigh_release(neigh_entry->key.n); kfree(neigh_entry); } @@ -4203,6 +4205,8 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp, if (err) goto err_neigh_entry_insert; + neigh_release(old_n); + read_lock_bh(&n->lock); nud_state = n->nud_state; dead = n->dead; @@ -4211,14 +4215,10 @@ mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp, list_for_each_entry(nh, &neigh_entry->nexthop_list, neigh_list_node) { - neigh_release(old_n); - neigh_clone(n); __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected); mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp); } - neigh_release(n); - return 0; err_neigh_entry_insert: @@ -4311,6 +4311,11 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp, } } + /* Release the reference taken by neigh_lookup() / neigh_create() since + * neigh_entry already holds one. + */ + neigh_release(n); + /* If that is the first nexthop connected to that neigh, add to * nexthop_neighs_list */ @@ -4337,11 +4342,9 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop *nh) { struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry; - struct neighbour *n; if (!neigh_entry) return; - n = neigh_entry->key.n; __mlxsw_sp_nexthop_neigh_update(nh, true); list_del(&nh->neigh_list_node); @@ -4355,8 +4358,6 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp, if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list)) mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); - - neigh_release(n); } static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev) -- Gitee From ca794e4abf89357aeef55b08a8e2ae017726f647 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Wed, 3 Dec 2025 01:44:13 +0800 Subject: [PATCH 0505/1449] mlxsw: spectrum_mr: Fix use-after-free when updating multicast route stats ANBZ: #35228 commit 5f2831fc593c2b2efbff7dd0dd7441cec76adcd5 stable. commit 8ac1dacec458f55f871f7153242ed6ab60373b90 upstream. Cited commit added a dedicated mutex (instead of RTNL) to protect the multicast route list, so that it will not change while the driver periodically traverses it in order to update the kernel about multicast route stats that were queried from the device. One instance of list entry deletion (during route replace) was missed and it can result in a use-after-free [1]. Fix by acquiring the mutex before deleting the entry from the list and releasing it afterwards. [1] BUG: KASAN: slab-use-after-free in mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum] Read of size 8 at addr ffff8881523c2fa8 by task kworker/2:5/22043 CPU: 2 UID: 0 PID: 22043 Comm: kworker/2:5 Not tainted 6.18.0-rc1-custom-g1a3d6d7cd014 #1 PREEMPT(full) Hardware name: Mellanox Technologies Ltd. MSN2010/SA002610, BIOS 5.6.5 08/24/2017 Workqueue: mlxsw_core mlxsw_sp_mr_stats_update [mlxsw_spectrum] Call Trace: dump_stack_lvl+0xba/0x110 print_report+0x174/0x4f5 kasan_report+0xdf/0x110 mlxsw_sp_mr_stats_update+0x4a5/0x540 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:1006 [mlxsw_spectrum] process_one_work+0x9cc/0x18e0 worker_thread+0x5df/0xe40 kthread+0x3b8/0x730 ret_from_fork+0x3e9/0x560 ret_from_fork_asm+0x1a/0x30 Allocated by task 29933: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x8f/0xa0 mlxsw_sp_mr_route_add+0xd8/0x4770 [mlxsw_spectrum] mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum] process_one_work+0x9cc/0x18e0 worker_thread+0x5df/0xe40 kthread+0x3b8/0x730 ret_from_fork+0x3e9/0x560 ret_from_fork_asm+0x1a/0x30 Freed by task 29933: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_save_free_info+0x3b/0x70 __kasan_slab_free+0x43/0x70 kfree+0x14e/0x700 mlxsw_sp_mr_route_add+0x2dea/0x4770 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c:444 [mlxsw_spectrum] mlxsw_sp_router_fibmr_event_work+0x371/0xad0 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:7965 [mlxsw_spectrum] process_one_work+0x9cc/0x18e0 worker_thread+0x5df/0xe40 kthread+0x3b8/0x730 ret_from_fork+0x3e9/0x560 ret_from_fork_asm+0x1a/0x30 Fixes: f38656d06725 ("mlxsw: spectrum_mr: Protect multicast route list with a lock") Signed-off-by: Ido Schimmel Reviewed-by: Petr Machata Signed-off-by: Petr Machata Reviewed-by: Simon Horman Link: https://patch.msgid.link/f996feecfd59fde297964bfc85040b6d83ec6089.1764695650.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c index 5afe6b155ef0..81935f87bfcd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c @@ -440,7 +440,9 @@ int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table, rhashtable_remove_fast(&mr_table->route_ht, &mr_orig_route->ht_node, mlxsw_sp_mr_route_ht_params); + mutex_lock(&mr_table->route_list_lock); list_del(&mr_orig_route->node); + mutex_unlock(&mr_table->route_list_lock); mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route); } -- Gitee From e893c7d73bd3b1cbd96aa44a5c8664e607c3b8a7 Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Thu, 4 Dec 2025 18:53:32 +0800 Subject: [PATCH 0506/1449] net: openvswitch: fix middle attribute validation in push_nsh() action ANBZ: #35228 commit 10ffc558246f2c75619aedda0921906095e46702 stable. commit 5ace7ef87f059d68b5f50837ef3e8a1a4870c36e upstream. The push_nsh() action structure looks like this: OVS_ACTION_ATTR_PUSH_NSH(OVS_KEY_ATTR_NSH(OVS_NSH_KEY_ATTR_BASE,...)) The outermost OVS_ACTION_ATTR_PUSH_NSH attribute is OK'ed by the nla_for_each_nested() inside __ovs_nla_copy_actions(). The innermost OVS_NSH_KEY_ATTR_BASE/MD1/MD2 are OK'ed by the nla_for_each_nested() inside nsh_key_put_from_nlattr(). But nothing checks if the attribute in the middle is OK. We don't even check that this attribute is the OVS_KEY_ATTR_NSH. We just do a double unwrap with a pair of nla_data() calls - first time directly while calling validate_push_nsh() and the second time as part of the nla_for_each_nested() macro, which isn't safe, potentially causing invalid memory access if the size of this attribute is incorrect. The failure may not be noticed during validation due to larger netlink buffer, but cause trouble later during action execution where the buffer is allocated exactly to the size: BUG: KASAN: slab-out-of-bounds in nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch] Read of size 184 at addr ffff88816459a634 by task a.out/22624 CPU: 8 UID: 0 PID: 22624 6.18.0-rc7+ #115 PREEMPT(voluntary) Call Trace: dump_stack_lvl+0x51/0x70 print_address_description.constprop.0+0x2c/0x390 kasan_report+0xdd/0x110 kasan_check_range+0x35/0x1b0 __asan_memcpy+0x20/0x60 nsh_hdr_from_nlattr+0x1dd/0x6a0 [openvswitch] push_nsh+0x82/0x120 [openvswitch] do_execute_actions+0x1405/0x2840 [openvswitch] ovs_execute_actions+0xd5/0x3b0 [openvswitch] ovs_packet_cmd_execute+0x949/0xdb0 [openvswitch] genl_family_rcv_msg_doit+0x1d6/0x2b0 genl_family_rcv_msg+0x336/0x580 genl_rcv_msg+0x9f/0x130 netlink_rcv_skb+0x11f/0x370 genl_rcv+0x24/0x40 netlink_unicast+0x73e/0xaa0 netlink_sendmsg+0x744/0xbf0 __sys_sendto+0x3d6/0x450 do_syscall_64+0x79/0x2c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Let's add some checks that the attribute is properly sized and it's the only one attribute inside the action. Technically, there is no real reason for OVS_KEY_ATTR_NSH to be there, as we know that we're pushing an NSH header already, it just creates extra nesting, but that's how uAPI works today. So, keeping as it is. Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support") Reported-by: Junvy Yang Signed-off-by: Ilya Maximets Acked-by: Eelco Chaudron echaudro@redhat.com Reviewed-by: Aaron Conole Link: https://patch.msgid.link/20251204105334.900379-1-i.maximets@ovn.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/openvswitch/flow_netlink.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 836e8e705d40..1d9a44d6216a 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -2788,13 +2788,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, return err; } -static bool validate_push_nsh(const struct nlattr *attr, bool log) +static bool validate_push_nsh(const struct nlattr *a, bool log) { + struct nlattr *nsh_key = nla_data(a); struct sw_flow_match match; struct sw_flow_key key; + /* There must be one and only one NSH header. */ + if (!nla_ok(nsh_key, nla_len(a)) || + nla_total_size(nla_len(nsh_key)) != nla_len(a) || + nla_type(nsh_key) != OVS_KEY_ATTR_NSH) + return false; + ovs_match_init(&match, &key, true, NULL); - return !nsh_key_put_from_nlattr(attr, &match, false, true, log); + return !nsh_key_put_from_nlattr(nsh_key, &match, false, true, log); } /* Return false if there are any non-masked bits set. @@ -3351,7 +3358,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr, return -EINVAL; } mac_proto = MAC_PROTO_NONE; - if (!validate_push_nsh(nla_data(a), log)) + if (!validate_push_nsh(a, log)) return -EINVAL; break; -- Gitee From f2e2bd65958fa32f30c93e2c58549cb05051ede8 Mon Sep 17 00:00:00 2001 From: Alexey Simakov Date: Fri, 5 Dec 2025 23:58:16 +0800 Subject: [PATCH 0507/1449] broadcom: b44: prevent uninitialized value usage ANBZ: #35228 commit 3e778855fbce631a745a4ad8f5580d36b079daa0 stable. commit 50b3db3e11864cb4e18ff099cfb38e11e7f87a68 upstream. On execution path with raised B44_FLAG_EXTERNAL_PHY, b44_readphy() leaves bmcr value uninitialized and it is used later in the code. Add check of this flag at the beginning of the b44_nway_reset() and exit early of the function with restarting autonegotiation if an external PHY is used. Fixes: 753f492093da ("[B44]: port to native ssb support") Reviewed-by: Jonas Gorski Reviewed-by: Andrew Lunn Signed-off-by: Alexey Simakov Reviewed-by: Michael Chan Link: https://patch.msgid.link/20251205155815.4348-1-bigalex934@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/broadcom/b44.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 1be6d14030bc..ba40549536e4 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -1789,6 +1789,9 @@ static int b44_nway_reset(struct net_device *dev) u32 bmcr; int r; + if (bp->flags & B44_FLAG_EXTERNAL_PHY) + return phy_ethtool_nway_reset(dev); + spin_lock_irq(&bp->lock); b44_readphy(bp, MII_BMCR, &bmcr); b44_readphy(bp, MII_BMCR, &bmcr); -- Gitee From 04b97a71a7c54757c6b82b20797d0e955886e474 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Fri, 5 Dec 2025 19:58:01 +0800 Subject: [PATCH 0508/1449] netfilter: nf_conncount: fix leaked ct in error paths ANBZ: #35228 commit 325eb61bb30790ea27782203a17b007ce1754a67 stable. commit 2e2a720766886190a6d35c116794693aabd332b6 upstream. There are some situations where ct might be leaked as error paths are skipping the refcounted check and return immediately. In order to solve it make sure that the check is always called. Fixes: be102eb6a0e7 ("netfilter: nf_conncount: rework API to use sk_buff directly") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_conncount.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index 97b631a81484..c00b8e522c5a 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net, struct nf_conn *found_ct; unsigned int collect = 0; bool refcounted = false; + int err = 0; if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) return -ENOENT; if (ct && nf_ct_is_confirmed(ct)) { - if (refcounted) - nf_ct_put(ct); - return -EEXIST; + err = -EEXIST; + goto out_put; } if ((u32)jiffies == list->last_gc) @@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net, } add_new_node: - if (WARN_ON_ONCE(list->count > INT_MAX)) - return -EOVERFLOW; + if (WARN_ON_ONCE(list->count > INT_MAX)) { + err = -EOVERFLOW; + goto out_put; + } conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); - if (conn == NULL) - return -ENOMEM; + if (conn == NULL) { + err = -ENOMEM; + goto out_put; + } conn->tuple = tuple; conn->zone = *zone; @@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net, out_put: if (refcounted) nf_ct_put(ct); - return 0; + return err; } int nf_conncount_add_skb(struct net *net, @@ -446,11 +450,10 @@ insert_tree(struct net *net, rb_link_node_rcu(&rbconn->node, parent, rbnode); rb_insert_color(&rbconn->node, root); - - if (refcounted) - nf_ct_put(ct); } out_unlock: + if (refcounted) + nf_ct_put(ct); spin_unlock_bh(&nf_conncount_locks[hash]); return count; } -- Gitee From 82b973558d58c94e23e4538dee4b1835dc00c89f Mon Sep 17 00:00:00 2001 From: Slavin Liu Date: Fri, 21 Nov 2025 16:52:13 +0800 Subject: [PATCH 0509/1449] ipvs: fix ipv4 null-ptr-deref in route error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4729ff0581fbb7ad098b6153b76b6f5aac94618a stable. commit ad891bb3d079a46a821bf2b8867854645191bab0 upstream. The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure() without ensuring skb->dev is set, leading to a NULL pointer dereference in fib_compute_spec_dst() when ipv4_link_failure() attempts to send ICMP destination unreachable messages. The issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") started calling __ip_options_compile() from ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst() which dereferences skb->dev. An attempt was made to fix the NULL skb->dev dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev) dereference by using a fallback device. The fix was incomplete because fib_compute_spec_dst() later in the call chain still accesses skb->dev directly, which remains NULL when IPVS calls dst_link_failure(). The crash occurs when: 1. IPVS processes a packet in NAT mode with a misconfigured destination 2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route 3. The error path calls dst_link_failure(skb) with skb->dev == NULL 4. ipv4_link_failure() → ipv4_send_dest_unreach() → __ip_options_compile() → fib_compute_spec_dst() 5. fib_compute_spec_dst() dereferences NULL skb->dev Apply the same fix used for IPv6 in commit 326bf17ea5d4 ("ipvs: fix ipv6 route unreach panic"): set skb->dev from skb_dst(skb)->dev before calling dst_link_failure(). KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f] CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2 RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233 RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285 Call Trace: spec_dst_fill net/ipv4/ip_options.c:232 spec_dst_fill net/ipv4/ip_options.c:229 __ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330 ipv4_send_dest_unreach net/ipv4/route.c:1252 ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265 dst_link_failure include/net/dst.h:437 __ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412 ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764 Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") Signed-off-by: Slavin Liu Acked-by: Julian Anastasov Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/ipvs/ip_vs_xmit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 0103c4a4d10a..2877706f0162 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, return -1; err_unreach: + if (!skb->dev) + skb->dev = skb_dst(skb)->dev; + dst_link_failure(skb); return -1; } -- Gitee From 05f3652a9e07b714e739c8065013262bd3922ab8 Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Thu, 4 Dec 2025 21:30:47 +0800 Subject: [PATCH 0510/1449] caif: fix integer underflow in cffrml_receive() ANBZ: #35228 commit f818cd472565f8b0c2c409b040e0121c5cf8592c stable. commit 8a11ff0948b5ad09b71896b7ccc850625f9878d1 upstream. The cffrml_receive() function extracts a length field from the packet header and, when FCS is disabled, subtracts 2 from this length without validating that len >= 2. If an attacker sends a malicious packet with a length field of 0 or 1 to an interface with FCS disabled, the subtraction causes an integer underflow. This can lead to memory exhaustion and kernel instability, potential information disclosure if padding contains uninitialized kernel memory. Fix this by validating that len >= 2 before performing the subtraction. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: b482cd2053e3 ("net-caif: add CAIF core protocol stack") Signed-off-by: Junrui Luo Reviewed-by: Simon Horman Link: https://patch.msgid.link/SYBPR01MB7881511122BAFEA8212A1608AFA6A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/caif/cffrml.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index 6651a8dc62e0..d4d63586053a 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c @@ -92,8 +92,15 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) len = le16_to_cpu(tmp); /* Subtract for FCS on length if FCS is not used. */ - if (!this->dofcs) + if (!this->dofcs) { + if (len < 2) { + ++cffrml_rcv_error; + pr_err("Invalid frame length (%d)\n", len); + cfpkt_destroy(pkt); + return -EPROTO; + } len -= 2; + } if (cfpkt_setlen(pkt, len) < 0) { ++cffrml_rcv_error; -- Gitee From 175511075bb1941af5d5a6a1c04b643dd51e8fb0 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Tue, 9 Dec 2025 03:01:24 +0800 Subject: [PATCH 0511/1449] net/sched: ets: Remove drr class from the active list if it changes to strict ANBZ: #35228 commit 2f125ebe47d6369e562f3cbd9b6227cff51eaf34 stable. commit b1e125ae425aba9b45252e933ca8df52a843ec70 upstream. Whenever a user issues an ets qdisc change command, transforming a drr class into a strict one, the ets code isn't checking whether that class was in the active list and removing it. This means that, if a user changes a strict class (which was in the active list) back to a drr one, that class will be added twice to the active list [1]. Doing so with the following commands: tc qdisc add dev lo root handle 1: ets bands 2 strict 1 tc qdisc add dev lo parent 1:2 handle 20: \ tbf rate 8bit burst 100b latency 1s tc filter add dev lo parent 1: basic classid 1:2 ping -c1 -W0.01 -s 56 127.0.0.1 tc qdisc change dev lo root handle 1: ets bands 2 strict 2 tc qdisc change dev lo root handle 1: ets bands 2 strict 1 ping -c1 -W0.01 -s 56 127.0.0.1 Will trigger the following splat with list debug turned on: [ 59.279014][ T365] ------------[ cut here ]------------ [ 59.279452][ T365] list_add double add: new=ffff88801d60e350, prev=ffff88801d60e350, next=ffff88801d60e2c0. [ 59.280153][ T365] WARNING: CPU: 3 PID: 365 at lib/list_debug.c:35 __list_add_valid_or_report+0x17f/0x220 [ 59.280860][ T365] Modules linked in: [ 59.281165][ T365] CPU: 3 UID: 0 PID: 365 Comm: tc Not tainted 6.18.0-rc7-00105-g7e9f13163c13-dirty #239 PREEMPT(voluntary) [ 59.281977][ T365] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 59.282391][ T365] RIP: 0010:__list_add_valid_or_report+0x17f/0x220 [ 59.282842][ T365] Code: 89 c6 e8 d4 b7 0d ff 90 0f 0b 90 90 31 c0 e9 31 ff ff ff 90 48 c7 c7 e0 a0 22 9f 48 89 f2 48 89 c1 4c 89 c6 e8 b2 b7 0d ff 90 <0f> 0b 90 90 31 c0 e9 0f ff ff ff 48 89 f7 48 89 44 24 10 4c 89 44 ... [ 59.288812][ T365] Call Trace: [ 59.289056][ T365] [ 59.289224][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.289546][ T365] ets_qdisc_change+0xd2b/0x1e80 [ 59.289891][ T365] ? __lock_acquire+0x7e7/0x1be0 [ 59.290223][ T365] ? __pfx_ets_qdisc_change+0x10/0x10 [ 59.290546][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.290898][ T365] ? __mutex_trylock_common+0xda/0x240 [ 59.291228][ T365] ? __pfx___mutex_trylock_common+0x10/0x10 [ 59.291655][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.291993][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.292313][ T365] ? trace_contention_end+0xc8/0x110 [ 59.292656][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.293022][ T365] ? srso_alias_return_thunk+0x5/0xfbef5 [ 59.293351][ T365] tc_modify_qdisc+0x63a/0x1cf0 Fix this by always checking and removing an ets class from the active list when changing it to strict. [1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/tree/net/sched/sch_ets.c?id=ce052b9402e461a9aded599f5b47e76bc727f7de#n663 Fixes: cd9b50adc6bb9 ("net/sched: ets: fix crash when flipping from 'strict' to 'quantum'") Acked-by: Jamal Hadi Salim Signed-off-by: Victor Nogueira Reviewed-by: Petr Machata Link: https://patch.msgid.link/20251208190125.1868423-1-victor@mojatatu.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_ets.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c index b732d09ede99..6ff619277ffd 100644 --- a/net/sched/sch_ets.c +++ b/net/sched/sch_ets.c @@ -664,6 +664,10 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt, q->classes[i].deficit = quanta[i]; } } + for (i = q->nstrict; i < nstrict; i++) { + if (cl_is_active(&q->classes[i])) + list_del_init(&q->classes[i].alist); + } WRITE_ONCE(q->nstrict, nstrict); memcpy(q->prio2band, priomap, sizeof(priomap)); -- Gitee From 121f82740d8d385eedd362274a78e15d6721e2d2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 9 Dec 2025 14:56:39 +0800 Subject: [PATCH 0512/1449] nfc: pn533: Fix error code in pn533_acr122_poweron_rdr() ANBZ: #35228 commit 8bc10b03e70599d83fe4de4541c8a1cb85e9d1b1 stable. commit 885bebac9909994050bbbeed0829c727e42bd1b7 upstream. Set the error code if "transferred != sizeof(cmd)" instead of returning success. Fixes: dbafc28955fa ("NFC: pn533: don't send USB data off of the stack") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/aTfIJ9tZPmeUF4W1@stanley.mountain Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nfc/pn533/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index a187f0e0b0f7..9e079be43583 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -407,7 +407,7 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy) if (rc || (transferred != sizeof(cmd))) { nfc_err(&phy->udev->dev, "Reader power on cmd error %d\n", rc); - return rc; + return rc ?: -EINVAL; } rc = usb_submit_urb(phy->in_urb, GFP_KERNEL); -- Gitee From 2c5264f0679169e86d522770fcfa290e3239e81d Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 20 Aug 2024 17:56:12 +0800 Subject: [PATCH 0513/1449] netfilter: nf_tables: pass context structure to nft_parse_register_load ANBZ: #35228 commit fb1347c5c0162d61b1b34223d80427b90902b5e4 stable. commit 7ea0522ef81a335c2d3a0ab1c8a4fab9a23c4a03 upstream. Mechanical transformation, no logical changes intended. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Stable-dep-of: a67fd55f6a09 ("netfilter: nf_tables: remove redundant chain validation on register store") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/netfilter/nf_tables.h | 3 ++- net/bridge/netfilter/nft_meta_bridge.c | 2 +- net/ipv4/netfilter/nft_dup_ipv4.c | 4 ++-- net/ipv6/netfilter/nft_dup_ipv6.c | 4 ++-- net/netfilter/nf_tables_api.c | 3 ++- net/netfilter/nft_bitwise.c | 4 ++-- net/netfilter/nft_byteorder.c | 2 +- net/netfilter/nft_cmp.c | 6 +++--- net/netfilter/nft_ct.c | 2 +- net/netfilter/nft_dup_netdev.c | 2 +- net/netfilter/nft_dynset.c | 4 ++-- net/netfilter/nft_exthdr.c | 2 +- net/netfilter/nft_fwd_netdev.c | 6 +++--- net/netfilter/nft_hash.c | 2 +- net/netfilter/nft_lookup.c | 2 +- net/netfilter/nft_masq.c | 4 ++-- net/netfilter/nft_meta.c | 2 +- net/netfilter/nft_nat.c | 8 ++++---- net/netfilter/nft_objref.c | 2 +- net/netfilter/nft_payload.c | 2 +- net/netfilter/nft_queue.c | 2 +- net/netfilter/nft_range.c | 2 +- net/netfilter/nft_redir.c | 4 ++-- net/netfilter/nft_tproxy.c | 4 ++-- 24 files changed, 40 insertions(+), 38 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 32606d543060..917edb4380e5 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -254,7 +254,8 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); -int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len); +int nft_parse_register_load(const struct nft_ctx *ctx, + const struct nlattr *attr, u8 *sreg, u32 len); int nft_parse_register_store(const struct nft_ctx *ctx, const struct nlattr *attr, u8 *dreg, const struct nft_data *data, diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c index affb740c8685..d12a221366d6 100644 --- a/net/bridge/netfilter/nft_meta_bridge.c +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -142,7 +142,7 @@ static int nft_meta_bridge_set_init(const struct nft_ctx *ctx, } priv->len = len; - err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len); + err = nft_parse_register_load(ctx, tb[NFTA_META_SREG], &priv->sreg, len); if (err < 0) return err; diff --git a/net/ipv4/netfilter/nft_dup_ipv4.c b/net/ipv4/netfilter/nft_dup_ipv4.c index a522c3a3be52..ef5dd88107dd 100644 --- a/net/ipv4/netfilter/nft_dup_ipv4.c +++ b/net/ipv4/netfilter/nft_dup_ipv4.c @@ -40,13 +40,13 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx, if (tb[NFTA_DUP_SREG_ADDR] == NULL) return -EINVAL; - err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr, + err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr, sizeof(struct in_addr)); if (err < 0) return err; if (tb[NFTA_DUP_SREG_DEV]) - err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], + err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev, sizeof(int)); return err; diff --git a/net/ipv6/netfilter/nft_dup_ipv6.c b/net/ipv6/netfilter/nft_dup_ipv6.c index c82f3fdd4a65..492a811828a7 100644 --- a/net/ipv6/netfilter/nft_dup_ipv6.c +++ b/net/ipv6/netfilter/nft_dup_ipv6.c @@ -38,13 +38,13 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx, if (tb[NFTA_DUP_SREG_ADDR] == NULL) return -EINVAL; - err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr, + err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr, sizeof(struct in6_addr)); if (err < 0) return err; if (tb[NFTA_DUP_SREG_DEV]) - err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], + err = nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev, sizeof(int)); return err; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 80443b4eaeff..7bccfb1a8a72 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -10912,7 +10912,8 @@ static int nft_validate_register_load(enum nft_registers reg, unsigned int len) return 0; } -int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len) +int nft_parse_register_load(const struct nft_ctx *ctx, + const struct nlattr *attr, u8 *sreg, u32 len) { u32 reg; int err; diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c index ca857afbf061..7de95674fd8c 100644 --- a/net/netfilter/nft_bitwise.c +++ b/net/netfilter/nft_bitwise.c @@ -171,7 +171,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx, priv->len = len; - err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg, + err = nft_parse_register_load(ctx, tb[NFTA_BITWISE_SREG], &priv->sreg, priv->len); if (err < 0) return err; @@ -365,7 +365,7 @@ static int nft_bitwise_fast_init(const struct nft_ctx *ctx, struct nft_bitwise_fast_expr *priv = nft_expr_priv(expr); int err; - err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg, + err = nft_parse_register_load(ctx, tb[NFTA_BITWISE_SREG], &priv->sreg, sizeof(u32)); if (err < 0) return err; diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c index f6e791a68101..2f82a444d21b 100644 --- a/net/netfilter/nft_byteorder.c +++ b/net/netfilter/nft_byteorder.c @@ -139,7 +139,7 @@ static int nft_byteorder_init(const struct nft_ctx *ctx, priv->len = len; - err = nft_parse_register_load(tb[NFTA_BYTEORDER_SREG], &priv->sreg, + err = nft_parse_register_load(ctx, tb[NFTA_BYTEORDER_SREG], &priv->sreg, priv->len); if (err < 0) return err; diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c index cd4652259095..2605f43737bc 100644 --- a/net/netfilter/nft_cmp.c +++ b/net/netfilter/nft_cmp.c @@ -83,7 +83,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr, if (err < 0) return err; - err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len); + err = nft_parse_register_load(ctx, tb[NFTA_CMP_SREG], &priv->sreg, desc.len); if (err < 0) return err; @@ -222,7 +222,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, if (err < 0) return err; - err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len); + err = nft_parse_register_load(ctx, tb[NFTA_CMP_SREG], &priv->sreg, desc.len); if (err < 0) return err; @@ -323,7 +323,7 @@ static int nft_cmp16_fast_init(const struct nft_ctx *ctx, if (err < 0) return err; - err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len); + err = nft_parse_register_load(ctx, tb[NFTA_CMP_SREG], &priv->sreg, desc.len); if (err < 0) return err; diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index ab1214da99ff..3ec63852d058 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -608,7 +608,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, } priv->len = len; - err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len); + err = nft_parse_register_load(ctx, tb[NFTA_CT_SREG], &priv->sreg, len); if (err < 0) goto err1; diff --git a/net/netfilter/nft_dup_netdev.c b/net/netfilter/nft_dup_netdev.c index e5739a59ebf1..0573f96ce079 100644 --- a/net/netfilter/nft_dup_netdev.c +++ b/net/netfilter/nft_dup_netdev.c @@ -40,7 +40,7 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx, if (tb[NFTA_DUP_SREG_DEV] == NULL) return -EINVAL; - return nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev, + return nft_parse_register_load(ctx, tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev, sizeof(int)); } diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index a81bd69b059b..9a0aaeed2360 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -214,7 +214,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx, return err; } - err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key, + err = nft_parse_register_load(ctx, tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key, set->klen); if (err < 0) return err; @@ -225,7 +225,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx, if (set->dtype == NFT_DATA_VERDICT) return -EOPNOTSUPP; - err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_DATA], + err = nft_parse_register_load(ctx, tb[NFTA_DYNSET_SREG_DATA], &priv->sreg_data, set->dlen); if (err < 0) return err; diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index cfa90ab660cf..1d4c9632072c 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -586,7 +586,7 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, priv->flags = flags; priv->op = op; - return nft_parse_register_load(tb[NFTA_EXTHDR_SREG], &priv->sreg, + return nft_parse_register_load(ctx, tb[NFTA_EXTHDR_SREG], &priv->sreg, priv->len); } diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c index fa9e4ae00b16..42ba31dfc035 100644 --- a/net/netfilter/nft_fwd_netdev.c +++ b/net/netfilter/nft_fwd_netdev.c @@ -52,7 +52,7 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx, if (tb[NFTA_FWD_SREG_DEV] == NULL) return -EINVAL; - return nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev, + return nft_parse_register_load(ctx, tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev, sizeof(int)); } @@ -178,12 +178,12 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx, return -EOPNOTSUPP; } - err = nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev, + err = nft_parse_register_load(ctx, tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev, sizeof(int)); if (err < 0) return err; - return nft_parse_register_load(tb[NFTA_FWD_SREG_ADDR], &priv->sreg_addr, + return nft_parse_register_load(ctx, tb[NFTA_FWD_SREG_ADDR], &priv->sreg_addr, addr_len); } diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 92d47e469204..c91f2bef5869 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c @@ -91,7 +91,7 @@ static int nft_jhash_init(const struct nft_ctx *ctx, priv->len = len; - err = nft_parse_register_load(tb[NFTA_HASH_SREG], &priv->sreg, len); + err = nft_parse_register_load(ctx, tb[NFTA_HASH_SREG], &priv->sreg, len); if (err < 0) return err; diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index dd5441f92fdb..aeaf6988efd6 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -113,7 +113,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx, if (IS_ERR(set)) return PTR_ERR(set); - err = nft_parse_register_load(tb[NFTA_LOOKUP_SREG], &priv->sreg, + err = nft_parse_register_load(ctx, tb[NFTA_LOOKUP_SREG], &priv->sreg, set->klen); if (err < 0) return err; diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c index eee05394c533..868bd4d73555 100644 --- a/net/netfilter/nft_masq.c +++ b/net/netfilter/nft_masq.c @@ -51,13 +51,13 @@ static int nft_masq_init(const struct nft_ctx *ctx, priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); if (tb[NFTA_MASQ_REG_PROTO_MIN]) { - err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN], + err = nft_parse_register_load(ctx, tb[NFTA_MASQ_REG_PROTO_MIN], &priv->sreg_proto_min, plen); if (err < 0) return err; if (tb[NFTA_MASQ_REG_PROTO_MAX]) { - err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MAX], + err = nft_parse_register_load(ctx, tb[NFTA_MASQ_REG_PROTO_MAX], &priv->sreg_proto_max, plen); if (err < 0) diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index dec76d28a0ac..8c8eb14d647b 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -655,7 +655,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx, } priv->len = len; - err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len); + err = nft_parse_register_load(ctx, tb[NFTA_META_SREG], &priv->sreg, len); if (err < 0) return err; diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index 3d3e639a7a83..6e21f72c5b57 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c @@ -213,13 +213,13 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, priv->family = family; if (tb[NFTA_NAT_REG_ADDR_MIN]) { - err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MIN], + err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_ADDR_MIN], &priv->sreg_addr_min, alen); if (err < 0) return err; if (tb[NFTA_NAT_REG_ADDR_MAX]) { - err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MAX], + err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_ADDR_MAX], &priv->sreg_addr_max, alen); if (err < 0) @@ -233,13 +233,13 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, plen = sizeof_field(struct nf_nat_range, min_proto.all); if (tb[NFTA_NAT_REG_PROTO_MIN]) { - err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN], + err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_PROTO_MIN], &priv->sreg_proto_min, plen); if (err < 0) return err; if (tb[NFTA_NAT_REG_PROTO_MAX]) { - err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MAX], + err = nft_parse_register_load(ctx, tb[NFTA_NAT_REG_PROTO_MAX], &priv->sreg_proto_max, plen); if (err < 0) diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c index 08a27433e2f5..1ee17098de0c 100644 --- a/net/netfilter/nft_objref.c +++ b/net/netfilter/nft_objref.c @@ -173,7 +173,7 @@ static int nft_objref_map_init(const struct nft_ctx *ctx, if (!(set->flags & NFT_SET_OBJECT)) return -EINVAL; - err = nft_parse_register_load(tb[NFTA_OBJREF_SET_SREG], &priv->sreg, + err = nft_parse_register_load(ctx, tb[NFTA_OBJREF_SET_SREG], &priv->sreg, set->klen); if (err < 0) return err; diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c index 2db38c06bede..7dfc5343dae4 100644 --- a/net/netfilter/nft_payload.c +++ b/net/netfilter/nft_payload.c @@ -984,7 +984,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, } priv->csum_type = csum_type; - return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg, + return nft_parse_register_load(ctx, tb[NFTA_PAYLOAD_SREG], &priv->sreg, priv->len); } diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c index b8ebb187814f..344fe311878f 100644 --- a/net/netfilter/nft_queue.c +++ b/net/netfilter/nft_queue.c @@ -135,7 +135,7 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx, struct nft_queue *priv = nft_expr_priv(expr); int err; - err = nft_parse_register_load(tb[NFTA_QUEUE_SREG_QNUM], + err = nft_parse_register_load(ctx, tb[NFTA_QUEUE_SREG_QNUM], &priv->sreg_qnum, sizeof(u32)); if (err < 0) return err; diff --git a/net/netfilter/nft_range.c b/net/netfilter/nft_range.c index 51ae64cd268f..ea382f7bbd78 100644 --- a/net/netfilter/nft_range.c +++ b/net/netfilter/nft_range.c @@ -83,7 +83,7 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr goto err2; } - err = nft_parse_register_load(tb[NFTA_RANGE_SREG], &priv->sreg, + err = nft_parse_register_load(ctx, tb[NFTA_RANGE_SREG], &priv->sreg, desc_from.len); if (err < 0) goto err2; diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c index 9051863509f3..95eedad85c83 100644 --- a/net/netfilter/nft_redir.c +++ b/net/netfilter/nft_redir.c @@ -50,13 +50,13 @@ static int nft_redir_init(const struct nft_ctx *ctx, plen = sizeof_field(struct nf_nat_range, min_proto.all); if (tb[NFTA_REDIR_REG_PROTO_MIN]) { - err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN], + err = nft_parse_register_load(ctx, tb[NFTA_REDIR_REG_PROTO_MIN], &priv->sreg_proto_min, plen); if (err < 0) return err; if (tb[NFTA_REDIR_REG_PROTO_MAX]) { - err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MAX], + err = nft_parse_register_load(ctx, tb[NFTA_REDIR_REG_PROTO_MAX], &priv->sreg_proto_max, plen); if (err < 0) diff --git a/net/netfilter/nft_tproxy.c b/net/netfilter/nft_tproxy.c index ed344af2a439..50481280abd2 100644 --- a/net/netfilter/nft_tproxy.c +++ b/net/netfilter/nft_tproxy.c @@ -254,14 +254,14 @@ static int nft_tproxy_init(const struct nft_ctx *ctx, } if (tb[NFTA_TPROXY_REG_ADDR]) { - err = nft_parse_register_load(tb[NFTA_TPROXY_REG_ADDR], + err = nft_parse_register_load(ctx, tb[NFTA_TPROXY_REG_ADDR], &priv->sreg_addr, alen); if (err < 0) return err; } if (tb[NFTA_TPROXY_REG_PORT]) { - err = nft_parse_register_load(tb[NFTA_TPROXY_REG_PORT], + err = nft_parse_register_load(ctx, tb[NFTA_TPROXY_REG_PORT], &priv->sreg_port, sizeof(u16)); if (err < 0) return err; -- Gitee From e0f210295443eae7b7b4061d110d04de8cab30f1 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 20 Aug 2024 17:56:13 +0800 Subject: [PATCH 0514/1449] netfilter: nf_tables: allow loads only when register is initialized ANBZ: #35228 commit 1816619b2fe813c326dcf9bb8dad814a40168f12 stable. commit 14fb07130c7ddd257e30079b87499b3f89097b09 upstream. Reject rules where a load occurs from a register that has not seen a store early in the same rule. commit 4c905f6740a3 ("netfilter: nf_tables: initialize registers in nft_do_chain()") had to add a unconditional memset to the nftables register space to avoid leaking stack information to userspace. This memset shows up in benchmarks. After this change, this commit can be reverted again. Note that this breaks userspace compatibility, because theoretically you can do rule 1: reg2 := meta load iif, reg2 == 1 jump ... rule 2: reg2 == 2 jump ... // read access with no store in this rule ... after this change this is rejected. Neither nftables nor iptables-nft generate such rules, each rule is always standalone. This resuts in a small increase of nft_ctx structure by sizeof(long). To cope with hypothetical rulesets like the example above one could emit on-demand "reg[x] = 0" store when generating the datapath blob in nf_tables_commit_chain_prepare(). A patch that does this is linked to below. For now, lets disable this. In nf_tables, a rule is the smallest unit that can be replaced from userspace, i.e. a hypothetical ruleset that relies on earlier initialisations of registers can't be changed at will as register usage would need to be coordinated. Link: https://lore.kernel.org/netfilter-devel/20240627135330.17039-4-fw@strlen.de/ Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Stable-dep-of: a67fd55f6a09 ("netfilter: nf_tables: remove redundant chain validation on register store") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/netfilter/nf_tables.h | 1 + net/netfilter/nf_tables_api.c | 38 +++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 917edb4380e5..a8fcbdb37a7f 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -221,6 +221,7 @@ struct nft_ctx { u8 family; u8 level; bool report; + DECLARE_BITMAP(reg_inited, NFT_REG32_NUM); }; enum nft_data_desc_flags { diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 7bccfb1a8a72..8b8895e4372d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -146,6 +146,8 @@ static void nft_ctx_init(struct nft_ctx *ctx, ctx->report = nlmsg_report(nlh); ctx->flags = nlh->nlmsg_flags; ctx->seq = nlh->nlmsg_seq; + + bitmap_zero(ctx->reg_inited, NFT_REG32_NUM); } static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx, @@ -10915,8 +10917,8 @@ static int nft_validate_register_load(enum nft_registers reg, unsigned int len) int nft_parse_register_load(const struct nft_ctx *ctx, const struct nlattr *attr, u8 *sreg, u32 len) { - u32 reg; - int err; + int err, invalid_reg; + u32 reg, next_register; err = nft_parse_register(attr, ®); if (err < 0) @@ -10926,11 +10928,36 @@ int nft_parse_register_load(const struct nft_ctx *ctx, if (err < 0) return err; + next_register = DIV_ROUND_UP(len, NFT_REG32_SIZE) + reg; + + /* Can't happen: nft_validate_register_load() should have failed */ + if (WARN_ON_ONCE(next_register > NFT_REG32_NUM)) + return -EINVAL; + + /* find first register that did not see an earlier store. */ + invalid_reg = find_next_zero_bit(ctx->reg_inited, NFT_REG32_NUM, reg); + + /* invalid register within the range that we're loading from? */ + if (invalid_reg < next_register) + return -ENODATA; + *sreg = reg; return 0; } EXPORT_SYMBOL_GPL(nft_parse_register_load); +static void nft_saw_register_store(const struct nft_ctx *__ctx, + int reg, unsigned int len) +{ + unsigned int registers = DIV_ROUND_UP(len, NFT_REG32_SIZE); + struct nft_ctx *ctx = (struct nft_ctx *)__ctx; + + if (WARN_ON_ONCE(len == 0 || reg < 0)) + return; + + bitmap_set(ctx->reg_inited, reg, registers); +} + static int nft_validate_register_store(const struct nft_ctx *ctx, enum nft_registers reg, const struct nft_data *data, @@ -10952,7 +10979,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, return err; } - return 0; + break; default: if (type != NFT_DATA_VALUE) return -EINVAL; @@ -10965,8 +10992,11 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, sizeof_field(struct nft_regs, data)) return -ERANGE; - return 0; + break; } + + nft_saw_register_store(ctx, reg, len); + return 0; } int nft_parse_register_store(const struct nft_ctx *ctx, -- Gitee From 97f9a275947fbee414df9e66915d6e167a4134ad Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 19 Nov 2025 20:42:05 +0800 Subject: [PATCH 0515/1449] netfilter: nf_tables: remove redundant chain validation on register store ANBZ: #35228 commit a9c87779df20f0e07c0354aeecc52fc1a30ae798 stable. commit a67fd55f6a09f4119b7232c19e0f348fe31ab0db upstream. This validation predates the introduction of the state machine that determines when to enter slow path validation for error reporting. Currently, table validation is perform when: - new rule contains expressions that need validation. - new set element with jump/goto verdict. Validation on register store skips most checks with no basechains, still this walks the graph searching for loops and ensuring expressions are called from the right hook. Remove this. Fixes: a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation") Signed-off-by: Pablo Neira Ayuso Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_tables_api.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 8b8895e4372d..394ee65e1d35 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -10964,21 +10964,10 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, enum nft_data_types type, unsigned int len) { - int err; - switch (reg) { case NFT_REG_VERDICT: if (type != NFT_DATA_VERDICT) return -EINVAL; - - if (data != NULL && - (data->verdict.code == NFT_GOTO || - data->verdict.code == NFT_JUMP)) { - err = nft_chain_validate(ctx, data->verdict.chain); - if (err < 0) - return err; - } - break; default: if (type != NFT_DATA_VALUE) -- Gitee From 22f4670a9cad24d991a8649401d123e3ddbb5aa4 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Mon, 8 Dec 2025 20:19:01 +0800 Subject: [PATCH 0516/1449] ethtool: Avoid overflowing userspace buffer on stats query ANBZ: #35228 commit ca9983bc3a1189bd72f9ae449d925a66b2616326 stable. commit 7b07be1ff1cb6c49869910518650e8d0abc7d25f upstream. The ethtool -S command operates across three ioctl calls: ETHTOOL_GSSET_INFO for the size, ETHTOOL_GSTRINGS for the names, and ETHTOOL_GSTATS for the values. If the number of stats changes between these calls (e.g., due to device reconfiguration), userspace's buffer allocation will be incorrect, potentially leading to buffer overflow. Drivers are generally expected to maintain stable stat counts, but some drivers (e.g., mlx5, bnx2x, bna, ksz884x) use dynamic counters, making this scenario possible. Some drivers try to handle this internally: - bnad_get_ethtool_stats() returns early in case stats.n_stats is not equal to the driver's stats count. - micrel/ksz884x also makes sure not to write anything beyond stats.n_stats and overflow the buffer. However, both use stats.n_stats which is already assigned with the value returned from get_sset_count(), hence won't solve the issue described here. Change ethtool_get_strings(), ethtool_get_stats(), ethtool_get_phy_stats() to not return anything in case of a mismatch between userspace's size and get_sset_size(), to prevent buffer overflow. The returned n_stats value will be equal to zero, to reflect that nothing has been returned. This could result in one of two cases when using upstream ethtool, depending on when the size change is detected: 1. When detected in ethtool_get_strings(): # ethtool -S eth2 no stats available 2. When detected in get stats, all stats will be reported as zero. Both cases are presumably transient, and a subsequent ethtool call should succeed. Other than the overflow avoidance, these two cases are very evident (no output/cleared stats), which is arguably better than presenting incorrect/shifted stats. I also considered returning an error instead of a "silent" response, but that seems more destructive towards userspace apps. Notes: - This patch does not claim to fix the inherent race, it only makes sure that we do not overflow the userspace buffer, and makes for a more predictable behavior. - RTNL lock is held during each ioctl, the race window exists between the separate ioctl calls when the lock is released. - Userspace ethtool always fills stats.n_stats, but it is likely that these stats ioctls are implemented in other userspace applications which might not fill it. The added code checks that it's not zero, to prevent any regressions. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Dragos Tatulea Reviewed-by: Tariq Toukan Signed-off-by: Gal Pressman Link: https://patch.msgid.link/20251208121901.3203692-1-gal@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ethtool/ioctl.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 4486cbe2faf0..eaeb514b7e5f 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1955,7 +1955,10 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) return -ENOMEM; WARN_ON_ONCE(!ret); - gstrings.len = ret; + if (gstrings.len && gstrings.len != ret) + gstrings.len = 0; + else + gstrings.len = ret; if (gstrings.len) { data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN)); @@ -2070,10 +2073,13 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) if (copy_from_user(&stats, useraddr, sizeof(stats))) return -EFAULT; - stats.n_stats = n_stats; + if (stats.n_stats && stats.n_stats != n_stats) + stats.n_stats = 0; + else + stats.n_stats = n_stats; - if (n_stats) { - data = vzalloc(array_size(n_stats, sizeof(u64))); + if (stats.n_stats) { + data = vzalloc(array_size(stats.n_stats, sizeof(u64))); if (!data) return -ENOMEM; ops->get_ethtool_stats(dev, &stats, data); @@ -2085,7 +2091,9 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) if (copy_to_user(useraddr, &stats, sizeof(stats))) goto out; useraddr += sizeof(stats); - if (n_stats && copy_to_user(useraddr, data, array_size(n_stats, sizeof(u64)))) + if (stats.n_stats && + copy_to_user(useraddr, data, + array_size(stats.n_stats, sizeof(u64)))) goto out; ret = 0; @@ -2121,6 +2129,10 @@ static int ethtool_get_phy_stats_phydev(struct phy_device *phydev, return -EOPNOTSUPP; n_stats = phy_ops->get_sset_count(phydev); + if (stats->n_stats && stats->n_stats != n_stats) { + stats->n_stats = 0; + return 0; + } ret = ethtool_vzalloc_stats_array(n_stats, data); if (ret) @@ -2141,6 +2153,10 @@ static int ethtool_get_phy_stats_ethtool(struct net_device *dev, return -EOPNOTSUPP; n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS); + if (stats->n_stats && stats->n_stats != n_stats) { + stats->n_stats = 0; + return 0; + } ret = ethtool_vzalloc_stats_array(n_stats, data); if (ret) @@ -2177,7 +2193,9 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) } useraddr += sizeof(stats); - if (copy_to_user(useraddr, data, array_size(stats.n_stats, sizeof(u64)))) + if (stats.n_stats && + copy_to_user(useraddr, data, + array_size(stats.n_stats, sizeof(u64)))) ret = -EFAULT; out: -- Gitee From cbafe26e6f8c2e4c2578683a9cabc23963b51d54 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Tue, 9 Dec 2025 20:56:09 +0800 Subject: [PATCH 0517/1449] net/mlx5: fw reset, clear reset requested on drain_fw_reset ANBZ: #35228 commit 24d3f86df879315f79c80482bd9143abada394c6 stable. commit 89a898d63f6f588acf5c104c65c94a38b68c69a6 upstream. drain_fw_reset() waits for ongoing firmware reset events and blocks new event handling, but does not clear the reset requested flag, and may keep sync reset polling. To fix it, call mlx5_sync_reset_clear_reset_requested() to clear the flag, stop sync reset polling, and resume health polling, ensuring health issues are still detected after the firmware reset drain. Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device") Signed-off-by: Moshe Shemesh Reviewed-by: Shay Drori Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1765284977-1363052-2-git-send-email-tariqt@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c index 4d64d179b5dd..dc7afc9e7777 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c @@ -804,7 +804,8 @@ void mlx5_drain_fw_reset(struct mlx5_core_dev *dev) cancel_work_sync(&fw_reset->reset_reload_work); cancel_work_sync(&fw_reset->reset_now_work); cancel_work_sync(&fw_reset->reset_abort_work); - cancel_delayed_work(&fw_reset->reset_timeout_work); + if (test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags)) + mlx5_sync_reset_clear_reset_requested(dev, true); } static const struct devlink_param mlx5_fw_reset_devlink_params[] = { -- Gitee From 5c57696a1ab19436bd2f99194bed6ac1924c5245 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Tue, 9 Dec 2025 20:56:10 +0800 Subject: [PATCH 0518/1449] net/mlx5: Drain firmware reset in shutdown callback ANBZ: #35228 commit 0b0e4639a827e152da97c18578fa0213b1175c97 stable. commit 5846a365fc6476b02d6766963cf0985520f0385f upstream. Invoke drain_fw_reset() in the shutdown callback to ensure all firmware reset handling is completed before shutdown proceeds. Fixes: 16d42d313350 ("net/mlx5: Drain fw_reset when removing device") Signed-off-by: Moshe Shemesh Reviewed-by: Shay Drori Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1765284977-1363052-3-git-send-email-tariqt@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 8a11e410f7c1..df6eeb0f57bc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -2164,6 +2164,7 @@ static void shutdown(struct pci_dev *pdev) mlx5_core_info(dev, "Shutdown was called\n"); set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state); + mlx5_drain_fw_reset(dev); mlx5_drain_health_wq(dev); err = mlx5_try_fast_unload(dev); if (err) -- Gitee From 42c165e0848444f02082fc9f188f101b79e3bc58 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Tue, 9 Dec 2025 20:56:11 +0800 Subject: [PATCH 0519/1449] net/mlx5: fw_tracer, Validate format string parameters ANBZ: #35228 commit 8ac688c0e430dab19f6a9b70df94b1f635612c1a stable. commit b35966042d20b14e2d83330049f77deec5229749 upstream. Add validation for format string parameters in the firmware tracer to prevent potential security vulnerabilities and crashes from malformed format strings received from firmware. The firmware tracer receives format strings from the device firmware and uses them to format trace messages. Without proper validation, bad firmware could provide format strings with invalid format specifiers (e.g., %s, %p, %n) that could lead to crashes, or other undefined behavior. Add mlx5_tracer_validate_params() to validate that all format specifiers in trace strings are limited to safe integer/hex formats (%x, %d, %i, %u, %llx, %lx, etc.). Reject strings containing other format types that could be used to access arbitrary memory or cause crashes. Invalid format strings are added to the trace output for visibility with "BAD_FORMAT: " prefix. Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support") Signed-off-by: Shay Drory Reviewed-by: Moshe Shemesh Reported-by: Breno Leitao Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/ Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1765284977-1363052-4-git-send-email-tariqt@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../mellanox/mlx5/core/diag/fw_tracer.c | 83 ++++++++++++++++--- .../mellanox/mlx5/core/diag/fw_tracer.h | 1 + 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c index 85d3bfa0780c..197c306d350b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -33,6 +33,7 @@ #include "lib/eq.h" #include "fw_tracer.h" #include "fw_tracer_tracepoint.h" +#include static int mlx5_query_mtrc_caps(struct mlx5_fw_tracer *tracer) { @@ -358,6 +359,43 @@ static const char *VAL_PARM = "%llx"; static const char *REPLACE_64_VAL_PARM = "%x%x"; static const char *PARAM_CHAR = "%"; +static bool mlx5_is_valid_spec(const char *str) +{ + /* Parse format specifiers to find the actual type. + * Structure: %[flags][width][.precision][length]type + * Skip flags, width, precision & length. + */ + while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l') + str++; + + /* Check if it's a valid integer/hex specifier: + * Valid formats: %x, %d, %i, %u, etc. + */ + if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' && + *str != 'u' && *str != 'c') + return false; + + return true; +} + +static bool mlx5_tracer_validate_params(const char *str) +{ + const char *substr = str; + + if (!str) + return false; + + substr = strstr(substr, PARAM_CHAR); + while (substr) { + if (!mlx5_is_valid_spec(substr + 1)) + return false; + + substr = strstr(substr + 1, PARAM_CHAR); + } + + return true; +} + static int mlx5_tracer_message_hash(u32 message_id) { return jhash_1word(message_id, 0) & (MESSAGE_HASH_SIZE - 1); @@ -419,6 +457,10 @@ static int mlx5_tracer_get_num_of_params(char *str) char *substr, *pstr = str; int num_of_params = 0; + /* Validate that all parameters are valid before processing */ + if (!mlx5_tracer_validate_params(str)) + return -EINVAL; + /* replace %llx with %x%x */ substr = strstr(pstr, VAL_PARM); while (substr) { @@ -570,14 +612,17 @@ void mlx5_tracer_print_trace(struct tracer_string_format *str_frmt, { char tmp[512]; - snprintf(tmp, sizeof(tmp), str_frmt->string, - str_frmt->params[0], - str_frmt->params[1], - str_frmt->params[2], - str_frmt->params[3], - str_frmt->params[4], - str_frmt->params[5], - str_frmt->params[6]); + if (str_frmt->invalid_string) + snprintf(tmp, sizeof(tmp), "BAD_FORMAT: %s", str_frmt->string); + else + snprintf(tmp, sizeof(tmp), str_frmt->string, + str_frmt->params[0], + str_frmt->params[1], + str_frmt->params[2], + str_frmt->params[3], + str_frmt->params[4], + str_frmt->params[5], + str_frmt->params[6]); trace_mlx5_fw(dev->tracer, trace_timestamp, str_frmt->lost, str_frmt->event_id, tmp); @@ -609,6 +654,13 @@ static int mlx5_tracer_handle_raw_string(struct mlx5_fw_tracer *tracer, return 0; } +static void mlx5_tracer_handle_bad_format_string(struct mlx5_fw_tracer *tracer, + struct tracer_string_format *cur_string) +{ + cur_string->invalid_string = true; + list_add_tail(&cur_string->list, &tracer->ready_strings_list); +} + static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer, struct tracer_event *tracer_event) { @@ -619,12 +671,18 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer, if (!cur_string) return mlx5_tracer_handle_raw_string(tracer, tracer_event); - cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string); - cur_string->last_param_num = 0; cur_string->event_id = tracer_event->event_id; cur_string->tmsn = tracer_event->string_event.tmsn; cur_string->timestamp = tracer_event->string_event.timestamp; cur_string->lost = tracer_event->lost_event; + cur_string->last_param_num = 0; + cur_string->num_of_params = mlx5_tracer_get_num_of_params(cur_string->string); + if (cur_string->num_of_params < 0) { + pr_debug("%s Invalid format string parameters\n", + __func__); + mlx5_tracer_handle_bad_format_string(tracer, cur_string); + return 0; + } if (cur_string->num_of_params == 0) /* trace with no params */ list_add_tail(&cur_string->list, &tracer->ready_strings_list); } else { @@ -634,6 +692,11 @@ static int mlx5_tracer_handle_string_trace(struct mlx5_fw_tracer *tracer, __func__, tracer_event->string_event.tmsn); return mlx5_tracer_handle_raw_string(tracer, tracer_event); } + if (cur_string->num_of_params < 0) { + pr_debug("%s string parameter of invalid string, dumping\n", + __func__); + return 0; + } cur_string->last_param_num += 1; if (cur_string->last_param_num > TRACER_MAX_PARAMS) { pr_debug("%s Number of params exceeds the max (%d)\n", diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h index 5c548bb74f07..30d0bcba8847 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.h @@ -125,6 +125,7 @@ struct tracer_string_format { struct list_head list; u32 timestamp; bool lost; + bool invalid_string; }; enum mlx5_fw_tracer_ownership_state { -- Gitee From 688a27e157ed08558a516895c0d4dd5b874b0619 Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Tue, 9 Dec 2025 20:56:12 +0800 Subject: [PATCH 0520/1449] net/mlx5: fw_tracer, Handle escaped percent properly ANBZ: #35228 commit de0560f2c33c07254fd9b4d4e88ff43d63618dbb stable. commit c0289f67f7d6a0dfba0e92cfe661a5c70c8c6e92 upstream. The firmware tracer's format string validation and parameter counting did not properly handle escaped percent signs (%%). This caused fw_tracer to count more parameters when trace format strings contained literal percent characters. To fix it, allow %% to pass string validation and skip %% sequences when counting parameters since they represent literal percent signs rather than format specifiers. Fixes: 70dd6fdb8987 ("net/mlx5: FW tracer, parse traces and kernel tracing support") Signed-off-by: Shay Drory Reported-by: Breno Leitao Reviewed-by: Moshe Shemesh Closes: https://lore.kernel.org/netdev/hanz6rzrb2bqbplryjrakvkbmv4y5jlmtthnvi3thg5slqvelp@t3s3erottr6s/ Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1765284977-1363052-5-git-send-email-tariqt@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../mellanox/mlx5/core/diag/fw_tracer.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c index 197c306d350b..0a33ab5f53fd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -368,11 +368,11 @@ static bool mlx5_is_valid_spec(const char *str) while (isdigit(*str) || *str == '#' || *str == '.' || *str == 'l') str++; - /* Check if it's a valid integer/hex specifier: + /* Check if it's a valid integer/hex specifier or %%: * Valid formats: %x, %d, %i, %u, etc. */ if (*str != 'x' && *str != 'X' && *str != 'd' && *str != 'i' && - *str != 'u' && *str != 'c') + *str != 'u' && *str != 'c' && *str != '%') return false; return true; @@ -390,7 +390,11 @@ static bool mlx5_tracer_validate_params(const char *str) if (!mlx5_is_valid_spec(substr + 1)) return false; - substr = strstr(substr + 1, PARAM_CHAR); + if (*(substr + 1) == '%') + substr = strstr(substr + 2, PARAM_CHAR); + else + substr = strstr(substr + 1, PARAM_CHAR); + } return true; @@ -469,11 +473,15 @@ static int mlx5_tracer_get_num_of_params(char *str) substr = strstr(pstr, VAL_PARM); } - /* count all the % characters */ + /* count all the % characters, but skip %% (escaped percent) */ substr = strstr(str, PARAM_CHAR); while (substr) { - num_of_params += 1; - str = substr + 1; + if (*(substr + 1) != '%') { + num_of_params += 1; + str = substr + 1; + } else { + str = substr + 2; + } substr = strstr(str, PARAM_CHAR); } -- Gitee From 4a569dcc18e5ba8814fbaf4cf5e1b2e502ef697b Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Thu, 12 Sep 2024 04:17:53 +0800 Subject: [PATCH 0521/1449] net/mlx5: Skip HotPlug check on sync reset using hot reset ANBZ: #35228 commit 873cb8bb91ba4cd7c56bcf713bd40a3507a00fba stable. commit 48bb52b0bc6693afb17a6024bab925b25fec44a1 upstream. Sync reset request is nacked by the driver when PCIe bridge connected to mlx5 device has HotPlug interrupt enabled. However, when using reset method of hot reset this check can be skipped as Hotplug is supported on this reset method. Signed-off-by: Moshe Shemesh Signed-off-by: Saeed Mahameed Reviewed-by: Jacob Keller Link: https://patch.msgid.link/20240911201757.1505453-12-saeed@kernel.org Signed-off-by: Jakub Kicinski Stable-dep-of: 367e501f8b09 ("net/mlx5: Serialize firmware reset with devlink") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c index dc7afc9e7777..bdcd9e530633 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c @@ -396,7 +396,8 @@ static int mlx5_check_dev_ids(struct mlx5_core_dev *dev, u16 dev_id) return 0; } -static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev) +static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev, + u8 reset_method) { u16 dev_id; int err; @@ -412,9 +413,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev) } #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE) - err = mlx5_check_hotplug_interrupt(dev); - if (err) - return false; + if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) { + err = mlx5_check_hotplug_interrupt(dev); + if (err) + return false; + } #endif err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id); @@ -435,7 +438,7 @@ static void mlx5_sync_reset_request_event(struct work_struct *work) mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err); if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) || - !mlx5_is_reset_now_capable(dev)) { + !mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) { err = mlx5_fw_reset_set_reset_sync_nack(dev); mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s", err ? "Failed" : "Sent"); -- Gitee From fd5a26a157ed961200310deb9b87b34cd7f5743d Mon Sep 17 00:00:00 2001 From: Shay Drory Date: Tue, 9 Dec 2025 20:56:13 +0800 Subject: [PATCH 0522/1449] net/mlx5: Serialize firmware reset with devlink ANBZ: #35228 commit 7646e5d8188b3e8cda1b9f12b98676f3a629c129 stable. commit 367e501f8b095eca08d2eb0ba4ccea5b5e82c169 upstream. The firmware reset mechanism can be triggered by asynchronous events, which may race with other devlink operations like devlink reload or devlink dev eswitch set, potentially leading to inconsistent states. This patch addresses the race by using the devl_lock to serialize the firmware reset against other devlink operations. When a reset is requested, the driver attempts to acquire the lock. If successful, it sets a flag to block devlink reload or eswitch changes, ACKs the reset to firmware and then releases the lock. If the lock is already held by another operation, the driver NACKs the firmware reset request, indicating that the reset cannot proceed. Firmware reset does not keep the devl_lock and instead uses an internal firmware reset bit. This is because firmware resets can be triggered by asynchronous events, and processed in different threads. It is illegal and unsafe to acquire a lock in one thread and attempt to release it in another, as lock ownership is intrinsically thread-specific. This change ensures that firmware resets and other devlink operations are mutually exclusive during the critical reset request phase, preventing race conditions. Fixes: 38b9f903f22b ("net/mlx5: Handle sync reset request event") Signed-off-by: Shay Drory Reviewed-by: Mateusz Berezecki Reviewed-by: Moshe Shemesh Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1765284977-1363052-6-git-send-email-tariqt@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/mellanox/mlx5/core/devlink.c | 5 +++ .../mellanox/mlx5/core/eswitch_offloads.c | 6 +++ .../ethernet/mellanox/mlx5/core/fw_reset.c | 45 +++++++++++++++++-- .../ethernet/mellanox/mlx5/core/fw_reset.h | 1 + 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index 8489b5087d9c..b2532b1c9565 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -144,6 +144,11 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change, bool sf_dev_allocated; int ret = 0; + if (mlx5_fw_reset_in_progress(dev)) { + NL_SET_ERR_MSG_MOD(extack, "Can't reload during firmware reset"); + return -EBUSY; + } + if (mlx5_dev_is_lightweight(dev)) { if (action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 86fb8197594f..c218593dc40f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -51,6 +51,7 @@ #include "devlink.h" #include "lag/lag.h" #include "en/tc/post_meter.h" +#include "fw_reset.h" /* There are two match-all miss flows, one for unicast dst mac and * one for multicast. @@ -3716,6 +3717,11 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, if (IS_ERR(esw)) return PTR_ERR(esw); + if (mlx5_fw_reset_in_progress(esw->dev)) { + NL_SET_ERR_MSG_MOD(extack, "Can't change eswitch mode during firmware reset"); + return -EBUSY; + } + if (esw_mode_from_devlink(mode, &mlx5_mode)) return -EINVAL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c index bdcd9e530633..f7e139279f5f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c @@ -15,6 +15,7 @@ enum { MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS, MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, + MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, }; struct mlx5_fw_reset { @@ -125,6 +126,16 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL); } +bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev) +{ + struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; + + if (!fw_reset) + return false; + + return test_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags); +} + static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev, u8 *reset_method) { @@ -240,6 +251,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE)); devl_unlock(devlink); } + + clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags); } static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev) @@ -431,27 +444,48 @@ static void mlx5_sync_reset_request_event(struct work_struct *work) struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, reset_request_work); struct mlx5_core_dev *dev = fw_reset->dev; + bool nack_request = false; + struct devlink *devlink; int err; err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method); - if (err) + if (err) { + nack_request = true; mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err); + } else if (!mlx5_is_reset_now_capable(dev, fw_reset->reset_method) || + test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, + &fw_reset->reset_flags)) { + nack_request = true; + } - if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) || - !mlx5_is_reset_now_capable(dev, fw_reset->reset_method)) { + devlink = priv_to_devlink(dev); + /* For external resets, try to acquire devl_lock. Skip if devlink reset is + * pending (lock already held) + */ + if (nack_request || + (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, + &fw_reset->reset_flags) && + !devl_trylock(devlink))) { err = mlx5_fw_reset_set_reset_sync_nack(dev); mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s", err ? "Failed" : "Sent"); return; } + if (mlx5_sync_reset_set_reset_requested(dev)) - return; + goto unlock; + + set_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags); err = mlx5_fw_reset_set_reset_sync_ack(dev); if (err) mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err); else mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n"); + +unlock: + if (!test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) + devl_unlock(devlink); } static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id) @@ -685,6 +719,8 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work) if (mlx5_sync_reset_clear_reset_requested(dev, true)) return; + + clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags); mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n"); } @@ -721,6 +757,7 @@ static void mlx5_sync_reset_timeout_work(struct work_struct *work) if (mlx5_sync_reset_clear_reset_requested(dev, true)) return; + clear_bit(MLX5_FW_RESET_FLAGS_RESET_IN_PROGRESS, &fw_reset->reset_flags); mlx5_core_warn(dev, "PCI Sync FW Update Reset Timeout.\n"); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h index d5b28525c960..2d96b2adc1cd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h @@ -10,6 +10,7 @@ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_ty int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel, struct netlink_ext_ack *extack); int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev); +bool mlx5_fw_reset_in_progress(struct mlx5_core_dev *dev); int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev); void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked); -- Gitee From b5ff9928a6048f73ff83bf1f7f3ee029ae48803b Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Wed, 10 Dec 2025 03:30:15 +0800 Subject: [PATCH 0523/1449] net/handshake: duplicate handshake cancellations leak socket ANBZ: #35228 commit 011ae80c49d9bfa5b4336f8bd387cd25c7593663 stable. commit 15564bd67e2975002f2a8e9defee33e321d3183f upstream. When a handshake request is cancelled it is removed from the handshake_net->hn_requests list, but it is still present in the handshake_rhashtbl until it is destroyed. If a second cancellation request arrives for the same handshake request, then remove_pending() will return false... and assuming HANDSHAKE_F_REQ_COMPLETED isn't set in req->hr_flags, we'll continue processing through the out_true label, where we put another reference on the sock and a refcount underflow occurs. This can happen for example if a handshake times out - particularly if the SUNRPC client sends the AUTH_TLS probe to the server but doesn't follow it up with the ClientHello due to a problem with tlshd. When the timeout is hit on the server, the server will send a FIN, which triggers a cancellation request via xs_reset_transport(). When the timeout is hit on the client, another cancellation request happens via xs_tls_handshake_sync(). Add a test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED) in the pending cancel path so duplicate cancels can be detected. Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests") Suggested-by: Chuck Lever Signed-off-by: Scott Mayhew Reviewed-by: Chuck Lever Link: https://patch.msgid.link/20251209193015.3032058-1-smayhew@redhat.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/handshake/request.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/handshake/request.c b/net/handshake/request.c index 94d5cef3e048..0ac126b0add6 100644 --- a/net/handshake/request.c +++ b/net/handshake/request.c @@ -325,7 +325,11 @@ bool handshake_req_cancel(struct sock *sk) hn = handshake_pernet(net); if (hn && remove_pending(hn, req)) { - /* Request hadn't been accepted */ + /* Request hadn't been accepted - mark cancelled */ + if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) { + trace_handshake_cancel_busy(net, req, sk); + return false; + } goto out_true; } if (test_and_set_bit(HANDSHAKE_F_REQ_COMPLETED, &req->hr_flags)) { -- Gitee From 01c542707289d19832af68a9520eebe94030d2ca Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Thu, 11 Dec 2025 10:09:19 +0800 Subject: [PATCH 0524/1449] net: enetc: do not transmit redirected XDP frames when the link is down ANBZ: #35228 commit 049538a3aa981aed2a6adae5f36e1752bcba20f1 stable. commit 2939203ffee818f1e5ebd60bbb85a174d63aab9c upstream. In the current implementation, the enetc_xdp_xmit() always transmits redirected XDP frames even if the link is down, but the frames cannot be transmitted from TX BD rings when the link is down, so the frames are still kept in the TX BD rings. If the XDP program is uninstalled, users will see the following warning logs. fsl_enetc 0000:00:00.0 eno0: timeout for tx ring #6 clear More worse, the TX BD ring cannot work properly anymore, because the HW PIR and CIR are not equal after the re-initialization of the TX BD ring. At this point, the BDs between CIR and PIR are invalid, which will cause a hardware malfunction. Another reason is that there is internal context in the ring prefetch logic that will retain the state from the first incarnation of the ring and continue prefetching from the stale location when we re-initialize the ring. The internal context is only reset by an FLR. That is to say, for LS1028A ENETC, software cannot set the HW CIR and PIR when initializing the TX BD ring. It does not make sense to transmit redirected XDP frames when the link is down. Add a link status check to prevent transmission in this condition. This fixes part of the issue, but more complex cases remain. For example, the TX BD ring may still contain unsent frames when the link goes down. Those situations require additional patches, which will build on this one. Fixes: 9d2b68cc108d ("net: enetc: add support for XDP_REDIRECT") Signed-off-by: Wei Fang Reviewed-by: Frank Li Reviewed-by: Hariprasad Kelam Reviewed-by: Vladimir Oltean Link: https://patch.msgid.link/20251211020919.121113-1-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/enetc/enetc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 7accf3a3e9f0..e3ab6f4f8dbb 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1429,7 +1429,8 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames, int xdp_tx_bd_cnt, i, k; int xdp_tx_frm_cnt = 0; - if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags) || + !netif_carrier_ok(ndev))) return -ENETDOWN; enetc_lock_mdio(); -- Gitee From eb9bc47600c6870030a22fe7fb1ce1cd1da17b33 Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Thu, 11 Dec 2025 10:37:35 +0800 Subject: [PATCH 0525/1449] net: hns3: using the num_tqps in the vf driver to apply for resources ANBZ: #35228 commit 1956d47a03eb625951e9e070db39fe2590e27510 stable. commit c2a16269742e176fccdd0ef9c016a233491a49ad upstream. Currently, hdev->htqp is allocated using hdev->num_tqps, and kinfo->tqp is allocated using kinfo->num_tqps. However, kinfo->num_tqps is set to min(new_tqps, hdev->num_tqps); Therefore, kinfo->num_tqps may be smaller than hdev->num_tqps, which causes some hdev->htqp[i] to remain uninitialized in hclgevf_knic_setup(). Thus, this patch allocates hdev->htqp and kinfo->tqp using hdev->num_tqps, ensuring that the lengths of hdev->htqp and kinfo->tqp are consistent and that all elements are properly initialized. Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support") Signed-off-by: Jian Shen Signed-off-by: Jijie Shao Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251211023737.2327018-2-shaojijie@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index ba5a57df6216..6c4b62a1846d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -370,12 +370,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev) new_tqps = kinfo->rss_size * num_tc; kinfo->num_tqps = min(new_tqps, hdev->num_tqps); - kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, + kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, sizeof(struct hnae3_queue *), GFP_KERNEL); if (!kinfo->tqp) return -ENOMEM; - for (i = 0; i < kinfo->num_tqps; i++) { + for (i = 0; i < hdev->num_tqps; i++) { hdev->htqp[i].q.handle = &hdev->nic; hdev->htqp[i].q.tqp_index = i; kinfo->tqp[i] = &hdev->htqp[i].q; -- Gitee From ea1d6f3313ff995e7ef8bf606075f24d380af511 Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Thu, 11 Dec 2025 10:37:36 +0800 Subject: [PATCH 0526/1449] net: hns3: using the num_tqps to check whether tqp_index is out of range when vf get ring info from mbx ANBZ: #35228 commit 3708637cb0d4f654c994e6f189bd62a6df00df04 stable. commit d180c11aa8a6fa735f9ac2c72c61364a9afc2ba7 upstream. Currently, rss_size = num_tqps / tc_num. If tc_num is 1, then num_tqps equals rss_size. However, if the tc_num is greater than 1, then rss_size will be less than num_tqps, causing the tqp_index check for subsequent TCs using rss_size to always fail. This patch uses the num_tqps to check whether tqp_index is out of range, instead of rss_size. Fixes: 326334aad024 ("net: hns3: add a check for tqp_index in hclge_get_ring_chain_from_mbx()") Signed-off-by: Jian Shen Signed-off-by: Jijie Shao Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251211023737.2327018-3-shaojijie@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 88298020a67f..fe96d100c7bf 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -193,10 +193,10 @@ static int hclge_get_ring_chain_from_mbx( return -EINVAL; for (i = 0; i < ring_num; i++) { - if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) { + if (req->msg.param[i].tqp_index >= vport->nic.kinfo.num_tqps) { dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n", req->msg.param[i].tqp_index, - vport->nic.kinfo.rss_size - 1U); + vport->nic.kinfo.num_tqps - 1U); return -EINVAL; } } -- Gitee From aea1c5e5fa1b4a5849ca72c5ef89a7cfd04e39e3 Mon Sep 17 00:00:00 2001 From: Jian Shen Date: Thu, 11 Dec 2025 10:37:37 +0800 Subject: [PATCH 0527/1449] net: hns3: add VLAN id validation before using ANBZ: #35228 commit b7b4f3bf118f51b67691a55b464f04452e5dc6fc stable. commit 6ef935e65902bfed53980ad2754b06a284ea8ac1 upstream. Currently, the VLAN id may be used without validation when receive a VLAN configuration mailbox from VF. The length of vlan_del_fail_bmap is BITS_TO_LONGS(VLAN_N_VID). It may cause out-of-bounds memory access once the VLAN id is bigger than or equal to VLAN_N_VID. Therefore, VLAN id needs to be checked to ensure it is within the range of VLAN_N_VID. Fixes: fe4144d47eef ("net: hns3: sync VLAN filter entries when kill VLAN ID failed") Signed-off-by: Jian Shen Signed-off-by: Jijie Shao Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251211023737.2327018-4-shaojijie@huawei.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 25e28748a443..2541691a95fe 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -11268,6 +11268,9 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, bool writen_to_tbl = false; int ret = 0; + if (vlan_id >= VLAN_N_VID) + return -EINVAL; + /* When device is resetting or reset failed, firmware is unable to * handle mailbox. Just record the vlan id, and remove it after * reset finished. -- Gitee From 713625edb8b92598aaf0a08b679ca8884cb59a5f Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Wed, 10 Dec 2025 17:48:08 +0800 Subject: [PATCH 0528/1449] hwmon: (ibmpex) fix use-after-free in high/low store ANBZ: #35228 commit fa37adcf1d564ef58b9dfb01b6c36d35c5294bad stable. commit 6946c726c3f4c36f0f049e6f97e88c510b15f65d upstream. The ibmpex_high_low_store() function retrieves driver data using dev_get_drvdata() and uses it without validation. This creates a race condition where the sysfs callback can be invoked after the data structure is freed, leading to use-after-free. Fix by adding a NULL check after dev_get_drvdata(), and reordering operations in the deletion path to prevent TOCTOU. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 57c7c3a0fdea ("hwmon: IBM power meter driver") Signed-off-by: Junrui Luo Link: https://lore.kernel.org/r/MEYPR01MB7886BE2F51BFE41875B74B60AFA0A@MEYPR01MB7886.ausprd01.prod.outlook.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/ibmpex.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index db066b368918..40fff7e95ea1 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -282,6 +282,9 @@ static ssize_t ibmpex_high_low_store(struct device *dev, { struct ibmpex_bmc_data *data = dev_get_drvdata(dev); + if (!data) + return -ENODEV; + ibmpex_reset_high_low_data(data); return count; @@ -514,6 +517,9 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) { int i, j; + hwmon_device_unregister(data->hwmon_dev); + dev_set_drvdata(data->bmc_device, NULL); + device_remove_file(data->bmc_device, &sensor_dev_attr_reset_high_low.dev_attr); device_remove_file(data->bmc_device, &sensor_dev_attr_name.dev_attr); @@ -527,8 +533,7 @@ static void ibmpex_bmc_delete(struct ibmpex_bmc_data *data) } list_del(&data->list); - dev_set_drvdata(data->bmc_device, NULL); - hwmon_device_unregister(data->hwmon_dev); + ipmi_destroy_user(data->user); kfree(data->sensors); kfree(data); -- Gitee From edd32f08e63a8ffbf81c80e3c38f1a5901d80772 Mon Sep 17 00:00:00 2001 From: Alexey Simakov Date: Fri, 12 Dec 2025 00:43:43 +0800 Subject: [PATCH 0529/1449] hwmon: (tmp401) fix overflow caused by default conversion rate value ANBZ: #35228 commit 11dddaed697896d8c38767f0f39b556b543df5c0 stable. commit 82f2aab35a1ab2e1460de06ef04c726460aed51c upstream. The driver computes conversion intervals using the formula: interval = (1 << (7 - rate)) * 125ms where 'rate' is the sensor's conversion rate register value. According to the datasheet, the power-on reset value of this register is 0x8, which could be assigned to the register, after handling i2c general call. Using this default value causes a result greater than the bit width of left operand and an undefined behaviour in the calculation above, since shifting by values larger than the bit width is undefined behaviour as per C language standard. Limit the maximum usable 'rate' value to 7 to prevent undefined behaviour in calculations. Found by Linux Verification Center (linuxtesting.org) with Svace. Note (groeck): This does not matter in practice unless someone overwrites the chip configuration from outside the driver while the driver is loaded. The conversion time register is initialized with a value of 5 (500ms) when the driver is loaded, and the driver never writes a bad value. Fixes: ca53e7640de7 ("hwmon: (tmp401) Convert to _info API") Signed-off-by: Alexey Simakov Link: https://lore.kernel.org/r/20251211164342.6291-1-bigalex934@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/tmp401.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index 91f2314568cf..5cc932ef0460 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -408,7 +408,7 @@ static int tmp401_chip_read(struct device *dev, u32 attr, int channel, long *val ret = regmap_read(data->regmap, TMP401_CONVERSION_RATE, ®val); if (ret < 0) return ret; - *val = (1 << (7 - regval)) * 125; + *val = (1 << (7 - min(regval, 7))) * 125; break; case hwmon_chip_temp_reset_history: *val = 0; -- Gitee From cab7c1de4316a41f51e61484324f59b688e77411 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 4 Dec 2025 18:36:18 +0800 Subject: [PATCH 0530/1449] MIPS: Fix a reference leak bug in ip22_check_gio() ANBZ: #35228 commit fd8bb8fa7bc9f7de799a334bd4da4b2fb6cc0b81 stable. commit 680ad315caaa2860df411cb378bf3614d96c7648 upstream. If gio_device_register fails, gio_dev_put() is required to drop the gio_dev device reference. Fixes: e84de0c61905 ("MIPS: GIO bus support for SGI IP22/28") Signed-off-by: Haoxiang Li Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/mips/sgi-ip22/ip22-gio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c index 81c9f0a8880b..7026b464b02e 100644 --- a/arch/mips/sgi-ip22/ip22-gio.c +++ b/arch/mips/sgi-ip22/ip22-gio.c @@ -373,7 +373,8 @@ static void ip22_check_gio(int slotno, unsigned long addr, int irq) gio_dev->resource.flags = IORESOURCE_MEM; gio_dev->irq = irq; dev_set_name(&gio_dev->dev, "%d", slotno); - gio_device_register(gio_dev); + if (gio_device_register(gio_dev)) + gio_dev_put(gio_dev); } else printk(KERN_INFO "GIO: slot %d : Empty\n", slotno); } -- Gitee From ef819435a3ede1ef7008a7e98cfb96d6a1f747e5 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 1 Dec 2025 06:40:05 +0800 Subject: [PATCH 0531/1449] drm/panel: sony-td4353-jdi: Enable prepare_prev_first ANBZ: #35228 commit 86fcc629fdc0cda431d538b0997ba5ccfd64cafa stable. commit 2b973ca48ff3ef1952091c8f988d7796781836c8 upstream. The DSI host must be enabled before our prepare function can run, which has to send its init sequence over DSI. Without enabling the host first the panel will not probe. Fixes: 9e15123eca79 ("drm/msm/dsi: Stop unconditionally powering up DSI hosts at modeset") Signed-off-by: Marijn Suijten Reviewed-by: Douglas Anderson Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Martin Botka Signed-off-by: Douglas Anderson Link: https://patch.msgid.link/20251130-sony-akari-fix-panel-v1-1-1d27c60a55f5@somainline.org Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/panel/panel-sony-td4353-jdi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c index 1bde2f01786b..e7383a0e3d36 100644 --- a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c +++ b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c @@ -283,6 +283,8 @@ static int sony_td4353_jdi_probe(struct mipi_dsi_device *dsi) if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); + ctx->panel.prepare_prev_first = true; + drm_panel_add(&ctx->panel); ret = mipi_dsi_attach(dsi); -- Gitee From 7ab8702dd15ae5275424e89197e102cac1c3c644 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Fri, 14 Mar 2025 23:12:14 +0800 Subject: [PATCH 0532/1449] x86/xen: Move Xen upcall handler ANBZ: #35228 commit 79ee93cb007ef1cf0d41b00d860ebbd69f781455 stable. commit 1ab7b5ed44ba9bce581e225f40219b793bc779d6 upstream. Move the upcall handler to Xen-specific files. No functional changes. Signed-off-by: Brian Gerst Signed-off-by: Ingo Molnar Reviewed-by: Juergen Gross Reviewed-by: Sohil Mehta Cc: Andy Lutomirski Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Josh Poimboeuf Link: https://lore.kernel.org/r/20250314151220.862768-2-brgerst@gmail.com Stable-dep-of: e5aff444e3a7 ("x86/xen: Fix sparse warning in enlighten_pv.c") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/entry/common.c | 72 ------------------------------------- arch/x86/xen/enlighten_pv.c | 69 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 72 deletions(-) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index e72dac092245..3c88bdf96e7a 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -20,11 +20,6 @@ #include #include -#ifdef CONFIG_XEN_PV -#include -#include -#endif - #include #include #include @@ -346,70 +341,3 @@ SYSCALL_DEFINE0(ni_syscall) { return -ENOSYS; } - -#ifdef CONFIG_XEN_PV -#ifndef CONFIG_PREEMPTION -/* - * Some hypercalls issued by the toolstack can take many 10s of - * seconds. Allow tasks running hypercalls via the privcmd driver to - * be voluntarily preempted even if full kernel preemption is - * disabled. - * - * Such preemptible hypercalls are bracketed by - * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() - * calls. - */ -DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); -EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); - -/* - * In case of scheduling the flag must be cleared and restored after - * returning from schedule as the task might move to a different CPU. - */ -static __always_inline bool get_and_clear_inhcall(void) -{ - bool inhcall = __this_cpu_read(xen_in_preemptible_hcall); - - __this_cpu_write(xen_in_preemptible_hcall, false); - return inhcall; -} - -static __always_inline void restore_inhcall(bool inhcall) -{ - __this_cpu_write(xen_in_preemptible_hcall, inhcall); -} -#else -static __always_inline bool get_and_clear_inhcall(void) { return false; } -static __always_inline void restore_inhcall(bool inhcall) { } -#endif - -static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - - inc_irq_stat(irq_hv_callback_count); - - xen_evtchn_do_upcall(); - - set_irq_regs(old_regs); -} - -__visible noinstr void xen_pv_evtchn_do_upcall(struct pt_regs *regs) -{ - irqentry_state_t state = irqentry_enter(regs); - bool inhcall; - - instrumentation_begin(); - run_sysvec_on_irqstack_cond(__xen_pv_evtchn_do_upcall, regs); - - inhcall = get_and_clear_inhcall(); - if (inhcall && !WARN_ON_ONCE(state.exit_rcu)) { - irqentry_exit_cond_resched(); - instrumentation_end(); - restore_inhcall(inhcall); - } else { - instrumentation_end(); - irqentry_exit(regs, state); - } -} -#endif /* CONFIG_XEN_PV */ diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 4c7660504c47..35b7db11b0bc 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -72,6 +72,7 @@ #include #include #include +#include #ifdef CONFIG_X86_IOPL_IOPERM #include #endif @@ -97,6 +98,44 @@ void *xen_initial_gdt; static int xen_cpu_up_prepare_pv(unsigned int cpu); static int xen_cpu_dead_pv(unsigned int cpu); +#ifndef CONFIG_PREEMPTION +/* + * Some hypercalls issued by the toolstack can take many 10s of + * seconds. Allow tasks running hypercalls via the privcmd driver to + * be voluntarily preempted even if full kernel preemption is + * disabled. + * + * Such preemptible hypercalls are bracketed by + * xen_preemptible_hcall_begin() and xen_preemptible_hcall_end() + * calls. + */ +DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); +EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); + +/* + * In case of scheduling the flag must be cleared and restored after + * returning from schedule as the task might move to a different CPU. + */ +static __always_inline bool get_and_clear_inhcall(void) +{ + bool inhcall = __this_cpu_read(xen_in_preemptible_hcall); + + __this_cpu_write(xen_in_preemptible_hcall, false); + return inhcall; +} + +static __always_inline void restore_inhcall(bool inhcall) +{ + __this_cpu_write(xen_in_preemptible_hcall, inhcall); +} + +#else + +static __always_inline bool get_and_clear_inhcall(void) { return false; } +static __always_inline void restore_inhcall(bool inhcall) { } + +#endif + struct tls_descs { struct desc_struct desc[3]; }; @@ -690,6 +729,36 @@ DEFINE_IDTENTRY_RAW(xenpv_exc_machine_check) } #endif +static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + inc_irq_stat(irq_hv_callback_count); + + xen_evtchn_do_upcall(); + + set_irq_regs(old_regs); +} + +__visible noinstr void xen_pv_evtchn_do_upcall(struct pt_regs *regs) +{ + irqentry_state_t state = irqentry_enter(regs); + bool inhcall; + + instrumentation_begin(); + run_sysvec_on_irqstack_cond(__xen_pv_evtchn_do_upcall, regs); + + inhcall = get_and_clear_inhcall(); + if (inhcall && !WARN_ON_ONCE(state.exit_rcu)) { + irqentry_exit_cond_resched(); + instrumentation_end(); + restore_inhcall(inhcall); + } else { + instrumentation_end(); + irqentry_exit(regs, state); + } +} + struct trap_array_entry { void (*orig)(void); void (*xen)(void); -- Gitee From 0207be756dab6ff6a4742434816eef13644f4d89 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 15 Dec 2025 19:51:12 +0800 Subject: [PATCH 0533/1449] x86/xen: Fix sparse warning in enlighten_pv.c ANBZ: #35228 commit a0fee4e618f13bd109df4d77c7fc448095ef7a4f stable. commit e5aff444e3a7bdeef5ea796a2099fc3c60a070fa upstream. The sparse tool issues a warning for arch/x76/xen/enlighten_pv.c: arch/x86/xen/enlighten_pv.c:120:9: sparse: sparse: incorrect type in initializer (different address spaces) expected void const [noderef] __percpu *__vpp_verify got bool * This is due to the percpu variable xen_in_preemptible_hcall being exported via EXPORT_SYMBOL_GPL() instead of EXPORT_PER_CPU_SYMBOL_GPL(). Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202512140856.Ic6FetG6-lkp@intel.com/ Fixes: fdfd811ddde3 ("x86/xen: allow privcmd hypercalls to be preempted") Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross Message-ID: <20251215115112.15072-1-jgross@suse.com> Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/xen/enlighten_pv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 35b7db11b0bc..b703372796b1 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -110,7 +110,7 @@ static int xen_cpu_dead_pv(unsigned int cpu); * calls. */ DEFINE_PER_CPU(bool, xen_in_preemptible_hcall); -EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); +EXPORT_PER_CPU_SYMBOL_GPL(xen_in_preemptible_hcall); /* * In case of scheduling the flag must be cleared and restored after -- Gitee From 1a73c07a8232f2158fb494239c4ca89c97414fac Mon Sep 17 00:00:00 2001 From: Anurag Dutta Date: Fri, 12 Dec 2025 15:23:12 +0800 Subject: [PATCH 0534/1449] spi: cadence-quadspi: Fix clock disable on probe failure path ANBZ: #35228 commit d9479998c19a1321af4bc62ef4dd6f4cadb7950f stable. commit 1889dd2081975ce1f6275b06cdebaa8d154847a9 upstream. When cqspi_request_mmap_dma() returns -EPROBE_DEFER after runtime PM is enabled, the error path calls clk_disable_unprepare() on an already disabled clock, causing an imbalance. Use pm_runtime_get_sync() to increment the usage counter and resume the device. This prevents runtime_suspend() from being invoked and causing a double clock disable. Fixes: 140623410536 ("mtd: spi-nor: Add driver for Cadence Quad SPI Flash Controller") Signed-off-by: Anurag Dutta Tested-by: Nishanth Menon Link: https://patch.msgid.link/20251212072312.2711806-3-a-dutta@ti.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-cadence-quadspi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 4141babdf861..404d1f342892 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1888,7 +1888,9 @@ static int cqspi_probe(struct platform_device *pdev) probe_reset_failed: if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi); - clk_disable_unprepare(cqspi->clk); + + if (pm_runtime_get_sync(&pdev->dev) >= 0) + clk_disable_unprepare(cqspi->clk); probe_clk_failed: pm_runtime_put_sync(dev); probe_pm_failed: -- Gitee From 79df6e7ba411595c60644cf4267e08dc9aae6e8d Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 17 Dec 2025 17:36:48 +0800 Subject: [PATCH 0535/1449] block: rnbd-clt: Fix leaked ID in init_dev() ANBZ: #35228 commit 378a5d28859881e09704b5a3eeb04c3433a292e8 stable. commit c9b5645fd8ca10f310e41b07540f98e6a9720f40 upstream. If kstrdup() fails in init_dev(), then the newly allocated ID is lost. Fixes: 64e8a6ece1a5 ("block/rnbd-clt: Dynamically alloc buffer for pathname & blk_symlink_name") Signed-off-by: Thomas Fourier Acked-by: Jack Wang Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/rnbd/rnbd-clt.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index b0550b68645d..0c3c63cf986b 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -1440,9 +1440,11 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, goto out_alloc; } - ret = ida_alloc_max(&index_ida, (1 << (MINORBITS - RNBD_PART_BITS)) - 1, - GFP_KERNEL); - if (ret < 0) { + dev->clt_device_id = ida_alloc_max(&index_ida, + (1 << (MINORBITS - RNBD_PART_BITS)) - 1, + GFP_KERNEL); + if (dev->clt_device_id < 0) { + ret = dev->clt_device_id; pr_err("Failed to initialize device '%s' from session %s, allocating idr failed, err: %d\n", pathname, sess->sessname, ret); goto out_queues; @@ -1451,10 +1453,9 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, dev->pathname = kstrdup(pathname, GFP_KERNEL); if (!dev->pathname) { ret = -ENOMEM; - goto out_queues; + goto out_ida; } - dev->clt_device_id = ret; dev->sess = sess; dev->access_mode = access_mode; dev->nr_poll_queues = nr_poll_queues; @@ -1470,6 +1471,8 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, return dev; +out_ida: + ida_free(&index_ida, dev->clt_device_id); out_queues: kfree(dev->hw_queues); out_alloc: -- Gitee From a732fe49574c972175774f02ee84fe7b5989954c Mon Sep 17 00:00:00 2001 From: Qianchang Zhao Date: Sun, 9 Nov 2025 09:00:55 +0800 Subject: [PATCH 0536/1449] ksmbd: skip lock-range check on equal size to avoid size==0 underflow ANBZ: #35228 commit da29cd197246c85c0473259f1cad897d9d28faea stable. commit 5d510ac31626ed157d2182149559430350cf2104 upstream. When size equals the current i_size (including 0), the code used to call check_lock_range(filp, i_size, size - 1, WRITE), which computes `size - 1` and can underflow for size==0. Skip the equal case. Cc: stable@vger.kernel.org Reported-by: Qianchang Zhao Reported-by: Zhitong Liu Signed-off-by: Qianchang Zhao Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/vfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 067b346921b6..820352463a06 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -333,6 +333,9 @@ static int check_lock_range(struct file *filp, loff_t start, loff_t end, struct file_lock_context *ctx = locks_inode_context(file_inode(filp)); int error = 0; + if (start == end) + return 0; + if (!ctx || list_empty_careful(&ctx->flc_posix)) return 0; @@ -834,7 +837,7 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work, if (size < inode->i_size) { err = check_lock_range(filp, size, inode->i_size - 1, WRITE); - } else { + } else if (size > inode->i_size) { err = check_lock_range(filp, inode->i_size, size - 1, WRITE); } -- Gitee From 0517c239da6df7445cec4c9d59255f3d18f71f4a Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sun, 14 Dec 2025 14:05:56 +0800 Subject: [PATCH 0537/1449] ksmbd: Fix refcount leak when invalid session is found on session lookup ANBZ: #35228 commit e54fb2a4772545701766cba08aab20de5eace8cd stable. commit cafb57f7bdd57abba87725eb4e82bbdca4959644 upstream. When a session is found but its state is not SMB2_SESSION_VALID, It indicates that no valid session was found, but it is missing to decrement the reference count acquired by the session lookup, which results in a reference count leak. This patch fixes the issue by explicitly calling ksmbd_user_session_put to release the reference to the session. Cc: stable@vger.kernel.org Reported-by: Alexandre Reported-by: Stanislas Polu Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/mgmt/user_session.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 408f47220c07..0ca788009c93 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -312,8 +312,10 @@ struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn, sess = ksmbd_session_lookup(conn, id); if (!sess && conn->binding) sess = ksmbd_session_lookup_slowpath(id); - if (sess && sess->state != SMB2_SESSION_VALID) + if (sess && sess->state != SMB2_SESSION_VALID) { + ksmbd_user_session_put(sess); sess = NULL; + } return sess; } -- Gitee From cfd99dad8a9b511a2c8b75b36de9c04338d0a404 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sun, 14 Dec 2025 14:06:34 +0800 Subject: [PATCH 0538/1449] ksmbd: fix buffer validation by including null terminator size in EA length ANBZ: #35228 commit a28a375a5439eb474e9f284509a407efb479c925 stable. commit 95d7a890e4b03e198836d49d699408fd1867cb55 upstream. The smb2_set_ea function, which handles Extended Attributes (EA), was performing buffer validation checks that incorrectly omitted the size of the null terminating character (+1 byte) for EA Name. This patch fixes the issue by explicitly adding '+ 1' to EaNameLength where the null terminator is expected to be present in the buffer, ensuring the validation accurately reflects the total required buffer size. Cc: stable@vger.kernel.org Reported-by: Roger Reported-by: Stanislas Polu Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 958d6edd512c..5fc83ece1f80 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2356,7 +2356,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, int rc = 0; unsigned int next = 0; - if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + + if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + 1 + le16_to_cpu(eabuf->EaValueLength)) return -EINVAL; @@ -2433,7 +2433,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, break; } - if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + + if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength + 1 + le16_to_cpu(eabuf->EaValueLength)) { rc = -EINVAL; break; -- Gitee From 6c5beb48b5a4ac03f56113c6ce4503448e0ed15a Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 28 Oct 2025 04:37:42 +0800 Subject: [PATCH 0539/1449] HID: input: map HID_GD_Z to ABS_DISTANCE for stylus/pen ANBZ: #35228 commit 2bee957f61550b6919556e193863540328eec65d stable. commit 7953794f741e94d30df9dafaaa4c031c85b891d6 upstream. HID_GD_Z is mapped to ABS_Z for stylus and pen in hid-input.c. But HID_GD_Z should be used to report ABS_DISTANCE for stylus and pen as described at: Documentation/input/event-codes.rst#n226 * ABS_DISTANCE: - Used to describe the distance of a tool from an interaction surface. This event should only be emitted while the tool is hovering, meaning in close proximity of the device and while the value of the BTN_TOUCH code is 0. If the input device may be used freely in three dimensions, consider ABS_Z instead. - BTN_TOOL_ should be set to 1 when the tool comes into detectable proximity and set to 0 when the tool leaves detectable proximity. BTN_TOOL_ signals the type of tool that is currently detected by the hardware and is otherwise independent of ABS_DISTANCE and/or BTN_TOUCH. This patch makes the correct mapping. The ABS_DISTANCE is currently not mapped by any HID usage in hid-generic driver. Signed-off-by: Ping Cheng Cc: stable@kernel.org Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-input.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index fa3efe9701c9..c1708caa6b6c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -864,7 +864,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel switch (usage->hid) { /* These usage IDs map directly to the usage codes. */ - case HID_GD_X: case HID_GD_Y: case HID_GD_Z: + case HID_GD_X: case HID_GD_Y: case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: if (field->flags & HID_MAIN_ITEM_RELATIVE) map_rel(usage->hid & 0xf); @@ -872,6 +872,22 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel map_abs_clear(usage->hid & 0xf); break; + case HID_GD_Z: + /* HID_GD_Z is mapped to ABS_DISTANCE for stylus/pen */ + if (field->flags & HID_MAIN_ITEM_RELATIVE) { + map_rel(usage->hid & 0xf); + } else { + if (field->application == HID_DG_PEN || + field->physical == HID_DG_PEN || + field->logical == HID_DG_STYLUS || + field->physical == HID_DG_STYLUS || + field->application == HID_DG_DIGITIZER) + map_abs_clear(ABS_DISTANCE); + else + map_abs_clear(usage->hid & 0xf); + } + break; + case HID_GD_WHEEL: if (field->flags & HID_MAIN_ITEM_RELATIVE) { set_bit(REL_WHEEL, input->relbit); -- Gitee From a13a221e056a6335812cf49501a5aa939aada89c Mon Sep 17 00:00:00 2001 From: Junjie Cao Date: Fri, 19 Dec 2025 13:56:59 +0800 Subject: [PATCH 0540/1449] Input: ti_am335x_tsc - fix off-by-one error in wire_order validation ANBZ: #35228 commit bf95ec55805828c4f2b5241fb6b0c12388548570 stable. commit 248d3a73a0167dce15ba100477c3e778c4787178 upstream. The current validation 'wire_order[i] > ARRAY_SIZE(config_pins)' allows wire_order[i] to equal ARRAY_SIZE(config_pins), which causes out-of-bounds access when used as index in 'config_pins[wire_order[i]]'. Since config_pins has 4 elements (indices 0-3), the valid range for wire_order should be 0-3. Fix the off-by-one error by using >= instead of > in the validation check. Signed-off-by: Junjie Cao Link: https://patch.msgid.link/20251114062817.852698-1-junjie.cao@intel.com Fixes: bb76dc09ddfc ("input: ti_am33x_tsc: Order of TSC wires, made configurable") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/touchscreen/ti_am335x_tsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 9aa4e35fb4f5..4c1101f01117 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -85,7 +85,7 @@ static int titsc_config_wires(struct titsc *ts_dev) wire_order[i] = ts_dev->config_inp[i] & 0x0F; if (WARN_ON(analog_line[i] > 7)) return -EINVAL; - if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins))) + if (WARN_ON(wire_order[i] >= ARRAY_SIZE(config_pins))) return -EINVAL; } -- Gitee From bf1017dd36160aedc98138c33226e9bf66ae24b1 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 25 Nov 2025 04:31:34 +0800 Subject: [PATCH 0541/1449] Input: i8042 - add TUXEDO InfinityBook Max Gen10 AMD to i8042 quirk table ANBZ: #35228 commit 3f3c1c05c6ff840e03e06f38f936d9a803d23295 stable. commit aed3716db7fff74919cc5775ca3a80c8bb246489 upstream. The device occasionally wakes up from suspend with missing input on the internal keyboard and the following suspend attempt results in an instant wake-up. The quirks fix both issues for this device. Signed-off-by: Christoffer Sandberg Signed-off-by: Werner Sembach Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251124203336.64072-1-wse@tuxedocomputers.com Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/serio/i8042-acpipnpio.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h index 630cdd5a1328..b24127e923db 100644 --- a/drivers/input/serio/i8042-acpipnpio.h +++ b/drivers/input/serio/i8042-acpipnpio.h @@ -1169,6 +1169,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "X5KK45xS_X5SP45xS"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) + }, /* * A lot of modern Clevo barebones have touchpad and/or keyboard issues * after suspend fixable with the forcenorestore quirk. -- Gitee From 503d7e3759695237a1c64511a45ee63cc002fd86 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 2 Dec 2025 02:26:38 +0800 Subject: [PATCH 0542/1449] can: gs_usb: gs_can_open(): fix error handling ANBZ: #35228 commit 20dbeaed245935bec2536e3f67302c593cf1c266 stable. commit 3e54d3b4a8437b6783d4145c86962a2aa51022f3 upstream. Commit 2603be9e8167 ("can: gs_usb: gs_can_open(): improve error handling") added missing error handling to the gs_can_open() function. The driver uses 2 USB anchors to track the allocated URBs: the TX URBs in struct gs_can::tx_submitted for each netdev and the RX URBs in struct gs_usb::rx_submitted for the USB device. gs_can_open() allocates the RX URBs, while TX URBs are allocated during gs_can_start_xmit(). The cleanup in gs_can_open() kills all anchored dev->tx_submitted URBs (which is not necessary since the netdev is not yet registered), but misses the parent->rx_submitted URBs. Fix the problem by killing the rx_submitted instead of the tx_submitted. Fixes: 2603be9e8167 ("can: gs_usb: gs_can_open(): improve error handling") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251210-gs_usb-fix-error-handling-v1-1-d6a5a03f10bb@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 72997312c956..a65526a71ce4 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -1071,7 +1071,7 @@ static int gs_can_open(struct net_device *netdev) usb_free_urb(urb); out_usb_kill_anchored_urbs: if (!parent->active_channels) { - usb_kill_anchored_urbs(&dev->tx_submitted); + usb_kill_anchored_urbs(&parent->rx_submitted); if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) gs_usb_timestamp_stop(parent); -- Gitee From 2b6bb877857aa668df6a65c54ba9e7cb3017a155 Mon Sep 17 00:00:00 2001 From: Pengjie Zhang Date: Wed, 10 Dec 2025 21:26:34 +0800 Subject: [PATCH 0543/1449] ACPI: PCC: Fix race condition by removing static qualifier ANBZ: #35228 commit ef0f9059a64786b9670c5169a15b44be8defa7ae stable. commit f103fa127c93016bcd89b05d8e11dc1a84f6990d upstream. Local variable 'ret' in acpi_pcc_address_space_setup() is currently declared as 'static'. This can lead to race conditions in a multithreaded environment. Remove the 'static' qualifier to ensure that 'ret' will be allocated directly on the stack as a local variable. Fixes: a10b1c99e2dc ("ACPI: PCC: Setup PCC Opregion handler only if platform interrupt is available") Signed-off-by: Pengjie Zhang Reviewed-by: Sudeep Holla Acked-by: lihuisong@huawei.com Cc: 6.2+ # 6.2+ [ rjw: Changelog edits ] Link: https://patch.msgid.link/20251210132634.2050033-1-zhangpengjie2@huawei.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/acpi_pcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c index 07a034a53aca..59d2308259cb 100644 --- a/drivers/acpi/acpi_pcc.c +++ b/drivers/acpi/acpi_pcc.c @@ -53,7 +53,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function, struct pcc_data *data; struct acpi_pcc_info *ctx = handler_context; struct pcc_mbox_chan *pcc_chan; - static acpi_status ret; + acpi_status ret; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) -- Gitee From b0f96751ed9665b12ca91fc36fee8e135456b991 Mon Sep 17 00:00:00 2001 From: Pengjie Zhang Date: Wed, 10 Dec 2025 21:22:27 +0800 Subject: [PATCH 0544/1449] ACPI: CPPC: Fix missing PCC check for guaranteed_perf ANBZ: #35228 commit a287987af35425787f1843eba24638b71aea2b49 stable. commit 6ea3a44cef28add2d93b1ef119d84886cb1e3c9b upstream. The current implementation overlooks the 'guaranteed_perf' register in this check. If the Guaranteed Performance register is located in the PCC subspace, the function currently attempts to read it without acquiring the lock and without sending the CMD_READ doorbell to the firmware. This can result in reading stale data. Fixes: 29523f095397 ("ACPI / CPPC: Add support for guaranteed performance") Signed-off-by: Pengjie Zhang Cc: 4.20+ # 4.20+ [ rjw: Subject and changelog edits ] Link: https://patch.msgid.link/20251210132227.1988380-1-zhangpengjie2@huawei.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/acpi/cppc_acpi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 3fa1c86c6b2d..f2434966a65e 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1375,7 +1375,8 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) /* Are any of the regs PCC ?*/ if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg) || - CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg)) { + CPC_IN_PCC(low_freq_reg) || CPC_IN_PCC(nom_freq_reg) || + CPC_IN_PCC(guaranteed_reg)) { if (pcc_ss_id < 0) { pr_debug("Invalid pcc_ss_id\n"); return -ENODEV; -- Gitee From 9e86a3f325c4fb7374c715d53fda5e72d3a96eac Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 20 Nov 2025 16:34:49 +0800 Subject: [PATCH 0545/1449] spi: fsl-cpm: Check length parity before switching to 16 bit mode ANBZ: #35228 commit 3dd6d01384823e1bd8602873153d6fc4337ac4fe stable. commit 1417927df8049a0194933861e9b098669a95c762 upstream. Commit fc96ec826bce ("spi: fsl-cpm: Use 16 bit mode for large transfers with even size") failed to make sure that the size is really even before switching to 16 bit mode. Until recently the problem went unnoticed because kernfs uses a pre-allocated bounce buffer of size PAGE_SIZE for reading EEPROM. But commit 8ad6249c51d0 ("eeprom: at25: convert to spi-mem API") introduced an additional dynamically allocated bounce buffer whose size is exactly the size of the transfer, leading to a buffer overrun in the fsl-cpm driver when that size is odd. Add the missing length parity verification and remain in 8 bit mode when the length is not even. Fixes: fc96ec826bce ("spi: fsl-cpm: Use 16 bit mode for large transfers with even size") Cc: stable@vger.kernel.org Closes: https://lore.kernel.org/all/638496dd-ec60-4e53-bad7-eb657f67d580@csgroup.eu/ Signed-off-by: Christophe Leroy Reviewed-by: Sverdlin Alexander Link: https://patch.msgid.link/3c4d81c3923c93f95ec56702a454744a4bad3cfc.1763627618.git.christophe.leroy@csgroup.eu Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-fsl-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 97faf984801f..750e2cd2594d 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -336,7 +336,7 @@ static int fsl_spi_prepare_message(struct spi_controller *ctlr, if (t->bits_per_word == 16 || t->bits_per_word == 32) t->bits_per_word = 8; /* pretend its 8 bits */ if (t->bits_per_word == 8 && t->len >= 256 && - (mpc8xxx_spi->flags & SPI_CPM1)) + !(t->len & 1) && (mpc8xxx_spi->flags & SPI_CPM1)) t->bits_per_word = 16; } } -- Gitee From 1f7d5b501b2a4066f781e72522a0dc8983a20262 Mon Sep 17 00:00:00 2001 From: Jared Kangas Date: Fri, 12 Dec 2025 23:03:17 +0800 Subject: [PATCH 0546/1449] mmc: sdhci-esdhc-imx: add alternate ARCH_S32 dependency to Kconfig ANBZ: #35228 commit d9bd2d0985b22a901ecb5c630adffd762f887b50 stable. commit d3ecb12e2e04ce53c95f933c462f2d8b150b965b upstream. MMC_SDHCI_ESDHC_IMX requires ARCH_MXC despite also being used on ARCH_S32, which results in unmet dependencies when compiling strictly for ARCH_S32. Resolve this by adding ARCH_S32 as an alternative to ARCH_MXC in the driver's dependencies. Fixes: 5c4f00627c9a ("mmc: sdhci-esdhc-imx: add NXP S32G2 support") Cc: stable@bvger.kernel.org Signed-off-by: Jared Kangas Reviewed-by: Haibo Chen Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mmc/host/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 52a75f861d62..da89a4d89926 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -279,14 +279,14 @@ config MMC_SDHCI_ESDHC_MCF config MMC_SDHCI_ESDHC_IMX tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller" - depends on ARCH_MXC || COMPILE_TEST + depends on ARCH_MXC || ARCH_S32 || COMPILE_TEST depends on MMC_SDHCI_PLTFM depends on OF select MMC_SDHCI_IO_ACCESSORS select MMC_CQHCI help This selects the Freescale eSDHC/uSDHC controller support - found on i.MX25, i.MX35 i.MX5x and i.MX6x. + found on i.MX25, i.MX35, i.MX5x, i.MX6x, and S32G. If you have a controller with this interface, say Y or M here. -- Gitee From 1fd11a217894c9cbd5d646dc2697adf1051c8a74 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Thu, 11 Dec 2025 16:45:48 +0800 Subject: [PATCH 0547/1449] dt-bindings: mmc: sdhci-of-aspeed: Switch ref to sdhci-common.yaml ANBZ: #35228 commit 97575fb2b714f5262617f6d0ac419e7aac9ad30f stable. commit ed724ea1b82a800af4704311cb89e5ef1b4ea7ac upstream. Enable use of common SDHCI-related properties such as sdhci-caps-mask as found in the AST2600 EVB DTS. Cc: stable@vger.kernel.org # v6.2+ Signed-off-by: Andrew Jeffery Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml index 9fce8cd7b0b6..d24950ccea95 100644 --- a/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/aspeed,sdhci.yaml @@ -41,7 +41,7 @@ properties: patternProperties: "^sdhci@[0-9a-f]+$": type: object - $ref: mmc-controller.yaml + $ref: sdhci-common.yaml unevaluatedProperties: false properties: -- Gitee From ba232d0881b9fcc01cc7e0a61414201153387aaa Mon Sep 17 00:00:00 2001 From: Shaurya Rane Date: Sat, 29 Nov 2025 17:37:18 +0800 Subject: [PATCH 0548/1449] net/hsr: fix NULL pointer dereference in prp_get_untagged_frame() ANBZ: #35228 commit 8f289fa12926aae44347ca7d490e216555d8f255 stable. commit 188e0fa5a679570ea35474575e724d8211423d17 upstream. prp_get_untagged_frame() calls __pskb_copy() to create frame->skb_std but doesn't check if the allocation failed. If __pskb_copy() returns NULL, skb_clone() is called with a NULL pointer, causing a crash: Oops: general protection fault, probably for non-canonical address 0xdffffc000000000f: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000078-0x000000000000007f] CPU: 0 UID: 0 PID: 5625 Comm: syz.1.18 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:skb_clone+0xd7/0x3a0 net/core/skbuff.c:2041 Code: 03 42 80 3c 20 00 74 08 4c 89 f7 e8 23 29 05 f9 49 83 3e 00 0f 85 a0 01 00 00 e8 94 dd 9d f8 48 8d 6b 7e 49 89 ee 49 c1 ee 03 <43> 0f b6 04 26 84 c0 0f 85 d1 01 00 00 44 0f b6 7d 00 41 83 e7 0c RSP: 0018:ffffc9000d00f200 EFLAGS: 00010207 RAX: ffffffff892235a1 RBX: 0000000000000000 RCX: ffff88803372a480 RDX: 0000000000000000 RSI: 0000000000000820 RDI: 0000000000000000 RBP: 000000000000007e R08: ffffffff8f7d0f77 R09: 1ffffffff1efa1ee R10: dffffc0000000000 R11: fffffbfff1efa1ef R12: dffffc0000000000 R13: 0000000000000820 R14: 000000000000000f R15: ffff88805144cc00 FS: 0000555557f6d500(0000) GS:ffff88808d72f000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000555581d35808 CR3: 000000005040e000 CR4: 0000000000352ef0 Call Trace: hsr_forward_do net/hsr/hsr_forward.c:-1 [inline] hsr_forward_skb+0x1013/0x2860 net/hsr/hsr_forward.c:741 hsr_handle_frame+0x6ce/0xa70 net/hsr/hsr_slave.c:84 __netif_receive_skb_core+0x10b9/0x4380 net/core/dev.c:5966 __netif_receive_skb_one_core net/core/dev.c:6077 [inline] __netif_receive_skb+0x72/0x380 net/core/dev.c:6192 netif_receive_skb_internal net/core/dev.c:6278 [inline] netif_receive_skb+0x1cb/0x790 net/core/dev.c:6337 tun_rx_batched+0x1b9/0x730 drivers/net/tun.c:1485 tun_get_user+0x2b65/0x3e90 drivers/net/tun.c:1953 tun_chr_write_iter+0x113/0x200 drivers/net/tun.c:1999 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x5c9/0xb30 fs/read_write.c:686 ksys_write+0x145/0x250 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f0449f8e1ff Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 f9 92 02 00 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 4c 93 02 00 48 RSP: 002b:00007ffd7ad94c90 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007f044a1e5fa0 RCX: 00007f0449f8e1ff RDX: 000000000000003e RSI: 0000200000000500 RDI: 00000000000000c8 RBP: 00007ffd7ad94d20 R08: 0000000000000000 R09: 0000000000000000 R10: 000000000000003e R11: 0000000000000293 R12: 0000000000000001 R13: 00007f044a1e5fa0 R14: 00007f044a1e5fa0 R15: 0000000000000003 Add a NULL check immediately after __pskb_copy() to handle allocation failures gracefully. Reported-by: syzbot+2fa344348a579b779e05@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=2fa344348a579b779e05 Fixes: f266a683a480 ("net/hsr: Better frame dispatch") Cc: stable@vger.kernel.org Signed-off-by: Shaurya Rane Reviewed-by: Felix Maurer Tested-by: Felix Maurer Link: https://patch.msgid.link/20251129093718.25320-1-ssrane_b23@ee.vjti.ac.in Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/hsr/hsr_forward.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 9317f96127c1..3852fd99509f 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -176,6 +176,8 @@ struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame, __pskb_copy(frame->skb_prp, skb_headroom(frame->skb_prp), GFP_ATOMIC); + if (!frame->skb_std) + return NULL; } else { /* Unexpected */ WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", -- Gitee From 22e2c929ed07c5b559cf83882fbdc69cb4bd19ea Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 15 Dec 2025 12:26:52 +0800 Subject: [PATCH 0549/1449] ALSA: vxpocket: Fix resource leak in vxpocket_probe error path ANBZ: #35228 commit 930acded6bbf71b561c6d05e2270d82b9173df42 stable. commit 2a03b40deacbd293ac9aed0f9b11197dad54fe5f upstream. When vxpocket_config() fails, vxpocket_probe() returns the error code directly without freeing the sound card resources allocated by snd_card_new(), which leads to a memory leak. Add proper error handling to free the sound card and clear the allocation bit when vxpocket_config() fails. Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251215042652.695-1-vulab@iscas.ac.cn Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pcmcia/vx/vxpocket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 7a0f0e73ceb2..867a477d53ae 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -295,7 +295,13 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) vxp->p_dev = p_dev; - return vxpocket_config(p_dev); + err = vxpocket_config(p_dev); + if (err < 0) { + card_alloc &= ~(1 << i); + snd_card_free(card); + return err; + } + return 0; } static void vxpocket_detach(struct pcmcia_device *link) -- Gitee From 5e791ab7becc981419a6abd30faa4e4b630b7e86 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 15 Dec 2025 17:04:33 +0800 Subject: [PATCH 0550/1449] ALSA: pcmcia: Fix resource leak in snd_pdacf_probe error path ANBZ: #35228 commit ba2d15635e591beed74f245bc78eaa877306fdd4 stable. commit 5032347c04ba7ff9ba878f262e075d745c06a2a8 upstream. When pdacf_config() fails, snd_pdacf_probe() returns the error code directly without freeing the sound card resources allocated by snd_card_new(), which leads to a memory leak. Add proper error handling to free the sound card and clear the card list entry when pdacf_config() fails. Fixes: 15b99ac17295 ("[PATCH] pcmcia: add return value to _config() functions") Suggested-by: Takashi Iwai Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251215090433.211-1-vulab@iscas.ac.cn Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pcmcia/pdaudiocf/pdaudiocf.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 8363ec08df5d..4468d81683ec 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -132,7 +132,13 @@ static int snd_pdacf_probe(struct pcmcia_device *link) link->config_index = 1; link->config_regs = PRESENT_OPTION; - return pdacf_config(link); + err = pdacf_config(link); + if (err < 0) { + card_list[i] = NULL; + snd_card_free(card); + return err; + } + return 0; } -- Gitee From 5c085ea36538a90932f500b01a2ded917eb241af Mon Sep 17 00:00:00 2001 From: Shipei Qu Date: Wed, 17 Dec 2025 10:46:30 +0800 Subject: [PATCH 0551/1449] ALSA: usb-mixer: us16x08: validate meter packet indices ANBZ: #35228 commit 2f21a7cbaaa93926f5be15bc095b9c57c35748d9 stable. commit 5526c1c6ba1d0913c7dfcbbd6fe1744ea7c55f1e upstream. get_meter_levels_from_urb() parses the 64-byte meter packets sent by the device and fills the per-channel arrays meter_level[], comp_level[] and master_level[] in struct snd_us16x08_meter_store. Currently the function derives the channel index directly from the meter packet (MUB2(meter_urb, s) - 1) and uses it to index those arrays without validating the range. If the packet contains a negative or out-of-range channel number, the driver may write past the end of these arrays. Introduce a local channel variable and validate it before updating the arrays. We reject negative indices, limit meter_level[] and comp_level[] to SND_US16X08_MAX_CHANNELS, and guard master_level[] updates with ARRAY_SIZE(master_level). Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk") Reported-by: DARKNAVY (@DarkNavyOrg) Closes: https://lore.kernel.org/tencent_21C112743C44C1A2517FF219@qq.com Signed-off-by: Shipei Qu Link: https://patch.msgid.link/20251217024630.59576-1-qu@darknavy.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/mixer_us16x08.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c index 20ac32635f1f..d05cb54de788 100644 --- a/sound/usb/mixer_us16x08.c +++ b/sound/usb/mixer_us16x08.c @@ -656,17 +656,25 @@ static void get_meter_levels_from_urb(int s, u8 *meter_urb) { int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8); + int ch = MUB2(meter_urb, s) - 1; + + if (ch < 0) + return; if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 && MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) { - if (MUC0(meter_urb, s) == 0x72) - store->meter_level[MUB2(meter_urb, s) - 1] = val; - if (MUC0(meter_urb, s) == 0xb2) - store->comp_level[MUB2(meter_urb, s) - 1] = val; + if (ch < SND_US16X08_MAX_CHANNELS) { + if (MUC0(meter_urb, s) == 0x72) + store->meter_level[ch] = val; + if (MUC0(meter_urb, s) == 0xb2) + store->comp_level[ch] = val; + } } if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 && - MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62) - store->master_level[MUB2(meter_urb, s) - 1] = val; + MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62) { + if (ch < ARRAY_SIZE(store->master_level)) + store->master_level[ch] = val; + } } /* Function to retrieve current meter values from the device. -- Gitee From a5787553eaf95e17a9c2866a3b995e290d1da106 Mon Sep 17 00:00:00 2001 From: Jinhui Guo Date: Tue, 30 Sep 2025 15:42:37 +0800 Subject: [PATCH 0552/1449] ipmi: Fix the race between __scan_channels() and deliver_response() ANBZ: #35228 commit 42985fb28312dc6595daf9558ba1b43448b557ff stable. commit 936750fdba4c45e13bbd17f261bb140dd55f5e93 upstream. The race window between __scan_channels() and deliver_response() causes the parameters of some channels to be set to 0. 1.[CPUA] __scan_channels() issues an IPMI request and waits with wait_event() until all channels have been scanned. wait_event() internally calls might_sleep(), which might yield the CPU. (Moreover, an interrupt can preempt wait_event() and force the task to yield the CPU.) 2.[CPUB] deliver_response() is invoked when the CPU receives the IPMI response. After processing a IPMI response, deliver_response() directly assigns intf->wchannels to intf->channel_list and sets intf->channels_ready to true. However, not all channels are actually ready for use. 3.[CPUA] Since intf->channels_ready is already true, wait_event() never enters __wait_event(). __scan_channels() immediately clears intf->null_user_handler and exits. 4.[CPUB] Once intf->null_user_handler is set to NULL, deliver_response() ignores further IPMI responses, leaving the remaining channels zero-initialized and unusable. CPUA CPUB ------------------------------- ----------------------------- __scan_channels() intf->null_user_handler = channel_handler; send_channel_info_cmd(intf, 0); wait_event(intf->waitq, intf->channels_ready); do { might_sleep(); deliver_response() channel_handler() intf->channel_list = intf->wchannels + set; intf->channels_ready = true; send_channel_info_cmd(intf, intf->curr_channel); if (condition) break; __wait_event(wq_head, condition); } while(0) intf->null_user_handler = NULL; deliver_response() if (!msg->user) if (intf->null_user_handler) rv = -EINVAL; return rv; ------------------------------- ----------------------------- Fix the race between __scan_channels() and deliver_response() by deferring both the assignment intf->channel_list = intf->wchannels and the flag intf->channels_ready = true until all channels have been successfully scanned or until the IPMI request has failed. Signed-off-by: Jinhui Guo Message-ID: <20250930074239.2353-2-guojinhui.liam@bytedance.com> Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/char/ipmi/ipmi_msghandler.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index b7d8bf202ed2..4619ee5c744c 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -3414,8 +3414,6 @@ channel_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) intf->channels_ready = true; wake_up(&intf->waitq); } else { - intf->channel_list = intf->wchannels + set; - intf->channels_ready = true; rv = send_channel_info_cmd(intf, intf->curr_channel); } -- Gitee From e494a4f77405abe5301fa7867b812d9ac2ac1e20 Mon Sep 17 00:00:00 2001 From: Jinhui Guo Date: Tue, 30 Sep 2025 15:42:38 +0800 Subject: [PATCH 0553/1449] ipmi: Fix __scan_channels() failing to rescan channels ANBZ: #35228 commit aafed85dbff7d35c3d70d451fad02e4699eae2ee stable. commit 6bd30d8fc523fb880b4be548e8501bc0fe8f42d4 upstream. channel_handler() sets intf->channels_ready to true but never clears it, so __scan_channels() skips any rescan. When the BMC firmware changes a rescan is required. Allow it by clearing the flag before starting a new scan. Signed-off-by: Jinhui Guo Message-ID: <20250930074239.2353-3-guojinhui.liam@bytedance.com> Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/char/ipmi/ipmi_msghandler.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4619ee5c744c..fc5f9d757b94 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -613,7 +613,8 @@ static void __ipmi_bmc_unregister(struct ipmi_smi *intf); static int __ipmi_bmc_register(struct ipmi_smi *intf, struct ipmi_device_id *id, bool guid_set, guid_t *guid, int intf_num); -static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id); +static int __scan_channels(struct ipmi_smi *intf, + struct ipmi_device_id *id, bool rescan); /* @@ -2665,7 +2666,7 @@ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, if (__ipmi_bmc_register(intf, &id, guid_set, &guid, intf_num)) need_waiter(intf); /* Retry later on an error. */ else - __scan_channels(intf, &id); + __scan_channels(intf, &id, false); if (!intf_set) { @@ -2685,7 +2686,7 @@ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, goto out_noprocessing; } else if (memcmp(&bmc->fetch_id, &bmc->id, sizeof(bmc->id))) /* Version info changes, scan the channels again. */ - __scan_channels(intf, &bmc->fetch_id); + __scan_channels(intf, &bmc->fetch_id, true); bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY; @@ -3435,10 +3436,17 @@ channel_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg) /* * Must be holding intf->bmc_reg_mutex to call this. */ -static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id) +static int __scan_channels(struct ipmi_smi *intf, + struct ipmi_device_id *id, + bool rescan) { int rv; + if (rescan) { + /* Clear channels_ready to force channels rescan. */ + intf->channels_ready = false; + } + if (ipmi_version_major(id) > 1 || (ipmi_version_major(id) == 1 && ipmi_version_minor(id) >= 5)) { @@ -3641,7 +3649,7 @@ int ipmi_add_smi(struct module *owner, } mutex_lock(&intf->bmc_reg_mutex); - rv = __scan_channels(intf, &id); + rv = __scan_channels(intf, &id, false); mutex_unlock(&intf->bmc_reg_mutex); if (rv) goto out_err_bmc_reg; -- Gitee From ba4fe5642a2c84c0a9035d361638b929ea991ddf Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:26 +0800 Subject: [PATCH 0554/1449] firmware: imx: scu-irq: Init workqueue before request mbox channel ANBZ: #35228 commit a6f1ced333a639d570602f637cde463d1923d384 stable. commit 81fb53feb66a3aefbf6fcab73bb8d06f5b0c54ad upstream. With mailbox channel requested, there is possibility that interrupts may come in, so need to make sure the workqueue is initialized before the queue is scheduled by mailbox rx callback. Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/imx/imx-scu-irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index f2b902e95b73..b9f6128d56f7 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -214,6 +214,8 @@ int imx_scu_enable_general_irq_channel(struct device *dev) cl->dev = dev; cl->rx_callback = imx_scu_irq_callback; + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + /* SCU general IRQ uses general interrupt channel 3 */ ch = mbox_request_channel_byname(cl, "gip3"); if (IS_ERR(ch)) { @@ -223,8 +225,6 @@ int imx_scu_enable_general_irq_channel(struct device *dev) return ret; } - INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); - if (!of_parse_phandle_with_args(dev->of_node, "mboxes", "#mbox-cells", 0, &spec)) { i = of_alias_get_id(spec.np, "mu"); -- Gitee From 7263269f480fb924f8336d651de7f635db6d9a4c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 25 Aug 2025 21:11:13 +0800 Subject: [PATCH 0555/1449] ti-sysc: allow OMAP2 and OMAP4 timers to be reserved on AM33xx ANBZ: #35228 commit cad4dfddaf6939072b8a38e92afbfe176063e45e stable. commit 3f61783920504b2cf99330b372d82914bb004d8e upstream. am33xx.dtsi has the same clock setup as am35xx.dtsi, setting ti,no-reset-on-init and ti,no-idle on timer1_target and timer2_target, so AM33 needs the same workaround as AM35 to avoid ti-sysc probe failing on certain target modules. Signed-off-by: Matthias Schiffer Signed-off-by: Alexander Stein Link: https://lore.kernel.org/r/20250825131114.2206804-1-alexander.stein@ew.tq-group.com Signed-off-by: Kevin Hilman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bus/ti-sysc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 46d7410f6f0f..b6a7d0d3f153 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -37,6 +37,7 @@ enum sysc_soc { SOC_UNKNOWN, SOC_2420, SOC_2430, + SOC_AM33, SOC_3430, SOC_AM35, SOC_3630, @@ -2996,6 +2997,7 @@ static void ti_sysc_idle(struct work_struct *work) static const struct soc_device_attribute sysc_soc_match[] = { SOC_FLAG("OMAP242*", SOC_2420), SOC_FLAG("OMAP243*", SOC_2430), + SOC_FLAG("AM33*", SOC_AM33), SOC_FLAG("AM35*", SOC_AM35), SOC_FLAG("OMAP3[45]*", SOC_3430), SOC_FLAG("OMAP3[67]*", SOC_3630), @@ -3201,10 +3203,15 @@ static int sysc_check_active_timer(struct sysc *ddata) * can be dropped if we stop supporting old beagleboard revisions * A to B4 at some point. */ - if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) + switch (sysc_soc->soc) { + case SOC_AM33: + case SOC_3430: + case SOC_AM35: error = -ENXIO; - else + break; + default: error = -EBUSY; + } if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) -- Gitee From 2c271fef0c89698d155878f2d64c2710d4c85470 Mon Sep 17 00:00:00 2001 From: Josua Mayer Date: Thu, 30 Oct 2025 23:16:26 +0800 Subject: [PATCH 0556/1449] clk: mvebu: cp110 add CLK_IGNORE_UNUSED to pcie_x10, pcie_x11 & pcie_x4 ANBZ: #35228 commit 71f543a5617795409aa9b598b85f7f4fda149d3c stable. commit f0e6bc0c3ef4b4afb299bd6912586cafd5d864e9 upstream. CP110 based platforms rely on the bootloader for pci port initialization. TF-A actively prevents non-uboot re-configuration of pci lanes, and many boards do not have software control over the pci card reset. If a pci port had link at boot-time and the clock is stopped at a later point, the link fails and can not be recovered. PCI controller driver probe - and by extension ownership of a driver for the pci clocks - may be delayed especially on large modular kernels, causing the clock core to start disabling unused clocks. Add the CLK_IGNORE_UNUSED flag to the three pci port's clocks to ensure they are not stopped before the pci controller driver has taken ownership and tested for an existing link. This fixes failed pci link detection when controller driver probes late, e.g. with arm64 defconfig and CONFIG_PHY_MVEBU_CP110_COMPHY=m. Closes: https://lore.kernel.org/r/b71596c7-461b-44b6-89ab-3cfbd492639f@solid-run.com Signed-off-by: Josua Mayer Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/mvebu/cp110-system-controller.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 03c59bf22106..b47c86906046 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -110,6 +110,25 @@ static const char * const gate_base_names[] = { [CP110_GATE_EIP197] = "eip197" }; +static unsigned long gate_flags(const u8 bit_idx) +{ + switch (bit_idx) { + case CP110_GATE_PCIE_X1_0: + case CP110_GATE_PCIE_X1_1: + case CP110_GATE_PCIE_X4: + /* + * If a port had an active link at boot time, stopping + * the clock creates a failed state from which controller + * driver can not recover. + * Prevent stopping this clock till after a driver has taken + * ownership. + */ + return CLK_IGNORE_UNUSED; + default: + return 0; + } +}; + struct cp110_gate_clk { struct clk_hw hw; struct regmap *regmap; @@ -171,6 +190,7 @@ static struct clk_hw *cp110_register_gate(const char *name, init.ops = &cp110_gate_ops; init.parent_names = &parent_name; init.num_parents = 1; + init.flags = gate_flags(bit_idx); gate->regmap = regmap; gate->bit_idx = bit_idx; -- Gitee From b01bdafb2470dd4e47b2aa8ccf169d8bb46d979d Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Tue, 22 Apr 2025 10:31:13 +0800 Subject: [PATCH 0557/1449] powerpc/addnote: Fix overflow on 32-bit builds ANBZ: #35228 commit b5020721e95364b954732852fe7bd5cfd8ee8bc8 stable. commit 825ce89a3ef17f84cf2c0eacfa6b8dc9fd11d13f upstream. The PUT_64[LB]E() macros need to cast the value to unsigned long long like the GET_64[LB]E() macros. Caused lots of warnings when compiled on 32-bit, and clobbered addresses (36-bit P4080). Signed-off-by: Ben Collins Reviewed-by: Christophe Leroy Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/2025042122-mustard-wrasse-694572@boujee-and-buff Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/boot/addnote.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index 53b3b2621457..78704927453a 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c @@ -68,8 +68,8 @@ static int e_class = ELFCLASS32; #define PUT_16BE(off, v)(buf[off] = ((v) >> 8) & 0xff, \ buf[(off) + 1] = (v) & 0xff) #define PUT_32BE(off, v)(PUT_16BE((off), (v) >> 16L), PUT_16BE((off) + 2, (v))) -#define PUT_64BE(off, v)((PUT_32BE((off), (v) >> 32L), \ - PUT_32BE((off) + 4, (v)))) +#define PUT_64BE(off, v)((PUT_32BE((off), (unsigned long long)(v) >> 32L), \ + PUT_32BE((off) + 4, (unsigned long long)(v)))) #define GET_16LE(off) ((buf[off]) + (buf[(off)+1] << 8)) #define GET_32LE(off) (GET_16LE(off) + (GET_16LE((off)+2U) << 16U)) @@ -78,7 +78,8 @@ static int e_class = ELFCLASS32; #define PUT_16LE(off, v) (buf[off] = (v) & 0xff, \ buf[(off) + 1] = ((v) >> 8) & 0xff) #define PUT_32LE(off, v) (PUT_16LE((off), (v)), PUT_16LE((off) + 2, (v) >> 16L)) -#define PUT_64LE(off, v) (PUT_32LE((off), (v)), PUT_32LE((off) + 4, (v) >> 32L)) +#define PUT_64LE(off, v) (PUT_32LE((off), (unsigned long long)(v)), \ + PUT_32LE((off) + 4, (unsigned long long)(v) >> 32L)) #define GET_16(off) (e_data == ELFDATA2MSB ? GET_16BE(off) : GET_16LE(off)) #define GET_32(off) (e_data == ELFDATA2MSB ? GET_32BE(off) : GET_32LE(off)) -- Gitee From 53474df82626f7c41eada6f8416b586d9cc23c8b Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Mon, 10 Nov 2025 23:50:05 +0800 Subject: [PATCH 0558/1449] scsi: qla2xxx: Fix lost interrupts with qlini_mode=disabled ANBZ: #35228 commit 61c4097803678eaeb88e0a7a5942267183c4bbdc stable. commit 4f6aaade2a22ac428fa99ed716cf2b87e79c9837 upstream. When qla2xxx is loaded with qlini_mode=disabled, ha->flags.disable_msix_handshake is used before it is set, resulting in the wrong interrupt handler being used on certain HBAs (qla2xxx_msix_rsp_q_hs() is used when qla2xxx_msix_rsp_q() should be used). The only difference between these two interrupt handlers is that the _hs() version writes to a register to clear the "RISC" interrupt, whereas the other version does not. So this bug results in the RISC interrupt being cleared when it should not be. This occasionally causes a different interrupt handler qla24xx_msix_default() for a different vector to see ((stat & HSRX_RISC_INT) == 0) and ignore its interrupt, which then causes problems like: qla2xxx [0000:02:00.0]-d04c:6: MBX Command timeout for cmd 20, iocontrol=8 jiffies=1090c0300 mb[0-3]=[0x4000 0x0 0x40 0xda] mb7 0x500 host_status 0x40000010 hccr 0x3f00 qla2xxx [0000:02:00.0]-101e:6: Mailbox cmd timeout occurred, cmd=0x20, mb[0]=0x20. Scheduling ISP abort (the cmd varies; sometimes it is 0x20, 0x22, 0x54, 0x5a, 0x5d, or 0x6a) This problem can be reproduced with a 16 or 32 Gbps HBA by loading qla2xxx with qlini_mode=disabled and running a high IOPS test while triggering frequent RSCN database change events. While analyzing the problem I discovered that even with disable_msix_handshake forced to 0, it is not necessary to clear the RISC interrupt from qla2xxx_msix_rsp_q_hs() (more below). So just completely remove qla2xxx_msix_rsp_q_hs() and the logic for selecting it, which also fixes the bug with qlini_mode=disabled. The test below describes the justification for not needing qla2xxx_msix_rsp_q_hs(): Force disable_msix_handshake to 0: qla24xx_config_rings(): if (0 && (ha->fw_attributes & BIT_6) && (IS_MSIX_NACK_CAPABLE(ha)) && (ha->flags.msix_enabled)) { In qla24xx_msix_rsp_q() and qla2xxx_msix_rsp_q_hs(), check: (rd_reg_dword(®->host_status) & HSRX_RISC_INT) Count the number of calls to each function with HSRX_RISC_INT set and the number with HSRX_RISC_INT not set while performing some I/O. If qla2xxx_msix_rsp_q_hs() clears the RISC interrupt (original code): qla24xx_msix_rsp_q: 50% of calls have HSRX_RISC_INT set qla2xxx_msix_rsp_q_hs: 5% of calls have HSRX_RISC_INT set (# of qla2xxx_msix_rsp_q_hs interrupts) = (# of qla24xx_msix_rsp_q interrupts) * 3 If qla2xxx_msix_rsp_q_hs() does not clear the RISC interrupt (patched code): qla24xx_msix_rsp_q: 100% of calls have HSRX_RISC_INT set qla2xxx_msix_rsp_q_hs: 9% of calls have HSRX_RISC_INT set (# of qla2xxx_msix_rsp_q_hs interrupts) = (# of qla24xx_msix_rsp_q interrupts) * 3 In the case of the original code, qla24xx_msix_rsp_q() was seeing HSRX_RISC_INT set only 50% of the time because qla2xxx_msix_rsp_q_hs() was clearing it when it shouldn't have been. In the patched code, qla24xx_msix_rsp_q() sees HSRX_RISC_INT set 100% of the time, which makes sense if that interrupt handler needs to clear the RISC interrupt (which it does). qla2xxx_msix_rsp_q_hs() sees HSRX_RISC_INT only 9% of the time, which is just overlap from the other interrupt during the high IOPS test. Tested with SCST on: QLE2742 FW:v9.08.02 (32 Gbps 2-port) QLE2694L FW:v9.10.11 (16 Gbps 4-port) QLE2694L FW:v9.08.02 (16 Gbps 4-port) QLE2672 FW:v8.07.12 (16 Gbps 2-port) both initiator and target mode Signed-off-by: Tony Battersby Link: https://patch.msgid.link/56d378eb-14ad-49c7-bae9-c649b6c7691e@cybernetics.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_def.h | 1 - drivers/scsi/qla2xxx/qla_gbl.h | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 32 +++----------------------------- drivers/scsi/qla2xxx/qla_mid.c | 4 +--- 4 files changed, 5 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 78a10d4979e9..4f7248643335 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3504,7 +3504,6 @@ struct isp_operations { #define QLA_MSIX_RSP_Q 0x01 #define QLA_ATIO_VECTOR 0x02 #define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x03 -#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS 0x04 #define QLA_MIDX_DEFAULT 0 #define QLA_MIDX_RSP_Q 1 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e556f57c91af..59f448e2e319 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -768,7 +768,7 @@ extern int qla2x00_dfs_remove(scsi_qla_host_t *); /* Globa function prototypes for multi-q */ extern int qla25xx_request_irq(struct qla_hw_data *, struct qla_qpair *, - struct qla_msix_entry *, int); + struct qla_msix_entry *); extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *); extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *); extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t, diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d48007e18288..a85d3a40ee49 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -4473,32 +4473,6 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id) return IRQ_HANDLED; } -irqreturn_t -qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) -{ - struct qla_hw_data *ha; - struct qla_qpair *qpair; - struct device_reg_24xx __iomem *reg; - unsigned long flags; - - qpair = dev_id; - if (!qpair) { - ql_log(ql_log_info, NULL, 0x505b, - "%s: NULL response queue pointer.\n", __func__); - return IRQ_NONE; - } - ha = qpair->hw; - - reg = &ha->iobase->isp24; - spin_lock_irqsave(&ha->hardware_lock, flags); - wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - queue_work(ha->wq, &qpair->q_work); - - return IRQ_HANDLED; -} - /* Interrupt handling helpers. */ struct qla_init_msix_entry { @@ -4511,7 +4485,6 @@ static const struct qla_init_msix_entry msix_entries[] = { { "rsp_q", qla24xx_msix_rsp_q }, { "atio_q", qla83xx_msix_atio_q }, { "qpair_multiq", qla2xxx_msix_rsp_q }, - { "qpair_multiq_hs", qla2xxx_msix_rsp_q_hs }, }; static const struct qla_init_msix_entry qla82xx_msix_entries[] = { @@ -4798,9 +4771,10 @@ qla2x00_free_irqs(scsi_qla_host_t *vha) } int qla25xx_request_irq(struct qla_hw_data *ha, struct qla_qpair *qpair, - struct qla_msix_entry *msix, int vector_type) + struct qla_msix_entry *msix) { - const struct qla_init_msix_entry *intr = &msix_entries[vector_type]; + const struct qla_init_msix_entry *intr = + &msix_entries[QLA_MSIX_QPAIR_MULTIQ_RSP_Q]; scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); int ret; diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 79879c4743e6..9946899dd83b 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -899,9 +899,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, rsp->options, rsp->id, rsp->rsp_q_in, rsp->rsp_q_out); - ret = qla25xx_request_irq(ha, qpair, qpair->msix, - ha->flags.disable_msix_handshake ? - QLA_MSIX_QPAIR_MULTIQ_RSP_Q : QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS); + ret = qla25xx_request_irq(ha, qpair, qpair->msix); if (ret) goto que_failed; -- Gitee From d7e631f52b2f85af4390a8f1d426b8d0c4cadfc8 Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Mon, 10 Nov 2025 23:48:45 +0800 Subject: [PATCH 0559/1449] scsi: qla2xxx: Fix initiator mode with qlini_mode=exclusive ANBZ: #35228 commit 0ec5059916f5f6fe5db428d1574d3e21fee80dfe stable. commit 8f58fc64d559b5fda1b0a5e2a71422be61e79ab9 upstream. When given the module parameter qlini_mode=exclusive, qla2xxx in initiator mode is initially unable to successfully send SCSI commands to devices it finds while scanning, resulting in an escalating series of resets until an adapter reset clears the issue. Fix by checking the active mode instead of the module parameter. Signed-off-by: Tony Battersby Link: https://patch.msgid.link/1715ec14-ba9a-45dc-9cf2-d41aa6b81b5e@cybernetics.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_os.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0a3a5af67f0a..4c7cf581bc86 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3459,13 +3459,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->mqenable = 0; if (ha->mqenable) { - bool startit = false; - - if (QLA_TGT_MODE_ENABLED()) - startit = false; - - if (ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) - startit = true; + bool startit = !!(host->active_mode & MODE_INITIATOR); /* Create start of day qpairs for Block MQ */ for (i = 0; i < ha->max_qpairs; i++) -- Gitee From abd81bae7307d21bcd48d5fcb2b535a3a0a31735 Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Mon, 10 Nov 2025 23:51:28 +0800 Subject: [PATCH 0560/1449] scsi: qla2xxx: Use reinit_completion on mbx_intr_comp ANBZ: #35228 commit 69f05f3e5390751f3adbe3d3955b6c2088d57a0e stable. commit 957aa5974989fba4ae4f807ebcb27f12796edd4d upstream. If a mailbox command completes immediately after wait_for_completion_timeout() times out, ha->mbx_intr_comp could be left in an inconsistent state, causing the next mailbox command not to wait for the hardware. Fix by reinitializing the completion before use. Signed-off-by: Tony Battersby Link: https://patch.msgid.link/11b6485e-0bfd-4784-8f99-c06a196dad94@cybernetics.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_mbx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 13b6cb1b93ac..41435e98092a 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -253,6 +253,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) /* Issue set host interrupt command to send cmd out. */ ha->flags.mbox_int = 0; clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); + reinit_completion(&ha->mbx_intr_comp); /* Unlock mbx registers and wait for interrupt */ ql_dbg(ql_dbg_mbx, vha, 0x100f, @@ -279,6 +280,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) "cmd=%x Timeout.\n", command); spin_lock_irqsave(&ha->hardware_lock, flags); clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); + reinit_completion(&ha->mbx_intr_comp); spin_unlock_irqrestore(&ha->hardware_lock, flags); if (chip_reset != ha->chip_reset) { -- Gitee From bd7a7203d78e2fb85300167842a430002f2fe4d9 Mon Sep 17 00:00:00 2001 From: Bernd Schubert Date: Thu, 23 Oct 2025 06:21:18 +0800 Subject: [PATCH 0561/1449] fuse: Always flush the page cache before FOPEN_DIRECT_IO write ANBZ: #35228 commit 6c6a81d86a3caa209359a0f40ca8ba8f384e8dc7 stable. commit 1ce120dcefc056ce8af2486cebbb77a458aad4c3 upstream. This was done as condition on direct_io_allow_mmap, but I believe this is not right, as a file might be open two times - once with write-back enabled another time with FOPEN_DIRECT_IO. Signed-off-by: Bernd Schubert Signed-off-by: Miklos Szeredi Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/fuse/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index f9fc75c97085..8946ca819c30 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1636,7 +1636,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, if (!ia) return -ENOMEM; - if (fopen_direct_io && fc->direct_io_allow_mmap) { + if (fopen_direct_io) { res = filemap_write_and_wait_range(mapping, pos, pos + count - 1); if (res) { fuse_io_free(ia); -- Gitee From d8f3322ff0fb7262c0d018b9b8855fcd9b4cec6c Mon Sep 17 00:00:00 2001 From: Bernd Schubert Date: Thu, 23 Oct 2025 06:21:17 +0800 Subject: [PATCH 0562/1449] fuse: Invalidate the page cache after FOPEN_DIRECT_IO write ANBZ: #35228 commit b39fa021839bf5158c055d4cf511fd47426fc9b5 stable. commit b359af8275a982a458e8df6c6beab1415be1f795 upstream. generic_file_direct_write() also does this and has a large comment about. Reproducer here is xfstest's generic/209, which is exactly to have competing DIO write and cached IO read. Signed-off-by: Bernd Schubert Signed-off-by: Miklos Szeredi Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/fuse/file.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8946ca819c30..31992b6062c0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1710,6 +1710,15 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, if (res > 0) *ppos = pos; + if (res > 0 && write && fopen_direct_io) { + /* + * As in generic_file_direct_write(), invalidate after the + * write, to invalidate read-ahead cache that may have competed + * with the write. + */ + invalidate_inode_pages2_range(mapping, idx_from, idx_to); + } + return res > 0 ? res : err; } EXPORT_SYMBOL_GPL(fuse_direct_io); -- Gitee From ecc11a9575f5d6da4f7e20c167ee44c599260620 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Sun, 28 Sep 2025 16:33:32 +0800 Subject: [PATCH 0563/1449] via_wdt: fix critical boot hang due to unnamed resource allocation ANBZ: #35228 commit d2c7c90aca7b37f60f16b2bedcfeb16204f2f35d stable. commit 7aa31ee9ec92915926e74731378c009c9cc04928 upstream. The VIA watchdog driver uses allocate_resource() to reserve a MMIO region for the watchdog control register. However, the allocated resource was not given a name, which causes the kernel resource tree to contain an entry marked as "" under /proc/iomem on x86 platforms. During boot, this unnamed resource can lead to a critical hang because subsequent resource lookups and conflict checks fail to handle the invalid entry properly. Signed-off-by: Li Qiang Reviewed-by: Guenter Roeck Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/watchdog/via_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c index eeb39f96e72e..c1ed3ce153cf 100644 --- a/drivers/watchdog/via_wdt.c +++ b/drivers/watchdog/via_wdt.c @@ -165,6 +165,7 @@ static int wdt_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "cannot enable PCI device\n"); return -ENODEV; } + wdt_res.name = "via_wdt"; /* * Allocate a MMIO region which contains watchdog control register -- Gitee From 9a30916d7cefda8d88806e3cc1b8ac47bbc5cf67 Mon Sep 17 00:00:00 2001 From: Encrow Thorne Date: Mon, 10 Nov 2025 14:10:37 +0800 Subject: [PATCH 0564/1449] reset: fix BIT macro reference ANBZ: #35228 commit b1cad002d69aeed82c2917cbc6705cf2af370b09 stable. commit f3d8b64ee46c9b4b0b82b1a4642027728bac95b8 upstream. RESET_CONTROL_FLAGS_BIT_* macros use BIT(), but reset.h does not include bits.h. This causes compilation errors when including reset.h standalone. Include bits.h to make reset.h self-contained. Suggested-by: Troy Mitchell Reviewed-by: Troy Mitchell Reviewed-by: Philipp Zabel Signed-off-by: Encrow Thorne Signed-off-by: Philipp Zabel Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/reset.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/reset.h b/include/linux/reset.h index 514ddf003efc..4b31d683776e 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -2,6 +2,7 @@ #ifndef _LINUX_RESET_H_ #define _LINUX_RESET_H_ +#include #include #include #include -- Gitee From ec627e6fd7b25c1addb7cad5ff9d27f6c3739423 Mon Sep 17 00:00:00 2001 From: Yuezhang Mo Date: Fri, 28 Nov 2025 17:51:10 +0800 Subject: [PATCH 0565/1449] exfat: fix remount failure in different process environments ANBZ: #35228 commit 44c8dccb09a20567742605f0c71cac78b9c07836 stable. commit 51fc7b4ce10ccab8ea5e4876bcdc42cf5202a0ef upstream. The kernel test robot reported that the exFAT remount operation failed. The reason for the failure was that the process's umask is different between mount and remount, causing fs_fmask and fs_dmask are changed. Potentially, both gid and uid may also be changed. Therefore, when initializing fs_context for remount, inherit these mount options from the options used during mount. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202511251637.81670f5c-lkp@intel.com Signed-off-by: Yuezhang Mo Signed-off-by: Namjae Jeon Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/exfat/super.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 957135f20cb6..da3e03b059cf 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -764,10 +764,21 @@ static int exfat_init_fs_context(struct fs_context *fc) ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); - sbi->options.fs_uid = current_uid(); - sbi->options.fs_gid = current_gid(); - sbi->options.fs_fmask = current->fs->umask; - sbi->options.fs_dmask = current->fs->umask; + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE && fc->root) { + struct super_block *sb = fc->root->d_sb; + struct exfat_mount_options *cur_opts = &EXFAT_SB(sb)->options; + + sbi->options.fs_uid = cur_opts->fs_uid; + sbi->options.fs_gid = cur_opts->fs_gid; + sbi->options.fs_fmask = cur_opts->fs_fmask; + sbi->options.fs_dmask = cur_opts->fs_dmask; + } else { + sbi->options.fs_uid = current_uid(); + sbi->options.fs_gid = current_gid(); + sbi->options.fs_fmask = current->fs->umask; + sbi->options.fs_dmask = current->fs->umask; + } + sbi->options.allow_utime = -1; sbi->options.iocharset = exfat_default_iocharset; sbi->options.errors = EXFAT_ERRORS_RO; -- Gitee From fee374f1d5fb9305eefb2191c422444e32d1bd5c Mon Sep 17 00:00:00 2001 From: Lizhi Xu Date: Tue, 16 Sep 2025 09:41:43 +0800 Subject: [PATCH 0566/1449] usbip: Fix locking bug in RT-enabled kernels ANBZ: #35228 commit de6dd14643e5041609208309f29440059f8fd2a3 stable. commit 09bf21bf5249880f62fe759b53b14b4b52900c6c upstream. Interrupts are disabled before entering usb_hcd_giveback_urb(). A spinlock_t becomes a sleeping lock on PREEMPT_RT, so it cannot be acquired with disabled interrupts. Save the interrupt status and restore it after usb_hcd_giveback_urb(). syz reported: BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48 Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 rt_spin_lock+0xc7/0x2c0 kernel/locking/spinlock_rt.c:57 spin_lock include/linux/spinlock_rt.h:44 [inline] mon_bus_complete drivers/usb/mon/mon_main.c:134 [inline] mon_complete+0x5c/0x200 drivers/usb/mon/mon_main.c:147 usbmon_urb_complete include/linux/usb/hcd.h:738 [inline] __usb_hcd_giveback_urb+0x254/0x5e0 drivers/usb/core/hcd.c:1647 vhci_urb_enqueue+0xb4f/0xe70 drivers/usb/usbip/vhci_hcd.c:818 Reported-by: syzbot+205ef33a3b636b4181fb@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=205ef33a3b636b4181fb Signed-off-by: Lizhi Xu Acked-by: Shuah Khan Link: https://lore.kernel.org/r/20250916014143.1439759-1-lizhi.xu@windriver.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/usbip/vhci_hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index b22e0881bfaf..0bc4805cfa3e 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -830,15 +830,15 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag no_need_xmit: usb_hcd_unlink_urb_from_ep(hcd, urb); no_need_unlink: - spin_unlock_irqrestore(&vhci->lock, flags); if (!ret) { /* usb_hcd_giveback_urb() should be called with * irqs disabled */ - local_irq_disable(); + spin_unlock(&vhci->lock); usb_hcd_giveback_urb(hcd, urb, urb->status); - local_irq_enable(); + spin_lock(&vhci->lock); } + spin_unlock_irqrestore(&vhci->lock, flags); return ret; } -- Gitee From 7c23022346ad26aea4c6aeab3ca6280fd804ce5e Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Fri, 22 Aug 2025 02:53:07 +0800 Subject: [PATCH 0567/1449] usb: typec: ucsi: Handle incorrect num_connectors capability ANBZ: #35228 commit 914605b0de8128434eafc9582445306830748b93 stable. commit 30cd2cb1abf4c4acdb1ddb468c946f68939819fb upstream. The UCSI spec states that the num_connectors field is 7 bits, and the 8th bit is reserved and should be set to zero. Some buggy FW has been known to set this bit, and it can lead to a system not booting. Flag that the FW is not behaving correctly, and auto-fix the value so that the system boots correctly. Found on Lenovo P1 G8 during Linux enablement program. The FW will be fixed, but seemed worth addressing in case it hit platforms that aren't officially Linux supported. Signed-off-by: Mark Pearson Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250821185319.2585023-1-mpearson-lenovo@squebb.ca Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/typec/ucsi/ucsi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index e5c001ee0cd7..b88f4e179a7a 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1428,6 +1428,12 @@ static int ucsi_init(struct ucsi *ucsi) ret = -ENODEV; goto err_reset; } + /* Check if reserved bit set. This is out of spec but happens in buggy FW */ + if (ucsi->cap.num_connectors & 0x80) { + dev_warn(ucsi->dev, "UCSI: Invalid num_connectors %d. Likely buggy FW\n", + ucsi->cap.num_connectors); + ucsi->cap.num_connectors &= 0x7f; // clear bit and carry on + } /* Allocate the connectors. Released in ucsi_unregister() */ connector = kcalloc(ucsi->cap.num_connectors + 1, sizeof(*connector), GFP_KERNEL); -- Gitee From adfeed21e733ed29d4d1f78684918b8dc0130707 Mon Sep 17 00:00:00 2001 From: Pei Xiao Date: Tue, 14 Oct 2025 17:12:50 +0800 Subject: [PATCH 0568/1449] iio: adc: ti_am335x_adc: Limit step_avg to valid range for gcc complains ANBZ: #35228 commit 1803fe66c9f22f2968f5a713f45243cfb04ad998 stable. commit c9fb952360d0c78bbe98239bd6b702f05c2dbb31 upstream. FIELD_PREP() checks that a value fits into the available bitfield, add a check for step_avg to fix gcc complains. which gcc complains about: drivers/iio/adc/ti_am335x_adc.c: In function 'tiadc_step_config': include/linux/compiler_types.h:572:38: error: call to '__compiletime_assert_491' declared with attribute error: FIELD_PREP: value too large for the field include/linux/mfd/ti_am335x_tscadc.h:58:29: note: in expansion of macro 'FIELD_PREP' #define STEPCONFIG_AVG(val) FIELD_PREP(GENMASK(4, 2), (val)) ^~~~~~~~~~ drivers/iio/adc/ti_am335x_adc.c:127:17: note: in expansion of macro 'STEPCONFIG_AVG' stepconfig = STEPCONFIG_AVG(ffs(adc_dev->step_avg[i]) - 1) Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202510102117.Jqxrw1vF-lkp@intel.com/ Signed-off-by: Pei Xiao Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/ti_am335x_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 32f1f91e2720..9e009b035eb5 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -123,7 +123,7 @@ static void tiadc_step_config(struct iio_dev *indio_dev) chan = adc_dev->channel_line[i]; - if (adc_dev->step_avg[i]) + if (adc_dev->step_avg[i] && adc_dev->step_avg[i] <= STEPCONFIG_AVG_16) stepconfig = STEPCONFIG_AVG(ffs(adc_dev->step_avg[i]) - 1) | STEPCONFIG_FIFO1; else -- Gitee From 070647244eb140810a08c1871e9364c430c0bd6c Mon Sep 17 00:00:00 2001 From: Hongyu Xie Date: Wed, 19 Nov 2025 22:23:55 +0800 Subject: [PATCH 0569/1449] usb: xhci: limit run_graceperiod for only usb 3.0 devices ANBZ: #35228 commit 4373a81f6b0ae93da87b6152b6b50f8804a2735d stable. commit 8d34983720155b8f05de765f0183d9b0e1345cc0 upstream. run_graceperiod blocks usb 2.0 devices from auto suspending after xhci_start for 500ms. Log shows: [ 13.387170] xhci_hub_control:1271: xhci-hcd PNP0D10:03: Get port status 7-1 read: 0x2a0, return 0x100 [ 13.387177] hub_event:5779: hub 7-0:1.0: state 7 ports 1 chg 0000 evt 0000 [ 13.387182] hub_suspend:3903: hub 7-0:1.0: hub_suspend [ 13.387188] hcd_bus_suspend:2250: usb usb7: bus auto-suspend, wakeup 1 [ 13.387191] hcd_bus_suspend:2279: usb usb7: suspend raced with wakeup event [ 13.387193] hcd_bus_resume:2303: usb usb7: usb auto-resume [ 13.387296] hub_event:5779: hub 3-0:1.0: state 7 ports 1 chg 0000 evt 0000 [ 13.393343] handle_port_status:2034: xhci-hcd PNP0D10:02: handle_port_status: starting usb5 port polling. [ 13.393353] xhci_hub_control:1271: xhci-hcd PNP0D10:02: Get port status 5-1 read: 0x206e1, return 0x10101 [ 13.400047] hub_suspend:3903: hub 3-0:1.0: hub_suspend [ 13.403077] hub_resume:3948: hub 7-0:1.0: hub_resume [ 13.403080] xhci_hub_control:1271: xhci-hcd PNP0D10:03: Get port status 7-1 read: 0x2a0, return 0x100 [ 13.403085] hub_event:5779: hub 7-0:1.0: state 7 ports 1 chg 0000 evt 0000 [ 13.403087] hub_suspend:3903: hub 7-0:1.0: hub_suspend [ 13.403090] hcd_bus_suspend:2250: usb usb7: bus auto-suspend, wakeup 1 [ 13.403093] hcd_bus_suspend:2279: usb usb7: suspend raced with wakeup event [ 13.403095] hcd_bus_resume:2303: usb usb7: usb auto-resume [ 13.405002] handle_port_status:1913: xhci-hcd PNP0D10:04: Port change event, 9-1, id 1, portsc: 0x6e1 [ 13.405016] hub_activate:1169: usb usb5-port1: status 0101 change 0001 [ 13.405026] xhci_clear_port_change_bit:658: xhci-hcd PNP0D10:02: clear port1 connect change, portsc: 0x6e1 [ 13.413275] hcd_bus_suspend:2250: usb usb3: bus auto-suspend, wakeup 1 [ 13.419081] hub_resume:3948: hub 7-0:1.0: hub_resume [ 13.419086] xhci_hub_control:1271: xhci-hcd PNP0D10:03: Get port status 7-1 read: 0x2a0, return 0x100 [ 13.419095] hub_event:5779: hub 7-0:1.0: state 7 ports 1 chg 0000 evt 0000 [ 13.419100] hub_suspend:3903: hub 7-0:1.0: hub_suspend [ 13.419106] hcd_bus_suspend:2250: usb usb7: bus auto-suspend, wakeup 1 [ 13.419110] hcd_bus_suspend:2279: usb usb7: suspend raced with wakeup event [ 13.419112] hcd_bus_resume:2303: usb usb7: usb auto-resume [ 13.420455] handle_port_status:2034: xhci-hcd PNP0D10:04: handle_port_status: starting usb9 port polling. [ 13.420493] handle_port_status:1913: xhci-hcd PNP0D10:05: Port change event, 10-1, id 1, portsc: 0x6e1 [ 13.425332] hcd_bus_suspend:2279: usb usb3: suspend raced with wakeup event [ 13.431931] handle_port_status:2034: xhci-hcd PNP0D10:05: handle_port_status: starting usb10 port polling. [ 13.435080] hub_resume:3948: hub 7-0:1.0: hub_resume [ 13.435084] xhci_hub_control:1271: xhci-hcd PNP0D10:03: Get port status 7-1 read: 0x2a0, return 0x100 [ 13.435092] hub_event:5779: hub 7-0:1.0: state 7 ports 1 chg 0000 evt 0000 [ 13.435096] hub_suspend:3903: hub 7-0:1.0: hub_suspend [ 13.435102] hcd_bus_suspend:2250: usb usb7: bus auto-suspend, wakeup 1 [ 13.435106] hcd_bus_suspend:2279: usb usb7: suspend raced with wakeup event usb7 and other usb 2.0 root hub were rapidly toggling between suspend and resume states. More, "suspend raced with wakeup event" confuses people. So, limit run_graceperiod for only usb 3.0 devices Signed-off-by: Hongyu Xie Signed-off-by: Mathias Nyman Link: https://patch.msgid.link/20251119142417.2820519-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/xhci-hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index d3d535ed00b5..61642c8d529f 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1669,7 +1669,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) * SS devices are only visible to roothub after link training completes. * Keep polling roothubs for a grace period after xHC start */ - if (xhci->run_graceperiod) { + if (hcd->speed >= HCD_USB3 && xhci->run_graceperiod) { if (time_before(jiffies, xhci->run_graceperiod)) status = 1; else -- Gitee From bdf7b3c53d63297afa7ec9e706161c2e369eab63 Mon Sep 17 00:00:00 2001 From: Chen Changcheng Date: Fri, 21 Nov 2025 14:40:20 +0800 Subject: [PATCH 0570/1449] usb: usb-storage: No additional quirks need to be added to the EL-R12 optical drive. ANBZ: #35228 commit 72ab74fce63bb86e38120b6a7b5c583201886542 stable. commit 955a48a5353f4fe009704a9a4272a3adf627cd35 upstream. The optical drive of EL-R12 has the same vid and pid as INIC-3069, as follows: T: Bus=02 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 3 Spd=5000 MxCh= 0 D: Ver= 3.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=13fd ProdID=3940 Rev= 3.10 S: Manufacturer=HL-DT-ST S: Product= DVD+-RW GT80N S: SerialNumber=423349524E4E38303338323439202020 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=144mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=02 Prot=50 Driver=usb-storage E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=0a(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms This will result in the optical drive device also adding the quirks of US_FL_NO_ATA_1X. When performing an erase operation, it will fail, and the reason for the failure is as follows: [ 388.967742] sr 5:0:0:0: [sr0] tag#0 Send: scmd 0x00000000d20c33a7 [ 388.967742] sr 5:0:0:0: [sr0] tag#0 CDB: ATA command pass through(12)/Blank a1 11 00 00 00 00 00 00 00 00 00 00 [ 388.967773] sr 5:0:0:0: [sr0] tag#0 Done: SUCCESS Result: hostbyte=DID_TARGET_FAILURE driverbyte=DRIVER_OK cmd_age=0s [ 388.967773] sr 5:0:0:0: [sr0] tag#0 CDB: ATA command pass through(12)/Blank a1 11 00 00 00 00 00 00 00 00 00 00 [ 388.967803] sr 5:0:0:0: [sr0] tag#0 Sense Key : Illegal Request [current] [ 388.967803] sr 5:0:0:0: [sr0] tag#0 Add. Sense: Invalid field in cdb [ 388.967803] sr 5:0:0:0: [sr0] tag#0 scsi host busy 1 failed 0 [ 388.967803] sr 5:0:0:0: Notifying upper driver of completion (result 8100002) [ 388.967834] sr 5:0:0:0: [sr0] tag#0 0 sectors total, 0 bytes done. For the EL-R12 standard optical drive, all operational commands and usage scenarios were tested without adding the IGNORE_RESIDUE quirks, and no issues were encountered. It can be reasonably concluded that removing the IGNORE_RESIDUE quirks has no impact. Signed-off-by: Chen Changcheng Link: https://patch.msgid.link/20251121064020.29332-1-chenchangcheng@kylinos.cn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/storage/unusual_uas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 1477e31d7763..b695f5ba9a40 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -98,7 +98,7 @@ UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160, US_FL_NO_ATA_1X), /* Reported-by: Benjamin Tissoires */ -UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, +UNUSUAL_DEV(0x13fd, 0x3940, 0x0309, 0x0309, "Initio Corporation", "INIC-3069", USB_SC_DEVICE, USB_PR_DEVICE, NULL, -- Gitee From 40b75f2855ce5fdb1ed189b84e55e4de2bbba56b Mon Sep 17 00:00:00 2001 From: Wenhua Lin Date: Wed, 22 Oct 2025 11:08:40 +0800 Subject: [PATCH 0571/1449] serial: sprd: Return -EPROBE_DEFER when uart clock is not ready ANBZ: #35228 commit 1abf4ddeda5cd631ef8a7433d633a8948ac74aac stable. commit 29e8a0c587e328ed458380a45d6028adf64d7487 upstream. In sprd_clk_init(), when devm_clk_get() returns -EPROBE_DEFER for either uart or source clock, we should propagate the error instead of just warning and continuing with NULL clocks. Currently the driver only emits a warning when clock acquisition fails and proceeds with NULL clock pointers. This can lead to issues later when the clocks are actually needed. More importantly, when the clock provider is not ready yet and returns -EPROBE_DEFER, we should return this error to allow deferred probing. This change adds explicit checks for -EPROBE_DEFER after both: 1. devm_clk_get(uport->dev, uart) 2. devm_clk_get(uport->dev, source) When -EPROBE_DEFER is encountered, the function now returns -EPROBE_DEFER to let the driver framework retry probing later when the clock dependencies are resolved. Signed-off-by: Wenhua Lin Link: https://patch.msgid.link/20251022030840.956589-1-Wenhua.Lin@unisoc.com Reviewed-by: Cixi Geng Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/tty/serial/sprd_serial.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index f328fa57231f..c6d2258d719b 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -1111,6 +1111,9 @@ static int sprd_clk_init(struct uart_port *uport) clk_uart = devm_clk_get(uport->dev, "uart"); if (IS_ERR(clk_uart)) { + if (PTR_ERR(clk_uart) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_warn(uport->dev, "uart%d can't get uart clock\n", uport->line); clk_uart = NULL; @@ -1118,6 +1121,9 @@ static int sprd_clk_init(struct uart_port *uport) clk_parent = devm_clk_get(uport->dev, "source"); if (IS_ERR(clk_parent)) { + if (PTR_ERR(clk_parent) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_warn(uport->dev, "uart%d can't get source clock\n", uport->line); clk_parent = NULL; -- Gitee From 2154478534cc33569b5eac94929943b097c138fd Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 4 Dec 2025 05:47:01 +0800 Subject: [PATCH 0572/1449] libperf cpumap: Fix perf_cpu_map__max for an empty/NULL map ANBZ: #35228 commit 92544ae44c441c7c68593e6b014f6c72ac3856e3 stable. commit a0a4173631bfcfd3520192c0a61cf911d6a52c3a upstream. Passing an empty map to perf_cpu_map__max triggered a SEGV. Explicitly test for the empty map. Reported-by: Ingo Molnar Closes: https://lore.kernel.org/linux-perf-users/aSwt7yzFjVJCEmVp@gmail.com/ Tested-by: Ingo Molnar Signed-off-by: Ian Rogers Tested-by: Thomas Richter Signed-off-by: Namhyung Kim Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/lib/perf/cpumap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index cae799ad44e1..e5938b91199f 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -409,10 +409,12 @@ struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map) .cpu = -1 }; - // cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as well. - return __perf_cpu_map__nr(map) > 0 - ? __perf_cpu_map__cpu(map, __perf_cpu_map__nr(map) - 1) - : result; + if (!map) + return result; + + // The CPUs are always sorted and nr is always > 0 as 0 length map is + // encoded as NULL. + return __perf_cpu_map__cpu(map, __perf_cpu_map__nr(map) - 1); } /** Is 'b' a subset of 'a'. */ -- Gitee From fe10a91eb9617ebfd983a3f7a697769a4de4a2aa Mon Sep 17 00:00:00 2001 From: Jinhui Guo Date: Tue, 21 Oct 2025 15:57:14 +0800 Subject: [PATCH 0573/1449] i2c: designware: Disable SMBus interrupts to prevent storms from mis-configured firmware ANBZ: #35228 commit 62641daa93cb8b8ed975fad75fb07f9f9e3488cd stable. commit d3429178ee51dd7155445d15a5ab87a45fae3c73 upstream. When probing the I2C master, disable SMBus interrupts to prevent storms caused by broken firmware mis-configuring IC_SMBUS=1; the handler never services them and a mis-configured SMBUS Master extend-clock timeout or SMBUS Slave extend-clock timeout can flood the CPU. Signed-off-by: Jinhui Guo Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20251021075714.3712-2-guojinhui.liam@bytedance.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/i2c/busses/i2c-designware-core.h | 1 + drivers/i2c/busses/i2c-designware-master.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index fcb4948f43ef..d3e691f22ec6 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -79,6 +79,7 @@ #define DW_IC_TX_ABRT_SOURCE 0x80 #define DW_IC_ENABLE_STATUS 0x9c #define DW_IC_CLR_RESTART_DET 0xa8 +#define DW_IC_SMBUS_INTR_MASK 0xcc #define DW_IC_COMP_PARAM_1 0xf4 #define DW_IC_COMP_VERSION 0xf8 #define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */ diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index a15c85675be5..db1ab6729a92 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -184,6 +184,13 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev) /* Disable the adapter */ __i2c_dw_disable(dev); + /* + * Mask SMBus interrupts to block storms from broken + * firmware that leaves IC_SMBUS=1; the handler never + * services them. + */ + regmap_write(dev->map, DW_IC_SMBUS_INTR_MASK, 0); + /* Write standard speed timing parameters */ regmap_write(dev->map, DW_IC_SS_SCL_HCNT, dev->ss_hcnt); regmap_write(dev->map, DW_IC_SS_SCL_LCNT, dev->ss_lcnt); -- Gitee From 579b883fe964d6028caebf823d7ef10b98e32f8c Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 30 Oct 2025 18:05:45 +0800 Subject: [PATCH 0574/1449] nvme-fc: don't hold rport lock when putting ctrl ANBZ: #35228 commit e3ef3e4888dea279610aab3deffbcfecb116c150 stable. commit b71cbcf7d170e51148d5467820ae8a72febcb651 upstream. nvme_fc_ctrl_put can acquire the rport lock when freeing the ctrl object: nvme_fc_ctrl_put nvme_fc_ctrl_free spin_lock_irqsave(rport->lock) Thus we can't hold the rport lock when calling nvme_fc_ctrl_put. Justin suggested use the safe list iterator variant because nvme_fc_ctrl_put will also modify the rport->list. Cc: Justin Tee Reviewed-by: Christoph Hellwig Signed-off-by: Daniel Wagner Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/fc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 37fede155b92..2954f0a27474 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -1462,14 +1462,14 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport, { struct fcnvme_ls_disconnect_assoc_rqst *rqst = &lsop->rqstbuf->rq_dis_assoc; - struct nvme_fc_ctrl *ctrl, *ret = NULL; + struct nvme_fc_ctrl *ctrl, *tmp, *ret = NULL; struct nvmefc_ls_rcv_op *oldls = NULL; u64 association_id = be64_to_cpu(rqst->associd.association_id); unsigned long flags; spin_lock_irqsave(&rport->lock, flags); - list_for_each_entry(ctrl, &rport->ctrl_list, ctrl_list) { + list_for_each_entry_safe(ctrl, tmp, &rport->ctrl_list, ctrl_list) { if (!nvme_fc_ctrl_get(ctrl)) continue; spin_lock(&ctrl->lock); @@ -1482,7 +1482,9 @@ nvme_fc_match_disconn_ls(struct nvme_fc_rport *rport, if (ret) /* leave the ctrl get reference */ break; + spin_unlock_irqrestore(&rport->lock, flags); nvme_fc_ctrl_put(ctrl); + spin_lock_irqsave(&rport->lock, flags); } spin_unlock_irqrestore(&rport->lock, flags); -- Gitee From 279c776298ae92be837620d2a77aec16ae066000 Mon Sep 17 00:00:00 2001 From: "Chia-Lin Kao (AceLan)" Date: Thu, 27 Nov 2025 15:04:07 +0800 Subject: [PATCH 0575/1449] platform/x86/intel/hid: Add Dell Pro Rugged 10/12 tablet to VGBS DMI quirks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 8d8cd3d315db5394e4cea56a7c294ff2aaff7f8e stable. commit b169e1733cadb614e87f69d7a5ae1b186c50d313 upstream. Dell Pro Rugged 10/12 tablets has a reliable VGBS method. If VGBS is not called on boot, the on-screen keyboard won't appear if the device is booted without a keyboard. Call VGBS on boot on thess devices to get the initial state of SW_TABLET_MODE in a reliable way. Signed-off-by: Chia-Lin Kao (AceLan) Reviewed-by: Hans de Goede Link: https://patch.msgid.link/20251127070407.656463-1-acelan.kao@canonical.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/intel/hid.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 36209997ba98..ac88119a73b8 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -163,6 +163,18 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 10 Tablet RA00260"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), + }, + }, { } }; -- Gitee From e537fa17eb1e3d6c552dae1e50af0685fef45af4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 20 Dec 2025 16:46:10 +0800 Subject: [PATCH 0576/1449] block: rnbd-clt: Fix signedness bug in init_dev() ANBZ: #35228 commit cebfc2ba2e6ffb68cca14d478f6596b79243eb9a stable. commit 1ddb815fdfd45613c32e9bd1f7137428f298e541 upstream. The "dev->clt_device_id" variable is set using ida_alloc_max() which returns an int and in particular it returns negative error codes. Change the type from u32 to int to fix the error checking. Fixes: c9b5645fd8ca ("block: rnbd-clt: Fix leaked ID in init_dev()") Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/rnbd/rnbd-clt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/rnbd/rnbd-clt.h b/drivers/block/rnbd/rnbd-clt.h index a48e040abe63..fbc1ed766025 100644 --- a/drivers/block/rnbd/rnbd-clt.h +++ b/drivers/block/rnbd/rnbd-clt.h @@ -112,7 +112,7 @@ struct rnbd_clt_dev { struct rnbd_queue *hw_queues; u32 device_id; /* local Idr index - used to track minor number allocations. */ - u32 clt_device_id; + int clt_device_id; struct mutex lock; enum rnbd_clt_dev_state dev_state; refcount_t refcount; -- Gitee From fcd981d47cd3118f0515b5eaf93bdd535c92696a Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 26 Nov 2025 21:38:26 +0800 Subject: [PATCH 0577/1449] vhost/vsock: improve RCU read sections around vhost_vsock_get() ANBZ: #35228 commit 23a89dda39f4690a0fcdfd61c866510607bc5926 stable. commit d8ee3cfdc89b75dc059dc21c27bef2c1440f67eb upstream. vhost_vsock_get() uses hash_for_each_possible_rcu() to find the `vhost_vsock` associated with the `guest_cid`. hash_for_each_possible_rcu() should only be called within an RCU read section, as mentioned in the following comment in include/linux/rculist.h: /** * hlist_for_each_entry_rcu - iterate over rcu list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the hlist_node within the struct. * @cond: optional lockdep expression if called from non-RCU protection. * * This list-traversal primitive may safely run concurrently with * the _rcu list-mutation primitives such as hlist_add_head_rcu() * as long as the traversal is guarded by rcu_read_lock(). */ Currently, all calls to vhost_vsock_get() are between rcu_read_lock() and rcu_read_unlock() except for calls in vhost_vsock_set_cid() and vhost_vsock_reset_orphans(). In both cases, the current code is safe, but we can make improvements to make it more robust. About vhost_vsock_set_cid(), when building the kernel with CONFIG_PROVE_RCU_LIST enabled, we get the following RCU warning when the user space issues `ioctl(dev, VHOST_VSOCK_SET_GUEST_CID, ...)` : WARNING: suspicious RCU usage 6.18.0-rc7 #62 Not tainted ----------------------------- drivers/vhost/vsock.c:74 RCU-list traversed in non-reader section!! other info that might help us debug this: rcu_scheduler_active = 2, debug_locks = 1 1 lock held by rpc-libvirtd/3443: #0: ffffffffc05032a8 (vhost_vsock_mutex){+.+.}-{4:4}, at: vhost_vsock_dev_ioctl+0x2ff/0x530 [vhost_vsock] stack backtrace: CPU: 2 UID: 0 PID: 3443 Comm: rpc-libvirtd Not tainted 6.18.0-rc7 #62 PREEMPT(none) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-7.fc42 06/10/2025 Call Trace: dump_stack_lvl+0x75/0xb0 dump_stack+0x14/0x1a lockdep_rcu_suspicious.cold+0x4e/0x97 vhost_vsock_get+0x8f/0xa0 [vhost_vsock] vhost_vsock_dev_ioctl+0x307/0x530 [vhost_vsock] __x64_sys_ioctl+0x4f2/0xa00 x64_sys_call+0xed0/0x1da0 do_syscall_64+0x73/0xfa0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ... This is not a real problem, because the vhost_vsock_get() caller, i.e. vhost_vsock_set_cid(), holds the `vhost_vsock_mutex` used by the hash table writers. Anyway, to prevent that warning, add lockdep_is_held() condition to hash_for_each_possible_rcu() to verify that either the caller is in an RCU read section or `vhost_vsock_mutex` is held when CONFIG_PROVE_RCU_LIST is enabled; and also clarify the comment for vhost_vsock_get() to better describe the locking requirements and the scope of the returned pointer validity. About vhost_vsock_reset_orphans(), currently this function is only called via vsock_for_each_connected_socket(), which holds the `vsock_table_lock` spinlock (which is also an RCU read-side critical section). However, add an explicit RCU read lock there to make the code more robust and explicit about the RCU requirements, and to prevent issues if the calling context changes in the future or if vhost_vsock_reset_orphans() is called from other contexts. Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers") Cc: stefanha@redhat.com Signed-off-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Message-Id: <20251126133826.142496-1-sgarzare@redhat.com> Message-ID: <20251126210313.GA499503@fedora> Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/vhost/vsock.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 2ec0d5260685..912e5153b1f8 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -64,14 +64,15 @@ static u32 vhost_transport_get_local_cid(void) return VHOST_VSOCK_DEFAULT_HOST_CID; } -/* Callers that dereference the return value must hold vhost_vsock_mutex or the - * RCU read lock. +/* Callers must be in an RCU read section or hold the vhost_vsock_mutex. + * The return value can only be dereferenced while within the section. */ static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) { struct vhost_vsock *vsock; - hash_for_each_possible_rcu(vhost_vsock_hash, vsock, hash, guest_cid) { + hash_for_each_possible_rcu(vhost_vsock_hash, vsock, hash, guest_cid, + lockdep_is_held(&vhost_vsock_mutex)) { u32 other_cid = vsock->guest_cid; /* Skip instances that have no CID yet */ @@ -695,9 +696,15 @@ static void vhost_vsock_reset_orphans(struct sock *sk) * executing. */ + rcu_read_lock(); + /* If the peer is still valid, no need to reset connection */ - if (vhost_vsock_get(vsk->remote_addr.svm_cid)) + if (vhost_vsock_get(vsk->remote_addr.svm_cid)) { + rcu_read_unlock(); return; + } + + rcu_read_unlock(); /* If the close timeout is pending, let it expire. This avoids races * with the timeout callback. -- Gitee From b77691c05566cfc9f0929c518cce44f70aca9132 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 24 Dec 2025 23:21:42 +0800 Subject: [PATCH 0578/1449] cifs: Fix memory and information leak in smb3_reconfigure() ANBZ: #35228 commit bc390b2737205163e48cc1655f6a0c8cd55b02fc stable. commit cb6d5aa9c0f10074f1ad056c3e2278ad2cc7ec8d upstream. In smb3_reconfigure(), if smb3_sync_session_ctx_passwords() fails, the function returns immediately without freeing and erasing the newly allocated new_password and new_password2. This causes both a memory leak and a potential information leak. Fix this by calling kfree_sensitive() on both password buffers before returning in this error case. Fixes: 0f0e357902957 ("cifs: during remount, make sure passwords are in sync") Signed-off-by: Zilin Guan Reviewed-by: ChenXiaoSong Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/fs_context.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index 6358f2483c86..37b04c23ee89 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -979,6 +979,8 @@ static int smb3_reconfigure(struct fs_context *fc) rc = smb3_sync_session_ctx_passwords(cifs_sb, ses); if (rc) { mutex_unlock(&ses->session_mutex); + kfree_sensitive(new_password); + kfree_sensitive(new_password2); return rc; } -- Gitee From 21cc1470cd9a3572b7b3e9174044ce8f35ee98e7 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Sat, 18 Oct 2025 18:30:36 +0800 Subject: [PATCH 0579/1449] KEYS: trusted: Fix a memory leak in tpm2_load_cmd ANBZ: #35228 commit 19166de9737218b77122c41a5730ac87025e089f stable. commit 62cd5d480b9762ce70d720a81fa5b373052ae05f upstream. 'tpm2_load_cmd' allocates a tempoary blob indirectly via 'tpm2_key_decode' but it is not freed in the failure paths. Address this by wrapping the blob into with a cleanup helper. Cc: stable@vger.kernel.org # v5.13+ Fixes: f2219745250f ("security: keys: trusted: use ASN.1 TPM2 key format for the blobs") Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- security/keys/trusted-keys/trusted_tpm2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c index ea277c55a38d..190dd32f8113 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -375,6 +375,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip, struct trusted_key_options *options, u32 *blob_handle) { + u8 *blob_ref __free(kfree) = NULL; struct tpm_buf buf; unsigned int private_len; unsigned int public_len; @@ -388,6 +389,9 @@ static int tpm2_load_cmd(struct tpm_chip *chip, /* old form */ blob = payload->blob; payload->old_format = 1; + } else { + /* Bind for cleanup: */ + blob_ref = blob; } /* new format carries keyhandle but old format doesn't */ @@ -446,8 +450,6 @@ static int tpm2_load_cmd(struct tpm_chip *chip, (__be32 *) &buf.data[TPM_HEADER_SIZE]); out: - if (blob != payload->blob) - kfree(blob); tpm_buf_destroy(&buf); if (rc > 0) -- Gitee From b5c211c02b86e8ff57733c684fd5fc3c4a56ba75 Mon Sep 17 00:00:00 2001 From: Prithvi Tambewagh Date: Thu, 25 Dec 2025 15:28:29 +0800 Subject: [PATCH 0580/1449] io_uring: fix filename leak in __io_openat_prep() ANBZ: #35228 commit 18b99fa603d0df5e1c898699c17d3b92ddc80746 stable. commit b14fad555302a2104948feaff70503b64c80ac01 upstream. __io_openat_prep() allocates a struct filename using getname(). However, for the condition of the file being installed in the fixed file table as well as having O_CLOEXEC flag set, the function returns early. At that point, the request doesn't have REQ_F_NEED_CLEANUP flag set. Due to this, the memory for the newly allocated struct filename is not cleaned up, causing a memory leak. Fix this by setting the REQ_F_NEED_CLEANUP for the request just after the successful getname() call, so that when the request is torn down, the filename will be cleaned up, along with other resources needing cleanup. Reported-by: syzbot+00e61c43eb5e4740438f@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=00e61c43eb5e4740438f Tested-by: syzbot+00e61c43eb5e4740438f@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Prithvi Tambewagh Fixes: b9445598d8c6 ("io_uring: openat directly into fixed fd table") Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- io_uring/openclose.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/openclose.c b/io_uring/openclose.c index e3fae26e025d..e4def78bf8b5 100644 --- a/io_uring/openclose.c +++ b/io_uring/openclose.c @@ -65,13 +65,13 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe open->filename = NULL; return ret; } + req->flags |= REQ_F_NEED_CLEANUP; open->file_slot = READ_ONCE(sqe->file_index); if (open->file_slot && (open->how.flags & O_CLOEXEC)) return -EINVAL; open->nofile = rlimit(RLIMIT_NOFILE); - req->flags |= REQ_F_NEED_CLEANUP; if (io_openat_force_async(open)) req->flags |= REQ_F_FORCE_ASYNC; return 0; -- Gitee From 34c0b5e20b1669aff337225937094c27bca1e63b Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Fri, 14 Nov 2025 16:28:24 +0800 Subject: [PATCH 0581/1449] mmc: sdhci-msm: Avoid early clock doubling during HS400 transition ANBZ: #35228 commit fe2ce8f925b09d819546feb5db52ab1db42cb0d4 stable. commit b1f856b1727c2eaa4be2c6d7cd7a8ed052bbeb87 upstream. According to the hardware programming guide, the clock frequency must remain below 52MHz during the transition to HS400 mode. However,in the current implementation, the timing is set to HS400 (a DDR mode) before adjusting the clock. This causes the clock to double prematurely to 104MHz during the transition phase, violating the specification and potentially resulting in CRC errors or CMD timeouts. This change ensures that clock doubling is avoided during intermediate transitions and is applied only when the card requires a 200MHz clock for HS400 operation. Signed-off-by: Sarthak Garg Reviewed-by: Bjorn Andersson Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mmc/host/sdhci-msm.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 74234ee5f608..0589bbbc064b 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -344,41 +344,43 @@ static void sdhci_msm_v5_variant_writel_relaxed(u32 val, writel_relaxed(val, host->ioaddr + offset); } -static unsigned int msm_get_clock_mult_for_bus_mode(struct sdhci_host *host) +static unsigned int msm_get_clock_mult_for_bus_mode(struct sdhci_host *host, + unsigned int clock, + unsigned int timing) { - struct mmc_ios ios = host->mmc->ios; /* * The SDHC requires internal clock frequency to be double the * actual clock that will be set for DDR mode. The controller * uses the faster clock(100/400MHz) for some of its parts and * send the actual required clock (50/200MHz) to the card. */ - if (ios.timing == MMC_TIMING_UHS_DDR50 || - ios.timing == MMC_TIMING_MMC_DDR52 || - ios.timing == MMC_TIMING_MMC_HS400 || + if (timing == MMC_TIMING_UHS_DDR50 || + timing == MMC_TIMING_MMC_DDR52 || + (timing == MMC_TIMING_MMC_HS400 && + clock == MMC_HS200_MAX_DTR) || host->flags & SDHCI_HS400_TUNING) return 2; return 1; } static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, - unsigned int clock) + unsigned int clock, + unsigned int timing) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); - struct mmc_ios curr_ios = host->mmc->ios; struct clk *core_clk = msm_host->bulk_clks[0].clk; unsigned long achieved_rate; unsigned int desired_rate; unsigned int mult; int rc; - mult = msm_get_clock_mult_for_bus_mode(host); + mult = msm_get_clock_mult_for_bus_mode(host, clock, timing); desired_rate = clock * mult; rc = dev_pm_opp_set_rate(mmc_dev(host->mmc), desired_rate); if (rc) { pr_err("%s: Failed to set clock at rate %u at timing %d\n", - mmc_hostname(host->mmc), desired_rate, curr_ios.timing); + mmc_hostname(host->mmc), desired_rate, timing); return; } @@ -397,7 +399,7 @@ static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, msm_host->clk_rate = desired_rate; pr_debug("%s: Setting clock at rate %lu at timing %d\n", - mmc_hostname(host->mmc), achieved_rate, curr_ios.timing); + mmc_hostname(host->mmc), achieved_rate, timing); } /* Platform specific tuning */ @@ -1239,7 +1241,7 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) */ if (host->flags & SDHCI_HS400_TUNING) { sdhci_msm_hc_select_mode(host); - msm_set_clock_rate_for_bus_mode(host, ios.clock); + msm_set_clock_rate_for_bus_mode(host, ios.clock, ios.timing); host->flags &= ~SDHCI_HS400_TUNING; } @@ -1864,6 +1866,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); + struct mmc_ios ios = host->mmc->ios; if (!clock) { host->mmc->actual_clock = msm_host->clk_rate = 0; @@ -1872,7 +1875,7 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_msm_hc_select_mode(host); - msm_set_clock_rate_for_bus_mode(host, clock); + msm_set_clock_rate_for_bus_mode(host, ios.clock, ios.timing); out: __sdhci_msm_set_clock(host, clock); } -- Gitee From bb8f7c7dbaf1c635d2275e06e14d5192800c436b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 3 Nov 2025 07:42:04 +0800 Subject: [PATCH 0582/1449] lib/crypto: x86/blake2s: Fix 32-bit arg treated as 64-bit ANBZ: #35228 commit 4f4515f024973e2c81c51fcea9013c324abbd203 stable. commit 2f22115709fc7ebcfa40af3367a508fbbd2f71e9 upstream. In the C code, the 'inc' argument to the assembly functions blake2s_compress_ssse3() and blake2s_compress_avx512() is declared with type u32, matching blake2s_compress(). The assembly code then reads it from the 64-bit %rcx. However, the ABI doesn't guarantee zero-extension to 64 bits, nor do gcc or clang guarantee it. Therefore, fix these functions to read this argument from the 32-bit %ecx. In theory, this bug could have caused the wrong 'inc' value to be used, causing incorrect BLAKE2s hashes. In practice, probably not: I've fixed essentially this same bug in many other assembly files too, but there's never been a real report of it having caused a problem. In x86_64, all writes to 32-bit registers are zero-extended to 64 bits. That results in zero-extension in nearly all situations. I've only been able to demonstrate a lack of zero-extension with a somewhat contrived example involving truncation, e.g. when the C code has a u64 variable holding 0x1234567800000040 and passes it as a u32 expecting it to be truncated to 0x40 (64). But that's not what the real code does, of course. Fixes: ed0356eda153 ("crypto: blake2s - x86_64 SIMD implementation") Cc: stable@vger.kernel.org Reviewed-by: Ard Biesheuvel Link: https://lore.kernel.org/r/20251102234209.62133-2-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/crypto/blake2s-core.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/crypto/blake2s-core.S b/arch/x86/crypto/blake2s-core.S index b50b35ff1fdb..ca2644820dfc 100644 --- a/arch/x86/crypto/blake2s-core.S +++ b/arch/x86/crypto/blake2s-core.S @@ -54,7 +54,7 @@ SYM_FUNC_START(blake2s_compress_ssse3) movdqa ROT16(%rip),%xmm12 movdqa ROR328(%rip),%xmm13 movdqu 0x20(%rdi),%xmm14 - movq %rcx,%xmm15 + movd %ecx,%xmm15 leaq SIGMA+0xa0(%rip),%r8 jmp .Lbeginofloop .align 32 @@ -179,7 +179,7 @@ SYM_FUNC_START(blake2s_compress_avx512) vmovdqu (%rdi),%xmm0 vmovdqu 0x10(%rdi),%xmm1 vmovdqu 0x20(%rdi),%xmm4 - vmovq %rcx,%xmm5 + vmovd %ecx,%xmm5 vmovdqa IV(%rip),%xmm14 vmovdqa IV+16(%rip),%xmm15 jmp .Lblake2s_compress_avx512_mainloop -- Gitee From be9d5fa6edd2f0e93c3f20d49b4266c914327362 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 27 Nov 2025 00:06:31 +0800 Subject: [PATCH 0583/1449] s390/dasd: Fix gendisk parent after copy pair swap ANBZ: #35228 commit 075e7d288ca3ff966f8b48fa6e5fab69ced302b3 stable. commit c943bfc6afb8d0e781b9b7406f36caa8bbf95cb9 upstream. After a copy pair swap the block device's "device" symlink points to the secondary CCW device, but the gendisk's parent remained the primary, leaving /sys/block/ under the wrong parent. Move the gendisk to the secondary's device with device_move(), keeping the sysfs topology consistent after the swap. Fixes: 413862caad6f ("s390/dasd: add copy pair swap capability") Cc: stable@vger.kernel.org #6.1 Reviewed-by: Jan Hoeppner Signed-off-by: Stefan Haberland Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/s390/block/dasd_eckd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index d9fb7f097b7e..593591711415 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -6189,6 +6189,7 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid struct dasd_copy_relation *copy; struct dasd_block *block; struct gendisk *gdp; + int rc; copy = device->copy; if (!copy) @@ -6223,6 +6224,13 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid /* swap blocklayer device link */ gdp = block->gdp; dasd_add_link_to_gendisk(gdp, secondary); + rc = device_move(disk_to_dev(gdp), &secondary->cdev->dev, DPM_ORDER_NONE); + if (rc) { + dev_err(&primary->cdev->dev, + "copy_pair_swap: moving blockdevice parent %s->%s failed (%d)\n", + dev_name(&primary->cdev->dev), + dev_name(&secondary->cdev->dev), rc); + } /* re-enable device */ dasd_device_remove_stop_bits(primary, DASD_STOPPED_PPRC); -- Gitee From fce83ff28bba231719af26092d6df4ec26392185 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 17 Nov 2025 13:34:07 +0800 Subject: [PATCH 0584/1449] block: rate-limit capacity change info log ANBZ: #35228 commit 59e7ee37d5f8d4f52577e11cbde1b6f42a5b5e89 stable. commit 3179a5f7f86bcc3acd5d6fb2a29f891ef5615852 upstream. loop devices under heavy stress-ng loop streessor can trigger many capacity change events in a short time. Each event prints an info message from set_capacity_and_notify(), flooding the console and contributing to soft lockups on slow consoles. Switch the printk in set_capacity_and_notify() to pr_info_ratelimited() so frequent capacity changes do not spam the log while still reporting occasional changes. Cc: stable@vger.kernel.org Signed-off-by: Li Chen Reviewed-by: Chaitanya Kulkarni Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- block/genhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/genhd.c b/block/genhd.c index 039e7c17523b..141dcf4facd5 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -83,7 +83,7 @@ bool set_capacity_and_notify(struct gendisk *disk, sector_t size) (disk->flags & GENHD_FL_HIDDEN)) return false; - pr_info("%s: detected capacity change from %lld to %lld\n", + pr_info_ratelimited("%s: detected capacity change from %lld to %lld\n", disk->disk_name, capacity, size); /* -- Gitee From a023890419a6acb99f11b72aee800ded19c68705 Mon Sep 17 00:00:00 2001 From: Rene Rebe Date: Fri, 14 Nov 2025 21:41:27 +0800 Subject: [PATCH 0585/1449] floppy: fix for PAGE_SIZE != 4KB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 037cf435316ee4ef9146bf8c4a2e5b3f50396ccc stable. commit 82d20481024cbae2ea87fe8b86d12961bfda7169 upstream. For years I wondered why the floppy driver does not just work on sparc64, e.g: root@SUNW_375_0066:# disktype /dev/fd0 disktype: Can't open /dev/fd0: No such device or address [ 525.341906] disktype: attempt to access beyond end of device fd0: rw=0, sector=0, nr_sectors = 16 limit=8 [ 525.341991] floppy: error 10 while reading block 0 Turns out floppy.c __floppy_read_block_0 tries to read one page for the first test read to determine the disk size and thus fails if that is greater than 4k. Adjust minimum MAX_DISK_SIZE to PAGE_SIZE to fix floppy on sparc64 and likely all other PAGE_SIZE != 4KB configs. Cc: stable@vger.kernel.org Signed-off-by: René Rebe Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/floppy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index ea4eb88a2e45..419143f6cf79 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -331,7 +331,7 @@ static bool initialized; * This default is used whenever the current disk size is unknown. * [Now it is rather a minimum] */ -#define MAX_DISK_SIZE 4 /* 3984 */ +#define MAX_DISK_SIZE (PAGE_SIZE / 1024) /* * globals used by 'result()' -- Gitee From 1e3c9cf4252c1a130895ad3dcd98ae99566555b2 Mon Sep 17 00:00:00 2001 From: Zheng Yejian Date: Fri, 11 Oct 2024 22:38:53 +0800 Subject: [PATCH 0586/1449] kallsyms: Fix wrong "big" kernel symbol type read from procfs ANBZ: #35228 commit 7ad2c3ae07955bf28a7cd9bc45f69cbe114399ca stable. commit f3f9f42232dee596d15491ca3f611d02174db49c upstream. Currently when the length of a symbol is longer than 0x7f characters, its type shown in /proc/kallsyms can be incorrect. I found this issue when reading the code, but it can be reproduced by following steps: 1. Define a function which symbol length is 130 characters: #define X13(x) x##x##x##x##x##x##x##x##x##x##x##x##x static noinline void X13(x123456789)(void) { printk("hello world\n"); } 2. The type in vmlinux is 't': $ nm vmlinux | grep x123456 ffffffff816290f0 t x123456789x123456789x123456789x12[...] 3. Then boot the kernel, the type shown in /proc/kallsyms becomes 'g' instead of the expected 't': # cat /proc/kallsyms | grep x123456 ffffffff816290f0 g x123456789x123456789x123456789x12[...] The root cause is that, after commit 73bbb94466fd ("kallsyms: support "big" kernel symbols"), ULEB128 was used to encode symbol name length. That is, for "big" kernel symbols of which name length is longer than 0x7f characters, the length info is encoded into 2 bytes. kallsyms_get_symbol_type() expects to read the first char of the symbol name which indicates the symbol type. However, due to the "big" symbol case not being handled, the symbol type read from /proc/kallsyms may be wrong, so handle it properly. Cc: stable@vger.kernel.org Fixes: 73bbb94466fd ("kallsyms: support "big" kernel symbols") Signed-off-by: Zheng Yejian Acked-by: Gary Guo Link: https://patch.msgid.link/20241011143853.3022643-1-zhengyejian@huaweicloud.com Signed-off-by: Miguel Ojeda Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/kallsyms.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 97e0e30d9610..d038aa94bfab 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -103,8 +103,11 @@ static char kallsyms_get_symbol_type(unsigned int off) { /* * Get just the first code, look it up in the token table, - * and return the first char from this token. + * and return the first char from this token. If MSB of length + * is 1, it is a "big" symbol, so needs an additional byte. */ + if (kallsyms_names[off] & 0x80) + off++; return kallsyms_token_table[kallsyms_token_index[kallsyms_names[off + 1]]]; } -- Gitee From 4a37c2bd241d3cffdf2b15da36ab59f9eb4cd7d6 Mon Sep 17 00:00:00 2001 From: Konstantin Komarov Date: Thu, 18 Sep 2025 18:35:24 +0800 Subject: [PATCH 0587/1449] fs/ntfs3: fix mount failure for sparse runs in run_unpack() ANBZ: #35228 commit 5fd1a6c631b2f8c82484ae3dc8cfd7dadf209bca stable. commit 801f614ba263cb37624982b27b4c82f3c3c597a9 upstream. Some NTFS volumes failed to mount because sparse data runs were not handled correctly during runlist unpacking. The code performed arithmetic on the special SPARSE_LCN64 marker, leading to invalid LCN values and mount errors. Add an explicit check for the case described above, marking the run as sparse without applying arithmetic. Fixes: 736fc7bf5f68 ("fs: ntfs3: Fix integer overflow in run_unpack()") Cc: stable@vger.kernel.org Signed-off-by: Konstantin Komarov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/run.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c index 0139124578d9..0256fa7c879f 100644 --- a/fs/ntfs3/run.c +++ b/fs/ntfs3/run.c @@ -984,8 +984,12 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, if (!dlcn) return -EINVAL; - if (check_add_overflow(prev_lcn, dlcn, &lcn)) + /* Check special combination: 0 + SPARSE_LCN64. */ + if (!prev_lcn && dlcn == SPARSE_LCN64) { + lcn = SPARSE_LCN64; + } else if (check_add_overflow(prev_lcn, dlcn, &lcn)) { return -EINVAL; + } prev_lcn = lcn; } else return -EINVAL; -- Gitee From ab6dafc2f1e0600d705e42821a3a480ab6c93960 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 4 Dec 2025 07:09:24 +0800 Subject: [PATCH 0588/1449] ktest.pl: Fix uninitialized var in config-bisect.pl ANBZ: #35228 commit 2c0acd1a1e94819165236baf6aeaf120f31ea66b stable. commit d3042cbe84a060b4df764eb6c5300bbe20d125ca upstream. The error path of copying the old config used the wrong variable in the error message: $ mkdir /tmp/build $ ./tools/testing/ktest/config-bisect.pl -b /tmp/build config-good /tmp/config-bad $ chmod 0 /tmp/build $ ./tools/testing/ktest/config-bisect.pl -b /tmp/build config-good /tmp/config-bad good cp /tmp/build//.config config-good.tmp ... [0 seconds] FAILED! Use of uninitialized value $config in concatenation (.) or string at ./tools/testing/ktest/config-bisect.pl line 744. failed to copy to config-good.tmp When it should have shown: failed to copy /tmp/build//.config to config-good.tmp Cc: stable@vger.kernel.org Cc: John 'Warthog9' Hawley Fixes: 0f0db065999cf ("ktest: Add standalone config-bisect.pl program") Link: https://patch.msgid.link/20251203180924.6862bd26@gandalf.local.home Reported-by: "John W. Krahn" Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/ktest/config-bisect.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/ktest/config-bisect.pl b/tools/testing/ktest/config-bisect.pl index 6fd864935319..bee7cb34a289 100755 --- a/tools/testing/ktest/config-bisect.pl +++ b/tools/testing/ktest/config-bisect.pl @@ -741,9 +741,9 @@ if ($start) { die "Can not find file $bad\n"; } if ($val eq "good") { - run_command "cp $output_config $good" or die "failed to copy $config to $good\n"; + run_command "cp $output_config $good" or die "failed to copy $output_config to $good\n"; } elsif ($val eq "bad") { - run_command "cp $output_config $bad" or die "failed to copy $config to $bad\n"; + run_command "cp $output_config $bad" or die "failed to copy $output_config to $bad\n"; } } -- Gitee From a86adaed333b364d89799b95f03d519fb0b0ba5d Mon Sep 17 00:00:00 2001 From: Karina Yankevich Date: Wed, 22 Oct 2025 17:32:53 +0800 Subject: [PATCH 0589/1449] ext4: xattr: fix null pointer deref in ext4_raw_inode() ANBZ: #35228 commit b5d942922182e82724b7152cb998f540132885ec stable. commit b97cb7d6a051aa6ebd57906df0e26e9e36c26d14 upstream. If ext4_get_inode_loc() fails (e.g. if it returns -EFSCORRUPTED), iloc.bh will remain set to NULL. Since ext4_xattr_inode_dec_ref_all() lacks error checking, this will lead to a null pointer dereference in ext4_raw_inode(), called right after ext4_get_inode_loc(). Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: c8e008b60492 ("ext4: ignore xattrs past end") Cc: stable@kernel.org Signed-off-by: Karina Yankevich Reviewed-by: Sergey Shtylyov Reviewed-by: Baokun Li Message-ID: <20251022093253.3546296-1-k.yankevich@omp.ru> Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/xattr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 591638530917..29114e194264 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1191,7 +1191,11 @@ ext4_xattr_inode_dec_ref_all(handle_t *handle, struct inode *parent, if (block_csum) end = (void *)bh->b_data + bh->b_size; else { - ext4_get_inode_loc(parent, &iloc); + err = ext4_get_inode_loc(parent, &iloc); + if (err) { + EXT4_ERROR_INODE(parent, "parent inode loc (error %d)", err); + return; + } end = (void *)ext4_raw_inode(&iloc) + EXT4_SB(parent->i_sb)->s_inode_size; } -- Gitee From aa8cebaf974b39454b853859e4eedddbf90c51eb Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Tue, 4 Nov 2025 16:12:24 +0800 Subject: [PATCH 0590/1449] ext4: clear i_state_flags when alloc inode ANBZ: #35228 commit 36bf0f765333411755d695c15939032ea7710346 stable. commit 4091c8206cfd2e3bb529ef260887296b90d9b6a2 upstream. i_state_flags used on 32-bit archs, need to clear this flag when alloc inode. Find this issue when umount ext4, sometimes track the inode as orphan accidently, cause ext4 mesg dump. Fixes: acf943e9768e ("ext4: fix checks for orphan inodes") Signed-off-by: Haibo Chen Reviewed-by: Baokun Li Reviewed-by: Zhang Yi Reviewed-by: Jan Kara Message-ID: <20251104-ext4-v1-1-73691a0800f9@nxp.com> Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/ialloc.c | 1 - fs/ext4/inode.c | 1 - fs/ext4/super.c | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 97223746a15f..18fcd468d20e 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1299,7 +1299,6 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap, sizeof(gen)); } - ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */ ext4_set_inode_state(inode, EXT4_STATE_NEW); ei->i_extra_isize = sbi->s_want_extra_isize; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2908c8637dc5..da778bcbd6ec 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4996,7 +4996,6 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, ei->i_projid = make_kprojid(&init_user_ns, i_projid); set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); - ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */ ei->i_inline_off = 0; ei->i_dir_start_lookup = 0; ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index babf9da6f4a8..e22761903eb3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1452,6 +1452,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) inode_set_iversion(&ei->vfs_inode, 1); ei->i_flags = 0; + ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */ spin_lock_init(&ei->i_raw_lock); ei->i_prealloc_node = RB_ROOT; atomic_set(&ei->i_prealloc_active, 0); -- Gitee From 98fa52f827a817b6ad15f424e29b1e7e90b5eb85 Mon Sep 17 00:00:00 2001 From: Yongjian Sun Date: Thu, 6 Nov 2025 14:06:13 +0800 Subject: [PATCH 0591/1449] ext4: fix incorrect group number assertion in mb_check_buddy ANBZ: #35228 commit dc06c9dc5e1d54f745dc2016b1520f1d5e85888c stable. commit 3f7a79d05c692c7cfec70bf104b1b3c3d0ce6247 upstream. When the MB_CHECK_ASSERT macro is enabled, an assertion failure can occur in __mb_check_buddy when checking preallocated blocks (pa) in a block group: Assertion failure in mb_free_blocks() : "groupnr == e4b->bd_group" This happens when a pa at the very end of a block group (e.g., pa_pstart=32765, pa_len=3 in a group of 32768 blocks) becomes exhausted - its pa_pstart is advanced by pa_len to 32768, which lies in the next block group. If this exhausted pa (with pa_len == 0) is still in the bb_prealloc_list during the buddy check, the assertion incorrectly flags it as belonging to the wrong group. A possible sequence is as follows: ext4_mb_new_blocks ext4_mb_release_context pa->pa_pstart += EXT4_C2B(sbi, ac->ac_b_ex.fe_len) pa->pa_len -= ac->ac_b_ex.fe_len __mb_check_buddy for each pa in group ext4_get_group_no_and_offset MB_CHECK_ASSERT(groupnr == e4b->bd_group) To fix this, we modify the check to skip block group validation for exhausted preallocations (where pa_len == 0). Such entries are in a transitional state and will be removed from the list soon, so they should not trigger an assertion. This change prevents the false positive while maintaining the integrity of the checks for active allocations. Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") Signed-off-by: Yongjian Sun Reviewed-by: Baokun Li Reviewed-by: Jan Kara Message-ID: <20251106060614.631382-2-sunyongjian@huaweicloud.com> Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/mballoc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 8a8b54e640bc..3896440a7ca1 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -782,6 +782,8 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, ext4_group_t groupnr; struct ext4_prealloc_space *pa; pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list); + if (!pa->pa_len) + continue; ext4_get_group_no_and_offset(sb, pa->pa_pstart, &groupnr, &k); MB_CHECK_ASSERT(groupnr == e4b->bd_group); for (i = 0; i < pa->pa_len; i++) -- Gitee From fae4464a3e8b0b5ab76ae09e4544bb766ab49ac2 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Thu, 20 Nov 2025 21:42:33 +0800 Subject: [PATCH 0592/1449] ext4: align max orphan file size with e2fsprogs limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 79a0e4d3fbef7c8ca3fd5e5b5c00d79cd399cd46 stable. commit 7c11c56eb32eae96893eebafdbe3decadefe88ad upstream. Kernel commit 0a6ce20c1564 ("ext4: verify orphan file size is not too big") limits the maximum supported orphan file size to 8 << 20. However, in e2fsprogs, the orphan file size is set to 32–512 filesystem blocks when creating a filesystem. With 64k block size, formatting an ext4 fs >32G gives an orphan file bigger than the kernel allows, so mount prints an error and fails: EXT4-fs (vdb): orphan file too big: 8650752 EXT4-fs (vdb): mount failed To prevent this issue and allow previously created 64KB filesystems to mount, we updates the maximum allowed orphan file size in the kernel to 512 filesystem blocks. Fixes: 0a6ce20c1564 ("ext4: verify orphan file size is not too big") Signed-off-by: Baokun Li Reviewed-by: Jan Kara Message-ID: <20251120134233.2994147-1-libaokun@huaweicloud.com> Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/orphan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c index 05997b4d0120..e5a6cb533242 100644 --- a/fs/ext4/orphan.c +++ b/fs/ext4/orphan.c @@ -8,6 +8,8 @@ #include "ext4.h" #include "ext4_jbd2.h" +#define EXT4_MAX_ORPHAN_FILE_BLOCKS 512 + static int ext4_orphan_file_add(handle_t *handle, struct inode *inode) { int i, j, start; @@ -589,7 +591,7 @@ int ext4_init_orphan_info(struct super_block *sb) * consuming absurd amounts of memory when pinning blocks of orphan * file in memory. */ - if (inode->i_size > 8 << 20) { + if (inode->i_size > (EXT4_MAX_ORPHAN_FILE_BLOCKS << inode->i_blkbits)) { ext4_msg(sb, KERN_ERR, "orphan file too big: %llu", (unsigned long long)inode->i_size); ret = -EFSCORRUPTED; -- Gitee From ac417bb11888fa88d109a413b760aa5554ee7d84 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Wed, 22 Oct 2025 20:11:37 +0900 Subject: [PATCH 0593/1449] jbd2: use a per-journal lock_class_key for jbd2_trans_commit_key ANBZ: #35228 commit 815327958ec41b0a2df2a50a01578d5cc8f36ae4 stable. commit 524c3853831cf4f7e1db579e487c757c3065165c upstream. syzbot is reporting possibility of deadlock due to sharing lock_class_key for jbd2_handle across ext4 and ocfs2. But this is a false positive, for one disk partition can't have two filesystems at the same time. Reported-by: syzbot+6e493c165d26d6fcbf72@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6e493c165d26d6fcbf72 Signed-off-by: Tetsuo Handa Tested-by: syzbot+6e493c165d26d6fcbf72@syzkaller.appspotmail.com Reviewed-by: Jan Kara Message-ID: <987110fc-5470-457a-a218-d286a09dd82f@I-love.SAKURA.ne.jp> Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- fs/jbd2/journal.c | 6 ++++-- include/linux/jbd2.h | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index fbc28a9d36cb..b992fe219db2 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1974,7 +1974,6 @@ static journal_t *journal_init_common(struct block_device *bdev, struct block_device *fs_dev, unsigned long long start, int len, int blocksize) { - static struct lock_class_key jbd2_trans_commit_key; journal_t *journal; int err; int n; @@ -1983,6 +1982,7 @@ static journal_t *journal_init_common(struct block_device *bdev, if (!journal) return ERR_PTR(-ENOMEM); + lockdep_register_key(&journal->jbd2_trans_commit_key); journal->j_blocksize = blocksize; journal->j_dev = bdev; journal->j_fs_dev = fs_dev; @@ -2015,7 +2015,7 @@ static journal_t *journal_init_common(struct block_device *bdev, journal->j_stall_thresh = JBD2_DEFAULT_TRANS_STALL_THRESH; atomic_set(&journal->j_reserved_credits, 0); lockdep_init_map(&journal->j_trans_commit_map, "jbd2_handle", - &jbd2_trans_commit_key, 0); + &journal->jbd2_trans_commit_key, 0); /* The journal is marked for error until we succeed with recovery! */ journal->j_flags = JBD2_ABORT; @@ -2069,6 +2069,7 @@ static journal_t *journal_init_common(struct block_device *bdev, kfree(journal->j_wbuf); jbd2_journal_destroy_revoke(journal); journal_fail_superblock(journal); + lockdep_unregister_key(&journal->jbd2_trans_commit_key); kfree(journal); return ERR_PTR(err); } @@ -2653,6 +2654,7 @@ int jbd2_journal_destroy(journal_t *journal) crypto_free_shash(journal->j_chksum_driver); kfree(journal->j_fc_wbuf); kfree(journal->j_wbuf); + lockdep_unregister_key(&journal->jbd2_trans_commit_key); kfree(journal); return err; diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 5ae8f81d6fe4..65825c598422 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -1307,6 +1307,13 @@ struct journal_s bool proxy_exec; bool proxy_exec_for_highclass; + /** + * @jbd2_trans_commit_key: + * + * "struct lock_class_key" for @j_trans_commit_map + */ + struct lock_class_key jbd2_trans_commit_key; + /** * @j_fc_cleanup_callback: * -- Gitee From d74a5bb8a0d5bce2369010d45e0a8013c1af3c14 Mon Sep 17 00:00:00 2001 From: Byungchul Park Date: Fri, 24 Oct 2025 15:39:40 +0800 Subject: [PATCH 0594/1449] jbd2: use a weaker annotation in journal handling ANBZ: #35228 commit 94a16a3a100171a63fde4176b3ddf7aeda104a2f stable. commit 40a71b53d5a6d4ea17e4d54b99b2ac03a7f5e783 upstream. jbd2 journal handling code doesn't want jbd2_might_wait_for_commit() to be placed between start_this_handle() and stop_this_handle(). So it marks the region with rwsem_acquire_read() and rwsem_release(). However, the annotation is too strong for that purpose. We don't have to use more than try lock annotation for that. rwsem_acquire_read() implies: 1. might be a waiter on contention of the lock. 2. enter to the critical section of the lock. All we need in here is to act 2, not 1. So trylock version of annotation is sufficient for that purpose. Now that dept partially relies on lockdep annotaions, dept interpets rwsem_acquire_read() as a potential wait and might report a deadlock by the wait. Replace it with trylock version of annotation. Signed-off-by: Byungchul Park Reviewed-by: Jan Kara Cc: stable@kernel.org Message-ID: <20251024073940.1063-1-byungchul@sk.com> Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/jbd2/transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index e6f507c3a685..a79a0bee019e 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -447,7 +447,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle, read_unlock(&journal->j_state_lock); current->journal_info = handle; - rwsem_acquire_read(&journal->j_trans_commit_map, 0, 0, _THIS_IP_); + rwsem_acquire_read(&journal->j_trans_commit_map, 0, 1, _THIS_IP_); jbd2_journal_free_transaction(new_transaction); /* * Ensure that no allocations done while the transaction is open are -- Gitee From 11a22bd84090bd82ee5959b62cf00d6b7aa6cd7f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 8 Oct 2025 17:55:18 +0800 Subject: [PATCH 0595/1449] media: v4l2-mem2mem: Fix outdated documentation ANBZ: #35228 commit fa4a445f832b185ca5f9975aa329a7be7b5f0343 stable. commit 082b86919b7a94de01d849021b4da820a6cb89dc upstream. Commit cbd9463da1b1 ("media: v4l2-mem2mem: Avoid calling .device_run in v4l2_m2m_job_finish") deferred calls to .device_run() to a work queue to avoid recursive calls when a job is finished right away from .device_run(). It failed to update the v4l2_m2m_job_finish() documentation that still states the function must not be called from .device_run(). Fix it. Fixes: cbd9463da1b1 ("media: v4l2-mem2mem: Avoid calling .device_run in v4l2_m2m_job_finish") Cc: stable@vger.kernel.org Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/media/v4l2-mem2mem.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index d6c8eb2b5201..370c230ad3be 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -185,8 +185,7 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); * other instances to take control of the device. * * This function has to be called only after &v4l2_m2m_ops->device_run - * callback has been called on the driver. To prevent recursion, it should - * not be called directly from the &v4l2_m2m_ops->device_run callback though. + * callback has been called on the driver. */ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx); -- Gitee From 3466f970e295a38068b2be4b107b0de89a6741d7 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Sat, 6 Dec 2025 02:55:16 +0800 Subject: [PATCH 0596/1449] mptcp: schedule rtx timer only after pushing data ANBZ: #35228 commit 17b470ee53ddc9e636596c1e9c69e1bce7d42793 stable. commit 2ea6190f42d0416a4310e60a7fcb0b49fcbbd4fb upstream. The MPTCP protocol usually schedule the retransmission timer only when there is some chances for such retransmissions to happen. With a notable exception: __mptcp_push_pending() currently schedule such timer unconditionally, potentially leading to unnecessary rtx timer expiration. The issue is present since the blamed commit below but become easily reproducible after commit 27b0e701d387 ("mptcp: drop bogus optimization in __mptcp_check_push()") Fixes: 33d41c9cd74c ("mptcp: more accurate timeout") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251205-net-mptcp-misc-fixes-6-19-rc1-v1-3-9e4781a6c1b8@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 816cf39dfa1e..22f22f494ce9 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1630,7 +1630,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) struct mptcp_sendmsg_info info = { .flags = flags, }; - bool do_check_data_fin = false; + bool copied = false; int push_count = 1; while (mptcp_send_head(sk) && (push_count > 0)) { @@ -1672,7 +1672,7 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) push_count--; continue; } - do_check_data_fin = true; + copied = true; } } } @@ -1681,11 +1681,14 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) if (ssk) mptcp_push_release(ssk, &info); - /* ensure the rtx timer is running */ - if (!mptcp_rtx_timer_pending(sk)) - mptcp_reset_rtx_timer(sk); - if (do_check_data_fin) + /* Avoid scheduling the rtx timer if no data has been pushed; the timer + * will be updated on positive acks by __mptcp_cleanup_una(). + */ + if (copied) { + if (!mptcp_rtx_timer_pending(sk)) + mptcp_reset_rtx_timer(sk); mptcp_check_send_data_fin(sk); + } } static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool first) -- Gitee From ff642a3e1786d672f72511eae5c9d68d8f783364 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Sat, 6 Dec 2025 02:55:17 +0800 Subject: [PATCH 0597/1449] mptcp: avoid deadlock on fallback while reinjecting ANBZ: #35228 commit 252892d5a6a2f163ce18f32716e46fa4da7d4e79 stable. commit ffb8c27b0539dd90262d1021488e7817fae57c42 upstream. Jakub reported an MPTCP deadlock at fallback time: WARNING: possible recursive locking detected 6.18.0-rc7-virtme #1 Not tainted -------------------------------------------- mptcp_connect/20858 is trying to acquire lock: ff1100001da18b60 (&msk->fallback_lock){+.-.}-{3:3}, at: __mptcp_try_fallback+0xd8/0x280 but task is already holding lock: ff1100001da18b60 (&msk->fallback_lock){+.-.}-{3:3}, at: __mptcp_retrans+0x352/0xaa0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&msk->fallback_lock); lock(&msk->fallback_lock); *** DEADLOCK *** May be due to missing lock nesting notation 3 locks held by mptcp_connect/20858: #0: ff1100001da18290 (sk_lock-AF_INET){+.+.}-{0:0}, at: mptcp_sendmsg+0x114/0x1bc0 #1: ff1100001db40fd0 (k-sk_lock-AF_INET#2){+.+.}-{0:0}, at: __mptcp_retrans+0x2cb/0xaa0 #2: ff1100001da18b60 (&msk->fallback_lock){+.-.}-{3:3}, at: __mptcp_retrans+0x352/0xaa0 stack backtrace: CPU: 0 UID: 0 PID: 20858 Comm: mptcp_connect Not tainted 6.18.0-rc7-virtme #1 PREEMPT(full) Hardware name: Bochs, BIOS Bochs 01/01/2011 Call Trace: dump_stack_lvl+0x6f/0xa0 print_deadlock_bug.cold+0xc0/0xcd validate_chain+0x2ff/0x5f0 __lock_acquire+0x34c/0x740 lock_acquire.part.0+0xbc/0x260 _raw_spin_lock_bh+0x38/0x50 __mptcp_try_fallback+0xd8/0x280 mptcp_sendmsg_frag+0x16c2/0x3050 __mptcp_retrans+0x421/0xaa0 mptcp_release_cb+0x5aa/0xa70 release_sock+0xab/0x1d0 mptcp_sendmsg+0xd5b/0x1bc0 sock_write_iter+0x281/0x4d0 new_sync_write+0x3c5/0x6f0 vfs_write+0x65e/0xbb0 ksys_write+0x17e/0x200 do_syscall_64+0xbb/0xfd0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7fa5627cbc5e Code: 4d 89 d8 e8 14 bd 00 00 4c 8b 5d f8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 11 c9 c3 0f 1f 80 00 00 00 00 48 8b 45 10 0f 05 c3 83 e2 39 83 fa 08 75 e7 e8 13 ff ff ff 0f 1f 00 f3 0f 1e fa RSP: 002b:00007fff1fe14700 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007fa5627cbc5e RDX: 0000000000001f9c RSI: 00007fff1fe16984 RDI: 0000000000000005 RBP: 00007fff1fe14710 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000202 R12: 00007fff1fe16920 R13: 0000000000002000 R14: 0000000000001f9c R15: 0000000000001f9c The packet scheduler could attempt a reinjection after receiving an MP_FAIL and before the infinite map has been transmitted, causing a deadlock since MPTCP needs to do the reinjection atomically from WRT fallback. Address the issue explicitly avoiding the reinjection in the critical scenario. Note that this is the only fallback critical section that could potentially send packets and hit the double-lock. Reported-by: Jakub Kicinski Closes: https://netdev-ctrl.bots.linux.dev/logs/vmksft/mptcp-dbg/results/412720/1-mptcp-join-sh/stderr Fixes: f8a1d9b18c5e ("mptcp: make fallback action and fallback decision atomic") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251205-net-mptcp-misc-fixes-6-19-rc1-v1-4-9e4781a6c1b8@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 22f22f494ce9..5ee00824a0a5 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2712,10 +2712,13 @@ static void __mptcp_retrans(struct sock *sk) /* * make the whole retrans decision, xmit, disallow - * fallback atomic + * fallback atomic, note that we can't retrans even + * when an infinite fallback is in progress, i.e. new + * subflows are disallowed. */ spin_lock_bh(&msk->fallback_lock); - if (__mptcp_check_fallback(msk)) { + if (__mptcp_check_fallback(msk) || + !msk->allow_subflows) { spin_unlock_bh(&msk->fallback_lock); release_sock(ssk); goto clear_scheduled; -- Gitee From 7b6a8712e407e42e891a6d52357e3710d7c22e43 Mon Sep 17 00:00:00 2001 From: Chen Changcheng Date: Thu, 18 Dec 2025 09:23:18 +0800 Subject: [PATCH 0598/1449] usb: usb-storage: Maintain minimal modifications to the bcdDevice range. ANBZ: #35228 commit 22847606976c321a172dba01cc0a7bd540a027ec stable. commit 0831269b5f71594882accfceb02638124f88955d upstream. We cannot determine which models require the NO_ATA_1X and IGNORE_RESIDUE quirks aside from the EL-R12 optical drive device. Fixes: 955a48a5353f ("usb: usb-storage: No additional quirks need to be added to the EL-R12 optical drive.") Signed-off-by: Chen Changcheng Link: https://patch.msgid.link/20251218012318.15978-1-chenchangcheng@kylinos.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/storage/unusual_uas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index b695f5ba9a40..939a98c2d3f7 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -98,7 +98,7 @@ UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160, US_FL_NO_ATA_1X), /* Reported-by: Benjamin Tissoires */ -UNUSUAL_DEV(0x13fd, 0x3940, 0x0309, 0x0309, +UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x0309, "Initio Corporation", "INIC-3069", USB_SC_DEVICE, USB_PR_DEVICE, NULL, -- Gitee From f2e46835a88ed376a801ab36879b9f74039a9e65 Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Mon, 21 Apr 2025 20:52:44 +0800 Subject: [PATCH 0599/1449] media: dvb-usb: dtv5100: fix out-of-bounds in dtv5100_i2c_msg() ANBZ: #35228 commit 4a54d8fcb093761e4c56eb211cf4e39bf8401fa1 stable. commit b91e6aafe8d356086cc621bc03e35ba2299e4788 upstream. rlen value is a user-controlled value, but dtv5100_i2c_msg() does not check the size of the rlen value. Therefore, if it is set to a value larger than sizeof(st->data), an out-of-bounds vuln occurs for st->data. Therefore, we need to add proper range checking to prevent this vuln. Fixes: 60688d5e6e6e ("V4L/DVB (8735): dtv5100: replace dummy frontend by zl10353") Cc: stable@vger.kernel.org Signed-off-by: Jeongjun Park Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/usb/dvb-usb/dtv5100.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c index 56c9d521a34a..ee8a76fb5cc1 100644 --- a/drivers/media/usb/dvb-usb/dtv5100.c +++ b/drivers/media/usb/dvb-usb/dtv5100.c @@ -55,6 +55,11 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, } index = (addr << 8) + wbuf[0]; + if (rlen > sizeof(st->data)) { + warn("rlen = %x is too big!\n", rlen); + return -EINVAL; + } + memcpy(st->data, rbuf, rlen); msleep(1); /* avoid I2C errors */ return usb_control_msg(d->udev, pipe, request, -- Gitee From eb4d069c7d42baa8c057c4ffd9e5708464bf10b7 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 3 Sep 2025 16:44:16 +0800 Subject: [PATCH 0600/1449] media: pvrusb2: Fix incorrect variable used in trace message ANBZ: #35228 commit f4cacf8827ba0c72c83f024128f97bf9bf72ea01 stable. commit be440980eace19c035a0745fd6b6e42707bc4f49 upstream. The pvr2_trace message is reporting an error about control read transfers, however it is using the incorrect variable write_len instead of read_lean. Fix this by using the correct variable read_len. Fixes: d855497edbfb ("V4L/DVB (4228a): pvrusb2 to kernel 2.6.18") Cc: stable@vger.kernel.org Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 29cc207194b9..2de104736f87 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -3622,7 +3622,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, pvr2_trace( PVR2_TRACE_ERROR_LEGS, "Attempted to execute %d byte control-read transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); + read_len, PVR2_CTL_BUFFSIZE); return -EINVAL; } if ((!write_len) && (!read_len)) { -- Gitee From 1edf048ecc00f9b43dd1b631a784823b0472c86a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 17 Oct 2025 13:45:37 +0800 Subject: [PATCH 0601/1449] phy: broadcom: bcm63xx-usbh: fix section mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4824123c9f8741c3167b8aed922fe209a2878977 stable. commit 356d1924b9a6bc2164ce2bf1fad147b0c37ae085 upstream. Platform drivers can be probed after their init sections have been discarded (e.g. on probe deferral or manual rebind through sysfs) so the probe function and match table must not live in init. Fixes: 783f6d3dcf35 ("phy: bcm63xx-usbh: Add BCM63xx USBH driver") Cc: stable@vger.kernel.org # 5.9 Cc: Álvaro Fernández Rojas Signed-off-by: Johan Hovold Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20251017054537.6884-1-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/broadcom/phy-bcm63xx-usbh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/phy/broadcom/phy-bcm63xx-usbh.c b/drivers/phy/broadcom/phy-bcm63xx-usbh.c index f8183dea774b..ec17930dcf2c 100644 --- a/drivers/phy/broadcom/phy-bcm63xx-usbh.c +++ b/drivers/phy/broadcom/phy-bcm63xx-usbh.c @@ -375,7 +375,7 @@ static struct phy *bcm63xx_usbh_phy_xlate(struct device *dev, return of_phy_simple_xlate(dev, args); } -static int __init bcm63xx_usbh_phy_probe(struct platform_device *pdev) +static int bcm63xx_usbh_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct bcm63xx_usbh_phy *usbh; @@ -432,7 +432,7 @@ static int __init bcm63xx_usbh_phy_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id bcm63xx_usbh_phy_ids[] __initconst = { +static const struct of_device_id bcm63xx_usbh_phy_ids[] = { { .compatible = "brcm,bcm6318-usbh-phy", .data = &usbh_bcm6318 }, { .compatible = "brcm,bcm6328-usbh-phy", .data = &usbh_bcm6328 }, { .compatible = "brcm,bcm6358-usbh-phy", .data = &usbh_bcm6358 }, @@ -443,7 +443,7 @@ static const struct of_device_id bcm63xx_usbh_phy_ids[] __initconst = { }; MODULE_DEVICE_TABLE(of, bcm63xx_usbh_phy_ids); -static struct platform_driver bcm63xx_usbh_phy_driver __refdata = { +static struct platform_driver bcm63xx_usbh_phy_driver = { .driver = { .name = "bcm63xx-usbh-phy", .of_match_table = bcm63xx_usbh_phy_ids, -- Gitee From ac99225644ba803f4f99a1e786906b21912c9552 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Mon, 15 Dec 2025 10:09:31 +0800 Subject: [PATCH 0602/1449] USB: lpc32xx_udc: Fix error handling in probe ANBZ: #35228 commit 8481323710062051b3c42bff94ee5b18a2b496ca stable. commit c84117912bddd9e5d87e68daf182410c98181407 upstream. lpc32xx_udc_probe() acquires an i2c_client reference through isp1301_get_client() but fails to release it in both error handling paths and the normal removal path. This could result in a reference count leak for the I2C device, preventing proper cleanup and potentially leading to resource exhaustion. Add put_device() to release the reference in the probe failure path and in the remove function. Calling path: isp1301_get_client() -> of_find_i2c_device_by_node() -> i2c_find_device_by_fwnode(). As comments of i2c_find_device_by_fwnode() says, 'The user must call put_device(&client->dev) once done with the i2c client.' Found by code review. Cc: stable Fixes: 24a28e428351 ("USB: gadget driver for LPC32xx") Signed-off-by: Ma Ke Link: https://patch.msgid.link/20251215020931.15324-1-make24@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/udc/lpc32xx_udc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index fe62db32dd0e..6085ffd0c470 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3027,7 +3027,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) pdev->dev.dma_mask = &lpc32xx_usbd_dmamask; retval = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (retval) - return retval; + goto i2c_fail; udc->board = &lpc32xx_usbddata; @@ -3045,28 +3045,32 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) /* Get IRQs */ for (i = 0; i < 4; i++) { udc->udp_irq[i] = platform_get_irq(pdev, i); - if (udc->udp_irq[i] < 0) - return udc->udp_irq[i]; + if (udc->udp_irq[i] < 0) { + retval = udc->udp_irq[i]; + goto i2c_fail; + } } udc->udp_baseaddr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(udc->udp_baseaddr)) { dev_err(udc->dev, "IO map failure\n"); - return PTR_ERR(udc->udp_baseaddr); + retval = PTR_ERR(udc->udp_baseaddr); + goto i2c_fail; } /* Get USB device clock */ udc->usb_slv_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(udc->usb_slv_clk)) { dev_err(udc->dev, "failed to acquire USB device clock\n"); - return PTR_ERR(udc->usb_slv_clk); + retval = PTR_ERR(udc->usb_slv_clk); + goto i2c_fail; } /* Enable USB device clock */ retval = clk_prepare_enable(udc->usb_slv_clk); if (retval < 0) { dev_err(udc->dev, "failed to start USB device clock\n"); - return retval; + goto i2c_fail; } /* Setup deferred workqueue data */ @@ -3168,6 +3172,8 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); i2c_fail: + if (udc->isp1301_i2c_client) + put_device(&udc->isp1301_i2c_client->dev); clk_disable_unprepare(udc->usb_slv_clk); dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval); @@ -3193,6 +3199,9 @@ static int lpc32xx_udc_remove(struct platform_device *pdev) dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); + if (udc->isp1301_i2c_client) + put_device(&udc->isp1301_i2c_client->dev); + clk_disable_unprepare(udc->usb_slv_clk); return 0; -- Gitee From 9b75bf1fafa57ca500cbcc3f743b2dfbf8978954 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Fri, 5 Dec 2025 11:48:31 +0800 Subject: [PATCH 0603/1449] usb: phy: fsl-usb: Fix use-after-free in delayed work during device removal ANBZ: #35228 commit 319f7a85b3c4e34ac2fe083eb146fe129a556317 stable. commit 41ca62e3e21e48c2903b3b45e232cf4f2ff7434f upstream. The delayed work item otg_event is initialized in fsl_otg_conf() and scheduled under two conditions: 1. When a host controller binds to the OTG controller. 2. When the USB ID pin state changes (cable insertion/removal). A race condition occurs when the device is removed via fsl_otg_remove(): the fsl_otg instance may be freed while the delayed work is still pending or executing. This leads to use-after-free when the work function fsl_otg_event() accesses the already freed memory. The problematic scenario: (detach thread) | (delayed work) fsl_otg_remove() | kfree(fsl_otg_dev) //FREE| fsl_otg_event() | og = container_of(...) //USE | og-> //USE Fix this by calling disable_delayed_work_sync() in fsl_otg_remove() before deallocating the fsl_otg structure. This ensures the delayed work is properly canceled and completes execution prior to memory deallocation. This bug was identified through static analysis. Fixes: 0807c500a1a6 ("USB: add Freescale USB OTG Transceiver driver") Cc: stable Signed-off-by: Duoming Zhou Link: https://patch.msgid.link/20251205034831.12846-1-duoming@zju.edu.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/phy/phy-fsl-usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index 79617bb0a70e..552899fa985e 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -987,6 +987,7 @@ static void fsl_otg_remove(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); + disable_delayed_work_sync(&fsl_otg_dev->otg_event); usb_remove_phy(&fsl_otg_dev->phy); free_irq(fsl_otg_dev->irq, fsl_otg_dev); -- Gitee From 325c6747e95032ebdc400ecd2f0d4ea3e08ef710 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 18 Dec 2025 23:35:16 +0800 Subject: [PATCH 0604/1449] usb: phy: isp1301: fix non-OF device reference imbalance ANBZ: #35228 commit 75c5d9bce072abbbc09b701a49869ac23c34a906 stable. commit b4b64fda4d30a83a7f00e92a0c8a1d47699609f3 upstream. A recent change fixing a device reference leak in a UDC driver introduced a potential use-after-free in the non-OF case as the isp1301_get_client() helper only increases the reference count for the returned I2C device in the OF case. Increment the reference count also for non-OF so that the caller can decrement it unconditionally. Note that this is inherently racy just as using the returned I2C device is since nothing is preventing the PHY driver from being unbound while in use. Fixes: c84117912bdd ("USB: lpc32xx_udc: Fix error handling in probe") Cc: stable@vger.kernel.org Cc: Ma Ke Signed-off-by: Johan Hovold Reviewed-by: Vladimir Zapolskiy Link: https://patch.msgid.link/20251218153519.19453-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/phy/phy-isp1301.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index 993d7525a102..183866b7fce2 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c @@ -149,7 +149,12 @@ struct i2c_client *isp1301_get_client(struct device_node *node) return client; /* non-DT: only one ISP1301 chip supported */ - return isp1301_i2c_client; + if (isp1301_i2c_client) { + get_device(&isp1301_i2c_client->dev); + return isp1301_i2c_client; + } + + return NULL; } EXPORT_SYMBOL_GPL(isp1301_get_client); -- Gitee From c50b6ba04688f76e1b4c5eba6a9743416665401e Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 11 Dec 2025 14:49:36 +0800 Subject: [PATCH 0605/1449] usb: dwc3: of-simple: fix clock resource leak in dwc3_of_simple_probe ANBZ: #35228 commit fa8747590b0e6c4f16ee3ca24dc17188207e818e stable. commit 3b4961313d31e200c9e974bb1536cdea217f78b5 upstream. When clk_bulk_prepare_enable() fails, the error path jumps to err_resetc_assert, skipping clk_bulk_put_all() and leaking the clock references acquired by clk_bulk_get_all(). Add err_clk_put_all label to properly release clock resources in all error paths. Found via static analysis and code review. Fixes: c0c61471ef86 ("usb: dwc3: of-simple: Convert to bulk clk API") Cc: stable Signed-off-by: Miaoqian Lin Acked-by: Thinh Nguyen Link: https://patch.msgid.link/20251211064937.2360510-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/dwc3-of-simple.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index d1539fc9eabd..793baffad6ce 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -71,11 +71,11 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) simple->num_clocks = ret; ret = clk_bulk_prepare_enable(simple->num_clocks, simple->clks); if (ret) - goto err_resetc_assert; + goto err_clk_put_all; ret = of_platform_populate(np, NULL, NULL, dev); if (ret) - goto err_clk_put; + goto err_clk_disable; pm_runtime_set_active(dev); pm_runtime_enable(dev); @@ -83,8 +83,9 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) return 0; -err_clk_put: +err_clk_disable: clk_bulk_disable_unprepare(simple->num_clocks, simple->clks); +err_clk_put_all: clk_bulk_put_all(simple->num_clocks, simple->clks); err_resetc_assert: -- Gitee From b2662326221f11bc3f1ac9e496d228a518134410 Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Wed, 26 Nov 2025 13:42:21 +0800 Subject: [PATCH 0606/1449] usb: dwc3: keep susphy enabled during exit to avoid controller faults ANBZ: #35228 commit 679e15fb53f9ac8af2623355820318ae80618cbd stable. commit e1003aa7ec9eccdde4c926bd64ef42816ad55f25 upstream. On some platforms, switching USB roles from host to device can trigger controller faults due to premature PHY power-down. This occurs when the PHY is disabled too early during teardown, causing synchronization issues between the PHY and controller. Keep susphy enabled during dwc3_host_exit() and dwc3_gadget_exit() ensures the PHY remains in a low-power state capable of handling required commands during role switch. Cc: stable Fixes: 6d735722063a ("usb: dwc3: core: Prevent phy suspend during init") Suggested-by: Thinh Nguyen Signed-off-by: Udipto Goswami Acked-by: Thinh Nguyen Link: https://patch.msgid.link/20251126054221.120638-1-udipto.goswami@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/gadget.c | 2 +- drivers/usb/dwc3/host.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 821e51eada18..8781ebeaab90 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -4807,7 +4807,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) if (!dwc->gadget) return; - dwc3_enable_susphy(dwc, false); + dwc3_enable_susphy(dwc, true); usb_del_gadget(dwc->gadget); dwc3_gadget_free_endpoints(dwc); usb_put_gadget(dwc->gadget); diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 6c143f7d2410..42510a3f8c39 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -168,7 +168,7 @@ void dwc3_host_exit(struct dwc3 *dwc) if (dwc->sys_wakeup) device_init_wakeup(&dwc->xhci->dev, false); - dwc3_enable_susphy(dwc, false); + dwc3_enable_susphy(dwc, true); platform_device_unregister(dwc->xhci); dwc->xhci = NULL; } -- Gitee From 096d87d963fd14b12df3993819d43d8ad70ca1f7 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 4 Dec 2025 21:21:29 +0800 Subject: [PATCH 0607/1449] usb: renesas_usbhs: Fix a resource leak in usbhs_pipe_malloc() ANBZ: #35228 commit 96e001d20405a6383d1ad428e365a3833697f9fe stable. commit 36cc7e09df9e43db21b46519b740145410dd9f4a upstream. usbhsp_get_pipe() set pipe's flags to IS_USED. In error paths, usbhsp_put_pipe() is required to clear pipe's flags to prevent pipe exhaustion. Fixes: f1407d5c6624 ("usb: renesas_usbhs: Add Renesas USBHS common code") Cc: stable Signed-off-by: Haoxiang Li Link: https://patch.msgid.link/20251204132129.109234-1-haoxiang_li2024@163.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/renesas_usbhs/pipe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 75fff2e4cbc6..56fc3ff5016f 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -713,11 +713,13 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, /* make sure pipe is not busy */ ret = usbhsp_pipe_barrier(pipe); if (ret < 0) { + usbhsp_put_pipe(pipe); dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe)); return NULL; } if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) { + usbhsp_put_pipe(pipe); dev_err(dev, "can't setup pipe\n"); return NULL; } -- Gitee From cf2839825cae62d38d1e54bdcd601362dbd05853 Mon Sep 17 00:00:00 2001 From: Tianchu Chen Date: Fri, 28 Nov 2025 15:53:23 +0800 Subject: [PATCH 0608/1449] char: applicom: fix NULL pointer dereference in ac_ioctl ANBZ: #35228 commit d285517429a75423789e6408653e57b6fdfc8e54 stable. commit 82d12088c297fa1cef670e1718b3d24f414c23f7 upstream. Discovered by Atuin - Automated Vulnerability Discovery Engine. In ac_ioctl, the validation of IndexCard and the check for a valid RamIO pointer are skipped when cmd is 6. However, the function unconditionally executes readb(apbs[IndexCard].RamIO + VERS) at the end. If cmd is 6, IndexCard may reference a board that does not exist (where RamIO is NULL), leading to a NULL pointer dereference. Fix this by skipping the readb access when cmd is 6, as this command is a global information query and does not target a specific board context. Signed-off-by: Tianchu Chen Acked-by: Arnd Bergmann Cc: stable Link: https://patch.msgid.link/20251128155323.a786fde92ebb926cbe96fcb1@linux.dev Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/char/applicom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 69314532f38c..70c07d7e590a 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -836,7 +836,10 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = -ENOTTY; break; } - Dummy = readb(apbs[IndexCard].RamIO + VERS); + + if (cmd != 6) + Dummy = readb(apbs[IndexCard].RamIO + VERS); + kfree(adgl); mutex_unlock(&ac_mutex); return ret; -- Gitee From 7bbb3d830908feb110611aefa8408532a9282bf4 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Wed, 12 Nov 2025 17:17:23 +0800 Subject: [PATCH 0609/1449] intel_th: Fix error handling in intel_th_output_open ANBZ: #35228 commit ed023a179150eec55bae16b98694deae9b77166f stable. commit 6d5925b667e4ed9e77c8278cc215191d29454a3f upstream. intel_th_output_open() calls bus_find_device_by_devt() which internally increments the device reference count via get_device(), but this reference is not properly released in several error paths. When device driver is unavailable, file operations cannot be obtained, or the driver's open method fails, the function returns without calling put_device(), leading to a permanent device reference count leak. This prevents the device from being properly released and could cause resource exhaustion over time. Found by code review. Cc: stable Fixes: 39f4034693b7 ("intel_th: Add driver infrastructure for Intel(R) Trace Hub devices") Signed-off-by: Ma Ke Link: https://patch.msgid.link/20251112091723.35963-1-make24@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwtracing/intel_th/core.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 06c84bffffb3..40a08f53bfb4 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -818,13 +818,17 @@ static int intel_th_output_open(struct inode *inode, struct file *file) int err; dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev); - if (!dev || !dev->driver) - return -ENODEV; + if (!dev || !dev->driver) { + err = -ENODEV; + goto out_no_device; + } thdrv = to_intel_th_driver(dev->driver); fops = fops_get(thdrv->fops); - if (!fops) - return -ENODEV; + if (!fops) { + err = -ENODEV; + goto out_put_device; + } replace_fops(file, fops); @@ -832,10 +836,16 @@ static int intel_th_output_open(struct inode *inode, struct file *file) if (file->f_op->open) { err = file->f_op->open(inode, file); - return err; + if (err) + goto out_put_device; } return 0; + +out_put_device: + put_device(dev); +out_no_device: + return err; } static const struct file_operations intel_th_output_fops = { -- Gitee From 904acd17edcba339d7103a0b43901d812b956d15 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 13 Nov 2025 21:24:31 +0800 Subject: [PATCH 0610/1449] cpuidle: governors: teo: Drop misguided target residency check ANBZ: #35228 commit dffe25224f5101f3b843191eea0f51eaba8b8c02 stable. commit a03b2011808ab02ccb7ab6b573b013b77fbb5921 upstream. When the target residency of the current candidate idle state is greater than the expected time till the closest timer (the sleep length), it does not matter whether or not the tick has already been stopped or if it is going to be stopped. The closest timer will trigger anyway at its due time, so if an idle state with target residency above the sleep length is selected, energy will be wasted and there may be excess latency. Of course, if the closest timer were canceled before it could trigger, a deeper idle state would be more suitable, but this is not expected to happen (generally speaking, hrtimers are not expected to be canceled as a rule). Accordingly, the teo_state_ok() check done in that case causes energy to be wasted more often than it allows any energy to be saved (if it allows any energy to be saved at all), so drop it and let the governor use the teo_find_shallower_state() return value as the new candidate idle state index. Fixes: 21d28cd2fa5f ("cpuidle: teo: Do not call tick_nohz_get_sleep_length() upfront") Cc: All applicable Signed-off-by: Rafael J. Wysocki Reviewed-by: Christian Loehle Tested-by: Christian Loehle Link: https://patch.msgid.link/5955081.DvuYhMxLoT@rafael.j.wysocki Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/cpuidle/governors/teo.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c index 7244f71c59c5..3a06ac29316d 100644 --- a/drivers/cpuidle/governors/teo.c +++ b/drivers/cpuidle/governors/teo.c @@ -595,11 +595,8 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, * If the closest expected timer is before the terget residency of the * candidate state, a shallower one needs to be found. */ - if (drv->states[idx].target_residency_ns > duration_ns) { - i = teo_find_shallower_state(drv, dev, idx, duration_ns, false); - if (teo_state_ok(i, drv)) - idx = i; - } + if (drv->states[idx].target_residency_ns > duration_ns) + idx = teo_find_shallower_state(drv, dev, idx, duration_ns, false); /* * If the selected state's target residency is below the tick length -- Gitee From af720eb80e63696d068649fcdc3f661eb3433f4b Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 27 Oct 2025 23:04:45 +0800 Subject: [PATCH 0611/1449] cpufreq: nforce2: fix reference count leak in nforce2 ANBZ: #35228 commit 6741f90220dc65b4060e3c47e3f6a1277765bb28 stable. commit 9600156bb99852c216a2128cdf9f114eb67c350f upstream. There are two reference count leaks in this driver: 1. In nforce2_fsb_read(): pci_get_subsys() increases the reference count of the PCI device, but pci_dev_put() is never called to release it, thus leaking the reference. 2. In nforce2_detect_chipset(): pci_get_subsys() gets a reference to the nforce2_dev which is stored in a global variable, but the reference is never released when the module is unloaded. Fix both by: - Adding pci_dev_put(nforce2_sub5) in nforce2_fsb_read() after reading the configuration. - Adding pci_dev_put(nforce2_dev) in nforce2_exit() to release the global device reference. Found via static analysis. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/cpufreq/cpufreq-nforce2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index fedad1081973..fbbbe501cf2d 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c @@ -145,6 +145,8 @@ static unsigned int nforce2_fsb_read(int bootfsb) pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb); fsb /= 1000000; + pci_dev_put(nforce2_sub5); + /* Check if PLL register is already set */ pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp); @@ -426,6 +428,7 @@ static int __init nforce2_init(void) static void __exit nforce2_exit(void) { cpufreq_unregister_driver(&nforce2_driver); + pci_dev_put(nforce2_dev); } module_init(nforce2_init); -- Gitee From 7b4c4fbcb9fcbb7a8e5c0877fdf7aacd3b91efac Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Mon, 10 Nov 2025 23:47:35 +0800 Subject: [PATCH 0612/1449] scsi: Revert "scsi: qla2xxx: Perform lockless command completion in abort path" ANBZ: #35228 commit e9e601b7df58ba0c667baf30263331df2c02ffe1 stable. commit b57fbc88715b6d18f379463f48a15b560b087ffe upstream. This reverts commit 0367076b0817d5c75dfb83001ce7ce5c64d803a9. The commit being reverted added code to __qla2x00_abort_all_cmds() to call sp->done() without holding a spinlock. But unlike the older code below it, this new code failed to check sp->cmd_type and just assumed TYPE_SRB, which results in a jump to an invalid pointer in target-mode with TYPE_TGT_CMD: qla2xxx [0000:65:00.0]-d034:8: qla24xx_do_nack_work create sess success 0000000009f7a79b qla2xxx [0000:65:00.0]-5003:8: ISP System Error - mbx1=1ff5h mbx2=10h mbx3=0h mbx4=0h mbx5=191h mbx6=0h mbx7=0h. qla2xxx [0000:65:00.0]-d01e:8: -> fwdump no buffer qla2xxx [0000:65:00.0]-f03a:8: qla_target(0): System error async event 0x8002 occurred qla2xxx [0000:65:00.0]-00af:8: Performing ISP error recovery - ha=0000000058183fda. BUG: kernel NULL pointer dereference, address: 0000000000000000 PF: supervisor instruction fetch in kernel mode PF: error_code(0x0010) - not-present page PGD 0 P4D 0 Oops: 0010 [#1] SMP CPU: 2 PID: 9446 Comm: qla2xxx_8_dpc Tainted: G O 6.1.133 #1 Hardware name: Supermicro Super Server/X11SPL-F, BIOS 4.2 12/15/2023 RIP: 0010:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. RSP: 0018:ffffc90001f93dc8 EFLAGS: 00010206 RAX: 0000000000000282 RBX: 0000000000000355 RCX: ffff88810d16a000 RDX: ffff88810dbadaa8 RSI: 0000000000080000 RDI: ffff888169dc38c0 RBP: ffff888169dc38c0 R08: 0000000000000001 R09: 0000000000000045 R10: ffffffffa034bdf0 R11: 0000000000000000 R12: ffff88810800bb40 R13: 0000000000001aa8 R14: ffff888100136610 R15: ffff8881070f7400 FS: 0000000000000000(0000) GS:ffff88bf80080000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 000000010c8ff006 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? __die+0x4d/0x8b ? page_fault_oops+0x91/0x180 ? trace_buffer_unlock_commit_regs+0x38/0x1a0 ? exc_page_fault+0x391/0x5e0 ? asm_exc_page_fault+0x22/0x30 __qla2x00_abort_all_cmds+0xcb/0x3e0 [qla2xxx_scst] qla2x00_abort_all_cmds+0x50/0x70 [qla2xxx_scst] qla2x00_abort_isp_cleanup+0x3b7/0x4b0 [qla2xxx_scst] qla2x00_abort_isp+0xfd/0x860 [qla2xxx_scst] qla2x00_do_dpc+0x581/0xa40 [qla2xxx_scst] kthread+0xa8/0xd0 Then commit 4475afa2646d ("scsi: qla2xxx: Complete command early within lock") added the spinlock back, because not having the lock caused a race and a crash. But qla2x00_abort_srb() in the switch below already checks for qla2x00_chip_is_down() and handles it the same way, so the code above the switch is now redundant and still buggy in target-mode. Remove it. Cc: stable@vger.kernel.org Signed-off-by: Tony Battersby Link: https://patch.msgid.link/3a8022dc-bcfd-4b01-9f9b-7a9ec61fa2a3@cybernetics.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_os.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4c7cf581bc86..ef894dc80b8f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1874,12 +1874,6 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { - if (qla2x00_chip_is_down(vha)) { - req->outstanding_cmds[cnt] = NULL; - sp->done(sp, res); - continue; - } - switch (sp->cmd_type) { case TYPE_SRB: qla2x00_abort_srb(qp, sp, res, &flags); -- Gitee From 79cc07f2b88ed30ac4756fae1c46e3ba94252a9f Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Wed, 29 Oct 2025 00:29:04 +0800 Subject: [PATCH 0613/1449] scsi: aic94xx: fix use-after-free in device removal path ANBZ: #35228 commit e354793a7ab9bb0934ea699a9d57bcd1b48fc27b stable. commit f6ab594672d4cba08540919a4e6be2e202b60007 upstream. The asd_pci_remove() function fails to synchronize with pending tasklets before freeing the asd_ha structure, leading to a potential use-after-free vulnerability. When a device removal is triggered (via hot-unplug or module unload), race condition can occur. The fix adds tasklet_kill() before freeing the asd_ha structure, ensuring all scheduled tasklets complete before cleanup proceeds. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") Cc: stable@vger.kernel.org Signed-off-by: Junrui Luo Link: https://patch.msgid.link/ME2PR01MB3156AB7DCACA206C845FC7E8AFFDA@ME2PR01MB3156.ausprd01.prod.outlook.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/aic94xx/aic94xx_init.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 8a3340d8d7ad..d64d126fb2da 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -896,6 +896,9 @@ static void asd_pci_remove(struct pci_dev *dev) asd_disable_ints(asd_ha); + /* Ensure all scheduled tasklets complete before freeing resources */ + tasklet_kill(&asd_ha->seq.dl_tasklet); + asd_remove_dev_attrs(asd_ha); /* XXX more here as needed */ -- Gitee From 45d15c2f0a15728cfd706bbbc84d03cde4b8a0db Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Thu, 6 Nov 2025 04:45:54 +0800 Subject: [PATCH 0614/1449] NFSD: use correct reservation type in nfsd4_scsi_fence_client ANBZ: #35228 commit 71074ea29886b93ea8cd96ad397b6265f3156e88 stable. commit 6f52063db9aabdaabea929b1e998af98c2e8d917 upstream. The reservation type argument for the pr_preempt call should match the one used in nfsd4_block_get_device_info_scsi. Fixes: f99d4fbdae67 ("nfsd: add SCSI layout support") Cc: stable@vger.kernel.org Signed-off-by: Dai Ngo Reviewed-by: Christoph Hellwig Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/blocklayout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 3a9415fd7754..5eae60425e57 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -334,7 +334,8 @@ nfsd4_scsi_fence_client(struct nfs4_layout_stateid *ls) struct block_device *bdev = ls->ls_file->nf_file->f_path.mnt->mnt_sb->s_bdev; bdev->bd_disk->fops->pr_ops->pr_preempt(bdev, NFSD_MDS_PR_KEY, - nfsd4_scsi_pr_key(clp), 0, true); + nfsd4_scsi_pr_key(clp), + PR_EXCLUSIVE_ACCESS_REG_ONLY, true); } const struct nfsd4_layout_ops scsi_layout_ops = { -- Gitee From 9ebcd26f83d0abcc8bd1177ba932de245339164c Mon Sep 17 00:00:00 2001 From: Andrey Vatoropin Date: Tue, 18 Nov 2025 16:42:31 +0800 Subject: [PATCH 0615/1449] scsi: target: Reset t_task_cdb pointer in error case ANBZ: #35228 commit 0260ad551b0815eb788d47f32899fbcd65d6f128 stable. commit 5053eab38a4c4543522d0c320c639c56a8b59908 upstream. If allocation of cmd->t_task_cdb fails, it remains NULL but is later dereferenced in the 'err' path. In case of error, reset NULL t_task_cdb value to point at the default fixed-size buffer. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 9e95fb805dc0 ("scsi: target: Fix NULL pointer dereference") Cc: stable@vger.kernel.org Signed-off-by: Andrey Vatoropin Reviewed-by: Mike Christie Link: https://patch.msgid.link/20251118084014.324940-1-a.vatoropin@crpt.ru Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/target/target_core_transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index fb93d74c5d0b..b9a144a59dff 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1524,6 +1524,7 @@ target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb, gfp_t gfp) if (scsi_command_size(cdb) > sizeof(cmd->__t_task_cdb)) { cmd->t_task_cdb = kzalloc(scsi_command_size(cdb), gfp); if (!cmd->t_task_cdb) { + cmd->t_task_cdb = &cmd->__t_task_cdb[0]; pr_err("Unable to allocate cmd->t_task_cdb" " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", scsi_command_size(cdb), -- Gitee From 92f36db8e0e932e5d3b687ea0a86b02f17440f44 Mon Sep 17 00:00:00 2001 From: Jan Prusakowski Date: Mon, 6 Oct 2025 16:46:15 +0800 Subject: [PATCH 0616/1449] f2fs: ensure node page reads complete before f2fs_put_super() finishes ANBZ: #35228 commit c3031cf2b61f1508662fc95ef9ad505cb0882a5f stable. commit 297baa4aa263ff8f5b3d246ee16a660d76aa82c4 upstream. Xfstests generic/335, generic/336 sometimes crash with the following message: F2FS-fs (dm-0): detect filesystem reference count leak during umount, type: 9, count: 1 ------------[ cut here ]------------ kernel BUG at fs/f2fs/super.c:1939! Oops: invalid opcode: 0000 [#1] SMP NOPTI CPU: 1 UID: 0 PID: 609351 Comm: umount Tainted: G W 6.17.0-rc5-xfstests-g9dd1835ecda5 #1 PREEMPT(none) Tainted: [W]=WARN Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:f2fs_put_super+0x3b3/0x3c0 Call Trace: generic_shutdown_super+0x7e/0x190 kill_block_super+0x1a/0x40 kill_f2fs_super+0x9d/0x190 deactivate_locked_super+0x30/0xb0 cleanup_mnt+0xba/0x150 task_work_run+0x5c/0xa0 exit_to_user_mode_loop+0xb7/0xc0 do_syscall_64+0x1ae/0x1c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ---[ end trace 0000000000000000 ]--- It appears that sometimes it is possible that f2fs_put_super() is called before all node page reads are completed. Adding a call to f2fs_wait_on_all_pages() for F2FS_RD_NODE fixes the problem. Cc: stable@kernel.org Fixes: 20872584b8c0b ("f2fs: fix to drop all dirty meta/node pages during umount()") Signed-off-by: Jan Prusakowski Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/super.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 0d6a47b4cf94..df7ac5ce0bf1 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1652,14 +1652,6 @@ static void f2fs_put_super(struct super_block *sb) truncate_inode_pages_final(META_MAPPING(sbi)); } - for (i = 0; i < NR_COUNT_TYPE; i++) { - if (!get_pages(sbi, i)) - continue; - f2fs_err(sbi, "detect filesystem reference count leak during " - "umount, type: %d, count: %lld", i, get_pages(sbi, i)); - f2fs_bug_on(sbi, 1); - } - f2fs_bug_on(sbi, sbi->fsync_node_num); f2fs_destroy_compress_inode(sbi); @@ -1670,6 +1662,15 @@ static void f2fs_put_super(struct super_block *sb) iput(sbi->meta_inode); sbi->meta_inode = NULL; + /* Should check the page counts after dropping all node/meta pages */ + for (i = 0; i < NR_COUNT_TYPE; i++) { + if (!get_pages(sbi, i)) + continue; + f2fs_err(sbi, "detect filesystem reference count leak during " + "umount, type: %d, count: %lld", i, get_pages(sbi, i)); + f2fs_bug_on(sbi, 1); + } + /* * iput() can update stat information, if f2fs_write_checkpoint() * above failed with error. -- Gitee From c8b3eb9aa00d5ef8940ad225248f627d8ff6e53f Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 20 Oct 2025 10:42:12 +0800 Subject: [PATCH 0617/1449] f2fs: fix to avoid updating zero-sized extent in extent cache ANBZ: #35228 commit efe3371001f50a2d6f746b50bdc6f9f26b2089ec stable. commit 7c37c79510329cd951a4dedf3f7bf7e2b18dccec upstream. As syzbot reported: F2FS-fs (loop0): __update_extent_tree_range: extent len is zero, type: 0, extent [0, 0, 0], age [0, 0] ------------[ cut here ]------------ kernel BUG at fs/f2fs/extent_cache.c:678! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 0 PID: 5336 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:__update_extent_tree_range+0x13bc/0x1500 fs/f2fs/extent_cache.c:678 Call Trace: f2fs_update_read_extent_cache_range+0x192/0x3e0 fs/f2fs/extent_cache.c:1085 f2fs_do_zero_range fs/f2fs/file.c:1657 [inline] f2fs_zero_range+0x10c1/0x1580 fs/f2fs/file.c:1737 f2fs_fallocate+0x583/0x990 fs/f2fs/file.c:2030 vfs_fallocate+0x669/0x7e0 fs/open.c:342 ioctl_preallocate fs/ioctl.c:289 [inline] file_ioctl+0x611/0x780 fs/ioctl.c:-1 do_vfs_ioctl+0xb33/0x1430 fs/ioctl.c:576 __do_sys_ioctl fs/ioctl.c:595 [inline] __se_sys_ioctl+0x82/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f07bc58eec9 In error path of f2fs_zero_range(), it may add a zero-sized extent into extent cache, it should be avoided. Fixes: 6e9619499f53 ("f2fs: support in batch fzero in dnode page") Cc: stable@kernel.org Reported-by: syzbot+24124df3170c3638b35f@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-f2fs-devel/68e5d698.050a0220.256323.0032.GAE@google.com Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/file.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 07b75bb10aa3..4bdc3366dc5b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1584,8 +1584,11 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start, f2fs_set_data_blkaddr(dn, NEW_ADDR); } - f2fs_update_read_extent_cache_range(dn, start, 0, index - start); - f2fs_update_age_extent_cache_range(dn, start, index - start); + if (index > start) { + f2fs_update_read_extent_cache_range(dn, start, 0, + index - start); + f2fs_update_age_extent_cache_range(dn, start, index - start); + } return ret; } -- Gitee From 31a5c7960d64183f64603fd01cb2fbbce2a968c7 Mon Sep 17 00:00:00 2001 From: Deepanshu Kartikey Date: Mon, 27 Oct 2025 21:06:34 +0800 Subject: [PATCH 0618/1449] f2fs: invalidate dentry cache on failed whiteout creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 3d65e27e57aaa9d66709fda4cbfb62a87c04a3f5 stable. commit d33f89b34aa313f50f9a512d58dd288999f246b0 upstream. F2FS can mount filesystems with corrupted directory depth values that get runtime-clamped to MAX_DIR_HASH_DEPTH. When RENAME_WHITEOUT operations are performed on such directories, f2fs_rename performs directory modifications (updating target entry and deleting source entry) before attempting to add the whiteout entry via f2fs_add_link. If f2fs_add_link fails due to the corrupted directory structure, the function returns an error to VFS, but the partial directory modifications have already been committed to disk. VFS assumes the entire rename operation failed and does not update the dentry cache, leaving stale mappings. In the error path, VFS does not call d_move() to update the dentry cache. This results in new_dentry still pointing to the old inode (new_inode) which has already had its i_nlink decremented to zero. The stale cache causes subsequent operations to incorrectly reference the freed inode. This causes subsequent operations to use cached dentry information that no longer matches the on-disk state. When a second rename targets the same entry, VFS attempts to decrement i_nlink on the stale inode, which may already have i_nlink=0, triggering a WARNING in drop_nlink(). Example sequence: 1. First rename (RENAME_WHITEOUT): file2 → file1 - f2fs updates file1 entry on disk (points to inode 8) - f2fs deletes file2 entry on disk - f2fs_add_link(whiteout) fails (corrupted directory) - Returns error to VFS - VFS does not call d_move() due to error - VFS cache still has: file1 → inode 7 (stale!) - inode 7 has i_nlink=0 (already decremented) 2. Second rename: file3 → file1 - VFS uses stale cache: file1 → inode 7 - Tries to drop_nlink on inode 7 (i_nlink already 0) - WARNING in drop_nlink() Fix this by explicitly invalidating old_dentry and new_dentry when f2fs_add_link fails during whiteout creation. This forces VFS to refresh from disk on subsequent operations, ensuring cache consistency even when the rename partially succeeds. Reproducer: 1. Mount F2FS image with corrupted i_current_depth 2. renameat2(file2, file1, RENAME_WHITEOUT) 3. renameat2(file3, file1, 0) 4. System triggers WARNING in drop_nlink() Fixes: 7e01e7ad746b ("f2fs: support RENAME_WHITEOUT") Reported-by: syzbot+632cf32276a9a564188d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=632cf32276a9a564188d Suggested-by: Chao Yu Link: https://lore.kernel.org/all/20251022233349.102728-1-kartikey406@gmail.com/ [v1] Cc: stable@vger.kernel.org Signed-off-by: Deepanshu Kartikey Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/namei.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 5a6c99f20d0c..e55d0ee3e294 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -1045,9 +1045,11 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, if (whiteout) { set_inode_flag(whiteout, FI_INC_LINK); err = f2fs_add_link(old_dentry, whiteout); - if (err) + if (err) { + d_invalidate(old_dentry); + d_invalidate(new_dentry); goto put_out_dir; - + } spin_lock(&whiteout->i_lock); whiteout->i_state &= ~I_LINKABLE; spin_unlock(&whiteout->i_lock); -- Gitee From 2d276afae6d9719171965163aebb88fc4a066a34 Mon Sep 17 00:00:00 2001 From: Xiaole He Date: Mon, 27 Oct 2025 17:23:41 +0800 Subject: [PATCH 0619/1449] f2fs: fix age extent cache insertion skip on counter overflow ANBZ: #35228 commit 4ce9eecb7466bb98fd8ab00f5f6813a4116e1481 stable. commit 27bf6a637b7613fc85fa6af468b7d612d78cd5c0 upstream. The age extent cache uses last_blocks (derived from allocated_data_blocks) to determine data age. However, there's a conflict between the deletion marker (last_blocks=0) and legitimate last_blocks=0 cases when allocated_data_blocks overflows to 0 after reaching ULLONG_MAX. In this case, valid extents are incorrectly skipped due to the "if (!tei->last_blocks)" check in __update_extent_tree_range(). This patch fixes the issue by: 1. Reserving ULLONG_MAX as an invalid/deletion marker 2. Limiting allocated_data_blocks to range [0, ULLONG_MAX-1] 3. Using F2FS_EXTENT_AGE_INVALID for deletion scenarios 4. Adjusting overflow age calculation from ULLONG_MAX to (ULLONG_MAX-1) Reproducer (using a patched kernel with allocated_data_blocks initialized to ULLONG_MAX - 3 for quick testing): Step 1: Mount and check initial state # dd if=/dev/zero of=/tmp/test.img bs=1M count=100 # mkfs.f2fs -f /tmp/test.img # mkdir -p /mnt/f2fs_test # mount -t f2fs -o loop,age_extent_cache /tmp/test.img /mnt/f2fs_test # cat /sys/kernel/debug/f2fs/status | grep -A 4 "Block Age" Allocated Data Blocks: 18446744073709551612 # ULLONG_MAX - 3 Inner Struct Count: tree: 1(0), node: 0 Step 2: Create files and write data to trigger overflow # touch /mnt/f2fs_test/{1,2,3,4}.txt; sync # cat /sys/kernel/debug/f2fs/status | grep -A 4 "Block Age" Allocated Data Blocks: 18446744073709551613 # ULLONG_MAX - 2 Inner Struct Count: tree: 5(0), node: 1 # dd if=/dev/urandom of=/mnt/f2fs_test/1.txt bs=4K count=1; sync # cat /sys/kernel/debug/f2fs/status | grep -A 4 "Block Age" Allocated Data Blocks: 18446744073709551614 # ULLONG_MAX - 1 Inner Struct Count: tree: 5(0), node: 2 # dd if=/dev/urandom of=/mnt/f2fs_test/2.txt bs=4K count=1; sync # cat /sys/kernel/debug/f2fs/status | grep -A 4 "Block Age" Allocated Data Blocks: 18446744073709551615 # ULLONG_MAX Inner Struct Count: tree: 5(0), node: 3 # dd if=/dev/urandom of=/mnt/f2fs_test/3.txt bs=4K count=1; sync # cat /sys/kernel/debug/f2fs/status | grep -A 4 "Block Age" Allocated Data Blocks: 0 # Counter overflowed! Inner Struct Count: tree: 5(0), node: 4 Step 3: Trigger the bug - next write should create node but gets skipped # dd if=/dev/urandom of=/mnt/f2fs_test/4.txt bs=4K count=1; sync # cat /sys/kernel/debug/f2fs/status | grep -A 4 "Block Age" Allocated Data Blocks: 1 Inner Struct Count: tree: 5(0), node: 4 Expected: node: 5 (new extent node for 4.txt) Actual: node: 4 (extent insertion was incorrectly skipped due to last_blocks = allocated_data_blocks = 0 in __get_new_block_age) After this fix, the extent node is correctly inserted and node count becomes 5 as expected. Fixes: 71644dff4811 ("f2fs: add block_age-based extent cache") Cc: stable@kernel.org Signed-off-by: Xiaole He Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/extent_cache.c | 5 +++-- fs/f2fs/f2fs.h | 6 ++++++ fs/f2fs/segment.c | 9 +++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 79d07c786f6a..847c50e40c22 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -755,7 +755,7 @@ static void __update_extent_tree_range(struct inode *inode, } goto out_read_extent_cache; update_age_extent_cache: - if (!tei->last_blocks) + if (tei->last_blocks == F2FS_EXTENT_AGE_INVALID) goto out_read_extent_cache; __set_extent_info(&ei, fofs, len, 0, false, @@ -859,7 +859,7 @@ static int __get_new_block_age(struct inode *inode, struct extent_info *ei, cur_age = cur_blocks - tei.last_blocks; else /* allocated_data_blocks overflow */ - cur_age = ULLONG_MAX - tei.last_blocks + cur_blocks; + cur_age = (ULLONG_MAX - 1) - tei.last_blocks + cur_blocks; if (tei.age) ei->age = __calculate_block_age(sbi, cur_age, tei.age); @@ -1063,6 +1063,7 @@ void f2fs_update_age_extent_cache_range(struct dnode_of_data *dn, struct extent_info ei = { .fofs = fofs, .len = len, + .last_blocks = F2FS_EXTENT_AGE_INVALID, }; if (!__may_extent_tree(dn->inode, EX_BLOCK_AGE)) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 406243395b94..7da0421236fb 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -626,6 +626,12 @@ enum extent_type { NR_EXTENT_CACHES, }; +/* + * Reserved value to mark invalid age extents, hence valid block range + * from 0 to ULLONG_MAX-1 + */ +#define F2FS_EXTENT_AGE_INVALID ULLONG_MAX + struct extent_info { unsigned int fofs; /* start offset in a file */ unsigned int len; /* length of the extent */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c7714e954cb5..764a3d084e4c 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3542,8 +3542,13 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); locate_dirty_segment(sbi, GET_SEGNO(sbi, *new_blkaddr)); - if (IS_DATASEG(curseg->seg_type)) - atomic64_inc(&sbi->allocated_data_blocks); + if (IS_DATASEG(curseg->seg_type)) { + unsigned long long new_val; + + new_val = atomic64_inc_return(&sbi->allocated_data_blocks); + if (unlikely(new_val == ULLONG_MAX)) + atomic64_set(&sbi->allocated_data_blocks, 0); + } up_write(&sit_i->sentry_lock); -- Gitee From 489bf3130c839752086fb2c3102b88305b77f7f2 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 5 Nov 2025 14:50:22 +0800 Subject: [PATCH 0620/1449] f2fs: fix return value of f2fs_recover_fsync_data() ANBZ: #35228 commit a4c67d96f92eefcfa5596a08f069e77b743c5865 stable. commit 01fba45deaddcce0d0b01c411435d1acf6feab7b upstream. With below scripts, it will trigger panic in f2fs: mkfs.f2fs -f /dev/vdd mount /dev/vdd /mnt/f2fs touch /mnt/f2fs/foo sync echo 111 >> /mnt/f2fs/foo f2fs_io fsync /mnt/f2fs/foo f2fs_io shutdown 2 /mnt/f2fs umount /mnt/f2fs mount -o ro,norecovery /dev/vdd /mnt/f2fs or mount -o ro,disable_roll_forward /dev/vdd /mnt/f2fs F2FS-fs (vdd): f2fs_recover_fsync_data: recovery fsync data, check_only: 0 F2FS-fs (vdd): Mounted with checkpoint version = 7f5c361f F2FS-fs (vdd): Stopped filesystem due to reason: 0 F2FS-fs (vdd): f2fs_recover_fsync_data: recovery fsync data, check_only: 1 Filesystem f2fs get_tree() didn't set fc->root, returned 1 ------------[ cut here ]------------ kernel BUG at fs/super.c:1761! Oops: invalid opcode: 0000 [#1] SMP PTI CPU: 3 UID: 0 PID: 722 Comm: mount Not tainted 6.18.0-rc2+ #721 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:vfs_get_tree.cold+0x18/0x1a Call Trace: fc_mount+0x13/0xa0 path_mount+0x34e/0xc50 __x64_sys_mount+0x121/0x150 do_syscall_64+0x84/0x800 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fa6cc126cfe The root cause is we missed to handle error number returned from f2fs_recover_fsync_data() when mounting image w/ ro,norecovery or ro,disable_roll_forward mount option, result in returning a positive error number to vfs_get_tree(), fix it. Cc: stable@kernel.org Fixes: 6781eabba1bd ("f2fs: give -EINVAL for norecovery and rw mount") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/super.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index df7ac5ce0bf1..31330a7e48a1 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -4707,11 +4707,15 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) } } else { err = f2fs_recover_fsync_data(sbi, true); - - if (!f2fs_readonly(sb) && err > 0) { - err = -EINVAL; - f2fs_err(sbi, "Need to recover fsync data"); - goto free_meta; + if (err > 0) { + if (!f2fs_readonly(sb)) { + f2fs_err(sbi, "Need to recover fsync data"); + err = -EINVAL; + goto free_meta; + } else { + f2fs_info(sbi, "drop all fsynced data"); + err = 0; + } } } -- Gitee From 6ca2fb0b7815abf3e58d15bea7a54b0d19dc6e7b Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Sat, 1 Nov 2025 07:42:20 +0800 Subject: [PATCH 0621/1449] tools/testing/nvdimm: Use per-DIMM device handle ANBZ: #35228 commit 1e90812c0220c40e094b0d4f1f364f0b068cf9af stable. commit f59b701b4674f7955170b54c4167c5590f4714eb upstream. KASAN reports a global-out-of-bounds access when running these nfit tests: clear.sh, pmem-errors.sh, pfn-meta-errors.sh, btt-errors.sh, daxdev-errors.sh, and inject-error.sh. [] BUG: KASAN: global-out-of-bounds in nfit_test_ctl+0x769f/0x7840 [nfit_test] [] Read of size 4 at addr ffffffffc03ea01c by task ndctl/1215 [] The buggy address belongs to the variable: [] handle+0x1c/0x1df4 [nfit_test] nfit_test_search_spa() uses handle[nvdimm->id] to retrieve a device handle and triggers a KASAN error when it reads past the end of the handle array. It should not be indexing the handle array at all. The correct device handle is stored in per-DIMM test data. Each DIMM has a struct nfit_mem that embeds a struct acpi_nfit_memdev that describes the NFIT device handle. Use that device handle here. Fixes: 10246dc84dfc ("acpi nfit: nfit_test supports translate SPA") Cc: stable@vger.kernel.org Signed-off-by: Alison Schofield Reviewed-by: Dave Jiang > --- Link: https://patch.msgid.link/20251031234227.1303113-1-alison.schofield@intel.com Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/nvdimm/test/nfit.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 005043bd9623..c0e1949d4016 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -670,6 +670,7 @@ static int nfit_test_search_spa(struct nvdimm_bus *bus, .addr = spa->spa, .region = NULL, }; + struct nfit_mem *nfit_mem; u64 dpa; ret = device_for_each_child(&bus->dev, &ctx, @@ -687,8 +688,12 @@ static int nfit_test_search_spa(struct nvdimm_bus *bus, */ nd_mapping = &nd_region->mapping[nd_region->ndr_mappings - 1]; nvdimm = nd_mapping->nvdimm; + nfit_mem = nvdimm_provider_data(nvdimm); + if (!nfit_mem) + return -EINVAL; - spa->devices[0].nfit_device_handle = handle[nvdimm->id]; + spa->devices[0].nfit_device_handle = + __to_nfit_memdev(nfit_mem)->device_handle; spa->num_nvdimms = 1; spa->devices[0].dpa = dpa; -- Gitee From 6e552630db587e9ac295ed112b5662f9aee34d83 Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Fri, 5 Sep 2025 13:18:16 +0800 Subject: [PATCH 0622/1449] media: vidtv: initialize local pointers upon transfer of memory ownership ANBZ: #35228 commit fb9bd6d8d314b748e946ed6555eb4a956ee8c4d8 stable. commit 98aabfe2d79f74613abc2b0b1cef08f97eaf5322 upstream. vidtv_channel_si_init() creates a temporary list (program, service, event) and ownership of the memory itself is transferred to the PAT/SDT/EIT tables through vidtv_psi_pat_program_assign(), vidtv_psi_sdt_service_assign(), vidtv_psi_eit_event_assign(). The problem here is that the local pointer where the memory ownership transfer was completed is not initialized to NULL. This causes the vidtv_psi_pmt_create_sec_for_each_pat_entry() function to fail, and in the flow that jumps to free_eit, the memory that was freed by vidtv_psi_*_table_destroy() can be accessed again by vidtv_psi_*_event_destroy() due to the uninitialized local pointer, so it is freed once again. Therefore, to prevent use-after-free and double-free vulnerability, local pointers must be initialized to NULL when transferring memory ownership. Cc: Reported-by: syzbot+1d9c0edea5907af239e0@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=1d9c0edea5907af239e0 Fixes: 3be8037960bc ("media: vidtv: add error checks") Signed-off-by: Jeongjun Park Reviewed-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/test-drivers/vidtv/vidtv_channel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index f3023e91b3eb..3541155c6fc6 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -461,12 +461,15 @@ int vidtv_channel_si_init(struct vidtv_mux *m) /* assemble all programs and assign to PAT */ vidtv_psi_pat_program_assign(m->si.pat, programs); + programs = NULL; /* assemble all services and assign to SDT */ vidtv_psi_sdt_service_assign(m->si.sdt, services); + services = NULL; /* assemble all events and assign to EIT */ vidtv_psi_eit_event_assign(m->si.eit, events); + events = NULL; m->si.pmt_secs = vidtv_psi_pmt_create_sec_for_each_pat_entry(m->si.pat, m->pcr_pid); -- Gitee From c06437f2c8fce5a64414aab893e12923a10d577b Mon Sep 17 00:00:00 2001 From: Prithvi Tambewagh Date: Mon, 1 Dec 2025 21:07:11 +0800 Subject: [PATCH 0623/1449] ocfs2: fix kernel BUG in ocfs2_find_victim_chain ANBZ: #35228 commit 96f1b074c98c20f55a3b23d2ab44d9fb0f619869 stable. commit 039bef30e320827bac8990c9f29d2a68cd8adb5f upstream. syzbot reported a kernel BUG in ocfs2_find_victim_chain() because the `cl_next_free_rec` field of the allocation chain list (next free slot in the chain list) is 0, triggring the BUG_ON(!cl->cl_next_free_rec) condition in ocfs2_find_victim_chain() and panicking the kernel. To fix this, an if condition is introduced in ocfs2_claim_suballoc_bits(), just before calling ocfs2_find_victim_chain(), the code block in it being executed when either of the following conditions is true: 1. `cl_next_free_rec` is equal to 0, indicating that there are no free chains in the allocation chain list 2. `cl_next_free_rec` is greater than `cl_count` (the total number of chains in the allocation chain list) Either of them being true is indicative of the fact that there are no chains left for usage. This is addressed using ocfs2_error(), which prints the error log for debugging purposes, rather than panicking the kernel. Link: https://lkml.kernel.org/r/20251201130711.143900-1-activprithvi@gmail.com Signed-off-by: Prithvi Tambewagh Reported-by: syzbot+96d38c6e1655c1420a72@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=96d38c6e1655c1420a72 Tested-by: syzbot+96d38c6e1655c1420a72@syzkaller.appspotmail.com Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Jun Piao Cc: Heming Zhao Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ocfs2/suballoc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 166c8918c825..1adf206ba538 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -1923,6 +1923,16 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, } cl = (struct ocfs2_chain_list *) &fe->id2.i_chain; + if (!le16_to_cpu(cl->cl_next_free_rec) || + le16_to_cpu(cl->cl_next_free_rec) > le16_to_cpu(cl->cl_count)) { + status = ocfs2_error(ac->ac_inode->i_sb, + "Chain allocator dinode %llu has invalid next " + "free chain record %u, but only %u total\n", + (unsigned long long)le64_to_cpu(fe->i_blkno), + le16_to_cpu(cl->cl_next_free_rec), + le16_to_cpu(cl->cl_count)); + goto bail; + } victim = ocfs2_find_victim_chain(cl); ac->ac_chain = victim; -- Gitee From f9951f5aca9ddb4719620805842ef7b5cfa09f76 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 15 Oct 2025 11:32:58 +0800 Subject: [PATCH 0624/1449] KVM: x86: Don't clear async #PF queue when CR0.PG is disabled (e.g. on #SMI) ANBZ: #35228 commit e30a69bf891e6c4d1ab5716450b1ad2c25269ff9 stable. commit ab4e41eb9fabd4607304fa7cfe8ec9c0bd8e1552 upstream. Fix an interaction between SMM and PV asynchronous #PFs where an #SMI can cause KVM to drop an async #PF ready event, and thus result in guest tasks becoming permanently stuck due to the task that encountered the #PF never being resumed. Specifically, don't clear the completion queue when paging is disabled, and re-check for completed async #PFs if/when paging is enabled. Prior to commit 2635b5c4a0e4 ("KVM: x86: interrupt based APF 'page ready' event delivery"), flushing the APF queue without notifying the guest of completed APF requests when paging is disabled was "necessary", in that delivering a #PF to the guest when paging is disabled would likely confuse and/or crash the guest. And presumably the original async #PF development assumed that a guest would only disable paging when there was no intent to ever re-enable paging. That assumption fails in several scenarios, most visibly on an emulated SMI, as entering SMM always disables CR0.PG (i.e. initially runs with paging disabled). When the SMM handler eventually executes RSM, the interrupted paging-enabled is restored, and the async #PF event is lost. Similarly, invoking firmware, e.g. via EFI runtime calls, might require a transition through paging modes and thus also disable paging with valid entries in the competion queue. To avoid dropping completion events, drop the "clear" entirely, and handle paging-enable transitions in the same way KVM already handles APIC enable/disable events: if a vCPU's APIC is disabled, APF completion events are not kept pending and not injected while APIC is disabled. Once a vCPU's APIC is re-enabled, KVM raises KVM_REQ_APF_READY so that the vCPU recognizes any pending pending #APF ready events. Signed-off-by: Maxim Levitsky Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251015033258.50974-4-mlevitsk@redhat.com [sean: rework changelog to call out #PF injection, drop "real mode" references, expand the code comment] Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/x86.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3d3e26e1f5b2..4679ed2c8c5e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -857,6 +857,13 @@ bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr) } EXPORT_SYMBOL_GPL(kvm_require_dr); +static bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu) +{ + u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT; + + return (vcpu->arch.apf.msr_en_val & mask) == mask; +} + static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu) { return vcpu->arch.reserved_gpa_bits | rsvd_bits(5, 8) | rsvd_bits(1, 2); @@ -949,15 +956,20 @@ void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned lon } if ((cr0 ^ old_cr0) & X86_CR0_PG) { - kvm_clear_async_pf_completion_queue(vcpu); - kvm_async_pf_hash_reset(vcpu); - /* * Clearing CR0.PG is defined to flush the TLB from the guest's * perspective. */ if (!(cr0 & X86_CR0_PG)) kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); + /* + * Check for async #PF completion events when enabling paging, + * as the vCPU may have previously encountered async #PFs (it's + * entirely legal for the guest to toggle paging on/off without + * waiting for the async #PF queue to drain). + */ + else if (kvm_pv_async_pf_enabled(vcpu)) + kvm_make_request(KVM_REQ_APF_READY, vcpu); } if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS) @@ -3397,13 +3409,6 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 0; } -static inline bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu) -{ - u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT; - - return (vcpu->arch.apf.msr_en_val & mask) == mask; -} - static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) { gpa_t gpa = data & ~0x3f; -- Gitee From 2af2961dda20c538b3e41207a5667e65cecac6ae Mon Sep 17 00:00:00 2001 From: Tzung-Bi Shih Date: Fri, 31 Oct 2025 11:39:00 +0800 Subject: [PATCH 0625/1449] platform/chrome: cros_ec_ishtp: Fix UAF after unbinding driver ANBZ: #35228 commit 393b8f9bedc7806acb9c47cefdbdb223b4b6164b stable. commit 944edca81e7aea15f83cf9a13a6ab67f711e8abd upstream. After unbinding the driver, another kthread `cros_ec_console_log_work` is still accessing the device, resulting an UAF and crash. The driver doesn't unregister the EC device in .remove() which should shutdown sub-devices synchronously. Fix it. Fixes: 26a14267aff2 ("platform/chrome: Add ChromeOS EC ISHTP driver") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20251031033900.3577394-1-tzungbi@kernel.org Signed-off-by: Tzung-Bi Shih Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/chrome/cros_ec_ishtp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c index cb2031cf7106..62cf15bcbc4a 100644 --- a/drivers/platform/chrome/cros_ec_ishtp.c +++ b/drivers/platform/chrome/cros_ec_ishtp.c @@ -715,6 +715,7 @@ static void cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device) cancel_work_sync(&client_data->work_ishtp_reset); cancel_work_sync(&client_data->work_ec_evt); + cros_ec_unregister(client_data->ec_dev); cros_ish_deinit(cros_ish_cl); ishtp_put_device(cl_device); } -- Gitee From a1ca8321258e0f4aa29170a4c6d749d39107d67e Mon Sep 17 00:00:00 2001 From: Zhichi Lin Date: Sat, 11 Oct 2025 16:22:22 +0800 Subject: [PATCH 0626/1449] scs: fix a wrong parameter in __scs_magic ANBZ: #35228 commit 062774439d442882b44f5eab8c256ad3423ef284 stable. commit 08bd4c46d5e63b78e77f2605283874bbe868ab19 upstream. __scs_magic() needs a 'void *' variable, but a 'struct task_struct *' is given. 'task_scs(tsk)' is the starting address of the task's shadow call stack, and '__scs_magic(task_scs(tsk))' is the end address of the task's shadow call stack. Here should be '__scs_magic(task_scs(tsk))'. The user-visible effect of this bug is that when CONFIG_DEBUG_STACK_USAGE is enabled, the shadow call stack usage checking function (scs_check_usage) would scan an incorrect memory range. This could lead to: 1. **Inaccurate stack usage reporting**: The function would calculate wrong usage statistics for the shadow call stack, potentially showing incorrect value in kmsg. 2. **Potential kernel crash**: If the value of __scs_magic(tsk)is greater than that of __scs_magic(task_scs(tsk)), the for loop may access unmapped memory, potentially causing a kernel panic. However, this scenario is unlikely because task_struct is allocated via the slab allocator (which typically returns lower addresses), while the shadow call stack returned by task_scs(tsk) is allocated via vmalloc(which typically returns higher addresses). However, since this is purely a debugging feature (CONFIG_DEBUG_STACK_USAGE), normal production systems should be not unaffected. The bug only impacts developers and testers who are actively debugging stack usage with this configuration enabled. Link: https://lkml.kernel.org/r/20251011082222.12965-1-zhichi.lin@vivo.com Fixes: 5bbaf9d1fcb9 ("scs: Add support for stack usage debugging") Signed-off-by: Jiyuan Xie Signed-off-by: Zhichi Lin Reviewed-by: Sami Tolvanen Acked-by: Will Deacon Cc: Andrey Konovalov Cc: Kees Cook Cc: Marco Elver Cc: Will Deacon Cc: Yee Lee Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/scs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/scs.c b/kernel/scs.c index d7809affe740..772488afd5b9 100644 --- a/kernel/scs.c +++ b/kernel/scs.c @@ -135,7 +135,7 @@ static void scs_check_usage(struct task_struct *tsk) if (!IS_ENABLED(CONFIG_DEBUG_STACK_USAGE)) return; - for (p = task_scs(tsk); p < __scs_magic(tsk); ++p) { + for (p = task_scs(tsk); p < __scs_magic(task_scs(tsk)); ++p) { if (!READ_ONCE_NOCHECK(*p)) break; used += sizeof(*p); -- Gitee From 5fb9eac8d4355ad99de76f357f4ecbc2aa735724 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 25 Nov 2025 22:23:02 +0800 Subject: [PATCH 0627/1449] parisc: Do not reprogram affinitiy on ASP chip ANBZ: #35228 commit e09fd2eb6d4c993ee9eaae556cb51e30ec1042df stable. commit dca7da244349eef4d78527cafc0bf80816b261f5 upstream. The ASP chip is a very old variant of the GSP chip and is used e.g. in HP 730 workstations. When trying to reprogram the affinity it will crash with a HPMC as the relevant registers don't seem to be at the usual location. Let's avoid the crash by checking the sversion. Also note, that reprogramming isn't necessary either, as the HP730 is a just a single-CPU machine. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/parisc/gsc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index a0daaa548bc3..8ba778170447 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -154,7 +154,9 @@ static int gsc_set_affinity_irq(struct irq_data *d, const struct cpumask *dest, gsc_dev->eim = ((u32) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data; /* switch IRQ's for devices below LASI/WAX to other CPU */ - gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR); + /* ASP chip (svers 0x70) does not support reprogramming */ + if (gsc_dev->gsc->id.sversion != 0x70) + gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR); irq_data_update_effective_affinity(d, &tmask); -- Gitee From 86164425fe7daf301f8bdba607c3b740cb0458c8 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 2 Dec 2025 17:32:31 +0800 Subject: [PATCH 0628/1449] libceph: make decode_pool() more resilient against corrupted osdmaps ANBZ: #35228 commit e927ab132b87ba3f076705fc2684d94b24201ed1 stable. commit 8c738512714e8c0aa18f8a10c072d5b01c83db39 upstream. If the osdmap is (maliciously) corrupted such that the encoded length of ceph_pg_pool envelope is less than what is expected for a particular encoding version, out-of-bounds reads may ensue because the only bounds check that is there is based on that length value. This patch adds explicit bounds checks for each field that is decoded or skipped. Cc: stable@vger.kernel.org Reported-by: ziming zhang Signed-off-by: Ilya Dryomov Reviewed-by: Xiubo Li Tested-by: ziming zhang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/osdmap.c | 116 +++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 64 deletions(-) diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index d245fa508e1c..f5f60deb680a 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -806,51 +806,49 @@ static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi) ceph_decode_need(p, end, len, bad); pool_end = *p + len; + ceph_decode_need(p, end, 4 + 4 + 4, bad); pi->type = ceph_decode_8(p); pi->size = ceph_decode_8(p); pi->crush_ruleset = ceph_decode_8(p); pi->object_hash = ceph_decode_8(p); - pi->pg_num = ceph_decode_32(p); pi->pgp_num = ceph_decode_32(p); - *p += 4 + 4; /* skip lpg* */ - *p += 4; /* skip last_change */ - *p += 8 + 4; /* skip snap_seq, snap_epoch */ + /* lpg*, last_change, snap_seq, snap_epoch */ + ceph_decode_skip_n(p, end, 8 + 4 + 8 + 4, bad); /* skip snaps */ - num = ceph_decode_32(p); + ceph_decode_32_safe(p, end, num, bad); while (num--) { - *p += 8; /* snapid key */ - *p += 1 + 1; /* versions */ - len = ceph_decode_32(p); - *p += len; + /* snapid key, pool snap (with versions) */ + ceph_decode_skip_n(p, end, 8 + 2, bad); + ceph_decode_skip_string(p, end, bad); } - /* skip removed_snaps */ - num = ceph_decode_32(p); - *p += num * (8 + 8); + /* removed_snaps */ + ceph_decode_skip_map(p, end, 64, 64, bad); + ceph_decode_need(p, end, 8 + 8 + 4, bad); *p += 8; /* skip auid */ pi->flags = ceph_decode_64(p); *p += 4; /* skip crash_replay_interval */ if (ev >= 7) - pi->min_size = ceph_decode_8(p); + ceph_decode_8_safe(p, end, pi->min_size, bad); else pi->min_size = pi->size - pi->size / 2; if (ev >= 8) - *p += 8 + 8; /* skip quota_max_* */ + /* quota_max_* */ + ceph_decode_skip_n(p, end, 8 + 8, bad); if (ev >= 9) { - /* skip tiers */ - num = ceph_decode_32(p); - *p += num * 8; + /* tiers */ + ceph_decode_skip_set(p, end, 64, bad); + ceph_decode_need(p, end, 8 + 1 + 8 + 8, bad); *p += 8; /* skip tier_of */ *p += 1; /* skip cache_mode */ - pi->read_tier = ceph_decode_64(p); pi->write_tier = ceph_decode_64(p); } else { @@ -858,86 +856,76 @@ static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi) pi->write_tier = -1; } - if (ev >= 10) { - /* skip properties */ - num = ceph_decode_32(p); - while (num--) { - len = ceph_decode_32(p); - *p += len; /* key */ - len = ceph_decode_32(p); - *p += len; /* val */ - } - } + if (ev >= 10) + /* properties */ + ceph_decode_skip_map(p, end, string, string, bad); if (ev >= 11) { - /* skip hit_set_params */ - *p += 1 + 1; /* versions */ - len = ceph_decode_32(p); - *p += len; + /* hit_set_params (with versions) */ + ceph_decode_skip_n(p, end, 2, bad); + ceph_decode_skip_string(p, end, bad); - *p += 4; /* skip hit_set_period */ - *p += 4; /* skip hit_set_count */ + /* hit_set_period, hit_set_count */ + ceph_decode_skip_n(p, end, 4 + 4, bad); } if (ev >= 12) - *p += 4; /* skip stripe_width */ + /* stripe_width */ + ceph_decode_skip_32(p, end, bad); - if (ev >= 13) { - *p += 8; /* skip target_max_bytes */ - *p += 8; /* skip target_max_objects */ - *p += 4; /* skip cache_target_dirty_ratio_micro */ - *p += 4; /* skip cache_target_full_ratio_micro */ - *p += 4; /* skip cache_min_flush_age */ - *p += 4; /* skip cache_min_evict_age */ - } + if (ev >= 13) + /* target_max_*, cache_target_*, cache_min_* */ + ceph_decode_skip_n(p, end, 16 + 8 + 8, bad); - if (ev >= 14) { - /* skip erasure_code_profile */ - len = ceph_decode_32(p); - *p += len; - } + if (ev >= 14) + /* erasure_code_profile */ + ceph_decode_skip_string(p, end, bad); /* * last_force_op_resend_preluminous, will be overridden if the * map was encoded with RESEND_ON_SPLIT */ if (ev >= 15) - pi->last_force_request_resend = ceph_decode_32(p); + ceph_decode_32_safe(p, end, pi->last_force_request_resend, bad); else pi->last_force_request_resend = 0; if (ev >= 16) - *p += 4; /* skip min_read_recency_for_promote */ + /* min_read_recency_for_promote */ + ceph_decode_skip_32(p, end, bad); if (ev >= 17) - *p += 8; /* skip expected_num_objects */ + /* expected_num_objects */ + ceph_decode_skip_64(p, end, bad); if (ev >= 19) - *p += 4; /* skip cache_target_dirty_high_ratio_micro */ + /* cache_target_dirty_high_ratio_micro */ + ceph_decode_skip_32(p, end, bad); if (ev >= 20) - *p += 4; /* skip min_write_recency_for_promote */ + /* min_write_recency_for_promote */ + ceph_decode_skip_32(p, end, bad); if (ev >= 21) - *p += 1; /* skip use_gmt_hitset */ + /* use_gmt_hitset */ + ceph_decode_skip_8(p, end, bad); if (ev >= 22) - *p += 1; /* skip fast_read */ + /* fast_read */ + ceph_decode_skip_8(p, end, bad); - if (ev >= 23) { - *p += 4; /* skip hit_set_grade_decay_rate */ - *p += 4; /* skip hit_set_search_last_n */ - } + if (ev >= 23) + /* hit_set_grade_decay_rate, hit_set_search_last_n */ + ceph_decode_skip_n(p, end, 4 + 4, bad); if (ev >= 24) { - /* skip opts */ - *p += 1 + 1; /* versions */ - len = ceph_decode_32(p); - *p += len; + /* opts (with versions) */ + ceph_decode_skip_n(p, end, 2, bad); + ceph_decode_skip_string(p, end, bad); } if (ev >= 25) - pi->last_force_request_resend = ceph_decode_32(p); + ceph_decode_32_safe(p, end, pi->last_force_request_resend, bad); /* ignore the rest */ -- Gitee From 767e4eebdbad10005d45b73e3c948312cae124fa Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 14 Nov 2025 04:51:11 +0800 Subject: [PATCH 0629/1449] KVM: x86: WARN if hrtimer callback for periodic APIC timer fires with period=0 ANBZ: #35228 commit 8ff24d46a4b22381f75d833f9eabf9a4564785fe stable. commit 0ea9494be9c931ddbc084ad5e11fda91b554cf47 upstream. WARN and don't restart the hrtimer if KVM's callback runs with the guest's APIC timer in periodic mode but with a period of '0', as not advancing the hrtimer's deadline would put the CPU into an infinite loop of hrtimer events. Observing a period of '0' should be impossible, even when the hrtimer is running on a different CPU than the vCPU, as KVM is supposed to cancel the hrtimer before changing (or zeroing) the period, e.g. when switching from periodic to one-shot. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251113205114.1647493-2-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index af4ae9216667..2a2ff56a1e94 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2855,7 +2855,7 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) apic_timer_expired(apic, true); - if (lapic_is_periodic(apic)) { + if (lapic_is_periodic(apic) && !WARN_ON_ONCE(!apic->lapic_timer.period)) { advance_periodic_target_expiration(apic); hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); return HRTIMER_RESTART; -- Gitee From 59236c28b5f7227d2426e6e0e7bae3077856c2b1 Mon Sep 17 00:00:00 2001 From: fuqiang wang Date: Fri, 14 Nov 2025 04:51:12 +0800 Subject: [PATCH 0630/1449] KVM: x86: Explicitly set new periodic hrtimer expiration in apic_timer_fn() ANBZ: #35228 commit 73f77550086fe1d185b5df75bf63480f84b455b6 stable. commit 9633f180ce994ab293ce4924a9b7aaf4673aa114 upstream. When restarting an hrtimer to emulate a the guest's APIC timer in periodic mode, explicitly set the expiration using the target expiration computed by advance_periodic_target_expiration() instead of adding the period to the existing timer. This will allow making adjustments to the expiration, e.g. to deal with expirations far in the past, without having to implement the same logic in both advance_periodic_target_expiration() and apic_timer_fn(). Cc: stable@vger.kernel.org Signed-off-by: fuqiang wang [sean: split to separate patch, write changelog] Link: https://patch.msgid.link/20251113205114.1647493-3-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 2a2ff56a1e94..a28c8878313c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2857,7 +2857,7 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) if (lapic_is_periodic(apic) && !WARN_ON_ONCE(!apic->lapic_timer.period)) { advance_periodic_target_expiration(apic); - hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); + hrtimer_set_expires(&ktimer->timer, ktimer->target_expiration); return HRTIMER_RESTART; } else return HRTIMER_NORESTART; -- Gitee From 8e3524b6a213c5e1ed6ca4a769102a29efab557c Mon Sep 17 00:00:00 2001 From: fuqiang wang Date: Fri, 14 Nov 2025 04:51:13 +0800 Subject: [PATCH 0631/1449] KVM: x86: Fix VM hard lockup after prolonged inactivity with periodic HV timer ANBZ: #35228 commit 7b54ccef865e0aa62e4871d4ada2ba4b9dcb8bed stable. commit 18ab3fc8e880791aa9f7c000261320fc812b5465 upstream. When advancing the target expiration for the guest's APIC timer in periodic mode, set the expiration to "now" if the target expiration is in the past (similar to what is done in update_target_expiration()). Blindly adding the period to the previous target expiration can result in KVM generating a practically unbounded number of hrtimer IRQs due to programming an expired timer over and over. In extreme scenarios, e.g. if userspace pauses/suspends a VM for an extended duration, this can even cause hard lockups in the host. Currently, the bug only affects Intel CPUs when using the hypervisor timer (HV timer), a.k.a. the VMX preemption timer. Unlike the software timer, a.k.a. hrtimer, which KVM keeps running even on exits to userspace, the HV timer only runs while the guest is active. As a result, if the vCPU does not run for an extended duration, there will be a huge gap between the target expiration and the current time the vCPU resumes running. Because the target expiration is incremented by only one period on each timer expiration, this leads to a series of timer expirations occurring rapidly after the vCPU/VM resumes. More critically, when the vCPU first triggers a periodic HV timer expiration after resuming, advancing the expiration by only one period will result in a target expiration in the past. As a result, the delta may be calculated as a negative value. When the delta is converted into an absolute value (tscdeadline is an unsigned u64), the resulting value can overflow what the HV timer is capable of programming. I.e. the large value will exceed the VMX Preemption Timer's maximum bit width of cpu_preemption_timer_multi + 32, and thus cause KVM to switch from the HV timer to the software timer (hrtimers). After switching to the software timer, periodic timer expiration callbacks may be executed consecutively within a single clock interrupt handler, because hrtimers honors KVM's request for an expiration in the past and immediately re-invokes KVM's callback after reprogramming. And because the interrupt handler runs with IRQs disabled, restarting KVM's hrtimer over and over until the target expiration is advanced to "now" can result in a hard lockup. E.g. the following hard lockup was triggered in the host when running a Windows VM (only relevant because it used the APIC timer in periodic mode) after resuming the VM from a long suspend (in the host). NMI watchdog: Watchdog detected hard LOCKUP on cpu 45 ... RIP: 0010:advance_periodic_target_expiration+0x4d/0x80 [kvm] ... RSP: 0018:ff4f88f5d98d8ef0 EFLAGS: 00000046 RAX: fff0103f91be678e RBX: fff0103f91be678e RCX: 00843a7d9e127bcc RDX: 0000000000000002 RSI: 0052ca4003697505 RDI: ff440d5bfbdbd500 RBP: ff440d5956f99200 R08: ff2ff2a42deb6a84 R09: 000000000002a6c0 R10: 0122d794016332b3 R11: 0000000000000000 R12: ff440db1af39cfc0 R13: ff440db1af39cfc0 R14: ffffffffc0d4a560 R15: ff440db1af39d0f8 FS: 00007f04a6ffd700(0000) GS:ff440db1af380000(0000) knlGS:000000e38a3b8000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000d5651feff8 CR3: 000000684e038002 CR4: 0000000000773ee0 PKRU: 55555554 Call Trace: apic_timer_fn+0x31/0x50 [kvm] __hrtimer_run_queues+0x100/0x280 hrtimer_interrupt+0x100/0x210 ? ttwu_do_wakeup+0x19/0x160 smp_apic_timer_interrupt+0x6a/0x130 apic_timer_interrupt+0xf/0x20 Moreover, if the suspend duration of the virtual machine is not long enough to trigger a hard lockup in this scenario, since commit 98c25ead5eda ("KVM: VMX: Move preemption timer <=> hrtimer dance to common x86"), KVM will continue using the software timer until the guest reprograms the APIC timer in some way. Since the periodic timer does not require frequent APIC timer register programming, the guest may continue to use the software timer in perpetuity. Fixes: d8f2f498d9ed ("x86/kvm: fix LAPIC timer drift when guest uses periodic mode") Cc: stable@vger.kernel.org Signed-off-by: fuqiang wang [sean: massage comments and changelog] Link: https://patch.msgid.link/20251113205114.1647493-4-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/lapic.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index a28c8878313c..01c71e67a093 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2058,15 +2058,33 @@ static void advance_periodic_target_expiration(struct kvm_lapic *apic) ktime_t delta; /* - * Synchronize both deadlines to the same time source or - * differences in the periods (caused by differences in the - * underlying clocks or numerical approximation errors) will - * cause the two to drift apart over time as the errors - * accumulate. + * Use kernel time as the time source for both the hrtimer deadline and + * TSC-based deadline so that they stay synchronized. Computing each + * deadline independently will cause the two deadlines to drift apart + * over time as differences in the periods accumulate, e.g. due to + * differences in the underlying clocks or numerical approximation errors. */ apic->lapic_timer.target_expiration = ktime_add_ns(apic->lapic_timer.target_expiration, apic->lapic_timer.period); + + /* + * If the new expiration is in the past, e.g. because userspace stopped + * running the VM for an extended duration, then force the expiration + * to "now" and don't try to play catch-up with the missed events. KVM + * will only deliver a single interrupt regardless of how many events + * are pending, i.e. restarting the timer with an expiration in the + * past will do nothing more than waste host cycles, and can even lead + * to a hard lockup in extreme cases. + */ + if (ktime_before(apic->lapic_timer.target_expiration, now)) + apic->lapic_timer.target_expiration = now; + + /* + * Note, ensuring the expiration isn't in the past also prevents delta + * from going negative, which could cause the TSC deadline to become + * excessively large due to it an unsigned value. + */ delta = ktime_sub(apic->lapic_timer.target_expiration, now); apic->lapic_timer.tscdeadline = kvm_read_l1_tsc(apic->vcpu, tscl) + nsec_to_cycles(apic->vcpu, delta); -- Gitee From 24ced52b9a569ab6bb03266c33bc76d63e192c59 Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Sat, 25 Oct 2025 03:29:18 +0800 Subject: [PATCH 0632/1449] KVM: nSVM: Avoid incorrect injection of SVM_EXIT_CR0_SEL_WRITE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit aab88dcc4fb4d18934d7ed149b6595b020d32dea stable. commit 3d80f4c93d3d26d0f9a0dd2844961a632eeea634 upstream. When emulating L2 instructions, svm_check_intercept() checks whether a write to CR0 should trigger a synthesized #VMEXIT with SVM_EXIT_CR0_SEL_WRITE. However, it does not check whether L1 enabled the intercept for SVM_EXIT_WRITE_CR0, which has higher priority according to the APM (24593—Rev. 3.42—March 2024, Table 15-7): When both selective and non-selective CR0-write intercepts are active at the same time, the non-selective intercept takes priority. With respect to exceptions, the priority of this intercept is the same as the generic CR0-write intercept. Make sure L1 does NOT intercept SVM_EXIT_WRITE_CR0 before checking if SVM_EXIT_CR0_SEL_WRITE needs to be injected. Opportunistically tweak the "not CR0" logic to explicitly bail early so that it's more obvious that only CR0 has a selective intercept, and that modifying icpt_info.exit_code is functionally necessary so that the call to nested_svm_exit_handled() checks the correct exit code. Fixes: cfec82cb7d31 ("KVM: SVM: Add intercept check for emulated cr accesses") Cc: stable@vger.kernel.org Signed-off-by: Yosry Ahmed Link: https://patch.msgid.link/20251024192918.3191141-4-yosry.ahmed@linux.dev [sean: isolate non-CR0 write logic, tweak comments accordingly] Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/svm.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 8e31d0ed5460..fbadeffe005e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4615,15 +4615,29 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, case SVM_EXIT_WRITE_CR0: { unsigned long cr0, val; - if (info->intercept == x86_intercept_cr_write) + /* + * Adjust the exit code accordingly if a CR other than CR0 is + * being written, and skip straight to the common handling as + * only CR0 has an additional selective intercept. + */ + if (info->intercept == x86_intercept_cr_write && info->modrm_reg) { icpt_info.exit_code += info->modrm_reg; + break; + } - if (icpt_info.exit_code != SVM_EXIT_WRITE_CR0 || - info->intercept == x86_intercept_clts) + /* + * Convert the exit_code to SVM_EXIT_CR0_SEL_WRITE if a + * selective CR0 intercept is triggered (the common logic will + * treat the selective intercept as being enabled). Note, the + * unconditional intercept has higher priority, i.e. this is + * only relevant if *only* the selective intercept is enabled. + */ + if (vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_CR0_WRITE) || + !(vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_SELECTIVE_CR0))) break; - if (!(vmcb12_is_intercept(&svm->nested.ctl, - INTERCEPT_SELECTIVE_CR0))) + /* CLTS never triggers INTERCEPT_SELECTIVE_CR0 */ + if (info->intercept == x86_intercept_clts) break; cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK; -- Gitee From beece1fab7fc4a87ab143ef4a04d4a85d399a0cf Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Tue, 23 Sep 2025 00:29:23 +0800 Subject: [PATCH 0633/1449] KVM: SVM: Mark VMCB_NPT as dirty on nested VMRUN ANBZ: #35228 commit 99c709294ac85df8f408993ea0e86d5165d39bc2 stable. commit 7c8b465a1c91f674655ea9cec5083744ec5f796a upstream. Mark the VMCB_NPT bit as dirty in nested_vmcb02_prepare_save() on every nested VMRUN. If L1 changes the PAT MSR between two VMRUN instructions on the same L1 vCPU, the g_pat field in the associated vmcb02 will change, and the VMCB_NPT clean bit should be cleared. Fixes: 4bb170a5430b ("KVM: nSVM: do not mark all VMCB02 fields dirty on nested vmexit") Cc: stable@vger.kernel.org Signed-off-by: Jim Mattson Link: https://lore.kernel.org/r/20250922162935.621409-3-jmattson@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/nested.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index f5850f12bf80..8345205ee529 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -544,6 +544,7 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12 struct kvm_vcpu *vcpu = &svm->vcpu; nested_vmcb02_compute_g_pat(svm); + vmcb_mark_dirty(vmcb02, VMCB_NPT); /* Load the nested guest state */ if (svm->nested.vmcb12_gpa != svm->nested.last_vmcb12_gpa) { -- Gitee From 208bb40ecbbbcae601fd0b152f30b81bd2a0ea19 Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Sat, 25 Oct 2025 03:29:17 +0800 Subject: [PATCH 0634/1449] KVM: nSVM: Propagate SVM_EXIT_CR0_SEL_WRITE correctly for LMSW emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 2d1d833b40253bc2e1015df1c4316fd4c830d302 stable. commit 5674a76db0213f9db1e4d08e847ff649b46889c0 upstream. When emulating L2 instructions, svm_check_intercept() checks whether a write to CR0 should trigger a synthesized #VMEXIT with SVM_EXIT_CR0_SEL_WRITE. For MOV-to-CR0, SVM_EXIT_CR0_SEL_WRITE is only triggered if any bit other than CR0.MP and CR0.TS is updated. However, according to the APM (24593—Rev. 3.42—March 2024, Table 15-7): The LMSW instruction treats the selective CR0-write intercept as a non-selective intercept (i.e., it intercepts regardless of the value being written). Skip checking the changed bits for x86_intercept_lmsw and always inject SVM_EXIT_CR0_SEL_WRITE. Fixes: cfec82cb7d31 ("KVM: SVM: Add intercept check for emulated cr accesses") Cc: stable@vger.kernel.org Reported-by: Matteo Rizzo Signed-off-by: Yosry Ahmed Link: https://patch.msgid.link/20251024192918.3191141-3-yosry.ahmed@linux.dev Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/svm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index fbadeffe005e..bd6f3879992e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4640,20 +4640,20 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, if (info->intercept == x86_intercept_clts) break; - cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK; - val = info->src_val & ~SVM_CR0_SELECTIVE_MASK; - + /* LMSW always triggers INTERCEPT_SELECTIVE_CR0 */ if (info->intercept == x86_intercept_lmsw) { - cr0 &= 0xfUL; - val &= 0xfUL; - /* lmsw can't clear PE - catch this here */ - if (cr0 & X86_CR0_PE) - val |= X86_CR0_PE; + icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE; + break; } + /* + * MOV-to-CR0 only triggers INTERCEPT_SELECTIVE_CR0 if any bit + * other than SVM_CR0_SELECTIVE_MASK is changed. + */ + cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK; + val = info->src_val & ~SVM_CR0_SELECTIVE_MASK; if (cr0 ^ val) icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE; - break; } case SVM_EXIT_READ_DR0: -- Gitee From c99a33570f477d6e5c0bf01afab87095176e2515 Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Tue, 23 Sep 2025 00:29:22 +0800 Subject: [PATCH 0635/1449] KVM: SVM: Mark VMCB_PERM_MAP as dirty on nested VMRUN ANBZ: #35228 commit d44197b5281d0e8eb528ae7c35c845e8e4fe295a stable. commit 93c9e107386dbe1243287a5b14ceca894de372b9 upstream. Mark the VMCB_PERM_MAP bit as dirty in nested_vmcb02_prepare_control() on every nested VMRUN. If L1 changes MSR interception (INTERCEPT_MSR_PROT) between two VMRUN instructions on the same L1 vCPU, the msrpm_base_pa in the associated vmcb02 will change, and the VMCB_PERM_MAP clean bit should be cleared. Fixes: 4bb170a5430b ("KVM: nSVM: do not mark all VMCB02 fields dirty on nested vmexit") Reported-by: Matteo Rizzo Cc: stable@vger.kernel.org Signed-off-by: Jim Mattson Link: https://lore.kernel.org/r/20250922162935.621409-2-jmattson@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/nested.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 8345205ee529..494adafdc272 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -676,6 +676,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, vmcb02->control.nested_ctl = vmcb01->control.nested_ctl; vmcb02->control.iopm_base_pa = vmcb01->control.iopm_base_pa; vmcb02->control.msrpm_base_pa = vmcb01->control.msrpm_base_pa; + vmcb_mark_dirty(vmcb02, VMCB_PERM_MAP); /* Done at vmrun: asid. */ -- Gitee From 911cddb2565a4160f78bfad3ddff86bec811ccdd Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 14 Nov 2025 06:56:14 +0800 Subject: [PATCH 0636/1449] KVM: nSVM: Set exit_code_hi to -1 when synthesizing SVM_EXIT_ERR (failed VMRUN) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d6d257ce44afcc718f163363548faf2abbf074e6 stable. commit f402ecd7a8b6446547076f4bd24bd5d4dcc94481 upstream. Set exit_code_hi to -1u as a temporary band-aid to fix a long-standing (effectively since KVM's inception) bug where KVM treats the exit code as a 32-bit value, when in reality it's a 64-bit value. Per the APM, offset 0x70 is a single 64-bit value: 070h 63:0 EXITCODE And a sane reading of the error values defined in "Table C-1. SVM Intercept Codes" is that negative values use the full 64 bits: –1 VMEXIT_INVALID Invalid guest state in VMCB. –2 VMEXIT_BUSYBUSY bit was set in the VMSA –3 VMEXIT_IDLE_REQUIREDThe sibling thread is not in an idle state -4 VMEXIT_INVALID_PMC Invalid PMC state And that interpretation is confirmed by testing on Milan and Turin (by setting bits in CR0[63:32] to generate VMEXIT_INVALID on VMRUN). Furthermore, Xen has treated exitcode as a 64-bit value since HVM support was adding in 2006 (see Xen commit d1bd157fbc ("Big merge the HVM full-virtualisation abstractions.")). Cc: Jim Mattson Cc: Yosry Ahmed Cc: stable@vger.kernel.org Reviewed-by: Yosry Ahmed Link: https://patch.msgid.link/20251113225621.1688428-3-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/nested.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 494adafdc272..f47242a1e602 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -886,7 +886,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) if (!nested_vmcb_check_save(vcpu) || !nested_vmcb_check_controls(vcpu)) { vmcb12->control.exit_code = SVM_EXIT_ERR; - vmcb12->control.exit_code_hi = 0; + vmcb12->control.exit_code_hi = -1u; vmcb12->control.exit_info_1 = 0; vmcb12->control.exit_info_2 = 0; goto out; @@ -919,7 +919,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) svm->soft_int_injected = false; svm->vmcb->control.exit_code = SVM_EXIT_ERR; - svm->vmcb->control.exit_code_hi = 0; + svm->vmcb->control.exit_code_hi = -1u; svm->vmcb->control.exit_info_1 = 0; svm->vmcb->control.exit_info_2 = 0; -- Gitee From b4b62fe30e25601d717f000381dd0760144c87a3 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 14 Nov 2025 06:56:13 +0800 Subject: [PATCH 0637/1449] KVM: nSVM: Clear exit_code_hi in VMCB when synthesizing nested VM-Exits ANBZ: #35228 commit 97bf1f13736410798642da8d9a3d2c896135156a stable. commit da01f64e7470988f8607776aa7afa924208863fb upstream. Explicitly clear exit_code_hi in the VMCB when synthesizing "normal" nested VM-Exits, as the full exit code is a 64-bit value (spoiler alert), and all exit codes for non-failing VMRUN use only bits 31:0. Cc: Jim Mattson Cc: Yosry Ahmed Cc: stable@vger.kernel.org Reviewed-by: Yosry Ahmed Link: https://patch.msgid.link/20251113225621.1688428-2-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/svm/svm.h | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index bd6f3879992e..93a3f2e5c19b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2674,6 +2674,7 @@ static bool check_selective_cr0_intercepted(struct kvm_vcpu *vcpu, if (cr0 ^ val) { svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; + svm->vmcb->control.exit_code_hi = 0; ret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE); } @@ -4714,6 +4715,7 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, if (static_cpu_has(X86_FEATURE_NRIPS)) vmcb->control.next_rip = info->next_rip; vmcb->control.exit_code = icpt_info.exit_code; + vmcb->control.exit_code_hi = 0; vmexit = nested_svm_exit_handled(svm); ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 91c4b9f34b1c..794de734ee19 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -610,9 +610,10 @@ int nested_svm_vmexit(struct vcpu_svm *svm); static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code) { - svm->vmcb->control.exit_code = exit_code; - svm->vmcb->control.exit_info_1 = 0; - svm->vmcb->control.exit_info_2 = 0; + svm->vmcb->control.exit_code = exit_code; + svm->vmcb->control.exit_code_hi = 0; + svm->vmcb->control.exit_info_1 = 0; + svm->vmcb->control.exit_info_2 = 0; return nested_svm_vmexit(svm); } -- Gitee From 4247b0bde21c342618e7911adf074309f9bfadb8 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Wed, 10 Dec 2025 17:06:01 +0800 Subject: [PATCH 0638/1449] xfs: fix a memory leak in xfs_buf_item_init() ANBZ: #35228 commit 079f1c3f5619c33c6724e22c8a5850d91448c499 stable. commit fc40459de82543b565ebc839dca8f7987f16f62e upstream. xfs_buf_item_get_format() may allocate memory for bip->bli_formats, free the memory in the error path. Fixes: c3d5f0c2fb85 ("xfs: complain if anyone tries to create a too-large buffer log item") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Reviewed-by: Christoph Hellwig Reviewed-by: Carlos Maiolino Signed-off-by: Carlos Maiolino Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/xfs/xfs_buf_item.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index b02ce568de0c..12134c79301a 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -900,6 +900,7 @@ xfs_buf_item_init( map_size = DIV_ROUND_UP(chunks, NBWORD); if (map_size > XFS_BLF_DATAMAP_SIZE) { + xfs_buf_item_free_format(bip); kmem_cache_free(xfs_buf_item_cache, bip); xfs_err(mp, "buffer item dirty bitmap (%u uints) too small to reflect %u bytes!", -- Gitee From f33274e075b22d9245c6cb84607f191f1c21dec7 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 17 Dec 2025 07:24:40 +0800 Subject: [PATCH 0639/1449] tracing: Do not register unsupported perf events ANBZ: #35228 commit 65b1971147ec12f0b1cee0811c859a3d7d9b04ce stable. commit ef7f38df890f5dcd2ae62f8dbde191d72f3bebae upstream. Synthetic events currently do not have a function to register perf events. This leads to calling the tracepoint register functions with a NULL function pointer which triggers: ------------[ cut here ]------------ WARNING: kernel/tracepoint.c:175 at tracepoint_add_func+0x357/0x370, CPU#2: perf/2272 Modules linked in: kvm_intel kvm irqbypass CPU: 2 UID: 0 PID: 2272 Comm: perf Not tainted 6.18.0-ftest-11964-ge022764176fc-dirty #323 PREEMPTLAZY Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 RIP: 0010:tracepoint_add_func+0x357/0x370 Code: 28 9c e8 4c 0b f5 ff eb 0f 4c 89 f7 48 c7 c6 80 4d 28 9c e8 ab 89 f4 ff 31 c0 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc <0f> 0b 49 c7 c6 ea ff ff ff e9 ee fe ff ff 0f 0b e9 f9 fe ff ff 0f RSP: 0018:ffffabc0c44d3c40 EFLAGS: 00010246 RAX: 0000000000000001 RBX: ffff9380aa9e4060 RCX: 0000000000000000 RDX: 000000000000000a RSI: ffffffff9e1d4a98 RDI: ffff937fcf5fd6c8 RBP: 0000000000000001 R08: 0000000000000007 R09: ffff937fcf5fc780 R10: 0000000000000003 R11: ffffffff9c193910 R12: 000000000000000a R13: ffffffff9e1e5888 R14: 0000000000000000 R15: ffffabc0c44d3c78 FS: 00007f6202f5f340(0000) GS:ffff93819f00f000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055d3162281a8 CR3: 0000000106a56003 CR4: 0000000000172ef0 Call Trace: tracepoint_probe_register+0x5d/0x90 synth_event_reg+0x3c/0x60 perf_trace_event_init+0x204/0x340 perf_trace_init+0x85/0xd0 perf_tp_event_init+0x2e/0x50 perf_try_init_event+0x6f/0x230 ? perf_event_alloc+0x4bb/0xdc0 perf_event_alloc+0x65a/0xdc0 __se_sys_perf_event_open+0x290/0x9f0 do_syscall_64+0x93/0x7b0 ? entry_SYSCALL_64_after_hwframe+0x76/0x7e ? trace_hardirqs_off+0x53/0xc0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Instead, have the code return -ENODEV, which doesn't warn and has perf error out with: # perf record -e synthetic:futex_wait Error: The sys_perf_event_open() syscall returned with 19 (No such device) for event (synthetic:futex_wait). "dmesg | grep -i perf" may provide additional information. Ideally perf should support synthetic events, but for now just fix the warning. The support can come later. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Namhyung Kim Link: https://patch.msgid.link/20251216182440.147e4453@gandalf.local.home Fixes: 4b147936fa509 ("tracing: Add support for 'synthetic' events") Reported-by: Ian Rogers Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/trace/trace_events.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 7b3c55bb0235..382e07cd49f9 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -689,6 +689,8 @@ int trace_event_reg(struct trace_event_call *call, #ifdef CONFIG_PERF_EVENTS case TRACE_REG_PERF_REGISTER: + if (!call->class->perf_probe) + return -ENODEV; return tracepoint_probe_register(call->tp, call->class->perf_probe, call); -- Gitee From fb8e57ea73835a860cd39d7fdfe090166a64cb02 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 15 Dec 2025 22:21:34 +0800 Subject: [PATCH 0640/1449] PM: runtime: Do not clear needs_force_resume with enabled runtime PM ANBZ: #35228 commit a143c3677662fa2722a5ff18ac55abe569ef35c0 stable. commit 359afc8eb02a518fbdd0cbd462c8c2827c6cbec2 upstream. Commit 89d9cec3b1e9 ("PM: runtime: Clear power.needs_force_resume in pm_runtime_reinit()") added provisional clearing of power.needs_force_resume to pm_runtime_reinit(), but it is done unconditionally which is a mistake because pm_runtime_reinit() may race with driver probing and removal [1]. To address this, notice that power.needs_force_resume should never be set when runtime PM is enabled and so it only needs to be cleared when runtime PM is disabled, and update pm_runtime_init() to only clear that flag when runtime PM is disabled. Fixes: 89d9cec3b1e9 ("PM: runtime: Clear power.needs_force_resume in pm_runtime_reinit()") Reported-by: Ed Tsai Closes: https://lore.kernel.org/linux-pm/20251215122154.3180001-1-ed.tsai@mediatek.com/ [1] Signed-off-by: Rafael J. Wysocki Cc: 6.17+ # 6.17+ Reviewed-by: Ulf Hansson Link: https://patch.msgid.link/12807571.O9o76ZdvQC@rafael.j.wysocki Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/base/power/runtime.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 5a33cee9a394..b28fb11cd6db 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1827,16 +1827,18 @@ void pm_runtime_init(struct device *dev) */ void pm_runtime_reinit(struct device *dev) { - if (!pm_runtime_enabled(dev)) { - if (dev->power.runtime_status == RPM_ACTIVE) - pm_runtime_set_suspended(dev); - if (dev->power.irq_safe) { - spin_lock_irq(&dev->power.lock); - dev->power.irq_safe = 0; - spin_unlock_irq(&dev->power.lock); - if (dev->parent) - pm_runtime_put(dev->parent); - } + if (pm_runtime_enabled(dev)) + return; + + if (dev->power.runtime_status == RPM_ACTIVE) + pm_runtime_set_suspended(dev); + + if (dev->power.irq_safe) { + spin_lock_irq(&dev->power.lock); + dev->power.irq_safe = 0; + spin_unlock_irq(&dev->power.lock); + if (dev->parent) + pm_runtime_put(dev->parent); } /* * Clear power.needs_force_resume in case it has been set by -- Gitee From ff8337879a702a2fa38ba42f9c0ac9a02998cbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Wed, 3 Dec 2025 02:41:37 +0800 Subject: [PATCH 0641/1449] r8169: fix RTL8117 Wake-on-Lan in DASH mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 19d4c57ae91b07d55691f16542ae82cf6e11a00e stable. commit dd75c723ef566f7f009c047f47e0eee95fe348ab upstream. Wake-on-Lan does currently not work for r8169 in DASH mode, e.g. the ASUS Pro WS X570-ACE with RTL8168fp/RTL8117. Fix by not returning early in rtl_prepare_power_down when dash_enabled. While this fixes WoL, it still kills the OOB RTL8117 remote management BMC connection. Fix by not calling rtl8168_driver_stop if WoL is enabled. Fixes: 065c27c184d6 ("r8169: phy power ops") Signed-off-by: René Rebe Cc: stable@vger.kernel.org Reviewed-by: Heiner Kallweit Link: https://patch.msgid.link/20251202.194137.1647877804487085954.rene@exactco.de Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/realtek/r8169_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index f4353ccb1b87..2e731b5587a2 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -2581,9 +2581,6 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp) static void rtl_prepare_power_down(struct rtl8169_private *tp) { - if (tp->dash_enabled) - return; - if (tp->mac_version == RTL_GIGA_MAC_VER_32 || tp->mac_version == RTL_GIGA_MAC_VER_33) rtl_ephy_write(tp, 0x19, 0xff64); @@ -4721,7 +4718,7 @@ static void rtl8169_down(struct rtl8169_private *tp) rtl_disable_exit_l1(tp); rtl_prepare_power_down(tp); - if (tp->dash_type != RTL_DASH_NONE) + if (tp->dash_type != RTL_DASH_NONE && !tp->saved_wolopts) rtl8168_driver_stop(tp); } -- Gitee From c37a4040315a08f4beef001e0025c8da06d59c33 Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Sun, 7 Dec 2025 18:44:55 +0800 Subject: [PATCH 0642/1449] fsnotify: do not generate ACCESS/MODIFY events on child for special files ANBZ: #35228 commit e0643d46759db8b84c0504a676043e5e341b6c81 stable. commit 635bc4def026a24e071436f4f356ea08c0eed6ff upstream. inotify/fanotify do not allow users with no read access to a file to subscribe to events (e.g. IN_ACCESS/IN_MODIFY), but they do allow the same user to subscribe for watching events on children when the user has access to the parent directory (e.g. /dev). Users with no read access to a file but with read access to its parent directory can still stat the file and see if it was accessed/modified via atime/mtime change. The same is not true for special files (e.g. /dev/null). Users will not generally observe atime/mtime changes when other users read/write to special files, only when someone sets atime/mtime via utimensat(). Align fsnotify events with this stat behavior and do not generate ACCESS/MODIFY events to parent watchers on read/write of special files. The events are still generated to parent watchers on utimensat(). This closes some side-channels that could be possibly used for information exfiltration [1]. [1] https://snee.la/pdf/pubs/file-notification-attacks.pdf Reported-by: Sudheendra Raghav Neela CC: stable@vger.kernel.org Signed-off-by: Amir Goldstein Signed-off-by: Jan Kara Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/notify/fsnotify.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 3facd6780bcb..8e6dc858a614 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -262,8 +262,15 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, /* * Include parent/name in notification either if some notification * groups require parent info or the parent is interested in this event. + * The parent interest in ACCESS/MODIFY events does not apply to special + * files, where read/write are not on the filesystem of the parent and + * events can provide an undesirable side-channel for information + * exfiltration. */ - parent_interested = mask & p_mask & ALL_FSNOTIFY_EVENTS; + parent_interested = mask & p_mask & ALL_FSNOTIFY_EVENTS && + !(data_type == FSNOTIFY_EVENT_PATH && + d_is_special(dentry) && + (mask & (FS_ACCESS | FS_MODIFY))); if (parent_needed || parent_interested) { /* When notifying parent, child should be passed as data */ WARN_ON_ONCE(inode != fsnotify_data_inode(data, data_type)); -- Gitee From 7a9d2587e67f53caf9b4834a4400d2879f88a577 Mon Sep 17 00:00:00 2001 From: caoping Date: Thu, 4 Dec 2025 17:10:58 +0800 Subject: [PATCH 0643/1449] net/handshake: restore destructor on submit failure ANBZ: #35228 commit cd8cf2be3717137554744233fda051ffc09d1d44 stable. commit 6af2a01d65f89e73c1cbb9267f8880d83a88cee4 upstream. handshake_req_submit() replaces sk->sk_destruct but never restores it when submission fails before the request is hashed. handshake_sk_destruct() then returns early and the original destructor never runs, leaking the socket. Restore sk_destruct on the error path. Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests") Reviewed-by: Chuck Lever Cc: stable@vger.kernel.org Signed-off-by: caoping Link: https://patch.msgid.link/20251204091058.1545151-1-caoping@cmss.chinamobile.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/handshake/request.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/handshake/request.c b/net/handshake/request.c index 0ac126b0add6..5df102534a59 100644 --- a/net/handshake/request.c +++ b/net/handshake/request.c @@ -277,6 +277,8 @@ int handshake_req_submit(struct socket *sock, struct handshake_req *req, out_unlock: spin_unlock(&hn->hn_lock); out_err: + /* Restore original destructor so socket teardown still runs on failure */ + req->hr_sk->sk_destruct = req->hr_odestruct; trace_handshake_submit_err(net, req, req->hr_sk, ret); handshake_req_destroy(req); return ret; -- Gitee From a2750ce2713d4f2ebd0086395fddf4221d777567 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 13 Nov 2025 16:31:31 +0800 Subject: [PATCH 0644/1449] nfsd: Mark variable __maybe_unused to avoid W=1 build break ANBZ: #35228 commit 354834eb78670a3bf9978442a3829644bfb68597 stable. commit ebae102897e760e9e6bc625f701dd666b2163bd1 upstream. Clang is not happy about set but (in some cases) unused variable: fs/nfsd/export.c:1027:17: error: variable 'inode' set but not used [-Werror,-Wunused-but-set-variable] since it's used as a parameter to dprintk() which might be configured a no-op. To avoid uglifying code with the specific ifdeffery just mark the variable __maybe_unused. The commit [1], which introduced this behaviour, is quite old and hence the Fixes tag points to the first of the Git era. Link: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=0431923fb7a1 [1] Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Andy Shevchenko Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index f4e77859aa85..782b58abb130 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -1014,7 +1014,7 @@ exp_rootfh(struct net *net, struct auth_domain *clp, char *name, { struct svc_export *exp; struct path path; - struct inode *inode; + struct inode *inode __maybe_unused; struct svc_fh fh; int err; struct nfsd_net *nn = net_generic(net, nfsd_net_id); -- Gitee From 3efa9dd04fecfcf7f5d82d2922f8fed1e6aa115f Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Fri, 7 Nov 2025 23:09:48 +0800 Subject: [PATCH 0645/1449] svcrdma: return 0 on success from svc_rdma_copy_inline_range ANBZ: #35228 commit 21a64218450eee59f05f671720add1e4a5583379 stable. commit 94972027ab55b200e031059fd6c7a649f8248020 upstream. The function comment specifies 0 on success and -EINVAL on invalid parameters. Make the tail return 0 after a successful copy loop. Fixes: d7cc73972661 ("svcrdma: support multiple Read chunks per RPC") Cc: stable@vger.kernel.org Signed-off-by: Joshua Rogers Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sunrpc/xprtrdma/svc_rdma_rw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index e460e25a1d6d..49d1023e66e9 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -834,7 +834,7 @@ static int svc_rdma_copy_inline_range(struct svc_rdma_read_info *info, offset += page_len; } - return -EINVAL; + return 0; } /** -- Gitee From 9ae2dd5f4b94fdb6474a786d7731fbdd1a094c49 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Fri, 7 Nov 2025 23:05:33 +0800 Subject: [PATCH 0646/1449] SUNRPC: svcauth_gss: avoid NULL deref on zero length gss_token in gss_read_proxy_verf ANBZ: #35228 commit 7452d53f293379e2c38cfa8ad0694aa46fc4788b stable. commit d4b69a6186b215d2dc1ebcab965ed88e8d41768d upstream. A zero length gss_token results in pages == 0 and in_token->pages[0] is NULL. The code unconditionally evaluates page_address(in_token->pages[0]) for the initial memcpy, which can dereference NULL even when the copy length is 0. Guard the first memcpy so it only runs when length > 0. Fixes: 5866efa8cbfb ("SUNRPC: Fix svcauth_gss_proxy_init()") Cc: stable@vger.kernel.org Signed-off-by: Joshua Rogers Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sunrpc/auth_gss/svcauth_gss.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index d063b63516f8..49a8623cc1d5 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1093,7 +1093,8 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp, } length = min_t(unsigned int, inlen, (char *)xdr->end - (char *)xdr->p); - memcpy(page_address(in_token->pages[0]), xdr->p, length); + if (length) + memcpy(page_address(in_token->pages[0]), xdr->p, length); inlen -= length; to_offs = length; -- Gitee From e8e3fca70a75bc635f77d5c8f511e404163362c7 Mon Sep 17 00:00:00 2001 From: "Nysal Jan K.A" Date: Tue, 28 Oct 2025 18:55:12 +0800 Subject: [PATCH 0647/1449] powerpc/kexec: Enable SMT before waking offline CPUs ANBZ: #35228 commit d790ef0c4819424ee0c2f448c0a8154c5ca369d1 stable. commit c2296a1e42418556efbeb5636c4fa6aa6106713a upstream. If SMT is disabled or a partial SMT state is enabled, when a new kernel image is loaded for kexec, on reboot the following warning is observed: kexec: Waking offline cpu 228. WARNING: CPU: 0 PID: 9062 at arch/powerpc/kexec/core_64.c:223 kexec_prepare_cpus+0x1b0/0x1bc [snip] NIP kexec_prepare_cpus+0x1b0/0x1bc LR kexec_prepare_cpus+0x1a0/0x1bc Call Trace: kexec_prepare_cpus+0x1a0/0x1bc (unreliable) default_machine_kexec+0x160/0x19c machine_kexec+0x80/0x88 kernel_kexec+0xd0/0x118 __do_sys_reboot+0x210/0x2c4 system_call_exception+0x124/0x320 system_call_vectored_common+0x15c/0x2ec This occurs as add_cpu() fails due to cpu_bootable() returning false for CPUs that fail the cpu_smt_thread_allowed() check or non primary threads if SMT is disabled. Fix the issue by enabling SMT and resetting the number of SMT threads to the number of threads per core, before attempting to wake up all present CPUs. Fixes: 38253464bc82 ("cpu/SMT: Create topology_smt_thread_allowed()") Reported-by: Sachin P Bappalige Cc: stable@vger.kernel.org # v6.6+ Reviewed-by: Srikar Dronamraju Signed-off-by: Nysal Jan K.A. Tested-by: Samir M Reviewed-by: Sourabh Jain Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20251028105516.26258-1-nysal@linux.ibm.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/kexec/core_64.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c index e465e4487737..ec7e909d7dcb 100644 --- a/arch/powerpc/kexec/core_64.c +++ b/arch/powerpc/kexec/core_64.c @@ -200,6 +200,23 @@ static void kexec_prepare_cpus_wait(int wait_state) mb(); } + +/* + * The add_cpu() call in wake_offline_cpus() can fail as cpu_bootable() + * returns false for CPUs that fail the cpu_smt_thread_allowed() check + * or non primary threads if SMT is disabled. Re-enable SMT and set the + * number of SMT threads to threads per core. + */ +static void kexec_smt_reenable(void) +{ +#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT) + lock_device_hotplug(); + cpu_smt_num_threads = threads_per_core; + cpu_smt_control = CPU_SMT_ENABLED; + unlock_device_hotplug(); +#endif +} + /* * We need to make sure each present CPU is online. The next kernel will scan * the device tree and assume primary threads are online and query secondary @@ -214,6 +231,8 @@ static void wake_offline_cpus(void) { int cpu = 0; + kexec_smt_reenable(); + for_each_present_cpu(cpu) { if (!cpu_online(cpu)) { printk(KERN_INFO "kexec: Waking offline cpu %d.\n", -- Gitee From 5f92ef6d2bec761e2ca92777860b3674dfc7a0a1 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Fri, 28 Nov 2025 00:35:59 +0800 Subject: [PATCH 0648/1449] btrfs: don't log conflicting inode if it's a dir moved in the current transaction ANBZ: #35228 commit 7359e1d39c78816ecbdb0cb4e93975794ce53973 stable. commit 266273eaf4d99475f1ae57f687b3e42bc71ec6f0 upstream. We can't log a conflicting inode if it's a directory and it was moved from one parent directory to another parent directory in the current transaction, as this can result an attempt to have a directory with two hard links during log replay, one for the old parent directory and another for the new parent directory. The following scenario triggers that issue: 1) We have directories "dir1" and "dir2" created in a past transaction. Directory "dir1" has inode A as its parent directory; 2) We move "dir1" to some other directory; 3) We create a file with the name "dir1" in directory inode A; 4) We fsync the new file. This results in logging the inode of the new file and the inode for the directory "dir1" that was previously moved in the current transaction. So the log tree has the INODE_REF item for the new location of "dir1"; 5) We move the new file to some other directory. This results in updating the log tree to included the new INODE_REF for the new location of the file and removes the INODE_REF for the old location. This happens during the rename when we call btrfs_log_new_name(); 6) We fsync the file, and that persists the log tree changes done in the previous step (btrfs_log_new_name() only updates the log tree in memory); 7) We have a power failure; 8) Next time the fs is mounted, log replay happens and when processing the inode for directory "dir1" we find a new INODE_REF and add that link, but we don't remove the old link of the inode since we have not logged the old parent directory of the directory inode "dir1". As a result after log replay finishes when we trigger writeback of the subvolume tree's extent buffers, the tree check will detect that we have a directory a hard link count of 2 and we get a mount failure. The errors and stack traces reported in dmesg/syslog are like this: [ 3845.729764] BTRFS info (device dm-0): start tree-log replay [ 3845.730304] page: refcount:3 mapcount:0 mapping:000000005c8a3027 index:0x1d00 pfn:0x11510c [ 3845.731236] memcg:ffff9264c02f4e00 [ 3845.731751] aops:btree_aops [btrfs] ino:1 [ 3845.732300] flags: 0x17fffc00000400a(uptodate|private|writeback|node=0|zone=2|lastcpupid=0x1ffff) [ 3845.733346] raw: 017fffc00000400a 0000000000000000 dead000000000122 ffff9264d978aea8 [ 3845.734265] raw: 0000000000001d00 ffff92650e6d4738 00000003ffffffff ffff9264c02f4e00 [ 3845.735305] page dumped because: eb page dump [ 3845.735981] BTRFS critical (device dm-0): corrupt leaf: root=5 block=30408704 slot=6 ino=257, invalid nlink: has 2 expect no more than 1 for dir [ 3845.737786] BTRFS info (device dm-0): leaf 30408704 gen 10 total ptrs 17 free space 14881 owner 5 [ 3845.737789] BTRFS info (device dm-0): refs 4 lock_owner 0 current 30701 [ 3845.737792] item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 [ 3845.737794] inode generation 3 transid 9 size 16 nbytes 16384 [ 3845.737795] block group 0 mode 40755 links 1 uid 0 gid 0 [ 3845.737797] rdev 0 sequence 2 flags 0x0 [ 3845.737798] atime 1764259517.0 [ 3845.737800] ctime 1764259517.572889464 [ 3845.737801] mtime 1764259517.572889464 [ 3845.737802] otime 1764259517.0 [ 3845.737803] item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12 [ 3845.737805] index 0 name_len 2 [ 3845.737807] item 2 key (256 DIR_ITEM 2363071922) itemoff 16077 itemsize 34 [ 3845.737808] location key (257 1 0) type 2 [ 3845.737810] transid 9 data_len 0 name_len 4 [ 3845.737811] item 3 key (256 DIR_ITEM 2676584006) itemoff 16043 itemsize 34 [ 3845.737813] location key (258 1 0) type 2 [ 3845.737814] transid 9 data_len 0 name_len 4 [ 3845.737815] item 4 key (256 DIR_INDEX 2) itemoff 16009 itemsize 34 [ 3845.737816] location key (257 1 0) type 2 [ 3845.737818] transid 9 data_len 0 name_len 4 [ 3845.737819] item 5 key (256 DIR_INDEX 3) itemoff 15975 itemsize 34 [ 3845.737820] location key (258 1 0) type 2 [ 3845.737821] transid 9 data_len 0 name_len 4 [ 3845.737822] item 6 key (257 INODE_ITEM 0) itemoff 15815 itemsize 160 [ 3845.737824] inode generation 9 transid 10 size 6 nbytes 0 [ 3845.737825] block group 0 mode 40755 links 2 uid 0 gid 0 [ 3845.737826] rdev 0 sequence 1 flags 0x0 [ 3845.737827] atime 1764259517.572889464 [ 3845.737828] ctime 1764259517.572889464 [ 3845.737830] mtime 1764259517.572889464 [ 3845.737831] otime 1764259517.572889464 [ 3845.737832] item 7 key (257 INODE_REF 256) itemoff 15801 itemsize 14 [ 3845.737833] index 2 name_len 4 [ 3845.737834] item 8 key (257 INODE_REF 258) itemoff 15787 itemsize 14 [ 3845.737836] index 2 name_len 4 [ 3845.737837] item 9 key (257 DIR_ITEM 2507850652) itemoff 15754 itemsize 33 [ 3845.737838] location key (259 1 0) type 1 [ 3845.737839] transid 10 data_len 0 name_len 3 [ 3845.737840] item 10 key (257 DIR_INDEX 2) itemoff 15721 itemsize 33 [ 3845.737842] location key (259 1 0) type 1 [ 3845.737843] transid 10 data_len 0 name_len 3 [ 3845.737844] item 11 key (258 INODE_ITEM 0) itemoff 15561 itemsize 160 [ 3845.737846] inode generation 9 transid 10 size 8 nbytes 0 [ 3845.737847] block group 0 mode 40755 links 1 uid 0 gid 0 [ 3845.737848] rdev 0 sequence 1 flags 0x0 [ 3845.737849] atime 1764259517.572889464 [ 3845.737850] ctime 1764259517.572889464 [ 3845.737851] mtime 1764259517.572889464 [ 3845.737852] otime 1764259517.572889464 [ 3845.737853] item 12 key (258 INODE_REF 256) itemoff 15547 itemsize 14 [ 3845.737855] index 3 name_len 4 [ 3845.737856] item 13 key (258 DIR_ITEM 1843588421) itemoff 15513 itemsize 34 [ 3845.737857] location key (257 1 0) type 2 [ 3845.737858] transid 10 data_len 0 name_len 4 [ 3845.737860] item 14 key (258 DIR_INDEX 2) itemoff 15479 itemsize 34 [ 3845.737861] location key (257 1 0) type 2 [ 3845.737862] transid 10 data_len 0 name_len 4 [ 3845.737863] item 15 key (259 INODE_ITEM 0) itemoff 15319 itemsize 160 [ 3845.737865] inode generation 10 transid 10 size 0 nbytes 0 [ 3845.737866] block group 0 mode 100600 links 1 uid 0 gid 0 [ 3845.737867] rdev 0 sequence 2 flags 0x0 [ 3845.737868] atime 1764259517.580874966 [ 3845.737869] ctime 1764259517.586121869 [ 3845.737870] mtime 1764259517.580874966 [ 3845.737872] otime 1764259517.580874966 [ 3845.737873] item 16 key (259 INODE_REF 257) itemoff 15306 itemsize 13 [ 3845.737874] index 2 name_len 3 [ 3845.737875] BTRFS error (device dm-0): block=30408704 write time tree block corruption detected [ 3845.739448] ------------[ cut here ]------------ [ 3845.740092] WARNING: CPU: 5 PID: 30701 at fs/btrfs/disk-io.c:335 btree_csum_one_bio+0x25a/0x270 [btrfs] [ 3845.741439] Modules linked in: btrfs dm_flakey crc32c_cryptoapi (...) [ 3845.750626] CPU: 5 UID: 0 PID: 30701 Comm: mount Tainted: G W 6.18.0-rc6-btrfs-next-218+ #1 PREEMPT(full) [ 3845.752414] Tainted: [W]=WARN [ 3845.752828] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 [ 3845.754499] RIP: 0010:btree_csum_one_bio+0x25a/0x270 [btrfs] [ 3845.755460] Code: 31 f6 48 89 (...) [ 3845.758685] RSP: 0018:ffffa8d9c5677678 EFLAGS: 00010246 [ 3845.759450] RAX: 0000000000000000 RBX: ffff92650e6d4738 RCX: 0000000000000000 [ 3845.760309] RDX: 0000000000000000 RSI: ffffffff9aab45b9 RDI: ffff9264c4748000 [ 3845.761239] RBP: ffff9264d4324000 R08: 0000000000000000 R09: ffffa8d9c5677468 [ 3845.762607] R10: ffff926bdc1fffa8 R11: 0000000000000003 R12: ffffa8d9c5677680 [ 3845.764099] R13: 0000000000004000 R14: ffff9264dd624000 R15: ffff9264d978aba8 [ 3845.765094] FS: 00007f751fa5a840(0000) GS:ffff926c42a82000(0000) knlGS:0000000000000000 [ 3845.766226] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3845.766970] CR2: 0000558df1815380 CR3: 000000010ed88003 CR4: 0000000000370ef0 [ 3845.768009] Call Trace: [ 3845.768392] [ 3845.768714] btrfs_submit_bbio+0x6ee/0x7f0 [btrfs] [ 3845.769640] ? write_one_eb+0x28e/0x340 [btrfs] [ 3845.770588] btree_write_cache_pages+0x2f0/0x550 [btrfs] [ 3845.771286] ? alloc_extent_state+0x19/0x100 [btrfs] [ 3845.771967] ? merge_next_state+0x1a/0x90 [btrfs] [ 3845.772586] ? set_extent_bit+0x233/0x8b0 [btrfs] [ 3845.773198] ? xas_load+0x9/0xc0 [ 3845.773589] ? xas_find+0x14d/0x1a0 [ 3845.773969] do_writepages+0xc6/0x160 [ 3845.774367] filemap_fdatawrite_wbc+0x48/0x60 [ 3845.775003] __filemap_fdatawrite_range+0x5b/0x80 [ 3845.775902] btrfs_write_marked_extents+0x61/0x170 [btrfs] [ 3845.776707] btrfs_write_and_wait_transaction+0x4e/0xc0 [btrfs] [ 3845.777379] ? _raw_spin_unlock_irqrestore+0x23/0x40 [ 3845.777923] btrfs_commit_transaction+0x5ea/0xd20 [btrfs] [ 3845.778551] ? _raw_spin_unlock+0x15/0x30 [ 3845.778986] ? release_extent_buffer+0x34/0x160 [btrfs] [ 3845.779659] btrfs_recover_log_trees+0x7a3/0x7c0 [btrfs] [ 3845.780416] ? __pfx_replay_one_buffer+0x10/0x10 [btrfs] [ 3845.781499] open_ctree+0x10bb/0x15f0 [btrfs] [ 3845.782194] btrfs_get_tree.cold+0xb/0x16c [btrfs] [ 3845.782764] ? fscontext_read+0x15c/0x180 [ 3845.783202] ? rw_verify_area+0x50/0x180 [ 3845.783667] vfs_get_tree+0x25/0xd0 [ 3845.784047] vfs_cmd_create+0x59/0xe0 [ 3845.784458] __do_sys_fsconfig+0x4f6/0x6b0 [ 3845.784914] do_syscall_64+0x50/0x1220 [ 3845.785340] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 3845.785980] RIP: 0033:0x7f751fc7f4aa [ 3845.786759] Code: 73 01 c3 48 (...) [ 3845.789951] RSP: 002b:00007ffcdba45dc8 EFLAGS: 00000246 ORIG_RAX: 00000000000001af [ 3845.791402] RAX: ffffffffffffffda RBX: 000055ccc8291c20 RCX: 00007f751fc7f4aa [ 3845.792688] RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003 [ 3845.794308] RBP: 000055ccc8292120 R08: 0000000000000000 R09: 0000000000000000 [ 3845.795829] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [ 3845.797183] R13: 00007f751fe11580 R14: 00007f751fe1326c R15: 00007f751fdf8a23 [ 3845.798633] [ 3845.799067] ---[ end trace 0000000000000000 ]--- [ 3845.800215] BTRFS: error (device dm-0) in btrfs_commit_transaction:2553: errno=-5 IO failure (Error while writing out transaction) [ 3845.801860] BTRFS warning (device dm-0 state E): Skipping commit of aborted transaction. [ 3845.802815] BTRFS error (device dm-0 state EA): Transaction aborted (error -5) [ 3845.803728] BTRFS: error (device dm-0 state EA) in cleanup_transaction:2036: errno=-5 IO failure [ 3845.805374] BTRFS: error (device dm-0 state EA) in btrfs_replay_log:2083: errno=-5 IO failure (Failed to recover log tree) [ 3845.807919] BTRFS error (device dm-0 state EA): open_ctree failed: -5 Fix this by never logging a conflicting inode that is a directory and was moved in the current transaction (its last_unlink_trans equals the current transaction) and instead fallback to a transaction commit. A test case for fstests will follow soon. Reported-by: Vyacheslav Kovalevsky Link: https://lore.kernel.org/linux-btrfs/7bbc9419-5c56-450a-b5a0-efeae7457113@gmail.com/ CC: stable@vger.kernel.org # 6.1+ Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/tree-log.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index ca01f2daac6e..3342f5ff1516 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5704,6 +5704,33 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino, return ret; } +static bool can_log_conflicting_inode(const struct btrfs_trans_handle *trans, + const struct btrfs_inode *inode) +{ + if (!S_ISDIR(inode->vfs_inode.i_mode)) + return true; + + if (inode->last_unlink_trans < trans->transid) + return true; + + /* + * If this is a directory and its unlink_trans is not from a past + * transaction then we must fallback to a transaction commit in order + * to avoid getting a directory with 2 hard links after log replay. + * + * This happens if a directory A is renamed, moved from one parent + * directory to another one, a new file is created in the old parent + * directory with the old name of our directory A, the new file is + * fsynced, then we moved the new file to some other parent directory + * and fsync again the new file. This results in a log tree where we + * logged that directory A existed, with the INODE_REF item for the + * new location but without having logged its old parent inode, so + * that on log replay we add a new link for the new location but the + * old link remains, resulting in a link count of 2. + */ + return false; +} + static int add_conflicting_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, @@ -5807,6 +5834,11 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans, return 0; } + if (!can_log_conflicting_inode(trans, inode)) { + btrfs_add_delayed_iput(inode); + return BTRFS_LOG_FORCE_COMMIT; + } + btrfs_add_delayed_iput(inode); ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS); @@ -5871,6 +5903,12 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, break; } + if (!can_log_conflicting_inode(trans, inode)) { + btrfs_add_delayed_iput(inode); + ret = BTRFS_LOG_FORCE_COMMIT; + break; + } + /* * Always log the directory, we cannot make this * conditional on need_log_inode() because the directory -- Gitee From 34ddbdbd8b594e42f82b41a341d0ca8bfa22576a Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Fri, 5 Dec 2025 17:58:57 +0800 Subject: [PATCH 0649/1449] s390/ipl: Clear SBP flag when bootprog is set ANBZ: #35228 commit 8c4e5a643de375b0ed211df03fb4161cae172c61 stable. commit b1aa01d31249bd116b18c7f512d3e46b4b4ad83b upstream. With z16 a new flag 'search boot program' was introduced for list-directed IPL (SCSI, NVMe, ECKD DASD). If this flag is set, e.g. via selecting the "Automatic" value for the "Boot program selector" control on an HMC load panel, it is copied to the reipl structure from the initial ipl structure. When a user now sets a boot prog via sysfs, the flag is not cleared and the bootloader will again automatically select the boot program, ignoring user configuration. To avoid that, clear the SBP flag when a bootprog sysfs file is written. Cc: stable@vger.kernel.org Reviewed-by: Peter Oberparleiter Reviewed-by: Heiko Carstens Signed-off-by: Sven Schnelle Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/s390/include/uapi/asm/ipl.h | 1 + arch/s390/kernel/ipl.c | 48 ++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/arch/s390/include/uapi/asm/ipl.h b/arch/s390/include/uapi/asm/ipl.h index 2cd28af50dd4..3d64a2251699 100644 --- a/arch/s390/include/uapi/asm/ipl.h +++ b/arch/s390/include/uapi/asm/ipl.h @@ -15,6 +15,7 @@ struct ipl_pl_hdr { #define IPL_PL_FLAG_IPLPS 0x80 #define IPL_PL_FLAG_SIPL 0x40 #define IPL_PL_FLAG_IPLSR 0x20 +#define IPL_PL_FLAG_SBP 0x10 /* IPL Parameter Block header */ struct ipl_pb_hdr { diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 720a62ee02b1..b9cd76a9d473 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -261,6 +261,24 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ sys_##_prefix##_##_name##_show, \ sys_##_prefix##_##_name##_store) +#define DEFINE_IPL_ATTR_BOOTPROG_RW(_prefix, _name, _fmt_out, _fmt_in, _hdr, _value) \ + IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value) \ +static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \ + struct kobj_attribute *attr, \ + const char *buf, size_t len) \ +{ \ + unsigned long long value; \ + if (sscanf(buf, _fmt_in, &value) != 1) \ + return -EINVAL; \ + (_value) = value; \ + (_hdr).flags &= ~IPL_PL_FLAG_SBP; \ + return len; \ +} \ +static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ + __ATTR(_name, 0644, \ + sys_##_prefix##_##_name##_show, \ + sys_##_prefix##_##_name##_store) + #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value) \ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \ @@ -825,12 +843,13 @@ DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n", reipl_block_fcp->fcp.wwpn); DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n", reipl_block_fcp->fcp.lun); -DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", - reipl_block_fcp->fcp.bootprog); DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n", reipl_block_fcp->fcp.br_lba); DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", reipl_block_fcp->fcp.devno); +DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", + reipl_block_fcp->hdr, + reipl_block_fcp->fcp.bootprog); static void reipl_get_ascii_loadparm(char *loadparm, struct ipl_parameter_block *ibp) @@ -983,10 +1002,11 @@ DEFINE_IPL_ATTR_RW(reipl_nvme, fid, "0x%08llx\n", "%llx\n", reipl_block_nvme->nvme.fid); DEFINE_IPL_ATTR_RW(reipl_nvme, nsid, "0x%08llx\n", "%llx\n", reipl_block_nvme->nvme.nsid); -DEFINE_IPL_ATTR_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n", - reipl_block_nvme->nvme.bootprog); DEFINE_IPL_ATTR_RW(reipl_nvme, br_lba, "%lld\n", "%lld\n", reipl_block_nvme->nvme.br_lba); +DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n", + reipl_block_nvme->hdr, + reipl_block_nvme->nvme.bootprog); static struct attribute *reipl_nvme_attrs[] = { &sys_reipl_nvme_fid_attr.attr, @@ -1113,8 +1133,9 @@ static struct bin_attribute *reipl_eckd_bin_attrs[] = { }; DEFINE_IPL_CCW_ATTR_RW(reipl_eckd, device, reipl_block_eckd->eckd); -DEFINE_IPL_ATTR_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n", - reipl_block_eckd->eckd.bootprog); +DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n", + reipl_block_eckd->hdr, + reipl_block_eckd->eckd.bootprog); static struct attribute *reipl_eckd_attrs[] = { &sys_reipl_eckd_device_attr.attr, @@ -1642,12 +1663,13 @@ DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n", dump_block_fcp->fcp.wwpn); DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n", dump_block_fcp->fcp.lun); -DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", - dump_block_fcp->fcp.bootprog); DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n", dump_block_fcp->fcp.br_lba); DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n", dump_block_fcp->fcp.devno); +DEFINE_IPL_ATTR_BOOTPROG_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", + dump_block_fcp->hdr, + dump_block_fcp->fcp.bootprog); static struct attribute *dump_fcp_attrs[] = { &sys_dump_fcp_device_attr.attr, @@ -1668,10 +1690,11 @@ DEFINE_IPL_ATTR_RW(dump_nvme, fid, "0x%08llx\n", "%llx\n", dump_block_nvme->nvme.fid); DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n", dump_block_nvme->nvme.nsid); -DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n", - dump_block_nvme->nvme.bootprog); DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n", dump_block_nvme->nvme.br_lba); +DEFINE_IPL_ATTR_BOOTPROG_RW(dump_nvme, bootprog, "%lld\n", "%llx\n", + dump_block_nvme->hdr, + dump_block_nvme->nvme.bootprog); static struct attribute *dump_nvme_attrs[] = { &sys_dump_nvme_fid_attr.attr, @@ -1688,8 +1711,9 @@ static struct attribute_group dump_nvme_attr_group = { /* ECKD dump device attributes */ DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd); -DEFINE_IPL_ATTR_RW(dump_eckd, bootprog, "%lld\n", "%llx\n", - dump_block_eckd->eckd.bootprog); +DEFINE_IPL_ATTR_BOOTPROG_RW(dump_eckd, bootprog, "%lld\n", "%llx\n", + dump_block_eckd->hdr, + dump_block_eckd->eckd.bootprog); IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd); IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd); -- Gitee From 84cd3aa4dd6ca1282180a398c0a0f553e323d2bc Mon Sep 17 00:00:00 2001 From: Wentao Guan Date: Thu, 4 Dec 2025 18:13:04 +0800 Subject: [PATCH 0650/1449] gpio: regmap: Fix memleak in error path in gpio_regmap_register() ANBZ: #35228 commit ec5aadc4fa499976096596eb6cceb58040fb9319 stable. commit 52721cfc78c76b09c66e092b52617006390ae96a upstream. Call gpiochip_remove() to free the resources allocated by gpiochip_add_data() in error path. Fixes: 553b75d4bfe9 ("gpio: regmap: Allow to allocate regmap-irq device") Fixes: ae495810cffe ("gpio: regmap: add the .fixed_direction_output configuration parameter") CC: stable@vger.kernel.org Co-developed-by: WangYuli Signed-off-by: WangYuli Signed-off-by: Wentao Guan Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20251204101303.30353-1-guanwentao@uniontech.com [Bartosz: reworked the commit message] Signed-off-by: Bartosz Golaszewski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index fd986afa7db5..f0bcb2c2c674 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -310,7 +310,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config config->regmap_irq_line, config->regmap_irq_flags, 0, config->regmap_irq_chip, &gpio->irq_chip_data); if (ret) - goto err_free_bitmap; + goto err_remove_gpiochip; irq_domain = regmap_irq_get_domain(gpio->irq_chip_data); } else -- Gitee From 52d133e0314baedaea5f8accd54a247275052b7d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 2 Dec 2025 04:25:22 +0800 Subject: [PATCH 0651/1449] io_uring/poll: correctly handle io_poll_add() return value on update ANBZ: #35228 commit 0126560370ed5217958b85657b590ad25e8b9c00 stable. Commit 84230ad2d2afbf0c44c32967e525c0ad92e26b4e upstream. When the core of io_uring was updated to handle completions consistently and with fixed return codes, the POLL_REMOVE opcode with updates got slightly broken. If a POLL_ADD is pending and then POLL_REMOVE is used to update the events of that request, if that update causes the POLL_ADD to now trigger, then that completion is lost and a CQE is never posted. Additionally, ensure that if an update does cause an existing POLL_ADD to complete, that the completion value isn't always overwritten with -ECANCELED. For that case, whatever io_poll_add() set the value to should just be retained. Cc: stable@vger.kernel.org Fixes: 97b388d70b53 ("io_uring: handle completions in the core") Reported-by: syzbot+641eec6b7af1f62f2b99@syzkaller.appspotmail.com Tested-by: syzbot+641eec6b7af1f62f2b99@syzkaller.appspotmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- io_uring/poll.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/io_uring/poll.c b/io_uring/poll.c index b6c8acd8625e..64835d692c37 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -1024,12 +1024,17 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags) ret2 = io_poll_add(preq, issue_flags & ~IO_URING_F_UNLOCKED); /* successfully updated, don't complete poll request */ - if (!ret2 || ret2 == -EIOCBQUEUED) + if (ret2 == IOU_ISSUE_SKIP_COMPLETE) goto out; + /* request completed as part of the update, complete it */ + else if (ret2 == IOU_OK) + goto complete; } - req_set_fail(preq); io_req_set_res(preq, -ECANCELED, 0); +complete: + if (preq->cqe.res < 0) + req_set_fail(preq); preq->io_task_work.func = io_req_task_complete; io_req_task_work_add(preq); out: -- Gitee From 9e3b489ec349f93a15dbe1aa4b1e2f77dc44e24e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 12 Nov 2025 00:17:22 +0800 Subject: [PATCH 0652/1449] drm/amd/display: Use GFP_ATOMIC in dc_create_plane_state() ANBZ: #35228 commit 4cd6081860a55e6b4417bf6bf6bea718aac641ab stable. commit 3c41114dcdabb7b25f5bc33273c6db9c7af7f4a7 upstream. This can get called from an atomic context. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4470 Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher (cherry picked from commit 8acdad9344cc7b4e7bc01f0dfea80093eb3768db) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index f4f3ca7aad60..9ab30dfb9ae8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -104,7 +104,7 @@ void enable_surface_flip_reporting(struct dc_plane_state *plane_state, struct dc_plane_state *dc_create_plane_state(struct dc *dc) { struct dc_plane_state *plane_state = kvzalloc(sizeof(*plane_state), - GFP_KERNEL); + GFP_ATOMIC); if (NULL == plane_state) return NULL; -- Gitee From 40f82aa53c260e2f87ec592616315f4f335983ab Mon Sep 17 00:00:00 2001 From: Adrian Moreno Date: Tue, 16 Apr 2024 17:09:13 +0800 Subject: [PATCH 0653/1449] selftests: openvswitch: Fix escape chars in regexp. ANBZ: #35228 commit d3c094e078536cd65b7119bd19f2390ccbe2110f stable. commit 3fde60afe1f84746c1177861bd27b3ebb00cb8f5 upstream. Character sequences starting with `\` are interpreted by python as escaped Unicode characters. However, they have other meaning in regular expressions (e.g: "\d"). It seems Python >= 3.12 starts emitting a SyntaxWarning when these escaped sequences are not recognized as valid Unicode characters. An example of these warnings: tools/testing/selftests/net/openvswitch/ovs-dpctl.py:505: SyntaxWarning: invalid escape sequence '\d' Fix all the warnings by flagging literals as raw strings. Signed-off-by: Adrian Moreno Reviewed-by: Aaron Conole Link: https://lore.kernel.org/r/20240416090913.2028475-1-amorenoz@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Adrian Yip Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../selftests/net/openvswitch/ovs-dpctl.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py index 8b120718768e..9f8dec2f6539 100644 --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py @@ -489,7 +489,7 @@ class ovsactions(nla): actstr, reason = parse_extract_field( actstr, "drop(", - "([0-9]+)", + r"([0-9]+)", lambda x: int(x, 0), False, None, @@ -502,9 +502,9 @@ class ovsactions(nla): actstr = actstr[len("drop"): ] return (totallen - len(actstr)) - elif parse_starts_block(actstr, "^(\d+)", False, True): + elif parse_starts_block(actstr, r"^(\d+)", False, True): actstr, output = parse_extract_field( - actstr, None, "(\d+)", lambda x: int(x), False, "0" + actstr, None, r"(\d+)", lambda x: int(x), False, "0" ) self["attrs"].append(["OVS_ACTION_ATTR_OUTPUT", output]) parsed = True @@ -512,7 +512,7 @@ class ovsactions(nla): actstr, recircid = parse_extract_field( actstr, "recirc(", - "([0-9a-fA-Fx]+)", + r"([0-9a-fA-Fx]+)", lambda x: int(x, 0), False, 0, @@ -588,17 +588,17 @@ class ovsactions(nla): actstr = actstr[3:] actstr, ip_block_min = parse_extract_field( - actstr, "=", "([0-9a-fA-F\.]+)", str, False + actstr, "=", r"([0-9a-fA-F\.]+)", str, False ) actstr, ip_block_max = parse_extract_field( - actstr, "-", "([0-9a-fA-F\.]+)", str, False + actstr, "-", r"([0-9a-fA-F\.]+)", str, False ) actstr, proto_min = parse_extract_field( - actstr, ":", "(\d+)", int, False + actstr, ":", r"(\d+)", int, False ) actstr, proto_max = parse_extract_field( - actstr, "-", "(\d+)", int, False + actstr, "-", r"(\d+)", int, False ) if t is not None: -- Gitee From 8393f899b491dc8c0acfd9f3cadff0e21b7b7897 Mon Sep 17 00:00:00 2001 From: Shivani Agarwal Date: Wed, 24 Sep 2025 14:01:48 +0800 Subject: [PATCH 0654/1449] crypto: af_alg - zero initialize memory allocated via sock_kmalloc ANBZ: #35228 commit 84238876e3b3b262cf62d5f4d1338e983fb27010 stable. commit 6f6e309328d53a10c0fe1f77dec2db73373179b6 upstream. Several crypto user API contexts and requests allocated with sock_kmalloc() were left uninitialized, relying on callers to set fields explicitly. This resulted in the use of uninitialized data in certain error paths or when new fields are added in the future. The ACVP patches also contain two user-space interface files: algif_kpp.c and algif_akcipher.c. These too rely on proper initialization of their context structures. A particular issue has been observed with the newly added 'inflight' variable introduced in af_alg_ctx by commit: 67b164a871af ("crypto: af_alg - Disallow multiple in-flight AIO requests") Because the context is not memset to zero after allocation, the inflight variable has contained garbage values. As a result, af_alg_alloc_areq() has incorrectly returned -EBUSY randomly when the garbage value was interpreted as true: https://github.com/gregkh/linux/blame/master/crypto/af_alg.c#L1209 The check directly tests ctx->inflight without explicitly comparing against true/false. Since inflight is only ever set to true or false later, an uninitialized value has triggered -EBUSY failures. Zero-initializing memory allocated with sock_kmalloc() ensures inflight and other fields start in a known state, removing random issues caused by uninitialized data. Fixes: fe869cdb89c9 ("crypto: algif_hash - User-space interface for hash operations") Fixes: 5afdfd22e6ba ("crypto: algif_rng - add random number generator support") Fixes: 2d97591ef43d ("crypto: af_alg - consolidation of duplicate code") Fixes: 67b164a871af ("crypto: af_alg - Disallow multiple in-flight AIO requests") Cc: stable@vger.kernel.org Signed-off-by: Shivani Agarwal Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- crypto/af_alg.c | 5 ++--- crypto/algif_hash.c | 3 +-- crypto/algif_rng.c | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 30b07f1782bb..2c1ec61cfb56 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -1182,15 +1182,14 @@ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, if (unlikely(!areq)) return ERR_PTR(-ENOMEM); + memset(areq, 0, areqlen); + ctx->inflight = true; areq->areqlen = areqlen; areq->sk = sk; areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl; - areq->last_rsgl = NULL; INIT_LIST_HEAD(&areq->rsgl_list); - areq->tsgl = NULL; - areq->tsgl_entries = 0; return areq; } diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 5ab7441734b8..265cabcb95e0 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -416,9 +416,8 @@ static int hash_accept_parent_nokey(void *private, struct sock *sk) if (!ctx) return -ENOMEM; - ctx->result = NULL; + memset(ctx, 0, len); ctx->len = len; - ctx->more = false; crypto_init_wait(&ctx->wait); ask->private = ctx; diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c index 10c41adac3b1..1a86e40c8372 100644 --- a/crypto/algif_rng.c +++ b/crypto/algif_rng.c @@ -248,9 +248,8 @@ static int rng_accept_parent(void *private, struct sock *sk) if (!ctx) return -ENOMEM; + memset(ctx, 0, len); ctx->len = len; - ctx->addtl = NULL; - ctx->addtl_len = 0; /* * No seeding done at that point -- if multiple accepts are -- Gitee From 6a5b4fe61676e34db22eb3b77f9234eb83553036 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Tue, 23 Sep 2025 20:44:18 +0800 Subject: [PATCH 0655/1449] crypto: caam - Add check for kcalloc() in test_len() ANBZ: #35228 commit 206c012bcbd1f1d94a1372fb3401bd23bf2617c9 stable. commit 7cf6e0b69b0d90ab042163e5bbddda0dfcf8b6a7 upstream. As kcalloc() may fail, check its return value to avoid a NULL pointer dereference when passing the buffer to rng->read(). On allocation failure, log the error and return since test_len() returns void. Fixes: 2be0d806e25e ("crypto: caam - add a test for the RNG") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/caam/caamrng.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c index b3d14a7f4dd1..0eb43c862516 100644 --- a/drivers/crypto/caam/caamrng.c +++ b/drivers/crypto/caam/caamrng.c @@ -181,7 +181,9 @@ static inline void test_len(struct hwrng *rng, size_t len, bool wait) struct device *dev = ctx->ctrldev; buf = kcalloc(CAAM_RNG_MAX_FIFO_STORE_SIZE, sizeof(u8), GFP_KERNEL); - + if (!buf) { + return; + } while (len > 0) { read_len = rng->read(rng, buf, len, wait); -- Gitee From ad95d6df3b6f22709dde613be91f3f34fb693c3e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 25 Sep 2025 23:00:07 +0800 Subject: [PATCH 0656/1449] amba: tegra-ahb: Fix device leak on SMMU enable ANBZ: #35228 commit b3b689729cbc0a1f9985dc62e48f1a72fde19bd5 stable. commit 500e1368e46928f4b2259612dcabb6999afae2a6 upstream. Make sure to drop the reference taken to the AHB platform device when looking up its driver data while enabling the SMMU. Note that holding a reference to a device does not prevent its driver data from going away. Fixes: 89c788bab1f0 ("ARM: tegra: Add SMMU enabler in AHB") Cc: stable@vger.kernel.org # 3.5 Signed-off-by: Johan Hovold Signed-off-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/amba/tegra-ahb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index c0e8b765522d..f23c3ed01810 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -144,6 +144,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn) if (!dev) return -EPROBE_DEFER; ahb = dev_get_drvdata(dev); + put_device(dev); val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL); val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE; gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL); -- Gitee From 560c19370547575b7b26160f2f56b4ff34c90492 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 5 Dec 2025 04:19:35 +0800 Subject: [PATCH 0657/1449] tracing: Fix fixed array of synthetic event ANBZ: #35228 commit 98bf1dece54c9d1e143e3cf0b7e22d3f00717a5b stable. commit 47ef834209e5981f443240d8a8b45bf680df22aa upstream. The commit 4d38328eb442d ("tracing: Fix synth event printk format for str fields") replaced "%.*s" with "%s" but missed removing the number size of the dynamic and static strings. The commit e1a453a57bc7 ("tracing: Do not add length to print format in synthetic events") fixed the dynamic part but did not fix the static part. That is, with the commands: # echo 's:wake_lat char[] wakee; u64 delta;' >> /sys/kernel/tracing/dynamic_events # echo 'hist:keys=pid:ts=common_timestamp.usecs if !(common_flags & 0x18)' > /sys/kernel/tracing/events/sched/sched_waking/trigger # echo 'hist:keys=next_pid:delta=common_timestamp.usecs-$ts:onmatch(sched.sched_waking).trace(wake_lat,next_comm,$delta)' > /sys/kernel/tracing/events/sched/sched_switch/trigger That caused the output of: -0 [001] d..5. 193.428167: wake_lat: wakee=(efault)sshd-sessiondelta=155 sshd-session-879 [001] d..5. 193.811080: wake_lat: wakee=(efault)kworker/u34:5delta=58 -0 [002] d..5. 193.811198: wake_lat: wakee=(efault)bashdelta=91 The commit e1a453a57bc7 fixed the part where the synthetic event had "char[] wakee". But if one were to replace that with a static size string: # echo 's:wake_lat char[16] wakee; u64 delta;' >> /sys/kernel/tracing/dynamic_events Where "wakee" is defined as "char[16]" and not "char[]" making it a static size, the code triggered the "(efaul)" again. Remove the added STR_VAR_LEN_MAX size as the string is still going to be nul terminated. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Douglas Raillard Link: https://patch.msgid.link/20251204151935.5fa30355@gandalf.local.home Fixes: e1a453a57bc7 ("tracing: Do not add length to print format in synthetic events") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/trace/trace_events_synth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 794e72dbb12d..181af676f93d 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -382,7 +382,6 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter, n_u64++; } else { trace_seq_printf(s, print_fmt, se->fields[i]->name, - STR_VAR_LEN_MAX, (char *)&entry->fields[n_u64].as_u64, i == se->n_fields - 1 ? "" : " "); n_u64 += STR_VAR_LEN_MAX / sizeof(u64); -- Gitee From 4818ed00ae3d50e5d069114476b43663a97de1bf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 26 Sep 2025 22:35:10 +0800 Subject: [PATCH 0658/1449] soc: qcom: ocmem: fix device leak on lookup ANBZ: #35228 commit c8ddc5f321d125cd2804106351e87aafa8e0df51 stable. commit b5c16ea57b030b8e9428ec726e26219dfe05c3d9 upstream. Make sure to drop the reference taken to the ocmem platform device when looking up its driver data. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Also note that commit 0ff027027e05 ("soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem") fixed the leak in a lookup error path, but the reference is still leaking on success. Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver") Cc: stable@vger.kernel.org # 5.5: 0ff027027e05 Cc: Brian Masney Cc: Miaoqian Lin Signed-off-by: Johan Hovold Reviewed-by: Brian Masney Link: https://lore.kernel.org/r/20250926143511.6715-2-johan@kernel.org Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/soc/qcom/ocmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index 20f5461d46b9..1511d19643d4 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -204,9 +204,9 @@ struct ocmem *of_get_ocmem(struct device *dev) of_node_put(devnode); ocmem = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!ocmem) { dev_err(dev, "Cannot get ocmem\n"); - put_device(&pdev->dev); return ERR_PTR(-ENODEV); } return ocmem; -- Gitee From cbfaf62b4d465d74348141f58d3f72103e6de13d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 26 Sep 2025 22:24:53 +0800 Subject: [PATCH 0659/1449] soc: amlogic: canvas: fix device leak on lookup ANBZ: #35228 commit 3ccb504e80450e0594e174c0336f20d3fb5169a1 stable. commit 32200f4828de9d7e6db379909898e718747f4e18 upstream. Make sure to drop the reference taken to the canvas platform device when looking up its driver data. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Also note that commit 28f851e6afa8 ("soc: amlogic: canvas: add missing put_device() call in meson_canvas_get()") fixed the leak in a lookup error path, but the reference is still leaking on success. Fixes: d4983983d987 ("soc: amlogic: add meson-canvas driver") Cc: stable@vger.kernel.org # 4.20: 28f851e6afa8 Cc: Yu Kuai Signed-off-by: Johan Hovold Reviewed-by: Martin Blumenstingl Link: https://patch.msgid.link/20250926142454.5929-2-johan@kernel.org Signed-off-by: Neil Armstrong Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/soc/amlogic/meson-canvas.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c index b6e06c4d2117..0711088da5dc 100644 --- a/drivers/soc/amlogic/meson-canvas.c +++ b/drivers/soc/amlogic/meson-canvas.c @@ -73,10 +73,9 @@ struct meson_canvas *meson_canvas_get(struct device *dev) * current state, this driver probe cannot return -EPROBE_DEFER */ canvas = dev_get_drvdata(&canvas_pdev->dev); - if (!canvas) { - put_device(&canvas_pdev->dev); + put_device(&canvas_pdev->dev); + if (!canvas) return ERR_PTR(-EINVAL); - } return canvas; } -- Gitee From 1a0a117ef0845166b150d08f273b713be2bcad72 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 22 Aug 2025 18:00:42 +0800 Subject: [PATCH 0660/1449] rpmsg: glink: fix rpmsg device leak ANBZ: #35228 commit c6210714347f72bae8e7142dc0a7f99923c466e7 stable. commit a53e356df548f6b0e82529ef3cc6070f42622189 upstream. While testing rpmsg-char interface it was noticed that duplicate sysfs entries are getting created and below warning is noticed. Reason for this is that we are leaking rpmsg device pointer, setting it null without actually unregistering device. Any further attempts to unregister fail because rpdev is NULL, resulting in a leak. Fix this by unregistering rpmsg device before removing its reference from rpmsg channel. sysfs: cannot create duplicate filename '/devices/platform/soc@0/3700000.remot eproc/remoteproc/remoteproc1/3700000.remoteproc:glink-edge/3700000.remoteproc: glink-edge.adsp_apps.-1.-1' [ 114.115347] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:0 Not tainted 6.16.0-rc4 #7 PREEMPT [ 114.115355] Hardware name: Qualcomm Technologies, Inc. Robotics RB3gen2 (DT) [ 114.115358] Workqueue: events qcom_glink_work [ 114.115371] Call trace:8 [ 114.115374] show_stack+0x18/0x24 (C) [ 114.115382] dump_stack_lvl+0x60/0x80 [ 114.115388] dump_stack+0x18/0x24 [ 114.115393] sysfs_warn_dup+0x64/0x80 [ 114.115402] sysfs_create_dir_ns+0xf4/0x120 [ 114.115409] kobject_add_internal+0x98/0x260 [ 114.115416] kobject_add+0x9c/0x108 [ 114.115421] device_add+0xc4/0x7a0 [ 114.115429] rpmsg_register_device+0x5c/0xb0 [ 114.115434] qcom_glink_work+0x4bc/0x820 [ 114.115438] process_one_work+0x148/0x284 [ 114.115446] worker_thread+0x2c4/0x3e0 [ 114.115452] kthread+0x12c/0x204 [ 114.115457] ret_from_fork+0x10/0x20 [ 114.115464] kobject: kobject_add_internal failed for 3700000.remoteproc: glink-edge.adsp_apps.-1.-1 with -EEXIST, don't try to register things with the same name in the same directory. [ 114.250045] rpmsg 3700000.remoteproc:glink-edge.adsp_apps.-1.-1: device_add failed: -17 Fixes: 835764ddd9af ("rpmsg: glink: Move the common glink protocol implementation to glink_native.c") Cc: Stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250822100043.2604794-2-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/rpmsg/qcom_glink_native.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index c7f91a82e634..da2fe69ba204 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1317,6 +1317,7 @@ static void qcom_glink_destroy_ept(struct rpmsg_endpoint *ept) { struct glink_channel *channel = to_glink_channel(ept); struct qcom_glink *glink = channel->glink; + struct rpmsg_channel_info chinfo; unsigned long flags; spin_lock_irqsave(&channel->recv_lock, flags); @@ -1324,6 +1325,13 @@ static void qcom_glink_destroy_ept(struct rpmsg_endpoint *ept) spin_unlock_irqrestore(&channel->recv_lock, flags); /* Decouple the potential rpdev from the channel */ + if (channel->rpdev) { + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); + chinfo.src = RPMSG_ADDR_ANY; + chinfo.dst = RPMSG_ADDR_ANY; + + rpmsg_unregister_device(glink->dev, &chinfo); + } channel->rpdev = NULL; qcom_glink_send_close_req(glink, channel); -- Gitee From 7f9e4a47a6277d330ec5f4a7a5219943a7ccbe40 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 21 Nov 2025 18:04:50 +0800 Subject: [PATCH 0661/1449] platform/x86: intel: chtwc_int33fe: don't dereference swnode args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit ad296c4e19c73f6ba9ecf45d5e4915e7a6f77279 stable. commit 527250cd9092461f1beac3e4180a4481bffa01b5 upstream. Members of struct software_node_ref_args should not be dereferenced directly but set using the provided macros. Commit d7cdbbc93c56 ("software node: allow referencing firmware nodes") changed the name of the software node member and caused a build failure. Remove all direct dereferences of the ref struct as a fix. However, this driver also seems to abuse the software node interface by waiting for a node with an arbitrary name "intel-xhci-usb-sw" to appear in the system before setting up the reference for the I2C device, while the actual software node already exists in the intel-xhci-usb-role-switch module and should be used to set up a static reference. Add a FIXME for a future improvement. Fixes: d7cdbbc93c56 ("software node: allow referencing firmware nodes") Fixes: 53c24c2932e5 ("platform/x86: intel_cht_int33fe: use inline reference properties") Cc: stable@vger.kernel.org Reported-by: Stephen Rothwell Closes: https://lore.kernel.org/all/20251121111534.7cdbfe5c@canb.auug.org.au/ Signed-off-by: Bartosz Golaszewski Reviewed-by: Hans de Goede Acked-by: Ilpo Järvinen Signed-off-by: Philipp Zabel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/intel/chtwc_int33fe.c | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/intel/chtwc_int33fe.c b/drivers/platform/x86/intel/chtwc_int33fe.c index 848baecc1bb0..a6ff3ef5b8db 100644 --- a/drivers/platform/x86/intel/chtwc_int33fe.c +++ b/drivers/platform/x86/intel/chtwc_int33fe.c @@ -77,7 +77,7 @@ static const struct software_node max17047_node = { * software node. */ static struct software_node_ref_args fusb302_mux_refs[] = { - { .node = NULL }, + SOFTWARE_NODE_REFERENCE(NULL), }; static const struct property_entry fusb302_properties[] = { @@ -190,11 +190,6 @@ static void cht_int33fe_remove_nodes(struct cht_int33fe_data *data) { software_node_unregister_node_group(node_group); - if (fusb302_mux_refs[0].node) { - fwnode_handle_put(software_node_fwnode(fusb302_mux_refs[0].node)); - fusb302_mux_refs[0].node = NULL; - } - if (data->dp) { data->dp->secondary = NULL; fwnode_handle_put(data->dp); @@ -202,7 +197,15 @@ static void cht_int33fe_remove_nodes(struct cht_int33fe_data *data) } } -static int cht_int33fe_add_nodes(struct cht_int33fe_data *data) +static void cht_int33fe_put_swnode(void *data) +{ + struct fwnode_handle *fwnode = data; + + fwnode_handle_put(fwnode); + fusb302_mux_refs[0] = SOFTWARE_NODE_REFERENCE(NULL); +} + +static int cht_int33fe_add_nodes(struct device *dev, struct cht_int33fe_data *data) { const struct software_node *mux_ref_node; int ret; @@ -212,17 +215,25 @@ static int cht_int33fe_add_nodes(struct cht_int33fe_data *data) * until the mux driver has created software node for the mux device. * It means we depend on the mux driver. This function will return * -EPROBE_DEFER until the mux device is registered. + * + * FIXME: the relevant software node exists in intel-xhci-usb-role-switch + * and - if exported - could be used to set up a static reference. */ mux_ref_node = software_node_find_by_name(NULL, "intel-xhci-usb-sw"); if (!mux_ref_node) return -EPROBE_DEFER; + ret = devm_add_action_or_reset(dev, cht_int33fe_put_swnode, + software_node_fwnode(mux_ref_node)); + if (ret) + return ret; + /* * Update node used in "usb-role-switch" property. Note that we * rely on software_node_register_node_group() to use the original * instance of properties instead of copying them. */ - fusb302_mux_refs[0].node = mux_ref_node; + fusb302_mux_refs[0] = SOFTWARE_NODE_REFERENCE(mux_ref_node); ret = software_node_register_node_group(node_group); if (ret) @@ -345,7 +356,7 @@ static int cht_int33fe_typec_probe(struct platform_device *pdev) return fusb302_irq; } - ret = cht_int33fe_add_nodes(data); + ret = cht_int33fe_add_nodes(dev, data); if (ret) return ret; -- Gitee From 86bebd88ab03243c1a9f8c866a9ad4b6a3a0996f Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Wed, 22 Oct 2025 17:54:02 +0800 Subject: [PATCH 0662/1449] i2c: amd-mp2: fix reference leak in MP2 PCI device ANBZ: #35228 commit 237a3095bcd6b0c191a1086b7850ae1ea9cb2353 stable. commit a6ee6aac66fb394b7f6e6187c73bdcd873f2d139 upstream. In i2c_amd_probe(), amd_mp2_find_device() utilizes driver_find_next_device() which internally calls driver_find_device() to locate the matching device. driver_find_device() increments the reference count of the found device by calling get_device(), but amd_mp2_find_device() fails to call put_device() to decrement the reference count before returning. This results in a reference count leak of the PCI device each time i2c_amd_probe() is executed, which may prevent the device from being properly released and cause a memory leak. Found by code review. Cc: stable@vger.kernel.org Fixes: 529766e0a011 ("i2c: Add drivers for the AMD PCIe MP2 I2C controller") Signed-off-by: Ma Ke Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20251022095402.8846-1-make24@iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/i2c/busses/i2c-amd-mp2-pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index 143165300949..73bab21aefc8 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -461,13 +461,16 @@ struct amd_mp2_dev *amd_mp2_find_device(void) { struct device *dev; struct pci_dev *pci_dev; + struct amd_mp2_dev *mp2_dev; dev = driver_find_next_device(&amd_mp2_pci_driver.driver, NULL); if (!dev) return NULL; pci_dev = to_pci_dev(dev); - return (struct amd_mp2_dev *)pci_get_drvdata(pci_dev); + mp2_dev = (struct amd_mp2_dev *)pci_get_drvdata(pci_dev); + put_device(dev); + return mp2_dev; } EXPORT_SYMBOL_GPL(amd_mp2_find_device); -- Gitee From cedba1bde51f6e0444722409db5007497d45ae53 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Fri, 28 Nov 2025 20:47:09 +0800 Subject: [PATCH 0663/1449] hwmon: (max16065) Use local variable to avoid TOCTOU ANBZ: #35228 commit 3769c56a1f0dddde0394a94ba83f1f664c05a5fa stable. commit b8d5acdcf525f44e521ca4ef51dce4dac403dab4 upstream. In max16065_current_show, data->curr_sense is read twice: once for the error check and again for the calculation. Since i2c_smbus_read_byte_data returns negative error codes on failure, if the data changes to an error code between the check and the use, ADC_TO_CURR results in an incorrect calculation. Read data->curr_sense into a local variable to ensure consistency. Note that data->curr_gain is constant and safe to access directly. This aligns max16065_current_show with max16065_input_show, which already uses a local variable for the same reason. Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/ Fixes: f5bae2642e3d ("hwmon: Driver for MAX16065 System Manager and compatibles") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Link: https://lore.kernel.org/r/20251128124709.3876-1-hanguidong02@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/max16065.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index 0ccb5eb596fc..4c9e7892a73c 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -216,12 +216,13 @@ static ssize_t max16065_current_show(struct device *dev, struct device_attribute *da, char *buf) { struct max16065_data *data = max16065_update_device(dev); + int curr_sense = data->curr_sense; - if (unlikely(data->curr_sense < 0)) - return data->curr_sense; + if (unlikely(curr_sense < 0)) + return curr_sense; return sysfs_emit(buf, "%d\n", - ADC_TO_CURR(data->curr_sense, data->curr_gain)); + ADC_TO_CURR(curr_sense, data->curr_gain)); } static ssize_t max16065_limit_store(struct device *dev, -- Gitee From fe2f86c6437683e2c0d399add917659847966603 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Wed, 3 Dec 2025 02:01:05 +0800 Subject: [PATCH 0664/1449] hwmon: (w83791d) Convert macros to functions to avoid TOCTOU ANBZ: #35228 commit f94800fbc26ccf7c81eb791707b038a57aa39a18 stable. commit 670d7ef945d3a84683594429aea6ab2cdfa5ceb4 upstream. The macro FAN_FROM_REG evaluates its arguments multiple times. When used in lockless contexts involving shared driver data, this leads to Time-of-Check to Time-of-Use (TOCTOU) race conditions, potentially causing divide-by-zero errors. Convert the macro to a static function. This guarantees that arguments are evaluated only once (pass-by-value), preventing the race conditions. Additionally, in store_fan_div, move the calculation of the minimum limit inside the update lock. This ensures that the read-modify-write sequence operates on consistent data. Adhere to the principle of minimal changes by only converting macros that evaluate arguments multiple times and are used in lockless contexts. Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/ Fixes: 9873964d6eb2 ("[PATCH] HWMON: w83791d: New hardware monitoring driver for the Winbond W83791D") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Link: https://lore.kernel.org/r/20251202180105.12842-1-hanguidong02@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/w83791d.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 9681eaa06c8e..30dbf15c3877 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -218,9 +218,14 @@ static u8 fan_to_reg(long rpm, int div) return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ - ((val) == 255 ? 0 : \ - 1350000 / ((val) * (div)))) +static int fan_from_reg(int val, int div) +{ + if (val == 0) + return -1; + if (val == 255) + return 0; + return 1350000 / (val * div); +} /* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */ #define TEMP1_FROM_REG(val) ((val) * 1000) @@ -521,7 +526,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ struct w83791d_data *data = w83791d_update_device(dev); \ int nr = sensor_attr->index; \ return sprintf(buf, "%d\n", \ - FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ + fan_from_reg(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ } show_fan_reg(fan); @@ -585,10 +590,10 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr, if (err) return err; + mutex_lock(&data->update_lock); /* Save fan_min */ - min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); + min = fan_from_reg(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); - mutex_lock(&data->update_lock); data->fan_div[nr] = div_to_reg(nr, val); switch (nr) { -- Gitee From e7fda7b053bd32fd23fc8e1f51e0d2e378639cd6 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Fri, 28 Nov 2025 20:38:16 +0800 Subject: [PATCH 0665/1449] hwmon: (w83l786ng) Convert macros to functions to avoid TOCTOU ANBZ: #35228 commit 84716eb9dc317f129403de70432efa601d105976 stable. commit 07272e883fc61574b8367d44de48917f622cdd83 upstream. The macros FAN_FROM_REG and TEMP_FROM_REG evaluate their arguments multiple times. When used in lockless contexts involving shared driver data, this causes Time-of-Check to Time-of-Use (TOCTOU) race conditions. Convert the macros to static functions. This guarantees that arguments are evaluated only once (pass-by-value), preventing the race conditions. Adhere to the principle of minimal changes by only converting macros that evaluate arguments multiple times and are used in lockless contexts. Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/ Fixes: 85f03bccd6e0 ("hwmon: Add support for Winbond W83L786NG/NR") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Link: https://lore.kernel.org/r/20251128123816.3670-1-hanguidong02@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/w83l786ng.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 75874cf7851c..627c766588e2 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -76,15 +76,25 @@ FAN_TO_REG(long rpm, int div) return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \ - ((val) == 255 ? 0 : \ - 1350000 / ((val) * (div)))) +static int fan_from_reg(int val, int div) +{ + if (val == 0) + return -1; + if (val == 255) + return 0; + return 1350000 / (val * div); +} /* for temp */ #define TEMP_TO_REG(val) (clamp_val(((val) < 0 ? (val) + 0x100 * 1000 \ : (val)) / 1000, 0, 0xff)) -#define TEMP_FROM_REG(val) (((val) & 0x80 ? \ - (val) - 0x100 : (val)) * 1000) + +static int temp_from_reg(int val) +{ + if (val & 0x80) + return (val - 0x100) * 1000; + return val * 1000; +} /* * The analog voltage inputs have 8mV LSB. Since the sysfs output is @@ -280,7 +290,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ int nr = to_sensor_dev_attr(attr)->index; \ struct w83l786ng_data *data = w83l786ng_update_device(dev); \ return sprintf(buf, "%d\n", \ - FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ + fan_from_reg(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \ } show_fan_reg(fan); @@ -347,7 +357,7 @@ store_fan_div(struct device *dev, struct device_attribute *attr, /* Save fan_min */ mutex_lock(&data->update_lock); - min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); + min = fan_from_reg(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); data->fan_div[nr] = DIV_TO_REG(val); @@ -409,7 +419,7 @@ show_temp(struct device *dev, struct device_attribute *attr, char *buf) int nr = sensor_attr->nr; int index = sensor_attr->index; struct w83l786ng_data *data = w83l786ng_update_device(dev); - return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr][index])); + return sprintf(buf, "%d\n", temp_from_reg(data->temp[nr][index])); } static ssize_t -- Gitee From a1af2692d41690e76945cb957c9050dd406a8671 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 14 Nov 2025 22:02:25 +0800 Subject: [PATCH 0666/1449] ARM: dts: microchip: sama5d2: fix spi flexcom fifo size to 32 ANBZ: #35228 commit e195784445877afcf235b237cf96c43883056efd stable. commit 7d5864dc5d5ea6a35983dd05295fb17f2f2f44ce upstream. Unlike standalone spi peripherals, on sama5d2, the flexcom spi have fifo size of 32 data. Fix flexcom/spi nodes where this property is wrong. Fixes: 6b9a3584c7ed ("ARM: dts: at91: sama5d2: Add missing flexcom definitions") Cc: stable@vger.kernel.org # 5.8+ Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20251114140225.30372-1-nicolas.ferre@microchip.com Signed-off-by: Claudiu Beznea Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/microchip/sama5d2.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/microchip/sama5d2.dtsi b/arch/arm/boot/dts/microchip/sama5d2.dtsi index 5f8e297e19ed..92ee26fec8b4 100644 --- a/arch/arm/boot/dts/microchip/sama5d2.dtsi +++ b/arch/arm/boot/dts/microchip/sama5d2.dtsi @@ -568,7 +568,7 @@ AT91_XDMAC_DT_PERID(11))>, AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(12))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -639,7 +639,7 @@ AT91_XDMAC_DT_PERID(13))>, AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(14))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -851,7 +851,7 @@ AT91_XDMAC_DT_PERID(15))>, AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(16))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -922,7 +922,7 @@ AT91_XDMAC_DT_PERID(17))>, AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(18))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; @@ -994,7 +994,7 @@ AT91_XDMAC_DT_PERID(19))>, AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(20))>; dma-names = "tx", "rx"; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; -- Gitee From 7325edc3344ca198784524ec476db5a71529ca4c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:10 +0800 Subject: [PATCH 0667/1449] iommu/mediatek: fix use-after-free on probe deferral ANBZ: #35228 commit 5c04217d06a1161aaf36267e9d971ab6f847d5a7 stable. commit de83d4617f9fe059623e97acf7e1e10d209625b5 upstream. The driver is dropping the references taken to the larb devices during probe after successful lookup as well as on errors. This can potentially lead to a use-after-free in case a larb device has not yet been bound to its driver so that the iommu driver probe defers. Fix this by keeping the references as expected while the iommu driver is bound. Fixes: 26593928564c ("iommu/mediatek: Add error path for loop of mm_dts_parse") Cc: stable@vger.kernel.org Cc: Yong Wu Acked-by: Robin Murphy Signed-off-by: Johan Hovold Reviewed-by: Yong Wu Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/mtk_iommu.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index a13c9120428d..ce84bf9ede00 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -1213,16 +1213,19 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m } component_match_add(dev, match, component_compare_dev, &plarbdev->dev); - platform_device_put(plarbdev); } - if (!frst_avail_smicomm_node) - return -EINVAL; + if (!frst_avail_smicomm_node) { + ret = -EINVAL; + goto err_larbdev_put; + } pcommdev = of_find_device_by_node(frst_avail_smicomm_node); of_node_put(frst_avail_smicomm_node); - if (!pcommdev) - return -ENODEV; + if (!pcommdev) { + ret = -ENODEV; + goto err_larbdev_put; + } data->smicomm_dev = &pcommdev->dev; link = device_link_add(data->smicomm_dev, dev, @@ -1230,7 +1233,8 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m platform_device_put(pcommdev); if (!link) { dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev)); - return -EINVAL; + ret = -EINVAL; + goto err_larbdev_put; } return 0; @@ -1402,8 +1406,12 @@ static int mtk_iommu_probe(struct platform_device *pdev) iommu_device_sysfs_remove(&data->iommu); out_list_del: list_del(&data->list); - if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) + if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { device_link_remove(data->smicomm_dev, dev); + + for (i = 0; i < MTK_LARB_NR_MAX; i++) + put_device(data->larb_imu[i].dev); + } out_runtime_disable: pm_runtime_disable(dev); return ret; @@ -1423,6 +1431,9 @@ static void mtk_iommu_remove(struct platform_device *pdev) if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { device_link_remove(data->smicomm_dev, &pdev->dev); component_master_del(&pdev->dev, &mtk_iommu_com_ops); + + for (i = 0; i < MTK_LARB_NR_MAX; i++) + put_device(data->larb_imu[i].dev); } pm_runtime_disable(&pdev->dev); for (i = 0; i < data->plat_data->banks_num; i++) { -- Gitee From 5d739bed56081b7e31c824304122e91a43d1e6b2 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Tue, 25 Nov 2025 09:38:49 +0800 Subject: [PATCH 0668/1449] wifi: rtw88: limit indirect IO under powered off for RTL8822CS ANBZ: #35228 commit 34e9dd0a1281287f2a8035a0198b48f351adbd08 stable. commit f3ccdfda345ca9a624ea425840a926b8338c1e25 upstream. The indirect IO is necessary for RTL8822CS, but not necessary for other chips. Otherwiese, it throws errors and becomes unusable. rtw88_8723cs mmc1:0001:1: WOW Firmware version 11.0.0, H2C version 0 rtw88_8723cs mmc1:0001:1: Firmware version 11.0.0, H2C version 0 rtw88_8723cs mmc1:0001:1: sdio read32 failed (0xf0): -110 rtw88_8723cs mmc1:0001:1: sdio write8 failed (0x1c): -110 rtw88_8723cs mmc1:0001:1: sdio read32 failed (0xf0): -110 By vendor driver, only RTL8822CS and RTL8822ES need indirect IO, but RTL8822ES isn't supported yet. Therefore, limit it to RTL8822CS only. Reported-by: Andrey Skvortsov Closes: https://lore.kernel.org/linux-wireless/07a32e2d6c764eb1bd9415b5a921a652@realtek.com/T/#m997b4522f7209ba629561c776bfd1d13ab24c1d4 Fixes: 58de1f91e033 ("wifi: rtw88: sdio: use indirect IO for device registers before power-on") Signed-off-by: Ping-Ke Shih Tested-by: Andrey Skvortsov Link: https://patch.msgid.link/1764034729-1251-1-git-send-email-pkshih@realtek.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/realtek/rtw88/sdio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index df4248744d87..025a97526551 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -143,8 +143,10 @@ static u32 rtw_sdio_to_io_address(struct rtw_dev *rtwdev, u32 addr, static bool rtw_sdio_use_direct_io(struct rtw_dev *rtwdev, u32 addr) { + bool might_indirect_under_power_off = rtwdev->chip->id == RTW_CHIP_TYPE_8822C; + if (!test_bit(RTW_FLAG_POWERON, rtwdev->flags) && - !rtw_sdio_is_bus_addr(addr)) + !rtw_sdio_is_bus_addr(addr) && might_indirect_under_power_off) return false; return !rtw_sdio_is_sdio30_supported(rtwdev) || -- Gitee From 8d96d3b013ff3fbc3331f791ce31b0cde5218cb8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 3 Dec 2025 19:14:47 +0800 Subject: [PATCH 0669/1449] wifi: cfg80211: sme: store capped length in __cfg80211_connect_result() ANBZ: #35228 commit 8e628bebb109261709734bfa9f1645dfca744e3e stable. commit 2b77b9551d1184cb5af8271ff350e6e2c1b3db0d upstream. The QGenie AI code review tool says we should store the capped length to wdev->u.client.ssid_len. The AI is correct. Fixes: 62b635dcd69c ("wifi: cfg80211: sme: cap SSID length in __cfg80211_connect_result()") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/aTAbp5RleyH_lnZE@stanley.mountain Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/wireless/sme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 5904c869085c..6f116ae5442b 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -925,7 +925,7 @@ void __cfg80211_connect_result(struct net_device *dev, ssid_len = min(ssid->datalen, IEEE80211_MAX_SSID_LEN); memcpy(wdev->u.client.ssid, ssid->data, ssid_len); - wdev->u.client.ssid_len = ssid->datalen; + wdev->u.client.ssid_len = ssid_len; break; } rcu_read_unlock(); -- Gitee From f763f87d86387939b8d9cd0bf156632b58921bf2 Mon Sep 17 00:00:00 2001 From: Aloka Dixit Date: Tue, 16 Dec 2025 01:46:56 +0800 Subject: [PATCH 0670/1449] wifi: mac80211: do not use old MBSSID elements ANBZ: #35228 commit e27036473d398ed52b02f603aebdc2793c8c5cdf stable. commit a519be2f5d958c5804f2cfd68f1f384291271fab upstream. When userspace brings down and deletes a non-transmitted profile, it is expected to send a new updated Beacon template for the transmitted profile of that multiple BSSID (MBSSID) group which does not include the removed profile in MBSSID element. This update comes via NL80211_CMD_SET_BEACON. Such updates work well as long as the group continues to have at least one non-transmitted profile as NL80211_ATTR_MBSSID_ELEMS is included in the new Beacon template. But when the last non-trasmitted profile is removed, it still gets included in Beacon templates sent to driver. This happens because when no MBSSID elements are sent by the userspace, ieee80211_assign_beacon() ends up using the element stored from earlier Beacon template. Do not copy old MBSSID elements, instead userspace should always include these when applicable. Fixes: 2b3171c6fe0a ("mac80211: MBSSID beacon handling in AP mode") Signed-off-by: Aloka Dixit Link: https://patch.msgid.link/20251215174656.2866319-2-aloka.dixit@oss.qualcomm.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/cfg.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1addfba4b285..16270bea49a2 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1147,7 +1147,6 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, size = sizeof(*new) + new_head_len + new_tail_len; - /* new or old multiple BSSID elements? */ if (params->mbssid_ies) { mbssid = params->mbssid_ies; size += struct_size(new->mbssid_ies, elem, mbssid->cnt); @@ -1157,15 +1156,6 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, } size += ieee80211_get_mbssid_beacon_len(mbssid, rnr, mbssid->cnt); - } else if (old && old->mbssid_ies) { - mbssid = old->mbssid_ies; - size += struct_size(new->mbssid_ies, elem, mbssid->cnt); - if (old && old->rnr_ies) { - rnr = old->rnr_ies; - size += struct_size(new->rnr_ies, elem, rnr->cnt); - } - size += ieee80211_get_mbssid_beacon_len(mbssid, rnr, - mbssid->cnt); } new = kzalloc(size, GFP_KERNEL); -- Gitee From 7c4f95dcbc73f62df1efe59a849c47e751d92400 Mon Sep 17 00:00:00 2001 From: Przemyslaw Korba Date: Thu, 20 Nov 2025 20:07:28 +0800 Subject: [PATCH 0671/1449] i40e: fix scheduling in set_rx_mode ANBZ: #35228 commit f38cca04a23f14d8a7f0bc23aea537338ed87eea stable. commit be43abc5514167cc129a8d8e9727b89b8e1d9719 upstream. Add service task schedule to set_rx_mode. In some cases there are error messages printed out in PTP application (ptp4l): ptp4l[13848.762]: port 1 (ens2f3np3): received SYNC without timestamp ptp4l[13848.825]: port 1 (ens2f3np3): received SYNC without timestamp ptp4l[13848.887]: port 1 (ens2f3np3): received SYNC without timestamp This happens when service task would not run immediately after set_rx_mode, and we need it for setup tasks. This service task checks, if PTP RX packets are hung in firmware, and propagate correct settings such as multicast address for IEEE 1588 Precision Time Protocol. RX timestamping depends on some of these filters set. Bug happens only with high PTP packets frequency incoming, and not every run since sometimes service task is being ran from a different place immediately after starting ptp4l. Fixes: 0e4425ed641f ("i40e: fix: do not sleep in netdev_ops") Reviewed-by: Grzegorz Nitka Reviewed-by: Jacob Keller Reviewed-by: Aleksandr Loktionov Signed-off-by: Przemyslaw Korba Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f0c481b83175..7af913d40fc8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2260,6 +2260,7 @@ static void i40e_set_rx_mode(struct net_device *netdev) vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED; set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state); } + i40e_service_event_schedule(vsi->back); } /** -- Gitee From 041d9f480c2d2960705057c00e7cb9eb48953a7a Mon Sep 17 00:00:00 2001 From: Kohei Enju Date: Sun, 26 Oct 2025 00:58:50 +0800 Subject: [PATCH 0672/1449] iavf: fix off-by-one issues in iavf_config_rss_reg() ANBZ: #35228 commit 18de0e41d69d97fab10b91fecf10ae78a5e43232 stable. commit 6daa2893f323981c7894c68440823326e93a7d61 upstream. There are off-by-one bugs when configuring RSS hash key and lookup table, causing out-of-bounds reads to memory [1] and out-of-bounds writes to device registers. Before commit 43a3d9ba34c9 ("i40evf: Allow PF driver to configure RSS"), the loop upper bounds were: i <= I40E_VFQF_{HKEY,HLUT}_MAX_INDEX which is safe since the value is the last valid index. That commit changed the bounds to: i <= adapter->rss_{key,lut}_size / 4 where `rss_{key,lut}_size / 4` is the number of dwords, so the last valid index is `(rss_{key,lut}_size / 4) - 1`. Therefore, using `<=` accesses one element past the end. Fix the issues by using `<` instead of `<=`, ensuring we do not exceed the bounds. [1] KASAN splat about rss_key_size off-by-one BUG: KASAN: slab-out-of-bounds in iavf_config_rss+0x619/0x800 Read of size 4 at addr ffff888102c50134 by task kworker/u8:6/63 CPU: 0 UID: 0 PID: 63 Comm: kworker/u8:6 Not tainted 6.18.0-rc2-enjuk-tnguy-00378-g3005f5b77652-dirty #156 PREEMPT(voluntary) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Workqueue: iavf iavf_watchdog_task Call Trace: dump_stack_lvl+0x6f/0xb0 print_report+0x170/0x4f3 kasan_report+0xe1/0x1a0 iavf_config_rss+0x619/0x800 iavf_watchdog_task+0x2be7/0x3230 process_one_work+0x7fd/0x1420 worker_thread+0x4d1/0xd40 kthread+0x344/0x660 ret_from_fork+0x249/0x320 ret_from_fork_asm+0x1a/0x30 Allocated by task 63: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x7f/0x90 __kmalloc_noprof+0x246/0x6f0 iavf_watchdog_task+0x28fc/0x3230 process_one_work+0x7fd/0x1420 worker_thread+0x4d1/0xd40 kthread+0x344/0x660 ret_from_fork+0x249/0x320 ret_from_fork_asm+0x1a/0x30 The buggy address belongs to the object at ffff888102c50100 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 0 bytes to the right of allocated 52-byte region [ffff888102c50100, ffff888102c50134) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x102c50 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000418c0 dead000000000122 0000000000000000 raw: 0000000000000000 0000000080200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888102c50000: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc ffff888102c50080: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc >ffff888102c50100: 00 00 00 00 00 00 04 fc fc fc fc fc fc fc fc fc ^ ffff888102c50180: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc ffff888102c50200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc Fixes: 43a3d9ba34c9 ("i40evf: Allow PF driver to configure RSS") Signed-off-by: Kohei Enju Reviewed-by: Aleksandr Loktionov Reviewed-by: Przemek Kitszel Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/iavf/iavf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index fde8d7b80ca6..f6a748ae1c95 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1750,11 +1750,11 @@ static int iavf_config_rss_reg(struct iavf_adapter *adapter) u16 i; dw = (u32 *)adapter->rss_key; - for (i = 0; i <= adapter->rss_key_size / 4; i++) + for (i = 0; i < adapter->rss_key_size / 4; i++) wr32(hw, IAVF_VFQF_HKEY(i), dw[i]); dw = (u32 *)adapter->rss_lut; - for (i = 0; i <= adapter->rss_lut_size / 4; i++) + for (i = 0; i < adapter->rss_lut_size / 4; i++) wr32(hw, IAVF_VFQF_HLUT(i), dw[i]); iavf_flush(hw); -- Gitee From 9cb33513d336532b6acb1d629a56b8b994eac674 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 17 Dec 2025 14:15:41 +0800 Subject: [PATCH 0673/1449] crypto: seqiv - Do not use req->iv after crypto_aead_encrypt ANBZ: #35228 commit 0279978adec6f1296af66b642cce641c6580be46 stable. commit 50fdb78b7c0bcc550910ef69c0984e751cac72fa upstream. As soon as crypto_aead_encrypt is called, the underlying request may be freed by an asynchronous completion. Thus dereferencing req->iv after it returns is invalid. Instead of checking req->iv against info, create a new variable unaligned_info and use it for that purpose instead. Fixes: 0a270321dbf9 ("[CRYPTO] seqiv: Add Sequence Number IV Generator") Reported-by: Xiumei Mu Reported-by: Xin Long Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- crypto/seqiv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crypto/seqiv.c b/crypto/seqiv.c index 17e11d51ddc3..04928df0095b 100644 --- a/crypto/seqiv.c +++ b/crypto/seqiv.c @@ -50,6 +50,7 @@ static int seqiv_aead_encrypt(struct aead_request *req) struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv); struct aead_request *subreq = aead_request_ctx(req); crypto_completion_t compl; + bool unaligned_info; void *data; u8 *info; unsigned int ivsize = 8; @@ -79,8 +80,9 @@ static int seqiv_aead_encrypt(struct aead_request *req) return err; } - if (unlikely(!IS_ALIGNED((unsigned long)info, - crypto_aead_alignmask(geniv) + 1))) { + unaligned_info = !IS_ALIGNED((unsigned long)info, + crypto_aead_alignmask(geniv) + 1); + if (unlikely(unaligned_info)) { info = kmemdup(req->iv, ivsize, req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC); @@ -100,7 +102,7 @@ static int seqiv_aead_encrypt(struct aead_request *req) scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1); err = crypto_aead_encrypt(subreq); - if (unlikely(info != req->iv)) + if (unlikely(unaligned_info)) seqiv_aead_encrypt_complete2(req, err); return err; } -- Gitee From 7fbb2f85d36c8518f7751b45e9e3b3bbff2d0c57 Mon Sep 17 00:00:00 2001 From: Raphael Pinsonneault-Thibeault Date: Thu, 11 Dec 2025 00:02:28 +0800 Subject: [PATCH 0674/1449] Bluetooth: btusb: revert use of devm_kzalloc in btusb ANBZ: #35228 commit c0ecb3e4451fe94f4315e6d09c4046dfbc42090b stable. commit 252714f1e8bdd542025b16321c790458014d6880 upstream. This reverts commit 98921dbd00c4e ("Bluetooth: Use devm_kzalloc in btusb.c file"). In btusb_probe(), we use devm_kzalloc() to allocate the btusb data. This ties the lifetime of all the btusb data to the binding of a driver to one interface, INTF. In a driver that binds to other interfaces, ISOC and DIAG, this is an accident waiting to happen. The issue is revealed in btusb_disconnect(), where calling usb_driver_release_interface(&btusb_driver, data->intf) will have devm free the data that is also being used by the other interfaces of the driver that may not be released yet. To fix this, revert the use of devm and go back to freeing memory explicitly. Fixes: 98921dbd00c4e ("Bluetooth: Use devm_kzalloc in btusb.c file") Signed-off-by: Raphael Pinsonneault-Thibeault Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bluetooth/btusb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 96b1e64377c6..c36394f0dd79 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -4342,7 +4342,7 @@ static int btusb_probe(struct usb_interface *intf, return -ENODEV; } - data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -4365,8 +4365,10 @@ static int btusb_probe(struct usb_interface *intf, } } - if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) + if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) { + kfree(data); return -ENODEV; + } if (id->driver_info & BTUSB_AMP) { data->cmdreq_type = USB_TYPE_CLASS | 0x01; @@ -4421,8 +4423,10 @@ static int btusb_probe(struct usb_interface *intf, data->recv_acl = hci_recv_frame; hdev = hci_alloc_dev_priv(priv_size); - if (!hdev) + if (!hdev) { + kfree(data); return -ENOMEM; + } hdev->bus = HCI_USB; hci_set_drvdata(hdev, data); @@ -4690,6 +4694,7 @@ static int btusb_probe(struct usb_interface *intf, if (data->reset_gpio) gpiod_put(data->reset_gpio); hci_free_dev(hdev); + kfree(data); return err; } @@ -4738,6 +4743,7 @@ static void btusb_disconnect(struct usb_interface *intf) } hci_free_dev(hdev); + kfree(data); } #ifdef CONFIG_PM -- Gitee From 5e68f8b0be2118786ecc65bc85343621cecd658d Mon Sep 17 00:00:00 2001 From: Jacky Chou Date: Thu, 11 Dec 2025 14:24:58 +0800 Subject: [PATCH 0675/1449] net: mdio: aspeed: add dummy read to avoid read-after-write issue ANBZ: #35228 commit 248dadfee95aad6833c1813de764ea9a7dc54bb6 stable. commit d1a1a4bade4b20c0858d0b2f81d2611de055f675 upstream. The Aspeed MDIO controller may return incorrect data when a read operation follows immediately after a write. Due to a controller bug, the subsequent read can latch stale data, causing the polling logic to terminate earlier than expected. To work around this hardware issue, insert a dummy read after each write operation. This ensures that the next actual read returns the correct data and prevents premature polling exit. This workaround has been verified to stabilize MDIO transactions on affected Aspeed platforms. Fixes: f160e99462c6 ("net: phy: Add mdio-aspeed") Signed-off-by: Jacky Chou Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20251211-aspeed_mdio_add_dummy_read-v3-1-382868869004@aspeedtech.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/mdio/mdio-aspeed.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/mdio/mdio-aspeed.c b/drivers/net/mdio/mdio-aspeed.c index c727103c8b05..339198a4dbc0 100644 --- a/drivers/net/mdio/mdio-aspeed.c +++ b/drivers/net/mdio/mdio-aspeed.c @@ -63,6 +63,13 @@ static int aspeed_mdio_op(struct mii_bus *bus, u8 st, u8 op, u8 phyad, u8 regad, iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL); + /* Workaround for read-after-write issue. + * The controller may return stale data if a read follows immediately + * after a write. A dummy read forces the hardware to update its + * internal state, ensuring that the next real read returns correct data. + */ + ioread32(ctx->base + ASPEED_MDIO_CTRL); + return readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl, !(ctrl & ASPEED_MDIO_CTRL_FIRE), ASPEED_MDIO_INTERVAL_US, -- Gitee From cc2d8c072e17ad8340bb425370963b0d9dc1fa20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Thu, 11 Dec 2025 19:50:05 +0800 Subject: [PATCH 0676/1449] net: openvswitch: Avoid needlessly taking the RTNL on vport destroy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 0fc642f011cb7a7eff41109e66d3b552e9f4d795 stable. commit 5498227676303e3ffa9a3a46214af96bc3e81314 upstream. The openvswitch teardown code will immediately call ovs_netdev_detach_dev() in response to a NETDEV_UNREGISTER notification. It will then start the dp_notify_work workqueue, which will later end up calling the vport destroy() callback. This callback takes the RTNL to do another ovs_netdev_detach_port(), which in this case is unnecessary. This causes extra pressure on the RTNL, in some cases leading to "unregister_netdevice: waiting for XX to become free" warnings on teardown. We can straight-forwardly avoid the extra RTNL lock acquisition by checking the device flags before taking the lock, and skip the locking altogether if the IFF_OVS_DATAPATH flag has already been unset. Fixes: b07c26511e94 ("openvswitch: fix vport-netdev unregister") Tested-by: Adrian Moreno Signed-off-by: Toke Høiland-Jørgensen Acked-by: Eelco Chaudron Acked-by: Aaron Conole Link: https://patch.msgid.link/20251211115006.228876-1-toke@redhat.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/openvswitch/vport-netdev.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 903537a5da22..3c41d53bb9e9 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -153,10 +153,19 @@ void ovs_netdev_detach_dev(struct vport *vport) static void netdev_destroy(struct vport *vport) { - rtnl_lock(); - if (netif_is_ovs_port(vport->dev)) - ovs_netdev_detach_dev(vport); - rtnl_unlock(); + /* When called from ovs_db_notify_wq() after a dp_device_event(), the + * port has already been detached, so we can avoid taking the RTNL by + * checking this first. + */ + if (netif_is_ovs_port(vport->dev)) { + rtnl_lock(); + /* Check again while holding the lock to ensure we don't race + * with the netdev notifier and detach twice. + */ + if (netif_is_ovs_port(vport->dev)) + ovs_netdev_detach_dev(vport); + rtnl_unlock(); + } call_rcu(&vport->rcu, vport_netdev_free); } -- Gitee From 568f3868b80859db58293e6d76440cd742461b50 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 12 Dec 2025 01:35:50 +0800 Subject: [PATCH 0677/1449] ip6_gre: make ip6gre_header() robust ANBZ: #35228 commit 1717357007db150c2d703f13f5695460e960f26c stable. commit db5b4e39c4e63700c68a7e65fc4e1f1375273476 upstream. Over the years, syzbot found many ways to crash the kernel in ip6gre_header() [1]. This involves team or bonding drivers ability to dynamically change their dev->needed_headroom and/or dev->hard_header_len In this particular crash mld_newpack() allocated an skb with a too small reserve/headroom, and by the time mld_sendpack() was called, syzbot managed to attach an ip6gre device. [1] skbuff: skb_under_panic: text:ffffffff8a1d69a8 len:136 put:40 head:ffff888059bc7000 data:ffff888059bc6fe8 tail:0x70 end:0x6c0 dev:team0 ------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:213 ! skb_under_panic net/core/skbuff.c:223 [inline] skb_push+0xc3/0xe0 net/core/skbuff.c:2641 ip6gre_header+0xc8/0x790 net/ipv6/ip6_gre.c:1371 dev_hard_header include/linux/netdevice.h:3436 [inline] neigh_connected_output+0x286/0x460 net/core/neighbour.c:1618 neigh_output include/net/neighbour.h:556 [inline] ip6_finish_output2+0xfb3/0x1480 net/ipv6/ip6_output.c:136 __ip6_finish_output net/ipv6/ip6_output.c:-1 [inline] ip6_finish_output+0x234/0x7d0 net/ipv6/ip6_output.c:220 NF_HOOK_COND include/linux/netfilter.h:307 [inline] ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247 NF_HOOK+0x9e/0x380 include/linux/netfilter.h:318 mld_sendpack+0x8d4/0xe60 net/ipv6/mcast.c:1855 mld_send_cr net/ipv6/mcast.c:2154 [inline] mld_ifc_work+0x83e/0xd60 net/ipv6/mcast.c:2693 Fixes: c12b395a4664 ("gre: Support GRE over IPv6") Reported-by: syzbot+43a2ebcf2a64b1102d64@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/693b002c.a70a0220.33cd7b.0033.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20251211173550.2032674-1-edumazet@google.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/ip6_gre.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 289b83347d9d..63ac4a8e095b 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -1382,9 +1382,16 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev, { struct ip6_tnl *t = netdev_priv(dev); struct ipv6hdr *ipv6h; + int needed; __be16 *p; - ipv6h = skb_push(skb, t->hlen + sizeof(*ipv6h)); + needed = t->hlen + sizeof(*ipv6h); + if (skb_headroom(skb) < needed && + pskb_expand_head(skb, HH_DATA_ALIGN(needed - skb_headroom(skb)), + 0, GFP_ATOMIC)) + return -needed; + + ipv6h = skb_push(skb, needed); ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb, t->fl.u.ip6.flowlabel, true, &t->fl.u.ip6)); -- Gitee From 0105b4a9ef057c2de55e2b4721cc89311a03c6e5 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 17 Dec 2025 18:36:13 +0800 Subject: [PATCH 0678/1449] platform/x86: msi-laptop: add missing sysfs_remove_group() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit ec24f3b4a8315ce1516652f611283e41348b4ae4 stable. commit 1461209cf813b6ee6d40f29b96b544587df6d2b1 upstream. A sysfs group is created in msi_init() when old_ec_model is enabled, but never removed. Remove the msipf_old_attribute_group in that case. Fixes: 03696e51d75a ("msi-laptop: Disable brightness control for new EC") Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20251217103617.27668-2-fourier.thomas@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/msi-laptop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index f4c6c36e05a5..2a8839135492 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -1130,6 +1130,9 @@ static void __exit msi_cleanup(void) sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); if (!quirks->old_ec_model && threeg_exists) device_remove_file(&msipf_device->dev, &dev_attr_threeg); + if (quirks->old_ec_model) + sysfs_remove_group(&msipf_device->dev.kobj, + &msipf_old_attribute_group); platform_device_unregister(msipf_device); platform_driver_unregister(&msipf_driver); backlight_device_unregister(msibl_device); -- Gitee From 1315ce8d429429ddd5be836ffeaa5cd49c7e487c Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Fri, 19 Dec 2025 16:30:29 +0800 Subject: [PATCH 0679/1449] platform/x86: ibm_rtl: fix EBDA signature search pointer arithmetic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 859bf9688bfbcea6b08be06953c5e8740ae551d2 stable. commit 15dd100349b8526cbdf2de0ce3e72e700eb6c208 upstream. The ibm_rtl_init() function searches for the signature but has a pointer arithmetic error. The loop counter suggests searching at 4-byte intervals but the implementation only advances by 1 byte per iteration. Fix by properly advancing the pointer by sizeof(unsigned int) bytes each iteration. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 35f0ce032b0f ("IBM Real-Time "SMI Free" mode driver -v7") Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB78812D887A92DE3802D0D06EAFA9A@SYBPR01MB7881.ausprd01.prod.outlook.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/ibm_rtl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index 2ab7d9ac542d..5fb25a602533 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c @@ -272,7 +272,7 @@ static int __init ibm_rtl_init(void) { /* search for the _RTL_ signature at the start of the table */ for (i = 0 ; i < ebda_size/sizeof(unsigned int); i++) { struct ibm_rtl_table __iomem * tmp; - tmp = (struct ibm_rtl_table __iomem *) (ebda_map+i); + tmp = (struct ibm_rtl_table __iomem *) (ebda_map + i*sizeof(unsigned int)); if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) { phys_addr_t addr; unsigned int plen; -- Gitee From 4531e72b5688775c26fbf3da667d7d87da06d0cd Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 12 Dec 2025 18:29:53 +0800 Subject: [PATCH 0680/1449] team: fix check for port enabled in team_queue_override_port_prio_changed() ANBZ: #35228 commit 6bfb62b6010a16112dcae52f490e5e0e6abe12a3 stable. commit 932ac51d9953eaf77a1252f79b656d4ca86163c6 upstream. There has been a syzkaller bug reported recently with the following trace: list_del corruption, ffff888058bea080->prev is LIST_POISON2 (dead000000000122) ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:59! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 3 UID: 0 PID: 21246 Comm: syz.0.2928 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:__list_del_entry_valid_or_report+0x13e/0x200 lib/list_debug.c:59 Code: 48 c7 c7 e0 71 f0 8b e8 30 08 ef fc 90 0f 0b 48 89 ef e8 a5 02 55 fd 48 89 ea 48 89 de 48 c7 c7 40 72 f0 8b e8 13 08 ef fc 90 <0f> 0b 48 89 ef e8 88 02 55 fd 48 89 ea 48 b8 00 00 00 00 00 fc ff RSP: 0018:ffffc9000d49f370 EFLAGS: 00010286 RAX: 000000000000004e RBX: ffff888058bea080 RCX: ffffc9002817d000 RDX: 0000000000000000 RSI: ffffffff819becc6 RDI: 0000000000000005 RBP: dead000000000122 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000080000000 R11: 0000000000000001 R12: ffff888039e9c230 R13: ffff888058bea088 R14: ffff888058bea080 R15: ffff888055461480 FS: 00007fbbcfe6f6c0(0000) GS:ffff8880d6d0a000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000110c3afcb0 CR3: 00000000382c7000 CR4: 0000000000352ef0 Call Trace: __list_del_entry_valid include/linux/list.h:132 [inline] __list_del_entry include/linux/list.h:223 [inline] list_del_rcu include/linux/rculist.h:178 [inline] __team_queue_override_port_del drivers/net/team/team_core.c:826 [inline] __team_queue_override_port_del drivers/net/team/team_core.c:821 [inline] team_queue_override_port_prio_changed drivers/net/team/team_core.c:883 [inline] team_priority_option_set+0x171/0x2f0 drivers/net/team/team_core.c:1534 team_option_set drivers/net/team/team_core.c:376 [inline] team_nl_options_set_doit+0x8ae/0xe60 drivers/net/team/team_core.c:2653 genl_family_rcv_msg_doit+0x209/0x2f0 net/netlink/genetlink.c:1115 genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] genl_rcv_msg+0x55c/0x800 net/netlink/genetlink.c:1210 netlink_rcv_skb+0x158/0x420 net/netlink/af_netlink.c:2552 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219 netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline] netlink_unicast+0x5aa/0x870 net/netlink/af_netlink.c:1346 netlink_sendmsg+0x8c8/0xdd0 net/netlink/af_netlink.c:1896 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg net/socket.c:742 [inline] ____sys_sendmsg+0xa98/0xc70 net/socket.c:2630 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2684 __sys_sendmsg+0x16d/0x220 net/socket.c:2716 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f The problem is in this flow: 1) Port is enabled, queue_id != 0, in qom_list 2) Port gets disabled -> team_port_disable() -> team_queue_override_port_del() -> del (removed from list) 3) Port is disabled, queue_id != 0, not in any list 4) Priority changes -> team_queue_override_port_prio_changed() -> checks: port disabled && queue_id != 0 -> calls del - hits the BUG as it is removed already To fix this, change the check in team_queue_override_port_prio_changed() so it returns early if port is not enabled. Reported-by: syzbot+422806e5f4cce722a71f@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=422806e5f4cce722a71f Fixes: 6c31ff366c11 ("team: remove synchronize_rcu() called during queue override change") Signed-off-by: Jiri Pirko Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251212102953.167287-1-jiri@resnulli.us Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/team/team.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 1ce3bccd4ebd..9baa13808933 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -876,7 +876,7 @@ static void __team_queue_override_enabled_check(struct team *team) static void team_queue_override_port_prio_changed(struct team *team, struct team_port *port) { - if (!port->queue_id || team_port_enabled(port)) + if (!port->queue_id || !team_port_enabled(port)) return; __team_queue_override_port_del(team, port); __team_queue_override_port_add(team, port); -- Gitee From 4d30ee5c178f8a1a362445e2002e2c4253017fdc Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Mon, 15 Dec 2025 23:17:28 +0800 Subject: [PATCH 0681/1449] amd-xgbe: reset retries and mode on RX adapt failures ANBZ: #35228 commit e5ee9d93229b2e0280338b103c2639539f7e3e24 stable. commit df60c332caf95d70f967aeace826e7e2f0847361 upstream. During the stress tests, early RX adaptation handshakes can fail, such as missing the RX_ADAPT ACK or not receiving a coefficient update before block lock is established. Continuing to retry RX adaptation in this state is often ineffective if the current mode selection is not viable. Resetting the RX adaptation retry counter when an RX_ADAPT request fails to receive ACK or a coefficient update prior to block lock, and clearing mode_set so the next bring-up performs a fresh mode selection rather than looping on a likely invalid configuration. Fixes: 4f3b20bfbb75 ("amd-xgbe: add support for rx-adaptation") Signed-off-by: Raju Rangoju Reviewed-by: Simon Horman Reviewed-by: Shyam Sundar S K Link: https://patch.msgid.link/20251215151728.311713-1-Raju.Rangoju@amd.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index 32e633d11348..6d2c401bb246 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -2036,6 +2036,7 @@ static void xgbe_set_rx_adap_mode(struct xgbe_prv_data *pdata, { if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) { pdata->rx_adapt_retries = 0; + pdata->mode_set = false; return; } @@ -2082,6 +2083,7 @@ static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata) */ netif_dbg(pdata, link, pdata->netdev, "Block_lock done"); pdata->rx_adapt_done = true; + pdata->rx_adapt_retries = 0; pdata->mode_set = false; return; } -- Gitee From 137b58053ac3eb480fa01be4d0487dd2b0781a44 Mon Sep 17 00:00:00 2001 From: Deepakkumar Karn Date: Tue, 16 Dec 2025 23:13:05 +0800 Subject: [PATCH 0682/1449] net: usb: rtl8150: fix memory leak on usb_submit_urb() failure ANBZ: #35228 commit 4bd4ea3eb326608ffc296db12c105f92dc2f2190 stable. commit 12cab1191d9890097171156d06bfa8d31f1e39c8 upstream. In async_set_registers(), when usb_submit_urb() fails, the allocated async_req structure and URB are not freed, causing a memory leak. The completion callback async_set_reg_cb() is responsible for freeing these allocations, but it is only called after the URB is successfully submitted and completes (successfully or with error). If submission fails, the callback never runs and the memory is leaked. Fix this by freeing both the URB and the request structure in the error path when usb_submit_urb() fails. Reported-by: syzbot+8dd915c7cb0490fc8c52@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8dd915c7cb0490fc8c52 Fixes: 4d12997a9bb3 ("drivers: net: usb: rtl8150: concurrent URB bugfix") Signed-off-by: Deepakkumar Karn Link: https://patch.msgid.link/20251216151304.59865-2-dkarn@redhat.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/rtl8150.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 278e6cb6f4d9..e40b0669d9f4 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -211,6 +211,8 @@ static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg) if (res == -ENODEV) netif_device_detach(dev->netdev); dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res); + kfree(req); + usb_free_urb(async_urb); } return res; } -- Gitee From 13a484f2cb3e93df7c78661f0089ea435c4d8f2b Mon Sep 17 00:00:00 2001 From: "Alice C. Munduruca" Date: Wed, 17 Dec 2025 01:06:41 +0800 Subject: [PATCH 0683/1449] selftests: net: fix "buffer overflow detected" for tap.c ANBZ: #35228 commit 2ac08f3dcd0c10b347071b5b071b3e86b4c77609 stable. commit 472c5dd6b95c02b3e5d7395acf542150e91165e7 upstream. When the selftest 'tap.c' is compiled with '-D_FORTIFY_SOURCE=3', the strcpy() in rtattr_add_strsz() is replaced with a checked version which causes the test to consistently fail when compiled with toolchains for which this option is enabled by default. TAP version 13 1..3 # Starting 3 tests from 1 test cases. # RUN tap.test_packet_valid_udp_gso ... *** buffer overflow detected ***: terminated # test_packet_valid_udp_gso: Test terminated by assertion # FAIL tap.test_packet_valid_udp_gso not ok 1 tap.test_packet_valid_udp_gso # RUN tap.test_packet_valid_udp_csum ... *** buffer overflow detected ***: terminated # test_packet_valid_udp_csum: Test terminated by assertion # FAIL tap.test_packet_valid_udp_csum not ok 2 tap.test_packet_valid_udp_csum # RUN tap.test_packet_crash_tap_invalid_eth_proto ... *** buffer overflow detected ***: terminated # test_packet_crash_tap_invalid_eth_proto: Test terminated by assertion # FAIL tap.test_packet_crash_tap_invalid_eth_proto not ok 3 tap.test_packet_crash_tap_invalid_eth_proto # FAILED: 0 / 3 tests passed. # Totals: pass:0 fail:3 xfail:0 xpass:0 skip:0 error:0 A buffer overflow is detected by the fortified glibc __strcpy_chk() since the __builtin_object_size() of `RTA_DATA(rta)` is incorrectly reported as 1, even though there is ample space in its bounding buffer `req`. Additionally, given that IFLA_IFNAME also expects a null-terminated string, callers of rtaddr_add_str{,sz}() could simply use the rtaddr_add_strsz() variant. (which has been renamed to remove the trailing `sz`) memset() has been used for this function since it is unchecked and thus circumvents the issue discussed in the previous paragraph. Fixes: 2e64fe4624d1 ("selftests: add few test cases for tap driver") Signed-off-by: Alice C. Munduruca Reviewed-by: Cengiz Can Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20251216170641.250494-1-alice.munduruca@canonical.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/tap.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/net/tap.c b/tools/testing/selftests/net/tap.c index 247c3b3ac1c9..51a209014f1c 100644 --- a/tools/testing/selftests/net/tap.c +++ b/tools/testing/selftests/net/tap.c @@ -56,18 +56,12 @@ static void rtattr_end(struct nlmsghdr *nh, struct rtattr *attr) static struct rtattr *rtattr_add_str(struct nlmsghdr *nh, unsigned short type, const char *s) { - struct rtattr *rta = rtattr_add(nh, type, strlen(s)); + unsigned int strsz = strlen(s) + 1; + struct rtattr *rta; - memcpy(RTA_DATA(rta), s, strlen(s)); - return rta; -} - -static struct rtattr *rtattr_add_strsz(struct nlmsghdr *nh, unsigned short type, - const char *s) -{ - struct rtattr *rta = rtattr_add(nh, type, strlen(s) + 1); + rta = rtattr_add(nh, type, strsz); - strcpy(RTA_DATA(rta), s); + memcpy(RTA_DATA(rta), s, strsz); return rta; } @@ -119,7 +113,7 @@ static int dev_create(const char *dev, const char *link_type, link_info = rtattr_begin(&req.nh, IFLA_LINKINFO); - rtattr_add_strsz(&req.nh, IFLA_INFO_KIND, link_type); + rtattr_add_str(&req.nh, IFLA_INFO_KIND, link_type); if (fill_info_data) { info_data = rtattr_begin(&req.nh, IFLA_INFO_DATA); -- Gitee From 2d3eaef64f97f3454c5a54d9db6d4423ffd798a1 Mon Sep 17 00:00:00 2001 From: Yeoreum Yun Date: Wed, 17 Dec 2025 16:51:15 +0800 Subject: [PATCH 0684/1449] smc91x: fix broken irq-context in PREEMPT_RT ANBZ: #35228 commit ef277ae121b3249c99994652210a326b52d527b0 stable. commit 6402078bd9d1ed46e79465e1faaa42e3458f8a33 upstream. When smc91x.c is built with PREEMPT_RT, the following splat occurs in FVP_RevC: [ 13.055000] smc91x LNRO0003:00 eth0: link up, 10Mbps, half-duplex, lpa 0x0000 [ 13.062137] BUG: workqueue leaked atomic, lock or RCU: kworker/2:1[106] [ 13.062137] preempt=0x00000000 lock=0->0 RCU=0->1 workfn=mld_ifc_work [ 13.062266] C ** replaying previous printk message ** [ 13.062266] CPU: 2 UID: 0 PID: 106 Comm: kworker/2:1 Not tainted 6.18.0-dirty #179 PREEMPT_{RT,(full)} [ 13.062353] Hardware name: , BIOS [ 13.062382] Workqueue: mld mld_ifc_work [ 13.062469] Call trace: [ 13.062494] show_stack+0x24/0x40 (C) [ 13.062602] __dump_stack+0x28/0x48 [ 13.062710] dump_stack_lvl+0x7c/0xb0 [ 13.062818] dump_stack+0x18/0x34 [ 13.062926] process_scheduled_works+0x294/0x450 [ 13.063043] worker_thread+0x260/0x3d8 [ 13.063124] kthread+0x1c4/0x228 [ 13.063235] ret_from_fork+0x10/0x20 This happens because smc_special_trylock() disables IRQs even on PREEMPT_RT, but smc_special_unlock() does not restore IRQs on PREEMPT_RT. The reason is that smc_special_unlock() calls spin_unlock_irqrestore(), and rcu_read_unlock_bh() in __dev_queue_xmit() cannot invoke rcu_read_unlock() through __local_bh_enable_ip() when current->softirq_disable_cnt becomes zero. To address this issue, replace smc_special_trylock() with spin_trylock_irqsave(). Fixes: 342a93247e08 ("locking/spinlock: Provide RT variant header: ") Signed-off-by: Yeoreum Yun Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251217085115.1730036-1-yeoreum.yun@arm.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/smsc/smc91x.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 032eccf8eb42..7c2fdd02f1d3 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -515,15 +515,7 @@ static inline void smc_rcv(struct net_device *dev) * any other concurrent access and C would always interrupt B. But life * isn't that easy in a SMP world... */ -#define smc_special_trylock(lock, flags) \ -({ \ - int __ret; \ - local_irq_save(flags); \ - __ret = spin_trylock(lock); \ - if (!__ret) \ - local_irq_restore(flags); \ - __ret; \ -}) +#define smc_special_trylock(lock, flags) spin_trylock_irqsave(lock, flags) #define smc_special_lock(lock, flags) spin_lock_irqsave(lock, flags) #define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) #else -- Gitee From 75eaa671100cb383db5f5e39dbc037f5bf1bdb00 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 28 Nov 2025 02:39:24 +0800 Subject: [PATCH 0685/1449] genalloc.h: fix htmldocs warning ANBZ: #35228 commit 535ce34a5bdba1c7353f1c5d0a1ae707e68df763 stable. commit 5393802c94e0ab1295c04c94c57bcb00222d4674 upstream. WARNING: include/linux/genalloc.h:52 function parameter 'start_addr' not described in 'genpool_algo_t' Fixes: 52fbf1134d47 ("lib/genalloc.c: fix allocation of aligned buffer from non-aligned chunk") Reported-by: Stephen Rothwell Closes: https://lkml.kernel.org/r/20251127130624.563597e3@canb.auug.org.au Acked-by: Randy Dunlap Tested-by: Randy Dunlap Cc: Alexey Skidanov Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/genalloc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 0bd581003cd5..60de63e46b33 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -44,6 +44,7 @@ struct gen_pool; * @nr: The number of zeroed bits we're looking for * @data: optional additional data used by the callback * @pool: the pool being allocated from + * @start_addr: start address of memory chunk */ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size, -- Gitee From 51c3810d83b9451e74c0349833607320a1b2ba26 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 17 Dec 2025 00:54:18 +0800 Subject: [PATCH 0686/1449] firewire: nosy: Fix dma_free_coherent() size ANBZ: #35228 commit 328dc0b12fb8be5c2f6bee356df5ede74a29e444 stable. commit c48c0fd0e19684b6ecdb4108a429e3a4e73f5e21 upstream. It looks like the buffer allocated and mapped in add_card() is done with size RCV_BUFFER_SIZE which is 16 KB and 4KB. Fixes: 286468210d83 ("firewire: new driver: nosy - IEEE 1394 traffic sniffer") Co-developed-by: Thomas Fourier Signed-off-by: Thomas Fourier Co-developed-by: Christophe JAILLET Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/20251216165420.38355-2-fourier.thomas@gmail.com Signed-off-by: Takashi Sakamoto Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firewire/nosy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index ea31ac7ac1ca..e59053738a43 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -36,6 +36,8 @@ static char driver_name[] = KBUILD_MODNAME; +#define RCV_BUFFER_SIZE (16 * 1024) + /* this is the physical layout of a PCL, its size is 128 bytes */ struct pcl { __le32 next; @@ -517,16 +519,14 @@ remove_card(struct pci_dev *dev) lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus); dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), lynx->rcv_pcl, lynx->rcv_pcl_bus); - dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, lynx->rcv_buffer, - lynx->rcv_buffer_bus); + dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE, + lynx->rcv_buffer, lynx->rcv_buffer_bus); iounmap(lynx->registers); pci_disable_device(dev); lynx_put(lynx); } -#define RCV_BUFFER_SIZE (16 * 1024) - static int add_card(struct pci_dev *dev, const struct pci_device_id *unused) { @@ -680,7 +680,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), lynx->rcv_pcl, lynx->rcv_pcl_bus); if (lynx->rcv_buffer) - dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, + dma_free_coherent(&lynx->pci_device->dev, RCV_BUFFER_SIZE, lynx->rcv_buffer, lynx->rcv_buffer_bus); iounmap(lynx->registers); -- Gitee From 0f3091516ccd4b4df5fb6ddbe7a0f73c431fb30c Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 18 Dec 2025 04:57:56 +0800 Subject: [PATCH 0687/1449] net: dsa: b53: skip multicast entries for fdb_dump() ANBZ: #35228 commit 0e85ce7a3755f8a5489c85b3a6af661053d00b5a stable. commit d42bce414d1c5c0b536758466a1f63ac358e613c upstream. port_fdb_dump() is supposed to only add fdb entries, but we iterate over the full ARL table, which also includes multicast entries. So check if the entry is a multicast entry before passing it on to the callback(). Additionally, the port of those entries is a bitmask, not a port number, so any included entries would have even be for the wrong port. Fixes: 1da6df85c6fb ("net: dsa: b53: Implement ARL add/del/dump operations") Signed-off-by: Jonas Gorski Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20251217205756.172123-1-jonas.gorski@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/b53/b53_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index ffe8db7c2f1f..ee20f6487a02 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1846,6 +1846,9 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, if (!ent->is_valid) return 0; + if (is_multicast_ether_addr(ent->mac)) + return 0; + if (port != ent->port) return 0; -- Gitee From 0f716b3bbc9ea0d6cc77e12e269f195ad54746cb Mon Sep 17 00:00:00 2001 From: Deepanshu Kartikey Date: Thu, 18 Dec 2025 09:11:56 +0800 Subject: [PATCH 0688/1449] net: usb: asix: validate PHY address before use ANBZ: #35228 commit 38722e69ee64dbb020028c93898d25d6f4c0e0b2 stable. commit a1e077a3f76eea0dc671ed6792e7d543946227e8 upstream. The ASIX driver reads the PHY address from the USB device via asix_read_phy_addr(). A malicious or faulty device can return an invalid address (>= PHY_MAX_ADDR), which causes a warning in mdiobus_get_phy(): addr 207 out of range WARNING: drivers/net/phy/mdio_bus.c:76 Validate the PHY address in asix_read_phy_addr() and remove the now-redundant check in ax88172a.c. Reported-by: syzbot+3d43c9066a5b54902232@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3d43c9066a5b54902232 Tested-by: syzbot+3d43c9066a5b54902232@syzkaller.appspotmail.com Fixes: 7e88b11a862a ("net: usb: asix: refactor asix_read_phy_addr() and handle errors on return") Link: https://lore.kernel.org/all/20251217085057.270704-1-kartikey406@gmail.com/T/ [v1] Signed-off-by: Deepanshu Kartikey Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20251218011156.276824-1-kartikey406@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/asix_common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c index 7fd763917ae2..6ab3486072cb 100644 --- a/drivers/net/usb/asix_common.c +++ b/drivers/net/usb/asix_common.c @@ -335,6 +335,11 @@ int asix_read_phy_addr(struct usbnet *dev, bool internal) offset = (internal ? 1 : 0); ret = buf[offset]; + if (ret >= PHY_MAX_ADDR) { + netdev_err(dev->net, "invalid PHY address: %d\n", ret); + return -ENODEV; + } + netdev_dbg(dev->net, "%s PHY address 0x%x\n", internal ? "internal" : "external", ret); -- Gitee From 57dc9d676d537e0f03761014e13346cd85161c76 Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Thu, 18 Dec 2025 12:29:37 +0800 Subject: [PATCH 0689/1449] net: bridge: Describe @tunnel_hash member in net_bridge_vlan_group struct ANBZ: #35228 commit 25be7178446cc5a0c33fd17ea1605792b2876642 stable. commit f79f9b7ace1713e4b83888c385f5f55519dfb687 upstream. Sphinx reports kernel-doc warning: WARNING: ./net/bridge/br_private.h:267 struct member 'tunnel_hash' not described in 'net_bridge_vlan_group' Fix it by describing @tunnel_hash member. Fixes: efa5356b0d9753 ("bridge: per vlan dst_metadata netlink support") Signed-off-by: Bagas Sanjaya Acked-by: Nikolay Aleksandrov Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20251218042936.24175-2-bagasdotme@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bridge/br_private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index c8a4e3b39b0e..371a948d29cc 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -245,6 +245,7 @@ struct net_bridge_vlan { * struct net_bridge_vlan_group * * @vlan_hash: VLAN entry rhashtable + * @tunnel_hash: Hash table to map from tunnel key ID (e.g. VXLAN VNI) to VLAN * @vlan_list: sorted VLAN entry list * @num_vlans: number of total VLAN entries * @pvid: PVID VLAN id -- Gitee From 1fd4cc04cf515bfffddfbc55a29bb1f35f72775c Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Fri, 26 Dec 2025 19:42:05 +0800 Subject: [PATCH 0690/1449] platform/x86: hp-bioscfg: Fix out-of-bounds array access in ACPI package parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit cf7ae870560b988247a4bbbe5399edd326632680 stable. commit e44c42c830b7ab36e3a3a86321c619f24def5206 upstream. The hp_populate_*_elements_from_package() functions in the hp-bioscfg driver contain out-of-bounds array access vulnerabilities. These functions parse ACPI packages into internal data structures using a for loop with index variable 'elem' that iterates through enum_obj/integer_obj/order_obj/password_obj/string_obj arrays. When processing multi-element fields like PREREQUISITES and ENUM_POSSIBLE_VALUES, these functions read multiple consecutive array elements using expressions like 'enum_obj[elem + reqs]' and 'enum_obj[elem + pos_values]' within nested loops. The bug is that the bounds check only validated elem, but did not consider the additional offset when accessing elem + reqs or elem + pos_values. The fix changes the bounds check to validate the actual accessed index. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: e6c7b3e15559 ("platform/x86: hp-bioscfg: string-attributes") Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB788173D7DD4EA2CB6383683DAFB0A@SYBPR01MB7881.ausprd01.prod.outlook.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c | 4 ++-- drivers/platform/x86/hp/hp-bioscfg/int-attributes.c | 2 +- drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c | 5 +++++ drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c | 5 +++++ drivers/platform/x86/hp/hp-bioscfg/string-attributes.c | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c index a2402d31c146..20de4596e301 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c @@ -210,7 +210,7 @@ static int hp_populate_enumeration_elements_from_package(union acpi_object *enum case PREREQUISITES: size = min_t(u32, enum_data->common.prerequisites_size, MAX_PREREQUISITES_SIZE); for (reqs = 0; reqs < size; reqs++) { - if (elem >= enum_obj_count) { + if (elem + reqs >= enum_obj_count) { pr_err("Error enum-objects package is too small\n"); return -EINVAL; } @@ -261,7 +261,7 @@ static int hp_populate_enumeration_elements_from_package(union acpi_object *enum for (pos_values = 0; pos_values < size && pos_values < MAX_VALUES_SIZE; pos_values++) { - if (elem >= enum_obj_count) { + if (elem + pos_values >= enum_obj_count) { pr_err("Error enum-objects package is too small\n"); return -EINVAL; } diff --git a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c index 86b7ac63fec2..875a807ccb89 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c @@ -228,7 +228,7 @@ static int hp_populate_integer_elements_from_package(union acpi_object *integer_ size = min_t(u32, integer_data->common.prerequisites_size, MAX_PREREQUISITES_SIZE); for (reqs = 0; reqs < size; reqs++) { - if (elem >= integer_obj_count) { + if (elem + reqs >= integer_obj_count) { pr_err("Error elem-objects package is too small\n"); return -EINVAL; } diff --git a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c index 1ff09dfb7d7e..94a95ee57810 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c @@ -220,6 +220,11 @@ static int hp_populate_ordered_list_elements_from_package(union acpi_object *ord size = min_t(u32, ordered_list_data->common.prerequisites_size, MAX_PREREQUISITES_SIZE); for (reqs = 0; reqs < size; reqs++) { + if (elem + reqs >= order_obj_count) { + pr_err("Error elem-objects package is too small\n"); + return -EINVAL; + } + ret = hp_convert_hexstr_to_str(order_obj[elem + reqs].string.pointer, order_obj[elem + reqs].string.length, &str_value, &value_len); diff --git a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c index 03d0188804ba..6775a7ca74f5 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c @@ -309,6 +309,11 @@ static int hp_populate_password_elements_from_package(union acpi_object *passwor MAX_PREREQUISITES_SIZE); for (reqs = 0; reqs < size; reqs++) { + if (elem + reqs >= password_obj_count) { + pr_err("Error elem-objects package is too small\n"); + return -EINVAL; + } + ret = hp_convert_hexstr_to_str(password_obj[elem + reqs].string.pointer, password_obj[elem + reqs].string.length, &str_value, &value_len); diff --git a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c index f0c20070094d..5b3eac7f1685 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c @@ -219,7 +219,7 @@ static int hp_populate_string_elements_from_package(union acpi_object *string_ob MAX_PREREQUISITES_SIZE); for (reqs = 0; reqs < size; reqs++) { - if (elem >= string_obj_count) { + if (elem + reqs >= string_obj_count) { pr_err("Error elem-objects package is too small\n"); return -EINVAL; } -- Gitee From ad0e8bc0c49158381ca4e6ca4ab093aa5f9978bb Mon Sep 17 00:00:00 2001 From: Anshumali Gaur Date: Fri, 19 Dec 2025 14:22:26 +0800 Subject: [PATCH 0691/1449] octeontx2-pf: fix "UBSAN: shift-out-of-bounds error" ANBZ: #35228 commit b23a2e15589466a027c9baa3fb5813c9f6a6c6dc stable. commit 85f4b0c650d9f9db10bda8d3acfa1af83bf78cf7 upstream. This patch ensures that the RX ring size (rx_pending) is not set below the permitted length. This avoids UBSAN shift-out-of-bounds errors when users passes small or zero ring sizes via ethtool -G. Fixes: d45d8979840d ("octeontx2-pf: Add basic ethtool support") Signed-off-by: Anshumali Gaur Link: https://patch.msgid.link/20251219062226.524844-1-agaur@marvell.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c index 532e84bc38c7..bd01c538f208 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c @@ -432,6 +432,14 @@ static int otx2_set_ringparam(struct net_device *netdev, */ if (rx_count < pfvf->hw.rq_skid) rx_count = pfvf->hw.rq_skid; + + if (ring->rx_pending < 16) { + netdev_err(netdev, + "rx ring size %u invalid, min is 16\n", + ring->rx_pending); + return -EINVAL; + } + rx_count = Q_COUNT(Q_SIZE(rx_count, 3)); /* Due pipelining impact minimum 2000 unused SQ CQE's -- Gitee From 4810b98cf029e666cbe262409019b6a24d874f73 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Thu, 4 Dec 2025 15:13:32 +0800 Subject: [PATCH 0692/1449] net: stmmac: fix the crash issue for zero copy XDP_TX action ANBZ: #35228 commit 4d0ceb7677e1c4616afb96abb4518f70b65abb0d stable. commit a48e232210009be50591fdea8ba7c07b0f566a13 upstream. There is a crash issue when running zero copy XDP_TX action, the crash log is shown below. [ 216.122464] Unable to handle kernel paging request at virtual address fffeffff80000000 [ 216.187524] Internal error: Oops: 0000000096000144 [#1] SMP [ 216.301694] Call trace: [ 216.304130] dcache_clean_poc+0x20/0x38 (P) [ 216.308308] __dma_sync_single_for_device+0x1bc/0x1e0 [ 216.313351] stmmac_xdp_xmit_xdpf+0x354/0x400 [ 216.317701] __stmmac_xdp_run_prog+0x164/0x368 [ 216.322139] stmmac_napi_poll_rxtx+0xba8/0xf00 [ 216.326576] __napi_poll+0x40/0x218 [ 216.408054] Kernel panic - not syncing: Oops: Fatal exception in interrupt For XDP_TX action, the xdp_buff is converted to xdp_frame by xdp_convert_buff_to_frame(). The memory type of the resulting xdp_frame depends on the memory type of the xdp_buff. For page pool based xdp_buff it produces xdp_frame with memory type MEM_TYPE_PAGE_POOL. For zero copy XSK pool based xdp_buff it produces xdp_frame with memory type MEM_TYPE_PAGE_ORDER0. However, stmmac_xdp_xmit_back() does not check the memory type and always uses the page pool type, this leads to invalid mappings and causes the crash. Therefore, check the xdp_buff memory type in stmmac_xdp_xmit_back() to fix this issue. Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") Signed-off-by: Wei Fang Reviewed-by: Hariprasad Kelam Link: https://patch.msgid.link/20251204071332.1907111-1-wei.fang@nxp.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index abb38af68ed6..8592df15d06b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -87,6 +87,7 @@ MODULE_PARM_DESC(phyaddr, "Physical device address"); #define STMMAC_XDP_CONSUMED BIT(0) #define STMMAC_XDP_TX BIT(1) #define STMMAC_XDP_REDIRECT BIT(2) +#define STMMAC_XSK_CONSUMED BIT(3) static int flow_ctrl = FLOW_AUTO; module_param(flow_ctrl, int, 0644); @@ -4892,6 +4893,7 @@ static int stmmac_xdp_get_tx_queue(struct stmmac_priv *priv, static int stmmac_xdp_xmit_back(struct stmmac_priv *priv, struct xdp_buff *xdp) { + bool zc = !!(xdp->rxq->mem.type == MEM_TYPE_XSK_BUFF_POOL); struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp); int cpu = smp_processor_id(); struct netdev_queue *nq; @@ -4908,9 +4910,18 @@ static int stmmac_xdp_xmit_back(struct stmmac_priv *priv, /* Avoids TX time-out as we are sharing with slow path */ txq_trans_cond_update(nq); - res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, false); - if (res == STMMAC_XDP_TX) + /* For zero copy XDP_TX action, dma_map is true */ + res = stmmac_xdp_xmit_xdpf(priv, queue, xdpf, zc); + if (res == STMMAC_XDP_TX) { stmmac_flush_tx_descriptors(priv, queue); + } else if (res == STMMAC_XDP_CONSUMED && zc) { + /* xdp has been freed by xdp_convert_buff_to_frame(), + * no need to call xsk_buff_free() again, so return + * STMMAC_XSK_CONSUMED. + */ + res = STMMAC_XSK_CONSUMED; + xdp_return_frame(xdpf); + } __netif_tx_unlock(nq); @@ -5256,6 +5267,8 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) break; case STMMAC_XDP_CONSUMED: xsk_buff_free(buf->xdp); + fallthrough; + case STMMAC_XSK_CONSUMED: rx_dropped++; break; case STMMAC_XDP_TX: -- Gitee From a1c4c1b47b55a746a9928ebc82c18c9e39018609 Mon Sep 17 00:00:00 2001 From: Will Rosenberg Date: Sat, 20 Dec 2025 01:36:37 +0800 Subject: [PATCH 0693/1449] ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr() ANBZ: #35228 commit c53aa6a5086f03f19564096ee084a202a8c738c0 stable. commit 58fc7342b529803d3c221101102fe913df7adb83 upstream. There exists a kernel oops caused by a BUG_ON(nhead < 0) at net/core/skbuff.c:2232 in pskb_expand_head(). This bug is triggered as part of the calipso_skbuff_setattr() routine when skb_cow() is passed headroom > INT_MAX (i.e. (int)(skb_headroom(skb) + len_delta) < 0). The root cause of the bug is due to an implicit integer cast in __skb_cow(). The check (headroom > skb_headroom(skb)) is meant to ensure that delta = headroom - skb_headroom(skb) is never negative, otherwise we will trigger a BUG_ON in pskb_expand_head(). However, if headroom > INT_MAX and delta <= -NET_SKB_PAD, the check passes, delta becomes negative, and pskb_expand_head() is passed a negative value for nhead. Fix the trigger condition in calipso_skbuff_setattr(). Avoid passing "negative" headroom sizes to skb_cow() within calipso_skbuff_setattr() by only using skb_cow() to grow headroom. PoC: Using `netlabelctl` tool: netlabelctl map del default netlabelctl calipso add pass doi:7 netlabelctl map add default address:0::1/128 protocol:calipso,7 Then run the following PoC: int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); // setup msghdr int cmsg_size = 2; int cmsg_len = 0x60; struct msghdr msg; struct sockaddr_in6 dest_addr; struct cmsghdr * cmsg = (struct cmsghdr *) calloc(1, sizeof(struct cmsghdr) + cmsg_len); msg.msg_name = &dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = NULL; msg.msg_iovlen = 0; msg.msg_control = cmsg; msg.msg_controllen = cmsg_len; msg.msg_flags = 0; // setup sockaddr dest_addr.sin6_family = AF_INET6; dest_addr.sin6_port = htons(31337); dest_addr.sin6_flowinfo = htonl(31337); dest_addr.sin6_addr = in6addr_loopback; dest_addr.sin6_scope_id = 31337; // setup cmsghdr cmsg->cmsg_len = cmsg_len; cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_HOPOPTS; char * hop_hdr = (char *)cmsg + sizeof(struct cmsghdr); hop_hdr[1] = 0x9; //set hop size - (0x9 + 1) * 8 = 80 sendmsg(fd, &msg, 0); Fixes: 2917f57b6bc1 ("calipso: Allow the lsm to label the skbuff directly.") Suggested-by: Paul Moore Signed-off-by: Will Rosenberg Acked-by: Paul Moore Link: https://patch.msgid.link/20251219173637.797418-1-whrosenb@asu.edu Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/calipso.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index 24666291c54a..72079ef2959b 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -1345,7 +1345,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb, /* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */ pad = ((new_end & 4) + (end & 7)) & 7; len_delta = new_end - (int)end + pad; - ret_val = skb_cow(skb, skb_headroom(skb) + len_delta); + ret_val = skb_cow(skb, + skb_headroom(skb) + (len_delta > 0 ? len_delta : 0)); if (ret_val < 0) return ret_val; -- Gitee From fe0ec4d883ab9633353b30575c3727428a385e50 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 21 Dec 2025 22:48:28 +0800 Subject: [PATCH 0694/1449] ipv4: Fix reference count leak when using error routes with nexthop objects ANBZ: #35228 commit 5979338c83012110ccd45cae6517591770bfe536 stable. commit ac782f4e3bfcde145b8a7f8af31d9422d94d172a upstream. When a nexthop object is deleted, it is marked as dead and then fib_table_flush() is called to flush all the routes that are using the dead nexthop. The current logic in fib_table_flush() is to only flush error routes (e.g., blackhole) when it is called as part of network namespace dismantle (i.e., with flush_all=true). Therefore, error routes are not flushed when their nexthop object is deleted: # ip link add name dummy1 up type dummy # ip nexthop add id 1 dev dummy1 # ip route add 198.51.100.1/32 nhid 1 # ip route add blackhole 198.51.100.2/32 nhid 1 # ip nexthop del id 1 # ip route show blackhole 198.51.100.2 nhid 1 dev dummy1 As such, they keep holding a reference on the nexthop object which in turn holds a reference on the nexthop device, resulting in a reference count leak: # ip link del dev dummy1 [ 70.516258] unregister_netdevice: waiting for dummy1 to become free. Usage count = 2 Fix by flushing error routes when their nexthop is marked as dead. IPv6 does not suffer from this problem. Fixes: 493ced1ac47c ("ipv4: Allow routes to use nexthop objects") Reported-by: Tetsuo Handa Closes: https://lore.kernel.org/netdev/d943f806-4da6-4970-ac28-b9373b0e63ac@I-love.SAKURA.ne.jp/ Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Link: https://patch.msgid.link/20251221144829.197694-1-idosch@nvidia.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv4/fib_trie.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index fa54b36b241a..4d148d089232 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -2059,10 +2059,11 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) continue; } - /* Do not flush error routes if network namespace is - * not being dismantled + /* When not flushing the entire table, skip error + * routes that are not marked for deletion. */ - if (!flush_all && fib_props[fa->fa_type].error) { + if (!flush_all && fib_props[fa->fa_type].error && + !(fi->fib_flags & RTNH_F_DEAD)) { slen = fa->fa_slen; continue; } -- Gitee From 8711e0c11fe99dadad7f6b2f92dfdfb5ad2c30f8 Mon Sep 17 00:00:00 2001 From: Pwnverse Date: Tue, 23 Dec 2025 05:22:27 +0800 Subject: [PATCH 0695/1449] net: rose: fix invalid array index in rose_kill_by_device() ANBZ: #35228 commit 9f6185a32496834d6980b168cffcccc2d6b17280 stable. commit 6595beb40fb0ec47223d3f6058ee40354694c8e4 upstream. rose_kill_by_device() collects sockets into a local array[] and then iterates over them to disconnect sockets bound to a device being brought down. The loop mistakenly indexes array[cnt] instead of array[i]. For cnt < ARRAY_SIZE(array), this reads an uninitialized entry; for cnt == ARRAY_SIZE(array), it is an out-of-bounds read. Either case can lead to an invalid socket pointer dereference and also leaks references taken via sock_hold(). Fix the index to use i. Fixes: 64b8bc7d5f143 ("net/rose: fix races in rose_kill_by_device()") Co-developed-by: Fatma Alwasmi Signed-off-by: Fatma Alwasmi Signed-off-by: Pwnverse Link: https://patch.msgid.link/20251222212227.4116041-1-ritviktanksalkar@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/rose/af_rose.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 614695444b6a..1cc5eaeb1c60 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -205,7 +205,7 @@ static void rose_kill_by_device(struct net_device *dev) spin_unlock_bh(&rose_list_lock); for (i = 0; i < cnt; i++) { - sk = array[cnt]; + sk = array[i]; rose = rose_sk(sk); lock_sock(sk); spin_lock_bh(&rose_list_lock); -- Gitee From cbfebad82ab6fef5349e444e777293da5870a16b Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Thu, 27 Nov 2025 22:31:50 +0800 Subject: [PATCH 0696/1449] RDMA/irdma: avoid invalid read in irdma_net_event ANBZ: #35228 commit fc23d05f0b3fb4d80657e7afebae2cae686b31c8 stable. commit 6f05611728e9d0ab024832a4f1abb74a5f5d0bb0 upstream. irdma_net_event() should not dereference anything from "neigh" (alias "ptr") until it has checked that the event is NETEVENT_NEIGH_UPDATE. Other events come with different structures pointed to by "ptr" and they may be smaller than struct neighbour. Move the read of neigh->dev under the NETEVENT_NEIGH_UPDATE case. The bug is mostly harmless, but it triggers KASAN on debug kernels: BUG: KASAN: stack-out-of-bounds in irdma_net_event+0x32e/0x3b0 [irdma] Read of size 8 at addr ffffc900075e07f0 by task kworker/27:2/542554 CPU: 27 PID: 542554 Comm: kworker/27:2 Kdump: loaded Not tainted 5.14.0-630.el9.x86_64+debug #1 Hardware name: [...] Workqueue: events rt6_probe_deferred Call Trace: dump_stack_lvl+0x60/0xb0 print_address_description.constprop.0+0x2c/0x3f0 print_report+0xb4/0x270 kasan_report+0x92/0xc0 irdma_net_event+0x32e/0x3b0 [irdma] notifier_call_chain+0x9e/0x180 atomic_notifier_call_chain+0x5c/0x110 rt6_do_redirect+0xb91/0x1080 tcp_v6_err+0xe9b/0x13e0 icmpv6_notify+0x2b2/0x630 ndisc_redirect_rcv+0x328/0x530 icmpv6_rcv+0xc16/0x1360 ip6_protocol_deliver_rcu+0xb84/0x12e0 ip6_input_finish+0x117/0x240 ip6_input+0xc4/0x370 ipv6_rcv+0x420/0x7d0 __netif_receive_skb_one_core+0x118/0x1b0 process_backlog+0xd1/0x5d0 __napi_poll.constprop.0+0xa3/0x440 net_rx_action+0x78a/0xba0 handle_softirqs+0x2d4/0x9c0 do_softirq+0xad/0xe0 Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions") Link: https://patch.msgid.link/r/20251127143150.121099-1-mschmidt@redhat.com Signed-off-by: Michal Schmidt Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/irdma/utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c index 6cd5cb85dafe..91ed7edcd788 100644 --- a/drivers/infiniband/hw/irdma/utils.c +++ b/drivers/infiniband/hw/irdma/utils.c @@ -251,7 +251,7 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event, void *ptr) { struct neighbour *neigh = ptr; - struct net_device *real_dev, *netdev = (struct net_device *)neigh->dev; + struct net_device *real_dev, *netdev; struct irdma_device *iwdev; struct ib_device *ibdev; __be32 *p; @@ -260,6 +260,7 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event, switch (event) { case NETEVENT_NEIGH_UPDATE: + netdev = neigh->dev; real_dev = rdma_vlan_dev_real_dev(netdev); if (!real_dev) real_dev = netdev; -- Gitee From 2b8c2d6697695746477f99cfa9fe6c11adcdcd39 Mon Sep 17 00:00:00 2001 From: Michael Margolin Date: Thu, 11 Dec 2025 01:36:56 +0800 Subject: [PATCH 0697/1449] RDMA/efa: Remove possible negative shift ANBZ: #35228 commit c67499757bcf8337b6585bd55e50c57d209cdd65 stable. commit 85463eb6a46caf2f1e0e1a6d0731f2f3bab17780 upstream. The page size used for device might in some cases be smaller than PAGE_SIZE what results in a negative shift when calculating the number of host pages in PAGE_SIZE for a debug log. Remove the debug line together with the calculation. Fixes: 40909f664d27 ("RDMA/efa: Add EFA verbs implementation") Link: https://patch.msgid.link/r/20251210173656.8180-1-mrgolin@amazon.com Reviewed-by: Tom Sela Reviewed-by: Yonatan Nachum Signed-off-by: Michael Margolin Reviewed-by: Gal Pressman Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/efa/efa_verbs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index 0f8ca99d0827..2a5b93ef4b33 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -1224,13 +1224,9 @@ static int umem_to_page_list(struct efa_dev *dev, u32 hp_cnt, u8 hp_shift) { - u32 pages_in_hp = BIT(hp_shift - PAGE_SHIFT); struct ib_block_iter biter; unsigned int hp_idx = 0; - ibdev_dbg(&dev->ibdev, "hp_cnt[%u], pages_in_hp[%u]\n", - hp_cnt, pages_in_hp); - rdma_umem_for_each_dma_block(umem, &biter, BIT(hp_shift)) page_list[hp_idx++] = rdma_block_iter_dma_address(&biter); -- Gitee From aed3eca226d96648b694ab4683a1d473f20f3846 Mon Sep 17 00:00:00 2001 From: Jang Ingyu Date: Fri, 19 Dec 2025 12:15:08 +0800 Subject: [PATCH 0698/1449] RDMA/core: Fix logic error in ib_get_gids_from_rdma_hdr() ANBZ: #35228 commit 78d9259378aa62992744da4988dedf03c877d38b stable. commit 8aaa848eaddd9ef8680fc6aafbd3a0646da5df40 upstream. Fix missing comparison operator for RDMA_NETWORK_ROCE_V1 in the conditional statement. The constant was used directly instead of being compared with net_type, causing the condition to always evaluate to true. Fixes: 1c15b4f2a42f ("RDMA/core: Modify enum ib_gid_type and enum rdma_network_type") Signed-off-by: Jang Ingyu Link: https://patch.msgid.link/20251219041508.1725947-1-ingyujang25@korea.ac.kr Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/core/verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 6567d4375128..615b73f038bb 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -735,7 +735,7 @@ int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr, (struct in6_addr *)dgid); return 0; } else if (net_type == RDMA_NETWORK_IPV6 || - net_type == RDMA_NETWORK_IB || RDMA_NETWORK_ROCE_V1) { + net_type == RDMA_NETWORK_IB || net_type == RDMA_NETWORK_ROCE_V1) { *dgid = hdr->ibgrh.dgid; *sgid = hdr->ibgrh.sgid; return 0; -- Gitee From 93f936549cacfab783ffc6b9395acfb3d96d682f Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Wed, 17 Dec 2025 18:01:41 +0800 Subject: [PATCH 0699/1449] RDMA/bnxt_re: Fix incorrect BAR check in bnxt_qplib_map_creq_db() ANBZ: #35228 commit 689eb90b703b75995b90a5c26bcef1fbab64976e stable. commit 145a417a39d7efbc881f52e829817376972b278c upstream. RCFW_COMM_CONS_PCI_BAR_REGION is defined as BAR 2, so checking !creq_db->reg.bar_id is incorrect and always false. pci_resource_start() returns the BAR base address, and a value of 0 indicates that the BAR is unassigned. Update the condition to test bar_base == 0 instead. This ensures the driver detects and logs an error for an unassigned RCFW communication BAR. Fixes: cee0c7bba486 ("RDMA/bnxt_re: Refactor command queue management code") Signed-off-by: Alok Tiwari Link: https://patch.msgid.link/20251217100158.752504-1-alok.a.tiwari@oracle.com Reviewed-by: Kalesh AP Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index e82bd37158ad..2accda5a04a1 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -1116,7 +1116,7 @@ static int bnxt_qplib_map_creq_db(struct bnxt_qplib_rcfw *rcfw, u32 reg_offt) creq_db->dbinfo.flags = 0; creq_db->reg.bar_id = RCFW_COMM_CONS_PCI_BAR_REGION; creq_db->reg.bar_base = pci_resource_start(pdev, creq_db->reg.bar_id); - if (!creq_db->reg.bar_id) + if (!creq_db->reg.bar_base) dev_err(&pdev->dev, "QPLIB: CREQ BAR region %d resc start is 0!", creq_db->reg.bar_id); -- Gitee From 5a116764ea3d94897412f285e5eb24dc580d8020 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Fri, 19 Dec 2025 17:32:57 +0800 Subject: [PATCH 0700/1449] RDMA/bnxt_re: Fix IB_SEND_IP_CSUM handling in post_send ANBZ: #35228 commit 639e07bbfa17bd9605e968ffeeaee366d74c6301 stable. commit f01765a2361323e78e3d91b1cb1d5527a83c5cf7 upstream. The bnxt_re SEND path checks wr->send_flags to enable features such as IP checksum offload. However, send_flags is a bitmask and may contain multiple flags (e.g. IB_SEND_SIGNALED | IB_SEND_IP_CSUM), while the existing code uses a switch() statement that only matches when send_flags is exactly IB_SEND_IP_CSUM. As a result, checksum offload is not enabled when additional SEND flags are present. Replace the switch() with a bitmask test: if (wr->send_flags & IB_SEND_IP_CSUM) This ensures IP checksum offload is enabled correctly when multiple SEND flags are used. Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Alok Tiwari Link: https://patch.msgid.link/20251219093308.2415620-1-alok.a.tiwari@oracle.com Reviewed-by: Kalesh AP Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 31fff5885f1a..5a4644f7ad98 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -2771,14 +2771,9 @@ int bnxt_re_post_send(struct ib_qp *ib_qp, const struct ib_send_wr *wr, wqe.rawqp1.lflags |= SQ_SEND_RAWETH_QP1_LFLAGS_ROCE_CRC; } - switch (wr->send_flags) { - case IB_SEND_IP_CSUM: + if (wr->send_flags & IB_SEND_IP_CSUM) wqe.rawqp1.lflags |= SQ_SEND_RAWETH_QP1_LFLAGS_IP_CHKSUM; - break; - default: - break; - } fallthrough; case IB_WR_SEND_WITH_INV: rc = bnxt_re_build_send_wqe(qp, wr, &wqe); -- Gitee From 921a2302356275522a65ea8e919ff1d576817560 Mon Sep 17 00:00:00 2001 From: Kalesh AP Date: Tue, 23 Dec 2025 21:18:55 +0800 Subject: [PATCH 0701/1449] RDMA/bnxt_re: Fix to use correct page size for PDE table ANBZ: #35228 commit 77645e82b739a2ee25b5eb8487b46c7dc372701d stable. commit 3d70e0fb0f289b0c778041c5bb04d099e1aa7c1c upstream. In bnxt_qplib_alloc_init_hwq(), while allocating memory for PDE table driver incorrectly is using the "pg_size" value passed to the function. Fixed to use the right value 4K. Also, fixed the allocation size for PBL table. Fixes: 0c4dcd602817 ("RDMA/bnxt_re: Refactor hardware queue memory allocation") Signed-off-by: Damodharam Ammepalli Signed-off-by: Kalesh AP Link: https://patch.msgid.link/20251223131855.145955-1-kalesh-anakkur.purayil@broadcom.com Reviewed-by: Selvin Xavier Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/bnxt_re/qplib_res.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c index 77da7cf34427..1c56a0107d1e 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c @@ -243,7 +243,7 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, if (npbl % BIT(MAX_PDL_LVL_SHIFT)) npde++; /* Alloc PDE pages */ - sginfo.pgsize = npde * pg_size; + sginfo.pgsize = npde * ROCE_PG_SIZE_4K; sginfo.npages = 1; rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); if (rc) @@ -251,7 +251,7 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, /* Alloc PBL pages */ sginfo.npages = npbl; - sginfo.pgsize = PAGE_SIZE; + sginfo.pgsize = ROCE_PG_SIZE_4K; rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_1], &sginfo); if (rc) goto fail; -- Gitee From 80c655607de9855bf733058e1653f7071d2d68a2 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 24 Dec 2025 22:20:16 +0800 Subject: [PATCH 0702/1449] ksmbd: Fix memory leak in get_file_all_info() ANBZ: #35228 commit 5012b4c812230ae066902a00442708c999111183 stable. commit 0c56693b06a68476ba113db6347e7897475f9e4c upstream. In get_file_all_info(), if vfs_getattr() fails, the function returns immediately without freeing the allocated filename, leading to a memory leak. Fix this by freeing the filename before returning in this error case. Fixes: 5614c8c487f6a ("ksmbd: replace generic_fillattr with vfs_getattr") Signed-off-by: Zilin Guan Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 5fc83ece1f80..35f0bc9c81f2 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4914,8 +4914,10 @@ static int get_file_all_info(struct ksmbd_work *work, ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); - if (ret) + if (ret) { + kfree(filename); return ret; + } ksmbd_debug(SMB, "filename = %s\n", filename); delete_pending = ksmbd_inode_pending_delete(fp); -- Gitee From f0d84c73d5c24baa76215ff5b45b0d4b1c6765ff Mon Sep 17 00:00:00 2001 From: Honggang LI Date: Mon, 29 Dec 2025 10:56:17 +0800 Subject: [PATCH 0703/1449] RDMA/rtrs: Fix clt_path::max_pages_per_mr calculation ANBZ: #35228 commit 0ca967c599fd06473ba0668c530eeb0c3e18ef22 stable. commit 43bd09d5b750f700499ae8ec45fd41a4c48673e6 upstream. If device max_mr_size bits in the range [mr_page_shift+31:mr_page_shift] are zero, the `min3` function will set clt_path::max_pages_per_mr to zero. `alloc_path_reqs` will pass zero, which is invalid, as the third parameter to `ib_alloc_mr`. Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality") Signed-off-by: Honggang LI Link: https://patch.msgid.link/20251229025617.13241-1-honggangli@163.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 82aa47efb807..eaf911e2ffa9 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -1465,6 +1465,7 @@ static void query_fast_reg_mode(struct rtrs_clt_path *clt_path) mr_page_shift = max(12, ffs(ib_dev->attrs.page_size_cap) - 1); max_pages_per_mr = ib_dev->attrs.max_mr_size; do_div(max_pages_per_mr, (1ull << mr_page_shift)); + max_pages_per_mr = min_not_zero((u32)max_pages_per_mr, U32_MAX); clt_path->max_pages_per_mr = min3(clt_path->max_pages_per_mr, (u32)max_pages_per_mr, ib_dev->attrs.max_fast_reg_page_list_len); -- Gitee From a49d483a83cde3cb6c88093f16849f12ef374e80 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 30 Dec 2025 16:51:21 +0800 Subject: [PATCH 0704/1449] RDMA/bnxt_re: fix dma_free_coherent() pointer ANBZ: #35228 commit 1d0026c1e4bcabf61b8a6648380c1f71ab94d4c2 stable. commit fcd431a9627f272b4c0bec445eba365fe2232a94 upstream. The dma_alloc_coherent() allocates a dma-mapped buffer, pbl->pg_arr[i]. The dma_free_coherent() should pass the same buffer to dma_free_coherent() and not page-aligned. Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20251230085121.8023-2-fourier.thomas@gmail.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/hw/bnxt_re/qplib_res.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c index 1c56a0107d1e..d2c8f21468dc 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c @@ -70,9 +70,7 @@ static void __free_pbl(struct bnxt_qplib_res *res, struct bnxt_qplib_pbl *pbl, for (i = 0; i < pbl->pg_count; i++) { if (pbl->pg_arr[i]) dma_free_coherent(&pdev->dev, pbl->pg_size, - (void *)((unsigned long) - pbl->pg_arr[i] & - PAGE_MASK), + pbl->pg_arr[i], pbl->pg_map_arr[i]); else dev_warn(&pdev->dev, -- Gitee From cee7aff4e413b2534ec6a4a34410352ed608e2a5 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Mar 2024 10:12:44 +0800 Subject: [PATCH 0705/1449] blk-mq: don't schedule block kworker on isolated CPUs ANBZ: #35228 commit 0fbd2d4a1e2c6efdfddfd780b7117a2373f2b48e stable. commit a46c27026da10a126dd870f7b65380010bd20db5 upstream. Kernel parameter of `isolcpus=` or 'nohz_full=' are used to isolate CPUs for specific task, and it isn't expected to let block IO disturb these CPUs. blk-mq kworker shouldn't be scheduled on isolated CPUs. Also if isolated CPUs is run for blk-mq kworker, long block IO latency can be caused. Kernel workqueue only respects CPU isolation for WQ_UNBOUND, for bound WQ, the responsibility is on user because CPU is specified as WQ API parameter, such as mod_delayed_work_on(cpu), queue_delayed_work_on(cpu) and queue_work_on(cpu). So not run blk-mq kworker on isolated CPUs by removing isolated CPUs from hctx->cpumask. Meantime use queue map to check if all CPUs in this hw queue are offline instead of hctx->cpumask, this way can avoid any cost in fast IO code path, and is safe since hctx->cpumask are only used in the two cases. Cc: Tim Chen Cc: Juri Lelli Cc: Andrew Theurer Cc: Joe Mario Cc: Sebastian Jug Cc: Frederic Weisbecker Cc: Bart Van Assche Cc: Tejun Heo Tesed-by: Joe Mario Signed-off-by: Ming Lei Reviewed-by: Ewan D. Milne Link: https://lore.kernel.org/r/20240322021244.1056223-1-ming.lei@redhat.com Signed-off-by: Jens Axboe Stable-dep-of: 10845a105bbc ("blk-mq: skip CPU offline notify on unmapped hctx") Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- block/blk-mq.c | 57 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 103da8441ecf..378ad6b9f4db 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -2247,6 +2248,15 @@ static inline int blk_mq_first_mapped_cpu(struct blk_mq_hw_ctx *hctx) return cpu; } +/* + * ->next_cpu is always calculated from hctx->cpumask, so simply use + * it for speeding up the check + */ +static bool blk_mq_hctx_empty_cpumask(struct blk_mq_hw_ctx *hctx) +{ + return hctx->next_cpu >= nr_cpu_ids; +} + /* * It'd be great if the workqueue API had a way to pass * in a mask and had some smarts for more clever placement. @@ -2258,7 +2268,8 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx) bool tried = false; int next_cpu = hctx->next_cpu; - if (hctx->queue->nr_hw_queues == 1) + /* Switch to unbound if no allowable CPUs in this hctx */ + if (hctx->queue->nr_hw_queues == 1 || blk_mq_hctx_empty_cpumask(hctx)) return WORK_CPU_UNBOUND; if (--hctx->next_cpu_batch <= 0) { @@ -3600,14 +3611,30 @@ static bool blk_mq_hctx_has_requests(struct blk_mq_hw_ctx *hctx) return data.has_rq; } -static inline bool blk_mq_last_cpu_in_hctx(unsigned int cpu, - struct blk_mq_hw_ctx *hctx) +static bool blk_mq_hctx_has_online_cpu(struct blk_mq_hw_ctx *hctx, + unsigned int this_cpu) { - if (cpumask_first_and(hctx->cpumask, cpu_online_mask) != cpu) - return false; - if (cpumask_next_and(cpu, hctx->cpumask, cpu_online_mask) < nr_cpu_ids) - return false; - return true; + enum hctx_type type = hctx->type; + int cpu; + + /* + * hctx->cpumask has to rule out isolated CPUs, but userspace still + * might submit IOs on these isolated CPUs, so use the queue map to + * check if all CPUs mapped to this hctx are offline + */ + for_each_online_cpu(cpu) { + struct blk_mq_hw_ctx *h = blk_mq_map_queue_type(hctx->queue, + type, cpu); + + if (h != hctx) + continue; + + /* this hctx has at least one online CPU */ + if (this_cpu != cpu) + return true; + } + + return false; } static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) @@ -3616,8 +3643,7 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) struct blk_mq_hw_ctx, cpuhp_online); int ret = 0; - if (!cpumask_test_cpu(cpu, hctx->cpumask) || - !blk_mq_last_cpu_in_hctx(cpu, hctx)) + if (blk_mq_hctx_has_online_cpu(hctx, cpu)) return 0; /* @@ -4110,6 +4136,8 @@ static void blk_mq_map_swqueue(struct request_queue *q) } queue_for_each_hw_ctx(q, hctx, i) { + int cpu; + /* * If no software queues are mapped to this hardware queue, * disable it and free the request entries. @@ -4136,6 +4164,15 @@ static void blk_mq_map_swqueue(struct request_queue *q) */ sbitmap_resize(&hctx->ctx_map, hctx->nr_ctx); + /* + * Rule out isolated CPUs from hctx->cpumask to avoid + * running block kworker on isolated CPUs + */ + for_each_cpu(cpu, hctx->cpumask) { + if (cpu_is_isolated(cpu)) + cpumask_clear_cpu(cpu, hctx->cpumask); + } + /* * Initialize batch roundrobin counts */ -- Gitee From 917dd71235d8faf6b00dbe2c42a474f27fa4849e Mon Sep 17 00:00:00 2001 From: Cong Zhang Date: Tue, 30 Dec 2025 17:17:05 +0800 Subject: [PATCH 0706/1449] blk-mq: skip CPU offline notify on unmapped hctx ANBZ: #35228 commit 21077a775094782e714b00ead7dc7647d84bcb66 stable. commit 10845a105bbcb030647a729f1716c2309da71d33 upstream. If an hctx has no software ctx mapped, blk_mq_map_swqueue() never allocates tags and leaves hctx->tags NULL. The CPU hotplug offline notifier can still run for that hctx, return early since hctx cannot hold any requests. Signed-off-by: Cong Zhang Fixes: bf0beec0607d ("blk-mq: drain I/O when all CPUs in a hctx are offline") Reviewed-by: Ming Lei Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- block/blk-mq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 378ad6b9f4db..b78f5cc3bea8 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3643,7 +3643,7 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) struct blk_mq_hw_ctx, cpuhp_online); int ret = 0; - if (blk_mq_hctx_has_online_cpu(hctx, cpu)) + if (!hctx->nr_ctx || blk_mq_hctx_has_online_cpu(hctx, cpu)) return 0; /* -- Gitee From 39eca962efb89a3c0a688c4d591882957561a2c6 Mon Sep 17 00:00:00 2001 From: Yipeng Zou Date: Fri, 18 Aug 2023 09:32:26 +0800 Subject: [PATCH 0707/1449] selftests/ftrace: traceonoff_triggers: strip off names ANBZ: #35228 commit 6c32d5bb9f8f5108fc959952bcac4dd7574c6c64 stable. commit b889b4fb4cbea3ca7eb9814075d6a51936394bd9 upstream. The func_traceonoff_triggers.tc sometimes goes to fail on my board, Kunpeng-920. [root@localhost]# ./ftracetest ./test.d/ftrace/func_traceonoff_triggers.tc -l fail.log === Ftrace unit tests === [1] ftrace - test for function traceon/off triggers [FAIL] [2] (instance) ftrace - test for function traceon/off triggers [UNSUPPORTED] I look up the log, and it shows that the md5sum is different between csum1 and csum2. ++ cnt=611 ++ sleep .1 +++ cnt_trace +++ grep -v '^#' trace +++ wc -l ++ cnt2=611 ++ '[' 611 -ne 611 ']' +++ cat tracing_on ++ on=0 ++ '[' 0 '!=' 0 ']' +++ md5sum trace ++ csum1='76896aa74362fff66a6a5f3cf8a8a500 trace' ++ sleep .1 +++ md5sum trace ++ csum2='ee8625a21c058818fc26e45c1ed3f6de trace' ++ '[' '76896aa74362fff66a6a5f3cf8a8a500 trace' '!=' 'ee8625a21c058818fc26e45c1ed3f6de trace' ']' ++ fail 'Tracing file is still changing' ++ echo Tracing file is still changing Tracing file is still changing ++ exit_fail ++ exit 1 So I directly dump the trace file before md5sum, the diff shows that: [root@localhost]# diff trace_1.log trace_2.log -y --suppress-common-lines dockerd-12285 [036] d.... 18385.510290: sched_stat | <...>-12285 [036] d.... 18385.510290: sched_stat dockerd-12285 [036] d.... 18385.510291: sched_swit | <...>-12285 [036] d.... 18385.510291: sched_swit <...>-740 [044] d.... 18385.602859: sched_stat | kworker/44:1-740 [044] d.... 18385.602859: sched_stat <...>-740 [044] d.... 18385.602860: sched_swit | kworker/44:1-740 [044] d.... 18385.602860: sched_swit And we can see that <...> filed be filled with names. We can strip off the names there to fix that. After strip off the names: kworker/u257:0-12 [019] d..2. 2528.758910: sched_stat | -12 [019] d..2. 2528.758910: sched_stat_runtime: comm=k kworker/u257:0-12 [019] d..2. 2528.758912: sched_swit | -12 [019] d..2. 2528.758912: sched_switch: prev_comm=kw -0 [000] d.s5. 2528.762318: sched_waki | -0 [000] d.s5. 2528.762318: sched_waking: comm=sshd pi -0 [037] dNh2. 2528.762326: sched_wake | -0 [037] dNh2. 2528.762326: sched_wakeup: comm=sshd pi -0 [037] d..2. 2528.762334: sched_swit | -0 [037] d..2. 2528.762334: sched_switch: prev_comm=sw Link: https://lore.kernel.org/r/20230818013226.2182299-1-zouyipeng@huawei.com Fixes: d87b29179aa0 ("selftests: ftrace: Use md5sum to take less time of checking logs") Suggested-by: Steven Rostedt (Google) Signed-off-by: Yipeng Zou Acked-by: Masami Hiramatsu (Google) Reviewed-by: Steven Rostedt (Google) Signed-off-by: Shuah Khan Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../ftrace/test.d/ftrace/func_traceonoff_triggers.tc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc index aee22289536b..1b57771dbfdf 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc @@ -90,9 +90,10 @@ if [ $on != "0" ]; then fail "Tracing is not off" fi -csum1=`md5sum trace` +# Cannot rely on names being around as they are only cached, strip them +csum1=`cat trace | sed -e 's/^ *[^ ]*\(-[0-9][0-9]*\)/\1/' | md5sum` sleep $SLEEP_TIME -csum2=`md5sum trace` +csum2=`cat trace | sed -e 's/^ *[^ ]*\(-[0-9][0-9]*\)/\1/' | md5sum` if [ "$csum1" != "$csum2" ]; then fail "Tracing file is still changing" -- Gitee From a595448981d8d05e43106723edb51f042f9ecf09 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Sat, 19 Jul 2025 03:53:58 +0800 Subject: [PATCH 0708/1449] ntfs: Do not overwrite uptodate pages ANBZ: #35228 commit 49c2ef075dbec895ae39d108e1bc9abad57f207a stable. commit 68f6bd128e75a032432eda9d16676ed2969a1096 upstream. When reading a compressed file, we may read several pages in addition to the one requested. The current code will overwrite pages in the page cache with the data from disc which can definitely result in changes that have been made being lost. For example if we have four consecutie pages ABCD in the file compressed into a single extent, on first access, we'll bring in ABCD. Then we write to page B. Memory pressure results in the eviction of ACD. When we attempt to write to page C, we will overwrite the data in page B with the data currently on disk. I haven't investigated the decompression code to check whether it's OK to overwrite a clean page or whether it might be possible to see corrupt data. Out of an abundance of caution, decline to overwrite uptodate pages, not just dirty pages. Fixes: 4342306f0f0d (fs/ntfs3: Add file operations and implementation) Signed-off-by: Matthew Wilcox (Oracle) Cc: stable@vger.kernel.org Signed-off-by: Konstantin Komarov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/frecord.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index 18e41faef8e6..06b1d82b5997 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -2075,6 +2075,29 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, return err; } +static struct page *ntfs_lock_new_page(struct address_space *mapping, + pgoff_t index, gfp_t gfp) +{ + struct folio *folio = __filemap_get_folio(mapping, index, + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp); + struct page *page; + + if (IS_ERR(folio)) + return ERR_CAST(folio); + + if (!folio_test_uptodate(folio)) + return folio_file_page(folio, index); + + /* Use a temporary page to avoid data corruption */ + folio_unlock(folio); + folio_put(folio); + page = alloc_page(gfp); + if (!page) + return ERR_PTR(-ENOMEM); + __SetPageLocked(page); + return page; +} + /* * ni_readpage_cmpr * @@ -2128,9 +2151,9 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page) if (i == idx) continue; - pg = find_or_create_page(mapping, index, gfp_mask); - if (!pg) { - err = -ENOMEM; + pg = ntfs_lock_new_page(mapping, index, gfp_mask); + if (IS_ERR(pg)) { + err = PTR_ERR(pg); goto out1; } pages[i] = pg; @@ -2232,13 +2255,13 @@ int ni_decompress_file(struct ntfs_inode *ni) for (i = 0; i < pages_per_frame; i++, index++) { struct page *pg; - pg = find_or_create_page(mapping, index, gfp_mask); - if (!pg) { + pg = ntfs_lock_new_page(mapping, index, gfp_mask); + if (IS_ERR(pg)) { while (i--) { unlock_page(pages[i]); put_page(pages[i]); } - err = -ENOMEM; + err = PTR_ERR(pg); goto out; } pages[i] = pg; -- Gitee From 5336c50db27698dc2e7162014813aaa7099ef2ab Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 24 Nov 2025 18:49:05 +0800 Subject: [PATCH 0709/1449] ASoC: stm32: sai: fix device leak on probe ANBZ: #35228 commit 637d027bb75c3f9b42e09c4f0f0f23b45f416a4a stable. commit e26ff429eaf10c4ef1bc3dabd9bf27eb54b7e1f4 upstream. Make sure to drop the reference taken when looking up the sync provider device and its driver data during DAI probe on probe failures and on unbind. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Fixes: 7dd0d835582f ("ASoC: stm32: sai: simplify sync modes management") Fixes: 1c3816a19487 ("ASoC: stm32: sai: add missing put_device()") Cc: stable@vger.kernel.org # 4.16: 1c3816a19487 Cc: olivier moysan Cc: Wen Yang Signed-off-by: Johan Hovold Reviewed-by: olivier moysan Link: https://patch.msgid.link/20251124104908.15754-2-johan@kernel.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/stm/stm32_sai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index 8e21e6f886fc..df167c389b98 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -127,6 +127,7 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, } sai_provider = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!sai_provider) { dev_err(&sai_client->pdev->dev, "SAI sync provider data not found\n"); @@ -143,7 +144,6 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, ret = stm32_sai_sync_conf_provider(sai_provider, synco); error: - put_device(&pdev->dev); of_node_put(np_provider); return ret; } -- Gitee From ff1f736c73292300b120d8c88a7a5f18396bd133 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 24 Nov 2025 18:49:06 +0800 Subject: [PATCH 0710/1449] ASoC: stm32: sai: fix clk prepare imbalance on probe failure ANBZ: #35228 commit 8a6826a43d8d26c410aea1d7a260ead22529dce2 stable. commit 312ec2f0d9d1a5656f76d770bbf1d967e9289aa7 upstream. Make sure to unprepare the parent clock also on probe failures (e.g. probe deferral). Fixes: a14bf98c045b ("ASoC: stm32: sai: fix possible circular locking") Cc: stable@vger.kernel.org # 5.5 Cc: Olivier Moysan Signed-off-by: Johan Hovold Reviewed-by: olivier moysan Link: https://patch.msgid.link/20251124104908.15754-3-johan@kernel.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/stm/stm32_sai_sub.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 351e96163406..e068ddb49ffa 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1501,14 +1501,21 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, if (of_property_present(np, "#clock-cells")) { ret = stm32_sai_add_mclk_provider(sai); if (ret < 0) - return ret; + goto err_unprepare_pclk; } else { sai->sai_mclk = devm_clk_get_optional(&pdev->dev, "MCLK"); - if (IS_ERR(sai->sai_mclk)) - return PTR_ERR(sai->sai_mclk); + if (IS_ERR(sai->sai_mclk)) { + ret = PTR_ERR(sai->sai_mclk); + goto err_unprepare_pclk; + } } return 0; + +err_unprepare_pclk: + clk_unprepare(sai->pdata->pclk); + + return ret; } static int stm32_sai_sub_probe(struct platform_device *pdev) @@ -1552,26 +1559,33 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) IRQF_SHARED, dev_name(&pdev->dev), sai); if (ret) { dev_err(&pdev->dev, "IRQ request returned %d\n", ret); - return ret; + goto err_unprepare_pclk; } if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) conf = &stm32_sai_pcm_config_spdif; ret = snd_dmaengine_pcm_register(&pdev->dev, conf, 0); - if (ret) - return dev_err_probe(&pdev->dev, ret, "Could not register pcm dma\n"); + if (ret) { + ret = dev_err_probe(&pdev->dev, ret, "Could not register pcm dma\n"); + goto err_unprepare_pclk; + } ret = snd_soc_register_component(&pdev->dev, &stm32_component, &sai->cpu_dai_drv, 1); if (ret) { snd_dmaengine_pcm_unregister(&pdev->dev); - return ret; + goto err_unprepare_pclk; } pm_runtime_enable(&pdev->dev); return 0; + +err_unprepare_pclk: + clk_unprepare(sai->pdata->pclk); + + return ret; } static void stm32_sai_sub_remove(struct platform_device *pdev) -- Gitee From 00a8fdc46c7872fa04e235185274cc68767990b4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 24 Nov 2025 18:49:07 +0800 Subject: [PATCH 0711/1449] ASoC: stm32: sai: fix OF node leak on probe ANBZ: #35228 commit 4054a3597d047f3fe87864ef87f399b5d523e6c0 stable. commit 23261f0de09427367e99f39f588e31e2856a690e upstream. The reference taken to the sync provider OF node when probing the platform device is currently only dropped if the set_sync() callback fails during DAI probe. Make sure to drop the reference on platform probe failures (e.g. probe deferral) and on driver unbind. This also avoids a potential use-after-free in case the DAI is ever reprobed without first rebinding the platform driver. Fixes: 5914d285f6b7 ("ASoC: stm32: sai: Add synchronization support") Fixes: d4180b4c02e7 ("ASoC: stm32: sai: fix set_sync service") Cc: Olivier Moysan Cc: stable@vger.kernel.org # 4.16: d4180b4c02e7 Signed-off-by: Johan Hovold Reviewed-by: olivier moysan Link: https://patch.msgid.link/20251124104908.15754-4-johan@kernel.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/stm/stm32_sai.c | 12 +++--------- sound/soc/stm/stm32_sai_sub.c | 23 ++++++++++++++++------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index df167c389b98..026321620a20 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -122,7 +122,6 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, if (!pdev) { dev_err(&sai_client->pdev->dev, "Device not found for node %pOFn\n", np_provider); - of_node_put(np_provider); return -ENODEV; } @@ -131,21 +130,16 @@ static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, if (!sai_provider) { dev_err(&sai_client->pdev->dev, "SAI sync provider data not found\n"); - ret = -EINVAL; - goto error; + return -EINVAL; } /* Configure sync client */ ret = stm32_sai_sync_conf_client(sai_client, synci); if (ret < 0) - goto error; + return ret; /* Configure sync provider */ - ret = stm32_sai_sync_conf_provider(sai_provider, synco); - -error: - of_node_put(np_provider); - return ret; + return stm32_sai_sync_conf_provider(sai_provider, synco); } static int stm32_sai_probe(struct platform_device *pdev) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index e068ddb49ffa..c47f23634e95 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1453,7 +1453,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, dev_err(&pdev->dev, "External synchro not supported\n"); of_node_put(args.np); - return -EINVAL; + ret = -EINVAL; + goto err_put_sync_provider; } sai->sync = SAI_SYNC_EXTERNAL; @@ -1462,7 +1463,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, (sai->synci > (SAI_GCR_SYNCIN_MAX + 1))) { dev_err(&pdev->dev, "Wrong SAI index\n"); of_node_put(args.np); - return -EINVAL; + ret = -EINVAL; + goto err_put_sync_provider; } if (of_property_match_string(args.np, "compatible", @@ -1476,7 +1478,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, if (!sai->synco) { dev_err(&pdev->dev, "Unknown SAI sub-block\n"); of_node_put(args.np); - return -EINVAL; + ret = -EINVAL; + goto err_put_sync_provider; } } @@ -1486,13 +1489,15 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, of_node_put(args.np); sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck"); - if (IS_ERR(sai->sai_ck)) - return dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck), - "Missing kernel clock sai_ck\n"); + if (IS_ERR(sai->sai_ck)) { + ret = dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck), + "Missing kernel clock sai_ck\n"); + goto err_put_sync_provider; + } ret = clk_prepare(sai->pdata->pclk); if (ret < 0) - return ret; + goto err_put_sync_provider; if (STM_SAI_IS_F4(sai->pdata)) return 0; @@ -1514,6 +1519,8 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, err_unprepare_pclk: clk_unprepare(sai->pdata->pclk); +err_put_sync_provider: + of_node_put(sai->np_sync_provider); return ret; } @@ -1584,6 +1591,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) err_unprepare_pclk: clk_unprepare(sai->pdata->pclk); + of_node_put(sai->np_sync_provider); return ret; } @@ -1596,6 +1604,7 @@ static void stm32_sai_sub_remove(struct platform_device *pdev) snd_dmaengine_pcm_unregister(&pdev->dev); snd_soc_unregister_component(&pdev->dev); pm_runtime_disable(&pdev->dev); + of_node_put(sai->np_sync_provider); } #ifdef CONFIG_PM_SLEEP -- Gitee From 1855dbfb4a5ca61609220443b0f410ac4a3701e0 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 23 Oct 2025 18:24:25 +0800 Subject: [PATCH 0712/1449] ASoC: qcom: q6apm-dai: set flags to reflect correct operation of appl_ptr ANBZ: #35228 commit ed120b75aef27d69760608c81e42dc4de0fa5c47 stable. commit 950a4e5788fc7dc6e8e93614a7d4d0449c39fb8d upstream. Driver does not expect the appl_ptr to move backward and requires explict sync. Make sure that the userspace does not do appl_ptr rewinds by specifying the correct flags in pcm_info. Without this patch, the result could be a forever loop as current logic assumes that appl_ptr can only move forward. Fixes: 3d4a4411aa8b ("ASoC: q6apm-dai: schedule all available frames to avoid dsp under-runs") Cc: Stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Tested-by: Alexey Klimov # RB5, RB3 Link: https://patch.msgid.link/20251023102444.88158-2-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/qcom/qdsp6/q6apm-dai.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index 179f4f7386dd..ddca7312274b 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -85,6 +85,7 @@ static struct snd_pcm_hardware q6apm_dai_hardware_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_NO_REWINDS | SNDRV_PCM_INFO_SYNC_APPLPTR | SNDRV_PCM_INFO_BATCH), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), .rates = SNDRV_PCM_RATE_8000_48000, @@ -104,6 +105,7 @@ static struct snd_pcm_hardware q6apm_dai_hardware_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_NO_REWINDS | SNDRV_PCM_INFO_SYNC_APPLPTR | SNDRV_PCM_INFO_BATCH), .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE), .rates = SNDRV_PCM_RATE_8000_192000, -- Gitee From 6305873d108e9454274526c8e8804db12e09b277 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 23 Oct 2025 18:24:28 +0800 Subject: [PATCH 0713/1449] ASoC: qcom: q6asm-dai: perform correct state check before closing ANBZ: #35228 commit 54b1b731d235e6c249efe861039c263de701c762 stable. commit bfbb12dfa144d45575bcfe139a71360b3ce80237 upstream. Do not stop a q6asm stream if its not started, this can result in unnecessary dsp command which will timeout anyway something like below: q6asm-dai ab00000.remoteproc:glink-edge:apr:service@7:dais: CMD 10bcd timeout Fix this by correctly checking the state. Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver") Cc: Stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Tested-by: Alexey Klimov # RB5, RB3 Link: https://patch.msgid.link/20251023102444.88158-5-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/qcom/qdsp6/q6asm-dai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 82ef8fdb914e..831a180191ac 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -237,13 +237,14 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, prtd->pcm_count = snd_pcm_lib_period_bytes(substream); prtd->pcm_irq_pos = 0; /* rate and channels are sent to audio driver */ - if (prtd->state) { + if (prtd->state == Q6ASM_STREAM_RUNNING) { /* clear the previous setup if any */ q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE); q6asm_unmap_memory_regions(substream->stream, prtd->audio_client); q6routing_stream_close(soc_prtd->dai_link->id, substream->stream); + prtd->state = Q6ASM_STREAM_STOPPED; } ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client, -- Gitee From 138734670eb250f688cb0172de3d5e10a0e088fa Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 23 Oct 2025 18:24:26 +0800 Subject: [PATCH 0714/1449] ASoC: qcom: q6adm: the the copp device only during last instance ANBZ: #35228 commit c4a8098b2985a2292da6f6c7a91618160ae7b6cf stable. commit 74cc4f3ea4e99262ba0d619c6a4ee33e2cd47f65 upstream. A matching Common object post processing instance is normally resused across multiple streams. However currently we close this on DSP even though there is a refcount on this copp object, this can result in below error. q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: Found Matching Copp 0x0 qcom-q6adm aprsvc:service:4:8: cmd = 0x10325 return error = 0x2 q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: DSP returned error[2] q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: Found Matching Copp 0x0 qcom-q6adm aprsvc:service:4:8: cmd = 0x10325 return error = 0x2 q6routing ab00000.remoteproc:glink-edge:apr:service@8:routing: DSP returned error[2] qcom-q6adm aprsvc:service:4:8: cmd = 0x10327 return error = 0x2 qcom-q6adm aprsvc:service:4:8: DSP returned error[2] qcom-q6adm aprsvc:service:4:8: Failed to close copp -22 qcom-q6adm aprsvc:service:4:8: cmd = 0x10327 return error = 0x2 qcom-q6adm aprsvc:service:4:8: DSP returned error[2] qcom-q6adm aprsvc:service:4:8: Failed to close copp -22 Fix this by addressing moving the adm_close to copp_kref destructor callback. Fixes: 7b20b2be51e1 ("ASoC: qdsp6: q6adm: Add q6adm driver") Cc: Stable@vger.kernel.org Reported-by: Martino Facchin Signed-off-by: Srinivas Kandagatla Tested-by: Alexey Klimov # RB5, RB3 Link: https://patch.msgid.link/20251023102444.88158-3-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/qcom/qdsp6/q6adm.c | 146 +++++++++++++++++------------------ 1 file changed, 71 insertions(+), 75 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c index 1530e98df165..75a029a696ac 100644 --- a/sound/soc/qcom/qdsp6/q6adm.c +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -109,11 +109,75 @@ static struct q6copp *q6adm_find_copp(struct q6adm *adm, int port_idx, } +static int q6adm_apr_send_copp_pkt(struct q6adm *adm, struct q6copp *copp, + struct apr_pkt *pkt, uint32_t rsp_opcode) +{ + struct device *dev = adm->dev; + uint32_t opcode = pkt->hdr.opcode; + int ret; + + mutex_lock(&adm->lock); + copp->result.opcode = 0; + copp->result.status = 0; + ret = apr_send_pkt(adm->apr, pkt); + if (ret < 0) { + dev_err(dev, "Failed to send APR packet\n"); + ret = -EINVAL; + goto err; + } + + /* Wait for the callback with copp id */ + if (rsp_opcode) + ret = wait_event_timeout(copp->wait, + (copp->result.opcode == opcode) || + (copp->result.opcode == rsp_opcode), + msecs_to_jiffies(TIMEOUT_MS)); + else + ret = wait_event_timeout(copp->wait, + (copp->result.opcode == opcode), + msecs_to_jiffies(TIMEOUT_MS)); + + if (!ret) { + dev_err(dev, "ADM copp cmd timedout\n"); + ret = -ETIMEDOUT; + } else if (copp->result.status > 0) { + dev_err(dev, "DSP returned error[%d]\n", + copp->result.status); + ret = -EINVAL; + } + +err: + mutex_unlock(&adm->lock); + return ret; +} + +static int q6adm_device_close(struct q6adm *adm, struct q6copp *copp, + int port_id, int copp_idx) +{ + struct apr_pkt close; + + close.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + close.hdr.pkt_size = sizeof(close); + close.hdr.src_port = port_id; + close.hdr.dest_port = copp->id; + close.hdr.token = port_id << 16 | copp_idx; + close.hdr.opcode = ADM_CMD_DEVICE_CLOSE_V5; + + return q6adm_apr_send_copp_pkt(adm, copp, &close, 0); +} + static void q6adm_free_copp(struct kref *ref) { struct q6copp *c = container_of(ref, struct q6copp, refcount); struct q6adm *adm = c->adm; unsigned long flags; + int ret; + + ret = q6adm_device_close(adm, c, c->afe_port, c->copp_idx); + if (ret < 0) + dev_err(adm->dev, "Failed to close copp %d\n", ret); spin_lock_irqsave(&adm->copps_list_lock, flags); clear_bit(c->copp_idx, &adm->copp_bitmap[c->afe_port]); @@ -155,13 +219,13 @@ static int q6adm_callback(struct apr_device *adev, struct apr_resp_pkt *data) switch (result->opcode) { case ADM_CMD_DEVICE_OPEN_V5: case ADM_CMD_DEVICE_CLOSE_V5: - copp = q6adm_find_copp(adm, port_idx, copp_idx); - if (!copp) - return 0; - - copp->result = *result; - wake_up(&copp->wait); - kref_put(&copp->refcount, q6adm_free_copp); + list_for_each_entry(copp, &adm->copps_list, node) { + if ((port_idx == copp->afe_port) && (copp_idx == copp->copp_idx)) { + copp->result = *result; + wake_up(&copp->wait); + break; + } + } break; case ADM_CMD_MATRIX_MAP_ROUTINGS_V5: adm->result = *result; @@ -234,65 +298,6 @@ static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx) return c; } -static int q6adm_apr_send_copp_pkt(struct q6adm *adm, struct q6copp *copp, - struct apr_pkt *pkt, uint32_t rsp_opcode) -{ - struct device *dev = adm->dev; - uint32_t opcode = pkt->hdr.opcode; - int ret; - - mutex_lock(&adm->lock); - copp->result.opcode = 0; - copp->result.status = 0; - ret = apr_send_pkt(adm->apr, pkt); - if (ret < 0) { - dev_err(dev, "Failed to send APR packet\n"); - ret = -EINVAL; - goto err; - } - - /* Wait for the callback with copp id */ - if (rsp_opcode) - ret = wait_event_timeout(copp->wait, - (copp->result.opcode == opcode) || - (copp->result.opcode == rsp_opcode), - msecs_to_jiffies(TIMEOUT_MS)); - else - ret = wait_event_timeout(copp->wait, - (copp->result.opcode == opcode), - msecs_to_jiffies(TIMEOUT_MS)); - - if (!ret) { - dev_err(dev, "ADM copp cmd timedout\n"); - ret = -ETIMEDOUT; - } else if (copp->result.status > 0) { - dev_err(dev, "DSP returned error[%d]\n", - copp->result.status); - ret = -EINVAL; - } - -err: - mutex_unlock(&adm->lock); - return ret; -} - -static int q6adm_device_close(struct q6adm *adm, struct q6copp *copp, - int port_id, int copp_idx) -{ - struct apr_pkt close; - - close.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - close.hdr.pkt_size = sizeof(close); - close.hdr.src_port = port_id; - close.hdr.dest_port = copp->id; - close.hdr.token = port_id << 16 | copp_idx; - close.hdr.opcode = ADM_CMD_DEVICE_CLOSE_V5; - - return q6adm_apr_send_copp_pkt(adm, copp, &close, 0); -} - static struct q6copp *q6adm_find_matching_copp(struct q6adm *adm, int port_id, int topology, int mode, int rate, @@ -567,15 +572,6 @@ EXPORT_SYMBOL_GPL(q6adm_matrix_map); */ int q6adm_close(struct device *dev, struct q6copp *copp) { - struct q6adm *adm = dev_get_drvdata(dev->parent); - int ret = 0; - - ret = q6adm_device_close(adm, copp, copp->afe_port, copp->copp_idx); - if (ret < 0) { - dev_err(adm->dev, "Failed to close copp %d\n", ret); - return ret; - } - kref_put(&copp->refcount, q6adm_free_copp); return 0; -- Gitee From 82011df60e1d73ddc7ccf1c570a2b9a69cce1e47 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 23 Oct 2025 18:24:27 +0800 Subject: [PATCH 0715/1449] ASoC: qcom: qdsp6: q6asm-dai: set 10 ms period and buffer alignment. ANBZ: #35228 commit 17ec295d39810c83fa07b611451036c5c73f3ad6 stable. commit 81c53b52de21b8d5a3de55ebd06b6bf188bf7efd upstream. DSP expects the periods to be aligned to fragment sizes, currently setting up to hw constriants on periods bytes is not going to work correctly as we can endup with periods sizes aligned to 32 bytes however not aligned to fragment size. Update the constriants to use fragment size, and also set at step of 10ms for period size to accommodate DSP requirements of 10ms latency. Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver") Cc: Stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Tested-by: Alexey Klimov # RB5, RB3 Link: https://patch.msgid.link/20251023102444.88158-4-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/qcom/qdsp6/q6asm-dai.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 831a180191ac..43e71d4fd66f 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -413,13 +413,13 @@ static int q6asm_dai_open(struct snd_soc_component *component, } ret = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 480); if (ret < 0) { dev_err(dev, "constraint for period bytes step ret = %d\n", ret); } ret = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 480); if (ret < 0) { dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret); -- Gitee From 3b557bc7740d5a4e428e9cc4c1d3ff210c661575 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:05 +0800 Subject: [PATCH 0716/1449] iommu/apple-dart: fix device leak on of_xlate() ANBZ: #35228 commit aa749c2daf028ef54e5f70f90c4277c6dd55df7c stable. commit a6eaa872c52a181ae9a290fd4e40c9df91166d7a upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Fixes: 46d1fb072e76 ("iommu/dart: Add DART iommu driver") Cc: stable@vger.kernel.org # 5.15 Cc: Sven Peter Acked-by: Robin Murphy Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/apple-dart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index 87deb1fc0fe9..6c1ecfb2150f 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -793,6 +793,8 @@ static int apple_dart_of_xlate(struct device *dev, struct apple_dart *cfg_dart; int i, sid; + put_device(&iommu_pdev->dev); + if (args->args_count != 1) return -EINVAL; sid = args->args[0]; -- Gitee From d3aefafe0064b2680520749ecb4d086ea7ca1160 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:07 +0800 Subject: [PATCH 0717/1449] iommu/exynos: fix device leak on of_xlate() ANBZ: #35228 commit e83739232b9fdda2cfd23e1781b6338195d0e083 stable. commit 05913cc43cb122f9afecdbe775115c058b906e1b upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Note that commit 1a26044954a6 ("iommu/exynos: add missing put_device() call in exynos_iommu_of_xlate()") fixed the leak in a couple of error paths, but the reference is still leaking on success. Fixes: aa759fd376fb ("iommu/exynos: Add callback for initializing devices from device tree") Cc: stable@vger.kernel.org # 4.2: 1a26044954a6 Cc: Yu Kuai Acked-by: Robin Murphy Acked-by: Marek Szyprowski Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/exynos-iommu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index ff559e74f6ef..63eb2fb6a401 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1443,17 +1443,14 @@ static int exynos_iommu_of_xlate(struct device *dev, return -ENODEV; data = platform_get_drvdata(sysmmu); - if (!data) { - put_device(&sysmmu->dev); + put_device(&sysmmu->dev); + if (!data) return -ENODEV; - } if (!owner) { owner = kzalloc(sizeof(*owner), GFP_KERNEL); - if (!owner) { - put_device(&sysmmu->dev); + if (!owner) return -ENOMEM; - } INIT_LIST_HEAD(&owner->controllers); mutex_init(&owner->rpm_lock); -- Gitee From ddf4b0568fc1d5e213838880a46babeccee1ecf6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:08 +0800 Subject: [PATCH 0718/1449] iommu/ipmmu-vmsa: fix device leak on of_xlate() ANBZ: #35228 commit 83a8e18f30a60f6e36876b803c60c3e102d39d3f stable. commit 80aa518452c4aceb9459f9a8e3184db657d1b441 upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Fixes: 7b2d59611fef ("iommu/ipmmu-vmsa: Replace local utlb code with fwspec ids") Cc: stable@vger.kernel.org # 4.14 Cc: Magnus Damm Acked-by: Robin Murphy Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/ipmmu-vmsa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index efe6abe986fb..2e12cf97cf23 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -719,6 +719,8 @@ static int ipmmu_init_platform_device(struct device *dev, dev_iommu_priv_set(dev, platform_get_drvdata(ipmmu_pdev)); + put_device(&ipmmu_pdev->dev); + return 0; } -- Gitee From 589d4394730cd87dbcf6475a7cabc2ba3f919a93 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:12 +0800 Subject: [PATCH 0719/1449] iommu/mediatek-v1: fix device leak on probe_device() ANBZ: #35228 commit e7bcedf59b28dc84196087381a754d2d896e8174 stable. commit c77ad28bfee0df9cbc719eb5adc9864462cfb65b upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during probe_device(). Fixes: b17336c55d89 ("iommu/mediatek: add support for mtk iommu generation one HW") Cc: stable@vger.kernel.org # 4.8 Cc: Honghui Zhang Acked-by: Robin Murphy Reviewed-by: Yong Wu Signed-off-by: Johan Hovold Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/mtk_iommu_v1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 0cf84f95b8ba..50cd371c52ee 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -426,6 +426,8 @@ static int mtk_iommu_v1_create_mapping(struct device *dev, return -EINVAL; dev_iommu_priv_set(dev, platform_get_drvdata(m4updev)); + + put_device(&m4updev->dev); } ret = iommu_fwspec_add_ids(dev, args->args, 1); -- Gitee From 9da5596dfcdb3cc6b4eedc635e8f2b9b5bf199a2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:13 +0800 Subject: [PATCH 0720/1449] iommu/mediatek-v1: fix device leaks on probe() ANBZ: #35228 commit 83f3010de73cfd600292635a62add5e9bf396b2d stable. commit 46207625c9f33da0e43bb4ae1e91f0791b6ed633 upstream. Make sure to drop the references taken to the larb devices during probe on probe failure (e.g. probe deferral) and on driver unbind. Fixes: b17336c55d89 ("iommu/mediatek: add support for mtk iommu generation one HW") Cc: stable@vger.kernel.org # 4.8 Cc: Honghui Zhang Acked-by: Robin Murphy Signed-off-by: Johan Hovold Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/mtk_iommu_v1.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 50cd371c52ee..5f90990e63f8 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -644,8 +644,10 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) struct platform_device *plarbdev; larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); - if (!larbnode) - return -EINVAL; + if (!larbnode) { + ret = -EINVAL; + goto out_put_larbs; + } if (!of_device_is_available(larbnode)) { of_node_put(larbnode); @@ -655,11 +657,14 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) plarbdev = of_find_device_by_node(larbnode); if (!plarbdev) { of_node_put(larbnode); - return -ENODEV; + ret = -ENODEV; + goto out_put_larbs; } if (!plarbdev->dev.driver) { of_node_put(larbnode); - return -EPROBE_DEFER; + put_device(&plarbdev->dev); + ret = -EPROBE_DEFER; + goto out_put_larbs; } data->larb_imu[i].dev = &plarbdev->dev; @@ -671,7 +676,7 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) ret = mtk_iommu_v1_hw_init(data); if (ret) - return ret; + goto out_put_larbs; ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, dev_name(&pdev->dev)); @@ -693,12 +698,17 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) iommu_device_sysfs_remove(&data->iommu); out_clk_unprepare: clk_disable_unprepare(data->bclk); +out_put_larbs: + for (i = 0; i < MTK_LARB_NR_MAX; i++) + put_device(data->larb_imu[i].dev); + return ret; } static void mtk_iommu_v1_remove(struct platform_device *pdev) { struct mtk_iommu_v1_data *data = platform_get_drvdata(pdev); + int i; iommu_device_sysfs_remove(&data->iommu); iommu_device_unregister(&data->iommu); @@ -706,6 +716,9 @@ static void mtk_iommu_v1_remove(struct platform_device *pdev) clk_disable_unprepare(data->bclk); devm_free_irq(&pdev->dev, data->irq, data); component_master_del(&pdev->dev, &mtk_iommu_v1_com_ops); + + for (i = 0; i < MTK_LARB_NR_MAX; i++) + put_device(data->larb_imu[i].dev); } static int __maybe_unused mtk_iommu_v1_suspend(struct device *dev) -- Gitee From f629ab9b4c25f76d1260aad9e2c40a0b4f5885ea Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:09 +0800 Subject: [PATCH 0721/1449] iommu/mediatek: fix device leak on of_xlate() ANBZ: #35228 commit 173ff5fc9a15e15af0546b7c024a7a5e2b55e858 stable. commit b3f1ee18280363ef17f82b564fc379ceba9ec86f upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Fixes: 0df4fabe208d ("iommu/mediatek: Add mt8173 IOMMU driver") Cc: stable@vger.kernel.org # 4.6 Acked-by: Robin Murphy Reviewed-by: Yong Wu Signed-off-by: Johan Hovold Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/mtk_iommu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index ce84bf9ede00..9ec0196b4c02 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -975,6 +975,8 @@ static int mtk_iommu_of_xlate(struct device *dev, return -EINVAL; dev_iommu_priv_set(dev, platform_get_drvdata(m4updev)); + + put_device(&m4updev->dev); } return iommu_fwspec_add_ids(dev, args->args, 1); -- Gitee From acdd3521e0ce997959c44c57696cdcb868b2b040 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:15 +0800 Subject: [PATCH 0722/1449] iommu/omap: fix device leaks on probe_device() ANBZ: #35228 commit 21a0e8bdee72421fe7c8be4a2fbc35497ae9acd3 stable. commit b5870691065e6bbe6ba0650c0412636c6a239c5a upstream. Make sure to drop the references taken to the iommu platform devices when looking up their driver data during probe_device(). Note that the arch data device pointer added by commit 604629bcb505 ("iommu/omap: add support for late attachment of iommu devices") has never been used. Remove it to underline that the references are not needed. Fixes: 9d5018deec86 ("iommu/omap: Add support to program multiple iommus") Fixes: 7d6827748d54 ("iommu/omap: Fix iommu archdata name for DT-based devices") Cc: stable@vger.kernel.org # 3.18 Cc: Suman Anna Acked-by: Robin Murphy Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/omap-iommu.c | 2 +- drivers/iommu/omap-iommu.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index e76309d9e23f..841f65599d0d 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1688,6 +1688,7 @@ static struct iommu_device *omap_iommu_probe_device(struct device *dev) } oiommu = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!oiommu) { of_node_put(np); kfree(arch_data); @@ -1695,7 +1696,6 @@ static struct iommu_device *omap_iommu_probe_device(struct device *dev) } tmp->iommu_dev = oiommu; - tmp->dev = &pdev->dev; of_node_put(np); } diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index 27697109ec79..50b39be61abc 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h @@ -88,7 +88,6 @@ struct omap_iommu { /** * struct omap_iommu_arch_data - omap iommu private data * @iommu_dev: handle of the OMAP iommu device - * @dev: handle of the iommu device * * This is an omap iommu private data object, which binds an iommu user * to its iommu device. This object should be placed at the iommu user's @@ -97,7 +96,6 @@ struct omap_iommu { */ struct omap_iommu_arch_data { struct omap_iommu *iommu_dev; - struct device *dev; }; struct cr_regs { -- Gitee From 0af9af5e493720fc3bf9831887ceaccda158c5e0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:06 +0800 Subject: [PATCH 0723/1449] iommu/qcom: fix device leak on of_xlate() ANBZ: #35228 commit 7b1df346f6c53bcccb76b6968cc2ed4a6a543393 stable. commit 6a3908ce56e6879920b44ef136252b2f0c954194 upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Note that commit e2eae09939a8 ("iommu/qcom: add missing put_device() call in qcom_iommu_of_xlate()") fixed the leak in a couple of error paths, but the reference is still leaking on success and late failures. Fixes: 0ae349a0f33f ("iommu/qcom: Add qcom_iommu") Cc: stable@vger.kernel.org # 4.14: e2eae09939a8 Cc: Rob Clark Cc: Yu Kuai Acked-by: Robin Murphy Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index 913ed0966164..943551be28af 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -567,14 +567,14 @@ static int qcom_iommu_of_xlate(struct device *dev, qcom_iommu = platform_get_drvdata(iommu_pdev); + put_device(&iommu_pdev->dev); + /* make sure the asid specified in dt is valid, so we don't have * to sanity check this elsewhere: */ if (WARN_ON(asid > qcom_iommu->max_asid) || - WARN_ON(qcom_iommu->ctxs[asid] == NULL)) { - put_device(&iommu_pdev->dev); + WARN_ON(qcom_iommu->ctxs[asid] == NULL)) return -EINVAL; - } if (!dev_iommu_priv_get(dev)) { dev_iommu_priv_set(dev, qcom_iommu); @@ -583,10 +583,8 @@ static int qcom_iommu_of_xlate(struct device *dev, * multiple different iommu devices. Multiple context * banks are ok, but multiple devices are not: */ - if (WARN_ON(qcom_iommu != dev_iommu_priv_get(dev))) { - put_device(&iommu_pdev->dev); + if (WARN_ON(qcom_iommu != dev_iommu_priv_get(dev))) return -EINVAL; - } } return iommu_fwspec_add_ids(dev, &asid, 1); -- Gitee From d3eabf25eff841774e389d67fae177adee86c355 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:17 +0800 Subject: [PATCH 0724/1449] iommu/sun50i: fix device leak on of_xlate() ANBZ: #35228 commit 0314de9c844da8bd1289b6cee36077605221a3de stable. commit f916109bf53864605d10bf6f4215afa023a80406 upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during of_xlate(). Fixes: 4100b8c229b3 ("iommu: Add Allwinner H6 IOMMU driver") Cc: stable@vger.kernel.org # 5.8 Cc: Maxime Ripard Acked-by: Robin Murphy Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/sun50i-iommu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index 8a2ce133d7b2..df5a64e73e1e 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -839,6 +839,8 @@ static int sun50i_iommu_of_xlate(struct device *dev, dev_iommu_priv_set(dev, platform_get_drvdata(iommu_pdev)); + put_device(&iommu_pdev->dev); + return iommu_fwspec_add_ids(dev, &id, 1); } -- Gitee From c70cd299fff53939647748ee8a33bf2bcca0f80c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 20 Oct 2025 12:53:18 +0800 Subject: [PATCH 0725/1449] iommu/tegra: fix device leak on probe_device() ANBZ: #35228 commit 3627e0e773f13fb5ddee2bf4347eed3b6744991d stable. commit c08934a61201db8f1d1c66fcc63fb2eb526b656d upstream. Make sure to drop the reference taken to the iommu platform device when looking up its driver data during probe_device(). Note that commit 9826e393e4a8 ("iommu/tegra-smmu: Fix missing put_device() call in tegra_smmu_find") fixed the leak in an error path, but the reference is still leaking on success. Fixes: 891846516317 ("memory: Add NVIDIA Tegra memory controller support") Cc: stable@vger.kernel.org # 3.19: 9826e393e4a8 Cc: Miaoqian Lin Acked-by: Robin Murphy Acked-by: Thierry Reding Signed-off-by: Johan Hovold Signed-off-by: Joerg Roedel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iommu/tegra-smmu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 9fb473dc56f6..c62a59d7d7b0 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -828,10 +828,9 @@ static struct tegra_smmu *tegra_smmu_find(struct device_node *np) return NULL; mc = platform_get_drvdata(pdev); - if (!mc) { - put_device(&pdev->dev); + put_device(&pdev->dev); + if (!mc) return NULL; - } return mc->smmu; } -- Gitee From ec596d48de403c0447ea71d7a8fdb5ca6ff9ab26 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 9 Nov 2025 05:03:18 +0800 Subject: [PATCH 0726/1449] HID: logitech-dj: Remove duplicate error logging ANBZ: #35228 commit 9024cb893f17a4fdfa76fe1f3797d7a7d625ac0e stable. commit ca389a55d8b2d86a817433bf82e0602b68c4d541 upstream. logi_dj_recv_query_paired_devices() and logi_dj_recv_switch_to_dj_mode() both have 2 callers which all log an error if the function fails. Move the error logging to inside these 2 functions to remove the duplicated error logging in the callers. While at it also move the logi_dj_recv_send_report() call error handling in logi_dj_recv_switch_to_dj_mode() to directly after the call. That call only fails if the report cannot be found and in that case it does nothing, so the msleep() is not necessary on failures. Fixes: 6f20d3261265 ("HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode()") Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-logitech-dj.c | 56 ++++++++++++++--------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index e2d5b3f69914..84ad70c9d038 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -805,7 +805,6 @@ static void delayedwork_callback(struct work_struct *work) struct dj_workitem workitem; unsigned long flags; int count; - int retval; dbg_hid("%s\n", __func__); @@ -842,11 +841,7 @@ static void delayedwork_callback(struct work_struct *work) logi_dj_recv_destroy_djhid_device(djrcv_dev, &workitem); break; case WORKITEM_TYPE_UNKNOWN: - retval = logi_dj_recv_query_paired_devices(djrcv_dev); - if (retval) { - hid_err(djrcv_dev->hidpp, "%s: logi_dj_recv_query_paired_devices error: %d\n", - __func__, retval); - } + logi_dj_recv_query_paired_devices(djrcv_dev); break; case WORKITEM_TYPE_EMPTY: dbg_hid("%s: device list is empty\n", __func__); @@ -1239,8 +1234,10 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) djrcv_dev->last_query = jiffies; - if (djrcv_dev->type != recvr_type_dj) - return logi_dj_recv_query_hidpp_devices(djrcv_dev); + if (djrcv_dev->type != recvr_type_dj) { + retval = logi_dj_recv_query_hidpp_devices(djrcv_dev); + goto out; + } dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); if (!dj_report) @@ -1250,6 +1247,10 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; retval = logi_dj_recv_send_report(djrcv_dev, dj_report); kfree(dj_report); +out: + if (retval < 0) + hid_err(djrcv_dev->hidpp, "%s error:%d\n", __func__, retval); + return retval; } @@ -1275,6 +1276,8 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, (u8)timeout; retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + if (retval) + goto out; /* * Ugly sleep to work around a USB 3.0 bug when the receiver is @@ -1283,11 +1286,6 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, * 50 msec should gives enough time to the receiver to be ready. */ msleep(50); - - if (retval) { - kfree(dj_report); - return retval; - } } /* @@ -1313,7 +1311,12 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); +out: kfree(dj_report); + + if (retval < 0) + hid_err(hdev, "%s error:%d\n", __func__, retval); + return retval; } @@ -1835,11 +1838,8 @@ static int logi_dj_probe(struct hid_device *hdev, if (has_hidpp) { retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0); - if (retval < 0) { - hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n", - __func__, retval); + if (retval < 0) goto switch_to_dj_mode_fail; - } } /* This is enabling the polling urb on the IN endpoint */ @@ -1857,15 +1857,11 @@ static int logi_dj_probe(struct hid_device *hdev, spin_lock_irqsave(&djrcv_dev->lock, flags); djrcv_dev->ready = true; spin_unlock_irqrestore(&djrcv_dev->lock, flags); - retval = logi_dj_recv_query_paired_devices(djrcv_dev); - if (retval < 0) { - hid_err(hdev, "%s: logi_dj_recv_query_paired_devices error:%d\n", - __func__, retval); - /* - * This can happen with a KVM, let the probe succeed, - * logi_dj_recv_queue_unknown_work will retry later. - */ - } + /* + * This can fail with a KVM. Ignore errors to let the probe + * succeed, logi_dj_recv_queue_unknown_work will retry later. + */ + logi_dj_recv_query_paired_devices(djrcv_dev); } return 0; @@ -1882,18 +1878,12 @@ static int logi_dj_probe(struct hid_device *hdev, #ifdef CONFIG_PM static int logi_dj_reset_resume(struct hid_device *hdev) { - int retval; struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); if (!djrcv_dev || djrcv_dev->hidpp != hdev) return 0; - retval = logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0); - if (retval < 0) { - hid_err(hdev, "%s: logi_dj_recv_switch_to_dj_mode returned error:%d\n", - __func__, retval); - } - + logi_dj_recv_switch_to_dj_mode(djrcv_dev, 0); return 0; } #endif -- Gitee From 4d5ba225f537a1f362643b4e8d335e6694d51529 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Wed, 19 Nov 2025 16:50:01 +0800 Subject: [PATCH 0727/1449] PCI/PM: Reinstate clearing state_saved in legacy and !PM codepaths ANBZ: #35228 commit a1d55aa866db58cb8339c89c69881b81b98c7c67 stable. commit 894f475f88e06c0f352c829849560790dbdedbe5 upstream. When a PCI device is suspended, it is normally the PCI core's job to save Config Space and put the device into a low power state. However drivers are allowed to assume these responsibilities. When they do, the PCI core can tell by looking at the state_saved flag in struct pci_dev: The flag is cleared before commencing the suspend sequence and it is set when pci_save_state() is called. If the PCI core finds the flag set late in the suspend sequence, it refrains from calling pci_save_state() itself. But there are two corner cases where the PCI core neglects to clear the flag before commencing the suspend sequence: * If a driver has legacy PCI PM callbacks, pci_legacy_suspend() neglects to clear the flag. The (stale) flag is subsequently queried by pci_legacy_suspend() itself and pci_legacy_suspend_late(). * If a device has no driver or its driver has no PCI PM callbacks, pci_pm_freeze() neglects to clear the flag. The (stale) flag is subsequently queried by pci_pm_freeze_noirq(). The flag may be set prior to suspend if the device went through error recovery: Drivers commonly invoke pci_restore_state() + pci_save_state() to restore Config Space after reset. The flag may also be set if drivers call pci_save_state() on probe to allow for recovery from subsequent errors. The result is that pci_legacy_suspend_late() and pci_pm_freeze_noirq() don't call pci_save_state() and so the state that will be restored on resume is the one recorded on last error recovery or on probe, not the one that the device had on suspend. If the two states happen to be identical, there's no problem. Reinstate clearing the flag in pci_legacy_suspend() and pci_pm_freeze(). The two functions used to do that until commit 4b77b0a2ba27 ("PCI: Clear saved_state after the state has been restored") deemed it unnecessary because it assumed that it's sufficient to clear the flag on resume in pci_restore_state(). The commit seemingly did not take into account that pci_save_state() and pci_restore_state() are not only used by power management code, but also for error recovery. Devices without driver or whose driver has no PCI PM callbacks may be in runtime suspend when pci_pm_freeze() is called. Their state has already been saved, so don't clear the flag to skip a pointless pci_save_state() in pci_pm_freeze_noirq(). None of the drivers with legacy PCI PM callbacks seem to use runtime PM, so clear the flag unconditionally in their case. Fixes: 4b77b0a2ba27 ("PCI: Clear saved_state after the state has been restored") Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Reviewed-by: Rafael J. Wysocki (Intel) Cc: stable@vger.kernel.org # v2.6.32+ Link: https://patch.msgid.link/094f2aad64418710daf0940112abe5a0afdc6bce.1763483367.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/pci-driver.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 206b8670dcfb..af16643f9a59 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -648,6 +648,8 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = pci_dev->driver; + pci_dev->state_saved = false; + if (drv && drv->suspend) { pci_power_t prev = pci_dev->current_state; int error; @@ -1052,6 +1054,8 @@ static int pci_pm_freeze(struct device *dev) if (!pm) { pci_pm_default_suspend(pci_dev); + if (!pm_runtime_suspended(dev)) + pci_dev->state_saved = false; return 0; } -- Gitee From 70f4818bc4771e2e99e32b896061407e6ebf7d06 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Thu, 20 Nov 2025 00:01:05 +0800 Subject: [PATCH 0728/1449] arm64: dts: ti: k3-j721e-sk: Fix pinmux for pin Y1 used by power regulator ANBZ: #35228 commit 14b08c85cb881e27bde1784bf01f73cacbcce81d stable. commit 51f89c488f2ecc020f82bfedd77482584ce8027a upstream. The SoC pin Y1 is incorrectly defined in the WKUP Pinmux device-tree node (pinctrl@4301c000) leading to the following silent failure: pinctrl-single 4301c000.pinctrl: mux offset out of range: 0x1dc (0x178) According to the datasheet for the J721E SoC [0], the pin Y1 belongs to the MAIN Pinmux device-tree node (pinctrl@11c000). This is confirmed by the address of the pinmux register for it on page 142 of the datasheet which is 0x00011C1DC. Hence fix it. [0]: https://www.ti.com/lit/ds/symlink/tda4vm.pdf Fixes: 97b67cc102dc ("arm64: dts: ti: k3-j721e-sk: Add DT nodes for power regulators") Cc: stable@vger.kernel.org Signed-off-by: Siddharth Vadapalli Reviewed-by: Yemike Abhilash Chandra Link: https://patch.msgid.link/20251119160148.2752616-1-s-vadapalli@ti.com Signed-off-by: Vignesh Raghavendra Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts index 952d2c72628e..895dc21e6b8a 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts @@ -571,6 +571,12 @@ rpi_header_gpio1_pins_default: rpi-header-gpio1-default-pins { J721E_IOPAD(0x234, PIN_INPUT, 7) /* (U3) EXT_REFCLK1.GPIO1_12 */ >; }; + + vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { + pinctrl-single,pins = < + J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ + >; + }; }; &wkup_pmx0 { @@ -626,12 +632,6 @@ J721E_WKUP_IOPAD(0xd4, PIN_OUTPUT, 7) /* (G26) WKUP_GPIO0_9 */ >; }; - vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { - pinctrl-single,pins = < - J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ - >; - }; - wkup_uart0_pins_default: wkup-uart0-default-pins { pinctrl-single,pins = < J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */ -- Gitee From d76d4811a99e486eb3dd41c7c96f68c1630c4eff Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Sun, 16 Nov 2025 14:40:46 +0800 Subject: [PATCH 0729/1449] powerpc, mm: Fix mprotect on book3s 32-bit ANBZ: #35228 commit db9c8e8d3cd65693c49b9e3b3a230e332480f6b3 stable. commit 78fc63ffa7813e33681839bb33826c24195f0eb7 upstream. On 32-bit book3s with hash-MMUs, tlb_flush() was a no-op. This was unnoticed because all uses until recently were for unmaps, and thus handled by __tlb_remove_tlb_entry(). After commit 4a18419f71cd ("mm/mprotect: use mmu_gather") in kernel 5.19, tlb_gather_mmu() started being used for mprotect as well. This caused mprotect to simply not work on these machines: int *ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); *ptr = 1; // force HPTE to be created mprotect(ptr, 4096, PROT_READ); *ptr = 2; // should segfault, but succeeds Fixed by making tlb_flush() actually flush TLB pages. This finally agrees with the behaviour of boot3s64's tlb_flush(). Fixes: 4a18419f71cd ("mm/mprotect: use mmu_gather") Cc: stable@vger.kernel.org Reviewed-by: Christophe Leroy Reviewed-by: Ritesh Harjani (IBM) Signed-off-by: Dave Vasilevsky Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20251116-vasi-mprotect-g3-v3-1-59a9bd33ba00@vasilevsky.ca Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/include/asm/book3s/32/tlbflush.h | 5 ++++- arch/powerpc/mm/book3s32/tlb.c | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/book3s/32/tlbflush.h b/arch/powerpc/include/asm/book3s/32/tlbflush.h index 4be572908124..e77245d7900f 100644 --- a/arch/powerpc/include/asm/book3s/32/tlbflush.h +++ b/arch/powerpc/include/asm/book3s/32/tlbflush.h @@ -11,6 +11,7 @@ void hash__flush_tlb_mm(struct mm_struct *mm); void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end); +void hash__flush_gather(struct mmu_gather *tlb); #ifdef CONFIG_SMP void _tlbie(unsigned long address); @@ -29,7 +30,9 @@ void _tlbia(void); static inline void tlb_flush(struct mmu_gather *tlb) { /* 603 needs to flush the whole TLB here since it doesn't use a hash table. */ - if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) + if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) + hash__flush_gather(tlb); + else _tlbia(); } diff --git a/arch/powerpc/mm/book3s32/tlb.c b/arch/powerpc/mm/book3s32/tlb.c index 9ad6b56bfec9..e54a7b011232 100644 --- a/arch/powerpc/mm/book3s32/tlb.c +++ b/arch/powerpc/mm/book3s32/tlb.c @@ -105,3 +105,12 @@ void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); } EXPORT_SYMBOL(hash__flush_tlb_page); + +void hash__flush_gather(struct mmu_gather *tlb) +{ + if (tlb->fullmm || tlb->need_flush_all) + hash__flush_tlb_mm(tlb->mm); + else + hash__flush_range(tlb->mm, tlb->start, tlb->end); +} +EXPORT_SYMBOL(hash__flush_gather); -- Gitee From 04b7777bfdd1b77acfada32c3a148003a8c193c9 Mon Sep 17 00:00:00 2001 From: Donet Tom Date: Thu, 30 Oct 2025 22:57:26 +0800 Subject: [PATCH 0730/1449] powerpc/64s/slb: Fix SLB multihit issue during SLB preload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit b13a3dbfa196af68eae2031f209743735ad416bf stable. commit 00312419f0863964625d6dcda8183f96849412c6 upstream. On systems using the hash MMU, there is a software SLB preload cache that mirrors the entries loaded into the hardware SLB buffer. This preload cache is subject to periodic eviction — typically after every 256 context switches — to remove old entry. To optimize performance, the kernel skips switch_mmu_context() in switch_mm_irqs_off() when the prev and next mm_struct are the same. However, on hash MMU systems, this can lead to inconsistencies between the hardware SLB and the software preload cache. If an SLB entry for a process is evicted from the software cache on one CPU, and the same process later runs on another CPU without executing switch_mmu_context(), the hardware SLB may retain stale entries. If the kernel then attempts to reload that entry, it can trigger an SLB multi-hit error. The following timeline shows how stale SLB entries are created and can cause a multi-hit error when a process moves between CPUs without a MMU context switch. CPU 0 CPU 1 ----- ----- Process P exec swapper/1 load_elf_binary begin_new_exc activate_mm switch_mm_irqs_off switch_mmu_context switch_slb /* * This invalidates all * the entries in the HW * and setup the new HW * SLB entries as per the * preload cache. */ context_switch sched_migrate_task migrates process P to cpu-1 Process swapper/0 context switch (to process P) (uses mm_struct of Process P) switch_mm_irqs_off() switch_slb load_slb++ /* * load_slb becomes 0 here * and we evict an entry from * the preload cache with * preload_age(). We still * keep HW SLB and preload * cache in sync, that is * because all HW SLB entries * anyways gets evicted in * switch_slb during SLBIA. * We then only add those * entries back in HW SLB, * which are currently * present in preload_cache * (after eviction). */ load_elf_binary continues... setup_new_exec() slb_setup_new_exec() sched_switch event sched_migrate_task migrates process P to cpu-0 context_switch from swapper/0 to Process P switch_mm_irqs_off() /* * Since both prev and next mm struct are same we don't call * switch_mmu_context(). This will cause the HW SLB and SW preload * cache to go out of sync in preload_new_slb_context. Because there * was an SLB entry which was evicted from both HW and preload cache * on cpu-1. Now later in preload_new_slb_context(), when we will try * to add the same preload entry again, we will add this to the SW * preload cache and then will add it to the HW SLB. Since on cpu-0 * this entry was never invalidated, hence adding this entry to the HW * SLB will cause a SLB multi-hit error. */ load_elf_binary continues... START_THREAD start_thread preload_new_slb_context /* * This tries to add a new EA to preload cache which was earlier * evicted from both cpu-1 HW SLB and preload cache. This caused the * HW SLB of cpu-0 to go out of sync with the SW preload cache. The * reason for this was, that when we context switched back on CPU-0, * we should have ideally called switch_mmu_context() which will * bring the HW SLB entries on CPU-0 in sync with SW preload cache * entries by setting up the mmu context properly. But we didn't do * that since the prev mm_struct running on cpu-0 was same as the * next mm_struct (which is true for swapper / kernel threads). So * now when we try to add this new entry into the HW SLB of cpu-0, * we hit a SLB multi-hit error. */ WARNING: CPU: 0 PID: 1810970 at arch/powerpc/mm/book3s64/slb.c:62 assert_slb_presence+0x2c/0x50(48 results) 02:47:29 [20157/42149] Modules linked in: CPU: 0 UID: 0 PID: 1810970 Comm: dd Not tainted 6.16.0-rc3-dirty #12 VOLUNTARY Hardware name: IBM pSeries (emulated by qemu) POWER8 (architected) 0x4d0200 0xf000004 of:SLOF,HEAD hv:linux,kvm pSeries NIP: c00000000015426c LR: c0000000001543b4 CTR: 0000000000000000 REGS: c0000000497c77e0 TRAP: 0700 Not tainted (6.16.0-rc3-dirty) MSR: 8000000002823033 CR: 28888482 XER: 00000000 CFAR: c0000000001543b0 IRQMASK: 3 <...> NIP [c00000000015426c] assert_slb_presence+0x2c/0x50 LR [c0000000001543b4] slb_insert_entry+0x124/0x390 Call Trace: 0x7fffceb5ffff (unreliable) preload_new_slb_context+0x100/0x1a0 start_thread+0x26c/0x420 load_elf_binary+0x1b04/0x1c40 bprm_execve+0x358/0x680 do_execveat_common+0x1f8/0x240 sys_execve+0x58/0x70 system_call_exception+0x114/0x300 system_call_common+0x160/0x2c4 >From the above analysis, during early exec the hardware SLB is cleared, and entries from the software preload cache are reloaded into hardware by switch_slb. However, preload_new_slb_context and slb_setup_new_exec also attempt to load some of the same entries, which can trigger a multi-hit. In most cases, these additional preloads simply hit existing entries and add nothing new. Removing these functions avoids redundant preloads and eliminates the multi-hit issue. This patch removes these two functions. We tested process switching performance using the context_switch benchmark on POWER9/hash, and observed no regression. Without this patch: 129041 ops/sec With this patch: 129341 ops/sec We also measured SLB faults during boot, and the counts are essentially the same with and without this patch. SLB faults without this patch: 19727 SLB faults with this patch: 19786 Fixes: 5434ae74629a ("powerpc/64s/hash: Add a SLB preload cache") cc: stable@vger.kernel.org Suggested-by: Nicholas Piggin Signed-off-by: Donet Tom Signed-off-by: Ritesh Harjani (IBM) Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/0ac694ae683494fe8cadbd911a1a5018d5d3c541.1761834163.git.ritesh.list@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/include/asm/book3s/64/mmu-hash.h | 1 - arch/powerpc/kernel/process.c | 5 -- arch/powerpc/mm/book3s64/internal.h | 2 - arch/powerpc/mm/book3s64/mmu_context.c | 2 - arch/powerpc/mm/book3s64/slb.c | 88 ------------------- 5 files changed, 98 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 1c4eebbc69c9..e1f77e2eead4 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -524,7 +524,6 @@ void slb_save_contents(struct slb_entry *slb_ptr); void slb_dump_contents(struct slb_entry *slb_ptr); extern void slb_vmalloc_update(void); -void preload_new_slb_context(unsigned long start, unsigned long sp); #ifdef CONFIG_PPC_64S_HASH_MMU void slb_set_size(u16 size); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9452a54d356c..dd23025ef2e1 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1882,8 +1882,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) return 0; } -void preload_new_slb_context(unsigned long start, unsigned long sp); - /* * Set up a thread for executing a new program */ @@ -1891,9 +1889,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) { #ifdef CONFIG_PPC64 unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ - - if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled()) - preload_new_slb_context(start, sp); #endif #ifdef CONFIG_PPC_TRANSACTIONAL_MEM diff --git a/arch/powerpc/mm/book3s64/internal.h b/arch/powerpc/mm/book3s64/internal.h index a57a25f06a21..c26a6f0c90fc 100644 --- a/arch/powerpc/mm/book3s64/internal.h +++ b/arch/powerpc/mm/book3s64/internal.h @@ -24,8 +24,6 @@ static inline bool stress_hpt(void) void hpt_do_stress(unsigned long ea, unsigned long hpte_group); -void slb_setup_new_exec(void); - void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush); #endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */ diff --git a/arch/powerpc/mm/book3s64/mmu_context.c b/arch/powerpc/mm/book3s64/mmu_context.c index 1715b07c630c..997bc13a690e 100644 --- a/arch/powerpc/mm/book3s64/mmu_context.c +++ b/arch/powerpc/mm/book3s64/mmu_context.c @@ -150,8 +150,6 @@ static int hash__init_new_context(struct mm_struct *mm) void hash__setup_new_exec(void) { slice_setup_new_exec(); - - slb_setup_new_exec(); } #else static inline int hash__init_new_context(struct mm_struct *mm) diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c index f2708c8629a5..8e8d5da7b482 100644 --- a/arch/powerpc/mm/book3s64/slb.c +++ b/arch/powerpc/mm/book3s64/slb.c @@ -328,94 +328,6 @@ static void preload_age(struct thread_info *ti) ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR; } -void slb_setup_new_exec(void) -{ - struct thread_info *ti = current_thread_info(); - struct mm_struct *mm = current->mm; - unsigned long exec = 0x10000000; - - WARN_ON(irqs_disabled()); - - /* - * preload cache can only be used to determine whether a SLB - * entry exists if it does not start to overflow. - */ - if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR) - return; - - hard_irq_disable(); - - /* - * We have no good place to clear the slb preload cache on exec, - * flush_thread is about the earliest arch hook but that happens - * after we switch to the mm and have already preloaded the SLBEs. - * - * For the most part that's probably okay to use entries from the - * previous exec, they will age out if unused. It may turn out to - * be an advantage to clear the cache before switching to it, - * however. - */ - - /* - * preload some userspace segments into the SLB. - * Almost all 32 and 64bit PowerPC executables are linked at - * 0x10000000 so it makes sense to preload this segment. - */ - if (!is_kernel_addr(exec)) { - if (preload_add(ti, exec)) - slb_allocate_user(mm, exec); - } - - /* Libraries and mmaps. */ - if (!is_kernel_addr(mm->mmap_base)) { - if (preload_add(ti, mm->mmap_base)) - slb_allocate_user(mm, mm->mmap_base); - } - - /* see switch_slb */ - asm volatile("isync" : : : "memory"); - - local_irq_enable(); -} - -void preload_new_slb_context(unsigned long start, unsigned long sp) -{ - struct thread_info *ti = current_thread_info(); - struct mm_struct *mm = current->mm; - unsigned long heap = mm->start_brk; - - WARN_ON(irqs_disabled()); - - /* see above */ - if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR) - return; - - hard_irq_disable(); - - /* Userspace entry address. */ - if (!is_kernel_addr(start)) { - if (preload_add(ti, start)) - slb_allocate_user(mm, start); - } - - /* Top of stack, grows down. */ - if (!is_kernel_addr(sp)) { - if (preload_add(ti, sp)) - slb_allocate_user(mm, sp); - } - - /* Bottom of heap, grows up. */ - if (heap && !is_kernel_addr(heap)) { - if (preload_add(ti, heap)) - slb_allocate_user(mm, heap); - } - - /* see switch_slb */ - asm volatile("isync" : : : "memory"); - - local_irq_enable(); -} - static void slb_cache_slbie_kernel(unsigned int index) { unsigned long slbie_data = get_paca()->slb_cache[index]; -- Gitee From 841c20432cf4d6cda882178b12471a484f96b0f6 Mon Sep 17 00:00:00 2001 From: Christian Hitz Date: Wed, 8 Oct 2025 20:32:21 +0800 Subject: [PATCH 0731/1449] leds: leds-lp50xx: Allow LED 0 to be added to module bank ANBZ: #35228 commit a406e6c74bd9ad967c05e30bd17f1ad40669ed0f stable. commit 26fe74d598c32e7bc6f150edfc4aa43e1bee55db upstream. led_banks contains LED module number(s) that should be grouped into the module bank. led_banks is 0-initialized. By checking the led_banks entries for 0, un-set entries are detected. But a 0-entry also indicates that LED module 0 should be grouped into the module bank. By only iterating over the available entries no check for unused entries is required and LED module 0 can be added to bank. Cc: stable@vger.kernel.org Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver") Signed-off-by: Christian Hitz Reviewed-by: Jacek Anaszewski Link: https://patch.msgid.link/20251008123222.1117331-1-christian@klarinett.li Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/leds/leds-lp50xx.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 182a590b0267..72371652f481 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -346,17 +346,15 @@ static int lp50xx_brightness_set(struct led_classdev *cdev, return ret; } -static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[]) +static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[], int num_leds) { u8 led_config_lo, led_config_hi; u32 bank_enable_mask = 0; int ret; int i; - for (i = 0; i < priv->chip_info->max_modules; i++) { - if (led_banks[i]) - bank_enable_mask |= (1 << led_banks[i]); - } + for (i = 0; i < num_leds; i++) + bank_enable_mask |= (1 << led_banks[i]); led_config_lo = bank_enable_mask; led_config_hi = bank_enable_mask >> 8; @@ -412,7 +410,7 @@ static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, return ret; } - ret = lp50xx_set_banks(priv, led_banks); + ret = lp50xx_set_banks(priv, led_banks, num_leds); if (ret) { dev_err(priv->dev, "Cannot setup banked LEDs\n"); return ret; -- Gitee From 06aaedfe83a45a4ab91797e1050446f9f8e7447c Mon Sep 17 00:00:00 2001 From: Christian Hitz Date: Wed, 22 Oct 2025 14:33:04 +0800 Subject: [PATCH 0732/1449] leds: leds-lp50xx: LP5009 supports 3 modules for a total of 9 LEDs ANBZ: #35228 commit cc468490d143025f33e41c9d9a2e770f7b3bf885 stable. commit 5246e3673eeeccb4f5bf4f42375dd495d465ac15 upstream. LP5009 supports 9 LED outputs that are grouped into 3 modules. Cc: stable@vger.kernel.org Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver") Signed-off-by: Christian Hitz Link: https://patch.msgid.link/20251022063305.972190-1-christian@klarinett.li Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/leds/leds-lp50xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 72371652f481..47f95b9242fb 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -56,7 +56,7 @@ /* There are 3 LED outputs per bank */ #define LP50XX_LEDS_PER_MODULE 3 -#define LP5009_MAX_LED_MODULES 2 +#define LP5009_MAX_LED_MODULES 3 #define LP5012_MAX_LED_MODULES 4 #define LP5018_MAX_LED_MODULES 6 #define LP5024_MAX_LED_MODULES 8 -- Gitee From d9b50a96e03d1e00f05ac2c61fe33391290f14b2 Mon Sep 17 00:00:00 2001 From: Christian Hitz Date: Tue, 28 Oct 2025 23:51:40 +0800 Subject: [PATCH 0733/1449] leds: leds-lp50xx: Enable chip before any communication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit ae80fb3d4e8cbc7ad8f26bcb663a25db8390b229 stable. commit 434959618c47efe9e5f2e20f4a850caac4f6b823 upstream. If a GPIO is used to control the chip's enable pin, it needs to be pulled high before any i2c communication is attempted. Currently, the enable GPIO handling is not correct. Assume the enable GPIO is low when the probe function is entered. In this case the device is in SHUTDOWN mode and does not react to i2c commands. During probe the following sequence happens: 1. The call to lp50xx_reset() on line 548 has no effect as i2c is not possible yet. 2. Then - on line 552 - lp50xx_enable_disable() is called. As "priv->enable_gpio“ has not yet been initialized, setting the GPIO has no effect. Also the i2c enable command is not executed as the device is still in SHUTDOWN. 3. On line 556 the call to lp50xx_probe_dt() finally parses the rest of the DT and the configured priv->enable_gpio is set up. As a result the device is still in SHUTDOWN mode and not ready for operation. Split lp50xx_enable_disable() into distinct enable and disable functions to enforce correct ordering between enable_gpio manipulations and i2c commands. Read enable_gpio configuration from DT before attempting to manipulate enable_gpio. Add delays to observe correct wait timing after manipulating enable_gpio and before any i2c communication. Cc: stable@vger.kernel.org Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver") Signed-off-by: Christian Hitz Link: https://patch.msgid.link/20251028155141.1603193-1-christian@klarinett.li Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/leds/leds-lp50xx.c | 55 +++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 47f95b9242fb..ba2978b5814b 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -52,6 +52,12 @@ #define LP50XX_SW_RESET 0xff #define LP50XX_CHIP_EN BIT(6) +#define LP50XX_CHIP_DISABLE 0x00 +#define LP50XX_START_TIME_US 500 +#define LP50XX_RESET_TIME_US 3 + +#define LP50XX_EN_GPIO_LOW 0 +#define LP50XX_EN_GPIO_HIGH 1 /* There are 3 LED outputs per bank */ #define LP50XX_LEDS_PER_MODULE 3 @@ -374,19 +380,42 @@ static int lp50xx_reset(struct lp50xx *priv) return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET); } -static int lp50xx_enable_disable(struct lp50xx *priv, int enable_disable) +static int lp50xx_enable(struct lp50xx *priv) { int ret; - ret = gpiod_direction_output(priv->enable_gpio, enable_disable); + if (priv->enable_gpio) { + ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_HIGH); + if (ret) + return ret; + + udelay(LP50XX_START_TIME_US); + } + + ret = lp50xx_reset(priv); if (ret) return ret; - if (enable_disable) - return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); - else - return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0); + return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); +} +static int lp50xx_disable(struct lp50xx *priv) +{ + int ret; + + ret = regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_DISABLE); + if (ret) + return ret; + + if (priv->enable_gpio) { + ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_LOW); + if (ret) + return ret; + + udelay(LP50XX_RESET_TIME_US); + } + + return 0; } static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, @@ -453,6 +482,10 @@ static int lp50xx_probe_dt(struct lp50xx *priv) return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio), "Failed to get enable GPIO\n"); + ret = lp50xx_enable(priv); + if (ret) + return ret; + priv->regulator = devm_regulator_get(priv->dev, "vled"); if (IS_ERR(priv->regulator)) priv->regulator = NULL; @@ -559,14 +592,6 @@ static int lp50xx_probe(struct i2c_client *client) return ret; } - ret = lp50xx_reset(led); - if (ret) - return ret; - - ret = lp50xx_enable_disable(led, 1); - if (ret) - return ret; - return lp50xx_probe_dt(led); } @@ -575,7 +600,7 @@ static void lp50xx_remove(struct i2c_client *client) struct lp50xx *led = i2c_get_clientdata(client); int ret; - ret = lp50xx_enable_disable(led, 0); + ret = lp50xx_disable(led); if (ret) dev_err(led->dev, "Failed to disable chip\n"); -- Gitee From 53c77dfbd6cf779ab2177ac648604f5d4c065bb1 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 25 Nov 2025 03:11:06 +0800 Subject: [PATCH 0734/1449] clk: samsung: exynos-clkout: Assign .num before accessing .hws ANBZ: #35228 commit fbf57f5e453dadadb3d29b2d1dbe067e3dc4e236 stable. commit cf33f0b7df13685234ccea7be7bfe316b60db4db upstream. Commit f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by") annotated the hws member of 'struct clk_hw_onecell_data' with __counted_by, which informs the bounds sanitizer (UBSAN_BOUNDS) about the number of elements in .hws[], so that it can warn when .hws[] is accessed out of bounds. As noted in that change, the __counted_by member must be initialized with the number of elements before the first array access happens, otherwise there will be a warning from each access prior to the initialization because the number of elements is zero. This occurs in exynos_clkout_probe() due to .num being assigned after .hws[] has been accessed: UBSAN: array-index-out-of-bounds in drivers/clk/samsung/clk-exynos-clkout.c:178:18 index 0 is out of range for type 'clk_hw *[*]' Move the .num initialization to before the first access of .hws[], clearing up the warning. Cc: stable@vger.kernel.org Fixes: f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by") Reported-by: Jochen Sprickerhof Closes: https://lore.kernel.org/aSIYDN5eyKFKoXKL@eldamar.lan/ Tested-by: Jochen Sprickerhof Signed-off-by: Nathan Chancellor Reviewed-by: Kees Cook Reviewed-by: Sam Protsenko Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clk/samsung/clk-exynos-clkout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c index 72b6cf83aff4..3c09e9a4b25b 100644 --- a/drivers/clk/samsung/clk-exynos-clkout.c +++ b/drivers/clk/samsung/clk-exynos-clkout.c @@ -168,6 +168,7 @@ static int exynos_clkout_probe(struct platform_device *pdev) clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; clkout->mux.lock = &clkout->slock; + clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout", parent_names, parent_count, &clkout->mux.hw, &clk_mux_ops, NULL, NULL, &clkout->gate.hw, @@ -178,7 +179,6 @@ static int exynos_clkout_probe(struct platform_device *pdev) goto err_unmap; } - clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data); if (ret) goto err_clk_unreg; -- Gitee From 1c8d1809af2d71cc8d8ff9fe13bfe746a94d51c2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 25 Sep 2025 23:02:19 +0800 Subject: [PATCH 0735/1449] mfd: altera-sysmgr: Fix device leak on sysmgr regmap lookup ANBZ: #35228 commit 1b630d8f2c27b87e82ef4f0baacbc27294610922 stable. commit ccb7cd3218e48665f3c7e19eede0da5f069c323d upstream. Make sure to drop the reference taken to the sysmgr platform device when retrieving its driver data. Note that holding a reference to a device does not prevent its driver data from going away. Fixes: f36e789a1f8d ("mfd: altera-sysmgr: Add SOCFPGA System Manager") Cc: stable@vger.kernel.org # 5.2 Signed-off-by: Johan Hovold Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mfd/altera-sysmgr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c index fb5f988e61f3..90c6902d537d 100644 --- a/drivers/mfd/altera-sysmgr.c +++ b/drivers/mfd/altera-sysmgr.c @@ -117,6 +117,8 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np, sysmgr = dev_get_drvdata(dev); + put_device(dev); + return sysmgr->regmap; } EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle); -- Gitee From 13c09bca648a6c4fdcfab6deb9f6229fe78cf899 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 23 Oct 2025 18:19:40 +0800 Subject: [PATCH 0736/1449] mfd: max77620: Fix potential IRQ chip conflict when probing two devices ANBZ: #35228 commit 52bae1ff6805faa83ff95c6b3d0ed13ae6cb69a0 stable. commit 2bac49bad1f3553cc3b3bfb22cc194e9bd9e8427 upstream. MAX77620 is most likely always a single device on the board, however nothing stops board designers to have two of them, thus same device driver could probe twice. Or user could manually try to probing second time. Device driver is not ready for that case, because it allocates statically 'struct regmap_irq_chip' as non-const and stores during probe in 'irq_drv_data' member a pointer to per-probe state container ('struct max77620_chip'). devm_regmap_add_irq_chip() does not make a copy of 'struct regmap_irq_chip' but store the pointer. Second probe - either successful or failure - would overwrite the 'irq_drv_data' from previous device probe, so interrupts would be executed in a wrong context. Cc: stable@vger.kernel.org Fixes: 3df140d11c6d ("mfd: max77620: Mask/unmask interrupt before/after servicing it") Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251023101939.67991-2-krzysztof.kozlowski@linaro.org Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mfd/max77620.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c index e63e8e47d908..9c85fc8197b5 100644 --- a/drivers/mfd/max77620.c +++ b/drivers/mfd/max77620.c @@ -253,7 +253,7 @@ static int max77620_irq_global_unmask(void *irq_drv_data) return ret; } -static struct regmap_irq_chip max77620_top_irq_chip = { +static const struct regmap_irq_chip max77620_top_irq_chip = { .name = "max77620-top", .irqs = max77620_top_irqs, .num_irqs = ARRAY_SIZE(max77620_top_irqs), @@ -498,6 +498,7 @@ static int max77620_probe(struct i2c_client *client) const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct regmap_config *rmap_config; struct max77620_chip *chip; + struct regmap_irq_chip *chip_desc; const struct mfd_cell *mfd_cells; int n_mfd_cells; bool pm_off; @@ -508,6 +509,14 @@ static int max77620_probe(struct i2c_client *client) return -ENOMEM; i2c_set_clientdata(client, chip); + + chip_desc = devm_kmemdup(&client->dev, &max77620_top_irq_chip, + sizeof(max77620_top_irq_chip), + GFP_KERNEL); + if (!chip_desc) + return -ENOMEM; + chip_desc->irq_drv_data = chip; + chip->dev = &client->dev; chip->chip_irq = client->irq; chip->chip_id = (enum max77620_chip_id)id->driver_data; @@ -544,11 +553,9 @@ static int max77620_probe(struct i2c_client *client) if (ret < 0) return ret; - max77620_top_irq_chip.irq_drv_data = chip; ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq, IRQF_ONESHOT | IRQF_SHARED, 0, - &max77620_top_irq_chip, - &chip->top_irq_data); + chip_desc, &chip->top_irq_data); if (ret < 0) { dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret); return ret; -- Gitee From a1273c42e0a00e2b514cc42f3519a81b51b451ee Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Fri, 31 Oct 2025 14:03:32 +0800 Subject: [PATCH 0737/1449] media: rc: st_rc: Fix reset control resource leak ANBZ: #35228 commit 13cf5cd4d53585d15b330b961bc37e8426b6ec40 stable. commit 1240abf4b71f632f0117b056e22488e4d9808938 upstream. The driver calls reset_control_get_optional_exclusive() but never calls reset_control_put() in error paths or in the remove function. This causes a resource leak when probe fails after successfully acquiring the reset control, or when the driver is unloaded. Switch to devm_reset_control_get_optional_exclusive() to automatically manage the reset control resource. Fixes: a4b80242d046 ("media: st-rc: explicitly request exclusive reset control") Cc: stable@vger.kernel.org Signed-off-by: Haotian Zhang Reviewed-by: Patrice Chotard Signed-off-by: Sean Young Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/rc/st_rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 28477aa95563..8a9f31e15b0c 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -283,7 +283,7 @@ static int st_rc_probe(struct platform_device *pdev) else rc_dev->rx_base = rc_dev->base; - rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL); + rc_dev->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(rc_dev->rstc)) { ret = PTR_ERR(rc_dev->rstc); goto err; -- Gitee From 342fb6ac8f12503457d96a3a728c967f008808be Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 30 Oct 2025 15:56:05 +0800 Subject: [PATCH 0738/1449] parisc: entry.S: fix space adjustment on interruption for 64-bit userspace ANBZ: #35228 commit d3842cbf13b7ef4072a330c1276db02dadbf4cca stable. commit 1aa4524c0c1b54842c4c0a370171d11b12d0709b upstream. In wide mode, the IASQ contain the upper part of the GVA during interruption. This needs to be reversed before the space is used - otherwise it contains parts of IAOQ. See Page 2-13 "Processing Resources / Interruption Instruction Address Queues" in the Parisc 2.0 Architecture Manual page 2-13 for an explanation. The IAOQ/IASQ space_adjust was skipped for other interruptions than itlb misses. However, the code in handle_interruption() checks whether iasq[0] contains a valid space. Due to the not masked out bits this match failed and the process was killed. Also add space_adjust for IAOQ1/IASQ1 so ptregs contains sane values. Signed-off-by: Sven Schnelle Cc: stable@vger.kernel.org # v6.0+ Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/parisc/kernel/entry.S | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index f4bf61a34701..bb383487e302 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1059,8 +1059,6 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ STREG %r17, PT_IOR(%r29) #if defined(CONFIG_64BIT) - b,n intr_save2 - skip_save_ior: /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we * need to adjust iasq/iaoq here in the same way we adjusted isr/ior @@ -1069,10 +1067,17 @@ skip_save_ior: bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 - /* adjust iasq/iaoq */ + /* adjust iasq0/iaoq0 */ space_adjust %r16,%r17,%r1 STREG %r16, PT_IASQ0(%r29) STREG %r17, PT_IAOQ0(%r29) + + LDREG PT_IASQ1(%r29), %r16 + LDREG PT_IAOQ1(%r29), %r17 + /* adjust iasq1/iaoq1 */ + space_adjust %r16,%r17,%r1 + STREG %r16, PT_IASQ1(%r29) + STREG %r17, PT_IAOQ1(%r29) #else skip_save_ior: #endif -- Gitee From 820441ffb1a2579134fc94d902a854dc92170407 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 16 Oct 2025 05:21:41 +0800 Subject: [PATCH 0739/1449] parisc: entry: set W bit for !compat tasks in syscall_restore_rfi() ANBZ: #35228 commit 40feb7bcde49a60d34f22f2532b5b535e24a76d2 stable. commit 5fb1d3ce3e74a4530042795e1e065422295f1371 upstream. When the kernel leaves to userspace via syscall_restore_rfi(), the W bit is not set in the new PSW. This doesn't cause any problems because there's no 64 bit userspace for parisc. Simple static binaries are usually loaded at addresses way below the 32 bit limit so the W bit doesn't matter. Fix this by setting the W bit when TIF_32BIT is not set. Signed-off-by: Sven Schnelle Cc: stable@vger.kernel.org Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/parisc/kernel/asm-offsets.c | 2 ++ arch/parisc/kernel/entry.S | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index 9abfe65492c6..3de4b5933b10 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -258,6 +258,8 @@ int main(void) BLANK(); DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP); DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP); + DEFINE(TIF_32BIT_PA_BIT, 31-TIF_32BIT); + BLANK(); DEFINE(ASM_PMD_SHIFT, PMD_SHIFT); DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT); diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index bb383487e302..e04c5d806c10 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1846,6 +1846,10 @@ syscall_restore_rfi: extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0 depi -1,7,1,%r20 /* T bit */ +#ifdef CONFIG_64BIT + extru,<> %r19,TIF_32BIT_PA_BIT,1,%r0 + depi -1,4,1,%r20 /* W bit */ +#endif STREG %r20,TASK_PT_PSW(%r1) /* Always store space registers, since sr3 can be changed (e.g. fork) */ @@ -1859,7 +1863,6 @@ syscall_restore_rfi: STREG %r25,TASK_PT_IASQ0(%r1) STREG %r25,TASK_PT_IASQ1(%r1) - /* XXX W bit??? */ /* Now if old D bit is clear, it means we didn't save all registers * on syscall entry, so do that now. This only happens on TRACEME * calls, or if someone attached to us while we were on a syscall. -- Gitee From 81d9af211bdbf5b27ee9c1e5fdf1ee367e6be8e4 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 21 Oct 2025 18:06:05 +0800 Subject: [PATCH 0740/1449] powerpc/pseries/cmm: call balloon_devinfo_init() also without CONFIG_BALLOON_COMPACTION ANBZ: #35228 commit 318d470f64bacd1bb20eecb5b26118d850c5a09e stable. commit fc6bcf9ac4de76f5e7bcd020b3c0a86faff3f2d5 upstream. Patch series "powerpc/pseries/cmm: two smaller fixes". Two smaller fixes identified while doing a bigger rework. This patch (of 2): We always have to initialize the balloon_dev_info, even when compaction is not configured in: otherwise the containing list and the lock are left uninitialized. Likely not many such configs exist in practice, but let's CC stable to be sure. This was found by code inspection. Link: https://lkml.kernel.org/r/20251021100606.148294-1-david@redhat.com Link: https://lkml.kernel.org/r/20251021100606.148294-2-david@redhat.com Fixes: fe030c9b85e6 ("powerpc/pseries/cmm: Implement balloon compaction") Signed-off-by: David Hildenbrand Reviewed-by: Ritesh Harjani (IBM) Cc: Christophe Leroy Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/platforms/pseries/cmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index 5f4037c1d7fe..1065f08cdcb9 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -550,7 +550,6 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info, static void cmm_balloon_compaction_init(void) { - balloon_devinfo_init(&b_dev_info); b_dev_info.migratepage = cmm_migratepage; } #else /* CONFIG_BALLOON_COMPACTION */ @@ -572,6 +571,7 @@ static int cmm_init(void) if (!firmware_has_feature(FW_FEATURE_CMO) && !simulate) return -EOPNOTSUPP; + balloon_devinfo_init(&b_dev_info); cmm_balloon_compaction_init(); rc = register_oom_notifier(&cmm_oom_nb); -- Gitee From ba1142d561437ac9cd19d1809be85f96e829513c Mon Sep 17 00:00:00 2001 From: Ivan Abramov Date: Wed, 3 Sep 2025 07:23:31 +0800 Subject: [PATCH 0741/1449] media: adv7842: Avoid possible out-of-bounds array accesses in adv7842_cp_log_status() ANBZ: #35228 commit a73881ae085db5702d8b13e2fc9f78d51c723d3f stable. commit 8163419e3e05d71dcfa8fb49c8fdf8d76908fe51 upstream. It's possible for cp_read() and hdmi_read() to return -EIO. Those values are further used as indexes for accessing arrays. Fix that by checking return values where it's needed. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: a89bcd4c6c20 ("[media] adv7842: add new video decoder driver") Cc: stable@vger.kernel.org Signed-off-by: Ivan Abramov Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/i2c/adv7842.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index cb90178ce4b1..cbda7dc54148 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -2680,6 +2680,7 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd) /* CP block */ struct adv7842_state *state = to_state(sd); struct v4l2_dv_timings timings; + int temp; u8 reg_io_0x02 = io_read(sd, 0x02); u8 reg_io_0x21 = io_read(sd, 0x21); u8 reg_rep_0x77 = rep_read(sd, 0x77); @@ -2802,8 +2803,9 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd) (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? "(16-235)" : "(0-255)", (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); + temp = cp_read(sd, 0xf4) >> 4; v4l2_info(sd, "Color space conversion: %s\n", - csc_coeff_sel_rb[cp_read(sd, 0xf4) >> 4]); + temp < 0 ? "" : csc_coeff_sel_rb[temp]); if (!is_digital_input(sd)) return 0; @@ -2833,8 +2835,9 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd) hdmi_read(sd, 0x5f)); v4l2_info(sd, "AV Mute: %s\n", (hdmi_read(sd, 0x04) & 0x40) ? "on" : "off"); + temp = hdmi_read(sd, 0x0b) >> 6; v4l2_info(sd, "Deep color mode: %s\n", - deep_color_mode_txt[hdmi_read(sd, 0x0b) >> 6]); + temp < 0 ? "" : deep_color_mode_txt[temp]); adv7842_log_infoframes(sd); -- Gitee From 84dc5158d0406414784564cde498c3e8bf79269f Mon Sep 17 00:00:00 2001 From: Mahesh Rao Date: Mon, 27 Oct 2025 22:54:40 +0800 Subject: [PATCH 0742/1449] firmware: stratix10-svc: Add mutex in stratix10 memory management ANBZ: #35228 commit 4654800c51be83850855b5b62018fb09a35fa6e8 stable. commit 85f96cbbbc67b59652b2c1ec394b8ddc0ddf1b0b upstream. Add mutex lock to stratix10_svc_allocate_memory and stratix10_svc_free_memory for thread safety. This prevents race conditions and ensures proper synchronization during memory operations. This is required for parallel communication with the Stratix10 service channel. Fixes: 7ca5ce896524f ("firmware: add Intel Stratix10 service layer driver") Cc: stable@vger.kernel.org Signed-off-by: Mahesh Rao Reviewed-by: Matthew Gerlach Signed-off-by: Dinh Nguyen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/stratix10-svc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index a133ac5fb037..2f263d1a6bd1 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2017-2018, Intel Corporation + * Copyright (C) 2025, Altera Corporation */ #include @@ -175,6 +176,12 @@ struct stratix10_svc_chan { static LIST_HEAD(svc_ctrl); static LIST_HEAD(svc_data_mem); +/** + * svc_mem_lock protects access to the svc_data_mem list for + * concurrent multi-client operations + */ +static DEFINE_MUTEX(svc_mem_lock); + /** * svc_pa_to_va() - translate physical address to virtual address * @addr: to be translated physical address @@ -187,6 +194,7 @@ static void *svc_pa_to_va(unsigned long addr) struct stratix10_svc_data_mem *pmem; pr_debug("claim back P-addr=0x%016x\n", (unsigned int)addr); + guard(mutex)(&svc_mem_lock); list_for_each_entry(pmem, &svc_data_mem, node) if (pmem->paddr == addr) return pmem->vaddr; @@ -996,6 +1004,7 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg) p_data->flag = ct->flags; } } else { + guard(mutex)(&svc_mem_lock); list_for_each_entry(p_mem, &svc_data_mem, node) if (p_mem->vaddr == p_msg->payload) { p_data->paddr = p_mem->paddr; @@ -1078,6 +1087,7 @@ void *stratix10_svc_allocate_memory(struct stratix10_svc_chan *chan, if (!pmem) return ERR_PTR(-ENOMEM); + guard(mutex)(&svc_mem_lock); va = gen_pool_alloc(genpool, s); if (!va) return ERR_PTR(-ENOMEM); @@ -1106,6 +1116,7 @@ EXPORT_SYMBOL_GPL(stratix10_svc_allocate_memory); void stratix10_svc_free_memory(struct stratix10_svc_chan *chan, void *kaddr) { struct stratix10_svc_data_mem *pmem; + guard(mutex)(&svc_mem_lock); list_for_each_entry(pmem, &svc_data_mem, node) if (pmem->vaddr == kaddr) { -- Gitee From 86f3cd6bee351c970c26ae4747e264e154ea1941 Mon Sep 17 00:00:00 2001 From: "Uladzislau Rezki (Sony)" Date: Mon, 17 Nov 2025 18:59:45 +0800 Subject: [PATCH 0743/1449] dm-ebs: Mark full buffer dirty even on partial write ANBZ: #35228 commit 34f6abd6e4c43579e2acbb72ef2105a6a02a1dfa stable. commit 7fa3e7d114abc9cc71cc35d768e116641074ddb4 upstream. When performing a read-modify-write(RMW) operation, any modification to a buffered block must cause the entire buffer to be marked dirty. Marking only a subrange as dirty is incorrect because the underlying device block size(ubs) defines the minimum read/write granularity. A lower device can perform I/O only on regions which are fully aligned and sized to ubs. This change ensures that write-back operations always occur in full ubs-sized chunks, matching the intended emulation semantics of the EBS target. As for user space visible impact, submitting sub-ubs and misaligned I/O for devices which are tuned to ubs sizes only, will reject such requests, therefore it can lead to losing data. Example: 1) Create a 8K nvme device in qemu by adding -device nvme,drive=drv0,serial=foo,logical_block_size=8192,physical_block_size=8192 2) Setup dm-ebs to emulate 512B to 8K mapping urezki@pc638:~/bin$ cat dmsetup.sh lower=/dev/nvme0n1 len=$(blockdev --getsz "$lower") echo "0 $len ebs $lower 0 1 16" | dmsetup create nvme-8k urezki@pc638:~/bin$ offset 0, ebs=1 and ubs=16(in sectors). 3) Create an ext4 filesystem(default 4K block size) urezki@pc638:~/bin$ sudo mkfs.ext4 -F /dev/dm-0 mke2fs 1.47.0 (5-Feb-2023) Discarding device blocks: done Creating filesystem with 2072576 4k blocks and 518144 inodes Filesystem UUID: bd0b6ca6-0506-4e31-86da-8d22c9d50b63 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: mkfs.ext4: Input/output error while writing out and closing file system urezki@pc638:~/bin$ dmesg [ 1618.875449] buffer_io_error: 1028 callbacks suppressed [ 1618.875456] Buffer I/O error on dev dm-0, logical block 0, lost async page write [ 1618.875527] Buffer I/O error on dev dm-0, logical block 1, lost async page write [ 1618.875602] Buffer I/O error on dev dm-0, logical block 2, lost async page write [ 1618.875620] Buffer I/O error on dev dm-0, logical block 3, lost async page write [ 1618.875639] Buffer I/O error on dev dm-0, logical block 4, lost async page write [ 1618.894316] Buffer I/O error on dev dm-0, logical block 5, lost async page write [ 1618.894358] Buffer I/O error on dev dm-0, logical block 6, lost async page write [ 1618.894380] Buffer I/O error on dev dm-0, logical block 7, lost async page write [ 1618.894405] Buffer I/O error on dev dm-0, logical block 8, lost async page write [ 1618.894427] Buffer I/O error on dev dm-0, logical block 9, lost async page write Many I/O errors because the lower 8K device rejects sub-ubs/misaligned requests. with a patch: urezki@pc638:~/bin$ sudo mkfs.ext4 -F /dev/dm-0 mke2fs 1.47.0 (5-Feb-2023) Discarding device blocks: done Creating filesystem with 2072576 4k blocks and 518144 inodes Filesystem UUID: 9b54f44f-ef55-4bd4-9e40-c8b775a616ac Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done urezki@pc638:~/bin$ sudo mount /dev/dm-0 /mnt/ urezki@pc638:~/bin$ ls -al /mnt/ total 24 drwxr-xr-x 3 root root 4096 Oct 17 15:13 . drwxr-xr-x 19 root root 4096 Jul 10 19:42 .. drwx------ 2 root root 16384 Oct 17 15:13 lost+found urezki@pc638:~/bin$ After this change: mkfs completes; mount succeeds. Signed-off-by: Uladzislau Rezki (Sony) Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/dm-ebs-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c index aead2215d780..45b8d314ef0d 100644 --- a/drivers/md/dm-ebs-target.c +++ b/drivers/md/dm-ebs-target.c @@ -103,7 +103,7 @@ static int __ebs_rw_bvec(struct ebs_c *ec, enum req_op op, struct bio_vec *bv, } else { flush_dcache_page(bv->bv_page); memcpy(ba, pa, cur_len); - dm_bufio_mark_partial_buffer_dirty(b, buf_off, buf_off + cur_len); + dm_bufio_mark_buffer_dirty(b); } dm_bufio_release(b); -- Gitee From abaa6ad4b6dbb02a63e47caebb7fd79aecfb2864 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 20 Oct 2025 20:48:13 +0800 Subject: [PATCH 0744/1449] dm-bufio: align write boundary on physical block size ANBZ: #35228 commit 2b0b703a3483baad5e033cb4c3f0c266cb14d2f4 stable. commit d0ac06ae53be0cdb61f5fe6b62d25d3317c51657 upstream. There may be devices with physical block size larger than 4k. If dm-bufio sends I/O that is not aligned on physical block size, performance is degraded. The 4k minimum alignment limit is there because some SSDs report logical and physical block size 512 despite having 4k internally - so dm-bufio shouldn't send I/Os not aligned on 4k boundary, because they perform badly (the SSD does read-modify-write for them). Signed-off-by: Mikulas Patocka Reported-by: Uladzislau Rezki (Sony) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/dm-bufio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 1f124ca180c6..ded85d8d4c9e 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -1375,7 +1375,7 @@ static void submit_io(struct dm_buffer *b, enum req_op op, { unsigned int n_sectors; sector_t sector; - unsigned int offset, end; + unsigned int offset, end, align; b->end_io = end_io; @@ -1389,9 +1389,11 @@ static void submit_io(struct dm_buffer *b, enum req_op op, b->c->write_callback(b); offset = b->write_start; end = b->write_end; - offset &= -DM_BUFIO_WRITE_ALIGN; - end += DM_BUFIO_WRITE_ALIGN - 1; - end &= -DM_BUFIO_WRITE_ALIGN; + align = max(DM_BUFIO_WRITE_ALIGN, + bdev_physical_block_size(b->c->bdev)); + offset &= -align; + end += align - 1; + end &= -align; if (unlikely(end > b->c->block_size)) end = b->c->block_size; -- Gitee From 04b9889919bbe52d7ee58bc87eadb48fc17e0cf4 Mon Sep 17 00:00:00 2001 From: Rene Rebe Date: Fri, 14 Nov 2025 23:00:42 +0800 Subject: [PATCH 0745/1449] fbdev: gbefb: fix to use physical address instead of dma address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 243b674b2b52c3fe48e407ec790f823587b5eb9e stable. commit e3f44742bbb10537fe53d83d20dea2a7c167674d upstream. While debuggigng why X would not start on mips64 Sgi/O2 I found the phys adress being off. Turns out the gbefb passed the internal dma_addr as phys. May be broken pre git history. Fix by converting dma_to_phys. Signed-off-by: René Rebe Cc: # v4.0+ Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/fbdev/gbefb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c index 4fccdccbc364..8db63a3cd5e0 100644 --- a/drivers/video/fbdev/gbefb.c +++ b/drivers/video/fbdev/gbefb.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,7 @@ struct gbefb_par { static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024; static void *gbe_mem; static dma_addr_t gbe_dma_addr; -static unsigned long gbe_mem_phys; +static phys_addr_t gbe_mem_phys; static struct { uint16_t *cpu; @@ -1182,7 +1183,7 @@ static int gbefb_probe(struct platform_device *p_dev) goto out_release_mem_region; } - gbe_mem_phys = (unsigned long) gbe_dma_addr; + gbe_mem_phys = dma_to_phys(&p_dev->dev, gbe_dma_addr); } par = info->par; -- Gitee From 5c0680ef96a4e4f46da5c3b8aa68767c2e95bf26 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Wed, 3 Dec 2025 02:15:32 +0800 Subject: [PATCH 0746/1449] fbdev: pxafb: Fix multiple clamped values in pxafb_adjust_timing ANBZ: #35228 commit cce58e4cc535d199ad0e509bd8c29453910958c7 stable. commit 0155e868cbc111846cc2809c1546ea53810a56ae upstream. The variables were never clamped because the return value of clamp_val() was not used. Fix this by assigning the clamped values, and use clamp() instead of clamp_val(). Cc: stable@vger.kernel.org Fixes: 3f16ff608a75 ("[ARM] pxafb: cleanup of the timing checking code") Signed-off-by: Thorsten Blum Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/fbdev/pxafb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c index 3a2427eb29f2..6cb685c84d3c 100644 --- a/drivers/video/fbdev/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -418,12 +418,12 @@ static int pxafb_adjust_timing(struct pxafb_info *fbi, var->yres = max_t(int, var->yres, MIN_YRES); if (!(fbi->lccr0 & LCCR0_LCDT)) { - clamp_val(var->hsync_len, 1, 64); - clamp_val(var->vsync_len, 1, 64); - clamp_val(var->left_margin, 1, 255); - clamp_val(var->right_margin, 1, 255); - clamp_val(var->upper_margin, 1, 255); - clamp_val(var->lower_margin, 1, 255); + var->hsync_len = clamp(var->hsync_len, 1, 64); + var->vsync_len = clamp(var->vsync_len, 1, 64); + var->left_margin = clamp(var->left_margin, 1, 255); + var->right_margin = clamp(var->right_margin, 1, 255); + var->upper_margin = clamp(var->upper_margin, 1, 255); + var->lower_margin = clamp(var->lower_margin, 1, 255); } /* make sure each line is aligned on word boundary */ -- Gitee From a0b256ccaf14dfdd54ba01f2797e2ef42033239d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Thu, 20 Nov 2025 21:24:00 +0800 Subject: [PATCH 0747/1449] fbdev: tcx.c fix mem_map to correct smem_start offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 6b5dd195993bc92ba7267e123a86adf59fdf19c3 stable. commit 35fa2b4bf96415b88d7edaa5cf8af5185d9ce76e upstream. 403ae52ac047 ("sparc: fix drivers/video/tcx.c warning") changed the physbase initializing breaking the user-space mmap, e.g. for Xorg entirely. Fix fbdev mmap table so the sbus mmap helper work correctly, and not try to map vastly (physbase) offset memory. Fixes: 403ae52ac047 ("sparc: fix drivers/video/tcx.c warning") Cc: Signed-off-by: René Rebe Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/fbdev/tcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/tcx.c b/drivers/video/fbdev/tcx.c index 7fb8179a8f41..c39fea2c3210 100644 --- a/drivers/video/fbdev/tcx.c +++ b/drivers/video/fbdev/tcx.c @@ -436,7 +436,7 @@ static int tcx_probe(struct platform_device *op) j = i; break; } - par->mmap_map[i].poff = op->resource[j].start; + par->mmap_map[i].poff = op->resource[j].start - info->fix.smem_start; } info->fbops = &tcx_ops; -- Gitee From 554fe3f71b75c3f151b6a578e2013a1e2c9ed0dd Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 29 Sep 2025 19:12:29 +0800 Subject: [PATCH 0748/1449] media: cec: Fix debugfs leak on bus_register() failure ANBZ: #35228 commit 4972ad7eec914f02361f8327940dff258969e1ea stable. commit c43bcd2b2aa3c2ca9d2433c3990ecbc2c47d10eb upstream. In cec_devnode_init(), the debugfs directory created with debugfs_create_dir() is not removed if bus_register() fails. This leaves a stale "cec" entry in debugfs and prevents proper module reloading. Fix this by removing the debugfs directory in the error path. Fixes: a56960e8b406 ("[media] cec: add HDMI CEC framework (core)") Cc: stable@vger.kernel.org Signed-off-by: Haotian Zhang Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/cec/core/cec-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 7e153c5cad04..b4dcc352a3c6 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -449,6 +449,7 @@ static int __init cec_devnode_init(void) ret = bus_register(&cec_bus_type); if (ret < 0) { + debugfs_remove_recursive(top_cec_dir); unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES); pr_warn("cec: bus_register failed\n"); return -EIO; -- Gitee From ab2c0c6ecae215c8e16969c88cdf3ed90aa04cab Mon Sep 17 00:00:00 2001 From: Ivan Abramov Date: Wed, 3 Sep 2025 07:28:14 +0800 Subject: [PATCH 0749/1449] media: msp3400: Avoid possible out-of-bounds array accesses in msp3400c_thread() ANBZ: #35228 commit 3a294b90cd1ab3fbf9226bf936af59e24475caee stable. commit d2bceb2e20e783d57e739c71e4e50b4b9f4a3953 upstream. It's possible for max1 to remain -1 if msp_read() always fail. This variable is further used as index for accessing arrays. Fix that by checking max1 prior to array accesses. It seems that restart is the preferable action in case of out-of-bounds value. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 8a4b275f9c19 ("V4L/DVB (3427): audmode and rxsubchans fixes (VIDIOC_G/S_TUNER)") Cc: stable@vger.kernel.org Signed-off-by: Ivan Abramov Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/i2c/msp3400-kthreads.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/i2c/msp3400-kthreads.c b/drivers/media/i2c/msp3400-kthreads.c index ecabc0e1d32e..1d9f41dd7c21 100644 --- a/drivers/media/i2c/msp3400-kthreads.c +++ b/drivers/media/i2c/msp3400-kthreads.c @@ -596,6 +596,8 @@ int msp3400c_thread(void *data) "carrier2 val: %5d / %s\n", val, cd[i].name); } + if (max1 < 0 || max1 > 3) + goto restart; /* program the msp3400 according to the results */ state->main = msp3400c_carrier_detect_main[max1].cdo; switch (max1) { -- Gitee From 867e5882759cb75b4ede5f6fe04460a639c6ebc8 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 3 Sep 2025 21:37:29 +0800 Subject: [PATCH 0750/1449] media: renesas: rcar_drif: fix device node reference leak in rcar_drif_bond_enabled ANBZ: #35228 commit 4d8da22db9355e914fa93e27751b5ab24e478fce stable. commit 445e1658894fd74eab7e53071fa16233887574ed upstream. The function calls of_parse_phandle() which returns a device node with an incremented reference count. When the bonded device is not available, the function returns NULL without releasing the reference, causing a reference leak. Add of_node_put(np) to release the device node reference. The of_node_put function handles NULL pointers. Found through static analysis by reviewing the doc of of_parse_phandle() and cross-checking its usage patterns across the codebase. Fixes: 7625ee981af1 ("[media] media: platform: rcar_drif: Add DRIF support") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Reviewed-by: Geert Uytterhoeven Reviewed-by: Fabrizio Castro Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/renesas/rcar_drif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/renesas/rcar_drif.c b/drivers/media/platform/renesas/rcar_drif.c index 163a4ba61c17..bf5721f70611 100644 --- a/drivers/media/platform/renesas/rcar_drif.c +++ b/drivers/media/platform/renesas/rcar_drif.c @@ -1249,6 +1249,7 @@ static struct device_node *rcar_drif_bond_enabled(struct platform_device *p) if (np && of_device_is_available(np)) return np; + of_node_put(np); return NULL; } -- Gitee From 6a761b0137017bbfdfcae715f2d35896d8e5bee4 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 14 Oct 2025 18:46:43 +0800 Subject: [PATCH 0751/1449] media: samsung: exynos4-is: fix potential ABBA deadlock on init ANBZ: #35228 commit 1b560207855771693c296cf4c58c7ef46836743e stable. commit 17dc8ccd6dd5ffe30aa9b0d36e2af1389344ce2b upstream. v4l2_device_register_subdev_nodes() must called without taking media_dev->graph_mutex to avoid potential AB-BA deadlock on further subdevice driver initialization. Fixes: fa91f1056f17 ("[media] exynos4-is: Add support for asynchronous subdevices registration") Cc: stable@vger.kernel.org Signed-off-by: Marek Szyprowski Acked-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/samsung/exynos4-is/media-dev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.c b/drivers/media/platform/samsung/exynos4-is/media-dev.c index 5f10bb4eb4f7..83f0fa078089 100644 --- a/drivers/media/platform/samsung/exynos4-is/media-dev.c +++ b/drivers/media/platform/samsung/exynos4-is/media-dev.c @@ -1410,12 +1410,14 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier) mutex_lock(&fmd->media_dev.graph_mutex); ret = fimc_md_create_links(fmd); - if (ret < 0) - goto unlock; + if (ret < 0) { + mutex_unlock(&fmd->media_dev.graph_mutex); + return ret; + } - ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); -unlock: mutex_unlock(&fmd->media_dev.graph_mutex); + + ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); if (ret < 0) return ret; -- Gitee From 7bb4513426210d22ddb799b51bc9fd4b86a0a2b8 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Mon, 1 Sep 2025 21:26:17 +0800 Subject: [PATCH 0752/1449] media: TDA1997x: Remove redundant cancel_delayed_work in probe ANBZ: #35228 commit b93abb4385b8f3ed34487ca0060d9bc32b4af1e1 stable. commit 29de195ca39fc2ac0af6fd45522994df9f431f80 upstream. The delayed_work delayed_work_enable_hpd is initialized with INIT_DELAYED_WORK(), but it is never scheduled in tda1997x_probe(). Calling cancel_delayed_work() on a work that has never been scheduled is redundant and unnecessary, as there is no pending work to cancel. Remove the redundant cancel_delayed_work() from error handling path in tda1997x_probe() to avoid potential confusion. Fixes: 9ac0038db9a7 ("media: i2c: Add TDA1997x HDMI receiver driver") Cc: stable@vger.kernel.org Signed-off-by: Duoming Zhou Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/i2c/tda1997x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 325e99125941..a6c8b52c3baf 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2794,7 +2794,6 @@ static int tda1997x_probe(struct i2c_client *client) err_free_handler: v4l2_ctrl_handler_free(&state->hdl); err_free_mutex: - cancel_delayed_work(&state->delayed_work_enable_hpd); mutex_destroy(&state->page_lock); mutex_destroy(&state->lock); tda1997x_set_power(state, 0); -- Gitee From 8d0db3ea2aa24ecc4a7d08d3689b77c134976227 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 23 Sep 2025 02:43:39 +0800 Subject: [PATCH 0753/1449] media: verisilicon: Protect G2 HEVC decoder against invalid DPB index ANBZ: #35228 commit 99293be855c320e6a937edcda6927c2ff4869b6e stable. commit 47825b1646a6a9eca0f90baa3d4f98947c2add96 upstream. Fix the Hantro G2 HEVC decoder so that we use DPB index 0 whenever a ninvalid index is received from user space. This protects the hardware from doing faulty memory access which then leads to bus errors. To be noted that when a reference is missing, userspace such as GStreamer passes an invalid DPB index of 255. This issue was found by seeking to a CRA picture using GStreamer. The framework is currently missing the code to skip over RASL pictures placed after the CRA. This situation can also occur while doing live streaming over lossy transport. Fixes: cb5dd5a0fa518 ("media: hantro: Introduce G2/HEVC decoder") Cc: stable@vger.kernel.org Reviewed-by: Benjamin Gaignard Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../platform/verisilicon/hantro_g2_hevc_dec.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c index d1971af5f7fa..d9da321af20e 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c @@ -297,6 +297,15 @@ static void set_params(struct hantro_ctx *ctx) hantro_reg_write(vpu, &g2_apf_threshold, 8); } +static u32 get_dpb_index(const struct v4l2_ctrl_hevc_decode_params *decode_params, + const u32 index) +{ + if (index > decode_params->num_active_dpb_entries) + return 0; + + return index; +} + static void set_ref_pic_list(struct hantro_ctx *ctx) { const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; @@ -369,8 +378,10 @@ static void set_ref_pic_list(struct hantro_ctx *ctx) list1[j++] = list1[i++]; for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { - hantro_reg_write(vpu, &ref_pic_regs0[i], list0[i]); - hantro_reg_write(vpu, &ref_pic_regs1[i], list1[i]); + hantro_reg_write(vpu, &ref_pic_regs0[i], + get_dpb_index(decode_params, list0[i])); + hantro_reg_write(vpu, &ref_pic_regs1[i], + get_dpb_index(decode_params, list1[i])); } } -- Gitee From a315a8a4dd67b0fbd20b1c27a3b644f7993c3459 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 28 Oct 2025 14:44:43 +0800 Subject: [PATCH 0754/1449] media: videobuf2: Fix device reference leak in vb2_dc_alloc error path ANBZ: #35228 commit 1ad7c817410965f6098f53ae543a26359d489ee5 stable. commit 94de23a9aa487d7c1372efb161721d7949a177ae upstream. In vb2_dc_alloc(), get_device() is called to increment the device reference count. However, if subsequent DMA allocation fails (vb2_dc_alloc_coherent or vb2_dc_alloc_non_coherent returns error), the function returns without calling put_device(), causing a device reference leak. Add put_device() call in the error path before kfree() to properly release the device reference acquired earlier. Fixes: de27891f675e ("media: videobuf2: handle non-contiguous DMA allocations") Cc: stable@vger.kernel.org Signed-off-by: Haotian Zhang Reviewed-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/common/videobuf2/videobuf2-dma-contig.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index 2fa455d4a048..5b6b4fe08408 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -258,6 +258,7 @@ static void *vb2_dc_alloc(struct vb2_buffer *vb, if (ret) { dev_err(dev, "dma alloc of size %lu failed\n", size); + put_device(buf->dev); kfree(buf); return ERR_PTR(-ENOMEM); } -- Gitee From 876d6f173abd267c5227bcadb5a2722d93fd2666 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 17 Oct 2025 13:33:20 +0800 Subject: [PATCH 0755/1449] media: vpif_capture: fix section mismatch ANBZ: #35228 commit 08c6c6f2a5707d98ea562efee5144adb2e3570d6 stable. commit 0ef841113724166c3c484d0e9ae6db1eb5634fde upstream. Platform drivers can be probed after their init sections have been discarded (e.g. on probe deferral or manual rebind through sysfs) so the probe function must not live in init. Note that commit ffa1b391c61b ("V4L/DVB: vpif_cap/disp: Removed section mismatch warning") incorrectly suppressed the modpost warning. Fixes: ffa1b391c61b ("V4L/DVB: vpif_cap/disp: Removed section mismatch warning") Fixes: 6ffefff5a9e7 ("V4L/DVB (12906c): V4L : vpif capture driver for DM6467") Cc: stable@vger.kernel.org # 2.6.32 Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/ti/davinci/vpif_capture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti/davinci/vpif_capture.c b/drivers/media/platform/ti/davinci/vpif_capture.c index 99fae8830c41..2d8ff91cf803 100644 --- a/drivers/media/platform/ti/davinci/vpif_capture.c +++ b/drivers/media/platform/ti/davinci/vpif_capture.c @@ -1601,7 +1601,7 @@ vpif_capture_get_pdata(struct platform_device *pdev, * This creates device entries by register itself to the V4L2 driver and * initializes fields of each channel objects */ -static __init int vpif_probe(struct platform_device *pdev) +static int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; struct i2c_adapter *i2c_adap; @@ -1808,7 +1808,7 @@ static int vpif_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume); -static __refdata struct platform_driver vpif_driver = { +static struct platform_driver vpif_driver = { .driver = { .name = VPIF_DRIVER_NAME, .pm = &vpif_pm_ops, -- Gitee From 69c097f1b15f7ef3a641f0ddf9b179378c824d65 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 17 Oct 2025 13:33:21 +0800 Subject: [PATCH 0756/1449] media: vpif_display: fix section mismatch ANBZ: #35228 commit 52604951b90cd0f6e58c988993a9f327d95cda9a stable. commit 59ca64bf98e4209df8ace8057d31ae3c80f948cd upstream. Platform drivers can be probed after their init sections have been discarded (e.g. on probe deferral or manual rebind through sysfs) so the probe function must not live in init. Note that commit ffa1b391c61b ("V4L/DVB: vpif_cap/disp: Removed section mismatch warning") incorrectly suppressed the modpost warning. Fixes: ffa1b391c61b ("V4L/DVB: vpif_cap/disp: Removed section mismatch warning") Fixes: e7332e3a552f ("V4L/DVB (12176): davinci/vpif_display: Add VPIF display driver") Cc: stable@vger.kernel.org # 2.6.32 Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/ti/davinci/vpif_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/ti/davinci/vpif_display.c b/drivers/media/platform/ti/davinci/vpif_display.c index f8ec2991c667..70c8e32398ab 100644 --- a/drivers/media/platform/ti/davinci/vpif_display.c +++ b/drivers/media/platform/ti/davinci/vpif_display.c @@ -1215,7 +1215,7 @@ static int vpif_probe_complete(void) * vpif_probe: This function creates device entries by register itself to the * V4L2 driver and initializes fields of each channel objects */ -static __init int vpif_probe(struct platform_device *pdev) +static int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; struct i2c_adapter *i2c_adap; @@ -1391,7 +1391,7 @@ static int vpif_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume); -static __refdata struct platform_driver vpif_driver = { +static struct platform_driver vpif_driver = { .driver = { .name = VPIF_DRIVER_NAME, .pm = &vpif_pm_ops, -- Gitee From aeca4322412d83012f1e4843052ae037b876412a Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Tue, 16 Sep 2025 14:10:07 +0800 Subject: [PATCH 0757/1449] media: amphion: Cancel message work before releasing the VPU core ANBZ: #35228 commit 4b139f88c2ab0eaa52839763ddea16a499bc833c stable. commit ae246b0032146e352c4c06a7bf03cd3d5bcb2ecd upstream. To avoid accessing the VPU register after release of the VPU core, cancel the message work and destroy the workqueue that handles the VPU message before release of the VPU core. Fixes: 3cd084519c6f ("media: amphion: add vpu v4l2 m2m support") Cc: stable@vger.kernel.org Signed-off-by: Ming Qian Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/amphion/vpu_v4l2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 75084ba8f93b..2bdfdcd324a0 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -682,15 +682,15 @@ static int vpu_v4l2_release(struct vpu_inst *inst) { vpu_trace(inst->vpu->dev, "%p\n", inst); - vpu_release_core(inst->core); - put_device(inst->dev); - if (inst->workqueue) { cancel_work_sync(&inst->msg_work); destroy_workqueue(inst->workqueue); inst->workqueue = NULL; } + vpu_release_core(inst->core); + put_device(inst->dev); + v4l2_ctrl_handler_free(&inst->ctrl_handler); mutex_destroy(&inst->lock); -- Gitee From 2dcf7fb47b2ac4602b423cd613da680d45b02771 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Tue, 2 Sep 2025 09:53:37 +0800 Subject: [PATCH 0758/1449] media: i2c: ADV7604: Remove redundant cancel_delayed_work in probe ANBZ: #35228 commit a8e6cf7fa2be90b4a82be23de7ab784c8d1cc054 stable. commit 8f34f24355a607b98ecd9924837aab13c676eeca upstream. The delayed_work delayed_work_enable_hotplug is initialized with INIT_DELAYED_WORK() in adv76xx_probe(), but it is never scheduled anywhere in the probe function. Calling cancel_delayed_work() on a work that has never been scheduled is redundant and unnecessary, as there is no pending work to cancel. Remove the redundant cancel_delayed_work() from error handling path and adjust the goto label accordingly to simplify the code and avoid potential confusion. Fixes: 54450f591c99 ("[media] adv7604: driver for the Analog Devices ADV7604 video decoder") Cc: stable@vger.kernel.org Signed-off-by: Duoming Zhou Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/i2c/adv7604.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 3bd31b587023..7baeffaffa20 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3620,7 +3620,7 @@ static int adv76xx_probe(struct i2c_client *client) err = media_entity_pads_init(&sd->entity, state->source_pad + 1, state->pads); if (err) - goto err_work_queues; + goto err_i2c; /* Configure regmaps */ err = configure_regmaps(state); @@ -3661,8 +3661,6 @@ static int adv76xx_probe(struct i2c_client *client) err_entity: media_entity_cleanup(&sd->entity); -err_work_queues: - cancel_delayed_work(&state->delayed_work_enable_hotplug); err_i2c: adv76xx_unregister_clients(state); err_hdl: -- Gitee From 18250d3cd47d3858972b8352c701f4fef7ccf2a9 Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Tue, 2 Sep 2025 09:10:31 +0800 Subject: [PATCH 0759/1449] media: i2c: adv7842: Remove redundant cancel_delayed_work in probe ANBZ: #35228 commit 53e256b5c3602776b5ec90b58424d7a598316ce2 stable. commit e66a5cc606c58e72f18f9cdd868a3672e918f9f8 upstream. The delayed_work delayed_work_enable_hotplug is initialized with INIT_DELAYED_WORK() in adv7842_probe(), but it is never scheduled anywhere in the probe function. Calling cancel_delayed_work() on a work that has never been scheduled is redundant and unnecessary, as there is no pending work to cancel. Remove the redundant cancel_delayed_work() from error handling path and adjust the goto label accordingly to simplify the code and avoid potential confusion. Fixes: a89bcd4c6c20 ("[media] adv7842: add new video decoder driver") Cc: stable@vger.kernel.org Signed-off-by: Duoming Zhou Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/i2c/adv7842.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index cbda7dc54148..06b19ef181cd 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3564,7 +3564,7 @@ static int adv7842_probe(struct i2c_client *client) err = media_entity_pads_init(&sd->entity, ADV7842_PAD_SOURCE + 1, state->pads); if (err) - goto err_work_queues; + goto err_i2c; err = adv7842_core_init(sd); if (err) @@ -3585,8 +3585,6 @@ static int adv7842_probe(struct i2c_client *client) err_entity: media_entity_cleanup(&sd->entity); -err_work_queues: - cancel_delayed_work(&state->delayed_work_enable_hotplug); err_i2c: adv7842_unregister_clients(sd); err_hdl: -- Gitee From 3f9a65439a905eebbe098313a237969e096ca024 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Mon, 15 Sep 2025 20:09:38 +0800 Subject: [PATCH 0760/1449] media: mediatek: vcodec: Fix a reference leak in mtk_vcodec_fw_vpu_init() ANBZ: #35228 commit 80617b75fd70b01b6e89c944c822436317c3ceee stable. commit cdd0f118ef87db8a664fb5ea366fd1766d2df1cd upstream. vpu_get_plat_device() increases the reference count of the returned platform device. However, when devm_kzalloc() fails, the reference is not released, causing a reference leak. Fix this by calling put_device() on fw_pdev->dev before returning on the error path. Fixes: e25a89f743b1 ("media: mtk-vcodec: potential dereference of null pointer") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Tzung-Bi Shih Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c index 42ce58c41e4f..87e067401a67 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c @@ -117,8 +117,10 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(void *priv, enum mtk_vcodec_fw_use vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_enc_handler, priv, rst_id); fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL); - if (!fw) + if (!fw) { + put_device(&fw_pdev->dev); return ERR_PTR(-ENOMEM); + } fw->type = VPU; fw->ops = &mtk_vcodec_vpu_msg; fw->pdev = fw_pdev; -- Gitee From fd3ec61d49b7b2b25a73035cc32f2a96d0f3f585 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 6 Dec 2025 10:39:49 +0800 Subject: [PATCH 0761/1449] LoongArch: Add new PCI ID for pci_fixup_vgadev() ANBZ: #35228 commit 4632c8b0966de992f502793de181ace7b7ac4c18 stable. commit bf3fa8f232a1eec8d7b88dcd9e925e60f04f018d upstream. Loongson-2K3000 has a new PCI ID (0x7a46) for its display controller, Add it for pci_fixup_vgadev() since we prefer a discrete graphics card as default boot device if present. Cc: stable@vger.kernel.org Signed-off-by: Tianrui Zhao Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/pci/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c index 927dd31f82b9..ea4dbac0b47b 100644 --- a/arch/loongarch/pci/pci.c +++ b/arch/loongarch/pci/pci.c @@ -15,6 +15,7 @@ #define PCI_DEVICE_ID_LOONGSON_HOST 0x7a00 #define PCI_DEVICE_ID_LOONGSON_DC1 0x7a06 #define PCI_DEVICE_ID_LOONGSON_DC2 0x7a36 +#define PCI_DEVICE_ID_LOONGSON_DC3 0x7a46 int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 *val) @@ -98,3 +99,4 @@ static void pci_fixup_vgadev(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC1, pci_fixup_vgadev); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC2, pci_fixup_vgadev); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DC3, pci_fixup_vgadev); -- Gitee From 5788da9e529ffb293b37c1e2a501e1951d9f68df Mon Sep 17 00:00:00 2001 From: Qiang Ma Date: Sat, 6 Dec 2025 10:39:49 +0800 Subject: [PATCH 0762/1449] LoongArch: Correct the calculation logic of thread_count ANBZ: #35228 commit 155d6a8f5d5f7549b3d2e6c505c741da428b591f stable. commit 1de0ae21f136efa6c5d8a4d3e07b7d1ca39c750f upstream. For thread_count, the current calculation method has a maximum of 255, which may not be sufficient in the future. Therefore, we are correcting it now. Reference: SMBIOS Specification, 7.5 Processor Information (Type 4)[1] [1]: https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.9.0.pdf Cc: stable@vger.kernel.org Signed-off-by: Qiang Ma Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/loongarch/kernel/setup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 3a0c3ca28084..dc35b7b5d0c0 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -58,6 +58,7 @@ #define SMBIOS_FREQLOW_MASK 0xFF #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 #define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 +#define SMBIOS_THREAD_PACKAGE_2_OFFSET 0x2E #define LOONGSON_EFI_ENABLE (1 << 3) #ifdef CONFIG_EFI @@ -132,7 +133,12 @@ static void __init parse_cpu_table(const struct dmi_header *dm) cpu_clock_freq = freq_temp * 1000000; loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); - loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); + loongson_sysconf.cores_per_package = *(u8 *)(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); + if (dm->length >= 0x30 && loongson_sysconf.cores_per_package == 0xff) { + /* SMBIOS 3.0+ has ThreadCount2 for more than 255 threads */ + loongson_sysconf.cores_per_package = + *(u16 *)(dmi_data + SMBIOS_THREAD_PACKAGE_2_OFFSET); + } __max_packages++; pr_info("CpuClock = %llu\n", cpu_clock_freq); -- Gitee From de15c784a8b29c74356ad7b31e364cf16fc7f94b Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sat, 6 Dec 2025 10:39:40 +0800 Subject: [PATCH 0763/1449] LoongArch: Fix build errors for CONFIG_RANDSTRUCT ANBZ: #35228 commit 582c1dcc5bb5a730a1d07ff77f7ec32f69fe8530 stable. commit 3c250aecef62da81deb38ac6738ac0a88d91f1fc upstream. When CONFIG_RANDSTRUCT enabled, members of task_struct are randomized. There is a chance that TASK_STACK_CANARY be out of 12bit immediate's range and causes build errors. TASK_STACK_CANARY is naturally aligned, so fix it by replacing ld.d/st.d with ldptr.d/stptr.d which have 14bit immediates. Cc: stable@vger.kernel.org Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202511240656.0NaPcJs1-lkp@intel.com/ Suggested-by: Rui Wang Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/kernel/switch.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S index 31dd8199b245..b42c0dcf6263 100644 --- a/arch/loongarch/kernel/switch.S +++ b/arch/loongarch/kernel/switch.S @@ -25,8 +25,8 @@ SYM_FUNC_START(__switch_to) stptr.d a4, a0, THREAD_SCHED_CFA #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) la t7, __stack_chk_guard - LONG_L t8, a1, TASK_STACK_CANARY - LONG_S t8, t7, 0 + ldptr.d t8, a1, TASK_STACK_CANARY + stptr.d t8, t7, 0 #endif move tp, a2 cpu_restore_nonscratch a1 -- Gitee From 9e6c005398501f37af12a104f4c023037e9baffe Mon Sep 17 00:00:00 2001 From: WangYuli Date: Sat, 6 Dec 2025 10:39:48 +0800 Subject: [PATCH 0764/1449] LoongArch: Use __pmd()/__pte() for swap entry conversions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit f0b9e0bdc8bc3e4294a1774bd35b084d3bab981a stable. commit 4a71df151e703b5e7e85b33369cee59ef2665e61 upstream. The __pmd() and __pte() helper macros provide the correct initialization syntax and abstraction for the pmd_t and pte_t types. Use __pmd() to fix follow warning about __swp_entry_to_pmd() with gcc-15 under specific configs [1] : In file included from ./include/linux/pgtable.h:6, from ./include/linux/mm.h:31, from ./include/linux/pagemap.h:8, from arch/loongarch/mm/init.c:14: ./include/linux/swapops.h: In function ‘swp_entry_to_pmd’: ./arch/loongarch/include/asm/pgtable.h:302:34: error: missing braces around initializer [-Werror=missing-braces] 302 | #define __swp_entry_to_pmd(x) ((pmd_t) { (x).val | _PAGE_HUGE }) | ^ ./include/linux/swapops.h:559:16: note: in expansion of macro ‘__swp_entry_to_pmd’ 559 | return __swp_entry_to_pmd(arch_entry); | ^~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors Also update __swp_entry_to_pte() to use __pte() for consistency. [1]. https://download.01.org/0day-ci/archive/20251119/202511190316.luI90kAo-lkp@intel.com/config Cc: stable@vger.kernel.org Signed-off-by: Yuli Wang Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/include/asm/pgtable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h index dc5f4943fc26..f361617c61de 100644 --- a/arch/loongarch/include/asm/pgtable.h +++ b/arch/loongarch/include/asm/pgtable.h @@ -295,9 +295,9 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) #define __swp_offset(x) ((x).val >> 24) #define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +#define __swp_entry_to_pte(x) __pte((x).val) #define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val(pmd) }) -#define __swp_entry_to_pmd(x) ((pmd_t) { (x).val | _PAGE_HUGE }) +#define __swp_entry_to_pmd(x) __pmd((x).val | _PAGE_HUGE) static inline int pte_swp_exclusive(pte_t pte) { -- Gitee From d994e93abb91640d50b5f46bbc865e46f2936a87 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Sat, 6 Dec 2025 10:39:48 +0800 Subject: [PATCH 0765/1449] LoongArch: Use unsigned long for _end and _text ANBZ: #35228 commit b9b5f45cc1b72953e1fe27bb32d9f3ace46ba4f2 stable. commit a258a3cb1895e3acf5f2fe245d17426e894bc935 upstream. It is better to use unsigned long rather than long for _end and _text to calculate the kernel length. Cc: stable@vger.kernel.org # v6.3+ Fixes: e5f02b51fa0c ("LoongArch: Add support for kernel address space layout randomization (KASLR)") Signed-off-by: Tiezhu Yang Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/kernel/relocate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c index 33d0010100d9..60ced23257f0 100644 --- a/arch/loongarch/kernel/relocate.c +++ b/arch/loongarch/kernel/relocate.c @@ -142,7 +142,7 @@ static inline void __init *determine_relocation_address(void) if (kaslr_disabled()) return destination; - kernel_length = (long)_end - (long)_text; + kernel_length = (unsigned long)_end - (unsigned long)_text; random_offset = get_random_boot() << 16; random_offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1); @@ -194,7 +194,7 @@ unsigned long __init relocate_kernel(void) early_memunmap(cmdline, COMMAND_LINE_SIZE); if (random_offset) { - kernel_length = (long)(_end) - (long)(_text); + kernel_length = (unsigned long)(_end) - (unsigned long)(_text); /* Copy the kernel to it's new location */ memcpy(location_new, _text, kernel_length); -- Gitee From 7e5299cdec8618c8f36d3068631baf6f91491d2e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sat, 19 Jul 2025 02:35:00 +0800 Subject: [PATCH 0766/1449] compiler_types.h: add "auto" as a macro for "__auto_type" ANBZ: #35228 commit e53bfe4530590f2832a96b21bd55e9416b4b1dc1 stable. commit 2fb6915fa22dc5524d704afba58a13305dd9f533 upstream. "auto" was defined as a keyword back in the K&R days, but as a storage type specifier. No one ever used it, since it was and is the default storage type for local variables. C++11 recycled the keyword to allow a type to be declared based on the type of an initializer. This was finally adopted into standard C in C23. gcc and clang provide the "__auto_type" alias keyword as an extension for pre-C23, however, there is no reason to pollute the bulk of the source base with this temporary keyword; instead define "auto" as a macro unless the compiler is running in C23+ mode. This macro is added in because that header is included in some of the tools headers, wheres is not as it has a bunch of very kernel-specific things in it. [ Cc: stable to reduce potential backporting burden. ] Signed-off-by: H. Peter Anvin (Intel) Acked-by: Miguel Ojeda Cc: Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/compiler_types.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 10aef2ef71d9..8a3844e8c770 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -4,6 +4,19 @@ #ifndef __ASSEMBLY__ +/* + * C23 introduces "auto" as a standard way to define type-inferred + * variables, but "auto" has been a (useless) keyword even since K&R C, + * so it has always been "namespace reserved." + * + * Until at some future time we require C23 support, we need the gcc + * extension __auto_type, but there is no reason to put that elsewhere + * in the source code. + */ +#if __STDC_VERSION__ < 202311L +# define auto __auto_type +#endif + /* * Skipped when running bindgen due to a libclang issue; * see https://github.com/rust-lang/rust-bindgen/issues/2244. -- Gitee From 9a830e60195a5891e48d64fcb83428db1b5c2921 Mon Sep 17 00:00:00 2001 From: Maciej Wieczor-Retman Date: Fri, 5 Dec 2025 03:00:04 +0800 Subject: [PATCH 0767/1449] kasan: refactor pcpu kasan vmalloc unpoison ANBZ: #35228 commit c9acbaec693b3bcbb61c2192ad0f92774cb0e53d stable. commit 6f13db031e27e88213381039032a9cc061578ea6 upstream. A KASAN tag mismatch, possibly causing a kernel panic, can be observed on systems with a tag-based KASAN enabled and with multiple NUMA nodes. It was reported on arm64 and reproduced on x86. It can be explained in the following points: 1. There can be more than one virtual memory chunk. 2. Chunk's base address has a tag. 3. The base address points at the first chunk and thus inherits the tag of the first chunk. 4. The subsequent chunks will be accessed with the tag from the first chunk. 5. Thus, the subsequent chunks need to have their tag set to match that of the first chunk. Refactor code by reusing __kasan_unpoison_vmalloc in a new helper in preparation for the actual fix. Link: https://lkml.kernel.org/r/eb61d93b907e262eefcaa130261a08bcb6c5ce51.1764874575.git.m.wieczorretman@pm.me Fixes: 1d96320f8d53 ("kasan, vmalloc: add vmalloc tagging for SW_TAGS") Signed-off-by: Maciej Wieczor-Retman Reviewed-by: Andrey Konovalov Cc: Alexander Potapenko Cc: Andrey Ryabinin Cc: Danilo Krummrich Cc: Dmitriy Vyukov Cc: Jiayuan Chen Cc: Kees Cook Cc: Marco Elver Cc: "Uladzislau Rezki (Sony)" Cc: Vincenzo Frascino Cc: [6.1+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/kasan.h | 15 +++++++++++++++ mm/kasan/common.c | 17 +++++++++++++++++ mm/vmalloc.c | 4 +--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 71fa9a40fb5a..92bc6bfde603 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -423,6 +423,16 @@ static __always_inline void kasan_poison_vmalloc(const void *start, __kasan_poison_vmalloc(start, size); } +void __kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms, + kasan_vmalloc_flags_t flags); +static __always_inline void +kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms, + kasan_vmalloc_flags_t flags) +{ + if (kasan_enabled()) + __kasan_unpoison_vmap_areas(vms, nr_vms, flags); +} + #else /* CONFIG_KASAN_VMALLOC */ static inline void kasan_populate_early_vm_area_shadow(void *start, @@ -446,6 +456,11 @@ static inline void *kasan_unpoison_vmalloc(const void *start, static inline void kasan_poison_vmalloc(const void *start, unsigned long size) { } +static __always_inline void +kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms, + kasan_vmalloc_flags_t flags) +{ } + #endif /* CONFIG_KASAN_VMALLOC */ #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 256930da578a..ce338a2a2025 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "kasan.h" #include "../slab.h" @@ -450,3 +451,19 @@ bool __kasan_check_byte(const void *address, unsigned long ip) } return true; } + +#ifdef CONFIG_KASAN_VMALLOC +void __kasan_unpoison_vmap_areas(struct vm_struct **vms, int nr_vms, + kasan_vmalloc_flags_t flags) +{ + unsigned long size; + void *addr; + int area; + + for (area = 0 ; area < nr_vms ; area++) { + size = vms[area]->size; + addr = vms[area]->addr; + vms[area]->addr = __kasan_unpoison_vmalloc(addr, size, flags); + } +} +#endif diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 4292356f1c90..7494b38c2e41 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -4265,9 +4265,7 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, * With hardware tag-based KASAN, marking is skipped for * non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc(). */ - for (area = 0; area < nr_vms; area++) - vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr, - vms[area]->size, KASAN_VMALLOC_PROT_NORMAL); + kasan_unpoison_vmap_areas(vms, nr_vms, KASAN_VMALLOC_PROT_NORMAL); kfree(vas); return vms; -- Gitee From e8ad7b22c9e1397c86e612c86b91d46892524cfb Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Sat, 29 Nov 2025 00:18:32 +0800 Subject: [PATCH 0768/1449] idr: fix idr_alloc() returning an ID out of range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 3e3c0dc025f06d331df6aeb939126e08742fa83f stable. commit c6e8e595a0798ad67da0f7bebaf69c31ef70dfff upstream. If you use an IDR with a non-zero base, and specify a range that lies entirely below the base, 'max - base' becomes very large and idr_get_free() can return an ID that lies outside of the requested range. Link: https://lkml.kernel.org/r/20251128161853.3200058-1-willy@infradead.org Fixes: 6ce711f27500 ("idr: Make 1-based IDRs more efficient") Signed-off-by: Matthew Wilcox (Oracle) Reported-by: Jan Sokolowski Reported-by: Koen Koning Reported-by: Peter Senna Tschudin Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6449 Reviewed-by: Christian König Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- lib/idr.c | 2 ++ tools/testing/radix-tree/idr-test.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/idr.c b/lib/idr.c index e2adc457abb4..457430cff8c5 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -40,6 +40,8 @@ int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid, if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR))) idr->idr_rt.xa_flags |= IDR_RT_MARKER; + if (max < base) + return -ENOSPC; id = (id < base) ? 0 : id - base; radix_tree_iter_init(&iter, id); diff --git a/tools/testing/radix-tree/idr-test.c b/tools/testing/radix-tree/idr-test.c index ca24f6839d50..f34e27452439 100644 --- a/tools/testing/radix-tree/idr-test.c +++ b/tools/testing/radix-tree/idr-test.c @@ -57,6 +57,26 @@ void idr_alloc_test(void) idr_destroy(&idr); } +void idr_alloc2_test(void) +{ + int id; + struct idr idr = IDR_INIT_BASE(idr, 1); + + id = idr_alloc(&idr, idr_alloc2_test, 0, 1, GFP_KERNEL); + assert(id == -ENOSPC); + + id = idr_alloc(&idr, idr_alloc2_test, 1, 2, GFP_KERNEL); + assert(id == 1); + + id = idr_alloc(&idr, idr_alloc2_test, 0, 1, GFP_KERNEL); + assert(id == -ENOSPC); + + id = idr_alloc(&idr, idr_alloc2_test, 0, 2, GFP_KERNEL); + assert(id == -ENOSPC); + + idr_destroy(&idr); +} + void idr_replace_test(void) { DEFINE_IDR(idr); @@ -409,6 +429,7 @@ void idr_checks(void) idr_replace_test(); idr_alloc_test(); + idr_alloc2_test(); idr_null_test(); idr_nowait_test(); idr_get_next_test(0); -- Gitee From c727b2d9beb4fe2d2f3e0211c203d53d61a04da6 Mon Sep 17 00:00:00 2001 From: Rong Zhang Date: Tue, 30 Dec 2025 02:22:21 +0800 Subject: [PATCH 0769/1449] x86/microcode/AMD: Fix Entrysign revision check for Zen5/Strix Halo ANBZ: #35228 commit 45b44c3a5e6246fad08383366413533c2228982d stable. commit 150b1b97e27513535dcd3795d5ecd28e61b6cb8c upstream. Zen5 also contains family 1Ah, models 70h-7Fh, which are mistakenly missing from cpu_has_entrysign(). Add the missing range. Fixes: 8a9fb5129e8e ("x86/microcode/AMD: Limit Entrysign signature checking to known generations") Signed-off-by: Rong Zhang Signed-off-by: Borislav Petkov (AMD) Cc: stable@kernel.org Link: https://patch.msgid.link/20251229182245.152747-1-i@rong.moe Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/x86/kernel/cpu/microcode/amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index d01bd393a151..23282b616d3e 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -237,7 +237,7 @@ static bool cpu_has_entrysign(void) if (fam == 0x1a) { if (model <= 0x2f || (0x40 <= model && model <= 0x4f) || - (0x60 <= model && model <= 0x6f)) + (0x60 <= model && model <= 0x7f)) return true; } -- Gitee From 059a8572e4a78d7b05cc812b2fa6200b6a8d949d Mon Sep 17 00:00:00 2001 From: Kaushlendra Kumar Date: Tue, 9 Dec 2025 12:45:52 +0800 Subject: [PATCH 0770/1449] tools/mm/page_owner_sort: fix timestamp comparison for stable sorting ANBZ: #35228 commit b8f12a3ecf031d76ec7b465007b5a21b03848308 stable. commit 7013803444dd3bbbe28fd3360c084cec3057c554 upstream. The ternary operator in compare_ts() returns 1 when timestamps are equal, causing unstable sorting behavior. Replace with explicit three-way comparison that returns 0 for equal timestamps, ensuring stable qsort ordering and consistent output. Link: https://lkml.kernel.org/r/20251209044552.3396468-1-kaushlendra.kumar@intel.com Fixes: 8f9c447e2e2b ("tools/vm/page_owner_sort.c: support sorting pid and time") Signed-off-by: Kaushlendra Kumar Cc: Chongxi Zhao Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/mm/page_owner_sort.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/mm/page_owner_sort.c b/tools/mm/page_owner_sort.c index 99798894b879..9863e92bc180 100644 --- a/tools/mm/page_owner_sort.c +++ b/tools/mm/page_owner_sort.c @@ -178,7 +178,11 @@ static int compare_ts(const void *p1, const void *p2) { const struct block_list *l1 = p1, *l2 = p2; - return l1->ts_nsec < l2->ts_nsec ? -1 : 1; + if (l1->ts_nsec < l2->ts_nsec) + return -1; + if (l1->ts_nsec > l2->ts_nsec) + return 1; + return 0; } static int compare_free_ts(const void *p1, const void *p2) -- Gitee From 44c800028b0896baa1ee6b7ce39e5889e60c4153 Mon Sep 17 00:00:00 2001 From: Chenghao Duan Date: Wed, 31 Dec 2025 15:19:25 +0800 Subject: [PATCH 0771/1449] samples/ftrace: Adjust LoongArch register restore order in direct calls ANBZ: #35228 commit a94bd2d93f7efb856d75dfd43fbe6e333723f58a stable. commit bb85d206be208bbf834883e948125a35ac59993a upstream. Ensure that in the ftrace direct call logic, the CPU register state (with ra = parent return address) is restored to the correct state after the execution of the custom trampoline function and before returning to the traced function. Additionally, guarantee the correctness of the jump logic for jr t0 (traced function address). Cc: stable@vger.kernel.org Fixes: 9cdc3b6a299c ("LoongArch: ftrace: Add direct call support") Reported-by: Youling Tang Acked-by: Steven Rostedt (Google) Signed-off-by: Chenghao Duan Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- samples/ftrace/ftrace-direct-modify.c | 8 ++++---- samples/ftrace/ftrace-direct-multi-modify.c | 8 ++++---- samples/ftrace/ftrace-direct-multi.c | 4 ++-- samples/ftrace/ftrace-direct-too.c | 4 ++-- samples/ftrace/ftrace-direct.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-direct-modify.c index 0ac9b8c77e1a..f754d88d7503 100644 --- a/samples/ftrace/ftrace-direct-modify.c +++ b/samples/ftrace/ftrace-direct-modify.c @@ -176,8 +176,8 @@ asm ( " st.d $t0, $sp, 0\n" " st.d $ra, $sp, 8\n" " bl my_direct_func1\n" -" ld.d $t0, $sp, 0\n" -" ld.d $ra, $sp, 8\n" +" ld.d $ra, $sp, 0\n" +" ld.d $t0, $sp, 8\n" " addi.d $sp, $sp, 16\n" " jr $t0\n" " .size my_tramp1, .-my_tramp1\n" @@ -189,8 +189,8 @@ asm ( " st.d $t0, $sp, 0\n" " st.d $ra, $sp, 8\n" " bl my_direct_func2\n" -" ld.d $t0, $sp, 0\n" -" ld.d $ra, $sp, 8\n" +" ld.d $ra, $sp, 0\n" +" ld.d $t0, $sp, 8\n" " addi.d $sp, $sp, 16\n" " jr $t0\n" " .size my_tramp2, .-my_tramp2\n" diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/ftrace-direct-multi-modify.c index f8c934cca41b..d4f72bea3323 100644 --- a/samples/ftrace/ftrace-direct-multi-modify.c +++ b/samples/ftrace/ftrace-direct-multi-modify.c @@ -199,8 +199,8 @@ asm ( " move $a0, $t0\n" " bl my_direct_func1\n" " ld.d $a0, $sp, 0\n" -" ld.d $t0, $sp, 8\n" -" ld.d $ra, $sp, 16\n" +" ld.d $ra, $sp, 8\n" +" ld.d $t0, $sp, 16\n" " addi.d $sp, $sp, 32\n" " jr $t0\n" " .size my_tramp1, .-my_tramp1\n" @@ -215,8 +215,8 @@ asm ( " move $a0, $t0\n" " bl my_direct_func2\n" " ld.d $a0, $sp, 0\n" -" ld.d $t0, $sp, 8\n" -" ld.d $ra, $sp, 16\n" +" ld.d $ra, $sp, 8\n" +" ld.d $t0, $sp, 16\n" " addi.d $sp, $sp, 32\n" " jr $t0\n" " .size my_tramp2, .-my_tramp2\n" diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-direct-multi.c index 09a68e2914d0..1eafa41a3120 100644 --- a/samples/ftrace/ftrace-direct-multi.c +++ b/samples/ftrace/ftrace-direct-multi.c @@ -131,8 +131,8 @@ asm ( " move $a0, $t0\n" " bl my_direct_func\n" " ld.d $a0, $sp, 0\n" -" ld.d $t0, $sp, 8\n" -" ld.d $ra, $sp, 16\n" +" ld.d $ra, $sp, 8\n" +" ld.d $t0, $sp, 16\n" " addi.d $sp, $sp, 32\n" " jr $t0\n" " .size my_tramp, .-my_tramp\n" diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-direct-too.c index 5b1afe1f6990..ed044622eb93 100644 --- a/samples/ftrace/ftrace-direct-too.c +++ b/samples/ftrace/ftrace-direct-too.c @@ -143,8 +143,8 @@ asm ( " ld.d $a0, $sp, 0\n" " ld.d $a1, $sp, 8\n" " ld.d $a2, $sp, 16\n" -" ld.d $t0, $sp, 24\n" -" ld.d $ra, $sp, 32\n" +" ld.d $ra, $sp, 24\n" +" ld.d $t0, $sp, 32\n" " addi.d $sp, $sp, 48\n" " jr $t0\n" " .size my_tramp, .-my_tramp\n" diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c index adb83a725b24..3e1e87e888ec 100644 --- a/samples/ftrace/ftrace-direct.c +++ b/samples/ftrace/ftrace-direct.c @@ -124,8 +124,8 @@ asm ( " st.d $ra, $sp, 16\n" " bl my_direct_func\n" " ld.d $a0, $sp, 0\n" -" ld.d $t0, $sp, 8\n" -" ld.d $ra, $sp, 16\n" +" ld.d $ra, $sp, 8\n" +" ld.d $t0, $sp, 16\n" " addi.d $sp, $sp, 32\n" " jr $t0\n" " .size my_tramp, .-my_tramp\n" -- Gitee From 4e55fb978ebf25f174508655326f6eeeccc14734 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Sat, 29 Nov 2025 01:37:28 +0800 Subject: [PATCH 0772/1449] RDMA/core: Check for the presence of LS_NLA_TYPE_DGID correctly ANBZ: #35228 commit 9d85524789c2f17c0e87de8d596bcccc3683a1fc stable. commit a7b8e876e0ef0232b8076972c57ce9a7286b47ca upstream. The netlink response for RDMA_NL_LS_OP_IP_RESOLVE should always have a LS_NLA_TYPE_DGID attribute, it is invalid if it does not. Use the nl parsing logic properly and call nla_parse_deprecated() to fill the nlattrs array and then directly index that array to get the data for the DGID. Just fail if it is NULL. Remove the for loop searching for the nla, and squash the validation and parsing into one function. Fixes an uninitialized read from the stack triggered by userspace if it does not provide the DGID to a kernel initiated RDMA_NL_LS_OP_IP_RESOLVE query. BUG: KMSAN: uninit-value in hex_byte_pack include/linux/hex.h:13 [inline] BUG: KMSAN: uninit-value in ip6_string+0xef4/0x13a0 lib/vsprintf.c:1490 hex_byte_pack include/linux/hex.h:13 [inline] ip6_string+0xef4/0x13a0 lib/vsprintf.c:1490 ip6_addr_string+0x18a/0x3e0 lib/vsprintf.c:1509 ip_addr_string+0x245/0xee0 lib/vsprintf.c:1633 pointer+0xc09/0x1bd0 lib/vsprintf.c:2542 vsnprintf+0xf8a/0x1bd0 lib/vsprintf.c:2930 vprintk_store+0x3ae/0x1530 kernel/printk/printk.c:2279 vprintk_emit+0x307/0xcd0 kernel/printk/printk.c:2426 vprintk_default+0x3f/0x50 kernel/printk/printk.c:2465 vprintk+0x36/0x50 kernel/printk/printk_safe.c:82 _printk+0x17e/0x1b0 kernel/printk/printk.c:2475 ib_nl_process_good_ip_rsep drivers/infiniband/core/addr.c:128 [inline] ib_nl_handle_ip_res_resp+0x963/0x9d0 drivers/infiniband/core/addr.c:141 rdma_nl_rcv_msg drivers/infiniband/core/netlink.c:-1 [inline] rdma_nl_rcv_skb drivers/infiniband/core/netlink.c:239 [inline] rdma_nl_rcv+0xefa/0x11c0 drivers/infiniband/core/netlink.c:259 netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline] netlink_unicast+0xf04/0x12b0 net/netlink/af_netlink.c:1346 netlink_sendmsg+0x10b3/0x1250 net/netlink/af_netlink.c:1896 sock_sendmsg_nosec net/socket.c:714 [inline] __sock_sendmsg+0x333/0x3d0 net/socket.c:729 ____sys_sendmsg+0x7e0/0xd80 net/socket.c:2617 ___sys_sendmsg+0x271/0x3b0 net/socket.c:2671 __sys_sendmsg+0x1aa/0x300 net/socket.c:2703 __compat_sys_sendmsg net/compat.c:346 [inline] __do_compat_sys_sendmsg net/compat.c:353 [inline] __se_compat_sys_sendmsg net/compat.c:350 [inline] __ia32_compat_sys_sendmsg+0xa4/0x100 net/compat.c:350 ia32_sys_call+0x3f6c/0x4310 arch/x86/include/generated/asm/syscalls_32.h:371 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline] __do_fast_syscall_32+0xb0/0x150 arch/x86/entry/syscall_32.c:306 do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:331 do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:3 Link: https://patch.msgid.link/r/0-v1-3fbaef094271+2cf-rdma_op_ip_rslv_syz_jgg@nvidia.com Cc: stable@vger.kernel.org Fixes: ae43f8286730 ("IB/core: Add IP to GID netlink offload") Reported-by: syzbot+938fcd548c303fe33c1a@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/68dc3dac.a00a0220.102ee.004f.GAE@google.com Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/core/addr.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 8bf705921618..e95745710610 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -80,37 +80,25 @@ static const struct nla_policy ib_nl_addr_policy[LS_NLA_TYPE_MAX] = { .min = sizeof(struct rdma_nla_ls_gid)}, }; -static inline bool ib_nl_is_good_ip_resp(const struct nlmsghdr *nlh) +static void ib_nl_process_ip_rsep(const struct nlmsghdr *nlh) { struct nlattr *tb[LS_NLA_TYPE_MAX] = {}; + union ib_gid gid; + struct addr_req *req; + int found = 0; int ret; if (nlh->nlmsg_flags & RDMA_NL_LS_F_ERR) - return false; + return; ret = nla_parse_deprecated(tb, LS_NLA_TYPE_MAX - 1, nlmsg_data(nlh), nlmsg_len(nlh), ib_nl_addr_policy, NULL); if (ret) - return false; - - return true; -} - -static void ib_nl_process_good_ip_rsep(const struct nlmsghdr *nlh) -{ - const struct nlattr *head, *curr; - union ib_gid gid; - struct addr_req *req; - int len, rem; - int found = 0; - - head = (const struct nlattr *)nlmsg_data(nlh); - len = nlmsg_len(nlh); + return; - nla_for_each_attr(curr, head, len, rem) { - if (curr->nla_type == LS_NLA_TYPE_DGID) - memcpy(&gid, nla_data(curr), nla_len(curr)); - } + if (!tb[LS_NLA_TYPE_DGID]) + return; + memcpy(&gid, nla_data(tb[LS_NLA_TYPE_DGID]), sizeof(gid)); spin_lock_bh(&lock); list_for_each_entry(req, &req_list, list) { @@ -137,8 +125,7 @@ int ib_nl_handle_ip_res_resp(struct sk_buff *skb, !(NETLINK_CB(skb).sk)) return -EPERM; - if (ib_nl_is_good_ip_resp(nlh)) - ib_nl_process_good_ip_rsep(nlh); + ib_nl_process_ip_rsep(nlh); return 0; } -- Gitee From 90b78a869acc4ff2c1e27b96c7c4fc413edbf61c Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Sat, 29 Nov 2025 08:53:21 +0800 Subject: [PATCH 0773/1449] RDMA/cm: Fix leaking the multicast GID table reference ANBZ: #35228 commit c0acdee513239e1d6e1b490f56be0e6837dfd162 stable. commit 57f3cb6c84159d12ba343574df2115fb18dd83ca upstream. If the CM ID is destroyed while the CM event for multicast creating is still queued the cancel_work_sync() will prevent the work from running which also prevents destroying the ah_attr. This leaks a refcount and triggers a WARN: GID entry ref leak for dev syz1 index 2 ref=573 WARNING: CPU: 1 PID: 655 at drivers/infiniband/core/cache.c:809 release_gid_table drivers/infiniband/core/cache.c:806 [inline] WARNING: CPU: 1 PID: 655 at drivers/infiniband/core/cache.c:809 gid_table_release_one+0x284/0x3cc drivers/infiniband/core/cache.c:886 Destroy the ah_attr after canceling the work, it is safe to call this twice. Link: https://patch.msgid.link/r/0-v1-4285d070a6b2+20a-rdma_mc_gid_leak_syz_jgg@nvidia.com Cc: stable@vger.kernel.org Fixes: fe454dc31e84 ("RDMA/ucma: Fix use-after-free bug in ucma_create_uevent") Reported-by: syzbot+b0da83a6c0e2e2bddbd4@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/68232e7b.050a0220.f2294.09f6.GAE@google.com Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/core/cma.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index a5ceae2e075a..7db79ff3fa06 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1993,6 +1993,7 @@ static void destroy_mc(struct rdma_id_private *id_priv, ib_sa_free_multicast(mc->sa_mc); if (rdma_protocol_roce(id_priv->id.device, id_priv->id.port_num)) { + struct rdma_cm_event *event = &mc->iboe_join.event; struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; struct net_device *ndev = NULL; @@ -2015,6 +2016,8 @@ static void destroy_mc(struct rdma_id_private *id_priv, dev_put(ndev); cancel_work_sync(&mc->iboe_join.work); + if (event->event == RDMA_CM_EVENT_MULTICAST_JOIN) + rdma_destroy_ah_attr(&event->param.ud.ah_attr); } kfree(mc); } -- Gitee From b3cef65b93f552d1abb2e783f00a0d264477c482 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Mon, 1 Dec 2025 11:40:58 +0800 Subject: [PATCH 0774/1449] e1000: fix OOB in e1000_tbi_should_accept() ANBZ: #35228 commit 2c4c0c09f9648ba766d399917d420d03e7b3e1f8 stable. commit 9c72a5182ed92904d01057f208c390a303f00a0f upstream. In e1000_tbi_should_accept() we read the last byte of the frame via 'data[length - 1]' to evaluate the TBI workaround. If the descriptor- reported length is zero or larger than the actual RX buffer size, this read goes out of bounds and can hit unrelated slab objects. The issue is observed from the NAPI receive path (e1000_clean_rx_irq): ================================================================== BUG: KASAN: slab-out-of-bounds in e1000_tbi_should_accept+0x610/0x790 Read of size 1 at addr ffff888014114e54 by task sshd/363 CPU: 0 PID: 363 Comm: sshd Not tainted 5.18.0-rc1 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 Call Trace: dump_stack_lvl+0x5a/0x74 print_address_description+0x7b/0x440 print_report+0x101/0x200 kasan_report+0xc1/0xf0 e1000_tbi_should_accept+0x610/0x790 e1000_clean_rx_irq+0xa8c/0x1110 e1000_clean+0xde2/0x3c10 __napi_poll+0x98/0x380 net_rx_action+0x491/0xa20 __do_softirq+0x2c9/0x61d do_softirq+0xd1/0x120 __local_bh_enable_ip+0xfe/0x130 ip_finish_output2+0x7d5/0xb00 __ip_queue_xmit+0xe24/0x1ab0 __tcp_transmit_skb+0x1bcb/0x3340 tcp_write_xmit+0x175d/0x6bd0 __tcp_push_pending_frames+0x7b/0x280 tcp_sendmsg_locked+0x2e4f/0x32d0 tcp_sendmsg+0x24/0x40 sock_write_iter+0x322/0x430 vfs_write+0x56c/0xa60 ksys_write+0xd1/0x190 do_syscall_64+0x43/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f511b476b10 Code: 73 01 c3 48 8b 0d 88 d3 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d f9 2b 2c 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 8e 9b 01 00 48 89 04 24 RSP: 002b:00007ffc9211d4e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000004024 RCX: 00007f511b476b10 RDX: 0000000000004024 RSI: 0000559a9385962c RDI: 0000000000000003 RBP: 0000559a9383a400 R08: fffffffffffffff0 R09: 0000000000004f00 R10: 0000000000000070 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffc9211d57f R14: 0000559a9347bde7 R15: 0000000000000003 Allocated by task 1: __kasan_krealloc+0x131/0x1c0 krealloc+0x90/0xc0 add_sysfs_param+0xcb/0x8a0 kernel_add_sysfs_param+0x81/0xd4 param_sysfs_builtin+0x138/0x1a6 param_sysfs_init+0x57/0x5b do_one_initcall+0x104/0x250 do_initcall_level+0x102/0x132 do_initcalls+0x46/0x74 kernel_init_freeable+0x28f/0x393 kernel_init+0x14/0x1a0 ret_from_fork+0x22/0x30 The buggy address belongs to the object at ffff888014114000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1620 bytes to the right of 2048-byte region [ffff888014114000, ffff888014114800] The buggy address belongs to the physical page: page:ffffea0000504400 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x14110 head:ffffea0000504400 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x100000000010200(slab|head|node=0|zone=1) raw: 0100000000010200 0000000000000000 dead000000000001 ffff888013442000 raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected ================================================================== This happens because the TBI check unconditionally dereferences the last byte without validating the reported length first: u8 last_byte = *(data + length - 1); Fix by rejecting the frame early if the length is zero, or if it exceeds adapter->rx_buffer_len. This preserves the TBI workaround semantics for valid frames and prevents touching memory beyond the RX buffer. Fixes: 2037110c96d5 ("e1000: move tbi workaround code into helper function") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li Reviewed-by: Simon Horman Reviewed-by: Aleksandr Loktionov Signed-off-by: Tony Nguyen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/e1000/e1000_main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index da6e303ad99b..d015a0a85f07 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -4091,7 +4091,15 @@ static bool e1000_tbi_should_accept(struct e1000_adapter *adapter, u32 length, const u8 *data) { struct e1000_hw *hw = &adapter->hw; - u8 last_byte = *(data + length - 1); + u8 last_byte; + + /* Guard against OOB on data[length - 1] */ + if (unlikely(!length)) + return false; + /* Upper bound: length must not exceed rx_buffer_len */ + if (unlikely(length > adapter->rx_buffer_len)) + return false; + last_byte = *(data + length - 1); if (TBI_ACCEPT(hw, status, errors, length, last_byte)) { unsigned long irq_flags; -- Gitee From 5e3ad06c056edce72c357ba6475a3235aa778ee5 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 11 Dec 2025 15:37:56 +0800 Subject: [PATCH 0775/1449] fjes: Add missing iounmap in fjes_hw_init() ANBZ: #35228 commit ad6ea65f154b1746d1fa37183e824985bf568d2f stable. commit 15ef641a0c6728d25a400df73922e80ab2cf029c upstream. In error paths, add fjes_hw_iounmap() to release the resource acquired by fjes_hw_iomap(). Add a goto label to do so. Fixes: 8cdc3f6c5d22 ("fjes: Hardware initialization routine") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Signed-off-by: Simon Horman Reviewed-by: Simon Horman Link: https://patch.msgid.link/20251211073756.101824-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/fjes/fjes_hw.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/fjes/fjes_hw.c b/drivers/net/fjes/fjes_hw.c index b9b5554ea862..5ad2673f213d 100644 --- a/drivers/net/fjes/fjes_hw.c +++ b/drivers/net/fjes/fjes_hw.c @@ -334,7 +334,7 @@ int fjes_hw_init(struct fjes_hw *hw) ret = fjes_hw_reset(hw); if (ret) - return ret; + goto err_iounmap; fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true); @@ -347,8 +347,10 @@ int fjes_hw_init(struct fjes_hw *hw) hw->max_epid = fjes_hw_get_max_epid(hw); hw->my_epid = fjes_hw_get_my_epid(hw); - if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid)) - return -ENXIO; + if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid)) { + ret = -ENXIO; + goto err_iounmap; + } ret = fjes_hw_setup(hw); @@ -356,6 +358,10 @@ int fjes_hw_init(struct fjes_hw *hw) hw->hw_info.trace_size = FJES_DEBUG_BUFFER_SIZE; return ret; + +err_iounmap: + fjes_hw_iounmap(hw); + return ret; } void fjes_hw_exit(struct fjes_hw *hw) -- Gitee From 703cf279e12b4545535244aa311212ba26f7a888 Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Wed, 31 Dec 2025 15:19:20 +0800 Subject: [PATCH 0776/1449] LoongArch: BPF: Zero-extend bpf_tail_call() index ANBZ: #35228 commit 446c851e338b2ab89f152ac5d4a9ca080dbc44d3 stable. commit eb71f5c433e1c6dff089b315881dec40a88a7baf upstream. The bpf_tail_call() index should be treated as a u32 value. Let's zero-extend it to avoid calling wrong BPF progs. See similar fixes for x86 [1]) and arm64 ([2]) for more details. [1]: https://github.com/torvalds/linux/commit/90caccdd8cc0215705f18b92771b449b01e2474a [2]: https://github.com/torvalds/linux/commit/16338a9b3ac30740d49f5dfed81bac0ffa53b9c7 Cc: stable@vger.kernel.org Fixes: 5dc615520c4d ("LoongArch: Add BPF JIT support") Signed-off-by: Hengqi Chen Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/net/bpf_jit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 869003f1c703..c6400d7b95ee 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -226,6 +226,8 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn) * goto out; */ tc_ninsn = insn ? ctx->offset[insn+1] - ctx->offset[insn] : ctx->offset[0]; + emit_zext_32(ctx, a2, true); + off = offsetof(struct bpf_array, map.max_entries); emit_insn(ctx, ldwu, t1, a1, off); /* bgeu $a2, $t1, jmp_offset */ -- Gitee From aa4022315b1a322ec0b9c0bcdc7ec1b128ecc73e Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Wed, 31 Dec 2025 15:19:20 +0800 Subject: [PATCH 0777/1449] LoongArch: BPF: Sign extend kfunc call arguments ANBZ: #35228 commit fd43edf357a3a1f5ed1c4bf450b60001c9091c39 stable. commit 3f5a238f24d7b75f9efe324d3539ad388f58536e upstream. The kfunc calls are native calls so they should follow LoongArch calling conventions. Sign extend its arguments properly to avoid kernel panic. This is done by adding a new emit_abi_ext() helper. The emit_abi_ext() helper performs extension in place meaning a value already store in the target register (Note: this is different from the existing sign_extend() helper and thus we can't reuse it). Cc: stable@vger.kernel.org Fixes: 5dc615520c4d ("LoongArch: Add BPF JIT support") Signed-off-by: Hengqi Chen Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/net/bpf_jit.c | 16 ++++++++++++++++ arch/loongarch/net/bpf_jit.h | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index c6400d7b95ee..54661cffd654 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -834,6 +834,22 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext if (ret < 0) return ret; + if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) { + const struct btf_func_model *m; + int i; + + m = bpf_jit_find_kfunc_model(ctx->prog, insn); + if (!m) + return -EINVAL; + + for (i = 0; i < m->nr_args; i++) { + u8 reg = regmap[BPF_REG_1 + i]; + bool sign = m->arg_flags[i] & BTF_FMODEL_SIGNED_ARG; + + emit_abi_ext(ctx, reg, m->arg_size[i], sign); + } + } + move_addr(ctx, t1, func_addr); emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0); diff --git a/arch/loongarch/net/bpf_jit.h b/arch/loongarch/net/bpf_jit.h index f9c569f53949..9352ea554530 100644 --- a/arch/loongarch/net/bpf_jit.h +++ b/arch/loongarch/net/bpf_jit.h @@ -87,6 +87,32 @@ static inline void emit_sext_32(struct jit_ctx *ctx, enum loongarch_gpr reg, boo emit_insn(ctx, addiw, reg, reg, 0); } +/* Emit proper extension according to ABI requirements. + * Note that it requires a value of size `size` already resides in register `reg`. + */ +static inline void emit_abi_ext(struct jit_ctx *ctx, int reg, u8 size, bool sign) +{ + /* ABI requires unsigned char/short to be zero-extended */ + if (!sign && (size == 1 || size == 2)) + return; + + switch (size) { + case 1: + emit_insn(ctx, extwb, reg, reg); + break; + case 2: + emit_insn(ctx, extwh, reg, reg); + break; + case 4: + emit_insn(ctx, addiw, reg, reg, 0); + break; + case 8: + break; + default: + pr_warn("bpf_jit: invalid size %d for extension\n", size); + } +} + static inline void move_addr(struct jit_ctx *ctx, enum loongarch_gpr rd, u64 addr) { u64 imm_11_0, imm_31_12, imm_51_32, imm_63_52; -- Gitee From b10eac6b72498ed41da46c279138c84095148ced Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Sat, 6 Dec 2025 15:38:42 +0800 Subject: [PATCH 0778/1449] nfsd: Drop the client reference in client_states_open() ANBZ: #35228 commit cff353b7d1c7ec201c14495ce2fcc2b9f4607192 stable. commit 1f941b2c23fd34c6f3b76d36f9d0a2528fa92b8f upstream. In error path, call drop_client() to drop the reference obtained by get_nfsdfs_clp(). Fixes: 78599c42ae3c ("nfsd4: add file to display list of client's opens") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton Signed-off-by: Haoxiang Li Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/nfs4state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9ef1c2372c66..1c9b6bf8f9a7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2801,8 +2801,10 @@ static int client_states_open(struct inode *inode, struct file *file) return -ENXIO; ret = seq_open(file, &states_seq_ops); - if (ret) + if (ret) { + drop_client(clp); return ret; + } s = file->private_data; s->private = clp; return 0; -- Gitee From e450d513252256bcfdceec522617b590f72b5ca0 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Sun, 21 Dec 2025 16:24:00 +0800 Subject: [PATCH 0779/1449] net: usb: sr9700: fix incorrect command used to write single register ANBZ: #35228 commit 907e8a8f506db6841e6536c4b518bafbfb8ffeb4 stable. commit fa0b198be1c6775bc7804731a43be5d899d19e7a upstream. This fixes the device failing to initialize with "error reading MAC address" for me, probably because the incorrect write of NCR_RST to SR_NCR is not actually resetting the device. Fixes: c9b37458e95629b1d1171457afdcc1bf1eb7881d ("USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support") Cc: stable@vger.kernel.org Signed-off-by: Ethan Nelson-Moore Link: https://patch.msgid.link/20251221082400.50688-1-enelsonmoore@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/sr9700.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c index cb7d2f798fb4..9587eb98cdb3 100644 --- a/drivers/net/usb/sr9700.c +++ b/drivers/net/usb/sr9700.c @@ -52,7 +52,7 @@ static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value) static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value) { - return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, + return usbnet_write_cmd(dev, SR_WR_REG, SR_REQ_WR_REG, value, reg, NULL, 0); } @@ -65,7 +65,7 @@ static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value) { - usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, + usbnet_write_cmd_async(dev, SR_WR_REG, SR_REQ_WR_REG, value, reg, NULL, 0); } -- Gitee From 9a520a5bc3141c2fe0efb66a43d3902ad99346e5 Mon Sep 17 00:00:00 2001 From: Deepanshu Kartikey Date: Thu, 18 Dec 2025 09:23:54 +0800 Subject: [PATCH 0780/1449] net: nfc: fix deadlock between nfc_unregister_device and rfkill_fop_write ANBZ: #35228 commit 6b93c8ab6f6cda8818983a4ae3fcf84b023037b4 stable. commit 1ab526d97a57e44d26fadcc0e9adeb9c0c0182f5 upstream. A deadlock can occur between nfc_unregister_device() and rfkill_fop_write() due to lock ordering inversion between device_lock and rfkill_global_mutex. The problematic lock order is: Thread A (rfkill_fop_write): rfkill_fop_write() mutex_lock(&rfkill_global_mutex) rfkill_set_block() nfc_rfkill_set_block() nfc_dev_down() device_lock(&dev->dev) <- waits for device_lock Thread B (nfc_unregister_device): nfc_unregister_device() device_lock(&dev->dev) rfkill_unregister() mutex_lock(&rfkill_global_mutex) <- waits for rfkill_global_mutex This creates a classic ABBA deadlock scenario. Fix this by moving rfkill_unregister() and rfkill_destroy() outside the device_lock critical section. Store the rfkill pointer in a local variable before releasing the lock, then call rfkill_unregister() after releasing device_lock. This change is safe because rfkill_fop_write() holds rfkill_global_mutex while calling the rfkill callbacks, and rfkill_unregister() also acquires rfkill_global_mutex before cleanup. Therefore, rfkill_unregister() will wait for any ongoing callback to complete before proceeding, and device_del() is only called after rfkill_unregister() returns, preventing any use-after-free. The similar lock ordering in nfc_register_device() (device_lock -> rfkill_global_mutex via rfkill_register) is safe because during registration the device is not yet in rfkill_list, so no concurrent rfkill operations can occur on this device. Fixes: 3e3b5dfcd16a ("NFC: reorder the logic in nfc_{un,}register_device") Cc: stable@vger.kernel.org Reported-by: syzbot+4ef89409a235d804c6c2@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4ef89409a235d804c6c2 Link: https://lore.kernel.org/all/20251217054908.178907-1-kartikey406@gmail.com/T/ [v1] Signed-off-by: Deepanshu Kartikey Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251218012355.279940-1-kartikey406@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/nfc/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/nfc/core.c b/net/nfc/core.c index eb2c0959e5b6..5352571b6214 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -1154,6 +1154,7 @@ EXPORT_SYMBOL(nfc_register_device); void nfc_unregister_device(struct nfc_dev *dev) { int rc; + struct rfkill *rfk = NULL; pr_debug("dev_name=%s\n", dev_name(&dev->dev)); @@ -1164,13 +1165,17 @@ void nfc_unregister_device(struct nfc_dev *dev) device_lock(&dev->dev); if (dev->rfkill) { - rfkill_unregister(dev->rfkill); - rfkill_destroy(dev->rfkill); + rfk = dev->rfkill; dev->rfkill = NULL; } dev->shutting_down = true; device_unlock(&dev->dev); + if (rfk) { + rfkill_unregister(rfk); + rfkill_destroy(rfk); + } + if (dev->ops->check_presence) { del_timer_sync(&dev->check_pres_timer); cancel_work_sync(&dev->check_pres_work); -- Gitee From 9e3bdebfbcbed0ecbe5c8eb5889e14691a9911f3 Mon Sep 17 00:00:00 2001 From: Xiaolei Wang Date: Mon, 22 Dec 2025 09:56:24 +0800 Subject: [PATCH 0781/1449] net: macb: Relocate mog_init_rings() callback from macb_mac_link_up() to macb_open() ANBZ: #35228 commit 9a8837f9a3e382eb1faadaf2079b2e799e4211e4 stable. commit 99537d5c476cada9cf75aef9fa75579a31faadb9 upstream. In the non-RT kernel, local_bh_disable() merely disables preemption, whereas it maps to an actual spin lock in the RT kernel. Consequently, when attempting to refill RX buffers via netdev_alloc_skb() in macb_mac_link_up(), a deadlock scenario arises as follows: WARNING: possible circular locking dependency detected 6.18.0-08691-g2061f18ad76e #39 Not tainted ------------------------------------------------------ kworker/0:0/8 is trying to acquire lock: ffff00080369bbe0 (&bp->lock){+.+.}-{3:3}, at: macb_start_xmit+0x808/0xb7c but task is already holding lock: ffff000803698e58 (&queue->tx_ptr_lock){+...}-{3:3}, at: macb_start_xmit +0x148/0xb7c which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (&queue->tx_ptr_lock){+...}-{3:3}: rt_spin_lock+0x50/0x1f0 macb_start_xmit+0x148/0xb7c dev_hard_start_xmit+0x94/0x284 sch_direct_xmit+0x8c/0x37c __dev_queue_xmit+0x708/0x1120 neigh_resolve_output+0x148/0x28c ip6_finish_output2+0x2c0/0xb2c __ip6_finish_output+0x114/0x308 ip6_output+0xc4/0x4a4 mld_sendpack+0x220/0x68c mld_ifc_work+0x2a8/0x4f4 process_one_work+0x20c/0x5f8 worker_thread+0x1b0/0x35c kthread+0x144/0x200 ret_from_fork+0x10/0x20 -> #2 (_xmit_ETHER#2){+...}-{3:3}: rt_spin_lock+0x50/0x1f0 sch_direct_xmit+0x11c/0x37c __dev_queue_xmit+0x708/0x1120 neigh_resolve_output+0x148/0x28c ip6_finish_output2+0x2c0/0xb2c __ip6_finish_output+0x114/0x308 ip6_output+0xc4/0x4a4 mld_sendpack+0x220/0x68c mld_ifc_work+0x2a8/0x4f4 process_one_work+0x20c/0x5f8 worker_thread+0x1b0/0x35c kthread+0x144/0x200 ret_from_fork+0x10/0x20 -> #1 ((softirq_ctrl.lock)){+.+.}-{3:3}: lock_release+0x250/0x348 __local_bh_enable_ip+0x7c/0x240 __netdev_alloc_skb+0x1b4/0x1d8 gem_rx_refill+0xdc/0x240 gem_init_rings+0xb4/0x108 macb_mac_link_up+0x9c/0x2b4 phylink_resolve+0x170/0x614 process_one_work+0x20c/0x5f8 worker_thread+0x1b0/0x35c kthread+0x144/0x200 ret_from_fork+0x10/0x20 -> #0 (&bp->lock){+.+.}-{3:3}: __lock_acquire+0x15a8/0x2084 lock_acquire+0x1cc/0x350 rt_spin_lock+0x50/0x1f0 macb_start_xmit+0x808/0xb7c dev_hard_start_xmit+0x94/0x284 sch_direct_xmit+0x8c/0x37c __dev_queue_xmit+0x708/0x1120 neigh_resolve_output+0x148/0x28c ip6_finish_output2+0x2c0/0xb2c __ip6_finish_output+0x114/0x308 ip6_output+0xc4/0x4a4 mld_sendpack+0x220/0x68c mld_ifc_work+0x2a8/0x4f4 process_one_work+0x20c/0x5f8 worker_thread+0x1b0/0x35c kthread+0x144/0x200 ret_from_fork+0x10/0x20 other info that might help us debug this: Chain exists of: &bp->lock --> _xmit_ETHER#2 --> &queue->tx_ptr_lock Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&queue->tx_ptr_lock); lock(_xmit_ETHER#2); lock(&queue->tx_ptr_lock); lock(&bp->lock); *** DEADLOCK *** Call trace: show_stack+0x18/0x24 (C) dump_stack_lvl+0xa0/0xf0 dump_stack+0x18/0x24 print_circular_bug+0x28c/0x370 check_noncircular+0x198/0x1ac __lock_acquire+0x15a8/0x2084 lock_acquire+0x1cc/0x350 rt_spin_lock+0x50/0x1f0 macb_start_xmit+0x808/0xb7c dev_hard_start_xmit+0x94/0x284 sch_direct_xmit+0x8c/0x37c __dev_queue_xmit+0x708/0x1120 neigh_resolve_output+0x148/0x28c ip6_finish_output2+0x2c0/0xb2c __ip6_finish_output+0x114/0x308 ip6_output+0xc4/0x4a4 mld_sendpack+0x220/0x68c mld_ifc_work+0x2a8/0x4f4 process_one_work+0x20c/0x5f8 worker_thread+0x1b0/0x35c kthread+0x144/0x200 ret_from_fork+0x10/0x20 Notably, invoking the mog_init_rings() callback upon link establishment is unnecessary. Instead, we can exclusively call mog_init_rings() within the ndo_open() callback. This adjustment resolves the deadlock issue. Furthermore, since MACB_CAPS_MACB_IS_EMAC cases do not use mog_init_rings() when opening the network interface via at91ether_open(), moving mog_init_rings() to macb_open() also eliminates the MACB_CAPS_MACB_IS_EMAC check. Fixes: 633e98a711ac ("net: macb: use resolved link config in mac_link_up()") Cc: stable@vger.kernel.org Suggested-by: Kevin Hao Signed-off-by: Xiaolei Wang Link: https://patch.msgid.link/20251222015624.1994551-1-xiaolei.wang@windriver.com Signed-off-by: Paolo Abeni Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/cadence/macb_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index bf7b5d1d5616..5cbda8ccdbf0 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -759,7 +759,6 @@ static void macb_mac_link_up(struct phylink_config *config, /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down * cleared the pipeline and control registers. */ - bp->macbgem_ops.mog_init_rings(bp); macb_init_buffers(bp); for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) @@ -2953,6 +2952,8 @@ static int macb_open(struct net_device *dev) goto pm_exit; } + bp->macbgem_ops.mog_init_rings(bp); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { napi_enable(&queue->napi_rx); napi_enable(&queue->napi_tx); -- Gitee From 6d8855c5b910d94d89a8757f9a4b76fd4078941a Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 25 Nov 2025 17:48:39 +0800 Subject: [PATCH 0782/1449] drm/amdgpu: add missing lock to amdgpu_ttm_access_memory_sdma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e05d53454b55fd999e48ddad8cf752f0e2347b63 stable. commit 4fa944255be521b1bbd9780383f77206303a3a5c upstream. Users of ttm entities need to hold the gtt_window_lock before using them to guarantee proper ordering of jobs. Cc: stable@vger.kernel.org Fixes: cb5cc4f573e1 ("drm/amdgpu: improve debug VRAM access performance using sdma") Signed-off-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Christian König Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 69dfc3da5e15..c56405b49050 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1495,6 +1495,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, if (r) goto out; + mutex_lock(&adev->mman.gtt_window_lock); amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm); src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) + src_mm.start; @@ -1509,6 +1510,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, WARN_ON(job->ibs[0].length_dw > num_dw); fence = amdgpu_job_submit(job); + mutex_unlock(&adev->mman.gtt_window_lock); if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout)) r = -ETIMEDOUT; -- Gitee From 01d488082abcc8af813f99e5cb6a02854ad912ca Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Tue, 18 Nov 2025 16:50:28 +0800 Subject: [PATCH 0783/1449] drm/msm/a6xx: Fix out of bound IO access in a6xx_get_gmu_registers ANBZ: #35228 commit f6916363112cd8f6d7f1924062b054029a7910e2 stable. commit 779b68a5bf2764c8ed3aa800e41ba0d5d007e1e7 upstream. REG_A6XX_GMU_AO_AHB_FENCE_CTRL register falls under GMU's register range. So, use gmu_write() routines to write to this register. Fixes: 1707add81551 ("drm/msm/a6xx: Add a6xx gpu state") Cc: stable@vger.kernel.org Signed-off-by: Akhil P Oommen Reviewed-by: Konrad Dybcio Patchwork: https://patchwork.freedesktop.org/patch/688993/ Message-ID: <20251118-kaana-gpu-support-v4-1-86eeb8e93fb6@oss.qualcomm.com> Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 4e5d650578c6..258de1bfc570 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -834,7 +834,7 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, return; /* Set the fence to ALLOW mode so we can access the registers */ - gpu_write(gpu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); + gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[2], &a6xx_state->gmu_registers[2], false); -- Gitee From 5af729d5b48e1269e85f5374a76560fab8bc4c08 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 29 Sep 2025 16:23:23 +0800 Subject: [PATCH 0784/1449] drm/gma500: Remove unused helper psb_fbdev_fb_setcolreg() ANBZ: #35228 commit ed51ddd5d449e3878111d038f5b31fddbb9b42f1 stable. commit be729f9de6c64240645dc80a24162ac4d3fe00a8 upstream. Remove psb_fbdev_fb_setcolreg(), which hasn't been called in almost a decade. Gma500 commit 4d8d096e9ae8 ("gma500: introduce the framebuffer support code") added the helper psb_fbdev_fb_setcolreg() for setting the fbdev palette via fbdev's fb_setcolreg callback. Later commit 3da6c2f3b730 ("drm/gma500: use DRM_FB_HELPER_DEFAULT_OPS for fb_ops") set several default helpers for fbdev emulation, including fb_setcmap. The fbdev subsystem always prefers fb_setcmap over fb_setcolreg. [1] Hence, the gma500 code is no longer in use and gma500 has been using drm_fb_helper_setcmap() for several years without issues. Fixes: 3da6c2f3b730 ("drm/gma500: use DRM_FB_HELPER_DEFAULT_OPS for fb_ops") Cc: Patrik Jakobsson Cc: Stefan Christ Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: # v4.10+ Link: https://elixir.bootlin.com/linux/v6.16.9/source/drivers/video/fbdev/core/fbcmap.c#L246 # [1] Signed-off-by: Thomas Zimmermann Acked-by: Patrik Jakobsson Link: https://lore.kernel.org/r/20250929082338.18845-1-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/gma500/fbdev.c | 43 ---------------------------------- 1 file changed, 43 deletions(-) diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c index 98b44974d42d..8e3128298728 100644 --- a/drivers/gpu/drm/gma500/fbdev.c +++ b/drivers/gpu/drm/gma500/fbdev.c @@ -51,48 +51,6 @@ static const struct vm_operations_struct psb_fbdev_vm_ops = { * struct fb_ops */ -#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) - -static int psb_fbdev_fb_setcolreg(unsigned int regno, - unsigned int red, unsigned int green, - unsigned int blue, unsigned int transp, - struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_framebuffer *fb = fb_helper->fb; - uint32_t v; - - if (!fb) - return -ENOMEM; - - if (regno > 255) - return 1; - - red = CMAP_TOHW(red, info->var.red.length); - blue = CMAP_TOHW(blue, info->var.blue.length); - green = CMAP_TOHW(green, info->var.green.length); - transp = CMAP_TOHW(transp, info->var.transp.length); - - v = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset) | - (transp << info->var.transp.offset); - - if (regno < 16) { - switch (fb->format->cpp[0] * 8) { - case 16: - ((uint32_t *) info->pseudo_palette)[regno] = v; - break; - case 24: - case 32: - ((uint32_t *) info->pseudo_palette)[regno] = v; - break; - } - } - - return 0; -} - static int psb_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { if (vma->vm_pgoff != 0) @@ -137,7 +95,6 @@ static const struct fb_ops psb_fbdev_fb_ops = { .owner = THIS_MODULE, __FB_DEFAULT_IOMEM_OPS_RDWR, DRM_FB_HELPER_DEFAULT_OPS, - .fb_setcolreg = psb_fbdev_fb_setcolreg, __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = psb_fbdev_fb_mmap, .fb_destroy = psb_fbdev_fb_destroy, -- Gitee From c1bf036a67dcf48b03c02de8d53306fa4aaab453 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 29 Oct 2025 15:23:06 +0800 Subject: [PATCH 0785/1449] drm/mediatek: Fix device node reference leak in mtk_dp_dt_parse() ANBZ: #35228 commit 3144af03d51783549ef0e25ab2c03b7f4bc3e2ab stable. commit a846505a193d7492ad3531e33cacfca31e4bcdd1 upstream. The function mtk_dp_dt_parse() calls of_graph_get_endpoint_by_regs() to get the endpoint device node, but fails to call of_node_put() to release the reference when the function returns. This results in a device node reference leak. Fix this by adding the missing of_node_put() call before returning from the function. Found via static analysis and code review. Fixes: f70ac097a2cf ("drm/mediatek: Add MT8195 Embedded DisplayPort driver") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Reviewed-by: Markus Schneider-Pargmann Reviewed-by: CK Hu Link: https://patchwork.kernel.org/project/dri-devel/patch/20251029072307.10955-1-linmq006@gmail.com/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/mediatek/mtk_dp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 199527643093..0cc3e2318754 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -1969,6 +1969,7 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp, endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 1, -1); len = of_property_count_elems_of_size(endpoint, "data-lanes", sizeof(u32)); + of_node_put(endpoint); if (len < 0 || len > 4 || len == 3) { dev_err(dev, "invalid data lane size: %d\n", len); return -EINVAL; -- Gitee From 0ba7255c1c5042647992c225ac224fb17b2a317c Mon Sep 17 00:00:00 2001 From: Simon Richter Date: Tue, 14 Oct 2025 00:11:33 +0800 Subject: [PATCH 0786/1449] drm/ttm: Avoid NULL pointer deref for evicted BOs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 3d004f7341d4898889801ebb2ef61ffca610dd6f stable. commit 491adc6a0f9903c32b05f284df1148de39e8e644 upstream. It is possible for a BO to exist that is not currently associated with a resource, e.g. because it has been evicted. When devcoredump tries to read the contents of all BOs for dumping, we need to expect this as well -- in this case, ENODATA is recorded instead of the buffer contents. Fixes: 7d08df5d0bd3 ("drm/ttm: Add ttm_bo_access") Fixes: 09ac4fcb3f25 ("drm/ttm: Implement vm_operations_struct.access v2") Cc: stable Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6271 Signed-off-by: Simon Richter Reviewed-by: Matthew Brost Reviewed-by: Shuicheng Lin Reviewed-by: Christian König Signed-off-by: Matthew Brost Link: https://patch.msgid.link/20251013161241.709916-1-Simon.Richter@hogyros.de Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 4212b8c91dd4..d69d71ed7dd9 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -421,6 +421,11 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, if (ret) return ret; + if (!bo->resource) { + ret = -ENODATA; + goto unlock; + } + switch (bo->resource->mem_type) { case TTM_PL_SYSTEM: fallthrough; @@ -435,6 +440,7 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, ret = -EIO; } +unlock: ttm_bo_unreserve(bo); return ret; -- Gitee From 28842ca57325572043bbc681450cb4e474ffa58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Mon, 8 Dec 2025 21:18:27 +0800 Subject: [PATCH 0787/1449] drm/mgag200: Fix big-endian support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 56f07bc0a0ff9b125179296110306b7bc421e26f stable. commit 6cb31fba137d45e682ce455b8ea364f44d5d4f98 upstream. Unlike the original, deleted Matrox mga driver, the new mgag200 driver has the XRGB frame-buffer byte swapped on big-endian "RISC" systems. Fix by enabling byte swapping "PowerPC" OPMODE for any __BIG_ENDIAN config. Fixes: 414c45310625 ("mgag200: initial g200se driver (v2)") Signed-off-by: René Rebe Cc: stable@kernel.org Reviewed-by: Thomas Zimmermann Signed-off-by: Thomas Zimmermann Link: https://patch.msgid.link/20251208.141827.965103015954471168.rene@exactco.de Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/mgag200/mgag200_mode.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 0f0d59938c3a..8e552107d80d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -173,6 +173,30 @@ static void mgag200_set_startadd(struct mga_device *mdev, WREG_ECRT(0x00, crtcext0); } +/* + * Set the opmode for the hardware swapper for Big-Endian processor + * support for the frame buffer aperture and DMAWIN space. + */ +static void mgag200_set_datasiz(struct mga_device *mdev, u32 format) +{ +#if defined(__BIG_ENDIAN) + u32 opmode = RREG32(MGAREG_OPMODE); + + opmode &= ~(GENMASK(17, 16) | GENMASK(9, 8) | GENMASK(3, 2)); + + /* Big-endian byte-swapping */ + switch (format) { + case DRM_FORMAT_RGB565: + opmode |= 0x10100; + break; + case DRM_FORMAT_XRGB8888: + opmode |= 0x20200; + break; + } + WREG32(MGAREG_OPMODE, opmode); +#endif +} + void mgag200_init_registers(struct mga_device *mdev) { u8 crtc11, misc; @@ -502,6 +526,7 @@ void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane, struct drm_atomic_helper_damage_iter iter; struct drm_rect damage; + mgag200_set_datasiz(mdev, fb->format->format); drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); drm_atomic_for_each_plane_damage(&iter, &damage) { mgag200_handle_damage(mdev, shadow_plane_state->data, fb, &damage); -- Gitee From 421b1001da00e3af3958aebe21605cb5b6e3859b Mon Sep 17 00:00:00 2001 From: Nikolay Kuratov Date: Thu, 11 Dec 2025 17:36:30 +0800 Subject: [PATCH 0788/1449] drm/msm/dpu: Add missing NULL pointer check for pingpong interface ANBZ: #35228 commit 678d1c86566dfbb247ba25482d37fddde6140cc9 stable. commit 88733a0b64872357e5ecd82b7488121503cb9cc6 upstream. It is checked almost always in dpu_encoder_phys_wb_setup_ctl(), but in a single place the check is missing. Also use convenient locals instead of phys_enc->* where available. Cc: stable@vger.kernel.org Fixes: d7d0e73f7de33 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback") Signed-off-by: Nikolay Kuratov Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/693860/ Link: https://lore.kernel.org/r/20251211093630.171014-1-kniv@yandex-team.ru Signed-off-by: Dmitry Baryshkov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index a5cd41c9224d..b6c7169b24ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -205,14 +205,12 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) if (mode_3d && hw_pp && hw_pp->merge_3d) intf_cfg.merge_3d = hw_pp->merge_3d->idx; - if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode) - phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, - mode_3d); + if (hw_pp && hw_pp->merge_3d && hw_pp->merge_3d->ops.setup_3d_mode) + hw_pp->merge_3d->ops.setup_3d_mode(hw_pp->merge_3d, mode_3d); /* setup which pp blk will connect to this wb */ - if (hw_pp && phys_enc->hw_wb->ops.bind_pingpong_blk) - phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, - phys_enc->hw_pp->idx); + if (hw_pp && hw_wb->ops.bind_pingpong_blk) + hw_wb->ops.bind_pingpong_blk(hw_wb, hw_pp->idx); phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg); } else if (phys_enc->hw_ctl && phys_enc->hw_ctl->ops.setup_intf_cfg) { -- Gitee From dbbad81a4a0b8fc35037b132d18352d13c94042d Mon Sep 17 00:00:00 2001 From: Krzysztof Niemiec Date: Wed, 17 Dec 2025 02:09:01 +0800 Subject: [PATCH 0789/1449] drm/i915/gem: Zero-initialize the eb.vma array in i915_gem_do_execbuffer ANBZ: #35228 commit 0336188cc85d0eab8463bd1bbd4ded4e9602de8b stable. commit 4fe2bd195435e71c117983d87f278112c5ab364c upstream. Initialize the eb.vma array with values of 0 when the eb structure is first set up. In particular, this sets the eb->vma[i].vma pointers to NULL, simplifying cleanup and getting rid of the bug described below. During the execution of eb_lookup_vmas(), the eb->vma array is successively filled up with struct eb_vma objects. This process includes calling eb_add_vma(), which might fail; however, even in the event of failure, eb->vma[i].vma is set for the currently processed buffer. If eb_add_vma() fails, eb_lookup_vmas() returns with an error, which prompts a call to eb_release_vmas() to clean up the mess. Since eb_lookup_vmas() might fail during processing any (possibly not first) buffer, eb_release_vmas() checks whether a buffer's vma is NULL to know at what point did the lookup function fail. In eb_lookup_vmas(), eb->vma[i].vma is set to NULL if either the helper function eb_lookup_vma() or eb_validate_vma() fails. eb->vma[i+1].vma is set to NULL in case i915_gem_object_userptr_submit_init() fails; the current one needs to be cleaned up by eb_release_vmas() at this point, so the next one is set. If eb_add_vma() fails, neither the current nor the next vma is set to NULL, which is a source of a NULL deref bug described in the issue linked in the Closes tag. When entering eb_lookup_vmas(), the vma pointers are set to the slab poison value, instead of NULL. This doesn't matter for the actual lookup, since it gets overwritten anyway, however the eb_release_vmas() function only recognizes NULL as the stopping value, hence the pointers are being set to NULL as they go in case of intermediate failure. This patch changes the approach to filling them all with NULL at the start instead, rather than handling that manually during failure. Reported-by: Gangmin Kim Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15062 Fixes: 544460c33821 ("drm/i915: Multi-BB execbuf") Cc: stable@vger.kernel.org # 5.16.x Signed-off-by: Krzysztof Niemiec Reviewed-by: Janusz Krzysztofik Reviewed-by: Krzysztof Karas Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20251216180900.54294-2-krzysztof.niemiec@intel.com (cherry picked from commit 08889b706d4f0b8d2352b7ca29c2d8df4d0787cd) Signed-off-by: Jani Nikula Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 5a687a3686bd..e208cc8c2ac1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -950,13 +950,13 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) vma = eb_lookup_vma(eb, eb->exec[i].handle); if (IS_ERR(vma)) { err = PTR_ERR(vma); - goto err; + return err; } err = eb_validate_vma(eb, &eb->exec[i], vma); if (unlikely(err)) { i915_vma_put(vma); - goto err; + return err; } err = eb_add_vma(eb, ¤t_batch, i, vma); @@ -965,19 +965,8 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) if (i915_gem_object_is_userptr(vma->obj)) { err = i915_gem_object_userptr_submit_init(vma->obj); - if (err) { - if (i + 1 < eb->buffer_count) { - /* - * Execbuffer code expects last vma entry to be NULL, - * since we already initialized this entry, - * set the next value to NULL or we mess up - * cleanup handling. - */ - eb->vma[i + 1].vma = NULL; - } - + if (err) return err; - } eb->vma[i].flags |= __EXEC_OBJECT_USERPTR_INIT; eb->args->flags |= __EXEC_USERPTR_USED; @@ -985,10 +974,6 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) } return 0; - -err: - eb->vma[i].vma = NULL; - return err; } static int eb_lock_vmas(struct i915_execbuffer *eb) @@ -3381,7 +3366,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, eb.exec = exec; eb.vma = (struct eb_vma *)(exec + args->buffer_count + 1); - eb.vma[0].vma = NULL; + memset(eb.vma, 0, (args->buffer_count + 1) * sizeof(struct eb_vma)); + eb.batch_pool = NULL; eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS; @@ -3590,7 +3576,18 @@ i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, if (err) return err; - /* Allocate extra slots for use by the command parser */ + /* + * Allocate extra slots for use by the command parser. + * + * Note that this allocation handles two different arrays (the + * exec2_list array, and the eventual eb.vma array introduced in + * i915_gem_do_execbuffer()), that reside in virtually contiguous + * memory. Also note that the allocation intentionally doesn't fill the + * area with zeros, because the exec2_list part doesn't need to be, as + * it's immediately overwritten by user data a few lines below. + * However, the eb.vma part is explicitly zeroed later in + * i915_gem_do_execbuffer(). + */ exec2_list = kvmalloc_array(count + 2, eb_element_size(), __GFP_NOWARN | GFP_KERNEL); if (exec2_list == NULL) { -- Gitee From f0c0f15ff400f7c9ed3da5bd14cdcc9290c3d26d Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Fri, 12 Dec 2025 03:02:54 +0800 Subject: [PATCH 0790/1449] drm/nouveau/dispnv50: Don't call drm_atomic_get_crtc_state() in prepare_fb ANBZ: #35228 commit 23525fc0ea623006eff32bd6df8753b3d24f5d2b stable. commit 560271e10b2c86e95ea35afa9e79822e4847f07a upstream. Since we recently started warning about uses of this function after the atomic check phase completes, we've started getting warnings about this in nouveau. It appears a misplaced drm_atomic_get_crtc_state() call has been hiding in our .prepare_fb callback for a while. So, fix this by adding a new nv50_head_atom_get_new() function and use that in our .prepare_fb callback instead. Signed-off-by: Lyude Paul Reviewed-by: Dave Airlie Fixes: 1590700d94ac ("drm/nouveau/kms/nv50-: split each resource type into their own source files") Cc: # v4.18+ Link: https://patch.msgid.link/20251211190256.396742-1-lyude@redhat.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 13 +++++++++++++ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index 93f8f4f64578..b43c4f9bbcdf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -152,8 +152,21 @@ static inline struct nv50_head_atom * nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) { struct drm_crtc_state *statec = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(statec)) return (void *)statec; + + return nv50_head_atom(statec); +} + +static inline struct nv50_head_atom * +nv50_head_atom_get_new(struct drm_atomic_state *state, struct drm_crtc *crtc) +{ + struct drm_crtc_state *statec = drm_atomic_get_new_crtc_state(state, crtc); + + if (!statec) + return NULL; + return nv50_head_atom(statec); } diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 1199dfc1194c..527fabc5b1ba 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -567,7 +567,7 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) asyw->image.offset[0] = nvbo->offset; if (wndw->func->prepare) { - asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); + asyh = nv50_head_atom_get_new(asyw->state.state, asyw->state.crtc); if (IS_ERR(asyh)) return PTR_ERR(asyh); -- Gitee From 6076624f61f7b935a5a8b8582470b09b098d9ac5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 18 Dec 2025 23:35:15 +0800 Subject: [PATCH 0791/1449] usb: gadget: lpc32xx_udc: fix clock imbalance in error path ANBZ: #35228 commit 9202337a2d903c25963b39e900a6571a932c3924 stable. commit 782be79e4551550d7a82b1957fc0f7347e6d461f upstream. A recent change fixing a device reference leak introduced a clock imbalance by reusing an error path so that the clock may be disabled before having been enabled. Note that the clock framework allows for passing in NULL clocks so there is no risk for a NULL pointer dereference. Also drop the bogus I2C client NULL check added by the offending commit as the pointer has already been verified to be non-NULL. Fixes: c84117912bdd ("USB: lpc32xx_udc: Fix error handling in probe") Cc: stable@vger.kernel.org Cc: Ma Ke Signed-off-by: Johan Hovold Reviewed-by: Vladimir Zapolskiy Link: https://patch.msgid.link/20251218153519.19453-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/gadget/udc/lpc32xx_udc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 6085ffd0c470..52413fbdafcc 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3027,7 +3027,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) pdev->dev.dma_mask = &lpc32xx_usbd_dmamask; retval = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (retval) - goto i2c_fail; + goto err_put_client; udc->board = &lpc32xx_usbddata; @@ -3047,7 +3047,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) udc->udp_irq[i] = platform_get_irq(pdev, i); if (udc->udp_irq[i] < 0) { retval = udc->udp_irq[i]; - goto i2c_fail; + goto err_put_client; } } @@ -3055,7 +3055,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) if (IS_ERR(udc->udp_baseaddr)) { dev_err(udc->dev, "IO map failure\n"); retval = PTR_ERR(udc->udp_baseaddr); - goto i2c_fail; + goto err_put_client; } /* Get USB device clock */ @@ -3063,14 +3063,14 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) if (IS_ERR(udc->usb_slv_clk)) { dev_err(udc->dev, "failed to acquire USB device clock\n"); retval = PTR_ERR(udc->usb_slv_clk); - goto i2c_fail; + goto err_put_client; } /* Enable USB device clock */ retval = clk_prepare_enable(udc->usb_slv_clk); if (retval < 0) { dev_err(udc->dev, "failed to start USB device clock\n"); - goto i2c_fail; + goto err_put_client; } /* Setup deferred workqueue data */ @@ -3172,9 +3172,10 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); i2c_fail: - if (udc->isp1301_i2c_client) - put_device(&udc->isp1301_i2c_client->dev); clk_disable_unprepare(udc->usb_slv_clk); +err_put_client: + put_device(&udc->isp1301_i2c_client->dev); + dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval); return retval; @@ -3199,11 +3200,10 @@ static int lpc32xx_udc_remove(struct platform_device *pdev) dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, udc->udca_v_base, udc->udca_p_base); - if (udc->isp1301_i2c_client) - put_device(&udc->isp1301_i2c_client->dev); - clk_disable_unprepare(udc->usb_slv_clk); + put_device(&udc->isp1301_i2c_client->dev); + return 0; } -- Gitee From 59a0ed32d2ff1dfa8858397ec4ad1c86a8d418c7 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 17 May 2024 10:05:14 +0800 Subject: [PATCH 0792/1449] blk-mq: add helper for checking if one CPU is mapped to specified hctx ANBZ: #35228 commit dbd0829d2458d7292b82bfc9d02cce23935b198f stable. commit 7b815817aa58d2e2101feb2fcf64c60cae0b2695 upstream. Commit a46c27026da1 ("blk-mq: don't schedule block kworker on isolated CPUs") rules out isolated CPUs from hctx->cpumask, and hctx->cpumask should only be used for scheduling kworker. Add helper blk_mq_cpu_mapped_to_hctx() and apply it into cpuhp handlers. This patch avoids to forget clearing INACTIVE of hctx state in case that one isolated CPU becomes online, and fixes hang issue when allocating request from this hctx's tags. Cc: Raju Cheerla Fixes: a46c27026da1 ("blk-mq: don't schedule block kworker on isolated CPUs") Signed-off-by: Ming Lei Link: https://lore.kernel.org/r/20240517020514.149771-1-ming.lei@redhat.com Tested-by: Raju Cheerla Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- block/blk-mq.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index b78f5cc3bea8..71868fc67338 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3682,12 +3682,28 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node) return ret; } +/* + * Check if one CPU is mapped to the specified hctx + * + * Isolated CPUs have been ruled out from hctx->cpumask, which is supposed + * to be used for scheduling kworker only. For other usage, please call this + * helper for checking if one CPU belongs to the specified hctx + */ +static bool blk_mq_cpu_mapped_to_hctx(unsigned int cpu, + const struct blk_mq_hw_ctx *hctx) +{ + struct blk_mq_hw_ctx *mapped_hctx = blk_mq_map_queue_type(hctx->queue, + hctx->type, cpu); + + return mapped_hctx == hctx; +} + static int blk_mq_hctx_notify_online(unsigned int cpu, struct hlist_node *node) { struct blk_mq_hw_ctx *hctx = hlist_entry_safe(node, struct blk_mq_hw_ctx, cpuhp_online); - if (cpumask_test_cpu(cpu, hctx->cpumask)) + if (blk_mq_cpu_mapped_to_hctx(cpu, hctx)) clear_bit(BLK_MQ_S_INACTIVE, &hctx->state); return 0; } @@ -3705,7 +3721,7 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node) enum hctx_type type; hctx = hlist_entry_safe(node, struct blk_mq_hw_ctx, cpuhp_dead); - if (!cpumask_test_cpu(cpu, hctx->cpumask)) + if (!blk_mq_cpu_mapped_to_hctx(cpu, hctx)) return 0; ctx = __blk_mq_get_ctx(hctx->queue, cpu); -- Gitee From 148a8c518509eb027c290ac96f02bb0f4bff35f1 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Tue, 30 Sep 2025 20:58:02 +0800 Subject: [PATCH 0793/1449] tpm: Cap the number of PCR banks ANBZ: #35228 commit d88481653d74d622d1d0d2c9bad845fc2cc6fd23 stable. commit faf07e611dfa464b201223a7253e9dc5ee0f3c9e upstream. tpm2_get_pcr_allocation() does not cap any upper limit for the number of banks. Cap the limit to eight banks so that out of bounds values coming from external I/O cause on only limited harm. Cc: stable@vger.kernel.org # v5.10+ Fixes: bcfff8384f6c ("tpm: dynamically allocate the allocated_banks array") Tested-by: Lai Yi Reviewed-by: Jonathan McDowell Reviewed-by: Roberto Sassu Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/char/tpm/tpm-chip.c | 1 - drivers/char/tpm/tpm1-cmd.c | 5 ----- drivers/char/tpm/tpm2-cmd.c | 8 +++----- include/linux/tpm.h | 8 +++++--- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 70e3fe20fdcf..458a3e9ea73a 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -279,7 +279,6 @@ static void tpm_dev_release(struct device *dev) kfree(chip->work_space.context_buf); kfree(chip->work_space.session_buf); - kfree(chip->allocated_banks); kfree(chip); } diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index cf64c7385105..b49a790f1bd5 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -799,11 +799,6 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr) */ int tpm1_get_pcr_allocation(struct tpm_chip *chip) { - chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks), - GFP_KERNEL); - if (!chip->allocated_banks) - return -ENOMEM; - chip->allocated_banks[0].alg_id = TPM_ALG_SHA1; chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1]; chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1; diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 93545be190a5..57bb3e34b770 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -574,11 +574,9 @@ ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) nr_possible_banks = be32_to_cpup( (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); - - chip->allocated_banks = kcalloc(nr_possible_banks, - sizeof(*chip->allocated_banks), - GFP_KERNEL); - if (!chip->allocated_banks) { + if (nr_possible_banks > TPM2_MAX_PCR_BANKS) { + pr_err("tpm: out of bank capacity: %u > %u\n", + nr_possible_banks, TPM2_MAX_PCR_BANKS); rc = -ENOMEM; goto out; } diff --git a/include/linux/tpm.h b/include/linux/tpm.h index bf8a4ec8a01c..f5e7cca2f257 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -25,7 +25,9 @@ #include #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ -#define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE + +#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE +#define TPM2_MAX_PCR_BANKS 8 struct tpm_chip; struct trusted_key_payload; @@ -51,7 +53,7 @@ enum tpm_algorithms { struct tpm_digest { u16 alg_id; - u8 digest[TPM_MAX_DIGEST_SIZE]; + u8 digest[TPM2_MAX_DIGEST_SIZE]; } __packed; struct tpm_bank_info { @@ -157,7 +159,7 @@ struct tpm_chip { unsigned int groups_cnt; u32 nr_allocated_banks; - struct tpm_bank_info *allocated_banks; + struct tpm_bank_info allocated_banks[TPM2_MAX_PCR_BANKS]; #ifdef CONFIG_ACPI acpi_handle acpi_dev_handle; char ppi_version[TPM_PPI_VERSION_LEN + 1]; -- Gitee From 238250e8d9174bf1050d8b0f469ff1fbb8ad876c Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 8 Dec 2025 19:36:00 +0800 Subject: [PATCH 0794/1449] mptcp: Initialise rcv_mss before calling tcp_send_active_reset() in mptcp_do_fastclose(). ANBZ: #35228 commit eee39f83246a81d970a9ecb7392b7ab74e660094 stable. commit f07f4ea53e22429c84b20832fa098b5ecc0d4e35 upstream. syzbot reported divide-by-zero in __tcp_select_window() by MPTCP socket. [0] We had a similar issue for the bare TCP and fixed in commit 499350a5a6e7 ("tcp: initialize rcv_mss to TCP_MIN_MSS instead of 0"). Let's apply the same fix to mptcp_do_fastclose(). [0]: Oops: divide error: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 6068 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 RIP: 0010:__tcp_select_window+0x824/0x1320 net/ipv4/tcp_output.c:3336 Code: ff ff ff 44 89 f1 d3 e0 89 c1 f7 d1 41 01 cc 41 21 c4 e9 a9 00 00 00 e8 ca 49 01 f8 e9 9c 00 00 00 e8 c0 49 01 f8 44 89 e0 99 7c 24 1c 41 29 d4 48 bb 00 00 00 00 00 fc ff df e9 80 00 00 00 RSP: 0018:ffffc90003017640 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff88807b469e40 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffc90003017730 R08: ffff888033268143 R09: 1ffff1100664d028 R10: dffffc0000000000 R11: ffffed100664d029 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 000055557faa0500(0000) GS:ffff888126135000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f64a1912ff8 CR3: 0000000072122000 CR4: 00000000003526f0 Call Trace: tcp_select_window net/ipv4/tcp_output.c:281 [inline] __tcp_transmit_skb+0xbc7/0x3aa0 net/ipv4/tcp_output.c:1568 tcp_transmit_skb net/ipv4/tcp_output.c:1649 [inline] tcp_send_active_reset+0x2d1/0x5b0 net/ipv4/tcp_output.c:3836 mptcp_do_fastclose+0x27e/0x380 net/mptcp/protocol.c:2793 mptcp_disconnect+0x238/0x710 net/mptcp/protocol.c:3253 mptcp_sendmsg_fastopen+0x2f8/0x580 net/mptcp/protocol.c:1776 mptcp_sendmsg+0x1774/0x1980 net/mptcp/protocol.c:1855 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg+0xe5/0x270 net/socket.c:742 __sys_sendto+0x3bd/0x520 net/socket.c:2244 __do_sys_sendto net/socket.c:2251 [inline] __se_sys_sendto net/socket.c:2247 [inline] __x64_sys_sendto+0xde/0x100 net/socket.c:2247 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f66e998f749 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffff9acedb8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00007f66e9be5fa0 RCX: 00007f66e998f749 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 00007ffff9acee10 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 R13: 00007f66e9be5fa0 R14: 00007f66e9be5fa0 R15: 0000000000000006 Fixes: ae155060247b ("mptcp: fix duplicate reset on fastclose") Reported-by: syzbot+3a92d359bc2ec6255a33@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/69260882.a70a0220.d98e3.00b4.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima Reviewed-by: Matthieu Baerts (NGI0) Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251125195331.309558-1-kuniyu@google.com Signed-off-by: Paolo Abeni [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 5ee00824a0a5..810a974c878c 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2823,6 +2823,12 @@ static void mptcp_do_fastclose(struct sock *sk) goto unlock; subflow->send_fastclose = 1; + + /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 + * issue in __tcp_select_window(), see tcp_disconnect(). + */ + inet_csk(ssk)->icsk_ack.rcv_mss = TCP_MIN_MSS; + tcp_send_active_reset(ssk, ssk->sk_allocation); unlock: release_sock(ssk); -- Gitee From 777207c302fe36c37a1a65b0b44a5e3812b63758 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Dec 2025 18:54:27 +0800 Subject: [PATCH 0795/1449] ALSA: wavefront: Use standard print API ANBZ: #35228 commit 596b04a1638e4ab80993677865c0386e8b9fc413 stable. commit 8b4ac5429938dd5f1fbf2eea0687f08cbcccb6be upstream. Use the standard print API with dev_*() instead of the old house-baked one. It gives better information and allows dynamically control of debug prints. Reviewed-by: Jaroslav Kysela Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20240807133452.9424-36-tiwai@suse.de Stable-dep-of: 0c4a13ba8859 ("ALSA: wavefront: Fix integer overflow in sample size validation") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/sound/snd_wavefront.h | 4 - sound/isa/wavefront/wavefront.c | 61 ++++---- sound/isa/wavefront/wavefront_fx.c | 36 ++--- sound/isa/wavefront/wavefront_midi.c | 15 +- sound/isa/wavefront/wavefront_synth.c | 196 +++++++++++++------------- 5 files changed, 158 insertions(+), 154 deletions(-) diff --git a/include/sound/snd_wavefront.h b/include/sound/snd_wavefront.h index 55053557c898..27f7e8a477c2 100644 --- a/include/sound/snd_wavefront.h +++ b/include/sound/snd_wavefront.h @@ -137,8 +137,4 @@ extern int snd_wavefront_fx_ioctl (struct snd_hwdep *, extern int snd_wavefront_fx_open (struct snd_hwdep *, struct file *); extern int snd_wavefront_fx_release (struct snd_hwdep *, struct file *); -/* prefix in all snd_printk() delivered messages */ - -#define LOGNAME "WaveFront: " - #endif /* __SOUND_SND_WAVEFRONT_H__ */ diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index e6e46a0266b0..621ab420a60f 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -140,7 +140,7 @@ snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *c err = pnp_activate_dev(pdev); if (err < 0) { - snd_printk(KERN_ERR "PnP WSS pnp configure failure\n"); + dev_err(&pdev->dev, "PnP WSS pnp configure failure\n"); return err; } @@ -156,7 +156,7 @@ snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *c err = pnp_activate_dev(pdev); if (err < 0) { - snd_printk(KERN_ERR "PnP ICS2115 pnp configure failure\n"); + dev_err(&pdev->dev, "PnP ICS2115 pnp configure failure\n"); return err; } @@ -174,26 +174,27 @@ snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *c err = pnp_activate_dev(pdev); if (err < 0) { - snd_printk(KERN_ERR "PnP MPU401 pnp configure failure\n"); + dev_err(&pdev->dev, "PnP MPU401 pnp configure failure\n"); cs4232_mpu_port[dev] = SNDRV_AUTO_PORT; } else { cs4232_mpu_port[dev] = pnp_port_start(pdev, 0); cs4232_mpu_irq[dev] = pnp_irq(pdev, 0); } - snd_printk (KERN_INFO "CS4232 MPU: port=0x%lx, irq=%i\n", - cs4232_mpu_port[dev], - cs4232_mpu_irq[dev]); + dev_info(&pdev->dev, "CS4232 MPU: port=0x%lx, irq=%i\n", + cs4232_mpu_port[dev], + cs4232_mpu_irq[dev]); } - snd_printdd ("CS4232: pcm port=0x%lx, fm port=0x%lx, dma1=%i, dma2=%i, irq=%i\nICS2115: port=0x%lx, irq=%i\n", - cs4232_pcm_port[dev], - fm_port[dev], - dma1[dev], - dma2[dev], - cs4232_pcm_irq[dev], - ics2115_port[dev], - ics2115_irq[dev]); + dev_dbg(&pdev->dev, + "CS4232: pcm port=0x%lx, fm port=0x%lx, dma1=%i, dma2=%i, irq=%i\nICS2115: port=0x%lx, irq=%i\n", + cs4232_pcm_port[dev], + fm_port[dev], + dma1[dev], + dma2[dev], + cs4232_pcm_irq[dev], + ics2115_port[dev], + ics2115_irq[dev]); return 0; } @@ -251,7 +252,7 @@ static struct snd_hwdep *snd_wavefront_new_fx(struct snd_card *card, struct snd_hwdep *fx_processor; if (snd_wavefront_fx_start (&acard->wavefront)) { - snd_printk (KERN_ERR "cannot initialize YSS225 FX processor"); + dev_err(card->dev, "cannot initialize YSS225 FX processor"); return NULL; } @@ -282,7 +283,7 @@ static struct snd_rawmidi *snd_wavefront_new_midi(struct snd_card *card, first = 0; acard->wavefront.midi.base = port; if (snd_wavefront_midi_start (acard)) { - snd_printk (KERN_ERR "cannot initialize MIDI interface\n"); + dev_err(card->dev, "cannot initialize MIDI interface\n"); return NULL; } } @@ -349,7 +350,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) cs4232_pcm_irq[dev], dma1[dev], dma2[dev], WSS_HW_DETECT, 0, &chip); if (err < 0) { - snd_printk(KERN_ERR "can't allocate WSS device\n"); + dev_err(card->dev, "can't allocate WSS device\n"); return err; } @@ -369,7 +370,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) err = snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2, OPL3_HW_OPL3_CS, 0, &opl3); if (err < 0) { - snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n"); + dev_err(card->dev, "can't allocate or detect OPL3 synth\n"); return err; } @@ -385,14 +386,14 @@ snd_wavefront_probe (struct snd_card *card, int dev) devm_request_region(card->dev, ics2115_port[dev], 16, "ICS2115"); if (acard->wavefront.res_base == NULL) { - snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n", - ics2115_port[dev], ics2115_port[dev] + 16 - 1); + dev_err(card->dev, "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n", + ics2115_port[dev], ics2115_port[dev] + 16 - 1); return -EBUSY; } if (devm_request_irq(card->dev, ics2115_irq[dev], snd_wavefront_ics2115_interrupt, 0, "ICS2115", acard)) { - snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]); + dev_err(card->dev, "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]); return -EBUSY; } @@ -402,7 +403,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) wavefront_synth = snd_wavefront_new_synth(card, hw_dev, acard); if (wavefront_synth == NULL) { - snd_printk (KERN_ERR "can't create WaveFront synth device\n"); + dev_err(card->dev, "can't create WaveFront synth device\n"); return -ENOMEM; } @@ -414,7 +415,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) err = snd_wss_mixer(chip); if (err < 0) { - snd_printk (KERN_ERR "can't allocate mixer device\n"); + dev_err(card->dev, "can't allocate mixer device\n"); return err; } @@ -425,7 +426,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) cs4232_mpu_port[dev], 0, cs4232_mpu_irq[dev], NULL); if (err < 0) { - snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n"); + dev_err(card->dev, "can't allocate CS4232 MPU-401 device\n"); return err; } midi_dev++; @@ -441,7 +442,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) ics2115_port[dev], internal_mpu); if (ics2115_internal_rmidi == NULL) { - snd_printk (KERN_ERR "can't setup ICS2115 internal MIDI device\n"); + dev_err(card->dev, "can't setup ICS2115 internal MIDI device\n"); return -ENOMEM; } midi_dev++; @@ -457,7 +458,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) ics2115_port[dev], external_mpu); if (ics2115_external_rmidi == NULL) { - snd_printk (KERN_ERR "can't setup ICS2115 external MIDI device\n"); + dev_err(card->dev, "can't setup ICS2115 external MIDI device\n"); return -ENOMEM; } midi_dev++; @@ -471,7 +472,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) acard, ics2115_port[dev]); if (fx_processor == NULL) { - snd_printk (KERN_ERR "can't setup FX device\n"); + dev_err(card->dev, "can't setup FX device\n"); return -ENOMEM; } @@ -525,11 +526,11 @@ static int snd_wavefront_isa_match(struct device *pdev, return 0; #endif if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify CS4232 port\n"); + dev_err(pdev, "specify CS4232 port\n"); return 0; } if (ics2115_port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify ICS2115 port\n"); + dev_err(pdev, "specify ICS2115 port\n"); return 0; } return 1; @@ -585,7 +586,7 @@ static int snd_wavefront_pnp_detect(struct pnp_card_link *pcard, if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) { if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { - snd_printk (KERN_ERR "isapnp detection failed\n"); + dev_err(card->dev, "isapnp detection failed\n"); return -ENODEV; } } diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 3c21324b2a0e..77e56fc92c5e 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -38,7 +38,7 @@ wavefront_fx_idle (snd_wavefront_t *dev) } if (x & 0x80) { - snd_printk ("FX device never idle.\n"); + dev_err(dev->card->dev, "FX device never idle.\n"); return 0; } @@ -64,14 +64,14 @@ wavefront_fx_memset (snd_wavefront_t *dev, unsigned short *data) { if (page < 0 || page > 7) { - snd_printk ("FX memset: " - "page must be >= 0 and <= 7\n"); + dev_err(dev->card->dev, + "FX memset: page must be >= 0 and <= 7\n"); return -EINVAL; } if (addr < 0 || addr > 0x7f) { - snd_printk ("FX memset: " - "addr must be >= 0 and <= 7f\n"); + dev_err(dev->card->dev, + "FX memset: addr must be >= 0 and <= 7f\n"); return -EINVAL; } @@ -83,7 +83,7 @@ wavefront_fx_memset (snd_wavefront_t *dev, outb ((data[0] >> 8), dev->fx_dsp_msb); outb ((data[0] & 0xff), dev->fx_dsp_lsb); - snd_printk ("FX: addr %d:%x set to 0x%x\n", + dev_err(dev->card->dev, "FX: addr %d:%x set to 0x%x\n", page, addr, data[0]); } else { @@ -102,9 +102,9 @@ wavefront_fx_memset (snd_wavefront_t *dev, } if (i != cnt) { - snd_printk ("FX memset " - "(0x%x, 0x%x, 0x%lx, %d) incomplete\n", - page, addr, (unsigned long) data, cnt); + dev_err(dev->card->dev, + "FX memset (0x%x, 0x%x, 0x%lx, %d) incomplete\n", + page, addr, (unsigned long) data, cnt); return -EIO; } } @@ -123,7 +123,7 @@ snd_wavefront_fx_detect (snd_wavefront_t *dev) */ if (inb (dev->fx_status) & 0x80) { - snd_printk ("Hmm, probably a Maui or Tropez.\n"); + dev_err(dev->card->dev, "Hmm, probably a Maui or Tropez.\n"); return -1; } @@ -180,15 +180,15 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file, case WFFX_MEMSET: if (r.data[2] <= 0) { - snd_printk ("cannot write " - "<= 0 bytes to FX\n"); + dev_err(dev->card->dev, + "cannot write <= 0 bytes to FX\n"); return -EIO; } else if (r.data[2] == 1) { pd = (unsigned short *) &r.data[3]; } else { if (r.data[2] > 256) { - snd_printk ("cannot write " - "> 512 bytes to FX\n"); + dev_err(dev->card->dev, + "cannot write > 512 bytes to FX\n"); return -EIO; } page_data = memdup_user((unsigned char __user *) @@ -208,8 +208,8 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file, break; default: - snd_printk ("FX: ioctl %d not yet supported\n", - r.request); + dev_err(dev->card->dev, "FX: ioctl %d not yet supported\n", + r.request); return -ENOTTY; } return err; @@ -254,8 +254,8 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) goto out; } } else { - snd_printk(KERN_ERR "invalid address" - " in register data\n"); + dev_err(dev->card->dev, + "invalid address in register data\n"); err = -1; goto out; } diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index 72e775ac7ad7..ead8cbe638de 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c @@ -501,7 +501,8 @@ snd_wavefront_midi_start (snd_wavefront_card_t *card) for (i = 0; i < 30000 && !output_ready (midi); i++); if (!output_ready (midi)) { - snd_printk ("MIDI interface not ready for command\n"); + dev_err(card->wavefront.card->dev, + "MIDI interface not ready for command\n"); return -1; } @@ -523,7 +524,8 @@ snd_wavefront_midi_start (snd_wavefront_card_t *card) } if (!ok) { - snd_printk ("cannot set UART mode for MIDI interface"); + dev_err(card->wavefront.card->dev, + "cannot set UART mode for MIDI interface"); dev->interrupts_are_midi = 0; return -1; } @@ -531,7 +533,8 @@ snd_wavefront_midi_start (snd_wavefront_card_t *card) /* Route external MIDI to WaveFront synth (by default) */ if (snd_wavefront_cmd (dev, WFC_MISYNTH_ON, rbuf, wbuf)) { - snd_printk ("can't enable MIDI-IN-2-synth routing.\n"); + dev_warn(card->wavefront.card->dev, + "can't enable MIDI-IN-2-synth routing.\n"); /* XXX error ? */ } @@ -547,14 +550,16 @@ snd_wavefront_midi_start (snd_wavefront_card_t *card) */ if (snd_wavefront_cmd (dev, WFC_VMIDI_OFF, rbuf, wbuf)) { - snd_printk ("virtual MIDI mode not disabled\n"); + dev_warn(card->wavefront.card->dev, + "virtual MIDI mode not disabled\n"); return 0; /* We're OK, but missing the external MIDI dev */ } snd_wavefront_midi_enable_virtual (card); if (snd_wavefront_cmd (dev, WFC_VMIDI_ON, rbuf, wbuf)) { - snd_printk ("cannot enable virtual MIDI mode.\n"); + dev_warn(card->wavefront.card->dev, + "cannot enable virtual MIDI mode.\n"); snd_wavefront_midi_disable_virtual (card); } return 0; diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 13ce96148fa3..bd679e2da154 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -116,7 +116,7 @@ MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS"); #define DPRINT(cond, ...) \ if ((dev->debug & (cond)) == (cond)) { \ - snd_printk (__VA_ARGS__); \ + pr_debug(__VA_ARGS__); \ } #else #define DPRINT(cond, args...) @@ -341,7 +341,7 @@ snd_wavefront_cmd (snd_wavefront_t *dev, wfcmd = wavefront_get_command(cmd); if (!wfcmd) { - snd_printk ("command 0x%x not supported.\n", + dev_err(dev->card->dev, "command 0x%x not supported.\n", cmd); return 1; } @@ -623,7 +623,7 @@ wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom) /* check sample status */ if (snd_wavefront_cmd (dev, WFC_GET_NSAMPLES, rbuf, wbuf)) { - snd_printk ("cannot request sample count.\n"); + dev_err(dev->card->dev, "cannot request sample count.\n"); return -1; } @@ -635,8 +635,8 @@ wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom) wbuf[1] = i >> 7; if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) { - snd_printk(KERN_WARNING "cannot identify sample " - "type of slot %d\n", i); + dev_warn(dev->card->dev, + "cannot identify sample type of slot %d\n", i); dev->sample_status[i] = WF_ST_EMPTY; continue; } @@ -661,9 +661,9 @@ wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom) break; default: - snd_printk ("unknown sample type for " - "slot %d (0x%x)\n", - i, rbuf[0]); + dev_err(dev->card->dev, + "unknown sample type for slot %d (0x%x)\n", + i, rbuf[0]); } if (rbuf[0] != WF_ST_EMPTY) { @@ -671,9 +671,10 @@ wavefront_get_sample_status (snd_wavefront_t *dev, int assume_rom) } } - snd_printk ("%d samples used (%d real, %d aliases, %d multi), " - "%d empty\n", dev->samples_used, sc_real, sc_alias, sc_multi, - WF_MAX_SAMPLE - dev->samples_used); + dev_info(dev->card->dev, + "%d samples used (%d real, %d aliases, %d multi), %d empty\n", + dev->samples_used, sc_real, sc_alias, sc_multi, + WF_MAX_SAMPLE - dev->samples_used); return (0); @@ -706,8 +707,8 @@ wavefront_get_patch_status (snd_wavefront_t *dev) } else if (x == 3) { /* Bad patch number */ dev->patch_status[i] = 0; } else { - snd_printk ("upload patch " - "error 0x%x\n", x); + dev_err(dev->card->dev, + "upload patch error 0x%x\n", x); dev->patch_status[i] = 0; return 1; } @@ -724,7 +725,8 @@ wavefront_get_patch_status (snd_wavefront_t *dev) } } - snd_printk ("%d patch slots filled, %d in use\n", cnt, cnt2); + dev_info(dev->card->dev, "%d patch slots filled, %d in use\n", + cnt, cnt2); return (0); } @@ -760,8 +762,8 @@ wavefront_get_program_status (snd_wavefront_t *dev) } else if (x == 1) { /* Bad program number */ dev->prog_status[i] = 0; } else { - snd_printk ("upload program " - "error 0x%x\n", x); + dev_err(dev->card->dev, + "upload program error 0x%x\n", x); dev->prog_status[i] = 0; } } @@ -772,7 +774,7 @@ wavefront_get_program_status (snd_wavefront_t *dev) } } - snd_printk ("%d programs slots in use\n", cnt); + dev_info(dev->card->dev, "%d programs slots in use\n", cnt); return (0); } @@ -796,7 +798,7 @@ wavefront_send_patch (snd_wavefront_t *dev, wavefront_patch_info *header) munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES); if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_PATCH, NULL, buf)) { - snd_printk ("download patch failed\n"); + dev_err(dev->card->dev, "download patch failed\n"); return -EIO; } @@ -837,7 +839,7 @@ wavefront_send_program (snd_wavefront_t *dev, wavefront_patch_info *header) munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES); if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_PROGRAM, NULL, buf)) { - snd_printk ("download patch failed\n"); + dev_err(dev->card->dev, "download patch failed\n"); return -EIO; } @@ -851,7 +853,7 @@ wavefront_freemem (snd_wavefront_t *dev) char rbuf[8]; if (snd_wavefront_cmd (dev, WFC_REPORT_FREE_MEMORY, rbuf, NULL)) { - snd_printk ("can't get memory stats.\n"); + dev_err(dev->card->dev, "can't get memory stats.\n"); return -1; } else { return demunge_int32 (rbuf, 4); @@ -901,7 +903,7 @@ wavefront_send_sample (snd_wavefront_t *dev, x = wavefront_find_free_sample(dev); if (x < 0) return -ENOMEM; - snd_printk ("unspecified sample => %d\n", x); + dev_info(dev->card->dev, "unspecified sample => %d\n", x); header->number = x; } @@ -935,9 +937,9 @@ wavefront_send_sample (snd_wavefront_t *dev, if (dev->rom_samples_rdonly) { if (dev->sample_status[header->number] & WF_SLOT_ROM) { - snd_printk ("sample slot %d " - "write protected\n", - header->number); + dev_err(dev->card->dev, + "sample slot %d write protected\n", + header->number); return -EACCES; } } @@ -949,9 +951,9 @@ wavefront_send_sample (snd_wavefront_t *dev, dev->freemem = wavefront_freemem (dev); if (dev->freemem < (int)header->size) { - snd_printk ("insufficient memory to " - "load %d byte sample.\n", - header->size); + dev_err(dev->card->dev, + "insufficient memory to load %d byte sample.\n", + header->size); return -ENOMEM; } @@ -960,8 +962,8 @@ wavefront_send_sample (snd_wavefront_t *dev, skip = WF_GET_CHANNEL(&header->hdr.s); if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) { - snd_printk ("channel selection only " - "possible on 16-bit samples"); + dev_err(dev->card->dev, + "channel selection only possible on 16-bit samples"); return -EINVAL; } @@ -1057,8 +1059,8 @@ wavefront_send_sample (snd_wavefront_t *dev, header->size ? WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER, NULL, sample_hdr)) { - snd_printk ("sample %sdownload refused.\n", - header->size ? "" : "header "); + dev_err(dev->card->dev, "sample %sdownload refused.\n", + header->size ? "" : "header "); return -EIO; } @@ -1083,8 +1085,8 @@ wavefront_send_sample (snd_wavefront_t *dev, } if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_BLOCK, NULL, NULL)) { - snd_printk ("download block " - "request refused.\n"); + dev_err(dev->card->dev, + "download block request refused.\n"); return -EIO; } @@ -1145,13 +1147,13 @@ wavefront_send_sample (snd_wavefront_t *dev, dma_ack = wavefront_read(dev); if (dma_ack != WF_DMA_ACK) { if (dma_ack == -1) { - snd_printk ("upload sample " - "DMA ack timeout\n"); + dev_err(dev->card->dev, + "upload sample DMA ack timeout\n"); return -EIO; } else { - snd_printk ("upload sample " - "DMA ack error 0x%x\n", - dma_ack); + dev_err(dev->card->dev, + "upload sample DMA ack error 0x%x\n", + dma_ack); return -EIO; } } @@ -1195,7 +1197,7 @@ wavefront_send_alias (snd_wavefront_t *dev, wavefront_patch_info *header) munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2); if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) { - snd_printk ("download alias failed.\n"); + dev_err(dev->card->dev, "download alias failed.\n"); return -EIO; } @@ -1248,7 +1250,7 @@ wavefront_send_multisample (snd_wavefront_t *dev, wavefront_patch_info *header) if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_MULTISAMPLE, (unsigned char *) (long) ((num_samples*2)+3), msample_hdr)) { - snd_printk ("download of multisample failed.\n"); + dev_err(dev->card->dev, "download of multisample failed.\n"); kfree(msample_hdr); return -EIO; } @@ -1271,7 +1273,7 @@ wavefront_fetch_multisample (snd_wavefront_t *dev, munge_int32 (header->number, number, 2); if (snd_wavefront_cmd (dev, WFC_UPLOAD_MULTISAMPLE, log_ns, number)) { - snd_printk ("upload multisample failed.\n"); + dev_err(dev->card->dev, "upload multisample failed.\n"); return -EIO; } @@ -1290,16 +1292,16 @@ wavefront_fetch_multisample (snd_wavefront_t *dev, val = wavefront_read(dev); if (val == -1) { - snd_printk ("upload multisample failed " - "during sample loop.\n"); + dev_err(dev->card->dev, + "upload multisample failed during sample loop.\n"); return -EIO; } d[0] = val; val = wavefront_read(dev); if (val == -1) { - snd_printk ("upload multisample failed " - "during sample loop.\n"); + dev_err(dev->card->dev, + "upload multisample failed during sample loop.\n"); return -EIO; } d[1] = val; @@ -1334,7 +1336,7 @@ wavefront_send_drum (snd_wavefront_t *dev, wavefront_patch_info *header) } if (snd_wavefront_cmd (dev, WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) { - snd_printk ("download drum failed.\n"); + dev_err(dev->card->dev, "download drum failed.\n"); return -EIO; } @@ -1352,7 +1354,7 @@ wavefront_find_free_sample (snd_wavefront_t *dev) return i; } } - snd_printk ("no free sample slots!\n"); + dev_err(dev->card->dev, "no free sample slots!\n"); return -1; } @@ -1368,7 +1370,7 @@ wavefront_find_free_patch (snd_wavefront_t *dev) return i; } } - snd_printk ("no free patch slots!\n"); + dev_err(dev->card->dev, "no free patch slots!\n"); return -1; } #endif @@ -1385,7 +1387,7 @@ wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr) if (copy_from_user (header, addr, sizeof(wavefront_patch_info) - sizeof(wavefront_any))) { - snd_printk ("bad address for load patch.\n"); + dev_err(dev->card->dev, "bad address for load patch.\n"); err = -EFAULT; goto __error; } @@ -1463,8 +1465,8 @@ wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr) break; default: - snd_printk ("unknown patch type %d.\n", - header->subkey); + dev_err(dev->card->dev, "unknown patch type %d.\n", + header->subkey); err = -EINVAL; break; } @@ -1527,13 +1529,13 @@ wavefront_synth_control (snd_wavefront_card_t *acard, switch (wc->cmd) { case WFC_DISABLE_INTERRUPTS: - snd_printk ("interrupts disabled.\n"); + dev_dbg(dev->card->dev, "interrupts disabled.\n"); outb (0x80|0x20, dev->control_port); dev->interrupts_are_midi = 1; return 0; case WFC_ENABLE_INTERRUPTS: - snd_printk ("interrupts enabled.\n"); + dev_dbg(dev->card->dev, "interrupts enabled.\n"); outb (0x80|0x40|0x20, dev->control_port); dev->interrupts_are_midi = 1; return 0; @@ -1550,7 +1552,7 @@ wavefront_synth_control (snd_wavefront_card_t *acard, case WFC_IDENTIFY_SLOT_TYPE: i = wc->wbuf[0] | (wc->wbuf[1] << 7); if (i <0 || i >= WF_MAX_SAMPLE) { - snd_printk ("invalid slot ID %d\n", + dev_err(dev->card->dev, "invalid slot ID %d\n", i); wc->status = EINVAL; return -EINVAL; @@ -1561,7 +1563,7 @@ wavefront_synth_control (snd_wavefront_card_t *acard, case WFC_DEBUG_DRIVER: dev->debug = wc->wbuf[0]; - snd_printk ("debug = 0x%x\n", dev->debug); + dev_dbg(dev->card->dev, "debug = 0x%x\n", dev->debug); return 0; case WFC_UPLOAD_PATCH: @@ -1578,8 +1580,8 @@ wavefront_synth_control (snd_wavefront_card_t *acard, return 0; case WFC_UPLOAD_SAMPLE_ALIAS: - snd_printk ("support for sample alias upload " - "being considered.\n"); + dev_err(dev->card->dev, + "support for sample alias upload being considered.\n"); wc->status = EINVAL; return -EINVAL; } @@ -1620,9 +1622,8 @@ wavefront_synth_control (snd_wavefront_card_t *acard, break; case WFC_UPLOAD_SAMPLE_ALIAS: - snd_printk ("support for " - "sample aliases still " - "being considered.\n"); + dev_err(dev->card->dev, + "support for sample aliases still being considered.\n"); break; case WFC_VMIDI_OFF: @@ -1760,7 +1761,7 @@ snd_wavefront_internal_interrupt (snd_wavefront_card_t *card) */ static int -snd_wavefront_interrupt_bits (int irq) +snd_wavefront_interrupt_bits(snd_wavefront_t *dev, int irq) { int bits; @@ -1780,7 +1781,7 @@ snd_wavefront_interrupt_bits (int irq) break; default: - snd_printk ("invalid IRQ %d\n", irq); + dev_err(dev->card->dev, "invalid IRQ %d\n", irq); bits = -1; } @@ -1815,7 +1816,7 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) /* IRQ already checked */ - bits = snd_wavefront_interrupt_bits (dev->irq); + bits = snd_wavefront_interrupt_bits(dev, dev->irq); /* try reset of port */ @@ -1885,7 +1886,7 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) */ if (!dev->irq_ok) { - snd_printk ("intr not received after h/w un-reset.\n"); + dev_err(dev->card->dev, "intr not received after h/w un-reset.\n"); goto gone_bad; } @@ -1909,18 +1910,18 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) dev->data_port, ramcheck_time*HZ); if (!dev->irq_ok) { - snd_printk ("post-RAM-check interrupt not received.\n"); + dev_err(dev->card->dev, "post-RAM-check interrupt not received.\n"); goto gone_bad; } if (!wavefront_wait (dev, STAT_CAN_READ)) { - snd_printk ("no response to HW version cmd.\n"); + dev_err(dev->card->dev, "no response to HW version cmd.\n"); goto gone_bad; } hwv[0] = wavefront_read(dev); if (hwv[0] == -1) { - snd_printk ("board not responding correctly.\n"); + dev_err(dev->card->dev, "board not responding correctly.\n"); goto gone_bad; } @@ -1932,11 +1933,11 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) hwv[0] = wavefront_read(dev); if (hwv[0] == -1) { - snd_printk ("on-board RAM test failed " - "(bad error code).\n"); + dev_err(dev->card->dev, + "on-board RAM test failed (bad error code).\n"); } else { - snd_printk ("on-board RAM test failed " - "(error code: 0x%x).\n", + dev_err(dev->card->dev, + "on-board RAM test failed (error code: 0x%x).\n", hwv[0]); } goto gone_bad; @@ -1946,12 +1947,12 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev) hwv[1] = wavefront_read(dev); if (hwv[1] == -1) { - snd_printk ("incorrect h/w response.\n"); + dev_err(dev->card->dev, "incorrect h/w response.\n"); goto gone_bad; } - snd_printk ("hardware version %d.%d\n", - hwv[0], hwv[1]); + dev_info(dev->card->dev, "hardware version %d.%d\n", + hwv[0], hwv[1]); return 0; @@ -1971,7 +1972,7 @@ wavefront_download_firmware (snd_wavefront_t *dev, char *path) err = request_firmware(&firmware, path, dev->card->dev); if (err < 0) { - snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path); + dev_err(dev->card->dev, "firmware (%s) download failed!!!\n", path); return 1; } @@ -1982,16 +1983,16 @@ wavefront_download_firmware (snd_wavefront_t *dev, char *path) if (section_length == 0) break; if (section_length < 0 || section_length > WF_SECTION_MAX) { - snd_printk(KERN_ERR - "invalid firmware section length %d\n", - section_length); + dev_err(dev->card->dev, + "invalid firmware section length %d\n", + section_length); goto failure; } buf++; len++; if (firmware->size < len + section_length) { - snd_printk(KERN_ERR "firmware section read error.\n"); + dev_err(dev->card->dev, "firmware section read error.\n"); goto failure; } @@ -2008,15 +2009,14 @@ wavefront_download_firmware (snd_wavefront_t *dev, char *path) /* get ACK */ if (!wavefront_wait(dev, STAT_CAN_READ)) { - snd_printk(KERN_ERR "time out for firmware ACK.\n"); + dev_err(dev->card->dev, "time out for firmware ACK.\n"); goto failure; } err = inb(dev->data_port); if (err != WF_ACK) { - snd_printk(KERN_ERR - "download of section #%d not " - "acknowledged, ack = 0x%x\n", - section_cnt_downloaded + 1, err); + dev_err(dev->card->dev, + "download of section #%d not acknowledged, ack = 0x%x\n", + section_cnt_downloaded + 1, err); goto failure; } @@ -2028,7 +2028,7 @@ wavefront_download_firmware (snd_wavefront_t *dev, char *path) failure: release_firmware(firmware); - snd_printk(KERN_ERR "firmware download failed!!!\n"); + dev_err(dev->card->dev, "firmware download failed!!!\n"); return 1; } @@ -2040,7 +2040,7 @@ wavefront_do_reset (snd_wavefront_t *dev) char voices[1]; if (wavefront_reset_to_cleanliness (dev)) { - snd_printk ("hw reset failed.\n"); + dev_err(dev->card->dev, "hw reset failed.\n"); goto gone_bad; } @@ -2064,7 +2064,7 @@ wavefront_do_reset (snd_wavefront_t *dev) (osrun_time*HZ)); if (!dev->irq_ok) { - snd_printk ("no post-OS interrupt.\n"); + dev_err(dev->card->dev, "no post-OS interrupt.\n"); goto gone_bad; } @@ -2074,7 +2074,7 @@ wavefront_do_reset (snd_wavefront_t *dev) dev->data_port, (10*HZ)); if (!dev->irq_ok) { - snd_printk ("no post-OS interrupt(2).\n"); + dev_err(dev->card->dev, "no post-OS interrupt(2).\n"); goto gone_bad; } @@ -2094,20 +2094,20 @@ wavefront_do_reset (snd_wavefront_t *dev) if (dev->freemem < 0) goto gone_bad; - snd_printk ("available DRAM %dk\n", dev->freemem / 1024); + dev_info(dev->card->dev, "available DRAM %dk\n", dev->freemem / 1024); if (wavefront_write (dev, 0xf0) || wavefront_write (dev, 1) || (wavefront_read (dev) < 0)) { dev->debug = 0; - snd_printk ("MPU emulation mode not set.\n"); + dev_err(dev->card->dev, "MPU emulation mode not set.\n"); goto gone_bad; } voices[0] = 32; if (snd_wavefront_cmd (dev, WFC_SET_NVOICES, NULL, voices)) { - snd_printk ("cannot set number of voices to 32.\n"); + dev_err(dev->card->dev, "cannot set number of voices to 32.\n"); goto gone_bad; } @@ -2187,8 +2187,8 @@ snd_wavefront_detect (snd_wavefront_card_t *card) dev->fw_version[0] = rbuf[0]; dev->fw_version[1] = rbuf[1]; - snd_printk ("firmware %d.%d already loaded.\n", - rbuf[0], rbuf[1]); + dev_info(dev->card->dev, "firmware %d.%d already loaded.\n", + rbuf[0], rbuf[1]); /* check that a command actually works */ @@ -2197,22 +2197,24 @@ snd_wavefront_detect (snd_wavefront_card_t *card) dev->hw_version[0] = rbuf[0]; dev->hw_version[1] = rbuf[1]; } else { - snd_printk ("not raw, but no " - "hardware version!\n"); + dev_err(dev->card->dev, + "not raw, but no hardware version!\n"); return -1; } if (!wf_raw) { return 0; } else { - snd_printk ("reloading firmware as you requested.\n"); + dev_info(dev->card->dev, + "reloading firmware as you requested.\n"); dev->israw = 1; } } else { dev->israw = 1; - snd_printk ("no response to firmware probe, assume raw.\n"); + dev_info(dev->card->dev, + "no response to firmware probe, assume raw.\n"); } -- Gitee From 7d852cd9f931265695556e3414f2963c70bea902 Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Tue, 16 Dec 2025 18:54:28 +0800 Subject: [PATCH 0796/1449] ALSA: wavefront: Fix integer overflow in sample size validation ANBZ: #35228 commit 02b63f3bc29265bd9e83191792d200ed563acacf stable. commit 0c4a13ba88594fd4a27292853e736c6b4349823d upstream. The wavefront_send_sample() function has an integer overflow issue when validating sample size. The header->size field is u32 but gets cast to int for comparison with dev->freemem Fix by using unsigned comparison to avoid integer overflow. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB7881B47789D1B060CE8BF4C3AFC2A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/isa/wavefront/wavefront_synth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index bd679e2da154..9eaab9ca4f95 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -950,9 +950,9 @@ wavefront_send_sample (snd_wavefront_t *dev, if (header->size) { dev->freemem = wavefront_freemem (dev); - if (dev->freemem < (int)header->size) { + if (dev->freemem < 0 || dev->freemem < header->size) { dev_err(dev->card->dev, - "insufficient memory to load %d byte sample.\n", + "insufficient memory to load %u byte sample.\n", header->size); return -ENOMEM; } -- Gitee From c9aff94ae80b922754293137f962f18dd795b0d5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 16 Dec 2025 19:06:29 +0800 Subject: [PATCH 0797/1449] ALSA: wavefront: Use guard() for spin locks ANBZ: #35228 commit 4425583a691a196a583f4989a43a7f3285206c5c stable. commit 4b97f8e614ba46a50bd181d40b5a1424411a211a upstream. Clean up the code using guard() for spin locks. Merely code refactoring, and no behavior change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250829145300.5460-19-tiwai@suse.de Stable-dep-of: e11c5c13ce0a ("ALSA: wavefront: Clear substream pointers on close") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/isa/wavefront/wavefront_midi.c | 131 ++++++++++---------------- sound/isa/wavefront/wavefront_synth.c | 18 ++-- 2 files changed, 61 insertions(+), 88 deletions(-) diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index ead8cbe638de..caa3b82f73f5 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c @@ -113,7 +113,6 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card) { snd_wavefront_midi_t *midi = &card->wavefront.midi; snd_wavefront_mpu_id mpu; - unsigned long flags; unsigned char midi_byte; int max = 256, mask = 1; int timeout; @@ -142,11 +141,9 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card) break; } - spin_lock_irqsave (&midi->virtual, flags); - if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0) { - spin_unlock_irqrestore (&midi->virtual, flags); + guard(spinlock_irqsave)(&midi->virtual); + if ((midi->mode[midi->output_mpu] & MPU401_MODE_OUTPUT) == 0) goto __second; - } if (output_ready (midi)) { if (snd_rawmidi_transmit(midi->substream_output[midi->output_mpu], &midi_byte, 1) == 1) { if (!midi->isvirtual || @@ -160,14 +157,11 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card) del_timer(&midi->timer); } midi->mode[midi->output_mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER; - spin_unlock_irqrestore (&midi->virtual, flags); goto __second; } } else { - spin_unlock_irqrestore (&midi->virtual, flags); return; } - spin_unlock_irqrestore (&midi->virtual, flags); } __second: @@ -185,15 +179,13 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card) break; } - spin_lock_irqsave (&midi->virtual, flags); + guard(spinlock_irqsave)(&midi->virtual); if (!midi->isvirtual) mask = 0; mpu = midi->output_mpu ^ mask; mask = 0; /* don't invert the value from now */ - if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) { - spin_unlock_irqrestore (&midi->virtual, flags); + if ((midi->mode[mpu] & MPU401_MODE_OUTPUT) == 0) return; - } if (snd_rawmidi_transmit_empty(midi->substream_output[mpu])) goto __timer; if (output_ready (midi)) { @@ -215,20 +207,16 @@ static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card) del_timer(&midi->timer); } midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER; - spin_unlock_irqrestore (&midi->virtual, flags); return; } } else { - spin_unlock_irqrestore (&midi->virtual, flags); return; } - spin_unlock_irqrestore (&midi->virtual, flags); } } static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream) { - unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; @@ -243,17 +231,15 @@ static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream if (!midi) return -EIO; - spin_lock_irqsave (&midi->open, flags); + guard(spinlock_irqsave)(&midi->open); midi->mode[mpu] |= MPU401_MODE_INPUT; midi->substream_input[mpu] = substream; - spin_unlock_irqrestore (&midi->open, flags); return 0; } static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream) { - unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; @@ -268,17 +254,15 @@ static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substrea if (!midi) return -EIO; - spin_lock_irqsave (&midi->open, flags); + guard(spinlock_irqsave)(&midi->open); midi->mode[mpu] |= MPU401_MODE_OUTPUT; midi->substream_output[mpu] = substream; - spin_unlock_irqrestore (&midi->open, flags); return 0; } static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream) { - unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; @@ -293,16 +277,14 @@ static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substrea if (!midi) return -EIO; - spin_lock_irqsave (&midi->open, flags); + guard(spinlock_irqsave)(&midi->open); midi->mode[mpu] &= ~MPU401_MODE_INPUT; - spin_unlock_irqrestore (&midi->open, flags); return 0; } static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream) { - unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; @@ -317,15 +299,13 @@ static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substre if (!midi) return -EIO; - spin_lock_irqsave (&midi->open, flags); + guard(spinlock_irqsave)(&midi->open); midi->mode[mpu] &= ~MPU401_MODE_OUTPUT; - spin_unlock_irqrestore (&midi->open, flags); return 0; } static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) { - unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; @@ -341,30 +321,27 @@ static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *subst if (!midi) return; - spin_lock_irqsave (&midi->virtual, flags); + guard(spinlock_irqsave)(&midi->virtual); if (up) { midi->mode[mpu] |= MPU401_MODE_INPUT_TRIGGER; } else { midi->mode[mpu] &= ~MPU401_MODE_INPUT_TRIGGER; } - spin_unlock_irqrestore (&midi->virtual, flags); } static void snd_wavefront_midi_output_timer(struct timer_list *t) { snd_wavefront_midi_t *midi = from_timer(midi, t, timer); snd_wavefront_card_t *card = midi->timer_card; - unsigned long flags; - spin_lock_irqsave (&midi->virtual, flags); - mod_timer(&midi->timer, 1 + jiffies); - spin_unlock_irqrestore (&midi->virtual, flags); + scoped_guard(spinlock_irqsave, &midi->virtual) { + mod_timer(&midi->timer, 1 + jiffies); + } snd_wavefront_midi_output_write(card); } static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) { - unsigned long flags; snd_wavefront_midi_t *midi; snd_wavefront_mpu_id mpu; @@ -380,22 +357,22 @@ static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *subs if (!midi) return; - spin_lock_irqsave (&midi->virtual, flags); - if (up) { - if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) { - if (!midi->istimer) { - timer_setup(&midi->timer, - snd_wavefront_midi_output_timer, - 0); - mod_timer(&midi->timer, 1 + jiffies); + scoped_guard(spinlock_irqsave, &midi->virtual) { + if (up) { + if ((midi->mode[mpu] & MPU401_MODE_OUTPUT_TRIGGER) == 0) { + if (!midi->istimer) { + timer_setup(&midi->timer, + snd_wavefront_midi_output_timer, + 0); + mod_timer(&midi->timer, 1 + jiffies); + } + midi->istimer++; + midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER; } - midi->istimer++; - midi->mode[mpu] |= MPU401_MODE_OUTPUT_TRIGGER; + } else { + midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER; } - } else { - midi->mode[mpu] &= ~MPU401_MODE_OUTPUT_TRIGGER; } - spin_unlock_irqrestore (&midi->virtual, flags); if (up) snd_wavefront_midi_output_write((snd_wavefront_card_t *)substream->rmidi->card->private_data); @@ -405,7 +382,6 @@ void snd_wavefront_midi_interrupt (snd_wavefront_card_t *card) { - unsigned long flags; snd_wavefront_midi_t *midi; static struct snd_rawmidi_substream *substream = NULL; static int mpu = external_mpu; @@ -419,37 +395,37 @@ snd_wavefront_midi_interrupt (snd_wavefront_card_t *card) return; } - spin_lock_irqsave (&midi->virtual, flags); - while (--max) { - - if (input_avail (midi)) { - byte = read_data (midi); - - if (midi->isvirtual) { - if (byte == WF_EXTERNAL_SWITCH) { - substream = midi->substream_input[external_mpu]; - mpu = external_mpu; - } else if (byte == WF_INTERNAL_SWITCH) { - substream = midi->substream_output[internal_mpu]; + scoped_guard(spinlock_irqsave, &midi->virtual) { + while (--max) { + + if (input_avail(midi)) { + byte = read_data(midi); + + if (midi->isvirtual) { + if (byte == WF_EXTERNAL_SWITCH) { + substream = midi->substream_input[external_mpu]; + mpu = external_mpu; + } else if (byte == WF_INTERNAL_SWITCH) { + substream = midi->substream_output[internal_mpu]; + mpu = internal_mpu; + } /* else just leave it as it is */ + } else { + substream = midi->substream_input[internal_mpu]; mpu = internal_mpu; - } /* else just leave it as it is */ - } else { - substream = midi->substream_input[internal_mpu]; - mpu = internal_mpu; - } + } - if (substream == NULL) { - continue; - } + if (substream == NULL) { + continue; + } - if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) { - snd_rawmidi_receive(substream, &byte, 1); + if (midi->mode[mpu] & MPU401_MODE_INPUT_TRIGGER) { + snd_rawmidi_receive(substream, &byte, 1); + } + } else { + break; } - } else { - break; } - } - spin_unlock_irqrestore (&midi->virtual, flags); + } snd_wavefront_midi_output_write(card); } @@ -471,13 +447,10 @@ void snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card) { - unsigned long flags; - - spin_lock_irqsave (&card->wavefront.midi.virtual, flags); + guard(spinlock_irqsave)(&card->wavefront.midi.virtual); // snd_wavefront_midi_input_close (card->ics2115_external_rmidi); // snd_wavefront_midi_output_close (card->ics2115_external_rmidi); card->wavefront.midi.isvirtual = 0; - spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags); } int diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 9eaab9ca4f95..0d78533e1cfd 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -1741,10 +1741,10 @@ snd_wavefront_internal_interrupt (snd_wavefront_card_t *card) return; } - spin_lock(&dev->irq_lock); - dev->irq_ok = 1; - dev->irq_cnt++; - spin_unlock(&dev->irq_lock); + scoped_guard(spinlock, &dev->irq_lock) { + dev->irq_ok = 1; + dev->irq_cnt++; + } wake_up(&dev->interrupt_sleeper); } @@ -1796,11 +1796,11 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev, wait_queue_entry_t wait; init_waitqueue_entry(&wait, current); - spin_lock_irq(&dev->irq_lock); - add_wait_queue(&dev->interrupt_sleeper, &wait); - dev->irq_ok = 0; - outb (val,port); - spin_unlock_irq(&dev->irq_lock); + scoped_guard(spinlock_irq, &dev->irq_lock) { + add_wait_queue(&dev->interrupt_sleeper, &wait); + dev->irq_ok = 0; + outb(val, port); + } while (!dev->irq_ok && time_before(jiffies, timeout)) { schedule_timeout_uninterruptible(1); barrier(); -- Gitee From 9e9d5be6db1168d7197250a74895a321d3e8e2b2 Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Tue, 16 Dec 2025 19:06:30 +0800 Subject: [PATCH 0798/1449] ALSA: wavefront: Clear substream pointers on close ANBZ: #35228 commit 931c86fc79894fc5c7760aa5dfc84379d6a1bf91 stable. commit e11c5c13ce0ab2325d38fe63500be1dd88b81e38 upstream. Clear substream pointers in close functions to avoid leaving dangling pointers, helping to improve code safety and prevents potential issues. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB7881DF762CAB45EE42F6D812AFC2A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/isa/wavefront/wavefront_midi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c index caa3b82f73f5..b9593b481396 100644 --- a/sound/isa/wavefront/wavefront_midi.c +++ b/sound/isa/wavefront/wavefront_midi.c @@ -278,6 +278,7 @@ static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substrea return -EIO; guard(spinlock_irqsave)(&midi->open); + midi->substream_input[mpu] = NULL; midi->mode[mpu] &= ~MPU401_MODE_INPUT; return 0; @@ -300,6 +301,7 @@ static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substre return -EIO; guard(spinlock_irqsave)(&midi->open); + midi->substream_output[mpu] = NULL; midi->mode[mpu] &= ~MPU401_MODE_OUTPUT; return 0; } -- Gitee From 7810c45b6315f005b30cd5f3fbf870c8b83af5bc Mon Sep 17 00:00:00 2001 From: Denis Arefev Date: Tue, 16 Dec 2025 19:42:26 +0800 Subject: [PATCH 0799/1449] ALSA: hda: cs35l41: Fix NULL pointer dereference in cs35l41_hda_read_acpi() ANBZ: #35228 commit 7a35a505d76a4b6cd426b59ff2d800d0394cc5d3 stable. commit c34b04cc6178f33c08331568c7fd25c5b9a39f66 upstream. The acpi_get_first_physical_node() function can return NULL, in which case the get_device() function also returns NULL, but this value is then dereferenced without checking,so add a check to prevent a crash. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 7b2f3eb492da ("ALSA: hda: cs35l41: Add support for CS35L41 in HDA systems") Cc: stable@vger.kernel.org Signed-off-by: Denis Arefev Reviewed-by: Richard Fitzgerald Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20251202101338.11437-1-arefev@swemel.ru [ NULL check right after acpi_dev_put(adev) cleanup call ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/hda/cs35l41_hda.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index d6aeadd44e65..aeefcf7a3206 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -1433,6 +1433,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i physdev = get_device(acpi_get_first_physical_node(adev)); acpi_dev_put(adev); + if (!physdev) + return -ENODEV; sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev)); if (IS_ERR(sub)) -- Gitee From 02468267879aee8186c503479a9a994d32ef4033 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Tue, 30 Dec 2025 08:47:24 +0800 Subject: [PATCH 0800/1449] ext4: fix string copying in parse_apply_sb_mount_options() ANBZ: #35228 commit 902ca2356f1e3ec5355c5808ad5d3f9d0095b0cc stable. commit ee5a977b4e771cc181f39d504426dbd31ed701cc upstream. strscpy_pad() can't be used to copy a non-NUL-term string into a NUL-term string of possibly bigger size. Commit 0efc5990bca5 ("string.h: Introduce memtostr() and memtostr_pad()") provides additional information in that regard. So if this happens, the following warning is observed: strnlen: detected buffer overflow: 65 byte read of buffer size 64 WARNING: CPU: 0 PID: 28655 at lib/string_helpers.c:1032 __fortify_report+0x96/0xc0 lib/string_helpers.c:1032 Modules linked in: CPU: 0 UID: 0 PID: 28655 Comm: syz-executor.3 Not tainted 6.12.54-syzkaller-00144-g5f0270f1ba00 #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:__fortify_report+0x96/0xc0 lib/string_helpers.c:1032 Call Trace: __fortify_panic+0x1f/0x30 lib/string_helpers.c:1039 strnlen include/linux/fortify-string.h:235 [inline] sized_strscpy include/linux/fortify-string.h:309 [inline] parse_apply_sb_mount_options fs/ext4/super.c:2504 [inline] __ext4_fill_super fs/ext4/super.c:5261 [inline] ext4_fill_super+0x3c35/0xad00 fs/ext4/super.c:5706 get_tree_bdev_flags+0x387/0x620 fs/super.c:1636 vfs_get_tree+0x93/0x380 fs/super.c:1814 do_new_mount fs/namespace.c:3553 [inline] path_mount+0x6ae/0x1f70 fs/namespace.c:3880 do_mount fs/namespace.c:3893 [inline] __do_sys_mount fs/namespace.c:4103 [inline] __se_sys_mount fs/namespace.c:4080 [inline] __x64_sys_mount+0x280/0x300 fs/namespace.c:4080 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x64/0x140 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x76/0x7e Since userspace is expected to provide s_mount_opts field to be at most 63 characters long with the ending byte being NUL-term, use a 64-byte buffer which matches the size of s_mount_opts, so that strscpy_pad() does its job properly. Return with error if the user still managed to provide a non-NUL-term string here. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 8ecb790ea8c3 ("ext4: avoid potential buffer over-read in parse_apply_sb_mount_options()") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin Reviewed-by: Baokun Li Reviewed-by: Jan Kara Message-ID: <20251101160430.222297-1-pchelkin@ispras.ru> Signed-off-by: Theodore Ts'o [ adapted 2-argument strscpy_pad() call to 3-argument form with explicit sizeof() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/super.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e22761903eb3..7280ac209131 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2548,7 +2548,7 @@ static int parse_apply_sb_mount_options(struct super_block *sb, struct ext4_fs_context *m_ctx) { struct ext4_sb_info *sbi = EXT4_SB(sb); - char s_mount_opts[65]; + char s_mount_opts[64]; struct ext4_fs_context *s_ctx = NULL; struct fs_context *fc = NULL; int ret = -ENOMEM; @@ -2556,7 +2556,8 @@ static int parse_apply_sb_mount_options(struct super_block *sb, if (!sbi->s_es->s_mount_opts[0]) return 0; - strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts, sizeof(s_mount_opts)); + if (strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts, sizeof(s_mount_opts)) < 0) + return -E2BIG; fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL); if (!fc) -- Gitee From da6b5176f2942db3d1ebbdb23701debc94cfac9b Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Tue, 30 Dec 2025 07:40:57 +0800 Subject: [PATCH 0801/1449] jbd2: fix the inconsistency between checksum and data in memory for journal sb ANBZ: #35228 commit 35521feb614d1ba3e62911d0d463fa1dcfe91290 stable. commit 6abfe107894af7e8ce3a2e120c619d81ee764ad5 upstream. Copying the file system while it is mounted as read-only results in a mount failure: [~]# mkfs.ext4 -F /dev/sdc [~]# mount /dev/sdc -o ro /mnt/test [~]# dd if=/dev/sdc of=/dev/sda bs=1M [~]# mount /dev/sda /mnt/test1 [ 1094.849826] JBD2: journal checksum error [ 1094.850927] EXT4-fs (sda): Could not load journal inode mount: mount /dev/sda on /mnt/test1 failed: Bad message The process described above is just an abstracted way I came up with to reproduce the issue. In the actual scenario, the file system was mounted read-only and then copied while it was still mounted. It was found that the mount operation failed. The user intended to verify the data or use it as a backup, and this action was performed during a version upgrade. Above issue may happen as follows: ext4_fill_super set_journal_csum_feature_set(sb) if (ext4_has_metadata_csum(sb)) incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3; if (test_opt(sb, JOURNAL_CHECKSUM) jbd2_journal_set_features(sbi->s_journal, compat, 0, incompat); lock_buffer(journal->j_sb_buffer); sb->s_feature_incompat |= cpu_to_be32(incompat); //The data in the journal sb was modified, but the checksum was not updated, so the data remaining in memory has a mismatch between the data and the checksum. unlock_buffer(journal->j_sb_buffer); In this case, the journal sb copied over is in a state where the checksum and data are inconsistent, so mounting fails. To solve the above issue, update the checksum in memory after modifying the journal sb. Fixes: 4fd5ea43bc11 ("jbd2: checksum journal superblock") Signed-off-by: Ye Bin Reviewed-by: Baokun Li Reviewed-by: Darrick J. Wong Reviewed-by: Jan Kara Message-ID: <20251103010123.3753631-1-yebin@huaweicloud.com> Signed-off-by: Theodore Ts'o Cc: stable@kernel.org [ jbd2_superblock_csum() also takes a journal param ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/jbd2/journal.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index b992fe219db2..4ac718d15d74 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -2829,6 +2829,12 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat, sb->s_feature_compat |= cpu_to_be32(compat); sb->s_feature_ro_compat |= cpu_to_be32(ro); sb->s_feature_incompat |= cpu_to_be32(incompat); + /* + * Update the checksum now so that it is valid even for read-only + * filesystems where jbd2_write_superblock() doesn't get called. + */ + if (jbd2_journal_has_csum_v2or3(journal)) + sb->s_checksum = jbd2_superblock_csum(journal, sb); unlock_buffer(journal->j_sb_buffer); jbd2_journal_init_transaction_limits(journal); @@ -2858,9 +2864,17 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat, sb = journal->j_superblock; + lock_buffer(journal->j_sb_buffer); sb->s_feature_compat &= ~cpu_to_be32(compat); sb->s_feature_ro_compat &= ~cpu_to_be32(ro); sb->s_feature_incompat &= ~cpu_to_be32(incompat); + /* + * Update the checksum now so that it is valid even for read-only + * filesystems where jbd2_write_superblock() doesn't get called. + */ + if (jbd2_journal_has_csum_v2or3(journal)) + sb->s_checksum = jbd2_superblock_csum(journal, sb); + unlock_buffer(journal->j_sb_buffer); jbd2_journal_init_transaction_limits(journal); } EXPORT_SYMBOL(jbd2_journal_clear_features); -- Gitee From 3f1f4a7744bfe00ba3b2498b3667779eb65a78ab Mon Sep 17 00:00:00 2001 From: Alexey Velichayshiy Date: Tue, 30 Dec 2025 07:15:51 +0800 Subject: [PATCH 0802/1449] gfs2: fix freeze error handling ANBZ: #35228 commit 0baa9f64bf79f0a8642570de0580d08c09cdef06 stable. commit 4cfc7d5a4a01d2133b278cdbb1371fba1b419174 upstream. After commit b77b4a4815a9 ("gfs2: Rework freeze / thaw logic"), the freeze error handling is broken because gfs2_do_thaw() overwrites the 'error' variable, causing incorrect processing of the original freeze error. Fix this by calling gfs2_do_thaw() when gfs2_lock_fs_check_clean() fails but ignoring its return value to preserve the original freeze error for proper reporting. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: b77b4a4815a9 ("gfs2: Rework freeze / thaw logic") Cc: stable@vger.kernel.org # v6.5+ Signed-off-by: Alexey Velichayshiy Signed-off-by: Andreas Gruenbacher [ gfs2_do_thaw() only takes one param ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/gfs2/super.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 49684bc82dc1..d43cac46e1dd 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -776,9 +776,7 @@ static int gfs2_freeze_super(struct super_block *sb, enum freeze_holder who) if (!error) break; /* success */ - error = gfs2_do_thaw(sdp); - if (error) - goto out; + (void)gfs2_do_thaw(sdp); if (error == -EBUSY) fs_err(sdp, "waiting for recovery before freeze\n"); -- Gitee From 787e6b0f370f439ca0effd0dece0b7d41fa36206 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 30 Dec 2025 05:51:49 +0800 Subject: [PATCH 0803/1449] btrfs: don't rewrite ret from inode_permission ANBZ: #35228 commit bb2805532f764a45fbbeb17ac74ef880228c1ff5 stable. commit 0185c2292c600993199bc6b1f342ad47a9e8c678 upstream. In our user safe ino resolve ioctl we'll just turn any ret into -EACCES from inode_permission(). This is redundant, and could potentially be wrong if we had an ENOMEM in the security layer or some such other error, so simply return the actual return value. Note: The patch was taken from v5 of fscrypt patchset (https://lore.kernel.org/linux-btrfs/cover.1706116485.git.josef@toxicpanda.com/) which was handled over time by various people: Omar Sandoval, Sweet Tea Dorminy, Josef Bacik. Fixes: 23d0b79dfaed ("btrfs: Add unprivileged version of ino_lookup ioctl") CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Johannes Thumshirn Signed-off-by: Josef Bacik Signed-off-by: Daniel Vacek Reviewed-by: David Sterba [ add note ] Signed-off-by: David Sterba [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/ioctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6c259b522dff..b3c951f99f61 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -2006,10 +2006,8 @@ static int btrfs_search_path_in_tree_user(struct mnt_idmap *idmap, ret = inode_permission(idmap, temp_inode, MAY_READ | MAY_EXEC); iput(temp_inode); - if (ret) { - ret = -EACCES; + if (ret) goto out_put; - } if (key.offset == upper_limit.objectid) break; -- Gitee From 677c7a656aa2819847c033d0b36b8b2c2c993ad5 Mon Sep 17 00:00:00 2001 From: "Sven Eckelmann (Plasma Cloud)" Date: Tue, 30 Dec 2025 04:36:31 +0800 Subject: [PATCH 0804/1449] wifi: mt76: Fix DTS power-limits on little endian systems ANBZ: #35228 commit 93e4a783d34c0b3f48eeef9123d43dfff76bb8f1 stable. commit 38b845e1f9e810869b0a0b69f202b877b7b7fb12 upstream. The power-limits for ru and mcs and stored in the devicetree as bytewise array (often with sizes which are not a multiple of 4). These arrays have a prefix which defines for how many modes a line is applied. This prefix is also only a byte - but the code still tried to fix the endianness of this byte with a be32 operation. As result, loading was mostly failing or was sending completely unexpected values to the firmware. Since the other rates are also stored in the devicetree as bytewise arrays, just drop the u32 access + be32_to_cpu conversion and directly access them as bytes arrays. Cc: stable@vger.kernel.org Fixes: 22b980badc0f ("mt76: add functions for parsing rate power limits from DT") Fixes: a9627d992b5e ("mt76: extend DT rate power limits to support 11ax devices") Signed-off-by: Sven Eckelmann (Plasma Cloud) Signed-off-by: Felix Fietkau [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/mediatek/mt76/eeprom.c | 37 +++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index 49e6c866a57f..1663090e58bb 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -245,6 +245,19 @@ mt76_get_of_array(struct device_node *np, char *name, size_t *len, int min) return prop->value; } +static const s8 * +mt76_get_of_array_s8(struct device_node *np, char *name, size_t *len, int min) +{ + struct property *prop = of_find_property(np, name, NULL); + + if (!prop || !prop->value || prop->length < min) + return NULL; + + *len = prop->length; + + return prop->value; +} + static struct device_node * mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan) { @@ -284,7 +297,7 @@ mt76_get_txs_delta(struct device_node *np, u8 nss) } static void -mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data, +mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data, s8 target_power, s8 nss_delta, s8 *max_power) { int i; @@ -293,15 +306,14 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data, return; for (i = 0; i < pwr_len; i++) { - pwr[i] = min_t(s8, target_power, - be32_to_cpu(data[i]) + nss_delta); + pwr[i] = min_t(s8, target_power, data[i] + nss_delta); *max_power = max(*max_power, pwr[i]); } } static void mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, - const __be32 *data, size_t len, s8 target_power, + const s8 *data, size_t len, s8 target_power, s8 nss_delta, s8 *max_power) { int i, cur; @@ -309,8 +321,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, if (!data) return; - len /= 4; - cur = be32_to_cpu(data[0]); + cur = data[0]; for (i = 0; i < pwr_num; i++) { if (len < pwr_len + 1) break; @@ -325,7 +336,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, if (!len) break; - cur = be32_to_cpu(data[0]); + cur = data[0]; } } @@ -336,7 +347,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, { struct mt76_dev *dev = phy->dev; struct device_node *np; - const __be32 *val; + const s8 *val; char name[16]; u32 mcs_rates = dev->drv->mcs_rates; u32 ru_rates = ARRAY_SIZE(dest->ru[0]); @@ -382,21 +393,21 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, txs_delta = mt76_get_txs_delta(np, hweight8(phy->antenna_mask)); - val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck)); + val = mt76_get_of_array_s8(np, "rates-cck", &len, ARRAY_SIZE(dest->cck)); mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val, target_power, txs_delta, &max_power); - val = mt76_get_of_array(np, "rates-ofdm", - &len, ARRAY_SIZE(dest->ofdm)); + val = mt76_get_of_array_s8(np, "rates-ofdm", + &len, ARRAY_SIZE(dest->ofdm)); mt76_apply_array_limit(dest->ofdm, ARRAY_SIZE(dest->ofdm), val, target_power, txs_delta, &max_power); - val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1); + val = mt76_get_of_array_s8(np, "rates-mcs", &len, mcs_rates + 1); mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]), ARRAY_SIZE(dest->mcs), val, len, target_power, txs_delta, &max_power); - val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1); + val = mt76_get_of_array_s8(np, "rates-ru", &len, ru_rates + 1); mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]), ARRAY_SIZE(dest->ru), val, len, target_power, txs_delta, &max_power); -- Gitee From 42c8a8dfb9d2e9cfa059919c4ae57620cdbce234 Mon Sep 17 00:00:00 2001 From: xu xin Date: Tue, 30 Dec 2025 10:54:43 +0800 Subject: [PATCH 0805/1449] mm/ksm: fix exec/fork inheritance support for prctl ANBZ: #35228 commit c08838ce6b502e969b554577501d84b4ede0818c stable. commit 590c03ca6a3fbb114396673314e2aa483839608b upstream. Patch series "ksm: fix exec/fork inheritance", v2. This series fixes exec/fork inheritance. See the detailed description of the issue below. This patch (of 2): Background ========== commit d7597f59d1d33 ("mm: add new api to enable ksm per process") introduced MMF_VM_MERGE_ANY for mm->flags, and allowed user to set it by prctl() so that the process's VMAs are forcibly scanned by ksmd. Subsequently, the 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") supported inheriting the MMF_VM_MERGE_ANY flag when a task calls execve(). Finally, commit 3a9e567ca45fb ("mm/ksm: fix ksm exec support for prctl") fixed the issue that ksmd doesn't scan the mm_struct with MMF_VM_MERGE_ANY by adding the mm_slot to ksm_mm_head in __bprm_mm_init(). Problem ======= In some extreme scenarios, however, this inheritance of MMF_VM_MERGE_ANY during exec/fork can fail. For example, when the scanning frequency of ksmd is tuned extremely high, a process carrying MMF_VM_MERGE_ANY may still fail to pass it to the newly exec'd process. This happens because ksm_execve() is executed too early in the do_execve flow (prematurely adding the new mm_struct to the ksm_mm_slot list). As a result, before do_execve completes, ksmd may have already performed a scan and found that this new mm_struct has no VM_MERGEABLE VMAs, thus clearing its MMF_VM_MERGE_ANY flag. Consequently, when the new program executes, the flag MMF_VM_MERGE_ANY inheritance missed. Root reason =========== commit d7597f59d1d33 ("mm: add new api to enable ksm per process") clear the flag MMF_VM_MERGE_ANY when ksmd found no VM_MERGEABLE VMAs. Solution ======== Firstly, Don't clear MMF_VM_MERGE_ANY when ksmd found no VM_MERGEABLE VMAs, because perhaps their mm_struct has just been added to ksm_mm_slot list, and its process has not yet officially started running or has not yet performed mmap/brk to allocate anonymous VMAS. Secondly, recheck MMF_VM_MERGEABLE again if a process takes MMF_VM_MERGE_ANY, and create a mm_slot and join it into ksm_scan_list again. Link: https://lkml.kernel.org/r/20251007182504440BJgK8VXRHh8TD7IGSUIY4@zte.com.cn Link: https://lkml.kernel.org/r/20251007182821572h_SoFqYZXEP1mvWI4n9VL@zte.com.cn Fixes: 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") Fixes: d7597f59d1d3 ("mm: add new api to enable ksm per process") Signed-off-by: xu xin Cc: Stefan Roesch Cc: David Hildenbrand Cc: Jinjiang Tu Cc: Wang Yaxin Cc: Yang Yang Cc: Signed-off-by: Andrew Morton [ changed mm_flags_test() and mm_flags_clear() calls to test_bit() and clear_bit() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/ksm.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/mm/ksm.c b/mm/ksm.c index d447874f75c0..4e9cba527ad3 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -2457,8 +2457,14 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page) spin_unlock(&ksm_mmlist_lock); mm_slot_free(mm_slot_cache, mm_slot); + /* + * Only clear MMF_VM_MERGEABLE. We must not clear + * MMF_VM_MERGE_ANY, because for those MMF_VM_MERGE_ANY process, + * perhaps their mm_struct has just been added to ksm_mm_slot + * list, and its process has not yet officially started running + * or has not yet performed mmap/brk to allocate anonymous VMAS. + */ clear_bit(MMF_VM_MERGEABLE, &mm->flags); - clear_bit(MMF_VM_MERGE_ANY, &mm->flags); mmap_read_unlock(mm); mmdrop(mm); } else { @@ -2573,8 +2579,16 @@ void ksm_add_vma(struct vm_area_struct *vma) { struct mm_struct *mm = vma->vm_mm; - if (test_bit(MMF_VM_MERGE_ANY, &mm->flags)) + if (test_bit(MMF_VM_MERGE_ANY, &mm->flags)) { __ksm_add_vma(vma); + /* + * Generally, the flags here always include MMF_VM_MERGEABLE. + * However, in rare cases, this flag may be cleared by ksmd who + * scans a cycle without finding any mergeable vma. + */ + if (unlikely(!test_bit(MMF_VM_MERGEABLE, &mm->flags))) + __ksm_enter(mm); + } } static void ksm_add_vmas(struct mm_struct *mm) -- Gitee From ed42e121fe90a85f7b057ae5dce278e51069e5b2 Mon Sep 17 00:00:00 2001 From: Zhang Zekun Date: Tue, 30 Dec 2025 21:19:20 +0800 Subject: [PATCH 0806/1449] usb: ohci-nxp: Use helper function devm_clk_get_enabled() ANBZ: #35228 commit 2a16f46eef6d344b0033f87ff54f35e8bcc15a62 stable. commit c146ede472717f352b7283a525bd9a1a2b15e2cf upstream. devm_clk_get() and clk_prepare_enable() can be replaced by helper function devm_clk_get_enabled(). Let's use devm_clk_get_enabled() to simplify code and avoid calling clk_disable_unprepare(). Signed-off-by: Zhang Zekun Acked-by: Alan Stern Link: https://lore.kernel.org/r/20240902123020.29267-3-zhangzekun11@huawei.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: b4c61e542faf ("usb: ohci-nxp: fix device leak on probe failure") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/ohci-nxp.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 8264c454f6bd..5b775e1ea527 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -51,8 +51,6 @@ static struct hc_driver __read_mostly ohci_nxp_hc_driver; static struct i2c_client *isp1301_i2c_client; -static struct clk *usb_host_clk; - static void isp1301_configure_lpc32xx(void) { /* LPC32XX only supports DAT_SE0 USB mode */ @@ -155,6 +153,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) struct resource *res; int ret = 0, irq; struct device_node *isp1301_node; + struct clk *usb_host_clk; if (pdev->dev.of_node) { isp1301_node = of_parse_phandle(pdev->dev.of_node, @@ -180,26 +179,20 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) } /* Enable USB host clock */ - usb_host_clk = devm_clk_get(&pdev->dev, NULL); + usb_host_clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(usb_host_clk)) { - dev_err(&pdev->dev, "failed to acquire USB OHCI clock\n"); + dev_err(&pdev->dev, "failed to acquire and start USB OHCI clock\n"); ret = PTR_ERR(usb_host_clk); goto fail_disable; } - ret = clk_prepare_enable(usb_host_clk); - if (ret < 0) { - dev_err(&pdev->dev, "failed to start USB OHCI clock\n"); - goto fail_disable; - } - isp1301_configure(); hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); ret = -ENOMEM; - goto fail_hcd; + goto fail_disable; } hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); @@ -229,8 +222,6 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) ohci_nxp_stop_hc(); fail_resource: usb_put_hcd(hcd); -fail_hcd: - clk_disable_unprepare(usb_host_clk); fail_disable: isp1301_i2c_client = NULL; return ret; @@ -243,7 +234,6 @@ static void ohci_hcd_nxp_remove(struct platform_device *pdev) usb_remove_hcd(hcd); ohci_nxp_stop_hc(); usb_put_hcd(hcd); - clk_disable_unprepare(usb_host_clk); isp1301_i2c_client = NULL; } -- Gitee From b7b5e02f62bce6170b920570b37e1e67d0d1c263 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 30 Dec 2025 21:19:21 +0800 Subject: [PATCH 0807/1449] usb: ohci-nxp: fix device leak on probe failure ANBZ: #35228 commit b0d2a7ccd17c16d29f9ad73c9928458f4fb3b82e stable. commit b4c61e542faf8c9131d69ecfc3ad6de96d1b2ab8 upstream. Make sure to drop the reference taken when looking up the PHY I2C device during probe on probe failure (e.g. probe deferral) and on driver unbind. Fixes: 73108aa90cbf ("USB: ohci-nxp: Use isp1301 driver") Cc: stable@vger.kernel.org # 3.5 Reported-by: Ma Ke Link: https://lore.kernel.org/lkml/20251117013428.21840-1-make24@iscas.ac.cn/ Signed-off-by: Johan Hovold Acked-by: Alan Stern Reviewed-by: Vladimir Zapolskiy Link: https://patch.msgid.link/20251218153519.19453-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/ohci-nxp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 5b775e1ea527..25a739ebc215 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -223,6 +223,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) fail_resource: usb_put_hcd(hcd); fail_disable: + put_device(&isp1301_i2c_client->dev); isp1301_i2c_client = NULL; return ret; } @@ -234,6 +235,7 @@ static void ohci_hcd_nxp_remove(struct platform_device *pdev) usb_remove_hcd(hcd); ohci_nxp_stop_hc(); usb_put_hcd(hcd); + put_device(&isp1301_i2c_client->dev); isp1301_i2c_client = NULL; } -- Gitee From 9bb54977a4e15b535159bae35ec2b4ea4335d9b7 Mon Sep 17 00:00:00 2001 From: Seunghwan Baek Date: Tue, 30 Dec 2025 23:58:01 +0800 Subject: [PATCH 0808/1449] scsi: ufs: core: Add ufshcd_update_evt_hist() for UFS suspend error ANBZ: #35228 commit d1d03d9184a686f6369d9a47eee9d562c6123af0 stable. commit c9f36f04a8a2725172cdf2b5e32363e4addcb14c upstream. If UFS resume fails, the event history is updated in ufshcd_resume(), but there is no code anywhere to record UFS suspend. Therefore, add code to record UFS suspend error event history. Fixes: dd11376b9f1b ("scsi: ufs: Split the drivers/scsi/ufs directory") Cc: stable@vger.kernel.org Signed-off-by: Seunghwan Baek Reviewed-by: Peter Wang Link: https://patch.msgid.link/20251210063854.1483899-2-sh8267.baek@samsung.com Signed-off-by: Martin K. Petersen [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ufs/core/ufshcd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 9d6a47abe4bc..50d8a816d943 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -10182,7 +10182,7 @@ static int ufshcd_suspend(struct ufs_hba *hba) ret = ufshcd_setup_clocks(hba, false); if (ret) { ufshcd_enable_irq(hba); - return ret; + goto out; } if (ufshcd_is_clkgating_allowed(hba)) { hba->clk_gating.state = CLKS_OFF; @@ -10193,6 +10193,9 @@ static int ufshcd_suspend(struct ufs_hba *hba) ufshcd_vreg_set_lpm(hba); /* Put the host controller in low power mode if possible */ ufshcd_hba_vreg_set_lpm(hba); +out: + if (ret) + ufshcd_update_evt_hist(hba, UFS_EVT_SUSPEND_ERR, (u32)ret); return ret; } -- Gitee From bcf3635b22f4c786fee28cb86fb9a17c64ccd40c Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Tue, 30 Dec 2025 21:42:06 +0800 Subject: [PATCH 0809/1449] mptcp: pm: ignore unknown endpoint flags ANBZ: #35228 commit 5ceea587c4e205c5eddd5390a678188b6dad4ff7 stable. commit 0ace3297a7301911e52d8195cb1006414897c859 upstream. Before this patch, the kernel was saving any flags set by the userspace, even unknown ones. This doesn't cause critical issues because the kernel is only looking at specific ones. But on the other hand, endpoints dumps could tell the userspace some recent flags seem to be supported on older kernel versions. Instead, ignore all unknown flags when parsing them. By doing that, the userspace can continue to set unsupported flags, but it has a way to verify what is supported by the kernel. Note that it sounds better to continue accepting unsupported flags not to change the behaviour, but also that eases things on the userspace side by adding "optional" endpoint types only supported by newer kernel versions without having to deal with the different kernel versions. A note for the backports: there will be conflicts in mptcp.h on older versions not having the mentioned flags, the new line should still be added last, and the '5' needs to be adapted to have the same value as the last entry. Fixes: 01cacb00b35c ("mptcp: add netlink-based PM") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251205-net-mptcp-misc-fixes-6-19-rc1-v1-1-9e4781a6c1b8@kernel.org Signed-off-by: Jakub Kicinski [ GENMASK(5, 0) => GENMASK(4, 0) + context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/uapi/linux/mptcp.h | 1 + net/mptcp/pm_netlink.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h index 00d622121673..926d5de5fd21 100644 --- a/include/uapi/linux/mptcp.h +++ b/include/uapi/linux/mptcp.h @@ -88,6 +88,7 @@ enum { #define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2) #define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3) #define MPTCP_PM_ADDR_FLAG_IMPLICIT (1 << 4) +#define MPTCP_PM_ADDR_FLAGS_MASK GENMASK(4, 0) enum { MPTCP_PM_CMD_UNSPEC, diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 8dbe826555d2..9f25cfd96f98 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -1435,7 +1435,8 @@ int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info, } if (tb[MPTCP_PM_ADDR_ATTR_FLAGS]) - entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]); + entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]) & + MPTCP_PM_ADDR_FLAGS_MASK; if (tb[MPTCP_PM_ADDR_ATTR_PORT]) entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT])); -- Gitee From df7bd616dfe94de0353cfebccd85f015e381c753 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 00:15:38 +0800 Subject: [PATCH 0810/1449] f2fs: use f2fs_err_ratelimited() to avoid redundant logs ANBZ: #35228 commit c375c4b3997e57afd01f71024eaa429aa855e244 stable. commit 0b8eb814e05885cde53c1d56ee012a029b8413e6 upstream. Use f2fs_err_ratelimited() to instead f2fs_err() in f2fs_record_stop_reason() and f2fs_record_errors() to avoid redundant logs. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: ca8b201f2854 ("f2fs: fix to avoid potential deadlock") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/super.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 31330a7e48a1..48d220bc31f5 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -4069,7 +4069,9 @@ static void f2fs_record_stop_reason(struct f2fs_sb_info *sbi) f2fs_up_write(&sbi->sb_lock); if (err) - f2fs_err(sbi, "f2fs_commit_super fails to record err:%d", err); + f2fs_err_ratelimited(sbi, + "f2fs_commit_super fails to record stop_reason, err:%d", + err); } void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag) @@ -4112,8 +4114,9 @@ static void f2fs_record_errors(struct f2fs_sb_info *sbi, unsigned char error) err = f2fs_commit_super(sbi, false); if (err) - f2fs_err(sbi, "f2fs_commit_super fails to record errors:%u, err:%d", - error, err); + f2fs_err_ratelimited(sbi, + "f2fs_commit_super fails to record errors:%u, err:%d", + error, err); out_unlock: f2fs_up_write(&sbi->sb_lock); } -- Gitee From 2a837b9a8569afc2c74e61bd19c83871647e376e Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 00:15:39 +0800 Subject: [PATCH 0811/1449] f2fs: fix to avoid potential deadlock ANBZ: #35228 commit 8bd6dff8b801abaa362272894bda795bf0cf1307 stable. commit ca8b201f28547e28343a6f00a6e91fa8c09572fe upstream. As Jiaming Zhang and syzbot reported, there is potential deadlock in f2fs as below: Chain exists of: &sbi->cp_rwsem --> fs_reclaim --> sb_internal#2 Possible unsafe locking scenario: CPU0 CPU1 ---- ---- rlock(sb_internal#2); lock(fs_reclaim); lock(sb_internal#2); rlock(&sbi->cp_rwsem); *** DEADLOCK *** 3 locks held by kswapd0/73: #0: ffffffff8e247a40 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat mm/vmscan.c:7015 [inline] #0: ffffffff8e247a40 (fs_reclaim){+.+.}-{0:0}, at: kswapd+0x951/0x2800 mm/vmscan.c:7389 #1: ffff8880118400e0 (&type->s_umount_key#50){.+.+}-{4:4}, at: super_trylock_shared fs/super.c:562 [inline] #1: ffff8880118400e0 (&type->s_umount_key#50){.+.+}-{4:4}, at: super_cache_scan+0x91/0x4b0 fs/super.c:197 #2: ffff888011840610 (sb_internal#2){.+.+}-{0:0}, at: f2fs_evict_inode+0x8d9/0x1b60 fs/f2fs/inode.c:890 stack backtrace: CPU: 0 UID: 0 PID: 73 Comm: kswapd0 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_circular_bug+0x2ee/0x310 kernel/locking/lockdep.c:2043 check_noncircular+0x134/0x160 kernel/locking/lockdep.c:2175 check_prev_add kernel/locking/lockdep.c:3165 [inline] check_prevs_add kernel/locking/lockdep.c:3284 [inline] validate_chain+0xb9b/0x2140 kernel/locking/lockdep.c:3908 __lock_acquire+0xab9/0xd20 kernel/locking/lockdep.c:5237 lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 down_read+0x46/0x2e0 kernel/locking/rwsem.c:1537 f2fs_down_read fs/f2fs/f2fs.h:2278 [inline] f2fs_lock_op fs/f2fs/f2fs.h:2357 [inline] f2fs_do_truncate_blocks+0x21c/0x10c0 fs/f2fs/file.c:791 f2fs_truncate_blocks+0x10a/0x300 fs/f2fs/file.c:867 f2fs_truncate+0x489/0x7c0 fs/f2fs/file.c:925 f2fs_evict_inode+0x9f2/0x1b60 fs/f2fs/inode.c:897 evict+0x504/0x9c0 fs/inode.c:810 f2fs_evict_inode+0x1dc/0x1b60 fs/f2fs/inode.c:853 evict+0x504/0x9c0 fs/inode.c:810 dispose_list fs/inode.c:852 [inline] prune_icache_sb+0x21b/0x2c0 fs/inode.c:1000 super_cache_scan+0x39b/0x4b0 fs/super.c:224 do_shrink_slab+0x6ef/0x1110 mm/shrinker.c:437 shrink_slab_memcg mm/shrinker.c:550 [inline] shrink_slab+0x7ef/0x10d0 mm/shrinker.c:628 shrink_one+0x28a/0x7c0 mm/vmscan.c:4955 shrink_many mm/vmscan.c:5016 [inline] lru_gen_shrink_node mm/vmscan.c:5094 [inline] shrink_node+0x315d/0x3780 mm/vmscan.c:6081 kswapd_shrink_node mm/vmscan.c:6941 [inline] balance_pgdat mm/vmscan.c:7124 [inline] kswapd+0x147c/0x2800 mm/vmscan.c:7389 kthread+0x70e/0x8a0 kernel/kthread.c:463 ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 The root cause is deadlock among four locks as below: kswapd - fs_reclaim --- Lock A - shrink_one - evict - f2fs_evict_inode - sb_start_intwrite --- Lock B - iput - evict - f2fs_evict_inode - sb_start_intwrite --- Lock B - f2fs_truncate - f2fs_truncate_blocks - f2fs_do_truncate_blocks - f2fs_lock_op --- Lock C ioctl - f2fs_ioc_commit_atomic_write - f2fs_lock_op --- Lock C - __f2fs_commit_atomic_write - __replace_atomic_write_block - f2fs_get_dnode_of_data - __get_node_folio - f2fs_check_nid_range - f2fs_handle_error - f2fs_record_errors - f2fs_down_write --- Lock D open - do_open - do_truncate - security_inode_need_killpriv - f2fs_getxattr - lookup_all_xattrs - f2fs_handle_error - f2fs_record_errors - f2fs_down_write --- Lock D - f2fs_commit_super - read_mapping_folio - filemap_alloc_folio_noprof - prepare_alloc_pages - fs_reclaim_acquire --- Lock A In order to avoid such deadlock, we need to avoid grabbing sb_lock in f2fs_handle_error(), so, let's use asynchronous method instead: - remove f2fs_handle_error() implementation - rename f2fs_handle_error_async() to f2fs_handle_error() - spread f2fs_handle_error() Fixes: 95fa90c9e5a7 ("f2fs: support recording errors into superblock") Cc: stable@kernel.org Reported-by: syzbot+14b90e1156b9f6fc1266@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-f2fs-devel/68eae49b.050a0220.ac43.0001.GAE@google.com Reported-by: Jiaming Zhang Closes: https://lore.kernel.org/lkml/CANypQFa-Gy9sD-N35o3PC+FystOWkNuN8pv6S75HLT0ga-Tzgw@mail.gmail.com Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/compress.c | 5 +---- fs/f2fs/f2fs.h | 1 - fs/f2fs/super.c | 41 ----------------------------------------- 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 0b0a049be681..231f6264be7d 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -754,10 +754,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) ret = -EFSCORRUPTED; /* Avoid f2fs_commit_super in irq context */ - if (!in_task) - f2fs_handle_error_async(sbi, ERROR_FAIL_DECOMPRESSION); - else - f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION); + f2fs_handle_error(sbi, ERROR_FAIL_DECOMPRESSION); goto out_release; } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 7da0421236fb..a45713660aeb 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3638,7 +3638,6 @@ void f2fs_quota_off_umount(struct super_block *sb); void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag); void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason); void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error); -void f2fs_handle_error_async(struct f2fs_sb_info *sbi, unsigned char error); int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover); int f2fs_sync_fs(struct super_block *sb, int sync); int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 48d220bc31f5..c0edf5b0e6cb 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -4086,48 +4086,7 @@ void f2fs_save_errors(struct f2fs_sb_info *sbi, unsigned char flag) spin_unlock_irqrestore(&sbi->error_lock, flags); } -static bool f2fs_update_errors(struct f2fs_sb_info *sbi) -{ - unsigned long flags; - bool need_update = false; - - spin_lock_irqsave(&sbi->error_lock, flags); - if (sbi->error_dirty) { - memcpy(F2FS_RAW_SUPER(sbi)->s_errors, sbi->errors, - MAX_F2FS_ERRORS); - sbi->error_dirty = false; - need_update = true; - } - spin_unlock_irqrestore(&sbi->error_lock, flags); - - return need_update; -} - -static void f2fs_record_errors(struct f2fs_sb_info *sbi, unsigned char error) -{ - int err; - - f2fs_down_write(&sbi->sb_lock); - - if (!f2fs_update_errors(sbi)) - goto out_unlock; - - err = f2fs_commit_super(sbi, false); - if (err) - f2fs_err_ratelimited(sbi, - "f2fs_commit_super fails to record errors:%u, err:%d", - error, err); -out_unlock: - f2fs_up_write(&sbi->sb_lock); -} - void f2fs_handle_error(struct f2fs_sb_info *sbi, unsigned char error) -{ - f2fs_save_errors(sbi, error); - f2fs_record_errors(sbi, error); -} - -void f2fs_handle_error_async(struct f2fs_sb_info *sbi, unsigned char error) { f2fs_save_errors(sbi, error); -- Gitee From 3970b4e9ae6ac99956035169f076d59f60ca25ec Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 31 Dec 2025 11:46:07 +0800 Subject: [PATCH 0812/1449] NFSD: Clear SECLABEL in the suppattr_exclcreat bitmap ANBZ: #35228 commit 2e14206551bc34e9be47839c32ac9b65b4c2ab0f stable. commit 27d17641cacfedd816789b75d342430f6b912bd2 upstream. >>From RFC 8881: 5.8.1.14. Attribute 75: suppattr_exclcreat > The bit vector that would set all REQUIRED and RECOMMENDED > attributes that are supported by the EXCLUSIVE4_1 method of file > creation via the OPEN operation. The scope of this attribute > applies to all objects with a matching fsid. There's nothing in RFC 8881 that states that suppattr_exclcreat is or is not allowed to contain bits for attributes that are clear in the reported supported_attrs bitmask. But it doesn't make sense for an NFS server to indicate that it /doesn't/ implement an attribute, but then also indicate that clients /are/ allowed to set that attribute using OPEN(create) with EXCLUSIVE4_1. Ensure that the SECURITY_LABEL and ACL bits are not set in the suppattr_exclcreat bitmask when they are also not set in the supported_attrs bitmask. Fixes: 8c18f2052e75 ("nfsd41: SUPPATTR_EXCLCREAT attribute") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/nfs4xdr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 3eff780fd8da..15189e683e83 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3419,6 +3419,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 supp[3]; memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp)); + if (!IS_POSIXACL(d_inode(dentry))) + supp[0] &= ~FATTR4_WORD0_ACL; + if (!contextsupport) + supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL; + supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0; supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1; supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2; -- Gitee From f8d0b11af32fb15ef0a8213739f71787beaccfc1 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Wed, 31 Dec 2025 23:00:59 +0800 Subject: [PATCH 0813/1449] gpiolib: acpi: Add quirk for Dell Precision 7780 ANBZ: #35228 commit 2ce95f8656b63c42cd0a1f3cdc5459b6c3a989b9 stable. commit 2d967310c49ed93ac11cef408a55ddf15c3dd52e upstream. Dell Precision 7780 often wakes up on its own from suspend. Sometimes wake up happens immediately (i. e. within 7 seconds), sometimes it happens after, say, 30 minutes. Fixes: 1796f808e4bb ("HID: i2c-hid: acpi: Stop setting wakeup_capable") Link: https://lore.kernel.org/linux-i2c/197ae95ffd8.dc819e60457077.7692120488609091556@zohomail.com/ Cc: stable@vger.kernel.org Reviewed-by: Andy Shevchenko Signed-off-by: Askar Safin Link: https://lore.kernel.org/r/20251206180414.3183334-2-safinaskar@gmail.com Signed-off-by: Bartosz Golaszewski [ adapted quirk entry location from gpiolib-acpi-quirks.c to gpiolib-acpi.c ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpiolib-acpi.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 8ddd5e8341a0..86de8740c0d4 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -1720,6 +1720,28 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { .ignore_interrupt = "AMDI0030:00@11", }, }, + { + /* + * Spurious wakeups, likely from touchpad controller + * Dell Precision 7780 + * Found in BIOS 1.24.1 + * + * Found in touchpad firmware, installed by Dell Touchpad Firmware Update Utility version 1160.4196.9, A01 + * ( Dell-Touchpad-Firmware-Update-Utility_VYGNN_WIN64_1160.4196.9_A00.EXE ), + * released on 11 Jul 2024 + * + * https://lore.kernel.org/linux-i2c/197ae95ffd8.dc819e60457077.7692120488609091556@zohomail.com/ + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Precision"), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7780"), + DMI_MATCH(DMI_BOARD_NAME, "0C6JVW"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "VEN_0488:00@355", + }, + }, {} /* Terminating entry */ }; -- Gitee From 2d23aa17b1d11d7f8cb27fc6a0883ac4317ff5d2 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Thu, 1 Jan 2026 05:20:37 +0800 Subject: [PATCH 0814/1449] ARM: dts: microchip: sama7g5: fix uart fifo size to 32 ANBZ: #35228 commit 8ca34c5cedecfb6f8da9b12394fd713eee6cc25e stable. commit 5654889a94b0de5ad6ceae3793e7f5e0b61b50b6 upstream. On some flexcom nodes related to uart, the fifo sizes were wrong: fix them to 32 data. Fixes: 7540629e2fc7 ("ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek") Cc: stable@vger.kernel.org # 5.15+ Signed-off-by: Nicolas Ferre Link: https://lore.kernel.org/r/20251114103313.20220-2-nicolas.ferre@microchip.com Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/microchip/sama7g5.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi index 7a95464bb78d..fc59f4e0b5aa 100644 --- a/arch/arm/boot/dts/microchip/sama7g5.dtsi +++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi @@ -811,7 +811,7 @@ uart4: serial@200 { dma-names = "tx", "rx"; atmel,use-dma-rx; atmel,use-dma-tx; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; }; @@ -837,7 +837,7 @@ uart7: serial@200 { dma-names = "tx", "rx"; atmel,use-dma-rx; atmel,use-dma-tx; - atmel,fifo-size = <16>; + atmel,fifo-size = <32>; status = "disabled"; }; }; -- Gitee From 3b3ea72a4570b5f6dc2650c98f27ceb97a84f4c1 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Thu, 1 Jan 2026 06:32:17 +0800 Subject: [PATCH 0815/1449] svcrdma: bound check rq_pages index in inline path ANBZ: #35228 commit 7ba826aae1d43212f3baa53a2175ad949e21926e stable. commit d1bea0ce35b6095544ee82bb54156fc62c067e58 upstream. svc_rdma_copy_inline_range indexed rqstp->rq_pages[rc_curpage] without verifying rc_curpage stays within the allocated page array. Add guards before the first use and after advancing to a new page. Fixes: d7cc73972661 ("svcrdma: support multiple Read chunks per RPC") Cc: stable@vger.kernel.org Signed-off-by: Joshua Rogers Signed-off-by: Chuck Lever [ adapted rc_curpage and rq_maxpages fields to ri_pageno and RPCSVC_MAXPAGES constant ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sunrpc/xprtrdma/svc_rdma_rw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 49d1023e66e9..82c4202fa3c1 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -815,6 +815,9 @@ static int svc_rdma_copy_inline_range(struct svc_rdma_read_info *info, for (page_no = 0; page_no < numpages; page_no++) { unsigned int page_len; + if (info->ri_pageno >= RPCSVC_MAXPAGES) + return -EINVAL; + page_len = min_t(unsigned int, remaining, PAGE_SIZE - info->ri_pageoff); -- Gitee From 8353966971f206a9d70f06ea6caa0a1015f7cd13 Mon Sep 17 00:00:00 2001 From: Joanne Koong Date: Thu, 1 Jan 2026 09:13:41 -0500 Subject: [PATCH 0816/1449] fuse: fix readahead reclaim deadlock ANBZ: #35228 commit cf74785c00b8b1c0c4a9dd74bfa9c22d62e2d99f stable. commit bd5603eaae0aabf527bfb3ce1bb07e979ce5bd50 upstream. Commit e26ee4efbc79 ("fuse: allocate ff->release_args only if release is needed") skips allocating ff->release_args if the server does not implement open. However in doing so, fuse_prepare_release() now skips grabbing the reference on the inode, which makes it possible for an inode to be evicted from the dcache while there are inflight readahead requests. This causes a deadlock if the server triggers reclaim while servicing the readahead request and reclaim attempts to evict the inode of the file being read ahead. Since the folio is locked during readahead, when reclaim evicts the fuse inode and fuse_evict_inode() attempts to remove all folios associated with the inode from the page cache (truncate_inode_pages_range()), reclaim will block forever waiting for the lock since readahead cannot relinquish the lock because it is itself blocked in reclaim: >>> stack_trace(1504735) folio_wait_bit_common (mm/filemap.c:1308:4) folio_lock (./include/linux/pagemap.h:1052:3) truncate_inode_pages_range (mm/truncate.c:336:10) fuse_evict_inode (fs/fuse/inode.c:161:2) evict (fs/inode.c:704:3) dentry_unlink_inode (fs/dcache.c:412:3) __dentry_kill (fs/dcache.c:615:3) shrink_kill (fs/dcache.c:1060:12) shrink_dentry_list (fs/dcache.c:1087:3) prune_dcache_sb (fs/dcache.c:1168:2) super_cache_scan (fs/super.c:221:10) do_shrink_slab (mm/shrinker.c:435:9) shrink_slab (mm/shrinker.c:626:10) shrink_node (mm/vmscan.c:5951:2) shrink_zones (mm/vmscan.c:6195:3) do_try_to_free_pages (mm/vmscan.c:6257:3) do_swap_page (mm/memory.c:4136:11) handle_pte_fault (mm/memory.c:5562:10) handle_mm_fault (mm/memory.c:5870:9) do_user_addr_fault (arch/x86/mm/fault.c:1338:10) handle_page_fault (arch/x86/mm/fault.c:1481:3) exc_page_fault (arch/x86/mm/fault.c:1539:2) asm_exc_page_fault+0x22/0x27 Fix this deadlock by allocating ff->release_args and grabbing the reference on the inode when preparing the file for release even if the server does not implement open. The inode reference will be dropped when the last reference on the fuse file is dropped (see fuse_file_put() -> fuse_release_end()). Fixes: e26ee4efbc79 ("fuse: allocate ff->release_args only if release is needed") Cc: stable@vger.kernel.org Signed-off-by: Joanne Koong Reported-by: Omar Sandoval Signed-off-by: Miklos Szeredi Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- fs/fuse/file.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 31992b6062c0..c06db5d9d21d 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -115,7 +115,9 @@ static void fuse_file_put(struct fuse_file *ff, bool sync) fuse_file_io_release(ff, ra->inode); if (!args) { - /* Do nothing when server does not implement 'open' */ + /* Do nothing when server does not implement 'opendir' */ + } else if (args->opcode == FUSE_RELEASE && ff->fm->fc->no_open) { + fuse_release_end(ff->fm, args, 0); } else if (sync) { fuse_simple_request(ff->fm, args); fuse_release_end(ff->fm, args, 0); @@ -136,8 +138,17 @@ struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid, struct fuse_file *ff; int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; bool open = isdir ? !fc->no_opendir : !fc->no_open; + bool release = !isdir || open; - ff = fuse_file_alloc(fm, open); + /* + * ff->args->release_args still needs to be allocated (so we can hold an + * inode reference while there are pending inflight file operations when + * ->release() is called, see fuse_prepare_release()) even if + * fc->no_open is set else it becomes possible for reclaim to deadlock + * if while servicing the readahead request the server triggers reclaim + * and reclaim evicts the inode of the file being read ahead. + */ + ff = fuse_file_alloc(fm, release); if (!ff) return ERR_PTR(-ENOMEM); @@ -156,13 +167,14 @@ struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid, fuse_file_free(ff); return ERR_PTR(err); } else { - /* No release needed */ - kfree(ff->release_args); - ff->release_args = NULL; - if (isdir) + if (isdir) { + /* No release needed */ + kfree(ff->release_args); + ff->release_args = NULL; fc->no_opendir = 1; - else + } else { fc->no_open = 1; + } } } -- Gitee From 0125da92d3a39486e2f300615d7cbe3366711dfb Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Tue, 6 Jan 2026 02:55:56 +0800 Subject: [PATCH 0817/1449] PCI: brcmstb: Fix disabling L0s capability ANBZ: #35228 commit 38a053796019554b55ce1c5840b57df99e654bc3 stable. commit 9583f9d22991d2cfb5cc59a2552040c4ae98d998 upstream. caab002d5069 ("PCI: brcmstb: Disable L0s component of ASPM if requested") set PCI_EXP_LNKCAP_ASPM_L1 and (optionally) PCI_EXP_LNKCAP_ASPM_L0S in PCI_EXP_LNKCAP (aka PCIE_RC_CFG_PRIV1_LINK_CAPABILITY in brcmstb). But instead of using PCI_EXP_LNKCAP_ASPM_L1 and PCI_EXP_LNKCAP_ASPM_L0S directly, it used PCIE_LINK_STATE_L1 and PCIE_LINK_STATE_L0S, which are Linux-created values that only coincidentally matched the PCIe spec. b478e162f227 ("PCI/ASPM: Consolidate link state defines") later changed them so they no longer matched the PCIe spec, so the bits ended up in the wrong place in PCI_EXP_LNKCAP. Use PCI_EXP_LNKCAP_ASPM_L0S to clear L0s support when there's an 'aspm-no-l0s' property. Rely on brcmstb hardware to advertise L0s and/or L1 support otherwise. Fixes: caab002d5069 ("PCI: brcmstb: Disable L0s component of ASPM if requested") Reported-by: Bjorn Helgaas Closes: https://lore.kernel.org/linux-pci/20250925194424.GA2197200@bhelgaas Signed-off-by: Jim Quinlan [mani: reworded subject and description, added closes tag and CCed stable] Signed-off-by: Manivannan Sadhasivam [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas Reviewed-by: Florian Fainelli Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251003170436.1446030-1-james.quinlan@broadcom.com [ adapted context due to missing link width negotiation defines and variables ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/controller/pcie-brcmstb.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 9bcf4c68058e..8850a15b0aec 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -46,7 +46,6 @@ #define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc -#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00 #define PCIE_RC_DL_MDIO_ADDR 0x1100 #define PCIE_RC_DL_MDIO_WR_DATA 0x1104 @@ -867,7 +866,7 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) void __iomem *base = pcie->base; struct pci_host_bridge *bridge; struct resource_entry *entry; - u32 tmp, burst, aspm_support; + u32 tmp, burst; int num_out_wins = 0; int ret, memc; @@ -971,12 +970,9 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) writel(tmp, base + PCIE_MISC_RC_BAR3_CONFIG_LO); /* Don't advertise L0s capability if 'aspm-no-l0s' */ - aspm_support = PCIE_LINK_STATE_L1; - if (!of_property_read_bool(pcie->np, "aspm-no-l0s")) - aspm_support |= PCIE_LINK_STATE_L0S; tmp = readl(base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY); - u32p_replace_bits(&tmp, aspm_support, - PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK); + if (of_property_read_bool(pcie->np, "aspm-no-l0s")) + tmp &= ~PCI_EXP_LNKCAP_ASPM_L0S; writel(tmp, base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY); /* -- Gitee From c75795d3beb4d62993173224ed85936ec9b024ac Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Wed, 7 Jan 2026 01:17:09 +0800 Subject: [PATCH 0818/1449] mptcp: fallback earlier on simult connection ANBZ: #35228 commit c9bf315228287653522894df9d851e9b43db9516 stable. commit 71154bbe49423128c1c8577b6576de1ed6836830 upstream. Syzkaller reports a simult-connect race leading to inconsistent fallback status: WARNING: CPU: 3 PID: 33 at net/mptcp/subflow.c:1515 subflow_data_ready+0x40b/0x7c0 net/mptcp/subflow.c:1515 Modules linked in: CPU: 3 UID: 0 PID: 33 Comm: ksoftirqd/3 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:subflow_data_ready+0x40b/0x7c0 net/mptcp/subflow.c:1515 Code: 89 ee e8 78 61 3c f6 40 84 ed 75 21 e8 8e 66 3c f6 44 89 fe bf 07 00 00 00 e8 c1 61 3c f6 41 83 ff 07 74 09 e8 76 66 3c f6 90 <0f> 0b 90 e8 6d 66 3c f6 48 89 df e8 e5 ad ff ff 31 ff 89 c5 89 c6 RSP: 0018:ffffc900006cf338 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff888031acd100 RCX: ffffffff8b7f2abf RDX: ffff88801e6ea440 RSI: ffffffff8b7f2aca RDI: 0000000000000005 RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000007 R10: 0000000000000004 R11: 0000000000002c10 R12: ffff88802ba69900 R13: 1ffff920000d9e67 R14: ffff888046f81800 R15: 0000000000000004 FS: 0000000000000000(0000) GS:ffff8880d69bc000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000560fc0ca1670 CR3: 0000000032c3a000 CR4: 0000000000352ef0 Call Trace: tcp_data_queue+0x13b0/0x4f90 net/ipv4/tcp_input.c:5197 tcp_rcv_state_process+0xfdf/0x4ec0 net/ipv4/tcp_input.c:6922 tcp_v6_do_rcv+0x492/0x1740 net/ipv6/tcp_ipv6.c:1672 tcp_v6_rcv+0x2976/0x41e0 net/ipv6/tcp_ipv6.c:1918 ip6_protocol_deliver_rcu+0x188/0x1520 net/ipv6/ip6_input.c:438 ip6_input_finish+0x1e4/0x4b0 net/ipv6/ip6_input.c:489 NF_HOOK include/linux/netfilter.h:318 [inline] NF_HOOK include/linux/netfilter.h:312 [inline] ip6_input+0x105/0x2f0 net/ipv6/ip6_input.c:500 dst_input include/net/dst.h:471 [inline] ip6_rcv_finish net/ipv6/ip6_input.c:79 [inline] NF_HOOK include/linux/netfilter.h:318 [inline] NF_HOOK include/linux/netfilter.h:312 [inline] ipv6_rcv+0x264/0x650 net/ipv6/ip6_input.c:311 __netif_receive_skb_one_core+0x12d/0x1e0 net/core/dev.c:5979 __netif_receive_skb+0x1d/0x160 net/core/dev.c:6092 process_backlog+0x442/0x15e0 net/core/dev.c:6444 __napi_poll.constprop.0+0xba/0x550 net/core/dev.c:7494 napi_poll net/core/dev.c:7557 [inline] net_rx_action+0xa9f/0xfe0 net/core/dev.c:7684 handle_softirqs+0x216/0x8e0 kernel/softirq.c:579 run_ksoftirqd kernel/softirq.c:968 [inline] run_ksoftirqd+0x3a/0x60 kernel/softirq.c:960 smpboot_thread_fn+0x3f7/0xae0 kernel/smpboot.c:160 kthread+0x3c2/0x780 kernel/kthread.c:463 ret_from_fork+0x5d7/0x6f0 arch/x86/kernel/process.c:148 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 The TCP subflow can process the simult-connect syn-ack packet after transitioning to TCP_FIN1 state, bypassing the MPTCP fallback check, as the sk_state_change() callback is not invoked for * -> FIN_WAIT1 transitions. That will move the msk socket to an inconsistent status and the next incoming data will hit the reported splat. Close the race moving the simult-fallback check at the earliest possible stage - that is at syn-ack generation time. About the fixes tags: [2] was supposed to also fix this issue introduced by [3]. [1] is required as a dependence: it was not explicitly marked as a fix, but it is one and it has already been backported before [3]. In other words, this commit should be backported up to [3], including [2] and [1] if that's not already there. Fixes: 23e89e8ee7be ("tcp: Don't drop SYN+ACK for simultaneous connect().") [1] Fixes: 4fd19a307016 ("mptcp: fix inconsistent state on fastopen race") [2] Fixes: 1e777f39b4d7 ("mptcp: add MSG_FASTOPEN sendmsg flag support") [3] Cc: stable@vger.kernel.org Reported-by: syzbot+0ff6b771b4f7a5bce83b@syzkaller.appspotmail.com Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/586 Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251212-net-mptcp-subflow_data_ready-warn-v1-1-d1f9fd1c36c8@kernel.org Signed-off-by: Paolo Abeni [ adapted mptcp_try_fallback() call ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/options.c | 10 ++++++++++ net/mptcp/protocol.h | 6 ++---- net/mptcp/subflow.c | 10 +--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index f1edae5f9079..b4f9c97af1b9 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -408,6 +408,16 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, */ subflow->snd_isn = TCP_SKB_CB(skb)->end_seq; if (subflow->request_mptcp) { + if (unlikely(subflow_simultaneous_connect(sk))) { + WARN_ON_ONCE(!mptcp_try_fallback(sk)); + + /* Ensure mptcp_finish_connect() will not process the + * MPC handshake. + */ + subflow->request_mptcp = 0; + return false; + } + opts->suboptions = OPTION_MPTCP_MPC_SYN; opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk)); opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk)); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 5d218c27c077..3bf45ca2678d 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -1175,10 +1175,8 @@ static inline bool subflow_simultaneous_connect(struct sock *sk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); - return (1 << sk->sk_state) & - (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING) && - is_active_ssk(subflow) && - !subflow->conn_finished; + /* Note that the sk state implies !subflow->conn_finished. */ + return sk->sk_state == TCP_SYN_RECV && is_active_ssk(subflow); } #ifdef CONFIG_SYN_COOKIES diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index b71675f46d10..c34f9f176587 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -1793,18 +1793,10 @@ static void subflow_state_change(struct sock *sk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct sock *parent = subflow->conn; - struct mptcp_sock *msk; + struct mptcp_sock *msk = mptcp_sk(parent); __subflow_state_change(sk); - msk = mptcp_sk(parent); - if (subflow_simultaneous_connect(sk)) { - WARN_ON_ONCE(!mptcp_try_fallback(sk)); - pr_fallback(msk); - subflow->conn_finished = 1; - mptcp_propagate_state(parent, sk, subflow, NULL); - } - /* as recvmsg() does not acquire the subflow socket for ssk selection * a fin packet carrying a DSS can be unnoticed if we don't trigger * the data available machinery here. -- Gitee From 1e59d1e7853bcfcbf8b011da63dc301c1fa75146 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 7 Jan 2026 04:34:33 +0800 Subject: [PATCH 0819/1449] lockd: fix vfs_test_lock() calls ANBZ: #35228 commit 46b9fd1433d2674e36cd78dcb8e8765106330d38 stable. commit a49a2a1baa0c553c3548a1c414b6a3c005a8deba upstream. Usage of vfs_test_lock() is somewhat confused. Documentation suggests it is given a "lock" but this is not the case. It is given a struct file_lock which contains some details of the sort of lock it should be looking for. In particular passing a "file_lock" containing fl_lmops or fl_ops is meaningless and possibly confusing. This is particularly problematic in lockd. nlmsvc_testlock() receives an initialised "file_lock" from xdr-decode, including manager ops and an owner. It then mistakenly passes this to vfs_test_lock() which might replace the owner and the ops. This can lead to confusion when freeing the lock. The primary role of the 'struct file_lock' passed to vfs_test_lock() is to report a conflicting lock that was found, so it makes more sense for nlmsvc_testlock() to pass "conflock", which it uses for returning the conflicting lock. With this change, freeing of the lock is not confused and code in __nlm4svc_proc_test() and __nlmsvc_proc_test() can be simplified. Documentation for vfs_test_lock() is improved to reflect its real purpose, and a WARN_ON_ONCE() is added to avoid a similar problem in the future. Reported-by: Olga Kornievskaia Closes: https://lore.kernel.org/all/20251021130506.45065-1-okorniev@redhat.com Signed-off-by: NeilBrown Fixes: 20fa19027286 ("nfs: add export operations") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever [ adapted fl->c.flc_* field references to flat fl->fl_* naming convention ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/lockd/svc4proc.c | 4 +--- fs/lockd/svclock.c | 21 ++++++++++++--------- fs/lockd/svcproc.c | 5 +---- fs/locks.c | 12 ++++++++++-- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index b72023a6b4c1..28ba7b1460aa 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -96,7 +96,6 @@ __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; - struct nlm_lockowner *test_owner; __be32 rc = rpc_success; dprintk("lockd: TEST4 called\n"); @@ -106,7 +105,6 @@ __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; - test_owner = argp->lock.fl.fl_owner; /* Now check for conflicting locks */ resp->status = nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie); if (resp->status == nlm_drop_reply) @@ -114,7 +112,7 @@ __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) else dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); - nlmsvc_put_lockowner(test_owner); + nlmsvc_release_lockowner(&argp->lock); nlmsvc_release_host(host); nlm_release_file(file); return rc; diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 43aeba9de55c..ef6d8061460d 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -615,7 +615,13 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, } mode = lock_to_openmode(&lock->fl); - error = vfs_test_lock(file->f_file[mode], &lock->fl); + locks_init_lock(&conflock->fl); + /* vfs_test_lock only uses start, end, and owner, but tests fl_file */ + conflock->fl.fl_file = lock->fl.fl_file; + conflock->fl.fl_start = lock->fl.fl_start; + conflock->fl.fl_end = lock->fl.fl_end; + conflock->fl.fl_owner = lock->fl.fl_owner; + error = vfs_test_lock(file->f_file[mode], &conflock->fl); if (error) { /* We can't currently deal with deferred test requests */ if (error == FILE_LOCK_DEFERRED) @@ -625,22 +631,19 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, goto out; } - if (lock->fl.fl_type == F_UNLCK) { + if (conflock->fl.fl_type == F_UNLCK) { ret = nlm_granted; goto out; } dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n", - lock->fl.fl_type, (long long)lock->fl.fl_start, - (long long)lock->fl.fl_end); + conflock->fl.fl_type, (long long)conflock->fl.fl_start, + (long long)conflock->fl.fl_end); conflock->caller = "somehost"; /* FIXME */ conflock->len = strlen(conflock->caller); conflock->oh.len = 0; /* don't return OH info */ - conflock->svid = lock->fl.fl_pid; - conflock->fl.fl_type = lock->fl.fl_type; - conflock->fl.fl_start = lock->fl.fl_start; - conflock->fl.fl_end = lock->fl.fl_end; - locks_release_private(&lock->fl); + conflock->svid = conflock->fl.fl_pid; + locks_release_private(&conflock->fl); ret = nlm_lck_denied; out: diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 32784f508c81..1a4459763644 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -117,7 +117,6 @@ __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; - struct nlm_lockowner *test_owner; __be32 rc = rpc_success; dprintk("lockd: TEST called\n"); @@ -127,8 +126,6 @@ __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; - test_owner = argp->lock.fl.fl_owner; - /* Now check for conflicting locks */ resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie)); if (resp->status == nlm_drop_reply) @@ -137,7 +134,7 @@ __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) dprintk("lockd: TEST status %d vers %d\n", ntohl(resp->status), rqstp->rq_vers); - nlmsvc_put_lockowner(test_owner); + nlmsvc_release_lockowner(&argp->lock); nlmsvc_release_host(host); nlm_release_file(file); return rc; diff --git a/fs/locks.c b/fs/locks.c index ccfa441e487e..19e9fcd1d4ca 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -2124,13 +2124,21 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) /** * vfs_test_lock - test file byte range lock * @filp: The file to test lock for - * @fl: The lock to test; also used to hold result + * @fl: The byte-range in the file to test; also used to hold result * + * On entry, @fl does not contain a lock, but identifies a range (fl_start, fl_end) + * in the file (c.flc_file), and an owner (c.flc_owner) for whom existing locks + * should be ignored. c.flc_type and c.flc_flags are ignored. + * Both fl_lmops and fl_ops in @fl must be NULL. * Returns -ERRNO on failure. Indicates presence of conflicting lock by - * setting conf->fl_type to something other than F_UNLCK. + * setting fl->fl_type to something other than F_UNLCK. + * + * If vfs_test_lock() does find a lock and return it, the caller must + * use locks_free_lock() or locks_release_private() on the returned lock. */ int vfs_test_lock(struct file *filp, struct file_lock *fl) { + WARN_ON_ONCE(fl->fl_ops || fl->fl_lmops); WARN_ON_ONCE(filp != fl->fl_file); if (filp->f_op->lock) return filp->f_op->lock(filp, F_GETLK, fl); -- Gitee From 76c1cfb3e4b563ac9e99ce160df2b0d0139fa3cb Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 7 Jan 2026 07:28:39 +0800 Subject: [PATCH 0820/1449] wifi: mac80211: Discard Beacon frames to non-broadcast address ANBZ: #35228 commit 6e5bff40bb38741e40c33043ba0816fba5f93661 stable. commit 193d18f60588e95d62e0f82b6a53893e5f2f19f8 upstream. Beacon frames are required to be sent to the broadcast address, see IEEE Std 802.11-2020, 11.1.3.1 ("The Address 1 field of the Beacon .. frame shall be set to the broadcast address"). A unicast Beacon frame might be used as a targeted attack to get one of the associated STAs to do something (e.g., using CSA to move it to another channel). As such, it is better have strict filtering for this on the received side and discard all Beacon frames that are sent to an unexpected address. This is even more important for cases where beacon protection is used. The current implementation in mac80211 is correctly discarding unicast Beacon frames if the Protected Frame bit in the Frame Control field is set to 0. However, if that bit is set to 1, the logic used for checking for configured BIGTK(s) does not actually work. If the driver does not have logic for dropping unicast Beacon frames with Protected Frame bit 1, these frames would be accepted in mac80211 processing as valid Beacon frames even though they are not protected. This would allow beacon protection to be bypassed. While the logic for checking beacon protection could be extended to cover this corner case, a more generic check for discard all Beacon frames based on A1=unicast address covers this without needing additional changes. Address all these issues by dropping received Beacon frames if they are sent to a non-broadcast address. Cc: stable@vger.kernel.org Fixes: af2d14b01c32 ("mac80211: Beacon protection using the new BIGTK (STA)") Signed-off-by: Jouni Malinen Link: https://patch.msgid.link/20251215151134.104501-1-jouni.malinen@oss.qualcomm.com Signed-off-by: Johannes Berg [ changed RX_DROP to RX_DROP_MONITOR ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/rx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d27303b9f3a9..6bfd262dce26 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3388,6 +3388,11 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) rx->skb->len < IEEE80211_MIN_ACTION_SIZE) return RX_DROP_U_RUNT_ACTION; + /* Drop non-broadcast Beacon frames */ + if (ieee80211_is_beacon(mgmt->frame_control) && + !is_broadcast_ether_addr(mgmt->da)) + return RX_DROP_MONITOR; + if (rx->sdata->vif.type == NL80211_IFTYPE_AP && ieee80211_is_beacon(mgmt->frame_control) && !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { -- Gitee From 652935abf7baf0d9834c7acd5f5002d42fe48d2d Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 6 Jan 2026 18:58:13 -0500 Subject: [PATCH 0821/1449] mm: simplify folio_expected_ref_count() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 7e0fcf9d71c2cea7b9164e7b754edb01173b939e stable. commit 78cb1a13c42a6d843e21389f74d1edb90ed07288 upstream. [Backport Note] We only modify WARN since folio_expected_ref_count() is following mainline. Now that PAGE_MAPPING_MOVABLE is gone, we can simplify and rely on the folio_test_anon() test only. ... but staring at the users, this function should never even have been called on movable_ops pages. E.g., * __buffer_migrate_folio() does not make sense for them * folio_migrate_mapping() does not make sense for them * migrate_huge_page_move_mapping() does not make sense for them * __migrate_folio() does not make sense for them * ... and khugepaged should never stumble over them Let's simply refuse typed pages (which includes slab) except hugetlb, and WARN. Link: https://lkml.kernel.org/r/20250704102524.326966-26-david@redhat.com Signed-off-by: David Hildenbrand Reviewed-by: Zi Yan Reviewed-by: Lorenzo Stoakes Reviewed-by: Harry Yoo Cc: Alistair Popple Cc: Al Viro Cc: Arnd Bergmann Cc: Brendan Jackman Cc: Byungchul Park Cc: Chengming Zhou Cc: Christian Brauner Cc: Christophe Leroy Cc: Eugenio Pé rez Cc: Greg Kroah-Hartman Cc: Gregory Price Cc: "Huang, Ying" Cc: Jan Kara Cc: Jason Gunthorpe Cc: Jason Wang Cc: Jerrin Shaji George Cc: Johannes Weiner Cc: John Hubbard Cc: Jonathan Corbet Cc: Joshua Hahn Cc: Liam Howlett Cc: Madhavan Srinivasan Cc: Mathew Brost Cc: Matthew Wilcox (Oracle) Cc: Miaohe Lin Cc: Michael Ellerman Cc: "Michael S. Tsirkin" Cc: Michal Hocko Cc: Mike Rapoport Cc: Minchan Kim Cc: Naoya Horiguchi Cc: Nicholas Piggin Cc: Oscar Salvador Cc: Peter Xu Cc: Qi Zheng Cc: Rakie Kim Cc: Rik van Riel Cc: Sergey Senozhatsky Cc: Shakeel Butt Cc: Suren Baghdasaryan Cc: Vlastimil Babka Cc: Xuan Zhuo Cc: xu xin Signed-off-by: Andrew Morton Stable-dep-of: f183663901f2 ("mm: consider non-anon swap cache folios in folio_expected_ref_count()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- include/linux/mm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index cd372aa3c22a..95e9433de37c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2396,7 +2396,7 @@ static inline int folio_expected_ref_count(struct folio *folio) const int order = folio_order(folio); int ref_count = 0; - if (WARN_ON_ONCE(folio_test_slab(folio))) + if (WARN_ON_ONCE(page_has_type(&folio->page) && !folio_test_hugetlb(folio))) return 0; /* One reference per page from the swapcache. */ -- Gitee From fbf149cc443ac6e63794102fb499e2de77848768 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Jan 2026 23:56:02 +0800 Subject: [PATCH 0822/1449] pmdomain: Use device_get_match_data() ANBZ: #35228 commit 4544cfa168340214355a07c4cc60476ff71be1a7 stable. commit 3ba9fdfaa550936837b50b73d6c27ac401fde875 upstream. Use preferred device_get_match_data() instead of of_match_device() to get the driver match data. With this, adjust the includes to explicitly include the correct headers. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20231006224614.444488-1-robh@kernel.org Signed-off-by: Ulf Hansson Stable-dep-of: 73cb5f6eafb0 ("pmdomain: imx: Fix reference count leak in imx_gpc_probe()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/actions/owl-sps.c | 16 +++++----------- drivers/pmdomain/imx/gpc.c | 7 +++---- drivers/pmdomain/rockchip/pm-domains.c | 13 ++++--------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/pmdomain/actions/owl-sps.c b/drivers/pmdomain/actions/owl-sps.c index 73a9e0bb7e8e..3a586d1f3256 100644 --- a/drivers/pmdomain/actions/owl-sps.c +++ b/drivers/pmdomain/actions/owl-sps.c @@ -8,8 +8,10 @@ * Copyright (c) 2017 Andreas Färber */ +#include #include -#include +#include +#include #include #include #include @@ -96,24 +98,16 @@ static int owl_sps_init_domain(struct owl_sps *sps, int index) static int owl_sps_probe(struct platform_device *pdev) { - const struct of_device_id *match; const struct owl_sps_info *sps_info; struct owl_sps *sps; int i, ret; - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "no device node\n"); - return -ENODEV; - } - - match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); - if (!match || !match->data) { + sps_info = device_get_match_data(&pdev->dev); + if (!sps_info) { dev_err(&pdev->dev, "unknown compatible or missing data\n"); return -EINVAL; } - sps_info = match->data; - sps = devm_kzalloc(&pdev->dev, struct_size(sps, domains, sps_info->num_domains), GFP_KERNEL); diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index d7c0301a7121..9ccab78c8986 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -7,9 +7,10 @@ #include #include #include -#include +#include #include #include +#include #include #include @@ -403,9 +404,7 @@ static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap, static int imx_gpc_probe(struct platform_device *pdev) { - const struct of_device_id *of_id = - of_match_device(imx_gpc_dt_ids, &pdev->dev); - const struct imx_gpc_dt_data *of_id_data = of_id->data; + const struct imx_gpc_dt_data *of_id_data = device_get_match_data(&pdev->dev); struct device_node *pgc_node; struct regmap *regmap; void __iomem *base; diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c index d5d3ecb38283..9b76b62869d0 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c @@ -9,11 +9,13 @@ #include #include #include +#include #include #include +#include +#include #include #include -#include #include #include #include @@ -857,7 +859,6 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) struct device_node *node; struct device *parent; struct rockchip_pmu *pmu; - const struct of_device_id *match; const struct rockchip_pmu_info *pmu_info; int error; @@ -866,13 +867,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) return -ENODEV; } - match = of_match_device(dev->driver->of_match_table, dev); - if (!match || !match->data) { - dev_err(dev, "missing pmu data\n"); - return -EINVAL; - } - - pmu_info = match->data; + pmu_info = device_get_match_data(dev); pmu = devm_kzalloc(dev, struct_size(pmu, domains, pmu_info->num_domains), -- Gitee From cf859525fa9212f43ad3705baba871a90784c02b Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Tue, 6 Jan 2026 23:56:03 +0800 Subject: [PATCH 0823/1449] pmdomain: imx: Fix reference count leak in imx_gpc_probe() ANBZ: #35228 commit b2e7973d83a844fa473130c12de56cef64d865ec stable. commit 73cb5f6eafb0ac7aea8cdeb8ff12981aa741d8fb upstream. of_get_child_by_name() returns a node pointer with refcount incremented. Use the __free() attribute to manage the pgc_node reference, ensuring automatic of_node_put() cleanup when pgc_node goes out of scope. This eliminates the need for explicit error handling paths and avoids reference count leaks. Fixes: 721cabf6c660 ("soc: imx: move PGC handling to a new GPC driver") Cc: stable@vger.kernel.org Signed-off-by: Wentao Liang Reviewed-by: Frank Li Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/gpc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index 9ccab78c8986..45625b6be62d 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -405,13 +405,12 @@ static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap, static int imx_gpc_probe(struct platform_device *pdev) { const struct imx_gpc_dt_data *of_id_data = device_get_match_data(&pdev->dev); - struct device_node *pgc_node; + struct device_node *pgc_node __free(device_node) + = of_get_child_by_name(pdev->dev.of_node, "pgc"); struct regmap *regmap; void __iomem *base; int ret; - pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc"); - /* bail out if DT too old and doesn't provide the necessary info */ if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") && !pgc_node) -- Gitee From 2b2d071d3a4f8b0b2acfa820ac125874fc757f44 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 7 Jan 2026 10:33:35 +0800 Subject: [PATCH 0824/1449] net: phy: mediatek: fix nvmem cell reference leak in mt798x_phy_calibration ANBZ: #35228 commit a902343f133154e438b772d3e7b538ed0b163acc stable. commit 1e5a541420b8c6d87d88eb50b6b978cdeafee1c9 upstream. When nvmem_cell_read() fails in mt798x_phy_calibration(), the function returns without calling nvmem_cell_put(), leaking the cell reference. Move nvmem_cell_put() right after nvmem_cell_read() to ensure the cell reference is always released regardless of the read result. Found via static analysis and code review. Fixes: 98c485eaf509 ("net: phy: add driver for MediaTek SoC built-in GE PHYs") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Reviewed-by: Daniel Golle Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20251211081313.2368460-1-linmq006@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/mediatek-ge-soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek-ge-soc.c index f4f9412d0cd7..4b2a9a5444c5 100644 --- a/drivers/net/phy/mediatek-ge-soc.c +++ b/drivers/net/phy/mediatek-ge-soc.c @@ -1082,9 +1082,9 @@ static int mt798x_phy_calibration(struct phy_device *phydev) } buf = (u32 *)nvmem_cell_read(cell, &len); + nvmem_cell_put(cell); if (IS_ERR(buf)) return PTR_ERR(buf); - nvmem_cell_put(cell); if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) { phydev_err(phydev, "invalid efuse data\n"); -- Gitee From 0cf14e06cb8f19346e23f19171ac5c89144c793c Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Wed, 7 Jan 2026 10:34:03 +0800 Subject: [PATCH 0825/1449] mptcp: ensure context reset on disconnect() ANBZ: #35228 commit 5c7c7135468f3fc6379cde9777a2c18bfe92d82f stable. commit 86730ac255b0497a272704de9a1df559f5d6602e upstream. After the blamed commit below, if the MPC subflow is already in TCP_CLOSE status or has fallback to TCP at mptcp_disconnect() time, mptcp_do_fastclose() skips setting the `send_fastclose flag` and the later __mptcp_close_ssk() does not reset anymore the related subflow context. Any later connection will be created with both the `request_mptcp` flag and the msk-level fallback status off (it is unconditionally cleared at MPTCP disconnect time), leading to a warning in subflow_data_ready(): WARNING: CPU: 26 PID: 8996 at net/mptcp/subflow.c:1519 subflow_data_ready (net/mptcp/subflow.c:1519 (discriminator 13)) Modules linked in: CPU: 26 UID: 0 PID: 8996 Comm: syz.22.39 Not tainted 6.18.0-rc7-05427-g11fc074f6c36 #1 PREEMPT(voluntary) Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 RIP: 0010:subflow_data_ready (net/mptcp/subflow.c:1519 (discriminator 13)) Code: 90 0f 0b 90 90 e9 04 fe ff ff e8 b7 1e f5 fe 89 ee bf 07 00 00 00 e8 db 19 f5 fe 83 fd 07 0f 84 35 ff ff ff e8 9d 1e f5 fe 90 <0f> 0b 90 e9 27 ff ff ff e8 8f 1e f5 fe 4c 89 e7 48 89 de e8 14 09 RSP: 0018:ffffc9002646fb30 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff88813b218000 RCX: ffffffff825c8435 RDX: ffff8881300b3580 RSI: ffffffff825c8443 RDI: 0000000000000005 RBP: 000000000000000b R08: ffffffff825c8435 R09: 000000000000000b R10: 0000000000000005 R11: 0000000000000007 R12: ffff888131ac0000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 00007f88330af6c0(0000) GS:ffff888a93dd2000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f88330aefe8 CR3: 000000010ff59000 CR4: 0000000000350ef0 Call Trace: tcp_data_ready (net/ipv4/tcp_input.c:5356) tcp_data_queue (net/ipv4/tcp_input.c:5445) tcp_rcv_state_process (net/ipv4/tcp_input.c:7165) tcp_v4_do_rcv (net/ipv4/tcp_ipv4.c:1955) __release_sock (include/net/sock.h:1158 (discriminator 6) net/core/sock.c:3180 (discriminator 6)) release_sock (net/core/sock.c:3737) mptcp_sendmsg (net/mptcp/protocol.c:1763 net/mptcp/protocol.c:1857) inet_sendmsg (net/ipv4/af_inet.c:853 (discriminator 7)) __sys_sendto (net/socket.c:727 (discriminator 15) net/socket.c:742 (discriminator 15) net/socket.c:2244 (discriminator 15)) __x64_sys_sendto (net/socket.c:2247) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) RIP: 0033:0x7f883326702d Address the issue setting an explicit `fastclosing` flag at fastclose time, and checking such flag after mptcp_do_fastclose(). Fixes: ae155060247b ("mptcp: fix duplicate reset on fastclose") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251212-net-mptcp-subflow_data_ready-warn-v1-2-d1f9fd1c36c8@kernel.org Signed-off-by: Paolo Abeni [ adapted context in mptcp_do_fastclose() to exclude missing mptcp_backlog_purge() call ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 8 +++++--- net/mptcp/protocol.h | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 810a974c878c..0dbf2e0d9762 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2441,10 +2441,10 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) */ static void __mptcp_subflow_disconnect(struct sock *ssk, struct mptcp_subflow_context *subflow, - unsigned int flags) + bool fastclosing) { if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || - subflow->send_fastclose) { + fastclosing) { /* The MPTCP code never wait on the subflow sockets, TCP-level * disconnect should never fail */ @@ -2496,7 +2496,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); if (!dispose_it) { - __mptcp_subflow_disconnect(ssk, subflow, flags); + __mptcp_subflow_disconnect(ssk, subflow, msk->fastclosing); release_sock(ssk); goto out; @@ -2808,6 +2808,7 @@ static void mptcp_do_fastclose(struct sock *sk) struct mptcp_sock *msk = mptcp_sk(sk); mptcp_set_state(sk, TCP_CLOSE); + msk->fastclosing = 1; /* Explicitly send the fastclose reset as need */ if (__mptcp_check_fallback(msk)) @@ -3320,6 +3321,7 @@ static int mptcp_disconnect(struct sock *sk, int flags) msk->bytes_sent = 0; msk->bytes_retrans = 0; msk->rcvspace_init = 0; + msk->fastclosing = 0; WRITE_ONCE(sk->sk_shutdown, 0); sk_error_report(sk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 3bf45ca2678d..0fbc1f13bd2d 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -305,7 +305,8 @@ struct mptcp_sock { fastopening:1, in_accept_queue:1, free_first:1, - rcvspace_init:1; + rcvspace_init:1, + fastclosing:1; int keepalive_cnt; int keepalive_idle; int keepalive_intvl; -- Gitee From 92a09ae822f328830863d5963c428fb7e9de36a2 Mon Sep 17 00:00:00 2001 From: Natalie Vock Date: Wed, 7 Jan 2026 19:54:14 +0800 Subject: [PATCH 0826/1449] drm/amdgpu: Forward VMID reservation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 11dba925f5feaab66375fd5ce96bc4a0813613ba stable. commit 8defb4f081a5feccc3ea8372d0c7af3522124e1f upstream. Otherwise userspace may be fooled into believing it has a reserved VMID when in reality it doesn't, ultimately leading to GPU hangs when SPM is used. Fixes: 80e709ee6ecc ("drm/amdgpu: add option params to enforce process isolation between graphics and compute") Cc: stable@vger.kernel.org Reviewed-by: Christian König Signed-off-by: Natalie Vock Signed-off-by: Alex Deucher [ adapted 3-argument amdgpu_vmid_alloc_reserved(adev, vm, vmhub) call to 2-argument version and added separate error check to preserve reserved_vmid tracking logic. ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 2992ce494e00..dc860544e6e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2496,10 +2496,12 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) case AMDGPU_VM_OP_RESERVE_VMID: /* We only have requirement to reserve vmid from gfxhub */ if (!fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)]) { - amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(0)); + int r = amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(0)); + + if (r) + return r; fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)] = true; } - break; case AMDGPU_VM_OP_UNRESERVE_VMID: if (fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)]) { -- Gitee From 3afab2e970ecc77cadedd7a86a29acbb3dd0d917 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 7 Jan 2026 20:07:09 +0800 Subject: [PATCH 0827/1449] drm/mediatek: Fix probe memory leak ANBZ: #35228 commit fef6d1474ab33a9c7e813c3d185041ff3924c3ad stable. commit 5e49200593f331cd0629b5376fab9192f698e8ef upstream. The Mediatek DRM driver allocates private data for components without a platform driver but as the lifetime is tied to each component device, the memory is never freed. Tie the allocation lifetime to the DRM platform device so that the memory is released on probe failure (e.g. probe deferral) and when the driver is unbound. Fixes: c0d36de868a6 ("drm/mediatek: Move clk info from struct mtk_ddp_comp to sub driver private data") Cc: stable@vger.kernel.org # 5.12 Cc: CK Hu Signed-off-by: Johan Hovold Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20250923152340.18234-3-johan@kernel.org/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 66ccde966e3c..9cdbac42b7f3 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -588,7 +588,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, type == MTK_DSI) return 0; - priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; -- Gitee From 66a415e005813761a6b664146980c7624f7d1223 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 7 Jan 2026 23:47:23 +0800 Subject: [PATCH 0828/1449] drm/mediatek: Fix probe resource leaks ANBZ: #35228 commit 205aa0c83cd43c391026e7872903b3fab8049249 stable. commit 07c7c640a8eb9e196f357d15d88a59602a947197 upstream. Make sure to unmap and release the component iomap and clock on probe failure (e.g. probe deferral) and on driver unbind. Note that unlike of_iomap(), devm_of_iomap() also checks whether the region is already mapped. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Cc: stable@vger.kernel.org # 4.7 Cc: CK Hu Signed-off-by: Johan Hovold Reviewed-by: AngeloGioacchino Del Regno Link: https://patchwork.kernel.org/project/dri-devel/patch/20250923152340.18234-2-johan@kernel.org/ Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 20 ++++++++++++++++---- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 4 ++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 9cdbac42b7f3..2b6ff11fd1cd 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -543,15 +543,20 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, return ret; } -int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, +static void mtk_ddp_comp_clk_put(void *_clk) +{ + struct clk *clk = _clk; + + clk_put(clk); +} + +int mtk_ddp_comp_init(struct device *dev, struct device_node *node, struct mtk_ddp_comp *comp, unsigned int comp_id) { struct platform_device *comp_pdev; enum mtk_ddp_comp_type type; struct mtk_ddp_comp_dev *priv; -#if IS_REACHABLE(CONFIG_MTK_CMDQ) int ret; -#endif if (comp_id >= DDP_COMPONENT_DRM_ID_MAX) return -EINVAL; @@ -592,11 +597,18 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, if (!priv) return -ENOMEM; - priv->regs = of_iomap(node, 0); + priv->regs = devm_of_iomap(dev, node, 0, NULL); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + priv->clk = of_clk_get(node, 0); if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); + ret = devm_add_action_or_reset(dev, mtk_ddp_comp_clk_put, priv->clk); + if (ret) + return ret; + #if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(comp->dev, &priv->cmdq_reg, 0); if (ret) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index febcaeef16a1..a9e0661b3b43 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -279,7 +279,7 @@ int mtk_ddp_comp_get_id(struct device_node *node, enum mtk_ddp_comp_type comp_type); unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, struct device *dev); -int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp, +int mtk_ddp_comp_init(struct device *dev, struct device_node *comp_node, struct mtk_ddp_comp *comp, unsigned int comp_id); enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id); void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index d97f45d986a9..530e152b9410 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -837,7 +837,7 @@ static int mtk_drm_probe(struct platform_device *pdev) (void *)private->mmsys_dev, sizeof(*private->mmsys_dev)); private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev; - mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR], + mtk_ddp_comp_init(dev, NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR], DDP_COMPONENT_DRM_OVL_ADAPTOR); component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev); } @@ -906,7 +906,7 @@ static int mtk_drm_probe(struct platform_device *pdev) node); } - ret = mtk_ddp_comp_init(node, &private->ddp_comp[comp_id], comp_id); + ret = mtk_ddp_comp_init(dev, node, &private->ddp_comp[comp_id], comp_id); if (ret) { of_node_put(node); goto err_node; -- Gitee From d451e8aa7daaa648526d32dc690ca170ffacc75c Mon Sep 17 00:00:00 2001 From: Philipp Stanner Date: Thu, 8 Jan 2026 00:14:07 +0800 Subject: [PATCH 0829/1449] drm/tilcdc: request and mapp iomem with devres ANBZ: #35228 commit 5bc791132f628efd0b9c1fafd45ef731275470c1 stable. commit a196a5166e0812db267281c32fa0724fc5be6582 upstream. tilcdc currently just ioremaps its iomem, without doing the (a bit more robust) request on the memory first. The devm_ functions provide a handy way to both request and ioremap the memory with automatic cleanup. Replace the manual ioremap with the devm_ version. Suggested-by: Thomas Zimmermann Signed-off-by: Philipp Stanner Reviewed-by: Jyri Sarha Tested-by: Jyri Sarha Signed-off-by: Jyri Sarha Link: https://patchwork.freedesktop.org/patch/msgid/20231222115216.19218-2-pstanner@redhat.com Stable-dep-of: a585c7ef9cab ("drm/tilcdc: Fix removal actions in case of failed probe") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index 2f6eaac7f659..c79613b66154 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -182,9 +182,6 @@ static void tilcdc_fini(struct drm_device *dev) if (priv->clk) clk_put(priv->clk); - if (priv->mmio) - iounmap(priv->mmio); - if (priv->wq) destroy_workqueue(priv->wq); @@ -201,7 +198,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct device_node *node = dev->of_node; struct tilcdc_drm_private *priv; - struct resource *res; u32 bpp = 0; int ret; @@ -226,17 +222,10 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) goto init_failed; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to get memory resource\n"); - ret = -EINVAL; - goto init_failed; - } - - priv->mmio = ioremap(res->start, resource_size(res)); - if (!priv->mmio) { - dev_err(dev, "failed to ioremap\n"); - ret = -ENOMEM; + priv->mmio = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->mmio)) { + dev_err(dev, "failed to request / ioremap\n"); + ret = PTR_ERR(priv->mmio); goto init_failed; } -- Gitee From 553586abf845fe7b6c160989540d6f42a876ba40 Mon Sep 17 00:00:00 2001 From: "Kory Maincent (TI.com)" Date: Thu, 8 Jan 2026 00:14:08 +0800 Subject: [PATCH 0830/1449] drm/tilcdc: Fix removal actions in case of failed probe ANBZ: #35228 commit 21e52dc7762908c3d499cfb493d1b8281fc1d3ab stable. commit a585c7ef9cabda58088916baedc6573e9a5cd2a7 upstream. The drm_kms_helper_poll_fini() and drm_atomic_helper_shutdown() helpers should only be called when the device has been successfully registered. Currently, these functions are called unconditionally in tilcdc_fini(), which causes warnings during probe deferral scenarios. [ 7.972317] WARNING: CPU: 0 PID: 23 at drivers/gpu/drm/drm_atomic_state_helper.c:175 drm_atomic_helper_crtc_duplicate_state+0x60/0x68 ... [ 8.005820] drm_atomic_helper_crtc_duplicate_state from drm_atomic_get_crtc_state+0x68/0x108 [ 8.005858] drm_atomic_get_crtc_state from drm_atomic_helper_disable_all+0x90/0x1c8 [ 8.005885] drm_atomic_helper_disable_all from drm_atomic_helper_shutdown+0x90/0x144 [ 8.005911] drm_atomic_helper_shutdown from tilcdc_fini+0x68/0xf8 [tilcdc] [ 8.005957] tilcdc_fini [tilcdc] from tilcdc_pdev_probe+0xb0/0x6d4 [tilcdc] Fix this by rewriting the failed probe cleanup path using the standard goto error handling pattern, which ensures that cleanup functions are only called on successfully initialized resources. Additionally, remove the now-unnecessary is_registered flag. Cc: stable@vger.kernel.org Fixes: 3c4babae3c4a ("drm: Call drm_atomic_helper_shutdown() at shutdown/remove time for misc drivers") Signed-off-by: Kory Maincent (TI.com) Reviewed-by: Douglas Anderson Reviewed-by: Luca Ceresoli Signed-off-by: Douglas Anderson Link: https://patch.msgid.link/20251125090546.137193-1-kory.maincent@bootlin.com Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 2 +- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 53 ++++++++++++++++++---------- drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index b5f60b2b2d0e..41802c9bd147 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -586,7 +586,7 @@ static void tilcdc_crtc_recover_work(struct work_struct *work) drm_modeset_unlock(&crtc->mutex); } -static void tilcdc_crtc_destroy(struct drm_crtc *crtc) +void tilcdc_crtc_destroy(struct drm_crtc *crtc) { struct tilcdc_drm_private *priv = crtc->dev->dev_private; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index c79613b66154..7bae0cddf088 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -171,8 +171,7 @@ static void tilcdc_fini(struct drm_device *dev) if (priv->crtc) tilcdc_crtc_shutdown(priv->crtc); - if (priv->is_registered) - drm_dev_unregister(dev); + drm_dev_unregister(dev); drm_kms_helper_poll_fini(dev); drm_atomic_helper_shutdown(dev); @@ -219,21 +218,21 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) priv->wq = alloc_ordered_workqueue("tilcdc", 0); if (!priv->wq) { ret = -ENOMEM; - goto init_failed; + goto put_drm; } priv->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->mmio)) { dev_err(dev, "failed to request / ioremap\n"); ret = PTR_ERR(priv->mmio); - goto init_failed; + goto free_wq; } priv->clk = clk_get(dev, "fck"); if (IS_ERR(priv->clk)) { dev_err(dev, "failed to get functional clock\n"); ret = -ENODEV; - goto init_failed; + goto free_wq; } pm_runtime_enable(dev); @@ -312,7 +311,7 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) ret = tilcdc_crtc_create(ddev); if (ret < 0) { dev_err(dev, "failed to create crtc\n"); - goto init_failed; + goto disable_pm; } modeset_init(ddev); @@ -323,46 +322,46 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) if (ret) { dev_err(dev, "failed to register cpufreq notifier\n"); priv->freq_transition.notifier_call = NULL; - goto init_failed; + goto destroy_crtc; } #endif if (priv->is_componentized) { ret = component_bind_all(dev, ddev); if (ret < 0) - goto init_failed; + goto unregister_cpufreq_notif; ret = tilcdc_add_component_encoder(ddev); if (ret < 0) - goto init_failed; + goto unbind_component; } else { ret = tilcdc_attach_external_device(ddev); if (ret) - goto init_failed; + goto unregister_cpufreq_notif; } if (!priv->external_connector && ((priv->num_encoders == 0) || (priv->num_connectors == 0))) { dev_err(dev, "no encoders/connectors found\n"); ret = -EPROBE_DEFER; - goto init_failed; + goto unbind_component; } ret = drm_vblank_init(ddev, 1); if (ret < 0) { dev_err(dev, "failed to initialize vblank\n"); - goto init_failed; + goto unbind_component; } ret = platform_get_irq(pdev, 0); if (ret < 0) - goto init_failed; + goto unbind_component; priv->irq = ret; ret = tilcdc_irq_install(ddev, priv->irq); if (ret < 0) { dev_err(dev, "failed to install IRQ handler\n"); - goto init_failed; + goto unbind_component; } drm_mode_config_reset(ddev); @@ -371,15 +370,33 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) ret = drm_dev_register(ddev, 0); if (ret) - goto init_failed; - priv->is_registered = true; + goto stop_poll; drm_fbdev_dma_setup(ddev, bpp); return 0; -init_failed: - tilcdc_fini(ddev); +stop_poll: + drm_kms_helper_poll_fini(ddev); + tilcdc_irq_uninstall(ddev); +unbind_component: + if (priv->is_componentized) + component_unbind_all(dev, ddev); +unregister_cpufreq_notif: +#ifdef CONFIG_CPU_FREQ + cpufreq_unregister_notifier(&priv->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +destroy_crtc: +#endif + tilcdc_crtc_destroy(priv->crtc); +disable_pm: + pm_runtime_disable(dev); + clk_put(priv->clk); +free_wq: + destroy_workqueue(priv->wq); +put_drm: platform_set_drvdata(pdev, NULL); + ddev->dev_private = NULL; + drm_dev_put(ddev); return ret; } diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index b818448c83f6..58b276f82a66 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -82,7 +82,6 @@ struct tilcdc_drm_private { struct drm_encoder *external_encoder; struct drm_connector *external_connector; - bool is_registered; bool is_componentized; bool irq_enabled; }; @@ -164,6 +163,7 @@ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, bool simulate_vesa_sync); void tilcdc_crtc_shutdown(struct drm_crtc *crtc); +void tilcdc_crtc_destroy(struct drm_crtc *crtc); int tilcdc_crtc_update_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event); -- Gitee From 5ab3aa886598cf800adad406a4a33b550b5659e7 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 31 Dec 2025 02:43:20 +0800 Subject: [PATCH 0831/1449] tty: introduce and use tty_port_tty_vhangup() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit dff9dd01533166809f2907f9a59857b983d0fe0f stable. commit 2b5eac0f8c6e79bc152c8804f9f88d16717013ab upstream. This code (tty_get -> vhangup -> tty_put) is repeated on few places. Introduce a helper similar to tty_port_tty_hangup() (asynchronous) to handle even vhangup (synchronous). And use it on those places. In fact, reuse the tty_port_tty_hangup()'s code and call tty_vhangup() depending on a new bool parameter. Signed-off-by: "Jiri Slaby (SUSE)" Cc: Karsten Keil Cc: David Lin Cc: Johan Hovold Cc: Alex Elder Cc: Oliver Neukum Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20250611100319.186924-2-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 74098cc06e75 ("xhci: dbgtty: fix device unregister: fixup") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/isdn/capi/capi.c | 8 +------- drivers/staging/greybus/uart.c | 7 +------ drivers/tty/serial/serial_core.c | 7 +------ drivers/tty/tty_port.c | 12 ++++++++---- drivers/usb/class/cdc-acm.c | 7 +------ drivers/usb/serial/usb-serial.c | 7 +------ include/linux/tty_port.h | 12 +++++++++++- net/bluetooth/rfcomm/tty.c | 7 +------ 8 files changed, 25 insertions(+), 42 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 2f3789515445..11a1a26f7510 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -304,15 +304,9 @@ static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np) static void capincci_free_minor(struct capincci *np) { struct capiminor *mp = np->minorp; - struct tty_struct *tty; if (mp) { - tty = tty_port_tty_get(&mp->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } - + tty_port_tty_vhangup(&mp->port); capiminor_free(mp); } } diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 999ce613dca8..526573556cda 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -914,7 +914,6 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev) { struct gb_tty *gb_tty = gb_gbphy_get_data(gbphy_dev); struct gb_connection *connection = gb_tty->connection; - struct tty_struct *tty; int ret; ret = gbphy_runtime_get_sync(gbphy_dev); @@ -927,11 +926,7 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev) wake_up_all(&gb_tty->wioctl); mutex_unlock(&gb_tty->mutex); - tty = tty_port_tty_get(&gb_tty->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } + tty_port_tty_vhangup(&gb_tty->port); gb_connection_disable_rx(connection); tty_unregister_device(gb_tty_driver, gb_tty->minor); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 8ff0efac6aa0..c3a51bd59ff7 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3250,7 +3250,6 @@ static void serial_core_remove_one_port(struct uart_driver *drv, struct uart_state *state = drv->state + uport->line; struct tty_port *port = &state->port; struct uart_port *uart_port; - struct tty_struct *tty; mutex_lock(&port->mutex); uart_port = uart_port_check(state); @@ -3269,11 +3268,7 @@ static void serial_core_remove_one_port(struct uart_driver *drv, */ tty_port_unregister_device(port, drv->tty_driver, uport->line); - tty = tty_port_tty_get(port); - if (tty) { - tty_vhangup(port->tty); - tty_kref_put(tty); - } + tty_port_tty_vhangup(port); /* * If the port is used as a console, unregister it diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 624d104bd145..eb51d1f10d56 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -414,15 +414,19 @@ EXPORT_SYMBOL(tty_port_hangup); * @port: tty port * @check_clocal: hang only ttys with %CLOCAL unset? */ -void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) +void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async) { struct tty_struct *tty = tty_port_tty_get(port); - if (tty && (!check_clocal || !C_CLOCAL(tty))) - tty_hangup(tty); + if (tty && (!check_clocal || !C_CLOCAL(tty))) { + if (async) + tty_hangup(tty); + else + tty_vhangup(tty); + } tty_kref_put(tty); } -EXPORT_SYMBOL_GPL(tty_port_tty_hangup); +EXPORT_SYMBOL_GPL(__tty_port_tty_hangup); /** * tty_port_tty_wakeup - helper to wake up a tty diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f0c87c914149..c0c4a9415a76 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1572,7 +1572,6 @@ static int acm_probe(struct usb_interface *intf, static void acm_disconnect(struct usb_interface *intf) { struct acm *acm = usb_get_intfdata(intf); - struct tty_struct *tty; int i; /* sibling interface is already cleaning up */ @@ -1599,11 +1598,7 @@ static void acm_disconnect(struct usb_interface *intf) usb_set_intfdata(acm->data, NULL); mutex_unlock(&acm->mutex); - tty = tty_port_tty_get(&acm->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } + tty_port_tty_vhangup(&acm->port); cancel_delayed_work_sync(&acm->dwork); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 17b09f03ef84..be81d4a2f79f 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1178,7 +1178,6 @@ static void usb_serial_disconnect(struct usb_interface *interface) struct usb_serial *serial = usb_get_intfdata(interface); struct device *dev = &interface->dev; struct usb_serial_port *port; - struct tty_struct *tty; /* sibling interface is cleaning up */ if (!serial) @@ -1193,11 +1192,7 @@ static void usb_serial_disconnect(struct usb_interface *interface) for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } + tty_port_tty_vhangup(&port->port); usb_serial_port_poison_urbs(port); wake_up_interruptible(&port->port.delta_msr_wait); cancel_work_sync(&port->work); diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h index 7187b88d706c..bc7ba52ba674 100644 --- a/include/linux/tty_port.h +++ b/include/linux/tty_port.h @@ -241,7 +241,7 @@ bool tty_port_carrier_raised(struct tty_port *port); void tty_port_raise_dtr_rts(struct tty_port *port); void tty_port_lower_dtr_rts(struct tty_port *port); void tty_port_hangup(struct tty_port *port); -void tty_port_tty_hangup(struct tty_port *port, bool check_clocal); +void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async); void tty_port_tty_wakeup(struct tty_port *port); int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp); @@ -260,4 +260,14 @@ static inline int tty_port_users(struct tty_port *port) return port->count + port->blocked_open; } +static inline void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) +{ + __tty_port_tty_hangup(port, check_clocal, true); +} + +static inline void tty_port_tty_vhangup(struct tty_port *port) +{ + __tty_port_tty_hangup(port, false, false); +} + #endif diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index e258ca191470..912e37cb8310 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -438,7 +438,6 @@ static int __rfcomm_release_dev(void __user *arg) { struct rfcomm_dev_req req; struct rfcomm_dev *dev; - struct tty_struct *tty; if (copy_from_user(&req, arg, sizeof(req))) return -EFAULT; @@ -464,11 +463,7 @@ static int __rfcomm_release_dev(void __user *arg) rfcomm_dlc_close(dev->dlc, 0); /* Shut down TTY synchronously before freeing rfcomm_dev */ - tty = tty_port_tty_get(&dev->port); - if (tty) { - tty_vhangup(tty); - tty_kref_put(tty); - } + tty_port_tty_vhangup(&dev->port); if (!test_bit(RFCOMM_TTY_OWNED, &dev->status)) tty_port_put(&dev->port); -- Gitee From 8cff33119fdd2f49d20607d0c5faa755b94170ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= Date: Wed, 31 Dec 2025 02:43:21 +0800 Subject: [PATCH 0832/1449] xhci: dbgtty: fix device unregister: fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit bf4127db6cb76d22cbce59967535a1130c9698b9 stable. commit 74098cc06e753d3ffd8398b040a3a1dfb65260c0 upstream. This fixup replaces tty_vhangup() call with call to tty_port_tty_vhangup(). Both calls hangup tty device synchronously however tty_port_tty_vhangup() increases reference count during the hangup operation using scoped_guard(tty_port_tty). Cc: stable Fixes: 1f73b8b56cf3 ("xhci: dbgtty: fix device unregister") Signed-off-by: Łukasz Bartosik Link: https://patch.msgid.link/20251127111644.3161386-1-ukaszb@google.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/xhci-dbgtty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index f2c74e20b572..3bc7bb958524 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -522,7 +522,7 @@ static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc) * Hang up the TTY. This wakes up any blocked * writers and causes subsequent writes to fail. */ - tty_vhangup(port->port.tty); + tty_port_tty_vhangup(&port->port); tty_unregister_device(dbc_tty_driver, port->minor); xhci_dbc_tty_exit_port(port); -- Gitee From b20c5021826a0936107ef387d89824687625f56f Mon Sep 17 00:00:00 2001 From: Niklas Neronin Date: Thu, 8 Jan 2026 16:50:20 +0800 Subject: [PATCH 0833/1449] usb: xhci: move link chain bit quirk checks into one helper function. ANBZ: #35228 commit bbda96e97a00a7f28ea57d0bcb7b56c29b22d442 stable. commit 7476a2215c07703db5e95efaa3fc5b9f957b9417 upstream. Older 0.95 xHCI hosts and some other specific newer hosts require the chain bit to be set for Link TRBs even if the link TRB is not in the middle of a transfer descriptor (TD). move the checks for all those cases into one xhci_link_chain_quirk() function to clean up and avoid code duplication. No functional changes. [skip renaming chain_links flag, reword commit message -Mathias] Signed-off-by: Niklas Neronin Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20240626124835.1023046-10-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman [Shivani: Modified to apply on 6.6.y] Signed-off-by: Shivani Agarwal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/xhci-mem.c | 10 ++-------- drivers/usb/host/xhci-ring.c | 8 ++------ drivers/usb/host/xhci.h | 7 +++++-- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 621f12c11cbc..264f8bbe8f9e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -136,10 +136,7 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, if (!ring || !first || !last) return; - /* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */ - chain_links = !!(xhci_link_trb_quirk(xhci) || - (ring->type == TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))); + chain_links = xhci_link_chain_quirk(xhci, ring->type); next = ring->enq_seg->next; xhci_link_segments(ring->enq_seg, first, ring->type, chain_links); @@ -330,10 +327,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, unsigned int num = 0; bool chain_links; - /* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */ - chain_links = !!(xhci_link_trb_quirk(xhci) || - (type == TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))); + chain_links = xhci_link_chain_quirk(xhci, type); prev = xhci_segment_alloc(xhci, cycle_state, max_packet, num, flags); if (!prev) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6a5005f3262c..aa9035eae250 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -245,9 +245,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, * AMD 0.96 host, carry over the chain bit of the previous TRB * (which may mean the chain bit is cleared). */ - if (!(ring->type == TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST)) && - !xhci_link_trb_quirk(xhci)) { + if (!xhci_link_chain_quirk(xhci, ring->type)) { next->link.control &= cpu_to_le32(~TRB_CHAIN); next->link.control |= cpu_to_le32(chain); } @@ -3384,9 +3382,7 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, /* If we're not dealing with 0.95 hardware or isoc rings * on AMD 0.96 host, clear the chain bit. */ - if (!xhci_link_trb_quirk(xhci) && - !(ep_ring->type == TYPE_ISOC && - (xhci->quirks & XHCI_AMD_0x96_HOST))) + if (!xhci_link_chain_quirk(xhci, ep_ring->type)) ep_ring->enqueue->link.control &= cpu_to_le32(~TRB_CHAIN); else diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 874ba4eace42..80917bbd263b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1785,9 +1785,12 @@ static inline void xhci_write_64(struct xhci_hcd *xhci, lo_hi_writeq(val, regs); } -static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) + +/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */ +static inline bool xhci_link_chain_quirk(struct xhci_hcd *xhci, enum xhci_ring_type type) { - return xhci->quirks & XHCI_LINK_TRB_QUIRK; + return (xhci->quirks & XHCI_LINK_TRB_QUIRK) || + (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST)); } /* xHCI debugging */ -- Gitee From 981a2fde527abc9b496ec180179a58d4a66a6eb6 Mon Sep 17 00:00:00 2001 From: Michal Pecio Date: Thu, 8 Jan 2026 16:50:21 +0800 Subject: [PATCH 0834/1449] usb: xhci: Apply the link chain quirk on NEC isoc endpoints ANBZ: #35228 commit dbf427663ce272070d3004b5fca63a4a537d781c stable. commit bb0ba4cb1065e87f9cc75db1fa454e56d0894d01 upstream. Two clearly different specimens of NEC uPD720200 (one with start/stop bug, one without) were seen to cause IOMMU faults after some Missed Service Errors. Faulting address is immediately after a transfer ring segment and patched dynamic debug messages revealed that the MSE was received when waiting for a TD near the end of that segment: [ 1.041954] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ffa08fe0 [ 1.042120] xhci_hcd: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0005 address=0xffa09000 flags=0x0000] [ 1.042146] xhci_hcd: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0005 address=0xffa09040 flags=0x0000] It gets even funnier if the next page is a ring segment accessible to the HC. Below, it reports MSE in segment at ff1e8000, plows through a zero-filled page at ff1e9000 and starts reporting events for TRBs in page at ff1ea000 every microframe, instead of jumping to seg ff1e6000. [ 7.041671] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ff1e8fe0 [ 7.041999] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ff1e8fe0 [ 7.042011] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042028] xhci_hcd: All TDs skipped for slot 1 ep 2. Clear skip flag. [ 7.042134] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042138] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 31 [ 7.042144] xhci_hcd: Looking for event-dma 00000000ff1ea040 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.042259] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042262] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 31 [ 7.042266] xhci_hcd: Looking for event-dma 00000000ff1ea050 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 At some point completion events change from Isoch Buffer Overrun to Short Packet and the HC finally finds cycle bit mismatch in ff1ec000. [ 7.098130] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 13 [ 7.098132] xhci_hcd: Looking for event-dma 00000000ff1ecc50 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.098254] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 13 [ 7.098256] xhci_hcd: Looking for event-dma 00000000ff1ecc60 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.098379] xhci_hcd: Overrun event on slot 1 ep 2 It's possible that data from the isochronous device were written to random buffers of pending TDs on other endpoints (either IN or OUT), other devices or even other HCs in the same IOMMU domain. Lastly, an error from a different USB device on another HC. Was it caused by the above? I don't know, but it may have been. The disk was working without any other issues and generated PCIe traffic to starve the NEC of upstream BW and trigger those MSEs. The two HCs shared one x1 slot by means of a commercial "PCIe splitter" board. [ 7.162604] usb 10-2: reset SuperSpeed USB device number 3 using xhci_hcd [ 7.178990] sd 9:0:0:0: [sdb] tag#0 UNKNOWN(0x2003) Result: hostbyte=0x07 driverbyte=DRIVER_OK cmd_age=0s [ 7.179001] sd 9:0:0:0: [sdb] tag#0 CDB: opcode=0x28 28 00 04 02 ae 00 00 02 00 00 [ 7.179004] I/O error, dev sdb, sector 67284480 op 0x0:(READ) flags 0x80700 phys_seg 5 prio class 0 Fortunately, it appears that this ridiculous bug is avoided by setting the chain bit of Link TRBs on isochronous rings. Other ancient HCs are known which also expect the bit to be set and they ignore Link TRBs if it's not. Reportedly, 0.95 spec guaranteed that the bit is set. The bandwidth-starved NEC HC running a 32KB/uframe UVC endpoint reports tens of MSEs per second and runs into the bug within seconds. Chaining Link TRBs allows the same workload to run for many minutes, many times. No negative side effects seen in UVC recording and UAC playback with a few devices at full speed, high speed and SuperSpeed. The problem doesn't reproduce on the newer Renesas uPD720201/uPD720202 and on old Etron EJ168 and VIA VL805 (but the VL805 has other bug). [shorten line length of log snippets in commit messge -Mathias] Signed-off-by: Michal Pecio Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250306144954.3507700-14-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman [Shivani: Modified to apply on 6.6.y] Signed-off-by: Shivani Agarwal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/xhci.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 80917bbd263b..590728f810e0 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1786,11 +1786,20 @@ static inline void xhci_write_64(struct xhci_hcd *xhci, } -/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */ +/* + * Reportedly, some chapters of v0.95 spec said that Link TRB always has its chain bit set. + * Other chapters and later specs say that it should only be set if the link is inside a TD + * which continues from the end of one segment to the next segment. + * + * Some 0.95 hardware was found to misbehave if any link TRB doesn't have the chain bit set. + * + * 0.96 hardware from AMD and NEC was found to ignore unchained isochronous link TRBs when + * "resynchronizing the pipe" after a Missed Service Error. + */ static inline bool xhci_link_chain_quirk(struct xhci_hcd *xhci, enum xhci_ring_type type) { return (xhci->quirks & XHCI_LINK_TRB_QUIRK) || - (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST)); + (type == TYPE_ISOC && (xhci->quirks & (XHCI_AMD_0x96_HOST | XHCI_NEC_HOST))); } /* xHCI debugging */ -- Gitee From d3d21fecf93ad6b454d4065b78b577417882591e Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 8 Jan 2026 01:21:02 +0800 Subject: [PATCH 0835/1449] net: Remove RTNL dance for SIOCBRADDIF and SIOCBRDELIF. ANBZ: #35228 commit d767ce15045df510f55cdd2af5df0eee71f928d0 stable. commit ed3ba9b6e280e14cc3148c1b226ba453f02fa76c upstream. SIOCBRDELIF is passed to dev_ioctl() first and later forwarded to br_ioctl_call(), which causes unnecessary RTNL dance and the splat below [0] under RTNL pressure. Let's say Thread A is trying to detach a device from a bridge and Thread B is trying to remove the bridge. In dev_ioctl(), Thread A bumps the bridge device's refcnt by netdev_hold() and releases RTNL because the following br_ioctl_call() also re-acquires RTNL. In the race window, Thread B could acquire RTNL and try to remove the bridge device. Then, rtnl_unlock() by Thread B will release RTNL and wait for netdev_put() by Thread A. Thread A, however, must hold RTNL after the unlock in dev_ifsioc(), which may take long under RTNL pressure, resulting in the splat by Thread B. Thread A (SIOCBRDELIF) Thread B (SIOCBRDELBR) ---------------------- ---------------------- sock_ioctl sock_ioctl `- sock_do_ioctl `- br_ioctl_call `- dev_ioctl `- br_ioctl_stub |- rtnl_lock | |- dev_ifsioc ' ' |- dev = __dev_get_by_name(...) |- netdev_hold(dev, ...) . / |- rtnl_unlock ------. | | |- br_ioctl_call `---> |- rtnl_lock Race | | `- br_ioctl_stub |- br_del_bridge Window | | | |- dev = __dev_get_by_name(...) | | | May take long | `- br_dev_delete(dev, ...) | | | under RTNL pressure | `- unregister_netdevice_queue(dev, ...) | | | | `- rtnl_unlock \ | |- rtnl_lock <-' `- netdev_run_todo | |- ... `- netdev_run_todo | `- rtnl_unlock |- __rtnl_unlock | |- netdev_wait_allrefs_any |- netdev_put(dev, ...) <----------------' Wait refcnt decrement and log splat below To avoid blocking SIOCBRDELBR unnecessarily, let's not call dev_ioctl() for SIOCBRADDIF and SIOCBRDELIF. In the dev_ioctl() path, we do the following: 1. Copy struct ifreq by get_user_ifreq in sock_do_ioctl() 2. Check CAP_NET_ADMIN in dev_ioctl() 3. Call dev_load() in dev_ioctl() 4. Fetch the master dev from ifr.ifr_name in dev_ifsioc() 3. can be done by request_module() in br_ioctl_call(), so we move 1., 2., and 4. to br_ioctl_stub(). Note that 2. is also checked later in add_del_if(), but it's better performed before RTNL. SIOCBRADDIF and SIOCBRDELIF have been processed in dev_ioctl() since the pre-git era, and there seems to be no specific reason to process them there. [0]: unregister_netdevice: waiting for wpan3 to become free. Usage count = 2 ref_tracker: wpan3@ffff8880662d8608 has 1/1 users at __netdev_tracker_alloc include/linux/netdevice.h:4282 [inline] netdev_hold include/linux/netdevice.h:4311 [inline] dev_ifsioc+0xc6a/0x1160 net/core/dev_ioctl.c:624 dev_ioctl+0x255/0x10c0 net/core/dev_ioctl.c:826 sock_do_ioctl+0x1ca/0x260 net/socket.c:1213 sock_ioctl+0x23a/0x6c0 net/socket.c:1318 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:906 [inline] __se_sys_ioctl fs/ioctl.c:892 [inline] __x64_sys_ioctl+0x1a4/0x210 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcb/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 893b19587534 ("net: bridge: fix ioctl locking") Reported-by: syzkaller Reported-by: yan kang Reported-by: yue sun Closes: https://lore.kernel.org/netdev/SY8P300MB0421225D54EB92762AE8F0F2A1D32@SY8P300MB0421.AUSP300.PROD.OUTLOOK.COM/ Signed-off-by: Kuniyuki Iwashima Acked-by: Stanislav Fomichev Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Link: https://patch.msgid.link/20250316192851.19781-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni [cascardo: fixed conflict at dev_ifsioc] Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/if_bridge.h | 6 ++---- net/bridge/br_ioctl.c | 36 +++++++++++++++++++++++++++++++++--- net/bridge/br_private.h | 3 +-- net/core/dev_ioctl.c | 16 ---------------- net/socket.c | 19 +++++++++---------- 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 3ff96ae31bf6..c5fe3b2a53e8 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -65,11 +65,9 @@ struct br_ip_list { #define BR_DEFAULT_AGEING_TIME (300 * HZ) struct net_bridge; -void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, - unsigned int cmd, struct ifreq *ifr, +void brioctl_set(int (*hook)(struct net *net, unsigned int cmd, void __user *uarg)); -int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, - struct ifreq *ifr, void __user *uarg); +int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg); #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) int br_multicast_list_adjacent(struct net_device *dev, diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index f213ed108361..6bc0a11f2ed3 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -394,10 +394,26 @@ static int old_deviceless(struct net *net, void __user *data) return -EOPNOTSUPP; } -int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd, - struct ifreq *ifr, void __user *uarg) +int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg) { int ret = -EOPNOTSUPP; + struct ifreq ifr; + + if (cmd == SIOCBRADDIF || cmd == SIOCBRDELIF) { + void __user *data; + char *colon; + + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + + if (get_user_ifreq(&ifr, &data, uarg)) + return -EFAULT; + + ifr.ifr_name[IFNAMSIZ - 1] = 0; + colon = strchr(ifr.ifr_name, ':'); + if (colon) + *colon = 0; + } rtnl_lock(); @@ -430,7 +446,21 @@ int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd, break; case SIOCBRADDIF: case SIOCBRDELIF: - ret = add_del_if(br, ifr->ifr_ifindex, cmd == SIOCBRADDIF); + { + struct net_device *dev; + + dev = __dev_get_by_name(net, ifr.ifr_name); + if (!dev || !netif_device_present(dev)) { + ret = -ENODEV; + break; + } + if (!netif_is_bridge_master(dev)) { + ret = -EOPNOTSUPP; + break; + } + + ret = add_del_if(netdev_priv(dev), ifr.ifr_ifindex, cmd == SIOCBRADDIF); + } break; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 371a948d29cc..f0d8edc378a0 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -948,8 +948,7 @@ br_port_get_check_rtnl(const struct net_device *dev) /* br_ioctl.c */ int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd); -int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd, - struct ifreq *ifr, void __user *uarg); +int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg); /* br_multicast.c */ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index b46aedc36939..541d42bf1e40 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -517,7 +517,6 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, int err; struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); const struct net_device_ops *ops; - netdevice_tracker dev_tracker; if (!dev) return -ENODEV; @@ -580,19 +579,6 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, case SIOCWANDEV: return dev_siocwandev(dev, &ifr->ifr_settings); - case SIOCBRADDIF: - case SIOCBRDELIF: - if (!netif_device_present(dev)) - return -ENODEV; - if (!netif_is_bridge_master(dev)) - return -EOPNOTSUPP; - netdev_hold(dev, &dev_tracker, GFP_KERNEL); - rtnl_unlock(); - err = br_ioctl_call(net, netdev_priv(dev), cmd, ifr, NULL); - netdev_put(dev, &dev_tracker); - rtnl_lock(); - return err; - case SIOCDEVPRIVATE ... SIOCDEVPRIVATE + 15: return dev_siocdevprivate(dev, ifr, data, cmd); @@ -773,8 +759,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, case SIOCBONDRELEASE: case SIOCBONDSETHWADDR: case SIOCBONDCHANGEACTIVE: - case SIOCBRADDIF: - case SIOCBRDELIF: case SIOCSHWTSTAMP: if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; diff --git a/net/socket.c b/net/socket.c index 0c3e8a815347..5dea2c9c16d5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1168,12 +1168,10 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from) */ static DEFINE_MUTEX(br_ioctl_mutex); -static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br, - unsigned int cmd, struct ifreq *ifr, +static int (*br_ioctl_hook)(struct net *net, unsigned int cmd, void __user *uarg); -void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, - unsigned int cmd, struct ifreq *ifr, +void brioctl_set(int (*hook)(struct net *net, unsigned int cmd, void __user *uarg)) { mutex_lock(&br_ioctl_mutex); @@ -1182,8 +1180,7 @@ void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, } EXPORT_SYMBOL(brioctl_set); -int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, - struct ifreq *ifr, void __user *uarg) +int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg) { int err = -ENOPKG; @@ -1192,7 +1189,7 @@ int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, mutex_lock(&br_ioctl_mutex); if (br_ioctl_hook) - err = br_ioctl_hook(net, br, cmd, ifr, uarg); + err = br_ioctl_hook(net, cmd, uarg); mutex_unlock(&br_ioctl_mutex); return err; @@ -1292,7 +1289,9 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) case SIOCSIFBR: case SIOCBRADDBR: case SIOCBRDELBR: - err = br_ioctl_call(net, NULL, cmd, NULL, argp); + case SIOCBRADDIF: + case SIOCBRDELIF: + err = br_ioctl_call(net, cmd, argp); break; case SIOCGIFVLAN: case SIOCSIFVLAN: @@ -3450,6 +3449,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, case SIOCGPGRP: case SIOCBRADDBR: case SIOCBRDELBR: + case SIOCBRADDIF: + case SIOCBRDELIF: case SIOCGIFVLAN: case SIOCSIFVLAN: case SIOCGSKNS: @@ -3489,8 +3490,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, case SIOCGIFPFLAGS: case SIOCGIFTXQLEN: case SIOCSIFTXQLEN: - case SIOCBRADDIF: - case SIOCBRDELIF: case SIOCGIFNAME: case SIOCSIFNAME: case SIOCGMIIPHY: -- Gitee From bd7472f024a5913d02b63080177b66e4f4bc197e Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Wed, 7 Jan 2026 18:15:26 +0800 Subject: [PATCH 0836/1449] drm/amd/display: Fix null pointer deref in dcn20_resource.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 6940c1d0c84a34d5a2038714c218238101a1db5b stable. commit ecbf60782662f0a388493685b85a645a0ba1613c upstream. Fixes a hang thats triggered when MPV is run on a DCN401 dGPU: mpv --hwdec=vaapi --vo=gpu --hwdec-codecs=all and then enabling fullscreen playback (double click on the video) The following calltrace will be seen: [ 181.843989] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 181.843997] #PF: supervisor instruction fetch in kernel mode [ 181.844003] #PF: error_code(0x0010) - not-present page [ 181.844009] PGD 0 P4D 0 [ 181.844020] Oops: 0010 [#1] PREEMPT SMP NOPTI [ 181.844028] CPU: 6 PID: 1892 Comm: gnome-shell Tainted: G W OE 6.5.0-41-generic #41~22.04.2-Ubuntu [ 181.844038] Hardware name: System manufacturer System Product Name/CROSSHAIR VI HERO, BIOS 6302 10/23/2018 [ 181.844044] RIP: 0010:0x0 [ 181.844079] Code: Unable to access opcode bytes at 0xffffffffffffffd6. [ 181.844084] RSP: 0018:ffffb593c2b8f7b0 EFLAGS: 00010246 [ 181.844093] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000004 [ 181.844099] RDX: ffffb593c2b8f804 RSI: ffffb593c2b8f7e0 RDI: ffff9e3c8e758400 [ 181.844105] RBP: ffffb593c2b8f7b8 R08: ffffb593c2b8f9c8 R09: ffffb593c2b8f96c [ 181.844110] R10: 0000000000000000 R11: 0000000000000000 R12: ffffb593c2b8f9c8 [ 181.844115] R13: 0000000000000001 R14: ffff9e3c88000000 R15: 0000000000000005 [ 181.844121] FS: 00007c6e323bb5c0(0000) GS:ffff9e3f85f80000(0000) knlGS:0000000000000000 [ 181.844128] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 181.844134] CR2: ffffffffffffffd6 CR3: 0000000140fbe000 CR4: 00000000003506e0 [ 181.844141] Call Trace: [ 181.844146] [ 181.844153] ? show_regs+0x6d/0x80 [ 181.844167] ? __die+0x24/0x80 [ 181.844179] ? page_fault_oops+0x99/0x1b0 [ 181.844192] ? do_user_addr_fault+0x31d/0x6b0 [ 181.844204] ? exc_page_fault+0x83/0x1b0 [ 181.844216] ? asm_exc_page_fault+0x27/0x30 [ 181.844237] dcn20_get_dcc_compression_cap+0x23/0x30 [amdgpu] [ 181.845115] amdgpu_dm_plane_validate_dcc.constprop.0+0xe5/0x180 [amdgpu] [ 181.845985] amdgpu_dm_plane_fill_plane_buffer_attributes+0x300/0x580 [amdgpu] [ 181.846848] fill_dc_plane_info_and_addr+0x258/0x350 [amdgpu] [ 181.847734] fill_dc_plane_attributes+0x162/0x350 [amdgpu] [ 181.848748] dm_update_plane_state.constprop.0+0x4e3/0x6b0 [amdgpu] [ 181.849791] ? dm_update_plane_state.constprop.0+0x4e3/0x6b0 [amdgpu] [ 181.850840] amdgpu_dm_atomic_check+0xdfe/0x1760 [amdgpu] Signed-off-by: Aurabindo Pillai Reviewed-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Signed-off-by: David Nyström Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 56c42867b20f..fdbb57fcb0e7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2187,10 +2187,11 @@ bool dcn20_get_dcc_compression_cap(const struct dc *dc, const struct dc_dcc_surface_param *input, struct dc_surface_dcc_cap *output) { - return dc->res_pool->hubbub->funcs->get_dcc_compression_cap( - dc->res_pool->hubbub, - input, - output); + if (dc->res_pool->hubbub->funcs->get_dcc_compression_cap) + return dc->res_pool->hubbub->funcs->get_dcc_compression_cap( + dc->res_pool->hubbub, input, output); + + return false; } static void dcn20_destroy_resource_pool(struct resource_pool **pool) -- Gitee From f62a7adec19b01c76194729bb044c412fe637472 Mon Sep 17 00:00:00 2001 From: Chenghao Duan Date: Tue, 6 Jan 2026 11:13:00 +0800 Subject: [PATCH 0837/1449] LoongArch: Refactor register restoration in ftrace_common_return ANBZ: #35228 commit 668350eba983600b5eecb180df898a33e9c62e5d stable. commit 45cb47c628dfbd1994c619f3eac271a780602826 upstream. Refactor the register restoration sequence in the ftrace_common_return function to clearly distinguish between the logic of normal returns and direct call returns in function tracing scenarios. The logic is as follows: 1. In the case of a normal return, the execution flow returns to the traced function, and ftrace must ensure that the register data is consistent with the state when the function was entered. ra = parent return address; t0 = traced function return address. 2. In the case of a direct call return, the execution flow jumps to the custom trampoline function, and ftrace must ensure that the register data is consistent with the state when ftrace was entered. ra = traced function return address; t0 = parent return address. Cc: stable@vger.kernel.org Fixes: 9cdc3b6a299c ("LoongArch: ftrace: Add direct call support") Signed-off-by: Chenghao Duan Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/loongarch/kernel/mcount_dyn.S | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/kernel/mcount_dyn.S b/arch/loongarch/kernel/mcount_dyn.S index 0c65cf09110c..4e05adb40504 100644 --- a/arch/loongarch/kernel/mcount_dyn.S +++ b/arch/loongarch/kernel/mcount_dyn.S @@ -94,7 +94,6 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL) * at the callsite, so there is no need to restore the T series regs. */ ftrace_common_return: - PTR_L ra, sp, PT_R1 PTR_L a0, sp, PT_R4 PTR_L a1, sp, PT_R5 PTR_L a2, sp, PT_R6 @@ -104,12 +103,17 @@ ftrace_common_return: PTR_L a6, sp, PT_R10 PTR_L a7, sp, PT_R11 PTR_L fp, sp, PT_R22 - PTR_L t0, sp, PT_ERA PTR_L t1, sp, PT_R13 - PTR_ADDI sp, sp, PT_SIZE bnez t1, .Ldirect + + PTR_L ra, sp, PT_R1 + PTR_L t0, sp, PT_ERA + PTR_ADDI sp, sp, PT_SIZE jr t0 .Ldirect: + PTR_L t0, sp, PT_R1 + PTR_L ra, sp, PT_ERA + PTR_ADDI sp, sp, PT_SIZE jr t1 SYM_CODE_END(ftrace_common) @@ -161,6 +165,8 @@ SYM_CODE_END(return_to_handler) #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS SYM_CODE_START(ftrace_stub_direct_tramp) UNWIND_HINT_UNDEFINED - jr t0 + move t1, ra + move ra, t0 + jr t1 SYM_CODE_END(ftrace_stub_direct_tramp) #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ -- Gitee From 735488a6ad9f5f3279b445939c0995aa06404dc8 Mon Sep 17 00:00:00 2001 From: Hari Bathini Date: Mon, 1 Jul 2024 21:00:21 +0800 Subject: [PATCH 0838/1449] powerpc/64s/radix/kfence: map __kfence_pool at page granularity ANBZ: #35228 commit 48098bb42a9f5de3accbd6690234d9e819d72c36 stable. commit 353d7a84c214f184d5a6b62acdec8b4424159b7c upstream. When KFENCE is enabled, total system memory is mapped at page level granularity. But in radix MMU mode, ~3GB additional memory is needed to map 100GB of system memory at page level granularity when compared to using 2MB direct mapping.This is not desired considering KFENCE is designed to be enabled in production kernels [1]. Mapping only the memory allocated for KFENCE pool at page granularity is sufficient to enable KFENCE support. So, allocate __kfence_pool during bootup and map it at page granularity instead of mapping all system memory at page granularity. Without patch: # cat /proc/meminfo MemTotal: 101201920 kB With patch: # cat /proc/meminfo MemTotal: 104483904 kB Note that enabling KFENCE at runtime is disabled for radix MMU for now, as it depends on the ability to split page table mappings and such APIs are not currently implemented for radix MMU. All kfence_test.c testcases passed with this patch. [1] https://lore.kernel.org/all/20201103175841.3495947-2-elver@google.com/ Signed-off-by: Hari Bathini Signed-off-by: Michael Ellerman Link: https://msgid.link/20240701130021.578240-1-hbathini@linux.ibm.com Cc: Aboorva Devarajan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/powerpc/include/asm/kfence.h | 11 +++- arch/powerpc/mm/book3s64/radix_pgtable.c | 84 ++++++++++++++++++++++-- arch/powerpc/mm/init-common.c | 3 + 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/kfence.h b/arch/powerpc/include/asm/kfence.h index 424ceef82ae6..fab124ada1c7 100644 --- a/arch/powerpc/include/asm/kfence.h +++ b/arch/powerpc/include/asm/kfence.h @@ -15,10 +15,19 @@ #define ARCH_FUNC_PREFIX "." #endif +#ifdef CONFIG_KFENCE +extern bool kfence_disabled; + +static inline void disable_kfence(void) +{ + kfence_disabled = true; +} + static inline bool arch_kfence_init_pool(void) { - return true; + return !kfence_disabled; } +#endif #ifdef CONFIG_PPC64 static inline bool kfence_protect_page(unsigned long addr, bool protect) diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index aff3b37e32d6..7581e0ef3f6c 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include @@ -293,7 +295,8 @@ static unsigned long next_boundary(unsigned long addr, unsigned long end) static int __meminit create_physical_mapping(unsigned long start, unsigned long end, - int nid, pgprot_t _prot) + int nid, pgprot_t _prot, + unsigned long mapping_sz_limit) { unsigned long vaddr, addr, mapping_size = 0; bool prev_exec, exec = false; @@ -301,7 +304,10 @@ static int __meminit create_physical_mapping(unsigned long start, int psize; unsigned long max_mapping_size = memory_block_size; - if (debug_pagealloc_enabled_or_kfence()) + if (mapping_sz_limit < max_mapping_size) + max_mapping_size = mapping_sz_limit; + + if (debug_pagealloc_enabled()) max_mapping_size = PAGE_SIZE; start = ALIGN(start, PAGE_SIZE); @@ -356,8 +362,74 @@ static int __meminit create_physical_mapping(unsigned long start, return 0; } +#ifdef CONFIG_KFENCE +static bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; + +static int __init parse_kfence_early_init(char *arg) +{ + int val; + + if (get_option(&arg, &val)) + kfence_early_init = !!val; + return 0; +} +early_param("kfence.sample_interval", parse_kfence_early_init); + +static inline phys_addr_t alloc_kfence_pool(void) +{ + phys_addr_t kfence_pool; + + /* + * TODO: Support to enable KFENCE after bootup depends on the ability to + * split page table mappings. As such support is not currently + * implemented for radix pagetables, support enabling KFENCE + * only at system startup for now. + * + * After support for splitting mappings is available on radix, + * alloc_kfence_pool() & map_kfence_pool() can be dropped and + * mapping for __kfence_pool memory can be + * split during arch_kfence_init_pool(). + */ + if (!kfence_early_init) + goto no_kfence; + + kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); + if (!kfence_pool) + goto no_kfence; + + memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); + return kfence_pool; + +no_kfence: + disable_kfence(); + return 0; +} + +static inline void map_kfence_pool(phys_addr_t kfence_pool) +{ + if (!kfence_pool) + return; + + if (create_physical_mapping(kfence_pool, kfence_pool + KFENCE_POOL_SIZE, + -1, PAGE_KERNEL, PAGE_SIZE)) + goto err; + + memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); + __kfence_pool = __va(kfence_pool); + return; + +err: + memblock_phys_free(kfence_pool, KFENCE_POOL_SIZE); + disable_kfence(); +} +#else +static inline phys_addr_t alloc_kfence_pool(void) { return 0; } +static inline void map_kfence_pool(phys_addr_t kfence_pool) { } +#endif + static void __init radix_init_pgtable(void) { + phys_addr_t kfence_pool; unsigned long rts_field; phys_addr_t start, end; u64 i; @@ -365,6 +437,8 @@ static void __init radix_init_pgtable(void) /* We don't support slb for radix */ slb_set_size(0); + kfence_pool = alloc_kfence_pool(); + /* * Create the linear mapping */ @@ -381,9 +455,11 @@ static void __init radix_init_pgtable(void) } WARN_ON(create_physical_mapping(start, end, - -1, PAGE_KERNEL)); + -1, PAGE_KERNEL, ~0UL)); } + map_kfence_pool(kfence_pool); + if (!cpu_has_feature(CPU_FTR_HVMODE) && cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) { /* @@ -875,7 +951,7 @@ int __meminit radix__create_section_mapping(unsigned long start, } return create_physical_mapping(__pa(start), __pa(end), - nid, prot); + nid, prot, ~0UL); } int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end) diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c index d3a7726ecf51..21131b96d209 100644 --- a/arch/powerpc/mm/init-common.c +++ b/arch/powerpc/mm/init-common.c @@ -31,6 +31,9 @@ EXPORT_SYMBOL_GPL(kernstart_virt_addr); bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP); bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP); +#ifdef CONFIG_KFENCE +bool __ro_after_init kfence_disabled; +#endif static int __init parse_nosmep(char *p) { -- Gitee From b4aeb688ad73087253f57471c663b1db7a67fb67 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Mon, 15 Dec 2025 16:52:56 +0800 Subject: [PATCH 0839/1449] ext4: introduce ITAIL helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 36acfec981d8fabfd65da0c584a197f74a6b42ca stable. commit 69f3a3039b0d0003de008659cafd5a1eaaa0a7a4 upstream. Introduce ITAIL helper to get the bound of xattr in inode. Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://patch.msgid.link/20250208063141.1539283-2-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: David Nyström Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/xattr.c | 10 +++++----- fs/ext4/xattr.h | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 29114e194264..d731cb59b77f 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -653,7 +653,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name, return error; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); - end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; + end = ITAIL(inode, raw_inode); error = xattr_check_inode(inode, header, end); if (error) goto cleanup; @@ -797,7 +797,7 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size) return error; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); - end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; + end = ITAIL(inode, raw_inode); error = xattr_check_inode(inode, header, end); if (error) goto cleanup; @@ -883,7 +883,7 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) goto out; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); - end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; + end = ITAIL(inode, raw_inode); ret = xattr_check_inode(inode, header, end); if (ret) goto out; @@ -2248,7 +2248,7 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i, header = IHDR(inode, raw_inode); is->s.base = is->s.first = IFIRST(header); is->s.here = is->s.first; - is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; + is->s.end = ITAIL(inode, raw_inode); if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { error = xattr_check_inode(inode, header, is->s.end); if (error) @@ -2799,7 +2799,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, */ base = IFIRST(header); - end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; + end = ITAIL(inode, raw_inode); min_offs = end - base; total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32); diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 824faf0b15a8..e7417fb0eb76 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -68,6 +68,9 @@ struct ext4_xattr_entry { ((void *)raw_inode + \ EXT4_GOOD_OLD_INODE_SIZE + \ EXT4_I(inode)->i_extra_isize)) +#define ITAIL(inode, raw_inode) \ + ((void *)(raw_inode) + \ + EXT4_SB((inode)->i_sb)->s_inode_size) #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) /* -- Gitee From c9d18be30b51fe9affa1e3d35ec615dee8573936 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Mon, 15 Dec 2025 16:52:57 +0800 Subject: [PATCH 0840/1449] ext4: fix out-of-bound read in ext4_xattr_inode_dec_ref_all() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 3c591353956ffcace2cc74d09930774afed60619 stable. commit 5701875f9609b000d91351eaa6bfd97fe2f157f4 upstream. There's issue as follows: BUG: KASAN: use-after-free in ext4_xattr_inode_dec_ref_all+0x6ff/0x790 Read of size 4 at addr ffff88807b003000 by task syz-executor.0/15172 CPU: 3 PID: 15172 Comm: syz-executor.0 Call Trace: __dump_stack lib/dump_stack.c:82 [inline] dump_stack+0xbe/0xfd lib/dump_stack.c:123 print_address_description.constprop.0+0x1e/0x280 mm/kasan/report.c:400 __kasan_report.cold+0x6c/0x84 mm/kasan/report.c:560 kasan_report+0x3a/0x50 mm/kasan/report.c:585 ext4_xattr_inode_dec_ref_all+0x6ff/0x790 fs/ext4/xattr.c:1137 ext4_xattr_delete_inode+0x4c7/0xda0 fs/ext4/xattr.c:2896 ext4_evict_inode+0xb3b/0x1670 fs/ext4/inode.c:323 evict+0x39f/0x880 fs/inode.c:622 iput_final fs/inode.c:1746 [inline] iput fs/inode.c:1772 [inline] iput+0x525/0x6c0 fs/inode.c:1758 ext4_orphan_cleanup fs/ext4/super.c:3298 [inline] ext4_fill_super+0x8c57/0xba40 fs/ext4/super.c:5300 mount_bdev+0x355/0x410 fs/super.c:1446 legacy_get_tree+0xfe/0x220 fs/fs_context.c:611 vfs_get_tree+0x8d/0x2f0 fs/super.c:1576 do_new_mount fs/namespace.c:2983 [inline] path_mount+0x119a/0x1ad0 fs/namespace.c:3316 do_mount+0xfc/0x110 fs/namespace.c:3329 __do_sys_mount fs/namespace.c:3540 [inline] __se_sys_mount+0x219/0x2e0 fs/namespace.c:3514 do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x67/0xd1 Memory state around the buggy address: ffff88807b002f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff88807b002f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffff88807b003000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ^ ffff88807b003080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff88807b003100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff Above issue happens as ext4_xattr_delete_inode() isn't check xattr is valid if xattr is in inode. To solve above issue call xattr_check_inode() check if xattr if valid in inode. In fact, we can directly verify in ext4_iget_extra_inode(), so that there is no divergent verification. Fixes: e50e5129f384 ("ext4: xattr-in-inode support") Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://patch.msgid.link/20250208063141.1539283-3-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: David Nyström Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/inode.c | 5 +++++ fs/ext4/xattr.c | 26 +------------------------- fs/ext4/xattr.h | 7 +++++++ 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index da778bcbd6ec..4c355177c8b7 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4778,6 +4778,11 @@ static inline int ext4_iget_extra_inode(struct inode *inode, *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { int err; + err = xattr_check_inode(inode, IHDR(inode, raw_inode), + ITAIL(inode, raw_inode)); + if (err) + return err; + ext4_set_inode_state(inode, EXT4_STATE_XATTR); err = ext4_find_inline_data_nolock(inode); if (!err && ext4_has_inline_data(inode)) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index d731cb59b77f..106fae6bac7a 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -312,7 +312,7 @@ __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh, __ext4_xattr_check_block((inode), (bh), __func__, __LINE__) -static inline int +int __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, void *end, const char *function, unsigned int line) { @@ -320,9 +320,6 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, function, line); } -#define xattr_check_inode(inode, header, end) \ - __xattr_check_inode((inode), (header), (end), __func__, __LINE__) - static int xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry, void *end, int name_index, const char *name, int sorted) @@ -654,9 +651,6 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name, raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); end = ITAIL(inode, raw_inode); - error = xattr_check_inode(inode, header, end); - if (error) - goto cleanup; entry = IFIRST(header); error = xattr_find_entry(inode, &entry, end, name_index, name, 0); if (error) @@ -787,7 +781,6 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size) struct ext4_xattr_ibody_header *header; struct ext4_inode *raw_inode; struct ext4_iloc iloc; - void *end; int error; if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR)) @@ -797,14 +790,9 @@ ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size) return error; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); - end = ITAIL(inode, raw_inode); - error = xattr_check_inode(inode, header, end); - if (error) - goto cleanup; error = ext4_xattr_list_entries(dentry, IFIRST(header), buffer, buffer_size); -cleanup: brelse(iloc.bh); return error; } @@ -872,7 +860,6 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) struct ext4_xattr_ibody_header *header; struct ext4_xattr_entry *entry; qsize_t ea_inode_refs = 0; - void *end; int ret; lockdep_assert_held_read(&EXT4_I(inode)->xattr_sem); @@ -883,10 +870,6 @@ int ext4_get_inode_usage(struct inode *inode, qsize_t *usage) goto out; raw_inode = ext4_raw_inode(&iloc); header = IHDR(inode, raw_inode); - end = ITAIL(inode, raw_inode); - ret = xattr_check_inode(inode, header, end); - if (ret) - goto out; for (entry = IFIRST(header); !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) @@ -2250,9 +2233,6 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i, is->s.here = is->s.first; is->s.end = ITAIL(inode, raw_inode); if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { - error = xattr_check_inode(inode, header, is->s.end); - if (error) - return error; /* Find the named attribute. */ error = xattr_find_entry(inode, &is->s.here, is->s.end, i->name_index, i->name, 0); @@ -2803,10 +2783,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, min_offs = end - base; total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32); - error = xattr_check_inode(inode, header, end); - if (error) - goto cleanup; - ifree = ext4_xattr_free_space(base, &min_offs, base, &total_ino); if (ifree >= isize_diff) goto shift; diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index e7417fb0eb76..17c0d6bb230b 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -210,6 +210,13 @@ extern int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, extern struct mb_cache *ext4_xattr_create_cache(void); extern void ext4_xattr_destroy_cache(struct mb_cache *); +extern int +__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, + void *end, const char *function, unsigned int line); + +#define xattr_check_inode(inode, header, end) \ + __xattr_check_inode((inode), (header), (end), __func__, __LINE__) + #ifdef CONFIG_EXT4_FS_SECURITY extern int ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, const struct qstr *qstr); -- Gitee From 7dbd8c11c89a1e74ea684be2d233b8361a77d7dc Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 11 Dec 2025 14:34:41 +0800 Subject: [PATCH 0841/1449] xfrm: state: fix out-of-bounds read during lookup ANBZ: #35228 commit b86dc510308d7a8955f3f47a4fea4bef887653e4 stable. commit e952837f3ddb0ff726d5b582aa1aad9aa38d024d upstream. lookup and resize can run in parallel. The xfrm_state_hash_generation seqlock ensures a retry, but the hash functions can observe a hmask value that is too large for the new hlist array. rehash does: rcu_assign_pointer(net->xfrm.state_bydst, ndst) [..] net->xfrm.state_hmask = nhashmask; While state lookup does: h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) { This is only safe in case the update to state_bydst is larger than net->xfrm.xfrm_state_hmask (or if the lookup function gets serialized via state spinlock again). Fix this by prefetching state_hmask and the associated pointers. The xfrm_state_hash_generation seqlock retry will ensure that the pointer and the hmask will be consistent. The existing helpers, like xfrm_dst_hash(), are now unsafe for RCU side, add lockdep assertions to document that they are only safe for insert side. xfrm_state_lookup_byaddr() uses the spinlock rather than RCU. AFAICS this is an oversight from back when state lookup was converted to RCU, this lock should be replaced with RCU in a future patch. Reported-by: syzbot+5f9f31cb7d985f584d8e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/CACT4Y+azwfrE3uz6A5ZErov5YN2LYBN5KrsymBerT36VU8qzBA@mail.gmail.com/ Diagnosed-by: Dmitry Vyukov Fixes: c2f672fc9464 ("xfrm: state lookup can be lockless") Signed-off-by: Florian Westphal Signed-off-by: Steffen Klassert [ Minor context change fixed ] Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/xfrm/xfrm_state.c | 84 +++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5396fe6b90c6..81e01cdc7a7d 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -34,6 +34,8 @@ #define xfrm_state_deref_prot(table, net) \ rcu_dereference_protected((table), lockdep_is_held(&(net)->xfrm.xfrm_state_lock)) +#define xfrm_state_deref_check(table, net) \ + rcu_dereference_check((table), lockdep_is_held(&(net)->xfrm.xfrm_state_lock)) static void xfrm_state_gc_task(struct work_struct *work); @@ -62,6 +64,8 @@ static inline unsigned int xfrm_dst_hash(struct net *net, u32 reqid, unsigned short family) { + lockdep_assert_held(&net->xfrm.xfrm_state_lock); + return __xfrm_dst_hash(daddr, saddr, reqid, family, net->xfrm.state_hmask); } @@ -70,6 +74,8 @@ static inline unsigned int xfrm_src_hash(struct net *net, const xfrm_address_t *saddr, unsigned short family) { + lockdep_assert_held(&net->xfrm.xfrm_state_lock); + return __xfrm_src_hash(daddr, saddr, family, net->xfrm.state_hmask); } @@ -77,11 +83,15 @@ static inline unsigned int xfrm_spi_hash(struct net *net, const xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) { + lockdep_assert_held(&net->xfrm.xfrm_state_lock); + return __xfrm_spi_hash(daddr, spi, proto, family, net->xfrm.state_hmask); } static unsigned int xfrm_seq_hash(struct net *net, u32 seq) { + lockdep_assert_held(&net->xfrm.xfrm_state_lock); + return __xfrm_seq_hash(seq, net->xfrm.state_hmask); } @@ -1025,16 +1035,38 @@ xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl, x->props.family = tmpl->encap_family; } -static struct xfrm_state *__xfrm_state_lookup_all(struct net *net, u32 mark, +struct xfrm_hash_state_ptrs { + const struct hlist_head *bydst; + const struct hlist_head *bysrc; + const struct hlist_head *byspi; + unsigned int hmask; +}; + +static void xfrm_hash_ptrs_get(const struct net *net, struct xfrm_hash_state_ptrs *ptrs) +{ + unsigned int sequence; + + do { + sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation); + + ptrs->bydst = xfrm_state_deref_check(net->xfrm.state_bydst, net); + ptrs->bysrc = xfrm_state_deref_check(net->xfrm.state_bysrc, net); + ptrs->byspi = xfrm_state_deref_check(net->xfrm.state_byspi, net); + ptrs->hmask = net->xfrm.state_hmask; + } while (read_seqcount_retry(&net->xfrm.xfrm_state_hash_generation, sequence)); +} + +static struct xfrm_state *__xfrm_state_lookup_all(const struct xfrm_hash_state_ptrs *state_ptrs, + u32 mark, const xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family, struct xfrm_dev_offload *xdo) { - unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); + unsigned int h = __xfrm_spi_hash(daddr, spi, proto, family, state_ptrs->hmask); struct xfrm_state *x; - hlist_for_each_entry_rcu(x, net->xfrm.state_byspi + h, byspi) { + hlist_for_each_entry_rcu(x, state_ptrs->byspi + h, byspi) { #ifdef CONFIG_XFRM_OFFLOAD if (xdo->type == XFRM_DEV_OFFLOAD_PACKET) { if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) @@ -1068,15 +1100,16 @@ static struct xfrm_state *__xfrm_state_lookup_all(struct net *net, u32 mark, return NULL; } -static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, +static struct xfrm_state *__xfrm_state_lookup(const struct xfrm_hash_state_ptrs *state_ptrs, + u32 mark, const xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) { - unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); + unsigned int h = __xfrm_spi_hash(daddr, spi, proto, family, state_ptrs->hmask); struct xfrm_state *x; - hlist_for_each_entry_rcu(x, net->xfrm.state_byspi + h, byspi) { + hlist_for_each_entry_rcu(x, state_ptrs->byspi + h, byspi) { if (x->props.family != family || x->id.spi != spi || x->id.proto != proto || @@ -1093,15 +1126,16 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, return NULL; } -static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, +static struct xfrm_state *__xfrm_state_lookup_byaddr(const struct xfrm_hash_state_ptrs *state_ptrs, + u32 mark, const xfrm_address_t *daddr, const xfrm_address_t *saddr, u8 proto, unsigned short family) { - unsigned int h = xfrm_src_hash(net, daddr, saddr, family); + unsigned int h = __xfrm_src_hash(daddr, saddr, family, state_ptrs->hmask); struct xfrm_state *x; - hlist_for_each_entry_rcu(x, net->xfrm.state_bysrc + h, bysrc) { + hlist_for_each_entry_rcu(x, state_ptrs->bysrc + h, bysrc) { if (x->props.family != family || x->id.proto != proto || !xfrm_addr_equal(&x->id.daddr, daddr, family) || @@ -1121,14 +1155,17 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, u32 mark, static inline struct xfrm_state * __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) { + struct xfrm_hash_state_ptrs state_ptrs; struct net *net = xs_net(x); u32 mark = x->mark.v & x->mark.m; + xfrm_hash_ptrs_get(net, &state_ptrs); + if (use_spi) - return __xfrm_state_lookup(net, mark, &x->id.daddr, + return __xfrm_state_lookup(&state_ptrs, mark, &x->id.daddr, x->id.spi, x->id.proto, family); else - return __xfrm_state_lookup_byaddr(net, mark, + return __xfrm_state_lookup_byaddr(&state_ptrs, mark, &x->id.daddr, &x->props.saddr, x->id.proto, family); @@ -1191,6 +1228,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, unsigned short family, u32 if_id) { static xfrm_address_t saddr_wildcard = { }; + struct xfrm_hash_state_ptrs state_ptrs; struct net *net = xp_net(pol); unsigned int h, h_wildcard; struct xfrm_state *x, *x0, *to_put; @@ -1207,8 +1245,10 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation); rcu_read_lock(); - h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); - hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) { + xfrm_hash_ptrs_get(net, &state_ptrs); + + h = __xfrm_dst_hash(daddr, saddr, tmpl->reqid, encap_family, state_ptrs.hmask); + hlist_for_each_entry_rcu(x, state_ptrs.bydst + h, bydst) { #ifdef CONFIG_XFRM_OFFLOAD if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET) { if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) @@ -1241,8 +1281,9 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, if (best || acquire_in_progress) goto found; - h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family); - hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h_wildcard, bydst) { + h_wildcard = __xfrm_dst_hash(daddr, &saddr_wildcard, tmpl->reqid, + encap_family, state_ptrs.hmask); + hlist_for_each_entry_rcu(x, state_ptrs.bydst + h_wildcard, bydst) { #ifdef CONFIG_XFRM_OFFLOAD if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET) { if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) @@ -1277,7 +1318,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, x = best; if (!x && !error && !acquire_in_progress) { if (tmpl->id.spi && - (x0 = __xfrm_state_lookup_all(net, mark, daddr, + (x0 = __xfrm_state_lookup_all(&state_ptrs, mark, daddr, tmpl->id.spi, tmpl->id.proto, encap_family, &pol->xdo)) != NULL) { @@ -2032,10 +2073,13 @@ struct xfrm_state * xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) { + struct xfrm_hash_state_ptrs state_ptrs; struct xfrm_state *x; rcu_read_lock(); - x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family); + xfrm_hash_ptrs_get(net, &state_ptrs); + + x = __xfrm_state_lookup(&state_ptrs, mark, daddr, spi, proto, family); rcu_read_unlock(); return x; } @@ -2046,10 +2090,14 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark, const xfrm_address_t *daddr, const xfrm_address_t *saddr, u8 proto, unsigned short family) { + struct xfrm_hash_state_ptrs state_ptrs; struct xfrm_state *x; spin_lock_bh(&net->xfrm.xfrm_state_lock); - x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family); + + xfrm_hash_ptrs_get(net, &state_ptrs); + + x = __xfrm_state_lookup_byaddr(&state_ptrs, mark, daddr, saddr, proto, family); spin_unlock_bh(&net->xfrm.xfrm_state_lock); return x; } -- Gitee From 25c85ae40deb82c38d85f22750c4e9b6d922ad14 Mon Sep 17 00:00:00 2001 From: Dong Chenchen Date: Wed, 10 Dec 2025 20:15:02 +0800 Subject: [PATCH 0842/1449] page_pool: Fix use-after-free in page_pool_recycle_in_ring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4914c0a166540e534a0c1d43affd329d95fb56fd stable. commit 271683bb2cf32e5126c592b5d5e6a756fa374fd9 upstream. syzbot reported a uaf in page_pool_recycle_in_ring: BUG: KASAN: slab-use-after-free in lock_release+0x151/0xa30 kernel/locking/lockdep.c:5862 Read of size 8 at addr ffff8880286045a0 by task syz.0.284/6943 CPU: 0 UID: 0 PID: 6943 Comm: syz.0.284 Not tainted 6.13.0-rc3-syzkaller-gdfa94ce54f41 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x169/0x550 mm/kasan/report.c:489 kasan_report+0x143/0x180 mm/kasan/report.c:602 lock_release+0x151/0xa30 kernel/locking/lockdep.c:5862 __raw_spin_unlock_bh include/linux/spinlock_api_smp.h:165 [inline] _raw_spin_unlock_bh+0x1b/0x40 kernel/locking/spinlock.c:210 spin_unlock_bh include/linux/spinlock.h:396 [inline] ptr_ring_produce_bh include/linux/ptr_ring.h:164 [inline] page_pool_recycle_in_ring net/core/page_pool.c:707 [inline] page_pool_put_unrefed_netmem+0x748/0xb00 net/core/page_pool.c:826 page_pool_put_netmem include/net/page_pool/helpers.h:323 [inline] page_pool_put_full_netmem include/net/page_pool/helpers.h:353 [inline] napi_pp_put_page+0x149/0x2b0 net/core/skbuff.c:1036 skb_pp_recycle net/core/skbuff.c:1047 [inline] skb_free_head net/core/skbuff.c:1094 [inline] skb_release_data+0x6c4/0x8a0 net/core/skbuff.c:1125 skb_release_all net/core/skbuff.c:1190 [inline] __kfree_skb net/core/skbuff.c:1204 [inline] sk_skb_reason_drop+0x1c9/0x380 net/core/skbuff.c:1242 kfree_skb_reason include/linux/skbuff.h:1263 [inline] __skb_queue_purge_reason include/linux/skbuff.h:3343 [inline] root cause is: page_pool_recycle_in_ring ptr_ring_produce spin_lock(&r->producer_lock); WRITE_ONCE(r->queue[r->producer++], ptr) //recycle last page to pool page_pool_release page_pool_scrub page_pool_empty_ring ptr_ring_consume page_pool_return_page //release all page __page_pool_destroy free_percpu(pool->recycle_stats); free(pool) //free spin_unlock(&r->producer_lock); //pool->ring uaf read recycle_stat_inc(pool, ring); page_pool can be free while page pool recycle the last page in ring. Add producer-lock barrier to page_pool_release to prevent the page pool from being free before all pages have been recycled. recycle_stat_inc() is empty when CONFIG_PAGE_POOL_STATS is not enabled, which will trigger Wempty-body build warning. Add definition for pool stat macro to fix warning. Suggested-by: Jakub Kicinski Link: https://lore.kernel.org/netdev/20250513083123.3514193-1-dongchenchen2@huawei.com Fixes: ff7d6b27f894 ("page_pool: refurbish version of page_pool code") Reported-by: syzbot+204a4382fcb3311f3858@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=204a4382fcb3311f3858 Signed-off-by: Dong Chenchen Reviewed-by: Toke Høiland-Jørgensen Reviewed-by: Mina Almasry Link: https://patch.msgid.link/20250527114152.3119109-1-dongchenchen2@huawei.com Signed-off-by: Jakub Kicinski [ Minor context change fixed. ] Signed-off-by: Ruohan Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/page_pool.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/net/core/page_pool.c b/net/core/page_pool.c index 0188d7f00785..c8e92a12af35 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -140,9 +140,9 @@ u64 *page_pool_ethtool_stats_get(u64 *data, void *stats) EXPORT_SYMBOL(page_pool_ethtool_stats_get); #else -#define alloc_stat_inc(pool, __stat) -#define recycle_stat_inc(pool, __stat) -#define recycle_stat_add(pool, __stat, val) +#define alloc_stat_inc(...) do { } while (0) +#define recycle_stat_inc(...) do { } while (0) +#define recycle_stat_add(...) do { } while (0) #endif static bool page_pool_producer_lock(struct page_pool *pool) @@ -549,19 +549,16 @@ static void page_pool_return_page(struct page_pool *pool, struct page *page) static bool page_pool_recycle_in_ring(struct page_pool *pool, struct page *page) { - int ret; - /* BH protection not needed if current is softirq */ - if (in_softirq()) - ret = ptr_ring_produce(&pool->ring, page); - else - ret = ptr_ring_produce_bh(&pool->ring, page); + bool in_softirq, ret; - if (!ret) { + /* BH protection not needed if current is softirq */ + in_softirq = page_pool_producer_lock(pool); + ret = !__ptr_ring_produce(&pool->ring, page); + if (ret) recycle_stat_inc(pool, ring); - return true; - } + page_pool_producer_unlock(pool, in_softirq); - return false; + return ret; } /* Only allow direct recycling in special circumstances, into the @@ -850,10 +847,14 @@ static void page_pool_scrub(struct page_pool *pool) static int page_pool_release(struct page_pool *pool) { + bool in_softirq; int inflight; page_pool_scrub(pool); inflight = page_pool_inflight(pool); + /* Acquire producer lock to make sure producers have exited. */ + in_softirq = page_pool_producer_lock(pool); + page_pool_producer_unlock(pool, in_softirq); if (!inflight) page_pool_free(pool); -- Gitee From 2a250cfeeaf097955cf4f3c6ff5fafec97a8652f Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 5 Dec 2025 11:12:23 +0800 Subject: [PATCH 0843/1449] net: dsa: sja1105: fix kasan out-of-bounds warning in sja1105_table_delete_entry() ANBZ: #35228 commit 4584486cfcca24b7b586da3377eb3cffd48669ec stable. commit 5f2b28b79d2d1946ee36ad8b3dc0066f73c90481 upstream. There are actually 2 problems: - deleting the last element doesn't require the memmove of elements [i + 1, end) over it. Actually, element i+1 is out of bounds. - The memmove itself should move size - i - 1 elements, because the last element is out of bounds. The out-of-bounds element still remains out of bounds after being accessed, so the problem is only that we touch it, not that it becomes in active use. But I suppose it can lead to issues if the out-of-bounds element is part of an unmapped page. Fixes: 6666cebc5e30 ("net: dsa: sja1105: Add support for VLAN operations") Signed-off-by: Vladimir Oltean Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250318115716.2124395-4-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Chen Yu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/dsa/sja1105/sja1105_static_config.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c index baba204ad62f..2ac91fe2a79b 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.c +++ b/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -1921,8 +1921,10 @@ int sja1105_table_delete_entry(struct sja1105_table *table, int i) if (i > table->entry_count) return -ERANGE; - memmove(entries + i * entry_size, entries + (i + 1) * entry_size, - (table->entry_count - i) * entry_size); + if (i + 1 < table->entry_count) { + memmove(entries + i * entry_size, entries + (i + 1) * entry_size, + (table->entry_count - i - 1) * entry_size); + } table->entry_count--; -- Gitee From 55e4cb8dde524331595bf5f6aa6d40d8fd9ea369 Mon Sep 17 00:00:00 2001 From: Gyeyoung Baek Date: Fri, 26 Dec 2025 09:53:07 +0800 Subject: [PATCH 0844/1449] genirq/irq_sim: Initialize work context pointers properly ANBZ: #35228 commit ec3656a8cb428d763def32bc2fa695f94be23629 stable. commit 8a2277a3c9e4cc5398f80821afe7ecbe9bdf2819 upstream. Initialize `ops` member's pointers properly by using kzalloc() instead of kmalloc() when allocating the simulation work context. Otherwise the pointers contain random content leading to invalid dereferencing. Signed-off-by: Gyeyoung Baek Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/all/20250612124827.63259-1-gye976@gmail.com [ The context change is due to the commit 011f583781fa ("genirq/irq_sim: add an extended irq_sim initializer") which is irrelevant to the logic of this patch. ] Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/irq/irq_sim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c index dd76323ea3fd..bde31468c19d 100644 --- a/kernel/irq/irq_sim.c +++ b/kernel/irq/irq_sim.c @@ -166,7 +166,7 @@ struct irq_domain *irq_domain_create_sim(struct fwnode_handle *fwnode, { struct irq_sim_work_ctx *work_ctx; - work_ctx = kmalloc(sizeof(*work_ctx), GFP_KERNEL); + work_ctx = kzalloc(sizeof(*work_ctx), GFP_KERNEL); if (!work_ctx) goto err_out; -- Gitee From 3abdca442550ea53b1ed63beec5d8894782eb3d9 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 01:05:37 +0800 Subject: [PATCH 0845/1449] f2fs: remove unused GC_FAILURE_PIN ANBZ: #35228 commit 64ed96a21f0fb6140e47d0055547ebb415d1f73d stable. commit 968c4f72b23c0c8f1e94e942eab89b8c5a3022e7 upstream. After commit 3db1de0e582c ("f2fs: change the current atomic write way"), we removed all GC_FAILURE_ATOMIC usage, let's change i_gc_failures[] array to i_pin_failure for cleanup. Meanwhile, let's define i_current_depth and i_gc_failures as union variable due to they won't be valid at the same time. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: 10b591e7fb7c ("f2fs: fix to avoid updating compression context during writeback") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/f2fs.h | 14 +++++--------- fs/f2fs/file.c | 12 +++++------- fs/f2fs/inode.c | 6 ++---- fs/f2fs/recovery.c | 3 +-- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a45713660aeb..3b18ff332753 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -762,11 +762,6 @@ enum { #define DEF_DIR_LEVEL 0 -enum { - GC_FAILURE_PIN, - MAX_GC_FAILURE -}; - /* used for f2fs_inode_info->flags */ enum { FI_NEW_INODE, /* indicate newly allocated inode */ @@ -814,9 +809,10 @@ struct f2fs_inode_info { unsigned long i_flags; /* keep an inode flags for ioctl */ unsigned char i_advise; /* use to give file attribute hints */ unsigned char i_dir_level; /* use for dentry level for large dir */ - unsigned int i_current_depth; /* only for directory depth */ - /* for gc failure statistic */ - unsigned int i_gc_failures[MAX_GC_FAILURE]; + union { + unsigned int i_current_depth; /* only for directory depth */ + unsigned int i_gc_failures; /* for gc failure statistic */ + }; unsigned int i_pino; /* parent inode number */ umode_t i_acl_mode; /* keep file acl mode temporarily */ @@ -3173,7 +3169,7 @@ static inline void f2fs_i_depth_write(struct inode *inode, unsigned int depth) static inline void f2fs_i_gc_failures_write(struct inode *inode, unsigned int count) { - F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = count; + F2FS_I(inode)->i_gc_failures = count; f2fs_mark_inode_dirty_sync(inode, true); } diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4bdc3366dc5b..f3979dac8e0a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3329,13 +3329,11 @@ int f2fs_pin_file_control(struct inode *inode, bool inc) /* Use i_gc_failures for normal file as a risk signal. */ if (inc) - f2fs_i_gc_failures_write(inode, - fi->i_gc_failures[GC_FAILURE_PIN] + 1); + f2fs_i_gc_failures_write(inode, fi->i_gc_failures + 1); - if (fi->i_gc_failures[GC_FAILURE_PIN] > sbi->gc_pin_file_threshold) { + if (fi->i_gc_failures > sbi->gc_pin_file_threshold) { f2fs_warn(sbi, "%s: Enable GC = ino %lx after %x GC trials", - __func__, inode->i_ino, - fi->i_gc_failures[GC_FAILURE_PIN]); + __func__, inode->i_ino, fi->i_gc_failures); clear_inode_flag(inode, FI_PIN_FILE); return -EAGAIN; } @@ -3404,7 +3402,7 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg) } set_inode_flag(inode, FI_PIN_FILE); - ret = F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]; + ret = F2FS_I(inode)->i_gc_failures; done: f2fs_update_time(sbi, REQ_TIME); out: @@ -3419,7 +3417,7 @@ static int f2fs_ioc_get_pin_file(struct file *filp, unsigned long arg) __u32 pin = 0; if (is_inode_flag_set(inode, FI_PIN_FILE)) - pin = F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]; + pin = F2FS_I(inode)->i_gc_failures; return put_user(pin, (u32 __user *)arg); } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index c35fd05c042f..f274578d8cbf 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -428,8 +428,7 @@ static int do_read_inode(struct inode *inode) if (S_ISDIR(inode->i_mode)) fi->i_current_depth = le32_to_cpu(ri->i_current_depth); else if (S_ISREG(inode->i_mode)) - fi->i_gc_failures[GC_FAILURE_PIN] = - le16_to_cpu(ri->i_gc_failures); + fi->i_gc_failures = le16_to_cpu(ri->i_gc_failures); fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); fi->i_flags = le32_to_cpu(ri->i_flags); if (S_ISREG(inode->i_mode)) @@ -691,8 +690,7 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page) ri->i_current_depth = cpu_to_le32(F2FS_I(inode)->i_current_depth); else if (S_ISREG(inode->i_mode)) - ri->i_gc_failures = - cpu_to_le16(F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN]); + ri->i_gc_failures = cpu_to_le16(F2FS_I(inode)->i_gc_failures); ri->i_xattr_nid = cpu_to_le32(F2FS_I(inode)->i_xattr_nid); ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index f8852aa52640..223fcdf785f7 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -330,8 +330,7 @@ static int recover_inode(struct inode *inode, struct page *page) F2FS_I(inode)->i_advise = raw->i_advise; F2FS_I(inode)->i_flags = le32_to_cpu(raw->i_flags); f2fs_set_inode_flags(inode); - F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = - le16_to_cpu(raw->i_gc_failures); + F2FS_I(inode)->i_gc_failures = le16_to_cpu(raw->i_gc_failures); recover_inline_flags(inode, raw); -- Gitee From d098981c830193322c229fe8a02df8ca4add02f9 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 31 Dec 2025 01:05:38 +0800 Subject: [PATCH 0846/1449] f2fs: keep POSIX_FADV_NOREUSE ranges ANBZ: #35228 commit 1a00afcdaefcf5bb86547c66062d33ab7f4c727e stable. commit ef0c333cad8d1940f132a7ce15f15920216a3bd5 upstream. This patch records POSIX_FADV_NOREUSE ranges for users to reclaim the caches instantly off from LRU. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: 10b591e7fb7c ("f2fs: fix to avoid updating compression context during writeback") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/debug.c | 3 +++ fs/f2fs/f2fs.h | 12 +++++++++- fs/f2fs/file.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----- fs/f2fs/inode.c | 14 ++++++++++++ fs/f2fs/super.c | 1 + 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 0d02224b99b7..68773b48ed4d 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -100,6 +100,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->ndirty_imeta = get_pages(sbi, F2FS_DIRTY_IMETA); si->ndirty_dirs = sbi->ndirty_inode[DIR_INODE]; si->ndirty_files = sbi->ndirty_inode[FILE_INODE]; + si->ndonate_files = sbi->donate_files; si->nquota_files = sbi->nquota_files; si->ndirty_all = sbi->ndirty_inode[DIRTY_META]; si->aw_cnt = atomic_read(&sbi->atomic_files); @@ -436,6 +437,8 @@ static int stat_show(struct seq_file *s, void *v) si->compr_inode, si->compr_blocks); seq_printf(s, " - Swapfile Inode: %u\n", si->swapfile_inode); + seq_printf(s, " - Donate Inode: %u\n", + si->ndonate_files); seq_printf(s, " - Orphan/Append/Update Inode: %u, %u, %u\n", si->orphans, si->append, si->update); seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n", diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 3b18ff332753..4682430434f5 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -837,6 +837,11 @@ struct f2fs_inode_info { #endif struct list_head dirty_list; /* dirty list for dirs and files */ struct list_head gdirty_list; /* linked in global dirty list */ + + /* linked in global inode list for cache donation */ + struct list_head gdonate_list; + pgoff_t donate_start, donate_end; /* inclusive */ + struct task_struct *atomic_write_task; /* store atomic write task */ struct extent_tree *extent_tree[NR_EXTENT_CACHES]; /* cached extent_tree entry */ @@ -1261,6 +1266,7 @@ enum inode_type { DIR_INODE, /* for dirty dir inode */ FILE_INODE, /* for dirty regular/symlink inode */ DIRTY_META, /* for all dirtied inode metadata */ + DONATE_INODE, /* for all inode to donate pages */ NR_INODE_TYPE, }; @@ -1613,6 +1619,9 @@ struct f2fs_sb_info { unsigned int warm_data_age_threshold; unsigned int last_age_weight; + /* control donate caches */ + unsigned int donate_files; + /* basic filesystem units */ unsigned int log_sectors_per_block; /* log2 sectors per block */ unsigned int log_blocksize; /* log2 block size */ @@ -3948,7 +3957,8 @@ struct f2fs_stat_info { unsigned long long allocated_data_blocks; int ndirty_node, ndirty_dent, ndirty_meta, ndirty_imeta; int ndirty_data, ndirty_qdata; - unsigned int ndirty_dirs, ndirty_files, nquota_files, ndirty_all; + unsigned int ndirty_dirs, ndirty_files, ndirty_all; + unsigned int nquota_files, ndonate_files; int nats, dirty_nats, sits, dirty_sits; int free_nids, avail_nids, alloc_nids; int total_count, utilization; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f3979dac8e0a..55728827e044 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2435,6 +2435,52 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) return ret; } +static void f2fs_keep_noreuse_range(struct inode *inode, + loff_t offset, loff_t len) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + u64 max_bytes = F2FS_BLK_TO_BYTES(max_file_blocks(inode)); + u64 start, end; + + if (!S_ISREG(inode->i_mode)) + return; + + if (offset >= max_bytes || len > max_bytes || + (offset + len) > max_bytes) + return; + + start = offset >> PAGE_SHIFT; + end = DIV_ROUND_UP(offset + len, PAGE_SIZE); + + inode_lock(inode); + if (f2fs_is_atomic_file(inode)) { + inode_unlock(inode); + return; + } + + spin_lock(&sbi->inode_lock[DONATE_INODE]); + /* let's remove the range, if len = 0 */ + if (!len) { + if (!list_empty(&F2FS_I(inode)->gdonate_list)) { + list_del_init(&F2FS_I(inode)->gdonate_list); + sbi->donate_files--; + } + } else { + if (list_empty(&F2FS_I(inode)->gdonate_list)) { + list_add_tail(&F2FS_I(inode)->gdonate_list, + &sbi->inode_list[DONATE_INODE]); + sbi->donate_files++; + } else { + list_move_tail(&F2FS_I(inode)->gdonate_list, + &sbi->inode_list[DONATE_INODE]); + } + F2FS_I(inode)->donate_start = start; + F2FS_I(inode)->donate_end = end - 1; + } + spin_unlock(&sbi->inode_lock[DONATE_INODE]); + inode_unlock(inode); +} + static int f2fs_ioc_fitrim(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -5078,12 +5124,16 @@ static int f2fs_file_fadvise(struct file *filp, loff_t offset, loff_t len, } err = generic_fadvise(filp, offset, len, advice); - if (!err && advice == POSIX_FADV_DONTNEED && - test_opt(F2FS_I_SB(inode), COMPRESS_CACHE) && - f2fs_compressed_file(inode)) - f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino); + if (err) + return err; - return err; + if (advice == POSIX_FADV_DONTNEED && + (test_opt(F2FS_I_SB(inode), COMPRESS_CACHE) && + f2fs_compressed_file(inode))) + f2fs_invalidate_compress_pages(F2FS_I_SB(inode), inode->i_ino); + else if (advice == POSIX_FADV_NOREUSE) + f2fs_keep_noreuse_range(inode, offset, len); + return 0; } #ifdef CONFIG_COMPAT diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index f274578d8cbf..c933eedad3f8 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -811,6 +811,19 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) return 0; } +static void f2fs_remove_donate_inode(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + + if (list_empty(&F2FS_I(inode)->gdonate_list)) + return; + + spin_lock(&sbi->inode_lock[DONATE_INODE]); + list_del_init(&F2FS_I(inode)->gdonate_list); + sbi->donate_files--; + spin_unlock(&sbi->inode_lock[DONATE_INODE]); +} + /* * Called at the last iput() if i_nlink is zero */ @@ -844,6 +857,7 @@ void f2fs_evict_inode(struct inode *inode) f2fs_bug_on(sbi, get_dirty_pages(inode)); f2fs_remove_dirty_inode(inode); + f2fs_remove_donate_inode(inode); f2fs_destroy_extent_tree(inode); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c0edf5b0e6cb..31eca7d84e82 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1428,6 +1428,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) spin_lock_init(&fi->i_size_lock); INIT_LIST_HEAD(&fi->dirty_list); INIT_LIST_HEAD(&fi->gdirty_list); + INIT_LIST_HEAD(&fi->gdonate_list); init_f2fs_rwsem(&fi->i_gc_rwsem[READ]); init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]); init_f2fs_rwsem(&fi->i_xattr_sem); -- Gitee From c38f892d955c9e17c62b4220f3d7cebd2f33239f Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 31 Dec 2025 01:05:39 +0800 Subject: [PATCH 0847/1449] f2fs: drop inode from the donation list when the last file is closed ANBZ: #35228 commit b54cdce20f867b525f122d276e7eff522cab2314 stable. commit 078cad8212ce4f4ebbafcc0936475b8215e1ca2a upstream. Let's drop the inode from the donation list when there is no other open file. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Stable-dep-of: 10b591e7fb7c ("f2fs: fix to avoid updating compression context during writeback") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/f2fs.h | 2 ++ fs/f2fs/file.c | 8 +++++++- fs/f2fs/inode.c | 2 +- fs/f2fs/super.c | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4682430434f5..b2e474a4655e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -841,6 +841,7 @@ struct f2fs_inode_info { /* linked in global inode list for cache donation */ struct list_head gdonate_list; pgoff_t donate_start, donate_end; /* inclusive */ + atomic_t open_count; /* # of open files */ struct task_struct *atomic_write_task; /* store atomic write task */ struct extent_tree *extent_tree[NR_EXTENT_CACHES]; @@ -3560,6 +3561,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink); void f2fs_update_inode(struct inode *inode, struct page *node_page); void f2fs_update_inode_page(struct inode *inode); int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc); +void f2fs_remove_donate_inode(struct inode *inode); void f2fs_evict_inode(struct inode *inode); void f2fs_handle_failed_inode(struct inode *inode); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 55728827e044..dea42a4bd916 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -621,7 +621,10 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) if (err) return err; - return finish_preallocate_blocks(inode); + err = finish_preallocate_blocks(inode); + if (!err) + atomic_inc(&F2FS_I(inode)->open_count); + return err; } void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) @@ -1966,6 +1969,9 @@ static long f2fs_fallocate(struct file *file, int mode, static int f2fs_release_file(struct inode *inode, struct file *filp) { + if (atomic_dec_and_test(&F2FS_I(inode)->open_count)) + f2fs_remove_donate_inode(inode); + /* * f2fs_release_file is called at every close calls. So we should * not drop any inmemory pages by close called by other process. diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index c933eedad3f8..0ff172d3f48b 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -811,7 +811,7 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) return 0; } -static void f2fs_remove_donate_inode(struct inode *inode) +void f2fs_remove_donate_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 31eca7d84e82..c39c102b8426 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1424,6 +1424,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) /* Initialize f2fs-specific inode info */ atomic_set(&fi->dirty_pages, 0); atomic_set(&fi->i_compr_blocks, 0); + atomic_set(&fi->open_count, 0); init_f2fs_rwsem(&fi->i_sem); spin_lock_init(&fi->i_size_lock); INIT_LIST_HEAD(&fi->dirty_list); -- Gitee From 24b5edfe89a2c2528390a3e17824d445a2f15842 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 01:05:40 +0800 Subject: [PATCH 0848/1449] f2fs: fix to avoid updating compression context during writeback ANBZ: #35228 commit bcd0086ee5a2e88c1224ff2ec1e4a43c83efe5a0 stable. commit 10b591e7fb7cdc8c1e53e9c000dc0ef7069aaa76 upstream. Bai, Shuangpeng reported a bug as below: Oops: divide error: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 11441 Comm: syz.0.46 Not tainted 6.17.0 #1 PREEMPT(full) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:f2fs_all_cluster_page_ready+0x106/0x550 fs/f2fs/compress.c:857 Call Trace: f2fs_write_cache_pages fs/f2fs/data.c:3078 [inline] __f2fs_write_data_pages fs/f2fs/data.c:3290 [inline] f2fs_write_data_pages+0x1c19/0x3600 fs/f2fs/data.c:3317 do_writepages+0x38e/0x640 mm/page-writeback.c:2634 filemap_fdatawrite_wbc mm/filemap.c:386 [inline] __filemap_fdatawrite_range mm/filemap.c:419 [inline] file_write_and_wait_range+0x2ba/0x3e0 mm/filemap.c:794 f2fs_do_sync_file+0x6e6/0x1b00 fs/f2fs/file.c:294 generic_write_sync include/linux/fs.h:3043 [inline] f2fs_file_write_iter+0x76e/0x2700 fs/f2fs/file.c:5259 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x7e9/0xe00 fs/read_write.c:686 ksys_write+0x19d/0x2d0 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf7/0x470 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f The bug was triggered w/ below race condition: fsync setattr ioctl - f2fs_do_sync_file - file_write_and_wait_range - f2fs_write_cache_pages : inode is non-compressed : cc.cluster_size = F2FS_I(inode)->i_cluster_size = 0 - tag_pages_for_writeback - f2fs_setattr - truncate_setsize - f2fs_truncate - f2fs_fileattr_set - f2fs_setflags_common - set_compress_context : F2FS_I(inode)->i_cluster_size = 4 : set_inode_flag(inode, FI_COMPRESSED_FILE) - f2fs_compressed_file : return true - f2fs_all_cluster_page_ready : "pgidx % cc->cluster_size" trigger dividing 0 issue Let's change as below to fix this issue: - introduce a new atomic type variable .writeback in structure f2fs_inode_info to track the number of threads which calling f2fs_write_cache_pages(). - use .i_sem lock to protect .writeback update. - check .writeback before update compression context in f2fs_setflags_common() to avoid race w/ ->writepages. Fixes: 4c8ff7095bef ("f2fs: support data compression") Cc: stable@kernel.org Reported-by: Bai, Shuangpeng Tested-by: Bai, Shuangpeng Closes: https://lore.kernel.org/lkml/44D8F7B3-68AD-425F-9915-65D27591F93F@psu.edu Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/data.c | 17 +++++++++++++++++ fs/f2fs/f2fs.h | 3 ++- fs/f2fs/file.c | 5 +++-- fs/f2fs/super.c | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 09541a004088..94017a6e08db 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3236,6 +3236,19 @@ static inline bool __should_serialize_io(struct inode *inode, return false; } +static inline void account_writeback(struct inode *inode, bool inc) +{ + if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) + return; + + f2fs_down_read(&F2FS_I(inode)->i_sem); + if (inc) + atomic_inc(&F2FS_I(inode)->writeback); + else + atomic_dec(&F2FS_I(inode)->writeback); + f2fs_up_read(&F2FS_I(inode)->i_sem); +} + static int __f2fs_write_data_pages(struct address_space *mapping, struct writeback_control *wbc, enum iostat_type io_type) @@ -3285,10 +3298,14 @@ static int __f2fs_write_data_pages(struct address_space *mapping, locked = true; } + account_writeback(inode, true); + blk_start_plug(&plug); ret = f2fs_write_cache_pages(mapping, wbc, io_type); blk_finish_plug(&plug); + account_writeback(inode, false); + if (locked) mutex_unlock(&sbi->writepages); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b2e474a4655e..f3ed2567e890 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -869,6 +869,7 @@ struct f2fs_inode_info { unsigned char i_compress_level; /* compress level (lz4hc,zstd) */ unsigned char i_compress_flag; /* compress flag */ unsigned int i_cluster_size; /* cluster size */ + atomic_t writeback; /* count # of writeback thread */ unsigned int atomic_write_cnt; loff_t original_i_size; /* original i_size before atomic write */ @@ -4485,7 +4486,7 @@ static inline bool f2fs_disable_compressed_file(struct inode *inode) f2fs_up_write(&F2FS_I(inode)->i_sem); return true; } - if (f2fs_is_mmap_file(inode) || + if (f2fs_is_mmap_file(inode) || atomic_read(&fi->writeback) || (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))) { f2fs_up_write(&F2FS_I(inode)->i_sem); return false; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index dea42a4bd916..c2124cccd72e 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2045,8 +2045,9 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask) f2fs_down_write(&F2FS_I(inode)->i_sem); if (!f2fs_may_compress(inode) || - (S_ISREG(inode->i_mode) && - F2FS_HAS_BLOCKS(inode))) { + atomic_read(&fi->writeback) || + (S_ISREG(inode->i_mode) && + F2FS_HAS_BLOCKS(inode))) { f2fs_up_write(&F2FS_I(inode)->i_sem); return -EINVAL; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c39c102b8426..c601bacb7dfe 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1425,6 +1425,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) atomic_set(&fi->dirty_pages, 0); atomic_set(&fi->i_compr_blocks, 0); atomic_set(&fi->open_count, 0); + atomic_set(&fi->writeback, 0); init_f2fs_rwsem(&fi->i_sem); spin_lock_init(&fi->i_size_lock); INIT_LIST_HEAD(&fi->dirty_list); -- Gitee From 2740a532a80e85a99e2a592e35c227ccc87db7d4 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 01:20:55 +0800 Subject: [PATCH 0849/1449] f2fs: fix to propagate error from f2fs_enable_checkpoint() ANBZ: #35228 commit 34c817843cb381faeb84c8e83555a534cecc8d4b stable. commit be112e7449a6e1b54aa9feac618825d154b3a5c7 upstream. In order to let userspace detect such error rather than suffering silent failure. Fixes: 4354994f097d ("f2fs: checkpoint disabling") Cc: stable@kernel.org Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ Adjust context, no rollback ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/super.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index c601bacb7dfe..23f4222232e3 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2282,9 +2282,10 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) return err; } -static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) +static int f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) { int retry = DEFAULT_RETRY_IO_COUNT; + int ret; /* we should flush all the data to keep data consistency */ do { @@ -2302,10 +2303,14 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) set_sbi_flag(sbi, SBI_IS_DIRTY); f2fs_up_write(&sbi->gc_lock); - f2fs_sync_fs(sbi->sb, 1); + ret = f2fs_sync_fs(sbi->sb, 1); + if (ret) + f2fs_err(sbi, "%s sync_fs failed, ret: %d", __func__, ret); /* Let's ensure there's no pending checkpoint anymore */ f2fs_flush_ckpt_thread(sbi); + + return ret; } static int f2fs_remount(struct super_block *sb, int *flags, char *data) @@ -2526,7 +2531,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) if (err) goto restore_discard; } else { - f2fs_enable_checkpoint(sbi); + err = f2fs_enable_checkpoint(sbi); + if (err) + goto restore_discard; } } @@ -4704,13 +4711,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* f2fs_recover_fsync_data() cleared this already */ clear_sbi_flag(sbi, SBI_POR_DOING); - if (test_opt(sbi, DISABLE_CHECKPOINT)) { + if (test_opt(sbi, DISABLE_CHECKPOINT)) err = f2fs_disable_checkpoint(sbi); - if (err) - goto sync_free_meta; - } else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) { - f2fs_enable_checkpoint(sbi); - } + else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) + err = f2fs_enable_checkpoint(sbi); + if (err) + goto sync_free_meta; /* * If filesystem is not mounted as read-only then -- Gitee From dfc6a23f7ac98650f702bb0696372c68d807b5fb Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 02:19:39 +0800 Subject: [PATCH 0850/1449] f2fs: use global inline_xattr_slab instead of per-sb slab cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit be4c3a3c6c2304a8fcd14095d18d26f0cc4e222a stable. commit 1f27ef42bb0b7c0740c5616ec577ec188b8a1d05 upstream. As Hong Yun reported in mailing list: loop7: detected capacity change from 0 to 131072 ------------[ cut here ]------------ kmem_cache of name 'f2fs_xattr_entry-7:7' already exists WARNING: CPU: 0 PID: 24426 at mm/slab_common.c:110 kmem_cache_sanity_check mm/slab_common.c:109 [inline] WARNING: CPU: 0 PID: 24426 at mm/slab_common.c:110 __kmem_cache_create_args+0xa6/0x320 mm/slab_common.c:307 CPU: 0 UID: 0 PID: 24426 Comm: syz.7.1370 Not tainted 6.17.0-rc4 #1 PREEMPT(full) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:kmem_cache_sanity_check mm/slab_common.c:109 [inline] RIP: 0010:__kmem_cache_create_args+0xa6/0x320 mm/slab_common.c:307 Call Trace:  __kmem_cache_create include/linux/slab.h:353 [inline]  f2fs_kmem_cache_create fs/f2fs/f2fs.h:2943 [inline]  f2fs_init_xattr_caches+0xa5/0xe0 fs/f2fs/xattr.c:843  f2fs_fill_super+0x1645/0x2620 fs/f2fs/super.c:4918  get_tree_bdev_flags+0x1fb/0x260 fs/super.c:1692  vfs_get_tree+0x43/0x140 fs/super.c:1815  do_new_mount+0x201/0x550 fs/namespace.c:3808  do_mount fs/namespace.c:4136 [inline]  __do_sys_mount fs/namespace.c:4347 [inline]  __se_sys_mount+0x298/0x2f0 fs/namespace.c:4324  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]  do_syscall_64+0x8e/0x3a0 arch/x86/entry/syscall_64.c:94  entry_SYSCALL_64_after_hwframe+0x76/0x7e The bug can be reproduced w/ below scripts: - mount /dev/vdb /mnt1 - mount /dev/vdc /mnt2 - umount /mnt1 - mounnt /dev/vdb /mnt1 The reason is if we created two slab caches, named f2fs_xattr_entry-7:3 and f2fs_xattr_entry-7:7, and they have the same slab size. Actually, slab system will only create one slab cache core structure which has slab name of "f2fs_xattr_entry-7:3", and two slab caches share the same structure and cache address. So, if we destroy f2fs_xattr_entry-7:3 cache w/ cache address, it will decrease reference count of slab cache, rather than release slab cache entirely, since there is one more user has referenced the cache. Then, if we try to create slab cache w/ name "f2fs_xattr_entry-7:3" again, slab system will find that there is existed cache which has the same name and trigger the warning. Let's changes to use global inline_xattr_slab instead of per-sb slab cache for fixing. Fixes: a999150f4fe3 ("f2fs: use kmem_cache pool during inline xattr lookups") Cc: stable@kernel.org Reported-by: Hong Yun Tested-by: Hong Yun Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ folio => page ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/f2fs.h | 3 --- fs/f2fs/super.c | 17 ++++++++--------- fs/f2fs/xattr.c | 30 ++++++++++-------------------- fs/f2fs/xattr.h | 10 ++++++---- 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f3ed2567e890..9a4eabd11c73 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1778,9 +1778,6 @@ struct f2fs_sb_info { spinlock_t error_lock; /* protect errors/stop_reason array */ bool error_dirty; /* errors of sb is dirty */ - struct kmem_cache *inline_xattr_slab; /* inline xattr entry */ - unsigned int inline_xattr_slab_size; /* default inline xattr slab size */ - /* For reclaimed segs statistics per each GC mode */ unsigned int gc_segment_mode; /* GC state for reclaimed segments */ unsigned int gc_reclaimed_segs[MAX_GC_MODE]; /* Reclaimed segs for each mode */ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 23f4222232e3..9305bf465ddc 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1698,7 +1698,6 @@ static void f2fs_put_super(struct super_block *sb) destroy_device_list(sbi); f2fs_destroy_page_array_cache(sbi); - f2fs_destroy_xattr_caches(sbi); #ifdef CONFIG_QUOTA for (i = 0; i < MAXQUOTAS; i++) kfree(F2FS_OPTION(sbi).s_qf_names[i]); @@ -4479,13 +4478,9 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) if (err) goto free_iostat; - /* init per sbi slab cache */ - err = f2fs_init_xattr_caches(sbi); - if (err) - goto free_percpu; err = f2fs_init_page_array_cache(sbi); if (err) - goto free_xattr_cache; + goto free_percpu; /* get an inode for meta space */ sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); @@ -4802,8 +4797,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) sbi->meta_inode = NULL; free_page_array_cache: f2fs_destroy_page_array_cache(sbi); -free_xattr_cache: - f2fs_destroy_xattr_caches(sbi); free_percpu: destroy_percpu_info(sbi); free_iostat: @@ -4964,10 +4957,15 @@ static int __init init_f2fs_fs(void) err = f2fs_create_casefold_cache(); if (err) goto free_compress_cache; - err = register_filesystem(&f2fs_fs_type); + err = f2fs_init_xattr_cache(); if (err) goto free_casefold_cache; + err = register_filesystem(&f2fs_fs_type); + if (err) + goto free_xattr_cache; return 0; +free_xattr_cache: + f2fs_destroy_xattr_cache(); free_casefold_cache: f2fs_destroy_casefold_cache(); free_compress_cache: @@ -5008,6 +5006,7 @@ static int __init init_f2fs_fs(void) static void __exit exit_f2fs_fs(void) { unregister_filesystem(&f2fs_fs_type); + f2fs_destroy_xattr_cache(); f2fs_destroy_casefold_cache(); f2fs_destroy_compress_cache(); f2fs_destroy_compress_mempool(); diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 54ab9caaae4d..c2cb24be4e79 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -23,11 +23,12 @@ #include "xattr.h" #include "segment.h" +static struct kmem_cache *inline_xattr_slab; static void *xattr_alloc(struct f2fs_sb_info *sbi, int size, bool *is_inline) { - if (likely(size == sbi->inline_xattr_slab_size)) { + if (likely(size == DEFAULT_XATTR_SLAB_SIZE)) { *is_inline = true; - return f2fs_kmem_cache_alloc(sbi->inline_xattr_slab, + return f2fs_kmem_cache_alloc(inline_xattr_slab, GFP_F2FS_ZERO, false, sbi); } *is_inline = false; @@ -38,7 +39,7 @@ static void xattr_free(struct f2fs_sb_info *sbi, void *xattr_addr, bool is_inline) { if (is_inline) - kmem_cache_free(sbi->inline_xattr_slab, xattr_addr); + kmem_cache_free(inline_xattr_slab, xattr_addr); else kfree(xattr_addr); } @@ -830,25 +831,14 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, return err; } -int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) +int __init f2fs_init_xattr_cache(void) { - dev_t dev = sbi->sb->s_bdev->bd_dev; - char slab_name[32]; - - sprintf(slab_name, "f2fs_xattr_entry-%u:%u", MAJOR(dev), MINOR(dev)); - - sbi->inline_xattr_slab_size = F2FS_OPTION(sbi).inline_xattr_size * - sizeof(__le32) + XATTR_PADDING_SIZE; - - sbi->inline_xattr_slab = f2fs_kmem_cache_create(slab_name, - sbi->inline_xattr_slab_size); - if (!sbi->inline_xattr_slab) - return -ENOMEM; - - return 0; + inline_xattr_slab = f2fs_kmem_cache_create("f2fs_xattr_entry", + DEFAULT_XATTR_SLAB_SIZE); + return inline_xattr_slab ? 0 : -ENOMEM; } -void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) +void f2fs_destroy_xattr_cache(void) { - kmem_cache_destroy(sbi->inline_xattr_slab); + kmem_cache_destroy(inline_xattr_slab); } diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index b1811c392e6f..a038a750fdde 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h @@ -89,6 +89,8 @@ struct f2fs_xattr_entry { F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - \ DEF_INLINE_RESERVED_SIZE - \ MIN_INLINE_DENTRY_SIZE / sizeof(__le32)) +#define DEFAULT_XATTR_SLAB_SIZE (DEFAULT_INLINE_XATTR_ADDRS * \ + sizeof(__le32) + XATTR_PADDING_SIZE) /* * On-disk structure of f2fs_xattr @@ -132,8 +134,8 @@ extern int f2fs_setxattr(struct inode *, int, const char *, extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t, struct page *); extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); -extern int f2fs_init_xattr_caches(struct f2fs_sb_info *); -extern void f2fs_destroy_xattr_caches(struct f2fs_sb_info *); +extern int __init f2fs_init_xattr_cache(void); +extern void f2fs_destroy_xattr_cache(void); #else #define f2fs_xattr_handlers NULL @@ -150,8 +152,8 @@ static inline int f2fs_getxattr(struct inode *inode, int index, { return -EOPNOTSUPP; } -static inline int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) { return 0; } -static inline void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) { } +static inline int __init f2fs_init_xattr_cache(void) { return 0; } +static inline void f2fs_destroy_xattr_cache(void) { } #endif #ifdef CONFIG_F2FS_FS_SECURITY -- Gitee From bce70b0e0875b1dcdb1640e8d6e073e3e3a2dc14 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 31 Dec 2025 02:53:24 +0800 Subject: [PATCH 0851/1449] f2fs: fix to detect recoverable inode during dryrun of find_fsync_dnodes() ANBZ: #35228 commit f7b8851c541ed30154819e0f7012901732b782ec stable. commit 68d05693f8c031257a0822464366e1c2a239a512 upstream. mkfs.f2fs -f /dev/vdd mount /dev/vdd /mnt/f2fs touch /mnt/f2fs/foo sync # avoid CP_UMOUNT_FLAG in last f2fs_checkpoint.ckpt_flags touch /mnt/f2fs/bar f2fs_io fsync /mnt/f2fs/bar f2fs_io shutdown 2 /mnt/f2fs umount /mnt/f2fs blockdev --setro /dev/vdd mount /dev/vdd /mnt/f2fs mount: /mnt/f2fs: WARNING: source write-protected, mounted read-only. For the case if we create and fsync a new inode before sudden power-cut, without norecovery or disable_roll_forward mount option, the following mount will succeed w/o recovering last fsynced inode. The problem here is that we only check inode_list list after find_fsync_dnodes() in f2fs_recover_fsync_data() to find out whether there is recoverable data in the iamge, but there is a missed case, if last fsynced inode is not existing in last checkpoint, then, we will fail to get its inode due to nat of inode node is not existing in last checkpoint, so the inode won't be linked in inode_list. Let's detect such case in dyrun mode to fix this issue. After this change, mount will fail as expected below: mount: /mnt/f2fs: cannot mount /dev/vdd read-only. dmesg(1) may have more information after failed mount system call. demsg: F2FS-fs (vdd): Need to recover fsync data, but write access unavailable, please try mount w/ disable_roll_forward or norecovery Cc: stable@kernel.org Fixes: 6781eabba1bd ("f2fs: give -EINVAL for norecovery and rw mount") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ folio => page ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/recovery.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 223fcdf785f7..332996ff5cce 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -404,7 +404,7 @@ static int sanity_check_node_chain(struct f2fs_sb_info *sbi, block_t blkaddr, } static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, - bool check_only) + bool check_only, bool *new_inode) { struct curseg_info *curseg; struct page *page = NULL; @@ -451,16 +451,19 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, quota_inode = true; } - /* - * CP | dnode(F) | inode(DF) - * For this case, we should not give up now. - */ entry = add_fsync_inode(sbi, head, ino_of_node(page), quota_inode); if (IS_ERR(entry)) { err = PTR_ERR(entry); - if (err == -ENOENT) + /* + * CP | dnode(F) | inode(DF) + * For this case, we should not give up now. + */ + if (err == -ENOENT) { + if (check_only) + *new_inode = true; goto next; + } f2fs_put_page(page, 1); break; } @@ -863,6 +866,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) unsigned long s_flags = sbi->sb->s_flags; bool need_writecp = false; bool fix_curseg_write_pointer = false; + bool new_inode = false; if (is_sbi_flag_set(sbi, SBI_IS_WRITABLE)) f2fs_info(sbi, "recover fsync data on readonly fs"); @@ -875,8 +879,8 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) f2fs_down_write(&sbi->cp_global_sem); /* step #1: find fsynced inode numbers */ - err = find_fsync_dnodes(sbi, &inode_list, check_only); - if (err || list_empty(&inode_list)) + err = find_fsync_dnodes(sbi, &inode_list, check_only, &new_inode); + if (err < 0 || (list_empty(&inode_list) && (!check_only || !new_inode))) goto skip; if (check_only) { -- Gitee From 22663527b64da29981ab72a232bd93c7ebd600cb Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Tue, 6 Jan 2026 00:48:58 +0800 Subject: [PATCH 0852/1449] media: verisilicon: Store chroma and motion vectors offset ANBZ: #35228 commit 381a387ececd531dd49df87b388be5d4666ba6d2 stable. commit 545bf944f978b7468d3a6bd668d9ff6953bc542e upstream. Store computed values of chroma and motion vectors offset because they depends on width and height values which change if the resolution change. Signed-off-by: Benjamin Gaignard Reviewed-by: Andrzej Pietrasiewicz CC: Ezequiel Garcia CC: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: 19c286b75507 ("media: verisilicon: Fix CPU stalls on G2 bus error") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/verisilicon/hantro.h | 2 ++ drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 77aee9489516..e9e15746f0aa 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -328,6 +328,8 @@ struct hantro_vp9_decoded_buffer_info { /* Info needed when the decoded frame serves as a reference frame. */ unsigned short width; unsigned short height; + size_t chroma_offset; + size_t mv_offset; u32 bit_depth : 4; }; diff --git a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c index 6fc4b555517f..6db1c32fce4d 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c @@ -158,9 +158,11 @@ static void config_output(struct hantro_ctx *ctx, chroma_addr = luma_addr + chroma_offset(ctx, dec_params); hantro_write_addr(ctx->dev, G2_OUT_CHROMA_ADDR, chroma_addr); + dst->vp9.chroma_offset = chroma_offset(ctx, dec_params); mv_addr = luma_addr + mv_offset(ctx, dec_params); hantro_write_addr(ctx->dev, G2_OUT_MV_ADDR, mv_addr); + dst->vp9.mv_offset = mv_offset(ctx, dec_params); } struct hantro_vp9_ref_reg { @@ -195,7 +197,7 @@ static void config_ref(struct hantro_ctx *ctx, luma_addr = hantro_get_dec_buf_addr(ctx, &buf->base.vb.vb2_buf); hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr); - chroma_addr = luma_addr + chroma_offset(ctx, dec_params); + chroma_addr = luma_addr + buf->vp9.chroma_offset; hantro_write_addr(ctx->dev, ref_reg->c_base, chroma_addr); } @@ -238,7 +240,7 @@ static void config_ref_registers(struct hantro_ctx *ctx, config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts); mv_addr = hantro_get_dec_buf_addr(ctx, &mv_ref->base.vb.vb2_buf) + - mv_offset(ctx, dec_params); + mv_ref->vp9.mv_offset; hantro_write_addr(ctx->dev, G2_REF_MV_ADDR(0), mv_addr); hantro_reg_write(ctx->dev, &vp9_last_sign_bias, -- Gitee From ba9bb8a7e4891d65439eed4a6b158987c48dfd32 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Tue, 6 Jan 2026 00:48:59 +0800 Subject: [PATCH 0853/1449] media: verisilicon: g2: Use common helpers to compute chroma and mv offsets ANBZ: #35228 commit 5acc3c7d3c4c0dcaa091fedca59e2c17394653a1 stable. commit 3eeaee737dcee3c32e256870dbc2687a2a6fe970 upstream. HEVC and VP9 are running on the same hardware and share the same chroma and motion vectors offset constraint. Create common helpers functions for these computation. Source and destination buffer height may not be the same because alignment constraint are different so use destination height to compute chroma offset because we target this buffer as hardware output. To be able to use the helpers in both VP9 HEVC code remove dec_params and use context->bit_depth instead. Signed-off-by: Benjamin Gaignard Reviewed-by: Andrzej Pietrasiewicz CC: Ezequiel Garcia CC: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: 19c286b75507 ("media: verisilicon: Fix CPU stalls on G2 bus error") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../media/platform/verisilicon/hantro_g2.c | 14 ++++++++++ .../platform/verisilicon/hantro_g2_hevc_dec.c | 18 ++----------- .../platform/verisilicon/hantro_g2_vp9_dec.c | 26 +++---------------- .../media/platform/verisilicon/hantro_hw.h | 3 +++ 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_g2.c b/drivers/media/platform/verisilicon/hantro_g2.c index ee5f14c5f8f2..b880a6849d58 100644 --- a/drivers/media/platform/verisilicon/hantro_g2.c +++ b/drivers/media/platform/verisilicon/hantro_g2.c @@ -8,6 +8,8 @@ #include "hantro_hw.h" #include "hantro_g2_regs.h" +#define G2_ALIGN 16 + void hantro_g2_check_idle(struct hantro_dev *vpu) { int i; @@ -42,3 +44,15 @@ irqreturn_t hantro_g2_irq(int irq, void *dev_id) return IRQ_HANDLED; } + +size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx) +{ + return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8; +} + +size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx) +{ + size_t cr_offset = hantro_g2_chroma_offset(ctx); + + return ALIGN((cr_offset * 3) / 2, G2_ALIGN); +} diff --git a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c index d9da321af20e..12e049b4cc60 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c @@ -8,20 +8,6 @@ #include "hantro_hw.h" #include "hantro_g2_regs.h" -#define G2_ALIGN 16 - -static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx) -{ - return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8; -} - -static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx) -{ - size_t cr_offset = hantro_hevc_chroma_offset(ctx); - - return ALIGN((cr_offset * 3) / 2, G2_ALIGN); -} - static void prepare_tile_info_buffer(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; @@ -395,8 +381,8 @@ static int set_ref(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_dst; struct hantro_decoded_buffer *dst; - size_t cr_offset = hantro_hevc_chroma_offset(ctx); - size_t mv_offset = hantro_hevc_motion_vectors_offset(ctx); + size_t cr_offset = hantro_g2_chroma_offset(ctx); + size_t mv_offset = hantro_g2_motion_vectors_offset(ctx); u32 max_ref_frames; u16 dpb_longterm_e; static const struct hantro_reg cur_poc[] = { diff --git a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c index 6db1c32fce4d..342e543dee4c 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c @@ -16,8 +16,6 @@ #include "hantro_vp9.h" #include "hantro_g2_regs.h" -#define G2_ALIGN 16 - enum hantro_ref_frames { INTRA_FRAME = 0, LAST_FRAME = 1, @@ -90,22 +88,6 @@ static int start_prepare_run(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_ return 0; } -static size_t chroma_offset(const struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp9_frame *dec_params) -{ - int bytes_per_pixel = dec_params->bit_depth == 8 ? 1 : 2; - - return ctx->src_fmt.width * ctx->src_fmt.height * bytes_per_pixel; -} - -static size_t mv_offset(const struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp9_frame *dec_params) -{ - size_t cr_offset = chroma_offset(ctx, dec_params); - - return ALIGN((cr_offset * 3) / 2, G2_ALIGN); -} - static struct hantro_decoded_buffer * get_ref_buf(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp) { @@ -156,13 +138,13 @@ static void config_output(struct hantro_ctx *ctx, luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf); hantro_write_addr(ctx->dev, G2_OUT_LUMA_ADDR, luma_addr); - chroma_addr = luma_addr + chroma_offset(ctx, dec_params); + chroma_addr = luma_addr + hantro_g2_chroma_offset(ctx); hantro_write_addr(ctx->dev, G2_OUT_CHROMA_ADDR, chroma_addr); - dst->vp9.chroma_offset = chroma_offset(ctx, dec_params); + dst->vp9.chroma_offset = hantro_g2_chroma_offset(ctx); - mv_addr = luma_addr + mv_offset(ctx, dec_params); + mv_addr = luma_addr + hantro_g2_motion_vectors_offset(ctx); hantro_write_addr(ctx->dev, G2_OUT_MV_ADDR, mv_addr); - dst->vp9.mv_offset = mv_offset(ctx, dec_params); + dst->vp9.mv_offset = hantro_g2_motion_vectors_offset(ctx); } struct hantro_vp9_ref_reg { diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h index 7f33f7b07ce4..c7a2a20c70b7 100644 --- a/drivers/media/platform/verisilicon/hantro_hw.h +++ b/drivers/media/platform/verisilicon/hantro_hw.h @@ -519,6 +519,9 @@ hantro_av1_mv_size(unsigned int width, unsigned int height) return ALIGN(num_sbs * 384, 16) * 2 + 512; } +size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx); +size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx); + int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx); void hantro_mpeg2_dec_copy_qtable(u8 *qtable, -- Gitee From 818ab85f15ee350bf1cfe841c7ebe3b2bdd88cb3 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 6 Jan 2026 00:49:00 +0800 Subject: [PATCH 0854/1449] media: verisilicon: Fix CPU stalls on G2 bus error ANBZ: #35228 commit 98a5af4a8eaede8bd2a03caf5a44728f50638645 stable. commit 19c286b755072a22a063052f530a6b1fac8a1f63 upstream. In some seek stress tests, we are getting IRQ from the G2 decoder where the dec_bus_int and the dec_e bits are high, meaning the decoder is still running despite the error. Fix this by reworking the IRQ handler to only finish the job once we have reached completion and move the software reset to when our software watchdog triggers. This way, we let the hardware continue on errors when it did not self reset and in worse case scenario the hardware timeout will automatically stop it. The actual error will be fixed in a follow up patch. Fixes: 3385c514ecc5a ("media: hantro: Convert imx8m_vpu_g2_irq to helper") Cc: stable@vger.kernel.org Reviewed-by: Benjamin Gaignard Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../media/platform/verisilicon/hantro_g2.c | 88 +++++++++++++++---- .../platform/verisilicon/hantro_g2_hevc_dec.c | 2 - .../platform/verisilicon/hantro_g2_regs.h | 13 +++ .../platform/verisilicon/hantro_g2_vp9_dec.c | 2 - .../media/platform/verisilicon/hantro_hw.h | 1 + .../media/platform/verisilicon/imx8m_vpu_hw.c | 2 + 6 files changed, 85 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_g2.c b/drivers/media/platform/verisilicon/hantro_g2.c index b880a6849d58..85fa2704a732 100644 --- a/drivers/media/platform/verisilicon/hantro_g2.c +++ b/drivers/media/platform/verisilicon/hantro_g2.c @@ -5,43 +5,93 @@ * Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz */ +#include #include "hantro_hw.h" #include "hantro_g2_regs.h" #define G2_ALIGN 16 -void hantro_g2_check_idle(struct hantro_dev *vpu) +static bool hantro_g2_active(struct hantro_ctx *ctx) { - int i; - - for (i = 0; i < 3; i++) { - u32 status; - - /* Make sure the VPU is idle */ - status = vdpu_read(vpu, G2_REG_INTERRUPT); - if (status & G2_REG_INTERRUPT_DEC_E) { - dev_warn(vpu->dev, "device still running, aborting"); - status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS; - vdpu_write(vpu, status, G2_REG_INTERRUPT); - } + struct hantro_dev *vpu = ctx->dev; + u32 status; + + status = vdpu_read(vpu, G2_REG_INTERRUPT); + + return (status & G2_REG_INTERRUPT_DEC_E); +} + +/** + * hantro_g2_reset: + * @ctx: the hantro context + * + * Emulates a reset using Hantro abort function. Failing this procedure would + * results in programming a running IP which leads to CPU hang. + * + * Using a hard reset procedure instead is prefferred. + */ +void hantro_g2_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + u32 status; + + status = vdpu_read(vpu, G2_REG_INTERRUPT); + if (status & G2_REG_INTERRUPT_DEC_E) { + dev_warn_ratelimited(vpu->dev, "device still running, aborting"); + status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS; + vdpu_write(vpu, status, G2_REG_INTERRUPT); + + do { + mdelay(1); + } while (hantro_g2_active(ctx)); } } irqreturn_t hantro_g2_irq(int irq, void *dev_id) { struct hantro_dev *vpu = dev_id; - enum vb2_buffer_state state; u32 status; status = vdpu_read(vpu, G2_REG_INTERRUPT); - state = (status & G2_REG_INTERRUPT_DEC_RDY_INT) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - vdpu_write(vpu, 0, G2_REG_INTERRUPT); - vdpu_write(vpu, G2_REG_CONFIG_DEC_CLK_GATE_E, G2_REG_CONFIG); + if (!(status & G2_REG_INTERRUPT_DEC_IRQ)) + return IRQ_NONE; + + hantro_reg_write(vpu, &g2_dec_irq, 0); + hantro_reg_write(vpu, &g2_dec_int_stat, 0); + hantro_reg_write(vpu, &g2_clk_gate_e, 1); + + if (status & G2_REG_INTERRUPT_DEC_RDY_INT) { + hantro_irq_done(vpu, VB2_BUF_STATE_DONE); + return IRQ_HANDLED; + } + + if (status & G2_REG_INTERRUPT_DEC_ABORT_INT) { + /* disabled on abort, though lets be safe and handle it */ + dev_warn_ratelimited(vpu->dev, "decode operation aborted."); + return IRQ_HANDLED; + } + + if (status & G2_REG_INTERRUPT_DEC_LAST_SLICE_INT) + dev_warn_ratelimited(vpu->dev, "not all macroblocks were decoded."); + + if (status & G2_REG_INTERRUPT_DEC_BUS_INT) + dev_warn_ratelimited(vpu->dev, "bus error detected."); + + if (status & G2_REG_INTERRUPT_DEC_ERROR_INT) + dev_warn_ratelimited(vpu->dev, "decode error detected."); + + if (status & G2_REG_INTERRUPT_DEC_TIMEOUT) + dev_warn_ratelimited(vpu->dev, "frame decode timed out."); - hantro_irq_done(vpu, state); + /** + * If the decoding haven't stopped, let it continue. The hardware timeout + * will trigger if it is trully stuck. + */ + if (status & G2_REG_INTERRUPT_DEC_E) + return IRQ_HANDLED; + hantro_irq_done(vpu, VB2_BUF_STATE_ERROR); return IRQ_HANDLED; } diff --git a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c index 12e049b4cc60..a701748bcf2e 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c @@ -578,8 +578,6 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; int ret; - hantro_g2_check_idle(vpu); - /* Prepare HEVC decoder context. */ ret = hantro_hevc_dec_prepare_run(ctx); if (ret) diff --git a/drivers/media/platform/verisilicon/hantro_g2_regs.h b/drivers/media/platform/verisilicon/hantro_g2_regs.h index 82606783591a..e238b1a308bb 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_regs.h +++ b/drivers/media/platform/verisilicon/hantro_g2_regs.h @@ -22,7 +22,14 @@ #define G2_REG_VERSION G2_SWREG(0) #define G2_REG_INTERRUPT G2_SWREG(1) +#define G2_REG_INTERRUPT_DEC_LAST_SLICE_INT BIT(19) +#define G2_REG_INTERRUPT_DEC_TIMEOUT BIT(18) +#define G2_REG_INTERRUPT_DEC_ERROR_INT BIT(16) +#define G2_REG_INTERRUPT_DEC_BUF_INT BIT(14) +#define G2_REG_INTERRUPT_DEC_BUS_INT BIT(13) #define G2_REG_INTERRUPT_DEC_RDY_INT BIT(12) +#define G2_REG_INTERRUPT_DEC_ABORT_INT BIT(11) +#define G2_REG_INTERRUPT_DEC_IRQ BIT(8) #define G2_REG_INTERRUPT_DEC_ABORT_E BIT(5) #define G2_REG_INTERRUPT_DEC_IRQ_DIS BIT(4) #define G2_REG_INTERRUPT_DEC_E BIT(0) @@ -35,6 +42,9 @@ #define BUS_WIDTH_128 2 #define BUS_WIDTH_256 3 +#define g2_dec_int_stat G2_DEC_REG(1, 11, 0xf) +#define g2_dec_irq G2_DEC_REG(1, 8, 0x1) + #define g2_strm_swap G2_DEC_REG(2, 28, 0xf) #define g2_strm_swap_old G2_DEC_REG(2, 27, 0x1f) #define g2_pic_swap G2_DEC_REG(2, 22, 0x1f) @@ -225,6 +235,9 @@ #define vp9_filt_level_seg5 G2_DEC_REG(19, 8, 0x3f) #define vp9_quant_seg5 G2_DEC_REG(19, 0, 0xff) +#define g2_timemout_override_e G2_DEC_REG(45, 31, 0x1) +#define g2_timemout_cycles G2_DEC_REG(45, 0, 0x7fffffff) + #define hevc_cur_poc_00 G2_DEC_REG(46, 24, 0xff) #define hevc_cur_poc_01 G2_DEC_REG(46, 16, 0xff) #define hevc_cur_poc_02 G2_DEC_REG(46, 8, 0xff) diff --git a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c index 342e543dee4c..70e7cedc33b8 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c @@ -893,8 +893,6 @@ int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx) struct vb2_v4l2_buffer *dst; int ret; - hantro_g2_check_idle(ctx->dev); - ret = start_prepare_run(ctx, &decode_params); if (ret) { hantro_end_prepare_run(ctx); diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h index c7a2a20c70b7..d71d00ef6d32 100644 --- a/drivers/media/platform/verisilicon/hantro_hw.h +++ b/drivers/media/platform/verisilicon/hantro_hw.h @@ -541,6 +541,7 @@ void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx); int hantro_vp9_dec_init(struct hantro_ctx *ctx); void hantro_vp9_dec_exit(struct hantro_ctx *ctx); void hantro_g2_check_idle(struct hantro_dev *vpu); +void hantro_g2_reset(struct hantro_ctx *ctx); irqreturn_t hantro_g2_irq(int irq, void *dev_id); #endif /* HANTRO_HW_H_ */ diff --git a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c index f850d8bddef6..74fd985a8aad 100644 --- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c +++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c @@ -312,11 +312,13 @@ static const struct hantro_codec_ops imx8mq_vpu_g1_codec_ops[] = { static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = { [HANTRO_MODE_HEVC_DEC] = { .run = hantro_g2_hevc_dec_run, + .reset = hantro_g2_reset, .init = hantro_hevc_dec_init, .exit = hantro_hevc_dec_exit, }, [HANTRO_MODE_VP9_DEC] = { .run = hantro_g2_vp9_dec_run, + .reset = hantro_g2_reset, .done = hantro_g2_vp9_dec_done, .init = hantro_vp9_dec_init, .exit = hantro_vp9_dec_exit, -- Gitee From 39456c603f84cae87001102f71f0920cfc142a71 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 6 Jan 2026 01:52:10 +0800 Subject: [PATCH 0855/1449] mm/balloon_compaction: we cannot have isolated pages in the balloon list ANBZ: #35228 commit 3339e058b80d5f2920a89ebdb8ac6714f59f59e4 stable. commit fb05f992b6bbb4702307d96f00703ee637b24dbf upstream. Patch series "mm/migration: rework movable_ops page migration (part 1)", v2. In the future, as we decouple "struct page" from "struct folio", pages that support "non-lru page migration" -- movable_ops page migration such as memory balloons and zsmalloc -- will no longer be folios. They will not have ->mapping, ->lru, and likely no refcount and no page lock. But they will have a type and flags Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/balloon_compaction.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c index b04f315eb560..c708f553897f 100644 --- a/mm/balloon_compaction.c +++ b/mm/balloon_compaction.c @@ -93,12 +93,6 @@ size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info, if (!trylock_page(page)) continue; - if (IS_ENABLED(CONFIG_BALLOON_COMPACTION) && - PageIsolated(page)) { - /* raced with isolation */ - unlock_page(page); - continue; - } balloon_page_delete(page); __count_vm_event(BALLOON_DEFLATE); list_add(&page->lru, pages); -- Gitee From 4ccdf6bd06af6cad839c58298d5bea76bf228b5a Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Jan 2026 12:52:11 -0500 Subject: [PATCH 0856/1449] mm/balloon_compaction: convert balloon_page_delete() to balloon_page_finalize() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 47dee8b41fd76f68f63df432cea1523239fd7a5b stable. commit 15504b1163007bbfbd9a63460d5c14737c16e96d upstream. [Backport Note] In balloon_page_list_dequeue_cont(), we still got balloon_page_delete. Here we change to balloon_page_finalize(). Let's move the removal of the page from the balloon list into the single caller, to remove the dependency on the PG_isolated flag and clarify locking requirements. Note that for now, balloon_page_delete() was used on two paths: (1) Removing a page from the balloon for deflation through balloon_page_list_dequeue() (2) Removing an isolated page from the balloon for migration in the per-driver migration handlers. Isolated pages were already removed from the balloon list during isolation. So instead of relying on the flag, we can just distinguish both cases directly and handle it accordingly in the caller. We'll shuffle the operations a bit such that they logically make more sense (e.g., remove from the list before clearing flags). In balloon migration functions we can now move the balloon_page_finalize() out of the balloon lock and perform the finalization just before dropping the balloon reference. Document that the page lock is currently required when modifying the movability aspects of a page; hopefully we can soon decouple this from the page lock. Link: https://lkml.kernel.org/r/20250704102524.326966-3-david@redhat.com Signed-off-by: David Hildenbrand Reviewed-by: Lorenzo Stoakes Cc: Alistair Popple Cc: Al Viro Cc: Arnd Bergmann Cc: Brendan Jackman Cc: Byungchul Park Cc: Chengming Zhou Cc: Christian Brauner Cc: Christophe Leroy Cc: Eugenio Pé rez Cc: Greg Kroah-Hartman Cc: Gregory Price Cc: Harry Yoo Cc: "Huang, Ying" Cc: Jan Kara Cc: Jason Gunthorpe Cc: Jason Wang Cc: Jerrin Shaji George Cc: Johannes Weiner Cc: John Hubbard Cc: Jonathan Corbet Cc: Joshua Hahn Cc: Liam Howlett Cc: Madhavan Srinivasan Cc: Mathew Brost Cc: Matthew Wilcox (Oracle) Cc: Miaohe Lin Cc: Michael Ellerman Cc: "Michael S. Tsirkin" Cc: Michal Hocko Cc: Mike Rapoport Cc: Minchan Kim Cc: Naoya Horiguchi Cc: Nicholas Piggin Cc: Oscar Salvador Cc: Peter Xu Cc: Qi Zheng Cc: Rakie Kim Cc: Rik van Riel Cc: Sergey Senozhatsky Cc: Shakeel Butt Cc: Suren Baghdasaryan Cc: Vlastimil Babka Cc: Xuan Zhuo Cc: xu xin Cc: Zi Yan Signed-off-by: Andrew Morton Stable-dep-of: 0da2ba35c0d5 ("powerpc/pseries/cmm: adjust BALLOON_MIGRATE when migrating pages") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/powerpc/platforms/pseries/cmm.c | 2 +- drivers/misc/vmw_balloon.c | 3 +- drivers/virtio/virtio_balloon.c | 4 +-- include/linux/balloon_compaction.h | 43 +++++++++++----------------- mm/balloon_compaction.c | 6 ++-- 5 files changed, 23 insertions(+), 35 deletions(-) diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index 1065f08cdcb9..f4c9a8753fff 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -532,7 +532,6 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info, spin_lock_irqsave(&b_dev_info->pages_lock, flags); balloon_page_insert(b_dev_info, newpage); - balloon_page_delete(page); b_dev_info->isolated_pages--; spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); @@ -542,6 +541,7 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info, */ plpar_page_set_active(page); + balloon_page_finalize(page); /* balloon page list reference */ put_page(page); diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index c817d8c21641..6653fc53c951 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -1778,8 +1778,7 @@ static int vmballoon_migratepage(struct balloon_dev_info *b_dev_info, * @pages_lock . We keep holding @comm_lock since we will need it in a * second. */ - balloon_page_delete(page); - + balloon_page_finalize(page); put_page(page); /* Inflate */ diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 33e3d9adf9b3..525c58645ddd 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -1074,9 +1074,6 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, tell_host(vb, vb->inflate_vq); /* balloon's page migration 2nd step -- deflate "page" */ - spin_lock_irqsave(&vb_dev_info->pages_lock, flags); - balloon_page_delete(page); - spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags); vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_TELL_64BIT)) set_page_pfns_64(vb, vb->pfns_buf, page); @@ -1086,6 +1083,7 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, mutex_unlock(&vb->balloon_lock); + balloon_page_finalize(page); put_page(page); /* balloon reference */ return MIGRATEPAGE_SUCCESS; diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h index cf01e0b3b01b..c1b7d3982f0a 100644 --- a/include/linux/balloon_compaction.h +++ b/include/linux/balloon_compaction.h @@ -107,27 +107,6 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, list_add(&page->lru, &balloon->pages); } -/* - * balloon_page_delete - delete a page from balloon's page list and clear - * the page->private assignement accordingly. - * @page : page to be released from balloon's page list - * - * Caller must ensure the page is locked and the spin_lock protecting balloon - * pages list is held before deleting a page from the balloon device. - */ -static inline void balloon_page_delete(struct page *page) -{ - __ClearPageOffline(page); - __ClearPageMovable(page); - set_page_private(page, 0); - /* - * No touch page.lru field once @page has been isolated - * because VM is using the field. - */ - if (!PageIsolated(page)) - list_del(&page->lru); -} - /* * balloon_page_device - get the b_dev_info descriptor for the balloon device * that enqueues the given page. @@ -151,12 +130,6 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon, list_add(&page->lru, &balloon->pages); } -static inline void balloon_page_delete(struct page *page) -{ - __ClearPageOffline(page); - list_del(&page->lru); -} - static inline gfp_t balloon_mapping_gfp_mask(void) { return GFP_HIGHUSER; @@ -164,6 +137,22 @@ static inline gfp_t balloon_mapping_gfp_mask(void) #endif /* CONFIG_BALLOON_COMPACTION */ +/* + * balloon_page_finalize - prepare a balloon page that was removed from the + * balloon list for release to the page allocator + * @page: page to be released to the page allocator + * + * Caller must ensure that the page is locked. + */ +static inline void balloon_page_finalize(struct page *page) +{ + if (IS_ENABLED(CONFIG_BALLOON_COMPACTION)) { + __ClearPageMovable(page); + set_page_private(page, 0); + } + __ClearPageOffline(page); +} + /* * balloon_page_push - insert a page into a page list. * @head : pointer to list diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c index c708f553897f..ca2b54cab80f 100644 --- a/mm/balloon_compaction.c +++ b/mm/balloon_compaction.c @@ -93,7 +93,8 @@ size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info, if (!trylock_page(page)) continue; - balloon_page_delete(page); + list_del(&page->lru); + balloon_page_finalize(page); __count_vm_event(BALLOON_DEFLATE); list_add(&page->lru, pages); unlock_page(page); @@ -228,7 +229,8 @@ size_t balloon_page_list_dequeue_cont(struct balloon_dev_info *b_dev_info, else break; } - balloon_page_delete(page); + list_del(&page->lru); + balloon_page_finalize(page); __count_vm_event(BALLOON_DEFLATE); list_add(&page->lru, pages); unlock_page(page); -- Gitee From 8ba013a0f2bb2948465fddc5889caf926847afa5 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Jan 2026 12:52:12 -0500 Subject: [PATCH 0857/1449] powerpc/pseries/cmm: adjust BALLOON_MIGRATE when migrating pages ANBZ: #35228 commit 2f3139eaae9905d723674e53dfdd970e9c92fa6b stable. commit 0da2ba35c0d532ca0fe7af698b17d74c4d084b9a upstream. Let's properly adjust BALLOON_MIGRATE like the other drivers. Note that the INFLATE/DEFLATE events are triggered from the core when enqueueing/dequeueing pages. This was found by code inspection. Link: https://lkml.kernel.org/r/20251021100606.148294-3-david@redhat.com Fixes: fe030c9b85e6 ("powerpc/pseries/cmm: Implement balloon compaction") Signed-off-by: David Hildenbrand Reviewed-by: Ritesh Harjani (IBM) Cc: Christophe Leroy Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/powerpc/platforms/pseries/cmm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index f4c9a8753fff..851670ad515a 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -532,6 +532,7 @@ static int cmm_migratepage(struct balloon_dev_info *b_dev_info, spin_lock_irqsave(&b_dev_info->pages_lock, flags); balloon_page_insert(b_dev_info, newpage); + __count_vm_event(BALLOON_MIGRATE); b_dev_info->isolated_pages--; spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); -- Gitee From 486f906a5f7efacea0f3e4a6b18a058711c709b5 Mon Sep 17 00:00:00 2001 From: Dongli Zhang Date: Wed, 31 Dec 2025 23:05:34 +0800 Subject: [PATCH 0858/1449] KVM: nVMX: Immediately refresh APICv controls as needed on nested VM-Exit ANBZ: #35228 commit 37304368a2a94db2ba3bf5a0aaf9aca7705ca814 stable. commit 29763138830916f46daaa50e83e7f4f907a3236b upstream. If an APICv status updated was pended while L2 was active, immediately refresh vmcs01's controls instead of pending KVM_REQ_APICV_UPDATE as kvm_vcpu_update_apicv() only calls into vendor code if a change is necessary. E.g. if APICv is inhibited, and then activated while L2 is running: kvm_vcpu_update_apicv() | -> __kvm_vcpu_update_apicv() | -> apic->apicv_active = true | -> vmx_refresh_apicv_exec_ctrl() | -> vmx->nested.update_vmcs01_apicv_status = true | -> return Then L2 exits to L1: __nested_vmx_vmexit() | -> kvm_make_request(KVM_REQ_APICV_UPDATE) vcpu_enter_guest(): KVM_REQ_APICV_UPDATE -> kvm_vcpu_update_apicv() | -> __kvm_vcpu_update_apicv() | -> return // because if (apic->apicv_active == activate) Reported-by: Chao Gao Closes: https://lore.kernel.org/all/aQ2jmnN8wUYVEawF@intel.com Fixes: 7c69661e225c ("KVM: nVMX: Defer APICv updates while L2 is active until L1 is active") Cc: stable@vger.kernel.org Signed-off-by: Dongli Zhang [sean: write changelog] Link: https://patch.msgid.link/20251205231913.441872-3-seanjc@google.com Signed-off-by: Sean Christopherson [ exported vmx_refresh_apicv_exec_ctrl() and added declaration in vmx.h ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/vmx/nested.c | 2 +- arch/x86/kvm/vmx/vmx.c | 2 +- arch/x86/kvm/vmx/vmx.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 684ba76379d7..c4e665d4bf6d 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4908,7 +4908,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, if (vmx->nested.update_vmcs01_apicv_status) { vmx->nested.update_vmcs01_apicv_status = false; - kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); + vmx_refresh_apicv_exec_ctrl(vcpu); } if (vmx->nested.update_vmcs01_hwapic_isr) { diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e463c668b1b1..71145b72a8a5 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4470,7 +4470,7 @@ static u32 vmx_vmexit_ctrl(void) ~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | VM_EXIT_LOAD_IA32_EFER); } -static void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) +void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index e65d98493e35..61133d0ccc9b 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -395,6 +395,7 @@ void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); +void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu); void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu); bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu); -- Gitee From e05b03e490c0c873365290f4563e73f971d8128e Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Tue, 6 Jan 2026 05:18:07 +0800 Subject: [PATCH 0859/1449] media: amphion: Add a frame flush mode for decoder ANBZ: #35228 commit 93f537ffaece796c864b4797cab9ec938c70bf19 stable. commit 9ea16ba6eaf93f25f61855751f71e2e701709ddf upstream. By default the amphion decoder will pre-parse 3 frames before starting to decode the first frame. Alternatively, a block of flush padding data can be appended to the frame, which will ensure that the decoder can start decoding immediately after parsing the flush padding data, thus potentially reducing decoding latency. This mode was previously only enabled, when the display delay was set to 0. Allow the user to manually toggle the use of that mode via a module parameter called low_latency, which enables the mode without changing the display order. Signed-off-by: Ming Qian Reviewed-by: Nicolas Dufresne Signed-off-by: Sebastian Fricke Signed-off-by: Hans Verkuil Stable-dep-of: 634c2cd17bd0 ("media: amphion: Remove vpu_vb_is_codecconfig") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/amphion/vpu_malone.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index d3425de7bccd..4fbf179d98dc 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -25,6 +25,10 @@ #include "vpu_imx8q.h" #include "vpu_malone.h" +static bool low_latency; +module_param(low_latency, bool, 0644); +MODULE_PARM_DESC(low_latency, "Set low latency frame flush mode: 0 (disable) or 1 (enable)"); + #define CMD_SIZE 25600 #define MSG_SIZE 25600 #define CODEC_SIZE 0x1000 @@ -1567,7 +1571,15 @@ static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer __iomem *str vpu_malone_update_wptr(str_buf, wptr); - if (disp_imm && !vpu_vb_is_codecconfig(vbuf)) { + /* + * Enable the low latency flush mode if display delay is set to 0 + * or the low latency frame flush mode if it is set to 1. + * The low latency flush mode requires some padding data to be appended to each frame, + * but there must not be any padding data between the sequence header and the frame. + * This module is currently only supported for the H264 and HEVC formats, + * for other formats, vpu_malone_add_scode() will return 0. + */ + if ((disp_imm || low_latency) && !vpu_vb_is_codecconfig(vbuf)) { ret = vpu_malone_add_scode(inst->core->iface, inst->id, &inst->stream_buffer, -- Gitee From a3e42bbbda71ccf188a2b581ea6790a3ebcac8ed Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 6 Jan 2026 05:18:08 +0800 Subject: [PATCH 0860/1449] media: amphion: Make some vpu_v4l2 functions static ANBZ: #35228 commit e42ccf472feb14f08547fa40956056a3658efbe0 stable. commit 5d1e54bb4dc6741284a3ed587e994308ddee2f16 upstream. Some functions defined in vpu_v4l2.c are never used outside of that compilation unit. Make them static. Signed-off-by: Laurent Pinchart Reviewed-by: Ming Qian Signed-off-by: Hans Verkuil Stable-dep-of: 634c2cd17bd0 ("media: amphion: Remove vpu_vb_is_codecconfig") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/amphion/vpu_v4l2.c | 12 +++++++++--- drivers/media/platform/amphion/vpu_v4l2.h | 8 -------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 2bdfdcd324a0..26d05e64e9e5 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -24,6 +24,11 @@ #include "vpu_msgs.h" #include "vpu_helpers.h" +static char *vpu_type_name(u32 type) +{ + return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture"; +} + void vpu_inst_lock(struct vpu_inst *inst) { mutex_lock(&inst->lock); @@ -42,7 +47,7 @@ dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no) vb->planes[plane_no].data_offset; } -unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no) +static unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no) { if (plane_no >= vb->num_planes) return 0; @@ -74,7 +79,7 @@ void vpu_v4l2_set_error(struct vpu_inst *inst) vpu_inst_unlock(inst); } -int vpu_notify_eos(struct vpu_inst *inst) +static int vpu_notify_eos(struct vpu_inst *inst) { static const struct v4l2_event ev = { .id = 0, @@ -546,7 +551,8 @@ static void vpu_vb2_buf_finish(struct vb2_buffer *vb) call_void_vop(inst, on_queue_empty, q->type); } -void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state) +static void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, + enum vb2_buffer_state state) { struct vb2_v4l2_buffer *buf; diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h index 60f43056a7a2..064f61773f62 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.h +++ b/drivers/media/platform/amphion/vpu_v4l2.h @@ -25,15 +25,12 @@ void vpu_skip_frame(struct vpu_inst *inst, int count); struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence); struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx); void vpu_v4l2_set_error(struct vpu_inst *inst); -int vpu_notify_eos(struct vpu_inst *inst); int vpu_notify_source_change(struct vpu_inst *inst); int vpu_set_last_buffer_dequeued(struct vpu_inst *inst, bool eos); -void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state); int vpu_get_num_buffers(struct vpu_inst *inst, u32 type); bool vpu_is_source_empty(struct vpu_inst *inst); dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no); -unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no); static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type) { if (V4L2_TYPE_IS_OUTPUT(type)) @@ -42,11 +39,6 @@ static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type) return &inst->cap_format; } -static inline char *vpu_type_name(u32 type) -{ - return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture"; -} - static inline int vpu_vb_is_codecconfig(struct vb2_v4l2_buffer *vbuf) { #ifdef V4L2_BUF_FLAG_CODECCONFIG -- Gitee From 258a377fee00c2a0e31c5ec0ea8884ec5eb058d4 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Tue, 6 Jan 2026 05:18:09 +0800 Subject: [PATCH 0861/1449] media: amphion: Remove vpu_vb_is_codecconfig ANBZ: #35228 commit cc12debd518bdb593255f811b8e4fedb40595089 stable. commit 634c2cd17bd021487c57b95973bddb14be8002ff upstream. Currently the function vpu_vb_is_codecconfig() always returns 0. Delete it and its related code. Fixes: 3cd084519c6f ("media: amphion: add vpu v4l2 m2m support") Cc: stable@vger.kernel.org Signed-off-by: Ming Qian Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/media/platform/amphion/vpu_malone.c | 23 +++------------------ drivers/media/platform/amphion/vpu_v4l2.c | 10 --------- drivers/media/platform/amphion/vpu_v4l2.h | 10 --------- 3 files changed, 3 insertions(+), 40 deletions(-) diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index 4fbf179d98dc..8418dd5ea253 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -1320,22 +1320,18 @@ static int vpu_malone_insert_scode_vc1_g_seq(struct malone_scode_t *scode) { if (!scode->inst->total_input_count) return 0; - if (vpu_vb_is_codecconfig(to_vb2_v4l2_buffer(scode->vb))) - scode->need_data = 0; return 0; } static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode) { - struct vb2_v4l2_buffer *vbuf; u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN]; u32 *data = NULL; int ret; - vbuf = to_vb2_v4l2_buffer(scode->vb); data = vb2_plane_vaddr(scode->vb, 0); - if (scode->inst->total_input_count == 0 || vpu_vb_is_codecconfig(vbuf)) + if (scode->inst->total_input_count == 0) return 0; if (MALONE_VC1_CONTAIN_NAL(*data)) return 0; @@ -1356,8 +1352,6 @@ static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode) int size = 0; u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN]; - if (vpu_vb_is_codecconfig(to_vb2_v4l2_buffer(scode->vb))) - scode->need_data = 0; if (scode->inst->total_input_count) return 0; scode->need_data = 0; @@ -1543,7 +1537,7 @@ static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer __iomem *str scode.vb = vb; scode.wptr = wptr; scode.need_data = 1; - if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf)) + if (vbuf->sequence == 0) ret = vpu_malone_insert_scode(&scode, SCODE_SEQUENCE); if (ret < 0) @@ -1579,7 +1573,7 @@ static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer __iomem *str * This module is currently only supported for the H264 and HEVC formats, * for other formats, vpu_malone_add_scode() will return 0. */ - if ((disp_imm || low_latency) && !vpu_vb_is_codecconfig(vbuf)) { + if (disp_imm || low_latency) { ret = vpu_malone_add_scode(inst->core->iface, inst->id, &inst->stream_buffer, @@ -1626,7 +1620,6 @@ int vpu_malone_input_frame(struct vpu_shared_addr *shared, struct vpu_inst *inst, struct vb2_buffer *vb) { struct vpu_dec_ctrl *hc = shared->priv; - struct vb2_v4l2_buffer *vbuf; struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[inst->id]; u32 disp_imm = hc->codec_param[inst->id].disp_imm; u32 size; @@ -1640,16 +1633,6 @@ int vpu_malone_input_frame(struct vpu_shared_addr *shared, return ret; size = ret; - /* - * if buffer only contain codec data, and the timestamp is invalid, - * don't put the invalid timestamp to resync - * merge the data to next frame - */ - vbuf = to_vb2_v4l2_buffer(vb); - if (vpu_vb_is_codecconfig(vbuf)) { - inst->extra_size += size; - return 0; - } if (inst->extra_size) { size += inst->extra_size; inst->extra_size = 0; diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 26d05e64e9e5..27c99f5c5b71 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -342,16 +342,6 @@ struct vb2_v4l2_buffer *vpu_next_src_buf(struct vpu_inst *inst) if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE) return NULL; - while (vpu_vb_is_codecconfig(src_buf)) { - v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx); - vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE); - v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); - - src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx); - if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE) - return NULL; - } - return src_buf; } diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h index 064f61773f62..4ec7f0b44172 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.h +++ b/drivers/media/platform/amphion/vpu_v4l2.h @@ -38,14 +38,4 @@ static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type) else return &inst->cap_format; } - -static inline int vpu_vb_is_codecconfig(struct vb2_v4l2_buffer *vbuf) -{ -#ifdef V4L2_BUF_FLAG_CODECCONFIG - return (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) ? 1 : 0; -#else - return 0; -#endif -} - #endif -- Gitee From c45bb740e71fdcc89a570d9ef6e60744dcd581e5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 6 Jan 2026 08:31:50 +0800 Subject: [PATCH 0862/1449] media: mediatek: vcodec: Use spinlock for context list protection lock ANBZ: #35228 commit 2c1ea6214827041f548279c9eda341eda0cc8351 stable. commit a5844227e0f030d2af2d85d4aed10c5eca6ca176 upstream. Previously a mutex was added to protect the encoder and decoder context lists from unexpected changes originating from the SCP IP block, causing the context pointer to go invalid, resulting in a NULL pointer dereference in the IPI handler. Turns out on the MT8173, the VPU IPI handler is called from hard IRQ context. This causes a big warning from the scheduler. This was first reported downstream on the ChromeOS kernels, but is also reproducible on mainline using Fluster with the FFmpeg v4l2m2m decoders. Even though the actual capture format is not supported, the affected code paths are triggered. Since this lock just protects the context list and operations on it are very fast, it should be OK to switch to a spinlock. Fixes: 6467cda18c9f ("media: mediatek: vcodec: adding lock to protect decoder context list") Fixes: afaaf3a0f647 ("media: mediatek: vcodec: adding lock to protect encoder context list") Cc: Yunfei Dong Cc: stable@vger.kernel.org Signed-off-by: Chen-Yu Tsai Reviewed-by: Fei Shao Reviewed-by: Tomasz Figa Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil [ adapted file_to_dec_ctx() and file_to_enc_ctx() helper calls to equivalent fh_to_dec_ctx(file->private_data) and fh_to_enc_ctx(file->private_data) pattern ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../mediatek/vcodec/common/mtk_vcodec_fw_vpu.c | 10 ++++++---- .../mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 12 +++++++----- .../mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h | 2 +- .../platform/mediatek/vcodec/decoder/vdec_vpu_if.c | 5 +++-- .../mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c | 12 +++++++----- .../mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h | 2 +- .../platform/mediatek/vcodec/encoder/venc_vpu_if.c | 5 +++-- 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c index 87e067401a67..591a278f4729 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c @@ -47,30 +47,32 @@ static void mtk_vcodec_vpu_reset_dec_handler(void *priv) { struct mtk_vcodec_dec_dev *dev = priv; struct mtk_vcodec_dec_ctx *ctx; + unsigned long flags; dev_err(&dev->plat_dev->dev, "Watchdog timeout!!"); - mutex_lock(&dev->dev_ctx_lock); + spin_lock_irqsave(&dev->dev_ctx_lock, flags); list_for_each_entry(ctx, &dev->ctx_list, list) { ctx->state = MTK_STATE_ABORT; mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id); } - mutex_unlock(&dev->dev_ctx_lock); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); } static void mtk_vcodec_vpu_reset_enc_handler(void *priv) { struct mtk_vcodec_enc_dev *dev = priv; struct mtk_vcodec_enc_ctx *ctx; + unsigned long flags; dev_err(&dev->plat_dev->dev, "Watchdog timeout!!"); - mutex_lock(&dev->dev_ctx_lock); + spin_lock_irqsave(&dev->dev_ctx_lock, flags); list_for_each_entry(ctx, &dev->ctx_list, list) { ctx->state = MTK_STATE_ABORT; mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id); } - mutex_unlock(&dev->dev_ctx_lock); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); } static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = { diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c index 20c0b1acf618..69bd978e68a5 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c @@ -198,6 +198,7 @@ static int fops_vcodec_open(struct file *file) struct mtk_vcodec_dec_ctx *ctx = NULL; int ret = 0, i, hw_count; struct vb2_queue *src_vq; + unsigned long flags; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -268,9 +269,9 @@ static int fops_vcodec_open(struct file *file) ctx->dev->vdec_pdata->init_vdec_params(ctx); - mutex_lock(&dev->dev_ctx_lock); + spin_lock_irqsave(&dev->dev_ctx_lock, flags); list_add(&ctx->list, &dev->ctx_list); - mutex_unlock(&dev->dev_ctx_lock); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); mtk_vcodec_dbgfs_create(ctx); mutex_unlock(&dev->dev_mutex); @@ -295,6 +296,7 @@ static int fops_vcodec_release(struct file *file) { struct mtk_vcodec_dec_dev *dev = video_drvdata(file); struct mtk_vcodec_dec_ctx *ctx = fh_to_dec_ctx(file->private_data); + unsigned long flags; mtk_v4l2_vdec_dbg(0, ctx, "[%d] decoder", ctx->id); mutex_lock(&dev->dev_mutex); @@ -313,9 +315,9 @@ static int fops_vcodec_release(struct file *file) v4l2_ctrl_handler_free(&ctx->ctrl_hdl); mtk_vcodec_dbgfs_remove(dev, ctx->id); - mutex_lock(&dev->dev_ctx_lock); + spin_lock_irqsave(&dev->dev_ctx_lock, flags); list_del_init(&ctx->list); - mutex_unlock(&dev->dev_ctx_lock); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); kfree(ctx); mutex_unlock(&dev->dev_mutex); return 0; @@ -382,7 +384,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) for (i = 0; i < MTK_VDEC_HW_MAX; i++) mutex_init(&dev->dec_mutex[i]); mutex_init(&dev->dev_mutex); - mutex_init(&dev->dev_ctx_lock); + spin_lock_init(&dev->dev_ctx_lock); spin_lock_init(&dev->irqlock); snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h index b3a59af7c8ac..255b011ed24f 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h @@ -271,7 +271,7 @@ struct mtk_vcodec_dec_dev { /* decoder hardware mutex lock */ struct mutex dec_mutex[MTK_VDEC_HW_MAX]; struct mutex dev_mutex; - struct mutex dev_ctx_lock; + spinlock_t dev_ctx_lock; struct workqueue_struct *decode_workqueue; spinlock_t irqlock; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c index 145958206e38..40b97f114cf6 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c @@ -75,16 +75,17 @@ static void handle_get_param_msg_ack(const struct vdec_vpu_ipi_get_param_ack *ms static bool vpu_dec_check_ap_inst(struct mtk_vcodec_dec_dev *dec_dev, struct vdec_vpu_inst *vpu) { struct mtk_vcodec_dec_ctx *ctx; + unsigned long flags; int ret = false; - mutex_lock(&dec_dev->dev_ctx_lock); + spin_lock_irqsave(&dec_dev->dev_ctx_lock, flags); list_for_each_entry(ctx, &dec_dev->ctx_list, list) { if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) { ret = true; break; } } - mutex_unlock(&dec_dev->dev_ctx_lock); + spin_unlock_irqrestore(&dec_dev->dev_ctx_lock, flags); return ret; } diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c index 3cb8a1622222..6dcd6e904732 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c @@ -117,6 +117,7 @@ static int fops_vcodec_open(struct file *file) struct mtk_vcodec_enc_ctx *ctx = NULL; int ret = 0; struct vb2_queue *src_vq; + unsigned long flags; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -177,9 +178,9 @@ static int fops_vcodec_open(struct file *file) mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ", ctx->id, ctx, ctx->m2m_ctx); - mutex_lock(&dev->dev_ctx_lock); + spin_lock_irqsave(&dev->dev_ctx_lock, flags); list_add(&ctx->list, &dev->ctx_list); - mutex_unlock(&dev->dev_ctx_lock); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); mutex_unlock(&dev->dev_mutex); mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev), @@ -204,6 +205,7 @@ static int fops_vcodec_release(struct file *file) { struct mtk_vcodec_enc_dev *dev = video_drvdata(file); struct mtk_vcodec_enc_ctx *ctx = fh_to_enc_ctx(file->private_data); + unsigned long flags; mtk_v4l2_venc_dbg(1, ctx, "[%d] encoder", ctx->id); mutex_lock(&dev->dev_mutex); @@ -214,9 +216,9 @@ static int fops_vcodec_release(struct file *file) v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); - mutex_lock(&dev->dev_ctx_lock); + spin_lock_irqsave(&dev->dev_ctx_lock, flags); list_del_init(&ctx->list); - mutex_unlock(&dev->dev_ctx_lock); + spin_unlock_irqrestore(&dev->dev_ctx_lock, flags); kfree(ctx); mutex_unlock(&dev->dev_mutex); return 0; @@ -298,7 +300,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) mutex_init(&dev->enc_mutex); mutex_init(&dev->dev_mutex); - mutex_init(&dev->dev_ctx_lock); + spin_lock_init(&dev->dev_ctx_lock); spin_lock_init(&dev->irqlock); snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h index 0bd85d0fb379..90b4f5ea0d6b 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h @@ -206,7 +206,7 @@ struct mtk_vcodec_enc_dev { /* encoder hardware mutex lock */ struct mutex enc_mutex; struct mutex dev_mutex; - struct mutex dev_ctx_lock; + spinlock_t dev_ctx_lock; struct workqueue_struct *encode_workqueue; int enc_irq; diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c index 51bb7ee141b9..3c229b1f6b21 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c @@ -45,16 +45,17 @@ static void handle_enc_encode_msg(struct venc_vpu_inst *vpu, const void *data) static bool vpu_enc_check_ap_inst(struct mtk_vcodec_enc_dev *enc_dev, struct venc_vpu_inst *vpu) { struct mtk_vcodec_enc_ctx *ctx; + unsigned long flags; int ret = false; - mutex_lock(&enc_dev->dev_ctx_lock); + spin_lock_irqsave(&enc_dev->dev_ctx_lock, flags); list_for_each_entry(ctx, &enc_dev->ctx_list, list) { if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) { ret = true; break; } } - mutex_unlock(&enc_dev->dev_ctx_lock); + spin_unlock_irqrestore(&enc_dev->dev_ctx_lock, flags); return ret; } -- Gitee From 00e65972806b144aaa9f81c08b27bead5772d504 Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Thu, 4 Dec 2025 02:42:17 +0800 Subject: [PATCH 0863/1449] KVM: SVM: Introduce svm_recalc_lbr_msr_intercepts() ANBZ: #35228 commit 991d961055d0378fa8bb2a2026d713b0214bfcad stable. Introduce a helper updating the intercepts for LBR MSRs, similar to the one introduced upstream by commit 160f143cc131 ("KVM: SVM: Manually recalc all MSR intercepts on userspace MSR filter change"). The main difference is that this version uses set_msr_interception(), which has inverted polarity compared to svm_set_intercept_for_msr(). This is intended to simplify incoming backports. No functional changes intended. Signed-off-by: Yosry Ahmed Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/svm.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 93a3f2e5c19b..999ad647fc80 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1021,18 +1021,31 @@ void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb) vmcb_mark_dirty(to_vmcb, VMCB_LBR); } -void svm_enable_lbrv(struct kvm_vcpu *vcpu) +static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); + bool intercept = !(svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK); - svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, + !intercept, !intercept); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, + !intercept, !intercept); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, + !intercept, !intercept); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, + !intercept, !intercept); if (sev_es_guest(vcpu->kvm)) - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, 1, 1); + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, + !intercept, !intercept); +} + +void svm_enable_lbrv(struct kvm_vcpu *vcpu) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; + svm_recalc_lbr_msr_intercepts(vcpu); /* Move the LBR msrs to the vmcb02 so that the guest can see them. */ if (is_guest_mode(vcpu)) @@ -1046,10 +1059,7 @@ static void svm_disable_lbrv(struct kvm_vcpu *vcpu) KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm); svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 0, 0); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 0, 0); + svm_recalc_lbr_msr_intercepts(vcpu); /* * Move the LBR msrs back to the vmcb01 to avoid copying them -- Gitee From fe230a8cf0dcbb6fab8d9bdc8bdc6348ac9ef4c5 Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Sat, 8 Nov 2025 08:45:20 +0800 Subject: [PATCH 0864/1449] KVM: nSVM: Always recalculate LBR MSR intercepts in svm_update_lbrv() ANBZ: #35228 commit e6ff197547a911ad6b9970740fb436cf5713e52d stable. commit fbe5e5f030c22ae717ee422aaab0e00ea84fab5e upstream. svm_update_lbrv() is called when MSR_IA32_DEBUGCTLMSR is updated, and on nested transitions where LBRV is used. It checks whether LBRV enablement needs to be changed in the current VMCB, and if it does, it also recalculate intercepts to LBR MSRs. However, there are cases where intercepts need to be updated even when LBRV enablement doesn't. Example scenario: - L1 has MSR_IA32_DEBUGCTLMSR cleared. - L1 runs L2 without LBR_CTL_ENABLE (no LBRV). - L2 sets DEBUGCTLMSR_LBR in MSR_IA32_DEBUGCTLMSR, svm_update_lbrv() sets LBR_CTL_ENABLE in VMCB02 and disables intercepts to LBR MSRs. - L2 exits to L1, svm_update_lbrv() is not called on this transition. - L1 clears MSR_IA32_DEBUGCTLMSR, svm_update_lbrv() finds that LBR_CTL_ENABLE is already cleared in VMCB01 and does nothing. - Intercepts remain disabled, L1 reads to LBR MSRs read the host MSRs. Fix it by always recalculating intercepts in svm_update_lbrv(). Fixes: 1d5a1b5860ed ("KVM: x86: nSVM: correctly virtualize LBR msrs when L2 is running") Cc: stable@vger.kernel.org Signed-off-by: Yosry Ahmed Link: https://patch.msgid.link/20251108004524.1600006-3-yosry.ahmed@linux.dev Signed-off-by: Paolo Bonzini Signed-off-by: Yosry Ahmed Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/svm.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 999ad647fc80..97543700b56f 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1040,26 +1040,30 @@ static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) !intercept, !intercept); } -void svm_enable_lbrv(struct kvm_vcpu *vcpu) +static void __svm_enable_lbrv(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; - svm_recalc_lbr_msr_intercepts(vcpu); /* Move the LBR msrs to the vmcb02 so that the guest can see them. */ if (is_guest_mode(vcpu)) svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr); } -static void svm_disable_lbrv(struct kvm_vcpu *vcpu) +void svm_enable_lbrv(struct kvm_vcpu *vcpu) +{ + __svm_enable_lbrv(vcpu); + svm_recalc_lbr_msr_intercepts(vcpu); +} + +static void __svm_disable_lbrv(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm); svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; - svm_recalc_lbr_msr_intercepts(vcpu); /* * Move the LBR msrs back to the vmcb01 to avoid copying them @@ -1088,13 +1092,18 @@ void svm_update_lbrv(struct kvm_vcpu *vcpu) (is_guest_mode(vcpu) && guest_can_use(vcpu, X86_FEATURE_LBRV) && (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK)); - if (enable_lbrv == current_enable_lbrv) - return; + if (enable_lbrv && !current_enable_lbrv) + __svm_enable_lbrv(vcpu); + else if (!enable_lbrv && current_enable_lbrv) + __svm_disable_lbrv(vcpu); - if (enable_lbrv) - svm_enable_lbrv(vcpu); - else - svm_disable_lbrv(vcpu); + /* + * During nested transitions, it is possible that the current VMCB has + * LBR_CTL set, but the previous LBR_CTL had it cleared (or vice versa). + * In this case, even though LBR_CTL does not need an update, intercepts + * do, so always recalculate the intercepts here. + */ + svm_recalc_lbr_msr_intercepts(vcpu); } void disable_nmi_singlestep(struct vcpu_svm *svm) -- Gitee From 5bf421b2b3d79245e1da2b463f749d023999cdce Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Sat, 8 Nov 2025 08:45:21 +0800 Subject: [PATCH 0865/1449] KVM: nSVM: Fix and simplify LBR virtualization handling with nested ANBZ: #35228 commit 35c53e4eae0f737ebfa3e17dc47251c6b805359b stable. commit 8a4821412cf2c1429fffa07c012dd150f2edf78c upstream. The current scheme for handling LBRV when nested is used is very complicated, especially when L1 does not enable LBRV (i.e. does not set LBR_CTL_ENABLE_MASK). To avoid copying LBRs between VMCB01 and VMCB02 on every nested transition, the current implementation switches between using VMCB01 or VMCB02 as the source of truth for the LBRs while L2 is running. If L2 enables LBR, VMCB02 is used as the source of truth. When L2 disables LBR, the LBRs are copied to VMCB01 and VMCB01 is used as the source of truth. This introduces significant complexity, and incorrect behavior in some cases. For example, on a nested #VMEXIT, the LBRs are only copied from VMCB02 to VMCB01 if LBRV is enabled in VMCB01. This is because L2's writes to MSR_IA32_DEBUGCTLMSR to enable LBR are intercepted and propagated to VMCB01 instead of VMCB02. However, LBRV is only enabled in VMCB02 when L2 is running. This means that if L2 enables LBR and exits to L1, the LBRs will not be propagated from VMCB02 to VMCB01, because LBRV is disabled in VMCB01. There is no meaningful difference in CPUID rate in L2 when copying LBRs on every nested transition vs. the current approach, so do the simple and correct thing and always copy LBRs between VMCB01 and VMCB02 on nested transitions (when LBRV is disabled by L1). Drop the conditional LBRs copying in __svm_{enable/disable}_lbrv() as it is now unnecessary. VMCB02 becomes the only source of truth for LBRs when L2 is running, regardless of LBRV being enabled by L1, drop svm_get_lbr_vmcb() and use svm->vmcb directly in its place. Fixes: 1d5a1b5860ed ("KVM: x86: nSVM: correctly virtualize LBR msrs when L2 is running") Cc: stable@vger.kernel.org Signed-off-by: Yosry Ahmed Link: https://patch.msgid.link/20251108004524.1600006-4-yosry.ahmed@linux.dev Signed-off-by: Paolo Bonzini Signed-off-by: Yosry Ahmed Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/nested.c | 20 ++++++----------- arch/x86/kvm/svm/svm.c | 47 +++++++++------------------------------ 2 files changed, 17 insertions(+), 50 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index f47242a1e602..53aa96957663 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -601,11 +601,10 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12 */ svm_copy_lbrs(vmcb02, vmcb12); vmcb02->save.dbgctl &= ~DEBUGCTL_RESERVED_BITS; - svm_update_lbrv(&svm->vcpu); - - } else if (unlikely(vmcb01->control.virt_ext & LBR_CTL_ENABLE_MASK)) { + } else { svm_copy_lbrs(vmcb02, vmcb01); } + svm_update_lbrv(&svm->vcpu); } static inline bool is_evtinj_soft(u32 evtinj) @@ -731,11 +730,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm, svm->soft_int_next_rip = vmcb12_rip; } - vmcb02->control.virt_ext = vmcb01->control.virt_ext & - LBR_CTL_ENABLE_MASK; - if (guest_can_use(vcpu, X86_FEATURE_LBRV)) - vmcb02->control.virt_ext |= - (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK); + /* LBR_CTL_ENABLE_MASK is controlled by svm_update_lbrv() */ if (!nested_vmcb_needs_vls_intercept(svm)) vmcb02->control.virt_ext |= VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK; @@ -1066,13 +1061,12 @@ int nested_svm_vmexit(struct vcpu_svm *svm) kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); if (unlikely(guest_can_use(vcpu, X86_FEATURE_LBRV) && - (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK))) { + (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK))) svm_copy_lbrs(vmcb12, vmcb02); - svm_update_lbrv(vcpu); - } else if (unlikely(vmcb01->control.virt_ext & LBR_CTL_ENABLE_MASK)) { + else svm_copy_lbrs(vmcb01, vmcb02); - svm_update_lbrv(vcpu); - } + + svm_update_lbrv(vcpu); if (vnmi) { if (vmcb02->control.int_ctl & V_NMI_BLOCKING_MASK) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 97543700b56f..b7af272e6872 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1042,13 +1042,7 @@ static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) static void __svm_enable_lbrv(struct kvm_vcpu *vcpu) { - struct vcpu_svm *svm = to_svm(vcpu); - - svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; - - /* Move the LBR msrs to the vmcb02 so that the guest can see them. */ - if (is_guest_mode(vcpu)) - svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr); + to_svm(vcpu)->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; } void svm_enable_lbrv(struct kvm_vcpu *vcpu) @@ -1059,36 +1053,15 @@ void svm_enable_lbrv(struct kvm_vcpu *vcpu) static void __svm_disable_lbrv(struct kvm_vcpu *vcpu) { - struct vcpu_svm *svm = to_svm(vcpu); - KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm); - - svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; - - /* - * Move the LBR msrs back to the vmcb01 to avoid copying them - * on nested guest entries. - */ - if (is_guest_mode(vcpu)) - svm_copy_lbrs(svm->vmcb01.ptr, svm->vmcb); -} - -static struct vmcb *svm_get_lbr_vmcb(struct vcpu_svm *svm) -{ - /* - * If LBR virtualization is disabled, the LBR MSRs are always kept in - * vmcb01. If LBR virtualization is enabled and L1 is running VMs of - * its own, the MSRs are moved between vmcb01 and vmcb02 as needed. - */ - return svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK ? svm->vmcb : - svm->vmcb01.ptr; + to_svm(vcpu)->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; } void svm_update_lbrv(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); bool current_enable_lbrv = svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK; - bool enable_lbrv = (svm_get_lbr_vmcb(svm)->save.dbgctl & DEBUGCTLMSR_LBR) || + bool enable_lbrv = (svm->vmcb->save.dbgctl & DEBUGCTLMSR_LBR) || (is_guest_mode(vcpu) && guest_can_use(vcpu, X86_FEATURE_LBRV) && (svm->nested.ctl.virt_ext & LBR_CTL_ENABLE_MASK)); @@ -2954,19 +2927,19 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = svm->tsc_aux; break; case MSR_IA32_DEBUGCTLMSR: - msr_info->data = svm_get_lbr_vmcb(svm)->save.dbgctl; + msr_info->data = svm->vmcb->save.dbgctl; break; case MSR_IA32_LASTBRANCHFROMIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.br_from; + msr_info->data = svm->vmcb->save.br_from; break; case MSR_IA32_LASTBRANCHTOIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.br_to; + msr_info->data = svm->vmcb->save.br_to; break; case MSR_IA32_LASTINTFROMIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.last_excp_from; + msr_info->data = svm->vmcb->save.last_excp_from; break; case MSR_IA32_LASTINTTOIP: - msr_info->data = svm_get_lbr_vmcb(svm)->save.last_excp_to; + msr_info->data = svm->vmcb->save.last_excp_to; break; case MSR_VM_HSAVE_PA: msr_info->data = svm->nested.hsave_msr; @@ -3234,10 +3207,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) if (data & DEBUGCTL_RESERVED_BITS) return 1; - if (svm_get_lbr_vmcb(svm)->save.dbgctl == data) + if (svm->vmcb->save.dbgctl == data) break; - svm_get_lbr_vmcb(svm)->save.dbgctl = data; + svm->vmcb->save.dbgctl = data; vmcb_mark_dirty(svm->vmcb, VMCB_LBR); svm_update_lbrv(vcpu); break; -- Gitee From 231034f7004d2a850aba2ec142113bc391983815 Mon Sep 17 00:00:00 2001 From: Yosry Ahmed Date: Wed, 12 Nov 2025 09:30:17 +0800 Subject: [PATCH 0866/1449] KVM: SVM: Fix redundant updates of LBR MSR intercepts ANBZ: #35228 commit 65a02ffb5223858d71df9c2d774dd8eb2745b033 stable. commit 3fa05f96fc08dff5e846c2cc283a249c1bf029a1 upstream. Don't update the LBR MSR intercept bitmaps if they're already up-to-date, as unconditionally updating the intercepts forces KVM to recalculate the MSR bitmaps for vmcb02 on every nested VMRUN. The redundant updates are functionally okay; however, they neuter an optimization in Hyper-V nested virtualization enlightenments and this manifests as a self-test failure. In particular, Hyper-V lets L1 mark "nested enlightenments" as clean, i.e. tell KVM that no changes were made to the MSR bitmap since the last VMRUN. The hyperv_svm_test KVM selftest intentionally changes the MSR bitmap "without telling KVM about it" to verify that KVM honors the clean hint, correctly fails because KVM notices the changed bitmap anyway: ==== Test Assertion Failure ==== x86/hyperv_svm_test.c:120: vmcb->control.exit_code == 0x081 pid=193558 tid=193558 errno=4 - Interrupted system call 1 0x0000000000411361: assert_on_unhandled_exception at processor.c:659 2 0x0000000000406186: _vcpu_run at kvm_util.c:1699 3 (inlined by) vcpu_run at kvm_util.c:1710 4 0x0000000000401f2a: main at hyperv_svm_test.c:175 5 0x000000000041d0d3: __libc_start_call_main at libc-start.o:? 6 0x000000000041f27c: __libc_start_main_impl at ??:? 7 0x00000000004021a0: _start at ??:? vmcb->control.exit_code == SVM_EXIT_VMMCALL Do *not* fix this by skipping svm_hv_vmcb_dirty_nested_enlightenments() when svm_set_intercept_for_msr() performs a no-op change. changes to the L0 MSR interception bitmap are only triggered by full CPUID updates and MSR filter updates, both of which should be rare. Changing svm_set_intercept_for_msr() risks hiding unintended pessimizations like this one, and is actually more complex than this change. Fixes: fbe5e5f030c2 ("KVM: nSVM: Always recalculate LBR MSR intercepts in svm_update_lbrv()") Cc: stable@vger.kernel.org Signed-off-by: Yosry Ahmed Link: https://patch.msgid.link/20251112013017.1836863-1-yosry.ahmed@linux.dev [Rewritten commit message based on mailing list discussion. - Paolo] Reviewed-by: Sean Christopherson Tested-by: Sean Christopherson Signed-off-by: Paolo Bonzini Signed-off-by: Yosry Ahmed Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kvm/svm/svm.c | 6 ++++++ arch/x86/kvm/svm/svm.h | 1 + 2 files changed, 7 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index b7af272e6872..c45e88ff9712 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1026,6 +1026,9 @@ static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) struct vcpu_svm *svm = to_svm(vcpu); bool intercept = !(svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK); + if (intercept == svm->lbr_msrs_intercepted) + return; + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, !intercept, !intercept); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, @@ -1038,6 +1041,8 @@ static void svm_recalc_lbr_msr_intercepts(struct kvm_vcpu *vcpu) if (sev_es_guest(vcpu->kvm)) set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, !intercept, !intercept); + + svm->lbr_msrs_intercepted = intercept; } static void __svm_enable_lbrv(struct kvm_vcpu *vcpu) @@ -1499,6 +1504,7 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu) } svm->x2avic_msrs_intercepted = true; + svm->lbr_msrs_intercepted = true; svm->vmcb01.ptr = page_address(vmcb01_page); svm->vmcb01.pa = __sme_set(page_to_pfn(vmcb01_page) << PAGE_SHIFT); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 794de734ee19..0879cb897630 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -297,6 +297,7 @@ struct vcpu_svm { bool guest_state_loaded; bool x2avic_msrs_intercepted; + bool lbr_msrs_intercepted; /* Guest GIF value, used when vGIF is not enabled */ bool guest_gif; -- Gitee From 105116d3d441d092040781469af4a6f1f2d02b6b Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:12 +0800 Subject: [PATCH 0867/1449] mm/damon/tests/vaddr-kunit: handle alloc failures in damon_test_split_evenly_fail() ANBZ: #35228 commit b75608e7547d87125cd8be9b8d3d782e0234ff97 stable. commit 7890e5b5bb6e386155c6e755fe70e0cdcc77f18e upstream. damon_test_split_evenly_fail() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-19-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/vaddr-test.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mm/damon/vaddr-test.h b/mm/damon/vaddr-test.h index b4fc21ef3c70..fdeaa32c23ab 100644 --- a/mm/damon/vaddr-test.h +++ b/mm/damon/vaddr-test.h @@ -250,7 +250,16 @@ static void damon_test_split_evenly_fail(struct kunit *test, unsigned long start, unsigned long end, unsigned int nr_pieces) { struct damon_target *t = damon_new_target(); - struct damon_region *r = damon_new_region(start, end); + struct damon_region *r; + + if (!t) + kunit_skip(test, "target alloc fail"); + + r = damon_new_region(start, end); + if (!r) { + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } damon_add_region(r, t); KUNIT_EXPECT_EQ(test, -- Gitee From fe6f8fed140f4752cde678f3f5f4e8cd7c597e35 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:11 +0800 Subject: [PATCH 0868/1449] mm/damon/tests/vaddr-kunit: handle alloc failures on damon_do_test_apply_three_regions() ANBZ: #35228 commit 339bcd3d051c3c0fd865eda2617b5a1e4ba38b12 stable. commit 2b22d0fcc6320ba29b2122434c1d2f0785fb0a25 upstream. damon_do_test_apply_three_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-18-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/vaddr-test.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/damon/vaddr-test.h b/mm/damon/vaddr-test.h index fdeaa32c23ab..0779f7f8390f 100644 --- a/mm/damon/vaddr-test.h +++ b/mm/damon/vaddr-test.h @@ -136,8 +136,14 @@ static void damon_do_test_apply_three_regions(struct kunit *test, int i; t = damon_new_target(); + if (!t) + kunit_skip(test, "target alloc fail"); for (i = 0; i < nr_regions / 2; i++) { r = damon_new_region(regions[i * 2], regions[i * 2 + 1]); + if (!r) { + damon_destroy_target(t); + kunit_skip(test, "region alloc fail"); + } damon_add_region(r, t); } -- Gitee From 87e91fd7915f0bcb54185dc456f76fb1f506e14e Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Tue, 6 May 2025 23:10:08 +0800 Subject: [PATCH 0869/1449] RDMA/core: Fix "KASAN: slab-use-after-free Read in ib_register_device" problem ANBZ: #35228 commit 17d3103325e891e10994e7aa28d12bea04dc2c60 stable. commit d0706bfd3ee40923c001c6827b786a309e2a8713 upstream. Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc3/0x670 mm/kasan/report.c:521 kasan_report+0xe0/0x110 mm/kasan/report.c:634 strlen+0x93/0xa0 lib/string.c:420 __fortify_strlen include/linux/fortify-string.h:268 [inline] get_kobj_path_length lib/kobject.c:118 [inline] kobject_get_path+0x3f/0x2a0 lib/kobject.c:158 kobject_uevent_env+0x289/0x1870 lib/kobject_uevent.c:545 ib_register_device drivers/infiniband/core/device.c:1472 [inline] ib_register_device+0x8cf/0xe00 drivers/infiniband/core/device.c:1393 rxe_register_device+0x275/0x320 drivers/infiniband/sw/rxe/rxe_verbs.c:1552 rxe_net_add+0x8e/0xe0 drivers/infiniband/sw/rxe/rxe_net.c:550 rxe_newlink+0x70/0x190 drivers/infiniband/sw/rxe/rxe.c:225 nldev_newlink+0x3a3/0x680 drivers/infiniband/core/nldev.c:1796 rdma_nl_rcv_msg+0x387/0x6e0 drivers/infiniband/core/netlink.c:195 rdma_nl_rcv_skb.constprop.0.isra.0+0x2e5/0x450 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] netlink_unicast+0x53a/0x7f0 net/netlink/af_netlink.c:1339 netlink_sendmsg+0x8d1/0xdd0 net/netlink/af_netlink.c:1883 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg net/socket.c:727 [inline] ____sys_sendmsg+0xa95/0xc70 net/socket.c:2566 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2620 __sys_sendmsg+0x16d/0x220 net/socket.c:2652 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f This problem is similar to the problem that the commit 1d6a9e7449e2 ("RDMA/core: Fix use-after-free when rename device name") fixes. The root cause is: the function ib_device_rename() renames the name with lock. But in the function kobject_uevent(), this name is accessed without lock protection at the same time. The solution is to add the lock protection when this name is accessed in the function kobject_uevent(). Fixes: 779e0bf47632 ("RDMA/core: Do not indicate device ready when device enablement fails") Link: https://patch.msgid.link/r/20250506151008.75701-1-yanjun.zhu@linux.dev Reported-by: syzbot+e2ce9e275ecc70a30b72@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=e2ce9e275ecc70a30b72 Signed-off-by: Zhu Yanjun Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin [ Ajay: Modified to apply on v5.10.y-v6.6.y ib_device_notify_register() not present in v5.10.y-v6.6.y, so directly added lock for kobject_uevent() ] Signed-off-by: Ajay Kaher Signed-off-by: Shivani Agarwal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/core/device.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 6769c42e46d4..9c11b6818f06 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -1450,8 +1450,13 @@ int ib_register_device(struct ib_device *device, const char *name, return ret; } dev_set_uevent_suppress(&device->dev, false); + + down_read(&devices_rwsem); + /* Mark for userspace that device is ready */ kobject_uevent(&device->dev.kobj, KOBJ_ADD); + + up_read(&devices_rwsem); ib_device_put(device); return 0; -- Gitee From dad63f1f58107cf7a57a93bfb992c2357c0f9ad0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Dec 2025 11:22:53 +0000 Subject: [PATCH 0870/1449] sched/fair: Small cleanup to sched_balance_newidle() ANBZ: #35228 commit 38d080768c858d482c7465bd0b1a78def5692c36 stable. commit e78e70dbf603c1425f15f32b455ca148c932f6c1 upstream. Pull out the !sd check to simplify code. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Dietmar Eggemann Tested-by: Dietmar Eggemann Tested-by: Chris Mason Link: https://patch.msgid.link/20251107161739.525916173@infradead.org [ Ajay: Modified to apply on v6.6 ] Signed-off-by: Ajay Kaher Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- kernel/sched/fair.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 87a54c42c1bc..5976aed35d12 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -14498,14 +14498,15 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) rcu_read_lock(); sd = rcu_dereference_check_sched_domain(this_rq->sd); + if (!sd) { + rcu_read_unlock(); + goto out; + } if (!READ_ONCE(this_rq->rd->overload) || - (sd && get_avg_idle(this_rq) < sd->max_newidle_lb_cost)) { - - if (sd) - update_next_balance(sd, &next_balance); + get_avg_idle(this_rq) < sd->max_newidle_lb_cost) { + update_next_balance(sd, &next_balance); rcu_read_unlock(); - goto out; } rcu_read_unlock(); -- Gitee From bdcc7e2de6d7bd0f88fb01a8f8270434a6c6145a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Dec 2025 11:22:54 +0000 Subject: [PATCH 0871/1449] sched/fair: Small cleanup to update_newidle_cost() ANBZ: #35228 commit 5b7949a95c39855cb7eba5fc1cc3dc6503948dd8 stable. commit 08d473dd8718e4a4d698b1113a14a40ad64a909b upstream. Simplify code by adding a few variables. Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Dietmar Eggemann Tested-by: Dietmar Eggemann Tested-by: Chris Mason Link: https://patch.msgid.link/20251107161739.655208666@infradead.org [ Ajay: Modified to apply on v6.6 ] Signed-off-by: Ajay Kaher Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- kernel/sched/fair.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5976aed35d12..338a73970ec0 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -13828,22 +13828,25 @@ void update_max_interval(void) static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) { + unsigned long next_decay = sd->last_decay_max_lb_cost + HZ; + unsigned long now = jiffies; + if (cost > sd->max_newidle_lb_cost) { /* * Track max cost of a domain to make sure to not delay the * next wakeup on the CPU. */ sd->max_newidle_lb_cost = cost; - sd->last_decay_max_lb_cost = jiffies; - } else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) { + sd->last_decay_max_lb_cost = now; + + } else if (time_after(now, next_decay)) { /* * Decay the newidle max times by ~1% per second to ensure that * it is not outdated and the current max cost is actually * shorter. */ sd->max_newidle_lb_cost = (sd->max_newidle_lb_cost * 253) / 256; - sd->last_decay_max_lb_cost = jiffies; - + sd->last_decay_max_lb_cost = now; return true; } -- Gitee From 1f5e2ba2b7d5de4d818097fb962349b2be091d47 Mon Sep 17 00:00:00 2001 From: "Peter Zijlstra (Intel)" Date: Wed, 3 Dec 2025 11:22:55 +0000 Subject: [PATCH 0872/1449] sched/fair: Proportional newidle balance ANBZ: #35228 commit 51445190c10a36d292e70db085d0fb6cc3bec94f stable. commit 33cf66d88306663d16e4759e9d24766b0aaa2e17 upstream. Add a randomized algorithm that runs newidle balancing proportional to its success rate. This improves schbench significantly: 6.18-rc4: 2.22 Mrps/s 6.18-rc4+revert: 2.04 Mrps/s 6.18-rc4+revert+random: 2.18 Mrps/S Conversely, per Adam Li this affects SpecJBB slightly, reducing it by 1%: 6.17: -6% 6.17+revert: 0% 6.17+revert+random: -1% Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Dietmar Eggemann Tested-by: Dietmar Eggemann Tested-by: Chris Mason Link: https://lkml.kernel.org/r/6825c50d-7fa7-45d8-9b81-c6e7e25738e2@meta.com Link: https://patch.msgid.link/20251107161739.770122091@infradead.org [ Ajay: Modified to apply on v6.6 ] Signed-off-by: Ajay Kaher Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- include/linux/sched/topology.h | 3 +++ kernel/sched/core.c | 3 +++ kernel/sched/fair.c | 44 ++++++++++++++++++++++++++++++---- kernel/sched/features.h | 5 ++++ kernel/sched/sched.h | 7 ++++++ kernel/sched/topology.c | 6 +++++ 6 files changed, 64 insertions(+), 4 deletions(-) diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index f489cf2636f1..c8da14f3351b 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -111,6 +111,9 @@ struct sched_domain { unsigned int nr_balance_failed; /* initialise to 0 */ /* idle_balance() stats */ + unsigned int newidle_call; + unsigned int newidle_success; + unsigned int newidle_ratio; u64 max_newidle_lb_cost; unsigned long last_decay_max_lb_cost; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index afa2768e182f..9dcc6dcdd18e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -117,6 +117,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_se_tp); EXPORT_TRACEPOINT_SYMBOL_GPL(sched_update_nr_running_tp); DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); +DEFINE_PER_CPU(struct rnd_state, sched_rnd_state); #ifdef CONFIG_SCHED_DEBUG /* @@ -8535,6 +8536,8 @@ void __init sched_init_smp(void) { sched_init_numa(NUMA_NO_NODE); + prandom_init_once(&sched_rnd_state); + /* * There's no userspace yet to cause hotplug operations; hence all the * CPU masks are stable and all blatant races in the below code cannot diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 338a73970ec0..2a8c9d39ce16 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -13826,11 +13826,27 @@ void update_max_interval(void) max_load_balance_interval = HZ*num_online_cpus()/10; } -static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) +static inline void update_newidle_stats(struct sched_domain *sd, unsigned int success) +{ + sd->newidle_call++; + sd->newidle_success += success; + + if (sd->newidle_call >= 1024) { + sd->newidle_ratio = sd->newidle_success; + sd->newidle_call /= 2; + sd->newidle_success /= 2; + } +} + +static inline bool +update_newidle_cost(struct sched_domain *sd, u64 cost, unsigned int success) { unsigned long next_decay = sd->last_decay_max_lb_cost + HZ; unsigned long now = jiffies; + if (cost) + update_newidle_stats(sd, success); + if (cost > sd->max_newidle_lb_cost) { /* * Track max cost of a domain to make sure to not delay the @@ -13883,7 +13899,7 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle) * Decay the newidle max times here because this is a regular * visit to all the domains. */ - need_decay = update_newidle_cost(sd, 0); + need_decay = update_newidle_cost(sd, 0, 0); max_cost += sd->max_newidle_lb_cost; /* @@ -14530,6 +14546,22 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) break; if (sd->flags & SD_BALANCE_NEWIDLE) { + unsigned int weight = 1; + + if (sched_feat(NI_RANDOM)) { + /* + * Throw a 1k sided dice; and only run + * newidle_balance according to the success + * rate. + */ + u32 d1k = sched_rng() % 1024; + weight = 1 + sd->newidle_ratio; + if (d1k > weight) { + update_newidle_stats(sd, 0); + continue; + } + weight = (1024 + weight/2) / weight; + } pulled_task = load_balance(this_cpu, this_rq, sd, CPU_NEWLY_IDLE, @@ -14537,10 +14569,14 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) t1 = sched_clock_cpu(this_cpu); domain_cost = t1 - t0; - update_newidle_cost(sd, domain_cost); - curr_cost += domain_cost; t0 = t1; + + /* + * Track max cost of a domain to make sure to not delay the + * next wakeup on the CPU. + */ + update_newidle_cost(sd, domain_cost, weight * !!pulled_task); } /* We wanna pull non-idle tasks to idle task only cpu. */ diff --git a/kernel/sched/features.h b/kernel/sched/features.h index d4547c2003a5..2d8b4ea26872 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -124,6 +124,11 @@ SCHED_FEAT(UTIL_EST_FASTUP, true) SCHED_FEAT(LATENCY_WARN, false) +/* + * Do newidle balancing proportional to its success rate using randomization. + */ +SCHED_FEAT(NI_RANDOM, true) + SCHED_FEAT(HZ_BW, true) #if defined(CONFIG_SCHED_CORE) && defined(CONFIG_CFS_BANDWIDTH) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index d3d5f7d111d9..b6ab2dc5d892 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -5,6 +5,7 @@ #ifndef _KERNEL_SCHED_SCHED_H #define _KERNEL_SCHED_SCHED_H +#include #include #include #include @@ -1675,6 +1676,12 @@ static inline bool is_migration_disabled(struct task_struct *p) } DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); +DECLARE_PER_CPU(struct rnd_state, sched_rnd_state); + +static inline u32 sched_rng(void) +{ + return prandom_u32_state(this_cpu_ptr(&sched_rnd_state)); +} #define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) #define this_rq() this_cpu_ptr(&runqueues) diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index d0171cd78e60..22cf8b214b8f 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -1680,6 +1680,12 @@ sd_init(struct sched_domain_topology_level *tl, .last_balance = jiffies, .balance_interval = sd_weight, + + /* 50% success rate */ + .newidle_call = 512, + .newidle_success = 256, + .newidle_ratio = 512, + .max_newidle_lb_cost = 0, .last_decay_max_lb_cost = jiffies, .child = child, -- Gitee From b7bfc02f77b088ea424540ef39f58866b53a7db8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 29 Dec 2025 15:53:16 +0800 Subject: [PATCH 0873/1449] net: Remove conditional threaded-NAPI wakeup based on task state. ANBZ: #35228 commit 03765d5c18084eab40351fda09bc6fc1a343cd07 stable. commit 56364c910691f6d10ba88c964c9041b9ab777bd6 upstream. A NAPI thread is scheduled by first setting NAPI_STATE_SCHED bit. If successful (the bit was not yet set) then the NAPI_STATE_SCHED_THREADED is set but only if thread's state is not TASK_INTERRUPTIBLE (is TASK_RUNNING) followed by task wakeup. If the task is idle (TASK_INTERRUPTIBLE) then the NAPI_STATE_SCHED_THREADED bit is not set. The thread is no relying on the bit but always leaving the wait-loop after returning from schedule() because there must have been a wakeup. The smpboot-threads implementation for per-CPU threads requires an explicit condition and does not support "if we get out of schedule() then there must be something to do". Removing this optimisation simplifies the following integration. Set NAPI_STATE_SCHED_THREADED unconditionally on wakeup and rely on it in the wait path by removing the `woken' condition. Acked-by: Jakub Kicinski Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Paolo Abeni Signed-off-by: Wen Yang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/dev.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 2d3e0e4130c2..d62cab2e4878 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4526,13 +4526,7 @@ static inline void ____napi_schedule(struct softnet_data *sd, */ thread = READ_ONCE(napi->thread); if (thread) { - /* Avoid doing set_bit() if the thread is in - * INTERRUPTIBLE state, cause napi_thread_wait() - * makes sure to proceed with napi polling - * if the thread is explicitly woken from here. - */ - if (READ_ONCE(thread->__state) != TASK_INTERRUPTIBLE) - set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); + set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); wake_up_process(thread); return; } @@ -6688,8 +6682,6 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll) static int napi_thread_wait(struct napi_struct *napi) { - bool woken = false; - set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { @@ -6698,15 +6690,13 @@ static int napi_thread_wait(struct napi_struct *napi) * Testing SCHED bit is not enough because SCHED bit might be * set by some other busy poll thread or by napi_disable(). */ - if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) { + if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state)) { WARN_ON(!list_empty(&napi->poll_list)); __set_current_state(TASK_RUNNING); return 0; } schedule(); - /* woken being true indicates this thread owns this napi. */ - woken = true; set_current_state(TASK_INTERRUPTIBLE); } __set_current_state(TASK_RUNNING); -- Gitee From eaa2d47b8895a391212959138ac71259205dcb87 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 29 Dec 2025 15:53:17 +0800 Subject: [PATCH 0874/1449] net: Allow to use SMP threads for backlog NAPI. ANBZ: #35228 commit f3652768a89cfdaedbe2c9384299eea7ec435fef stable. commit dad6b97702639fba27a2bd3e986982ad6f0db3a7 upstream. Backlog NAPI is a per-CPU NAPI struct only (with no device behind it) used by drivers which don't do NAPI them self, RPS and parts of the stack which need to avoid recursive deadlocks while processing a packet. The non-NAPI driver use the CPU local backlog NAPI. If RPS is enabled then a flow for the skb is computed and based on the flow the skb can be enqueued on a remote CPU. Scheduling/ raising the softirq (for backlog's NAPI) on the remote CPU isn't trivial because the softirq is only scheduled on the local CPU and performed after the hardirq is done. In order to schedule a softirq on the remote CPU, an IPI is sent to the remote CPU which schedules the backlog-NAPI on the then local CPU. On PREEMPT_RT interrupts are force-threaded. The soft interrupts are raised within the interrupt thread and processed after the interrupt handler completed still within the context of the interrupt thread. The softirq is handled in the context where it originated. With force-threaded interrupts enabled, ksoftirqd is woken up if a softirq is raised from hardirq context. This is the case if it is raised from an IPI. Additionally there is a warning on PREEMPT_RT if the softirq is raised from the idle thread. This was done for two reasons: - With threaded interrupts the processing should happen in thread context (where it originated) and ksoftirqd is the only thread for this context if raised from hardirq. Using the currently running task instead would "punish" a random task. - Once ksoftirqd is active it consumes all further softirqs until it stops running. This changed recently and is no longer the case. Instead of keeping the backlog NAPI in ksoftirqd (in force-threaded/ PREEMPT_RT setups) I am proposing NAPI-threads for backlog. The "proper" setup with threaded-NAPI is not doable because the threads are not pinned to an individual CPU and can be modified by the user. Additionally a dummy network device would have to be assigned. Also CPU-hotplug has to be considered if additional CPUs show up. All this can be probably done/ solved but the smpboot-threads already provide this infrastructure. Sending UDP packets over loopback expects that the packet is processed within the call. Delaying it by handing it over to the thread hurts performance. It is not beneficial to the outcome if the context switch happens immediately after enqueue or after a while to process a few packets in a batch. There is no need to always use the thread if the backlog NAPI is requested on the local CPU. This restores the loopback throuput. The performance drops mostly to the same value after enabling RPS on the loopback comparing the IPI and the tread result. Create NAPI-threads for backlog if request during boot. The thread runs the inner loop from napi_threaded_poll(), the wait part is different. It checks for NAPI_STATE_SCHED (the backlog NAPI can not be disabled). The NAPI threads for backlog are optional, it has to be enabled via the boot argument "thread_backlog_napi". It is mandatory for PREEMPT_RT to avoid the wakeup of ksoftirqd from the IPI. Acked-by: Jakub Kicinski Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Paolo Abeni Signed-off-by: Wen Yang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/dev.c | 148 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 35 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index d62cab2e4878..cf5b5a4cbfd7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include @@ -217,6 +218,31 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)]; } +#ifndef CONFIG_PREEMPT_RT + +static DEFINE_STATIC_KEY_FALSE(use_backlog_threads_key); + +static int __init setup_backlog_napi_threads(char *arg) +{ + static_branch_enable(&use_backlog_threads_key); + return 0; +} +early_param("thread_backlog_napi", setup_backlog_napi_threads); + +static bool use_backlog_threads(void) +{ + return static_branch_unlikely(&use_backlog_threads_key); +} + +#else + +static bool use_backlog_threads(void) +{ + return true; +} + +#endif + static inline void rps_lock_irqsave(struct softnet_data *sd, unsigned long *flags) { @@ -4494,6 +4520,7 @@ EXPORT_SYMBOL(__dev_direct_xmit); /************************************************************************* * Receiver routines *************************************************************************/ +static DEFINE_PER_CPU(struct task_struct *, backlog_napi); int netdev_max_backlog __read_mostly = 1000; EXPORT_SYMBOL(netdev_max_backlog); @@ -4526,12 +4553,16 @@ static inline void ____napi_schedule(struct softnet_data *sd, */ thread = READ_ONCE(napi->thread); if (thread) { + if (use_backlog_threads() && thread == raw_cpu_read(backlog_napi)) + goto use_local_napi; + set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); wake_up_process(thread); return; } } +use_local_napi: list_add_tail(&napi->poll_list, &sd->poll_list); WRITE_ONCE(napi->list_owner, smp_processor_id()); /* If not called from net_rx_action() @@ -4777,6 +4808,11 @@ static void napi_schedule_rps(struct softnet_data *sd) #ifdef CONFIG_RPS if (sd != mysd) { + if (use_backlog_threads()) { + __napi_schedule_irqoff(&sd->backlog); + return; + } + sd->rps_ipi_next = mysd->rps_ipi_list; mysd->rps_ipi_list = sd; @@ -6000,7 +6036,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) #ifdef CONFIG_RPS struct softnet_data *remsd = sd->rps_ipi_list; - if (remsd) { + if (!use_backlog_threads() && remsd) { sd->rps_ipi_list = NULL; local_irq_enable(); @@ -6015,7 +6051,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) { #ifdef CONFIG_RPS - return sd->rps_ipi_list != NULL; + return !use_backlog_threads() && sd->rps_ipi_list; #else return false; #endif @@ -6059,7 +6095,7 @@ static int process_backlog(struct napi_struct *napi, int quota) * We can use a plain write instead of clear_bit(), * and we dont need an smp_mb() memory barrier. */ - napi->state = 0; + napi->state &= NAPIF_STATE_THREADED; again = false; } else { skb_queue_splice_tail_init(&sd->input_pkt_queue, @@ -6725,43 +6761,48 @@ static void skb_defer_free_flush(struct softnet_data *sd) } } -static int napi_threaded_poll(void *data) +static void napi_threaded_poll_loop(struct napi_struct *napi) { - struct napi_struct *napi = data; struct softnet_data *sd; - void *have; - - while (!napi_thread_wait(napi)) { - unsigned long last_qs = jiffies; + unsigned long last_qs = jiffies; - for (;;) { - bool repoll = false; + for (;;) { + bool repoll = false; + void *have; - local_bh_disable(); - sd = this_cpu_ptr(&softnet_data); - sd->in_napi_threaded_poll = true; + local_bh_disable(); + sd = this_cpu_ptr(&softnet_data); + sd->in_napi_threaded_poll = true; - have = netpoll_poll_lock(napi); - __napi_poll(napi, &repoll); - netpoll_poll_unlock(have); + have = netpoll_poll_lock(napi); + __napi_poll(napi, &repoll); + netpoll_poll_unlock(have); - sd->in_napi_threaded_poll = false; - barrier(); + sd->in_napi_threaded_poll = false; + barrier(); - if (sd_has_rps_ipi_waiting(sd)) { - local_irq_disable(); - net_rps_action_and_irq_enable(sd); - } - skb_defer_free_flush(sd); - local_bh_enable(); + if (sd_has_rps_ipi_waiting(sd)) { + local_irq_disable(); + net_rps_action_and_irq_enable(sd); + } + skb_defer_free_flush(sd); + local_bh_enable(); - if (!repoll) - break; + if (!repoll) + break; - rcu_softirq_qs_periodic(last_qs); - cond_resched(); - } + rcu_softirq_qs_periodic(last_qs); + cond_resched(); } +} + +static int napi_threaded_poll(void *data) +{ + struct napi_struct *napi = data; + + while (!napi_thread_wait(napi)) + napi_threaded_poll_loop(napi); + return 0; } @@ -11346,7 +11387,7 @@ static int dev_cpu_dead(unsigned int oldcpu) list_del_init(&napi->poll_list); if (napi->poll == process_backlog) - napi->state = 0; + napi->state &= NAPIF_STATE_THREADED; else ____napi_schedule(sd, napi); } @@ -11354,12 +11395,14 @@ static int dev_cpu_dead(unsigned int oldcpu) raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); + if (!use_backlog_threads()) { #ifdef CONFIG_RPS - remsd = oldsd->rps_ipi_list; - oldsd->rps_ipi_list = NULL; + remsd = oldsd->rps_ipi_list; + oldsd->rps_ipi_list = NULL; #endif - /* send out pending IPI's on offline CPU */ - net_rps_send_ipi(remsd); + /* send out pending IPI's on offline CPU */ + net_rps_send_ipi(remsd); + } /* Process offline CPU's input_pkt_queue */ while ((skb = __skb_dequeue(&oldsd->process_queue))) { @@ -11622,6 +11665,38 @@ static struct pernet_operations __net_initdata default_device_ops = { * */ +static int backlog_napi_should_run(unsigned int cpu) +{ + struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); + struct napi_struct *napi = &sd->backlog; + + return test_bit(NAPI_STATE_SCHED_THREADED, &napi->state); +} + +static void run_backlog_napi(unsigned int cpu) +{ + struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); + + napi_threaded_poll_loop(&sd->backlog); +} + +static void backlog_napi_setup(unsigned int cpu) +{ + struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); + struct napi_struct *napi = &sd->backlog; + + napi->thread = this_cpu_read(backlog_napi); + set_bit(NAPI_STATE_THREADED, &napi->state); +} + +static struct smp_hotplug_thread backlog_threads = { + .store = &backlog_napi, + .thread_should_run = backlog_napi_should_run, + .thread_fn = run_backlog_napi, + .thread_comm = "backlog_napi/%u", + .setup = backlog_napi_setup, +}; + /* * This is called single threaded during boot, so no need * to take the rtnl semaphore. @@ -11672,7 +11747,10 @@ static int __init net_dev_init(void) init_gro_hash(&sd->backlog); sd->backlog.poll = process_backlog; sd->backlog.weight = weight_p; + INIT_LIST_HEAD(&sd->backlog.poll_list); } + if (use_backlog_threads()) + smpboot_register_percpu_thread(&backlog_threads); dev_boot_phase = 0; -- Gitee From 37c37d7c141af583941cde06a5c226beeed6da6f Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Thu, 8 Jan 2026 18:05:39 +0800 Subject: [PATCH 0875/1449] RDMA/rxe: Remove the direct link to net_device ANBZ: #35228 commit 32ca3557d968e662957131374a5f81c9c9cdbba8 stable. commit 2ac5415022d16d63d912a39a06f32f1f51140261 upstream. The similar patch in siw is in the link: https://git.kernel.org/rdma/rdma/c/16b87037b48889 This problem also occurred in RXE. The following analyze this problem. In the following Call Traces: " BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 Read of size 4 at addr ffff8880554640b0 by task kworker/1:4/5295 CPU: 1 UID: 0 PID: 5295 Comm: kworker/1:4 Not tainted 6.12.0-rc3-syzkaller-00399-g9197b73fd7bb #0 Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Workqueue: infiniband ib_cache_event_task Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 dev_get_flags+0x188/0x1d0 net/core/dev.c:8782 rxe_query_port+0x12d/0x260 drivers/infiniband/sw/rxe/rxe_verbs.c:60 __ib_query_port drivers/infiniband/core/device.c:2111 [inline] ib_query_port+0x168/0x7d0 drivers/infiniband/core/device.c:2143 ib_cache_update+0x1a9/0xb80 drivers/infiniband/core/cache.c:1494 ib_cache_event_task+0xf3/0x1e0 drivers/infiniband/core/cache.c:1568 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa65/0x1850 kernel/workqueue.c:3310 worker_thread+0x870/0xd30 kernel/workqueue.c:3391 kthread+0x2f2/0x390 kernel/kthread.c:389 ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 " 1). In the link [1], " infiniband syz2: set down " This means that on 839.350575, the event ib_cache_event_task was sent andi queued in ib_wq. 2). In the link [1], " team0 (unregistering): Port device team_slave_0 removed " It indicates that before 843.251853, the net device should be freed. 3). In the link [1], " BUG: KASAN: slab-use-after-free in dev_get_flags+0x188/0x1d0 " This means that on 850.559070, this slab-use-after-free problem occurred. In all, on 839.350575, the event ib_cache_event_task was sent and queued in ib_wq, before 843.251853, the net device veth was freed. on 850.559070, this event was executed, and the mentioned freed net device was called. Thus, the above call trace occurred. [1] https://syzkaller.appspot.com/x/log.txt?x=12e7025f980000 Reported-by: syzbot+4b87489410b4efd181bf@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4b87489410b4efd181bf Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Zhu Yanjun Link: https://patch.msgid.link/20241220222325.2487767-1-yanjun.zhu@linux.dev Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin [Shivani: - exported ib_device_get_netdev() function. - added ib_device_get_netdev() to ib_verbs.h.] Signed-off-by: Shivani Agarwal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/core/device.c | 1 + drivers/infiniband/sw/rxe/rxe.c | 23 +++++++++++++++++++---- drivers/infiniband/sw/rxe/rxe.h | 3 ++- drivers/infiniband/sw/rxe/rxe_mcast.c | 22 ++++++++++++++++++++-- drivers/infiniband/sw/rxe/rxe_net.c | 25 ++++++++++++++++++++----- drivers/infiniband/sw/rxe/rxe_verbs.c | 26 +++++++++++++++++++++----- drivers/infiniband/sw/rxe/rxe_verbs.h | 11 ++++++++--- include/rdma/ib_verbs.h | 2 ++ 8 files changed, 93 insertions(+), 20 deletions(-) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 9c11b6818f06..d5931bb1de41 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2259,6 +2259,7 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev, return res; } +EXPORT_SYMBOL(ib_device_get_netdev); /** * ib_device_get_by_netdev - Find an IB device associated with a netdev diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 0f8356cea293..1fb4fa4514bf 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -40,6 +40,8 @@ void rxe_dealloc(struct ib_device *ib_dev) /* initialize rxe device parameters */ static void rxe_init_device_param(struct rxe_dev *rxe) { + struct net_device *ndev; + rxe->max_inline_data = RXE_MAX_INLINE_DATA; rxe->attr.vendor_id = RXE_VENDOR_ID; @@ -71,8 +73,15 @@ static void rxe_init_device_param(struct rxe_dev *rxe) rxe->attr.max_fast_reg_page_list_len = RXE_MAX_FMR_PAGE_LIST_LEN; rxe->attr.max_pkeys = RXE_MAX_PKEYS; rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY; + + ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); + if (!ndev) + return; + addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid, - rxe->ndev->dev_addr); + ndev->dev_addr); + + dev_put(ndev); rxe->max_ucontext = RXE_MAX_UCONTEXT; } @@ -109,10 +118,15 @@ static void rxe_init_port_param(struct rxe_port *port) static void rxe_init_ports(struct rxe_dev *rxe) { struct rxe_port *port = &rxe->port; + struct net_device *ndev; rxe_init_port_param(port); + ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); + if (!ndev) + return; addrconf_addr_eui48((unsigned char *)&port->port_guid, - rxe->ndev->dev_addr); + ndev->dev_addr); + dev_put(ndev); spin_lock_init(&port->port_lock); } @@ -169,12 +183,13 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) /* called by ifc layer to create new rxe device. * The caller should allocate memory for rxe by calling ib_alloc_device. */ -int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name) +int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name, + struct net_device *ndev) { rxe_init(rxe); rxe_set_mtu(rxe, mtu); - return rxe_register_device(rxe, ibdev_name); + return rxe_register_device(rxe, ibdev_name, ndev); } static int rxe_newlink(const char *ibdev_name, struct net_device *ndev) diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h index d8fb2c7af30a..fe7f97066732 100644 --- a/drivers/infiniband/sw/rxe/rxe.h +++ b/drivers/infiniband/sw/rxe/rxe.h @@ -139,7 +139,8 @@ enum resp_states { void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); -int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name); +int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name, + struct net_device *ndev); void rxe_rcv(struct sk_buff *skb); diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 86cc2e18a7fd..07ff47bae31d 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -31,10 +31,19 @@ static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid) { unsigned char ll_addr[ETH_ALEN]; + struct net_device *ndev; + int ret; + + ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); + if (!ndev) + return -ENODEV; ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr); - return dev_mc_add(rxe->ndev, ll_addr); + ret = dev_mc_add(ndev, ll_addr); + dev_put(ndev); + + return ret; } /** @@ -47,10 +56,19 @@ static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid) static int rxe_mcast_del(struct rxe_dev *rxe, union ib_gid *mgid) { unsigned char ll_addr[ETH_ALEN]; + struct net_device *ndev; + int ret; + + ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); + if (!ndev) + return -ENODEV; ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr); - return dev_mc_del(rxe->ndev, ll_addr); + ret = dev_mc_del(ndev, ll_addr); + dev_put(ndev); + + return ret; } /** diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index e5827064ab1e..e2859bbc9a71 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -509,7 +509,16 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, */ const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num) { - return rxe->ndev->name; + struct net_device *ndev; + char *ndev_name; + + ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); + if (!ndev) + return NULL; + ndev_name = ndev->name; + dev_put(ndev); + + return ndev_name; } int rxe_net_add(const char *ibdev_name, struct net_device *ndev) @@ -521,9 +530,7 @@ int rxe_net_add(const char *ibdev_name, struct net_device *ndev) if (!rxe) return -ENOMEM; - rxe->ndev = ndev; - - err = rxe_add(rxe, ndev->mtu, ibdev_name); + err = rxe_add(rxe, ndev->mtu, ibdev_name, ndev); if (err) { ib_dealloc_device(&rxe->ib_dev); return err; @@ -571,10 +578,18 @@ void rxe_port_down(struct rxe_dev *rxe) void rxe_set_port_state(struct rxe_dev *rxe) { - if (netif_running(rxe->ndev) && netif_carrier_ok(rxe->ndev)) + struct net_device *ndev; + + ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); + if (!ndev) + return; + + if (netif_running(ndev) && netif_carrier_ok(ndev)) rxe_port_up(rxe); else rxe_port_down(rxe); + + dev_put(ndev); } static int rxe_notify(struct notifier_block *not_blk, diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index dbb9baa4ffd0..102fc5f56ca7 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -41,6 +41,7 @@ static int rxe_query_port(struct ib_device *ibdev, u32 port_num, struct ib_port_attr *attr) { struct rxe_dev *rxe = to_rdev(ibdev); + struct net_device *ndev; int err, ret; if (port_num != 1) { @@ -51,19 +52,26 @@ static int rxe_query_port(struct ib_device *ibdev, memcpy(attr, &rxe->port.attr, sizeof(*attr)); + ndev = rxe_ib_device_get_netdev(ibdev); + if (!ndev) { + err = -ENODEV; + goto err_out; + } + mutex_lock(&rxe->usdev_lock); ret = ib_get_eth_speed(ibdev, port_num, &attr->active_speed, &attr->active_width); if (attr->state == IB_PORT_ACTIVE) attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP; - else if (dev_get_flags(rxe->ndev) & IFF_UP) + else if (dev_get_flags(ndev) & IFF_UP) attr->phys_state = IB_PORT_PHYS_STATE_POLLING; else attr->phys_state = IB_PORT_PHYS_STATE_DISABLED; mutex_unlock(&rxe->usdev_lock); + dev_put(ndev); return ret; err_out: @@ -1428,9 +1436,16 @@ static const struct attribute_group rxe_attr_group = { static int rxe_enable_driver(struct ib_device *ib_dev) { struct rxe_dev *rxe = container_of(ib_dev, struct rxe_dev, ib_dev); + struct net_device *ndev; + + ndev = rxe_ib_device_get_netdev(ib_dev); + if (!ndev) + return -ENODEV; rxe_set_port_state(rxe); - dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(rxe->ndev)); + dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(ndev)); + + dev_put(ndev); return 0; } @@ -1498,7 +1513,8 @@ static const struct ib_device_ops rxe_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_mw, rxe_mw, ibmw), }; -int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) +int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name, + struct net_device *ndev) { int err; struct ib_device *dev = &rxe->ib_dev; @@ -1510,13 +1526,13 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) dev->num_comp_vectors = num_possible_cpus(); dev->local_dma_lkey = 0; addrconf_addr_eui48((unsigned char *)&dev->node_guid, - rxe->ndev->dev_addr); + ndev->dev_addr); dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND) | BIT_ULL(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ); ib_set_device_ops(dev, &rxe_dev_ops); - err = ib_device_set_netdev(&rxe->ib_dev, rxe->ndev, 1); + err = ib_device_set_netdev(&rxe->ib_dev, ndev, 1); if (err) return err; diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index ccb9d19ffe8a..4242b24a47da 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -369,6 +369,7 @@ struct rxe_port { u32 qp_gsi_index; }; +#define RXE_PORT 1 struct rxe_dev { struct ib_device ib_dev; struct ib_device_attr attr; @@ -376,8 +377,6 @@ struct rxe_dev { int max_inline_data; struct mutex usdev_lock; - struct net_device *ndev; - struct rxe_pool uc_pool; struct rxe_pool pd_pool; struct rxe_pool ah_pool; @@ -405,6 +404,11 @@ struct rxe_dev { struct crypto_shash *tfm; }; +static inline struct net_device *rxe_ib_device_get_netdev(struct ib_device *dev) +{ + return ib_device_get_netdev(dev, RXE_PORT); +} + static inline void rxe_counter_inc(struct rxe_dev *rxe, enum rxe_counters index) { atomic64_inc(&rxe->stats_counters[index]); @@ -470,6 +474,7 @@ static inline struct rxe_pd *rxe_mw_pd(struct rxe_mw *mw) return to_rpd(mw->ibmw.pd); } -int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name); +int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name, + struct net_device *ndev); #endif /* RXE_VERBS_H */ diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 6df22f674f99..0c1585a3753f 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -4466,6 +4466,8 @@ struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u32 port, const struct sockaddr *addr); int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, unsigned int port); +struct net_device *ib_device_get_netdev(struct ib_device *ib_dev, + u32 port); struct ib_wq *ib_create_wq(struct ib_pd *pd, struct ib_wq_init_attr *init_attr); int ib_destroy_wq_user(struct ib_wq *wq, struct ib_udata *udata); -- Gitee From c9e2176e56e2a6797d9764ab62ab940b6c11353d Mon Sep 17 00:00:00 2001 From: Zhu Yanjun Date: Thu, 8 Jan 2026 18:05:40 +0800 Subject: [PATCH 0876/1449] RDMA/rxe: Fix the failure of ibv_query_device() and ibv_query_device_ex() tests ANBZ: #35228 commit c62c5296fdb8fb7b017188f28d2801ebb67c3156 stable. commit 8ce2eb9dfac8743d1c423b86339336a5b6a6069e upstream. In rdma-core, the following failures appear. " $ ./build/bin/run_tests.py -k device ssssssss....FF........s ====================================================================== FAIL: test_query_device (tests.test_device.DeviceTest.test_query_device) Test ibv_query_device() ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/ubuntu/rdma-core/tests/test_device.py", line 63, in test_query_device self.verify_device_attr(attr, dev) File "/home/ubuntu/rdma-core/tests/test_device.py", line 200, in verify_device_attr assert attr.sys_image_guid != 0 ^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError ====================================================================== FAIL: test_query_device_ex (tests.test_device.DeviceTest.test_query_device_ex) Test ibv_query_device_ex() ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/ubuntu/rdma-core/tests/test_device.py", line 222, in test_query_device_ex self.verify_device_attr(attr_ex.orig_attr, dev) File "/home/ubuntu/rdma-core/tests/test_device.py", line 200, in verify_device_attr assert attr.sys_image_guid != 0 ^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError " The root cause is: before a net device is set with rxe, this net device is used to generate a sys_image_guid. Fixes: 2ac5415022d1 ("RDMA/rxe: Remove the direct link to net_device") Signed-off-by: Zhu Yanjun Link: https://patch.msgid.link/20250302215444.3742072-1-yanjun.zhu@linux.dev Reviewed-by: Daisuke Matsuda Tested-by: Daisuke Matsuda Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin [Shivani: Modified to apply on 6.6.y] Signed-off-by: Shivani Agarwal Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/infiniband/sw/rxe/rxe.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 1fb4fa4514bf..50c583a55464 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -38,10 +38,8 @@ void rxe_dealloc(struct ib_device *ib_dev) } /* initialize rxe device parameters */ -static void rxe_init_device_param(struct rxe_dev *rxe) +static void rxe_init_device_param(struct rxe_dev *rxe, struct net_device *ndev) { - struct net_device *ndev; - rxe->max_inline_data = RXE_MAX_INLINE_DATA; rxe->attr.vendor_id = RXE_VENDOR_ID; @@ -74,15 +72,9 @@ static void rxe_init_device_param(struct rxe_dev *rxe) rxe->attr.max_pkeys = RXE_MAX_PKEYS; rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY; - ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); - if (!ndev) - return; - addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid, ndev->dev_addr); - dev_put(ndev); - rxe->max_ucontext = RXE_MAX_UCONTEXT; } @@ -115,18 +107,13 @@ static void rxe_init_port_param(struct rxe_port *port) /* initialize port state, note IB convention that HCA ports are always * numbered from 1 */ -static void rxe_init_ports(struct rxe_dev *rxe) +static void rxe_init_ports(struct rxe_dev *rxe, struct net_device *ndev) { struct rxe_port *port = &rxe->port; - struct net_device *ndev; rxe_init_port_param(port); - ndev = rxe_ib_device_get_netdev(&rxe->ib_dev); - if (!ndev) - return; addrconf_addr_eui48((unsigned char *)&port->port_guid, ndev->dev_addr); - dev_put(ndev); spin_lock_init(&port->port_lock); } @@ -144,12 +131,12 @@ static void rxe_init_pools(struct rxe_dev *rxe) } /* initialize rxe device state */ -static void rxe_init(struct rxe_dev *rxe) +static void rxe_init(struct rxe_dev *rxe, struct net_device *ndev) { /* init default device parameters */ - rxe_init_device_param(rxe); + rxe_init_device_param(rxe, ndev); - rxe_init_ports(rxe); + rxe_init_ports(rxe, ndev); rxe_init_pools(rxe); /* init pending mmap list */ @@ -186,7 +173,7 @@ void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu) int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name, struct net_device *ndev) { - rxe_init(rxe); + rxe_init(rxe, ndev); rxe_set_mtu(rxe, mtu); return rxe_register_device(rxe, ibdev_name, ndev); -- Gitee From df06df08ee5e844df1b3d7af7eb98bd77c069190 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:13 +0800 Subject: [PATCH 0877/1449] mm/damon/tests/vaddr-kunit: handle alloc failures on damon_test_split_evenly_succ() ANBZ: #35228 commit 1c5a0de2687961b1944ad59c6999ee472e731682 stable. commit 0a63a0e7570b9b2631dfb8d836dc572709dce39e upstream. damon_test_split_evenly_succ() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-20-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/vaddr-test.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm/damon/vaddr-test.h b/mm/damon/vaddr-test.h index 0779f7f8390f..292736d3f395 100644 --- a/mm/damon/vaddr-test.h +++ b/mm/damon/vaddr-test.h @@ -284,10 +284,17 @@ static void damon_test_split_evenly_succ(struct kunit *test, unsigned long start, unsigned long end, unsigned int nr_pieces) { struct damon_target *t = damon_new_target(); - struct damon_region *r = damon_new_region(start, end); + struct damon_region *r; unsigned long expected_width = (end - start) / nr_pieces; unsigned long i = 0; + if (!t) + kunit_skip(test, "target alloc fail"); + r = damon_new_region(start, end); + if (!r) { + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } damon_add_region(r, t); KUNIT_EXPECT_EQ(test, damon_va_evenly_split_region(t, r, nr_pieces), 0); -- Gitee From 38db28ba7e5e3676d93db22a23edcce5f97b9c83 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:07 +0800 Subject: [PATCH 0878/1449] mm/damon/tests/core-kunit: handle alloc failres in damon_test_new_filter() ANBZ: #35228 commit 5988035dd57abde3211f085b715564252e74f495 stable. commit 28ab2265e9422ccd81e4beafc0ace90f78de04c4 upstream. damon_test_new_filter() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-14-sj@kernel.org Fixes: 2a158e956b98 ("mm/damon/core-test: add a test for damos_new_filter()") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [6.6+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 6cc8b245586d..2bd14d2bfdbb 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -346,6 +346,8 @@ static void damos_test_new_filter(struct kunit *test) struct damos_filter *filter; filter = damos_new_filter(DAMOS_FILTER_TYPE_ANON, true); + if (!filter) + kunit_skip(test, "filter alloc fail"); KUNIT_EXPECT_EQ(test, filter->type, DAMOS_FILTER_TYPE_ANON); KUNIT_EXPECT_EQ(test, filter->matching, true); KUNIT_EXPECT_PTR_EQ(test, filter->list.prev, &filter->list); -- Gitee From 5d4a242f189a7941057bd5b11648e5ccf064f787 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:19:56 +0800 Subject: [PATCH 0879/1449] mm/damon/tests/core-kunit: handle allocation failures in damon_test_regions() ANBZ: #35228 commit c6e1f6e91e9cef06e54a03de35de5311fc47dc30 stable. commit e16fdd4f754048d6e23c56bd8d920b71e41e3777 upstream. damon_test_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-3-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 2bd14d2bfdbb..24ef1462c604 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -20,11 +20,17 @@ static void damon_test_regions(struct kunit *test) struct damon_target *t; r = damon_new_region(1, 2); + if (!r) + kunit_skip(test, "region alloc fail"); KUNIT_EXPECT_EQ(test, 1ul, r->ar.start); KUNIT_EXPECT_EQ(test, 2ul, r->ar.end); KUNIT_EXPECT_EQ(test, 0u, r->nr_accesses); t = damon_new_target(); + if (!t) { + damon_free_region(r); + kunit_skip(test, "target alloc fail"); + } KUNIT_EXPECT_EQ(test, 0u, damon_nr_regions(t)); damon_add_region(r, t); -- Gitee From 667bf0ddb73ee4e2034127563bd1684ccb443187 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:19:59 +0800 Subject: [PATCH 0880/1449] mm/damon/tests/core-kunit: handle alloc failures on damon_test_split_at() ANBZ: #35228 commit 8feb7885b769cdad63a45c8d477b7e09a7b773f5 stable. commit 5e80d73f22043c59c8ad36452a3253937ed77955 upstream. damon_test_split_at() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-6-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 24ef1462c604..66c02253b313 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -129,8 +129,19 @@ static void damon_test_split_at(struct kunit *test) struct damon_target *t; struct damon_region *r; + if (!c) + kunit_skip(test, "ctx alloc fail"); t = damon_new_target(); + if (!t) { + damon_destroy_ctx(c); + kunit_skip(test, "target alloc fail"); + } r = damon_new_region(0, 100); + if (!r) { + damon_destroy_ctx(c); + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } damon_add_region(r, t); damon_split_region_at(t, r, 25); KUNIT_EXPECT_EQ(test, r->ar.start, 0ul); -- Gitee From 300ec83e1928bc111997f8746d65eb173564b8cc Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:01 +0800 Subject: [PATCH 0881/1449] mm/damon/tests/core-kunit: handle alloc failures on dasmon_test_merge_regions_of() ANBZ: #35228 commit 7110f671d86a5980dea49367ecdf8c81c305718e stable. commit 0998d2757218771c59d5ca59ccf13d1542a38f17 upstream. damon_test_merge_regions_of() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-8-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 66c02253b313..02135cac70b3 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -210,8 +210,14 @@ static void damon_test_merge_regions_of(struct kunit *test) int i; t = damon_new_target(); + if (!t) + kunit_skip(test, "target alloc fail"); for (i = 0; i < ARRAY_SIZE(sa); i++) { r = damon_new_region(sa[i], ea[i]); + if (!r) { + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } r->nr_accesses = nrs[i]; damon_add_region(r, t); } -- Gitee From 85ac66607480a535f4bc989865a5f9a65f332e36 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:00 +0800 Subject: [PATCH 0882/1449] mm/damon/tests/core-kunit: handle alloc failures on damon_test_merge_two() ANBZ: #35228 commit 3fc04a106f87f8db0f342600266997c36bb69ebd stable. commit 3d443dd29a1db7efa587a4bb0c06a497e13ca9e4 upstream. damon_test_merge_two() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-7-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 02135cac70b3..fc950fad0440 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -162,10 +162,20 @@ static void damon_test_merge_two(struct kunit *test) int i; t = damon_new_target(); + if (!t) + kunit_skip(test, "target alloc fail"); r = damon_new_region(0, 100); + if (!r) { + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } r->nr_accesses = 10; damon_add_region(r, t); r2 = damon_new_region(100, 300); + if (!r2) { + damon_free_target(t); + kunit_skip(test, "second region alloc fail"); + } r2->nr_accesses = 20; damon_add_region(r2, t); -- Gitee From 4b7447e3f43b8c623b65c4a90c246e7edfcab879 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:19:57 +0800 Subject: [PATCH 0883/1449] mm/damon/tests/core-kunit: handle memory failure from damon_test_target() ANBZ: #35228 commit 945e0575dcfce8dd8f1d4efb8cf3af5dde342ea4 stable. commit fafe953de2c661907c94055a2497c6b8dbfd26f3 upstream. damon_test_target() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-4-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index fc950fad0440..91dd41a6b7fb 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -58,7 +58,14 @@ static void damon_test_target(struct kunit *test) struct damon_ctx *c = damon_new_ctx(); struct damon_target *t; + if (!c) + kunit_skip(test, "ctx alloc fail"); + t = damon_new_target(); + if (!t) { + damon_destroy_ctx(c); + kunit_skip(test, "target alloc fail"); + } KUNIT_EXPECT_EQ(test, 0u, nr_damon_targets(c)); damon_add_target(c, t); -- Gitee From 1c483ceb1d70e4a4cba2264fcec5dc9f966036ab Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:02 +0800 Subject: [PATCH 0884/1449] mm/damon/tests/core-kunit: handle alloc failures on damon_test_split_regions_of() ANBZ: #35228 commit 520e8b12f0a47488f93998063b0422c82de4c80c stable. commit eded254cb69044bd4abde87394ea44909708d7c0 upstream. damon_test_split_regions_of() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-9-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 91dd41a6b7fb..f2e5cdb277a0 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -256,15 +256,35 @@ static void damon_test_split_regions_of(struct kunit *test) struct damon_target *t; struct damon_region *r; + if (!c) + kunit_skip(test, "ctx alloc fail"); t = damon_new_target(); + if (!t) { + damon_destroy_ctx(c); + kunit_skip(test, "target alloc fail"); + } r = damon_new_region(0, 22); + if (!r) { + damon_destroy_ctx(c); + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } damon_add_region(r, t); damon_split_regions_of(t, 2); KUNIT_EXPECT_LE(test, damon_nr_regions(t), 2u); damon_free_target(t); t = damon_new_target(); + if (!t) { + damon_destroy_ctx(c); + kunit_skip(test, "second target alloc fail"); + } r = damon_new_region(0, 220); + if (!r) { + damon_destroy_ctx(c); + damon_free_target(t); + kunit_skip(test, "second region alloc fail"); + } damon_add_region(r, t); damon_split_regions_of(t, 4); KUNIT_EXPECT_LE(test, damon_nr_regions(t), 4u); -- Gitee From 47a8f1ea3c2d47aba142b8e9be42102d2944fbe4 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:19:58 +0800 Subject: [PATCH 0885/1449] mm/damon/tests/core-kunit: handle memory alloc failure from damon_test_aggregate() ANBZ: #35228 commit 8b6d3b7c12bd07df956b8c29e828dca833cefcd6 stable. commit f79f2fc44ebd0ed655239046be3e80e8804b5545 upstream. damon_test_aggregate() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-5-sj@kernel.org Fixes: 17ccae8bb5c9 ("mm/damon: add kunit tests") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.15+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index f2e5cdb277a0..6014b915eb69 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -97,8 +97,15 @@ static void damon_test_aggregate(struct kunit *test) struct damon_region *r; int it, ir; + if (!ctx) + kunit_skip(test, "ctx alloc fail"); + for (it = 0; it < 3; it++) { t = damon_new_target(); + if (!t) { + damon_destroy_ctx(ctx); + kunit_skip(test, "target alloc fail"); + } damon_add_target(ctx, t); } @@ -106,6 +113,10 @@ static void damon_test_aggregate(struct kunit *test) damon_for_each_target(t, ctx) { for (ir = 0; ir < 3; ir++) { r = damon_new_region(saddr[it][ir], eaddr[it][ir]); + if (!r) { + damon_destroy_ctx(ctx); + kunit_skip(test, "region alloc fail"); + } r->nr_accesses = accesses[it][ir]; damon_add_region(r, t); } -- Gitee From 576bf33639ff960bd5a243feccd5786a8cd44885 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:09 +0800 Subject: [PATCH 0886/1449] mm/damon/tests/core-kunit: handle alloc failures on damos_test_filter_out() ANBZ: #35228 commit e471ed55f3d6a83f64f4b56b5b372b9ded1b1430 stable. commit d14d5671e7c9cc788c5a1edfa94e6f9064275905 upstream. damon_test_filter_out() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-16-sj@kernel.org Fixes: 26713c890875 ("mm/damon/core-test: add a unit test for __damos_filter_out()") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [6.6+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 6014b915eb69..409d926e5630 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -433,11 +433,22 @@ static void damos_test_filter_out(struct kunit *test) struct damos_filter *f; f = damos_new_filter(DAMOS_FILTER_TYPE_ADDR, true); + if (!f) + kunit_skip(test, "filter alloc fail"); f->addr_range = (struct damon_addr_range){ .start = DAMON_MIN_REGION * 2, .end = DAMON_MIN_REGION * 6}; t = damon_new_target(); + if (!t) { + damos_destroy_filter(f); + kunit_skip(test, "target alloc fail"); + } r = damon_new_region(DAMON_MIN_REGION * 3, DAMON_MIN_REGION * 5); + if (!r) { + damos_destroy_filter(f); + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } damon_add_region(r, t); /* region in the range */ -- Gitee From 560328abc53d7101602be70aa154d6fd1b8ddd2f Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:04 +0800 Subject: [PATCH 0887/1449] mm/damon/tests/core-kunit: handle alloc failures in damon_test_set_regions() ANBZ: #35228 commit d41809aa8e24174981d75fe52beff14b28e4b5e8 stable. commit 74d5969995d129fd59dd93b9c7daa6669cb6810f upstream. damon_test_set_regions() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-11-sj@kernel.org Fixes: 62f409560eb2 ("mm/damon/core-test: test damon_set_regions") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [6.1+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 409d926e5630..e71d50f0a2df 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -341,13 +341,26 @@ static void damon_test_ops_registration(struct kunit *test) static void damon_test_set_regions(struct kunit *test) { struct damon_target *t = damon_new_target(); - struct damon_region *r1 = damon_new_region(4, 16); - struct damon_region *r2 = damon_new_region(24, 32); + struct damon_region *r1, *r2; struct damon_addr_range range = {.start = 8, .end = 28}; unsigned long expects[] = {8, 16, 16, 24, 24, 28}; int expect_idx = 0; struct damon_region *r; + if (!t) + kunit_skip(test, "target alloc fail"); + r1 = damon_new_region(4, 16); + if (!r1) { + damon_free_target(t); + kunit_skip(test, "region alloc fail"); + } + r2 = damon_new_region(24, 32); + if (!r2) { + damon_free_target(t); + damon_free_region(r1); + kunit_skip(test, "second region alloc fail"); + } + damon_add_region(r1, t); damon_add_region(r2, t); damon_set_regions(t, &range, 1); -- Gitee From e3c76e13176586cdf330bf5b588903cb0c6c2d4a Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:03 +0800 Subject: [PATCH 0888/1449] mm/damon/tests/core-kunit: handle alloc failures in damon_test_ops_registration() ANBZ: #35228 commit c45dcf86c75eef78456f01e4705572ada5ced754 stable. commit 4f835f4e8c863985f15abd69db033c2f66546094 upstream. damon_test_ops_registration() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-10-sj@kernel.org Fixes: 4f540f5ab4f2 ("mm/damon/core-test: add a kunit test case for ops registration") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [5.19+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index e71d50f0a2df..d714fe76e35d 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -308,6 +308,9 @@ static void damon_test_ops_registration(struct kunit *test) struct damon_ctx *c = damon_new_ctx(); struct damon_operations ops, bak; + if (!c) + kunit_skip(test, "ctx alloc fail"); + /* DAMON_OPS_{V,P}ADDR are registered on subsys_initcall */ KUNIT_EXPECT_EQ(test, damon_select_ops(c, DAMON_OPS_VADDR), 0); KUNIT_EXPECT_EQ(test, damon_select_ops(c, DAMON_OPS_PADDR), 0); -- Gitee From a441a4b2f9f03bd20892d0e254be73ecad0ec886 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:06 +0800 Subject: [PATCH 0889/1449] mm/damon/tests/core-kunit: handle alloc failure on damon_test_set_attrs() ANBZ: #35228 commit 8bf34bd1223109121b0422e55b9850ab663eb0b9 stable. commit 915a2453d824a9b6bf724e3f970d86ae1d092a61 upstream. damon_test_set_attrs() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-13-sj@kernel.org Fixes: aa13779be6b7 ("mm/damon/core-test: add a test for damon_set_attrs()") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [6.5+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index d714fe76e35d..030a11a9f3cf 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -413,6 +413,9 @@ static void damon_test_set_attrs(struct kunit *test) .sample_interval = 5000, .aggr_interval = 100000,}; struct damon_attrs invalid_attrs; + if (!c) + kunit_skip(test, "ctx alloc fail"); + KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &valid_attrs), 0); invalid_attrs = valid_attrs; -- Gitee From 6303f4545858c3aa07b5649717f16886baabe4f3 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Sun, 2 Nov 2025 02:20:05 +0800 Subject: [PATCH 0890/1449] mm/damon/tests/core-kunit: handle alloc failures in damon_test_update_monitoring_result() ANBZ: #35228 commit 8d8a670c1c287e18c20ec2f996274423e9b24952 stable. commit 8cf298c01b7fdb08eef5b6b26d0fe98d48134d72 upstream. damon_test_update_monitoring_result() is assuming all dynamic memory allocation in it will succeed. Those are indeed likely in the real use cases since those allocations are too small to fail, but theoretically those could fail. In the case, inappropriate memory access can happen. Fix it by appropriately cleanup pre-allocated memory and skip the execution of the remaining tests in the failure cases. Link: https://lkml.kernel.org/r/20251101182021.74868-12-sj@kernel.org Fixes: f4c978b6594b ("mm/damon/core-test: add a test for damon_update_monitoring_results()") Signed-off-by: SeongJae Park Cc: Brendan Higgins Cc: David Gow Cc: Kefeng Wang Cc: [6.3+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/core-test.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index 030a11a9f3cf..a2aa410d6d0d 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -383,6 +383,9 @@ static void damon_test_update_monitoring_result(struct kunit *test) struct damon_attrs new_attrs; struct damon_region *r = damon_new_region(3, 7); + if (!r) + kunit_skip(test, "region alloc fail"); + r->nr_accesses = 15; r->age = 20; -- Gitee From 442bf37a54d8dfbae9a90d88fa2b40eda7890fbf Mon Sep 17 00:00:00 2001 From: Maximilian Immanuel Brandtner Date: Mon, 24 Mar 2025 22:42:46 +0800 Subject: [PATCH 0891/1449] virtio_console: fix order of fields cols and rows ANBZ: #35228 commit f6dcbd2bbea5e43f33e31d09667fd7e59c40aab9 stable. commit 5326ab737a47278dbd16ed3ee7380b26c7056ddd upstream. According to section 5.3.6.2 (Multiport Device Operation) of the virtio spec(version 1.2) a control buffer with the event VIRTIO_CONSOLE_RESIZE is followed by a virtio_console_resize struct containing cols then rows. The kernel implements this the wrong way around (rows then cols) resulting in the two values being swapped. Signed-off-by: Maximilian Immanuel Brandtner Message-Id: <20250324144300.905535-1-maxbr@linux.ibm.com> Signed-off-by: Michael S. Tsirkin Cc: Filip Hejsek Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/char/virtio_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 80e0f485170a..f09b02f85cf6 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1612,8 +1612,8 @@ static void handle_control_message(struct virtio_device *vdev, break; case VIRTIO_CONSOLE_RESIZE: { struct { - __virtio16 rows; __virtio16 cols; + __virtio16 rows; } size; if (!is_console_port(port)) -- Gitee From 1188629bf40a07d97eccf3d02ba0bdd5067d8c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= Date: Thu, 29 May 2025 17:07:24 +0800 Subject: [PATCH 0892/1449] net: stmmac: make sure that ptp_rate is not 0 before configuring EST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit b92ec4a848728460f181def33735605f154d438f stable. commit cbefe2ffa7784525ec5d008ba87c7add19ec631a upstream. If the ptp_rate recorded earlier in the driver happens to be 0, this bogus value will propagate up to EST configuration, where it will trigger a division by 0. Prevent this division by 0 by adding the corresponding check and error code. Suggested-by: Maxime Chevallier Signed-off-by: Alexis Lothoré Fixes: 8572aec3d0dc ("net: stmmac: Add basic EST support for XGMAC") Link: https://patch.msgid.link/20250529-stmmac_tstamp_div-v4-2-d73340a794d5@bootlin.com Signed-off-by: Jakub Kicinski [ The context change is due to the commit c3f3b97238f6 ("net: stmmac: Refactor EST implementation") which is irrelevant to the logic of this patch. ] Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 5 +++++ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c index 8fd167501fa0..0afd4644a985 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c @@ -597,6 +597,11 @@ int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, int i, ret = 0x0; u32 ctrl; + if (!ptp_rate) { + pr_warn("Dwmac5: Invalid PTP rate"); + return -EINVAL; + } + ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false); ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false); ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c index 0bcb378fa0bc..aab02328a613 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c @@ -1537,6 +1537,11 @@ static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, int i, ret = 0x0; u32 ctrl; + if (!ptp_rate) { + pr_warn("Dwxgmac2: Invalid PTP rate"); + return -EINVAL; + } + ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_LOW, cfg->btr[0], false); ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_HIGH, cfg->btr[1], false); ret |= dwxgmac3_est_write(ioaddr, XGMAC_TER, cfg->ter, false); -- Gitee From a5fef59c3b1f513c57638416cebac5f4a295b26d Mon Sep 17 00:00:00 2001 From: Sean Nyekjaer Date: Thu, 8 Jan 2026 20:45:23 +0800 Subject: [PATCH 0893/1449] pwm: stm32: Always program polarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d292db57e9152d7cdc8ed391744b7944471e0ed5 stable. Commit 7346e7a058a2 ("pwm: stm32: Always do lazy disabling") triggered a regression where PWM polarity changes could be ignored. stm32_pwm_set_polarity() was skipped due to a mismatch between the cached pwm->state.polarity and the actual hardware state, leaving the hardware polarity unchanged. Fixes: 7edf7369205b ("pwm: Add driver for STM32 plaftorm") Cc: stable@vger.kernel.org # <= 6.12 Signed-off-by: Sean Nyekjaer Co-developed-by: Uwe Kleine-König Signed-off-by: Uwe Kleine-König Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pwm/pwm-stm32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 67414b97ef4d..b613ce74346a 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -462,8 +462,7 @@ static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, return 0; } - if (state->polarity != pwm->state.polarity) - stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity); + stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity); ret = stm32_pwm_config(priv, pwm->hwpwm, state->duty_cycle, state->period); -- Gitee From 7df7a78adcba5970d8f2735e7e82b01b78cbc64a Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 14 Oct 2024 08:51:15 +0800 Subject: [PATCH 0894/1449] blk-mq: setup queue ->tag_set before initializing hctx ANBZ: #35228 commit 25466e5b4bb11a8415ce8d0be89ab77135f7e444 stable. commit c25c0c9035bb8b28c844dfddeda7b8bdbcfcae95 upstream. Commit 7b815817aa58 ("blk-mq: add helper for checking if one CPU is mapped to specified hctx") needs to check queue mapping via tag set in hctx's cpuhp handler. However, q->tag_set may not be setup yet when the cpuhp handler is enabled, then kernel oops is triggered. Fix the issue by setup queue tag_set before initializing hctx. Cc: stable@vger.kernel.org Reported-and-tested-by: Rick Koch Closes: https://lore.kernel.org/linux-block/CANa58eeNDozLaBHKPLxSAhEy__FPfJT_F71W=sEQw49UCrC9PQ@mail.gmail.com Fixes: 7b815817aa58 ("blk-mq: add helper for checking if one CPU is mapped to specified hctx") Signed-off-by: Ming Lei Reviewed-by: Christoph Hellwig Reviewed-by: John Garry Link: https://lore.kernel.org/r/20241014005115.2699642-1-ming.lei@redhat.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- block/blk-mq.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 71868fc67338..cb56ba23d8e1 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -4518,6 +4518,12 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, /* mark the queue as mq asap */ q->mq_ops = set->ops; + /* + * ->tag_set has to be setup before initialize hctx, which cpuphp + * handler needs it for checking queue mapping + */ + q->tag_set = set; + if (blk_mq_alloc_ctxs(q)) goto err_exit; @@ -4536,8 +4542,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, INIT_WORK(&q->timeout_work, blk_mq_timeout_work); blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); - q->tag_set = set; - q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; blk_mq_update_poll_flag(q); -- Gitee From 81b1f9cb4bb91d32e10b81a05e1392093e68657c Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 24 Jun 2025 16:06:41 +0800 Subject: [PATCH 0895/1449] tty: fix tty_port_tty_*hangup() kernel-doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 21e82354cdd7c954dbcf3e06d8536b40d2813c16 stable. commit 6241b49540a65a6d5274fa938fd3eb4cbfe2e076 upstream. The commit below added a new helper, but omitted to move (and add) the corressponding kernel-doc. Do it now. Signed-off-by: "Jiri Slaby (SUSE)" Fixes: 2b5eac0f8c6e ("tty: introduce and use tty_port_tty_vhangup() helper") Link: https://lore.kernel.org/all/b23d566c-09dc-7374-cc87-0ad4660e8b2e@linux.intel.com/ Reported-by: Ilpo Järvinen Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Link: https://lore.kernel.org/r/20250624080641.509959-6-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/driver-api/tty/tty_port.rst | 5 +++-- drivers/tty/tty_port.c | 5 ----- include/linux/tty_port.h | 9 +++++++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Documentation/driver-api/tty/tty_port.rst b/Documentation/driver-api/tty/tty_port.rst index 5cb90e954fcf..504a353f2682 100644 --- a/Documentation/driver-api/tty/tty_port.rst +++ b/Documentation/driver-api/tty/tty_port.rst @@ -42,9 +42,10 @@ TTY Refcounting TTY Helpers ----------- +.. kernel-doc:: include/linux/tty_port.h + :identifiers: tty_port_tty_hangup tty_port_tty_vhangup .. kernel-doc:: drivers/tty/tty_port.c - :identifiers: tty_port_tty_hangup tty_port_tty_wakeup - + :identifiers: tty_port_tty_wakeup Modem Signals ------------- diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index eb51d1f10d56..21430e64b412 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -409,11 +409,6 @@ void tty_port_hangup(struct tty_port *port) } EXPORT_SYMBOL(tty_port_hangup); -/** - * tty_port_tty_hangup - helper to hang up a tty - * @port: tty port - * @check_clocal: hang only ttys with %CLOCAL unset? - */ void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async) { struct tty_struct *tty = tty_port_tty_get(port); diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h index bc7ba52ba674..47600b18c76f 100644 --- a/include/linux/tty_port.h +++ b/include/linux/tty_port.h @@ -260,11 +260,20 @@ static inline int tty_port_users(struct tty_port *port) return port->count + port->blocked_open; } +/** + * tty_port_tty_hangup - helper to hang up a tty asynchronously + * @port: tty port + * @check_clocal: hang only ttys with %CLOCAL unset? + */ static inline void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) { __tty_port_tty_hangup(port, check_clocal, true); } +/** + * tty_port_tty_vhangup - helper to hang up a tty synchronously + * @port: tty port + */ static inline void tty_port_tty_vhangup(struct tty_port *port) { __tty_port_tty_hangup(port, false, false); -- Gitee From af4ab26fd85203e2713f4168679dc1c004cd9562 Mon Sep 17 00:00:00 2001 From: Amitai Gottlieb Date: Tue, 16 Dec 2025 19:50:09 +0800 Subject: [PATCH 0896/1449] firmware: arm_scmi: Fix unused notifier-block in unregister ANBZ: #35228 commit 0e8ac70521e679fd0e1eca86a536aa797db38b15 stable. In scmi_devm_notifier_unregister(), the notifier-block argument was ignored and never passed to devres_release(). As a result, the function always returned -ENOENT and failed to unregister the notifier. Drivers that depend on this helper for teardown could therefore hit unexpected failures, including kernel panics. Commit 264a2c520628 ("firmware: arm_scmi: Simplify scmi_devm_notifier_unregister") removed the faulty code path during refactoring and hence this fix is not required upstream. Cc: # 5.15.x, 6.1.x, and 6.6.x Fixes: 5ad3d1cf7d34 ("firmware: arm_scmi: Introduce new devres notification ops") Reviewed-by: Dan Carpenter Reviewed-by: Cristian Marussi Signed-off-by: Amitai Gottlieb Reviewed-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/arm_scmi/notify.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c index 0efd20cd9d69..4782b115e6ec 100644 --- a/drivers/firmware/arm_scmi/notify.c +++ b/drivers/firmware/arm_scmi/notify.c @@ -1539,6 +1539,7 @@ static int scmi_devm_notifier_unregister(struct scmi_device *sdev, dres.handle = sdev->handle; dres.proto_id = proto_id; dres.evt_id = evt_id; + dres.nb = nb; if (src_id) { dres.__src_id = *src_id; dres.src_id = &dres.__src_id; -- Gitee From 29ffc8657ac86e1560bb84571a4f0d26e5292b55 Mon Sep 17 00:00:00 2001 From: Lizhi Xu Date: Thu, 8 Jan 2026 23:03:49 +0800 Subject: [PATCH 0897/1449] ext4: filesystems without casefold feature cannot be mounted with siphash ANBZ: #35228 commit 52c4538a92da6f3242d4140c03ddc5ee71b39ba8 stable. commit 985b67cd86392310d9e9326de941c22fc9340eec upstream. When mounting the ext4 filesystem, if the default hash version is set to DX_HASH_SIPHASH but the casefold feature is not set, exit the mounting. Reported-by: syzbot+340581ba9dceb7e06fb3@syzkaller.appspotmail.com Signed-off-by: Lizhi Xu Link: https://patch.msgid.link/20240605012335.44086-1-lizhi.xu@windriver.com Signed-off-by: Theodore Ts'o [cascardo: small conflict fixup] Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/super.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7280ac209131..8da85e0e4084 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3664,6 +3664,14 @@ int ext4_feature_set_ok(struct super_block *sb, int readonly) } #endif + if (EXT4_SB(sb)->s_es->s_def_hash_version == DX_HASH_SIPHASH && + !ext4_has_feature_casefold(sb)) { + ext4_msg(sb, KERN_ERR, + "Filesystem without casefold feature cannot be " + "mounted with siphash"); + return 0; + } + if (readonly) return 1; -- Gitee From a9faed1e6936f64da5d7f41948ac3821f7f464ab Mon Sep 17 00:00:00 2001 From: Gabriel Krisman Bertazi Date: Thu, 8 Jan 2026 23:03:50 +0800 Subject: [PATCH 0898/1449] ext4: fix error message when rejecting the default hash ANBZ: #35228 commit 0eb7d3da258b05538f573200fab751420ca93b2f stable. commit a2187431c395cdfbf144e3536f25468c64fc7cfa upstream. Commit 985b67cd8639 ("ext4: filesystems without casefold feature cannot be mounted with siphash") properly rejects volumes where s_def_hash_version is set to DX_HASH_SIPHASH, but the check and the error message should not look into casefold setup - a filesystem should never have DX_HASH_SIPHASH as the default hash. Fix it and, since we are there, move the check to ext4_hash_info_init. Fixes:985b67cd8639 ("ext4: filesystems without casefold feature cannot be mounted with siphash") Signed-off-by: Gabriel Krisman Bertazi Link: https://patch.msgid.link/87jzg1en6j.fsf_-_@mailhost.krisman.be Signed-off-by: Theodore Ts'o Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/ext4.h | 1 + fs/ext4/super.c | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 2ac7d4d545a8..cfa2d97d7a1f 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2457,6 +2457,7 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize) #define DX_HASH_HALF_MD4_UNSIGNED 4 #define DX_HASH_TEA_UNSIGNED 5 #define DX_HASH_SIPHASH 6 +#define DX_HASH_LAST DX_HASH_SIPHASH static inline u32 ext4_chksum(struct ext4_sb_info *sbi, u32 crc, const void *address, unsigned int length) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8da85e0e4084..db53d2bf5acf 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3664,14 +3664,6 @@ int ext4_feature_set_ok(struct super_block *sb, int readonly) } #endif - if (EXT4_SB(sb)->s_es->s_def_hash_version == DX_HASH_SIPHASH && - !ext4_has_feature_casefold(sb)) { - ext4_msg(sb, KERN_ERR, - "Filesystem without casefold feature cannot be " - "mounted with siphash"); - return 0; - } - if (readonly) return 1; @@ -5181,16 +5173,27 @@ static int ext4_load_super(struct super_block *sb, ext4_fsblk_t *lsb, return ret; } -static void ext4_hash_info_init(struct super_block *sb) +static int ext4_hash_info_init(struct super_block *sb) { struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_super_block *es = sbi->s_es; unsigned int i; + sbi->s_def_hash_version = es->s_def_hash_version; + + if (sbi->s_def_hash_version > DX_HASH_LAST) { + ext4_msg(sb, KERN_ERR, + "Invalid default hash set in the superblock"); + return -EINVAL; + } else if (sbi->s_def_hash_version == DX_HASH_SIPHASH) { + ext4_msg(sb, KERN_ERR, + "SIPHASH is not a valid default hash value"); + return -EINVAL; + } + for (i = 0; i < 4; i++) sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); - sbi->s_def_hash_version = es->s_def_hash_version; if (ext4_has_feature_dir_index(sb)) { i = le32_to_cpu(es->s_flags); if (i & EXT2_FLAGS_UNSIGNED_HASH) @@ -5208,6 +5211,7 @@ static void ext4_hash_info_init(struct super_block *sb) #endif } } + return 0; } static int ext4_block_group_meta_init(struct super_block *sb, int silent) @@ -5360,7 +5364,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) if (err) goto failed_mount; - ext4_hash_info_init(sb); + err = ext4_hash_info_init(sb); + if (err) + goto failed_mount; err = ext4_handle_clustersize(sb); if (err) -- Gitee From 0a62db27570a795cb20e9d3f52987c3df485a39c Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Thu, 11 Dec 2025 20:34:34 +0800 Subject: [PATCH 0899/1449] NFSD: Fix permission check for read access to executable-only files ANBZ: #35228 commit e15e59b5aa624ed3b0c10c92d42623dd6fd707a9 stable. commit e901c7fce59e72d9f3c92733c379849c4034ac50 upstream. Commit abc02e5602f7 ("NFSD: Support write delegations in LAYOUTGET") added NFSD_MAY_OWNER_OVERRIDE to the access flags passed from nfsd4_layoutget() to fh_verify(). This causes LAYOUTGET to fail for executable-only files, and causes xfstests generic/126 to fail on pNFS SCSI. To allow read access to executable-only files, what we really want is: 1. The "permissions" portion of the access flags (the lower 6 bits) must be exactly NFSD_MAY_READ 2. The "hints" portion of the access flags (the upper 26 bits) can contain any combination of NFSD_MAY_OWNER_OVERRIDE and NFSD_MAY_READ_IF_EXEC Fixes: abc02e5602f7 ("NFSD: Support write delegations in LAYOUTGET") Cc: stable@vger.kernel.org # v6.6+ Signed-off-by: Scott Mayhew Reviewed-by: Jeff Layton Reviewed-by: NeilBrown Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/vfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 4133238faa66..0152ba1a45ab 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2481,8 +2481,8 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && - (acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE) || - acc == (NFSD_MAY_READ | NFSD_MAY_READ_IF_EXEC))) + (((acc & NFSD_MAY_MASK) == NFSD_MAY_READ) && + (acc & (NFSD_MAY_OWNER_OVERRIDE | NFSD_MAY_READ_IF_EXEC)))) err = inode_permission(&nop_mnt_idmap, inode, MAY_EXEC); return err? nfserrno(err) : 0; -- Gitee From ae5cee4627812ed36f59184b3e748806ad117d7e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 13 Dec 2025 13:41:59 -0500 Subject: [PATCH 0900/1449] nfsd: provide locking for v4_end_grace ANBZ: #35228 commit 06600719d0f7a723811c45e4d51f5b742f345309 stable. commit 2857bd59feb63fcf40fe4baf55401baea6b4feb4 upstream. Writing to v4_end_grace can race with server shutdown and result in memory being accessed after it was freed - reclaim_str_hashtbl in particularly. We cannot hold nfsd_mutex across the nfsd4_end_grace() call as that is held while client_tracking_op->init() is called and that can wait for an upcall to nfsdcltrack which can write to v4_end_grace, resulting in a deadlock. nfsd4_end_grace() is also called by the landromat work queue and this doesn't require locking as server shutdown will stop the work and wait for it before freeing anything that nfsd4_end_grace() might access. However, we must be sure that writing to v4_end_grace doesn't restart the work item after shutdown has already waited for it. For this we add a new flag protected with nn->client_lock. It is set only while it is safe to make client tracking calls, and v4_end_grace only schedules work while the flag is set with the spinlock held. So this patch adds a nfsd_net field "client_tracking_active" which is set as described. Another field "grace_end_forced", is set when v4_end_grace is written. After this is set, and providing client_tracking_active is set, the laundromat is scheduled. This "grace_end_forced" field bypasses other checks for whether the grace period has finished. This resolves a race which can result in use-after-free. Reported-by: Li Lingfeng Closes: https://lore.kernel.org/linux-nfs/20250623030015.2353515-1-neil@brown.name/T/#t Fixes: 7f5ef2e900d9 ("nfsd: add a v4_end_grace file to /proc/fs/nfsd") Cc: stable@vger.kernel.org Signed-off-by: NeilBrown Tested-by: Li Lingfeng Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- fs/nfsd/netns.h | 2 ++ fs/nfsd/nfs4state.c | 42 ++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/nfsctl.c | 3 +-- fs/nfsd/state.h | 2 +- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 881ca44ebda4..f8d1a7c13d10 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -65,6 +65,8 @@ struct nfsd_net { struct lock_manager nfsd4_manager; bool grace_ended; + bool grace_end_forced; + bool client_tracking_active; time64_t boot_time; struct dentry *nfsd_client_dir; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1c9b6bf8f9a7..393dd2f019e5 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -84,7 +84,7 @@ static u64 current_sessionid = 1; /* forward declarations */ static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner); static void nfs4_free_ol_stateid(struct nfs4_stid *stid); -void nfsd4_end_grace(struct nfsd_net *nn); +static void nfsd4_end_grace(struct nfsd_net *nn); static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps); static void nfsd4_file_hash_remove(struct nfs4_file *fi); @@ -5923,7 +5923,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return nfs_ok; } -void +static void nfsd4_end_grace(struct nfsd_net *nn) { /* do nothing if grace period already ended */ @@ -5956,6 +5956,33 @@ nfsd4_end_grace(struct nfsd_net *nn) */ } +/** + * nfsd4_force_end_grace - forcibly end the NFSv4 grace period + * @nn: network namespace for the server instance to be updated + * + * Forces bypass of normal grace period completion, then schedules + * the laundromat to end the grace period immediately. Does not wait + * for the grace period to fully terminate before returning. + * + * Return values: + * %true: Grace termination schedule + * %false: No action was taken + */ +bool nfsd4_force_end_grace(struct nfsd_net *nn) +{ + if (!nn->client_tracking_ops) + return false; + spin_lock(&nn->client_lock); + if (nn->grace_ended || !nn->client_tracking_active) { + spin_unlock(&nn->client_lock); + return false; + } + WRITE_ONCE(nn->grace_end_forced, true); + mod_delayed_work(laundry_wq, &nn->laundromat_work, 0); + spin_unlock(&nn->client_lock); + return true; +} + /* * If we've waited a lease period but there are still clients trying to * reclaim, wait a little longer to give them a chance to finish. @@ -5965,6 +5992,8 @@ static bool clients_still_reclaiming(struct nfsd_net *nn) time64_t double_grace_period_end = nn->boot_time + 2 * nn->nfsd4_lease; + if (READ_ONCE(nn->grace_end_forced)) + return false; if (nn->track_reclaim_completes && atomic_read(&nn->nr_reclaim_complete) == nn->reclaim_str_hashtbl_size) @@ -8196,6 +8225,8 @@ static int nfs4_state_create_net(struct net *net) nn->unconf_name_tree = RB_ROOT; nn->boot_time = ktime_get_real_seconds(); nn->grace_ended = false; + nn->grace_end_forced = false; + nn->client_tracking_active = false; nn->nfsd4_manager.block_opens = true; INIT_LIST_HEAD(&nn->nfsd4_manager.list); INIT_LIST_HEAD(&nn->client_lru); @@ -8276,6 +8307,10 @@ nfs4_state_start_net(struct net *net) return ret; locks_start_grace(net, &nn->nfsd4_manager); nfsd4_client_tracking_init(net); + /* safe for laundromat to run now */ + spin_lock(&nn->client_lock); + nn->client_tracking_active = true; + spin_unlock(&nn->client_lock); if (nn->track_reclaim_completes && nn->reclaim_str_hashtbl_size == 0) goto skip_grace; printk(KERN_INFO "NFSD: starting %lld-second grace period (net %x)\n", @@ -8322,6 +8357,9 @@ nfs4_state_shutdown_net(struct net *net) shrinker_free(nn->nfsd_client_shrinker); cancel_work_sync(&nn->nfsd_shrinker_work); + spin_lock(&nn->client_lock); + nn->client_tracking_active = false; + spin_unlock(&nn->client_lock); cancel_delayed_work_sync(&nn->laundromat_work); locks_end_grace(&nn->nfsd4_manager); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 887035b74467..ba8d653de273 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1110,10 +1110,9 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size) case 'Y': case 'y': case '1': - if (!nn->nfsd_serv) + if (!nfsd4_force_end_grace(nn)) return -EBUSY; trace_nfsd_end_grace(netns(file)); - nfsd4_end_grace(nn); break; default: return -EINVAL; diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index cbddcf484dba..5da7785609b0 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -717,7 +717,7 @@ static inline void get_nfs4_file(struct nfs4_file *fi) struct nfsd_file *find_any_file(struct nfs4_file *f); /* grace period management */ -void nfsd4_end_grace(struct nfsd_net *nn); +bool nfsd4_force_end_grace(struct nfsd_net *nn); /* nfs4recover operations */ extern int nfsd4_client_tracking_init(struct net *net); -- Gitee From a1729b4632feb04cbe8c264d2c71d25790765dff Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 7 Jan 2026 17:01:36 +0800 Subject: [PATCH 0901/1449] atm: Fix dma_free_coherent() size ANBZ: #35228 commit 8f5211fc891d029a6edd9a4f87ef5856912aa64f stable. commit 4d984b0574ff708e66152763fbfdef24ea40933f upstream. The size of the buffer is not the same when alloc'd with dma_alloc_coherent() in he_init_tpdrq() and freed. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20260107090141.80900-2-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/atm/he.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/atm/he.c b/drivers/atm/he.c index ad91cc6a34fc..92a041d5387b 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -1587,7 +1587,8 @@ he_stop(struct he_dev *he_dev) he_dev->tbrq_base, he_dev->tbrq_phys); if (he_dev->tpdrq_base) - dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), + dma_free_coherent(&he_dev->pci_dev->dev, + CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq), he_dev->tpdrq_base, he_dev->tpdrq_phys); dma_pool_destroy(he_dev->tpd_pool); -- Gitee From a6a9d9c34a2ffbf174260dbd67a81b93a2947066 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 6 Jan 2026 17:47:21 +0800 Subject: [PATCH 0902/1449] net: 3com: 3c59x: fix possible null dereference in vortex_probe1() ANBZ: #35228 commit 28b2a805609699be7b90020ae7dccfb234be1ceb stable. commit a4e305ed60f7c41bbf9aabc16dd75267194e0de3 upstream. pdev can be null and free_ring: can be called in 1297 with a null pdev. Fixes: 55c82617c3e8 ("3c59x: convert to generic DMA API") Cc: Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20260106094731.25819-2-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/3com/3c59x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 082388bb6169..4a843c2ce111 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -1473,7 +1473,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, return 0; free_ring: - dma_free_coherent(&pdev->dev, + dma_free_coherent(gendev, sizeof(struct boom_rx_desc) * RX_RING_SIZE + sizeof(struct boom_tx_desc) * TX_RING_SIZE, vp->rx_ring, vp->rx_ring_dma); -- Gitee From 9dc6ad770d30a0b419e86284249954ed34555b8d Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 11 Dec 2025 23:06:26 +0800 Subject: [PATCH 0903/1449] btrfs: always detect conflicting inodes when logging inode refs ANBZ: #35228 commit a63998cd6687c14b160dccb0bbcf281b2eb0dab3 stable. commit 7ba0b6461bc4edb3005ea6e00cdae189bcf908a5 upstream. After rename exchanging (either with the rename exchange operation or regular renames in multiple non-atomic steps) two inodes and at least one of them is a directory, we can end up with a log tree that contains only of the inodes and after a power failure that can result in an attempt to delete the other inode when it should not because it was not deleted before the power failure. In some case that delete attempt fails when the target inode is a directory that contains a subvolume inside it, since the log replay code is not prepared to deal with directory entries that point to root items (only inode items). 1) We have directories "dir1" (inode A) and "dir2" (inode B) under the same parent directory; 2) We have a file (inode C) under directory "dir1" (inode A); 3) We have a subvolume inside directory "dir2" (inode B); 4) All these inodes were persisted in a past transaction and we are currently at transaction N; 5) We rename the file (inode C), so at btrfs_log_new_name() we update inode C's last_unlink_trans to N; 6) We get a rename exchange for "dir1" (inode A) and "dir2" (inode B), so after the exchange "dir1" is inode B and "dir2" is inode A. During the rename exchange we call btrfs_log_new_name() for inodes A and B, but because they are directories, we don't update their last_unlink_trans to N; 7) An fsync against the file (inode C) is done, and because its inode has a last_unlink_trans with a value of N we log its parent directory (inode A) (through btrfs_log_all_parents(), called from btrfs_log_inode_parent()). 8) So we end up with inode B not logged, which now has the old name of inode A. At copy_inode_items_to_log(), when logging inode A, we did not check if we had any conflicting inode to log because inode A has a generation lower than the current transaction (created in a past transaction); 9) After a power failure, when replaying the log tree, since we find that inode A has a new name that conflicts with the name of inode B in the fs tree, we attempt to delete inode B... this is wrong since that directory was never deleted before the power failure, and because there is a subvolume inside that directory, attempting to delete it will fail since replay_dir_deletes() and btrfs_unlink_inode() are not prepared to deal with dir items that point to roots instead of inodes. When that happens the mount fails and we get a stack trace like the following: [87.2314] BTRFS info (device dm-0): start tree-log replay [87.2318] BTRFS critical (device dm-0): failed to delete reference to subvol, root 5 inode 256 parent 259 [87.2332] ------------[ cut here ]------------ [87.2338] BTRFS: Transaction aborted (error -2) [87.2346] WARNING: CPU: 1 PID: 638968 at fs/btrfs/inode.c:4345 __btrfs_unlink_inode+0x416/0x440 [btrfs] [87.2368] Modules linked in: btrfs loop dm_thin_pool (...) [87.2470] CPU: 1 UID: 0 PID: 638968 Comm: mount Tainted: G W 6.18.0-rc7-btrfs-next-218+ #2 PREEMPT(full) [87.2489] Tainted: [W]=WARN [87.2494] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 [87.2514] RIP: 0010:__btrfs_unlink_inode+0x416/0x440 [btrfs] [87.2538] Code: c0 89 04 24 (...) [87.2568] RSP: 0018:ffffc0e741f4b9b8 EFLAGS: 00010286 [87.2574] RAX: 0000000000000000 RBX: ffff9d3ec8a6cf60 RCX: 0000000000000000 [87.2582] RDX: 0000000000000002 RSI: ffffffff84ab45a1 RDI: 00000000ffffffff [87.2591] RBP: ffff9d3ec8a6ef20 R08: 0000000000000000 R09: ffffc0e741f4b840 [87.2599] R10: ffff9d45dc1fffa8 R11: 0000000000000003 R12: ffff9d3ee26d77e0 [87.2608] R13: ffffc0e741f4ba98 R14: ffff9d4458040800 R15: ffff9d44b6b7ca10 [87.2618] FS: 00007f7b9603a840(0000) GS:ffff9d4658982000(0000) knlGS:0000000000000000 [87.2629] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [87.2637] CR2: 00007ffc9ec33b98 CR3: 000000011273e003 CR4: 0000000000370ef0 [87.2648] Call Trace: [87.2651] [87.2654] btrfs_unlink_inode+0x15/0x40 [btrfs] [87.2661] unlink_inode_for_log_replay+0x27/0xf0 [btrfs] [87.2669] check_item_in_log+0x1ea/0x2c0 [btrfs] [87.2676] replay_dir_deletes+0x16b/0x380 [btrfs] [87.2684] fixup_inode_link_count+0x34b/0x370 [btrfs] [87.2696] fixup_inode_link_counts+0x41/0x160 [btrfs] [87.2703] btrfs_recover_log_trees+0x1ff/0x7c0 [btrfs] [87.2711] ? __pfx_replay_one_buffer+0x10/0x10 [btrfs] [87.2719] open_ctree+0x10bb/0x15f0 [btrfs] [87.2726] btrfs_get_tree.cold+0xb/0x16c [btrfs] [87.2734] ? fscontext_read+0x15c/0x180 [87.2740] ? rw_verify_area+0x50/0x180 [87.2746] vfs_get_tree+0x25/0xd0 [87.2750] vfs_cmd_create+0x59/0xe0 [87.2755] __do_sys_fsconfig+0x4f6/0x6b0 [87.2760] do_syscall_64+0x50/0x1220 [87.2764] entry_SYSCALL_64_after_hwframe+0x76/0x7e [87.2770] RIP: 0033:0x7f7b9625f4aa [87.2775] Code: 73 01 c3 48 (...) [87.2803] RSP: 002b:00007ffc9ec35b08 EFLAGS: 00000246 ORIG_RAX: 00000000000001af [87.2817] RAX: ffffffffffffffda RBX: 0000558bfa91ac20 RCX: 00007f7b9625f4aa [87.2829] RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003 [87.2842] RBP: 0000558bfa91b120 R08: 0000000000000000 R09: 0000000000000000 [87.2854] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [87.2864] R13: 00007f7b963f1580 R14: 00007f7b963f326c R15: 00007f7b963d8a23 [87.2877] [87.2882] ---[ end trace 0000000000000000 ]--- [87.2891] BTRFS: error (device dm-0 state A) in __btrfs_unlink_inode:4345: errno=-2 No such entry [87.2904] BTRFS: error (device dm-0 state EAO) in do_abort_log_replay:191: errno=-2 No such entry [87.2915] BTRFS critical (device dm-0 state EAO): log tree (for root 5) leaf currently being processed (slot 7 key (258 12 257)): [87.2929] BTRFS info (device dm-0 state EAO): leaf 30736384 gen 10 total ptrs 7 free space 15712 owner 18446744073709551610 [87.2929] BTRFS info (device dm-0 state EAO): refs 3 lock_owner 0 current 638968 [87.2929] item 0 key (257 INODE_ITEM 0) itemoff 16123 itemsize 160 [87.2929] inode generation 9 transid 10 size 0 nbytes 0 [87.2929] block group 0 mode 40755 links 1 uid 0 gid 0 [87.2929] rdev 0 sequence 7 flags 0x0 [87.2929] atime 1765464494.678070921 [87.2929] ctime 1765464494.686606513 [87.2929] mtime 1765464494.686606513 [87.2929] otime 1765464494.678070921 [87.2929] item 1 key (257 INODE_REF 256) itemoff 16109 itemsize 14 [87.2929] index 4 name_len 4 [87.2929] item 2 key (257 DIR_LOG_INDEX 2) itemoff 16101 itemsize 8 [87.2929] dir log end 2 [87.2929] item 3 key (257 DIR_LOG_INDEX 3) itemoff 16093 itemsize 8 [87.2929] dir log end 18446744073709551615 [87.2930] item 4 key (257 DIR_INDEX 3) itemoff 16060 itemsize 33 [87.2930] location key (258 1 0) type 1 [87.2930] transid 10 data_len 0 name_len 3 [87.2930] item 5 key (258 INODE_ITEM 0) itemoff 15900 itemsize 160 [87.2930] inode generation 9 transid 10 size 0 nbytes 0 [87.2930] block group 0 mode 100644 links 1 uid 0 gid 0 [87.2930] rdev 0 sequence 2 flags 0x0 [87.2930] atime 1765464494.678456467 [87.2930] ctime 1765464494.686606513 [87.2930] mtime 1765464494.678456467 [87.2930] otime 1765464494.678456467 [87.2930] item 6 key (258 INODE_REF 257) itemoff 15887 itemsize 13 [87.2930] index 3 name_len 3 [87.2930] BTRFS critical (device dm-0 state EAO): log replay failed in unlink_inode_for_log_replay:1045 for root 5, stage 3, with error -2: failed to unlink inode 256 parent dir 259 name subvol root 5 [87.2963] BTRFS: error (device dm-0 state EAO) in btrfs_recover_log_trees:7743: errno=-2 No such entry [87.2981] BTRFS: error (device dm-0 state EAO) in btrfs_replay_log:2083: errno=-2 No such entry (Failed to recover log tr So fix this by changing copy_inode_items_to_log() to always detect if there are conflicting inodes for the ref/extref of the inode being logged even if the inode was created in a past transaction. A test case for fstests will follow soon. CC: stable@vger.kernel.org # 6.1+ Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/tree-log.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3342f5ff1516..882bb3c04c23 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -6002,10 +6002,8 @@ static int copy_inode_items_to_log(struct btrfs_trans_handle *trans, * and no keys greater than that, so bail out. */ break; - } else if ((min_key->type == BTRFS_INODE_REF_KEY || - min_key->type == BTRFS_INODE_EXTREF_KEY) && - (inode->generation == trans->transid || - ctx->logging_conflict_inodes)) { + } else if (min_key->type == BTRFS_INODE_REF_KEY || + min_key->type == BTRFS_INODE_EXTREF_KEY) { u64 other_ino = 0; u64 other_parent = 0; -- Gitee From 43e94697600c1c99a3096b9f65034ee961065491 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 15 Dec 2025 18:59:15 +0800 Subject: [PATCH 0904/1449] mei: me: add nova lake point S DID ANBZ: #35228 commit e1e8d4973c1a744d2781253b415550c46e29903c stable. commit 420f423defcf6d0af2263d38da870ca4a20c0990 upstream. Add Nova Lake S device id. Cc: stable Co-developed-by: Tomas Winkler Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Link: https://patch.msgid.link/20251215105915.1672659-1-alexander.usyskin@intel.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/misc/mei/hw-me-regs.h | 2 ++ drivers/misc/mei/pci-me.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index fcfc6c7e6dc8..1992784faa09 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -122,6 +122,8 @@ #define MEI_DEV_ID_WCL_P 0x4D70 /* Wildcat Lake P */ +#define MEI_DEV_ID_NVL_S 0x6E68 /* Nova Lake Point S */ + /* * MEI HW Section */ diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 1a1df0390a40..e2dadb93743d 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -129,6 +129,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_WCL_P, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_NVL_S, MEI_ME_PCH15_CFG)}, + /* required last entry */ {0, } }; -- Gitee From 05dbae5e848872d86b644a0b7994b8921c59f40c Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 7 Jan 2026 13:20:23 +0800 Subject: [PATCH 0905/1449] lib/crypto: aes: Fix missing MMU protection for AES S-box ANBZ: #35228 commit 84875a1d92243d192298022e4590e2be2f42e674 stable. commit 74d74bb78aeccc9edc10db216d6be121cf7ec176 upstream. __cacheline_aligned puts the data in the ".data..cacheline_aligned" section, which isn't marked read-only i.e. it doesn't receive MMU protection. Replace it with ____cacheline_aligned which does the right thing and just aligns the data while keeping it in ".rodata". Fixes: b5e0b032b6c3 ("crypto: aes - add generic time invariant AES cipher") Cc: stable@vger.kernel.org Reported-by: Qingfang Deng Closes: https://lore.kernel.org/r/20260105074712.498-1-dqfext@gmail.com/ Acked-by: Ard Biesheuvel Link: https://lore.kernel.org/r/20260107052023.174620-1-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- lib/crypto/aes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index 827fe89922ff..59a1d964497d 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -12,7 +12,7 @@ * Emit the sbox as volatile const to prevent the compiler from doing * constant folding on sbox references involving fixed indexes. */ -static volatile const u8 __cacheline_aligned aes_sbox[] = { +static volatile const u8 ____cacheline_aligned aes_sbox[] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, @@ -47,7 +47,7 @@ static volatile const u8 __cacheline_aligned aes_sbox[] = { 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, }; -static volatile const u8 __cacheline_aligned aes_inv_sbox[] = { +static volatile const u8 ____cacheline_aligned aes_inv_sbox[] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, -- Gitee From d8c701ed3ed3bbed3409b7cca33d41c68c8ef67a Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 15 Dec 2025 10:01:14 +0800 Subject: [PATCH 0906/1449] counter: 104-quad-8: Fix incorrect return value in IRQ handler ANBZ: #35228 commit 8a1b8778b78682d5d4dd442d7dd5aae475711af4 stable. commit 9517d76dd160208b7a432301ce7bec8fc1ddc305 upstream. quad8_irq_handler() should return irqreturn_t enum values, but it directly returns negative errno codes from regmap operations on error. Return IRQ_NONE if the interrupt status cannot be read. If clearing the interrupt fails, return IRQ_HANDLED to prevent the kernel from disabling the IRQ line due to a spurious interrupt storm. Also, log these regmap failures with dev_WARN_ONCE. Fixes: 98ffe0252911 ("counter: 104-quad-8: Migrate to the regmap API") Suggested-by: Andy Shevchenko Signed-off-by: Haotian Zhang Link: https://lore.kernel.org/r/20251215020114.1913-1-vulab@iscas.ac.cn Cc: stable@vger.kernel.org Signed-off-by: William Breathitt Gray Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/counter/104-quad-8.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c index ed1f57511955..09c7f5a627ad 100644 --- a/drivers/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -1192,6 +1192,7 @@ static irqreturn_t quad8_irq_handler(int irq, void *private) { struct counter_device *counter = private; struct quad8 *const priv = counter_priv(counter); + struct device *dev = counter->parent; unsigned int status; unsigned long irq_status; unsigned long channel; @@ -1200,8 +1201,11 @@ static irqreturn_t quad8_irq_handler(int irq, void *private) int ret; ret = regmap_read(priv->map, QUAD8_INTERRUPT_STATUS, &status); - if (ret) - return ret; + if (ret) { + dev_WARN_ONCE(dev, true, + "Attempt to read Interrupt Status Register failed: %d\n", ret); + return IRQ_NONE; + } if (!status) return IRQ_NONE; @@ -1223,8 +1227,9 @@ static irqreturn_t quad8_irq_handler(int irq, void *private) break; default: /* should never reach this path */ - WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n", - flg_pins, channel); + dev_WARN_ONCE(dev, true, + "invalid interrupt trigger function %u configured for channel %lu\n", + flg_pins, channel); continue; } @@ -1232,8 +1237,11 @@ static irqreturn_t quad8_irq_handler(int irq, void *private) } ret = regmap_write(priv->map, QUAD8_CHANNEL_OPERATION, CLEAR_PENDING_INTERRUPTS); - if (ret) - return ret; + if (ret) { + dev_WARN_ONCE(dev, true, + "Attempt to clear pending interrupts by writing to Channel Operation Register failed: %d\n", ret); + return IRQ_HANDLED; + } return IRQ_HANDLED; } -- Gitee From bcf59beb8b67823ac44efe4f1f030894612865da Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Tue, 18 Nov 2025 16:35:48 +0800 Subject: [PATCH 0907/1449] counter: interrupt-cnt: Drop IRQF_NO_THREAD flag ANBZ: #35228 commit 1c5a3175aecf82cd86dfcbef2a23e8b26d8d8e7c stable. commit 23f9485510c338476b9735d516c1d4aacb810d46 upstream. An IRQ handler can either be IRQF_NO_THREAD or acquire spinlock_t, as CONFIG_PROVE_RAW_LOCK_NESTING warns: ============================= [ BUG: Invalid wait context ] 6.18.0-rc1+git... #1 ----------------------------- some-user-space-process/1251 is trying to lock: (&counter->events_list_lock){....}-{3:3}, at: counter_push_event [counter] other info that might help us debug this: context-{2:2} no locks held by some-user-space-process/.... stack backtrace: CPU: 0 UID: 0 PID: 1251 Comm: some-user-space-process 6.18.0-rc1+git... #1 PREEMPT Call trace: show_stack (C) dump_stack_lvl dump_stack __lock_acquire lock_acquire _raw_spin_lock_irqsave counter_push_event [counter] interrupt_cnt_isr [interrupt_cnt] __handle_irq_event_percpu handle_irq_event handle_simple_irq handle_irq_desc generic_handle_domain_irq gpio_irq_handler handle_irq_desc generic_handle_domain_irq gic_handle_irq call_on_irq_stack do_interrupt_handler el0_interrupt __el0_irq_handler_common el0t_64_irq_handler el0t_64_irq ... and Sebastian correctly points out. Remove IRQF_NO_THREAD as an alternative to switching to raw_spinlock_t, because the latter would limit all potential nested locks to raw_spinlock_t only. Cc: Sebastian Andrzej Siewior Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20251117151314.xwLAZrWY@linutronix.de/ Fixes: a55ebd47f21f ("counter: add IRQ or GPIO based counter") Signed-off-by: Alexander Sverdlin Reviewed-by: Sebastian Andrzej Siewior Reviewed-by: Oleksij Rempel Link: https://lore.kernel.org/r/20251118083603.778626-1-alexander.sverdlin@siemens.com Signed-off-by: William Breathitt Gray Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/counter/interrupt-cnt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c index bc762ba87a19..2a8259f0c6be 100644 --- a/drivers/counter/interrupt-cnt.c +++ b/drivers/counter/interrupt-cnt.c @@ -229,8 +229,7 @@ static int interrupt_cnt_probe(struct platform_device *pdev) irq_set_status_flags(priv->irq, IRQ_NOAUTOEN); ret = devm_request_irq(dev, priv->irq, interrupt_cnt_isr, - IRQF_TRIGGER_RISING | IRQF_NO_THREAD, - dev_name(dev), counter); + IRQF_TRIGGER_RISING, dev_name(dev), counter); if (ret) return ret; -- Gitee From d8d1085e85ebebc2210aaa4a7d7d41589a20afd6 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 11 Dec 2025 20:33:44 +0800 Subject: [PATCH 0908/1449] drm/pl111: Fix error handling in pl111_amba_probe ANBZ: #35228 commit 526bd4bfa1206236bd4873dd002415022c233150 stable. commit 0ddd3bb4b14c9102c0267b3fd916c81fe5ab89c1 upstream. Jump to the existing dev_put label when devm_request_irq() fails so drm_dev_put() and of_reserved_mem_device_release() run instead of returning early and leaking resources. Found via static analysis and code review. Fixes: bed41005e617 ("drm/pl111: Initial drm/kms driver for pl111") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij Link: https://patch.msgid.link/20251211123345.2392065-1-linmq006@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/pl111/pl111_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c index 02e6b74d5016..cc28af7717ab 100644 --- a/drivers/gpu/drm/pl111/pl111_drv.c +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -294,7 +294,7 @@ static int pl111_amba_probe(struct amba_device *amba_dev, variant->name, priv); if (ret != 0) { dev_err(dev, "%s failed irq %d\n", __func__, ret); - return ret; + goto dev_put; } ret = pl111_modeset_init(drm); -- Gitee From d551ecc86f38f79c185432bc7a3eaab2f982789c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 30 Jun 2025 22:47:09 +0800 Subject: [PATCH 0909/1449] drm/radeon: Remove __counted_by from ClockInfoArray.clockInfo[] ANBZ: #35228 commit e23882b11f8d3f29583e58f6cdfa6fd0a3f1bbdd stable. commit 19158c7332468bc28572bdca428e89c7954ee1b1 upstream. clockInfo[] is a generic uchar pointer to variable sized structures which vary from ASIC to ASIC. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4374 Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher (cherry picked from commit dc135aa73561b5acc74eadf776e48530996529a3) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/radeon/pptable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/pptable.h b/drivers/gpu/drm/radeon/pptable.h index ce8832916704..083dad8a6a5f 100644 --- a/drivers/gpu/drm/radeon/pptable.h +++ b/drivers/gpu/drm/radeon/pptable.h @@ -450,7 +450,7 @@ typedef struct _ClockInfoArray{ //sizeof(ATOM_PPLIB_CLOCK_INFO) UCHAR ucEntrySize; - UCHAR clockInfo[] __counted_by(ucNumEntries); + UCHAR clockInfo[] /*__counted_by(ucNumEntries)*/; }ClockInfoArray; typedef struct _NonClockInfoArray{ -- Gitee From eb461f6bf1c6c4313b2ebc95fbf365b9631d8034 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 6 Jan 2026 17:00:11 +0800 Subject: [PATCH 0910/1449] gpio: rockchip: mark the GPIO controller as sleeping ANBZ: #35228 commit 7291ef23491f9aeafa17b16b35635b51afbd3b5f stable. commit 20cf2aed89ac6d78a0122e31c875228e15247194 upstream. The GPIO controller is configured as non-sleeping but it uses generic pinctrl helpers which use a mutex for synchronization. This can cause the following lockdep splat with shared GPIOs enabled on boards which have multiple devices using the same GPIO: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:591 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 12, name: kworker/u16:0 preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 6 locks held by kworker/u16:0/12: #0: ffff0001f0018d48 ((wq_completion)events_unbound#2){+.+.}-{0:0}, at: process_one_work+0x18c/0x604 #1: ffff8000842dbdf0 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work+0x1b4/0x604 #2: ffff0001f18498f8 (&dev->mutex){....}-{4:4}, at: __device_attach+0x38/0x1b0 #3: ffff0001f75f1e90 (&gdev->srcu){.+.?}-{0:0}, at: gpiod_direction_output_raw_commit+0x0/0x360 #4: ffff0001f46e3db8 (&shared_desc->spinlock){....}-{3:3}, at: gpio_shared_proxy_direction_output+0xd0/0x144 [gpio_shared_proxy] #5: ffff0001f180ee90 (&gdev->srcu){.+.?}-{0:0}, at: gpiod_direction_output_raw_commit+0x0/0x360 irq event stamp: 81450 hardirqs last enabled at (81449): [] _raw_spin_unlock_irqrestore+0x74/0x78 hardirqs last disabled at (81450): [] _raw_spin_lock_irqsave+0x84/0x88 softirqs last enabled at (79616): [] __alloc_skb+0x17c/0x1e8 softirqs last disabled at (79614): [] __alloc_skb+0x17c/0x1e8 CPU: 2 UID: 0 PID: 12 Comm: kworker/u16:0 Not tainted 6.19.0-rc4-next-20260105+ #11975 PREEMPT Hardware name: Hardkernel ODROID-M1 (DT) Workqueue: events_unbound deferred_probe_work_func Call trace: show_stack+0x18/0x24 (C) dump_stack_lvl+0x90/0xd0 dump_stack+0x18/0x24 __might_resched+0x144/0x248 __might_sleep+0x48/0x98 __mutex_lock+0x5c/0x894 mutex_lock_nested+0x24/0x30 pinctrl_get_device_gpio_range+0x44/0x128 pinctrl_gpio_direction+0x3c/0xe0 pinctrl_gpio_direction_output+0x14/0x20 rockchip_gpio_direction_output+0xb8/0x19c gpiochip_direction_output+0x38/0x94 gpiod_direction_output_raw_commit+0x1d8/0x360 gpiod_direction_output_nonotify+0x7c/0x230 gpiod_direction_output+0x34/0xf8 gpio_shared_proxy_direction_output+0xec/0x144 [gpio_shared_proxy] gpiochip_direction_output+0x38/0x94 gpiod_direction_output_raw_commit+0x1d8/0x360 gpiod_direction_output_nonotify+0x7c/0x230 gpiod_configure_flags+0xbc/0x480 gpiod_find_and_request+0x1a0/0x574 gpiod_get_index+0x58/0x84 devm_gpiod_get_index+0x20/0xb4 devm_gpiod_get_optional+0x18/0x30 rockchip_pcie_probe+0x98/0x380 platform_probe+0x5c/0xac really_probe+0xbc/0x298 Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio") Cc: stable@vger.kernel.org Reported-by: Marek Szyprowski Closes: https://lore.kernel.org/all/d035fc29-3b03-4cd6-b8ec-001f93540bc6@samsung.com/ Acked-by: Heiko Stuebner Link: https://lore.kernel.org/r/20260106090011.21603-1-bartosz.golaszewski@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-rockchip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index caeb3bdc78f8..4173ea19550e 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -584,6 +584,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) gc->ngpio = bank->nr_pins; gc->label = bank->name; gc->parent = bank->dev; + gc->can_sleep = true; ret = gpiochip_add_data(gc, bank); if (ret) { -- Gitee From c4ab4ab3c07afb5be096e1650c21e300aea03220 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 26 Nov 2025 20:22:19 +0800 Subject: [PATCH 0911/1449] pinctrl: qcom: lpass-lpi: mark the GPIO controller as sleeping ANBZ: #35228 commit 16e107d58620871431676dd6b55198261c58597f stable. commit ebc18e9854e5a2b62a041fb57b216a903af45b85 upstream. The gpio_chip settings in this driver say the controller can't sleep but it actually uses a mutex for synchronization. This triggers the following BUG(): [ 9.233659] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:281 [ 9.233665] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 554, name: (udev-worker) [ 9.233669] preempt_count: 1, expected: 0 [ 9.233673] RCU nest depth: 0, expected: 0 [ 9.233688] Tainted: [W]=WARN [ 9.233690] Hardware name: Dell Inc. Latitude 7455/0FK7MX, BIOS 2.10.1 05/20/2025 [ 9.233694] Call trace: [ 9.233696] show_stack+0x24/0x38 (C) [ 9.233709] dump_stack_lvl+0x40/0x88 [ 9.233716] dump_stack+0x18/0x24 [ 9.233722] __might_resched+0x148/0x160 [ 9.233731] __might_sleep+0x38/0x98 [ 9.233736] mutex_lock+0x30/0xd8 [ 9.233749] lpi_config_set+0x2e8/0x3c8 [pinctrl_lpass_lpi] [ 9.233757] lpi_gpio_direction_output+0x58/0x90 [pinctrl_lpass_lpi] [ 9.233761] gpiod_direction_output_raw_commit+0x110/0x428 [ 9.233772] gpiod_direction_output_nonotify+0x234/0x358 [ 9.233779] gpiod_direction_output+0x38/0xd0 [ 9.233786] gpio_shared_proxy_direction_output+0xb8/0x2a8 [gpio_shared_proxy] [ 9.233792] gpiod_direction_output_raw_commit+0x110/0x428 [ 9.233799] gpiod_direction_output_nonotify+0x234/0x358 [ 9.233806] gpiod_configure_flags+0x2c0/0x580 [ 9.233812] gpiod_find_and_request+0x358/0x4f8 [ 9.233819] gpiod_get_index+0x7c/0x98 [ 9.233826] devm_gpiod_get+0x34/0xb0 [ 9.233829] reset_gpio_probe+0x58/0x128 [reset_gpio] [ 9.233836] auxiliary_bus_probe+0xb0/0xf0 [ 9.233845] really_probe+0x14c/0x450 [ 9.233853] __driver_probe_device+0xb0/0x188 [ 9.233858] driver_probe_device+0x4c/0x250 [ 9.233863] __driver_attach+0xf8/0x2a0 [ 9.233868] bus_for_each_dev+0xf8/0x158 [ 9.233872] driver_attach+0x30/0x48 [ 9.233876] bus_add_driver+0x158/0x2b8 [ 9.233880] driver_register+0x74/0x118 [ 9.233886] __auxiliary_driver_register+0x94/0xe8 [ 9.233893] init_module+0x34/0xfd0 [reset_gpio] [ 9.233898] do_one_initcall+0xec/0x300 [ 9.233903] do_init_module+0x64/0x260 [ 9.233910] load_module+0x16c4/0x1900 [ 9.233915] __arm64_sys_finit_module+0x24c/0x378 [ 9.233919] invoke_syscall+0x4c/0xe8 [ 9.233925] el0_svc_common+0x8c/0xf0 [ 9.233929] do_el0_svc+0x28/0x40 [ 9.233934] el0_svc+0x38/0x100 [ 9.233938] el0t_64_sync_handler+0x84/0x130 [ 9.233943] el0t_64_sync+0x17c/0x180 Mark the controller as sleeping. Fixes: 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver") Cc: stable@vger.kernel.org Reported-by: Val Packett Closes: https://lore.kernel.org/all/98c0f185-b0e0-49ea-896c-f3972dd011ca@packett.cool/ Signed-off-by: Bartosz Golaszewski Reviewed-by: Dmitry Baryshkov Reviewed-by: Bjorn Andersson Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c index 0b2839d27fd6..2b32da357af3 100644 --- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c @@ -464,7 +464,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev) pctrl->chip.base = -1; pctrl->chip.ngpio = data->npins; pctrl->chip.label = dev_name(dev); - pctrl->chip.can_sleep = false; + pctrl->chip.can_sleep = true; mutex_init(&pctrl->lock); -- Gitee From 7c540f391e4c3e7cf10370327be4e1a6acbeebbe Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 8 Jan 2026 18:19:27 +0800 Subject: [PATCH 0912/1449] wifi: avoid kernel-infoleak from struct iw_point ANBZ: #35228 commit d21ec867d84c9f3a9845d7d8c90c9ce35dbe48f8 stable. commit 21cbf883d073abbfe09e3924466aa5e0449e7261 upstream. struct iw_point has a 32bit hole on 64bit arches. struct iw_point { void __user *pointer; /* Pointer to the data (in user space) */ __u16 length; /* number of fields or size in bytes */ __u16 flags; /* Optional params */ }; Make sure to zero the structure to avoid disclosing 32bits of kernel data to user space. Fixes: 87de87d5e47f ("wext: Dispatch and handle compat ioctls entirely in net/wireless/wext.c") Reported-by: syzbot+bfc7323743ca6dbcc3d3@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/695f83f3.050a0220.1c677c.0392.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260108101927.857582-1-edumazet@google.com Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/wireless/wext-core.c | 4 ++++ net/wireless/wext-priv.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 838ad6541a17..73a29ee3eff2 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -1103,6 +1103,10 @@ static int compat_standard_call(struct net_device *dev, return ioctl_standard_call(dev, iwr, cmd, info, handler); iwp_compat = (struct compat_iw_point *) &iwr->u.data; + + /* struct iw_point has a 32bit hole on 64bit arches. */ + memset(&iwp, 0, sizeof(iwp)); + iwp.pointer = compat_ptr(iwp_compat->pointer); iwp.length = iwp_compat->length; iwp.flags = iwp_compat->flags; diff --git a/net/wireless/wext-priv.c b/net/wireless/wext-priv.c index 674d426a9d24..37d1147019c2 100644 --- a/net/wireless/wext-priv.c +++ b/net/wireless/wext-priv.c @@ -228,6 +228,10 @@ int compat_private_call(struct net_device *dev, struct iwreq *iwr, struct iw_point iwp; iwp_compat = (struct compat_iw_point *) &iwr->u.data; + + /* struct iw_point has a 32bit hole on 64bit arches. */ + memset(&iwp, 0, sizeof(iwp)); + iwp.pointer = compat_ptr(iwp_compat->pointer); iwp.length = iwp_compat->length; iwp.flags = iwp_compat->flags; -- Gitee From ab8a623699d467a36afb8ebe201f796bf6a6f43f Mon Sep 17 00:00:00 2001 From: ziming zhang Date: Thu, 11 Dec 2025 16:52:58 +0800 Subject: [PATCH 0913/1449] libceph: prevent potential out-of-bounds reads in handle_auth_done() ANBZ: #35228 commit ef208ea331ef688729f64089b895ed1b49e842e3 stable. commit 818156caffbf55cb4d368f9c3cac64e458fb49c9 upstream. Perform an explicit bounds check on payload_len to avoid a possible out-of-bounds access in the callout. [ idryomov: changelog ] Cc: stable@vger.kernel.org Signed-off-by: ziming zhang Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/messenger_v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index 73ac1c1f3394..858198724439 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -2409,7 +2409,9 @@ static int process_auth_done(struct ceph_connection *con, void *p, void *end) ceph_decode_64_safe(&p, end, global_id, bad); ceph_decode_32_safe(&p, end, con->v2.con_mode, bad); + ceph_decode_32_safe(&p, end, payload_len, bad); + ceph_decode_need(&p, end, payload_len, bad); dout("%s con %p global_id %llu con_mode %d payload_len %d\n", __func__, con, global_id, con->v2.con_mode, payload_len); -- Gitee From 670d6c6b725dcb74299dd2060b70491aee72fd86 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 15 Dec 2025 18:53:31 +0800 Subject: [PATCH 0914/1449] libceph: replace overzealous BUG_ON in osdmap_apply_incremental() ANBZ: #35228 commit d3613770e2677683e65d062da5e31f48c409abe9 stable. commit e00c3f71b5cf75681dbd74ee3f982a99cb690c2b upstream. If the osdmap is (maliciously) corrupted such that the incremental osdmap epoch is different from what is expected, there is no need to BUG. Instead, just declare the incremental osdmap to be invalid. Cc: stable@vger.kernel.org Reported-by: ziming zhang Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/osdmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index f5f60deb680a..0722e9347a64 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -1979,11 +1979,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, bool msgr2, sizeof(u64) + sizeof(u32), e_inval); ceph_decode_copy(p, &fsid, sizeof(fsid)); epoch = ceph_decode_32(p); - BUG_ON(epoch != map->epoch+1); ceph_decode_copy(p, &modified, sizeof(modified)); new_pool_max = ceph_decode_64(p); new_flags = ceph_decode_32(p); + if (epoch != map->epoch + 1) + goto e_inval; + /* full map? */ ceph_decode_32_safe(p, end, len, e_inval); if (len > 0) { -- Gitee From f251819d56430174dfa3f5ffdacc4cc3c8f30f0a Mon Sep 17 00:00:00 2001 From: Tuo Li Date: Sun, 21 Dec 2025 02:11:49 +0800 Subject: [PATCH 0915/1449] libceph: make free_choose_arg_map() resilient to partial allocation ANBZ: #35228 commit 8081faaf089db5280c3be820948469f7c58ef8dd stable. commit e3fe30e57649c551757a02e1cad073c47e1e075e upstream. free_choose_arg_map() may dereference a NULL pointer if its caller fails after a partial allocation. For example, in decode_choose_args(), if allocation of arg_map->args fails, execution jumps to the fail label and free_choose_arg_map() is called. Since arg_map->size is updated to a non-zero value before memory allocation, free_choose_arg_map() will iterate over arg_map->args and dereference a NULL pointer. To prevent this potential NULL pointer dereference and make free_choose_arg_map() more resilient, add checks for pointers before iterating. Cc: stable@vger.kernel.org Co-authored-by: Ilya Dryomov Signed-off-by: Tuo Li Reviewed-by: Viacheslav Dubeyko Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/osdmap.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 0722e9347a64..7c76eb9d6cee 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -241,22 +241,26 @@ static struct crush_choose_arg_map *alloc_choose_arg_map(void) static void free_choose_arg_map(struct crush_choose_arg_map *arg_map) { - if (arg_map) { - int i, j; + int i, j; + + if (!arg_map) + return; - WARN_ON(!RB_EMPTY_NODE(&arg_map->node)); + WARN_ON(!RB_EMPTY_NODE(&arg_map->node)); + if (arg_map->args) { for (i = 0; i < arg_map->size; i++) { struct crush_choose_arg *arg = &arg_map->args[i]; - - for (j = 0; j < arg->weight_set_size; j++) - kfree(arg->weight_set[j].weights); - kfree(arg->weight_set); + if (arg->weight_set) { + for (j = 0; j < arg->weight_set_size; j++) + kfree(arg->weight_set[j].weights); + kfree(arg->weight_set); + } kfree(arg->ids); } kfree(arg_map->args); - kfree(arg_map); } + kfree(arg_map); } DEFINE_RB_FUNCS(choose_arg_map, struct crush_choose_arg_map, choose_args_index, -- Gitee From 67f9cc3e6f9aa631e08e1942ef5505501b227da9 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 29 Dec 2025 22:14:48 +0800 Subject: [PATCH 0916/1449] libceph: return the handler error from mon_handle_auth_done() ANBZ: #35228 commit e097cd858196b1914309e7e3d79b4fa79383754d stable. commit e84b48d31b5008932c0a0902982809fbaa1d3b70 upstream. Currently any error from ceph_auth_handle_reply_done() is propagated via finish_auth() but isn't returned from mon_handle_auth_done(). This results in higher layers learning that (despite the monitor considering us to be successfully authenticated) something went wrong in the authentication phase and reacting accordingly, but msgr2 still trying to proceed with establishing the session in the background. In the case of secure mode this can trigger a WARN in setup_crypto() and later lead to a NULL pointer dereference inside of prepare_auth_signature(). Cc: stable@vger.kernel.org Fixes: cd1a677cad99 ("libceph, ceph: implement msgr2.1 protocol (crc and secure modes)") Signed-off-by: Ilya Dryomov Reviewed-by: Viacheslav Dubeyko Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/mon_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 68f955293177..0f8b8335981c 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -1417,7 +1417,7 @@ static int mon_handle_auth_done(struct ceph_connection *con, if (!ret) finish_hunting(monc); mutex_unlock(&monc->mutex); - return 0; + return ret; } static int mon_handle_auth_bad_method(struct ceph_connection *con, -- Gitee From 29795421aeecc50d8575d0f564a6c2ec2301c093 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Wed, 31 Dec 2025 12:05:06 +0800 Subject: [PATCH 0917/1449] libceph: reset sparse-read state in osd_fault() ANBZ: #35228 commit 90a60fe61908afa0eaf7f8fcf1421b9b50e5f7ff stable. commit 11194b416ef95012c2cfe5f546d71af07b639e93 upstream. When a fault occurs, the connection is abandoned, reestablished, and any pending operations are retried. The OSD client tracks the progress of a sparse-read reply using a separate state machine, largely independent of the messenger's state. If a connection is lost mid-payload or the sparse-read state machine returns an error, the sparse-read state is not reset. The OSD client will then interpret the beginning of a new reply as the continuation of the old one. If this makes the sparse-read machinery enter a failure state, it may never recover, producing loops like: libceph: [0] got 0 extents libceph: data len 142248331 != extent len 0 libceph: osd0 (1)...:6801 socket error on read libceph: data len 142248331 != extent len 0 libceph: osd0 (1)...:6801 socket error on read Therefore, reset the sparse-read state in osd_fault(), ensuring retries start from a clean state. Cc: stable@vger.kernel.org Fixes: f628d7999727 ("libceph: add sparse read support to OSD client") Signed-off-by: Sam Edwards Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/osd_client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 0b6a8bb0642f..c80d77915491 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -4306,6 +4306,9 @@ static void osd_fault(struct ceph_connection *con) goto out_unlock; } + osd->o_sparse_op_idx = -1; + ceph_init_sparse_read(&osd->o_sparse_read); + if (!reopen_osd(osd)) kick_osd_requests(osd); maybe_request_map(osdc); -- Gitee From f41b2f67f01f6b45e3602e70e7e6051852840a30 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 6 Jan 2026 02:23:19 +0800 Subject: [PATCH 0918/1449] libceph: make calc_target() set t->paused, not just clear it ANBZ: #35228 commit 4ebc711b738d139cabe2fc9e7e7749847676a342 stable. commit c0fe2994f9a9d0a2ec9e42441ea5ba74b6a16176 upstream. Currently calc_target() clears t->paused if the request shouldn't be paused anymore, but doesn't ever set t->paused even though it's able to determine when the request should be paused. Setting t->paused is left to __submit_request() which is fine for regular requests but doesn't work for linger requests -- since __submit_request() doesn't operate on linger requests, there is nowhere for lreq->t.paused to be set. One consequence of this is that watches don't get reestablished on paused -> unpaused transitions in cases where requests have been paused long enough for the (paused) unwatch request to time out and for the subsequent (re)watch request to enter the paused state. On top of the watch not getting reestablished, rbd_reregister_watch() gets stuck with rbd_dev->watch_mutex held: rbd_register_watch __rbd_register_watch ceph_osdc_watch linger_reg_commit_wait It's waiting for lreq->reg_commit_wait to be completed, but for that to happen the respective request needs to end up on need_resend_linger list and be kicked when requests are unpaused. There is no chance for that if the request in question is never marked paused in the first place. The fact that rbd_dev->watch_mutex remains taken out forever then prevents the image from getting unmapped -- "rbd unmap" would inevitably hang in D state on an attempt to grab the mutex. Cc: stable@vger.kernel.org Reported-by: Raphael Zimmer Signed-off-by: Ilya Dryomov Reviewed-by: Viacheslav Dubeyko Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ceph/osd_client.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index c80d77915491..a86ba8b78575 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -1611,6 +1611,7 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc, struct ceph_pg_pool_info *pi; struct ceph_pg pgid, last_pgid; struct ceph_osds up, acting; + bool should_be_paused; bool is_read = t->flags & CEPH_OSD_FLAG_READ; bool is_write = t->flags & CEPH_OSD_FLAG_WRITE; bool force_resend = false; @@ -1679,10 +1680,16 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc, &last_pgid)) force_resend = true; - if (t->paused && !target_should_be_paused(osdc, t, pi)) { - t->paused = false; + should_be_paused = target_should_be_paused(osdc, t, pi); + if (t->paused && !should_be_paused) { unpaused = true; } + if (t->paused != should_be_paused) { + dout("%s t %p paused %d -> %d\n", __func__, t, t->paused, + should_be_paused); + t->paused = should_be_paused; + } + legacy_change = ceph_pg_compare(&t->pgid, &pgid) || ceph_osds_changed(&t->acting, &acting, t->used_replica || any_change); -- Gitee From 3289d1749e3288fe11a5e64baf9685011a6ee9ae Mon Sep 17 00:00:00 2001 From: Pedro Demarchi Gomes Date: Wed, 22 Oct 2025 23:30:59 +0800 Subject: [PATCH 0919/1449] ksm: use range-walk function to jump over holes in scan_get_next_rmap_item ANBZ: #35228 commit 9c2f8a9b68024e5ebb4813665845ec0a95f2eac3 stable. commit f5548c318d6520d4fa3c5ed6003eeb710763cbc5 upstream. Currently, scan_get_next_rmap_item() walks every page address in a VMA to locate mergeable pages. This becomes highly inefficient when scanning large virtual memory areas that contain mostly unmapped regions, causing ksmd to use large amount of cpu without deduplicating much pages. This patch replaces the per-address lookup with a range walk using walk_page_range(). The range walker allows KSM to skip over entire unmapped holes in a VMA, avoiding unnecessary lookups. This problem was previously discussed in [1]. Consider the following test program which creates a 32 TiB mapping in the virtual address space but only populates a single page: #include #include #include /* 32 TiB */ const size_t size = 32ul * 1024 * 1024 * 1024 * 1024; int main() { char *area = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0); if (area == MAP_FAILED) { perror("mmap() failed\n"); return -1; } /* Populate a single page such that we get an anon_vma. */ *area = 0; /* Enable KSM. */ madvise(area, size, MADV_MERGEABLE); pause(); return 0; } $ ./ksm-sparse & $ echo 1 > /sys/kernel/mm/ksm/run Without this patch ksmd uses 100% of the cpu for a long time (more then 1 hour in my test machine) scanning all the 32 TiB virtual address space that contain only one mapped page. This makes ksmd essentially deadlocked not able to deduplicate anything of value. With this patch ksmd walks only the one mapped page and skips the rest of the 32 TiB virtual address space, making the scan fast using little cpu. Link: https://lkml.kernel.org/r/20251023035841.41406-1-pedrodemargomes@gmail.com Link: https://lkml.kernel.org/r/20251022153059.22763-1-pedrodemargomes@gmail.com Link: https://lore.kernel.org/linux-mm/423de7a3-1c62-4e72-8e79-19a6413e420c@redhat.com/ [1] Fixes: 31dbd01f3143 ("ksm: Kernel SamePage Merging") Signed-off-by: Pedro Demarchi Gomes Co-developed-by: David Hildenbrand Signed-off-by: David Hildenbrand Reported-by: craftfever Closes: https://lkml.kernel.org/r/020cf8de6e773bb78ba7614ef250129f11a63781@murena.io Suggested-by: David Hildenbrand Acked-by: David Hildenbrand Cc: Chengming Zhou Cc: xu xin Cc: Signed-off-by: Andrew Morton [ change page to folios ] Signed-off-by: Pedro Demarchi Gomes Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/ksm.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 13 deletions(-) diff --git a/mm/ksm.c b/mm/ksm.c index 4e9cba527ad3..1906df92ad68 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -2310,6 +2310,95 @@ static struct ksm_rmap_item *get_next_rmap_item(struct ksm_mm_slot *mm_slot, return rmap_item; } +struct ksm_next_page_arg { + struct folio *folio; + struct page *page; + unsigned long addr; +}; + +static int ksm_next_page_pmd_entry(pmd_t *pmdp, unsigned long addr, unsigned long end, + struct mm_walk *walk) +{ + struct ksm_next_page_arg *private = walk->private; + struct vm_area_struct *vma = walk->vma; + pte_t *start_ptep = NULL, *ptep, pte; + struct mm_struct *mm = walk->mm; + struct folio *folio; + struct page *page; + spinlock_t *ptl; + pmd_t pmd; + + if (ksm_test_exit(mm)) + return 0; + + cond_resched(); + + pmd = pmdp_get_lockless(pmdp); + if (!pmd_present(pmd)) + return 0; + + if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pmd_leaf(pmd)) { + ptl = pmd_lock(mm, pmdp); + pmd = pmdp_get(pmdp); + + if (!pmd_present(pmd)) { + goto not_found_unlock; + } else if (pmd_leaf(pmd)) { + page = vm_normal_page_pmd(vma, addr, pmd); + if (!page) + goto not_found_unlock; + folio = page_folio(page); + + if (folio_is_zone_device(folio) || !folio_test_anon(folio)) + goto not_found_unlock; + + page += ((addr & (PMD_SIZE - 1)) >> PAGE_SHIFT); + goto found_unlock; + } + spin_unlock(ptl); + } + + start_ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); + if (!start_ptep) + return 0; + + for (ptep = start_ptep; addr < end; ptep++, addr += PAGE_SIZE) { + pte = ptep_get(ptep); + + if (!pte_present(pte)) + continue; + + page = vm_normal_page(vma, addr, pte); + if (!page) + continue; + folio = page_folio(page); + + if (folio_is_zone_device(folio) || !folio_test_anon(folio)) + continue; + goto found_unlock; + } + +not_found_unlock: + spin_unlock(ptl); + if (start_ptep) + pte_unmap(start_ptep); + return 0; +found_unlock: + folio_get(folio); + spin_unlock(ptl); + if (start_ptep) + pte_unmap(start_ptep); + private->page = page; + private->folio = folio; + private->addr = addr; + return 1; +} + +static struct mm_walk_ops ksm_next_page_ops = { + .pmd_entry = ksm_next_page_pmd_entry, + .walk_lock = PGWALK_RDLOCK, +}; + static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page) { struct mm_struct *mm; @@ -2396,32 +2485,43 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page) ksm_scan.address = vma->vm_end; while (ksm_scan.address < vma->vm_end) { + struct ksm_next_page_arg ksm_next_page_arg; + struct page *tmp_page = NULL; + struct folio *folio; + if (ksm_test_exit(mm)) break; - *page = follow_page(vma, ksm_scan.address, FOLL_GET); - if (IS_ERR_OR_NULL(*page)) { - ksm_scan.address += PAGE_SIZE; - cond_resched(); - continue; + + int found; + + found = walk_page_range_vma(vma, ksm_scan.address, + vma->vm_end, + &ksm_next_page_ops, + &ksm_next_page_arg); + + if (found > 0) { + folio = ksm_next_page_arg.folio; + tmp_page = ksm_next_page_arg.page; + ksm_scan.address = ksm_next_page_arg.addr; + } else { + VM_WARN_ON_ONCE(found < 0); + ksm_scan.address = vma->vm_end - PAGE_SIZE; } - if (is_zone_device_page(*page)) - goto next_page; - if (PageAnon(*page)) { - flush_anon_page(vma, *page, ksm_scan.address); - flush_dcache_page(*page); + if (tmp_page) { + flush_anon_page(vma, tmp_page, ksm_scan.address); + flush_dcache_page(tmp_page); rmap_item = get_next_rmap_item(mm_slot, ksm_scan.rmap_list, ksm_scan.address); if (rmap_item) { ksm_scan.rmap_list = &rmap_item->rmap_list; ksm_scan.address += PAGE_SIZE; + *page = tmp_page; } else - put_page(*page); + folio_put(folio); mmap_read_unlock(mm); return rmap_item; } -next_page: - put_page(*page); ksm_scan.address += PAGE_SIZE; cond_resched(); } -- Gitee From 8dc8e46f20b1e0b871eeb2eb2a1d41654f818381 Mon Sep 17 00:00:00 2001 From: Sharath Chandra Vurukala Date: Wed, 30 Jul 2025 18:51:18 +0800 Subject: [PATCH 0920/1449] net: Add locking to protect skb->dev access in ip_output ANBZ: #35228 commit 1310640f9ae92055e2320f1d69a1e69144caa6a9 stable. commit 1dbf1d590d10a6d1978e8184f8dfe20af22d680a upstream. In ip_output() skb->dev is updated from the skb_dst(skb)->dev this can become invalid when the interface is unregistered and freed, Introduced new skb_dst_dev_rcu() function to be used instead of skb_dst_dev() within rcu_locks in ip_output.This will ensure that all the skb's associated with the dev being deregistered will be transnmitted out first, before freeing the dev. Given that ip_output() is called within an rcu_read_lock() critical section or from a bottom-half context, it is safe to introduce an RCU read-side critical section within it. Multiple panic call stacks were observed when UL traffic was run in concurrency with device deregistration from different functions, pasting one sample for reference. [496733.627565][T13385] Call trace: [496733.627570][T13385] bpf_prog_ce7c9180c3b128ea_cgroupskb_egres+0x24c/0x7f0 [496733.627581][T13385] __cgroup_bpf_run_filter_skb+0x128/0x498 [496733.627595][T13385] ip_finish_output+0xa4/0xf4 [496733.627605][T13385] ip_output+0x100/0x1a0 [496733.627613][T13385] ip_send_skb+0x68/0x100 [496733.627618][T13385] udp_send_skb+0x1c4/0x384 [496733.627625][T13385] udp_sendmsg+0x7b0/0x898 [496733.627631][T13385] inet_sendmsg+0x5c/0x7c [496733.627639][T13385] __sys_sendto+0x174/0x1e4 [496733.627647][T13385] __arm64_sys_sendto+0x28/0x3c [496733.627653][T13385] invoke_syscall+0x58/0x11c [496733.627662][T13385] el0_svc_common+0x88/0xf4 [496733.627669][T13385] do_el0_svc+0x2c/0xb0 [496733.627676][T13385] el0_svc+0x2c/0xa4 [496733.627683][T13385] el0t_64_sync_handler+0x68/0xb4 [496733.627689][T13385] el0t_64_sync+0x1a4/0x1a8 Changes in v3: - Replaced WARN_ON() with WARN_ON_ONCE(), as suggested by Willem de Bruijn. - Dropped legacy lines mistakenly pulled in from an outdated branch. Changes in v2: - Addressed review comments from Eric Dumazet - Used READ_ONCE() to prevent potential load/store tearing - Added skb_dst_dev_rcu() and used along with rcu_read_lock() in ip_output Signed-off-by: Sharath Chandra Vurukala Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20250730105118.GA26100@hu-sharathv-hyd.qualcomm.com Signed-off-by: Jakub Kicinski [ Keerthana: Backported the patch to v6.6.y ] Signed-off-by: Keerthana K Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/dst.h | 12 ++++++++++++ net/ipv4/ip_output.c | 15 ++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 4aa32b87814f..f24ef6a47e79 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -578,6 +578,18 @@ static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu) dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } +static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) +{ + /* In the future, use rcu_dereference(dst->dev) */ + WARN_ON_ONCE(!rcu_read_lock_held()); + return READ_ONCE(dst->dev); +} + +static inline struct net_device *skb_dst_dev_rcu(const struct sk_buff *skb) +{ + return dst_dev_rcu(skb_dst(skb)); +} + struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, bool confirm_neigh); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index c321d964178b..305d0e2786a2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -425,15 +425,20 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb) int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) { - struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev; + struct net_device *dev, *indev = skb->dev; + int ret_val; + rcu_read_lock(); + dev = skb_dst_dev_rcu(skb); skb->dev = dev; skb->protocol = htons(ETH_P_IP); - return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, - net, sk, skb, indev, dev, - ip_finish_output, - !(IPCB(skb)->flags & IPSKB_REROUTED)); + ret_val = NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, + net, sk, skb, indev, dev, + ip_finish_output, + !(IPCB(skb)->flags & IPSKB_REROUTED)); + rcu_read_unlock(); + return ret_val; } EXPORT_SYMBOL(ip_output); -- Gitee From dd7a1b04a6ae908455366388edfd772a0be7a02d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 5 Oct 2023 02:52:37 +0800 Subject: [PATCH 0921/1449] nfsd: convert to new timestamp accessors ANBZ: #35228 commit ab2b5755269cfb06e79dc84a394f3f30d4048134 stable. commit 11fec9b9fb04fd1b3330a3b91ab9dcfa81ad5ad3 upstream. Convert to using the new inode timestamp accessor functions. Signed-off-by: Jeff Layton Link: https://lore.kernel.org/r/20231004185347.80880-50-jlayton@kernel.org Stable-dep-of: 24d92de9186e ("nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr()") Signed-off-by: Christian Brauner [ cel: d68886bae76a has already been applied ] Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/blocklayout.c | 3 ++- fs/nfsd/nfs3proc.c | 4 ++-- fs/nfsd/nfs4proc.c | 8 ++++---- fs/nfsd/nfsctl.c | 2 +- fs/nfsd/vfs.c | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index 5eae60425e57..cedca5a07e65 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -119,11 +119,12 @@ static __be32 nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp, struct iomap *iomaps, int nr_iomaps) { + struct timespec64 mtime = inode_get_mtime(inode); struct iattr iattr = { .ia_valid = 0 }; int error; if (lcp->lc_mtime.tv_nsec == UTIME_NOW || - timespec64_compare(&lcp->lc_mtime, &inode->i_mtime) < 0) + timespec64_compare(&lcp->lc_mtime, &mtime) < 0) lcp->lc_mtime = current_time(inode); iattr.ia_valid |= ATTR_ATIME | ATTR_CTIME | ATTR_MTIME; iattr.ia_atime = iattr.ia_ctime = iattr.ia_mtime = lcp->lc_mtime; diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 268ef57751c4..666bad8182e5 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -294,8 +294,8 @@ nfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, status = nfserr_exist; break; case NFS3_CREATE_EXCLUSIVE: - if (d_inode(child)->i_mtime.tv_sec == v_mtime && - d_inode(child)->i_atime.tv_sec == v_atime && + if (inode_get_mtime_sec(d_inode(child)) == v_mtime && + inode_get_atime_sec(d_inode(child)) == v_atime && d_inode(child)->i_size == 0) { break; } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index dc2591574a1c..e8e9d10b1365 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -322,8 +322,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, status = nfserr_exist; break; case NFS4_CREATE_EXCLUSIVE: - if (d_inode(child)->i_mtime.tv_sec == v_mtime && - d_inode(child)->i_atime.tv_sec == v_atime && + if (inode_get_mtime_sec(d_inode(child)) == v_mtime && + inode_get_atime_sec(d_inode(child)) == v_atime && d_inode(child)->i_size == 0) { open->op_created = true; break; /* subtle */ @@ -331,8 +331,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, status = nfserr_exist; break; case NFS4_CREATE_EXCLUSIVE4_1: - if (d_inode(child)->i_mtime.tv_sec == v_mtime && - d_inode(child)->i_atime.tv_sec == v_atime && + if (inode_get_mtime_sec(d_inode(child)) == v_mtime && + inode_get_atime_sec(d_inode(child)) == v_atime && d_inode(child)->i_size == 0) { open->op_created = true; goto set_attr; /* subtle */ diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index ba8d653de273..185994185fac 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1139,7 +1139,7 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode) /* Following advice from simple_fill_super documentation: */ inode->i_ino = iunique(sb, NFSD_MaxReserved); inode->i_mode = mode; - inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode); + simple_inode_init_ts(inode); switch (mode & S_IFMT) { case S_IFDIR: inode->i_fop = &simple_dir_operations; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 0152ba1a45ab..fa42e7cbea3a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -521,7 +521,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_sanitize_attrs(inode, iap); - if (check_guard && guardtime != inode_get_ctime(inode).tv_sec) + if (check_guard && guardtime != inode_get_ctime_sec(inode)) return nfserr_notsync; /* -- Gitee From b025f005ca11c0d9fcfdcf666119fdaefd6748cc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 16 Feb 2024 09:24:51 +0800 Subject: [PATCH 0922/1449] nfsd: Fix NFSv3 atomicity bugs in nfsd_setattr() ANBZ: #35228 commit d761a185f8950d360baeaaceaaeff7fbf017306a stable. commit 24d92de9186ebc340687caf7356e1070773e67bc upstream. The main point of the guarded SETATTR is to prevent races with other WRITE and SETATTR calls. That requires that the check of the guard time against the inode ctime be done after taking the inode lock. Furthermore, we need to take into account the 32-bit nature of timestamps in NFSv3, and the possibility that files may change at a faster rate than once a second. Signed-off-by: Trond Myklebust Reviewed-by: Jeff Layton Reviewed-by: NeilBrown Stable-dep-of: 442d27ff09a2 ("nfsd: set security label during create operations") Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/nfs3proc.c | 6 ++++-- fs/nfsd/nfs3xdr.c | 5 +---- fs/nfsd/nfs4proc.c | 3 +-- fs/nfsd/nfs4state.c | 2 +- fs/nfsd/nfsproc.c | 6 +++--- fs/nfsd/vfs.c | 20 +++++++++++++------- fs/nfsd/vfs.h | 2 +- fs/nfsd/xdr3.h | 2 +- 8 files changed, 25 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 666bad8182e5..f4ccbb1f49ba 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -71,13 +71,15 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp) struct nfsd_attrs attrs = { .na_iattr = &argp->attrs, }; + const struct timespec64 *guardtime = NULL; dprintk("nfsd: SETATTR(3) %s\n", SVCFH_fmt(&argp->fh)); fh_copy(&resp->fh, &argp->fh); - resp->status = nfsd_setattr(rqstp, &resp->fh, &attrs, - argp->check_guard, argp->guardtime); + if (argp->check_guard) + guardtime = &argp->guardtime; + resp->status = nfsd_setattr(rqstp, &resp->fh, &attrs, guardtime); return rpc_success; } diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index f32128955ec8..a7a07470c1f8 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -295,17 +295,14 @@ svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr, static bool svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args) { - __be32 *p; u32 check; if (xdr_stream_decode_bool(xdr, &check) < 0) return false; if (check) { - p = xdr_inline_decode(xdr, XDR_UNIT * 2); - if (!p) + if (!svcxdr_decode_nfstime3(xdr, &args->guardtime)) return false; args->check_guard = 1; - args->guardtime = be32_to_cpup(p); } else args->check_guard = 0; diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index e8e9d10b1365..0ed8be9bc172 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1160,8 +1160,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; save_no_wcc = cstate->current_fh.fh_no_wcc; cstate->current_fh.fh_no_wcc = true; - status = nfsd_setattr(rqstp, &cstate->current_fh, &attrs, - 0, (time64_t)0); + status = nfsd_setattr(rqstp, &cstate->current_fh, &attrs, NULL); cstate->current_fh.fh_no_wcc = save_no_wcc; if (!status) status = nfserrno(attrs.na_labelerr); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 393dd2f019e5..06f1fb8ebc4e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5224,7 +5224,7 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, return 0; if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) return nfserr_inval; - return nfsd_setattr(rqstp, fh, &attrs, 0, (time64_t)0); + return nfsd_setattr(rqstp, fh, &attrs, NULL); } static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp, diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index a7315928a760..36370b957b63 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -103,7 +103,7 @@ nfsd_proc_setattr(struct svc_rqst *rqstp) } } - resp->status = nfsd_setattr(rqstp, fhp, &attrs, 0, (time64_t)0); + resp->status = nfsd_setattr(rqstp, fhp, &attrs, NULL); if (resp->status != nfs_ok) goto out; @@ -390,8 +390,8 @@ nfsd_proc_create(struct svc_rqst *rqstp) */ attr->ia_valid &= ATTR_SIZE; if (attr->ia_valid) - resp->status = nfsd_setattr(rqstp, newfhp, &attrs, 0, - (time64_t)0); + resp->status = nfsd_setattr(rqstp, newfhp, &attrs, + NULL); } out_unlock: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index fa42e7cbea3a..0250c528cdce 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -459,7 +459,6 @@ static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap) * @rqstp: controlling RPC transaction * @fhp: filehandle of target * @attr: attributes to set - * @check_guard: set to 1 if guardtime is a valid timestamp * @guardtime: do not act if ctime.tv_sec does not match this timestamp * * This call may adjust the contents of @attr (in particular, this @@ -471,8 +470,7 @@ static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap) */ __be32 nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfsd_attrs *attr, - int check_guard, time64_t guardtime) + struct nfsd_attrs *attr, const struct timespec64 *guardtime) { struct dentry *dentry; struct inode *inode; @@ -521,9 +519,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_sanitize_attrs(inode, iap); - if (check_guard && guardtime != inode_get_ctime_sec(inode)) - return nfserr_notsync; - /* * The size case is special, it changes the file in addition to the * attributes, and file systems don't expect it to be mixed with @@ -541,6 +536,16 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, err = fh_fill_pre_attrs(fhp); if (err) goto out_unlock; + + if (guardtime) { + struct timespec64 ctime = inode_get_ctime(inode); + if ((u32)guardtime->tv_sec != (u32)ctime.tv_sec || + guardtime->tv_nsec != ctime.tv_nsec) { + err = nfserr_notsync; + goto out_fill_attrs; + } + } + for (retries = 1;;) { struct iattr attrs; @@ -568,6 +573,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, attr->na_aclerr = set_posix_acl(&nop_mnt_idmap, dentry, ACL_TYPE_DEFAULT, attr->na_dpacl); +out_fill_attrs: fh_fill_post_attrs(fhp); out_unlock: inode_unlock(inode); @@ -1381,7 +1387,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, * if the attributes have not changed. */ if (iap->ia_valid) - status = nfsd_setattr(rqstp, resfhp, attrs, 0, (time64_t)0); + status = nfsd_setattr(rqstp, resfhp, attrs, NULL); else status = nfserrno(commit_metadata(resfhp)); diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index e3c29596f4df..b476028e020b 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -69,7 +69,7 @@ __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, const char *, unsigned int, struct svc_export **, struct dentry **); __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, - struct nfsd_attrs *, int, time64_t); + struct nfsd_attrs *, const struct timespec64 *); int nfsd_mountpoint(struct dentry *, struct svc_export *); #ifdef CONFIG_NFSD_V4 __be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *, diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h index 03fe4e21306c..522067b7fd75 100644 --- a/fs/nfsd/xdr3.h +++ b/fs/nfsd/xdr3.h @@ -14,7 +14,7 @@ struct nfsd3_sattrargs { struct svc_fh fh; struct iattr attrs; int check_guard; - time64_t guardtime; + struct timespec64 guardtime; }; struct nfsd3_diropargs { -- Gitee From 08d2c6aa25ccea1fc2c06ccc17ae8c654c4774cb Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Fri, 3 May 2024 21:09:06 +0800 Subject: [PATCH 0923/1449] nfsd: set security label during create operations ANBZ: #35228 commit 4c06b7cb87e5ba6f82517c5d6a256daddc1d8481 stable. commit 442d27ff09a218b61020ab56387dbc508ad6bfa6 upstream. When security labeling is enabled, the client can pass a file security label as part of a create operation for the new file, similar to mode and other attributes. At present, the security label is received by nfsd and passed down to nfsd_create_setattr(), but nfsd_setattr() is never called and therefore the label is never set on the new file. This bug may have been introduced on or around commit d6a97d3f589a ("NFSD: add security label to struct nfsd_attrs"). Looking at nfsd_setattr() I am uncertain as to whether the same issue presents for file ACLs and therefore requires a similar fix for those. An alternative approach would be to introduce a new LSM hook to set the "create SID" of the current task prior to the actual file creation, which would atomically label the new inode at creation time. This would be better for SELinux and a similar approach has been used previously (see security_dentry_create_files_as) but perhaps not usable by other LSMs. Reproducer: 1. Install a Linux distro with SELinux - Fedora is easiest 2. git clone https://github.com/SELinuxProject/selinux-testsuite 3. Install the requisite dependencies per selinux-testsuite/README.md 4. Run something like the following script: MOUNT=$HOME/selinux-testsuite sudo systemctl start nfs-server sudo exportfs -o rw,no_root_squash,security_label localhost:$MOUNT sudo mkdir -p /mnt/selinux-testsuite sudo mount -t nfs -o vers=4.2 localhost:$MOUNT /mnt/selinux-testsuite pushd /mnt/selinux-testsuite/ sudo make -C policy load pushd tests/filesystem sudo runcon -t test_filesystem_t ./create_file -f trans_test_file \ -e test_filesystem_filetranscon_t -v sudo rm -f trans_test_file popd sudo make -C policy unload popd sudo umount /mnt/selinux-testsuite sudo exportfs -u localhost:$MOUNT sudo rmdir /mnt/selinux-testsuite sudo systemctl stop nfs-server Expected output: Process context: unconfined_u:unconfined_r:test_filesystem_t:s0-s0:c0.c1023 Created file: trans_test_file File context: unconfined_u:object_r:test_filesystem_filetranscon_t:s0 File context is correct Actual output: Process context: unconfined_u:unconfined_r:test_filesystem_t:s0-s0:c0.c1023 Created file: trans_test_file File context: system_u:object_r:test_file_t:s0 File context error, expected: test_filesystem_filetranscon_t got: test_file_t Signed-off-by: Stephen Smalley Reviewed-by: Jeff Layton Reviewed-by: NeilBrown Stable-dep-of: 913f7cf77bf1 ("NFSD: NFSv4 file creation neglects setting ACL") Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/vfs.c | 2 +- fs/nfsd/vfs.h | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 0250c528cdce..0637595b7913 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1386,7 +1386,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, * Callers expect new file metadata to be committed even * if the attributes have not changed. */ - if (iap->ia_valid) + if (nfsd_attrs_valid(attrs)) status = nfsd_setattr(rqstp, resfhp, attrs, NULL); else status = nfserrno(commit_metadata(resfhp)); diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index b476028e020b..df9baaee052e 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -60,6 +60,14 @@ static inline void nfsd_attrs_free(struct nfsd_attrs *attrs) posix_acl_release(attrs->na_dpacl); } +static inline bool nfsd_attrs_valid(struct nfsd_attrs *attrs) +{ + struct iattr *iap = attrs->na_iattr; + + return (iap->ia_valid || (attrs->na_seclabel && + attrs->na_seclabel->len)); +} + __be32 nfserrno (int errno); int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, struct svc_export **expp); -- Gitee From 8e5fb411307ce76ef6055f96fdbc23a531c24dea Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 19 Nov 2025 08:51:19 +0800 Subject: [PATCH 0924/1449] NFSD: NFSv4 file creation neglects setting ACL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 381261f24f4e4b41521c0e5ef5cc0b9a786a9862 stable. commit 913f7cf77bf14c13cfea70e89bcb6d0b22239562 upstream. An NFSv4 client that sets an ACL with a named principal during file creation retrieves the ACL afterwards, and finds that it is only a default ACL (based on the mode bits) and not the ACL that was requested during file creation. This violates RFC 8881 section 6.4.1.3: "the ACL attribute is set as given". The issue occurs in nfsd_create_setattr(), which calls nfsd_attrs_valid() to determine whether to call nfsd_setattr(). However, nfsd_attrs_valid() checks only for iattr changes and security labels, but not POSIX ACLs. When only an ACL is present, the function returns false, nfsd_setattr() is skipped, and the POSIX ACL is never applied to the inode. Subsequently, when the client retrieves the ACL, the server finds no POSIX ACL on the inode and returns one generated from the file's mode bits rather than returning the originally-specified ACL. Reported-by: Aurélien Couderc Fixes: c0cbe70742f4 ("NFSD: add posix ACLs to struct nfsd_attrs") Cc: Roland Mainz Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/vfs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index df9baaee052e..6f059c5ac22b 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -65,7 +65,8 @@ static inline bool nfsd_attrs_valid(struct nfsd_attrs *attrs) struct iattr *iap = attrs->na_iattr; return (iap->ia_valid || (attrs->na_seclabel && - attrs->na_seclabel->len)); + attrs->na_seclabel->len) || + attrs->na_pacl || attrs->na_dpacl); } __be32 nfserrno (int errno); -- Gitee From b17c8f1fe4f01d037f741af91fb264f793a3b500 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Wed, 17 Sep 2025 05:47:23 +0800 Subject: [PATCH 0925/1449] tls: Use __sk_dst_get() and dst_dev_rcu() in get_netdev_for_sock(). ANBZ: #35228 commit 13159c7125636371543a82cb7bbae00ab36730cc stable. commit c65f27b9c3be2269918e1cbad6d8884741f835c5 upstream. get_netdev_for_sock() is called during setsockopt(), so not under RCU. Using sk_dst_get(sk)->dev could trigger UAF. Let's use __sk_dst_get() and dst_dev_rcu(). Note that the only ->ndo_sk_get_lower_dev() user is bond_sk_get_lower_dev(), which uses RCU. Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Reviewed-by: Sabrina Dubroca Link: https://patch.msgid.link/20250916214758.650211-6-kuniyu@google.com Signed-off-by: Jakub Kicinski [ Keerthana: Backport to v6.6.y ] Signed-off-by: Keerthana K Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/tls/tls_device.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 4f72fd26ab40..1fc1e8e2a9cb 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -125,17 +125,19 @@ static void tls_device_queue_ctx_destruction(struct tls_context *ctx) /* We assume that the socket is already connected */ static struct net_device *get_netdev_for_sock(struct sock *sk) { - struct dst_entry *dst = sk_dst_get(sk); - struct net_device *netdev = NULL; + struct net_device *dev, *lowest_dev = NULL; + struct dst_entry *dst; - if (likely(dst)) { - netdev = netdev_sk_get_lowest_dev(dst->dev, sk); - dev_hold(netdev); + rcu_read_lock(); + dst = __sk_dst_get(sk); + dev = dst ? dst_dev_rcu(dst) : NULL; + if (likely(dev)) { + lowest_dev = netdev_sk_get_lowest_dev(dev, sk); + dev_hold(lowest_dev); } + rcu_read_unlock(); - dst_release(dst); - - return netdev; + return lowest_dev; } static void destroy_record(struct tls_record_info *record) -- Gitee From 142d4b49d82a09de9a86d911fbaf2c3aa16571a2 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Wed, 16 Oct 2024 17:56:26 +0800 Subject: [PATCH 0926/1449] csky: fix csky_cmpxchg_fixup not working ANBZ: #35228 commit 78faf283336dc34df4a3f7b4627f0a9f5bc03370 stable. commit 809ef03d6d21d5fea016bbf6babeec462e37e68c upstream. In the csky_cmpxchg_fixup function, it is incorrect to use the global variable csky_cmpxchg_stw to determine the address where the exception occurred.The global variable csky_cmpxchg_stw stores the opcode at the time of the exception, while &csky_cmpxchg_stw shows the address where the exception occurred. Signed-off-by: Yang Li Signed-off-by: Guo Ren Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/csky/mm/fault.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c index a885518ce1dd..5226bc08c336 100644 --- a/arch/csky/mm/fault.c +++ b/arch/csky/mm/fault.c @@ -45,8 +45,8 @@ static inline void csky_cmpxchg_fixup(struct pt_regs *regs) if (trap_no(regs) != VEC_TLBMODIFIED) return; - if (instruction_pointer(regs) == csky_cmpxchg_stw) - instruction_pointer_set(regs, csky_cmpxchg_ldw); + if (instruction_pointer(regs) == (unsigned long)&csky_cmpxchg_stw) + instruction_pointer_set(regs, (unsigned long)&csky_cmpxchg_ldw); return; } #endif -- Gitee From 27f0a2882224b17135675e4f866183242d988f1d Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 11 Nov 2025 23:54:37 +0800 Subject: [PATCH 0927/1449] ARM: 9461/1: Disable HIGHPTE on PREEMPT_RT kernels ANBZ: #35228 commit be3bc3d84a2a5ed3f0732e3acdf83115e7f5a27f stable. commit fedadc4137234c3d00c4785eeed3e747fe9036ae upstream. gup_pgd_range() is invoked with disabled interrupts and invokes __kmap_local_page_prot() via pte_offset_map(), gup_p4d_range(). With HIGHPTE enabled, __kmap_local_page_prot() invokes kmap_high_get() which uses a spinlock_t via lock_kmap_any(). This leads to an sleeping-while-atomic error on PREEMPT_RT because spinlock_t becomes a sleeping lock and must not be acquired in atomic context. The loop in map_new_virtual() uses wait_queue_head_t for wake up which also is using a spinlock_t. Since HIGHPTE is rarely needed at all, turn it off for PREEMPT_RT to allow the use of get_user_pages_fast(). [arnd: rework patch to turn off HIGHPTE instead of HAVE_PAST_GUP] Co-developed-by: Arnd Bergmann Acked-by: Linus Walleij Reviewed-by: Arnd Bergmann Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Russell King (Oracle) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 57c0448d017a..be3b0f83eee5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1308,7 +1308,7 @@ config HIGHMEM config HIGHPTE bool "Allocate 2nd-level pagetables from highmem" if EXPERT - depends on HIGHMEM + depends on HIGHMEM && !PREEMPT_RT default y help The VM uses one page of physical memory for each page table. -- Gitee From 2896640d90f7022341643b65c736c1ebbc71945e Mon Sep 17 00:00:00 2001 From: Sam James Date: Fri, 5 Dec 2025 16:14:57 +0800 Subject: [PATCH 0928/1449] alpha: don't reference obsolete termio struct for TC* constants ANBZ: #35228 commit fc220dae3cf8945451b9f4710114e69f804a2727 stable. commit 9aeed9041929812a10a6d693af050846942a1d16 upstream. Similar in nature to ab107276607af90b13a5994997e19b7b9731e251. glibc-2.42 drops the legacy termio struct, but the ioctls.h header still defines some TC* constants in terms of termio (via sizeof). Hardcode the values instead. This fixes building Python for example, which falls over like: ./Modules/termios.c:1119:16: error: invalid application of 'sizeof' to incomplete type 'struct termio' Link: https://bugs.gentoo.org/961769 Link: https://bugs.gentoo.org/962600 Signed-off-by: Sam James Reviewed-by: Magnus Lindholm Link: https://lore.kernel.org/r/6ebd3451908785cad53b50ca6bc46cfe9d6bc03c.1764922497.git.sam@gentoo.org Signed-off-by: Magnus Lindholm Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/alpha/include/uapi/asm/ioctls.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h index 971311605288..a09d04b49cc6 100644 --- a/arch/alpha/include/uapi/asm/ioctls.h +++ b/arch/alpha/include/uapi/asm/ioctls.h @@ -23,10 +23,10 @@ #define TCSETSW _IOW('t', 21, struct termios) #define TCSETSF _IOW('t', 22, struct termios) -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) +#define TCGETA 0x40127417 +#define TCSETA 0x80127418 +#define TCSETAW 0x80127419 +#define TCSETAF 0x8012741c #define TCSBRK _IO('t', 29) #define TCXONC _IO('t', 30) -- Gitee From 54d14684781adf5368dc5043c760015936af59f8 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 2 Dec 2025 05:13:10 +0800 Subject: [PATCH 0929/1449] dm-snapshot: fix 'scheduling while atomic' on real-time kernels ANBZ: #35228 commit af4fc583fd9005a61c6d2c16bf95d64fd29897fd stable. commit 8581b19eb2c5ccf06c195d3b5468c3c9d17a5020 upstream. There is reported 'scheduling while atomic' bug when using dm-snapshot on real-time kernels. The reason for the bug is that the hlist_bl code does preempt_disable() when taking the lock and the kernel attempts to take other spinlocks while holding the hlist_bl lock. Fix this by converting a hlist_bl spinlock into a regular spinlock. Signed-off-by: Mikulas Patocka Reported-by: Jiping Ma Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/md/dm-exception-store.h | 2 +- drivers/md/dm-snap.c | 73 +++++++++++++++------------------ 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index b67976637538..061b4d310813 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h @@ -29,7 +29,7 @@ typedef sector_t chunk_t; * chunk within the device. */ struct dm_exception { - struct hlist_bl_node hash_list; + struct hlist_node hash_list; chunk_t old_chunk; chunk_t new_chunk; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 0ace06d1bee3..dcffa3441a66 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -40,10 +40,15 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; #define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \ (DM_TRACKED_CHUNK_HASH_SIZE - 1)) +struct dm_hlist_head { + struct hlist_head head; + spinlock_t lock; +}; + struct dm_exception_table { uint32_t hash_mask; unsigned int hash_shift; - struct hlist_bl_head *table; + struct dm_hlist_head *table; }; struct dm_snapshot { @@ -628,8 +633,8 @@ static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk); /* Lock to protect access to the completed and pending exception hash tables. */ struct dm_exception_table_lock { - struct hlist_bl_head *complete_slot; - struct hlist_bl_head *pending_slot; + spinlock_t *complete_slot; + spinlock_t *pending_slot; }; static void dm_exception_table_lock_init(struct dm_snapshot *s, chunk_t chunk, @@ -638,20 +643,20 @@ static void dm_exception_table_lock_init(struct dm_snapshot *s, chunk_t chunk, struct dm_exception_table *complete = &s->complete; struct dm_exception_table *pending = &s->pending; - lock->complete_slot = &complete->table[exception_hash(complete, chunk)]; - lock->pending_slot = &pending->table[exception_hash(pending, chunk)]; + lock->complete_slot = &complete->table[exception_hash(complete, chunk)].lock; + lock->pending_slot = &pending->table[exception_hash(pending, chunk)].lock; } static void dm_exception_table_lock(struct dm_exception_table_lock *lock) { - hlist_bl_lock(lock->complete_slot); - hlist_bl_lock(lock->pending_slot); + spin_lock_nested(lock->complete_slot, 1); + spin_lock_nested(lock->pending_slot, 2); } static void dm_exception_table_unlock(struct dm_exception_table_lock *lock) { - hlist_bl_unlock(lock->pending_slot); - hlist_bl_unlock(lock->complete_slot); + spin_unlock(lock->pending_slot); + spin_unlock(lock->complete_slot); } static int dm_exception_table_init(struct dm_exception_table *et, @@ -661,13 +666,15 @@ static int dm_exception_table_init(struct dm_exception_table *et, et->hash_shift = hash_shift; et->hash_mask = size - 1; - et->table = kvmalloc_array(size, sizeof(struct hlist_bl_head), + et->table = kvmalloc_array(size, sizeof(struct dm_hlist_head), GFP_KERNEL); if (!et->table) return -ENOMEM; - for (i = 0; i < size; i++) - INIT_HLIST_BL_HEAD(et->table + i); + for (i = 0; i < size; i++) { + INIT_HLIST_HEAD(&et->table[i].head); + spin_lock_init(&et->table[i].lock); + } return 0; } @@ -675,16 +682,17 @@ static int dm_exception_table_init(struct dm_exception_table *et, static void dm_exception_table_exit(struct dm_exception_table *et, struct kmem_cache *mem) { - struct hlist_bl_head *slot; + struct dm_hlist_head *slot; struct dm_exception *ex; - struct hlist_bl_node *pos, *n; + struct hlist_node *pos; int i, size; size = et->hash_mask + 1; for (i = 0; i < size; i++) { slot = et->table + i; - hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) { + hlist_for_each_entry_safe(ex, pos, &slot->head, hash_list) { + hlist_del(&ex->hash_list); kmem_cache_free(mem, ex); cond_resched(); } @@ -700,7 +708,7 @@ static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk) static void dm_remove_exception(struct dm_exception *e) { - hlist_bl_del(&e->hash_list); + hlist_del(&e->hash_list); } /* @@ -710,12 +718,11 @@ static void dm_remove_exception(struct dm_exception *e) static struct dm_exception *dm_lookup_exception(struct dm_exception_table *et, chunk_t chunk) { - struct hlist_bl_head *slot; - struct hlist_bl_node *pos; + struct hlist_head *slot; struct dm_exception *e; - slot = &et->table[exception_hash(et, chunk)]; - hlist_bl_for_each_entry(e, pos, slot, hash_list) + slot = &et->table[exception_hash(et, chunk)].head; + hlist_for_each_entry(e, slot, hash_list) if (chunk >= e->old_chunk && chunk <= e->old_chunk + dm_consecutive_chunk_count(e)) return e; @@ -762,18 +769,17 @@ static void free_pending_exception(struct dm_snap_pending_exception *pe) static void dm_insert_exception(struct dm_exception_table *eh, struct dm_exception *new_e) { - struct hlist_bl_head *l; - struct hlist_bl_node *pos; + struct hlist_head *l; struct dm_exception *e = NULL; - l = &eh->table[exception_hash(eh, new_e->old_chunk)]; + l = &eh->table[exception_hash(eh, new_e->old_chunk)].head; /* Add immediately if this table doesn't support consecutive chunks */ if (!eh->hash_shift) goto out; /* List is ordered by old_chunk */ - hlist_bl_for_each_entry(e, pos, l, hash_list) { + hlist_for_each_entry(e, l, hash_list) { /* Insert after an existing chunk? */ if (new_e->old_chunk == (e->old_chunk + dm_consecutive_chunk_count(e) + 1) && @@ -804,13 +810,13 @@ static void dm_insert_exception(struct dm_exception_table *eh, * Either the table doesn't support consecutive chunks or slot * l is empty. */ - hlist_bl_add_head(&new_e->hash_list, l); + hlist_add_head(&new_e->hash_list, l); } else if (new_e->old_chunk < e->old_chunk) { /* Add before an existing exception */ - hlist_bl_add_before(&new_e->hash_list, &e->hash_list); + hlist_add_before(&new_e->hash_list, &e->hash_list); } else { /* Add to l's tail: e is the last exception in this slot */ - hlist_bl_add_behind(&new_e->hash_list, &e->hash_list); + hlist_add_behind(&new_e->hash_list, &e->hash_list); } } @@ -820,7 +826,6 @@ static void dm_insert_exception(struct dm_exception_table *eh, */ static int dm_add_exception(void *context, chunk_t old, chunk_t new) { - struct dm_exception_table_lock lock; struct dm_snapshot *s = context; struct dm_exception *e; @@ -833,17 +838,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) /* Consecutive_count is implicitly initialised to zero */ e->new_chunk = new; - /* - * Although there is no need to lock access to the exception tables - * here, if we don't then hlist_bl_add_head(), called by - * dm_insert_exception(), will complain about accessing the - * corresponding list without locking it first. - */ - dm_exception_table_lock_init(s, old, &lock); - - dm_exception_table_lock(&lock); dm_insert_exception(&s->complete, e); - dm_exception_table_unlock(&lock); return 0; } @@ -873,7 +868,7 @@ static int calc_max_buckets(void) /* use a fixed size of 2MB */ unsigned long mem = 2 * 1024 * 1024; - mem /= sizeof(struct hlist_bl_head); + mem /= sizeof(struct dm_hlist_head); return mem; } -- Gitee From b203160fd009211ed9347c305ca751b4abe26b29 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Mon, 3 Nov 2025 23:44:15 +0800 Subject: [PATCH 0930/1449] NFSv4: ensure the open stateid seqid doesn't go backwards ANBZ: #35228 commit f719a300eaa058131251b933706c3374ee8f8d6c stable. commit 2e47c3cc64b44b0b06cd68c2801db92ff143f2b2 upstream. We have observed an NFSv4 client receiving a LOCK reply with a status of NFS4ERR_OLD_STATEID and subsequently retrying the LOCK request with an earlier seqid value in the stateid. As this was for a new lockowner, that would imply that nfs_set_open_stateid_locked() had updated the open stateid seqid with an earlier value. Looking at nfs_set_open_stateid_locked(), if the incoming seqid is out of sequence, the task will sleep on the state->waitq for up to 5 seconds. If the task waits for the full 5 seconds, then after finishing the wait it'll update the open stateid seqid with whatever value the incoming seqid has. If there are multiple waiters in this scenario, then the last one to perform said update may not be the one with the highest seqid. Add a check to ensure that the seqid can only be incremented, and add a tracepoint to indicate when old seqids are skipped. Signed-off-by: Scott Mayhew Reviewed-by: Benjamin Coddington Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/nfs4proc.c | 13 +++++++++++-- fs/nfs/nfs4trace.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a0a71a163ffe..fe6986939bc9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1700,8 +1700,17 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, if (nfs_stateid_is_sequential(state, stateid)) break; - if (status) - break; + if (status) { + if (nfs4_stateid_match_other(stateid, &state->open_stateid) && + !nfs4_stateid_is_newer(stateid, &state->open_stateid)) { + trace_nfs4_open_stateid_update_skip(state->inode, + stateid, status); + return; + } else { + break; + } + } + /* Rely on seqids for serialisation with NFSv4.0 */ if (!nfs4_has_session(NFS_SERVER(state->inode)->nfs_client)) break; diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h index d27919d7241d..52a985ebe2b1 100644 --- a/fs/nfs/nfs4trace.h +++ b/fs/nfs/nfs4trace.h @@ -1248,6 +1248,7 @@ DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_setattr); DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_delegreturn); DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update); DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_wait); +DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_skip); DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_close_stateid_update_wait); DECLARE_EVENT_CLASS(nfs4_getattr_event, -- Gitee From 66bad4d91c71704296da75b85f6b758b03eec0e5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 29 Nov 2025 07:56:46 +0800 Subject: [PATCH 0931/1449] NFS: Fix up the automount fs_context to use the correct cred ANBZ: #35228 commit f18975f2cd41c0a00617d901655194c81d05e2ec stable. commit a2a8fc27dd668e7562b5326b5ed2f1604cb1e2e9 upstream. When automounting, the fs_context should be fixed up to use the cred from the parent filesystem, since the operation is just extending the namespace. Authorisation to enter that namespace will already have been provided by the preceding lookup. Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/namespace.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 923b5c1eb47e..99ef1146096f 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -170,6 +170,11 @@ struct vfsmount *nfs_d_automount(struct path *path) if (!ctx->clone_data.fattr) goto out_fc; + if (fc->cred != server->cred) { + put_cred(fc->cred); + fc->cred = get_cred(server->cred); + } + if (fc->net_ns != client->cl_net) { put_net(fc->net_ns); fc->net_ns = get_net(client->cl_net); -- Gitee From 52f8c8da126876be757d232ca2f4a42f30e10b32 Mon Sep 17 00:00:00 2001 From: ChenXiaoSong Date: Sun, 7 Dec 2025 09:22:53 +0800 Subject: [PATCH 0932/1449] smb/client: fix NT_STATUS_UNABLE_TO_FREE_VM value ANBZ: #35228 commit ca9b4aaa7e63be9d2863aeb140d68f70f4d95916 stable. commit 9f99caa8950a76f560a90074e3a4b93cfa8b3d84 upstream. This was reported by the KUnit tests in the later patches. See MS-ERREF 2.3.1 STATUS_UNABLE_TO_FREE_VM. Keep it consistent with the value in the documentation. Signed-off-by: ChenXiaoSong Acked-by: Paulo Alcantara (Red Hat) Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/nterr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/nterr.h b/fs/smb/client/nterr.h index edd4741cab0a..7ce063a1dc3f 100644 --- a/fs/smb/client/nterr.h +++ b/fs/smb/client/nterr.h @@ -70,7 +70,7 @@ extern const struct nt_err_code_struct nt_errs[]; #define NT_STATUS_NO_MEMORY 0xC0000000 | 0x0017 #define NT_STATUS_CONFLICTING_ADDRESSES 0xC0000000 | 0x0018 #define NT_STATUS_NOT_MAPPED_VIEW 0xC0000000 | 0x0019 -#define NT_STATUS_UNABLE_TO_FREE_VM 0x80000000 | 0x001a +#define NT_STATUS_UNABLE_TO_FREE_VM 0xC0000000 | 0x001a #define NT_STATUS_UNABLE_TO_DELETE_SECTION 0xC0000000 | 0x001b #define NT_STATUS_INVALID_SYSTEM_SERVICE 0xC0000000 | 0x001c #define NT_STATUS_ILLEGAL_INSTRUCTION 0xC0000000 | 0x001d -- Gitee From 333305d2bcdb0c5aa6c79d0ff49c0ce635ed26ac Mon Sep 17 00:00:00 2001 From: Ian Ray Date: Mon, 1 Dec 2025 17:56:05 +0800 Subject: [PATCH 0933/1449] ARM: dts: imx6q-ba16: fix RTC interrupt level ANBZ: #35228 commit b6600d9d893f68243561b16295c4cdd22fa5947a stable. commit e6a4eedd49ce27c16a80506c66a04707e0ee0116 upstream. RTC interrupt level should be set to "LOW". This was revealed by the introduction of commit: f181987ef477 ("rtc: m41t80: use IRQ flags obtained from fwnode") which changed the way IRQ type is obtained. Fixes: 56c27310c1b4 ("ARM: dts: imx: Add Advantech BA-16 Qseven module") Signed-off-by: Ian Ray Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi index f266f1b7e0cf..0c033e69ecc0 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi @@ -335,7 +335,7 @@ rtc@32 { pinctrl-0 = <&pinctrl_rtc>; reg = <0x32>; interrupt-parent = <&gpio4>; - interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; }; }; -- Gitee From 34af2e2d3cd721b783a0244aec8117e6cec4fc92 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 2 Dec 2025 21:41:51 +0800 Subject: [PATCH 0934/1449] arm64: dts: imx8mp: Fix LAN8740Ai PHY reference clock on DH electronics i.MX8M Plus DHCOM ANBZ: #35228 commit 51ea246778e578334bc143697567dddbac6c9d42 stable. commit c63749a7ddc59ac6ec0b05abfa0a21af9f2c1d38 upstream. Add missing 'clocks' property to LAN8740Ai PHY node, to allow the PHY driver to manage LAN8740Ai CLKIN reference clock supply. This fixes sporadic link bouncing caused by interruptions on the PHY reference clock, by letting the PHY driver manage the reference clock and assure there are no interruptions. This follows the matching PHY driver recommendation described in commit bedd8d78aba3 ("net: phy: smsc: LAN8710/20: add phy refclk in support") Fixes: 8d6712695bc8 ("arm64: dts: imx8mp: Add support for DH electronics i.MX8M Plus DHCOM and PDK2") Signed-off-by: Marek Vasut Tested-by: Christoph Niedermaier Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi index 2e93d922c861..2ff47f6ec797 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi @@ -105,6 +105,7 @@ mdio { ethphy0f: ethernet-phy@0 { /* SMSC LAN8740Ai */ compatible = "ethernet-phy-id0007.c110", "ethernet-phy-ieee802.3-c22"; + clocks = <&clk IMX8MP_CLK_ENET_QOS>; interrupt-parent = <&gpio3>; interrupts = <19 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&pinctrl_ethphy0>; -- Gitee From 76d166b98663ebd5965b2035490cc730cdfc4258 Mon Sep 17 00:00:00 2001 From: ChenXiaoSong Date: Sun, 7 Dec 2025 09:17:57 +0800 Subject: [PATCH 0935/1449] smb/client: fix NT_STATUS_DEVICE_DOOR_OPEN value ANBZ: #35228 commit bbbc1a48f121ad1ea0a4d87eab36af96e7b05b52 stable. commit b2b50fca34da5ec231008edba798ddf92986bd7f upstream. This was reported by the KUnit tests in the later patches. See MS-ERREF 2.3.1 STATUS_DEVICE_DOOR_OPEN. Keep it consistent with the value in the documentation. Signed-off-by: ChenXiaoSong Acked-by: Paulo Alcantara (Red Hat) Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/nterr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/nterr.h b/fs/smb/client/nterr.h index 7ce063a1dc3f..d46d42559eea 100644 --- a/fs/smb/client/nterr.h +++ b/fs/smb/client/nterr.h @@ -44,7 +44,7 @@ extern const struct nt_err_code_struct nt_errs[]; #define NT_STATUS_NO_DATA_DETECTED 0x8000001c #define NT_STATUS_STOPPED_ON_SYMLINK 0x8000002d #define NT_STATUS_DEVICE_REQUIRES_CLEANING 0x80000288 -#define NT_STATUS_DEVICE_DOOR_OPEN 0x80000288 +#define NT_STATUS_DEVICE_DOOR_OPEN 0x80000289 #define NT_STATUS_UNSUCCESSFUL 0xC0000000 | 0x0001 #define NT_STATUS_NOT_IMPLEMENTED 0xC0000000 | 0x0002 #define NT_STATUS_INVALID_INFO_CLASS 0xC0000000 | 0x0003 -- Gitee From 8f9d6f6ad34bbd1fd6b5ea721b20d23332d66594 Mon Sep 17 00:00:00 2001 From: ChenXiaoSong Date: Sun, 7 Dec 2025 09:13:06 +0800 Subject: [PATCH 0936/1449] smb/client: fix NT_STATUS_NO_DATA_DETECTED value ANBZ: #35228 commit afd993bababfeda937998650bdf167ae19d3b226 stable. commit a1237c203f1757480dc2f3b930608ee00072d3cc upstream. This was reported by the KUnit tests in the later patches. See MS-ERREF 2.3.1 STATUS_NO_DATA_DETECTED. Keep it consistent with the value in the documentation. Signed-off-by: ChenXiaoSong Acked-by: Paulo Alcantara (Red Hat) Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/nterr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/client/nterr.h b/fs/smb/client/nterr.h index d46d42559eea..e3a341316a71 100644 --- a/fs/smb/client/nterr.h +++ b/fs/smb/client/nterr.h @@ -41,7 +41,7 @@ extern const struct nt_err_code_struct nt_errs[]; #define NT_STATUS_MEDIA_CHANGED 0x8000001c #define NT_STATUS_END_OF_MEDIA 0x8000001e #define NT_STATUS_MEDIA_CHECK 0x80000020 -#define NT_STATUS_NO_DATA_DETECTED 0x8000001c +#define NT_STATUS_NO_DATA_DETECTED 0x80000022 #define NT_STATUS_STOPPED_ON_SYMLINK 0x8000002d #define NT_STATUS_DEVICE_REQUIRES_CLEANING 0x80000288 #define NT_STATUS_DEVICE_DOOR_OPEN 0x80000289 -- Gitee From bf565f83f6badab61e2dbdfde0c3438f18ac94d9 Mon Sep 17 00:00:00 2001 From: Wen Xiong Date: Tue, 28 Oct 2025 22:24:26 +0800 Subject: [PATCH 0937/1449] scsi: ipr: Enable/disable IRQD_NO_BALANCING during reset ANBZ: #35228 commit ac01c92333497d125acb9e428149b79bac4b30e0 stable. commit 6ac3484fb13b2fc7f31cfc7f56093e7d0ce646a5 upstream. A dynamic remove/add storage adapter test hits EEH on PowerPC: EEH: [c00000000004f75c] __eeh_send_failure_event+0x7c/0x160 EEH: [c000000000048444] eeh_dev_check_failure.part.0+0x254/0x650 EEH: [c008000001650678] eeh_readl+0x60/0x90 [ipr] EEH: [c00800000166746c] ipr_cancel_op+0x2b8/0x524 [ipr] EEH: [c008000001656524] ipr_eh_abort+0x6c/0x130 [ipr] EEH: [c000000000ab0d20] scmd_eh_abort_handler+0x140/0x440 EEH: [c00000000017e558] process_one_work+0x298/0x590 EEH: [c00000000017eef8] worker_thread+0xa8/0x620 EEH: [c00000000018be34] kthread+0x124/0x130 EEH: [c00000000000cd64] ret_from_kernel_thread+0x5c/0x64 A PCIe bus trace reveals that a vector of MSI-X is cleared to 0 by irqbalance daemon. If we disable irqbalance daemon, we won't see the issue. With debug enabled in ipr driver: [ 44.103071] ipr: Entering __ipr_remove [ 44.103083] ipr: Entering ipr_initiate_ioa_bringdown [ 44.103091] ipr: Entering ipr_reset_shutdown_ioa [ 44.103099] ipr: Leaving ipr_reset_shutdown_ioa [ 44.103105] ipr: Leaving ipr_initiate_ioa_bringdown [ 44.149918] ipr: Entering ipr_reset_ucode_download [ 44.149935] ipr: Entering ipr_reset_alert [ 44.150032] ipr: Entering ipr_reset_start_timer [ 44.150038] ipr: Leaving ipr_reset_alert [ 44.244343] scsi 1:2:3:0: alua: Detached [ 44.254300] ipr: Entering ipr_reset_start_bist [ 44.254320] ipr: Entering ipr_reset_start_timer [ 44.254325] ipr: Leaving ipr_reset_start_bist [ 44.364329] scsi 1:2:4:0: alua: Detached [ 45.134341] scsi 1:2:5:0: alua: Detached [ 45.860949] ipr: Entering ipr_reset_shutdown_ioa [ 45.860962] ipr: Leaving ipr_reset_shutdown_ioa [ 45.860966] ipr: Entering ipr_reset_alert [ 45.861028] ipr: Entering ipr_reset_start_timer [ 45.861035] ipr: Leaving ipr_reset_alert [ 45.964302] ipr: Entering ipr_reset_start_bist [ 45.964309] ipr: Entering ipr_reset_start_timer [ 45.964313] ipr: Leaving ipr_reset_start_bist [ 46.264301] ipr: Entering ipr_reset_bist_done [ 46.264309] ipr: Leaving ipr_reset_bist_done During adapter reset, ipr device driver blocks config space access but can't block MMIO access for MSI-X entries. There is very small window: irqbalance daemon kicks in during adapter reset before ipr driver calls pci_restore_state(pdev) to restore MSI-X table. irqbalance daemon reads back all 0 for that MSI-X vector in __pci_read_msi_msg(). irqbalance daemon: msi_domain_set_affinity() ->irq_chip_set_affinity_patent() ->xive_irq_set_affinity() ->irq_chip_compose_msi_msg() ->pseries_msi_compose_msg() ->__pci_read_msi_msg(): read all 0 since didn't call pci_restore_state ->irq_chip_write_msi_msg() -> pci_write_msg_msi(): write 0 to the msix vector entry When ipr driver calls pci_restore_state(pdev) in ipr_reset_restore_cfg_space(), the MSI-X vector entry has been cleared by irqbalance daemon in pci_write_msg_msix(). pci_restore_state() ->__pci_restore_msix_state() Below is the MSI-X table for ipr adapter after irqbalance daemon kicked in during adapter reset: Dump MSIx table: index=0 address_lo=c800 address_hi=10000000 msg_data=0 Dump MSIx table: index=1 address_lo=c810 address_hi=10000000 msg_data=0 Dump MSIx table: index=2 address_lo=c820 address_hi=10000000 msg_data=0 Dump MSIx table: index=3 address_lo=c830 address_hi=10000000 msg_data=0 Dump MSIx table: index=4 address_lo=c840 address_hi=10000000 msg_data=0 Dump MSIx table: index=5 address_lo=c850 address_hi=10000000 msg_data=0 Dump MSIx table: index=6 address_lo=c860 address_hi=10000000 msg_data=0 Dump MSIx table: index=7 address_lo=c870 address_hi=10000000 msg_data=0 Dump MSIx table: index=8 address_lo=0 address_hi=0 msg_data=0 ---------> Hit EEH since msix vector of index=8 are 0 Dump MSIx table: index=9 address_lo=c890 address_hi=10000000 msg_data=0 Dump MSIx table: index=10 address_lo=c8a0 address_hi=10000000 msg_data=0 Dump MSIx table: index=11 address_lo=c8b0 address_hi=10000000 msg_data=0 Dump MSIx table: index=12 address_lo=c8c0 address_hi=10000000 msg_data=0 Dump MSIx table: index=13 address_lo=c8d0 address_hi=10000000 msg_data=0 Dump MSIx table: index=14 address_lo=c8e0 address_hi=10000000 msg_data=0 Dump MSIx table: index=15 address_lo=c8f0 address_hi=10000000 msg_data=0 [ 46.264312] ipr: Entering ipr_reset_restore_cfg_space [ 46.267439] ipr: Entering ipr_fail_all_ops [ 46.267447] ipr: Leaving ipr_fail_all_ops [ 46.267451] ipr: Leaving ipr_reset_restore_cfg_space [ 46.267454] ipr: Entering ipr_ioa_bringdown_done [ 46.267458] ipr: Leaving ipr_ioa_bringdown_done [ 46.267467] ipr: Entering ipr_worker_thread [ 46.267470] ipr: Leaving ipr_worker_thread IRQ balancing is not required during adapter reset. Enable "IRQ_NO_BALANCING" flag before starting adapter reset and disable it after calling pci_restore_state(). The irqbalance daemon is disabled for this short period of time (~2s). Co-developed-by: Kyle Mahlkuch Signed-off-by: Kyle Mahlkuch Signed-off-by: Wen Xiong Link: https://patch.msgid.link/20251028142427.3969819-2-wenxiong@linux.ibm.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/ipr.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 4e13797b2a4a..5cda5b3f0020 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -61,8 +61,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -7892,6 +7892,30 @@ static int ipr_dump_mailbox_wait(struct ipr_cmnd *ipr_cmd) return IPR_RC_JOB_RETURN; } +/** + * ipr_set_affinity_nobalance + * @ioa_cfg: ipr_ioa_cfg struct for an ipr device + * @flag: bool + * true: ensable "IRQ_NO_BALANCING" bit for msix interrupt + * false: disable "IRQ_NO_BALANCING" bit for msix interrupt + * Description: This function will be called to disable/enable + * "IRQ_NO_BALANCING" to avoid irqbalance daemon + * kicking in during adapter reset. + **/ +static void ipr_set_affinity_nobalance(struct ipr_ioa_cfg *ioa_cfg, bool flag) +{ + int irq, i; + + for (i = 0; i < ioa_cfg->nvectors; i++) { + irq = pci_irq_vector(ioa_cfg->pdev, i); + + if (flag) + irq_set_status_flags(irq, IRQ_NO_BALANCING); + else + irq_clear_status_flags(irq, IRQ_NO_BALANCING); + } +} + /** * ipr_reset_restore_cfg_space - Restore PCI config space. * @ipr_cmd: ipr command struct @@ -7916,6 +7940,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) return IPR_RC_JOB_CONTINUE; } + ipr_set_affinity_nobalance(ioa_cfg, false); ipr_fail_all_ops(ioa_cfg); if (ioa_cfg->sis64) { @@ -7995,6 +8020,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START); if (rc == PCIBIOS_SUCCESSFUL) { + ipr_set_affinity_nobalance(ioa_cfg, true); ipr_cmd->job_step = ipr_reset_bist_done; ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); rc = IPR_RC_JOB_RETURN; -- Gitee From e4033e1b74e7b0623770569f9d70f0442e8a03dd Mon Sep 17 00:00:00 2001 From: Brian Kao Date: Wed, 12 Nov 2025 14:32:02 +0800 Subject: [PATCH 0938/1449] scsi: ufs: core: Fix EH failure after W-LUN resume error ANBZ: #35228 commit cf73e6020b3d7bd329c09eb21bb0568755ee8536 stable. commit b4bb6daf4ac4d4560044ecdd81e93aa2f6acbb06 upstream. When a W-LUN resume fails, its parent devices in the SCSI hierarchy, including the scsi_target, may be runtime suspended. Subsequently, the error handler in ufshcd_recover_pm_error() fails to set the W-LUN device back to active because the parent target is not active. This results in the following errors: google-ufshcd 3c2d0000.ufs: ufshcd_err_handler started; HBA state eh_fatal; ... ufs_device_wlun 0:0:0:49488: START_STOP failed for power mode: 1, result 40000 ufs_device_wlun 0:0:0:49488: ufshcd_wl_runtime_resume failed: -5 ... ufs_device_wlun 0:0:0:49488: runtime PM trying to activate child device 0:0:0:49488 but parent (target0:0:0) is not active Address this by: 1. Ensuring the W-LUN's parent scsi_target is runtime resumed before attempting to set the W-LUN to active within ufshcd_recover_pm_error(). 2. Explicitly checking for power.runtime_error on the HBA and W-LUN devices before calling pm_runtime_set_active() to clear the error state. 3. Adding pm_runtime_get_sync(hba->dev) in ufshcd_err_handling_prepare() to ensure the HBA itself is active during error recovery, even if a child device resume failed. These changes ensure the device power states are managed correctly during error recovery. Signed-off-by: Brian Kao Tested-by: Brian Kao Reviewed-by: Bart Van Assche Link: https://patch.msgid.link/20251112063214.1195761-1-powenkao@google.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ufs/core/ufshcd.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 50d8a816d943..9f53ee92486d 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -6383,6 +6383,11 @@ static void ufshcd_clk_scaling_suspend(struct ufs_hba *hba, bool suspend) static void ufshcd_err_handling_prepare(struct ufs_hba *hba) { + /* + * A WLUN resume failure could potentially lead to the HBA being + * runtime suspended, so take an extra reference on hba->dev. + */ + pm_runtime_get_sync(hba->dev); ufshcd_rpm_get_sync(hba); if (pm_runtime_status_suspended(&hba->ufs_device_wlun->sdev_gendev) || hba->is_sys_suspended) { @@ -6423,6 +6428,7 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) if (ufshcd_is_clkscaling_supported(hba)) ufshcd_clk_scaling_suspend(hba, false); ufshcd_rpm_put(hba); + pm_runtime_put(hba->dev); } static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) @@ -6437,28 +6443,42 @@ static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) #ifdef CONFIG_PM static void ufshcd_recover_pm_error(struct ufs_hba *hba) { + struct scsi_target *starget = hba->ufs_device_wlun->sdev_target; struct Scsi_Host *shost = hba->host; struct scsi_device *sdev; struct request_queue *q; - int ret; + bool resume_sdev_queues = false; hba->is_sys_suspended = false; + /* - * Set RPM status of wlun device to RPM_ACTIVE, - * this also clears its runtime error. + * Ensure the parent's error status is cleared before proceeding + * to the child, as the parent must be active to activate the child. */ - ret = pm_runtime_set_active(&hba->ufs_device_wlun->sdev_gendev); + if (hba->dev->power.runtime_error) { + /* hba->dev has no functional parent thus simplily set RPM_ACTIVE */ + pm_runtime_set_active(hba->dev); + resume_sdev_queues = true; + } + + if (hba->ufs_device_wlun->sdev_gendev.power.runtime_error) { + /* + * starget, parent of wlun, might be suspended if wlun resume failed. + * Make sure parent is resumed before set child (wlun) active. + */ + pm_runtime_get_sync(&starget->dev); + pm_runtime_set_active(&hba->ufs_device_wlun->sdev_gendev); + pm_runtime_put_sync(&starget->dev); + resume_sdev_queues = true; + } - /* hba device might have a runtime error otherwise */ - if (ret) - ret = pm_runtime_set_active(hba->dev); /* * If wlun device had runtime error, we also need to resume those * consumer scsi devices in case any of them has failed to be * resumed due to supplier runtime resume failure. This is to unblock * blk_queue_enter in case there are bios waiting inside it. */ - if (!ret) { + if (resume_sdev_queues) { shost_for_each_device(sdev, shost) { q = sdev->request_queue; if (q->dev && (q->rpm_status == RPM_SUSPENDED || -- Gitee From 934bc3676ba7492c28e64c57582ffe73aea36a7c Mon Sep 17 00:00:00 2001 From: Xingui Yang Date: Tue, 2 Dec 2025 14:56:27 +0800 Subject: [PATCH 0939/1449] scsi: Revert "scsi: libsas: Fix exp-attached device scan after probe failure scanned in again after probe failed" ANBZ: #35228 commit c6f7b3cf4485601b1eeb326ee17306b75d177b5f stable. commit 278712d20bc8ec29d1ad6ef9bdae9000ef2c220c upstream. This reverts commit ab2068a6fb84751836a84c26ca72b3beb349619d. When probing the exp-attached sata device, libsas/libata will issue a hard reset in sas_probe_sata() -> ata_sas_async_probe(), then a broadcast event will be received after the disk probe fails, and this commit causes the probe will be re-executed on the disk, and a faulty disk may get into an indefinite loop of probe. Therefore, revert this commit, although it can fix some temporary issues with disk probe failure. Signed-off-by: Xingui Yang Reviewed-by: Jason Yan Reviewed-by: John Garry Link: https://patch.msgid.link/20251202065627.140361-1-yangxingui@huawei.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/libsas/sas_internal.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 277e45fed85d..a6dc7dc07fce 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -133,20 +133,6 @@ static inline void sas_fail_probe(struct domain_device *dev, const char *func, i func, dev->parent ? "exp-attached" : "direct-attached", SAS_ADDR(dev->sas_addr), err); - - /* - * If the device probe failed, the expander phy attached address - * needs to be reset so that the phy will not be treated as flutter - * in the next revalidation - */ - if (dev->parent && !dev_is_expander(dev->dev_type)) { - struct sas_phy *phy = dev->phy; - struct domain_device *parent = dev->parent; - struct ex_phy *ex_phy = &parent->ex_dev.ex_phy[phy->number]; - - memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - } - sas_unregister_dev(dev->port, dev); } -- Gitee From d805cc9303a0f147e96a3caf1250e2b98eaef6d9 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Wed, 19 Nov 2025 11:22:40 +0800 Subject: [PATCH 0940/1449] arm64: dts: add off-on-delay-us for usdhc2 regulator ANBZ: #35228 commit 837fe3df686010dac9267a17f60ceb0c8f62a269 stable. commit ca643894a37a25713029b36cfe7d1bae515cac08 upstream. For SD card, according to the spec requirement, for sd card power reset operation, it need sd card supply voltage to be lower than 0.5v and keep over 1ms, otherwise, next time power back the sd card supply voltage to 3.3v, sd card can't support SD3.0 mode again. To match such requirement on imx8qm-mek board, add 4.8ms delay between sd power off and power on. Fixes: 307fd14d4b14 ("arm64: dts: imx: add imx8qm mek support") Reviewed-by: Frank Li Signed-off-by: Haibo Chen Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/freescale/imx8qm-mek.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts index a9ab87699f3d..d22cec32b7ce 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts @@ -38,6 +38,7 @@ reg_usdhc2_vmmc: usdhc2-vmmc { regulator-max-microvolt = <3000000>; gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>; enable-active-high; + off-on-delay-us = <4800>; }; }; -- Gitee From b9328acb06d79ed4ae8f49b623bed8ee3ce6a679 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Thu, 18 Dec 2025 04:21:59 +0800 Subject: [PATCH 0941/1449] netfilter: nft_synproxy: avoid possible data-race on update operation ANBZ: #35228 commit 62ecdf65b8ab0b5b0f664d1dd586ec2fd0b2bb4e stable. commit 36a3200575642846a96436d503d46544533bb943 upstream. During nft_synproxy eval we are reading nf_synproxy_info struct which can be modified on update operation concurrently. As nf_synproxy_info struct fits in 32 bits, use READ_ONCE/WRITE_ONCE annotations. Fixes: ee394f96ad75 ("netfilter: nft_synproxy: add synproxy stateful object support") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nft_synproxy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nft_synproxy.c b/net/netfilter/nft_synproxy.c index 5d3e51825985..4d3e5a31b412 100644 --- a/net/netfilter/nft_synproxy.c +++ b/net/netfilter/nft_synproxy.c @@ -48,7 +48,7 @@ static void nft_synproxy_eval_v4(const struct nft_synproxy *priv, struct tcphdr *_tcph, struct synproxy_options *opts) { - struct nf_synproxy_info info = priv->info; + struct nf_synproxy_info info = READ_ONCE(priv->info); struct net *net = nft_net(pkt); struct synproxy_net *snet = synproxy_pernet(net); struct sk_buff *skb = pkt->skb; @@ -79,7 +79,7 @@ static void nft_synproxy_eval_v6(const struct nft_synproxy *priv, struct tcphdr *_tcph, struct synproxy_options *opts) { - struct nf_synproxy_info info = priv->info; + struct nf_synproxy_info info = READ_ONCE(priv->info); struct net *net = nft_net(pkt); struct synproxy_net *snet = synproxy_pernet(net); struct sk_buff *skb = pkt->skb; @@ -340,7 +340,7 @@ static void nft_synproxy_obj_update(struct nft_object *obj, struct nft_synproxy *newpriv = nft_obj_data(newobj); struct nft_synproxy *priv = nft_obj_data(obj); - priv->info = newpriv->info; + WRITE_ONCE(priv->info, newpriv->info); } static struct nft_object_type nft_synproxy_obj_type; -- Gitee From 4033d426428fc47a6e39f3fd7a527afea276e481 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 1 Sep 2023 21:40:34 +0800 Subject: [PATCH 0942/1449] gpio: pca953x: Utilise dev_err_probe() where it makes sense ANBZ: #35228 commit 2a968d1fd7bd6f47ac3248088bac3b792caee0ab stable. commit c47f7ff0fe61738a40b1b4fef3cd8317ec314079 upstream. At least in pca953x_irq_setup() we may use dev_err_probe(). Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski Stable-dep-of: 014a17deb412 ("gpio: pca953x: handle short interrupt pulses on PCAL devices") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-pca953x.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index faadbe66b23e..3a0b999521e4 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -895,6 +895,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) { struct i2c_client *client = chip->client; + struct device *dev = &client->dev; DECLARE_BITMAP(reg_direction, MAX_LINE); DECLARE_BITMAP(irq_stat, MAX_LINE); struct gpio_irq_chip *girq; @@ -943,11 +944,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) NULL, pca953x_irq_handler, IRQF_ONESHOT | IRQF_SHARED, dev_name(&client->dev), chip); - if (ret) { - dev_err(&client->dev, "failed to request irq %d\n", - client->irq); - return ret; - } + if (ret) + return dev_err_probe(dev, client->irq, "failed to request irq\n"); return 0; } -- Gitee From 7877e8b598973342156215e4035bc36c7204d29c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 1 Sep 2023 21:40:37 +0800 Subject: [PATCH 0943/1449] gpio: pca953x: Utilise temporary variable for struct device ANBZ: #35228 commit 26f64b3ee51728b1fdbae4eb0a330b77d0f5f676 stable. commit 6811886ac91eb414b1b74920e05e6590c3f2a688 upstream. We have a temporary variable to keep pointer to struct device. Utilise it where it makes sense. Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski Stable-dep-of: 014a17deb412 ("gpio: pca953x: handle short interrupt pulses on PCAL devices") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-pca953x.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 3a0b999521e4..de965e6353c5 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -781,11 +781,11 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); + struct device *dev = &chip->client->dev; irq_hw_number_t hwirq = irqd_to_hwirq(d); if (!(type & IRQ_TYPE_EDGE_BOTH)) { - dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", - d->irq, type); + dev_err(dev, "irq %d: unsupported type %d\n", d->irq, type); return -EINVAL; } @@ -902,7 +902,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) int ret; if (dmi_first_match(pca953x_dmi_acpi_irq_info)) { - ret = pca953x_acpi_get_irq(&client->dev); + ret = pca953x_acpi_get_irq(dev); if (ret > 0) client->irq = ret; } @@ -940,10 +940,9 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) girq->threaded = true; girq->first = irq_base; /* FIXME: get rid of this */ - ret = devm_request_threaded_irq(&client->dev, client->irq, - NULL, pca953x_irq_handler, - IRQF_ONESHOT | IRQF_SHARED, - dev_name(&client->dev), chip); + ret = devm_request_threaded_irq(dev, client->irq, NULL, pca953x_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), + chip); if (ret) return dev_err_probe(dev, client->irq, "failed to request irq\n"); @@ -951,13 +950,13 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) } #else /* CONFIG_GPIO_PCA953X_IRQ */ -static int pca953x_irq_setup(struct pca953x_chip *chip, - int irq_base) +static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) { struct i2c_client *client = chip->client; + struct device *dev = &client->dev; if (client->irq && irq_base != -1 && (chip->driver_data & PCA_INT)) - dev_warn(&client->dev, "interrupt support not compiled in\n"); + dev_warn(dev, "interrupt support not compiled in\n"); return 0; } @@ -1048,11 +1047,11 @@ static int pca953x_probe(struct i2c_client *client) int ret; const struct regmap_config *regmap_config; - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; - pdata = dev_get_platdata(&client->dev); + pdata = dev_get_platdata(dev); if (pdata) { irq_base = pdata->irq_base; chip->gpio_start = pdata->gpio_base; @@ -1069,8 +1068,7 @@ static int pca953x_probe(struct i2c_client *client) * using "reset" GPIO. Otherwise any of those platform * must use _DSD method with corresponding property. */ - reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", - GPIOD_OUT_LOW); + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(reset_gpio)) return dev_err_probe(dev, PTR_ERR(reset_gpio), "Failed to get reset gpio\n"); @@ -1090,10 +1088,10 @@ static int pca953x_probe(struct i2c_client *client) pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK); if (NBANK(chip) > 2 || PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { - dev_info(&client->dev, "using AI\n"); + dev_info(dev, "using AI\n"); regmap_config = &pca953x_ai_i2c_regmap; } else { - dev_info(&client->dev, "using no AI\n"); + dev_info(dev, "using no AI\n"); regmap_config = &pca953x_i2c_regmap; } -- Gitee From bd2be0bde8a18cbfa2df87712375160a0ed03216 Mon Sep 17 00:00:00 2001 From: Potin Lai Date: Wed, 9 Apr 2025 23:37:30 +0800 Subject: [PATCH 0944/1449] gpio: pca953x: Add support for level-triggered interrupts ANBZ: #35228 commit 4d7652d1a352591488d2d0dcc374a14b2ea2f335 stable. commit 417b0f8d08f878615de9481c6e8827fbc8b57ed2 upstream. Adds support for level-triggered interrupts in the PCA953x GPIO expander driver. Previously, the driver only supported edge-triggered interrupts, which could lead to missed events in scenarios where an interrupt condition persists until it is explicitly cleared. By enabling level-triggered interrupts, the driver can now detect and respond to sustained interrupt conditions more reliably. Signed-off-by: Potin Lai Link: https://lore.kernel.org/r/20250409-gpio-pca953x-level-triggered-irq-v3-1-7f184d814934@gmail.com Signed-off-by: Bartosz Golaszewski Stable-dep-of: 014a17deb412 ("gpio: pca953x: handle short interrupt pulses on PCAL devices") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-pca953x.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index de965e6353c5..6b9bfdebadb5 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -207,6 +207,8 @@ struct pca953x_chip { DECLARE_BITMAP(irq_stat, MAX_LINE); DECLARE_BITMAP(irq_trig_raise, MAX_LINE); DECLARE_BITMAP(irq_trig_fall, MAX_LINE); + DECLARE_BITMAP(irq_trig_level_high, MAX_LINE); + DECLARE_BITMAP(irq_trig_level_low, MAX_LINE); #endif atomic_t wakeup_path; @@ -767,6 +769,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) pca953x_read_regs(chip, chip->regs->direction, reg_direction); bitmap_or(irq_mask, chip->irq_trig_fall, chip->irq_trig_raise, gc->ngpio); + bitmap_or(irq_mask, irq_mask, chip->irq_trig_level_high, gc->ngpio); + bitmap_or(irq_mask, irq_mask, chip->irq_trig_level_low, gc->ngpio); bitmap_complement(reg_direction, reg_direction, gc->ngpio); bitmap_and(irq_mask, irq_mask, reg_direction, gc->ngpio); @@ -784,13 +788,15 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) struct device *dev = &chip->client->dev; irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (!(type & IRQ_TYPE_EDGE_BOTH)) { + if (!(type & IRQ_TYPE_SENSE_MASK)) { dev_err(dev, "irq %d: unsupported type %d\n", d->irq, type); return -EINVAL; } assign_bit(hwirq, chip->irq_trig_fall, type & IRQ_TYPE_EDGE_FALLING); assign_bit(hwirq, chip->irq_trig_raise, type & IRQ_TYPE_EDGE_RISING); + assign_bit(hwirq, chip->irq_trig_level_low, type & IRQ_TYPE_LEVEL_LOW); + assign_bit(hwirq, chip->irq_trig_level_high, type & IRQ_TYPE_LEVEL_HIGH); return 0; } @@ -803,6 +809,8 @@ static void pca953x_irq_shutdown(struct irq_data *d) clear_bit(hwirq, chip->irq_trig_raise); clear_bit(hwirq, chip->irq_trig_fall); + clear_bit(hwirq, chip->irq_trig_level_low); + clear_bit(hwirq, chip->irq_trig_level_high); } static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p) @@ -833,6 +841,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin DECLARE_BITMAP(cur_stat, MAX_LINE); DECLARE_BITMAP(new_stat, MAX_LINE); DECLARE_BITMAP(trigger, MAX_LINE); + DECLARE_BITMAP(edges, MAX_LINE); int ret; ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); @@ -850,13 +859,26 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin bitmap_copy(chip->irq_stat, new_stat, gc->ngpio); - if (bitmap_empty(trigger, gc->ngpio)) - return false; + if (bitmap_empty(chip->irq_trig_level_high, gc->ngpio) && + bitmap_empty(chip->irq_trig_level_low, gc->ngpio)) { + if (bitmap_empty(trigger, gc->ngpio)) + return false; + } bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio); bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio); - bitmap_or(new_stat, old_stat, cur_stat, gc->ngpio); - bitmap_and(pending, new_stat, trigger, gc->ngpio); + bitmap_or(edges, old_stat, cur_stat, gc->ngpio); + bitmap_and(pending, edges, trigger, gc->ngpio); + + bitmap_and(cur_stat, new_stat, chip->irq_trig_level_high, gc->ngpio); + bitmap_and(cur_stat, cur_stat, chip->irq_mask, gc->ngpio); + bitmap_or(pending, pending, cur_stat, gc->ngpio); + + bitmap_complement(cur_stat, new_stat, gc->ngpio); + bitmap_and(cur_stat, cur_stat, reg_direction, gc->ngpio); + bitmap_and(old_stat, cur_stat, chip->irq_trig_level_low, gc->ngpio); + bitmap_and(old_stat, old_stat, chip->irq_mask, gc->ngpio); + bitmap_or(pending, pending, old_stat, gc->ngpio); return !bitmap_empty(pending, gc->ngpio); } -- Gitee From 7be651d168d081ad4c57e66676d5751eecd5100f Mon Sep 17 00:00:00 2001 From: Ernest Van Hoecke Date: Wed, 17 Dec 2025 23:30:25 +0800 Subject: [PATCH 0945/1449] gpio: pca953x: handle short interrupt pulses on PCAL devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 76f4218bdadde15f6c662fb47d128358474ae74e stable. commit 014a17deb41201449f76df2b20c857a9c3294a7c upstream. GPIO drivers with latch input support may miss short pulses on input pins even when input latching is enabled. The generic interrupt logic in the pca953x driver reports interrupts by comparing the current input value against the previously sampled one and only signals an event when a level change is observed between two reads. For short pulses, the first edge is captured when the input register is read, but if the signal returns to its previous level before the read, the second edge is not observed. As a result, successive pulses can produce identical input values at read time and no level change is detected, causing interrupts to be missed. Below timing diagram shows this situation where the top signal is the input pin level and the bottom signal indicates the latched value. ─────┐ ┌──*───────────────┐ ┌──*─────────────────┐ ┌──*─── │ │ . │ │ . │ │ . │ │ │ │ │ │ │ │ │ └──*──┘ │ └──*──┘ │ └──*──┘ │ Input │ │ │ │ │ │ ▼ │ ▼ │ ▼ │ IRQ │ IRQ │ IRQ │ . . . ─────┐ .┌──────────────┐ .┌────────────────┐ .┌── │ │ │ │ │ │ │ │ │ │ │ │ └────────*┘ └────────*┘ └────────*┘ Latched │ │ │ ▼ ▼ ▼ READ 0 READ 0 READ 0 NO CHANGE NO CHANGE PCAL variants provide an interrupt status register that records which pins triggered an interrupt, but the status and input registers cannot be read atomically. The interrupt status is only cleared when the input port is read, and the input value must also be read to determine the triggering edge. If another interrupt occurs on a different line after the status register has been read but before the input register is sampled, that event will not be reflected in the earlier status snapshot, so relying solely on the interrupt status register is also insufficient. Support for input latching and interrupt status handling was previously added by [1], but the interrupt status-based logic was reverted by [2] due to these issues. This patch addresses the original problem by combining both sources of information. Events indicated by the interrupt status register are merged with events detected through the existing level-change logic. As a result: * short pulses, whose second edges are invisible, are detected via the interrupt status register, and * interrupts that occur between the status and input reads are still caught by the generic level-change logic. This significantly improves robustness on devices that signal interrupts as short pulses, while avoiding the issues that led to the earlier reversion. In practice, even if only the first edge of a pulse is observable, the interrupt is reliably detected. This fixes missed interrupts from an Ilitek touch controller with its interrupt line connected to a PCAL6416A, where active-low pulses are approximately 200 us long. [1] commit 44896beae605 ("gpio: pca953x: add PCAL9535 interrupt support for Galileo Gen2") [2] commit d6179f6c6204 ("gpio: pca953x: Improve interrupt support") Fixes: d6179f6c6204 ("gpio: pca953x: Improve interrupt support") Signed-off-by: Ernest Van Hoecke Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20251217153050.142057-1-ernestvanhoecke@gmail.com Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-pca953x.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 6b9bfdebadb5..120d6695a4b5 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -840,14 +840,35 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin DECLARE_BITMAP(old_stat, MAX_LINE); DECLARE_BITMAP(cur_stat, MAX_LINE); DECLARE_BITMAP(new_stat, MAX_LINE); + DECLARE_BITMAP(int_stat, MAX_LINE); DECLARE_BITMAP(trigger, MAX_LINE); DECLARE_BITMAP(edges, MAX_LINE); int ret; + if (chip->driver_data & PCA_PCAL) { + /* Read INT_STAT before it is cleared by the input-port read. */ + ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, int_stat); + if (ret) + return false; + } + ret = pca953x_read_regs(chip, chip->regs->input, cur_stat); if (ret) return false; + if (chip->driver_data & PCA_PCAL) { + /* Detect short pulses via INT_STAT. */ + bitmap_and(trigger, int_stat, chip->irq_mask, gc->ngpio); + + /* Apply filter for rising/falling edge selection. */ + bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, + cur_stat, gc->ngpio); + + bitmap_and(int_stat, new_stat, trigger, gc->ngpio); + } else { + bitmap_zero(int_stat, gc->ngpio); + } + /* Remove output pins from the equation */ pca953x_read_regs(chip, chip->regs->direction, reg_direction); @@ -861,7 +882,8 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin if (bitmap_empty(chip->irq_trig_level_high, gc->ngpio) && bitmap_empty(chip->irq_trig_level_low, gc->ngpio)) { - if (bitmap_empty(trigger, gc->ngpio)) + if (bitmap_empty(trigger, gc->ngpio) && + bitmap_empty(int_stat, gc->ngpio)) return false; } @@ -869,6 +891,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio); bitmap_or(edges, old_stat, cur_stat, gc->ngpio); bitmap_and(pending, edges, trigger, gc->ngpio); + bitmap_or(pending, pending, int_stat, gc->ngpio); bitmap_and(cur_stat, new_stat, chip->irq_trig_level_high, gc->ngpio); bitmap_and(cur_stat, cur_stat, chip->irq_mask, gc->ngpio); -- Gitee From 00166ebda8eb90fc3ae83edb6f0ffe35584e585d Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 24 Dec 2025 20:48:26 +0800 Subject: [PATCH 0946/1449] netfilter: nf_tables: fix memory leak in nf_tables_newrule() ANBZ: #35228 commit c6cfd767005511b92031c9cba787392ac1f4eb82 stable. commit d077e8119ddbb4fca67540f1a52453631a47f221 upstream. In nf_tables_newrule(), if nft_use_inc() fails, the function jumps to the err_release_rule label without freeing the allocated flow, leading to a memory leak. Fix this by adding a new label err_destroy_flow and jumping to it when nft_use_inc() fails. This ensures that the flow is properly released in this error case. Fixes: 1689f25924ada ("netfilter: nf_tables: report use refcount overflow") Signed-off-by: Zilin Guan Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_tables_api.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 394ee65e1d35..43ebe3b4f886 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4098,7 +4098,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, if (!nft_use_inc(&chain->use)) { err = -EMFILE; - goto err_release_rule; + goto err_destroy_flow; } if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { @@ -4148,6 +4148,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, err_destroy_flow_rule: nft_use_dec_restore(&chain->use); +err_destroy_flow: if (flow) nft_flow_rule_destroy(flow); err_release_rule: -- Gitee From e68cdd41eb05f618ee4cb543b41d6223dc3bff0d Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Wed, 17 Dec 2025 22:46:40 +0800 Subject: [PATCH 0947/1449] netfilter: nf_conncount: update last_gc only when GC has been performed ANBZ: #35228 commit 3cd717359e56f82f06cbf8279b47a7d79880c6f3 stable. commit 7811ba452402d58628e68faedf38745b3d485e3c upstream. Currently last_gc is being updated everytime a new connection is tracked, that means that it is updated even if a GC wasn't performed. With a sufficiently high packet rate, it is possible to always bypass the GC, causing the list to grow infinitely. Update the last_gc value only when a GC has been actually performed. Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_conncount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index c00b8e522c5a..a2c5a7ba0c6f 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -229,6 +229,7 @@ static int __nf_conncount_add(struct net *net, nf_ct_put(found_ct); } + list->last_gc = (u32)jiffies; add_new_node: if (WARN_ON_ONCE(list->count > INT_MAX)) { @@ -248,7 +249,6 @@ static int __nf_conncount_add(struct net *net, conn->jiffies32 = (u32)jiffies; list_add_tail(&conn->node, &list->head); list->count++; - list->last_gc = (u32)jiffies; out_put: if (refcounted) -- Gitee From 9c0bfe74858553a2283397a4ad390302f7abc7c7 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Tue, 30 Dec 2025 13:21:18 +0800 Subject: [PATCH 0948/1449] net: marvell: prestera: fix NULL dereference on devlink_alloc() failure ANBZ: #35228 commit 94e070cd50790317fba7787ae6006934b7edcb6f stable. commit a428e0da1248c353557970848994f35fd3f005e2 upstream. devlink_alloc() may return NULL on allocation failure, but prestera_devlink_alloc() unconditionally calls devlink_priv() on the returned pointer. This leads to a NULL pointer dereference if devlink allocation fails. Add a check for a NULL devlink pointer and return NULL early to avoid the crash. Fixes: 34dd1710f5a3 ("net: marvell: prestera: Add basic devlink support") Signed-off-by: Alok Tiwari Acked-by: Elad Nachman Link: https://patch.msgid.link/20251230052124.897012-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/marvell/prestera/prestera_devlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c index 2a4c9df4eb79..e63d95c1842f 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c @@ -387,6 +387,8 @@ struct prestera_switch *prestera_devlink_alloc(struct prestera_device *dev) dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch), dev->dev); + if (!dl) + return NULL; return devlink_priv(dl); } -- Gitee From 9040953e14edb7db18631de60556819ff8b29bbd Mon Sep 17 00:00:00 2001 From: Alexandre Knecht Date: Sun, 28 Dec 2025 10:00:57 +0800 Subject: [PATCH 0949/1449] bridge: fix C-VLAN preservation in 802.1ad vlan_tunnel egress ANBZ: #35228 commit 4c8facf028ec7ef8a3a70da2039189322e6250cb stable. commit 3128df6be147768fe536986fbb85db1d37806a9f upstream. When using an 802.1ad bridge with vlan_tunnel, the C-VLAN tag is incorrectly stripped from frames during egress processing. br_handle_egress_vlan_tunnel() uses skb_vlan_pop() to remove the S-VLAN from hwaccel before VXLAN encapsulation. However, skb_vlan_pop() also moves any "next" VLAN from the payload into hwaccel: /* move next vlan tag to hw accel tag */ __skb_vlan_pop(skb, &vlan_tci); __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); For QinQ frames where the C-VLAN sits in the payload, this moves it to hwaccel where it gets lost during VXLAN encapsulation. Fix by calling __vlan_hwaccel_clear_tag() directly, which clears only the hwaccel S-VLAN and leaves the payload untouched. This path is only taken when vlan_tunnel is enabled and tunnel_info is configured, so 802.1Q bridges are unaffected. Tested with 802.1ad bridge + VXLAN vlan_tunnel, verified C-VLAN preserved in VXLAN payload via tcpdump. Fixes: 11538d039ac6 ("bridge: vlan dst_metadata hooks in ingress and egress paths") Signed-off-by: Alexandre Knecht Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Link: https://patch.msgid.link/20251228020057.2788865-1-knecht.alexandre@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bridge/br_vlan_tunnel.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_vlan_tunnel.c b/net/bridge/br_vlan_tunnel.c index 81833ca7a2c7..b41494ce5943 100644 --- a/net/bridge/br_vlan_tunnel.c +++ b/net/bridge/br_vlan_tunnel.c @@ -187,7 +187,6 @@ int br_handle_egress_vlan_tunnel(struct sk_buff *skb, { struct metadata_dst *tunnel_dst; __be64 tunnel_id; - int err; if (!vlan) return 0; @@ -197,9 +196,13 @@ int br_handle_egress_vlan_tunnel(struct sk_buff *skb, return 0; skb_dst_drop(skb); - err = skb_vlan_pop(skb); - if (err) - return err; + /* For 802.1ad (QinQ), skb_vlan_pop() incorrectly moves the C-VLAN + * from payload to hwaccel after clearing S-VLAN. We only need to + * clear the hwaccel S-VLAN; the C-VLAN must stay in payload for + * correct VXLAN encapsulation. This is also correct for 802.1Q + * where no C-VLAN exists in payload. + */ + __vlan_hwaccel_clear_tag(skb); if (BR_INPUT_SKB_CB(skb)->backup_nhid) { tunnel_dst = __ip_tun_set_dst(0, 0, 0, 0, 0, TUNNEL_KEY, -- Gitee From 40a6bdbd29fdeb64cb66f0e4da2d4f5c26ce0a4f Mon Sep 17 00:00:00 2001 From: Jerry Wu Date: Fri, 26 Dec 2025 04:36:17 +0800 Subject: [PATCH 0950/1449] net: mscc: ocelot: Fix crash when adding interface under a lag ANBZ: #35228 commit 2985712dc76dfa670eb7fd607c09d4d48e5f5c6e stable. commit 34f3ff52cb9fa7dbf04f5c734fcc4cb6ed5d1a95 upstream. Commit 15faa1f67ab4 ("lan966x: Fix crash when adding interface under a lag") fixed a similar issue in the lan966x driver caused by a NULL pointer dereference. The ocelot_set_aggr_pgids() function in the ocelot driver has similar logic and is susceptible to the same crash. This issue specifically affects the ocelot_vsc7514.c frontend, which leaves unused ports as NULL pointers. The felix_vsc9959.c frontend is unaffected as it uses the DSA framework which registers all ports. Fix this by checking if the port pointer is valid before accessing it. Fixes: 528d3f190c98 ("net: mscc: ocelot: drop the use of the "lags" array") Signed-off-by: Jerry Wu Reviewed-by: Vladimir Oltean Link: https://patch.msgid.link/tencent_75EF812B305E26B0869C673DD1160866C90A@qq.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mscc/ocelot.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 252d8e6f18c3..a77d42d611da 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -2307,14 +2307,16 @@ static void ocelot_set_aggr_pgids(struct ocelot *ocelot) /* Now, set PGIDs for each active LAG */ for (lag = 0; lag < ocelot->num_phys_ports; lag++) { - struct net_device *bond = ocelot->ports[lag]->bond; + struct ocelot_port *ocelot_port = ocelot->ports[lag]; int num_active_ports = 0; + struct net_device *bond; unsigned long bond_mask; u8 aggr_idx[16]; - if (!bond || (visited & BIT(lag))) + if (!ocelot_port || !ocelot_port->bond || (visited & BIT(lag))) continue; + bond = ocelot_port->bond; bond_mask = ocelot_get_bond_mask(ocelot, bond); for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) { -- Gitee From 0e2b91a68e0e43b27a619c746a79bb7179679a08 Mon Sep 17 00:00:00 2001 From: "yuan.gao" Date: Wed, 24 Dec 2025 14:31:45 +0800 Subject: [PATCH 0951/1449] inet: ping: Fix icmp out counting ANBZ: #35228 commit 874794fb4f3dbadfe9f2deb25f6f93a435d8212e stable. commit 4c0856c225b39b1def6c9a6bc56faca79550da13 upstream. When the ping program uses an IPPROTO_ICMP socket to send ICMP_ECHO messages, ICMP_MIB_OUTMSGS is counted twice. ping_v4_sendmsg ping_v4_push_pending_frames ip_push_pending_frames ip_finish_skb __ip_make_skb icmp_out_count(net, icmp_type); // first count icmp_out_count(sock_net(sk), user_icmph.type); // second count However, when the ping program uses an IPPROTO_RAW socket, ICMP_MIB_OUTMSGS is counted correctly only once. Therefore, the first count should be removed. Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind") Signed-off-by: yuan.gao Reviewed-by: Ido Schimmel Tested-by: Ido Schimmel Link: https://patch.msgid.link/20251224063145.3615282-1-yuan.gao@ucloud.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv4/ping.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 5c848136bc26..47f2e7dd554a 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -839,10 +839,8 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) out_free: if (free) kfree(ipc.opt); - if (!err) { - icmp_out_count(sock_net(sk), user_icmph.type); + if (!err) return len; - } return err; do_confirm: -- Gitee From 1dd1286ec351d0bee01221464860b5fddaacc6ef Mon Sep 17 00:00:00 2001 From: Weiming Shi Date: Wed, 24 Dec 2025 04:35:35 +0800 Subject: [PATCH 0952/1449] net: sock: fix hardened usercopy panic in sock_recv_errqueue ANBZ: #35228 commit 582a5e922a9652fcbb7d0165c95d5b20aa37575d stable. commit 2a71a1a8d0ed718b1c7a9ac61f07e5755c47ae20 upstream. skbuff_fclone_cache was created without defining a usercopy region, [1] unlike skbuff_head_cache which properly whitelists the cb[] field. [2] This causes a usercopy BUG() when CONFIG_HARDENED_USERCOPY is enabled and the kernel attempts to copy sk_buff.cb data to userspace via sock_recv_errqueue() -> put_cmsg(). The crash occurs when: 1. TCP allocates an skb using alloc_skb_fclone() (from skbuff_fclone_cache) [1] 2. The skb is cloned via skb_clone() using the pre-allocated fclone [3] 3. The cloned skb is queued to sk_error_queue for timestamp reporting 4. Userspace reads the error queue via recvmsg(MSG_ERRQUEUE) 5. sock_recv_errqueue() calls put_cmsg() to copy serr->ee from skb->cb [4] 6. __check_heap_object() fails because skbuff_fclone_cache has no usercopy whitelist [5] When cloned skbs allocated from skbuff_fclone_cache are used in the socket error queue, accessing the sock_exterr_skb structure in skb->cb via put_cmsg() triggers a usercopy hardening violation: [ 5.379589] usercopy: Kernel memory exposure attempt detected from SLUB object 'skbuff_fclone_cache' (offset 296, size 16)! [ 5.382796] kernel BUG at mm/usercopy.c:102! [ 5.383923] Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI [ 5.384903] CPU: 1 UID: 0 PID: 138 Comm: poc_put_cmsg Not tainted 6.12.57 #7 [ 5.384903] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 [ 5.384903] RIP: 0010:usercopy_abort+0x6c/0x80 [ 5.384903] Code: 1a 86 51 48 c7 c2 40 15 1a 86 41 52 48 c7 c7 c0 15 1a 86 48 0f 45 d6 48 c7 c6 80 15 1a 86 48 89 c1 49 0f 45 f3 e8 84 27 88 ff <0f> 0b 490 [ 5.384903] RSP: 0018:ffffc900006f77a8 EFLAGS: 00010246 [ 5.384903] RAX: 000000000000006f RBX: ffff88800f0ad2a8 RCX: 1ffffffff0f72e74 [ 5.384903] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffff87b973a0 [ 5.384903] RBP: 0000000000000010 R08: 0000000000000000 R09: fffffbfff0f72e74 [ 5.384903] R10: 0000000000000003 R11: 79706f6372657375 R12: 0000000000000001 [ 5.384903] R13: ffff88800f0ad2b8 R14: ffffea00003c2b40 R15: ffffea00003c2b00 [ 5.384903] FS: 0000000011bc4380(0000) GS:ffff8880bf100000(0000) knlGS:0000000000000000 [ 5.384903] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 5.384903] CR2: 000056aa3b8e5fe4 CR3: 000000000ea26004 CR4: 0000000000770ef0 [ 5.384903] PKRU: 55555554 [ 5.384903] Call Trace: [ 5.384903] [ 5.384903] __check_heap_object+0x9a/0xd0 [ 5.384903] __check_object_size+0x46c/0x690 [ 5.384903] put_cmsg+0x129/0x5e0 [ 5.384903] sock_recv_errqueue+0x22f/0x380 [ 5.384903] tls_sw_recvmsg+0x7ed/0x1960 [ 5.384903] ? srso_alias_return_thunk+0x5/0xfbef5 [ 5.384903] ? schedule+0x6d/0x270 [ 5.384903] ? srso_alias_return_thunk+0x5/0xfbef5 [ 5.384903] ? mutex_unlock+0x81/0xd0 [ 5.384903] ? __pfx_mutex_unlock+0x10/0x10 [ 5.384903] ? __pfx_tls_sw_recvmsg+0x10/0x10 [ 5.384903] ? _raw_spin_lock_irqsave+0x8f/0xf0 [ 5.384903] ? _raw_read_unlock_irqrestore+0x20/0x40 [ 5.384903] ? srso_alias_return_thunk+0x5/0xfbef5 The crash offset 296 corresponds to skb2->cb within skbuff_fclones: - sizeof(struct sk_buff) = 232 - offsetof(struct sk_buff, cb) = 40 - offset of skb2.cb in fclones = 232 + 40 = 272 - crash offset 296 = 272 + 24 (inside sock_exterr_skb.ee) This patch uses a local stack variable as a bounce buffer to avoid the hardened usercopy check failure. [1] https://elixir.bootlin.com/linux/v6.12.62/source/net/ipv4/tcp.c#L885 [2] https://elixir.bootlin.com/linux/v6.12.62/source/net/core/skbuff.c#L5104 [3] https://elixir.bootlin.com/linux/v6.12.62/source/net/core/skbuff.c#L5566 [4] https://elixir.bootlin.com/linux/v6.12.62/source/net/core/skbuff.c#L5491 [5] https://elixir.bootlin.com/linux/v6.12.62/source/mm/slub.c#L5719 Fixes: 6d07d1cd300f ("usercopy: Restrict non-usercopy caches to size 0") Reported-by: Xiang Mei Signed-off-by: Weiming Shi Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20251223203534.1392218-2-bestswngs@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/sock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index 91f101231309..8e4c87a39dc8 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3653,7 +3653,7 @@ void sock_enable_timestamp(struct sock *sk, enum sock_flags flag) int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, int type) { - struct sock_exterr_skb *serr; + struct sock_extended_err ee; struct sk_buff *skb; int copied, err; @@ -3673,8 +3673,9 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, sock_recv_timestamp(msg, sk, skb); - serr = SKB_EXT_ERR(skb); - put_cmsg(msg, level, type, sizeof(serr->ee), &serr->ee); + /* We must use a bounce buffer for CONFIG_HARDENED_USERCOPY=y */ + ee = SKB_EXT_ERR(skb)->ee; + put_cmsg(msg, level, type, sizeof(ee), &ee); msg->msg_flags |= MSG_ERRQUEUE; err = copied; -- Gitee From e456827acb098593b2292eddb9f3679eddac95a1 Mon Sep 17 00:00:00 2001 From: Di Zhu Date: Wed, 24 Dec 2025 09:22:24 +0800 Subject: [PATCH 0953/1449] netdev: preserve NETIF_F_ALL_FOR_ALL across TSO updates ANBZ: #35228 commit 0ab968d9c56bd076b7541cf9a61ac6b28fbfea67 stable. commit 02d1e1a3f9239cdb3ecf2c6d365fb959d1bf39df upstream. Directly increment the TSO features incurs a side effect: it will also directly clear the flags in NETIF_F_ALL_FOR_ALL on the master device, which can cause issues such as the inability to enable the nocache copy feature on the bonding driver. The fix is to include NETIF_F_ALL_FOR_ALL in the update mask, thereby preventing it from being cleared. Fixes: b0ce3508b25e ("bonding: allow TSO being set on bonding master") Signed-off-by: Di Zhu Link: https://patch.msgid.link/20251224012224.56185-1-zhud@hygon.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/netdevice.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cc469949e777..8ba096cee5cc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -5076,7 +5076,8 @@ netdev_features_t netdev_increment_features(netdev_features_t all, static inline netdev_features_t netdev_add_tso_features(netdev_features_t features, netdev_features_t mask) { - return netdev_increment_features(features, NETIF_F_ALL_TSO, mask); + return netdev_increment_features(features, NETIF_F_ALL_TSO | + NETIF_F_ALL_FOR_ALL, mask); } int __netdev_update_features(struct net_device *dev); -- Gitee From 54b2197ff23cf2e40bd2187dc2857bb6c3090186 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Thu, 25 Dec 2025 21:27:16 +0800 Subject: [PATCH 0954/1449] net/mlx5e: Don't print error message due to invalid module ANBZ: #35228 commit 81e7205b82a7fdcd4f682fc7ea1fb1e1b5065504 stable. commit 144297e2a24e3e54aee1180ec21120ea38822b97 upstream. Dumping module EEPROM on newer modules is supported through the netlink interface only. Querying with old userspace ethtool (or other tools, such as 'lshw') which still uses the ioctl interface results in an error message that could flood dmesg (in addition to the expected error return value). The original message was added under the assumption that the driver should be able to handle all module types, but now that such flows are easily triggered from userspace, it doesn't serve its purpose. Change the log level of the print in mlx5_query_module_eeprom() to debug. Fixes: bb64143eee8c ("net/mlx5e: Add ethtool support for dump module EEPROM") Signed-off-by: Gal Pressman Reviewed-by: Tariq Toukan Signed-off-by: Mark Bloch Link: https://patch.msgid.link/20251225132717.358820-5-mbloch@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index 749f0fc2c189..a5622b44385e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -432,7 +432,8 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, mlx5_qsfp_eeprom_params_set(&query.i2c_address, &query.page, &offset); break; default: - mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id); + mlx5_core_dbg(dev, "Module ID not recognized: 0x%x\n", + module_id); return -EINVAL; } -- Gitee From 020f640c7cd0545e0bfed7c996692066f7977513 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Tue, 30 Dec 2025 15:18:53 +0800 Subject: [PATCH 0955/1449] net: wwan: iosm: Fix memory leak in ipc_mux_deinit() ANBZ: #35228 commit dc6f73f73ce8837bc826556723a5d79392309542 stable. commit 92e6e0a87f6860a4710f9494f8c704d498ae60f8 upstream. Commit 1f52d7b62285 ("net: wwan: iosm: Enable M.2 7360 WWAN card support") allocated memory for pp_qlt in ipc_mux_init() but did not free it in ipc_mux_deinit(). This results in a memory leak when the driver is unloaded. Free the allocated memory in ipc_mux_deinit() to fix the leak. Fixes: 1f52d7b62285 ("net: wwan: iosm: Enable M.2 7360 WWAN card support") Co-developed-by: Jianhao Xu Signed-off-by: Jianhao Xu Signed-off-by: Zilin Guan Reviewed-by: Loic Poulain Link: https://patch.msgid.link/20251230071853.1062223-1-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wwan/iosm/iosm_ipc_mux.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux.c b/drivers/net/wwan/iosm/iosm_ipc_mux.c index fc928b298a98..b846889fcb09 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_mux.c +++ b/drivers/net/wwan/iosm/iosm_ipc_mux.c @@ -456,6 +456,7 @@ void ipc_mux_deinit(struct iosm_mux *ipc_mux) struct sk_buff_head *free_list; union mux_msg mux_msg; struct sk_buff *skb; + int i; if (!ipc_mux->initialized) return; @@ -479,5 +480,10 @@ void ipc_mux_deinit(struct iosm_mux *ipc_mux) ipc_mux->channel->dl_pipe.is_open = false; } + if (ipc_mux->protocol != MUX_LITE) { + for (i = 0; i < IPC_MEM_MUX_IP_SESSION_ENTRIES; i++) + kfree(ipc_mux->ul_adb.pp_qlt[i]); + } + kfree(ipc_mux); } -- Gitee From 93ad8f90232117bc69157dc92471299f02d6f5e9 Mon Sep 17 00:00:00 2001 From: Srijit Bose Date: Wed, 31 Dec 2025 16:36:25 +0800 Subject: [PATCH 0956/1449] bnxt_en: Fix potential data corruption with HW GRO/LRO ANBZ: #35228 commit 970a1ac90325fefe10dc37fe7ffab2bdc50301b3 stable. commit ffeafa65b2b26df2f5b5a6118d3174f17bd12ec5 upstream. Fix the max number of bits passed to find_first_zero_bit() in bnxt_alloc_agg_idx(). We were incorrectly passing the number of long words. find_first_zero_bit() may fail to find a zero bit and cause a wrong ID to be used. If the wrong ID is already in use, this can cause data corruption. Sometimes an error like this can also be seen: bnxt_en 0000:83:00.0 enp131s0np0: TPA end agg_buf 2 != expected agg_bufs 1 Fix it by passing the correct number of bits MAX_TPA_P5. Use DECLARE_BITMAP() to more cleanly define the bitmap. Add a sanity check to warn if a bit cannot be found and reset the ring [MChan]. Fixes: ec4d8e7cf024 ("bnxt_en: Add TPA ID mapping logic for 57500 chips.") Reviewed-by: Ray Jui Signed-off-by: Srijit Bose Signed-off-by: Michael Chan Reviewed-by: Vadim Fedorenko Link: https://patch.msgid.link/20251231083625.3911652-1-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 15 ++++++++++++--- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 +--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 7d21b6b4060d..0d909f820f24 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1268,9 +1268,11 @@ static u16 bnxt_alloc_agg_idx(struct bnxt_rx_ring_info *rxr, u16 agg_id) struct bnxt_tpa_idx_map *map = rxr->rx_tpa_idx_map; u16 idx = agg_id & MAX_TPA_P5_MASK; - if (test_bit(idx, map->agg_idx_bmap)) - idx = find_first_zero_bit(map->agg_idx_bmap, - BNXT_AGG_IDX_BMAP_SIZE); + if (test_bit(idx, map->agg_idx_bmap)) { + idx = find_first_zero_bit(map->agg_idx_bmap, MAX_TPA_P5); + if (idx >= MAX_TPA_P5) + return INVALID_HW_RING_ID; + } __set_bit(idx, map->agg_idx_bmap); map->agg_id_tbl[agg_id] = idx; return idx; @@ -1303,6 +1305,13 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, if (bp->flags & BNXT_FLAG_CHIP_P5) { agg_id = TPA_START_AGG_ID_P5(tpa_start); agg_id = bnxt_alloc_agg_idx(rxr, agg_id); + if (unlikely(agg_id == INVALID_HW_RING_ID)) { + netdev_warn(bp->dev, "Unable to allocate agg ID for ring %d, agg 0x%x\n", + rxr->bnapi->index, + TPA_START_AGG_ID_P5(tpa_start)); + bnxt_sched_reset_rxr(bp, rxr); + return; + } } else { agg_id = TPA_START_AGG_ID(tpa_start); } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 6d42908a374e..bc1ff1085da7 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -898,11 +898,9 @@ struct bnxt_tpa_info { struct rx_agg_cmp *agg_arr; }; -#define BNXT_AGG_IDX_BMAP_SIZE (MAX_TPA_P5 / BITS_PER_LONG) - struct bnxt_tpa_idx_map { u16 agg_id_tbl[1024]; - unsigned long agg_idx_bmap[BNXT_AGG_IDX_BMAP_SIZE]; + DECLARE_BITMAP(agg_idx_bmap, MAX_TPA_P5); }; struct bnxt_rx_ring_info { -- Gitee From 229313a18f9516e41fe0f4dde7eb7128b42ff1bb Mon Sep 17 00:00:00 2001 From: Mohammad Heib Date: Mon, 5 Jan 2026 05:31:01 +0800 Subject: [PATCH 0957/1449] net: fix memory leak in skb_segment_list for GRO packets ANBZ: #35228 commit 88bea149db2057112af3aaf63534b24fab5858ab stable. commit 238e03d0466239410b72294b79494e43d4fabe77 upstream. When skb_segment_list() is called during packet forwarding, it handles packets that were aggregated by the GRO engine. Historically, the segmentation logic in skb_segment_list assumes that individual segments are split from a parent SKB and may need to carry their own socket memory accounting. Accordingly, the code transfers truesize from the parent to the newly created segments. Prior to commit ed4cccef64c1 ("gro: fix ownership transfer"), this truesize subtraction in skb_segment_list() was valid because fragments still carry a reference to the original socket. However, commit ed4cccef64c1 ("gro: fix ownership transfer") changed this behavior by ensuring that fraglist entries are explicitly orphaned (skb->sk = NULL) to prevent illegal orphaning later in the stack. This change meant that the entire socket memory charge remained with the head SKB, but the corresponding accounting logic in skb_segment_list() was never updated. As a result, the current code unconditionally adds each fragment's truesize to delta_truesize and subtracts it from the parent SKB. Since the fragments are no longer charged to the socket, this subtraction results in an effective under-count of memory when the head is freed. This causes sk_wmem_alloc to remain non-zero, preventing socket destruction and leading to a persistent memory leak. The leak can be observed via KMEMLEAK when tearing down the networking environment: unreferenced object 0xffff8881e6eb9100 (size 2048): comm "ping", pid 6720, jiffies 4295492526 backtrace: kmem_cache_alloc_noprof+0x5c6/0x800 sk_prot_alloc+0x5b/0x220 sk_alloc+0x35/0xa00 inet6_create.part.0+0x303/0x10d0 __sock_create+0x248/0x640 __sys_socket+0x11b/0x1d0 Since skb_segment_list() is exclusively used for SKB_GSO_FRAGLIST packets constructed by GRO, the truesize adjustment is removed. The call to skb_release_head_state() must be preserved. As documented in commit cf673ed0e057 ("net: fix fraglist segmentation reference count leak"), it is still required to correctly drop references to SKB extensions that may be overwritten during __copy_skb_header(). Fixes: ed4cccef64c1 ("gro: fix ownership transfer") Signed-off-by: Mohammad Heib Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20260104213101.352887-1-mheib@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/skbuff.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 073e2c527407..4c28954f915f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4344,12 +4344,14 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, { struct sk_buff *list_skb = skb_shinfo(skb)->frag_list; unsigned int tnl_hlen = skb_tnl_header_len(skb); - unsigned int delta_truesize = 0; unsigned int delta_len = 0; struct sk_buff *tail = NULL; struct sk_buff *nskb, *tmp; int len_diff, err; + /* Only skb_gro_receive_list generated skbs arrive here */ + DEBUG_NET_WARN_ON_ONCE(!(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)); + skb_push(skb, -skb_network_offset(skb) + offset); /* Ensure the head is writeable before touching the shared info */ @@ -4363,8 +4365,9 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, nskb = list_skb; list_skb = list_skb->next; + DEBUG_NET_WARN_ON_ONCE(nskb->sk); + err = 0; - delta_truesize += nskb->truesize; if (skb_shared(nskb)) { tmp = skb_clone(nskb, GFP_ATOMIC); if (tmp) { @@ -4407,7 +4410,6 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, goto err_linearize; } - skb->truesize = skb->truesize - delta_truesize; skb->data_len = skb->data_len - delta_len; skb->len = skb->len - delta_len; -- Gitee From b1876c864fb25600aa8d4d7f5999c103b17b9e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Fri, 28 Nov 2025 20:46:41 +0800 Subject: [PATCH 0958/1449] HID: quirks: work around VID/PID conflict for appledisplay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9be826178831cb1d9de5042c5ae34a91d173da03 stable. commit c7fabe4ad9219866c203164a214c474c95b36bf2 upstream. For years I wondered why the Apple Cinema Display driver would not just work for me. Turns out the hidraw driver instantly takes it over. Fix by adding appledisplay VID/PIDs to hid_have_special_driver. Fixes: 069e8a65cd79 ("Driver for Apple Cinema Display") Signed-off-by: René Rebe Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-quirks.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 2da21415e676..192b8f63baaa 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -232,6 +232,15 @@ static const struct hid_device_id hid_quirks[] = { * used as a driver. See hid_scan_report(). */ static const struct hid_device_id hid_have_special_driver[] = { +#if IS_ENABLED(CONFIG_APPLEDISPLAY) + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9218) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9219) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x921c) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x921d) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9222) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9226) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, 0x9236) }, +#endif #if IS_ENABLED(CONFIG_HID_A4TECH) { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, -- Gitee From 3e4c93530e06279cbcd8a43083be941f1a075f8c Mon Sep 17 00:00:00 2001 From: Xiang Mei Date: Tue, 6 Jan 2026 11:41:00 +0800 Subject: [PATCH 0959/1449] net/sched: sch_qfq: Fix NULL deref when deactivating inactive aggregate in qfq_reset ANBZ: #35228 commit 11bf9134613f6c71fc0ff36c5d8d33856f6ae3bb stable. commit c1d73b1480235731e35c81df70b08f4714a7d095 upstream. `qfq_class->leaf_qdisc->q.qlen > 0` does not imply that the class itself is active. Two qfq_class objects may point to the same leaf_qdisc. This happens when: 1. one QFQ qdisc is attached to the dev as the root qdisc, and 2. another QFQ qdisc is temporarily referenced (e.g., via qdisc_get() / qdisc_put()) and is pending to be destroyed, as in function tc_new_tfilter. When packets are enqueued through the root QFQ qdisc, the shared leaf_qdisc->q.qlen increases. At the same time, the second QFQ qdisc triggers qdisc_put and qdisc_destroy: the qdisc enters qfq_reset() with its own q->q.qlen == 0, but its class's leaf qdisc->q.qlen > 0. Therefore, the qfq_reset would wrongly deactivate an inactive aggregate and trigger a null-deref in qfq_deactivate_agg: [ 0.903172] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 0.903571] #PF: supervisor write access in kernel mode [ 0.903860] #PF: error_code(0x0002) - not-present page [ 0.904177] PGD 10299b067 P4D 10299b067 PUD 10299c067 PMD 0 [ 0.904502] Oops: Oops: 0002 [#1] SMP NOPTI [ 0.904737] CPU: 0 UID: 0 PID: 135 Comm: exploit Not tainted 6.19.0-rc3+ #2 NONE [ 0.905157] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014 [ 0.905754] RIP: 0010:qfq_deactivate_agg (include/linux/list.h:992 (discriminator 2) include/linux/list.h:1006 (discriminator 2) net/sched/sch_qfq.c:1367 (discriminator 2) net/sched/sch_qfq.c:1393 (discriminator 2)) [ 0.906046] Code: 0f 84 4d 01 00 00 48 89 70 18 8b 4b 10 48 c7 c2 ff ff ff ff 48 8b 78 08 48 d3 e2 48 21 f2 48 2b 13 48 8b 30 48 d3 ea 8b 4b 18 0 Code starting with the faulting instruction =========================================== 0: 0f 84 4d 01 00 00 je 0x153 6: 48 89 70 18 mov %rsi,0x18(%rax) a: 8b 4b 10 mov 0x10(%rbx),%ecx d: 48 c7 c2 ff ff ff ff mov $0xffffffffffffffff,%rdx 14: 48 8b 78 08 mov 0x8(%rax),%rdi 18: 48 d3 e2 shl %cl,%rdx 1b: 48 21 f2 and %rsi,%rdx 1e: 48 2b 13 sub (%rbx),%rdx 21: 48 8b 30 mov (%rax),%rsi 24: 48 d3 ea shr %cl,%rdx 27: 8b 4b 18 mov 0x18(%rbx),%ecx ... [ 0.907095] RSP: 0018:ffffc900004a39a0 EFLAGS: 00010246 [ 0.907368] RAX: ffff8881043a0880 RBX: ffff888102953340 RCX: 0000000000000000 [ 0.907723] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 0.908100] RBP: ffff888102952180 R08: 0000000000000000 R09: 0000000000000000 [ 0.908451] R10: ffff8881043a0000 R11: 0000000000000000 R12: ffff888102952000 [ 0.908804] R13: ffff888102952180 R14: ffff8881043a0ad8 R15: ffff8881043a0880 [ 0.909179] FS: 000000002a1a0380(0000) GS:ffff888196d8d000(0000) knlGS:0000000000000000 [ 0.909572] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.909857] CR2: 0000000000000000 CR3: 0000000102993002 CR4: 0000000000772ef0 [ 0.910247] PKRU: 55555554 [ 0.910391] Call Trace: [ 0.910527] [ 0.910638] qfq_reset_qdisc (net/sched/sch_qfq.c:357 net/sched/sch_qfq.c:1485) [ 0.910826] qdisc_reset (include/linux/skbuff.h:2195 include/linux/skbuff.h:2501 include/linux/skbuff.h:3424 include/linux/skbuff.h:3430 net/sched/sch_generic.c:1036) [ 0.911040] __qdisc_destroy (net/sched/sch_generic.c:1076) [ 0.911236] tc_new_tfilter (net/sched/cls_api.c:2447) [ 0.911447] rtnetlink_rcv_msg (net/core/rtnetlink.c:6958) [ 0.911663] ? __pfx_rtnetlink_rcv_msg (net/core/rtnetlink.c:6861) [ 0.911894] netlink_rcv_skb (net/netlink/af_netlink.c:2550) [ 0.912100] netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344) [ 0.912296] ? __alloc_skb (net/core/skbuff.c:706) [ 0.912484] netlink_sendmsg (net/netlink/af_netlink.c:1894) [ 0.912682] sock_write_iter (net/socket.c:727 (discriminator 1) net/socket.c:742 (discriminator 1) net/socket.c:1195 (discriminator 1)) [ 0.912880] vfs_write (fs/read_write.c:593 fs/read_write.c:686) [ 0.913077] ksys_write (fs/read_write.c:738) [ 0.913252] do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) [ 0.913438] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131) [ 0.913687] RIP: 0033:0x424c34 [ 0.913844] Code: 89 02 48 c7 c0 ff ff ff ff eb bd 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 80 3d 2d 44 09 00 00 74 13 b8 01 00 00 00 0f 05 9 Code starting with the faulting instruction =========================================== 0: 89 02 mov %eax,(%rdx) 2: 48 c7 c0 ff ff ff ff mov $0xffffffffffffffff,%rax 9: eb bd jmp 0xffffffffffffffc8 b: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) 12: 00 00 00 15: 90 nop 16: f3 0f 1e fa endbr64 1a: 80 3d 2d 44 09 00 00 cmpb $0x0,0x9442d(%rip) # 0x9444e 21: 74 13 je 0x36 23: b8 01 00 00 00 mov $0x1,%eax 28: 0f 05 syscall 2a: 09 .byte 0x9 [ 0.914807] RSP: 002b:00007ffea1938b78 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [ 0.915197] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 0000000000424c34 [ 0.915556] RDX: 000000000000003c RSI: 000000002af378c0 RDI: 0000000000000003 [ 0.915912] RBP: 00007ffea1938bc0 R08: 00000000004b8820 R09: 0000000000000000 [ 0.916297] R10: 0000000000000001 R11: 0000000000000202 R12: 00007ffea1938d28 [ 0.916652] R13: 00007ffea1938d38 R14: 00000000004b3828 R15: 0000000000000001 [ 0.917039] [ 0.917158] Modules linked in: [ 0.917316] CR2: 0000000000000000 [ 0.917484] ---[ end trace 0000000000000000 ]--- [ 0.917717] RIP: 0010:qfq_deactivate_agg (include/linux/list.h:992 (discriminator 2) include/linux/list.h:1006 (discriminator 2) net/sched/sch_qfq.c:1367 (discriminator 2) net/sched/sch_qfq.c:1393 (discriminator 2)) [ 0.917978] Code: 0f 84 4d 01 00 00 48 89 70 18 8b 4b 10 48 c7 c2 ff ff ff ff 48 8b 78 08 48 d3 e2 48 21 f2 48 2b 13 48 8b 30 48 d3 ea 8b 4b 18 0 Code starting with the faulting instruction =========================================== 0: 0f 84 4d 01 00 00 je 0x153 6: 48 89 70 18 mov %rsi,0x18(%rax) a: 8b 4b 10 mov 0x10(%rbx),%ecx d: 48 c7 c2 ff ff ff ff mov $0xffffffffffffffff,%rdx 14: 48 8b 78 08 mov 0x8(%rax),%rdi 18: 48 d3 e2 shl %cl,%rdx 1b: 48 21 f2 and %rsi,%rdx 1e: 48 2b 13 sub (%rbx),%rdx 21: 48 8b 30 mov (%rax),%rsi 24: 48 d3 ea shr %cl,%rdx 27: 8b 4b 18 mov 0x18(%rbx),%ecx ... [ 0.918902] RSP: 0018:ffffc900004a39a0 EFLAGS: 00010246 [ 0.919198] RAX: ffff8881043a0880 RBX: ffff888102953340 RCX: 0000000000000000 [ 0.919559] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 [ 0.919908] RBP: ffff888102952180 R08: 0000000000000000 R09: 0000000000000000 [ 0.920289] R10: ffff8881043a0000 R11: 0000000000000000 R12: ffff888102952000 [ 0.920648] R13: ffff888102952180 R14: ffff8881043a0ad8 R15: ffff8881043a0880 [ 0.921014] FS: 000000002a1a0380(0000) GS:ffff888196d8d000(0000) knlGS:0000000000000000 [ 0.921424] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.921710] CR2: 0000000000000000 CR3: 0000000102993002 CR4: 0000000000772ef0 [ 0.922097] PKRU: 55555554 [ 0.922240] Kernel panic - not syncing: Fatal exception [ 0.922590] Kernel Offset: disabled Fixes: 0545a3037773 ("pkt_sched: QFQ - quick fair queue scheduler") Signed-off-by: Xiang Mei Link: https://patch.msgid.link/20260106034100.1780779-1-xmei5@asu.edu Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_qfq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 69fdbbbb3b63..29847c28ffac 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -1484,7 +1484,7 @@ static void qfq_reset_qdisc(struct Qdisc *sch) for (i = 0; i < q->clhash.hashsize; i++) { hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) { - if (cl->qdisc->q.qlen > 0) + if (cl_is_active(cl)) qfq_deactivate_class(q, cl); qdisc_reset(cl->qdisc); -- Gitee From af83041dbbf5936492acf76d8f8ea21f98a77654 Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Tue, 6 Jan 2026 16:48:21 +0800 Subject: [PATCH 0960/1449] net: usb: pegasus: fix memory leak in update_eth_regs_async() ANBZ: #35228 commit 93f18eaa190374e0f2d253e3b1a65cee19a7abe6 stable. commit afa27621a28af317523e0836dad430bec551eb54 upstream. When asynchronously writing to the device registers and if usb_submit_urb() fail, the code fail to release allocated to this point resources. Fixes: 323b34963d11 ("drivers: net: usb: pegasus: fix control urb submission") Signed-off-by: Petko Manolov Link: https://patch.msgid.link/20260106084821.3746677-1-petko.manolov@konsulko.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/pegasus.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 81ca64debc5b..c514483134f0 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -168,6 +168,8 @@ static int update_eth_regs_async(pegasus_t *pegasus) netif_device_detach(pegasus->net); netif_err(pegasus, drv, pegasus->net, "%s returned %d\n", __func__, ret); + usb_free_urb(async_urb); + kfree(req); } return ret; } -- Gitee From f2e08bb44e6cba713a7092f72478528bee52b3d0 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Wed, 7 Jan 2026 17:12:04 +0800 Subject: [PATCH 0961/1449] net: enetc: fix build warning when PAGE_SIZE is greater than 128K ANBZ: #35228 commit 0d254b0a15f294293c7f6982330ce03f23923187 stable. commit 4b5bdabb5449b652122e43f507f73789041d4abe upstream. The max buffer size of ENETC RX BD is 0xFFFF bytes, so if the PAGE_SIZE is greater than 128K, ENETC_RXB_DMA_SIZE and ENETC_RXB_DMA_SIZE_XDP will be greater than 0xFFFF, thus causing a build warning. This will not cause any practical issues because ENETC is currently only used on the ARM64 platform, and the max PAGE_SIZE is 64K. So this patch is only for fixing the build warning that occurs when compiling ENETC drivers for other platforms. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202601050637.kHEKKOG7-lkp@intel.com/ Fixes: e59bc32df2e9 ("net: enetc: correct the value of ENETC_RXB_TRUESIZE") Signed-off-by: Wei Fang Reviewed-by: Frank Li Link: https://patch.msgid.link/20260107091204.1980222-1-wei.fang@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/enetc/enetc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h index dcf3e4b4e3f5..14b2f471fc68 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -44,9 +44,9 @@ struct enetc_tx_swbd { #define ENETC_RXB_TRUESIZE (PAGE_SIZE >> 1) #define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */ #define ENETC_RXB_DMA_SIZE \ - (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD) + min(SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD, 0xffff) #define ENETC_RXB_DMA_SIZE_XDP \ - (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - XDP_PACKET_HEADROOM) + min(SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - XDP_PACKET_HEADROOM, 0xffff) struct enetc_rx_swbd { dma_addr_t dma; -- Gitee From 36ba28df17aaf81eb7b26dd741e57bf0381087cc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 8 Jan 2026 05:22:50 +0800 Subject: [PATCH 0962/1449] arp: do not assume dev_hard_header() does not change skb->head ANBZ: #35228 commit 029935507d0af6553c45380fbf6feecf756fd226 stable. commit c92510f5e3f82ba11c95991824a41e59a9c5ed81 upstream. arp_create() is the only dev_hard_header() caller making assumption about skb->head being unchanged. A recent commit broke this assumption. Initialize @arp pointer after dev_hard_header() call. Fixes: db5b4e39c4e6 ("ip6_gre: make ip6gre_header() robust") Reported-by: syzbot+58b44a770a1585795351@syzkaller.appspotmail.com Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260107212250.384552-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv4/arp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 784dc8b37be5..4ea5987e06b6 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -563,7 +563,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, skb_reserve(skb, hlen); skb_reset_network_header(skb); - arp = skb_put(skb, arp_hdr_len(dev)); + skb_put(skb, arp_hdr_len(dev)); skb->dev = dev; skb->protocol = htons(ETH_P_ARP); if (!src_hw) @@ -571,12 +571,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, if (!dest_hw) dest_hw = dev->broadcast; - /* - * Fill the device header for the ARP frame + /* Fill the device header for the ARP frame. + * Note: skb->head can be changed. */ if (dev_hard_header(skb, dev, ptype, dest_hw, src_hw, skb->len) < 0) goto out; + arp = arp_hdr(skb); /* * Fill out the arp protocol part. * -- Gitee From 3b0ca04b90b3dcf544bcce74affec4c5eac71527 Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Wed, 8 Nov 2023 14:12:15 +0800 Subject: [PATCH 0963/1449] LoongArch: Add more instruction opcodes and emit_* helpers ANBZ: #35228 commit a19df91b5b93be80f032dd831007b9469ceb264b stable. commit add28024405ed600afaa02749989d4fd119f9057 upstream. This patch adds more instruction opcodes and their corresponding emit_* helpers which will be used in later patches. Signed-off-by: Hengqi Chen Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/loongarch/include/asm/inst.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index 1d43a781a2dd..a6f18c6d824d 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -66,6 +66,8 @@ enum reg2_op { revbd_op = 0x0f, revh2w_op = 0x10, revhd_op = 0x11, + extwh_op = 0x16, + extwb_op = 0x17, cpucfg_op = 0x1b, iocsrrdb_op = 0x19200, iocsrrdh_op = 0x19201, @@ -574,6 +576,8 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \ DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op) DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op) DEF_EMIT_REG2_FORMAT(revbd, revbd_op) +DEF_EMIT_REG2_FORMAT(extwh, extwh_op) +DEF_EMIT_REG2_FORMAT(extwb, extwb_op) #define DEF_EMIT_REG2I5_FORMAT(NAME, OP) \ static inline void emit_##NAME(union loongarch_instruction *insn, \ @@ -625,6 +629,9 @@ DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_op) DEF_EMIT_REG2I12_FORMAT(andi, andi_op) DEF_EMIT_REG2I12_FORMAT(ori, ori_op) DEF_EMIT_REG2I12_FORMAT(xori, xori_op) +DEF_EMIT_REG2I12_FORMAT(ldb, ldb_op) +DEF_EMIT_REG2I12_FORMAT(ldh, ldh_op) +DEF_EMIT_REG2I12_FORMAT(ldw, ldw_op) DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op) DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op) DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op) @@ -713,9 +720,12 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \ insn->reg3_format.rk = rk; \ } +DEF_EMIT_REG3_FORMAT(addw, addw_op) DEF_EMIT_REG3_FORMAT(addd, addd_op) DEF_EMIT_REG3_FORMAT(subd, subd_op) DEF_EMIT_REG3_FORMAT(muld, muld_op) +DEF_EMIT_REG3_FORMAT(divd, divd_op) +DEF_EMIT_REG3_FORMAT(modd, modd_op) DEF_EMIT_REG3_FORMAT(divdu, divdu_op) DEF_EMIT_REG3_FORMAT(moddu, moddu_op) DEF_EMIT_REG3_FORMAT(and, and_op) @@ -727,6 +737,9 @@ DEF_EMIT_REG3_FORMAT(srlw, srlw_op) DEF_EMIT_REG3_FORMAT(srld, srld_op) DEF_EMIT_REG3_FORMAT(sraw, sraw_op) DEF_EMIT_REG3_FORMAT(srad, srad_op) +DEF_EMIT_REG3_FORMAT(ldxb, ldxb_op) +DEF_EMIT_REG3_FORMAT(ldxh, ldxh_op) +DEF_EMIT_REG3_FORMAT(ldxw, ldxw_op) DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op) DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op) DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op) -- Gitee From dc4acd495a55103437fe9a9fc3c20905a769b36c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Jan 2026 01:25:57 +0800 Subject: [PATCH 0964/1449] ALSA: ac97bus: Use guard() for mutex locks ANBZ: #35228 commit 3b7c1a3805a517f78ec01c9c738e46a12470097b stable. commit c07824a14d99c10edd4ec4c389d219af336ecf20 upstream. Replace the manual mutex lock/unlock pairs with guard() for code simplification. Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250829151335.7342-18-tiwai@suse.de Stable-dep-of: 830988b6cf19 ("ALSA: ac97: fix a double free in snd_ac97_controller_register()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/ac97/bus.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index 3173e9d98927..1a966d74e8af 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -242,10 +242,9 @@ static ssize_t cold_reset_store(struct device *dev, { struct ac97_controller *ac97_ctrl; - mutex_lock(&ac97_controllers_mutex); + guard(mutex)(&ac97_controllers_mutex); ac97_ctrl = to_ac97_controller(dev); ac97_ctrl->ops->reset(ac97_ctrl); - mutex_unlock(&ac97_controllers_mutex); return len; } static DEVICE_ATTR_WO(cold_reset); @@ -259,10 +258,9 @@ static ssize_t warm_reset_store(struct device *dev, if (!dev) return -ENODEV; - mutex_lock(&ac97_controllers_mutex); + guard(mutex)(&ac97_controllers_mutex); ac97_ctrl = to_ac97_controller(dev); ac97_ctrl->ops->warm_reset(ac97_ctrl); - mutex_unlock(&ac97_controllers_mutex); return len; } static DEVICE_ATTR_WO(warm_reset); @@ -285,10 +283,10 @@ static const struct attribute_group *ac97_adapter_groups[] = { static void ac97_del_adapter(struct ac97_controller *ac97_ctrl) { - mutex_lock(&ac97_controllers_mutex); - ac97_ctrl_codecs_unregister(ac97_ctrl); - list_del(&ac97_ctrl->controllers); - mutex_unlock(&ac97_controllers_mutex); + scoped_guard(mutex, &ac97_controllers_mutex) { + ac97_ctrl_codecs_unregister(ac97_ctrl); + list_del(&ac97_ctrl->controllers); + } device_unregister(&ac97_ctrl->adap); } @@ -312,7 +310,7 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl) { int ret; - mutex_lock(&ac97_controllers_mutex); + guard(mutex)(&ac97_controllers_mutex); ret = idr_alloc(&ac97_adapter_idr, ac97_ctrl, 0, 0, GFP_KERNEL); ac97_ctrl->nr = ret; if (ret >= 0) { @@ -323,13 +321,11 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl) if (ret) put_device(&ac97_ctrl->adap); } - if (!ret) + if (!ret) { list_add(&ac97_ctrl->controllers, &ac97_controllers); - mutex_unlock(&ac97_controllers_mutex); - - if (!ret) dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n", dev_name(ac97_ctrl->parent)); + } return ret; } -- Gitee From 3cf4ae69ed4ec0a2637d9d0205610a03d0640f38 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Tue, 13 Jan 2026 01:25:58 +0800 Subject: [PATCH 0965/1449] ALSA: ac97: fix a double free in snd_ac97_controller_register() ANBZ: #35228 commit 21f8bc5179bed91c3f946adb5e55d717b891960c stable. commit 830988b6cf197e6dcffdfe2008c5738e6c6c3c0f upstream. If ac97_add_adapter() fails, put_device() is the correct way to drop the device reference. kfree() is not required. Add kfree() if idr_alloc() fails and in ac97_adapter_release() to do the cleanup. Found by code review. Fixes: 74426fbff66e ("ALSA: ac97: add an ac97 bus") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Link: https://patch.msgid.link/20251219162845.657525-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/ac97/bus.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index 1a966d74e8af..b33a45560b8a 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -299,6 +299,7 @@ static void ac97_adapter_release(struct device *dev) idr_remove(&ac97_adapter_idr, ac97_ctrl->nr); dev_dbg(&ac97_ctrl->adap, "adapter unregistered by %s\n", dev_name(ac97_ctrl->parent)); + kfree(ac97_ctrl); } static const struct device_type ac97_adapter_type = { @@ -320,7 +321,9 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl) ret = device_register(&ac97_ctrl->adap); if (ret) put_device(&ac97_ctrl->adap); - } + } else + kfree(ac97_ctrl); + if (!ret) { list_add(&ac97_ctrl->controllers, &ac97_controllers); dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n", @@ -361,14 +364,11 @@ struct ac97_controller *snd_ac97_controller_register( ret = ac97_add_adapter(ac97_ctrl); if (ret) - goto err; + return ERR_PTR(ret); ac97_bus_reset(ac97_ctrl); ac97_bus_scan(ac97_ctrl); return ac97_ctrl; -err: - kfree(ac97_ctrl); - return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(snd_ac97_controller_register); -- Gitee From 0395695b62540ae33ba33ef28909b2e5ac9599e0 Mon Sep 17 00:00:00 2001 From: Chen Hanxiao Date: Mon, 12 Jan 2026 22:26:59 +0800 Subject: [PATCH 0966/1449] NFS: trace: show TIMEDOUT instead of 0x6e ANBZ: #35228 commit 93a2e7eaf876dbcd4cae416464390a6e6f58cdf3 stable. commit cef48236dfe55fa266d505e8a497963a7bc5ef2a upstream. __nfs_revalidate_inode may return ETIMEDOUT. print symbol of ETIMEDOUT in nfs trace: before: cat-5191 [005] 119.331127: nfs_revalidate_inode_exit: error=-110 (0x6e) after: cat-1738 [004] 44.365509: nfs_revalidate_inode_exit: error=-110 (TIMEDOUT) Signed-off-by: Chen Hanxiao Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Stable-dep-of: c6c209ceb87f ("NFSD: Remove NFSERR_EAGAIN") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/trace/misc/nfs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/trace/misc/nfs.h b/include/trace/misc/nfs.h index 0d9d48dca38a..5b6c36fe9cdf 100644 --- a/include/trace/misc/nfs.h +++ b/include/trace/misc/nfs.h @@ -52,6 +52,7 @@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); { NFSERR_IO, "IO" }, \ { NFSERR_NXIO, "NXIO" }, \ { ECHILD, "CHILD" }, \ + { ETIMEDOUT, "TIMEDOUT" }, \ { NFSERR_EAGAIN, "AGAIN" }, \ { NFSERR_ACCES, "ACCES" }, \ { NFSERR_EXIST, "EXIST" }, \ -- Gitee From f80979fcfecf71609289c798ec087f26195d4cc2 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Mon, 12 Jan 2026 22:27:00 +0800 Subject: [PATCH 0967/1449] nfs_common: factor out nfs_errtbl and nfs_stat_to_errno ANBZ: #35228 commit 249d45ca97381d56abeb8e9d882f6c39bbba8381 stable. commit 4806ded4c14c5e8fdc6ce885d83221a78c06a428 upstream. Common nfs_stat_to_errno() is used by both fs/nfs/nfs2xdr.c and fs/nfs/nfs3xdr.c Will also be used by fs/nfsd/localio.c Signed-off-by: Mike Snitzer Reviewed-by: Jeff Layton Reviewed-by: NeilBrown Signed-off-by: Anna Schumaker Stable-dep-of: c6c209ceb87f ("NFSD: Remove NFSERR_EAGAIN") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/Kconfig | 1 + fs/nfs/nfs2xdr.c | 70 +----------------------- fs/nfs/nfs3xdr.c | 108 +++++++------------------------------ fs/nfs/nfs4xdr.c | 4 +- fs/nfs_common/Makefile | 2 + fs/nfs_common/common.c | 67 +++++++++++++++++++++++ fs/nfsd/Kconfig | 1 + include/linux/nfs_common.h | 16 ++++++ 8 files changed, 109 insertions(+), 160 deletions(-) create mode 100644 fs/nfs_common/common.c create mode 100644 include/linux/nfs_common.h diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 2d99f5e7a686..baa8c0bbd0b0 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -5,6 +5,7 @@ config NFS_FS select CRC32 select LOCKD select SUNRPC + select NFS_COMMON select NFS_ACL_SUPPORT if NFS_V3_ACL help Choose Y here if you want to access files residing on other diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index c19093814296..6e75c6c2d234 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -22,14 +22,12 @@ #include #include #include +#include #include "nfstrace.h" #include "internal.h" #define NFSDBG_FACILITY NFSDBG_XDR -/* Mapping from NFS error code to "errno" error code. */ -#define errno_NFSERR_IO EIO - /* * Declare the space requirements for NFS arguments and replies as * number of 32bit-words @@ -64,8 +62,6 @@ #define NFS_readdirres_sz (1+NFS_pagepad_sz) #define NFS_statfsres_sz (1+NFS_info_sz) -static int nfs_stat_to_errno(enum nfs_stat); - /* * Encode/decode NFSv2 basic data types * @@ -1054,70 +1050,6 @@ static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr, return nfs_stat_to_errno(status); } - -/* - * We need to translate between nfs status return values and - * the local errno values which may not be the same. - */ -static const struct { - int stat; - int errno; -} nfs_errtbl[] = { - { NFS_OK, 0 }, - { NFSERR_PERM, -EPERM }, - { NFSERR_NOENT, -ENOENT }, - { NFSERR_IO, -errno_NFSERR_IO}, - { NFSERR_NXIO, -ENXIO }, -/* { NFSERR_EAGAIN, -EAGAIN }, */ - { NFSERR_ACCES, -EACCES }, - { NFSERR_EXIST, -EEXIST }, - { NFSERR_XDEV, -EXDEV }, - { NFSERR_NODEV, -ENODEV }, - { NFSERR_NOTDIR, -ENOTDIR }, - { NFSERR_ISDIR, -EISDIR }, - { NFSERR_INVAL, -EINVAL }, - { NFSERR_FBIG, -EFBIG }, - { NFSERR_NOSPC, -ENOSPC }, - { NFSERR_ROFS, -EROFS }, - { NFSERR_MLINK, -EMLINK }, - { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, - { NFSERR_NOTEMPTY, -ENOTEMPTY }, - { NFSERR_DQUOT, -EDQUOT }, - { NFSERR_STALE, -ESTALE }, - { NFSERR_REMOTE, -EREMOTE }, -#ifdef EWFLUSH - { NFSERR_WFLUSH, -EWFLUSH }, -#endif - { NFSERR_BADHANDLE, -EBADHANDLE }, - { NFSERR_NOT_SYNC, -ENOTSYNC }, - { NFSERR_BAD_COOKIE, -EBADCOOKIE }, - { NFSERR_NOTSUPP, -ENOTSUPP }, - { NFSERR_TOOSMALL, -ETOOSMALL }, - { NFSERR_SERVERFAULT, -EREMOTEIO }, - { NFSERR_BADTYPE, -EBADTYPE }, - { NFSERR_JUKEBOX, -EJUKEBOX }, - { -1, -EIO } -}; - -/** - * nfs_stat_to_errno - convert an NFS status code to a local errno - * @status: NFS status code to convert - * - * Returns a local errno value, or -EIO if the NFS status code is - * not recognized. This function is used jointly by NFSv2 and NFSv3. - */ -static int nfs_stat_to_errno(enum nfs_stat status) -{ - int i; - - for (i = 0; nfs_errtbl[i].stat != -1; i++) { - if (nfs_errtbl[i].stat == (int)status) - return nfs_errtbl[i].errno; - } - dprintk("NFS: Unrecognized nfs status value: %u\n", status); - return nfs_errtbl[i].errno; -} - #define PROC(proc, argtype, restype, timer) \ [NFSPROC_##proc] = { \ .p_proc = NFSPROC_##proc, \ diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 60f032be805a..4ae01c10b7e2 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -21,14 +21,13 @@ #include #include #include +#include + #include "nfstrace.h" #include "internal.h" #define NFSDBG_FACILITY NFSDBG_XDR -/* Mapping from NFS error code to "errno" error code. */ -#define errno_NFSERR_IO EIO - /* * Declare the space requirements for NFS arguments and replies as * number of 32bit-words @@ -91,8 +90,6 @@ NFS3_pagepad_sz) #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) -static int nfs3_stat_to_errno(enum nfs_stat); - /* * Map file type to S_IFMT bits */ @@ -1406,7 +1403,7 @@ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, out: return error; out_default: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1445,7 +1442,7 @@ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1495,7 +1492,7 @@ static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, error = decode_post_op_attr(xdr, result->dir_attr, userns); if (unlikely(error)) goto out; - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1537,7 +1534,7 @@ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, out: return error; out_default: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1578,7 +1575,7 @@ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, out: return error; out_default: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1658,7 +1655,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1728,7 +1725,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1795,7 +1792,7 @@ static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, error = decode_wcc_data(xdr, result->dir_attr, userns); if (unlikely(error)) goto out; - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1835,7 +1832,7 @@ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1881,7 +1878,7 @@ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -1926,7 +1923,7 @@ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /** @@ -2101,7 +2098,7 @@ static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, error = decode_post_op_attr(xdr, result->dir_attr, rpc_rqst_userns(req)); if (unlikely(error)) goto out; - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -2167,7 +2164,7 @@ static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -2243,7 +2240,7 @@ static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -2304,7 +2301,7 @@ static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } /* @@ -2350,7 +2347,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, out: return error; out_status: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } #ifdef CONFIG_NFS_V3_ACL @@ -2416,7 +2413,7 @@ static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, out: return error; out_default: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, @@ -2435,76 +2432,11 @@ static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, out: return error; out_default: - return nfs3_stat_to_errno(status); + return nfs_stat_to_errno(status); } #endif /* CONFIG_NFS_V3_ACL */ - -/* - * We need to translate between nfs status return values and - * the local errno values which may not be the same. - */ -static const struct { - int stat; - int errno; -} nfs_errtbl[] = { - { NFS_OK, 0 }, - { NFSERR_PERM, -EPERM }, - { NFSERR_NOENT, -ENOENT }, - { NFSERR_IO, -errno_NFSERR_IO}, - { NFSERR_NXIO, -ENXIO }, -/* { NFSERR_EAGAIN, -EAGAIN }, */ - { NFSERR_ACCES, -EACCES }, - { NFSERR_EXIST, -EEXIST }, - { NFSERR_XDEV, -EXDEV }, - { NFSERR_NODEV, -ENODEV }, - { NFSERR_NOTDIR, -ENOTDIR }, - { NFSERR_ISDIR, -EISDIR }, - { NFSERR_INVAL, -EINVAL }, - { NFSERR_FBIG, -EFBIG }, - { NFSERR_NOSPC, -ENOSPC }, - { NFSERR_ROFS, -EROFS }, - { NFSERR_MLINK, -EMLINK }, - { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, - { NFSERR_NOTEMPTY, -ENOTEMPTY }, - { NFSERR_DQUOT, -EDQUOT }, - { NFSERR_STALE, -ESTALE }, - { NFSERR_REMOTE, -EREMOTE }, -#ifdef EWFLUSH - { NFSERR_WFLUSH, -EWFLUSH }, -#endif - { NFSERR_BADHANDLE, -EBADHANDLE }, - { NFSERR_NOT_SYNC, -ENOTSYNC }, - { NFSERR_BAD_COOKIE, -EBADCOOKIE }, - { NFSERR_NOTSUPP, -ENOTSUPP }, - { NFSERR_TOOSMALL, -ETOOSMALL }, - { NFSERR_SERVERFAULT, -EREMOTEIO }, - { NFSERR_BADTYPE, -EBADTYPE }, - { NFSERR_JUKEBOX, -EJUKEBOX }, - { -1, -EIO } -}; - -/** - * nfs3_stat_to_errno - convert an NFS status code to a local errno - * @status: NFS status code to convert - * - * Returns a local errno value, or -EIO if the NFS status code is - * not recognized. This function is used jointly by NFSv2 and NFSv3. - */ -static int nfs3_stat_to_errno(enum nfs_stat status) -{ - int i; - - for (i = 0; nfs_errtbl[i].stat != -1; i++) { - if (nfs_errtbl[i].stat == (int)status) - return nfs_errtbl[i].errno; - } - dprintk("NFS: Unrecognized nfs status value: %u\n", status); - return nfs_errtbl[i].errno; -} - - #define PROC(proc, argtype, restype, timer) \ [NFS3PROC_##proc] = { \ .p_proc = NFS3PROC_##proc, \ diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index deec76cf5afe..a9d57fcdf9b4 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "nfs4_fs.h" #include "nfs4trace.h" @@ -63,9 +64,6 @@ #define NFSDBG_FACILITY NFSDBG_XDR -/* Mapping from NFS error code to "errno" error code. */ -#define errno_NFSERR_IO EIO - struct compound_hdr; static int nfs4_stat_to_errno(int); static void encode_layoutget(struct xdr_stream *xdr, diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile index 119c75ab9fd0..e58b01bb8dda 100644 --- a/fs/nfs_common/Makefile +++ b/fs/nfs_common/Makefile @@ -8,3 +8,5 @@ nfs_acl-objs := nfsacl.o obj-$(CONFIG_GRACE_PERIOD) += grace.o obj-$(CONFIG_NFS_V4_2_SSC_HELPER) += nfs_ssc.o + +obj-$(CONFIG_NFS_COMMON) += common.o diff --git a/fs/nfs_common/common.c b/fs/nfs_common/common.c new file mode 100644 index 000000000000..a4ee95da2174 --- /dev/null +++ b/fs/nfs_common/common.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include + +/* + * We need to translate between nfs status return values and + * the local errno values which may not be the same. + */ +static const struct { + int stat; + int errno; +} nfs_errtbl[] = { + { NFS_OK, 0 }, + { NFSERR_PERM, -EPERM }, + { NFSERR_NOENT, -ENOENT }, + { NFSERR_IO, -errno_NFSERR_IO}, + { NFSERR_NXIO, -ENXIO }, +/* { NFSERR_EAGAIN, -EAGAIN }, */ + { NFSERR_ACCES, -EACCES }, + { NFSERR_EXIST, -EEXIST }, + { NFSERR_XDEV, -EXDEV }, + { NFSERR_NODEV, -ENODEV }, + { NFSERR_NOTDIR, -ENOTDIR }, + { NFSERR_ISDIR, -EISDIR }, + { NFSERR_INVAL, -EINVAL }, + { NFSERR_FBIG, -EFBIG }, + { NFSERR_NOSPC, -ENOSPC }, + { NFSERR_ROFS, -EROFS }, + { NFSERR_MLINK, -EMLINK }, + { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, + { NFSERR_NOTEMPTY, -ENOTEMPTY }, + { NFSERR_DQUOT, -EDQUOT }, + { NFSERR_STALE, -ESTALE }, + { NFSERR_REMOTE, -EREMOTE }, +#ifdef EWFLUSH + { NFSERR_WFLUSH, -EWFLUSH }, +#endif + { NFSERR_BADHANDLE, -EBADHANDLE }, + { NFSERR_NOT_SYNC, -ENOTSYNC }, + { NFSERR_BAD_COOKIE, -EBADCOOKIE }, + { NFSERR_NOTSUPP, -ENOTSUPP }, + { NFSERR_TOOSMALL, -ETOOSMALL }, + { NFSERR_SERVERFAULT, -EREMOTEIO }, + { NFSERR_BADTYPE, -EBADTYPE }, + { NFSERR_JUKEBOX, -EJUKEBOX }, + { -1, -EIO } +}; + +/** + * nfs_stat_to_errno - convert an NFS status code to a local errno + * @status: NFS status code to convert + * + * Returns a local errno value, or -EIO if the NFS status code is + * not recognized. This function is used jointly by NFSv2 and NFSv3. + */ +int nfs_stat_to_errno(enum nfs_stat status) +{ + int i; + + for (i = 0; nfs_errtbl[i].stat != -1; i++) { + if (nfs_errtbl[i].stat == (int)status) + return nfs_errtbl[i].errno; + } + return nfs_errtbl[i].errno; +} +EXPORT_SYMBOL_GPL(nfs_stat_to_errno); diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 05c10f70456c..75a3e5407a87 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -8,6 +8,7 @@ config NFSD select LOCKD select SUNRPC select EXPORTFS + select NFS_COMMON select NFS_ACL_SUPPORT if NFSD_V2_ACL select NFS_ACL_SUPPORT if NFSD_V3_ACL depends on MULTIUSER diff --git a/include/linux/nfs_common.h b/include/linux/nfs_common.h new file mode 100644 index 000000000000..3395c4a4d372 --- /dev/null +++ b/include/linux/nfs_common.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This file contains constants and methods used by both NFS client and server. + */ +#ifndef _LINUX_NFS_COMMON_H +#define _LINUX_NFS_COMMON_H + +#include +#include + +/* Mapping from NFS error code to "errno" error code. */ +#define errno_NFSERR_IO EIO + +int nfs_stat_to_errno(enum nfs_stat status); + +#endif /* _LINUX_NFS_COMMON_H */ -- Gitee From d77b06c54ab53346eb363eaca4e3805bddb21c88 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 12 Jan 2026 22:27:01 +0800 Subject: [PATCH 0968/1449] NFSD: Remove NFSERR_EAGAIN ANBZ: #35228 commit 90c4cb136e398e6b7ffdfc307d2f7ce8fc667036 stable. commit c6c209ceb87f64a6ceebe61761951dcbbf4a0baa upstream. I haven't found an NFSERR_EAGAIN in RFCs 1094, 1813, 7530, or 8881. None of these RFCs have an NFS status code that match the numeric value "11". Based on the meaning of the EAGAIN errno, I presume the use of this status in NFSD means NFS4ERR_DELAY. So replace the one usage of nfserr_eagain, and remove it from NFSD's NFS status conversion tables. As far as I can tell, NFSERR_EAGAIN has existed since the pre-git era, but was not actually used by any code until commit f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed."), at which time it become possible for NFSD to return a status code of 11 (which is not valid NFS protocol). Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.") Cc: stable@vger.kernel.org Reviewed-by: NeilBrown Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs_common/common.c | 1 - fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfsd.h | 1 - include/trace/misc/nfs.h | 2 -- include/uapi/linux/nfs.h | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/fs/nfs_common/common.c b/fs/nfs_common/common.c index a4ee95da2174..5cb0781e918f 100644 --- a/fs/nfs_common/common.c +++ b/fs/nfs_common/common.c @@ -16,7 +16,6 @@ static const struct { { NFSERR_NOENT, -ENOENT }, { NFSERR_IO, -errno_NFSERR_IO}, { NFSERR_NXIO, -ENXIO }, -/* { NFSERR_EAGAIN, -EAGAIN }, */ { NFSERR_ACCES, -EACCES }, { NFSERR_EXIST, -EEXIST }, { NFSERR_XDEV, -EXDEV }, diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0ed8be9bc172..c1594876d45f 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1354,7 +1354,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr, (schedule_timeout(20*HZ) == 0)) { finish_wait(&nn->nfsd_ssc_waitq, &wait); kfree(work); - return nfserr_eagain; + return nfserr_jukebox; } finish_wait(&nn->nfsd_ssc_waitq, &wait); goto try_again; diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index d05bd2b811f3..bb24ecbf2109 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -201,7 +201,6 @@ void nfsd_lockd_shutdown(void); #define nfserr_noent cpu_to_be32(NFSERR_NOENT) #define nfserr_io cpu_to_be32(NFSERR_IO) #define nfserr_nxio cpu_to_be32(NFSERR_NXIO) -#define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN) #define nfserr_acces cpu_to_be32(NFSERR_ACCES) #define nfserr_exist cpu_to_be32(NFSERR_EXIST) #define nfserr_xdev cpu_to_be32(NFSERR_XDEV) diff --git a/include/trace/misc/nfs.h b/include/trace/misc/nfs.h index 5b6c36fe9cdf..7d336ba1c34f 100644 --- a/include/trace/misc/nfs.h +++ b/include/trace/misc/nfs.h @@ -16,7 +16,6 @@ TRACE_DEFINE_ENUM(NFSERR_PERM); TRACE_DEFINE_ENUM(NFSERR_NOENT); TRACE_DEFINE_ENUM(NFSERR_IO); TRACE_DEFINE_ENUM(NFSERR_NXIO); -TRACE_DEFINE_ENUM(NFSERR_EAGAIN); TRACE_DEFINE_ENUM(NFSERR_ACCES); TRACE_DEFINE_ENUM(NFSERR_EXIST); TRACE_DEFINE_ENUM(NFSERR_XDEV); @@ -53,7 +52,6 @@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); { NFSERR_NXIO, "NXIO" }, \ { ECHILD, "CHILD" }, \ { ETIMEDOUT, "TIMEDOUT" }, \ - { NFSERR_EAGAIN, "AGAIN" }, \ { NFSERR_ACCES, "ACCES" }, \ { NFSERR_EXIST, "EXIST" }, \ { NFSERR_XDEV, "XDEV" }, \ diff --git a/include/uapi/linux/nfs.h b/include/uapi/linux/nfs.h index 946cb62d64b0..5dc726070b51 100644 --- a/include/uapi/linux/nfs.h +++ b/include/uapi/linux/nfs.h @@ -49,7 +49,6 @@ NFSERR_NOENT = 2, /* v2 v3 v4 */ NFSERR_IO = 5, /* v2 v3 v4 */ NFSERR_NXIO = 6, /* v2 v3 v4 */ - NFSERR_EAGAIN = 11, /* v2 v3 */ NFSERR_ACCES = 13, /* v2 v3 v4 */ NFSERR_EXIST = 17, /* v2 v3 v4 */ NFSERR_XDEV = 18, /* v3 v4 */ -- Gitee From 321ee5b523d74430ddb48b5e5311650768564ef2 Mon Sep 17 00:00:00 2001 From: "Borislav Petkov (AMD)" Date: Mon, 12 Jan 2026 19:27:48 +0800 Subject: [PATCH 0969/1449] x86/microcode/AMD: Select which microcode patch to load ANBZ: #35228 commit 5c7c4131beade68a52dacfc7d7fede833a396837 stable. Commit 8d171045069c804e5ffaa18be590c42c6af0cf3f upstream. All microcode patches up to the proper BIOS Entrysign fix are loaded only after the sha256 signature carried in the driver has been verified. Microcode patches after the Entrysign fix has been applied, do not need that signature verification anymore. In order to not abandon machines which haven't received the BIOS update yet, add the capability to select which microcode patch to load. The corresponding microcode container supplied through firmware-linux has been modified to carry two patches per CPU type (family/model/stepping) so that the proper one gets selected. Signed-off-by: Borislav Petkov (AMD) Tested-by: Waiman Long Link: https://patch.msgid.link/20251027133818.4363-1-bp@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kernel/cpu/microcode/amd.c | 104 ++++++++++++++++++---------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 23282b616d3e..c5d6b4c81da2 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -176,50 +176,61 @@ static u32 cpuid_to_ucode_rev(unsigned int val) return p.ucode_rev; } +static u32 get_cutoff_revision(u32 rev) +{ + switch (rev >> 8) { + case 0x80012: return 0x8001277; break; + case 0x80082: return 0x800820f; break; + case 0x83010: return 0x830107c; break; + case 0x86001: return 0x860010e; break; + case 0x86081: return 0x8608108; break; + case 0x87010: return 0x8701034; break; + case 0x8a000: return 0x8a0000a; break; + case 0xa0010: return 0xa00107a; break; + case 0xa0011: return 0xa0011da; break; + case 0xa0012: return 0xa001243; break; + case 0xa0082: return 0xa00820e; break; + case 0xa1011: return 0xa101153; break; + case 0xa1012: return 0xa10124e; break; + case 0xa1081: return 0xa108109; break; + case 0xa2010: return 0xa20102f; break; + case 0xa2012: return 0xa201212; break; + case 0xa4041: return 0xa404109; break; + case 0xa5000: return 0xa500013; break; + case 0xa6012: return 0xa60120a; break; + case 0xa7041: return 0xa704109; break; + case 0xa7052: return 0xa705208; break; + case 0xa7080: return 0xa708009; break; + case 0xa70c0: return 0xa70C009; break; + case 0xaa001: return 0xaa00116; break; + case 0xaa002: return 0xaa00218; break; + case 0xb0021: return 0xb002146; break; + case 0xb0081: return 0xb008111; break; + case 0xb1010: return 0xb101046; break; + case 0xb2040: return 0xb204031; break; + case 0xb4040: return 0xb404031; break; + case 0xb4041: return 0xb404101; break; + case 0xb6000: return 0xb600031; break; + case 0xb6080: return 0xb608031; break; + case 0xb7000: return 0xb700031; break; + default: break; + + } + return 0; +} + static bool need_sha_check(u32 cur_rev) { + u32 cutoff; + if (!cur_rev) { cur_rev = cpuid_to_ucode_rev(bsp_cpuid_1_eax); pr_info_once("No current revision, generating the lowest one: 0x%x\n", cur_rev); } - switch (cur_rev >> 8) { - case 0x80012: return cur_rev <= 0x8001277; break; - case 0x80082: return cur_rev <= 0x800820f; break; - case 0x83010: return cur_rev <= 0x830107c; break; - case 0x86001: return cur_rev <= 0x860010e; break; - case 0x86081: return cur_rev <= 0x8608108; break; - case 0x87010: return cur_rev <= 0x8701034; break; - case 0x8a000: return cur_rev <= 0x8a0000a; break; - case 0xa0010: return cur_rev <= 0xa00107a; break; - case 0xa0011: return cur_rev <= 0xa0011da; break; - case 0xa0012: return cur_rev <= 0xa001243; break; - case 0xa0082: return cur_rev <= 0xa00820e; break; - case 0xa1011: return cur_rev <= 0xa101153; break; - case 0xa1012: return cur_rev <= 0xa10124e; break; - case 0xa1081: return cur_rev <= 0xa108109; break; - case 0xa2010: return cur_rev <= 0xa20102f; break; - case 0xa2012: return cur_rev <= 0xa201212; break; - case 0xa4041: return cur_rev <= 0xa404109; break; - case 0xa5000: return cur_rev <= 0xa500013; break; - case 0xa6012: return cur_rev <= 0xa60120a; break; - case 0xa7041: return cur_rev <= 0xa704109; break; - case 0xa7052: return cur_rev <= 0xa705208; break; - case 0xa7080: return cur_rev <= 0xa708009; break; - case 0xa70c0: return cur_rev <= 0xa70C009; break; - case 0xaa001: return cur_rev <= 0xaa00116; break; - case 0xaa002: return cur_rev <= 0xaa00218; break; - case 0xb0021: return cur_rev <= 0xb002146; break; - case 0xb0081: return cur_rev <= 0xb008111; break; - case 0xb1010: return cur_rev <= 0xb101046; break; - case 0xb2040: return cur_rev <= 0xb204031; break; - case 0xb4040: return cur_rev <= 0xb404031; break; - case 0xb4041: return cur_rev <= 0xb404101; break; - case 0xb6000: return cur_rev <= 0xb600031; break; - case 0xb6080: return cur_rev <= 0xb608031; break; - case 0xb7000: return cur_rev <= 0xb700031; break; - default: break; - } + cutoff = get_cutoff_revision(cur_rev); + if (cutoff) + return cur_rev <= cutoff; pr_info("You should not be seeing this. Please send the following couple of lines to x86--kernel.org\n"); pr_info("CPUID(1).EAX: 0x%x, current revision: 0x%x\n", bsp_cpuid_1_eax, cur_rev); @@ -477,6 +488,7 @@ static int verify_patch(const u8 *buf, size_t buf_size, u32 *patch_size) { u8 family = x86_family(bsp_cpuid_1_eax); struct microcode_header_amd *mc_hdr; + u32 cur_rev, cutoff, patch_rev; u32 sh_psize; u16 proc_id; u8 patch_fam; @@ -518,6 +530,24 @@ static int verify_patch(const u8 *buf, size_t buf_size, u32 *patch_size) if (patch_fam != family) return 1; + cur_rev = get_patch_level(); + + /* No cutoff revision means old/unaffected by signing algorithm weakness => matches */ + cutoff = get_cutoff_revision(cur_rev); + if (!cutoff) + goto ok; + + patch_rev = mc_hdr->patch_id; + + if (cur_rev <= cutoff && patch_rev <= cutoff) + goto ok; + + if (cur_rev > cutoff && patch_rev > cutoff) + goto ok; + + return 1; +ok: + return 0; } -- Gitee From ba7a57f351c854415bcd3de56ee3223a481e6edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Date: Wed, 14 Jan 2026 09:18:30 +0800 Subject: [PATCH 0970/1449] riscv: uprobes: Add missing fence.i after building the XOL buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 77c956152a3a7c7a18b68f3654f70565b2181d03 stable. commit 7d1d19a11cfbfd8bae1d89cc010b2cc397cd0c48 upstream. The XOL (execute out-of-line) buffer is used to single-step the replaced instruction(s) for uprobes. The RISC-V port was missing a proper fence.i (i$ flushing) after constructing the XOL buffer, which can result in incorrect execution of stale/broken instructions. This was found running the BPF selftests "test_progs: uprobe_autoattach, attach_probe" on the Spacemit K1/X60, where the uprobes tests randomly blew up. Reviewed-by: Guo Ren Fixes: 74784081aac8 ("riscv: Add uprobes supported") Signed-off-by: Björn Töpel Link: https://lore.kernel.org/r/20250419111402.1660267-2-bjorn@kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/riscv/kernel/probes/uprobes.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c index 4b3dc8beaf77..cc15f7ca6cc1 100644 --- a/arch/riscv/kernel/probes/uprobes.c +++ b/arch/riscv/kernel/probes/uprobes.c @@ -167,6 +167,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, /* Initialize the slot */ void *kaddr = kmap_atomic(page); void *dst = kaddr + (vaddr & ~PAGE_MASK); + unsigned long start = (unsigned long)dst; memcpy(dst, src, len); @@ -176,13 +177,6 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, *(uprobe_opcode_t *)dst = __BUG_INSN_32; } + flush_icache_range(start, start + len); kunmap_atomic(kaddr); - - /* - * We probably need flush_icache_user_page() but it needs vma. - * This should work on most of architectures by default. If - * architecture needs to do something different it can define - * its own version of the function. - */ - flush_dcache_page(page); } -- Gitee From 97ade1da88908d94dd0278de95b4ba9be7e65e67 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Thu, 12 Jun 2025 11:50:32 +0800 Subject: [PATCH 0971/1449] bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater than 4K ANBZ: #35228 commit a60c827903b45e2cbf45de782d0a14c2037e2122 stable. commit 4fc012daf9c074772421c904357abf586336b1ca upstream. The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on arm64 with 64KB page: xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on when constructing frags, with 64K page size, the frag data_len could be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail(). To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel can test different page size properly. With the kernel change, the user space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default value is 17, so for 4K page, the maximum packet size will be less than 68K. To test 64K page, a bigger maximum packet size than 68K is desired. So two different functions are implemented for subtest xdp_adjust_frags_tail_grow. Depending on different page size, different data input/output sizes are used to adapt with different page size. Signed-off-by: Yonghong Song Link: https://lore.kernel.org/r/20250612035032.2207498-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 2 +- .../bpf/prog_tests/xdp_adjust_tail.c | 96 +++++++++++++++++-- .../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +- 3 files changed, 97 insertions(+), 9 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index d6d175b0c928..71294b26be74 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -1202,7 +1202,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, headroom -= ctx->data; } - max_data_sz = 4096 - headroom - tailroom; + max_data_sz = PAGE_SIZE - headroom - tailroom; if (size > max_data_sz) { /* disallow live data mode for jumbo frames */ if (do_live) diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c index 53d6ad8c2257..df90f5b4cee5 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c @@ -37,21 +37,26 @@ static void test_xdp_adjust_tail_shrink(void) bpf_object__close(obj); } -static void test_xdp_adjust_tail_grow(void) +static void test_xdp_adjust_tail_grow(bool is_64k_pagesize) { const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; struct bpf_object *obj; - char buf[4096]; /* avoid segfault: large buf to hold grow results */ + char buf[8192]; /* avoid segfault: large buf to hold grow results */ __u32 expect_sz; int err, prog_fd; LIBBPF_OPTS(bpf_test_run_opts, topts, .data_in = &pkt_v4, - .data_size_in = sizeof(pkt_v4), .data_out = buf, .data_size_out = sizeof(buf), .repeat = 1, ); + /* topts.data_size_in as a special signal to bpf prog */ + if (is_64k_pagesize) + topts.data_size_in = sizeof(pkt_v4) - 1; + else + topts.data_size_in = sizeof(pkt_v4); + err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow")) return; @@ -206,7 +211,7 @@ static void test_xdp_adjust_frags_tail_shrink(void) bpf_object__close(obj); } -static void test_xdp_adjust_frags_tail_grow(void) +static void test_xdp_adjust_frags_tail_grow_4k(void) { const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; __u32 exp_size; @@ -271,16 +276,93 @@ static void test_xdp_adjust_frags_tail_grow(void) bpf_object__close(obj); } +static void test_xdp_adjust_frags_tail_grow_64k(void) +{ + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + __u32 exp_size; + struct bpf_program *prog; + struct bpf_object *obj; + int err, i, prog_fd; + __u8 *buf; + LIBBPF_OPTS(bpf_test_run_opts, topts); + + obj = bpf_object__open(file); + if (libbpf_get_error(obj)) + return; + + prog = bpf_object__next_program(obj, NULL); + if (bpf_object__load(obj)) + goto out; + + prog_fd = bpf_program__fd(prog); + + buf = malloc(262144); + if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb")) + goto out; + + /* Test case add 10 bytes to last frag */ + memset(buf, 1, 262144); + exp_size = 90000 + 10; + + topts.data_in = buf; + topts.data_out = buf; + topts.data_size_in = 90000; + topts.data_size_out = 262144; + err = bpf_prog_test_run_opts(prog_fd, &topts); + + ASSERT_OK(err, "90Kb+10b"); + ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval"); + ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); + + for (i = 0; i < 90000; i++) { + if (buf[i] != 1) + ASSERT_EQ(buf[i], 1, "90Kb+10b-old"); + } + + for (i = 90000; i < 90010; i++) { + if (buf[i] != 0) + ASSERT_EQ(buf[i], 0, "90Kb+10b-new"); + } + + for (i = 90010; i < 262144; i++) { + if (buf[i] != 1) + ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched"); + } + + /* Test a too large grow */ + memset(buf, 1, 262144); + exp_size = 90001; + + topts.data_in = topts.data_out = buf; + topts.data_size_in = 90001; + topts.data_size_out = 262144; + err = bpf_prog_test_run_opts(prog_fd, &topts); + + ASSERT_OK(err, "90Kb+10b"); + ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval"); + ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); + + free(buf); +out: + bpf_object__close(obj); +} + void test_xdp_adjust_tail(void) { + int page_size = getpagesize(); + if (test__start_subtest("xdp_adjust_tail_shrink")) test_xdp_adjust_tail_shrink(); if (test__start_subtest("xdp_adjust_tail_grow")) - test_xdp_adjust_tail_grow(); + test_xdp_adjust_tail_grow(page_size == 65536); if (test__start_subtest("xdp_adjust_tail_grow2")) test_xdp_adjust_tail_grow2(); if (test__start_subtest("xdp_adjust_frags_tail_shrink")) test_xdp_adjust_frags_tail_shrink(); - if (test__start_subtest("xdp_adjust_frags_tail_grow")) - test_xdp_adjust_frags_tail_grow(); + if (test__start_subtest("xdp_adjust_frags_tail_grow")) { + if (page_size == 65536) + test_xdp_adjust_frags_tail_grow_64k(); + else + test_xdp_adjust_frags_tail_grow_4k(); + } } diff --git a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c index 81bb38d72ced..e311e206be07 100644 --- a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +++ b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c @@ -17,7 +17,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) /* Data length determine test case */ if (data_len == 54) { /* sizeof(pkt_v4) */ - offset = 4096; /* test too large offset */ + offset = 4096; /* test too large offset, 4k page size */ + } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */ + offset = 65536; /* test too large offset, 64k page size */ } else if (data_len == 74) { /* sizeof(pkt_v6) */ offset = 40; } else if (data_len == 64) { @@ -29,6 +31,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) offset = 10; } else if (data_len == 9001) { offset = 4096; + } else if (data_len == 90000) { + offset = 10; /* test a small offset, 64k page size */ + } else if (data_len == 90001) { + offset = 65536; /* test too large offset, 64k page size */ } else { return XDP_ABORTED; /* No matching test */ } -- Gitee From 50b2cc948db28cde242bce06c5dd16caffa12cb2 Mon Sep 17 00:00:00 2001 From: Amery Hung Date: Tue, 23 Sep 2025 07:33:53 +0800 Subject: [PATCH 0972/1449] bpf: Make variables in bpf_prog_test_run_xdp less confusing ANBZ: #35228 commit 875d7cb4fe156d1a378bf38400e36797123ca9a6 stable. commit 7eb83bff02ad5e82e8c456c58717ef181c220870 upstream. Change the variable naming in bpf_prog_test_run_xdp() to make the overall logic less confusing. As different modes were added to the function over the time, some variables got overloaded, making it hard to understand and changing the code becomes error-prone. Replace "size" with "linear_sz" where it refers to the size of metadata and data. If "size" refers to input data size, use test.data_size_in directly. Replace "max_data_sz" with "max_linear_sz" to better reflect the fact that it is the maximum size of metadata and data (i.e., linear_sz). Also, xdp_rxq.frags_size is always PAGE_SIZE, so just set it directly instead of subtracting headroom and tailroom and adding them back. Signed-off-by: Amery Hung Signed-off-by: Martin KaFai Lau Link: https://patch.msgid.link/20250922233356.3356453-6-ameryhung@gmail.com Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 71294b26be74..42f1f0567da4 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -1154,9 +1154,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, { bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + u32 retval = 0, duration, max_linear_sz, size; + u32 linear_sz = kattr->test.data_size_in; u32 batch_size = kattr->test.batch_size; - u32 retval = 0, duration, max_data_sz; - u32 size = kattr->test.data_size_in; u32 headroom = XDP_PACKET_HEADROOM; u32 repeat = kattr->test.repeat; struct netdev_rx_queue *rxqueue; @@ -1193,7 +1193,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (ctx) { /* There can't be user provided data before the meta data */ - if (ctx->data_meta || ctx->data_end != size || + if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || ctx->data > ctx->data_end || unlikely(xdp_metalen_invalid(ctx->data)) || (do_live && (kattr->test.data_out || kattr->test.ctx_out))) @@ -1202,30 +1202,30 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, headroom -= ctx->data; } - max_data_sz = PAGE_SIZE - headroom - tailroom; - if (size > max_data_sz) { - /* disallow live data mode for jumbo frames */ - if (do_live) - goto free_ctx; - size = max_data_sz; - } + max_linear_sz = PAGE_SIZE - headroom - tailroom; + linear_sz = min_t(u32, linear_sz, max_linear_sz); + + /* disallow live data mode for jumbo frames */ + if (do_live && kattr->test.data_size_in > linear_sz) + goto free_ctx; - data = bpf_test_init(kattr, size, max_data_sz, headroom, tailroom); + data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); if (IS_ERR(data)) { ret = PTR_ERR(data); goto free_ctx; } rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0); - rxqueue->xdp_rxq.frag_size = headroom + max_data_sz + tailroom; + rxqueue->xdp_rxq.frag_size = PAGE_SIZE; xdp_init_buff(&xdp, rxqueue->xdp_rxq.frag_size, &rxqueue->xdp_rxq); - xdp_prepare_buff(&xdp, data, headroom, size, true); + xdp_prepare_buff(&xdp, data, headroom, linear_sz, true); sinfo = xdp_get_shared_info_from_buff(&xdp); ret = xdp_convert_md_to_buff(ctx, &xdp); if (ret) goto free_data; + size = linear_sz; if (unlikely(kattr->test.data_size_in > size)) { void __user *data_in = u64_to_user_ptr(kattr->test.data_in); -- Gitee From 4363f01673ada6bd804d927a93362f21d3c236f8 Mon Sep 17 00:00:00 2001 From: Amery Hung Date: Tue, 23 Sep 2025 07:33:54 +0800 Subject: [PATCH 0973/1449] bpf: Support specifying linear xdp packet data size for BPF_PROG_TEST_RUN ANBZ: #35228 commit d08b4193cd55adbbf3700cdd777e5b2054ad1485 stable. commit fe9544ed1a2e9217b2c5285c3a4ac0dc5a38bd7b upstream. To test bpf_xdp_pull_data(), an xdp packet containing fragments as well as free linear data area after xdp->data_end needs to be created. However, bpf_prog_test_run_xdp() always fills the linear area with data_in before creating fragments, leaving no space to pull data. This patch will allow users to specify the linear data size through ctx->data_end. Currently, ctx_in->data_end must match data_size_in and will not be the final ctx->data_end seen by xdp programs. This is because ctx->data_end is populated according to the xdp_buff passed to test_run. The linear data area available in an xdp_buff, max_linear_sz, is alawys filled up before copying data_in into fragments. This patch will allow users to specify the size of data that goes into the linear area. When ctx_in->data_end is different from data_size_in, only ctx_in->data_end bytes of data will be put into the linear area when creating the xdp_buff. While ctx_in->data_end will be allowed to be different from data_size_in, it cannot be larger than the data_size_in as there will be no data to copy from user space. If it is larger than the maximum linear data area size, the layout suggested by the user will not be honored. Data beyond max_linear_sz bytes will still be copied into fragments. Finally, since it is possible for a NIC to produce a xdp_buff with empty linear data area, allow it when calling bpf_test_init() from bpf_prog_test_run_xdp() so that we can test XDP kfuncs with such xdp_buff. This is done by moving lower-bound check to callers as most of them already do except bpf_prog_test_run_skb(). The change also fixes a bug that allows passing an xdp_buff with data < ETH_HLEN. This can happen when ctx is used and metadata is at least ETH_HLEN. Signed-off-by: Amery Hung Signed-off-by: Martin KaFai Lau Link: https://patch.msgid.link/20250922233356.3356453-7-ameryhung@gmail.com Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 15 ++++++++++++--- .../bpf/prog_tests/xdp_context_test_run.c | 4 +--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 42f1f0567da4..8231bff66a34 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -640,7 +640,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, void __user *data_in = u64_to_user_ptr(kattr->test.data_in); void *data; - if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) + if (user_size > PAGE_SIZE - headroom - tailroom) return ERR_PTR(-EINVAL); size = SKB_DATA_ALIGN(size); @@ -974,6 +974,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, if (kattr->test.flags || kattr->test.cpu || kattr->test.batch_size) return -EINVAL; + if (size < ETH_HLEN) + return -EINVAL; + data = bpf_test_init(kattr, kattr->test.data_size_in, size, NET_SKB_PAD + NET_IP_ALIGN, SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); @@ -1154,7 +1157,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, { bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - u32 retval = 0, duration, max_linear_sz, size; + u32 retval = 0, meta_sz = 0, duration, max_linear_sz, size; u32 linear_sz = kattr->test.data_size_in; u32 batch_size = kattr->test.batch_size; u32 headroom = XDP_PACKET_HEADROOM; @@ -1193,13 +1196,16 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (ctx) { /* There can't be user provided data before the meta data */ - if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || + if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || ctx->data > ctx->data_end || unlikely(xdp_metalen_invalid(ctx->data)) || (do_live && (kattr->test.data_out || kattr->test.ctx_out))) goto free_ctx; /* Meta data is allocated from the headroom */ headroom -= ctx->data; + + meta_sz = ctx->data; + linear_sz = ctx->data_end; } max_linear_sz = PAGE_SIZE - headroom - tailroom; @@ -1209,6 +1215,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (do_live && kattr->test.data_size_in > linear_sz) goto free_ctx; + if (kattr->test.data_size_in - meta_sz < ETH_HLEN) + return -EINVAL; + data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); if (IS_ERR(data)) { ret = PTR_ERR(data); diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c index ab4952b9fb1d..eab8625aad3b 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c @@ -80,9 +80,7 @@ void test_xdp_context_test_run(void) /* Meta data must be 32 bytes or smaller */ test_xdp_context_error(prog_fd, opts, 0, 36, sizeof(data), 0, 0, 0); - /* Total size of data must match data_end - data_meta */ - test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), - sizeof(data) - 1, 0, 0, 0); + /* Total size of data must be data_end - data_meta or larger */ test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data) + 1, 0, 0, 0); -- Gitee From 4fa9e9cb7811d5dabcf756bf99bc62c66adc4ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Mon, 5 Jan 2026 19:47:45 +0800 Subject: [PATCH 0974/1449] bpf, test_run: Subtract size of xdp_frame from allowed metadata size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 7c81ad5e580bd8441f8a521a8d34824ce6582ae5 stable. commit e558cca217790286e799a8baacd1610bda31b261 upstream. The xdp_frame structure takes up part of the XDP frame headroom, limiting the size of the metadata. However, in bpf_test_run, we don't take this into account, which makes it possible for userspace to supply a metadata size that is too large (taking up the entire headroom). If userspace supplies such a large metadata size in live packet mode, the xdp_update_frame_from_buff() call in xdp_test_run_init_page() call will fail, after which packet transmission proceeds with an uninitialised frame structure, leading to the usual Bad Stuff. The commit in the Fixes tag fixed a related bug where the second check in xdp_update_frame_from_buff() could fail, but did not add any additional constraints on the metadata size. Complete the fix by adding an additional check on the metadata size. Reorder the checks slightly to make the logic clearer and add a comment. Link: https://lore.kernel.org/r/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn Fixes: b6f1f780b393 ("bpf, test_run: Fix packet size check for live packet mode") Reported-by: Yinhao Hu Reported-by: Kaiyan Mei Signed-off-by: Toke Høiland-Jørgensen Reviewed-by: Amery Hung Link: https://lore.kernel.org/r/20260105114747.1358750-1-toke@redhat.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 8231bff66a34..647c6d187742 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -1184,8 +1184,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, batch_size = NAPI_POLL_WEIGHT; else if (batch_size > TEST_XDP_MAX_BATCH) return -E2BIG; - - headroom += sizeof(struct xdp_page_head); } else if (batch_size) { return -EINVAL; } @@ -1198,16 +1196,26 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, /* There can't be user provided data before the meta data */ if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || ctx->data > ctx->data_end || - unlikely(xdp_metalen_invalid(ctx->data)) || (do_live && (kattr->test.data_out || kattr->test.ctx_out))) goto free_ctx; - /* Meta data is allocated from the headroom */ - headroom -= ctx->data; meta_sz = ctx->data; + if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame)) + goto free_ctx; + + /* Meta data is allocated from the headroom */ + headroom -= meta_sz; linear_sz = ctx->data_end; } + /* The xdp_page_head structure takes up space in each page, limiting the + * size of the packet data; add the extra size to headroom here to make + * sure it's accounted in the length checks below, but not in the + * metadata size check above. + */ + if (do_live) + headroom += sizeof(struct xdp_page_head); + max_linear_sz = PAGE_SIZE - headroom - tailroom; linear_sz = min_t(u32, linear_sz, max_linear_sz); -- Gitee From 3771c28e920e061b71bda78f3ae5904ab755154f Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Thu, 8 Jan 2026 20:36:48 +0800 Subject: [PATCH 0975/1449] bpf: Fix reference count leak in bpf_prog_test_run_xdp() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 98676ee71fd4eafeb8be63c7f3f1905d40e03101 stable. commit ec69daabe45256f98ac86c651b8ad1b2574489a7 upstream. syzbot is reporting unregister_netdevice: waiting for sit0 to become free. Usage count = 2 problem. A debug printk() patch found that a refcount is obtained at xdp_convert_md_to_buff() from bpf_prog_test_run_xdp(). According to commit ec94670fcb3b ("bpf: Support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN"), the refcount obtained by xdp_convert_md_to_buff() will be released by xdp_convert_buff_to_md(). Therefore, we can consider that the error handling path introduced by commit 1c1949982524 ("bpf: introduce frags support to bpf_prog_test_run_xdp()") forgot to call xdp_convert_buff_to_md(). Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 Fixes: 1c1949982524 ("bpf: introduce frags support to bpf_prog_test_run_xdp()") Signed-off-by: Tetsuo Handa Reviewed-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/r/af090e53-9d9b-4412-8acb-957733b3975c@I-love.SAKURA.ne.jp Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 647c6d187742..8316f56b54f5 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -1253,13 +1253,13 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (sinfo->nr_frags == MAX_SKB_FRAGS) { ret = -ENOMEM; - goto out; + goto out_put_dev; } page = alloc_page(GFP_KERNEL); if (!page) { ret = -ENOMEM; - goto out; + goto out_put_dev; } frag = &sinfo->frags[sinfo->nr_frags++]; @@ -1271,7 +1271,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, if (copy_from_user(page_address(page), data_in + size, data_len)) { ret = -EFAULT; - goto out; + goto out_put_dev; } sinfo->xdp_frags_size += data_len; size += data_len; @@ -1286,6 +1286,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, ret = bpf_test_run_xdp_live(prog, &xdp, repeat, batch_size, &duration); else ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); +out_put_dev: /* We convert the xdp_buff back to an xdp_md before checking the return * code so the reference count of any held netdevice will be decremented * even if the test run failed. -- Gitee From 5aa48fda08d884560c94f81082b6f601be9740a7 Mon Sep 17 00:00:00 2001 From: Sumeet Pawnikar Date: Sat, 6 Dec 2025 03:02:16 +0800 Subject: [PATCH 0976/1449] powercap: fix race condition in register_control_type() ANBZ: #35228 commit e07dea55aa13435d048ee4bc7ee2d02c4491b47e stable. commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e upstream. The device becomes visible to userspace via device_register() even before it fully initialized by idr_init(). If userspace or another thread tries to register a zone immediately after device_register(), the control_type_valid() will fail because the control_type is not yet in the list. The IDR is not yet initialized, so this race condition causes zone registration failure. Move idr_init() and list addition before device_register() fix the race condition. Signed-off-by: Sumeet Pawnikar [ rjw: Subject adjustment, empty line added ] Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/powercap/powercap_sys.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index 4112a0097338..d14b36b75189 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type( INIT_LIST_HEAD(&control_type->node); control_type->dev.class = &powercap_class; dev_set_name(&control_type->dev, "%s", name); - result = device_register(&control_type->dev); - if (result) { - put_device(&control_type->dev); - return ERR_PTR(result); - } idr_init(&control_type->idr); mutex_lock(&powercap_cntrl_list_lock); list_add_tail(&control_type->node, &powercap_cntrl_list); mutex_unlock(&powercap_cntrl_list_lock); + result = device_register(&control_type->dev); + if (result) { + mutex_lock(&powercap_cntrl_list_lock); + list_del(&control_type->node); + mutex_unlock(&powercap_cntrl_list_lock); + + idr_destroy(&control_type->idr); + put_device(&control_type->dev); + return ERR_PTR(result); + } + return control_type; } EXPORT_SYMBOL_GPL(powercap_register_control_type); -- Gitee From 93d4a256b02ed99ba05a061fbf133bb19c9a5cac Mon Sep 17 00:00:00 2001 From: Sumeet Pawnikar Date: Sun, 7 Dec 2025 23:15:48 +0800 Subject: [PATCH 0977/1449] powercap: fix sscanf() error return value handling ANBZ: #35228 commit c04b3a832c06240ec2abaab02836e5d87a232513 stable. commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 upstream. Fix inconsistent error handling for sscanf() return value check. Implicit boolean conversion is used instead of explicit return value checks. The code checks if (!sscanf(...)) which is incorrect because: 1. sscanf returns the number of successfully parsed items 2. On success, it returns 1 (one item passed) 3. On failure, it returns 0 or EOF 4. The check 'if (!sscanf(...))' is wrong because it treats success (1) as failure All occurrences of sscanf() now uses explicit return value check. With this behavior it returns '-EINVAL' when parsing fails (returns 0 or EOF), and continues when parsing succeeds (returns 1). Signed-off-by: Sumeet Pawnikar [ rjw: Subject and changelog edits ] Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/powercap/powercap_sys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index d14b36b75189..1ff369880beb 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -68,7 +68,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ int id; \ struct powercap_zone_constraint *pconst;\ \ - if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ + if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ return -EINVAL; \ if (id >= power_zone->const_id_cnt) \ return -EINVAL; \ @@ -93,7 +93,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ int id; \ struct powercap_zone_constraint *pconst;\ \ - if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ + if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ return -EINVAL; \ if (id >= power_zone->const_id_cnt) \ return -EINVAL; \ @@ -162,7 +162,7 @@ static ssize_t show_constraint_name(struct device *dev, ssize_t len = -ENODATA; struct powercap_zone_constraint *pconst; - if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) + if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) return -EINVAL; if (id >= power_zone->const_id_cnt) return -EINVAL; -- Gitee From 478195abc427c807cb26b6d739cd5581f29443f6 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Sun, 7 Jul 2024 07:18:25 +0800 Subject: [PATCH 0978/1449] netfilter: nf_tables: avoid chain re-validation if possible ANBZ: #35228 commit 53de1e6cde8f9b791d9cf61aa0e7b02cf5bbe8b1 stable. commit 8e1a1bc4f5a42747c08130b8242ebebd1210b32f upstream. Hamza Mahfooz reports cpu soft lock-ups in nft_chain_validate(): watchdog: BUG: soft lockup - CPU#1 stuck for 27s! [iptables-nft-re:37547] [..] RIP: 0010:nft_chain_validate+0xcb/0x110 [nf_tables] [..] nft_immediate_validate+0x36/0x50 [nf_tables] nft_chain_validate+0xc9/0x110 [nf_tables] nft_immediate_validate+0x36/0x50 [nf_tables] nft_chain_validate+0xc9/0x110 [nf_tables] nft_immediate_validate+0x36/0x50 [nf_tables] nft_chain_validate+0xc9/0x110 [nf_tables] nft_immediate_validate+0x36/0x50 [nf_tables] nft_chain_validate+0xc9/0x110 [nf_tables] nft_immediate_validate+0x36/0x50 [nf_tables] nft_chain_validate+0xc9/0x110 [nf_tables] nft_immediate_validate+0x36/0x50 [nf_tables] nft_chain_validate+0xc9/0x110 [nf_tables] nft_table_validate+0x6b/0xb0 [nf_tables] nf_tables_validate+0x8b/0xa0 [nf_tables] nf_tables_commit+0x1df/0x1eb0 [nf_tables] [..] Currently nf_tables will traverse the entire table (chain graph), starting from the entry points (base chains), exploring all possible paths (chain jumps). But there are cases where we could avoid revalidation. Consider: 1 input -> j2 -> j3 2 input -> j2 -> j3 3 input -> j1 -> j2 -> j3 Then the second rule does not need to revalidate j2, and, by extension j3, because this was already checked during validation of the first rule. We need to validate it only for rule 3. This is needed because chain loop detection also ensures we do not exceed the jump stack: Just because we know that j2 is cycle free, its last jump might now exceed the allowed stack size. We also need to update all reachable chains with the new largest observed call depth. Care has to be taken to revalidate even if the chain depth won't be an issue: chain validation also ensures that expressions are not called from invalid base chains. For example, the masquerade expression can only be called from NAT postrouting base chains. Therefore we also need to keep record of the base chain context (type, hooknum) and revalidate if the chain becomes reachable from a different hook location. Reported-by: Hamza Mahfooz Closes: https://lore.kernel.org/netfilter-devel/20251118221735.GA5477@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net/ Tested-by: Hamza Mahfooz Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/netfilter/nf_tables.h | 34 +++++++++++---- net/netfilter/nf_tables_api.c | 69 +++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index a8fcbdb37a7f..02a73037fae0 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1079,6 +1079,29 @@ struct nft_rule_blob { __attribute__((aligned(__alignof__(struct nft_rule_dp)))); }; +enum nft_chain_types { + NFT_CHAIN_T_DEFAULT = 0, + NFT_CHAIN_T_ROUTE, + NFT_CHAIN_T_NAT, + NFT_CHAIN_T_MAX +}; + +/** + * struct nft_chain_validate_state - validation state + * + * If a chain is encountered again during table validation it is + * possible to avoid revalidation provided the calling context is + * compatible. This structure stores relevant calling context of + * previous validations. + * + * @hook_mask: the hook numbers and locations the chain is linked to + * @depth: the deepest call chain level the chain is linked to + */ +struct nft_chain_validate_state { + u8 hook_mask[NFT_CHAIN_T_MAX]; + u8 depth; +}; + /** * struct nft_chain - nf_tables chain * @@ -1097,6 +1120,7 @@ struct nft_rule_blob { * @udlen: user data length * @udata: user data in the chain * @blob_next: rule blob pointer to the next in the chain + * @vstate: validation state */ struct nft_chain { struct nft_rule_blob __rcu *blob_gen_0; @@ -1116,9 +1140,10 @@ struct nft_chain { /* Only used during control plane commit phase: */ struct nft_rule_blob *blob_next; + struct nft_chain_validate_state vstate; }; -int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain); +int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain); int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, const struct nft_set_iter *iter, struct nft_set_elem *elem); @@ -1126,13 +1151,6 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set); int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); -enum nft_chain_types { - NFT_CHAIN_T_DEFAULT = 0, - NFT_CHAIN_T_ROUTE, - NFT_CHAIN_T_NAT, - NFT_CHAIN_T_MAX -}; - /** * struct nft_chain_type - nf_tables chain type info * diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 43ebe3b4f886..c00dd7dae5cb 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -121,6 +121,29 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s table->validate_state = new_validate_state; } + +static bool nft_chain_vstate_valid(const struct nft_ctx *ctx, + const struct nft_chain *chain) +{ + const struct nft_base_chain *base_chain; + enum nft_chain_types type; + u8 hooknum; + + if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) + return false; + + base_chain = nft_base_chain(ctx->chain); + hooknum = base_chain->ops.hooknum; + type = base_chain->type->type; + + /* chain is already validated for this call depth */ + if (chain->vstate.depth >= ctx->level && + chain->vstate.hook_mask[type] & BIT(hooknum)) + return true; + + return false; +} + static void nf_tables_trans_destroy_work(struct work_struct *w); static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work); @@ -3798,6 +3821,29 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r nf_tables_rule_destroy(ctx, rule); } +static void nft_chain_vstate_update(const struct nft_ctx *ctx, struct nft_chain *chain) +{ + const struct nft_base_chain *base_chain; + enum nft_chain_types type; + u8 hooknum; + + /* ctx->chain must hold the calling base chain. */ + if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) { + memset(&chain->vstate, 0, sizeof(chain->vstate)); + return; + } + + base_chain = nft_base_chain(ctx->chain); + hooknum = base_chain->ops.hooknum; + type = base_chain->type->type; + + BUILD_BUG_ON(BIT(NF_INET_NUMHOOKS) > U8_MAX); + + chain->vstate.hook_mask[type] |= BIT(hooknum); + if (chain->vstate.depth < ctx->level) + chain->vstate.depth = ctx->level; +} + /** nft_chain_validate - loop detection and hook validation * * @ctx: context containing call depth and base chain @@ -3807,15 +3853,25 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r * and set lookups until either the jump limit is hit or all reachable * chains have been validated. */ -int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) +int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain) { struct nft_expr *expr, *last; struct nft_rule *rule; int err; + BUILD_BUG_ON(NFT_JUMP_STACK_SIZE > 255); if (ctx->level == NFT_JUMP_STACK_SIZE) return -EMLINK; + if (ctx->level > 0) { + /* jumps to base chains are not allowed. */ + if (nft_is_base_chain(chain)) + return -ELOOP; + + if (nft_chain_vstate_valid(ctx, chain)) + return 0; + } + list_for_each_entry(rule, &chain->rules, list) { if (fatal_signal_pending(current)) return -EINTR; @@ -3836,6 +3892,7 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) } } + nft_chain_vstate_update(ctx, chain); return 0; } EXPORT_SYMBOL_GPL(nft_chain_validate); @@ -3847,7 +3904,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) .net = net, .family = table->family, }; - int err; + int err = 0; list_for_each_entry(chain, &table->chains, list) { if (!nft_is_base_chain(chain)) @@ -3856,12 +3913,16 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) ctx.chain = chain; err = nft_chain_validate(&ctx, chain); if (err < 0) - return err; + goto err; cond_resched(); } - return 0; +err: + list_for_each_entry(chain, &table->chains, list) + memset(&chain->vstate, 0, sizeof(chain->vstate)); + + return err; } int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, -- Gitee From a7c431fac391e0e0d78d3bbff906ff2707d1c4df Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Sat, 29 Nov 2025 08:38:31 +0800 Subject: [PATCH 0979/1449] drm/amd/display: Fix DP no audio issue ANBZ: #35228 commit f73d92997388b7b50b15b4ac82c5ba0dec138559 stable. commit 3886b198bd6e49c801fe9552fcfbfc387a49fbbc upstream. [why] need to enable APG_CLOCK_ENABLE enable first also need to wake up az from D3 before access az block Reviewed-by: Swapnil Patel Signed-off-by: Charlene Liu Signed-off-by: Chenyu Chen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher (cherry picked from commit bf5e396957acafd46003318965500914d5f4edfa) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index d389eeb264a7..0172fede51b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1097,13 +1097,13 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) num_audio++; } + if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) { + /*wake AZ from D3 first before access az endpoint*/ + clk_mgr->funcs->enable_pme_wa(clk_mgr); + } pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); - if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) - /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ - clk_mgr->funcs->enable_pme_wa(clk_mgr); - link_hwss->enable_audio_packet(pipe_ctx); if (pipe_ctx->stream_res.audio) -- Gitee From 2a745707bbfe6ae7e93349c6d8a670a145cb3f65 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 25 Nov 2025 21:39:59 +0800 Subject: [PATCH 0980/1449] can: j1939: make j1939_session_activate() fail if device is no longer registered ANBZ: #35228 commit 78d87b72cebe2a993fd5b017e9f14fb6278f2eae stable. commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d upstream. syzbot is still reporting unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 even after commit 93a27b5891b8 ("can: j1939: add missing calls in NETDEV_UNREGISTER notification handler") was added. A debug printk() patch found that j1939_session_activate() can succeed even after j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) has completed. Since j1939_cancel_active_session() is processed with the session list lock held, checking ndev->reg_state in j1939_session_activate() with the session list lock held can reliably close the race window. Reported-by: syzbot Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 Signed-off-by: Tetsuo Handa Acked-by: Oleksij Rempel Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/can/j1939/transport.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 9b72d118d756..1186326b0f2e 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -1571,6 +1571,8 @@ int j1939_session_activate(struct j1939_session *session) if (active) { j1939_session_put(active); ret = -EAGAIN; + } else if (priv->ndev->reg_state != NETREG_REGISTERED) { + ret = -ENODEV; } else { WARN_ON_ONCE(session->state != J1939_SESSION_NEW); list_add_tail(&session->active_session_list_entry, -- Gitee From ecbfdbcf451738f896d0e78140dfc1345d59c0c0 Mon Sep 17 00:00:00 2001 From: Jussi Laako Date: Thu, 11 Dec 2025 23:22:21 +0800 Subject: [PATCH 0981/1449] ALSA: usb-audio: Update for native DSD support quirks ANBZ: #35228 commit be3923930a71b114519d8f76aff706b2937a5583 stable. commit da3a7efff64ec0d63af4499eea3a46a2e13b5797 upstream. Maintenance patch for native DSD support. Add set of missing device and vendor quirks; TEAC, Esoteric, Luxman and Musical Fidelity. Signed-off-by: Jussi Laako Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20251211152224.1780782-1-jussi@sonarnerd.net Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/quirks.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 44274f39d693..cde5b5c16509 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2125,6 +2125,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x0644, 0x807d, /* TEAC UD-507 */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x0644, 0x806c, /* Esoteric XD */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_IFACE_DELAY), DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ @@ -2277,6 +2283,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_CTL_MSG_DELAY_1M), DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x3255, 0x0000, /* Luxman D-10X */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), DEVICE_FLG(0x339b, 0x3a07, /* Synaptics HONOR USB-C HEADSET */ QUIRK_FLAG_MIXER_MIN_MUTE), DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ @@ -2320,6 +2328,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x2622, /* IAG Limited devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2772, /* Musical Fidelity devices */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x278b, /* Rotel? */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x292b, /* Gustard/Ess based devices */ -- Gitee From 4abbfeea05a3e5297bb0a289f5093f2444c58574 Mon Sep 17 00:00:00 2001 From: Andrew Elantsev Date: Thu, 11 Dec 2025 04:38:00 +0800 Subject: [PATCH 0982/1449] ASoC: amd: yc: Add quirk for Honor MagicBook X16 2025 ANBZ: #35228 commit 2c4404d6e4edb9c84e309eab8962a07f80957466 stable. commit e2cb8ef0372665854fca6fa7b30b20dd35acffeb upstream. Add a DMI quirk for the Honor MagicBook X16 2025 laptop fixing the issue where the internal microphone was not detected. Signed-off-by: Andrew Elantsev Link: https://patch.msgid.link/20251210203800.142822-1-elantsew.andrew@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 24919e68b346..54dac6bfc9d1 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -654,6 +654,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7UCX"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HONOR"), + DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"), + } + }, {} }; -- Gitee From b0a7c479b92dba39bf792d0b55d6229bdd4c32ff Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 16 Dec 2025 18:22:45 +0800 Subject: [PATCH 0983/1449] ASoC: fsl_sai: Add missing registers to cache default ANBZ: #35228 commit 06f90c7dce191af5836d6464efedf01adc988930 stable. commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb upstream. Drivers does cache sync during runtime resume, setting all writable registers. Not all writable registers are set in cache default, resulting in the erorr message: fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause unexpected behavior Fix this by adding missing writable register defaults. Signed-off-by: Alexander Stein Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/fsl/fsl_sai.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 0de878d64a3b..95a502ec3a05 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -979,6 +979,7 @@ static struct reg_default fsl_sai_reg_defaults_ofs0[] = { {FSL_SAI_TDR6, 0}, {FSL_SAI_TDR7, 0}, {FSL_SAI_TMR, 0}, + {FSL_SAI_TTCTL, 0}, {FSL_SAI_RCR1(0), 0}, {FSL_SAI_RCR2(0), 0}, {FSL_SAI_RCR3(0), 0}, @@ -1002,12 +1003,14 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = { {FSL_SAI_TDR6, 0}, {FSL_SAI_TDR7, 0}, {FSL_SAI_TMR, 0}, + {FSL_SAI_TTCTL, 0}, {FSL_SAI_RCR1(8), 0}, {FSL_SAI_RCR2(8), 0}, {FSL_SAI_RCR3(8), 0}, {FSL_SAI_RCR4(8), 0}, {FSL_SAI_RCR5(8), 0}, {FSL_SAI_RMR, 0}, + {FSL_SAI_RTCTL, 0}, {FSL_SAI_MCTL, 0}, {FSL_SAI_MDIV, 0}, }; -- Gitee From 2618f463e7fe685297b199b4e6d74c88a2fa28b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20R=C3=A1bek?= Date: Sat, 13 Dec 2025 00:08:23 +0800 Subject: [PATCH 0984/1449] scsi: sg: Fix occasional bogus elapsed time that exceeds timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 83eef6f904a84bc960a013d536dd2ba7905f7036 stable. commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 upstream. A race condition was found in sg_proc_debug_helper(). It was observed on a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring /proc/scsi/sg/debug every second. A very large elapsed time would sometimes appear. This is caused by two race conditions. We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 architecture. A patched kernel was built, and the race condition could not be observed anymore after the application of this patch. A reproducer C program utilising the scsi_debug module was also built by Changhui Zhong and can be viewed here: https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c The first race happens between the reading of hp->duration in sg_proc_debug_helper() and request completion in sg_rq_end_io(). The hp->duration member variable may hold either of two types of information: #1 - The start time of the request. This value is present while the request is not yet finished. #2 - The total execution time of the request (end_time - start_time). If sg_proc_debug_helper() executes *after* the value of hp->duration was changed from #1 to #2, but *before* srp->done is set to 1 in sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the elapsed time (value type #2) is subtracted from a timestamp, which cannot yield a valid elapsed time (which is a type #2 value as well). To fix this issue, the value of hp->duration must change under the protection of the sfp->rq_list_lock in sg_rq_end_io(). Since sg_proc_debug_helper() takes this read lock, the change to srp->done and srp->header.duration will happen atomically from the perspective of sg_proc_debug_helper() and the race condition is thus eliminated. The second race condition happens between sg_proc_debug_helper() and sg_new_write(). Even though hp->duration is set to the current time stamp in sg_add_request() under the write lock's protection, it gets overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() to copy struct sg_io_hdr from userspace into kernel space. hp->duration is set to the start time again in sg_common_write(). If sg_proc_debug_helper() is called between these two calls, an arbitrary value set by userspace (usually zero) is used to compute the elapsed time. To fix this issue, hp->duration must be set to the current timestamp again after get_sg_io_hdr() returns successfully. A small race window still exists between get_sg_io_hdr() and setting hp->duration, but this window is only a few instructions wide and does not result in observable issues in practice, as confirmed by testing. Additionally, we fix the format specifier from %d to %u for printing unsigned int values in sg_proc_debug_helper(). Signed-off-by: Michal Rábek Suggested-by: Tomas Henzl Tested-by: Changhui Zhong Reviewed-by: Ewan D. Milne Reviewed-by: John Meneghini Reviewed-by: Tomas Henzl Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/sg.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 9258a1a8c23c..0dd8b9f8d671 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -731,6 +731,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, sg_remove_request(sfp, srp); return -EFAULT; } + hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != 'S') { sg_remove_request(sfp, srp); return -ENOSYS; @@ -815,7 +817,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, return -ENODEV; } - hp->duration = jiffies_to_msecs(jiffies); if (hp->interface_id != '\0' && /* v3 (or later) interface */ (SG_FLAG_Q_AT_TAIL & hp->flags)) at_head = 0; @@ -1339,9 +1340,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) "sg_cmd_done: pack_id=%d, res=0x%x\n", srp->header.pack_id, result)); srp->header.resid = resid; - ms = jiffies_to_msecs(jiffies); - srp->header.duration = (ms > srp->header.duration) ? - (ms - srp->header.duration) : 0; if (0 != result) { struct scsi_sense_hdr sshdr; @@ -1390,6 +1388,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) done = 0; } srp->done = done; + ms = jiffies_to_msecs(jiffies); + srp->header.duration = (ms > srp->header.duration) ? + (ms - srp->header.duration) : 0; write_unlock_irqrestore(&sfp->rq_list_lock, iflags); if (likely(done)) { @@ -2537,6 +2538,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) const sg_io_hdr_t *hp; const char * cp; unsigned int ms; + unsigned int duration; k = 0; list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { @@ -2574,13 +2576,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) seq_printf(s, " id=%d blen=%d", srp->header.pack_id, blen); if (srp->done) - seq_printf(s, " dur=%d", hp->duration); + seq_printf(s, " dur=%u", hp->duration); else { ms = jiffies_to_msecs(jiffies); - seq_printf(s, " t_o/elap=%d/%d", + duration = READ_ONCE(hp->duration); + if (duration) + duration = (ms > duration ? + ms - duration : 0); + seq_printf(s, " t_o/elap=%u/%u", (new_interface ? hp->timeout : jiffies_to_msecs(fp->timeout)), - (ms > hp->duration ? ms - hp->duration : 0)); + duration); } seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, (int) srp->data.cmd_opcode); -- Gitee From d36529e5417a76877e38856b0f396078874dd0e5 Mon Sep 17 00:00:00 2001 From: Shardul Bankar Date: Tue, 14 Oct 2025 20:00:37 +0800 Subject: [PATCH 0985/1449] bpf: test_run: Fix ctx leak in bpf_prog_test_run_xdp error path ANBZ: #35228 commit 5192f17d1127a6a62022ef8363099b6d20967d2a stable. commit 7f9ee5fc97e14682e36fe22ae2654c07e4998b82 upstream. Fix a memory leak in bpf_prog_test_run_xdp() where the context buffer allocated by bpf_ctx_init() is not freed when the function returns early due to a data size check. On the failing path: ctx = bpf_ctx_init(...); if (kattr->test.data_size_in - meta_sz < ETH_HLEN) return -EINVAL; The early return bypasses the cleanup label that kfree()s ctx, leading to a leak detectable by kmemleak under fuzzing. Change the return to jump to the existing free_ctx label. Fixes: fe9544ed1a2e ("bpf: Support specifying linear xdp packet data size for BPF_PROG_TEST_RUN") Reported-by: BPF Runtime Fuzzer (BRF) Signed-off-by: Shardul Bankar Signed-off-by: Martin KaFai Lau Acked-by: Jiri Olsa Acked-by: Daniel Borkmann Link: https://patch.msgid.link/20251014120037.1981316-1-shardulsb08@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 8316f56b54f5..53db2f64e567 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -1224,7 +1224,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, goto free_ctx; if (kattr->test.data_size_in - meta_sz < ETH_HLEN) - return -EINVAL; + goto free_ctx; data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); if (IS_ERR(data)) { -- Gitee From cbb442b05ff592aba129e7aac571e9d7ffcee5c5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 16 Jun 2025 21:45:03 +0800 Subject: [PATCH 0986/1449] gpio: pca953x: fix wrong error probe return value ANBZ: #35228 commit d03ee4185486672deff845afc52bb8af4b70a04f stable. commit 0a1db19f66c0960eb00e1f2ccd40708b6747f5b1 upstream. The second argument to dev_err_probe() is the error value. Pass the return value of devm_request_threaded_irq() there instead of the irq number. Signed-off-by: Sascha Hauer Fixes: c47f7ff0fe61 ("gpio: pca953x: Utilise dev_err_probe() where it makes sense") Link: https://lore.kernel.org/r/20250616134503.1201138-1-s.hauer@pengutronix.de Signed-off-by: Bartosz Golaszewski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-pca953x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 120d6695a4b5..633493b860f2 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -989,7 +989,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base) IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), chip); if (ret) - return dev_err_probe(dev, client->irq, "failed to request irq\n"); + return dev_err_probe(dev, ret, "failed to request irq\n"); return 0; } -- Gitee From d975b97022f834bf4157ae6d1ed7696d2d616431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Date: Sat, 19 Apr 2025 13:13:59 +0200 Subject: [PATCH 0987/1449] riscv: Replace function-like macro by static inline function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 0b1ac9743f3d9cfced2ac3cb9f274c0675bd4189 stable. commit 121f34341d396b666d8a90b24768b40e08ca0d61 upstream. The flush_icache_range() function is implemented as a "function-like macro with unused parameters", which can result in "unused variables" warnings. Replace the macro with a static inline function, as advised by Documentation/process/coding-style.rst. Fixes: 08f051eda33b ("RISC-V: Flush I$ when making a dirty page executable") Signed-off-by: Björn Töpel Link: https://lore.kernel.org/r/20250419111402.1660267-1-bjorn@kernel.org Signed-off-by: Palmer Dabbelt Signed-off-by: Ron Economos Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/riscv/include/asm/cacheflush.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h index 0a8dd761df3a..e2e150605b44 100644 --- a/arch/riscv/include/asm/cacheflush.h +++ b/arch/riscv/include/asm/cacheflush.h @@ -34,11 +34,6 @@ static inline void flush_dcache_page(struct page *page) flush_dcache_folio(page_folio(page)); } -/* - * RISC-V doesn't have an instruction to flush parts of the instruction cache, - * so instead we just flush the whole thing. - */ -#define flush_icache_range(start, end) flush_icache_all() #define flush_icache_user_page(vma, pg, addr, len) \ flush_icache_mm(vma->vm_mm, 0) @@ -75,6 +70,16 @@ void flush_icache_mm(struct mm_struct *mm, bool local); #endif /* CONFIG_SMP */ +/* + * RISC-V doesn't have an instruction to flush parts of the instruction cache, + * so instead we just flush the whole thing. + */ +#define flush_icache_range flush_icache_range +static inline void flush_icache_range(unsigned long start, unsigned long end) +{ + flush_icache_all(); +} + extern unsigned int riscv_cbom_block_size; extern unsigned int riscv_cboz_block_size; extern unsigned int riscv_cbop_block_size; -- Gitee From 29f0284b77cb6cd298de34c96f81041e549b0e45 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:27 +0800 Subject: [PATCH 0988/1449] firmware: imx: scu-irq: Set mu_resource_id before get handle ANBZ: #35228 commit 73069e11340296ca01f90a7f5f15f143b1c7729b stable. commit ff3f9913bc0749364fbfd86ea62ba2d31c6136c8 upstream. mu_resource_id is referenced in imx_scu_irq_get_status() and imx_scu_irq_group_enable() which could be used by other modules, so need to set correct value before using imx_sc_irq_ipc_handle in SCU API call. Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo Fixes: 81fb53feb66a ("firmware: imx: scu-irq: Init workqueue before request mbox channel") Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/imx/imx-scu-irq.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index b9f6128d56f7..f587abcd7ca3 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -203,6 +203,18 @@ int imx_scu_enable_general_irq_channel(struct device *dev) struct mbox_chan *ch; int ret = 0, i = 0; + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", + "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); + of_node_put(spec.np); + } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) + i = 1; + + mu_resource_id = IMX_SC_R_MU_0A + i; + ret = imx_scu_get_handle(&imx_sc_irq_ipc_handle); if (ret) return ret; @@ -225,18 +237,6 @@ int imx_scu_enable_general_irq_channel(struct device *dev) return ret; } - if (!of_parse_phandle_with_args(dev->of_node, "mboxes", - "#mbox-cells", 0, &spec)) { - i = of_alias_get_id(spec.np, "mu"); - of_node_put(spec.np); - } - - /* use mu1 as general mu irq channel if failed */ - if (i < 0) - i = 1; - - mu_resource_id = IMX_SC_R_MU_0A + i; - /* Create directory under /sysfs/firmware */ wakeup_obj = kobject_create_and_add("scu_wakeup_source", firmware_kobj); if (!wakeup_obj) { -- Gitee From ca0eea933c8e637f067c2cd052cff627a57010b8 Mon Sep 17 00:00:00 2001 From: Morduan Zang Date: Wed, 14 Jan 2026 13:30:33 +0800 Subject: [PATCH 0989/1449] efi/cper: Fix cper_bits_to_str buffer handling and return value ANBZ: #35228 commit 30f9b41b039030d639e1dd37ea41f70c80703c5f stable. commit d7f1b4bdc7108be1b178e1617b5f45c8918e88d7 upstream. The return value calculation was incorrect: `return len - buf_size;` Initially `len = buf_size`, then `len` decreases with each operation. This results in a negative return value on success. Fix by returning `buf_size - len` which correctly calculates the actual number of bytes written. Fixes: a976d790f494 ("efi/cper: Add a new helper function to print bitmasks") Signed-off-by: Morduan Zang Signed-off-by: Ard Biesheuvel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/firmware/efi/cper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index e23396473c46..5540aa391e89 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -162,7 +162,7 @@ int cper_bits_to_str(char *buf, int buf_size, unsigned long bits, len -= size; str += size; } - return len - buf_size; + return buf_size - len; } EXPORT_SYMBOL_GPL(cper_bits_to_str); -- Gitee From 75bef0260b8310d094199cfed22f8d2afdcdd03b Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Mon, 12 Jan 2026 18:47:35 +0800 Subject: [PATCH 0990/1449] Revert "gfs2: Fix use of bio_chain" ANBZ: #35228 commit ca72af7608d68fbc9d9e49bdefb2d05189fad319 stable. commit 469d71512d135907bf5ea0972dfab8c420f57848 upstream. This reverts commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941. That commit incorrectly assumed that the bio_chain() arguments were swapped in gfs2. However, gfs2 intentionally constructs bio chains so that the first bio's bi_end_io callback is invoked when all bios in the chain have completed, unlike bio chains where the last bio's callback is invoked. Fixes: 8a157e0a0aa5 ("gfs2: Fix use of bio_chain") Cc: stable@vger.kernel.org Signed-off-by: Andreas Gruenbacher Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/gfs2/lops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index b25b741e3c96..483f69807062 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -492,7 +492,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); bio_clone_blkg_association(new, prev); new->bi_iter.bi_sector = bio_end_sector(prev); - bio_chain(prev, new); + bio_chain(new, prev); submit_bio(prev); return new; } -- Gitee From 90d9fcdabffd7bd2c1f4e73d5fe0eb95245e5974 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 2 Jan 2026 19:14:12 +0800 Subject: [PATCH 0991/1449] ASoC: codecs: wsa884x: fix codec initialisation ANBZ: #35228 commit 6eb597cb4e37f1e7ef3557168a0029685dd8900d stable. commit 120f3e6ff76209ee2f62a64e5e7e9d70274df42b upstream. The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED. Fix the inverted hw_init flag which was set to false instead of true after initialisation which defeats its purpose and may result in repeated unnecessary initialisation. Similarly, the initial state of the flag was also inverted so that the codec would only be initialised and brought out of regmap cache only mode if its status first transitions to UNATTACHED. Fixes: aa21a7d4f68a ("ASoC: codecs: wsa884x: Add WSA884x family of speakers") Cc: stable@vger.kernel.org # 6.5 Cc: Krzysztof Kozlowski Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Tested-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-4-johan@kernel.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/wsa884x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index 1cd52fab7b40..7228a1418f2a 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -1482,7 +1482,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x) wsa884x_set_gain_parameters(wsa884x); - wsa884x->hw_init = false; + wsa884x->hw_init = true; } static int wsa884x_update_status(struct sdw_slave *slave, @@ -1884,7 +1884,6 @@ static int wsa884x_probe(struct sdw_slave *pdev, /* Start in cache-only until device is enumerated */ regcache_cache_only(wsa884x->regmap, true); - wsa884x->hw_init = true; pm_runtime_set_autosuspend_delay(dev, 3000); pm_runtime_use_autosuspend(dev); -- Gitee From cbe42fc5ebf21f189ff2e19fd8fbe2b685e3a2ea Mon Sep 17 00:00:00 2001 From: Jianbo Liu Date: Thu, 20 Nov 2025 11:56:09 +0800 Subject: [PATCH 0992/1449] xfrm: Fix inner mode lookup in tunnel mode GSO segmentation ANBZ: #35228 commit 55787a73fbb61cd385264fe4500c9fca352fa899 stable. commit 3d5221af9c7711b7aec8da1298c8fc393ef6183d upstream. Commit 61fafbee6cfe ("xfrm: Determine inner GSO type from packet inner protocol") attempted to fix GSO segmentation by reading the inner protocol from XFRM_MODE_SKB_CB(skb)->protocol. This was incorrect because the field holds the inner L4 protocol (TCP/UDP) instead of the required tunnel protocol. Also, the memory location (shared by XFRM_SKB_CB(skb) which could be overwritten by xfrm_replay_overflow()) is prone to corruption. This combination caused the kernel to select the wrong inner mode and get the wrong address family. The correct value is in xfrm_offload(skb)->proto, which is set from the outer tunnel header's protocol field by esp[4|6]_gso_encap(). It is initialized by xfrm[4|6]_tunnel_encap_add() to either IPPROTO_IPIP or IPPROTO_IPV6, using xfrm_af2proto() and correctly reflects the inner packet's address family. Fixes: 61fafbee6cfe ("xfrm: Determine inner GSO type from packet inner protocol") Signed-off-by: Jianbo Liu Reviewed-by: Sabrina Dubroca Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv4/esp4_offload.c | 4 ++-- net/ipv6/esp6_offload.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index 11e33a431267..028d2d3477d1 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -111,8 +111,8 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { - const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, - XFRM_MODE_SKB_CB(skb)->protocol); + struct xfrm_offload *xo = xfrm_offload(skb); + const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, xo->proto); __be16 type = inner_mode->family == AF_INET6 ? htons(ETH_P_IPV6) : htons(ETH_P_IP); diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index 438f9cbdca29..333d87557bf3 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -145,8 +145,8 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x, struct sk_buff *skb, netdev_features_t features) { - const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, - XFRM_MODE_SKB_CB(skb)->protocol); + struct xfrm_offload *xo = xfrm_offload(skb); + const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, xo->proto); __be16 type = inner_mode->family == AF_INET ? htons(ETH_P_IP) : htons(ETH_P_IPV6); -- Gitee From 1d3648086f638b81d5120cd4c7e26867c25cfd04 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Thu, 25 Dec 2025 15:41:03 +0800 Subject: [PATCH 0993/1449] pnfs/flexfiles: Fix memory leak in nfs4_ff_alloc_deviceid_node() ANBZ: #35228 commit 869862056e100973e76ce9f5f1b01837771b7722 stable. commit 0c728083654f0066f5e10a1d2b0bd0907af19a58 upstream. In nfs4_ff_alloc_deviceid_node(), if the allocation for ds_versions fails, the function jumps to the out_scratch label without freeing the already allocated dsaddrs list, leading to a memory leak. Fix this by jumping to the out_err_drain_dsaddrs label, which properly frees the dsaddrs list before cleaning up other resources. Fixes: d67ae825a59d6 ("pnfs/flexfiles: Add the FlexFile Layout Driver") Signed-off-by: Zilin Guan Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index 95d5dca67145..ed18e9e87c25 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -103,7 +103,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, sizeof(struct nfs4_ff_ds_version), gfp_flags); if (!ds_versions) - goto out_scratch; + goto out_err_drain_dsaddrs; for (i = 0; i < version_count; i++) { /* 20 = version(4) + minor_version(4) + rsize(4) + wsize(4) + -- Gitee From e89de2bf66d7d55b1d44fdf60f88e29aa17dc646 Mon Sep 17 00:00:00 2001 From: Szymon Wilczek Date: Tue, 23 Dec 2025 09:17:32 +0800 Subject: [PATCH 0994/1449] can: etas_es58x: allow partial RX URB allocation to succeed ANBZ: #35228 commit 611e839d2d552416b498ed5593e10670f61fcd4d stable. commit b1979778e98569c1e78c2c7f16bb24d76541ab00 upstream. When es58x_alloc_rx_urbs() fails to allocate the requested number of URBs but succeeds in allocating some, it returns an error code. This causes es58x_open() to return early, skipping the cleanup label 'free_urbs', which leads to the anchored URBs being leaked. As pointed out by maintainer Vincent Mailhol, the driver is designed to handle partial URB allocation gracefully. Therefore, partial allocation should not be treated as a fatal error. Modify es58x_alloc_rx_urbs() to return 0 if at least one URB has been allocated, restoring the intended behavior and preventing the leak in es58x_open(). Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") Reported-by: syzbot+e8cb6691a7cf68256cb8@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=e8cb6691a7cf68256cb8 Signed-off-by: Szymon Wilczek Reviewed-by: Vincent Mailhol Link: https://patch.msgid.link/20251223011732.39361-1-swilczek.lx@gmail.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/etas_es58x/es58x_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index bb49a2c0a9a5..77f193861bcc 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -1736,7 +1736,7 @@ static int es58x_alloc_rx_urbs(struct es58x_device *es58x_dev) dev_dbg(dev, "%s: Allocated %d rx URBs each of size %u\n", __func__, i, rx_buf_len); - return ret; + return 0; } /** -- Gitee From b6526167f587b38715356cf1ab49b9a959d66169 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Fri, 22 Dec 2023 23:17:50 +0800 Subject: [PATCH 0995/1449] nvmet-tcp: remove boilerplate code ANBZ: #35228 commit 50f80e82e79669dd5222fcd191ab872cad485f2b stable. commit 75011bd0f9c55db523242f9f9a0b0b826165f14b upstream. Simplify the nvmet_tcp_handle_h2c_data_pdu() function by removing boilerplate code. Signed-off-by: Maurizio Lombardi Reviewed-by: Sagi Grimberg Signed-off-by: Keith Busch Stable-dep-of: 32b63acd78f5 ("nvme-tcp: fix NULL pointer dereferences in nvmet_tcp_build_pdu_iovec") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/target/tcp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 386d74ab578f..2e8733e1464d 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -987,8 +987,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) if (unlikely(data->ttag >= queue->nr_cmds)) { pr_err("queue %d: received out of bound ttag %u, nr_cmds %u\n", queue->idx, data->ttag, queue->nr_cmds); - nvmet_tcp_fatal_error(queue); - return -EPROTO; + goto err_proto; } cmd = &queue->cmds[data->ttag]; } else { @@ -999,9 +998,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) pr_err("ttag %u unexpected data offset %u (expected %u)\n", data->ttag, le32_to_cpu(data->data_offset), cmd->rbytes_done); - /* FIXME: use path and transport errors */ - nvmet_tcp_fatal_error(queue); - return -EPROTO; + goto err_proto; } exp_data_len = le32_to_cpu(data->hdr.plen) - @@ -1014,9 +1011,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) cmd->pdu_len == 0 || cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) { pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); - /* FIXME: use proper transport errors */ - nvmet_tcp_fatal_error(queue); - return -EPROTO; + goto err_proto; } cmd->pdu_recv = 0; nvmet_tcp_build_pdu_iovec(cmd); @@ -1024,6 +1019,11 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) queue->rcv_state = NVMET_TCP_RECV_DATA; return 0; + +err_proto: + /* FIXME: use proper transport errors */ + nvmet_tcp_fatal_error(queue); + return -EPROTO; } static int nvmet_tcp_done_recv_pdu(struct nvmet_tcp_queue *queue) -- Gitee From 70e84fb6d8fda67fa365079c7713679fcbcb920c Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Sun, 14 Dec 2025 02:57:48 +0800 Subject: [PATCH 0996/1449] nvme-tcp: fix NULL pointer dereferences in nvmet_tcp_build_pdu_iovec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit fdecd3b6aac10d5a18d0dc500fe57f8648b66cd4 stable. commit 32b63acd78f577b332d976aa06b56e70d054cbba upstream. Commit efa56305908b ("nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length") added ttag bounds checking and data_offset validation in nvmet_tcp_handle_h2c_data_pdu(), but it did not validate whether the command's data structures (cmd->req.sg and cmd->iov) have been properly initialized before processing H2C_DATA PDUs. The nvmet_tcp_build_pdu_iovec() function dereferences these pointers without NULL checks. This can be triggered by sending H2C_DATA PDU immediately after the ICREQ/ICRESP handshake, before sending a CONNECT command or NVMe write command. Attack vectors that trigger NULL pointer dereferences: 1. H2C_DATA PDU sent before CONNECT → both pointers NULL 2. H2C_DATA PDU for READ command → cmd->req.sg allocated, cmd->iov NULL 3. H2C_DATA PDU for uninitialized command slot → both pointers NULL The fix validates both cmd->req.sg and cmd->iov before calling nvmet_tcp_build_pdu_iovec(). Both checks are required because: - Uninitialized commands: both NULL - READ commands: cmd->req.sg allocated, cmd->iov NULL - WRITE commands: both allocated Fixes: efa56305908b ("nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length") Reviewed-by: Sagi Grimberg Signed-off-by: Shivam Kumar Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/target/tcp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 2e8733e1464d..519bfba3c055 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1013,6 +1013,18 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); goto err_proto; } + /* + * Ensure command data structures are initialized. We must check both + * cmd->req.sg and cmd->iov because they can have different NULL states: + * - Uninitialized commands: both NULL + * - READ commands: cmd->req.sg allocated, cmd->iov NULL + * - WRITE commands: both allocated + */ + if (unlikely(!cmd->req.sg || !cmd->iov)) { + pr_err("queue %d: H2CData PDU received for invalid command state (ttag %u)\n", + queue->idx, data->ttag); + goto err_proto; + } cmd->pdu_recv = 0; nvmet_tcp_build_pdu_iovec(cmd); queue->cmd = cmd; -- Gitee From 7cd6cbf4b20c7a59ee3c686e32b0a61d6b99e803 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 6 Jan 2026 17:56:40 +0800 Subject: [PATCH 0997/1449] btrfs: send: check for inline extents in range_is_hole_in_parent() ANBZ: #35228 commit f2dc6ab3a14c2d2eb0b14783427eb9b03bf631c9 stable. commit 08b096c1372cd69627f4f559fb47c9fb67a52b39 upstream. Before accessing the disk_bytenr field of a file extent item we need to check if we are dealing with an inline extent. This is because for inline extents their data starts at the offset of the disk_bytenr field. So accessing the disk_bytenr means we are accessing inline data or in case the inline data is less than 8 bytes we can actually cause an invalid memory access if this inline extent item is the first item in the leaf or access metadata from other items. Fixes: 82bfb2e7b645 ("Btrfs: incremental send, fix unnecessary hole writes for sparse files") Reviewed-by: Filipe Manana Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/send.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index c25eb4416a67..6768e2231d61 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -6545,6 +6545,8 @@ static int range_is_hole_in_parent(struct send_ctx *sctx, extent_end = btrfs_file_extent_end(path); if (extent_end <= start) goto next; + if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) + return 0; if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) { search_start = extent_end; goto next; -- Gitee From e92ab2d0179ea46cb8e69c0780a77c262a772e14 Mon Sep 17 00:00:00 2001 From: Johannes Nixdorf Date: Mon, 16 Oct 2023 21:27:20 +0800 Subject: [PATCH 0998/1449] net: bridge: Set BR_FDB_ADDED_BY_USER early in fdb_add_entry ANBZ: #35228 commit 9f1ac4c98add75e286dfaf6b87a1687868aa90c9 stable. commit cbf51acbc5d50341290c79c97bda8cf46f5c4f22 upstream. In preparation of the following fdb limit for dynamically learned entries, allow fdb_create to detect that the entry was added by the user. This way it can skip applying the limit in this case. Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: Johannes Nixdorf Link: https://lore.kernel.org/r/20231016-fdb_limit-v5-1-32cddff87758@avm.de Signed-off-by: Jakub Kicinski Stable-dep-of: b25a0b4a2193 ("net: bridge: annotate data-races around fdb->{updated,used}") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bridge/br_fdb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index a6d8cd9a5807..91903076d30b 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -1056,7 +1056,8 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, if (!(flags & NLM_F_CREATE)) return -ENOENT; - fdb = fdb_create(br, source, addr, vid, 0); + fdb = fdb_create(br, source, addr, vid, + BIT(BR_FDB_ADDED_BY_USER)); if (!fdb) return -ENOMEM; @@ -1069,6 +1070,8 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, WRITE_ONCE(fdb->dst, source); modified = true; } + + set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); } if (fdb_to_nud(br, fdb) != state) { @@ -1100,8 +1103,6 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, if (fdb_handle_notify(fdb, notify)) modified = true; - set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); - fdb->used = jiffies; if (modified) { if (refresh) -- Gitee From d4b148c8ed18087c4963fea89f4b73939bcf1f19 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 8 Jan 2026 17:38:06 +0800 Subject: [PATCH 0999/1449] net: bridge: annotate data-races around fdb->{updated,used} ANBZ: #35228 commit 98151bb13af1e5f37d3ff1c20fb24e8915260ea3 stable. commit b25a0b4a2193407aa72a4cd1df66a7ed07dd4f1e upstream. fdb->updated and fdb->used are read and written locklessly. Add READ_ONCE()/WRITE_ONCE() annotations. Fixes: 31cbc39b6344 ("net: bridge: add option to allow activity notifications for any fdb entries") Reported-by: syzbot+bfab43087ad57222ce96@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/695e3d74.050a0220.1c677c.035f.GAE@google.com/ Signed-off-by: Eric Dumazet Acked-by: Nikolay Aleksandrov Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20260108093806.834459-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bridge/br_fdb.c | 28 ++++++++++++++++------------ net/bridge/br_input.c | 4 ++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 91903076d30b..fa2970db2130 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -73,7 +73,7 @@ static inline int has_expired(const struct net_bridge *br, { return !test_bit(BR_FDB_STATIC, &fdb->flags) && !test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) && - time_before_eq(fdb->updated + hold_time(br), jiffies); + time_before_eq(READ_ONCE(fdb->updated) + hold_time(br), jiffies); } static void fdb_rcu_free(struct rcu_head *head) @@ -136,9 +136,9 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, if (nla_put_u32(skb, NDA_FLAGS_EXT, ext_flags)) goto nla_put_failure; - ci.ndm_used = jiffies_to_clock_t(now - fdb->used); + ci.ndm_used = jiffies_to_clock_t(now - READ_ONCE(fdb->used)); ci.ndm_confirmed = 0; - ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); + ci.ndm_updated = jiffies_to_clock_t(now - READ_ONCE(fdb->updated)); ci.ndm_refcnt = 0; if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) goto nla_put_failure; @@ -534,7 +534,7 @@ void br_fdb_cleanup(struct work_struct *work) */ rcu_read_lock(); hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { - unsigned long this_timer = f->updated + delay; + unsigned long this_timer = READ_ONCE(f->updated) + delay; if (test_bit(BR_FDB_STATIC, &f->flags) || test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags)) { @@ -792,6 +792,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, { struct net_bridge_fdb_entry *f; struct __fdb_entry *fe = buf; + unsigned long delta; int num = 0; memset(buf, 0, maxnum*sizeof(struct __fdb_entry)); @@ -821,8 +822,11 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf, fe->port_hi = f->dst->port_no >> 8; fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags); - if (!test_bit(BR_FDB_STATIC, &f->flags)) - fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated); + if (!test_bit(BR_FDB_STATIC, &f->flags)) { + delta = jiffies - READ_ONCE(f->updated); + fe->ageing_timer_value = + jiffies_delta_to_clock_t(delta); + } ++fe; ++num; } @@ -870,8 +874,8 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, unsigned long now = jiffies; bool fdb_modified = false; - if (now != fdb->updated) { - fdb->updated = now; + if (now != READ_ONCE(fdb->updated)) { + WRITE_ONCE(fdb->updated, now); fdb_modified = __fdb_mark_active(fdb); } @@ -1103,10 +1107,10 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source, if (fdb_handle_notify(fdb, notify)) modified = true; - fdb->used = jiffies; + WRITE_ONCE(fdb->used, jiffies); if (modified) { if (refresh) - fdb->updated = jiffies; + WRITE_ONCE(fdb->updated, jiffies); fdb_notify(br, fdb, RTM_NEWNEIGH, true); } @@ -1419,7 +1423,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, goto err_unlock; } - fdb->updated = jiffies; + WRITE_ONCE(fdb->updated, jiffies); if (READ_ONCE(fdb->dst) != p) { WRITE_ONCE(fdb->dst, p); @@ -1428,7 +1432,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, if (test_and_set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) { /* Refresh entry */ - fdb->used = jiffies; + WRITE_ONCE(fdb->used, jiffies); } else { modified = true; } diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 951330c1a813..2d5b81ebbaa6 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -207,8 +207,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb if (test_bit(BR_FDB_LOCAL, &dst->flags)) return br_pass_frame_up(skb, false); - if (now != dst->used) - dst->used = now; + if (now != READ_ONCE(dst->used)) + WRITE_ONCE(dst->used, now); br_forward(dst->dst, skb, local_rcv, false); } else { if (!mcast_hit) -- Gitee From 0f39afa1ac1714de135dcbe0b7e458573c78fe2c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 8 Jan 2026 00:31:09 +0800 Subject: [PATCH 1000/1449] ip6_tunnel: use skb_vlan_inet_prepare() in __ip6_tnl_rcv() ANBZ: #35228 commit 2f03dafea0a8096a2eb60f551218b360e5bab9a3 stable. commit 81c734dae203757fb3c9eee6f9896386940776bd upstream. Blamed commit did not take care of VLAN encapsulations as spotted by syzbot [1]. Use skb_vlan_inet_prepare() instead of pskb_inet_may_pull(). [1] BUG: KMSAN: uninit-value in __INET_ECN_decapsulate include/net/inet_ecn.h:253 [inline] BUG: KMSAN: uninit-value in INET_ECN_decapsulate include/net/inet_ecn.h:275 [inline] BUG: KMSAN: uninit-value in IP6_ECN_decapsulate+0x7a8/0x1fa0 include/net/inet_ecn.h:321 __INET_ECN_decapsulate include/net/inet_ecn.h:253 [inline] INET_ECN_decapsulate include/net/inet_ecn.h:275 [inline] IP6_ECN_decapsulate+0x7a8/0x1fa0 include/net/inet_ecn.h:321 ip6ip6_dscp_ecn_decapsulate+0x16f/0x1b0 net/ipv6/ip6_tunnel.c:729 __ip6_tnl_rcv+0xed9/0x1b50 net/ipv6/ip6_tunnel.c:860 ip6_tnl_rcv+0xc3/0x100 net/ipv6/ip6_tunnel.c:903 gre_rcv+0x1529/0x1b90 net/ipv6/ip6_gre.c:-1 ip6_protocol_deliver_rcu+0x1c89/0x2c60 net/ipv6/ip6_input.c:438 ip6_input_finish+0x1f4/0x4a0 net/ipv6/ip6_input.c:489 NF_HOOK include/linux/netfilter.h:318 [inline] ip6_input+0x9c/0x330 net/ipv6/ip6_input.c:500 ip6_mc_input+0x7ca/0xc10 net/ipv6/ip6_input.c:590 dst_input include/net/dst.h:474 [inline] ip6_rcv_finish+0x958/0x990 net/ipv6/ip6_input.c:79 NF_HOOK include/linux/netfilter.h:318 [inline] ipv6_rcv+0xf1/0x3c0 net/ipv6/ip6_input.c:311 __netif_receive_skb_one_core net/core/dev.c:6139 [inline] __netif_receive_skb+0x1df/0xac0 net/core/dev.c:6252 netif_receive_skb_internal net/core/dev.c:6338 [inline] netif_receive_skb+0x57/0x630 net/core/dev.c:6397 tun_rx_batched+0x1df/0x980 drivers/net/tun.c:1485 tun_get_user+0x5c0e/0x6c60 drivers/net/tun.c:1953 tun_chr_write_iter+0x3e9/0x5c0 drivers/net/tun.c:1999 new_sync_write fs/read_write.c:593 [inline] vfs_write+0xbe2/0x15d0 fs/read_write.c:686 ksys_write fs/read_write.c:738 [inline] __do_sys_write fs/read_write.c:749 [inline] __se_sys_write fs/read_write.c:746 [inline] __x64_sys_write+0x1fb/0x4d0 fs/read_write.c:746 x64_sys_call+0x30ab/0x3e70 arch/x86/include/generated/asm/syscalls_64.h:2 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd3/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Uninit was created at: slab_post_alloc_hook mm/slub.c:4960 [inline] slab_alloc_node mm/slub.c:5263 [inline] kmem_cache_alloc_node_noprof+0x9e7/0x17a0 mm/slub.c:5315 kmalloc_reserve+0x13c/0x4b0 net/core/skbuff.c:586 __alloc_skb+0x805/0x1040 net/core/skbuff.c:690 alloc_skb include/linux/skbuff.h:1383 [inline] alloc_skb_with_frags+0xc5/0xa60 net/core/skbuff.c:6712 sock_alloc_send_pskb+0xacc/0xc60 net/core/sock.c:2995 tun_alloc_skb drivers/net/tun.c:1461 [inline] tun_get_user+0x1142/0x6c60 drivers/net/tun.c:1794 tun_chr_write_iter+0x3e9/0x5c0 drivers/net/tun.c:1999 new_sync_write fs/read_write.c:593 [inline] vfs_write+0xbe2/0x15d0 fs/read_write.c:686 ksys_write fs/read_write.c:738 [inline] __do_sys_write fs/read_write.c:749 [inline] __se_sys_write fs/read_write.c:746 [inline] __x64_sys_write+0x1fb/0x4d0 fs/read_write.c:746 x64_sys_call+0x30ab/0x3e70 arch/x86/include/generated/asm/syscalls_64.h:2 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd3/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f CPU: 0 UID: 0 PID: 6465 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(none) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 Fixes: 8d975c15c0cd ("ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv()") Reported-by: syzbot+d4dda070f833dc5dc89a@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/695e88b2.050a0220.1c677c.036d.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260107163109.4188620-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/ip6_tunnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index e635ddd41aba..69cace90ece1 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -844,7 +844,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, skb_reset_network_header(skb); - if (!pskb_inet_may_pull(skb)) { + if (skb_vlan_inet_prepare(skb, true)) { DEV_STATS_INC(tunnel->dev, rx_length_errors); DEV_STATS_INC(tunnel->dev, rx_errors); goto drop; -- Gitee From 169e6b54eca397eea33509ddaaecc98a94eb5a6b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 8 Jan 2026 17:32:44 +0800 Subject: [PATCH 1001/1449] net: update netdev_lock_{type,name} ANBZ: #35228 commit 0ba0a79500fcfc25ae80a4d57b7ae9bb81b3e894 stable. commit eb74c19fe10872ee1f29a8f90ca5ce943921afe9 upstream. Add missing entries in netdev_lock_type[] and netdev_lock_name[] : CAN, MCTP, RAWIP, CAIF, IP6GRE, 6LOWPAN, NETLINK, VSOCKMON, IEEE802154_MONITOR. Also add a WARN_ONCE() in netdev_lock_pos() to help future bug hunting next time a protocol is added without updating these arrays. Fixes: 1a33e10e4a95 ("net: partially revert dynamic lockdep key changes") Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260108093244.830280-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/dev.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index cf5b5a4cbfd7..8a7a5e16da00 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -481,15 +481,21 @@ static const unsigned short netdev_lock_type[] = { ARPHRD_IEEE1394, ARPHRD_EUI64, ARPHRD_INFINIBAND, ARPHRD_SLIP, ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6, ARPHRD_RSRVD, ARPHRD_ADAPT, ARPHRD_ROSE, ARPHRD_X25, ARPHRD_HWX25, + ARPHRD_CAN, ARPHRD_MCTP, ARPHRD_PPP, ARPHRD_CISCO, ARPHRD_LAPB, ARPHRD_DDCMP, - ARPHRD_RAWHDLC, ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD, + ARPHRD_RAWHDLC, ARPHRD_RAWIP, + ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD, ARPHRD_SKIP, ARPHRD_LOOPBACK, ARPHRD_LOCALTLK, ARPHRD_FDDI, ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE, ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET, ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, ARPHRD_FCFABRIC, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, - ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, ARPHRD_PHONET_PIPE, - ARPHRD_IEEE802154, ARPHRD_VOID, ARPHRD_NONE}; + ARPHRD_IEEE80211_RADIOTAP, + ARPHRD_IEEE802154, ARPHRD_IEEE802154_MONITOR, + ARPHRD_PHONET, ARPHRD_PHONET_PIPE, + ARPHRD_CAIF, ARPHRD_IP6GRE, ARPHRD_NETLINK, ARPHRD_6LOWPAN, + ARPHRD_VSOCKMON, + ARPHRD_VOID, ARPHRD_NONE}; static const char *const netdev_lock_name[] = { "_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", @@ -498,15 +504,21 @@ static const char *const netdev_lock_name[] = { "_xmit_IEEE1394", "_xmit_EUI64", "_xmit_INFINIBAND", "_xmit_SLIP", "_xmit_CSLIP", "_xmit_SLIP6", "_xmit_CSLIP6", "_xmit_RSRVD", "_xmit_ADAPT", "_xmit_ROSE", "_xmit_X25", "_xmit_HWX25", + "_xmit_CAN", "_xmit_MCTP", "_xmit_PPP", "_xmit_CISCO", "_xmit_LAPB", "_xmit_DDCMP", - "_xmit_RAWHDLC", "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD", + "_xmit_RAWHDLC", "_xmit_RAWIP", + "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD", "_xmit_SKIP", "_xmit_LOOPBACK", "_xmit_LOCALTLK", "_xmit_FDDI", "_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE", "_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET", "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", "_xmit_FCFABRIC", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM", - "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", "_xmit_PHONET_PIPE", - "_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"}; + "_xmit_IEEE80211_RADIOTAP", + "_xmit_IEEE802154", "_xmit_IEEE802154_MONITOR", + "_xmit_PHONET", "_xmit_PHONET_PIPE", + "_xmit_CAIF", "_xmit_IP6GRE", "_xmit_NETLINK", "_xmit_6LOWPAN", + "_xmit_VSOCKMON", + "_xmit_VOID", "_xmit_NONE"}; static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; @@ -519,6 +531,7 @@ static inline unsigned short netdev_lock_pos(unsigned short dev_type) if (netdev_lock_type[i] == dev_type) return i; /* the last key is used by default */ + WARN_ONCE(1, "netdev_lock_pos() could not find dev_type=%u\n", dev_type); return ARRAY_SIZE(netdev_lock_type) - 1; } -- Gitee From 6befef37fa16ee9cd6f6f14cc4b3f7db09964470 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 8 Jan 2026 21:36:51 +0800 Subject: [PATCH 1002/1449] macvlan: fix possible UAF in macvlan_forward_source() ANBZ: #35228 commit 15f6faf36e162532bec5cc05eb3fc622108bf2ed stable. commit 7470a7a63dc162f07c26dbf960e41ee1e248d80e upstream. Add RCU protection on (struct macvlan_source_entry)->vlan. Whenever macvlan_hash_del_source() is called, we must clear entry->vlan pointer before RCU grace period starts. This allows macvlan_forward_source() to skip over entries queued for freeing. Note that macvlan_dev are already RCU protected, as they are embedded in a standard netdev (netdev_priv(ndev)). Fixes: 79cf79abce71 ("macvlan: add source mode") Reported-by: syzbot+7182fbe91e58602ec1fe@syzkaller.appspotmail.com https: //lore.kernel.org/netdev/695fb1e8.050a0220.1c677c.039f.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260108133651.1130486-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/macvlan.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index c8da94af4161..09db43ce3176 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -58,7 +58,7 @@ struct macvlan_port { struct macvlan_source_entry { struct hlist_node hlist; - struct macvlan_dev *vlan; + struct macvlan_dev __rcu *vlan; unsigned char addr[6+2] __aligned(sizeof(u16)); struct rcu_head rcu; }; @@ -145,7 +145,7 @@ static struct macvlan_source_entry *macvlan_hash_lookup_source( hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { if (ether_addr_equal_64bits(entry->addr, addr) && - entry->vlan == vlan) + rcu_access_pointer(entry->vlan) == vlan) return entry; } return NULL; @@ -167,7 +167,7 @@ static int macvlan_hash_add_source(struct macvlan_dev *vlan, return -ENOMEM; ether_addr_copy(entry->addr, addr); - entry->vlan = vlan; + RCU_INIT_POINTER(entry->vlan, vlan); h = &port->vlan_source_hash[macvlan_eth_hash(addr)]; hlist_add_head_rcu(&entry->hlist, h); vlan->macaddr_count++; @@ -186,6 +186,7 @@ static void macvlan_hash_add(struct macvlan_dev *vlan) static void macvlan_hash_del_source(struct macvlan_source_entry *entry) { + RCU_INIT_POINTER(entry->vlan, NULL); hlist_del_rcu(&entry->hlist); kfree_rcu(entry, rcu); } @@ -389,7 +390,7 @@ static void macvlan_flush_sources(struct macvlan_port *port, int i; hash_for_each_safe(port->vlan_source_hash, i, next, entry, hlist) - if (entry->vlan == vlan) + if (rcu_access_pointer(entry->vlan) == vlan) macvlan_hash_del_source(entry); vlan->macaddr_count = 0; @@ -432,9 +433,14 @@ static bool macvlan_forward_source(struct sk_buff *skb, hlist_for_each_entry_rcu(entry, h, hlist) { if (ether_addr_equal_64bits(entry->addr, addr)) { - if (entry->vlan->flags & MACVLAN_FLAG_NODST) + struct macvlan_dev *vlan = rcu_dereference(entry->vlan); + + if (!vlan) + continue; + + if (vlan->flags & MACVLAN_FLAG_NODST) consume = true; - macvlan_forward_source_one(skb, entry->vlan); + macvlan_forward_source_one(skb, vlan); } } @@ -1685,7 +1691,7 @@ static int macvlan_fill_info_macaddr(struct sk_buff *skb, struct macvlan_source_entry *entry; hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { - if (entry->vlan != vlan) + if (rcu_access_pointer(entry->vlan) != vlan) continue; if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr)) return 1; -- Gitee From 31f33548f0c39752a92529b13b412fbcbaf5bdc3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 9 Jan 2026 03:02:14 +0800 Subject: [PATCH 1003/1449] ipv4: ip_gre: make ipgre_header() robust ANBZ: #35228 commit 06fe0801396a36cab865b34f666de1d65bc5ce8e stable. commit e67c577d89894811ce4dcd1a9ed29d8b63476667 upstream. Analog to commit db5b4e39c4e6 ("ip6_gre: make ip6gre_header() robust") Over the years, syzbot found many ways to crash the kernel in ipgre_header() [1]. This involves team or bonding drivers ability to dynamically change their dev->needed_headroom and/or dev->hard_header_len In this particular crash mld_newpack() allocated an skb with a too small reserve/headroom, and by the time mld_sendpack() was called, syzbot managed to attach an ipgre device. [1] skbuff: skb_under_panic: text:ffffffff89ea3cb7 len:2030915468 put:2030915372 head:ffff888058b43000 data:ffff887fdfa6e194 tail:0x120 end:0x6c0 dev:team0 kernel BUG at net/core/skbuff.c:213 ! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 1 UID: 0 PID: 1322 Comm: kworker/1:9 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 Workqueue: mld mld_ifc_work RIP: 0010:skb_panic+0x157/0x160 net/core/skbuff.c:213 Call Trace: skb_under_panic net/core/skbuff.c:223 [inline] skb_push+0xc3/0xe0 net/core/skbuff.c:2641 ipgre_header+0x67/0x290 net/ipv4/ip_gre.c:897 dev_hard_header include/linux/netdevice.h:3436 [inline] neigh_connected_output+0x286/0x460 net/core/neighbour.c:1618 NF_HOOK_COND include/linux/netfilter.h:307 [inline] ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247 NF_HOOK+0x9e/0x380 include/linux/netfilter.h:318 mld_sendpack+0x8d4/0xe60 net/ipv6/mcast.c:1855 mld_send_cr net/ipv6/mcast.c:2154 [inline] mld_ifc_work+0x83e/0xd60 net/ipv6/mcast.c:2693 process_one_work kernel/workqueue.c:3257 [inline] process_scheduled_works+0xad1/0x1770 kernel/workqueue.c:3340 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3421 kthread+0x711/0x8a0 kernel/kthread.c:463 ret_from_fork+0x510/0xa50 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246 Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.") Reported-by: syzbot+7c134e1c3aa3283790b9@syzkaller.appspotmail.com Closes: https://www.spinics.net/lists/netdev/msg1147302.html Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260108190214.1667040-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv4/ip_gre.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f261e29adc7c..75d388dd5ac6 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -860,10 +860,17 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, const void *daddr, const void *saddr, unsigned int len) { struct ip_tunnel *t = netdev_priv(dev); - struct iphdr *iph; struct gre_base_hdr *greh; + struct iphdr *iph; + int needed; + + needed = t->hlen + sizeof(*iph); + if (skb_headroom(skb) < needed && + pskb_expand_head(skb, HH_DATA_ALIGN(needed - skb_headroom(skb)), + 0, GFP_ATOMIC)) + return -needed; - iph = skb_push(skb, t->hlen + sizeof(*iph)); + iph = skb_push(skb, needed); greh = (struct gre_base_hdr *)(iph+1); greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags); greh->protocol = htons(type); -- Gitee From 5fa4c7e5abe408885082669c7532906dbeef2aa6 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Thu, 8 Jan 2026 19:44:19 +0800 Subject: [PATCH 1004/1449] vsock/test: add a final full barrier after run all tests ANBZ: #35228 commit 147b9a2fc7a3516131039abff6b76b0bc1650a0e stable. commit c39a6a277e0e67ffff6a8efcbbf7e7e23ce9e38c upstream. If the last test fails, the other side still completes correctly, which could lead to false positives. Let's add a final barrier that ensures that the last test has finished correctly on both sides, but also that the two sides agree on the number of tests to be performed. Fixes: 2f65b44e199c ("VSOCK: add full barrier between test cases") Reviewed-by: Luigi Leonardi Signed-off-by: Stefano Garzarella Link: https://patch.msgid.link/20260108114419.52747-1-sgarzare@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/vsock/util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c index 01b636d3039a..751fe7c6632e 100644 --- a/tools/testing/vsock/util.c +++ b/tools/testing/vsock/util.c @@ -360,6 +360,18 @@ void run_tests(const struct test_case *test_cases, printf("ok\n"); } + + printf("All tests have been executed. Waiting other peer..."); + fflush(stdout); + + /* + * Final full barrier, to ensure that all tests have been run and + * that even the last one has been successful on both sides. + */ + control_writeln("COMPLETED"); + control_expectln("COMPLETED"); + + printf("ok\n"); } void list_tests(const struct test_case *test_cases) -- Gitee From 841732b36b427d5b9aa20f348e577e8924c53985 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Fri, 9 Jan 2026 05:26:57 +0800 Subject: [PATCH 1005/1449] net/mlx5e: Restore destroying state bit after profile cleanup ANBZ: #35228 commit 6126877f90fe74a210a8a4edb2b8c9431a630ea8 stable. commit 5629f8859dca7ef74d7314b60de6a957f23166c0 upstream. Profile rollback can fail in mlx5e_netdev_change_profile() and we will end up with invalid mlx5e_priv memset to 0, we must maintain the 'destroying' bit in order to gracefully shutdown even if the profile/priv are not valid. This patch maintains the previous state of the 'destroying' state of mlx5e_priv after priv cleanup, to allow the remove flow to cleanup common resources from mlx5_core to avoid FW fatal errors as seen below: $ devlink dev eswitch set pci/0000:00:03.0 mode switchdev Error: mlx5_core: Failed setting eswitch to offloads. dmesg: mlx5_core 0000:00:03.0 enp0s3np0: failed to rollback to orig profile, ... $ devlink dev reload pci/0000:00:03.0 mlx5_core 0000:00:03.0: E-Switch: Disable: mode(LEGACY), nvfs(0), necvfs(0), active vports(0) mlx5_core 0000:00:03.0: poll_health:803:(pid 519): Fatal error 3 detected mlx5_core 0000:00:03.0: firmware version: 28.41.1000 mlx5_core 0000:00:03.0: 0.000 Gb/s available PCIe bandwidth (Unknown x255 link) mlx5_core 0000:00:03.0: mlx5_function_enable:1200:(pid 519): enable hca failed mlx5_core 0000:00:03.0: mlx5_function_enable:1200:(pid 519): enable hca failed mlx5_core 0000:00:03.0: mlx5_health_try_recover:340:(pid 141): handling bad device here mlx5_core 0000:00:03.0: mlx5_handle_bad_state:285:(pid 141): Expected to see disabled NIC but it is full driver mlx5_core 0000:00:03.0: mlx5_error_sw_reset:236:(pid 141): start mlx5_core 0000:00:03.0: NIC IFC still 0 after 4000ms. Fixes: c4d7eb57687f ("net/mxl5e: Add change profile method") Signed-off-by: Saeed Mahameed Reviewed-by: Tariq Toukan Link: https://patch.msgid.link/20260108212657.25090-5-saeed@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 4fb8477026c1..1517e7f97e56 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -5684,6 +5684,7 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, void mlx5e_priv_cleanup(struct mlx5e_priv *priv) { + bool destroying = test_bit(MLX5E_STATE_DESTROYING, &priv->state); int i; /* bail if change profile failed and also rollback failed */ @@ -5709,6 +5710,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) } memset(priv, 0, sizeof(*priv)); + if (destroying) /* restore destroying bit, to allow unload */ + set_bit(MLX5E_STATE_DESTROYING, &priv->state); } static unsigned int mlx5e_get_max_num_txqs(struct mlx5_core_dev *mdev, -- Gitee From 28fd2090afea216a9a4f7a0b2f52bebfd9569107 Mon Sep 17 00:00:00 2001 From: Boris Burkov Date: Sat, 3 Feb 2024 03:52:57 +0800 Subject: [PATCH 1006/1449] btrfs: store fs_info in space_info ANBZ: #35228 commit 1fe74715ccb4e48001be551402acb6f83e99cf20 stable. commit 42f620aec182f62ee72e3fce41cb3353951b3508 upstream. This is handy when computing space_info dynamic reclaim thresholds where we do not have access to a block group. We could add it to the various functions as a parameter, but it seems reasonable for space_info to have an fs_info pointer. Reviewed-by: Josef Bacik Reviewed-by: Johannes Thumshirn Signed-off-by: Boris Burkov Reviewed-by: David Sterba Signed-off-by: David Sterba Stable-dep-of: a11224a016d6 ("btrfs: fix memory leaks in create_space_info() error paths") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/space-info.c | 1 + fs/btrfs/space-info.h | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 27690c518f6d..bf5e509eb9fa 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -233,6 +233,7 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags) if (!space_info) return -ENOMEM; + space_info->fs_info = info; for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) INIT_LIST_HEAD(&space_info->block_groups[i]); init_rwsem(&space_info->groups_sem); diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h index b0187f25dbb5..39452e36625a 100644 --- a/fs/btrfs/space-info.h +++ b/fs/btrfs/space-info.h @@ -84,6 +84,7 @@ enum btrfs_flush_state { }; struct btrfs_space_info { + struct btrfs_fs_info *fs_info; spinlock_t lock; u64 total_bytes; /* total bytes in the space, -- Gitee From a13780123dd8606a8820fb0888d6efd6ba0baba8 Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Wed, 23 Apr 2025 10:43:43 +0800 Subject: [PATCH 1007/1449] btrfs: factor out init_space_info() from create_space_info() ANBZ: #35228 commit 34d5cd41418af8cda0e0594db454e0abf3d6407f stable. commit ac5578fef380e68e539a2238ba63dd978a450ef2 upstream. Factor out initialization of the space_info struct, which is used in a later patch. There is no functional change. Reviewed-by: Johannes Thumshirn Signed-off-by: Naohiro Aota Reviewed-by: David Sterba Signed-off-by: David Sterba Stable-dep-of: a11224a016d6 ("btrfs: fix memory leaks in create_space_info() error paths") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/space-info.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index bf5e509eb9fa..38f730246e02 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -222,19 +222,11 @@ void btrfs_update_space_info_chunk_size(struct btrfs_space_info *space_info, WRITE_ONCE(space_info->chunk_size, chunk_size); } -static int create_space_info(struct btrfs_fs_info *info, u64 flags) +static void init_space_info(struct btrfs_fs_info *info, + struct btrfs_space_info *space_info, u64 flags) { - - struct btrfs_space_info *space_info; - int i; - int ret; - - space_info = kzalloc(sizeof(*space_info), GFP_NOFS); - if (!space_info) - return -ENOMEM; - space_info->fs_info = info; - for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) + for (int i = 0; i < BTRFS_NR_RAID_TYPES; i++) INIT_LIST_HEAD(&space_info->block_groups[i]); init_rwsem(&space_info->groups_sem); spin_lock_init(&space_info->lock); @@ -248,6 +240,19 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags) if (btrfs_is_zoned(info)) space_info->bg_reclaim_threshold = BTRFS_DEFAULT_ZONED_RECLAIM_THRESH; +} + +static int create_space_info(struct btrfs_fs_info *info, u64 flags) +{ + + struct btrfs_space_info *space_info; + int ret; + + space_info = kzalloc(sizeof(*space_info), GFP_NOFS); + if (!space_info) + return -ENOMEM; + + init_space_info(info, space_info, flags); ret = btrfs_sysfs_add_space_info_type(info, space_info); if (ret) -- Gitee From 1cc4b14d19a9467e0c1a416aacb1d8dd80633aa1 Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Wed, 23 Apr 2025 10:43:45 +0800 Subject: [PATCH 1008/1449] btrfs: factor out check_removing_space_info() from btrfs_free_block_groups() ANBZ: #35228 commit 42c8d48bf3abeba7041658bc2470ee432f94d55c stable. commit 1cfdbe0d53b27b4b4a4f4cf2a4e430bc65ba2ba5 upstream. Factor out check_removing_space_info() from btrfs_free_block_groups(). It sanity checks a to-be-removed space_info. There is no functional change. Reviewed-by: Johannes Thumshirn Signed-off-by: Naohiro Aota Reviewed-by: David Sterba Signed-off-by: David Sterba Stable-dep-of: a11224a016d6 ("btrfs: fix memory leaks in create_space_info() error paths") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/block-group.c | 49 +++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 5678ca67f91b..c244bf1674ca 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -4379,6 +4379,32 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info) } } +static void check_removing_space_info(struct btrfs_space_info *space_info) +{ + struct btrfs_fs_info *info = space_info->fs_info; + + /* + * Do not hide this behind enospc_debug, this is actually important and + * indicates a real bug if this happens. + */ + if (WARN_ON(space_info->bytes_pinned > 0 || space_info->bytes_may_use > 0)) + btrfs_dump_space_info(info, space_info, 0, 0); + + /* + * If there was a failure to cleanup a log tree, very likely due to an + * IO failure on a writeback attempt of one or more of its extent + * buffers, we could not do proper (and cheap) unaccounting of their + * reserved space, so don't warn on bytes_reserved > 0 in that case. + */ + if (!(space_info->flags & BTRFS_BLOCK_GROUP_METADATA) || + !BTRFS_FS_LOG_CLEANUP_ERROR(info)) { + if (WARN_ON(space_info->bytes_reserved > 0)) + btrfs_dump_space_info(info, space_info, 0, 0); + } + + WARN_ON(space_info->reclaim_size > 0); +} + /* * Must be called only after stopping all workers, since we could have block * group caching kthreads running, and therefore they could race with us if we @@ -4480,28 +4506,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) struct btrfs_space_info, list); - /* - * Do not hide this behind enospc_debug, this is actually - * important and indicates a real bug if this happens. - */ - if (WARN_ON(space_info->bytes_pinned > 0 || - space_info->bytes_may_use > 0)) - btrfs_dump_space_info(info, space_info, 0, 0); - - /* - * If there was a failure to cleanup a log tree, very likely due - * to an IO failure on a writeback attempt of one or more of its - * extent buffers, we could not do proper (and cheap) unaccounting - * of their reserved space, so don't warn on bytes_reserved > 0 in - * that case. - */ - if (!(space_info->flags & BTRFS_BLOCK_GROUP_METADATA) || - !BTRFS_FS_LOG_CLEANUP_ERROR(info)) { - if (WARN_ON(space_info->bytes_reserved > 0)) - btrfs_dump_space_info(info, space_info, 0, 0); - } - - WARN_ON(space_info->reclaim_size > 0); + check_removing_space_info(space_info); list_del(&space_info->list); btrfs_sysfs_remove_space_info(space_info); } -- Gitee From 3b2bf79c5a7dfb5462ca0e8c87674b08b13b7723 Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Wed, 23 Apr 2025 10:43:48 +0800 Subject: [PATCH 1009/1449] btrfs: introduce btrfs_space_info sub-group ANBZ: #35228 commit 0bd151ce4200ca847990e05cca29a76456982ca5 stable. commit f92ee31e031c7819126d2febdda0c3e91f5d2eb9 upstream. Current code assumes we have only one space_info for each block group type (DATA, METADATA, and SYSTEM). We sometime need multiple space infos to manage special block groups. One example is handling the data relocation block group for the zoned mode. That block group is dedicated for writing relocated data and we cannot allocate any regular extent from that block group, which is implemented in the zoned extent allocator. This block group still belongs to the normal data space_info. So, when all the normal data block groups are full and there is some free space in the dedicated block group, the space_info looks to have some free space, while it cannot allocate normal extent anymore. That results in a strange ENOSPC error. We need to have a space_info for the relocation data block group to represent the situation properly. Adds a basic infrastructure for having a "sub-group" of a space_info: creation and removing. A sub-group space_info belongs to one of the primary space_infos and has the same flags as its parent. This commit first introduces the relocation data sub-space_info, and the next commit will introduce tree-log sub-space_info. In the future, it could be useful to implement tiered storage for btrfs e.g. by implementing a sub-group space_info for block groups resides on a fast storage. Reviewed-by: Johannes Thumshirn Signed-off-by: Naohiro Aota Signed-off-by: David Sterba Stable-dep-of: a11224a016d6 ("btrfs: fix memory leaks in create_space_info() error paths") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/block-group.c | 11 +++++++++++ fs/btrfs/space-info.c | 44 +++++++++++++++++++++++++++++++++++++++--- fs/btrfs/space-info.h | 9 +++++++++ fs/btrfs/sysfs.c | 18 ++++++++++++++--- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index c244bf1674ca..70680a7b9a7b 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -4383,6 +4383,17 @@ static void check_removing_space_info(struct btrfs_space_info *space_info) { struct btrfs_fs_info *info = space_info->fs_info; + if (space_info->subgroup_id == BTRFS_SUB_GROUP_PRIMARY) { + /* This is a top space_info, proceed with its children first. */ + for (int i = 0; i < BTRFS_SPACE_INFO_SUB_GROUP_MAX; i++) { + if (space_info->sub_group[i]) { + check_removing_space_info(space_info->sub_group[i]); + kfree(space_info->sub_group[i]); + space_info->sub_group[i] = NULL; + } + } + } + /* * Do not hide this behind enospc_debug, this is actually important and * indicates a real bug if this happens. diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 38f730246e02..01d9a93346c2 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -237,16 +237,44 @@ static void init_space_info(struct btrfs_fs_info *info, INIT_LIST_HEAD(&space_info->priority_tickets); space_info->clamp = 1; btrfs_update_space_info_chunk_size(space_info, calc_chunk_size(info, flags)); + space_info->subgroup_id = BTRFS_SUB_GROUP_PRIMARY; if (btrfs_is_zoned(info)) space_info->bg_reclaim_threshold = BTRFS_DEFAULT_ZONED_RECLAIM_THRESH; } +static int create_space_info_sub_group(struct btrfs_space_info *parent, u64 flags, + enum btrfs_space_info_sub_group id, int index) +{ + struct btrfs_fs_info *fs_info = parent->fs_info; + struct btrfs_space_info *sub_group; + int ret; + + ASSERT(parent->subgroup_id == BTRFS_SUB_GROUP_PRIMARY); + ASSERT(id != BTRFS_SUB_GROUP_PRIMARY); + + sub_group = kzalloc(sizeof(*sub_group), GFP_NOFS); + if (!sub_group) + return -ENOMEM; + + init_space_info(fs_info, sub_group, flags); + parent->sub_group[index] = sub_group; + sub_group->parent = parent; + sub_group->subgroup_id = id; + + ret = btrfs_sysfs_add_space_info_type(fs_info, sub_group); + if (ret) { + kfree(sub_group); + parent->sub_group[index] = NULL; + } + return ret; +} + static int create_space_info(struct btrfs_fs_info *info, u64 flags) { struct btrfs_space_info *space_info; - int ret; + int ret = 0; space_info = kzalloc(sizeof(*space_info), GFP_NOFS); if (!space_info) @@ -254,6 +282,15 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags) init_space_info(info, space_info, flags); + if (btrfs_is_zoned(info)) { + if (flags & BTRFS_BLOCK_GROUP_DATA) + ret = create_space_info_sub_group(space_info, flags, + BTRFS_SUB_GROUP_DATA_RELOC, + 0); + if (ret) + return ret; + } + ret = btrfs_sysfs_add_space_info_type(info, space_info); if (ret) return ret; @@ -496,8 +533,9 @@ static void __btrfs_dump_space_info(const struct btrfs_fs_info *fs_info, lockdep_assert_held(&info->lock); /* The free space could be negative in case of overcommit */ - btrfs_info(fs_info, "space_info %s has %lld free, is %sfull", - flag_str, + btrfs_info(fs_info, + "space_info %s (sub-group id %d) has %lld free, is %sfull", + flag_str, info->subgroup_id, (s64)(info->total_bytes - btrfs_space_info_used(info, true)), info->full ? "" : "not "); btrfs_info(fs_info, diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h index 39452e36625a..0670f074902d 100644 --- a/fs/btrfs/space-info.h +++ b/fs/btrfs/space-info.h @@ -83,8 +83,17 @@ enum btrfs_flush_state { COMMIT_TRANS = 11, }; +enum btrfs_space_info_sub_group { + BTRFS_SUB_GROUP_PRIMARY, + BTRFS_SUB_GROUP_DATA_RELOC, +}; + +#define BTRFS_SPACE_INFO_SUB_GROUP_MAX 1 struct btrfs_space_info { struct btrfs_fs_info *fs_info; + struct btrfs_space_info *parent; + struct btrfs_space_info *sub_group[BTRFS_SPACE_INFO_SUB_GROUP_MAX]; + int subgroup_id; spinlock_t lock; u64 total_bytes; /* total bytes in the space, diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 512d4cbac1ca..9609579d2289 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -1641,16 +1641,28 @@ void btrfs_sysfs_remove_space_info(struct btrfs_space_info *space_info) kobject_put(&space_info->kobj); } -static const char *alloc_name(u64 flags) +static const char *alloc_name(struct btrfs_space_info *space_info) { + u64 flags = space_info->flags; + switch (flags) { case BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA: return "mixed"; case BTRFS_BLOCK_GROUP_METADATA: + ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_PRIMARY); return "metadata"; case BTRFS_BLOCK_GROUP_DATA: - return "data"; + switch (space_info->subgroup_id) { + case BTRFS_SUB_GROUP_PRIMARY: + return "data"; + case BTRFS_SUB_GROUP_DATA_RELOC: + return "data-reloc"; + default: + WARN_ON_ONCE(1); + return "data (unknown sub-group)"; + } case BTRFS_BLOCK_GROUP_SYSTEM: + ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_PRIMARY); return "system"; default: WARN_ON(1); @@ -1669,7 +1681,7 @@ int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info, ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype, fs_info->space_info_kobj, "%s", - alloc_name(space_info->flags)); + alloc_name(space_info)); if (ret) { kobject_put(&space_info->kobj); return ret; -- Gitee From 3f84634e87a11b8024e6b5031e6ad760cdba7bfd Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Mon, 12 Jan 2026 03:20:37 +0800 Subject: [PATCH 1010/1449] btrfs: fix memory leaks in create_space_info() error paths ANBZ: #35228 commit 58208907c4044a764dbd8896026283905da6d9be stable. commit a11224a016d6d1d46a4d9b6573244448a80d4d7f upstream. In create_space_info(), the 'space_info' object is allocated at the beginning of the function. However, there are two error paths where the function returns an error code without freeing the allocated memory: 1. When create_space_info_sub_group() fails in zoned mode. 2. When btrfs_sysfs_add_space_info_type() fails. In both cases, 'space_info' has not yet been added to the fs_info->space_info list, resulting in a memory leak. Fix this by adding an error handling label to kfree(space_info) before returning. Fixes: 2be12ef79fe9 ("btrfs: Separate space_info create/update") Reviewed-by: Qu Wenruo Signed-off-by: Jiasheng Jiang Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/space-info.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 01d9a93346c2..00d596a8176f 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -288,18 +288,22 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags) BTRFS_SUB_GROUP_DATA_RELOC, 0); if (ret) - return ret; + goto out_free; } ret = btrfs_sysfs_add_space_info_type(info, space_info); if (ret) - return ret; + goto out_free; list_add(&space_info->list, &info->space_info); if (flags & BTRFS_BLOCK_GROUP_DATA) info->data_sinfo = space_info; return ret; + +out_free: + kfree(space_info); + return ret; } int btrfs_init_space_info(struct btrfs_fs_info *fs_info) -- Gitee From 08814f7dbc7cf7aaae443ecdf18f6d009be2eb71 Mon Sep 17 00:00:00 2001 From: Aditya Garg Date: Mon, 12 Jan 2026 18:01:33 +0800 Subject: [PATCH 1011/1449] net: hv_netvsc: reject RSS hash key programming without RX indirection table ANBZ: #35228 commit 82c9039c8ebb715753a40434df714f865a3aec9c stable. commit d23564955811da493f34412d7de60fa268c8cb50 upstream. RSS configuration requires a valid RX indirection table. When the device reports a single receive queue, rndis_filter_device_add() does not allocate an indirection table, accepting RSS hash key updates in this state leads to a hang. Fix this by gating netvsc_set_rxfh() on ndc->rx_table_sz and return -EOPNOTSUPP when the table is absent. This aligns set_rxfh with the device capabilities and prevents incorrect behavior. Fixes: 962f3fee83a4 ("netvsc: add ethtool ops to get/set RSS key") Signed-off-by: Aditya Garg Reviewed-by: Dipayaan Roy Reviewed-by: Haiyang Zhang Link: https://patch.msgid.link/1768212093-1594-1-git-send-email-gargaditya@linux.microsoft.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/hyperv/netvsc_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index aa114240e340..af001e2e688b 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -1762,6 +1762,9 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir, if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) return -EOPNOTSUPP; + if (!ndc->rx_table_sz) + return -EOPNOTSUPP; + rndis_dev = ndev->extension; if (indir) { for (i = 0; i < ndc->rx_table_sz; i++) -- Gitee From f2658a669942c4e3a856132d1ea5f70a627d5cd3 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Tue, 13 Jan 2026 09:05:08 +0800 Subject: [PATCH 1012/1449] ipv6: Fix use-after-free in inet6_addr_del(). ANBZ: #35228 commit 9356b69d03d0f50cce91cebdabd33dda023fbd64 stable. commit ddf96c393a33aef4887e2e406c76c2f8cda1419c upstream. syzbot reported use-after-free of inet6_ifaddr in inet6_addr_del(). [0] The cited commit accidentally moved ipv6_del_addr() for mngtmpaddr before reading its ifp->flags for temporary addresses in inet6_addr_del(). Let's move ipv6_del_addr() down to fix the UAF. [0]: BUG: KASAN: slab-use-after-free in inet6_addr_del.constprop.0+0x67a/0x6b0 net/ipv6/addrconf.c:3117 Read of size 4 at addr ffff88807b89c86c by task syz.3.1618/9593 CPU: 0 UID: 0 PID: 9593 Comm: syz.3.1618 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xcd/0x630 mm/kasan/report.c:482 kasan_report+0xe0/0x110 mm/kasan/report.c:595 inet6_addr_del.constprop.0+0x67a/0x6b0 net/ipv6/addrconf.c:3117 addrconf_del_ifaddr+0x11e/0x190 net/ipv6/addrconf.c:3181 inet6_ioctl+0x1e5/0x2b0 net/ipv6/af_inet6.c:582 sock_do_ioctl+0x118/0x280 net/socket.c:1254 sock_ioctl+0x227/0x6b0 net/socket.c:1375 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl fs/ioctl.c:583 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f164cf8f749 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f164de64038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f164d1e5fa0 RCX: 00007f164cf8f749 RDX: 0000200000000000 RSI: 0000000000008936 RDI: 0000000000000003 RBP: 00007f164d013f91 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f164d1e6038 R14: 00007f164d1e5fa0 R15: 00007ffde15c8288 Allocated by task 9593: kasan_save_stack+0x33/0x60 mm/kasan/common.c:56 kasan_save_track+0x14/0x30 mm/kasan/common.c:77 poison_kmalloc_redzone mm/kasan/common.c:397 [inline] __kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:414 kmalloc_noprof include/linux/slab.h:957 [inline] kzalloc_noprof include/linux/slab.h:1094 [inline] ipv6_add_addr+0x4e3/0x2010 net/ipv6/addrconf.c:1120 inet6_addr_add+0x256/0x9b0 net/ipv6/addrconf.c:3050 addrconf_add_ifaddr+0x1fc/0x450 net/ipv6/addrconf.c:3160 inet6_ioctl+0x103/0x2b0 net/ipv6/af_inet6.c:580 sock_do_ioctl+0x118/0x280 net/socket.c:1254 sock_ioctl+0x227/0x6b0 net/socket.c:1375 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl fs/ioctl.c:583 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 6099: kasan_save_stack+0x33/0x60 mm/kasan/common.c:56 kasan_save_track+0x14/0x30 mm/kasan/common.c:77 kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:584 poison_slab_object mm/kasan/common.c:252 [inline] __kasan_slab_free+0x5f/0x80 mm/kasan/common.c:284 kasan_slab_free include/linux/kasan.h:234 [inline] slab_free_hook mm/slub.c:2540 [inline] slab_free_freelist_hook mm/slub.c:2569 [inline] slab_free_bulk mm/slub.c:6696 [inline] kmem_cache_free_bulk mm/slub.c:7383 [inline] kmem_cache_free_bulk+0x2bf/0x680 mm/slub.c:7362 kfree_bulk include/linux/slab.h:830 [inline] kvfree_rcu_bulk+0x1b7/0x1e0 mm/slab_common.c:1523 kvfree_rcu_drain_ready mm/slab_common.c:1728 [inline] kfree_rcu_monitor+0x1d0/0x2f0 mm/slab_common.c:1801 process_one_work+0x9ba/0x1b20 kernel/workqueue.c:3257 process_scheduled_works kernel/workqueue.c:3340 [inline] worker_thread+0x6c8/0xf10 kernel/workqueue.c:3421 kthread+0x3c5/0x780 kernel/kthread.c:463 ret_from_fork+0x983/0xb10 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246 Fixes: 00b5b7aab9e42 ("net/ipv6: delete temporary address if mngtmpaddr is removed or unmanaged") Reported-by: syzbot+72e610f4f1a930ca9d8a@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/696598e9.050a0220.3be5c5.0009.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima Reviewed-by: Hangbin Liu Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20260113010538.2019411-1-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/addrconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2737bb4751e4..4958452cd332 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3111,12 +3111,12 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags, in6_ifa_hold(ifp); read_unlock_bh(&idev->lock); - ipv6_del_addr(ifp); - if (!(ifp->flags & IFA_F_TEMPORARY) && (ifp->flags & IFA_F_MANAGETEMPADDR)) delete_tempaddrs(idev, ifp); + ipv6_del_addr(ifp); + addrconf_verify_rtnl(net); if (ipv6_addr_is_multicast(pfx)) { ipv6_mc_config(net->ipv6.mc_autojoin_sk, -- Gitee From 57451d6bbb48a7fb9284cad0487f9339778119f9 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Tue, 13 Jan 2026 01:37:15 +0800 Subject: [PATCH 1013/1449] selftests: drv-net: fix RPS mask handling for high CPU numbers ANBZ: #35228 commit a3f895d4494a8c3ee92bbb0baa36cc20501e8df5 stable. commit cf055f8c000445aa688c53a706ef4f580818eedb upstream. The RPS bitmask bounds check uses ~(RPS_MAX_CPUS - 1) which equals ~15 = 0xfff0, only allowing CPUs 0-3. Change the mask to ~((1UL << RPS_MAX_CPUS) - 1) = ~0xffff to allow CPUs 0-15. Fixes: 5ebfb4cc3048 ("selftests/net: toeplitz test") Reviewed-by: Nimrod Oren Signed-off-by: Gal Pressman Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20260112173715.384843-3-gal@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/toeplitz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/toeplitz.c b/tools/testing/selftests/net/toeplitz.c index 9ba03164d73a..5099157f01b9 100644 --- a/tools/testing/selftests/net/toeplitz.c +++ b/tools/testing/selftests/net/toeplitz.c @@ -473,8 +473,8 @@ static void parse_rps_bitmap(const char *arg) bitmap = strtoul(arg, NULL, 0); - if (bitmap & ~(RPS_MAX_CPUS - 1)) - error(1, 0, "rps bitmap 0x%lx out of bounds 0..%lu", + if (bitmap & ~((1UL << RPS_MAX_CPUS) - 1)) + error(1, 0, "rps bitmap 0x%lx out of bounds, max cpu %lu", bitmap, RPS_MAX_CPUS - 1); for (i = 0; i < RPS_MAX_CPUS; i++) -- Gitee From 61733f1fad43f84154ff0eeadb5efd23afe40923 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 13 Jan 2026 01:56:56 +0800 Subject: [PATCH 1014/1449] net/sched: sch_qfq: do not free existing class in qfq_change_class() ANBZ: #35228 commit 0a234660dc70ce45d771cbc76b20d925b73ec160 stable. commit 3879cffd9d07aa0377c4b8835c4f64b4fb24ac78 upstream. Fixes qfq_change_class() error case. cl->qdisc and cl should only be freed if a new class and qdisc were allocated, or we risk various UAF. Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost") Reported-by: syzbot+07f3f38f723c335f106d@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6965351d.050a0220.eaf7.00c5.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Reviewed-by: Jamal Hadi Salim Link: https://patch.msgid.link/20260112175656.17605-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_qfq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 29847c28ffac..7c6b5428b8ed 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -532,8 +532,10 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, return 0; destroy_class: - qdisc_put(cl->qdisc); - kfree(cl); + if (!existing) { + qdisc_put(cl->qdisc); + kfree(cl); + } return err; } -- Gitee From 86cf7a6dae0335c835977077ff53f8fed48da604 Mon Sep 17 00:00:00 2001 From: Emil Svendsen Date: Tue, 13 Jan 2026 18:58:45 +0800 Subject: [PATCH 1015/1449] ASoC: tlv320adcx140: fix null pointer ANBZ: #35228 commit 659939d08e5f7bc17b941c53e8c9c0a6c6113b21 stable. commit be7664c81d3129fc313ef62ff275fd3d33cfecd4 upstream. The "snd_soc_component" in "adcx140_priv" was only used once but never set. It was only used for reaching "dev" which is already present in "adcx140_priv". Fixes: 4e82971f7b55 ("ASoC: tlv320adcx140: Add a new kcontrol") Signed-off-by: Emil Svendsen Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-2-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/tlv320adcx140.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 41342b340680..d366c1c51f07 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -24,7 +24,6 @@ #include "tlv320adcx140.h" struct adcx140_priv { - struct snd_soc_component *component; struct regulator *supply_areg; struct gpio_desc *gpio_reset; struct regmap *regmap; @@ -702,7 +701,6 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state) { int pwr_ctrl = 0; int ret = 0; - struct snd_soc_component *component = adcx140->component; if (power_state) pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ; @@ -714,7 +712,7 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state) ret = regmap_write(adcx140->regmap, ADCX140_PHASE_CALIB, adcx140->phase_calib_on ? 0x00 : 0x40); if (ret) - dev_err(component->dev, "%s: register write error %d\n", + dev_err(adcx140->dev, "%s: register write error %d\n", __func__, ret); } -- Gitee From 28db00aa5bb4a15b3cc56b62a8e8e0a73d466eb7 Mon Sep 17 00:00:00 2001 From: Emil Svendsen Date: Tue, 13 Jan 2026 18:58:47 +0800 Subject: [PATCH 1016/1449] ASoC: tlv320adcx140: fix word length ANBZ: #35228 commit 805f1c634817ac2b50a257509dc28ff091f61a59 stable. commit 46378ab9fcb796dca46b51e10646f636e2c661f9 upstream. The word length is the physical width of the channel slots. So the hw_params would misconfigure when format width and physical width doesn't match. Like S24_LE which has data width of 24 bits but physical width of 32 bits. So if using asymmetric formats you will get a lot of noise. Fixes: 689c7655b50c5 ("ASoC: tlv320adcx140: Add the tlv320adcx140 codec driver family") Signed-off-by: Emil Svendsen Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-4-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/tlv320adcx140.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index d366c1c51f07..78d95b8be2f2 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -728,7 +728,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream, struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); u8 data = 0; - switch (params_width(params)) { + switch (params_physical_width(params)) { case 16: data = ADCX140_16_BIT_WORD; break; @@ -743,7 +743,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream, break; default: dev_err(component->dev, "%s: Unsupported width %d\n", - __func__, params_width(params)); + __func__, params_physical_width(params)); return -EINVAL; } -- Gitee From 2ca1e4067a6c4098bad4996bd1be6cec5e10196e Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Fri, 19 Dec 2025 09:40:05 +0800 Subject: [PATCH 1017/1449] textsearch: describe @list member in ts_ops search ANBZ: #35228 commit f332d75388ea518d7efd0ed028c19801de2b6949 stable. commit f26528478bb102c28e7ac0cbfc8ec8185afdafc7 upstream. Sphinx reports kernel-doc warning: WARNING: ./include/linux/textsearch.h:49 struct member 'list' not described in 'ts_ops' Describe @list member to fix it. Link: https://lkml.kernel.org/r/20251219014006.16328-4-bagasdotme@gmail.com Fixes: 2de4ff7bd658 ("[LIB]: Textsearch infrastructure.") Signed-off-by: Bagas Sanjaya Cc: Thomas Graf Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/textsearch.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h index 6673e4d4ac2e..4933777404d6 100644 --- a/include/linux/textsearch.h +++ b/include/linux/textsearch.h @@ -35,6 +35,7 @@ struct ts_state * @get_pattern: return head of pattern * @get_pattern_len: return length of pattern * @owner: module reference to algorithm + * @list: list to search */ struct ts_ops { -- Gitee From 04d90ed180c75b6d35326158d7f8f51360b1ccbd Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Fri, 19 Dec 2025 09:40:07 +0800 Subject: [PATCH 1018/1449] mm, kfence: describe @slab parameter in __kfence_obj_info() ANBZ: #35228 commit 7602a67114cd55916af42f5094ca0aac7e14bade stable. commit 6cfab50e1440fde19af7c614aacd85e11aa4dcea upstream. Sphinx reports kernel-doc warning: WARNING: ./include/linux/kfence.h:220 function parameter 'slab' not described in '__kfence_obj_info' Fix it by describing @slab parameter. Link: https://lkml.kernel.org/r/20251219014006.16328-6-bagasdotme@gmail.com Fixes: 2dfe63e61cc3 ("mm, kfence: support kmem_dump_obj() for KFENCE objects") Signed-off-by: Bagas Sanjaya Acked-by: Marco Elver Acked-by: David Hildenbrand (Red Hat) Acked-by: Harry Yoo Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/kfence.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/kfence.h b/include/linux/kfence.h index 6771c6eea720..6f79ab7710cc 100644 --- a/include/linux/kfence.h +++ b/include/linux/kfence.h @@ -343,6 +343,7 @@ struct kmem_obj_info; * __kfence_obj_info() - fill kmem_obj_info struct * @kpp: kmem_obj_info to be filled * @object: the object + * @slab: the slab * * Return: * * false - not a KFENCE object -- Gitee From f945ba00007b3c4a3a2dc373d9a8b8cb38ebc6f8 Mon Sep 17 00:00:00 2001 From: Anthony Brandon Date: Mon, 13 Oct 2025 23:48:49 +0800 Subject: [PATCH 1019/1449] dmaengine: xilinx: xdma: Fix regmap max_register ANBZ: #35228 commit df8a131a41ff6202d47f59452735787f2b71dd2d stable. commit c7d436a6c1a274c1ac28d5fb3b8eb8f03b6d0e10 upstream. The max_register field is assigned the size of the register memory region instead of the offset of the last register. The result is that reading from the regmap via debugfs can cause a segmentation fault: tail /sys/kernel/debug/regmap/xdma.1.auto/registers Unable to handle kernel paging request at virtual address ffff800082f70000 Mem abort info: ESR = 0x0000000096000007 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x07: level 3 translation fault [...] Call trace: regmap_mmio_read32le+0x10/0x30 _regmap_bus_reg_read+0x74/0xc0 _regmap_read+0x68/0x198 regmap_read+0x54/0x88 regmap_read_debugfs+0x140/0x380 regmap_map_read_file+0x30/0x48 full_proxy_read+0x68/0xc8 vfs_read+0xcc/0x310 ksys_read+0x7c/0x120 __arm64_sys_read+0x24/0x40 invoke_syscall.constprop.0+0x64/0x108 do_el0_svc+0xb0/0xd8 el0_svc+0x38/0x130 el0t_64_sync_handler+0x120/0x138 el0t_64_sync+0x194/0x198 Code: aa1e03e9 d503201f f9400000 8b214000 (b9400000) ---[ end trace 0000000000000000 ]--- note: tail[1217] exited with irqs disabled note: tail[1217] exited with preempt_count 1 Segmentation fault Fixes: 17ce252266c7 ("dmaengine: xilinx: xdma: Add xilinx xdma driver") Reviewed-by: Lizhi Hou Reviewed-by: Radhey Shyam Pandey Reviewed-by: Alexander Stein Signed-off-by: Anthony Brandon Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/xilinx/xdma-regs.h | 1 + drivers/dma/xilinx/xdma.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/xilinx/xdma-regs.h b/drivers/dma/xilinx/xdma-regs.h index dd98b4526b90..b19c173d8bfc 100644 --- a/drivers/dma/xilinx/xdma-regs.h +++ b/drivers/dma/xilinx/xdma-regs.h @@ -9,6 +9,7 @@ /* The length of register space exposed to host */ #define XDMA_REG_SPACE_LEN 65536 +#define XDMA_MAX_REG_OFFSET (XDMA_REG_SPACE_LEN - 4) /* * maximum number of DMA channels for each direction: diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c index e0bfd129d563..dbab4c449914 100644 --- a/drivers/dma/xilinx/xdma.c +++ b/drivers/dma/xilinx/xdma.c @@ -38,7 +38,7 @@ static const struct regmap_config xdma_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .max_register = XDMA_REG_SPACE_LEN, + .max_register = XDMA_MAX_REG_OFFSET, }; /** -- Gitee From 533c79ddabecb1244fbbeaf9ab6f17aec20dd076 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 10 Nov 2025 22:24:45 +0800 Subject: [PATCH 1020/1449] dmaengine: tegra-adma: Fix use-after-free ANBZ: #35228 commit 59cb421b0902fbef2b9512ae8ba198a20f26b41f stable. commit 2efd07a7c36949e6fa36a69183df24d368bf9e96 upstream. A use-after-free bug exists in the Tegra ADMA driver when audio streams are terminated, particularly during XRUN conditions. The issue occurs when the DMA buffer is freed by tegra_adma_terminate_all() before the vchan completion tasklet finishes accessing it. The race condition follows this sequence: 1. DMA transfer completes, triggering an interrupt that schedules the completion tasklet (tasklet has not executed yet) 2. Audio playback stops, calling tegra_adma_terminate_all() which frees the DMA buffer memory via kfree() 3. The scheduled tasklet finally executes, calling vchan_complete() which attempts to access the already-freed memory Since tasklets can execute at any time after being scheduled, there is no guarantee that the buffer will remain valid when vchan_complete() runs. Fix this by properly synchronizing the virtual channel completion: - Calling vchan_terminate_vdesc() in tegra_adma_stop() to mark the descriptors as terminated instead of freeing the descriptor. - Add the callback tegra_adma_synchronize() that calls vchan_synchronize() which kills any pending tasklets and frees any terminated descriptors. Crash logs: [ 337.427523] BUG: KASAN: use-after-free in vchan_complete+0x124/0x3b0 [ 337.427544] Read of size 8 at addr ffff000132055428 by task swapper/0/0 [ 337.427562] Call trace: [ 337.427564] dump_backtrace+0x0/0x320 [ 337.427571] show_stack+0x20/0x30 [ 337.427575] dump_stack_lvl+0x68/0x84 [ 337.427584] print_address_description.constprop.0+0x74/0x2b8 [ 337.427590] kasan_report+0x1f4/0x210 [ 337.427598] __asan_load8+0xa0/0xd0 [ 337.427603] vchan_complete+0x124/0x3b0 [ 337.427609] tasklet_action_common.constprop.0+0x190/0x1d0 [ 337.427617] tasklet_action+0x30/0x40 [ 337.427623] __do_softirq+0x1a0/0x5c4 [ 337.427628] irq_exit+0x110/0x140 [ 337.427633] handle_domain_irq+0xa4/0xe0 [ 337.427640] gic_handle_irq+0x64/0x160 [ 337.427644] call_on_irq_stack+0x20/0x4c [ 337.427649] do_interrupt_handler+0x7c/0x90 [ 337.427654] el1_interrupt+0x30/0x80 [ 337.427659] el1h_64_irq_handler+0x18/0x30 [ 337.427663] el1h_64_irq+0x7c/0x80 [ 337.427667] cpuidle_enter_state+0xe4/0x540 [ 337.427674] cpuidle_enter+0x54/0x80 [ 337.427679] do_idle+0x2e0/0x380 [ 337.427685] cpu_startup_entry+0x2c/0x70 [ 337.427690] rest_init+0x114/0x130 [ 337.427695] arch_call_rest_init+0x18/0x24 [ 337.427702] start_kernel+0x380/0x3b4 [ 337.427706] __primary_switched+0xc0/0xc8 Fixes: f46b195799b5 ("dmaengine: tegra-adma: Add support for Tegra210 ADMA") Signed-off-by: Sheetal Acked-by: Thierry Reding Link: https://patch.msgid.link/20251110142445.3842036-1-sheetal@nvidia.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/tegra210-adma.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index e557bada1510..37848d558ae4 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -342,10 +342,17 @@ static void tegra_adma_stop(struct tegra_adma_chan *tdc) return; } - kfree(tdc->desc); + vchan_terminate_vdesc(&tdc->desc->vd); tdc->desc = NULL; } +static void tegra_adma_synchronize(struct dma_chan *dc) +{ + struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); + + vchan_synchronize(&tdc->vc); +} + static void tegra_adma_start(struct tegra_adma_chan *tdc) { struct virt_dma_desc *vd = vchan_next_desc(&tdc->vc); @@ -909,6 +916,7 @@ static int tegra_adma_probe(struct platform_device *pdev) tdma->dma_dev.device_config = tegra_adma_slave_config; tdma->dma_dev.device_tx_status = tegra_adma_tx_status; tdma->dma_dev.device_terminate_all = tegra_adma_terminate_all; + tdma->dma_dev.device_synchronize = tegra_adma_synchronize; tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -- Gitee From eae28d1b26b62748a302cb77a1effcd3cf9ca346 Mon Sep 17 00:00:00 2001 From: Suraj Gupta Date: Wed, 22 Oct 2025 02:30:06 +0800 Subject: [PATCH 1021/1449] dmaengine: xilinx_dma: Fix uninitialized addr_width when "xlnx,addrwidth" property is missing ANBZ: #35228 commit 0fd2001907fea63da79819bfdbf033d71fe69922 stable. commit c0732fe78728718c853ef8e7af5bbb05262acbd1 upstream. When device tree lacks optional "xlnx,addrwidth" property, the addr_width variable remained uninitialized with garbage values, causing incorrect DMA mask configuration and subsequent probe failure. The fix ensures a fallback to the default 32-bit address width when this property is missing. Signed-off-by: Suraj Gupta Fixes: b72db4005fe4 ("dmaengine: vdma: Add 64 bit addressing support to the driver") Reviewed-by: Radhey Shyam Pandey Reviewed-by: Folker Schwesinger Link: https://patch.msgid.link/20251021183006.3434495-1-suraj.gupta2@amd.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/xilinx/xilinx_dma.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 14c4c5031b55..176cac3f37a7 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -128,6 +128,7 @@ #define XILINX_MCDMA_MAX_CHANS_PER_DEVICE 0x20 #define XILINX_DMA_MAX_CHANS_PER_DEVICE 0x2 #define XILINX_CDMA_MAX_CHANS_PER_DEVICE 0x1 +#define XILINX_DMA_DFAULT_ADDRWIDTH 0x20 #define XILINX_DMA_DMAXR_ALL_IRQ_MASK \ (XILINX_DMA_DMASR_FRM_CNT_IRQ | \ @@ -3057,7 +3058,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; struct xilinx_dma_device *xdev; struct device_node *child, *np = pdev->dev.of_node; - u32 num_frames, addr_width, len_width; + u32 num_frames, addr_width = XILINX_DMA_DFAULT_ADDRWIDTH, len_width; int i, err; /* Allocate and initialize the DMA engine structure */ @@ -3131,7 +3132,9 @@ static int xilinx_dma_probe(struct platform_device *pdev) err = of_property_read_u32(node, "xlnx,addrwidth", &addr_width); if (err < 0) - dev_warn(xdev->dev, "missing xlnx,addrwidth property\n"); + dev_warn(xdev->dev, + "missing xlnx,addrwidth property, using default value %d\n", + XILINX_DMA_DFAULT_ADDRWIDTH); if (addr_width > 32) xdev->ext_addr = true; -- Gitee From 9fe9d0626599842fac4fe42b5586cc03016da433 Mon Sep 17 00:00:00 2001 From: Stefano Radaelli Date: Sat, 20 Dec 2025 00:09:12 +0800 Subject: [PATCH 1022/1449] phy: fsl-imx8mq-usb: Clear the PCS_TX_SWING_FULL field before using it ANBZ: #35228 commit 0b347b180ad5eb3babfb6713e954184da0b2bbd0 stable. commit 8becf9179a4b45104a1701010ed666b55bf4b3a6 upstream. Clear the PCS_TX_SWING_FULL field mask before setting the new value in PHY_CTRL5 register. Without clearing the mask first, the OR operation could leave previously set bits, resulting in incorrect register configuration. Fixes: 63c85ad0cd81 ("phy: fsl-imx8mp-usb: add support for phy tuning") Suggested-by: Leonid Segal Acked-by: Pierluigi Passaro Signed-off-by: Stefano Radaelli Reviewed-by: Xu Yang Reviewed-by: Frank Li Reviewed-by: Fabio Estevam Reviewed-by: Ahmad Fatoum Link: https://patch.msgid.link/20251219160912.561431-1-stefano.r@variscite.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c index f914f016b3d2..043063699e06 100644 --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c @@ -206,6 +206,7 @@ static void imx8m_phy_tune(struct imx8mq_usb_phy *imx_phy) if (imx_phy->pcs_tx_swing_full != PHY_TUNE_DEFAULT) { value = readl(imx_phy->base + PHY_CTRL5); + value &= ~PHY_CTRL5_PCS_TX_SWING_FULL_MASK; value |= FIELD_PREP(PHY_CTRL5_PCS_TX_SWING_FULL_MASK, imx_phy->pcs_tx_swing_full); writel(value, imx_phy->base + PHY_CTRL5); -- Gitee From 6a4cc0af8e008d516b830785bdd4d6bc26a0a8d8 Mon Sep 17 00:00:00 2001 From: Ivaylo Ivanov Date: Sun, 4 May 2025 22:45:21 +0800 Subject: [PATCH 1023/1449] phy: phy-snps-eusb2: refactor constructs names ANBZ: #35228 commit 7070ed66aba3bc8aee0225b6f619608b48f8e610 stable. commit 93dbe9b5b3a265c7e5466c7b6ada439b01577de5 upstream. As the driver now resides outside the phy subdirectory under a different name, refactor all definitions, structures and functions to explicitly specify what code is Qualcomm-specific and what is not. Signed-off-by: Ivaylo Ivanov Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250504144527.1723980-5-ivo.ivanov.ivanov1@gmail.com Signed-off-by: Vinod Koul Stable-dep-of: 1ca52c0983c3 ("phy: qcom-qusb2: Fix NULL pointer dereference on early suspend") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/qualcomm/phy-qcom-snps-eusb2.c | 256 ++++++++++----------- 1 file changed, 128 insertions(+), 128 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c index 1484691a41d5..e1b175f481b4 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c @@ -13,15 +13,15 @@ #include #include -#define USB_PHY_UTMI_CTRL0 (0x3c) +#define QCOM_USB_PHY_UTMI_CTRL0 (0x3c) #define SLEEPM BIT(0) #define OPMODE_MASK GENMASK(4, 3) #define OPMODE_NONDRIVING BIT(3) -#define USB_PHY_UTMI_CTRL5 (0x50) +#define QCOM_USB_PHY_UTMI_CTRL5 (0x50) #define POR BIT(1) -#define USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) +#define QCOM_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) #define PHY_ENABLE BIT(0) #define SIDDQ_SEL BIT(1) #define SIDDQ BIT(2) @@ -30,15 +30,15 @@ #define FSEL_19_2_MHZ_VAL (0x0) #define FSEL_38_4_MHZ_VAL (0x4) -#define USB_PHY_CFG_CTRL_1 (0x58) +#define QCOM_USB_PHY_CFG_CTRL_1 (0x58) #define PHY_CFG_PLL_CPBIAS_CNTRL_MASK GENMASK(7, 1) -#define USB_PHY_CFG_CTRL_2 (0x5c) +#define QCOM_USB_PHY_CFG_CTRL_2 (0x5c) #define PHY_CFG_PLL_FB_DIV_7_0_MASK GENMASK(7, 0) #define DIV_7_0_19_2_MHZ_VAL (0x90) #define DIV_7_0_38_4_MHZ_VAL (0xc8) -#define USB_PHY_CFG_CTRL_3 (0x60) +#define QCOM_USB_PHY_CFG_CTRL_3 (0x60) #define PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(3, 0) #define DIV_11_8_19_2_MHZ_VAL (0x1) #define DIV_11_8_38_4_MHZ_VAL (0x0) @@ -46,73 +46,73 @@ #define PHY_CFG_PLL_REF_DIV GENMASK(7, 4) #define PLL_REF_DIV_VAL (0x0) -#define USB_PHY_HS_PHY_CTRL2 (0x64) +#define QCOM_USB_PHY_HS_PHY_CTRL2 (0x64) #define VBUSVLDEXT0 BIT(0) #define USB2_SUSPEND_N BIT(2) #define USB2_SUSPEND_N_SEL BIT(3) #define VBUS_DET_EXT_SEL BIT(4) -#define USB_PHY_CFG_CTRL_4 (0x68) +#define QCOM_USB_PHY_CFG_CTRL_4 (0x68) #define PHY_CFG_PLL_GMP_CNTRL_MASK GENMASK(1, 0) #define PHY_CFG_PLL_INT_CNTRL_MASK GENMASK(7, 2) -#define USB_PHY_CFG_CTRL_5 (0x6c) +#define QCOM_USB_PHY_CFG_CTRL_5 (0x6c) #define PHY_CFG_PLL_PROP_CNTRL_MASK GENMASK(4, 0) #define PHY_CFG_PLL_VREF_TUNE_MASK GENMASK(7, 6) -#define USB_PHY_CFG_CTRL_6 (0x70) +#define QCOM_USB_PHY_CFG_CTRL_6 (0x70) #define PHY_CFG_PLL_VCO_CNTRL_MASK GENMASK(2, 0) -#define USB_PHY_CFG_CTRL_7 (0x74) +#define QCOM_USB_PHY_CFG_CTRL_7 (0x74) -#define USB_PHY_CFG_CTRL_8 (0x78) +#define QCOM_USB_PHY_CFG_CTRL_8 (0x78) #define PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(1, 0) #define PHY_CFG_TX_FSLS_VREG_BYPASS BIT(2) #define PHY_CFG_TX_HS_VREF_TUNE_MASK GENMASK(5, 3) #define PHY_CFG_TX_HS_XV_TUNE_MASK GENMASK(7, 6) -#define USB_PHY_CFG_CTRL_9 (0x7c) +#define QCOM_USB_PHY_CFG_CTRL_9 (0x7c) #define PHY_CFG_TX_PREEMP_TUNE_MASK GENMASK(2, 0) #define PHY_CFG_TX_RES_TUNE_MASK GENMASK(4, 3) #define PHY_CFG_TX_RISE_TUNE_MASK GENMASK(6, 5) #define PHY_CFG_RCAL_BYPASS BIT(7) -#define USB_PHY_CFG_CTRL_10 (0x80) +#define QCOM_USB_PHY_CFG_CTRL_10 (0x80) -#define USB_PHY_CFG0 (0x94) +#define QCOM_USB_PHY_CFG0 (0x94) #define DATAPATH_CTRL_OVERRIDE_EN BIT(0) #define CMN_CTRL_OVERRIDE_EN BIT(1) -#define UTMI_PHY_CMN_CTRL0 (0x98) +#define QCOM_UTMI_PHY_CMN_CTRL0 (0x98) #define TESTBURNIN BIT(6) -#define USB_PHY_FSEL_SEL (0xb8) +#define QCOM_USB_PHY_FSEL_SEL (0xb8) #define FSEL_SEL BIT(0) -#define USB_PHY_APB_ACCESS_CMD (0x130) +#define QCOM_USB_PHY_APB_ACCESS_CMD (0x130) #define RW_ACCESS BIT(0) #define APB_START_CMD BIT(1) #define APB_LOGIC_RESET BIT(2) -#define USB_PHY_APB_ACCESS_STATUS (0x134) +#define QCOM_USB_PHY_APB_ACCESS_STATUS (0x134) #define ACCESS_DONE BIT(0) #define TIMED_OUT BIT(1) #define ACCESS_ERROR BIT(2) #define ACCESS_IN_PROGRESS BIT(3) -#define USB_PHY_APB_ADDRESS (0x138) +#define QCOM_USB_PHY_APB_ADDRESS (0x138) #define APB_REG_ADDR_MASK GENMASK(7, 0) -#define USB_PHY_APB_WRDATA_LSB (0x13c) +#define QCOM_USB_PHY_APB_WRDATA_LSB (0x13c) #define APB_REG_WRDATA_7_0_MASK GENMASK(3, 0) -#define USB_PHY_APB_WRDATA_MSB (0x140) +#define QCOM_USB_PHY_APB_WRDATA_MSB (0x140) #define APB_REG_WRDATA_15_8_MASK GENMASK(7, 4) -#define USB_PHY_APB_RDDATA_LSB (0x144) +#define QCOM_USB_PHY_APB_RDDATA_LSB (0x144) #define APB_REG_RDDATA_7_0_MASK GENMASK(3, 0) -#define USB_PHY_APB_RDDATA_MSB (0x148) +#define QCOM_USB_PHY_APB_RDDATA_MSB (0x148) #define APB_REG_RDDATA_15_8_MASK GENMASK(7, 4) static const char * const eusb2_hsphy_vreg_names[] = { @@ -121,7 +121,7 @@ static const char * const eusb2_hsphy_vreg_names[] = { #define EUSB2_NUM_VREGS ARRAY_SIZE(eusb2_hsphy_vreg_names) -struct qcom_snps_eusb2_hsphy { +struct snps_eusb2_hsphy { struct phy *phy; void __iomem *base; @@ -135,17 +135,17 @@ struct qcom_snps_eusb2_hsphy { struct phy *repeater; }; -static int qcom_snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode) +static int snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode) { - struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p); + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); phy->mode = mode; return phy_set_mode_ext(phy->repeater, mode, submode); } -static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset, - u32 mask, u32 val) +static void snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset, + u32 mask, u32 val) { u32 reg; @@ -158,65 +158,65 @@ static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset, readl_relaxed(base + offset); } -static void qcom_eusb2_default_parameters(struct qcom_snps_eusb2_hsphy *phy) +static void qcom_eusb2_default_parameters(struct snps_eusb2_hsphy *phy) { /* default parameters: tx pre-emphasis */ - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9, - PHY_CFG_TX_PREEMP_TUNE_MASK, - FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9, + PHY_CFG_TX_PREEMP_TUNE_MASK, + FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0)); /* tx rise/fall time */ - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9, - PHY_CFG_TX_RISE_TUNE_MASK, - FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9, + PHY_CFG_TX_RISE_TUNE_MASK, + FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2)); /* source impedance adjustment */ - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9, - PHY_CFG_TX_RES_TUNE_MASK, - FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9, + PHY_CFG_TX_RES_TUNE_MASK, + FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1)); /* dc voltage level adjustement */ - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8, - PHY_CFG_TX_HS_VREF_TUNE_MASK, - FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8, + PHY_CFG_TX_HS_VREF_TUNE_MASK, + FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3)); /* transmitter HS crossover adjustement */ - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8, - PHY_CFG_TX_HS_XV_TUNE_MASK, - FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8, + PHY_CFG_TX_HS_XV_TUNE_MASK, + FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0)); } -static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy) +static int qcom_eusb2_ref_clk_init(struct snps_eusb2_hsphy *phy) { unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk); switch (ref_clk_freq) { case 19200000: - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, - FSEL_MASK, - FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, + FSEL_MASK, + FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2, - PHY_CFG_PLL_FB_DIV_7_0_MASK, - DIV_7_0_19_2_MHZ_VAL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_2, + PHY_CFG_PLL_FB_DIV_7_0_MASK, + DIV_7_0_19_2_MHZ_VAL); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3, - PHY_CFG_PLL_FB_DIV_11_8_MASK, - DIV_11_8_19_2_MHZ_VAL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3, + PHY_CFG_PLL_FB_DIV_11_8_MASK, + DIV_11_8_19_2_MHZ_VAL); break; case 38400000: - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, - FSEL_MASK, - FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, + FSEL_MASK, + FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2, - PHY_CFG_PLL_FB_DIV_7_0_MASK, - DIV_7_0_38_4_MHZ_VAL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_2, + PHY_CFG_PLL_FB_DIV_7_0_MASK, + DIV_7_0_38_4_MHZ_VAL); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3, - PHY_CFG_PLL_FB_DIV_11_8_MASK, - DIV_11_8_38_4_MHZ_VAL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3, + PHY_CFG_PLL_FB_DIV_11_8_MASK, + DIV_11_8_38_4_MHZ_VAL); break; default: @@ -224,15 +224,15 @@ static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy) return -EINVAL; } - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3, - PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3, + PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL); return 0; } -static int qcom_snps_eusb2_hsphy_init(struct phy *p) +static int snps_eusb2_hsphy_init(struct phy *p) { - struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p); + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); int ret; ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs); @@ -265,73 +265,73 @@ static int qcom_snps_eusb2_hsphy_init(struct phy *p) goto disable_ref_clk; } - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG0, - CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG0, + CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, POR); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, POR); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, - PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, + PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_APB_ACCESS_CMD, - APB_LOGIC_RESET, APB_LOGIC_RESET); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_APB_ACCESS_CMD, + APB_LOGIC_RESET, APB_LOGIC_RESET); - qcom_snps_eusb2_hsphy_write_mask(phy->base, UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_FSEL_SEL, - FSEL_SEL, FSEL_SEL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_FSEL_SEL, + FSEL_SEL, FSEL_SEL); /* update ref_clk related registers */ ret = qcom_eusb2_ref_clk_init(phy); if (ret) - goto disable_ref_clk; + return ret; - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_1, - PHY_CFG_PLL_CPBIAS_CNTRL_MASK, - FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_1, + PHY_CFG_PLL_CPBIAS_CNTRL_MASK, + FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4, - PHY_CFG_PLL_INT_CNTRL_MASK, - FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4, + PHY_CFG_PLL_INT_CNTRL_MASK, + FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4, - PHY_CFG_PLL_GMP_CNTRL_MASK, - FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4, + PHY_CFG_PLL_GMP_CNTRL_MASK, + FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5, - PHY_CFG_PLL_PROP_CNTRL_MASK, - FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5, + PHY_CFG_PLL_PROP_CNTRL_MASK, + FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_6, - PHY_CFG_PLL_VCO_CNTRL_MASK, - FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_6, + PHY_CFG_PLL_VCO_CNTRL_MASK, + FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5, - PHY_CFG_PLL_VREF_TUNE_MASK, - FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1)); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5, + PHY_CFG_PLL_VREF_TUNE_MASK, + FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1)); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2, - VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2, + VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL); /* set default parameters */ qcom_eusb2_default_parameters(phy); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2, - USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, - USB2_SUSPEND_N_SEL | USB2_SUSPEND_N); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2, + USB2_SUSPEND_N_SEL | USB2_SUSPEND_N, + USB2_SUSPEND_N_SEL | USB2_SUSPEND_N); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, - SIDDQ_SEL, SIDDQ_SEL); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, + SIDDQ_SEL, SIDDQ_SEL); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0, - SIDDQ, 0); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0, + SIDDQ, 0); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, 0); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, 0); - qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2, - USB2_SUSPEND_N_SEL, 0); + snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2, + USB2_SUSPEND_N_SEL, 0); return 0; @@ -344,9 +344,9 @@ static int qcom_snps_eusb2_hsphy_init(struct phy *p) return ret; } -static int qcom_snps_eusb2_hsphy_exit(struct phy *p) +static int snps_eusb2_hsphy_exit(struct phy *p) { - struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p); + struct snps_eusb2_hsphy *phy = phy_get_drvdata(p); clk_disable_unprepare(phy->ref_clk); @@ -357,18 +357,18 @@ static int qcom_snps_eusb2_hsphy_exit(struct phy *p) return 0; } -static const struct phy_ops qcom_snps_eusb2_hsphy_ops = { - .init = qcom_snps_eusb2_hsphy_init, - .exit = qcom_snps_eusb2_hsphy_exit, - .set_mode = qcom_snps_eusb2_hsphy_set_mode, +static const struct phy_ops snps_eusb2_hsphy_ops = { + .init = snps_eusb2_hsphy_init, + .exit = snps_eusb2_hsphy_exit, + .set_mode = snps_eusb2_hsphy_set_mode, .owner = THIS_MODULE, }; -static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev) +static int snps_eusb2_hsphy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - struct qcom_snps_eusb2_hsphy *phy; + struct snps_eusb2_hsphy *phy; struct phy_provider *phy_provider; struct phy *generic_phy; int ret, i; @@ -405,7 +405,7 @@ static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(phy->repeater), "failed to get repeater\n"); - generic_phy = devm_phy_create(dev, NULL, &qcom_snps_eusb2_hsphy_ops); + generic_phy = devm_phy_create(dev, NULL, &snps_eusb2_hsphy_ops); if (IS_ERR(generic_phy)) { dev_err(dev, "failed to create phy %d\n", ret); return PTR_ERR(generic_phy); @@ -418,25 +418,25 @@ static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - dev_info(dev, "Registered Qcom-eUSB2 phy\n"); + dev_info(dev, "Registered Snps-eUSB2 phy\n"); return 0; } -static const struct of_device_id qcom_snps_eusb2_hsphy_of_match_table[] = { +static const struct of_device_id snps_eusb2_hsphy_of_match_table[] = { { .compatible = "qcom,sm8550-snps-eusb2-phy", }, { }, }; -MODULE_DEVICE_TABLE(of, qcom_snps_eusb2_hsphy_of_match_table); +MODULE_DEVICE_TABLE(of, snps_eusb2_hsphy_of_match_table); -static struct platform_driver qcom_snps_eusb2_hsphy_driver = { - .probe = qcom_snps_eusb2_hsphy_probe, +static struct platform_driver snps_eusb2_hsphy_driver = { + .probe = snps_eusb2_hsphy_probe, .driver = { - .name = "qcom-snps-eusb2-hsphy", - .of_match_table = qcom_snps_eusb2_hsphy_of_match_table, + .name = "snps-eusb2-hsphy", + .of_match_table = snps_eusb2_hsphy_of_match_table, }, }; -module_platform_driver(qcom_snps_eusb2_hsphy_driver); -MODULE_DESCRIPTION("Qualcomm SNPS eUSB2 HS PHY driver"); +module_platform_driver(snps_eusb2_hsphy_driver); +MODULE_DESCRIPTION("Synopsys eUSB2 HS PHY driver"); MODULE_LICENSE("GPL"); -- Gitee From 85456b58d917686c6eecee0b5c4e0b1fa3a3f975 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 23 May 2025 16:51:12 +0800 Subject: [PATCH 1024/1449] phy: drop probe registration printks ANBZ: #35228 commit 8151ecaaf08e37801ec5553dbd54ad6093ae9c35 stable. commit 95463cbb4fe6489921fb8c72890113dca54ce83f upstream. Drivers should generally be quiet on successful probe, but this is not followed by some PHY drivers, for example: snps-eusb2-hsphy 88e1000.phy: Registered Snps-eUSB2 phy qcom-eusb2-repeater c432000.spmi:pmic@7:phy@fd00: Registered Qcom-eUSB2 repeater qcom-eusb2-repeater c432000.spmi:pmic@a:phy@fd00: Registered Qcom-eUSB2 repeater qcom-eusb2-repeater c432000.spmi:pmic@b:phy@fd00: Registered Qcom-eUSB2 repeater snps-eusb2-hsphy fd3000.phy: Registered Snps-eUSB2 phy snps-eusb2-hsphy fd9000.phy: Registered Snps-eUSB2 phy snps-eusb2-hsphy fde000.phy: Registered Snps-eUSB2 phy snps-eusb2-hsphy 88e0000.phy: Registered Snps-eUSB2 phy snps-eusb2-hsphy 88e2000.phy: Registered Snps-eUSB2 phy Drop (or demote to debug level) unnecessary registration info messages to make boot logs a little less noisy. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20250523085112.11287-1-johan+linaro@kernel.org Signed-off-by: Vinod Koul Stable-dep-of: 1ca52c0983c3 ("phy: qcom-qusb2: Fix NULL pointer dereference on early suspend") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/broadcom/phy-bcm-ns2-pcie.c | 2 -- drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c | 1 - drivers/phy/broadcom/phy-bcm-sr-pcie.c | 2 -- drivers/phy/broadcom/phy-brcm-sata.c | 2 +- drivers/phy/marvell/phy-pxa-usb.c | 1 - drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c | 2 -- drivers/phy/qualcomm/phy-qcom-m31.c | 2 -- drivers/phy/qualcomm/phy-qcom-qusb2.c | 4 +--- drivers/phy/qualcomm/phy-qcom-snps-eusb2.c | 2 -- drivers/phy/st/phy-stih407-usb.c | 2 -- drivers/phy/st/phy-stm32-usbphyc.c | 4 ++-- drivers/phy/ti/phy-twl4030-usb.c | 1 - 12 files changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/phy/broadcom/phy-bcm-ns2-pcie.c b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c index 2eaa41f8fc70..67a6ae5ecba0 100644 --- a/drivers/phy/broadcom/phy-bcm-ns2-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c @@ -61,8 +61,6 @@ static int ns2_pci_phy_probe(struct mdio_device *mdiodev) return PTR_ERR(provider); } - dev_info(dev, "%s PHY registered\n", dev_name(dev)); - return 0; } diff --git a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c index 36ad02c33ac5..8473fa574529 100644 --- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c +++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c @@ -395,7 +395,6 @@ static int ns2_drd_phy_probe(struct platform_device *pdev) platform_set_drvdata(pdev, driver); - dev_info(dev, "Registered NS2 DRD Phy device\n"); queue_delayed_work(system_power_efficient_wq, &driver->wq_extcon, driver->debounce_jiffies); diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c b/drivers/phy/broadcom/phy-bcm-sr-pcie.c index 8a4aadf166cf..c85af6508677 100644 --- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c @@ -277,8 +277,6 @@ static int sr_pcie_phy_probe(struct platform_device *pdev) return PTR_ERR(provider); } - dev_info(dev, "Stingray PCIe PHY driver initialized\n"); - return 0; } diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index ed9e18791ec9..6838cb76e826 100644 --- a/drivers/phy/broadcom/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c @@ -836,7 +836,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) return PTR_ERR(provider); } - dev_info(dev, "registered %d port(s)\n", count); + dev_dbg(dev, "registered %d port(s)\n", count); return 0; put_child: diff --git a/drivers/phy/marvell/phy-pxa-usb.c b/drivers/phy/marvell/phy-pxa-usb.c index 6c98eb9608e9..c0bb71f80c04 100644 --- a/drivers/phy/marvell/phy-pxa-usb.c +++ b/drivers/phy/marvell/phy-pxa-usb.c @@ -325,7 +325,6 @@ static int pxa_usb_phy_probe(struct platform_device *pdev) phy_create_lookup(pxa_usb_phy->phy, "usb", "mv-otg"); } - dev_info(dev, "Marvell PXA USB PHY"); return 0; } diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c index a43e20abb10d..ad7bf049d726 100644 --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c @@ -251,8 +251,6 @@ static int eusb2_repeater_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - dev_info(dev, "Registered Qcom-eUSB2 repeater\n"); - return 0; } diff --git a/drivers/phy/qualcomm/phy-qcom-m31.c b/drivers/phy/qualcomm/phy-qcom-m31.c index a5e60039a264..116cfa6ddac6 100644 --- a/drivers/phy/qualcomm/phy-qcom-m31.c +++ b/drivers/phy/qualcomm/phy-qcom-m31.c @@ -267,8 +267,6 @@ static int m31usb_phy_probe(struct platform_device *pdev) phy_set_drvdata(qphy->phy, qphy); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (!IS_ERR(phy_provider)) - dev_info(dev, "Registered M31 USB phy\n"); return PTR_ERR_OR_ZERO(phy_provider); } diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index c52655a383ce..531c3860c316 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -1084,9 +1084,7 @@ static int qusb2_phy_probe(struct platform_device *pdev) phy_set_drvdata(generic_phy, qphy); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (!IS_ERR(phy_provider)) - dev_info(dev, "Registered Qcom-QUSB2 phy\n"); - else + if (IS_ERR(phy_provider)) pm_runtime_disable(dev); return PTR_ERR_OR_ZERO(phy_provider); diff --git a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c index e1b175f481b4..4a1dfef5ff8f 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c @@ -418,8 +418,6 @@ static int snps_eusb2_hsphy_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - dev_info(dev, "Registered Snps-eUSB2 phy\n"); - return 0; } diff --git a/drivers/phy/st/phy-stih407-usb.c b/drivers/phy/st/phy-stih407-usb.c index a4ae2cca7f63..02e6117709dc 100644 --- a/drivers/phy/st/phy-stih407-usb.c +++ b/drivers/phy/st/phy-stih407-usb.c @@ -149,8 +149,6 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev) if (IS_ERR(phy_provider)) return PTR_ERR(phy_provider); - dev_info(dev, "STiH407 USB Generic picoPHY driver probed!"); - return 0; } diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index d5e7e44000b5..f8374a7f3a65 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -757,8 +757,8 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) } version = readl_relaxed(usbphyc->base + STM32_USBPHYC_VERSION); - dev_info(dev, "registered rev:%lu.%lu\n", - FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version)); + dev_dbg(dev, "registered rev: %lu.%lu\n", + FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version)); return 0; diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c index 6b265992d988..e5918d3b486c 100644 --- a/drivers/phy/ti/phy-twl4030-usb.c +++ b/drivers/phy/ti/phy-twl4030-usb.c @@ -784,7 +784,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(twl->dev); - dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); return 0; } -- Gitee From 8b93c24fd1bceb94d609b251b30b249a37d64016 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Fri, 19 Dec 2025 16:56:40 +0800 Subject: [PATCH 1025/1449] phy: qcom-qusb2: Fix NULL pointer dereference on early suspend ANBZ: #35228 commit beba460a299150b5d8dcbe3474a8f4bdf0205180 stable. commit 1ca52c0983c34fca506921791202ed5bdafd5306 upstream. Enabling runtime PM before attaching the QPHY instance as driver data can lead to a NULL pointer dereference in runtime PM callbacks that expect valid driver data. There is a small window where the suspend callback may run after PM runtime enabling and before runtime forbid. This causes a sporadic crash during boot: ``` Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a1 [...] CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 6.16.7+ #116 PREEMPT Workqueue: pm pm_runtime_work pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : qusb2_phy_runtime_suspend+0x14/0x1e0 [phy_qcom_qusb2] lr : pm_generic_runtime_suspend+0x2c/0x44 [...] ``` Attach the QPHY instance as driver data before enabling runtime PM to prevent NULL pointer dereference in runtime PM callbacks. Reorder pm_runtime_enable() and pm_runtime_forbid() to prevent a short window where an unnecessary runtime suspend can occur. Use the devres-managed version to ensure PM runtime is symmetrically disabled during driver removal for proper cleanup. Fixes: 891a96f65ac3 ("phy: qcom-qusb2: Add support for runtime PM") Signed-off-by: Loic Poulain Reviewed-by: Dmitry Baryshkov Reviewed-by: Abel Vesa Link: https://patch.msgid.link/20251219085640.114473-1-loic.poulain@oss.qualcomm.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 531c3860c316..d3c26a39873f 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -1063,29 +1063,29 @@ static int qusb2_phy_probe(struct platform_device *pdev) or->hsdisc_trim.override = true; } - pm_runtime_set_active(dev); - pm_runtime_enable(dev); + dev_set_drvdata(dev, qphy); + /* - * Prevent runtime pm from being ON by default. Users can enable - * it using power/control in sysfs. + * Enable runtime PM support, but forbid it by default. + * Users can allow it again via the power/control attribute in sysfs. */ + pm_runtime_set_active(dev); pm_runtime_forbid(dev); + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; generic_phy = devm_phy_create(dev, NULL, &qusb2_phy_gen_ops); if (IS_ERR(generic_phy)) { ret = PTR_ERR(generic_phy); dev_err(dev, "failed to create phy, %d\n", ret); - pm_runtime_disable(dev); return ret; } qphy->phy = generic_phy; - dev_set_drvdata(dev, qphy); phy_set_drvdata(generic_phy, qphy); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - pm_runtime_disable(dev); return PTR_ERR_OR_ZERO(phy_provider); } -- Gitee From 089d1a546cd061cf1d6b4fc17a6cfce5683ec914 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 9 Dec 2025 14:53:36 +0800 Subject: [PATCH 1026/1449] phy: stm32-usphyc: Fix off by one in probe() ANBZ: #35228 commit 76b870fdaad82171a24b8aacffe5e4d9e0d2ee2c stable. commit cabd25b57216ddc132efbcc31f972baa03aad15a upstream. The "index" variable is used as an index into the usbphyc->phys[] array which has usbphyc->nphys elements. So if it is equal to usbphyc->nphys then it is one element out of bounds. The "index" comes from the device tree so it's data that we trust and it's unlikely to be wrong, however it's obviously still worth fixing the bug. Change the > to >=. Fixes: 94c358da3a05 ("phy: stm32: add support for STM32 USB PHY Controller (USBPHYC)") Signed-off-by: Dan Carpenter Reviewed-by: Amelie Delaunay Link: https://patch.msgid.link/aTfHcMJK1wFVnvEe@stanley.mountain Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/st/phy-stm32-usbphyc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index f8374a7f3a65..4a8f2ab65571 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -712,7 +712,7 @@ static int stm32_usbphyc_probe(struct platform_device *pdev) } ret = of_property_read_u32(child, "reg", &index); - if (ret || index > usbphyc->nphys) { + if (ret || index >= usbphyc->nphys) { dev_err(&phy->dev, "invalid reg property: %d\n", ret); if (!ret) ret = -EINVAL; -- Gitee From 84442d3267c553675c16fdd9d8b0875e92507ef1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 24 Dec 2025 19:55:34 +0800 Subject: [PATCH 1027/1449] phy: broadcom: ns-usb3: Fix Wvoid-pointer-to-enum-cast warning (again) ANBZ: #35228 commit 2a7ddafac3820e299c892d0c90d1fee3e929c207 stable. commit fb21116099bbea1fc59efa9207e63c4be390ab72 upstream. "family" is an enum, thus cast of pointer on 64-bit compile test with clang W=1 causes: phy-bcm-ns-usb3.c:206:17: error: cast to smaller integer type 'enum bcm_ns_family' from 'const void *' [-Werror,-Wvoid-pointer-to-enum-cast] This was already fixed in commit bd6e74a2f0a0 ("phy: broadcom: ns-usb3: fix Wvoid-pointer-to-enum-cast warning") but then got bad in commit 21bf6fc47a1e ("phy: Use device_get_match_data()"). Note that after various discussions the preferred cast is via "unsigned long", not "uintptr_t". Fixes: 21bf6fc47a1e ("phy: Use device_get_match_data()") Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251224115533.154162-2-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/broadcom/phy-bcm-ns-usb3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb3.c b/drivers/phy/broadcom/phy-bcm-ns-usb3.c index 2c8b1b7dda5b..5c2710597df2 100644 --- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c @@ -203,7 +203,7 @@ static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev) usb3->dev = dev; usb3->mdiodev = mdiodev; - usb3->family = (enum bcm_ns_family)device_get_match_data(dev); + usb3->family = (unsigned long)device_get_match_data(dev); syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0); err = of_address_to_resource(syscon_np, 0, &res); -- Gitee From 369c74d176307d476f807a418d6583df4e1f519f Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Mon, 3 Nov 2025 15:30:18 +0800 Subject: [PATCH 1028/1449] dmaengine: omap-dma: fix dma_pool resource leak in error paths ANBZ: #35228 commit 88a9483f093bbb9263dcf21bc7fdb5132e5de88d stable. commit 2e1136acf8a8887c29f52e35a77b537309af321f upstream. The dma_pool created by dma_pool_create() is not destroyed when dma_async_device_register() or of_dma_controller_register() fails, causing a resource leak in the probe error paths. Add dma_pool_destroy() in both error paths to properly release the allocated dma_pool resource. Fixes: 7bedaa553760 ("dmaengine: add OMAP DMA engine driver") Signed-off-by: Haotian Zhang Link: https://patch.msgid.link/20251103073018.643-1-vulab@iscas.ac.cn Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/ti/omap-dma.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c index cf96cf915c0c..efc9093707e5 100644 --- a/drivers/dma/ti/omap-dma.c +++ b/drivers/dma/ti/omap-dma.c @@ -1809,6 +1809,8 @@ static int omap_dma_probe(struct platform_device *pdev) if (rc) { pr_warn("OMAP-DMA: failed to register slave DMA engine device: %d\n", rc); + if (od->ll123_supported) + dma_pool_destroy(od->desc_pool); omap_dma_free(od); return rc; } @@ -1824,6 +1826,8 @@ static int omap_dma_probe(struct platform_device *pdev) if (rc) { pr_warn("OMAP-DMA: failed to register DMA controller\n"); dma_async_device_unregister(&od->ddev); + if (od->ll123_supported) + dma_pool_destroy(od->desc_pool); omap_dma_free(od); } } -- Gitee From ec3f3f4c871e1797afe8f30b02852a1f07dd721d Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 30 Oct 2025 02:07:42 +0800 Subject: [PATCH 1029/1449] i2c: qcom-geni: make sure I2C hub controllers can't use SE DMA ANBZ: #35228 commit d66d8ad31057d4761ad10603e603508f917cbfe4 stable. commit c0c50e3743e467ec4752c638e10e97f89c8644e2 upstream. The I2C Hub controller is a simpler GENI I2C variant that doesn't support DMA at all, add a no_dma flag to make sure it nevers selects the SE DMA mode with mappable 32bytes long transfers. Fixes: cacd9643eca7 ("i2c: qcom-geni: add support for I2C Master Hub variant") Signed-off-by: Neil Armstrong Reviewed-by: Konrad Dybcio Reviewed-by: Mukesh Kumar Savaliya > Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/i2c/busses/i2c-qcom-geni.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 350f7827fbac..f6e46168571f 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -97,6 +97,7 @@ struct geni_i2c_dev { dma_addr_t dma_addr; struct dma_chan *tx_c; struct dma_chan *rx_c; + bool no_dma; bool gpi_mode; bool abort_done; }; @@ -411,7 +412,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, size_t len = msg->len; struct i2c_msg *cur; - dma_buf = i2c_get_dma_safe_msg_buf(msg, 32); + dma_buf = gi2c->no_dma ? NULL : i2c_get_dma_safe_msg_buf(msg, 32); if (dma_buf) geni_se_select_mode(se, GENI_SE_DMA); else @@ -450,7 +451,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, size_t len = msg->len; struct i2c_msg *cur; - dma_buf = i2c_get_dma_safe_msg_buf(msg, 32); + dma_buf = gi2c->no_dma ? NULL : i2c_get_dma_safe_msg_buf(msg, 32); if (dma_buf) geni_se_select_mode(se, GENI_SE_DMA); else @@ -866,10 +867,12 @@ static int geni_i2c_probe(struct platform_device *pdev) return -ENXIO; } - if (desc && desc->no_dma_support) + if (desc && desc->no_dma_support) { fifo_disable = false; - else + gi2c->no_dma = true; + } else { fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; + } if (fifo_disable) { /* FIFO is disabled, so we can only use GPI DMA */ -- Gitee From 7f30b8c7bd863ab5c58de7d3dbf80dc505f1ead8 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 15 Dec 2025 19:57:21 +0800 Subject: [PATCH 1030/1449] HID: usbhid: paper over wrong bNumDescriptor field ANBZ: #35228 commit d64557b61c1dd3d994184ef2a80cb9881e8f05bd stable. commit f28beb69c51517aec7067dfb2074e7c751542384 upstream. Some faulty devices (ZWO EFWmini) have a wrong optional HID class descriptor count compared to the provided length. Given that we plainly ignore those optional descriptor, we can attempt to fix the provided number so we do not lock out those devices. Signed-off-by: Benjamin Tissoires Cc: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/usbhid/hid-core.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index a8e8da002b9b..5e3bd615066c 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -983,6 +983,7 @@ static int usbhid_parse(struct hid_device *hid) struct usb_device *dev = interface_to_usbdev (intf); struct hid_descriptor *hdesc; struct hid_class_descriptor *hcdesc; + __u8 fixed_opt_descriptors_size; u32 quirks = 0; unsigned int rsize = 0; char *rdesc; @@ -1013,7 +1014,21 @@ static int usbhid_parse(struct hid_device *hid) (hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) { dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n", hdesc->bLength, hdesc->bNumDescriptors); - return -EINVAL; + + /* + * Some devices may expose a wrong number of descriptors compared + * to the provided length. + * However, we ignore the optional hid class descriptors entirely + * so we can safely recompute the proper field. + */ + if (hdesc->bLength >= sizeof(*hdesc)) { + fixed_opt_descriptors_size = hdesc->bLength - sizeof(*hdesc); + + hid_warn(intf, "fixing wrong optional hid class descriptors count\n"); + hdesc->bNumDescriptors = fixed_opt_descriptors_size / sizeof(*hcdesc) + 1; + } else { + return -EINVAL; + } } hid->version = le16_to_cpu(hdesc->bcdHID); -- Gitee From e9160d1c56d97eb69efa3eb6e1d54fc95ffa173d Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 4 Jun 2025 08:30:55 +0800 Subject: [PATCH 1031/1449] drm/amd/display: Check dce_hwseq before dereferencing it ANBZ: #35228 commit 60e450eec5d63113c6ad5c456ce64c12b4496a6e stable. commit b669507b637eb6b1aaecf347f193efccc65d756e upstream. [WHAT] hws was checked for null earlier in dce110_blank_stream, indicating hws can be null, and should be checked whenever it is used. Cc: Mario Limonciello Cc: Alex Deucher Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Hung Signed-off-by: Aurabindo Pillai Signed-off-by: Alex Deucher (cherry picked from commit 79db43611ff61280b6de58ce1305e0b2ecf675ad) Cc: stable@vger.kernel.org Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 0172fede51b5..14f5b4f00f72 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1228,7 +1228,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) struct dce_hwseq *hws = link->dc->hwseq; if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { - if (!link->skip_implict_edp_power_control) + if (!link->skip_implict_edp_power_control && hws) hws->funcs.edp_backlight_control(link, false); link->dc->hwss.set_abm_immediate_disable(pipe_ctx); } -- Gitee From 50de25e0973dd72e5bdba35ed7ed847d619233f4 Mon Sep 17 00:00:00 2001 From: Brian Kao Date: Thu, 18 Dec 2025 11:17:23 +0800 Subject: [PATCH 1032/1449] scsi: core: Fix error handler encryption support ANBZ: #35228 commit 8fab42516eb3cc37c0514f66e8ad91581bdef7a4 stable. commit 9a49157deeb23581fc5c8189b486340d7343264a upstream. Some low-level drivers (LLD) access block layer crypto fields, such as rq->crypt_keyslot and rq->crypt_ctx within `struct request`, to configure hardware for inline encryption. However, SCSI Error Handling (EH) commands (e.g., TEST UNIT READY, START STOP UNIT) should not involve any encryption setup. To prevent drivers from erroneously applying crypto settings during EH, this patch saves the original values of rq->crypt_keyslot and rq->crypt_ctx before an EH command is prepared via scsi_eh_prep_cmnd(). These fields in the 'struct request' are then set to NULL. The original values are restored in scsi_eh_restore_cmnd() after the EH command completes. This ensures that the block layer crypto context does not leak into EH command execution. Signed-off-by: Brian Kao Link: https://patch.msgid.link/20251218031726.2642834-1-powenkao@google.com Cc: stable@vger.kernel.org Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/scsi_error.c | 24 ++++++++++++++++++++++++ include/scsi/scsi_eh.h | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 43eff1107038..5882b5f80c04 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1039,6 +1039,9 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, unsigned char *cmnd, int cmnd_size, unsigned sense_bytes) { struct scsi_device *sdev = scmd->device; +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + struct request *rq = scsi_cmd_to_rq(scmd); +#endif /* * We need saved copies of a number of fields - this is because @@ -1090,6 +1093,18 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | (sdev->lun << 5 & 0xe0); + /* + * Encryption must be disabled for the commands submitted by the error handler. + * Hence, clear the encryption context information. + */ +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + ses->rq_crypt_keyslot = rq->crypt_keyslot; + ses->rq_crypt_ctx = rq->crypt_ctx; + + rq->crypt_keyslot = NULL; + rq->crypt_ctx = NULL; +#endif + /* * Zero the sense buffer. The scsi spec mandates that any * untransferred sense data should be interpreted as being zero. @@ -1107,6 +1122,10 @@ EXPORT_SYMBOL(scsi_eh_prep_cmnd); */ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) { +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + struct request *rq = scsi_cmd_to_rq(scmd); +#endif + /* * Restore original data */ @@ -1119,6 +1138,11 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) scmd->underflow = ses->underflow; scmd->prot_op = ses->prot_op; scmd->eh_eflags = ses->eh_eflags; + +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + rq->crypt_keyslot = ses->rq_crypt_keyslot; + rq->crypt_ctx = ses->rq_crypt_ctx; +#endif } EXPORT_SYMBOL(scsi_eh_restore_cmnd); diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 1ae08e81339f..15679be90c5c 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -41,6 +41,12 @@ struct scsi_eh_save { unsigned char cmnd[32]; struct scsi_data_buffer sdb; struct scatterlist sense_sgl; + + /* struct request fields */ +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + struct bio_crypt_ctx *rq_crypt_ctx; + struct blk_crypto_keyslot *rq_crypt_keyslot; +#endif }; extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, -- Gitee From 4bd0df9caab08b2b7e845ed1c0abead6a71bd67f Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 8 Jan 2026 05:36:42 +0800 Subject: [PATCH 1033/1449] ALSA: pcm: Improve the fix for race of buffer access at PCM OSS layer ANBZ: #35228 commit 2de6d3348937f344ff2496f3cac172e3d123ff36 stable. commit 47c27c9c9c720bc93fdc69605d0ecd9382e99047 upstream. Handle the error code from snd_pcm_buffer_access_lock() in snd_pcm_runtime_buffer_set_silence() function. Found by Alexandros Panagiotou Fixes: 93a81ca06577 ("ALSA: pcm: Fix race of buffer access at PCM OSS layer") Cc: stable@vger.kernel.org # 6.15 Signed-off-by: Jaroslav Kysela Link: https://patch.msgid.link/20260107213642.332954-1-perex@perex.cz Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/sound/pcm.h | 2 +- sound/core/oss/pcm_oss.c | 4 +++- sound/core/pcm_native.c | 9 +++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index ed4449cbdf80..911eeb19cc65 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1427,7 +1427,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s #define snd_pcm_lib_mmap_iomem NULL #endif -void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime); +int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime); /** * snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 471de2d1b37a..23ecbd70ccf6 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1085,7 +1085,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) runtime->oss.params = 0; runtime->oss.prepare = 1; runtime->oss.buffer_used = 0; - snd_pcm_runtime_buffer_set_silence(runtime); + err = snd_pcm_runtime_buffer_set_silence(runtime); + if (err < 0) + goto failure; runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size); diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index f37fd1e48740..23578307f126 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -705,13 +705,18 @@ static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime) } /* fill the PCM buffer with the current silence format; called from pcm_oss.c */ -void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime) +int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime) { - snd_pcm_buffer_access_lock(runtime); + int err; + + err = snd_pcm_buffer_access_lock(runtime); + if (err < 0) + return err; if (runtime->dma_area) snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes)); snd_pcm_buffer_access_unlock(runtime); + return 0; } EXPORT_SYMBOL_GPL(snd_pcm_runtime_buffer_set_silence); -- Gitee From e0858871ca6295106c686297b9c37b13e88c9bb7 Mon Sep 17 00:00:00 2001 From: Nilay Shroff Date: Tue, 13 Jan 2026 14:57:22 +0800 Subject: [PATCH 1034/1449] null_blk: fix kmemleak by releasing references to fault configfs items ANBZ: #35228 commit 1a3286edf4d48ce37f8982ff3c3b65159a5ecbb2 stable. commit 40b94ec7edbbb867c4e26a1a43d2b898f04b93c5 upstream. When CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION is enabled, the null-blk driver sets up fault injection support by creating the timeout_inject, requeue_inject, and init_hctx_fault_inject configfs items as children of the top-level nullbX configfs group. However, when the nullbX device is removed, the references taken to these fault-config configfs items are not released. As a result, kmemleak reports a memory leak, for example: unreferenced object 0xc00000021ff25c40 (size 32): comm "mkdir", pid 10665, jiffies 4322121578 hex dump (first 32 bytes): 69 6e 69 74 5f 68 63 74 78 5f 66 61 75 6c 74 5f init_hctx_fault_ 69 6e 6a 65 63 74 00 88 00 00 00 00 00 00 00 00 inject.......... backtrace (crc 1a018c86): __kmalloc_node_track_caller_noprof+0x494/0xbd8 kvasprintf+0x74/0xf4 config_item_set_name+0xf0/0x104 config_group_init_type_name+0x48/0xfc fault_config_init+0x48/0xf0 0xc0080000180559e4 configfs_mkdir+0x304/0x814 vfs_mkdir+0x49c/0x604 do_mkdirat+0x314/0x3d0 sys_mkdir+0xa0/0xd8 system_call_exception+0x1b0/0x4f0 system_call_vectored_common+0x15c/0x2ec Fix this by explicitly releasing the references to the fault-config configfs items when dropping the reference to the top-level nullbX configfs group. Cc: stable@vger.kernel.org Reviewed-by: Chaitanya Kulkarni Fixes: bb4c19e030f4 ("block: null_blk: make fault-injection dynamically configurable per device") Signed-off-by: Nilay Shroff Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/null_blk/main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 2dd254c720f5..355b23f3fc5d 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -622,12 +622,22 @@ static void nullb_add_fault_config(struct nullb_device *dev) configfs_add_default_group(&dev->init_hctx_fault_config.group, &dev->group); } +static void nullb_del_fault_config(struct nullb_device *dev) +{ + config_item_put(&dev->init_hctx_fault_config.group.cg_item); + config_item_put(&dev->requeue_config.group.cg_item); + config_item_put(&dev->timeout_config.group.cg_item); +} + #else static void nullb_add_fault_config(struct nullb_device *dev) { } +static void nullb_del_fault_config(struct nullb_device *dev) +{ +} #endif static struct @@ -659,7 +669,7 @@ nullb_group_drop_item(struct config_group *group, struct config_item *item) null_del_dev(dev->nullb); mutex_unlock(&lock); } - + nullb_del_fault_config(dev); config_item_put(item); } -- Gitee From 5127333fb6a1a64ad3e0f78f0bd9bb4fa8b25690 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 24 Dec 2025 04:21:39 +0800 Subject: [PATCH 1035/1449] can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak ANBZ: #35228 commit f905bcfa971edb89e398c98957838d8c6381c0c7 stable. commit 7352e1d5932a0e777e39fa4b619801191f57e603 upstream. In gs_can_open(), the URBs for USB-in transfers are allocated, added to the parent->rx_submitted anchor and submitted. In the complete callback gs_usb_receive_bulk_callback(), the URB is processed and resubmitted. In gs_can_close() the URBs are freed by calling usb_kill_anchored_urbs(parent->rx_submitted). However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in gs_can_close(). Fix the memory leak by anchoring the URB in the gs_usb_receive_bulk_callback() to the parent->rx_submitted anchor. Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260105-gs_usb-fix-memory-leak-v2-1-cc6ed6438034@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index a65526a71ce4..d3837252e505 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -748,6 +748,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) hf, parent->hf_size_rx, gs_usb_receive_bulk_callback, parent); + usb_anchor_urb(urb, &parent->rx_submitted); + rc = usb_submit_urb(urb, GFP_ATOMIC); /* USB failure take down all interfaces */ -- Gitee From 0788d1590344f265b97566a0684fa0a8e57cab5a Mon Sep 17 00:00:00 2001 From: Ondrej Ille Date: Mon, 5 Jan 2026 19:16:20 +0800 Subject: [PATCH 1036/1449] can: ctucanfd: fix SSP_SRC in cases when bit-rate is higher than 1 MBit. ANBZ: #35228 commit 58d236065ba65ef980b5779aab1e48f1ed655b78 stable. commit e707c591a139d1bfa4ddc83036fc820ca006a140 upstream. The Secondary Sample Point Source field has been set to an incorrect value by some mistake in the past 0b01 - SSP_SRC_NO_SSP - SSP is not used. for data bitrates above 1 MBit/s. The correct/default value already used for lower bitrates is 0b00 - SSP_SRC_MEAS_N_OFFSET - SSP position = TRV_DELAY (Measured Transmitter delay) + SSP_OFFSET. The related configuration register structure is described in section 3.1.46 SSP_CFG of the CTU CAN FD IP CORE Datasheet. The analysis leading to the proper configuration is described in section 2.8.3 Secondary sampling point of the datasheet. The change has been tested on AMD/Xilinx Zynq with the next CTU CN FD IP core versions: - 2.6 aka master in the "integration with Zynq-7000 system" test 6.12.43-rt12+ #1 SMP PREEMPT_RT kernel with CTU CAN FD git driver (change already included in the driver repo) - older 2.5 snapshot with mainline kernels with this patch applied locally in the multiple CAN latency tester nightly runs 6.18.0-rc4-rt3-dut #1 SMP PREEMPT_RT 6.19.0-rc3-dut The logs, the datasheet and sources are available at https://canbus.pages.fel.cvut.cz/ Signed-off-by: Ondrej Ille Signed-off-by: Pavel Pisa Link: https://patch.msgid.link/20260105111620.16580-1-pisa@fel.cvut.cz Fixes: 2dcb8e8782d8 ("can: ctucanfd: add support for CTU CAN FD open-source IP core - bus independent part.") Cc: stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/ctucanfd/ctucanfd_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c index f65c1a1e05cc..0d40564febee 100644 --- a/drivers/net/can/ctucanfd/ctucanfd_base.c +++ b/drivers/net/can/ctucanfd/ctucanfd_base.c @@ -310,7 +310,7 @@ static int ctucan_set_secondary_sample_point(struct net_device *ndev) } ssp_cfg = FIELD_PREP(REG_TRV_DELAY_SSP_OFFSET, ssp_offset); - ssp_cfg |= FIELD_PREP(REG_TRV_DELAY_SSP_SRC, 0x1); + ssp_cfg |= FIELD_PREP(REG_TRV_DELAY_SSP_SRC, 0x0); } ctucan_write32(priv, CTUCANFD_TRV_DELAY, ssp_cfg); -- Gitee From d9fee95327fe7326c2dffbeab4e75ec2017866ce Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 13 Jan 2026 23:28:47 +0800 Subject: [PATCH 1037/1449] net: can: j1939: j1939_xtp_rx_rts_session_active(): deactivate session upon receiving the second rts ANBZ: #35228 commit 809a437e27a3bf3c1c6c8c157773635552116f2b stable. commit 1809c82aa073a11b7d335ae932d81ce51a588a4a upstream. Since j1939_session_deactivate_activate_next() in j1939_tp_rxtimer() is called only when the timer is enabled, we need to call j1939_session_deactivate_activate_next() if we cancelled the timer. Otherwise, refcount for j1939_session leaks, which will later appear as | unregister_netdevice: waiting for vcan0 to become free. Usage count = 2. problem. Reported-by: syzbot Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 Signed-off-by: Tetsuo Handa Tested-by: Oleksij Rempel Acked-by: Oleksij Rempel Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") Link: https://patch.msgid.link/b1212653-8fa1-44e1-be9d-12f950fb3a07@I-love.SAKURA.ne.jp Cc: stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/can/j1939/transport.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 1186326b0f2e..6c37562a50f7 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -1699,8 +1699,16 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session, j1939_session_timers_cancel(session); j1939_session_cancel(session, J1939_XTP_ABORT_BUSY); - if (session->transmission) + if (session->transmission) { j1939_session_deactivate_activate_next(session); + } else if (session->state == J1939_SESSION_WAITING_ABORT) { + /* Force deactivation for the receiver. + * If we rely on the timer starting in j1939_session_cancel, + * a second RTS call here will cancel that timer and fail + * to restart it because the state is already WAITING_ABORT. + */ + j1939_session_deactivate_activate_next(session); + } return -EBUSY; } -- Gitee From 1edc4030f85abe4abb11bd58d112533916fb7d92 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 7 Nov 2025 07:13:50 +0800 Subject: [PATCH 1038/1449] x86/kaslr: Recognize all ZONE_DEVICE users as physaddr consumers ANBZ: #35228 commit 9716e427489f6cb8c7351120c5855f44d135b740 stable. commit 269031b15c1433ff39e30fa7ea3ab8f0be9d6ae2 upstream. Commit 7ffb791423c7 ("x86/kaslr: Reduce KASLR entropy on most x86 systems") is too narrow. The effect being mitigated in that commit is caused by ZONE_DEVICE which PCI_P2PDMA has a dependency. ZONE_DEVICE, in general, lets any physical address be added to the direct-map. I.e. not only ACPI hotplug ranges, CXL Memory Windows, or EFI Specific Purpose Memory, but also any PCI MMIO range for the DEVICE_PRIVATE and PCI_P2PDMA cases. Update the mitigation, limit KASLR entropy, to apply in all ZONE_DEVICE=y cases. Distro kernels typically have PCI_P2PDMA=y, so the practical exposure of this problem is limited to the PCI_P2PDMA=n case. A potential path to recover entropy would be to walk ACPI and determine the limits for hotplug and PCI MMIO before kernel_randomize_memory(). On smaller systems that could yield some KASLR address bits. This needs additional investigation to determine if some limited ACPI table scanning can happen this early without an open coded solution like arch/x86/boot/compressed/acpi.c needs to deploy. Cc: Ingo Molnar Cc: Kees Cook Cc: Bjorn Helgaas Cc: Peter Zijlstra Cc: Andy Lutomirski Cc: Logan Gunthorpe Cc: Andrew Morton Cc: David Hildenbrand Cc: Lorenzo Stoakes Cc: "Liam R. Howlett" Cc: Vlastimil Babka Cc: Mike Rapoport Cc: Suren Baghdasaryan Cc: Michal Hocko Fixes: 7ffb791423c7 ("x86/kaslr: Reduce KASLR entropy on most x86 systems") Cc: Signed-off-by: Dan Williams Reviewed-by: Balbir Singh Tested-by: Yasunori Goto Acked-by: Dave Hansen Link: http://patch.msgid.link/692e08b2516d4_261c1100a3@dwillia2-mobl4.notmuch Signed-off-by: Dave Jiang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/mm/kaslr.c | 10 +++++----- drivers/pci/Kconfig | 6 ------ mm/Kconfig | 12 ++++++++---- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c index e0b0ec0f8245..7e3dc0cead96 100644 --- a/arch/x86/mm/kaslr.c +++ b/arch/x86/mm/kaslr.c @@ -111,12 +111,12 @@ void __init kernel_randomize_memory(void) /* * Adapt physical memory region size based on available memory, - * except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the - * device BAR space assuming the direct map space is large enough - * for creating a ZONE_DEVICE mapping in the direct map corresponding - * to the physical BAR address. + * except when CONFIG_ZONE_DEVICE is enabled. ZONE_DEVICE wants to map + * any physical address into the direct-map. KASLR wants to reliably + * steal some physical address bits. Those design choices are in direct + * conflict. */ - if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb)) + if (!IS_ENABLED(CONFIG_ZONE_DEVICE) && (memory_tb < kaslr_regions[0].size_tb)) kaslr_regions[0].size_tb = memory_tb; /* diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 67cd3373c1a5..3672d3723427 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -189,12 +189,6 @@ config PCI_P2PDMA P2P DMA transactions must be between devices behind the same root port. - Enabling this option will reduce the entropy of x86 KASLR memory - regions. For example - on a 46 bit system, the entropy goes down - from 16 bits to 15 bits. The actual reduction in entropy depends - on the physical address bits, on processor features, kernel config - (5 level page table) and physical memory present on the system. - If unsure, say N. config PCI_LABEL diff --git a/mm/Kconfig b/mm/Kconfig index 002a6d8b8aff..e0d03e79192f 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1094,10 +1094,14 @@ config ZONE_DEVICE Device memory hotplug support allows for establishing pmem, or other device driver discovered memory regions, in the memmap. This allows pfn_to_page() lookups of otherwise - "device-physical" addresses which is needed for using a DAX - mapping in an O_DIRECT operation, among other things. - - If FS_DAX is enabled, then say Y. + "device-physical" addresses which is needed for DAX, PCI_P2PDMA, and + DEVICE_PRIVATE features among others. + + Enabling this option will reduce the entropy of x86 KASLR memory + regions. For example - on a 46 bit system, the entropy goes down + from 16 bits to 15 bits. The actual reduction in entropy depends + on the physical address bits, on processor features, kernel config + (5 level page table) and physical memory present on the system. # # Helpers to mirror range of the CPU page tables of a process into device page -- Gitee From 49a91e94b56a773af572f9f93fb8a961f6e29167 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Thu, 27 Nov 2025 18:26:17 +0800 Subject: [PATCH 1039/1449] phy: rockchip: inno-usb2: fix communication disruption in gadget mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 942381794fc31e567e360fe7125728619002da9a stable. commit 7d8f725b79e35fa47e42c88716aad8711e1168d8 upstream. When the OTG USB port is used to power to SoC, configured as peripheral and used in gadget mode, communication stops without notice about 6 seconds after the gadget is configured and enumerated. The problem was observed on a Radxa Rock Pi S board, which can only be powered by the only USB-C connector. That connector is the only one usable in gadget mode. This implies the USB cable is connected from before boot and never disconnects while the kernel runs. The related code flow in the PHY driver code can be summarized as: * the first time chg_detect_work starts (6 seconds after gadget is configured and enumerated) -> rockchip_chg_detect_work(): if chg_state is UNDEFINED: property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); [Y] * rockchip_chg_detect_work() changes state and re-triggers itself a few times until it reaches the DETECTED state: -> rockchip_chg_detect_work(): if chg_state is DETECTED: property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); [Z] At [Y] all existing communications stop. E.g. using a CDC serial gadget, the /dev/tty* devices are still present on both host and device, but no data is transferred anymore. The later call with a 'true' argument at [Z] does not restore it. Due to the lack of documentation, what chg_det.opmode does exactly is not clear, however by code inspection it seems reasonable that is disables something needed to keep the communication working, and testing proves that disabling these lines lets gadget mode keep working. So prevent changes to chg_det.opmode when there is a cable connected (VBUS present). Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399") Cc: stable@vger.kernel.org Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/ Signed-off-by: Luca Ceresoli Reviewed-by: Théo Lebrun Link: https://patch.msgid.link/20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-2-dac8a02cd2ca@bootlin.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index b982c3f0d4b5..7d54c6463672 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -799,7 +799,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) if (!rport->suspended) rockchip_usb2phy_power_off(rport->phy); /* put the controller in non-driving mode */ - property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); + if (!vbus_attach) + property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); /* Start DCD processing stage 1 */ rockchip_chg_enable_dcd(rphy, true); rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD; @@ -862,7 +863,8 @@ static void rockchip_chg_detect_work(struct work_struct *work) fallthrough; case USB_CHG_STATE_DETECTED: /* put the controller in normal mode */ - property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); + if (!vbus_attach) + property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); dev_dbg(&rport->phy->dev, "charger = %s\n", chg_to_string(rphy->chg_type)); -- Gitee From 5b4714fa3444a27ad55283e357bb4af493b7bc6a Mon Sep 17 00:00:00 2001 From: Rafael Beims Date: Tue, 23 Dec 2025 23:02:54 +0800 Subject: [PATCH 1040/1449] phy: freescale: imx8m-pcie: assert phy reset during power on ANBZ: #35228 commit 16a6a73087fb49b8aaeb5771806d95f05b8a31d3 stable. commit f2ec4723defbc66a50e0abafa830ae9f8bceb0d7 upstream. After U-Boot initializes PCIe with "pcie enum", Linux fails to detect an NVMe disk on some boot cycles with: phy phy-32f00000.pcie-phy.0: phy poweron failed --> -110 Discussion with NXP identified that the iMX8MP PCIe PHY PLL may fail to lock when re-initialized without a reset cycle [1]. The issue reproduces on 7% of tested hardware platforms, with a 30-40% failure rate per affected device across boot cycles. Insert a reset cycle in the power-on routine to ensure the PHY is initialized from a known state. [1] https://community.nxp.com/t5/i-MX-Processors/iMX8MP-PCIe-initialization-in-U-Boot/m-p/2248437#M242401 Signed-off-by: Rafael Beims Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251223150254.1075221-1-rafael@beims.me Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c index afd52392cd53..7bdf7aba41ff 100644 --- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c @@ -89,7 +89,8 @@ static int imx8_pcie_phy_power_on(struct phy *phy) writel(imx8_phy->tx_deemph_gen2, imx8_phy->base + PCIE_PHY_TRSV_REG6); break; - case IMX8MP: /* Do nothing. */ + case IMX8MP: + reset_control_assert(imx8_phy->reset); break; } -- Gitee From 937520bd588b07c3240a6185c180ff7728539436 Mon Sep 17 00:00:00 2001 From: Louis Chauvet Date: Thu, 27 Nov 2025 18:26:16 +0800 Subject: [PATCH 1041/1449] phy: rockchip: inno-usb2: fix disconnection in gadget mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9e0d336e71c47e32a8bf0ce85fdd284540bdb8c7 stable. commit 028e8ca7b20fb7324f3e5db34ba8bd366d9d3acc upstream. When the OTG USB port is used to power the SoC, configured as peripheral and used in gadget mode, there is a disconnection about 6 seconds after the gadget is configured and enumerated. The problem was observed on a Radxa Rock Pi S board, which can only be powered by the only USB-C connector. That connector is the only one usable in gadget mode. This implies the USB cable is connected from before boot and never disconnects while the kernel runs. The problem happens because of the PHY driver code flow, summarized as: * UDC start code (triggered via configfs at any time after boot) -> phy_init -> rockchip_usb2phy_init -> schedule_delayed_work(otg_sm_work [A], 6 sec) -> phy_power_on -> rockchip_usb2phy_power_on -> enable clock -> rockchip_usb2phy_reset * Now the gadget interface is up and running. * 6 seconds later otg_sm_work starts [A] -> rockchip_usb2phy_otg_sm_work(): if (B_IDLE state && VBUS present && ...): schedule_delayed_work(&rport->chg_work [B], 0); * immediately the chg_detect_work starts [B] -> rockchip_chg_detect_work(): if chg_state is UNDEFINED: if (!rport->suspended): rockchip_usb2phy_power_off() <--- [X] At [X], the PHY is powered off, causing a disconnection. This quickly triggers a new connection and following re-enumeration, but any connection that had been established during the 6 seconds is broken. The code already checks for !rport->suspended (which, somewhat counter-intuitively, means the PHY is powered on), so add a guard for VBUS as well to avoid a disconnection when a cable is connected. Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399") Cc: stable@vger.kernel.org Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/ Signed-off-by: Louis Chauvet Co-developed-by: Luca Ceresoli Signed-off-by: Luca Ceresoli Reviewed-by: Théo Lebrun Link: https://patch.msgid.link/20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-1-dac8a02cd2ca@bootlin.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 7d54c6463672..a7b7f631cdac 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -789,14 +789,16 @@ static void rockchip_chg_detect_work(struct work_struct *work) container_of(work, struct rockchip_usb2phy_port, chg_work.work); struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); struct regmap *base = get_reg_base(rphy); - bool is_dcd, tmout, vout; + bool is_dcd, tmout, vout, vbus_attach; unsigned long delay; + vbus_attach = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid); + dev_dbg(&rport->phy->dev, "chg detection work state = %d\n", rphy->chg_state); switch (rphy->chg_state) { case USB_CHG_STATE_UNDEFINED: - if (!rport->suspended) + if (!rport->suspended && !vbus_attach) rockchip_usb2phy_power_off(rport->phy); /* put the controller in non-driving mode */ if (!vbus_attach) -- Gitee From 0c8dfdbd6be800f5de55d4760c4aa5f9c67e7b7c Mon Sep 17 00:00:00 2001 From: Wayne Chang Date: Fri, 12 Dec 2025 11:21:16 +0800 Subject: [PATCH 1042/1449] phy: tegra: xusb: Explicitly configure HS_DISCON_LEVEL to 0x7 ANBZ: #35228 commit ee82bc9f1df97f051a189c7815dcfc07a17634cf stable. commit b246caa68037aa495390a60d080acaeb84f45fff upstream. The USB2 Bias Pad Control register manages analog parameters for signal detection. Previously, the HS_DISCON_LEVEL relied on hardware reset values, which may lead to the detection failure. Explicitly configure HS_DISCON_LEVEL to 0x7. This ensures the disconnect threshold is sufficient to guarantee reliable detection. Fixes: bbf711682cd5 ("phy: tegra: xusb: Add Tegra186 support") Cc: stable@vger.kernel.org Signed-off-by: Wayne Chang Link: https://patch.msgid.link/20251212032116.768307-1-waynec@nvidia.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/tegra/xusb-tegra186.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index e818f6c3980e..bec9616c4a2e 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -84,6 +84,7 @@ #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 0x284 #define BIAS_PAD_PD BIT(11) #define HS_SQUELCH_LEVEL(x) (((x) & 0x7) << 0) +#define HS_DISCON_LEVEL(x) (((x) & 0x7) << 3) #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1 0x288 #define USB2_TRK_START_TIMER(x) (((x) & 0x7f) << 12) @@ -623,6 +624,8 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl) value &= ~BIAS_PAD_PD; value &= ~HS_SQUELCH_LEVEL(~0); value |= HS_SQUELCH_LEVEL(priv->calib.hs_squelch); + value &= ~HS_DISCON_LEVEL(~0); + value |= HS_DISCON_LEVEL(0x7); padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); udelay(1); -- Gitee From ffd476d7e12076eae6c1a5b77f5b2af0a1e511da Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Sat, 3 Jan 2026 05:53:46 +0800 Subject: [PATCH 1043/1449] usb: dwc3: Check for USB4 IP_NAME ANBZ: #35228 commit 928e7d022d167b807f6d7f3a1c29c95c36906e95 stable. commit 0ed91d47959cb7573c17e06487f0fb891d59dfb3 upstream. Synopsys renamed DWC_usb32 IP to DWC_usb4 as of IP version 1.30. No functional change except checking for the IP_NAME here. The driver will treat the new IP_NAME as if it's DWC_usb32. Additional features for USB4 will be introduced and checked separately. Cc: stable@vger.kernel.org Signed-off-by: Thinh Nguyen Link: https://patch.msgid.link/e6f1827754c7a7ddc5eb7382add20bfe3a9b312f.1767390747.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/dwc3/core.c | 2 ++ drivers/usb/dwc3/core.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 22975a4b19a4..45c9a399f8a5 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -892,6 +892,8 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); dwc->ip = DWC3_GSNPS_ID(reg); + if (dwc->ip == DWC4_IP) + dwc->ip = DWC32_IP; /* This should read as U3 followed by revision number */ if (DWC3_IP_IS(DWC3)) { diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 06be72f78969..9fc91f5c0bdb 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1221,6 +1221,7 @@ struct dwc3 { #define DWC3_IP 0x5533 #define DWC31_IP 0x3331 #define DWC32_IP 0x3332 +#define DWC4_IP 0x3430 u32 revision; -- Gitee From 2b085172cc0e3db7db720bc4b14c3c952dba0859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Br=C3=BCderl?= Date: Sun, 7 Dec 2025 17:02:20 +0800 Subject: [PATCH 1044/1449] usb: core: add USB_QUIRK_NO_BOS for devices that hang on BOS descriptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 93f21786487cd282017c291a6b92dbbbc503e349 stable. commit 2740ac33c87b3d0dfa022efd6ba04c6261b1abbd upstream. Add USB_QUIRK_NO_BOS quirk flag to skip requesting the BOS descriptor for devices that cannot handle it. Add Elgato 4K X (0fd9:009b) to the quirk table. This device hangs when the BOS descriptor is requested at SuperSpeed Plus (10Gbps). Link: https://bugzilla.kernel.org/show_bug.cgi?id=220027 Cc: stable Signed-off-by: Johannes Brüderl Link: https://patch.msgid.link/20251207090220.14807-1-johannes.bruederl@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/core/config.c | 5 +++++ drivers/usb/core/quirks.c | 3 +++ include/linux/usb/quirks.h | 3 +++ 3 files changed, 11 insertions(+) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 3180419424c0..10a1bc059ea1 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -1004,6 +1004,11 @@ int usb_get_bos_descriptor(struct usb_device *dev) __u8 cap_type; int ret; + if (dev->quirks & USB_QUIRK_NO_BOS) { + dev_dbg(ddev, "skipping BOS descriptor\n"); + return -ENOMSG; + } + bos = kzalloc(sizeof(*bos), GFP_KERNEL); if (!bos) return -ENOMEM; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c322d0c1d965..323a949bbb05 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -447,6 +447,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x0c45, 0x7056), .driver_info = USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* Elgato 4K X - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x0fd9, 0x009b), .driver_info = USB_QUIRK_NO_BOS }, + /* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */ { USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM }, diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index 59409c1fc3de..2f7bd2fdc616 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -75,4 +75,7 @@ /* short SET_ADDRESS request timeout */ #define USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT BIT(16) +/* skip BOS descriptor request */ +#define USB_QUIRK_NO_BOS BIT(17) + #endif /* __LINUX_USB_QUIRKS_H */ -- Gitee From c5aead9ad2694a2fa23b4a603c2c2ee4814fd015 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Mon, 12 Jan 2026 16:48:02 +0800 Subject: [PATCH 1045/1449] USB: OHCI/UHCI: Add soft dependencies on ehci_platform ANBZ: #35228 commit 384084a094c742650270ac637c749a74bd6a4856 stable. commit 01ef7f1b8713a78ab1a9512cf8096d2474c70633 upstream. Commit 9beeee6584b9aa4f ("USB: EHCI: log a warning if ehci-hcd is not loaded first") said that ehci-hcd should be loaded before ohci-hcd and uhci-hcd. However, commit 05c92da0c52494ca ("usb: ohci/uhci - add soft dependencies on ehci_pci") only makes ohci-pci/uhci-pci depend on ehci- pci, which is not enough and we may still see the warnings in boot log. To eliminate the warnings we should make ohci-hcd/uhci-hcd depend on ehci-hcd. But Alan said that the warning introduced by 9beeee6584b9aa4f is bogus, we only need the soft dependencies in the PCI level rather than the HCD level. However, there is really another neccessary soft dependencies between ohci-platform/uhci-platform and ehci-platform, which is added by this patch. The boot logs are below. 1. ohci-platform loaded before ehci-platform: ohci-platform 1f058000.usb: Generic Platform OHCI controller ohci-platform 1f058000.usb: new USB bus registered, assigned bus number 1 ohci-platform 1f058000.usb: irq 28, io mem 0x1f058000 hub 1-0:1.0: USB hub found hub 1-0:1.0: 4 ports detected Warning! ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after usb 1-4: new low-speed USB device number 2 using ohci-platform ehci-platform 1f050000.usb: EHCI Host Controller ehci-platform 1f050000.usb: new USB bus registered, assigned bus number 2 ehci-platform 1f050000.usb: irq 29, io mem 0x1f050000 ehci-platform 1f050000.usb: USB 2.0 started, EHCI 1.00 usb 1-4: device descriptor read/all, error -62 hub 2-0:1.0: USB hub found hub 2-0:1.0: 4 ports detected usb 1-4: new low-speed USB device number 3 using ohci-platform input: YSPRINGTECH USB OPTICAL MOUSE as /devices/platform/bus@10000000/1f058000.usb/usb1/1-4/1-4:1.0/0003:10C4:8105.0001/input/input0 hid-generic 0003:10C4:8105.0001: input,hidraw0: USB HID v1.11 Mouse [YSPRINGTECH USB OPTICAL MOUSE] on usb-1f058000.usb-4/input0 2. ehci-platform loaded before ohci-platform: ehci-platform 1f050000.usb: EHCI Host Controller ehci-platform 1f050000.usb: new USB bus registered, assigned bus number 1 ehci-platform 1f050000.usb: irq 28, io mem 0x1f050000 ehci-platform 1f050000.usb: USB 2.0 started, EHCI 1.00 hub 1-0:1.0: USB hub found hub 1-0:1.0: 4 ports detected ohci-platform 1f058000.usb: Generic Platform OHCI controller ohci-platform 1f058000.usb: new USB bus registered, assigned bus number 2 ohci-platform 1f058000.usb: irq 29, io mem 0x1f058000 hub 2-0:1.0: USB hub found hub 2-0:1.0: 4 ports detected usb 2-4: new low-speed USB device number 2 using ohci-platform input: YSPRINGTECH USB OPTICAL MOUSE as /devices/platform/bus@10000000/1f058000.usb/usb2/2-4/2-4:1.0/0003:10C4:8105.0001/input/input0 hid-generic 0003:10C4:8105.0001: input,hidraw0: USB HID v1.11 Mouse [YSPRINGTECH USB OPTICAL MOUSE] on usb-1f058000.usb-4/input0 In the later case, there is no re-connection for USB-1.0/1.1 devices, which is expected. Cc: stable Reported-by: Shengwen Xiao Signed-off-by: Huacai Chen Reviewed-by: Alan Stern Link: https://patch.msgid.link/20260112084802.1995923-1-chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/host/ohci-platform.c | 1 + drivers/usb/host/uhci-platform.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4a75507325dd..1cd4757f24da 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -376,3 +376,4 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Hauke Mehrtens"); MODULE_AUTHOR("Alan Stern"); MODULE_LICENSE("GPL"); +MODULE_SOFTDEP("pre: ehci_platform"); diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 712389599d46..55b61df0ebb7 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -191,3 +191,4 @@ static struct platform_driver uhci_platform_driver = { .of_match_table = platform_uhci_ids, }, }; +MODULE_SOFTDEP("pre: ehci_platform"); -- Gitee From 7c75da07f82343e84af9da3223fb371bee13cd5b Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Wed, 10 Dec 2025 04:08:41 +0800 Subject: [PATCH 1046/1449] USB: serial: option: add Telit LE910 MBIM composition ANBZ: #35228 commit f890044ad2959d511949ed5bcb34a697e5ec4691 stable. commit 8af4274ab5999831f4757dfd5bd11665ba3b1569 upstream. Add support for Telit LE910 module when operating in MBIM composition with additional ttys. This USB product ID is used by the module when AT#USBCFG is set to 7. 0x1252: MBIM + tty(NMEA) + tty(MODEM) + tty(MODEM) + SAP T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=1252 Rev=03.18 S: Manufacturer=Android S: Product=LE910C1-EU S: SerialNumber=0123456789ABCDEF C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=03(Int.) MxPS= 10 Ivl=32ms Signed-off-by: Ulrich Mohr Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2dfbf62d934a..60993836cf91 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1505,6 +1505,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */ .driver_info = NCTRL(2) | RSVD(3) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) }, /* Telit LE910Cx (rmnet) */ + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1252, 0xff) }, /* Telit LE910Cx (MBIM) */ { USB_DEVICE(TELIT_VENDOR_ID, 0x1260), .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, { USB_DEVICE(TELIT_VENDOR_ID, 0x1261), -- Gitee From b65d316b6a4bacdfbc6602f676289a32d75c23d2 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Thu, 11 Dec 2025 10:01:17 +0800 Subject: [PATCH 1047/1449] USB: serial: ftdi_sio: add support for PICAXE AXE027 cable ANBZ: #35228 commit 3f6a36c9dc73dfae3ff46b287bb206cf995341a5 stable. commit c0afe95e62984ceea171c3ea319beaf84a21181c upstream. The vendor provides instructions to write "0403 bd90" to /sys/bus/usb-serial/drivers/ftdi_sio/new_id; see: https://picaxe.com/docs/picaxe_linux_instructions.pdf Cc: stable@vger.kernel.org Signed-off-by: Ethan Nelson-Moore Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 53f36762de9b..02c738a6e511 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -850,6 +850,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID, 1) }, + { USB_DEVICE(FTDI_VID, FTDI_AXE027_PID) }, { USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_TURTELIZER_PID, 1) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 2539b9e2f712..6c76cfebfd0e 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -96,6 +96,8 @@ #define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 #define LMI_LM3S_ICDI_BOARD_PID 0xbcda +#define FTDI_AXE027_PID 0xBD90 /* PICAXE AXE027 USB download cable */ + #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */ /* OpenDCC (www.opendcc.de) product id */ -- Gitee From 07ad4f72e88851620bcd568741ff7635dbd19d07 Mon Sep 17 00:00:00 2001 From: Ilikara Zheng Date: Mon, 8 Dec 2025 21:23:40 +0800 Subject: [PATCH 1048/1449] nvme-pci: disable secondary temp for Wodposit WPBSNM8 ANBZ: #35228 commit ed61badfc2bc859250886b3e3e3b12ab75017973 stable. commit 340f4fc5508c2905a1f30de229e2a4b299d55735 upstream. Secondary temperature thresholds (temp2_{min,max}) were not reported properly on this NVMe SSD. This resulted in an error while attempting to read these values with sensors(1): ERROR: Can't get value of subfeature temp2_min: I/O error ERROR: Can't get value of subfeature temp2_max: I/O error Add the device to the nvme_id_table with the NVME_QUIRK_NO_SECONDARY_TEMP_THRESH flag to suppress access to all non- composite temperature thresholds. Cc: stable@vger.kernel.org Tested-by: Wu Haotian Signed-off-by: Ilikara Zheng Signed-off-by: Keith Busch Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 74638a5c53b8..b20965a0247b 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3665,6 +3665,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0x1e49, 0x0041), /* ZHITAI TiPro7000 NVMe SSD */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x1fa0, 0x2283), /* Wodposit WPBSNM8-256GTP */ + .driver_data = NVME_QUIRK_NO_SECONDARY_TEMP_THRESH, }, { PCI_DEVICE(0x025e, 0xf1ac), /* SOLIDIGM P44 pro SSDPFKKW020X7 */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0xc0a9, 0x540a), /* Crucial P2 */ -- Gitee From 975c8f50429f9444c31017f4a970dd98b1fd82b6 Mon Sep 17 00:00:00 2001 From: Yang Erkun Date: Sat, 13 Dec 2025 13:57:06 +0800 Subject: [PATCH 1049/1449] ext4: fix iloc.bh leak in ext4_xattr_inode_update_ref ANBZ: #35228 commit 0b06cde92f2f960f4ebe3c988c69f2711f2a24dc stable. commit d250bdf531d9cd4096fedbb9f172bb2ca660c868 upstream. The error branch for ext4_xattr_inode_update_ref forget to release the refcount for iloc.bh. Find this when review code. Fixes: 57295e835408 ("ext4: guard against EA inode refcount underflow in xattr update") Signed-off-by: Yang Erkun Reviewed-by: Baokun Li Reviewed-by: Zhang Yi Link: https://patch.msgid.link/20251213055706.3417529-1-yangerkun@huawei.com Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ext4/xattr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 106fae6bac7a..c25f36e55a20 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1037,6 +1037,7 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, ext4_error_inode(ea_inode, __func__, __LINE__, 0, "EA inode %lu ref wraparound: ref_count=%lld ref_change=%d", ea_inode->i_ino, ref_count, ref_change); + brelse(iloc.bh); ret = -EFSCORRUPTED; goto out; } -- Gitee From 858b44516bf797b2f029c4974ffaf85e760d977d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Wed, 7 Jan 2026 18:39:24 +0800 Subject: [PATCH 1050/1449] hrtimer: Fix softirq base check in update_needs_ipi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit ac9256360151370d450c023542623a65c09548e0 stable. commit 05dc4a9fc8b36d4c99d76bbc02aa9ec0132de4c2 upstream. The 'clockid' field is not the correct way to check for a softirq base. Fix the check to correctly compare the base type instead of the clockid. Fixes: 1e7f7fbcd40c ("hrtimer: Avoid more SMP function calls in clock_was_set()") Signed-off-by: Thomas Weißschuh Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260107-hrtimer-clock-base-check-v1-1-afb5dbce94a1@linutronix.de Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/time/hrtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index ccea52adcba6..0320f49bd1f4 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -941,7 +941,7 @@ static bool update_needs_ipi(struct hrtimer_cpu_base *cpu_base, return true; /* Extra check for softirq clock bases */ - if (base->clockid < HRTIMER_BASE_MONOTONIC_SOFT) + if (base->index < HRTIMER_BASE_MONOTONIC_SOFT) continue; if (cpu_base->softirq_activated) continue; -- Gitee From b50f75ad33acad3874f060f9f6cc2e383a57046c Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Tue, 23 Dec 2025 20:43:50 +0800 Subject: [PATCH 1051/1449] EDAC/x38: Fix a resource leak in x38_probe1() ANBZ: #35228 commit dc2365df328a966ffcb878b8b9624d8f039aaf7f stable. commit 0ff7c44106b4715fc27a2e455d9f57f1dfcfd54f upstream. If edac_mc_alloc() fails, also unmap the window. [ bp: Use separate labels, turning it into the classic unwind pattern. ] Fixes: df8bc08c192f ("edac x38: new MC driver module") Signed-off-by: Haoxiang Li Signed-off-by: Borislav Petkov (AMD) Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251223124350.1496325-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/edac/x38_edac.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c index 49ab5721aab2..292dda754c23 100644 --- a/drivers/edac/x38_edac.c +++ b/drivers/edac/x38_edac.c @@ -341,9 +341,12 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = x38_channel_num; layers[1].is_virt_csrow = false; + + + rc = -ENOMEM; mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0); if (!mci) - return -ENOMEM; + goto unmap; edac_dbg(3, "MC: init mci\n"); @@ -403,9 +406,9 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx) return 0; fail: + edac_mc_free(mci); +unmap: iounmap(window); - if (mci) - edac_mc_free(mci); return rc; } -- Gitee From 7076d9a089103fe674653a4e4c9a938c441a3cc3 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Tue, 23 Dec 2025 20:32:02 +0800 Subject: [PATCH 1052/1449] EDAC/i3200: Fix a resource leak in i3200_probe1() ANBZ: #35228 commit bfefcc78a8ec576fd9146e2fef0b7387512a168a stable. commit d42d5715dcb559342ff356327b241c53a67584d9 upstream. If edac_mc_alloc() fails, also unmap the window. [ bp: Use separate labels, turning it into the classic unwind pattern. ] Fixes: dd8ef1db87a4 ("edac: i3200 memory controller driver") Signed-off-by: Haoxiang Li Signed-off-by: Borislav Petkov (AMD) Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251223123202.1492038-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/edac/i3200_edac.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c index afccdebf5ac1..6cade6d7ceff 100644 --- a/drivers/edac/i3200_edac.c +++ b/drivers/edac/i3200_edac.c @@ -358,10 +358,11 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = nr_channels; layers[1].is_virt_csrow = false; - mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, - sizeof(struct i3200_priv)); + + rc = -ENOMEM; + mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(struct i3200_priv)); if (!mci) - return -ENOMEM; + goto unmap; edac_dbg(3, "MC: init mci\n"); @@ -421,9 +422,9 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx) return 0; fail: + edac_mc_free(mci); +unmap: iounmap(window); - if (mci) - edac_mc_free(mci); return rc; } -- Gitee From f8e3188bd35650fa6ca2939c09c24a1fe3754d65 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Mon, 5 Jan 2026 16:43:23 +0800 Subject: [PATCH 1053/1449] tcpm: allow looking for role_sw device in the main node ANBZ: #35228 commit 71c5bc6720b60a7f81d461bfb34f39cb720091f1 stable. commit 1366cd228b0c67b60a2c0c26ef37fe9f7cfedb7f upstream. If ports are defined in the tcpc main node, fwnode_usb_role_switch_get() returns an error, meaning usb_role_switch_get() (which would succeed) never gets a chance to run as port->role_sw isn't NULL, causing a regression on devices where this is the case. Fix this by turning the NULL check into IS_ERR_OR_NULL(), so usb_role_switch_get() can actually run and the device get properly probed. Fixes: 2d8713f807a4 ("tcpm: switch check for role_sw device with fw_node") Cc: stable Reviewed-by: Heikki Krogerus Reviewed-by: Dragan Simic Signed-off-by: Arnaud Ferraris Link: https://patch.msgid.link/20260105-fix-ppp-power-v2-1-6924f5a41224@collabora.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/typec/tcpm/tcpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 2e39686e01c9..5e6d68958409 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -6637,7 +6637,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) port->port_type = port->typec_caps.type; port->role_sw = fwnode_usb_role_switch_get(tcpc->fwnode); - if (!port->role_sw) + if (IS_ERR_OR_NULL(port->role_sw)) port->role_sw = usb_role_switch_get(port->dev); if (IS_ERR(port->role_sw)) { err = PTR_ERR(port->role_sw); -- Gitee From 0284e74eebca17e50757a3a23471ed270c8633d8 Mon Sep 17 00:00:00 2001 From: Aboorva Devarajan Date: Mon, 1 Dec 2025 14:00:09 +0800 Subject: [PATCH 1054/1449] mm/page_alloc: make percpu_pagelist_high_fraction reads lock-free ANBZ: #35228 commit 6ef36b329bbe2c8b2d530fb7134f5843ce7cf8ab stable. commit b9efe36b5e3eb2e91aa3d706066428648af034fc upstream. When page isolation loops indefinitely during memory offline, reading /proc/sys/vm/percpu_pagelist_high_fraction blocks on pcp_batch_high_lock, causing hung task warnings. Make procfs reads lock-free since percpu_pagelist_high_fraction is a simple integer with naturally atomic reads, writers still serialize via the mutex. This prevents hung task warnings when reading the procfs file during long-running memory offline operations. [akpm@linux-foundation.org: add comment, per Michal] Link: https://lkml.kernel.org/r/aS_y9AuJQFydLEXo@tiehlicka Link: https://lkml.kernel.org/r/20251201060009.1420792-1-aboorvad@linux.ibm.com Signed-off-by: Aboorva Devarajan Acked-by: Michal Hocko Cc: Brendan Jackman Cc: Johannes Weiner Cc: Suren Baghdasaryan Cc: Vlastimil Babka Cc: Zi Yan Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/page_alloc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ed97ab4a6dc0..f88b0f036bd1 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -6644,11 +6644,19 @@ static int percpu_pagelist_high_fraction_sysctl_handler(struct ctl_table *table, int old_percpu_pagelist_high_fraction; int ret; + /* + * Avoid using pcp_batch_high_lock for reads as the value is read + * atomically and a race with offlining is harmless. + */ + + if (!write) + return proc_dointvec_minmax(table, write, buffer, length, ppos); + mutex_lock(&pcp_batch_high_lock); old_percpu_pagelist_high_fraction = percpu_pagelist_high_fraction; ret = proc_dointvec_minmax(table, write, buffer, length, ppos); - if (!write || ret < 0) + if (ret < 0) goto out; /* Sanity checking to avoid pcp imbalance */ -- Gitee From 0f3b979e3d591eec64ed411027e0c765e548677b Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Thu, 25 Dec 2025 10:30:35 +0800 Subject: [PATCH 1055/1449] mm/damon/sysfs: cleanup attrs subdirs on context dir setup failure ANBZ: #35228 commit 43964644348f6b1add3055c4a6cae8f77d892a6e stable. commit 9814cc832b88bd040fc2a1817c2b5469d0f7e862 upstream. When a context DAMON sysfs directory setup is failed after setup of attrs/ directory, subdirectories of attrs/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked. Cleanup the directories under such failures. Link: https://lkml.kernel.org/r/20251225023043.18579-3-sj@kernel.org Fixes: c951cd3b8901 ("mm/damon: implement a minimal stub for sysfs-based DAMON interface") Signed-off-by: SeongJae Park Cc: chongjiapeng Cc: # 5.18.x Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/sysfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index 91893543d47c..acb6e57cd9cb 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -716,7 +716,7 @@ static int damon_sysfs_context_add_dirs(struct damon_sysfs_context *context) err = damon_sysfs_context_set_targets(context); if (err) - goto put_attrs_out; + goto rmdir_put_attrs_out; err = damon_sysfs_context_set_schemes(context); if (err) @@ -726,7 +726,8 @@ static int damon_sysfs_context_add_dirs(struct damon_sysfs_context *context) put_targets_attrs_out: kobject_put(&context->targets->kobj); context->targets = NULL; -put_attrs_out: +rmdir_put_attrs_out: + damon_sysfs_attrs_rm_dirs(context->attrs); kobject_put(&context->attrs->kobj); context->attrs = NULL; return err; -- Gitee From 9cd2ec15cef02701abda650e04702cb8e5f71215 Mon Sep 17 00:00:00 2001 From: Lisa Robinson Date: Sat, 17 Jan 2026 10:56:43 +0800 Subject: [PATCH 1056/1449] LoongArch: Fix PMU counter allocation for mixed-type event groups ANBZ: #35228 commit 1d8f4d24fc1b3fc6976e45198f28a81aacd87d46 stable. commit a91f86e27087f250a5d9c89bb4a427b9c30fd815 upstream. When validating a perf event group, validate_group() unconditionally attempts to allocate hardware PMU counters for the leader, sibling events and the new event being added. This is incorrect for mixed-type groups. If a PERF_TYPE_SOFTWARE event is part of the group, the current code still tries to allocate a hardware PMU counter for it, which can wrongly consume hardware PMU resources and cause spurious allocation failures. Fix this by only allocating PMU counters for hardware events during group validation, and skipping software events. A trimmed down reproducer is as simple as this: #include #include #include #include #include #include int main (int argc, char *argv[]) { struct perf_event_attr attr = { 0 }; int fds[5]; attr.disabled = 1; attr.exclude_kernel = 1; attr.exclude_hv = 1; attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING | PERF_FORMAT_ID | PERF_FORMAT_GROUP; attr.size = sizeof (attr); attr.type = PERF_TYPE_SOFTWARE; attr.config = PERF_COUNT_SW_DUMMY; fds[0] = syscall (SYS_perf_event_open, &attr, 0, -1, -1, 0); assert (fds[0] >= 0); attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_CPU_CYCLES; fds[1] = syscall (SYS_perf_event_open, &attr, 0, -1, fds[0], 0); assert (fds[1] >= 0); attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_INSTRUCTIONS; fds[2] = syscall (SYS_perf_event_open, &attr, 0, -1, fds[0], 0); assert (fds[2] >= 0); attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_BRANCH_MISSES; fds[3] = syscall (SYS_perf_event_open, &attr, 0, -1, fds[0], 0); assert (fds[3] >= 0); attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_CACHE_REFERENCES; fds[4] = syscall (SYS_perf_event_open, &attr, 0, -1, fds[0], 0); assert (fds[4] >= 0); printf ("PASSED\n"); return 0; } Cc: stable@vger.kernel.org Fixes: b37042b2bb7c ("LoongArch: Add perf events support") Signed-off-by: Lisa Robinson Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/kernel/perf_event.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/arch/loongarch/kernel/perf_event.c b/arch/loongarch/kernel/perf_event.c index f86a4b838dd7..8f800de92797 100644 --- a/arch/loongarch/kernel/perf_event.c +++ b/arch/loongarch/kernel/perf_event.c @@ -627,6 +627,18 @@ static const struct loongarch_perf_event *loongarch_pmu_map_cache_event(u64 conf return pev; } +static inline bool loongarch_pmu_event_requires_counter(const struct perf_event *event) +{ + switch (event->attr.type) { + case PERF_TYPE_HARDWARE: + case PERF_TYPE_HW_CACHE: + case PERF_TYPE_RAW: + return true; + default: + return false; + } +} + static int validate_group(struct perf_event *event) { struct cpu_hw_events fake_cpuc; @@ -634,15 +646,18 @@ static int validate_group(struct perf_event *event) memset(&fake_cpuc, 0, sizeof(fake_cpuc)); - if (loongarch_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0) + if (loongarch_pmu_event_requires_counter(leader) && + loongarch_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0) return -EINVAL; for_each_sibling_event(sibling, leader) { - if (loongarch_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0) + if (loongarch_pmu_event_requires_counter(sibling) && + loongarch_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0) return -EINVAL; } - if (loongarch_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0) + if (loongarch_pmu_event_requires_counter(event) && + loongarch_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0) return -EINVAL; return 0; -- Gitee From 5077d3caa23af448c24e917a5623584c884b22f7 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 16 Dec 2025 04:08:30 +0800 Subject: [PATCH 1057/1449] drm/amd/display: Bump the HDMI clock to 340MHz ANBZ: #35228 commit d9a82256a4c7e1e2b97bda11008b84a655bc225f stable. commit fee50077656d8a58011f13bca48f743d1b6d6015 upstream. [Why] DP-HDMI dongles can execeed bandwidth requirements on high resolution monitors. This can lead to pruning the high resolution modes. HDMI 1.3 bumped the clock to 340MHz, but display code never matched it. [How] Set default to (DVI) 165MHz. Once HDMI display is identified update to 340MHz. Reported-by: Dianne Skoll Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4780 Reviewed-by: Chris Park Signed-off-by: Mario Limonciello Signed-off-by: Matthew Stewart Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit ac1e65d8ade46c09fb184579b81acadf36dcb91e) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h | 2 +- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h index b015e80672ec..fcd3ab4b0045 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h @@ -41,7 +41,7 @@ /* kHZ*/ #define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000 /* kHZ*/ -#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000 +#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 340000 struct dp_hdmi_dongle_signature_data { int8_t id[15];/* "DP-HDMI ADAPTOR"*/ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 2d98f539a100..0717f69f7c45 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -325,7 +325,7 @@ static void query_dp_dual_mode_adaptor( /* Assume we have no valid DP passive dongle connected */ *dongle = DISPLAY_DONGLE_NONE; - sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK; + sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK; /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/ if (!i2c_read( @@ -381,6 +381,8 @@ static void query_dp_dual_mode_adaptor( } } + if (is_valid_hdmi_signature) + sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK; if (is_type2_dongle) { uint32_t max_tmds_clk = -- Gitee From 3e458ba1bbb61212aed01db023bb678554d52032 Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Thu, 8 Jan 2026 05:37:28 +0800 Subject: [PATCH 1058/1449] drm/amd: Clean up kfd node on surprise disconnect ANBZ: #35228 commit a4218ac0bb8e70f7c0896f9df464baf2d5171ee6 stable. commit 28695ca09d326461f8078332aa01db516983e8a2 upstream. When an eGPU is unplugged the KFD topology should also be destroyed for that GPU. This never happens because the fini_sw callbacks never get to run. Run them manually before calling amdgpu_device_ip_fini_early() when a device has already been disconnected. This location is intentionally chosen to make sure that the kfd locking refcount doesn't get incremented unintentionally. Cc: kent.russell@amd.com Closes: https://community.frame.work/t/amd-egpu-on-linux/8691/33 Signed-off-by: Mario Limonciello (AMD) Reviewed-by: Kent Russell Signed-off-by: Alex Deucher (cherry picked from commit 6a23e7b4332c10f8b56c33a9c5431b52ecff9aab) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c1b9333d7b78..017552e79178 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4029,6 +4029,14 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) /* disable ras feature must before hw fini */ amdgpu_ras_pre_fini(adev); + /* + * device went through surprise hotplug; we need to destroy topology + * before ip_fini_early to prevent kfd locking refcount issues by calling + * amdgpu_amdkfd_suspend() + */ + if (drm_dev_is_unplugged(adev_to_drm(adev))) + amdgpu_amdkfd_device_fini_sw(adev); + amdgpu_device_ip_fini_early(adev); amdgpu_irq_fini_hw(adev); -- Gitee From da45211c9a70cf51a968442603b60db75f74a266 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 8 Jan 2026 15:18:22 +0800 Subject: [PATCH 1059/1449] drm/amdkfd: fix a memory leak in device_queue_manager_init() ANBZ: #35228 commit 3dc1a40180264b3508737f6944272155551d659a stable. commit 80614c509810fc051312d1a7ccac8d0012d6b8d0 upstream. If dqm->ops.initialize() fails, add deallocate_hiq_sdma_mqd() to release the memory allocated by allocate_hiq_sdma_mqd(). Move deallocate_hiq_sdma_mqd() up to ensure proper function visibility at the point of use. Fixes: 11614c36bc8f ("drm/amdkfd: Allocate MQD trunk for HIQ and SDMA") Signed-off-by: Haoxiang Li Signed-off-by: Felix Kuehling Reviewed-by: Oak Zeng Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher (cherry picked from commit b7cccc8286bb9919a0952c812872da1dcfe9d390) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index fd4a75073364..48eb5545adcd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -2446,6 +2446,14 @@ static int allocate_hiq_sdma_mqd(struct device_queue_manager *dqm) return retval; } +static void deallocate_hiq_sdma_mqd(struct kfd_node *dev, + struct kfd_mem_obj *mqd) +{ + WARN(!mqd, "No hiq sdma mqd trunk to free"); + + amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem); +} + struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev) { struct device_queue_manager *dqm; @@ -2567,19 +2575,14 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev) return dqm; } + if (!dev->kfd->shared_resources.enable_mes) + deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd); + out_free: kfree(dqm); return NULL; } -static void deallocate_hiq_sdma_mqd(struct kfd_node *dev, - struct kfd_mem_obj *mqd) -{ - WARN(!mqd, "No hiq sdma mqd trunk to free"); - - amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem); -} - void device_queue_manager_uninit(struct device_queue_manager *dqm) { dqm->ops.stop(dqm); -- Gitee From 12477b91727d3d0a30f1ea72e3ef8faed1e4d463 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Sat, 20 Dec 2025 05:52:02 +0800 Subject: [PATCH 1060/1449] drm/nouveau/disp/nv50-: Set lock_core in curs507a_prepare ANBZ: #35228 commit cb4c9fc5e79a7d8b7365d3550e0ef3542a6d538e stable. commit 9e9bc6be0fa0b6b6b73f4f831f3b77716d0a8d9e upstream. For a while, I've been seeing a strange issue where some (usually not all) of the display DMA channels will suddenly hang, particularly when there is a visible cursor on the screen that is being frequently updated, and especially when said cursor happens to go between two screens. While this brings back lovely memories of fixing Intel Skylake bugs, I would quite like to fix it :). It turns out the problem that's happening here is that we're managing to reach nv50_head_flush_set() in our atomic commit path without actually holding nv50_disp->mutex. This means that cursor updates happening in parallel (along with any other atomic updates that need to use the core channel) will race with eachother, which eventually causes us to corrupt the pushbuffer - leading to a plethora of various GSP errors, usually: nouveau 0000:c1:00.0: gsp: Xid:56 CMDre 00000000 00000218 00102680 00000004 00800003 nouveau 0000:c1:00.0: gsp: Xid:56 CMDre 00000000 0000021c 00040509 00000004 00000001 nouveau 0000:c1:00.0: gsp: Xid:56 CMDre 00000000 00000000 00000000 00000001 00000001 The reason this is happening is because generally we check whether we need to set nv50_atom->lock_core at the end of nv50_head_atomic_check(). However, curs507a_prepare is called from the fb_prepare callback, which happens after the atomic check phase. As a result, this can lead to commits that both touch the core channel but also don't grab nv50_disp->mutex. So, fix this by making sure that we set nv50_atom->lock_core in cus507a_prepare(). Reviewed-by: Dave Airlie Signed-off-by: Lyude Paul Fixes: 1590700d94ac ("drm/nouveau/kms/nv50-: split each resource type into their own source files") Cc: # v4.18+ Link: https://patch.msgid.link/20251219215344.170852-2-lyude@redhat.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index a95ee5dcc2e3..1a889139cb05 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -84,6 +84,7 @@ curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, asyh->curs.handle = handle; asyh->curs.offset = offset; asyh->set.curs = asyh->curs.visible; + nv50_atom(asyh->state.state)->lock_core = true; } } -- Gitee From 248c0cf8cce50c744fded15a40fe29e050d22d9c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 10 Jan 2026 23:27:28 +0800 Subject: [PATCH 1061/1449] drm/panel-simple: fix connector type for DataImage SCF0700C48GGU18 panel ANBZ: #35228 commit bc0b17bdba3838e9e17e7e9adc968384ac99938b stable. commit 6ab3d4353bf75005eaa375677c9fed31148154d6 upstream. The connector type for the DataImage SCF0700C48GGU18 panel is missing and devm_drm_panel_bridge_add() requires connector type to be set. This leads to a warning and a backtrace in the kernel log and panel does not work: " WARNING: CPU: 3 PID: 38 at drivers/gpu/drm/bridge/panel.c:379 devm_drm_of_get_bridge+0xac/0xb8 " The warning is triggered by a check for valid connector type in devm_drm_panel_bridge_add(). If there is no valid connector type set for a panel, the warning is printed and panel is not added. Fill in the missing connector type to fix the warning and make the panel operational once again. Cc: stable@vger.kernel.org Fixes: 97ceb1fb08b6 ("drm/panel: simple: Add support for DataImage SCF0700C48GGU18") Signed-off-by: Marek Vasut Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patch.msgid.link/20260110152750.73848-1-marex@nabladev.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 0d69098eddd9..8a94eee57d94 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1607,6 +1607,7 @@ static const struct panel_desc dataimage_scf0700c48ggu18 = { }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, }; static const struct display_timing dlc_dlc0700yzg_1_timing = { -- Gitee From 1df0eb17d749f20b39ad91549bbd2d684f257eec Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Wed, 24 Dec 2025 17:11:05 +0800 Subject: [PATCH 1062/1449] drm/vmwgfx: Fix an error return check in vmw_compat_shader_add() ANBZ: #35228 commit 1f70af89b0893081030ac090042336e09a65564a stable. commit bf72b4b7bb7dbb643d204fa41e7463894a95999f upstream. In vmw_compat_shader_add(), the return value check of vmw_shader_alloc() is not proper. Modify the check for the return pointer 'res'. Found by code review and compiled on ubuntu 20.04. Fixes: 18e4a4669c50 ("drm/vmwgfx: Fix compat shader namespace") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Signed-off-by: Zack Rusin Link: https://patch.msgid.link/20251224091105.1569464-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index 69dfe69ce0f8..a8c8c9375d29 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -923,8 +923,10 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, ttm_bo_unreserve(&buf->tbo); res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type); - if (unlikely(ret != 0)) + if (IS_ERR(res)) { + ret = PTR_ERR(res); goto no_reserve; + } ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_shader, vmw_shader_key(user_key, shader_type), -- Gitee From a32c85fc67beb7f144a1209815d1e96e22a5fd03 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 31 Dec 2025 20:34:59 +0800 Subject: [PATCH 1063/1449] dmaengine: apple-admac: Add "apple,t8103-admac" compatible ANBZ: #35228 commit 2838cb6133ac268d75ebd492818adbfd6855dfa5 stable. commit 76cba1e60b69c9cd53b9127d017a7dc5945455b1 upstream. After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,admac" anymore [1]. Use "apple,t8103-admac" as base compatible as it is the SoC the driver and bindings were written for. [1]: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ Fixes: b127315d9a78 ("dmaengine: apple-admac: Add Apple ADMAC driver") Cc: stable@vger.kernel.org Reviewed-by: Neal Gompa Signed-off-by: Janne Grunau Link: https://patch.msgid.link/20251231-apple-admac-t8103-base-compat-v1-1-ec24a3708f76@jannau.net Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/apple-admac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c index 5b1457f6e3bf..4034ace367ab 100644 --- a/drivers/dma/apple-admac.c +++ b/drivers/dma/apple-admac.c @@ -938,6 +938,7 @@ static int admac_remove(struct platform_device *pdev) } static const struct of_device_id admac_of_match[] = { + { .compatible = "apple,t8103-admac", }, { .compatible = "apple,admac", }, { } }; -- Gitee From 31acdd1d365efb87cd0f4223e9b7d49cce28f6ab Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:43 +0800 Subject: [PATCH 1064/1449] dmaengine: at_hdmac: fix device leak on of_dma_xlate() ANBZ: #35228 commit 987c71671367f42460689b78244d7b894c50999a stable. commit b9074b2d7a230b6e28caa23165e9d8bc0677d333 upstream. Make sure to drop the reference taken when looking up the DMA platform device during of_dma_xlate() when releasing channel resources. Note that commit 3832b78b3ec2 ("dmaengine: at_hdmac: add missing put_device() call in at_dma_xlate()") fixed the leak in a couple of error paths but the reference is still leaking on successful allocation. Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding") Fixes: 3832b78b3ec2 ("dmaengine: at_hdmac: add missing put_device() call in at_dma_xlate()") Cc: stable@vger.kernel.org # 3.10: 3832b78b3ec2 Cc: Yu Kuai Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251117161258.10679-2-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/at_hdmac.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index b2876f67471f..ce9b707e8ac1 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1755,6 +1755,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan) static void atc_free_chan_resources(struct dma_chan *chan) { struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_dma_slave *atslave; BUG_ON(atc_chan_is_enabled(atchan)); @@ -1764,8 +1765,12 @@ static void atc_free_chan_resources(struct dma_chan *chan) /* * Free atslave allocated in at_dma_xlate() */ - kfree(chan->private); - chan->private = NULL; + atslave = chan->private; + if (atslave) { + put_device(atslave->dma_dev); + kfree(atslave); + chan->private = NULL; + } dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); } -- Gitee From 1ec55f64f0427a243bf5128c0ee9098b5e4ca1c1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:45 +0800 Subject: [PATCH 1065/1449] dmaengine: bcm-sba-raid: fix device leak on probe ANBZ: #35228 commit c80ca7bdff158401440741bdcf9175bd8608580b stable. commit 7c3a46ebf15a9796b763a54272407fdbf945bed8 upstream. Make sure to drop the reference taken when looking up the mailbox device during probe on probe failures and on driver unbind. Fixes: 743e1c8ffe4e ("dmaengine: Add Broadcom SBA RAID driver") Cc: stable@vger.kernel.org # 4.13 Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251117161258.10679-4-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/bcm-sba-raid.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/dma/bcm-sba-raid.c b/drivers/dma/bcm-sba-raid.c index 94ea35330eb5..7573860be162 100644 --- a/drivers/dma/bcm-sba-raid.c +++ b/drivers/dma/bcm-sba-raid.c @@ -1699,7 +1699,7 @@ static int sba_probe(struct platform_device *pdev) /* Prealloc channel resource */ ret = sba_prealloc_channel_resources(sba); if (ret) - goto fail_free_mchan; + goto fail_put_mbox; /* Check availability of debugfs */ if (!debugfs_initialized()) @@ -1729,6 +1729,8 @@ static int sba_probe(struct platform_device *pdev) fail_free_resources: debugfs_remove_recursive(sba->root); sba_freeup_channel_resources(sba); +fail_put_mbox: + put_device(sba->mbox_dev); fail_free_mchan: mbox_free_channel(sba->mchan); return ret; @@ -1744,6 +1746,8 @@ static int sba_remove(struct platform_device *pdev) sba_freeup_channel_resources(sba); + put_device(sba->mbox_dev); + mbox_free_channel(sba->mchan); return 0; -- Gitee From d6120b512d51760dd3a80453fa355533545eca07 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:47 +0800 Subject: [PATCH 1066/1449] dmaengine: dw: dmamux: fix OF node leak on route allocation failure ANBZ: #35228 commit db7c79c1bbfb1b0184e78a17ac2bd0f2bc3134d1 stable. commit ec25e60f9f95464aa11411db31d0906b3fb7b9f2 upstream. Make sure to drop the reference taken to the DMA master OF node also on late route allocation failures. Fixes: 134d9c52fca2 ("dmaengine: dw: dmamux: Introduce RZN1 DMA router support") Cc: stable@vger.kernel.org # 5.19 Cc: Miquel Raynal Signed-off-by: Johan Hovold Reviewed-by: Miquel Raynal Link: https://patch.msgid.link/20251117161258.10679-6-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/dw/rzn1-dmamux.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/dw/rzn1-dmamux.c b/drivers/dma/dw/rzn1-dmamux.c index deadf135681b..cbec277af4dd 100644 --- a/drivers/dma/dw/rzn1-dmamux.c +++ b/drivers/dma/dw/rzn1-dmamux.c @@ -90,7 +90,7 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec, if (test_and_set_bit(map->req_idx, dmamux->used_chans)) { ret = -EBUSY; - goto free_map; + goto put_dma_spec_np; } mask = BIT(map->req_idx); @@ -103,6 +103,8 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec, clear_bitmap: clear_bit(map->req_idx, dmamux->used_chans); +put_dma_spec_np: + of_node_put(dma_spec->np); free_map: kfree(map); put_device: -- Gitee From 6674c68835f1f391b9bb2ef8cc82ddecf3ceca63 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:48 +0800 Subject: [PATCH 1067/1449] dmaengine: idxd: fix device leaks on compat bind and unbind ANBZ: #35228 commit c81ea0222eaaafdd77348e27d1e84a1b8cfc0c99 stable. commit 799900f01792cf8b525a44764f065f83fcafd468 upstream. Make sure to drop the reference taken when looking up the idxd device as part of the compat bind and unbind sysfs interface. Fixes: 6e7f3ee97bbe ("dmaengine: idxd: move dsa_drv support to compatible mode") Cc: stable@vger.kernel.org # 5.15 Cc: Dave Jiang Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251117161258.10679-7-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/idxd/compat.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index 5fd38d1b9d28..ff73e0b11924 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -21,11 +21,16 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t c int rc = -ENODEV; dev = bus_find_device_by_name(bus, NULL, buf); - if (dev && dev->driver) { + if (!dev) + return -ENODEV; + + if (dev->driver) { device_driver_detach(dev); rc = count; } + put_device(dev); + return rc; } static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); @@ -39,9 +44,12 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou struct idxd_dev *idxd_dev; dev = bus_find_device_by_name(bus, NULL, buf); - if (!dev || dev->driver || drv != &dsa_drv.drv) + if (!dev) return -ENODEV; + if (dev->driver || drv != &dsa_drv.drv) + goto err_put_dev; + idxd_dev = confdev_to_idxd_dev(dev); if (is_idxd_dev(idxd_dev)) { alt_drv = driver_find("idxd", bus); @@ -54,13 +62,20 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou alt_drv = driver_find("user", bus); } if (!alt_drv) - return -ENODEV; + goto err_put_dev; rc = device_driver_attach(alt_drv, dev); if (rc < 0) - return rc; + goto err_put_dev; + + put_device(dev); return count; + +err_put_dev: + put_device(dev); + + return rc; } static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store); -- Gitee From eae880063a3fd7657bdc2f723920ad0ef258dd8a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:49 +0800 Subject: [PATCH 1068/1449] dmaengine: lpc18xx-dmamux: fix device leak on route allocation ANBZ: #35228 commit 9fba97baa520c9446df51a64708daf27c5a7ed32 stable. commit d4d63059dee7e7cae0c4d9a532ed558bc90efb55 upstream. Make sure to drop the reference taken when looking up the DMA mux platform device during route allocation. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Fixes: e5f4ae84be74 ("dmaengine: add driver for lpc18xx dmamux") Cc: stable@vger.kernel.org # 4.3 Signed-off-by: Johan Hovold Reviewed-by: Vladimir Zapolskiy Link: https://patch.msgid.link/20251117161258.10679-8-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/lpc18xx-dmamux.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/dma/lpc18xx-dmamux.c b/drivers/dma/lpc18xx-dmamux.c index 2b6436f4b193..d3ff521951b8 100644 --- a/drivers/dma/lpc18xx-dmamux.c +++ b/drivers/dma/lpc18xx-dmamux.c @@ -57,30 +57,31 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec, struct lpc18xx_dmamux_data *dmamux = platform_get_drvdata(pdev); unsigned long flags; unsigned mux; + int ret = -EINVAL; if (dma_spec->args_count != 3) { dev_err(&pdev->dev, "invalid number of dma mux args\n"); - return ERR_PTR(-EINVAL); + goto err_put_pdev; } mux = dma_spec->args[0]; if (mux >= dmamux->dma_master_requests) { dev_err(&pdev->dev, "invalid mux number: %d\n", dma_spec->args[0]); - return ERR_PTR(-EINVAL); + goto err_put_pdev; } if (dma_spec->args[1] > LPC18XX_DMAMUX_MAX_VAL) { dev_err(&pdev->dev, "invalid dma mux value: %d\n", dma_spec->args[1]); - return ERR_PTR(-EINVAL); + goto err_put_pdev; } /* The of_node_put() will be done in the core for the node */ dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); if (!dma_spec->np) { dev_err(&pdev->dev, "can't get dma master\n"); - return ERR_PTR(-EINVAL); + goto err_put_pdev; } spin_lock_irqsave(&dmamux->lock, flags); @@ -89,7 +90,8 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec, dev_err(&pdev->dev, "dma request %u busy with %u.%u\n", mux, mux, dmamux->muxes[mux].value); of_node_put(dma_spec->np); - return ERR_PTR(-EBUSY); + ret = -EBUSY; + goto err_put_pdev; } dmamux->muxes[mux].busy = true; @@ -106,7 +108,14 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec, dev_dbg(&pdev->dev, "mapping dmamux %u.%u to dma request %u\n", mux, dmamux->muxes[mux].value, mux); + put_device(&pdev->dev); + return &dmamux->muxes[mux]; + +err_put_pdev: + put_device(&pdev->dev); + + return ERR_PTR(ret); } static int lpc18xx_dmamux_probe(struct platform_device *pdev) -- Gitee From 2c3784a5eac0639dcf05cd7e183f1df125182e9b Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 29 Oct 2025 20:34:19 +0800 Subject: [PATCH 1069/1449] dmaengine: qcom: gpi: Fix memory leak in gpi_peripheral_config() ANBZ: #35228 commit 6bf4ef078fd11910988889a6c0b3698d2e0c89af stable. commit 3f747004bbd641131d9396d87b5d2d3d1e182728 upstream. Fix a memory leak in gpi_peripheral_config() where the original memory pointed to by gchan->config could be lost if krealloc() fails. The issue occurs when: 1. gchan->config points to previously allocated memory 2. krealloc() fails and returns NULL 3. The function directly assigns NULL to gchan->config, losing the reference to the original memory 4. The original memory becomes unreachable and cannot be freed Fix this by using a temporary variable to hold the krealloc() result and only updating gchan->config when the allocation succeeds. Found via static analysis and code review. Fixes: 5d0c3533a19f ("dmaengine: qcom: Add GPI dma driver") Cc: stable@vger.kernel.org Signed-off-by: Miaoqian Lin Reviewed-by: Bjorn Andersson Link: https://patch.msgid.link/20251029123421.91973-1-linmq006@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/qcom/gpi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index 1c93864e0e4d..36830efd13f7 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1621,14 +1621,16 @@ static int gpi_peripheral_config(struct dma_chan *chan, struct dma_slave_config *config) { struct gchan *gchan = to_gchan(chan); + void *new_config; if (!config->peripheral_config) return -EINVAL; - gchan->config = krealloc(gchan->config, config->peripheral_size, GFP_NOWAIT); - if (!gchan->config) + new_config = krealloc(gchan->config, config->peripheral_size, GFP_NOWAIT); + if (!new_config) return -ENOMEM; + gchan->config = new_config; memcpy(gchan->config, config->peripheral_config, config->peripheral_size); return 0; -- Gitee From 529fc527acf91e188af51ba2e2b2ed2de057de2f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 14 Nov 2025 03:50:48 +0800 Subject: [PATCH 1070/1449] dmaengine: sh: rz-dmac: Fix rz_dmac_terminate_all() ANBZ: #35228 commit 4e45ae701b81680d16ff1f79b794d20bf578c511 stable. commit 747213b08a1ab6a76e3e3b3e7a209cc1d402b5d0 upstream. After audio full duplex testing, playing the recorded file contains a few playback frames from the previous time. The rz_dmac_terminate_all() does not reset all the hardware descriptors queued previously, leading to the wrong descriptor being picked up during the next DMA transfer. Fix the above issue by resetting all the descriptor headers for a channel in rz_dmac_terminate_all() as rz_dmac_lmdesc_recycle() points to the proper descriptor header filled by the rz_dmac_prepare_descs_for_slave_sg(). Cc: stable@kernel.org Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC") Reviewed-by: Geert Uytterhoeven Signed-off-by: Biju Das Reviewed-by: Claudiu Beznea Tested-by: Claudiu Beznea Link: https://patch.msgid.link/20251113195052.564338-1-biju.das.jz@bp.renesas.com Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/sh/rz-dmac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index f777addda8ba..d11be1884774 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -533,11 +533,16 @@ rz_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, static int rz_dmac_terminate_all(struct dma_chan *chan) { struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); + struct rz_lmdesc *lmdesc = channel->lmdesc.base; unsigned long flags; + unsigned int i; LIST_HEAD(head); rz_dmac_disable_hw(channel); spin_lock_irqsave(&channel->vc.lock, flags); + for (i = 0; i < DMAC_NR_LMDESC; i++) + lmdesc[i].header = 0; + list_splice_tail_init(&channel->ld_active, &channel->ld_free); list_splice_tail_init(&channel->ld_queue, &channel->ld_free); spin_unlock_irqrestore(&channel->vc.lock, flags); -- Gitee From 0b544b2343dd7a8a4d523b617915dd11acb4674e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:55 +0800 Subject: [PATCH 1071/1449] dmaengine: ti: dma-crossbar: fix device leak on dra7x route allocation ANBZ: #35228 commit 8df7c3e6d1e5e5fe3a331ed78aa9463ac27fe54e stable. commit dc7e44db01fc2498644e3106db3e62a9883a93d5 upstream. Make sure to drop the reference taken when looking up the crossbar platform device during dra7x route allocation. Note that commit 615a4bfc426e ("dmaengine: ti: Add missing put_device in ti_dra7_xbar_route_allocate") fixed the leak in the error paths but the reference is still leaking on successful allocation. Fixes: a074ae38f859 ("dmaengine: Add driver for TI DMA crossbar on DRA7x") Fixes: 615a4bfc426e ("dmaengine: ti: Add missing put_device in ti_dra7_xbar_route_allocate") Cc: stable@vger.kernel.org # 4.2: 615a4bfc426e Cc: Peter Ujfalusi Cc: Miaoqian Lin Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251117161258.10679-14-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/ti/dma-crossbar.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c index 7f17ee87a6dc..e52b0e139900 100644 --- a/drivers/dma/ti/dma-crossbar.c +++ b/drivers/dma/ti/dma-crossbar.c @@ -288,6 +288,8 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec, ti_dra7_xbar_write(xbar->iomem, map->xbar_out, map->xbar_in); + put_device(&pdev->dev); + return map; } -- Gitee From 91d8a25d07c2885094a57ccdce553bf7f30b281a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:56 +0800 Subject: [PATCH 1072/1449] dmaengine: ti: dma-crossbar: fix device leak on am335x route allocation ANBZ: #35228 commit 6fdf168f57e331e148a1177a9b590a845c21b315 stable. commit 4fc17b1c6d2e04ad13fd6c21cfbac68043ec03f9 upstream. Make sure to drop the reference taken when looking up the crossbar platform device during am335x route allocation. Fixes: 42dbdcc6bf96 ("dmaengine: ti-dma-crossbar: Add support for crossbar on AM33xx/AM43xx") Cc: stable@vger.kernel.org # 4.4 Cc: Peter Ujfalusi Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251117161258.10679-15-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/ti/dma-crossbar.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c index e52b0e139900..ff05b150ad37 100644 --- a/drivers/dma/ti/dma-crossbar.c +++ b/drivers/dma/ti/dma-crossbar.c @@ -79,34 +79,35 @@ static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec, { struct platform_device *pdev = of_find_device_by_node(ofdma->of_node); struct ti_am335x_xbar_data *xbar = platform_get_drvdata(pdev); - struct ti_am335x_xbar_map *map; + struct ti_am335x_xbar_map *map = ERR_PTR(-EINVAL); if (dma_spec->args_count != 3) - return ERR_PTR(-EINVAL); + goto out_put_pdev; if (dma_spec->args[2] >= xbar->xbar_events) { dev_err(&pdev->dev, "Invalid XBAR event number: %d\n", dma_spec->args[2]); - return ERR_PTR(-EINVAL); + goto out_put_pdev; } if (dma_spec->args[0] >= xbar->dma_requests) { dev_err(&pdev->dev, "Invalid DMA request line number: %d\n", dma_spec->args[0]); - return ERR_PTR(-EINVAL); + goto out_put_pdev; } /* The of_node_put() will be done in the core for the node */ dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); if (!dma_spec->np) { dev_err(&pdev->dev, "Can't get DMA master\n"); - return ERR_PTR(-EINVAL); + goto out_put_pdev; } map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) { of_node_put(dma_spec->np); - return ERR_PTR(-ENOMEM); + map = ERR_PTR(-ENOMEM); + goto out_put_pdev; } map->dma_line = (u16)dma_spec->args[0]; @@ -120,6 +121,9 @@ static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec, ti_am335x_xbar_write(xbar->iomem, map->dma_line, map->mux_val); +out_put_pdev: + put_device(&pdev->dev); + return map; } -- Gitee From 95d4f4302a1e1449300e302bad7fed0399e11d2c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 18 Nov 2025 00:12:58 +0800 Subject: [PATCH 1073/1449] dmaengine: ti: k3-udma: fix device leak on udma lookup ANBZ: #35228 commit 696ebf74738b966e732063edbe93d5733a270279 stable. commit 430f7803b69cd5e5694e5dfc884c6628870af36e upstream. Make sure to drop the reference taken when looking up the UDMA platform device. Note that holding a reference to a platform device does not prevent its driver data from going away so there is no point in keeping the reference after the lookup helper returns. Fixes: d70241913413 ("dmaengine: ti: k3-udma: Add glue layer for non DMAengine users") Fixes: 1438cde8fe9c ("dmaengine: ti: k3-udma: add missing put_device() call in of_xudma_dev_get()") Cc: stable@vger.kernel.org # 5.6: 1438cde8fe9c Cc: Grygorii Strashko Cc: Yu Kuai Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251117161258.10679-17-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/ti/k3-udma-private.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c index 05228bf00033..624360423ef1 100644 --- a/drivers/dma/ti/k3-udma-private.c +++ b/drivers/dma/ti/k3-udma-private.c @@ -42,9 +42,9 @@ struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property) } ud = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!ud) { pr_debug("UDMA has not been probed\n"); - put_device(&pdev->dev); return ERR_PTR(-EPROBE_DEFER); } -- Gitee From 5c96b87b315c1c48fed0c8309bc02ba6bf76bfcd Mon Sep 17 00:00:00 2001 From: Robbie Ko Date: Thu, 11 Dec 2025 13:30:33 +0800 Subject: [PATCH 1074/1449] btrfs: fix deadlock in wait_current_trans() due to ignored transaction type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 99da896614d17e8a84aeb2b2d464ac046cc8633d stable. commit 5037b342825df7094a4906d1e2a9674baab50cb2 upstream. When wait_current_trans() is called during start_transaction(), it currently waits for a blocked transaction without considering whether the given transaction type actually needs to wait for that particular transaction state. The btrfs_blocked_trans_types[] array already defines which transaction types should wait for which transaction states, but this check was missing in wait_current_trans(). This can lead to a deadlock scenario involving two transactions and pending ordered extents: 1. Transaction A is in TRANS_STATE_COMMIT_DOING state 2. A worker processing an ordered extent calls start_transaction() with TRANS_JOIN 3. join_transaction() returns -EBUSY because Transaction A is in TRANS_STATE_COMMIT_DOING 4. Transaction A moves to TRANS_STATE_UNBLOCKED and completes 5. A new Transaction B is created (TRANS_STATE_RUNNING) 6. The ordered extent from step 2 is added to Transaction B's pending ordered extents 7. Transaction B immediately starts commit by another task and enters TRANS_STATE_COMMIT_START 8. The worker finally reaches wait_current_trans(), sees Transaction B in TRANS_STATE_COMMIT_START (a blocked state), and waits unconditionally 9. However, TRANS_JOIN should NOT wait for TRANS_STATE_COMMIT_START according to btrfs_blocked_trans_types[] 10. Transaction B is waiting for pending ordered extents to complete 11. Deadlock: Transaction B waits for ordered extent, ordered extent waits for Transaction B This can be illustrated by the following call stacks: CPU0 CPU1 btrfs_finish_ordered_io() start_transaction(TRANS_JOIN) join_transaction() # -EBUSY (Transaction A is # TRANS_STATE_COMMIT_DOING) # Transaction A completes # Transaction B created # ordered extent added to # Transaction B's pending list btrfs_commit_transaction() # Transaction B enters # TRANS_STATE_COMMIT_START # waiting for pending ordered # extents wait_current_trans() # waits for Transaction B # (should not wait!) Task bstore_kv_sync in btrfs_commit_transaction waiting for ordered extents: __schedule+0x2e7/0x8a0 schedule+0x64/0xe0 btrfs_commit_transaction+0xbf7/0xda0 [btrfs] btrfs_sync_file+0x342/0x4d0 [btrfs] __x64_sys_fdatasync+0x4b/0x80 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Task kworker in wait_current_trans waiting for transaction commit: Workqueue: btrfs-syno_nocow btrfs_work_helper [btrfs] __schedule+0x2e7/0x8a0 schedule+0x64/0xe0 wait_current_trans+0xb0/0x110 [btrfs] start_transaction+0x346/0x5b0 [btrfs] btrfs_finish_ordered_io.isra.0+0x49b/0x9c0 [btrfs] btrfs_work_helper+0xe8/0x350 [btrfs] process_one_work+0x1d3/0x3c0 worker_thread+0x4d/0x3e0 kthread+0x12d/0x150 ret_from_fork+0x1f/0x30 Fix this by passing the transaction type to wait_current_trans() and checking btrfs_blocked_trans_types[cur_trans->state] against the given type before deciding to wait. This ensures that transaction types which are allowed to join during certain blocked states will not unnecessarily wait and cause deadlocks. Reviewed-by: Filipe Manana Signed-off-by: Robbie Ko Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Cc: Motiejus Jakštys Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/transaction.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 20add63421b3..ce1e5b5dae3a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -517,13 +517,14 @@ static inline int is_transaction_blocked(struct btrfs_transaction *trans) * when this is done, it is safe to start a new transaction, but the current * transaction might not be fully on disk. */ -static void wait_current_trans(struct btrfs_fs_info *fs_info) +static void wait_current_trans(struct btrfs_fs_info *fs_info, unsigned int type) { struct btrfs_transaction *cur_trans; spin_lock(&fs_info->trans_lock); cur_trans = fs_info->running_transaction; - if (cur_trans && is_transaction_blocked(cur_trans)) { + if (cur_trans && is_transaction_blocked(cur_trans) && + (btrfs_blocked_trans_types[cur_trans->state] & type)) { refcount_inc(&cur_trans->use_count); spin_unlock(&fs_info->trans_lock); @@ -676,12 +677,12 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, sb_start_intwrite(fs_info->sb); if (may_wait_transaction(fs_info, type)) - wait_current_trans(fs_info); + wait_current_trans(fs_info, type); do { ret = join_transaction(fs_info, type); if (ret == -EBUSY) { - wait_current_trans(fs_info); + wait_current_trans(fs_info, type); if (unlikely(type == TRANS_ATTACH || type == TRANS_JOIN_NOSTART)) ret = -ENOENT; @@ -966,7 +967,7 @@ int btrfs_wait_for_commit(struct btrfs_fs_info *fs_info, u64 transid) void btrfs_throttle(struct btrfs_fs_info *fs_info) { - wait_current_trans(fs_info); + wait_current_trans(fs_info, TRANS_START); } bool btrfs_should_end_transaction(struct btrfs_trans_handle *trans) -- Gitee From 2e949d5d39530004202a94bdac27a73136c1b5e8 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 14 Jan 2026 16:54:05 +0800 Subject: [PATCH 1075/1449] io_uring: move local task_work in exit cancel loop ANBZ: #35228 commit 2c590e4b3d4cc78cf93d243b6ba59bcd7b809969 stable. commit da579f05ef0faada3559e7faddf761c75cdf85e1 upstream. With IORING_SETUP_DEFER_TASKRUN, task work is queued to ctx->work_llist (local work) rather than the fallback list. During io_ring_exit_work(), io_move_task_work_from_local() was called once before the cancel loop, moving work from work_llist to fallback_llist. However, task work can be added to work_llist during the cancel loop itself. There are two cases: 1) io_kill_timeouts() is called from io_uring_try_cancel_requests() to cancel pending timeouts, and it adds task work via io_req_queue_tw_complete() for each cancelled timeout: 2) URING_CMD requests like ublk can be completed via io_uring_cmd_complete_in_task() from ublk_queue_rq() during canceling, given ublk request queue is only quiesced when canceling the 1st uring_cmd. Since io_allowed_defer_tw_run() returns false in io_ring_exit_work() (kworker != submitter_task), io_run_local_work() is never invoked, and the work_llist entries are never processed. This causes io_uring_try_cancel_requests() to loop indefinitely, resulting in 100% CPU usage in kworker threads. Fix this by moving io_move_task_work_from_local() inside the cancel loop, ensuring any work on work_llist is moved to fallback before each cancel attempt. Cc: stable@vger.kernel.org Fixes: c0e0d6ba25f1 ("io_uring: add IORING_SETUP_DEFER_TASKRUN") Signed-off-by: Ming Lei Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- io_uring/io_uring.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 8b8cc1cb00b5..fbd7edb2266c 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3194,11 +3194,11 @@ static __cold void io_ring_exit_work(struct work_struct *work) mutex_unlock(&ctx->uring_lock); } - if (ctx->flags & IORING_SETUP_DEFER_TASKRUN) - io_move_task_work_from_local(ctx); - - while (io_uring_try_cancel_requests(ctx, NULL, true)) + do { + if (ctx->flags & IORING_SETUP_DEFER_TASKRUN) + io_move_task_work_from_local(ctx); cond_resched(); + } while (io_uring_try_cancel_requests(ctx, NULL, true)); if (ctx->sq_data) { struct io_sq_data *sqd = ctx->sq_data; -- Gitee From 7a31fefad641887eb9768092a0e59860bdc24f47 Mon Sep 17 00:00:00 2001 From: Xabier Marquiegui Date: Thu, 12 Oct 2023 00:39:53 +0200 Subject: [PATCH 1076/1449] posix-clock: introduce posix_clock_context concept ANBZ: #35228 commit 221e4d1e29bb442ac4c47bc8ee095abf009ee8f3 stable. commit 60c6946675fc06dd2fd2b7a4b6fd1c1f046f1056 upstream. Add the necessary structure to support custom private-data per posix-clock user. The previous implementation of posix-clock assumed all file open instances need access to the same clock structure on private_data. The need for individual data structures per file open instance has been identified when developing support for multiple timestamp event queue users for ptp_clock. Signed-off-by: Xabier Marquiegui Suggested-by: Richard Cochran Suggested-by: Vinicius Costa Gomes Signed-off-by: David S. Miller Stable-dep-of: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context") Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- drivers/ptp/ptp_chardev.c | 21 +++++++++++++-------- drivers/ptp/ptp_private.h | 16 +++++++++------- include/linux/posix-clock.h | 35 +++++++++++++++++++++++++++-------- kernel/time/posix-clock.c | 36 +++++++++++++++++++++++++++--------- 4 files changed, 76 insertions(+), 32 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 6f6019fb41c0..6eecb53b3e67 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -103,14 +103,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, return 0; } -int ptp_open(struct posix_clock *pc, fmode_t fmode) +int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode) { return 0; } -long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) +long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, + unsigned long arg) { - struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock *ptp = + container_of(pccontext->clk, struct ptp_clock, clock); struct ptp_sys_offset_extended *extoff = NULL; struct ptp_sys_offset_precise precise_offset; struct system_device_crosststamp xtstamp; @@ -437,9 +439,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) return err; } -__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait) +__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp, + poll_table *wait) { - struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock *ptp = + container_of(pccontext->clk, struct ptp_clock, clock); poll_wait(fp, &ptp->tsev_wq, wait); @@ -448,10 +452,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait) #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event)) -ssize_t ptp_read(struct posix_clock *pc, - uint rdflags, char __user *buf, size_t cnt) +ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags, + char __user *buf, size_t cnt) { - struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock *ptp = + container_of(pccontext->clk, struct ptp_clock, clock); struct timestamp_event_queue *queue = &ptp->tsevq; struct ptp_extts_event *event; unsigned long flags; diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index a9c3c04f032c..7fc7ac9c1232 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -141,16 +141,18 @@ extern struct class *ptp_class; int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan); -long ptp_ioctl(struct posix_clock *pc, - unsigned int cmd, unsigned long arg); +long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, + unsigned long arg); -int ptp_open(struct posix_clock *pc, fmode_t fmode); +int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode); -ssize_t ptp_read(struct posix_clock *pc, - uint flags, char __user *buf, size_t cnt); +int ptp_release(struct posix_clock_context *pccontext); -__poll_t ptp_poll(struct posix_clock *pc, - struct file *fp, poll_table *wait); +ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf, + size_t cnt); + +__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp, + poll_table *wait); /* * see ptp_sysfs.c diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h index 4df1db8896e3..e3df43fadb51 100644 --- a/include/linux/posix-clock.h +++ b/include/linux/posix-clock.h @@ -14,6 +14,7 @@ #include struct posix_clock; +struct posix_clock_context; /** * struct posix_clock_operations - functional interface to the clock @@ -50,18 +51,18 @@ struct posix_clock_operations { /* * Optional character device methods: */ - long (*ioctl) (struct posix_clock *pc, - unsigned int cmd, unsigned long arg); + long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd, + unsigned long arg); - int (*open) (struct posix_clock *pc, fmode_t f_mode); + int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode); - __poll_t (*poll) (struct posix_clock *pc, - struct file *file, poll_table *wait); + __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file, + poll_table *wait); - int (*release) (struct posix_clock *pc); + int (*release)(struct posix_clock_context *pccontext); - ssize_t (*read) (struct posix_clock *pc, - uint flags, char __user *buf, size_t cnt); + ssize_t (*read)(struct posix_clock_context *pccontext, uint flags, + char __user *buf, size_t cnt); CK_KABI_RESERVE(1) CK_KABI_RESERVE(2) @@ -104,6 +105,24 @@ struct posix_clock { CK_KABI_RESERVE(8) }; +/** + * struct posix_clock_context - represents clock file operations context + * + * @clk: Pointer to the clock + * @private_clkdata: Pointer to user data + * + * Drivers should use struct posix_clock_context during specific character + * device file operation methods to access the posix clock. + * + * Drivers can store a private data structure during the open operation + * if they have specific information that is required in other file + * operations. + */ +struct posix_clock_context { + struct posix_clock *clk; + void *private_clkdata; +}; + /** * posix_clock_register() - register a new clock * @clk: Pointer to the clock. Caller must provide 'ops' field diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index 05e73d209aa8..706559ed7579 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -19,7 +19,8 @@ */ static struct posix_clock *get_posix_clock(struct file *fp) { - struct posix_clock *clk = fp->private_data; + struct posix_clock_context *pccontext = fp->private_data; + struct posix_clock *clk = pccontext->clk; down_read(&clk->rwsem); @@ -39,6 +40,7 @@ static void put_posix_clock(struct posix_clock *clk) static ssize_t posix_clock_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) { + struct posix_clock_context *pccontext = fp->private_data; struct posix_clock *clk = get_posix_clock(fp); int err = -EINVAL; @@ -46,7 +48,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf, return -ENODEV; if (clk->ops.read) - err = clk->ops.read(clk, fp->f_flags, buf, count); + err = clk->ops.read(pccontext, fp->f_flags, buf, count); put_posix_clock(clk); @@ -55,6 +57,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf, static __poll_t posix_clock_poll(struct file *fp, poll_table *wait) { + struct posix_clock_context *pccontext = fp->private_data; struct posix_clock *clk = get_posix_clock(fp); __poll_t result = 0; @@ -62,7 +65,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait) return EPOLLERR; if (clk->ops.poll) - result = clk->ops.poll(clk, fp, wait); + result = clk->ops.poll(pccontext, fp, wait); put_posix_clock(clk); @@ -72,6 +75,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait) static long posix_clock_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { + struct posix_clock_context *pccontext = fp->private_data; struct posix_clock *clk = get_posix_clock(fp); int err = -ENOTTY; @@ -79,7 +83,7 @@ static long posix_clock_ioctl(struct file *fp, return -ENODEV; if (clk->ops.ioctl) - err = clk->ops.ioctl(clk, cmd, arg); + err = clk->ops.ioctl(pccontext, cmd, arg); put_posix_clock(clk); @@ -90,6 +94,7 @@ static long posix_clock_ioctl(struct file *fp, static long posix_clock_compat_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { + struct posix_clock_context *pccontext = fp->private_data; struct posix_clock *clk = get_posix_clock(fp); int err = -ENOTTY; @@ -97,7 +102,7 @@ static long posix_clock_compat_ioctl(struct file *fp, return -ENODEV; if (clk->ops.ioctl) - err = clk->ops.ioctl(clk, cmd, arg); + err = clk->ops.ioctl(pccontext, cmd, arg); put_posix_clock(clk); @@ -110,6 +115,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) int err; struct posix_clock *clk = container_of(inode->i_cdev, struct posix_clock, cdev); + struct posix_clock_context *pccontext; down_read(&clk->rwsem); @@ -117,14 +123,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp) err = -ENODEV; goto out; } + pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL); + if (!pccontext) { + err = -ENOMEM; + goto out; + } + pccontext->clk = clk; + fp->private_data = pccontext; if (clk->ops.open) - err = clk->ops.open(clk, fp->f_mode); + err = clk->ops.open(pccontext, fp->f_mode); else err = 0; if (!err) { get_device(clk->dev); - fp->private_data = clk; } out: up_read(&clk->rwsem); @@ -133,14 +145,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp) static int posix_clock_release(struct inode *inode, struct file *fp) { - struct posix_clock *clk = fp->private_data; + struct posix_clock_context *pccontext = fp->private_data; + struct posix_clock *clk; int err = 0; + if (!pccontext) + return -ENODEV; + clk = pccontext->clk; + if (clk->ops.release) - err = clk->ops.release(clk); + err = clk->ops.release(pccontext); put_device(clk->dev); + kfree(pccontext); fp->private_data = NULL; return err; -- Gitee From 377090c8c2d1e2201970fde9bc6010af7ea77c76 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 26 Mar 2024 14:59:48 -0700 Subject: [PATCH 1077/1449] Fix memory leak in posix_clock_open() ANBZ: #35228 commit ea2d9bfd422e92fd197f6a0b1fe7d81413b871e0 stable. commit 5b4cdd9c5676559b8a7c944ac5269b914b8c0bb8 upstream. If the clk ops.open() function returns an error, we don't release the pccontext we allocated for this clock. Re-organize the code slightly to make it all more obvious. Reported-by: Rohit Keshri Acked-by: Oleg Nesterov Fixes: 60c6946675fc ("posix-clock: introduce posix_clock_context concept") Cc: Jakub Kicinski Cc: David S. Miller Cc: Thomas Gleixner Signed-off-by: Linus Torvalds Stable-dep-of: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context") Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- kernel/time/posix-clock.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index 706559ed7579..a6487a9d6085 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -129,15 +129,17 @@ static int posix_clock_open(struct inode *inode, struct file *fp) goto out; } pccontext->clk = clk; - fp->private_data = pccontext; - if (clk->ops.open) + if (clk->ops.open) { err = clk->ops.open(pccontext, fp->f_mode); - else - err = 0; - - if (!err) { - get_device(clk->dev); + if (err) { + kfree(pccontext); + goto out; + } } + + fp->private_data = pccontext; + get_device(clk->dev); + err = 0; out: up_read(&clk->rwsem); return err; -- Gitee From ac0eed36165d5aed969038e04c85cb563d5b7698 Mon Sep 17 00:00:00 2001 From: Wojtek Wasko Date: Mon, 3 Mar 2025 18:13:43 +0200 Subject: [PATCH 1078/1449] posix-clock: Store file pointer in struct posix_clock_context ANBZ: #35228 commit ba3a97c832725ccd0cf0904115c71ba30f4c2089 stable. commit e859d375d1694488015e6804bfeea527a0b25b9f upstream. File descriptor based pc_clock_*() operations of dynamic posix clocks have access to the file pointer and implement permission checks in the generic code before invoking the relevant dynamic clock callback. Character device operations (open, read, poll, ioctl) do not implement a generic permission control and the dynamic clock callbacks have no access to the file pointer to implement them. Extend struct posix_clock_context with a struct file pointer and initialize it in posix_clock_open(), so that all dynamic clock callbacks can access it. Acked-by: Richard Cochran Reviewed-by: Vadim Fedorenko Reviewed-by: Thomas Gleixner Signed-off-by: Wojtek Wasko Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- include/linux/posix-clock.h | 6 +++++- kernel/time/posix-clock.c | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h index e3df43fadb51..b0f3fb771e79 100644 --- a/include/linux/posix-clock.h +++ b/include/linux/posix-clock.h @@ -109,10 +109,13 @@ struct posix_clock { * struct posix_clock_context - represents clock file operations context * * @clk: Pointer to the clock + * @fp: Pointer to the file used to open the clock * @private_clkdata: Pointer to user data * * Drivers should use struct posix_clock_context during specific character - * device file operation methods to access the posix clock. + * device file operation methods to access the posix clock. In particular, + * the file pointer can be used to verify correct access mode for ioctl() + * calls. * * Drivers can store a private data structure during the open operation * if they have specific information that is required in other file @@ -120,6 +123,7 @@ struct posix_clock { */ struct posix_clock_context { struct posix_clock *clk; + struct file *fp; void *private_clkdata; }; diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index a6487a9d6085..b130bb56cc4e 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -129,6 +129,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) goto out; } pccontext->clk = clk; + pccontext->fp = fp; if (clk->ops.open) { err = clk->ops.open(pccontext, fp->f_mode); if (err) { -- Gitee From 3c1a4d3237b3f3d3a34e7dca789f4495a551272f Mon Sep 17 00:00:00 2001 From: Wojtek Wasko Date: Tue, 4 Mar 2025 00:13:44 +0800 Subject: [PATCH 1079/1449] ptp: Add PHC file mode checks. Allow RO adjtime() without FMODE_WRITE. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4fbfc6bca4e37c0b4c3ea521c196c7f9db2e2f14 stable. commit b4e53b15c04e3852949003752f48f7a14ae39e86 upstream. Many devices implement highly accurate clocks, which the kernel manages as PTP Hardware Clocks (PHCs). Userspace applications rely on these clocks to timestamp events, trace workload execution, correlate timescales across devices, and keep various clocks in sync. The kernel’s current implementation of PTP clocks does not enforce file permissions checks for most device operations except for POSIX clock operations, where file mode is verified in the POSIX layer before forwarding the call to the PTP subsystem. Consequently, it is common practice to not give unprivileged userspace applications any access to PTP clocks whatsoever by giving the PTP chardevs 600 permissions. An example of users running into this limitation is documented in [1]. Additionally, POSIX layer requires WRITE permission even for readonly adjtime() calls which are used in PTP layer to return current frequency offset applied to the PHC. Add permission checks for functions that modify the state of a PTP device. Continue enforcing permission checks for POSIX clock operations (settime, adjtime) in the POSIX layer. Only require WRITE access for dynamic clocks adjtime() if any flags are set in the modes field. [1] https://lists.nwtime.org/sympa/arc/linuxptp-users/2024-01/msg00036.html Changes in v4: - Require FMODE_WRITE in ajtime() only for calls modifying the clock in any way. Acked-by: Richard Cochran Reviewed-by: Vadim Fedorenko Signed-off-by: Wojtek Wasko Reviewed-by: Thomas Gleixner Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ptp/ptp_chardev.c | 16 ++++++++++++++++ kernel/time/posix-clock.c | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 6eecb53b3e67..1ed12e86ee00 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -153,6 +153,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, case PTP_EXTTS_REQUEST: case PTP_EXTTS_REQUEST2: + if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) { + err = -EACCES; + break; + } memset(&req, 0, sizeof(req)); if (copy_from_user(&req.extts, (void __user *)arg, @@ -194,6 +198,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, case PTP_PEROUT_REQUEST: case PTP_PEROUT_REQUEST2: + if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) { + err = -EACCES; + break; + } memset(&req, 0, sizeof(req)); if (copy_from_user(&req.perout, (void __user *)arg, @@ -262,6 +270,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, case PTP_ENABLE_PPS: case PTP_ENABLE_PPS2: + if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) { + err = -EACCES; + break; + } memset(&req, 0, sizeof(req)); if (!capable(CAP_SYS_TIME)) @@ -400,6 +412,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd, case PTP_PIN_SETFUNC: case PTP_PIN_SETFUNC2: + if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) { + err = -EACCES; + break; + } if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) { err = -EFAULT; break; diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index b130bb56cc4e..827abede7274 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -253,7 +253,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx) if (err) return err; - if ((cd.fp->f_mode & FMODE_WRITE) == 0) { + if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) { err = -EACCES; goto out; } -- Gitee From e836600c3d397160cc8c475df59aace3f60de89c Mon Sep 17 00:00:00 2001 From: Xabier Marquiegui Date: Thu, 12 Oct 2023 06:39:58 +0800 Subject: [PATCH 1080/1449] ptp: add testptp mask test ANBZ: #35228 commit 59ac47a0275fcd5a7637c3d5da20b0905563c7f5 stable. commit 26285e689c6cd2cf3849568c83b2ebe53f467143 upstream. Add option to test timestamp event queue mask manipulation in testptp. Option -F allows the user to specify a single channel that will be applied on the mask filter via IOCTL. The test program will maintain the file open until user input is received. This allows checking the effect of the IOCTL in debugfs. eg: Console 1: ``` Channel 12 exclusively enabled. Check on debugfs. Press any key to continue ``` Console 2: ``` 0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 ``` Signed-off-by: Xabier Marquiegui Suggested-by: Richard Cochran Suggested-by: Vinicius Costa Gomes Signed-off-by: David S. Miller Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/ptp/testptp.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c index c9f6cca4feb4..011252fe238c 100644 --- a/tools/testing/selftests/ptp/testptp.c +++ b/tools/testing/selftests/ptp/testptp.c @@ -121,6 +121,7 @@ static void usage(char *progname) " -d name device to open\n" " -e val read 'val' external time stamp events\n" " -f val adjust the ptp clock frequency by 'val' ppb\n" + " -F chan Enable single channel mask and keep device open for debugfs verification.\n" " -g get the ptp clock time\n" " -h prints this message\n" " -i val index for event/trigger\n" @@ -187,6 +188,7 @@ int main(int argc, char *argv[]) int pps = -1; int seconds = 0; int settime = 0; + int channel = -1; int64_t t1, t2, tp; int64_t interval, offset; @@ -196,7 +198,7 @@ int main(int argc, char *argv[]) progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; - while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) { + while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) { switch (c) { case 'c': capabilities = 1; @@ -210,6 +212,9 @@ int main(int argc, char *argv[]) case 'f': adjfreq = atoi(optarg); break; + case 'F': + channel = atoi(optarg); + break; case 'g': gettime = 1; break; @@ -604,6 +609,18 @@ int main(int argc, char *argv[]) free(xts); } + if (channel >= 0) { + if (ioctl(fd, PTP_MASK_CLEAR_ALL)) { + perror("PTP_MASK_CLEAR_ALL"); + } else if (ioctl(fd, PTP_MASK_EN_SINGLE, (unsigned int *)&channel)) { + perror("PTP_MASK_EN_SINGLE"); + } else { + printf("Channel %d exclusively enabled. Check on debugfs.\n", channel); + printf("Press any key to continue\n."); + getchar(); + } + } + close(fd); return 0; } -- Gitee From ead99d28afadbc2ccd8e19ad012ac9b9f3430c6e Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Thu, 3 Oct 2024 18:15:06 +0800 Subject: [PATCH 1081/1449] selftest/ptp: update ptp selftest to exercise the gettimex options ANBZ: #35228 commit 4f3c8c7f4e1bda9c802873f3b937427dfb61301d stable. commit 3d07b691ee707c00afaf365440975e81bb96cd9b upstream. With the inclusion of commit c259acab839e ("ptp/ioctl: support MONOTONIC{,_RAW} timestamps for PTP_SYS_OFFSET_EXTENDED") clock_gettime() now allows retrieval of pre/post timestamps for CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW timebases along with the previously supported CLOCK_REALTIME. This patch adds a command line option 'y' to the testptp program to choose one of the allowed timebases [realtime aka system, monotonic, and monotonic-raw). Signed-off-by: Mahesh Bandewar Cc: Shuah Khan Acked-by: Richard Cochran Link: https://patch.msgid.link/20241003101506.769418-1-maheshb@google.com Signed-off-by: Jakub Kicinski Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/ptp/testptp.c | 62 ++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c index 011252fe238c..58064151f2c8 100644 --- a/tools/testing/selftests/ptp/testptp.c +++ b/tools/testing/selftests/ptp/testptp.c @@ -146,6 +146,7 @@ static void usage(char *progname) " -T val set the ptp clock time to 'val' seconds\n" " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n" " -X get a ptp clock cross timestamp\n" + " -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n" " -z test combinations of rising/falling external time stamp flags\n", progname, PTP_MAX_SAMPLES); } @@ -189,6 +190,7 @@ int main(int argc, char *argv[]) int seconds = 0; int settime = 0; int channel = -1; + clockid_t ext_clockid = CLOCK_REALTIME; int64_t t1, t2, tp; int64_t interval, offset; @@ -198,7 +200,7 @@ int main(int argc, char *argv[]) progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; - while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) { + while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) { switch (c) { case 'c': capabilities = 1; @@ -278,6 +280,21 @@ int main(int argc, char *argv[]) case 'X': getcross = 1; break; + case 'y': + if (!strcasecmp(optarg, "realtime")) + ext_clockid = CLOCK_REALTIME; + else if (!strcasecmp(optarg, "monotonic")) + ext_clockid = CLOCK_MONOTONIC; + else if (!strcasecmp(optarg, "monotonic-raw")) + ext_clockid = CLOCK_MONOTONIC_RAW; + else { + fprintf(stderr, + "type needs to be realtime, monotonic or monotonic-raw; was given %s\n", + optarg); + return -1; + } + break; + case 'z': flagtest = 1; break; @@ -566,6 +583,7 @@ int main(int argc, char *argv[]) } soe->n_samples = getextended; + soe->clockid = ext_clockid; if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) { perror("PTP_SYS_OFFSET_EXTENDED"); @@ -574,12 +592,46 @@ int main(int argc, char *argv[]) getextended); for (i = 0; i < getextended; i++) { - printf("sample #%2d: system time before: %lld.%09u\n", - i, soe->ts[i][0].sec, soe->ts[i][0].nsec); + switch (ext_clockid) { + case CLOCK_REALTIME: + printf("sample #%2d: real time before: %lld.%09u\n", + i, soe->ts[i][0].sec, + soe->ts[i][0].nsec); + break; + case CLOCK_MONOTONIC: + printf("sample #%2d: monotonic time before: %lld.%09u\n", + i, soe->ts[i][0].sec, + soe->ts[i][0].nsec); + break; + case CLOCK_MONOTONIC_RAW: + printf("sample #%2d: monotonic-raw time before: %lld.%09u\n", + i, soe->ts[i][0].sec, + soe->ts[i][0].nsec); + break; + default: + break; + } printf(" phc time: %lld.%09u\n", soe->ts[i][1].sec, soe->ts[i][1].nsec); - printf(" system time after: %lld.%09u\n", - soe->ts[i][2].sec, soe->ts[i][2].nsec); + switch (ext_clockid) { + case CLOCK_REALTIME: + printf(" real time after: %lld.%09u\n", + soe->ts[i][2].sec, + soe->ts[i][2].nsec); + break; + case CLOCK_MONOTONIC: + printf(" monotonic time after: %lld.%09u\n", + soe->ts[i][2].sec, + soe->ts[i][2].nsec); + break; + case CLOCK_MONOTONIC_RAW: + printf(" monotonic-raw time after: %lld.%09u\n", + soe->ts[i][2].sec, + soe->ts[i][2].nsec); + break; + default: + break; + } } } -- Gitee From bbb7eeb83936a6b3c043cb29b42c3227a7dc888d Mon Sep 17 00:00:00 2001 From: Wojtek Wasko Date: Tue, 4 Mar 2025 00:13:45 +0800 Subject: [PATCH 1082/1449] testptp: Add option to open PHC in readonly mode ANBZ: #35228 commit 8d9f22c570ba302d8e861915b749fe88ab7442fb stable. commit 76868642e42795353106197abf9c607ad80f4c9e upstream. PTP Hardware Clocks no longer require WRITE permission to perform readonly operations, such as listing device capabilities or listening to EXTTS events once they have been enabled by a process with WRITE permissions. Add '-r' option to testptp to open the PHC in readonly mode instead of the default read-write mode. Skip enabling EXTTS if readonly mode is requested. Acked-by: Richard Cochran Reviewed-by: Vadim Fedorenko Signed-off-by: Wojtek Wasko Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/ptp/testptp.c | 37 +++++++++++++++++---------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c index 58064151f2c8..edc08a4433fd 100644 --- a/tools/testing/selftests/ptp/testptp.c +++ b/tools/testing/selftests/ptp/testptp.c @@ -140,6 +140,7 @@ static void usage(char *progname) " -H val set output phase to 'val' nanoseconds (requires -p)\n" " -w val set output pulse width to 'val' nanoseconds (requires -p)\n" " -P val enable or disable (val=1|0) the system clock PPS\n" + " -r open the ptp clock in readonly mode\n" " -s set the ptp clock time from the system time\n" " -S set the system time from the ptp clock time\n" " -t val shift the ptp clock time by 'val' seconds\n" @@ -188,6 +189,7 @@ int main(int argc, char *argv[]) int pin_index = -1, pin_func; int pps = -1; int seconds = 0; + int readonly = 0; int settime = 0; int channel = -1; clockid_t ext_clockid = CLOCK_REALTIME; @@ -200,7 +202,7 @@ int main(int argc, char *argv[]) progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; - while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) { + while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) { switch (c) { case 'c': capabilities = 1; @@ -252,6 +254,9 @@ int main(int argc, char *argv[]) case 'P': pps = atoi(optarg); break; + case 'r': + readonly = 1; + break; case 's': settime = 1; break; @@ -308,7 +313,7 @@ int main(int argc, char *argv[]) } } - fd = open(device, O_RDWR); + fd = open(device, readonly ? O_RDONLY : O_RDWR); if (fd < 0) { fprintf(stderr, "opening %s: %s\n", device, strerror(errno)); return -1; @@ -436,14 +441,16 @@ int main(int argc, char *argv[]) } if (extts) { - memset(&extts_request, 0, sizeof(extts_request)); - extts_request.index = index; - extts_request.flags = PTP_ENABLE_FEATURE; - if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { - perror("PTP_EXTTS_REQUEST"); - extts = 0; - } else { - puts("external time stamp request okay"); + if (!readonly) { + memset(&extts_request, 0, sizeof(extts_request)); + extts_request.index = index; + extts_request.flags = PTP_ENABLE_FEATURE; + if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { + perror("PTP_EXTTS_REQUEST"); + extts = 0; + } else { + puts("external time stamp request okay"); + } } for (; extts; extts--) { cnt = read(fd, &event, sizeof(event)); @@ -455,10 +462,12 @@ int main(int argc, char *argv[]) event.t.sec, event.t.nsec); fflush(stdout); } - /* Disable the feature again. */ - extts_request.flags = 0; - if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { - perror("PTP_EXTTS_REQUEST"); + if (!readonly) { + /* Disable the feature again. */ + extts_request.flags = 0; + if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) { + perror("PTP_EXTTS_REQUEST"); + } } } -- Gitee From 59e2e9b2db06e9f46ba146d3d4fa9eb937a96c14 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Wed, 3 Dec 2025 01:36:22 +0800 Subject: [PATCH 1083/1449] arm64: dts: qcom: sc8280xp: Add missing VDD_MXC links ANBZ: #35228 commit 11536f3371f4a4ebf5b388daa09768e646adbef4 stable. commit 868b979c5328b867c95a6d5a93ba13ad0d3cd2f1 upstream. To make sure that power rail is voted for, wire it up to its consumers. Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform") Signed-off-by: Konrad Dybcio Reviewed-by: Ulf Hansson Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-3-46cdf47a829e@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi index 3e70e79ce24b..8472e00bde5a 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -4412,8 +4412,12 @@ remoteproc_nsp0: remoteproc@1b300000 { clocks = <&rpmhcc RPMH_CXO_CLK>; clock-names = "xo"; - power-domains = <&rpmhpd SC8280XP_NSP>; - power-domain-names = "nsp"; + power-domains = <&rpmhpd SC8280XP_NSP>, + <&rpmhpd SC8280XP_CX>, + <&rpmhpd SC8280XP_MXC>; + power-domain-names = "nsp", + "cx", + "mxc"; memory-region = <&pil_nsp0_mem>; @@ -4543,8 +4547,12 @@ remoteproc_nsp1: remoteproc@21300000 { clocks = <&rpmhcc RPMH_CXO_CLK>; clock-names = "xo"; - power-domains = <&rpmhpd SC8280XP_NSP>; - power-domain-names = "nsp"; + power-domains = <&rpmhpd SC8280XP_NSP>, + <&rpmhpd SC8280XP_CX>, + <&rpmhpd SC8280XP_MXC>; + power-domain-names = "nsp", + "cx", + "mxc"; memory-region = <&pil_nsp1_mem>; -- Gitee From 1fd6e447488f42a04eb6b83e66962f3bf48004b2 Mon Sep 17 00:00:00 2001 From: Nuno Das Neves Date: Tue, 20 Feb 2024 22:55:33 +0800 Subject: [PATCH 1084/1449] hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_* ANBZ: #35228 commit fe11f976dd0ad54486acc3ef184a57eb5ac52d29 stable. commit 0e3f7d120086c8b9d6e1ae0dd4917fc529daa1ca upstream. The HV_REGISTER_ are used as arguments to hv_set/get_register(), which delegate to arch-specific mechanisms for getting/setting synthetic Hyper-V MSRs. On arm64, HV_REGISTER_ defines are synthetic VP registers accessed via the get/set vp registers hypercalls. The naming matches the TLFS document, although these register names are not specific to arm64. However, on x86 the prefix HV_REGISTER_ indicates Hyper-V MSRs accessed via rdmsrl()/wrmsrl(). This is not consistent with the TLFS doc, where HV_REGISTER_ is *only* used for used for VP register names used by the get/set register hypercalls. To fix this inconsistency and prevent future confusion, change the arch-generic aliases used by callers of hv_set/get_register() to have the prefix HV_MSR_ instead of HV_REGISTER_. Use the prefix HV_X64_MSR_ for the x86-only Hyper-V MSRs. On x86, the generic HV_MSR_'s point to the corresponding HV_X64_MSR_. Move the arm64 HV_REGISTER_* defines to the asm-generic hyperv-tlfs.h, since these are not specific to arm64. On arm64, the generic HV_MSR_'s point to the corresponding HV_REGISTER_. While at it, rename hv_get/set_registers() and related functions to hv_get/set_msr(), hv_get/set_nested_msr(), etc. These are only used for Hyper-V MSRs and this naming makes that clear. Signed-off-by: Nuno Das Neves Reviewed-by: Wei Liu Reviewed-by: Michael Kelley Link: https://lore.kernel.org/r/1708440933-27125-1-git-send-email-nunodasneves@linux.microsoft.com Signed-off-by: Wei Liu Message-ID: <1708440933-27125-1-git-send-email-nunodasneves@linux.microsoft.com> Stable-dep-of: 49f49d47af67 ("Drivers: hv: Always do Hyper-V panic notification in hv_kmsg_dump()") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/include/asm/hyperv-tlfs.h | 45 ++++----- arch/arm64/include/asm/mshyperv.h | 4 +- arch/x86/hyperv/hv_init.c | 8 +- arch/x86/include/asm/hyperv-tlfs.h | 145 ++++++++++++++------------- arch/x86/include/asm/mshyperv.h | 30 +++--- arch/x86/kernel/cpu/mshyperv.c | 56 +++++------ drivers/clocksource/hyperv_timer.c | 26 ++--- drivers/hv/hv.c | 36 +++---- drivers/hv/hv_common.c | 22 ++-- include/asm-generic/hyperv-tlfs.h | 32 +++++- include/asm-generic/mshyperv.h | 2 +- 11 files changed, 216 insertions(+), 190 deletions(-) diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h index bc6c7ac934a1..54846d1d29c3 100644 --- a/arch/arm64/include/asm/hyperv-tlfs.h +++ b/arch/arm64/include/asm/hyperv-tlfs.h @@ -21,14 +21,6 @@ * byte ordering of Linux running on ARM64, so no special handling is required. */ -/* - * These Hyper-V registers provide information equivalent to the CPUID - * instruction on x86/x64. - */ -#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */ -#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */ -#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */ - /* * Group C Features. See the asm-generic version of hyperv-tlfs.h * for a description of Feature Groups. @@ -41,28 +33,29 @@ #define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13) /* - * Synthetic register definitions equivalent to MSRs on x86/x64 + * To support arch-generic code calling hv_set/get_register: + * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl + * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall */ -#define HV_REGISTER_CRASH_P0 0x00000210 -#define HV_REGISTER_CRASH_P1 0x00000211 -#define HV_REGISTER_CRASH_P2 0x00000212 -#define HV_REGISTER_CRASH_P3 0x00000213 -#define HV_REGISTER_CRASH_P4 0x00000214 -#define HV_REGISTER_CRASH_CTL 0x00000215 +#define HV_MSR_CRASH_P0 (HV_REGISTER_CRASH_P0) +#define HV_MSR_CRASH_P1 (HV_REGISTER_CRASH_P1) +#define HV_MSR_CRASH_P2 (HV_REGISTER_CRASH_P2) +#define HV_MSR_CRASH_P3 (HV_REGISTER_CRASH_P3) +#define HV_MSR_CRASH_P4 (HV_REGISTER_CRASH_P4) +#define HV_MSR_CRASH_CTL (HV_REGISTER_CRASH_CTL) -#define HV_REGISTER_GUEST_OSID 0x00090002 -#define HV_REGISTER_VP_INDEX 0x00090003 -#define HV_REGISTER_TIME_REF_COUNT 0x00090004 -#define HV_REGISTER_REFERENCE_TSC 0x00090017 +#define HV_MSR_VP_INDEX (HV_REGISTER_VP_INDEX) +#define HV_MSR_TIME_REF_COUNT (HV_REGISTER_TIME_REF_COUNT) +#define HV_MSR_REFERENCE_TSC (HV_REGISTER_REFERENCE_TSC) -#define HV_REGISTER_SINT0 0x000A0000 -#define HV_REGISTER_SCONTROL 0x000A0010 -#define HV_REGISTER_SIEFP 0x000A0012 -#define HV_REGISTER_SIMP 0x000A0013 -#define HV_REGISTER_EOM 0x000A0014 +#define HV_MSR_SINT0 (HV_REGISTER_SINT0) +#define HV_MSR_SCONTROL (HV_REGISTER_SCONTROL) +#define HV_MSR_SIEFP (HV_REGISTER_SIEFP) +#define HV_MSR_SIMP (HV_REGISTER_SIMP) +#define HV_MSR_EOM (HV_REGISTER_EOM) -#define HV_REGISTER_STIMER0_CONFIG 0x000B0000 -#define HV_REGISTER_STIMER0_COUNT 0x000B0001 +#define HV_MSR_STIMER0_CONFIG (HV_REGISTER_STIMER0_CONFIG) +#define HV_MSR_STIMER0_COUNT (HV_REGISTER_STIMER0_COUNT) union hv_msi_entry { u64 as_uint64[2]; diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h index 20070a847304..a975e1a689dd 100644 --- a/arch/arm64/include/asm/mshyperv.h +++ b/arch/arm64/include/asm/mshyperv.h @@ -31,12 +31,12 @@ void hv_set_vpreg(u32 reg, u64 value); u64 hv_get_vpreg(u32 reg); void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result); -static inline void hv_set_register(unsigned int reg, u64 value) +static inline void hv_set_msr(unsigned int reg, u64 value) { hv_set_vpreg(reg, value); } -static inline u64 hv_get_register(unsigned int reg) +static inline u64 hv_get_msr(unsigned int reg) { return hv_get_vpreg(reg); } diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index d1e2d12279e2..95eada2994e1 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -664,14 +664,14 @@ void hyperv_cleanup(void) hv_hypercall_pg = NULL; /* Reset the hypercall page */ - hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL); + hypercall_msr.as_uint64 = hv_get_msr(HV_X64_MSR_HYPERCALL); hypercall_msr.enable = 0; - hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); + hv_set_msr(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); /* Reset the TSC page */ - tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC); + tsc_msr.as_uint64 = hv_get_msr(HV_X64_MSR_REFERENCE_TSC); tsc_msr.enable = 0; - hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); + hv_set_msr(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); } void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index 2ff26f53cd62..3787d26810c1 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -182,7 +182,7 @@ enum hv_isolation_type { #define HV_X64_MSR_HYPERCALL 0x40000001 /* MSR used to provide vcpu index */ -#define HV_REGISTER_VP_INDEX 0x40000002 +#define HV_X64_MSR_VP_INDEX 0x40000002 /* MSR used to reset the guest OS. */ #define HV_X64_MSR_RESET 0x40000003 @@ -191,10 +191,10 @@ enum hv_isolation_type { #define HV_X64_MSR_VP_RUNTIME 0x40000010 /* MSR used to read the per-partition time reference counter */ -#define HV_REGISTER_TIME_REF_COUNT 0x40000020 +#define HV_X64_MSR_TIME_REF_COUNT 0x40000020 /* A partition's reference time stamp counter (TSC) page */ -#define HV_REGISTER_REFERENCE_TSC 0x40000021 +#define HV_X64_MSR_REFERENCE_TSC 0x40000021 /* MSR used to retrieve the TSC frequency */ #define HV_X64_MSR_TSC_FREQUENCY 0x40000022 @@ -209,61 +209,61 @@ enum hv_isolation_type { #define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073 /* Define synthetic interrupt controller model specific registers. */ -#define HV_REGISTER_SCONTROL 0x40000080 -#define HV_REGISTER_SVERSION 0x40000081 -#define HV_REGISTER_SIEFP 0x40000082 -#define HV_REGISTER_SIMP 0x40000083 -#define HV_REGISTER_EOM 0x40000084 -#define HV_REGISTER_SINT0 0x40000090 -#define HV_REGISTER_SINT1 0x40000091 -#define HV_REGISTER_SINT2 0x40000092 -#define HV_REGISTER_SINT3 0x40000093 -#define HV_REGISTER_SINT4 0x40000094 -#define HV_REGISTER_SINT5 0x40000095 -#define HV_REGISTER_SINT6 0x40000096 -#define HV_REGISTER_SINT7 0x40000097 -#define HV_REGISTER_SINT8 0x40000098 -#define HV_REGISTER_SINT9 0x40000099 -#define HV_REGISTER_SINT10 0x4000009A -#define HV_REGISTER_SINT11 0x4000009B -#define HV_REGISTER_SINT12 0x4000009C -#define HV_REGISTER_SINT13 0x4000009D -#define HV_REGISTER_SINT14 0x4000009E -#define HV_REGISTER_SINT15 0x4000009F +#define HV_X64_MSR_SCONTROL 0x40000080 +#define HV_X64_MSR_SVERSION 0x40000081 +#define HV_X64_MSR_SIEFP 0x40000082 +#define HV_X64_MSR_SIMP 0x40000083 +#define HV_X64_MSR_EOM 0x40000084 +#define HV_X64_MSR_SINT0 0x40000090 +#define HV_X64_MSR_SINT1 0x40000091 +#define HV_X64_MSR_SINT2 0x40000092 +#define HV_X64_MSR_SINT3 0x40000093 +#define HV_X64_MSR_SINT4 0x40000094 +#define HV_X64_MSR_SINT5 0x40000095 +#define HV_X64_MSR_SINT6 0x40000096 +#define HV_X64_MSR_SINT7 0x40000097 +#define HV_X64_MSR_SINT8 0x40000098 +#define HV_X64_MSR_SINT9 0x40000099 +#define HV_X64_MSR_SINT10 0x4000009A +#define HV_X64_MSR_SINT11 0x4000009B +#define HV_X64_MSR_SINT12 0x4000009C +#define HV_X64_MSR_SINT13 0x4000009D +#define HV_X64_MSR_SINT14 0x4000009E +#define HV_X64_MSR_SINT15 0x4000009F /* * Define synthetic interrupt controller model specific registers for * nested hypervisor. */ -#define HV_REGISTER_NESTED_SCONTROL 0x40001080 -#define HV_REGISTER_NESTED_SVERSION 0x40001081 -#define HV_REGISTER_NESTED_SIEFP 0x40001082 -#define HV_REGISTER_NESTED_SIMP 0x40001083 -#define HV_REGISTER_NESTED_EOM 0x40001084 -#define HV_REGISTER_NESTED_SINT0 0x40001090 +#define HV_X64_MSR_NESTED_SCONTROL 0x40001080 +#define HV_X64_MSR_NESTED_SVERSION 0x40001081 +#define HV_X64_MSR_NESTED_SIEFP 0x40001082 +#define HV_X64_MSR_NESTED_SIMP 0x40001083 +#define HV_X64_MSR_NESTED_EOM 0x40001084 +#define HV_X64_MSR_NESTED_SINT0 0x40001090 /* * Synthetic Timer MSRs. Four timers per vcpu. */ -#define HV_REGISTER_STIMER0_CONFIG 0x400000B0 -#define HV_REGISTER_STIMER0_COUNT 0x400000B1 -#define HV_REGISTER_STIMER1_CONFIG 0x400000B2 -#define HV_REGISTER_STIMER1_COUNT 0x400000B3 -#define HV_REGISTER_STIMER2_CONFIG 0x400000B4 -#define HV_REGISTER_STIMER2_COUNT 0x400000B5 -#define HV_REGISTER_STIMER3_CONFIG 0x400000B6 -#define HV_REGISTER_STIMER3_COUNT 0x400000B7 +#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0 +#define HV_X64_MSR_STIMER0_COUNT 0x400000B1 +#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2 +#define HV_X64_MSR_STIMER1_COUNT 0x400000B3 +#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4 +#define HV_X64_MSR_STIMER2_COUNT 0x400000B5 +#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 +#define HV_X64_MSR_STIMER3_COUNT 0x400000B7 /* Hyper-V guest idle MSR */ #define HV_X64_MSR_GUEST_IDLE 0x400000F0 /* Hyper-V guest crash notification MSR's */ -#define HV_REGISTER_CRASH_P0 0x40000100 -#define HV_REGISTER_CRASH_P1 0x40000101 -#define HV_REGISTER_CRASH_P2 0x40000102 -#define HV_REGISTER_CRASH_P3 0x40000103 -#define HV_REGISTER_CRASH_P4 0x40000104 -#define HV_REGISTER_CRASH_CTL 0x40000105 +#define HV_X64_MSR_CRASH_P0 0x40000100 +#define HV_X64_MSR_CRASH_P1 0x40000101 +#define HV_X64_MSR_CRASH_P2 0x40000102 +#define HV_X64_MSR_CRASH_P3 0x40000103 +#define HV_X64_MSR_CRASH_P4 0x40000104 +#define HV_X64_MSR_CRASH_CTL 0x40000105 /* TSC emulation after migration */ #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 @@ -276,31 +276,38 @@ enum hv_isolation_type { /* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */ #define HV_EXPOSE_INVARIANT_TSC BIT_ULL(0) -/* Register name aliases for temporary compatibility */ -#define HV_X64_MSR_STIMER0_COUNT HV_REGISTER_STIMER0_COUNT -#define HV_X64_MSR_STIMER0_CONFIG HV_REGISTER_STIMER0_CONFIG -#define HV_X64_MSR_STIMER1_COUNT HV_REGISTER_STIMER1_COUNT -#define HV_X64_MSR_STIMER1_CONFIG HV_REGISTER_STIMER1_CONFIG -#define HV_X64_MSR_STIMER2_COUNT HV_REGISTER_STIMER2_COUNT -#define HV_X64_MSR_STIMER2_CONFIG HV_REGISTER_STIMER2_CONFIG -#define HV_X64_MSR_STIMER3_COUNT HV_REGISTER_STIMER3_COUNT -#define HV_X64_MSR_STIMER3_CONFIG HV_REGISTER_STIMER3_CONFIG -#define HV_X64_MSR_SCONTROL HV_REGISTER_SCONTROL -#define HV_X64_MSR_SVERSION HV_REGISTER_SVERSION -#define HV_X64_MSR_SIMP HV_REGISTER_SIMP -#define HV_X64_MSR_SIEFP HV_REGISTER_SIEFP -#define HV_X64_MSR_VP_INDEX HV_REGISTER_VP_INDEX -#define HV_X64_MSR_EOM HV_REGISTER_EOM -#define HV_X64_MSR_SINT0 HV_REGISTER_SINT0 -#define HV_X64_MSR_SINT15 HV_REGISTER_SINT15 -#define HV_X64_MSR_CRASH_P0 HV_REGISTER_CRASH_P0 -#define HV_X64_MSR_CRASH_P1 HV_REGISTER_CRASH_P1 -#define HV_X64_MSR_CRASH_P2 HV_REGISTER_CRASH_P2 -#define HV_X64_MSR_CRASH_P3 HV_REGISTER_CRASH_P3 -#define HV_X64_MSR_CRASH_P4 HV_REGISTER_CRASH_P4 -#define HV_X64_MSR_CRASH_CTL HV_REGISTER_CRASH_CTL -#define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT -#define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC +/* + * To support arch-generic code calling hv_set/get_register: + * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl + * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall + */ +#define HV_MSR_CRASH_P0 (HV_X64_MSR_CRASH_P0) +#define HV_MSR_CRASH_P1 (HV_X64_MSR_CRASH_P1) +#define HV_MSR_CRASH_P2 (HV_X64_MSR_CRASH_P2) +#define HV_MSR_CRASH_P3 (HV_X64_MSR_CRASH_P3) +#define HV_MSR_CRASH_P4 (HV_X64_MSR_CRASH_P4) +#define HV_MSR_CRASH_CTL (HV_X64_MSR_CRASH_CTL) + +#define HV_MSR_VP_INDEX (HV_X64_MSR_VP_INDEX) +#define HV_MSR_TIME_REF_COUNT (HV_X64_MSR_TIME_REF_COUNT) +#define HV_MSR_REFERENCE_TSC (HV_X64_MSR_REFERENCE_TSC) + +#define HV_MSR_SINT0 (HV_X64_MSR_SINT0) +#define HV_MSR_SVERSION (HV_X64_MSR_SVERSION) +#define HV_MSR_SCONTROL (HV_X64_MSR_SCONTROL) +#define HV_MSR_SIEFP (HV_X64_MSR_SIEFP) +#define HV_MSR_SIMP (HV_X64_MSR_SIMP) +#define HV_MSR_EOM (HV_X64_MSR_EOM) + +#define HV_MSR_NESTED_SCONTROL (HV_X64_MSR_NESTED_SCONTROL) +#define HV_MSR_NESTED_SVERSION (HV_X64_MSR_NESTED_SVERSION) +#define HV_MSR_NESTED_SIEFP (HV_X64_MSR_NESTED_SIEFP) +#define HV_MSR_NESTED_SIMP (HV_X64_MSR_NESTED_SIMP) +#define HV_MSR_NESTED_EOM (HV_X64_MSR_NESTED_EOM) +#define HV_MSR_NESTED_SINT0 (HV_X64_MSR_NESTED_SINT0) + +#define HV_MSR_STIMER0_CONFIG (HV_X64_MSR_STIMER0_CONFIG) +#define HV_MSR_STIMER0_COUNT (HV_X64_MSR_STIMER0_COUNT) /* * Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index b31d0b643b3a..5f0bc6a6d025 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -292,24 +292,24 @@ static inline void hv_ivm_msr_write(u64 msr, u64 value) {} static inline void hv_ivm_msr_read(u64 msr, u64 *value) {} #endif -static inline bool hv_is_synic_reg(unsigned int reg) +static inline bool hv_is_synic_msr(unsigned int reg) { - return (reg >= HV_REGISTER_SCONTROL) && - (reg <= HV_REGISTER_SINT15); + return (reg >= HV_X64_MSR_SCONTROL) && + (reg <= HV_X64_MSR_SINT15); } -static inline bool hv_is_sint_reg(unsigned int reg) +static inline bool hv_is_sint_msr(unsigned int reg) { - return (reg >= HV_REGISTER_SINT0) && - (reg <= HV_REGISTER_SINT15); + return (reg >= HV_X64_MSR_SINT0) && + (reg <= HV_X64_MSR_SINT15); } -u64 hv_get_register(unsigned int reg); -void hv_set_register(unsigned int reg, u64 value); -u64 hv_get_non_nested_register(unsigned int reg); -void hv_set_non_nested_register(unsigned int reg, u64 value); +u64 hv_get_msr(unsigned int reg); +void hv_set_msr(unsigned int reg, u64 value); +u64 hv_get_non_nested_msr(unsigned int reg); +void hv_set_non_nested_msr(unsigned int reg, u64 value); -static __always_inline u64 hv_raw_get_register(unsigned int reg) +static __always_inline u64 hv_raw_get_msr(unsigned int reg) { return __rdmsr(reg); } @@ -330,10 +330,10 @@ static inline int hyperv_flush_guest_mapping_range(u64 as, { return -1; } -static inline void hv_set_register(unsigned int reg, u64 value) { } -static inline u64 hv_get_register(unsigned int reg) { return 0; } -static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { } -static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; } +static inline void hv_set_msr(unsigned int reg, u64 value) { } +static inline u64 hv_get_msr(unsigned int reg) { return 0; } +static inline void hv_set_non_nested_msr(unsigned int reg, u64 value) { } +static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; } #endif /* CONFIG_HYPERV */ diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index e709070eed70..fc692125d82f 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -44,70 +44,70 @@ bool hyperv_paravisor_present __ro_after_init; EXPORT_SYMBOL_GPL(hyperv_paravisor_present); #if IS_ENABLED(CONFIG_HYPERV) -static inline unsigned int hv_get_nested_reg(unsigned int reg) +static inline unsigned int hv_get_nested_msr(unsigned int reg) { - if (hv_is_sint_reg(reg)) - return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0; + if (hv_is_sint_msr(reg)) + return reg - HV_X64_MSR_SINT0 + HV_X64_MSR_NESTED_SINT0; switch (reg) { - case HV_REGISTER_SIMP: - return HV_REGISTER_NESTED_SIMP; - case HV_REGISTER_SIEFP: - return HV_REGISTER_NESTED_SIEFP; - case HV_REGISTER_SVERSION: - return HV_REGISTER_NESTED_SVERSION; - case HV_REGISTER_SCONTROL: - return HV_REGISTER_NESTED_SCONTROL; - case HV_REGISTER_EOM: - return HV_REGISTER_NESTED_EOM; + case HV_X64_MSR_SIMP: + return HV_X64_MSR_NESTED_SIMP; + case HV_X64_MSR_SIEFP: + return HV_X64_MSR_NESTED_SIEFP; + case HV_X64_MSR_SVERSION: + return HV_X64_MSR_NESTED_SVERSION; + case HV_X64_MSR_SCONTROL: + return HV_X64_MSR_NESTED_SCONTROL; + case HV_X64_MSR_EOM: + return HV_X64_MSR_NESTED_EOM; default: return reg; } } -u64 hv_get_non_nested_register(unsigned int reg) +u64 hv_get_non_nested_msr(unsigned int reg) { u64 value; - if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) + if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) hv_ivm_msr_read(reg, &value); else rdmsrl(reg, value); return value; } -EXPORT_SYMBOL_GPL(hv_get_non_nested_register); +EXPORT_SYMBOL_GPL(hv_get_non_nested_msr); -void hv_set_non_nested_register(unsigned int reg, u64 value) +void hv_set_non_nested_msr(unsigned int reg, u64 value) { - if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) { + if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) { hv_ivm_msr_write(reg, value); /* Write proxy bit via wrmsl instruction */ - if (hv_is_sint_reg(reg)) + if (hv_is_sint_msr(reg)) wrmsrl(reg, value | 1 << 20); } else { wrmsrl(reg, value); } } -EXPORT_SYMBOL_GPL(hv_set_non_nested_register); +EXPORT_SYMBOL_GPL(hv_set_non_nested_msr); -u64 hv_get_register(unsigned int reg) +u64 hv_get_msr(unsigned int reg) { if (hv_nested) - reg = hv_get_nested_reg(reg); + reg = hv_get_nested_msr(reg); - return hv_get_non_nested_register(reg); + return hv_get_non_nested_msr(reg); } -EXPORT_SYMBOL_GPL(hv_get_register); +EXPORT_SYMBOL_GPL(hv_get_msr); -void hv_set_register(unsigned int reg, u64 value) +void hv_set_msr(unsigned int reg, u64 value) { if (hv_nested) - reg = hv_get_nested_reg(reg); + reg = hv_get_nested_msr(reg); - hv_set_non_nested_register(reg, value); + hv_set_non_nested_msr(reg, value); } -EXPORT_SYMBOL_GPL(hv_set_register); +EXPORT_SYMBOL_GPL(hv_set_msr); static void (*vmbus_handler)(void); static void (*hv_stimer0_handler)(void); diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c index 5eec1457e139..51ee0a756681 100644 --- a/drivers/clocksource/hyperv_timer.c +++ b/drivers/clocksource/hyperv_timer.c @@ -82,14 +82,14 @@ static int hv_ce_set_next_event(unsigned long delta, current_tick = hv_read_reference_counter(); current_tick += delta; - hv_set_register(HV_REGISTER_STIMER0_COUNT, current_tick); + hv_set_msr(HV_MSR_STIMER0_COUNT, current_tick); return 0; } static int hv_ce_shutdown(struct clock_event_device *evt) { - hv_set_register(HV_REGISTER_STIMER0_COUNT, 0); - hv_set_register(HV_REGISTER_STIMER0_CONFIG, 0); + hv_set_msr(HV_MSR_STIMER0_COUNT, 0); + hv_set_msr(HV_MSR_STIMER0_CONFIG, 0); if (direct_mode_enabled && stimer0_irq >= 0) disable_percpu_irq(stimer0_irq); @@ -120,7 +120,7 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt) timer_cfg.direct_mode = 0; timer_cfg.sintx = stimer0_message_sint; } - hv_set_register(HV_REGISTER_STIMER0_CONFIG, timer_cfg.as_uint64); + hv_set_msr(HV_MSR_STIMER0_CONFIG, timer_cfg.as_uint64); return 0; } @@ -373,11 +373,11 @@ static __always_inline u64 read_hv_clock_msr(void) * is set to 0 when the partition is created and is incremented in 100 * nanosecond units. * - * Use hv_raw_get_register() because this function is used from - * noinstr. Notable; while HV_REGISTER_TIME_REF_COUNT is a synthetic + * Use hv_raw_get_msr() because this function is used from + * noinstr. Notable; while HV_MSR_TIME_REF_COUNT is a synthetic * register it doesn't need the GHCB path. */ - return hv_raw_get_register(HV_REGISTER_TIME_REF_COUNT); + return hv_raw_get_msr(HV_MSR_TIME_REF_COUNT); } /* @@ -440,9 +440,9 @@ static void suspend_hv_clock_tsc(struct clocksource *arg) union hv_reference_tsc_msr tsc_msr; /* Disable the TSC page */ - tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); + tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC); tsc_msr.enable = 0; - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); + hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64); } @@ -451,10 +451,10 @@ static void resume_hv_clock_tsc(struct clocksource *arg) union hv_reference_tsc_msr tsc_msr; /* Re-enable the TSC page */ - tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); + tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC); tsc_msr.enable = 1; tsc_msr.pfn = tsc_pfn; - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); + hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64); } /* @@ -567,14 +567,14 @@ static void __init hv_init_tsc_clocksource(void) * thus TSC clocksource will work even without the real TSC page * mapped. */ - tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); + tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC); if (hv_root_partition) tsc_pfn = tsc_msr.pfn; else tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page)); tsc_msr.enable = 1; tsc_msr.pfn = tsc_pfn; - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); + hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64); clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100); diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 51e5018ac9b2..a8ad728354cb 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -270,7 +270,7 @@ void hv_synic_enable_regs(unsigned int cpu) union hv_synic_scontrol sctrl; /* Setup the Synic's message page */ - simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP); + simp.as_uint64 = hv_get_msr(HV_MSR_SIMP); simp.simp_enabled = 1; if (ms_hyperv.paravisor_present || hv_root_partition) { @@ -286,10 +286,10 @@ void hv_synic_enable_regs(unsigned int cpu) >> HV_HYP_PAGE_SHIFT; } - hv_set_register(HV_REGISTER_SIMP, simp.as_uint64); + hv_set_msr(HV_MSR_SIMP, simp.as_uint64); /* Setup the Synic's event page */ - siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP); + siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP); siefp.siefp_enabled = 1; if (ms_hyperv.paravisor_present || hv_root_partition) { @@ -305,13 +305,12 @@ void hv_synic_enable_regs(unsigned int cpu) >> HV_HYP_PAGE_SHIFT; } - hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64); + hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64); /* Setup the shared SINT. */ if (vmbus_irq != -1) enable_percpu_irq(vmbus_irq, 0); - shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 + - VMBUS_MESSAGE_SINT); + shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT); shared_sint.vector = vmbus_interrupt; shared_sint.masked = false; @@ -326,14 +325,13 @@ void hv_synic_enable_regs(unsigned int cpu) #else shared_sint.auto_eoi = 0; #endif - hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT, - shared_sint.as_uint64); + hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); /* Enable the global synic bit */ - sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL); + sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL); sctrl.enable = 1; - hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64); + hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64); } int hv_synic_init(unsigned int cpu) @@ -357,17 +355,15 @@ void hv_synic_disable_regs(unsigned int cpu) union hv_synic_siefp siefp; union hv_synic_scontrol sctrl; - shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 + - VMBUS_MESSAGE_SINT); + shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT); shared_sint.masked = 1; /* Need to correctly cleanup in the case of SMP!!! */ /* Disable the interrupt */ - hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT, - shared_sint.as_uint64); + hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); - simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP); + simp.as_uint64 = hv_get_msr(HV_MSR_SIMP); /* * In Isolation VM, sim and sief pages are allocated by * paravisor. These pages also will be used by kdump @@ -382,9 +378,9 @@ void hv_synic_disable_regs(unsigned int cpu) simp.base_simp_gpa = 0; } - hv_set_register(HV_REGISTER_SIMP, simp.as_uint64); + hv_set_msr(HV_MSR_SIMP, simp.as_uint64); - siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP); + siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP); siefp.siefp_enabled = 0; if (ms_hyperv.paravisor_present || hv_root_partition) { @@ -394,12 +390,12 @@ void hv_synic_disable_regs(unsigned int cpu) siefp.base_siefp_gpa = 0; } - hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64); + hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64); /* Disable the global synic bit */ - sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL); + sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL); sctrl.enable = 0; - hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64); + hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64); if (vmbus_irq != -1) disable_percpu_irq(vmbus_irq); diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c index 5561714313d7..0935c4f0b80d 100644 --- a/drivers/hv/hv_common.c +++ b/drivers/hv/hv_common.c @@ -228,19 +228,19 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper, * contain the size of the panic data in that page. Rest of the * registers are no-op when the NOTIFY_MSG flag is set. */ - hv_set_register(HV_REGISTER_CRASH_P0, 0); - hv_set_register(HV_REGISTER_CRASH_P1, 0); - hv_set_register(HV_REGISTER_CRASH_P2, 0); - hv_set_register(HV_REGISTER_CRASH_P3, virt_to_phys(hv_panic_page)); - hv_set_register(HV_REGISTER_CRASH_P4, bytes_written); + hv_set_msr(HV_MSR_CRASH_P0, 0); + hv_set_msr(HV_MSR_CRASH_P1, 0); + hv_set_msr(HV_MSR_CRASH_P2, 0); + hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page)); + hv_set_msr(HV_MSR_CRASH_P4, bytes_written); /* * Let Hyper-V know there is crash data available along with * the panic message. */ - hv_set_register(HV_REGISTER_CRASH_CTL, - (HV_CRASH_CTL_CRASH_NOTIFY | - HV_CRASH_CTL_CRASH_NOTIFY_MSG)); + hv_set_msr(HV_MSR_CRASH_CTL, + (HV_CRASH_CTL_CRASH_NOTIFY | + HV_CRASH_CTL_CRASH_NOTIFY_MSG)); } static struct kmsg_dumper hv_kmsg_dumper = { @@ -311,7 +311,7 @@ int __init hv_common_init(void) * Register for panic kmsg callback only if the right * capability is supported by the hypervisor. */ - hyperv_crash_ctl = hv_get_register(HV_REGISTER_CRASH_CTL); + hyperv_crash_ctl = hv_get_msr(HV_MSR_CRASH_CTL); if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG) hv_kmsg_dump_register(); @@ -410,7 +410,7 @@ int hv_common_cpu_init(unsigned int cpu) *inputarg = mem; } - msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX); + msr_vp_index = hv_get_msr(HV_MSR_VP_INDEX); hv_vp_index[cpu] = msr_vp_index; @@ -503,7 +503,7 @@ EXPORT_SYMBOL_GPL(hv_is_hibernation_supported); */ static u64 __hv_read_ref_counter(void) { - return hv_get_register(HV_REGISTER_TIME_REF_COUNT); + return hv_get_msr(HV_MSR_TIME_REF_COUNT); } u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter; diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h index fdac4a1714ec..3d1b31f90ed6 100644 --- a/include/asm-generic/hyperv-tlfs.h +++ b/include/asm-generic/hyperv-tlfs.h @@ -625,6 +625,37 @@ struct hv_retarget_device_interrupt { struct hv_device_interrupt_target int_target; } __packed __aligned(8); +/* + * These Hyper-V registers provide information equivalent to the CPUID + * instruction on x86/x64. + */ +#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */ +#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */ +#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */ + +/* + * Synthetic register definitions equivalent to MSRs on x86/x64 + */ +#define HV_REGISTER_CRASH_P0 0x00000210 +#define HV_REGISTER_CRASH_P1 0x00000211 +#define HV_REGISTER_CRASH_P2 0x00000212 +#define HV_REGISTER_CRASH_P3 0x00000213 +#define HV_REGISTER_CRASH_P4 0x00000214 +#define HV_REGISTER_CRASH_CTL 0x00000215 + +#define HV_REGISTER_GUEST_OSID 0x00090002 +#define HV_REGISTER_VP_INDEX 0x00090003 +#define HV_REGISTER_TIME_REF_COUNT 0x00090004 +#define HV_REGISTER_REFERENCE_TSC 0x00090017 + +#define HV_REGISTER_SINT0 0x000A0000 +#define HV_REGISTER_SCONTROL 0x000A0010 +#define HV_REGISTER_SIEFP 0x000A0012 +#define HV_REGISTER_SIMP 0x000A0013 +#define HV_REGISTER_EOM 0x000A0014 + +#define HV_REGISTER_STIMER0_CONFIG 0x000B0000 +#define HV_REGISTER_STIMER0_COUNT 0x000B0001 /* HvGetVpRegisters hypercall input with variable size reg name list*/ struct hv_get_vp_registers_input { @@ -640,7 +671,6 @@ struct hv_get_vp_registers_input { } element[]; } __packed; - /* HvGetVpRegisters returns an array of these output elements */ struct hv_get_vp_registers_output { union { diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index 430f0ae0dde2..04424a446bb7 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -157,7 +157,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) * possibly deliver another msg from the * hypervisor */ - hv_set_register(HV_REGISTER_EOM, 0); + hv_set_msr(HV_MSR_EOM, 0); } } -- Gitee From 3f3106d12f345682721c7a91ee65efb7f378d4ca Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Thu, 1 Jan 2026 04:14:47 +0800 Subject: [PATCH 1085/1449] Drivers: hv: Always do Hyper-V panic notification in hv_kmsg_dump() ANBZ: #35228 commit 774089dc718f59f9b40d0fb1eb516ddfe4ec25a5 stable. commit 49f49d47af67f8a7b221db1d758fc634242dc91a upstream. hv_kmsg_dump() currently skips the panic notification entirely if it doesn't get any message bytes to pass to Hyper-V due to an error from kmsg_dump_get_buffer(). Skipping the notification is undesirable because it leaves the Hyper-V host uncertain about the state of a panic'ed guest. Fix this by always doing the panic notification, even if bytes_written is zero. Also ensure that bytes_written is initialized, which fixes a kernel test robot warning. The warning is actually bogus because kmsg_dump_get_buffer() happens to set bytes_written even if it fails, and in the kernel test robot's CONFIG_PRINTK not set case, hv_kmsg_dump() is never called. But do the initialization for robustness and to quiet the static checker. Fixes: 9c318a1d9b50 ("Drivers: hv: move panic report code from vmbus to hv early init code") Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/all/202512172103.OcUspn1Z-lkp@intel.com/ Signed-off-by: Michael Kelley Reviewed-by: Roman Kisel Signed-off-by: Wei Liu Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hv/hv_common.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c index 0935c4f0b80d..cf741dfcb0e2 100644 --- a/drivers/hv/hv_common.c +++ b/drivers/hv/hv_common.c @@ -216,13 +216,15 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper, /* * Write dump contents to the page. No need to synchronize; panic should - * be single-threaded. + * be single-threaded. Ignore failures from kmsg_dump_get_buffer() since + * panic notification should be done even if there is no message data. + * Don't assume bytes_written is set in case of failure, so initialize it. */ kmsg_dump_rewind(&iter); - kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE, + bytes_written = 0; + (void)kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE, &bytes_written); - if (!bytes_written) - return; + /* * P3 to contain the physical address of the panic page & P4 to * contain the size of the panic data in that page. Rest of the @@ -231,7 +233,7 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper, hv_set_msr(HV_MSR_CRASH_P0, 0); hv_set_msr(HV_MSR_CRASH_P1, 0); hv_set_msr(HV_MSR_CRASH_P2, 0); - hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page)); + hv_set_msr(HV_MSR_CRASH_P3, bytes_written ? virt_to_phys(hv_panic_page) : 0); hv_set_msr(HV_MSR_CRASH_P4, bytes_written); /* -- Gitee From 974eeeb78d35b4bc21fadfbda2585df562337bbc Mon Sep 17 00:00:00 2001 From: Mark Harmstone Date: Wed, 14 Jan 2026 02:37:56 +0800 Subject: [PATCH 1086/1449] btrfs: fix missing fields in superblock backup with BLOCK_GROUP_TREE ANBZ: #35228 commit ce5ee09c0aeeaa4d01076a577a7055e06890cafb stable. commit 1d8f69f453c2e8a2d99b158e58e02ed65031fa6d upstream. When the BLOCK_GROUP_TREE compat_ro flag is set, the extent root and csum root fields are getting missed. This is because EXTENT_TREE_V2 treated these differently, and when they were split off this special-casing was mistakenly assigned to BGT rather than the rump EXTENT_TREE_V2. There's no reason why the existence of the block group tree should mean that we don't record the details of the last commit's extent root and csum root. Fix the code in backup_super_roots() so that the correct check gets made. Fixes: 1c56ab991903 ("btrfs: separate BLOCK_GROUP_TREE compat RO flag from EXTENT_TREE_V2") Reviewed-by: Qu Wenruo Signed-off-by: Mark Harmstone Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/disk-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7ad1734cbbfc..3c26e91a8055 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1654,7 +1654,7 @@ static void backup_super_roots(struct btrfs_fs_info *info) btrfs_set_backup_chunk_root_level(root_backup, btrfs_header_level(info->chunk_root->node)); - if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) { + if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) { struct btrfs_root *extent_root = btrfs_extent_root(info, 0); struct btrfs_root *csum_root = btrfs_csum_root(info, 0); -- Gitee From 561f2ad458896e8ca93df3a0586ab00e41feb0d7 Mon Sep 17 00:00:00 2001 From: Danila Tikhonov Date: Sun, 17 Sep 2023 01:59:51 +0800 Subject: [PATCH 1087/1449] dt-bindings: power: qcom,rpmpd: Add SM7150 ANBZ: #35228 commit f33305f0925bef3051d6ea951c44c06e5fc03d32 stable. commit 0cd3f86ad558d3f585634e211c6fccbe786cbc28 upstream. Add a compatible for SM7150 platforms. Signed-off-by: Danila Tikhonov Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230916175952.178611-2-danila@jiaxyga.com Signed-off-by: Ulf Hansson Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 9b03c41d3604..53886f02d98a 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -46,6 +46,7 @@ properties: - qcom,sm6125-rpmpd - qcom,sm6350-rpmhpd - qcom,sm6375-rpmpd + - qcom,sm7150-rpmhpd - qcom,sm8150-rpmhpd - qcom,sm8250-rpmhpd - qcom,sm8350-rpmhpd -- Gitee From 65e8497406df8ede40f04b57cfdd781ff377ca92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Pfl=C3=BCger?= Date: Sat, 14 Oct 2023 21:38:21 +0800 Subject: [PATCH 1088/1449] dt-bindings: power: rpmpd: Add MSM8917, MSM8937 and QM215 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 25ebc01125e60d748962a36a38f510f3ab2e7133 stable. commit 61848698288d93a230cab9c0585e726df66f2402 upstream. The MSM8917, MSM8937 and QM215 SoCs have VDDCX and VDDMX power domains controlled in voltage level mode. Define the MSM8937 and QM215 power domains as aliases because these SoCs are similar to MSM8917 and may share some parts of the device tree. Also add the compatibles for these SoCs to the documentation, with qcom,msm8937-rpmpd using qcom,msm8917-rpmpd as a fallback compatible because there are no known differences. QM215 is not compatible with these because it uses different regulators. Signed-off-by: Otto Pflüger Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20231014133823.14088-2-otto.pflueger@abscue.de Signed-off-by: Ulf Hansson Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../devicetree/bindings/power/qcom,rpmpd.yaml | 81 ++++++++++--------- include/dt-bindings/power/qcom-rpmpd.h | 21 +++++ 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 53886f02d98a..d38c762e1280 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -15,43 +15,50 @@ description: properties: compatible: - enum: - - qcom,mdm9607-rpmpd - - qcom,msm8226-rpmpd - - qcom,msm8909-rpmpd - - qcom,msm8916-rpmpd - - qcom,msm8939-rpmpd - - qcom,msm8953-rpmpd - - qcom,msm8976-rpmpd - - qcom,msm8994-rpmpd - - qcom,msm8996-rpmpd - - qcom,msm8998-rpmpd - - qcom,qcm2290-rpmpd - - qcom,qcs404-rpmpd - - qcom,qdu1000-rpmhpd - - qcom,sa8155p-rpmhpd - - qcom,sa8540p-rpmhpd - - qcom,sa8775p-rpmhpd - - qcom,sdm660-rpmpd - - qcom,sc7180-rpmhpd - - qcom,sc7280-rpmhpd - - qcom,sc8180x-rpmhpd - - qcom,sc8280xp-rpmhpd - - qcom,sdm670-rpmhpd - - qcom,sdm845-rpmhpd - - qcom,sdx55-rpmhpd - - qcom,sdx65-rpmhpd - - qcom,sdx75-rpmhpd - - qcom,sm6115-rpmpd - - qcom,sm6125-rpmpd - - qcom,sm6350-rpmhpd - - qcom,sm6375-rpmpd - - qcom,sm7150-rpmhpd - - qcom,sm8150-rpmhpd - - qcom,sm8250-rpmhpd - - qcom,sm8350-rpmhpd - - qcom,sm8450-rpmhpd - - qcom,sm8550-rpmhpd + oneOf: + - enum: + - qcom,mdm9607-rpmpd + - qcom,msm8226-rpmpd + - qcom,msm8909-rpmpd + - qcom,msm8916-rpmpd + - qcom,msm8917-rpmpd + - qcom,msm8939-rpmpd + - qcom,msm8953-rpmpd + - qcom,msm8976-rpmpd + - qcom,msm8994-rpmpd + - qcom,msm8996-rpmpd + - qcom,msm8998-rpmpd + - qcom,qcm2290-rpmpd + - qcom,qcs404-rpmpd + - qcom,qdu1000-rpmhpd + - qcom,qm215-rpmpd + - qcom,sa8155p-rpmhpd + - qcom,sa8540p-rpmhpd + - qcom,sa8775p-rpmhpd + - qcom,sc7180-rpmhpd + - qcom,sc7280-rpmhpd + - qcom,sc8180x-rpmhpd + - qcom,sc8280xp-rpmhpd + - qcom,sdm660-rpmpd + - qcom,sdm670-rpmhpd + - qcom,sdm845-rpmhpd + - qcom,sdx55-rpmhpd + - qcom,sdx65-rpmhpd + - qcom,sdx75-rpmhpd + - qcom,sm6115-rpmpd + - qcom,sm6125-rpmpd + - qcom,sm6350-rpmhpd + - qcom,sm6375-rpmpd + - qcom,sm7150-rpmhpd + - qcom,sm8150-rpmhpd + - qcom,sm8250-rpmhpd + - qcom,sm8350-rpmhpd + - qcom,sm8450-rpmhpd + - qcom,sm8550-rpmhpd + - items: + - enum: + - qcom,msm8937-rpmpd + - const: qcom,msm8917-rpmpd '#power-domain-cells': const: 1 diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 83be996cb5eb..7f4e2983a4c5 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -278,6 +278,27 @@ #define MSM8909_VDDMX MSM8916_VDDMX #define MSM8909_VDDMX_AO MSM8916_VDDMX_AO +/* MSM8917 Power Domain Indexes */ +#define MSM8917_VDDCX 0 +#define MSM8917_VDDCX_AO 1 +#define MSM8917_VDDCX_VFL 2 +#define MSM8917_VDDMX 3 +#define MSM8917_VDDMX_AO 4 + +/* MSM8937 Power Domain Indexes */ +#define MSM8937_VDDCX MSM8917_VDDCX +#define MSM8937_VDDCX_AO MSM8917_VDDCX_AO +#define MSM8937_VDDCX_VFL MSM8917_VDDCX_VFL +#define MSM8937_VDDMX MSM8917_VDDMX +#define MSM8937_VDDMX_AO MSM8917_VDDMX_AO + +/* QM215 Power Domain Indexes */ +#define QM215_VDDCX MSM8917_VDDCX +#define QM215_VDDCX_AO MSM8917_VDDCX_AO +#define QM215_VDDCX_VFL MSM8917_VDDCX_VFL +#define QM215_VDDMX MSM8917_VDDMX +#define QM215_VDDMX_AO MSM8917_VDDMX_AO + /* MSM8953 Power Domain Indexes */ #define MSM8953_VDDMD 0 #define MSM8953_VDDMD_AO 1 -- Gitee From e76651b7ef73e38128501009e8525586c0becb09 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 25 Oct 2023 15:32:02 +0800 Subject: [PATCH 1089/1449] dt-bindings: power: qcom,rpmpd: document the SM8650 RPMh Power Domains ANBZ: #35228 commit ce649f43c49366a72caec38f206c6fe0fdf4223f stable. commit d4d56c079ddd19293b11de1f2309add0b8972af2 upstream. Document the RPMh Power Domains on the SM8650 Platform. Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20231025-topic-sm8650-upstream-rpmpd-v1-1-f25d313104c6@linaro.org Signed-off-by: Ulf Hansson Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 + include/dt-bindings/power/qcom,rpmhpd.h | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index d38c762e1280..2803f7d56821 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -55,6 +55,7 @@ properties: - qcom,sm8350-rpmhpd - qcom,sm8450-rpmhpd - qcom,sm8550-rpmhpd + - qcom,sm8650-rpmhpd - items: - enum: - qcom,msm8937-rpmpd diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h index 7c201a66bc69..0f6a74e09970 100644 --- a/include/dt-bindings/power/qcom,rpmhpd.h +++ b/include/dt-bindings/power/qcom,rpmhpd.h @@ -26,5 +26,6 @@ #define RPMHPD_QPHY 16 #define RPMHPD_DDR 17 #define RPMHPD_XO 18 +#define RPMHPD_NSP2 19 #endif -- Gitee From 31d8edae00da3876ae6cd699251ac672a79b0bf3 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Thu, 23 Nov 2023 18:00:20 +0800 Subject: [PATCH 1090/1449] dt-bindings: power: rpmpd: Update part number to X1E80100 ANBZ: #35228 commit 658e1879ebe68daa128c2eabd8b7dc6fe12947c3 stable. commit 3d123f513af055b4c085b555f9c856bbd7390536 upstream. There was a recent part number update from SC8380XP to X1E80100 and as a result of which the SC8380xp rpmpd bindings introduced is no longer correct. Given that it currently has no users, it was agreed that it can be updated to the correct part number (X1E80100) without causing any binding breakage. Signed-off-by: Sibi Sankar Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20231123100021.10918-2-quic_sibis@quicinc.com Signed-off-by: Ulf Hansson Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 2803f7d56821..2ff246cf8b81 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -56,6 +56,7 @@ properties: - qcom,sm8450-rpmhpd - qcom,sm8550-rpmhpd - qcom,sm8650-rpmhpd + - qcom,x1e80100-rpmhpd - items: - enum: - qcom,msm8937-rpmpd -- Gitee From 5e8ba88f3084e238fb1abee113d3fd153ae7a0c3 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 12 Nov 2024 08:24:43 +0800 Subject: [PATCH 1091/1449] dt-bindings: power: qcom,rpmpd: document the SM8750 RPMh Power Domains ANBZ: #35228 commit 64a0b97df8366bf9bf6e11027e7d3bce6accc47c stable. commit 134e9d035d830aabd1121bcda89f7ee9a476d3a3 upstream. Document the RPMh Power Domains on the SM8750 Platform. Signed-off-by: Taniya Das Signed-off-by: Jishnu Prakash Signed-off-by: Melody Olvera Message-ID: <20241112002444.2802092-2-quic_molvera@quicinc.com> Signed-off-by: Ulf Hansson Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 + include/dt-bindings/power/qcom-rpmpd.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 2ff246cf8b81..bb01bf5663f3 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml @@ -56,6 +56,7 @@ properties: - qcom,sm8450-rpmhpd - qcom,sm8550-rpmhpd - qcom,sm8650-rpmhpd + - qcom,sm8750-rpmhpd - qcom,x1e80100-rpmhpd - items: - enum: diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 7f4e2983a4c5..ced784a8afc1 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -218,6 +218,7 @@ /* SDM845 Power Domain performance levels */ #define RPMH_REGULATOR_LEVEL_RETENTION 16 #define RPMH_REGULATOR_LEVEL_MIN_SVS 48 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50 #define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52 #define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 #define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60 @@ -238,6 +239,7 @@ #define RPMH_REGULATOR_LEVEL_TURBO_L1 416 #define RPMH_REGULATOR_LEVEL_TURBO_L2 432 #define RPMH_REGULATOR_LEVEL_TURBO_L3 448 +#define RPMH_REGULATOR_LEVEL_TURBO_L4 452 #define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 #define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 -- Gitee From 9b26e2b19e4bd99dffbc15cc571142250f1caf00 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Wed, 2 Jul 2025 00:20:45 +0800 Subject: [PATCH 1092/1449] dt-bindings: power: qcom,rpmpd: add Turbo L5 corner ANBZ: #35228 commit 564752b42d137761c6bdf85bd92f642b81c372f8 stable. commit 1c402295c10891988fb2a6fc658e6e95d4852a20 upstream. Update the RPMH level definitions to include TURBO_L5 corner. Acked-by: Krzysztof Kozlowski Signed-off-by: Akhil P Oommen Patchwork: https://patchwork.freedesktop.org/patch/661840/ Signed-off-by: Rob Clark Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/dt-bindings/power/qcom-rpmpd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index ced784a8afc1..73b3655155ec 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -240,6 +240,7 @@ #define RPMH_REGULATOR_LEVEL_TURBO_L2 432 #define RPMH_REGULATOR_LEVEL_TURBO_L3 448 #define RPMH_REGULATOR_LEVEL_TURBO_L4 452 +#define RPMH_REGULATOR_LEVEL_TURBO_L5 456 #define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 #define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 -- Gitee From 4e22b36260fa906bff3667267574017e4a7832e3 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 19 Jul 2025 00:13:39 +0800 Subject: [PATCH 1093/1449] dt-bindings: power: qcom-rpmpd: split RPMh domains definitions ANBZ: #35228 commit 230c9ed464edac0ac2c4fc57173022a0a6023449 stable. commit dcb8d01b65fb5a891ddbbedcbe6eff0b8ec37867 upstream. Historically both RPM and RPMh domain definitions were a part of the same, qcom-rpmpd.h header. Now as we have a separate header for RPMh definitions, qcom,rpmhpd.h, move all RPMh power domain definitions to that header. Signed-off-by: Dmitry Baryshkov Acked-by: Rob Herring (Arm) Reviewed-by: Konrad Dybcio Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20250718-rework-rpmhpd-rpmpd-v1-1-eedca108e540@oss.qualcomm.com Signed-off-by: Ulf Hansson Stable-dep-of: 45e1be5ddec9 ("dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/dt-bindings/power/qcom,rpmhpd.h | 233 ++++++++++++++++++++++++ include/dt-bindings/power/qcom-rpmpd.h | 228 +---------------------- 2 files changed, 234 insertions(+), 227 deletions(-) diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h index 0f6a74e09970..758c3487bd66 100644 --- a/include/dt-bindings/power/qcom,rpmhpd.h +++ b/include/dt-bindings/power/qcom,rpmhpd.h @@ -28,4 +28,237 @@ #define RPMHPD_XO 18 #define RPMHPD_NSP2 19 +/* RPMh Power Domain performance levels */ +#define RPMH_REGULATOR_LEVEL_RETENTION 16 +#define RPMH_REGULATOR_LEVEL_MIN_SVS 48 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60 +#define RPMH_REGULATOR_LEVEL_LOW_SVS 64 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96 +#define RPMH_REGULATOR_LEVEL_SVS 128 +#define RPMH_REGULATOR_LEVEL_SVS_L0 144 +#define RPMH_REGULATOR_LEVEL_SVS_L1 192 +#define RPMH_REGULATOR_LEVEL_SVS_L2 224 +#define RPMH_REGULATOR_LEVEL_NOM 256 +#define RPMH_REGULATOR_LEVEL_NOM_L0 288 +#define RPMH_REGULATOR_LEVEL_NOM_L1 320 +#define RPMH_REGULATOR_LEVEL_NOM_L2 336 +#define RPMH_REGULATOR_LEVEL_TURBO 384 +#define RPMH_REGULATOR_LEVEL_TURBO_L0 400 +#define RPMH_REGULATOR_LEVEL_TURBO_L1 416 +#define RPMH_REGULATOR_LEVEL_TURBO_L2 432 +#define RPMH_REGULATOR_LEVEL_TURBO_L3 448 +#define RPMH_REGULATOR_LEVEL_TURBO_L4 452 +#define RPMH_REGULATOR_LEVEL_TURBO_L5 456 +#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 +#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 + +/* + * Platform-specific power domain bindings. Don't add new entries here, use + * RPMHPD_* above. + */ + +/* SA8775P Power Domain Indexes */ +#define SA8775P_CX 0 +#define SA8775P_CX_AO 1 +#define SA8775P_DDR 2 +#define SA8775P_EBI 3 +#define SA8775P_GFX 4 +#define SA8775P_LCX 5 +#define SA8775P_LMX 6 +#define SA8775P_MMCX 7 +#define SA8775P_MMCX_AO 8 +#define SA8775P_MSS 9 +#define SA8775P_MX 10 +#define SA8775P_MX_AO 11 +#define SA8775P_MXC 12 +#define SA8775P_MXC_AO 13 +#define SA8775P_NSP0 14 +#define SA8775P_NSP1 15 +#define SA8775P_XO 16 + +/* SDM670 Power Domain Indexes */ +#define SDM670_MX 0 +#define SDM670_MX_AO 1 +#define SDM670_CX 2 +#define SDM670_CX_AO 3 +#define SDM670_LMX 4 +#define SDM670_LCX 5 +#define SDM670_GFX 6 +#define SDM670_MSS 7 + +/* SDM845 Power Domain Indexes */ +#define SDM845_EBI 0 +#define SDM845_MX 1 +#define SDM845_MX_AO 2 +#define SDM845_CX 3 +#define SDM845_CX_AO 4 +#define SDM845_LMX 5 +#define SDM845_LCX 6 +#define SDM845_GFX 7 +#define SDM845_MSS 8 + +/* SDX55 Power Domain Indexes */ +#define SDX55_MSS 0 +#define SDX55_MX 1 +#define SDX55_CX 2 + +/* SDX65 Power Domain Indexes */ +#define SDX65_MSS 0 +#define SDX65_MX 1 +#define SDX65_MX_AO 2 +#define SDX65_CX 3 +#define SDX65_CX_AO 4 +#define SDX65_MXC 5 + +/* SM6350 Power Domain Indexes */ +#define SM6350_CX 0 +#define SM6350_GFX 1 +#define SM6350_LCX 2 +#define SM6350_LMX 3 +#define SM6350_MSS 4 +#define SM6350_MX 5 + +/* SM8150 Power Domain Indexes */ +#define SM8150_MSS 0 +#define SM8150_EBI 1 +#define SM8150_LMX 2 +#define SM8150_LCX 3 +#define SM8150_GFX 4 +#define SM8150_MX 5 +#define SM8150_MX_AO 6 +#define SM8150_CX 7 +#define SM8150_CX_AO 8 +#define SM8150_MMCX 9 +#define SM8150_MMCX_AO 10 + +/* SA8155P is a special case, kept for backwards compatibility */ +#define SA8155P_CX SM8150_CX +#define SA8155P_CX_AO SM8150_CX_AO +#define SA8155P_EBI SM8150_EBI +#define SA8155P_GFX SM8150_GFX +#define SA8155P_MSS SM8150_MSS +#define SA8155P_MX SM8150_MX +#define SA8155P_MX_AO SM8150_MX_AO + +/* SM8250 Power Domain Indexes */ +#define SM8250_CX 0 +#define SM8250_CX_AO 1 +#define SM8250_EBI 2 +#define SM8250_GFX 3 +#define SM8250_LCX 4 +#define SM8250_LMX 5 +#define SM8250_MMCX 6 +#define SM8250_MMCX_AO 7 +#define SM8250_MX 8 +#define SM8250_MX_AO 9 + +/* SM8350 Power Domain Indexes */ +#define SM8350_CX 0 +#define SM8350_CX_AO 1 +#define SM8350_EBI 2 +#define SM8350_GFX 3 +#define SM8350_LCX 4 +#define SM8350_LMX 5 +#define SM8350_MMCX 6 +#define SM8350_MMCX_AO 7 +#define SM8350_MX 8 +#define SM8350_MX_AO 9 +#define SM8350_MXC 10 +#define SM8350_MXC_AO 11 +#define SM8350_MSS 12 + +/* SM8450 Power Domain Indexes */ +#define SM8450_CX 0 +#define SM8450_CX_AO 1 +#define SM8450_EBI 2 +#define SM8450_GFX 3 +#define SM8450_LCX 4 +#define SM8450_LMX 5 +#define SM8450_MMCX 6 +#define SM8450_MMCX_AO 7 +#define SM8450_MX 8 +#define SM8450_MX_AO 9 +#define SM8450_MXC 10 +#define SM8450_MXC_AO 11 +#define SM8450_MSS 12 + +/* SM8550 Power Domain Indexes */ +#define SM8550_CX 0 +#define SM8550_CX_AO 1 +#define SM8550_EBI 2 +#define SM8550_GFX 3 +#define SM8550_LCX 4 +#define SM8550_LMX 5 +#define SM8550_MMCX 6 +#define SM8550_MMCX_AO 7 +#define SM8550_MX 8 +#define SM8550_MX_AO 9 +#define SM8550_MXC 10 +#define SM8550_MXC_AO 11 +#define SM8550_MSS 12 +#define SM8550_NSP 13 + +/* QDU1000/QRU1000 Power Domain Indexes */ +#define QDU1000_EBI 0 +#define QDU1000_MSS 1 +#define QDU1000_CX 2 +#define QDU1000_MX 3 + +/* SC7180 Power Domain Indexes */ +#define SC7180_CX 0 +#define SC7180_CX_AO 1 +#define SC7180_GFX 2 +#define SC7180_MX 3 +#define SC7180_MX_AO 4 +#define SC7180_LMX 5 +#define SC7180_LCX 6 +#define SC7180_MSS 7 + +/* SC7280 Power Domain Indexes */ +#define SC7280_CX 0 +#define SC7280_CX_AO 1 +#define SC7280_EBI 2 +#define SC7280_GFX 3 +#define SC7280_MX 4 +#define SC7280_MX_AO 5 +#define SC7280_LMX 6 +#define SC7280_LCX 7 +#define SC7280_MSS 8 + +/* SC8180X Power Domain Indexes */ +#define SC8180X_CX 0 +#define SC8180X_CX_AO 1 +#define SC8180X_EBI 2 +#define SC8180X_GFX 3 +#define SC8180X_LCX 4 +#define SC8180X_LMX 5 +#define SC8180X_MMCX 6 +#define SC8180X_MMCX_AO 7 +#define SC8180X_MSS 8 +#define SC8180X_MX 9 +#define SC8180X_MX_AO 10 + +/* SC8280XP Power Domain Indexes */ +#define SC8280XP_CX 0 +#define SC8280XP_CX_AO 1 +#define SC8280XP_DDR 2 +#define SC8280XP_EBI 3 +#define SC8280XP_GFX 4 +#define SC8280XP_LCX 5 +#define SC8280XP_LMX 6 +#define SC8280XP_MMCX 7 +#define SC8280XP_MMCX_AO 8 +#define SC8280XP_MSS 9 +#define SC8280XP_MX 10 +#define SC8280XP_MXC 12 +#define SC8280XP_MX_AO 11 +#define SC8280XP_NSP 13 +#define SC8280XP_QPHY 14 +#define SC8280XP_XO 15 + #endif diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 73b3655155ec..f160f373be2a 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -4,66 +4,7 @@ #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H #define _DT_BINDINGS_POWER_QCOM_RPMPD_H -/* SA8775P Power Domain Indexes */ -#define SA8775P_CX 0 -#define SA8775P_CX_AO 1 -#define SA8775P_DDR 2 -#define SA8775P_EBI 3 -#define SA8775P_GFX 4 -#define SA8775P_LCX 5 -#define SA8775P_LMX 6 -#define SA8775P_MMCX 7 -#define SA8775P_MMCX_AO 8 -#define SA8775P_MSS 9 -#define SA8775P_MX 10 -#define SA8775P_MX_AO 11 -#define SA8775P_MXC 12 -#define SA8775P_MXC_AO 13 -#define SA8775P_NSP0 14 -#define SA8775P_NSP1 15 -#define SA8775P_XO 16 - -/* SDM670 Power Domain Indexes */ -#define SDM670_MX 0 -#define SDM670_MX_AO 1 -#define SDM670_CX 2 -#define SDM670_CX_AO 3 -#define SDM670_LMX 4 -#define SDM670_LCX 5 -#define SDM670_GFX 6 -#define SDM670_MSS 7 - -/* SDM845 Power Domain Indexes */ -#define SDM845_EBI 0 -#define SDM845_MX 1 -#define SDM845_MX_AO 2 -#define SDM845_CX 3 -#define SDM845_CX_AO 4 -#define SDM845_LMX 5 -#define SDM845_LCX 6 -#define SDM845_GFX 7 -#define SDM845_MSS 8 - -/* SDX55 Power Domain Indexes */ -#define SDX55_MSS 0 -#define SDX55_MX 1 -#define SDX55_CX 2 - -/* SDX65 Power Domain Indexes */ -#define SDX65_MSS 0 -#define SDX65_MX 1 -#define SDX65_MX_AO 2 -#define SDX65_CX 3 -#define SDX65_CX_AO 4 -#define SDX65_MXC 5 - -/* SM6350 Power Domain Indexes */ -#define SM6350_CX 0 -#define SM6350_GFX 1 -#define SM6350_LCX 2 -#define SM6350_LMX 3 -#define SM6350_MSS 4 -#define SM6350_MX 5 +#include /* SM6350 Power Domain Indexes */ #define SM6375_VDDCX 0 @@ -77,173 +18,6 @@ #define SM6375_VDD_LPI_CX 8 #define SM6375_VDD_LPI_MX 9 -/* SM8150 Power Domain Indexes */ -#define SM8150_MSS 0 -#define SM8150_EBI 1 -#define SM8150_LMX 2 -#define SM8150_LCX 3 -#define SM8150_GFX 4 -#define SM8150_MX 5 -#define SM8150_MX_AO 6 -#define SM8150_CX 7 -#define SM8150_CX_AO 8 -#define SM8150_MMCX 9 -#define SM8150_MMCX_AO 10 - -/* SA8155P is a special case, kept for backwards compatibility */ -#define SA8155P_CX SM8150_CX -#define SA8155P_CX_AO SM8150_CX_AO -#define SA8155P_EBI SM8150_EBI -#define SA8155P_GFX SM8150_GFX -#define SA8155P_MSS SM8150_MSS -#define SA8155P_MX SM8150_MX -#define SA8155P_MX_AO SM8150_MX_AO - -/* SM8250 Power Domain Indexes */ -#define SM8250_CX 0 -#define SM8250_CX_AO 1 -#define SM8250_EBI 2 -#define SM8250_GFX 3 -#define SM8250_LCX 4 -#define SM8250_LMX 5 -#define SM8250_MMCX 6 -#define SM8250_MMCX_AO 7 -#define SM8250_MX 8 -#define SM8250_MX_AO 9 - -/* SM8350 Power Domain Indexes */ -#define SM8350_CX 0 -#define SM8350_CX_AO 1 -#define SM8350_EBI 2 -#define SM8350_GFX 3 -#define SM8350_LCX 4 -#define SM8350_LMX 5 -#define SM8350_MMCX 6 -#define SM8350_MMCX_AO 7 -#define SM8350_MX 8 -#define SM8350_MX_AO 9 -#define SM8350_MXC 10 -#define SM8350_MXC_AO 11 -#define SM8350_MSS 12 - -/* SM8450 Power Domain Indexes */ -#define SM8450_CX 0 -#define SM8450_CX_AO 1 -#define SM8450_EBI 2 -#define SM8450_GFX 3 -#define SM8450_LCX 4 -#define SM8450_LMX 5 -#define SM8450_MMCX 6 -#define SM8450_MMCX_AO 7 -#define SM8450_MX 8 -#define SM8450_MX_AO 9 -#define SM8450_MXC 10 -#define SM8450_MXC_AO 11 -#define SM8450_MSS 12 - -/* SM8550 Power Domain Indexes */ -#define SM8550_CX 0 -#define SM8550_CX_AO 1 -#define SM8550_EBI 2 -#define SM8550_GFX 3 -#define SM8550_LCX 4 -#define SM8550_LMX 5 -#define SM8550_MMCX 6 -#define SM8550_MMCX_AO 7 -#define SM8550_MX 8 -#define SM8550_MX_AO 9 -#define SM8550_MXC 10 -#define SM8550_MXC_AO 11 -#define SM8550_MSS 12 -#define SM8550_NSP 13 - -/* QDU1000/QRU1000 Power Domain Indexes */ -#define QDU1000_EBI 0 -#define QDU1000_MSS 1 -#define QDU1000_CX 2 -#define QDU1000_MX 3 - -/* SC7180 Power Domain Indexes */ -#define SC7180_CX 0 -#define SC7180_CX_AO 1 -#define SC7180_GFX 2 -#define SC7180_MX 3 -#define SC7180_MX_AO 4 -#define SC7180_LMX 5 -#define SC7180_LCX 6 -#define SC7180_MSS 7 - -/* SC7280 Power Domain Indexes */ -#define SC7280_CX 0 -#define SC7280_CX_AO 1 -#define SC7280_EBI 2 -#define SC7280_GFX 3 -#define SC7280_MX 4 -#define SC7280_MX_AO 5 -#define SC7280_LMX 6 -#define SC7280_LCX 7 -#define SC7280_MSS 8 - -/* SC8180X Power Domain Indexes */ -#define SC8180X_CX 0 -#define SC8180X_CX_AO 1 -#define SC8180X_EBI 2 -#define SC8180X_GFX 3 -#define SC8180X_LCX 4 -#define SC8180X_LMX 5 -#define SC8180X_MMCX 6 -#define SC8180X_MMCX_AO 7 -#define SC8180X_MSS 8 -#define SC8180X_MX 9 -#define SC8180X_MX_AO 10 - -/* SC8280XP Power Domain Indexes */ -#define SC8280XP_CX 0 -#define SC8280XP_CX_AO 1 -#define SC8280XP_DDR 2 -#define SC8280XP_EBI 3 -#define SC8280XP_GFX 4 -#define SC8280XP_LCX 5 -#define SC8280XP_LMX 6 -#define SC8280XP_MMCX 7 -#define SC8280XP_MMCX_AO 8 -#define SC8280XP_MSS 9 -#define SC8280XP_MX 10 -#define SC8280XP_MXC 12 -#define SC8280XP_MX_AO 11 -#define SC8280XP_NSP 13 -#define SC8280XP_QPHY 14 -#define SC8280XP_XO 15 - -/* SDM845 Power Domain performance levels */ -#define RPMH_REGULATOR_LEVEL_RETENTION 16 -#define RPMH_REGULATOR_LEVEL_MIN_SVS 48 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60 -#define RPMH_REGULATOR_LEVEL_LOW_SVS 64 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96 -#define RPMH_REGULATOR_LEVEL_SVS 128 -#define RPMH_REGULATOR_LEVEL_SVS_L0 144 -#define RPMH_REGULATOR_LEVEL_SVS_L1 192 -#define RPMH_REGULATOR_LEVEL_SVS_L2 224 -#define RPMH_REGULATOR_LEVEL_NOM 256 -#define RPMH_REGULATOR_LEVEL_NOM_L0 288 -#define RPMH_REGULATOR_LEVEL_NOM_L1 320 -#define RPMH_REGULATOR_LEVEL_NOM_L2 336 -#define RPMH_REGULATOR_LEVEL_TURBO 384 -#define RPMH_REGULATOR_LEVEL_TURBO_L0 400 -#define RPMH_REGULATOR_LEVEL_TURBO_L1 416 -#define RPMH_REGULATOR_LEVEL_TURBO_L2 432 -#define RPMH_REGULATOR_LEVEL_TURBO_L3 448 -#define RPMH_REGULATOR_LEVEL_TURBO_L4 452 -#define RPMH_REGULATOR_LEVEL_TURBO_L5 456 -#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 -#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 - /* MDM9607 Power Domains */ #define MDM9607_VDDCX 0 #define MDM9607_VDDCX_AO 1 -- Gitee From 041725deb6c02946135f2946c3f10697000b574e Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Wed, 3 Dec 2025 01:36:20 +0800 Subject: [PATCH 1094/1449] dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO ANBZ: #35228 commit f0070413c65800d2b0f43685d020d0e0d424f389 stable. commit 45e1be5ddec98db71e7481fa7a3005673200d85c upstream. Not sure how useful it's gonna be in practice, but the definition is missing (unlike the previously-unused SC8280XP_MXC-non-_AO), so add it to allow the driver to create the corresponding pmdomain. Fixes: dbfb5f94e084 ("dt-bindings: power: rpmpd: Add sc8280xp RPMh power-domains") Acked-by: Rob Herring (Arm) Signed-off-by: Konrad Dybcio Reviewed-by: Ulf Hansson Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-1-46cdf47a829e@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/dt-bindings/power/qcom,rpmhpd.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h index 758c3487bd66..0abd1c4c5314 100644 --- a/include/dt-bindings/power/qcom,rpmhpd.h +++ b/include/dt-bindings/power/qcom,rpmhpd.h @@ -260,5 +260,6 @@ #define SC8280XP_NSP 13 #define SC8280XP_QPHY 14 #define SC8280XP_XO 15 +#define SC8280XP_MXC_AO 16 #endif -- Gitee From 852b4fce3082f57e43fba73c5de47321ca49d1db Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Wed, 3 Dec 2025 01:36:21 +0800 Subject: [PATCH 1095/1449] pmdomain: qcom: rpmhpd: Add MXC to SC8280XP ANBZ: #35228 commit e2d46e0b76cabbae98103331a0f2655d5e6d0827 stable. commit 5bc3e720e725cd5fa34875fa1e5434d565858067 upstream. This was apparently accounted for in dt-bindings, but never made its way into the driver. Fix it for SC8280XP and its VDD_GFX-less cousin, SA8540P. Fixes: f68f1cb3437d ("soc: qcom: rpmhpd: add sc8280xp & sa8540p rpmh power-domains") Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio Reviewed-by: Ulf Hansson Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-2-46cdf47a829e@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/qcom/rpmhpd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c index 1bb9f70ab04c..823604952b5e 100644 --- a/drivers/pmdomain/qcom/rpmhpd.c +++ b/drivers/pmdomain/qcom/rpmhpd.c @@ -217,6 +217,8 @@ static struct rpmhpd *sa8540p_rpmhpds[] = { [SC8280XP_MMCX_AO] = &mmcx_ao, [SC8280XP_MX] = &mx, [SC8280XP_MX_AO] = &mx_ao, + [SC8280XP_MXC] = &mxc, + [SC8280XP_MXC_AO] = &mxc_ao, [SC8280XP_NSP] = &nsp, }; @@ -541,6 +543,8 @@ static struct rpmhpd *sc8280xp_rpmhpds[] = { [SC8280XP_MMCX_AO] = &mmcx_ao, [SC8280XP_MX] = &mx, [SC8280XP_MX_AO] = &mx_ao, + [SC8280XP_MXC] = &mxc, + [SC8280XP_MXC_AO] = &mxc_ao, [SC8280XP_NSP] = &nsp, [SC8280XP_QPHY] = &qphy, }; -- Gitee From 2fc45244dbb4b7cf07e75308c40e5af020a14899 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Mon, 12 Jan 2026 20:20:49 +0800 Subject: [PATCH 1096/1449] ata: libata: Add cpr_log to ata_dev_print_features() early return ANBZ: #35228 commit 557b62028c0770ca24100fcffc28bbb701729356 stable. commit a6bee5e5243ad02cae575becc4c83df66fc29573 upstream. ata_dev_print_features() is supposed to return early and not print anything if there are no features supported. However, commit fe22e1c2f705 ("libata: support concurrent positioning ranges log") added another feature to ata_dev_print_features() without updating the early return conditional. Add the missing feature to the early return conditional. Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log") Signed-off-by: Niklas Cassel Tested-by: Wolf Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f627753519b9..f332835156db 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2782,7 +2782,7 @@ static void ata_dev_config_cpr(struct ata_device *dev) static void ata_dev_print_features(struct ata_device *dev) { - if (!(dev->flags & ATA_DFLAG_FEATURES_MASK)) + if (!(dev->flags & ATA_DFLAG_FEATURES_MASK) && !dev->cpr_log) return; ata_dev_info(dev, -- Gitee From a254d0120fb62934ed7d59f2ffc42a1a4d998dbc Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 1 Jul 2025 20:53:12 +0800 Subject: [PATCH 1097/1449] ata: libata-core: Introduce ata_dev_config_lpm() ANBZ: #35228 commit 1c6714932c3df1829feeccc63f6a03b6b45469f2 stable. commit d360121832d8a36871249271df5b9ff05f835f62 upstream. If the port of a device does not support Device Initiated Power Management (DIPM), that is, the port is flagged with ATA_FLAG_NO_DIPM, the DIPM feature of a device should not be used. Though DIPM is disabled by default on a device, the "Software Settings Preservation feature" may keep DIPM enabled or DIPM may have been enabled by the system firmware. Introduce the function ata_dev_config_lpm() to always disable DIPM on a device that supports this feature if the port of the device is flagged with ATA_FLAG_NO_DIPM. ata_dev_config_lpm() is called from ata_dev_configure(), ensuring that a device DIPM feature is disabled when it cannot be used. Signed-off-by: Damien Le Moal Reviewed-by: Niklas Cassel Reviewed-by: Hannes Reinecke Link: https://lore.kernel.org/r/20250701125321.69496-2-dlemoal@kernel.org Signed-off-by: Niklas Cassel Stable-dep-of: c8c6fb886f57 ("ata: libata: Print features also for ATAPI devices") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ata/libata-core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f332835156db..b748c8ead39d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2780,6 +2780,30 @@ static void ata_dev_config_cpr(struct ata_device *dev) kfree(buf); } +/* + * Configure features related to link power management. + */ +static void ata_dev_config_lpm(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + + /* + * Device Initiated Power Management (DIPM) is normally disabled by + * default on a device. However, DIPM may have been enabled and that + * setting kept even after COMRESET because of the Software Settings + * Preservation feature. So if the port does not support DIPM and the + * device does, disable DIPM on the device. + */ + if (ap->flags & ATA_FLAG_NO_DIPM && ata_id_has_dipm(dev->id)) { + err_mask = ata_dev_set_feature(dev, + SETFEATURES_SATA_DISABLE, SATA_DIPM); + if (err_mask && err_mask != AC_ERR_DEV) + ata_dev_err(dev, "Disable DIPM failed, Emask 0x%x\n", + err_mask); + } +} + static void ata_dev_print_features(struct ata_device *dev) { if (!(dev->flags & ATA_DFLAG_FEATURES_MASK) && !dev->cpr_log) @@ -2949,6 +2973,7 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_config_chs(dev); } + ata_dev_config_lpm(dev); ata_dev_config_fua(dev); ata_dev_config_devslp(dev); ata_dev_config_sense_reporting(dev); -- Gitee From 95fb904af8f153ae7b0ce763f5cf0158c0770c01 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Mon, 12 Jan 2026 20:20:47 +0800 Subject: [PATCH 1098/1449] ata: libata: Call ata_dev_config_lpm() for ATAPI devices ANBZ: #35228 commit 02fc7c01a35d30af712c87c8f667a8c9f3d4c180 stable. commit 8f3fb33f8f3f825c708ece800c921977c157f9b6 upstream. Commit d360121832d8 ("ata: libata-core: Introduce ata_dev_config_lpm()") introduced ata_dev_config_lpm(). However, it only called this function for ATA_DEV_ATA and ATA_DEV_ZAC devices, not for ATA_DEV_ATAPI devices. Additionally, commit d99a9142e782 ("ata: libata-core: Move device LPM quirk settings to ata_dev_config_lpm()") moved the LPM quirk application from ata_dev_configure() to ata_dev_config_lpm(), causing LPM quirks for ATAPI devices to no longer be applied. Call ata_dev_config_lpm() also for ATAPI devices, such that LPM quirks are applied for ATAPI devices with an entry in __ata_dev_quirks once again. Fixes: d360121832d8 ("ata: libata-core: Introduce ata_dev_config_lpm()") Fixes: d99a9142e782 ("ata: libata-core: Move device LPM quirk settings to ata_dev_config_lpm()") Signed-off-by: Niklas Cassel Tested-by: Wolf Signed-off-by: Damien Le Moal Stable-dep-of: c8c6fb886f57 ("ata: libata: Print features also for ATAPI devices") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ata/libata-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b748c8ead39d..e51a27ae0a7d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3047,6 +3047,8 @@ int ata_dev_configure(struct ata_device *dev) ata_mode_string(xfer_mask), cdb_intr_string, atapi_an_string, dma_dir_string); + + ata_dev_config_lpm(dev); } /* determine max_sectors */ -- Gitee From 1ffbc5ef12c4b1b7876e136a055bb9e19873a9e4 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Mon, 12 Jan 2026 20:20:51 +0800 Subject: [PATCH 1099/1449] ata: libata: Print features also for ATAPI devices ANBZ: #35228 commit e635e5b7eac83e547511c8277b42f85d8cd69eb7 stable. commit c8c6fb886f57d5bf71fb6de6334a143608d35707 upstream. Commit d633b8a702ab ("libata: print feature list on device scan") added a print of the features supported by the device for ATA_DEV_ATA and ATA_DEV_ZAC devices, but not for ATA_DEV_ATAPI devices. Fix this by printing the features also for ATAPI devices. Before changes: ata1.00: ATAPI: Slimtype DVD A DU8AESH, 6C2M, max UDMA/133 After changes: ata1.00: ATAPI: Slimtype DVD A DU8AESH, 6C2M, max UDMA/133 ata1.00: Features: Dev-Attention HIPM DIPM Fixes: d633b8a702ab ("libata: print feature list on device scan") Signed-off-by: Niklas Cassel Tested-by: Wolf Signed-off-by: Damien Le Moal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/ata/libata-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index e51a27ae0a7d..d5e713f284b7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3049,6 +3049,9 @@ int ata_dev_configure(struct ata_device *dev) dma_dir_string); ata_dev_config_lpm(dev); + + if (print_info) + ata_dev_print_features(dev); } /* determine max_sectors */ -- Gitee From 02175391d209ba0dcea22575daa57817096973f6 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Fri, 21 Nov 2025 04:20:41 +0800 Subject: [PATCH 1100/1449] ice: initialize ring_stats->syncp ANBZ: #35228 commit a6a0dd00178ea546299908d23f2eb5625f24d59f stable. commit 8439016c3b8b5ab687c2420317b1691585106611 upstream. The u64_stats_sync structure is empty on 64-bit systems. However, on 32-bit systems it contains a seqcount_t which needs to be initialized. While the memory is zero-initialized, a lack of u64_stats_init means that lockdep won't get initialized properly. Fix this by adding u64_stats_init() calls to the rings just after allocation. Fixes: 2b245cb29421 ("ice: Implement transmit and NAPI support") Reviewed-by: Aleksandr Loktionov Signed-off-by: Jacob Keller Reviewed-by: Simon Horman Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/ice/ice_lib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index a6a290514e54..972c515d8789 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -396,6 +396,8 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi) if (!ring_stats) goto err_out; + u64_stats_init(&ring_stats->syncp); + WRITE_ONCE(tx_ring_stats[i], ring_stats); } @@ -415,6 +417,8 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi) if (!ring_stats) goto err_out; + u64_stats_init(&ring_stats->syncp); + WRITE_ONCE(rx_ring_stats[i], ring_stats); } -- Gitee From 1942fbc1132014b1292cd377514c8c8d5f779042 Mon Sep 17 00:00:00 2001 From: Dave Ertman Date: Fri, 21 Nov 2025 01:58:26 +0800 Subject: [PATCH 1101/1449] ice: Avoid detrimental cleanup for bond during interface stop ANBZ: #35228 commit 9a151fd0bd7d918845b8e3ac9856a867c976ed87 stable. commit a9d45c22ed120cdd15ff56d0a6e4700c46451901 upstream. When the user issues an administrative down to an interface that is the primary for an aggregate bond, the prune lists are being purged. This breaks communication to the secondary interface, which shares a prune list on the main switch block while bonded together. For the primary interface of an aggregate, avoid deleting these prune lists during stop, and since they are hardcoded to specific values for the default vlan and QinQ vlans, the attempt to re-add them during the up phase will quietly fail without any additional problem. Fixes: 1e0f9881ef79 ("ice: Flesh out implementation of support for SRIOV on bonded interface") Reviewed-by: Jacob Keller Reviewed-by: Marcin Szycik Signed-off-by: Dave Ertman Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/ice/ice_lib.c | 25 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 972c515d8789..7aef40b50b89 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -3897,22 +3897,31 @@ int ice_vsi_add_vlan_zero(struct ice_vsi *vsi) int ice_vsi_del_vlan_zero(struct ice_vsi *vsi) { struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi); + struct ice_pf *pf = vsi->back; struct ice_vlan vlan; int err; - vlan = ICE_VLAN(0, 0, 0); - err = vlan_ops->del_vlan(vsi, &vlan); - if (err && err != -EEXIST) - return err; + if (pf->lag && pf->lag->primary) { + dev_dbg(ice_pf_to_dev(pf), "Interface is primary in aggregate - not deleting prune list\n"); + } else { + vlan = ICE_VLAN(0, 0, 0); + err = vlan_ops->del_vlan(vsi, &vlan); + if (err && err != -EEXIST) + return err; + } /* in SVM both VLAN 0 filters are identical */ if (!ice_is_dvm_ena(&vsi->back->hw)) return 0; - vlan = ICE_VLAN(ETH_P_8021Q, 0, 0); - err = vlan_ops->del_vlan(vsi, &vlan); - if (err && err != -EEXIST) - return err; + if (pf->lag && pf->lag->primary) { + dev_dbg(ice_pf_to_dev(pf), "Interface is primary in aggregate - not deleting QinQ prune list\n"); + } else { + vlan = ICE_VLAN(ETH_P_8021Q, 0, 0); + err = vlan_ops->del_vlan(vsi, &vlan); + if (err && err != -EEXIST) + return err; + } /* when deleting the last VLAN filter, make sure to disable the VLAN * promisc mode so the filter isn't left by accident -- Gitee From d2092001279cd63303e6222ae09ad5ca2866a676 Mon Sep 17 00:00:00 2001 From: Chwee-Lin Choong Date: Fri, 28 Nov 2025 18:53:04 +0800 Subject: [PATCH 1102/1449] igc: fix race condition in TX timestamp read for register 0 ANBZ: #35228 commit b36bbac746ee65532abd44e5a0cc68fbc8588d6e stable. commit 6990dc392a9ab10e52af37e0bee8c7b753756dc4 upstream. The current HW bug workaround checks the TXTT_0 ready bit first, then reads TXSTMPL_0 twice (before and after reading TXSTMPH_0) to detect whether a new timestamp was captured by timestamp register 0 during the workaround. This sequence has a race: if a new timestamp is captured after checking the TXTT_0 bit but before the first TXSTMPL_0 read, the detection fails because both the "old" and "new" values come from the same timestamp. Fix by reading TXSTMPL_0 first to establish a baseline, then checking the TXTT_0 bit. This ensures any timestamp captured during the race window will be detected. Old sequence: 1. Check TXTT_0 ready bit 2. Read TXSTMPL_0 (baseline) 3. Read TXSTMPH_0 (interrupt workaround) 4. Read TXSTMPL_0 (detect changes vs baseline) New sequence: 1. Read TXSTMPL_0 (baseline) 2. Check TXTT_0 ready bit 3. Read TXSTMPH_0 (interrupt workaround) 4. Read TXSTMPL_0 (detect changes vs baseline) Fixes: c789ad7cbebc ("igc: Work around HW bug causing missing timestamps") Suggested-by: Avi Shalev Reviewed-by: Aleksandr Loktionov Co-developed-by: Song Yoong Siang Signed-off-by: Song Yoong Siang Signed-off-by: Chwee-Lin Choong Tested-by: Avigail Dahan Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/igc/igc_ptp.c | 43 ++++++++++++++---------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index a82af96e6bd1..4c07c1e4aa99 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -758,36 +758,43 @@ static void igc_ptp_tx_reg_to_stamp(struct igc_adapter *adapter, static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) { struct igc_hw *hw = &adapter->hw; + u32 txstmpl_old; u64 regval; u32 mask; int i; + /* Establish baseline of TXSTMPL_0 before checking TXTT_0. + * This baseline is used to detect if a new timestamp arrives in + * register 0 during the hardware bug workaround below. + */ + txstmpl_old = rd32(IGC_TXSTMPL); + mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY; if (mask & IGC_TSYNCTXCTL_TXTT_0) { regval = rd32(IGC_TXSTMPL); regval |= (u64)rd32(IGC_TXSTMPH) << 32; } else { - /* There's a bug in the hardware that could cause - * missing interrupts for TX timestamping. The issue - * is that for new interrupts to be triggered, the - * IGC_TXSTMPH_0 register must be read. + /* TXTT_0 not set - register 0 has no new timestamp initially. + * + * Hardware bug: Future timestamp interrupts won't fire unless + * TXSTMPH_0 is read, even if the timestamp was captured in + * registers 1-3. * - * To avoid discarding a valid timestamp that just - * happened at the "wrong" time, we need to confirm - * that there was no timestamp captured, we do that by - * assuming that no two timestamps in sequence have - * the same nanosecond value. + * Workaround: Read TXSTMPH_0 here to enable future interrupts. + * However, this read clears TXTT_0. If a timestamp arrives in + * register 0 after checking TXTT_0 but before this read, it + * would be lost. * - * So, we read the "low" register, read the "high" - * register (to latch a new timestamp) and read the - * "low" register again, if "old" and "new" versions - * of the "low" register are different, a valid - * timestamp was captured, we can read the "high" - * register again. + * To detect this race: We saved a baseline read of TXSTMPL_0 + * before TXTT_0 check. After performing the workaround read of + * TXSTMPH_0, we read TXSTMPL_0 again. Since consecutive + * timestamps never share the same nanosecond value, a change + * between the baseline and new TXSTMPL_0 indicates a timestamp + * arrived during the race window. If so, read the complete + * timestamp. */ - u32 txstmpl_old, txstmpl_new; + u32 txstmpl_new; - txstmpl_old = rd32(IGC_TXSTMPL); rd32(IGC_TXSTMPH); txstmpl_new = rd32(IGC_TXSTMPL); @@ -802,7 +809,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter) done: /* Now that the problematic first register was handled, we can - * use retrieve the timestamps from the other registers + * retrieve the timestamps from the other registers * (starting from '1') with less complications. */ for (i = 1; i < IGC_MAX_TX_TSTAMP_REGS; i++) { -- Gitee From ffdbb481fd6601b7468fce033ac1d2b050dc7803 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Tue, 13 Jan 2026 14:39:24 +0800 Subject: [PATCH 1103/1449] net: usb: dm9601: remove broken SR9700 support ANBZ: #35228 commit b66dfde203fb42be500a95b11cf5e60957f3783e stable. commit 7d7dbafefbe74f5a25efc4807af093b857a7612e upstream. The SR9700 chip sends more than one packet in a USB transaction, like the DM962x chips can optionally do, but the dm9601 driver does not support this mode, and the hardware does not have the DM962x MODE_CTL register to disable it, so this driver drops packets on SR9700 devices. The sr9700 driver correctly handles receiving more than one packet per transaction. While the dm9601 driver could be improved to handle this, the easiest way to fix this issue in the short term is to remove the SR9700 device ID from the dm9601 driver so the sr9700 driver is always used. This device ID should not have been in more than one driver to begin with. The "Fixes" commit was chosen so that the patch is automatically included in all kernels that have the sr9700 driver, even though the issue affects dm9601. Fixes: c9b37458e956 ("USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support") Signed-off-by: Ethan Nelson-Moore Acked-by: Peter Korsgaard Link: https://patch.msgid.link/20260113063924.74464-1-enelsonmoore@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/dm9601.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 8b6d6a1b3c2e..2b4716ccf0c5 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -603,10 +603,6 @@ static const struct usb_device_id products[] = { USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */ .driver_info = (unsigned long)&dm9601_info, }, - { - USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */ - .driver_info = (unsigned long)&dm9601_info, - }, { USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ .driver_info = (unsigned long)&dm9601_info, -- Gitee From 80a56c53be7e42fdfa96f9ac34c3b40b8e5fcc65 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 14 Jan 2026 03:12:01 +0800 Subject: [PATCH 1104/1449] bonding: limit BOND_MODE_8023AD to Ethernet devices ANBZ: #35228 commit 80c881e53a4fa0a80fa4bef7bc0ead0e8e88940d stable. commit c84fcb79e5dbde0b8d5aeeaf04282d2149aebcf6 upstream. BOND_MODE_8023AD makes sense for ARPHRD_ETHER only. syzbot reported: BUG: KASAN: global-out-of-bounds in __hw_addr_create net/core/dev_addr_lists.c:63 [inline] BUG: KASAN: global-out-of-bounds in __hw_addr_add_ex+0x25d/0x760 net/core/dev_addr_lists.c:118 Read of size 16 at addr ffffffff8bf94040 by task syz.1.3580/19497 CPU: 1 UID: 0 PID: 19497 Comm: syz.1.3580 Tainted: G L syzkaller #0 PREEMPT(full) Tainted: [L]=SOFTLOCKUP Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 Call Trace: dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xca/0x240 mm/kasan/report.c:482 kasan_report+0x118/0x150 mm/kasan/report.c:595 check_region_inline mm/kasan/generic.c:-1 [inline] kasan_check_range+0x2b0/0x2c0 mm/kasan/generic.c:200 __asan_memcpy+0x29/0x70 mm/kasan/shadow.c:105 __hw_addr_create net/core/dev_addr_lists.c:63 [inline] __hw_addr_add_ex+0x25d/0x760 net/core/dev_addr_lists.c:118 __dev_mc_add net/core/dev_addr_lists.c:868 [inline] dev_mc_add+0xa1/0x120 net/core/dev_addr_lists.c:886 bond_enslave+0x2b8b/0x3ac0 drivers/net/bonding/bond_main.c:2180 do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2963 do_setlink+0xcf0/0x41c0 net/core/rtnetlink.c:3165 rtnl_changelink net/core/rtnetlink.c:3776 [inline] __rtnl_newlink net/core/rtnetlink.c:3935 [inline] rtnl_newlink+0x161c/0x1c90 net/core/rtnetlink.c:4072 rtnetlink_rcv_msg+0x7cf/0xb70 net/core/rtnetlink.c:6958 netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2550 netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline] netlink_unicast+0x82f/0x9e0 net/netlink/af_netlink.c:1344 netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1894 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg+0x21c/0x270 net/socket.c:742 ____sys_sendmsg+0x505/0x820 net/socket.c:2592 ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2646 __sys_sendmsg+0x164/0x220 net/socket.c:2678 do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline] __do_fast_syscall_32+0x1dc/0x560 arch/x86/entry/syscall_32.c:307 do_fast_syscall_32+0x34/0x80 arch/x86/entry/syscall_32.c:332 entry_SYSENTER_compat_after_hwframe+0x84/0x8e The buggy address belongs to the variable: lacpdu_mcast_addr+0x0/0x40 Fixes: 872254dd6b1f ("net/bonding: Enable bonding to enslave non ARPHRD_ETHER") Reported-by: syzbot+9c081b17773615f24672@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6966946b.a70a0220.245e30.0002.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Cc: Andrew Lunn Acked-by: Jay Vosburgh Link: https://patch.msgid.link/20260113191201.3970737-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/bonding/bond_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5f30863e1906..f6f2d2285bfc 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1942,6 +1942,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, */ if (!bond_has_slaves(bond)) { if (bond_dev->type != slave_dev->type) { + if (slave_dev->type != ARPHRD_ETHER && + BOND_MODE(bond) == BOND_MODE_8023AD) { + SLAVE_NL_ERR(bond_dev, slave_dev, extack, + "8023AD mode requires Ethernet devices"); + return -EINVAL; + } slave_dbg(bond_dev, slave_dev, "change device type from %d to %d\n", bond_dev->type, slave_dev->type); -- Gitee From 4d1eaed29fa97d24afcc3fe272eaab61a30d7f5d Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Wed, 13 Dec 2023 14:08:53 +0800 Subject: [PATCH 1105/1449] selftests/net: convert fib-onlink-tests.sh to run it in unique namespace ANBZ: #35228 commit 8ba4cf99c61cd0a022ce071c7cb6b8167b801b78 stable. commit 3a06833b2adc0a902f2469ad4ce41ccd64f1f3ab upstream. Remove PEER_CMD, which is not used in this test Here is the test result after conversion. ]# ./fib-onlink-tests.sh Error: ipv4: FIB table does not exist. Flush terminated Error: ipv6: FIB table does not exist. Flush terminated ######################################## Configuring interfaces ... TEST: Gateway resolves to wrong nexthop device - VRF [ OK ] Tests passed: 38 Tests failed: 0 Acked-by: David Ahern Signed-off-by: Hangbin Liu Link: https://lore.kernel.org/r/20231213060856.4030084-11-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski Stable-dep-of: 4f5f148dd7c0 ("selftests: net: fib-onlink-tests: Convert to use namespaces by default") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/fib-onlink-tests.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/net/fib-onlink-tests.sh b/tools/testing/selftests/net/fib-onlink-tests.sh index c287b90b8af8..ec2d6ceb1f08 100755 --- a/tools/testing/selftests/net/fib-onlink-tests.sh +++ b/tools/testing/selftests/net/fib-onlink-tests.sh @@ -3,6 +3,7 @@ # IPv4 and IPv6 onlink tests +source lib.sh PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} VERBOSE=0 @@ -74,9 +75,6 @@ TEST_NET4IN6[2]=10.2.1.254 # mcast address MCAST6=ff02::1 - -PEER_NS=bart -PEER_CMD="ip netns exec ${PEER_NS}" VRF=lisa VRF_TABLE=1101 PBR_TABLE=101 @@ -176,8 +174,7 @@ setup() set -e # create namespace - ip netns add ${PEER_NS} - ip -netns ${PEER_NS} li set lo up + setup_ns PEER_NS # add vrf table ip li add ${VRF} type vrf table ${VRF_TABLE} @@ -219,7 +216,7 @@ setup() cleanup() { # make sure we start from a clean slate - ip netns del ${PEER_NS} 2>/dev/null + cleanup_ns ${PEER_NS} 2>/dev/null for n in 1 3 5 7; do ip link del ${NETIFS[p${n}]} 2>/dev/null done -- Gitee From 24c5c77a2803b3894d3e6e114c7051b2b8a80435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20B=2E=20Marli=C3=A8re?= Date: Tue, 13 Jan 2026 23:37:44 +0800 Subject: [PATCH 1106/1449] selftests: net: fib-onlink-tests: Convert to use namespaces by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4b37dc63957cb52932954db668854e3fef3d5e06 stable. commit 4f5f148dd7c0459229d2ab9a769b2e820f9ee6a2 upstream. Currently, the test breaks if the SUT already has a default route configured for IPv6. Fix by avoiding the use of the default namespace. Fixes: 4ed591c8ab44 ("net/ipv6: Allow onlink routes to have a device mismatch if it is the default route") Suggested-by: Fernando Fernandez Mancera Signed-off-by: Ricardo B. Marlière Reviewed-by: Ido Schimmel Reviewed-by: Fernando Fernandez Mancera Link: https://patch.msgid.link/20260113-selftests-net-fib-onlink-v2-1-89de2b931389@suse.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../testing/selftests/net/fib-onlink-tests.sh | 71 ++++++++----------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/tools/testing/selftests/net/fib-onlink-tests.sh b/tools/testing/selftests/net/fib-onlink-tests.sh index ec2d6ceb1f08..c01be076b210 100755 --- a/tools/testing/selftests/net/fib-onlink-tests.sh +++ b/tools/testing/selftests/net/fib-onlink-tests.sh @@ -120,7 +120,7 @@ log_subsection() run_cmd() { - local cmd="$*" + local cmd="$1" local out local rc @@ -145,7 +145,7 @@ get_linklocal() local pfx local addr - addr=$(${pfx} ip -6 -br addr show dev ${dev} | \ + addr=$(${pfx} ${IP} -6 -br addr show dev ${dev} | \ awk '{ for (i = 3; i <= NF; ++i) { if ($i ~ /^fe80/) @@ -173,58 +173,48 @@ setup() set -e - # create namespace - setup_ns PEER_NS + # create namespaces + setup_ns ns1 + IP="ip -netns $ns1" + setup_ns ns2 # add vrf table - ip li add ${VRF} type vrf table ${VRF_TABLE} - ip li set ${VRF} up - ip ro add table ${VRF_TABLE} unreachable default metric 8192 - ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192 + ${IP} li add ${VRF} type vrf table ${VRF_TABLE} + ${IP} li set ${VRF} up + ${IP} ro add table ${VRF_TABLE} unreachable default metric 8192 + ${IP} -6 ro add table ${VRF_TABLE} unreachable default metric 8192 # create test interfaces - ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]} - ip li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]} - ip li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]} - ip li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]} + ${IP} li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]} + ${IP} li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]} + ${IP} li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]} + ${IP} li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]} # enslave vrf interfaces for n in 5 7; do - ip li set ${NETIFS[p${n}]} vrf ${VRF} + ${IP} li set ${NETIFS[p${n}]} vrf ${VRF} done # add addresses for n in 1 3 5 7; do - ip li set ${NETIFS[p${n}]} up - ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]} - ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad + ${IP} li set ${NETIFS[p${n}]} up + ${IP} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]} + ${IP} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad done # move peer interfaces to namespace and add addresses for n in 2 4 6 8; do - ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up - ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]} - ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad + ${IP} li set ${NETIFS[p${n}]} netns ${ns2} up + ip -netns $ns2 addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]} + ip -netns $ns2 addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad done - ip -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64} - ip -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64} + ${IP} -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64} + ${IP} -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64} set +e } -cleanup() -{ - # make sure we start from a clean slate - cleanup_ns ${PEER_NS} 2>/dev/null - for n in 1 3 5 7; do - ip link del ${NETIFS[p${n}]} 2>/dev/null - done - ip link del ${VRF} 2>/dev/null - ip ro flush table ${VRF_TABLE} - ip -6 ro flush table ${VRF_TABLE} -} - ################################################################################ # IPv4 tests # @@ -241,7 +231,7 @@ run_ip() # dev arg may be empty [ -n "${dev}" ] && dev="dev ${dev}" - run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink + run_cmd "${IP} ro add table ${table} ${prefix}/32 via ${gw} ${dev} onlink" log_test $? ${exp_rc} "${desc}" } @@ -257,8 +247,8 @@ run_ip_mpath() # dev arg may be empty [ -n "${dev}" ] && dev="dev ${dev}" - run_cmd ip ro add table "${table}" "${prefix}"/32 \ - nexthop via ${nh1} nexthop via ${nh2} + run_cmd "${IP} ro add table ${table} ${prefix}/32 \ + nexthop via ${nh1} nexthop via ${nh2}" log_test $? ${exp_rc} "${desc}" } @@ -339,7 +329,7 @@ run_ip6() # dev arg may be empty [ -n "${dev}" ] && dev="dev ${dev}" - run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink + run_cmd "${IP} -6 ro add table ${table} ${prefix}/128 via ${gw} ${dev} onlink" log_test $? ${exp_rc} "${desc}" } @@ -353,8 +343,8 @@ run_ip6_mpath() local exp_rc="$6" local desc="$7" - run_cmd ip -6 ro add table "${table}" "${prefix}"/128 "${opts}" \ - nexthop via ${nh1} nexthop via ${nh2} + run_cmd "${IP} -6 ro add table ${table} ${prefix}/128 ${opts} \ + nexthop via ${nh1} nexthop via ${nh2}" log_test $? ${exp_rc} "${desc}" } @@ -491,10 +481,9 @@ do esac done -cleanup setup run_onlink_tests -cleanup +cleanup_ns ${ns1} ${ns2} if [ "$TESTS" != "none" ]; then printf "\nTests passed: %3d\n" ${nsuccess} -- Gitee From 2fa12edf5f4771c18513983406bb5627ee6d148b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 16 Jan 2026 21:10:10 +0800 Subject: [PATCH 1107/1449] can: gs_usb: gs_usb_receive_bulk_callback(): unanchor URL on usb_submit_urb() error ANBZ: #35228 commit ce4352057fc5a986c76ece90801b9755e7c6e56c stable. commit 79a6d1bfe1148bc921b8d7f3371a7fbce44e30f7 upstream. In commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak"), the URB was re-anchored before usb_submit_urb() in gs_usb_receive_bulk_callback() to prevent a leak of this URB during cleanup. However, this patch did not take into account that usb_submit_urb() could fail. The URB remains anchored and usb_kill_anchored_urbs(&parent->rx_submitted) in gs_can_close() loops infinitely since the anchor list never becomes empty. To fix the bug, unanchor the URB when an usb_submit_urb() error occurs, also print an info message. Fixes: 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak") Reported-by: Jakub Kicinski Closes: https://lore.kernel.org/all/20260110223836.3890248-1-kuba@kernel.org/ Link: https://patch.msgid.link/20260116-can_usb-fix-reanchor-v1-1-9d74e7289225@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index d3837252e505..63439affd59d 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -751,6 +751,10 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) usb_anchor_urb(urb, &parent->rx_submitted); rc = usb_submit_urb(urb, GFP_ATOMIC); + if (!rc) + return; + + usb_unanchor_urb(urb); /* USB failure take down all interfaces */ if (rc == -ENODEV) { @@ -759,6 +763,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) if (parent->canch[rc]) netif_device_detach(parent->canch[rc]->netdev); } + } else if (rc != -ESHUTDOWN && net_ratelimit()) { + netdev_info(netdev, "failed to re-submit IN URB: %pe\n", + ERR_PTR(urb->status)); } } -- Gitee From 661dd116eb66181b6b68d91c5eb2c2fb7f394b80 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Wed, 14 Jan 2026 01:10:26 +0800 Subject: [PATCH 1108/1449] sctp: move SCTP_CMD_ASSOC_SHKEY right after SCTP_CMD_PEER_INIT ANBZ: #35228 commit e7e81abbcc5620c9532080538f9709a6ea382855 stable. commit a80c9d945aef55b23b54838334345f20251dad83 upstream. A null-ptr-deref was reported in the SCTP transmit path when SCTP-AUTH key initialization fails: ================================================================== KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f] CPU: 0 PID: 16 Comm: ksoftirqd/0 Tainted: G W 6.6.0 #2 RIP: 0010:sctp_packet_bundle_auth net/sctp/output.c:264 [inline] RIP: 0010:sctp_packet_append_chunk+0xb36/0x1260 net/sctp/output.c:401 Call Trace: sctp_packet_transmit_chunk+0x31/0x250 net/sctp/output.c:189 sctp_outq_flush_data+0xa29/0x26d0 net/sctp/outqueue.c:1111 sctp_outq_flush+0xc80/0x1240 net/sctp/outqueue.c:1217 sctp_cmd_interpreter.isra.0+0x19a5/0x62c0 net/sctp/sm_sideeffect.c:1787 sctp_side_effects net/sctp/sm_sideeffect.c:1198 [inline] sctp_do_sm+0x1a3/0x670 net/sctp/sm_sideeffect.c:1169 sctp_assoc_bh_rcv+0x33e/0x640 net/sctp/associola.c:1052 sctp_inq_push+0x1dd/0x280 net/sctp/inqueue.c:88 sctp_rcv+0x11ae/0x3100 net/sctp/input.c:243 sctp6_rcv+0x3d/0x60 net/sctp/ipv6.c:1127 The issue is triggered when sctp_auth_asoc_init_active_key() fails in sctp_sf_do_5_1C_ack() while processing an INIT_ACK. In this case, the command sequence is currently: - SCTP_CMD_PEER_INIT - SCTP_CMD_TIMER_STOP (T1_INIT) - SCTP_CMD_TIMER_START (T1_COOKIE) - SCTP_CMD_NEW_STATE (COOKIE_ECHOED) - SCTP_CMD_ASSOC_SHKEY - SCTP_CMD_GEN_COOKIE_ECHO If SCTP_CMD_ASSOC_SHKEY fails, asoc->shkey remains NULL, while asoc->peer.auth_capable and asoc->peer.peer_chunks have already been set by SCTP_CMD_PEER_INIT. This allows a DATA chunk with auth = 1 and shkey = NULL to be queued by sctp_datamsg_from_user(). Since command interpretation stops on failure, no COOKIE_ECHO should been sent via SCTP_CMD_GEN_COOKIE_ECHO. However, the T1_COOKIE timer has already been started, and it may enqueue a COOKIE_ECHO into the outqueue later. As a result, the DATA chunk can be transmitted together with the COOKIE_ECHO in sctp_outq_flush_data(), leading to the observed issue. Similar to the other places where it calls sctp_auth_asoc_init_active_key() right after sctp_process_init(), this patch moves the SCTP_CMD_ASSOC_SHKEY immediately after SCTP_CMD_PEER_INIT, before stopping T1_INIT and starting T1_COOKIE. This ensures that if shared key generation fails, authenticated DATA cannot be sent. It also allows the T1_INIT timer to retransmit INIT, giving the client another chance to process INIT_ACK and retry key setup. Fixes: 730fc3d05cd4 ("[SCTP]: Implete SCTP-AUTH parameter processing") Reported-by: Zhen Chen Tested-by: Zhen Chen Signed-off-by: Xin Long Link: https://patch.msgid.link/44881224b375aa8853f5e19b4055a1a56d895813.1768324226.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sctp/sm_statefuns.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index cd18b22b2bba..e0e626dc7953 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -602,6 +602,11 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net, sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT, SCTP_PEER_INIT(initchunk)); + /* SCTP-AUTH: generate the association shared keys so that + * we can potentially sign the COOKIE-ECHO. + */ + sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL()); + /* Reset init error count upon receipt of INIT-ACK. */ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL()); @@ -616,11 +621,6 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_COOKIE_ECHOED)); - /* SCTP-AUTH: generate the association shared keys so that - * we can potentially sign the COOKIE-ECHO. - */ - sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL()); - /* 5.1 C) "A" shall then send the State Cookie received in the * INIT ACK chunk in a COOKIE ECHO chunk, ... */ -- Gitee From 82f007b429c1b1a0d4e12f95a996616adcd5c688 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Thu, 15 Jan 2026 00:30:37 +0800 Subject: [PATCH 1109/1449] amd-xgbe: avoid misleading per-packet error log ANBZ: #35228 commit 8a8a5a43fef4ee34ff6c9c23be44227e5f20f844 stable. commit c158f985cf6c2c36c99c4f67af2ff3f5ebe09f8f upstream. On the receive path, packet can be damaged because of buffer overflow in Rx FIFO. Avoid misleading per-packet error log when packet->errors is set, this can flood the log. Instead, rely on the standard rtnl_link_stats64 stats. Fixes: c5aa9e3b8156 ("amd-xgbe: Initial AMD 10GbE platform driver") Signed-off-by: Raju Rangoju Link: https://patch.msgid.link/20260114163037.2062606-1-Raju.Rangoju@amd.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index b4d57da71de2..3d6f8f3a8336 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -2105,7 +2105,7 @@ static void xgbe_get_stats64(struct net_device *netdev, s->multicast = pstats->rxmulticastframes_g; s->rx_length_errors = pstats->rxlengtherror; s->rx_crc_errors = pstats->rxcrcerror; - s->rx_fifo_errors = pstats->rxfifooverflow; + s->rx_over_errors = pstats->rxfifooverflow; s->tx_packets = pstats->txframecount_gb; s->tx_bytes = pstats->txoctetcount_gb; @@ -2559,9 +2559,6 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) goto read_again; if (error || packet->errors) { - if (packet->errors) - netif_err(pdata, rx_err, netdev, - "error in received packet\n"); dev_kfree_skb(skb); goto next_packet; } -- Gitee From 6eb81c83af9f102249849a0c53cf377d219b1d9f Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 16 Jan 2026 01:24:46 +0800 Subject: [PATCH 1110/1449] gue: Fix skb memleak with inner IP protocol 0. ANBZ: #35228 commit f87b9b7a618c82e7465e872eb10e14c803871892 stable. commit 9a56796ad258786d3624eef5aefba394fc9bdded upstream. syzbot reported skb memleak below. [0] The repro generated a GUE packet with its inner protocol 0. gue_udp_recv() returns -guehdr->proto_ctype for "resubmit" in ip_protocol_deliver_rcu(), but this only works with non-zero protocol number. Let's drop such packets. Note that 0 is a valid number (IPv6 Hop-by-Hop Option). I think it is not practical to encap HOPOPT in GUE, so once someone starts to complain, we could pass down a resubmit flag pointer to distinguish two zeros from the upper layer: * no error * resubmit HOPOPT [0] BUG: memory leak unreferenced object 0xffff888109695a00 (size 240): comm "syz.0.17", pid 6088, jiffies 4294943096 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 40 c2 10 81 88 ff ff 00 00 00 00 00 00 00 00 .@.............. backtrace (crc a84b336f): kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline] slab_post_alloc_hook mm/slub.c:4958 [inline] slab_alloc_node mm/slub.c:5263 [inline] kmem_cache_alloc_noprof+0x3b4/0x590 mm/slub.c:5270 __build_skb+0x23/0x60 net/core/skbuff.c:474 build_skb+0x20/0x190 net/core/skbuff.c:490 __tun_build_skb drivers/net/tun.c:1541 [inline] tun_build_skb+0x4a1/0xa40 drivers/net/tun.c:1636 tun_get_user+0xc12/0x2030 drivers/net/tun.c:1770 tun_chr_write_iter+0x71/0x120 drivers/net/tun.c:1999 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x45d/0x710 fs/read_write.c:686 ksys_write+0xa7/0x170 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xa4/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 37dd0247797b1 ("gue: Receive side for Generic UDP Encapsulation") Reported-by: syzbot+4d8c7d16b0e95c0d0f0d@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6965534b.050a0220.38aacd.0001.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20260115172533.693652-2-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv4/fou_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index 4e0a7d038e21..6df7a0c614d5 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -215,6 +215,9 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) return gue_control_message(skb, guehdr); proto_ctype = guehdr->proto_ctype; + if (unlikely(!proto_ctype)) + goto drop; + __skb_pull(skb, sizeof(struct udphdr) + hdrlen); skb_reset_transport_header(skb); -- Gitee From c9ab060ae54098b06213ff830c527e32e17c478b Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 16 Jan 2026 01:24:47 +0800 Subject: [PATCH 1111/1449] tools: ynl: Specify --no-line-number in ynl-regen.sh. ANBZ: #35228 commit 4170ec351e456c133255c76e3e50731c34694d6d stable. commit 68578370f9b3a2aba5964b273312d51c581b6aad upstream. If grep.lineNumber is enabled in .gitconfig, [grep] lineNumber = true ynl-regen.sh fails with the following error: $ ./tools/net/ynl/ynl-regen.sh -f ... ynl_gen_c.py: error: argument --mode: invalid choice: '4:' (choose from user, kernel, uapi) GEN 4: net/ipv4/fou_nl.c Let's specify --no-line-number explicitly. Fixes: be5bea1cc0bf ("net: add basic C code generators for Netlink") Suggested-by: Jakub Kicinski Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20260115172533.693652-3-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/net/ynl/ynl-regen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/net/ynl/ynl-regen.sh b/tools/net/ynl/ynl-regen.sh index bdba24066cf1..88bd42496cac 100755 --- a/tools/net/ynl/ynl-regen.sh +++ b/tools/net/ynl/ynl-regen.sh @@ -21,7 +21,7 @@ files=$(git grep --files-with-matches '^/\* YNL-GEN \(kernel\|uapi\|user\)') for f in $files; do # params: 0 1 2 3 # $YAML YNL-GEN kernel $mode - params=( $(git grep -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') ) + params=( $(git grep --no-line-number -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') ) args=$(sed -n 's@/\* YNL-ARG \(.*\) \*/@\1@p' $f) if [ $f -nt ${params[0]} -a -z "$force" ]; then -- Gitee From 6ef53b85a8760a04bf5cea253c1b2f56b5709b75 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 16 Jan 2026 01:24:48 +0800 Subject: [PATCH 1112/1449] fou: Don't allow 0 for FOU_ATTR_IPPROTO. ANBZ: #35228 commit 1cc98b8887cabb1808d2f4a37cd10a7be7574771 stable. commit 7a9bc9e3f42391e4c187e099263cf7a1c4b69ff5 upstream. fou_udp_recv() has the same problem mentioned in the previous patch. If FOU_ATTR_IPPROTO is set to 0, skb is not freed by fou_udp_recv() nor "resubmit"-ted in ip_protocol_deliver_rcu(). Let's forbid 0 for FOU_ATTR_IPPROTO. Fixes: 23461551c0062 ("fou: Support for foo-over-udp RX path") Signed-off-by: Kuniyuki Iwashima Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20260115172533.693652-4-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- Documentation/netlink/specs/fou.yaml | 2 ++ net/ipv4/fou_nl.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/netlink/specs/fou.yaml b/Documentation/netlink/specs/fou.yaml index 0af5ab842c04..91721ee40641 100644 --- a/Documentation/netlink/specs/fou.yaml +++ b/Documentation/netlink/specs/fou.yaml @@ -39,6 +39,8 @@ attribute-sets: - name: ipproto type: u8 + checks: + min: 1 - name: type type: u8 diff --git a/net/ipv4/fou_nl.c b/net/ipv4/fou_nl.c index 98b90107b5ab..bbd955f4c9d1 100644 --- a/net/ipv4/fou_nl.c +++ b/net/ipv4/fou_nl.c @@ -14,7 +14,7 @@ const struct nla_policy fou_nl_policy[FOU_ATTR_IFINDEX + 1] = { [FOU_ATTR_PORT] = { .type = NLA_U16, }, [FOU_ATTR_AF] = { .type = NLA_U8, }, - [FOU_ATTR_IPPROTO] = { .type = NLA_U8, }, + [FOU_ATTR_IPPROTO] = NLA_POLICY_MIN(NLA_U8, 1), [FOU_ATTR_TYPE] = { .type = NLA_U8, }, [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, }, [FOU_ATTR_LOCAL_V4] = { .type = NLA_U32, }, -- Gitee From 723cd854b9483b92079b32208030506d42066722 Mon Sep 17 00:00:00 2001 From: David Yang Date: Wed, 14 Jan 2026 20:24:45 +0800 Subject: [PATCH 1113/1449] veth: fix data race in veth_get_ethtool_stats ANBZ: #35228 commit 0bb986d83922c5380bbc56ed993468578b8d2b2a stable. commit b47adaab8b3d443868096bac08fdbb3d403194ba upstream. In veth_get_ethtool_stats(), some statistics protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. These statistics, peer_tq_xdp_xmit and peer_tq_xdp_xmit_err, are already accumulated by veth_xdp_xmit(). Fix this by reading them into a temporary buffer first. Fixes: 5fe6e56776ba ("veth: rely on peer veth_rq for ndo_xdp_xmit accounting") Signed-off-by: David Yang Link: https://patch.msgid.link/20260114122450.227982-1-mmyangfl@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/veth.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 7767b6ff5a15..2b3b0beb55c8 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -226,16 +226,20 @@ static void veth_get_ethtool_stats(struct net_device *dev, const struct veth_rq_stats *rq_stats = &rcv_priv->rq[i].stats; const void *base = (void *)&rq_stats->vs; unsigned int start, tx_idx = idx; + u64 buf[VETH_TQ_STATS_LEN]; size_t offset; - tx_idx += (i % dev->real_num_tx_queues) * VETH_TQ_STATS_LEN; do { start = u64_stats_fetch_begin(&rq_stats->syncp); for (j = 0; j < VETH_TQ_STATS_LEN; j++) { offset = veth_tq_stats_desc[j].offset; - data[tx_idx + j] += *(u64 *)(base + offset); + buf[j] = *(u64 *)(base + offset); } } while (u64_stats_fetch_retry(&rq_stats->syncp, start)); + + tx_idx += (i % dev->real_num_tx_queues) * VETH_TQ_STATS_LEN; + for (j = 0; j < VETH_TQ_STATS_LEN; j++) + data[tx_idx + j] += buf[j]; } pp_idx = idx + dev->real_num_tx_queues * VETH_TQ_STATS_LEN; -- Gitee From bba469fa6a356f1ebc9d70377b7fac86beacf5d4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 15 Jan 2026 17:21:39 +0800 Subject: [PATCH 1114/1449] l2tp: avoid one data-race in l2tp_tunnel_del_work() ANBZ: #35228 commit 68e92085427c84e7679ddb53c0d68836d220b6e7 stable. commit 7a29f6bf60f2590fe5e9c4decb451e19afad2bcf upstream. We should read sk->sk_socket only when dealing with kernel sockets. syzbot reported the following data-race: BUG: KCSAN: data-race in l2tp_tunnel_del_work / sk_common_release write to 0xffff88811c182b20 of 8 bytes by task 5365 on cpu 0: sk_set_socket include/net/sock.h:2092 [inline] sock_orphan include/net/sock.h:2118 [inline] sk_common_release+0xae/0x230 net/core/sock.c:4003 udp_lib_close+0x15/0x20 include/net/udp.h:325 inet_release+0xce/0xf0 net/ipv4/af_inet.c:437 __sock_release net/socket.c:662 [inline] sock_close+0x6b/0x150 net/socket.c:1455 __fput+0x29b/0x650 fs/file_table.c:468 ____fput+0x1c/0x30 fs/file_table.c:496 task_work_run+0x131/0x1a0 kernel/task_work.c:233 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] __exit_to_user_mode_loop kernel/entry/common.c:44 [inline] exit_to_user_mode_loop+0x1fe/0x740 kernel/entry/common.c:75 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline] syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline] do_syscall_64+0x1e1/0x2b0 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f read to 0xffff88811c182b20 of 8 bytes by task 827 on cpu 1: l2tp_tunnel_del_work+0x2f/0x1a0 net/l2tp/l2tp_core.c:1418 process_one_work kernel/workqueue.c:3257 [inline] process_scheduled_works+0x4ce/0x9d0 kernel/workqueue.c:3340 worker_thread+0x582/0x770 kernel/workqueue.c:3421 kthread+0x489/0x510 kernel/kthread.c:463 ret_from_fork+0x149/0x290 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:246 value changed: 0xffff88811b818000 -> 0x0000000000000000 Fixes: d00fa9adc528 ("l2tp: fix races with tunnel socket close") Reported-by: syzbot+7312e82745f7fa2526db@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6968b029.050a0220.58bed.0016.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Cc: James Chapman Reviewed-by: Guillaume Nault Link: https://patch.msgid.link/20260115092139.3066180-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/l2tp/l2tp_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 70da78ab9520..e0ca08ebd16a 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1250,8 +1250,6 @@ static void l2tp_tunnel_del_work(struct work_struct *work) { struct l2tp_tunnel *tunnel = container_of(work, struct l2tp_tunnel, del_work); - struct sock *sk = tunnel->sock; - struct socket *sock = sk->sk_socket; l2tp_tunnel_closeall(tunnel); @@ -1259,6 +1257,8 @@ static void l2tp_tunnel_del_work(struct work_struct *work) * the sk API to release it here. */ if (tunnel->fd < 0) { + struct socket *sock = tunnel->sock->sk_socket; + if (sock) { kernel_sock_shutdown(sock, SHUT_RDWR); sock_release(sock); -- Gitee From f92b80f9f1ff558c687abd97fdb39d8b6ed4b85c Mon Sep 17 00:00:00 2001 From: Dmitry Skorodumov Date: Mon, 12 Jan 2026 22:24:06 +0800 Subject: [PATCH 1115/1449] ipvlan: Make the addrs_lock be per port ANBZ: #35228 commit 04ba6de6eff61238e5397c14ac26a6578c7735a5 stable. commit d3ba32162488283c0a4c5bedd8817aec91748802 upstream. Make the addrs_lock be per port, not per ipvlan dev. Initial code seems to be written in the assumption, that any address change must occur under RTNL. But it is not so for the case of IPv6. So 1) Introduce per-port addrs_lock. 2) It was needed to fix places where it was forgotten to take lock (ipvlan_open/ipvlan_close) This appears to be a very minor problem though. Since it's highly unlikely that ipvlan_add_addr() will be called on 2 CPU simultaneously. But nevertheless, this could cause: 1) False-negative of ipvlan_addr_busy(): one interface iterated through all port->ipvlans + ipvlan->addrs under some ipvlan spinlock, and another added IP under its own lock. Though this is only possible for IPv6, since looks like only ipvlan_addr6_event() can be called without rtnl_lock. 2) Race since ipvlan_ht_addr_add(port) is called under different ipvlan->addrs_lock locks This should not affect performance, since add/remove IP is a rare situation and spinlock is not taken on fast paths. Fixes: 8230819494b3 ("ipvlan: use per device spinlock to protect addrs list updates") Signed-off-by: Dmitry Skorodumov Reviewed-by: Paolo Abeni Link: https://patch.msgid.link/20260112142417.4039566-2-skorodumov.dmitry@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ipvlan/ipvlan.h | 2 +- drivers/net/ipvlan/ipvlan_core.c | 16 +++++------ drivers/net/ipvlan/ipvlan_main.c | 49 +++++++++++++++++++------------- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h index 025e0c19ec25..fce3ced90bd3 100644 --- a/drivers/net/ipvlan/ipvlan.h +++ b/drivers/net/ipvlan/ipvlan.h @@ -69,7 +69,6 @@ struct ipvl_dev { DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE); netdev_features_t sfeatures; u32 msg_enable; - spinlock_t addrs_lock; }; struct ipvl_addr { @@ -90,6 +89,7 @@ struct ipvl_port { struct net_device *dev; possible_net_t pnet; struct hlist_head hlhead[IPVLAN_HASH_SIZE]; + spinlock_t addrs_lock; /* guards hash-table and addrs */ struct list_head ipvlans; u16 mode; u16 flags; diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 83bd65a22770..268ea41a17d5 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -107,17 +107,15 @@ void ipvlan_ht_addr_del(struct ipvl_addr *addr) struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan, const void *iaddr, bool is_v6) { - struct ipvl_addr *addr, *ret = NULL; + struct ipvl_addr *addr; - rcu_read_lock(); - list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) { - if (addr_equal(is_v6, addr, iaddr)) { - ret = addr; - break; - } + assert_spin_locked(&ipvlan->port->addrs_lock); + + list_for_each_entry(addr, &ipvlan->addrs, anode) { + if (addr_equal(is_v6, addr, iaddr)) + return addr; } - rcu_read_unlock(); - return ret; + return NULL; } bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6) diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 57c79f5f2991..679e816146d8 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -74,6 +74,7 @@ static int ipvlan_port_create(struct net_device *dev) for (idx = 0; idx < IPVLAN_HASH_SIZE; idx++) INIT_HLIST_HEAD(&port->hlhead[idx]); + spin_lock_init(&port->addrs_lock); skb_queue_head_init(&port->backlog); INIT_WORK(&port->wq, ipvlan_process_multicast); ida_init(&port->ida); @@ -179,6 +180,7 @@ static void ipvlan_uninit(struct net_device *dev) static int ipvlan_open(struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); + struct ipvl_port *port = ipvlan->port; struct ipvl_addr *addr; if (ipvlan->port->mode == IPVLAN_MODE_L3 || @@ -187,10 +189,10 @@ static int ipvlan_open(struct net_device *dev) else dev->flags &= ~IFF_NOARP; - rcu_read_lock(); - list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) + spin_lock_bh(&port->addrs_lock); + list_for_each_entry(addr, &ipvlan->addrs, anode) ipvlan_ht_addr_add(ipvlan, addr); - rcu_read_unlock(); + spin_unlock_bh(&port->addrs_lock); return 0; } @@ -204,10 +206,10 @@ static int ipvlan_stop(struct net_device *dev) dev_uc_unsync(phy_dev, dev); dev_mc_unsync(phy_dev, dev); - rcu_read_lock(); - list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) + spin_lock_bh(&ipvlan->port->addrs_lock); + list_for_each_entry(addr, &ipvlan->addrs, anode) ipvlan_ht_addr_del(addr); - rcu_read_unlock(); + spin_unlock_bh(&ipvlan->port->addrs_lock); return 0; } @@ -574,7 +576,6 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev, if (!tb[IFLA_MTU]) ipvlan_adjust_mtu(ipvlan, phy_dev); INIT_LIST_HEAD(&ipvlan->addrs); - spin_lock_init(&ipvlan->addrs_lock); /* TODO Probably put random address here to be presented to the * world but keep using the physical-dev address for the outgoing @@ -652,13 +653,13 @@ void ipvlan_link_delete(struct net_device *dev, struct list_head *head) struct ipvl_dev *ipvlan = netdev_priv(dev); struct ipvl_addr *addr, *next; - spin_lock_bh(&ipvlan->addrs_lock); + spin_lock_bh(&ipvlan->port->addrs_lock); list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { ipvlan_ht_addr_del(addr); list_del_rcu(&addr->anode); kfree_rcu(addr, rcu); } - spin_unlock_bh(&ipvlan->addrs_lock); + spin_unlock_bh(&ipvlan->port->addrs_lock); ida_simple_remove(&ipvlan->port->ida, dev->dev_id); list_del_rcu(&ipvlan->pnode); @@ -805,6 +806,8 @@ static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6) { struct ipvl_addr *addr; + assert_spin_locked(&ipvlan->port->addrs_lock); + addr = kzalloc(sizeof(struct ipvl_addr), GFP_ATOMIC); if (!addr) return -ENOMEM; @@ -835,16 +838,16 @@ static void ipvlan_del_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6) { struct ipvl_addr *addr; - spin_lock_bh(&ipvlan->addrs_lock); + spin_lock_bh(&ipvlan->port->addrs_lock); addr = ipvlan_find_addr(ipvlan, iaddr, is_v6); if (!addr) { - spin_unlock_bh(&ipvlan->addrs_lock); + spin_unlock_bh(&ipvlan->port->addrs_lock); return; } ipvlan_ht_addr_del(addr); list_del_rcu(&addr->anode); - spin_unlock_bh(&ipvlan->addrs_lock); + spin_unlock_bh(&ipvlan->port->addrs_lock); kfree_rcu(addr, rcu); } @@ -866,14 +869,14 @@ static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) { int ret = -EINVAL; - spin_lock_bh(&ipvlan->addrs_lock); + spin_lock_bh(&ipvlan->port->addrs_lock); if (ipvlan_addr_busy(ipvlan->port, ip6_addr, true)) netif_err(ipvlan, ifup, ipvlan->dev, "Failed to add IPv6=%pI6c addr for %s intf\n", ip6_addr, ipvlan->dev->name); else ret = ipvlan_add_addr(ipvlan, ip6_addr, true); - spin_unlock_bh(&ipvlan->addrs_lock); + spin_unlock_bh(&ipvlan->port->addrs_lock); return ret; } @@ -912,21 +915,24 @@ static int ipvlan_addr6_validator_event(struct notifier_block *unused, struct in6_validator_info *i6vi = (struct in6_validator_info *)ptr; struct net_device *dev = (struct net_device *)i6vi->i6vi_dev->dev; struct ipvl_dev *ipvlan = netdev_priv(dev); + int ret = NOTIFY_OK; if (!ipvlan_is_valid_dev(dev)) return NOTIFY_DONE; switch (event) { case NETDEV_UP: + spin_lock_bh(&ipvlan->port->addrs_lock); if (ipvlan_addr_busy(ipvlan->port, &i6vi->i6vi_addr, true)) { NL_SET_ERR_MSG(i6vi->extack, "Address already assigned to an ipvlan device"); - return notifier_from_errno(-EADDRINUSE); + ret = notifier_from_errno(-EADDRINUSE); } + spin_unlock_bh(&ipvlan->port->addrs_lock); break; } - return NOTIFY_OK; + return ret; } #endif @@ -934,14 +940,14 @@ static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) { int ret = -EINVAL; - spin_lock_bh(&ipvlan->addrs_lock); + spin_lock_bh(&ipvlan->port->addrs_lock); if (ipvlan_addr_busy(ipvlan->port, ip4_addr, false)) netif_err(ipvlan, ifup, ipvlan->dev, "Failed to add IPv4=%pI4 on %s intf.\n", ip4_addr, ipvlan->dev->name); else ret = ipvlan_add_addr(ipvlan, ip4_addr, false); - spin_unlock_bh(&ipvlan->addrs_lock); + spin_unlock_bh(&ipvlan->port->addrs_lock); return ret; } @@ -983,21 +989,24 @@ static int ipvlan_addr4_validator_event(struct notifier_block *unused, struct in_validator_info *ivi = (struct in_validator_info *)ptr; struct net_device *dev = (struct net_device *)ivi->ivi_dev->dev; struct ipvl_dev *ipvlan = netdev_priv(dev); + int ret = NOTIFY_OK; if (!ipvlan_is_valid_dev(dev)) return NOTIFY_DONE; switch (event) { case NETDEV_UP: + spin_lock_bh(&ipvlan->port->addrs_lock); if (ipvlan_addr_busy(ipvlan->port, &ivi->ivi_addr, false)) { NL_SET_ERR_MSG(ivi->extack, "Address already assigned to an ipvlan device"); - return notifier_from_errno(-EADDRINUSE); + ret = notifier_from_errno(-EADDRINUSE); } + spin_unlock_bh(&ipvlan->port->addrs_lock); break; } - return NOTIFY_OK; + return ret; } static struct notifier_block ipvlan_addr4_notifier_block __read_mostly = { -- Gitee From 1f2be2dbe903b7103caf5397d6045d999ce9918b Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Sat, 17 Jan 2026 00:47:12 +0800 Subject: [PATCH 1116/1449] octeontx2: cn10k: fix RX flowid TCAM mask handling ANBZ: #35228 commit fcf8cd4654790ac053a04286667d89efe830d198 stable. commit ab9b218a1521133a4410722907fa7189566be9bc upstream. The RX flowid programming initializes the TCAM mask to all ones, but then overwrites it when clearing the MAC DA mask bits. This results in losing the intended initialization and may affect other match fields. Update the code to clear the MAC DA bits using an AND operation, making the handling of mask[0] consistent with mask[1], where the field-specific bits are cleared after initializing the mask to ~0ULL. Fixes: 57d00d4364f3 ("octeontx2-pf: mcs: Match macsec ethertype along with DMAC") Signed-off-by: Alok Tiwari Reviewed-by: Subbaraya Sundeep Link: https://patch.msgid.link/20260116164724.2733511-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c index 74953f67a2bf..3af58bc9f533 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c @@ -330,7 +330,7 @@ static int cn10k_mcs_write_rx_flowid(struct otx2_nic *pfvf, req->data[0] = FIELD_PREP(MCS_TCAM0_MAC_DA_MASK, mac_da); req->mask[0] = ~0ULL; - req->mask[0] = ~MCS_TCAM0_MAC_DA_MASK; + req->mask[0] &= ~MCS_TCAM0_MAC_DA_MASK; req->data[1] = FIELD_PREP(MCS_TCAM1_ETYPE_MASK, ETH_P_MACSEC); req->mask[1] = ~0ULL; -- Gitee From 873b04cc67070b8970efc5254266e29b79e091d0 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Thu, 15 Jan 2026 00:02:41 +0800 Subject: [PATCH 1117/1449] net/sched: Enforce that teql can only be used as root qdisc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 0686bedfed34155520f3f735cbf3210cb9044380 stable. commit 50da4b9d07a7a463e2cfb738f3ad4cff6b2c9c3b upstream. Design intent of teql is that it is only supposed to be used as root qdisc. We need to check for that constraint. Although not important, I will describe the scenario that unearthed this issue for the curious. GangMin Kim managed to concot a scenario as follows: ROOT qdisc 1:0 (QFQ) ├── class 1:1 (weight=15, lmax=16384) netem with delay 6.4s └── class 1:2 (weight=1, lmax=1514) teql GangMin sends a packet which is enqueued to 1:1 (netem). Any invocation of dequeue by QFQ from this class will not return a packet until after 6.4s. In the meantime, a second packet is sent and it lands on 1:2. teql's enqueue will return success and this will activate class 1:2. Main issue is that teql only updates the parent visible qlen (sch->q.qlen) at dequeue. Since QFQ will only call dequeue if peek succeeds (and teql's peek always returns NULL), dequeue will never be called and thus the qlen will remain as 0. With that in mind, when GangMin updates 1:2's lmax value, the qfq_change_class calls qfq_deact_rm_from_agg. Since the child qdisc's qlen was not incremented, qfq fails to deactivate the class, but still frees its pointers from the aggregate. So when the first packet is rescheduled after 6.4 seconds (netem's delay), a dangling pointer is accessed causing GangMin's causing a UAF. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: GangMin Kim Tested-by: Victor Nogueira Signed-off-by: Jamal Hadi Salim Link: https://patch.msgid.link/20260114160243.913069-2-jhs@mojatatu.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_teql.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 7721239c185f..0a7856e14a97 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -178,6 +178,11 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt, if (m->dev == dev) return -ELOOP; + if (sch->parent != TC_H_ROOT) { + NL_SET_ERR_MSG_MOD(extack, "teql can only be used as root"); + return -EOPNOTSUPP; + } + q->m = m; skb_queue_head_init(&q->q); -- Gitee From 920e0ce3be6d4727c243ffaea4a55f9c958da405 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Thu, 15 Jan 2026 00:02:42 +0800 Subject: [PATCH 1118/1449] net/sched: qfq: Use cl_is_active to determine whether class is active in qfq_rm_from_ag ANBZ: #35228 commit 93b8635974fb050c43d07e35e5edfe6e685ca28a stable. commit d837fbee92453fbb829f950c8e7cf76207d73f33 upstream. This is more of a preventive patch to make the code more consistent and to prevent possible exploits that employ child qlen manipulations on qfq. use cl_is_active instead of relying on the child qdisc's qlen to determine class activation. Fixes: 462dbc9101acd ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost") Signed-off-by: Jamal Hadi Salim Link: https://patch.msgid.link/20260114160243.913069-3-jhs@mojatatu.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/sch_qfq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 7c6b5428b8ed..a17f7c31378e 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -373,7 +373,7 @@ static void qfq_rm_from_agg(struct qfq_sched *q, struct qfq_class *cl) /* Deschedule class and remove it from its parent aggregate. */ static void qfq_deact_rm_from_agg(struct qfq_sched *q, struct qfq_class *cl) { - if (cl->qdisc->q.qlen > 0) /* class is active */ + if (cl_is_active(cl)) /* class is active */ qfq_deactivate_class(q, cl); qfq_rm_from_agg(q, cl); -- Gitee From 10d27b1250c1d265b6d0d0ed7cf5d7f1d7164d38 Mon Sep 17 00:00:00 2001 From: Taeyang Lee <0wn@theori.io> Date: Fri, 16 Jan 2026 16:03:58 +0900 Subject: [PATCH 1119/1449] crypto: authencesn - reject too-short AAD (assoclen<8) to match ESP/ESN spec ANBZ: #35228 commit b0a9609283a5c852addb513dafa655c61eebc1ef stable. commit 2397e9264676be7794f8f7f1e9763d90bd3c7335 upstream. authencesn assumes an ESP/ESN-formatted AAD. When assoclen is shorter than the minimum expected length, crypto_authenc_esn_decrypt() can advance past the end of the destination scatterlist and trigger a NULL pointer dereference in scatterwalk_map_and_copy(), leading to a kernel panic (DoS). Add a minimum AAD length check to fail fast on invalid inputs. Fixes: 104880a6b470 ("crypto: authencesn - Convert to new AEAD interface") Reported-By: Taeyang Lee <0wn@theori.io> Signed-off-by: Taeyang Lee <0wn@theori.io> Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- crypto/authencesn.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crypto/authencesn.c b/crypto/authencesn.c index 2e20c32197fe..73e5d0d8a91f 100644 --- a/crypto/authencesn.c +++ b/crypto/authencesn.c @@ -173,6 +173,9 @@ static int crypto_authenc_esn_encrypt(struct aead_request *req) struct scatterlist *src, *dst; int err; + if (assoclen < 8) + return -EINVAL; + sg_init_table(areq_ctx->src, 2); src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen); dst = src; @@ -270,6 +273,9 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req) u32 tmp[2]; int err; + if (assoclen < 8) + return -EINVAL; + if (!authsize) goto tail; -- Gitee From 450b957e7b12998f1f2b9dd6918bec378b6aa513 Mon Sep 17 00:00:00 2001 From: Marnix Rijnart Date: Mon, 12 Jan 2026 08:08:23 +0800 Subject: [PATCH 1120/1449] serial: 8250_pci: Fix broken RS485 for F81504/508/512 ANBZ: #35228 commit dce0865a5828a09caa48d6daf109d47a3b965296 stable. commit 27aff0a56b3c77ea1a73641c9b3c4172a8f7238f upstream. Fintek F81504/508/512 can support both RTS_ON_SEND and RTS_AFTER_SEND, but pci_fintek_rs485_supported only announces the former. This makes it impossible to unset SER_RS485_RTS_ON_SEND from userspace because of uart_sanitize_serial_rs485(). Some devices with these chips need RTS low on TX, so they are effectively broken. Fix this by announcing the support for SER_RS485_RTS_AFTER_SEND, similar to commit 068d35a7be65 ("serial: sc16is7xx: announce support for SER_RS485_RTS_ON_SEND"). Fixes: 4afeced55baa ("serial: core: fix sanitizing check for RTS settings") Cc: stable Signed-off-by: Marnix Rijnart Link: https://patch.msgid.link/20260112000931.61703-1-marnix.rijnart@iwell.eu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/tty/serial/8250/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 18fddd65c010..623fd4aa8499 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1563,7 +1563,7 @@ static int pci_fintek_rs485_config(struct uart_port *port, struct ktermios *term } static const struct serial_rs485 pci_fintek_rs485_supported = { - .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND, /* F81504/508/512 does not support RTS delay before or after send */ }; -- Gitee From 2ef441e590cfce8bdb1f58c50fe13945ae97477b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 13 Jan 2026 00:28:35 +0800 Subject: [PATCH 1121/1449] comedi: dmm32at: serialize use of paged registers ANBZ: #35228 commit aaff8f3a35c9d7e8f3241ae08e6d399d752a6850 stable. commit e03b29b55f2b7c345a919a6ee36633b06bf3fb56 upstream. Some of the hardware registers of the DMM-32-AT board are multiplexed, using the least significant two bits of the Miscellaneous Control register to select the function of registers at offsets 12 to 15: 00 => 8254 timer/counter registers are accessible 01 => 8255 digital I/O registers are accessible 10 => Reserved 11 => Calibration registers are accessible The interrupt service routine (`dmm32at_isr()`) clobbers the bottom two bits of the register with value 00, which would interfere with access to the 8255 registers by the `dm32at_8255_io()` function (used for Comedi instruction handling on the digital I/O subdevice). Make use of the generic Comedi device spin-lock `dev->spinlock` (which is otherwise unused by this driver) to serialize access to the miscellaneous control register and paged registers. Fixes: 3c501880ac44 ("Staging: comedi: add dmm32at driver") Cc: stable@vger.kernel.org Signed-off-by: Ian Abbott Link: https://patch.msgid.link/20260112162835.91688-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/comedi/drivers/dmm32at.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/comedi/drivers/dmm32at.c b/drivers/comedi/drivers/dmm32at.c index fe023c722aa3..d17cba93578c 100644 --- a/drivers/comedi/drivers/dmm32at.c +++ b/drivers/comedi/drivers/dmm32at.c @@ -330,6 +330,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) { + unsigned long irq_flags; unsigned char lo1, lo2, hi2; unsigned short both2; @@ -342,6 +343,9 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) /* set counter clocks to 10MHz, disable all aux dio */ outb(0, dev->iobase + DMM32AT_CTRDIO_CFG_REG); + /* serialize access to control register and paged registers */ + spin_lock_irqsave(&dev->spinlock, irq_flags); + /* get access to the clock regs */ outb(DMM32AT_CTRL_PAGE_8254, dev->iobase + DMM32AT_CTRL_REG); @@ -354,6 +358,8 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) outb(lo2, dev->iobase + DMM32AT_CLK2); outb(hi2, dev->iobase + DMM32AT_CLK2); + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + /* enable the ai conversion interrupt and the clock to start scans */ outb(DMM32AT_INTCLK_ADINT | DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL, @@ -363,13 +369,19 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec) static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_cmd *cmd = &s->async->cmd; + unsigned long irq_flags; int ret; dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len); + /* serialize access to control register and paged registers */ + spin_lock_irqsave(&dev->spinlock, irq_flags); + /* reset the interrupt just in case */ outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + /* * wait for circuit to settle * we don't have the 'insn' here but it's not needed @@ -429,8 +441,13 @@ static irqreturn_t dmm32at_isr(int irq, void *d) comedi_handle_events(dev, s); } + /* serialize access to control register and paged registers */ + spin_lock(&dev->spinlock); + /* reset the interrupt */ outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); + + spin_unlock(&dev->spinlock); return IRQ_HANDLED; } @@ -481,14 +498,25 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev, static int dmm32at_8255_io(struct comedi_device *dev, int dir, int port, int data, unsigned long regbase) { + unsigned long irq_flags; + int ret; + + /* serialize access to control register and paged registers */ + spin_lock_irqsave(&dev->spinlock, irq_flags); + /* get access to the DIO regs */ outb(DMM32AT_CTRL_PAGE_8255, dev->iobase + DMM32AT_CTRL_REG); if (dir) { outb(data, dev->iobase + regbase + port); - return 0; + ret = 0; + } else { + ret = inb(dev->iobase + regbase + port); } - return inb(dev->iobase + regbase + port); + + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + + return ret; } /* Make sure the board is there and put it to a known state */ -- Gitee From 176fb412fb2e6415dc2e3c2131fdbd3a8da842b8 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Tue, 16 Dec 2025 22:50:03 +0800 Subject: [PATCH 1122/1449] w1: therm: Fix off-by-one buffer overflow in alarms_store ANBZ: #35228 commit 6a5820ecfa5a76c3d3e154802c8c15f391ef442e stable. commit 761fcf46a1bd797bd32d23f3ea0141ffd437668a upstream. The sysfs buffer passed to alarms_store() is allocated with 'size + 1' bytes and a NUL terminator is appended. However, the 'size' argument does not account for this extra byte. The original code then allocated 'size' bytes and used strcpy() to copy 'buf', which always writes one byte past the allocated buffer since strcpy() copies until the NUL terminator at index 'size'. Fix this by parsing the 'buf' parameter directly using simple_strtoll() without allocating any intermediate memory or string copying. This removes the overflow while simplifying the code. Cc: stable@vger.kernel.org Fixes: e2c94d6f5720 ("w1_therm: adding alarm sysfs entry") Signed-off-by: Thorsten Blum Link: https://patch.msgid.link/20251216145007.44328-2-thorsten.blum@linux.dev Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/w1/slaves/w1_therm.c | 62 ++++++++++++------------------------ 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index c85e80c7e130..3cbb23bbe236 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -1846,53 +1846,35 @@ static ssize_t alarms_store(struct device *device, struct w1_slave *sl = dev_to_w1_slave(device); struct therm_info info; u8 new_config_register[3]; /* array of data to be written */ - int temp, ret; - char *token = NULL; + long long temp; + int ret = 0; s8 tl, th; /* 1 byte per value + temp ring order */ - char *p_args, *orig; - - p_args = orig = kmalloc(size, GFP_KERNEL); - /* Safe string copys as buf is const */ - if (!p_args) { - dev_warn(device, - "%s: error unable to allocate memory %d\n", - __func__, -ENOMEM); - return size; - } - strcpy(p_args, buf); - - /* Split string using space char */ - token = strsep(&p_args, " "); - - if (!token) { - dev_info(device, - "%s: error parsing args %d\n", __func__, -EINVAL); - goto free_m; - } - - /* Convert 1st entry to int */ - ret = kstrtoint (token, 10, &temp); + const char *p = buf; + char *endp; + + temp = simple_strtoll(p, &endp, 10); + if (p == endp || *endp != ' ') + ret = -EINVAL; + else if (temp < INT_MIN || temp > INT_MAX) + ret = -ERANGE; if (ret) { dev_info(device, "%s: error parsing args %d\n", __func__, ret); - goto free_m; + return size; } tl = int_to_short(temp); - /* Split string using space char */ - token = strsep(&p_args, " "); - if (!token) { - dev_info(device, - "%s: error parsing args %d\n", __func__, -EINVAL); - goto free_m; - } - /* Convert 2nd entry to int */ - ret = kstrtoint (token, 10, &temp); + p = endp + 1; + temp = simple_strtoll(p, &endp, 10); + if (p == endp) + ret = -EINVAL; + else if (temp < INT_MIN || temp > INT_MAX) + ret = -ERANGE; if (ret) { dev_info(device, "%s: error parsing args %d\n", __func__, ret); - goto free_m; + return size; } /* Prepare to cast to short by eliminating out of range values */ @@ -1915,7 +1897,7 @@ static ssize_t alarms_store(struct device *device, dev_info(device, "%s: error reading from the slave device %d\n", __func__, ret); - goto free_m; + return size; } /* Write data in the device RAM */ @@ -1923,7 +1905,7 @@ static ssize_t alarms_store(struct device *device, dev_info(device, "%s: Device not supported by the driver %d\n", __func__, -ENODEV); - goto free_m; + return size; } ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register); @@ -1932,10 +1914,6 @@ static ssize_t alarms_store(struct device *device, "%s: error writing to the slave device %d\n", __func__, ret); -free_m: - /* free allocated memory */ - kfree(orig); - return size; } -- Gitee From a0aab7775d0b05db23072ea0e5257f097c2600ef Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 18 Dec 2025 19:14:14 +0800 Subject: [PATCH 1123/1449] w1: fix redundant counter decrement in w1_attach_slave_device() ANBZ: #35228 commit 9367b4709b528b08c9a6c8b3f9519776d55c3413 stable. commit cc8f92e41eb76f450f05234fef2054afc3633100 upstream. In w1_attach_slave_device(), if __w1_attach_slave_device() fails, put_device() -> w1_slave_release() is called to do the cleanup job. In w1_slave_release(), sl->family->refcnt and sl->master->slave_count have already been decremented. There is no need to decrement twice in w1_attach_slave_device(). Fixes: 2c927c0c73fd ("w1: Fix slave count on 1-Wire bus (resend)") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Link: https://patch.msgid.link/20251218111414.564403-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/w1/w1.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 5353cbd75126..570c1ff780fc 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -758,8 +758,6 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) if (err < 0) { dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__, sl->name); - dev->slave_count--; - w1_family_put(sl->family); atomic_dec(&sl->master->refcnt); kfree(sl); return err; -- Gitee From ad6e17ce79e013a3c66ace3189657ec2dee34d3c Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Wed, 14 Jan 2026 04:24:58 +0800 Subject: [PATCH 1124/1449] Revert "nfc/nci: Add the inconsistency check between the input data length and count" ANBZ: #35228 commit 93cbf6d80da2aaecabc5dd0b6745894b25238217 stable. commit f40ddcc0c0ca1a0122a7f4440b429f97d5832bdf upstream. This reverts commit 068648aab72c9ba7b0597354ef4d81ffaac7b979. NFC packets may have NUL-bytes. Checking for string length is not a correct assumption here. As long as there is a check for the length copied from copy_from_user, all should be fine. The fix only prevented the syzbot reproducer from triggering the bug because the packet is not enqueued anymore and the code that triggers the bug is not exercised. The fix even broke testing/selftests/nci/nci_dev, making all tests there fail. After the revert, 6 out of 8 tests pass. Fixes: 068648aab72c ("nfc/nci: Add the inconsistency check between the input data length and count") Cc: stable@vger.kernel.org Signed-off-by: Thadeu Lima de Souza Cascardo Link: https://patch.msgid.link/20260113202458.449455-1-cascardo@igalia.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nfc/virtual_ncidev.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c index 6b89d596ba9a..590b038e449e 100644 --- a/drivers/nfc/virtual_ncidev.c +++ b/drivers/nfc/virtual_ncidev.c @@ -125,10 +125,6 @@ static ssize_t virtual_ncidev_write(struct file *file, kfree_skb(skb); return -EFAULT; } - if (strnlen(skb->data, count) != count) { - kfree_skb(skb); - return -EINVAL; - } nci_recv_frame(vdev->ndev, skb); return count; -- Gitee From b926ec4a7bc49d497dff5ecff5c70ccc76353638 Mon Sep 17 00:00:00 2001 From: gongqi <550230171hxy@gmail.com> Date: Thu, 22 Jan 2026 23:54:59 +0800 Subject: [PATCH 1125/1449] Input: i8042 - add quirks for MECHREVO Wujie 15X Pro ANBZ: #35228 commit dcecb4269dd4b8411b20cba9571612f991077a42 stable. commit 19a5d9ba6208e9006a2a9d5962aea4d6e427d8ab upstream. The MECHREVO Wujie 15X Pro requires several i8042 quirks to function correctly. Specifically, NOMUX, RESET_ALWAYS, NOLOOP, and NOPNP are needed to ensure the keyboard and touchpad work reliably. Signed-off-by: gongqi <550230171hxy@gmail.com> Link: https://patch.msgid.link/20260122155501.376199-3-550230171hxy@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/serio/i8042-acpipnpio.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h index b24127e923db..3c28839ad56e 100644 --- a/drivers/input/serio/i8042-acpipnpio.h +++ b/drivers/input/serio/i8042-acpipnpio.h @@ -1176,6 +1176,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) + }, /* * A lot of modern Clevo barebones have touchpad and/or keyboard issues * after suspend fixable with the forcenorestore quirk. -- Gitee From 3c123d931edfd7882333bf69c14d3187de62a080 Mon Sep 17 00:00:00 2001 From: feng Date: Sun, 25 Jan 2026 13:44:12 +0800 Subject: [PATCH 1126/1449] Input: i8042 - add quirk for ASUS Zenbook UX425QA_UM425QA ANBZ: #35228 commit 21937a189daa806a9384f6dec692b8befe5b0581 stable. commit 2934325f56150ad8dab8ab92cbe2997242831396 upstream. The ASUS Zenbook UX425QA_UM425QA fails to initialize the keyboard after a cold boot. A quirk already exists for "ZenBook UX425", but some Zenbooks report "Zenbook" with a lowercase 'b'. Since DMI matching is case-sensitive, the existing quirk is not applied to these "extra special" Zenbooks. Testing confirms that this model needs the same quirks as the ZenBook UX425 variants. Signed-off-by: feng Link: https://patch.msgid.link/20260122013957.11184-1-alec.jiang@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/input/serio/i8042-acpipnpio.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h index 3c28839ad56e..d492aa93a7c3 100644 --- a/drivers/input/serio/i8042-acpipnpio.h +++ b/drivers/input/serio/i8042-acpipnpio.h @@ -115,6 +115,17 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { }, .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) }, + { + /* + * ASUS Zenbook UX425QA_UM425QA + * Some Zenbooks report "Zenbook" with a lowercase b. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook UX425QA_UM425QA"), + }, + .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) + }, { /* ASUS ZenBook UX425UA/QA */ .matches = { -- Gitee From c726f18d43ffc5d33148a69662d9ed012a4c2889 Mon Sep 17 00:00:00 2001 From: Long Li Date: Sat, 17 Jan 2026 09:03:02 +0800 Subject: [PATCH 1127/1449] scsi: storvsc: Process unsupported MODE_SENSE_10 ANBZ: #35228 commit 156284ab2f641545736945366d95f40aac236a17 stable. commit 9eacec5d18f98f89be520eeeef4b377acee3e4b8 upstream. The Hyper-V host does not support MODE_SENSE_10 and MODE_SENSE. The driver handles MODE_SENSE as unsupported command, but not for MODE_SENSE_10. Add MODE_SENSE_10 to the same handling logic and return correct code to SCSI layer. Fixes: 89ae7d709357 ("Staging: hv: storvsc: Move the storage driver out of the staging area") Cc: stable@kernel.org Signed-off-by: Long Li Reviewed-by: Michael Kelley Link: https://patch.msgid.link/20260117010302.294068-1-longli@linux.microsoft.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/storvsc_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 954a1cc50ba7..9dcad02ce489 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1145,7 +1145,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, * The current SCSI handling on the host side does * not correctly handle: * INQUIRY command with page code parameter set to 0x80 - * MODE_SENSE command with cmd[2] == 0x1c + * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c * MAINTENANCE_IN is not supported by HyperV FC passthrough * * Setup srb and scsi status so this won't be fatal. @@ -1155,6 +1155,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || (stor_pkt->vm_srb.cdb[0] == MODE_SENSE) || + (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) || (stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN && hv_dev_is_fc(device))) { vstor_packet->vm_srb.scsi_status = 0; -- Gitee From ca5cf9f46bc42da15b5d8e44cb89a1294e37767f Mon Sep 17 00:00:00 2001 From: Abdun Nihaal Date: Tue, 23 Dec 2025 14:30:11 +0800 Subject: [PATCH 1128/1449] scsi: xen: scsiback: Fix potential memory leak in scsiback_remove() ANBZ: #35228 commit f86264ec0e2b102fcd49bf3e4f32fee669d482fc stable. commit 901a5f309daba412e2a30364d7ec1492fa11c32c upstream. Memory allocated for struct vscsiblk_info in scsiback_probe() is not freed in scsiback_remove() leading to potential memory leaks on remove, as well as in the scsiback_probe() error paths. Fix that by freeing it in scsiback_remove(). Cc: stable@vger.kernel.org Fixes: d9d660f6e562 ("xen-scsiback: Add Xen PV SCSI backend driver") Signed-off-by: Abdun Nihaal Reviewed-by: Juergen Gross Link: https://patch.msgid.link/20251223063012.119035-1-nihaal@cse.iitm.ac.in Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/xen/xen-scsiback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 8b77e4c06e43..3fbea676b377 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -1262,6 +1262,7 @@ static void scsiback_remove(struct xenbus_device *dev) gnttab_page_cache_shrink(&info->free_pages, 0); dev_set_drvdata(&dev->dev, NULL); + kfree(info); } static int scsiback_probe(struct xenbus_device *dev, -- Gitee From 4dd116daa50a393d86f4e5ccda771a1087bb0fd9 Mon Sep 17 00:00:00 2001 From: Geraldo Nascimento Date: Tue, 18 Nov 2025 05:47:43 +0800 Subject: [PATCH 1129/1449] arm64: dts: rockchip: remove dangerous max-link-speed from helios64 ANBZ: #35228 commit 929229fdd116a5a33d216f6f51299108b33cadfc stable. commit 0368e4afcf20f377c81fa77b1c7d0dee4a625a44 upstream. Shawn Lin from Rockchip strongly discourages attempts to use their RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic failures that may happen. Even if the odds are low, drop from last user of this non-default property for the RK3399 platform, helios64 board dts. Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64") Link: https://lore.kernel.org/all/e8524bf8-a90c-423f-8a58-9ef05a3db1dd@rock-chips.com/ Cc: stable@vger.kernel.org Reported-by: Shawn Lin Reviewed-by: Dragan Simic Signed-off-by: Geraldo Nascimento Acked-by: Shawn Lin Link: https://patch.msgid.link/43bb639c120f599106fca2deee6c6599b2692c5c.1763415706.git.geraldogabriel@gmail.com Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts index 1eb287a3f8c0..f3d419799708 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts @@ -427,7 +427,6 @@ &pcie_phy { &pcie0 { ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; - max-link-speed = <2>; num-lanes = <2>; pinctrl-names = "default"; status = "okay"; -- Gitee From 1b8040a4d9a4b337c8865e6270d7e37c05e65477 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Tue, 25 Nov 2025 11:47:03 +0800 Subject: [PATCH 1130/1449] arm64: dts: rockchip: Fix voltage threshold for volume keys for Pinephone Pro ANBZ: #35228 commit 8adc31a561a55cc955dbb55e3ef264891391e860 stable. commit 5497ffe305b2ea31ae62d4a311d7cabfb671f54a upstream. Previously sometimes pressing the volume-down button would register as a volume-up button. Match the thresholds as shown in the Pinephone Pro schematic. Tests: ~ $ evtest // Mashed the volume down ~100 times with varying intensity Event: time xxx, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1 Event: time xxx, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0 // Mashed the volume up ~100 times with varying intensity Event: time xxx, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1 Event: time xxx, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0 Fixes: d3150ed53580 ("arm64: dts: rockchip: Add support for volume keys to rk3399-pinephone-pro") Cc: stable@vger.kernel.org Signed-off-by: Ondrej Jirman Signed-off-by: Rudraksha Gupta Reviewed-by: Pavel Machek Link: https://patch.msgid.link/20251124-ppp_light_accel_mag_vol-down-v5-4-f9a10a0a50eb@gmail.com Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts index f4829b28c71e..3c6f4982cf1b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts @@ -40,13 +40,13 @@ adc-keys { button-up { label = "Volume Up"; linux,code = ; - press-threshold-microvolt = <100000>; + press-threshold-microvolt = <2000>; }; button-down { label = "Volume Down"; linux,code = ; - press-threshold-microvolt = <600000>; + press-threshold-microvolt = <300000>; }; }; -- Gitee From 4a9b3e808aac632bd7489b1b4b9d477739946b51 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 7 Jan 2026 02:04:26 +0800 Subject: [PATCH 1131/1449] x86/kfence: avoid writing L1TF-vulnerable PTEs ANBZ: #35228 commit bf843b0624d892a6ccd0831de7d9a5a963f848be stable. commit b505f1944535f83d369ae68813e7634d11b990d3 upstream. For native, the choice of PTE is fine. There's real memory backing the non-present PTE. However, for XenPV, Xen complains: (XEN) d1 L1TF-vulnerable L1e 8010000018200066 - Shadowing To explain, some background on XenPV pagetables: Xen PV guests are control their own pagetables; they choose the new PTE value, and use hypercalls to make changes so Xen can audit for safety. In addition to a regular reference count, Xen also maintains a type reference count. e.g. SegDesc (referenced by vGDT/vLDT), Writable (referenced with _PAGE_RW) or L{1..4} (referenced by vCR3 or a lower pagetable level). This is in order to prevent e.g. a page being inserted into the pagetables for which the guest has a writable mapping. For non-present mappings, all other bits become software accessible, and typically contain metadata rather a real frame address. There is nothing that a reference count could sensibly be tied to. As such, even if Xen could recognise the address as currently safe, nothing would prevent that frame from changing owner to another VM in the future. When Xen detects a PV guest writing a L1TF-PTE, it responds by activating shadow paging. This is normally only used for the live phase of migration, and comes with a reasonable overhead. KFENCE only cares about getting #PF to catch wild accesses; it doesn't care about the value for non-present mappings. Use a fully inverted PTE, to avoid hitting the slow path when running under Xen. While adjusting the logic, take the opportunity to skip all actions if the PTE is already in the right state, half the number PVOps callouts, and skip TLB maintenance on a !P -> P transition which benefits non-Xen cases too. Link: https://lkml.kernel.org/r/20260106180426.710013-1-andrew.cooper3@citrix.com Fixes: 1dc0da6e9ec0 ("x86, kfence: enable KFENCE for x86") Signed-off-by: Andrew Cooper Tested-by: Marco Elver Cc: Alexander Potapenko Cc: Marco Elver Cc: Dmitry Vyukov Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Jann Horn Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/include/asm/kfence.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kfence.h b/arch/x86/include/asm/kfence.h index 1ac011d4c293..9eb234296890 100644 --- a/arch/x86/include/asm/kfence.h +++ b/arch/x86/include/asm/kfence.h @@ -43,10 +43,34 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) { unsigned int level; pte_t *pte = lookup_address(addr, &level); + pteval_t val; if (WARN_ON(!pte || level != PG_LEVEL_4K)) return false; + val = pte_val(*pte); + + /* + * protect requires making the page not-present. If the PTE is + * already in the right state, there's nothing to do. + */ + if (protect != !!(val & _PAGE_PRESENT)) + return true; + + /* + * Otherwise, invert the entire PTE. This avoids writing out an + * L1TF-vulnerable PTE (not present, without the high address bits + * set). + */ + set_pte(pte, __pte(~val)); + + /* + * If the page was protected (non-present) and we're making it + * present, there is no need to flush the TLB at all. + */ + if (!protect) + return true; + /* * We need to avoid IPIs, as we may get KFENCE allocations or faults * with interrupts disabled. Therefore, the below is best-effort, and @@ -54,11 +78,6 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) * lazy fault handling takes care of faults after the page is PRESENT. */ - if (protect) - set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); - else - set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); - /* * Flush this CPU's TLB, assuming whoever did the allocation/free is * likely to continue running on this CPU. -- Gitee From 1f812868629bf8d84b75d2d1f0c9fdd21de33ba9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 4 Dec 2025 00:24:38 +0800 Subject: [PATCH 1132/1449] comedi: Fix getting range information for subdevices 16 to 255 ANBZ: #35228 commit 6484f43740cc969cdac6d922eb69aaf5a19173ee stable. commit 10d28cffb3f6ec7ad67f0a4cd32c2afa92909452 upstream. The `COMEDI_RANGEINFO` ioctl does not work properly for subdevice indices above 15. Currently, the only in-tree COMEDI drivers that support more than 16 subdevices are the "8255" driver and the "comedi_bond" driver. Making the ioctl work for subdevice indices up to 255 is achievable. It needs minor changes to the handling of the `COMEDI_RANGEINFO` and `COMEDI_CHANINFO` ioctls that should be mostly harmless to user-space, apart from making them less broken. Details follow... The `COMEDI_RANGEINFO` ioctl command gets the list of supported ranges (usually with units of volts or milliamps) for a COMEDI subdevice or channel. (Only some subdevices have per-channel range tables, indicated by the `SDF_RANGETYPE` flag in the subdevice information.) It uses a `range_type` value and a user-space pointer, both supplied by user-space, but the `range_type` value should match what was obtained using the `COMEDI_CHANINFO` ioctl (if the subdevice has per-channel range tables) or `COMEDI_SUBDINFO` ioctl (if the subdevice uses a single range table for all channels). Bits 15 to 0 of the `range_type` value contain the length of the range table, which is the only part that user-space should care about (so it can use a suitably sized buffer to fetch the range table). Bits 23 to 16 store the channel index, which is assumed to be no more than 255 if the subdevice has per-channel range tables, and is set to 0 if the subdevice has a single range table. For `range_type` values produced by the `COMEDI_SUBDINFO` ioctl, bits 31 to 24 contain the subdevice index, which is assumed to be no more than 255. But for `range_type` values produced by the `COMEDI_CHANINFO` ioctl, bits 27 to 24 contain the subdevice index, which is assumed to be no more than 15, and bits 31 to 28 contain the COMEDI device's minor device number for some unknown reason lost in the mists of time. The `COMEDI_RANGEINFO` ioctl extract the length from bits 15 to 0 of the user-supplied `range_type` value, extracts the channel index from bits 23 to 16 (only used if the subdevice has per-channel range tables), extracts the subdevice index from bits 27 to 24, and ignores bits 31 to 28. So for subdevice indices 16 to 255, the `COMEDI_SUBDINFO` or `COMEDI_CHANINFO` ioctl will report a `range_type` value that doesn't work with the `COMEDI_RANGEINFO` ioctl. It will either get the range table for the subdevice index modulo 16, or will fail with `-EINVAL`. To fix this, always use bits 31 to 24 of the `range_type` value to hold the subdevice index (assumed to be no more than 255). This affects the `COMEDI_CHANINFO` and `COMEDI_RANGEINFO` ioctls. There should not be anything in user-space that depends on the old, broken usage, although it may now see different values in bits 31 to 28 of the `range_type` values reported by the `COMEDI_CHANINFO` ioctl for subdevices that have per-channel subdevices. User-space should not be trying to decode bits 31 to 16 of the `range_type` values anyway. Fixes: ed9eccbe8970 ("Staging: add comedi core") Cc: stable@vger.kernel.org #5.17+ Signed-off-by: Ian Abbott Link: https://patch.msgid.link/20251203162438.176841-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/comedi/comedi_fops.c | 2 +- drivers/comedi/range.c | 2 +- include/uapi/linux/comedi.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c index bb4fbfa80c82..12201ebf22eb 100644 --- a/drivers/comedi/comedi_fops.c +++ b/drivers/comedi/comedi_fops.c @@ -1099,7 +1099,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, for (i = 0; i < s->n_chan; i++) { int x; - x = (dev->minor << 28) | (it->subdev << 24) | (i << 16) | + x = (it->subdev << 24) | (i << 16) | (s->range_table_list[i]->length); if (put_user(x, it->rangelist + i)) return -EFAULT; diff --git a/drivers/comedi/range.c b/drivers/comedi/range.c index 8f43cf88d784..5b8f662365e3 100644 --- a/drivers/comedi/range.c +++ b/drivers/comedi/range.c @@ -52,7 +52,7 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, const struct comedi_lrange *lr; struct comedi_subdevice *s; - subd = (it->range_type >> 24) & 0xf; + subd = (it->range_type >> 24) & 0xff; chan = (it->range_type >> 16) & 0xff; if (!dev->attached) diff --git a/include/uapi/linux/comedi.h b/include/uapi/linux/comedi.h index 7314e5ee0a1e..798ec9a39e12 100644 --- a/include/uapi/linux/comedi.h +++ b/include/uapi/linux/comedi.h @@ -640,7 +640,7 @@ struct comedi_chaninfo { /** * struct comedi_rangeinfo - used to retrieve the range table for a channel - * @range_type: Encodes subdevice index (bits 27:24), channel index + * @range_type: Encodes subdevice index (bits 31:24), channel index * (bits 23:16) and range table length (bits 15:0). * @range_ptr: Pointer to array of @struct comedi_krange to be filled * in with the range table for the channel or subdevice. -- Gitee From 7f5abdc29350504a7fe0a497df23157fb9fafd23 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 16 Jan 2026 04:31:10 +0800 Subject: [PATCH 1133/1449] platform/x86: hp-bioscfg: Fix kobject warnings for empty attribute names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 29917c80aa96a25cbcf5876fd774a1cfd72b01a9 stable. commit fdee1b09721605f532352628d0a24623e7062efb upstream. The hp-bioscfg driver attempts to register kobjects with empty names when the HP BIOS returns attributes with empty name strings. This causes multiple kernel warnings: kobject: (00000000135fb5e6): attempted to be registered with empty name! WARNING: CPU: 14 PID: 3336 at lib/kobject.c:219 kobject_add_internal+0x2eb/0x310 Add validation in hp_init_bios_buffer_attribute() to check if the attribute name is empty after parsing it from the WMI buffer. If empty, log a debug message and skip registration of that attribute, allowing the module to continue processing other valid attributes. Cc: stable@vger.kernel.org Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg") Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20260115203725.828434-2-mario.limonciello@amd.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c index b62b158cffd8..e9bade74997b 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include "bioscfg.h" #include "../../firmware_attributes_class.h" @@ -786,6 +788,12 @@ static int hp_init_bios_buffer_attribute(enum hp_wmi_data_type attr_type, if (ret < 0) goto buff_attr_exit; + if (strlen(str) == 0) { + pr_debug("Ignoring attribute with empty name\n"); + ret = 0; + goto buff_attr_exit; + } + if (attr_type == HPWMI_PASSWORD_TYPE || attr_type == HPWMI_SECURE_PLATFORM_TYPE) temp_kset = bioscfg_drv.authentication_dir_kset; -- Gitee From 351ca0da339c92e1e610dc7cc2072f78c155bc71 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 16 Jan 2026 04:31:11 +0800 Subject: [PATCH 1134/1449] platform/x86: hp-bioscfg: Fix kernel panic in GET_INSTANCE_ID macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit eb5ff1025c92117d5d1cc728bcfa294abe484da1 stable. commit 25150715e0b049b99df664daf05dab12f41c3e13 upstream. The GET_INSTANCE_ID macro that caused a kernel panic when accessing sysfs attributes: 1. Off-by-one error: The loop condition used '<=' instead of '<', causing access beyond array bounds. Since array indices are 0-based and go from 0 to instances_count-1, the loop should use '<'. 2. Missing NULL check: The code dereferenced attr_name_kobj->name without checking if attr_name_kobj was NULL, causing a null pointer dereference in min_length_show() and other attribute show functions. The panic occurred when fwupd tried to read BIOS configuration attributes: Oops: general protection fault [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:min_length_show+0xcf/0x1d0 [hp_bioscfg] Add a NULL check for attr_name_kobj before dereferencing and corrects the loop boundary to match the pattern used elsewhere in the driver. Cc: stable@vger.kernel.org Fixes: 5f94f181ca25 ("platform/x86: hp-bioscfg: bioscfg-h") Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20260115203725.828434-3-mario.limonciello@amd.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h index 3166ef328eba..6b6748e4be21 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -285,8 +286,9 @@ enum hp_wmi_data_elements { { \ int i; \ \ - for (i = 0; i <= bioscfg_drv.type##_instances_count; i++) { \ - if (!strcmp(kobj->name, bioscfg_drv.type##_data[i].attr_name_kobj->name)) \ + for (i = 0; i < bioscfg_drv.type##_instances_count; i++) { \ + if (bioscfg_drv.type##_data[i].attr_name_kobj && \ + !strcmp(kobj->name, bioscfg_drv.type##_data[i].attr_name_kobj->name)) \ return i; \ } \ return -EIO; \ -- Gitee From b0dce6fb0332ac11114c9b70349a851f8e0461d0 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 20 Jan 2026 22:42:50 +0800 Subject: [PATCH 1135/1449] io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop ANBZ: #35228 commit 85eb83694a91c89d9abe615d717c0053c3efa714 stable. commit 10dc959398175736e495f71c771f8641e1ca1907 upstream. Currently this is checked before running the pending work. Normally this is quite fine, as work items either end up blocking (which will create a new worker for other items), or they complete fairly quickly. But syzbot reports an issue where io-wq takes seemingly forever to exit, and with a bit of debugging, this turns out to be because it queues a bunch of big (2GB - 4096b) reads with a /dev/msr* file. Since this file type doesn't support ->read_iter(), loop_rw_iter() ends up handling them. Each read returns 16MB of data read, which takes 20 (!!) seconds. With a bunch of these pending, processing the whole chain can take a long time. Easily longer than the syzbot uninterruptible sleep timeout of 140 seconds. This then triggers a complaint off the io-wq exit path: INFO: task syz.4.135:6326 blocked for more than 143 seconds. Not tainted syzkaller #0 Blocked by coredump. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz.4.135 state:D stack:26824 pid:6326 tgid:6324 ppid:5957 task_flags:0x400548 flags:0x00080000 Call Trace: context_switch kernel/sched/core.c:5256 [inline] __schedule+0x1139/0x6150 kernel/sched/core.c:6863 __schedule_loop kernel/sched/core.c:6945 [inline] schedule+0xe7/0x3a0 kernel/sched/core.c:6960 schedule_timeout+0x257/0x290 kernel/time/sleep_timeout.c:75 do_wait_for_common kernel/sched/completion.c:100 [inline] __wait_for_common+0x2fc/0x4e0 kernel/sched/completion.c:121 io_wq_exit_workers io_uring/io-wq.c:1328 [inline] io_wq_put_and_exit+0x271/0x8a0 io_uring/io-wq.c:1356 io_uring_clean_tctx+0x10d/0x190 io_uring/tctx.c:203 io_uring_cancel_generic+0x69c/0x9a0 io_uring/cancel.c:651 io_uring_files_cancel include/linux/io_uring.h:19 [inline] do_exit+0x2ce/0x2bd0 kernel/exit.c:911 do_group_exit+0xd3/0x2a0 kernel/exit.c:1112 get_signal+0x2671/0x26d0 kernel/signal.c:3034 arch_do_signal_or_restart+0x8f/0x7e0 arch/x86/kernel/signal.c:337 __exit_to_user_mode_loop kernel/entry/common.c:41 [inline] exit_to_user_mode_loop+0x8c/0x540 kernel/entry/common.c:75 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline] syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline] do_syscall_64+0x4ee/0xf80 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fa02738f749 RSP: 002b:00007fa0281ae0e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca RAX: fffffffffffffe00 RBX: 00007fa0275e6098 RCX: 00007fa02738f749 RDX: 0000000000000000 RSI: 0000000000000080 RDI: 00007fa0275e6098 RBP: 00007fa0275e6090 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fa0275e6128 R14: 00007fff14e4fcb0 R15: 00007fff14e4fd98 There's really nothing wrong here, outside of processing these reads will take a LONG time. However, we can speed up the exit by checking the IO_WQ_BIT_EXIT inside the io_worker_handle_work() loop, as syzbot will exit the ring after queueing up all of these reads. Then once the first item is processed, io-wq will simply cancel the rest. That should avoid syzbot running into this complaint again. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/68a2decc.050a0220.e29e5.0099.GAE@google.com/ Reported-by: syzbot+4eb282331cab6d5b6588@syzkaller.appspotmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- io_uring/io-wq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index 1c4ef4e4eb52..c848a5018d12 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -554,9 +554,9 @@ static void io_worker_handle_work(struct io_wq_acct *acct, __releases(&acct->lock) { struct io_wq *wq = worker->wq; - bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state); do { + bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state); struct io_wq_work *work; /* -- Gitee From a9901451a97b7f2092168d42a21deea4c588373c Mon Sep 17 00:00:00 2001 From: Francesco Lavra Date: Mon, 1 Dec 2025 18:00:10 +0800 Subject: [PATCH 1136/1449] iio: imu: st_lsm6dsx: fix iio_chan_spec for sensors without event detection ANBZ: #35228 commit 7673167fac9323110973a3300637adba7d45de3a stable. commit c34e2e2d67b3bb8d5a6d09b0d6dac845cdd13fb3 upstream. The st_lsm6dsx_acc_channels array of struct iio_chan_spec has a non-NULL event_spec field, indicating support for IIO events. However, event detection is not supported for all sensors, and if userspace tries to configure accelerometer wakeup events on a sensor device that does not support them (e.g. LSM6DS0), st_lsm6dsx_write_event() dereferences a NULL pointer when trying to write to the wakeup register. Define an additional struct iio_chan_spec array whose members have a NULL event_spec field, and use this array instead of st_lsm6dsx_acc_channels for sensors without event detection capability. Fixes: b5969abfa8b8 ("iio: imu: st_lsm6dsx: add motion events") Signed-off-by: Francesco Lavra Reviewed-by: Andy Shevchenko Acked-by: Lorenzo Bianconi Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 6e42e0c659e0..ef664c7c661b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -84,6 +84,13 @@ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3), }; +static const struct iio_chan_spec st_lsm6ds0_acc_channels[] = { + ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0), + ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), + ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), @@ -125,8 +132,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { }, .channels = { [ST_LSM6DSX_ID_ACC] = { - .chan = st_lsm6dsx_acc_channels, - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + .chan = st_lsm6ds0_acc_channels, + .len = ARRAY_SIZE(st_lsm6ds0_acc_channels), }, [ST_LSM6DSX_ID_GYRO] = { .chan = st_lsm6ds0_gyro_channels, @@ -1428,8 +1435,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { }, .channels = { [ST_LSM6DSX_ID_ACC] = { - .chan = st_lsm6dsx_acc_channels, - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + .chan = st_lsm6ds0_acc_channels, + .len = ARRAY_SIZE(st_lsm6ds0_acc_channels), }, [ST_LSM6DSX_ID_GYRO] = { .chan = st_lsm6dsx_gyro_channels, -- Gitee From 4107ada8ab6b3a0b5fb89ed3682a08e36c5fd661 Mon Sep 17 00:00:00 2001 From: Pavel Zhigulin Date: Fri, 14 Nov 2025 23:13:01 +0800 Subject: [PATCH 1137/1449] iio: adc: ad7280a: handle spi_setup() errors in probe() ANBZ: #35228 commit ce8d8a3368128af0ba308bda3923d0aa32152867 stable. commit 6b39824ac4c15783787e6434449772bfb2e31214 upstream. The probe() function ignored the return value of spi_setup(), leaving SPI configuration failures undetected. If spi_setup() fails, the driver should stop initialization and propagate the error to the caller. Add proper error handling: check the return value of spi_setup() and return it on failure. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 2051f25d2a26 ("iio: adc: New driver for AD7280A Lithium Ion Battery Monitoring System") Signed-off-by: Pavel Zhigulin Reviewed-by: Marcelo Schmitt Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/ad7280a.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c index 9080c795dcb7..10cc623bf62a 100644 --- a/drivers/iio/adc/ad7280a.c +++ b/drivers/iio/adc/ad7280a.c @@ -1028,7 +1028,9 @@ static int ad7280_probe(struct spi_device *spi) st->spi->max_speed_hz = AD7280A_MAX_SPI_CLK_HZ; st->spi->mode = SPI_MODE_1; - spi_setup(st->spi); + ret = spi_setup(st->spi); + if (ret < 0) + return ret; st->ctrl_lb = FIELD_PREP(AD7280A_CTRL_LB_ACQ_TIME_MSK, st->acquisition_time) | FIELD_PREP(AD7280A_CTRL_LB_THERMISTOR_MSK, st->thermistor_term_en); -- Gitee From 8fc3c88ad7df4328462128abc6cbdf4714d6ba9b Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Fri, 9 Jan 2026 20:25:23 +0800 Subject: [PATCH 1138/1449] interconnect: debugfs: initialize src_node and dst_node to empty strings ANBZ: #35228 commit aa79a5a959c7c414bd6fba01ea8dbaddd44f13e7 stable. commit 8cc27f5c6dd17dd090f3a696683f04336c162ff5 upstream. The debugfs_create_str() API assumes that the string pointer is either NULL or points to valid kmalloc() memory. Leaving the pointer uninitialized can cause problems. Initialize src_node and dst_node to empty strings before creating the debugfs entries to guarantee that reads and writes are safe. Fixes: 770c69f037c1 ("interconnect: Add debugfs test client") Signed-off-by: Georgi Djakov Reviewed-by: Kuan-Wei Chiu Tested-by: Kuan-Wei Chiu Link: https://lore.kernel.org/r/20260109122523.125843-1-djakov@kernel.org Signed-off-by: Georgi Djakov Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/interconnect/debugfs-client.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c index 778deeb4a7e8..24d7b5a57794 100644 --- a/drivers/interconnect/debugfs-client.c +++ b/drivers/interconnect/debugfs-client.c @@ -150,6 +150,11 @@ int icc_debugfs_client_init(struct dentry *icc_dir) return ret; } + src_node = devm_kstrdup(&pdev->dev, "", GFP_KERNEL); + dst_node = devm_kstrdup(&pdev->dev, "", GFP_KERNEL); + if (!src_node || !dst_node) + return -ENOMEM; + client_dir = debugfs_create_dir("test_client", icc_dir); debugfs_create_str("src_node", 0600, client_dir, &src_node); -- Gitee From 96dd3b6dcc20b92f1b1cf8b90edafac2d08a8a06 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Sat, 18 Nov 2023 00:10:05 +0800 Subject: [PATCH 1139/1449] spi: sprd: adi: Use devm_register_restart_handler() ANBZ: #35228 commit 74634f4a64897dfe4660ec20a96ad0495fccce54 stable. commit 8e6a43961f24cf841d3c0d199521d0b284d948b9 upstream. Use device life-cycle managed register function to simplify probe error path and eliminate need for explicit remove function. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20231117161006.87734-5-afd@ti.com Signed-off-by: Mark Brown Stable-dep-of: 383d4f5cffcc ("spi: spi-sprd-adi: Fix double free in probe error path") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-sprd-adi.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c index bf01feedbf93..58c3badd9c79 100644 --- a/drivers/spi/spi-sprd-adi.c +++ b/drivers/spi/spi-sprd-adi.c @@ -138,8 +138,7 @@ struct sprd_adi_data { u32 slave_offset; u32 slave_addr_size; int (*read_check)(u32 val, u32 reg); - int (*restart)(struct notifier_block *this, - unsigned long mode, void *cmd); + int (*restart)(struct sys_off_data *data); void (*wdg_rst)(void *p); }; @@ -150,7 +149,6 @@ struct sprd_adi { struct hwspinlock *hwlock; unsigned long slave_vbase; unsigned long slave_pbase; - struct notifier_block restart_handler; const struct sprd_adi_data *data; }; @@ -370,11 +368,9 @@ static void sprd_adi_set_wdt_rst_mode(void *p) #endif } -static int sprd_adi_restart(struct notifier_block *this, unsigned long mode, - void *cmd, struct sprd_adi_wdg *wdg) +static int sprd_adi_restart(struct sprd_adi *sadi, unsigned long mode, + const char *cmd, struct sprd_adi_wdg *wdg) { - struct sprd_adi *sadi = container_of(this, struct sprd_adi, - restart_handler); u32 val, reboot_mode = 0; if (!cmd) @@ -448,8 +444,7 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode, return NOTIFY_DONE; } -static int sprd_adi_restart_sc9860(struct notifier_block *this, - unsigned long mode, void *cmd) +static int sprd_adi_restart_sc9860(struct sys_off_data *data) { struct sprd_adi_wdg wdg = { .base = PMIC_WDG_BASE, @@ -458,7 +453,7 @@ static int sprd_adi_restart_sc9860(struct notifier_block *this, .wdg_clk = PMIC_CLK_EN, }; - return sprd_adi_restart(this, mode, cmd, &wdg); + return sprd_adi_restart(data->cb_data, data->mode, data->cmd, &wdg); } static void sprd_adi_hw_init(struct sprd_adi *sadi) @@ -590,9 +585,9 @@ static int sprd_adi_probe(struct platform_device *pdev) } if (sadi->data->restart) { - sadi->restart_handler.notifier_call = sadi->data->restart; - sadi->restart_handler.priority = 128; - ret = register_restart_handler(&sadi->restart_handler); + ret = devm_register_restart_handler(&pdev->dev, + sadi->data->restart, + sadi); if (ret) { dev_err(&pdev->dev, "can not register restart handler\n"); goto put_ctlr; @@ -606,14 +601,6 @@ static int sprd_adi_probe(struct platform_device *pdev) return ret; } -static void sprd_adi_remove(struct platform_device *pdev) -{ - struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev); - struct sprd_adi *sadi = spi_controller_get_devdata(ctlr); - - unregister_restart_handler(&sadi->restart_handler); -} - static struct sprd_adi_data sc9860_data = { .slave_offset = ADI_10BIT_SLAVE_OFFSET, .slave_addr_size = ADI_10BIT_SLAVE_ADDR_SIZE, @@ -657,7 +644,6 @@ static struct platform_driver sprd_adi_driver = { .of_match_table = sprd_adi_of_match, }, .probe = sprd_adi_probe, - .remove_new = sprd_adi_remove, }; module_platform_driver(sprd_adi_driver); -- Gitee From 1e00df00147c8ab0be94c23cb97016b567fb8573 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 28 Nov 2023 17:30:06 +0800 Subject: [PATCH 1140/1449] spi: sprd-adi: switch to use spi_alloc_host() ANBZ: #35228 commit 1a27bd3c6949f0c4ffb4682fc32a0cb88458f85f stable. commit 0a3d087d09a8f52c02d0014bad63be99c53c4812 upstream. Switch to use modern name function spi_alloc_host(). No functional changed. Signed-off-by: Yang Yingliang Link: https://msgid.link/r/20231128093031.3707034-2-yangyingliang@huawei.com Signed-off-by: Mark Brown Stable-dep-of: 383d4f5cffcc ("spi: spi-sprd-adi: Fix double free in probe error path") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-sprd-adi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c index 58c3badd9c79..262c11d977ea 100644 --- a/drivers/spi/spi-sprd-adi.c +++ b/drivers/spi/spi-sprd-adi.c @@ -528,7 +528,7 @@ static int sprd_adi_probe(struct platform_device *pdev) pdev->id = of_alias_get_id(np, "spi"); num_chipselect = of_get_child_count(np); - ctlr = spi_alloc_master(&pdev->dev, sizeof(struct sprd_adi)); + ctlr = spi_alloc_host(&pdev->dev, sizeof(struct sprd_adi)); if (!ctlr) return -ENOMEM; -- Gitee From 60d28c826a09fa101d3efc33e9530ea6fab13952 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Fri, 9 Jan 2026 20:49:53 +0800 Subject: [PATCH 1141/1449] spi: spi-sprd-adi: Fix double free in probe error path ANBZ: #35228 commit 417cdfd9b9f986e95bfcb1d68eb443e6e0a15f8c stable. commit 383d4f5cffcc8df930d95b06518a9d25a6d74aac upstream. The driver currently uses spi_alloc_host() to allocate the controller but registers it using devm_spi_register_controller(). If devm_register_restart_handler() fails, the code jumps to the put_ctlr label and calls spi_controller_put(). However, since the controller was registered via a devm function, the device core will automatically call spi_controller_put() again when the probe fails. This results in a double-free of the spi_controller structure. Fix this by switching to devm_spi_alloc_host() and removing the manual spi_controller_put() call. Fixes: ac17750 ("spi: sprd: Add the support of restarting the system") Signed-off-by: Felix Gu Reviewed-by: Baolin Wang Link: https://patch.msgid.link/tencent_AC7D389CE7E24318445E226F7CDCCC2F0D07@qq.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-sprd-adi.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c index 262c11d977ea..f25b34a91756 100644 --- a/drivers/spi/spi-sprd-adi.c +++ b/drivers/spi/spi-sprd-adi.c @@ -528,7 +528,7 @@ static int sprd_adi_probe(struct platform_device *pdev) pdev->id = of_alias_get_id(np, "spi"); num_chipselect = of_get_child_count(np); - ctlr = spi_alloc_host(&pdev->dev, sizeof(struct sprd_adi)); + ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(struct sprd_adi)); if (!ctlr) return -ENOMEM; @@ -536,10 +536,8 @@ static int sprd_adi_probe(struct platform_device *pdev) sadi = spi_controller_get_devdata(ctlr); sadi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(sadi->base)) { - ret = PTR_ERR(sadi->base); - goto put_ctlr; - } + if (IS_ERR(sadi->base)) + return PTR_ERR(sadi->base); sadi->slave_vbase = (unsigned long)sadi->base + data->slave_offset; @@ -551,18 +549,15 @@ static int sprd_adi_probe(struct platform_device *pdev) if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) { sadi->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, ret); - if (!sadi->hwlock) { - ret = -ENXIO; - goto put_ctlr; - } + if (!sadi->hwlock) + return -ENXIO; } else { switch (ret) { case -ENOENT: dev_info(&pdev->dev, "no hardware spinlock supplied\n"); break; default: - dev_err_probe(&pdev->dev, ret, "failed to find hwlock id\n"); - goto put_ctlr; + return dev_err_probe(&pdev->dev, ret, "failed to find hwlock id\n"); } } @@ -579,26 +574,18 @@ static int sprd_adi_probe(struct platform_device *pdev) ctlr->transfer_one = sprd_adi_transfer_one; ret = devm_spi_register_controller(&pdev->dev, ctlr); - if (ret) { - dev_err(&pdev->dev, "failed to register SPI controller\n"); - goto put_ctlr; - } + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to register SPI controller\n"); if (sadi->data->restart) { ret = devm_register_restart_handler(&pdev->dev, sadi->data->restart, sadi); - if (ret) { - dev_err(&pdev->dev, "can not register restart handler\n"); - goto put_ctlr; - } + if (ret) + return dev_err_probe(&pdev->dev, ret, "can not register restart handler\n"); } return 0; - -put_ctlr: - spi_controller_put(ctlr); - return ret; } static struct sprd_adi_data sc9860_data = { -- Gitee From fe9ac25f087b8505a2eb252c86711a6af37b40fb Mon Sep 17 00:00:00 2001 From: Cheng-Yu Lee Date: Fri, 9 Jan 2026 11:26:33 +0800 Subject: [PATCH 1142/1449] regmap: Fix race condition in hwspinlock irqsave routine ANBZ: #35228 commit 24f31be6ad70537fd7706269d99c92cade465a09 stable. commit 4b58aac989c1e3fafb1c68a733811859df388250 upstream. Previously, the address of the shared member '&map->spinlock_flags' was passed directly to 'hwspin_lock_timeout_irqsave'. This creates a race condition where multiple contexts contending for the lock could overwrite the shared flags variable, potentially corrupting the state for the current lock owner. Fix this by using a local stack variable 'flags' to store the IRQ state temporarily. Fixes: 8698b9364710 ("regmap: Add hardware spinlock support") Signed-off-by: Cheng-Yu Lee Co-developed-by: Yu-Chun Lin Signed-off-by: Yu-Chun Lin Link: https://patch.msgid.link/20260109032633.8732-1-eleanor.lin@realtek.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/base/regmap/regmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 9603c28a3ed8..48860beff95c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -408,9 +408,11 @@ static void regmap_lock_hwlock_irq(void *__map) static void regmap_lock_hwlock_irqsave(void *__map) { struct regmap *map = __map; + unsigned long flags = 0; hwspin_lock_timeout_irqsave(map->hwlock, UINT_MAX, - &map->spinlock_flags); + &flags); + map->spinlock_flags = flags; } static void regmap_unlock_hwlock(void *__map) -- Gitee From 7532a0cd1c5c11e8d1b4a4416cfb43e5a73f22cd Mon Sep 17 00:00:00 2001 From: Arkadiusz Kozdra Date: Sat, 10 Jan 2026 19:48:08 +0800 Subject: [PATCH 1143/1449] kconfig: fix static linking of nconf ANBZ: #35228 commit 1b47e6d3bc026105d22f9aef7b24061e09318c4c stable. commit baaecfcac559bcac73206df447eb5c385fa22f2a upstream. When running make nconfig with a static linking host toolchain, the libraries are linked in an incorrect order, resulting in errors similar to the following: $ MAKEFLAGS='HOSTCC=cc\ -static' make nconfig /usr/bin/ld: /usr/lib64/gcc/x86_64-unknown-linux-gnu/14.2.1/../../../../lib64/libpanel.a(p_new.o): in function `new_panel': (.text+0x13): undefined reference to `_nc_panelhook_sp' /usr/bin/ld: (.text+0x6c): undefined reference to `_nc_panelhook_sp' Fixes: 1c5af5cf9308 ("kconfig: refactor ncurses package checks for building mconf and nconf") Signed-off-by: Arusekk Link: https://patch.msgid.link/20260110114808.22595-1-floss@arusekk.pl [nsc: Added comment about library order] Signed-off-by: Nicolas Schier Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- scripts/kconfig/nconf-cfg.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh index f871a2160e36..59814eb3616c 100755 --- a/scripts/kconfig/nconf-cfg.sh +++ b/scripts/kconfig/nconf-cfg.sh @@ -4,8 +4,9 @@ cflags=$1 libs=$2 -PKG="ncursesw menuw panelw" -PKG2="ncurses menu panel" +# Keep library order for static linking (HOSTCC='cc -static') +PKG="menuw panelw ncursesw" +PKG2="menu panel ncurses" if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then if ${HOSTPKG_CONFIG} --exists $PKG; then @@ -26,19 +27,19 @@ fi # find ncurses by pkg-config.) if [ -f /usr/include/ncursesw/ncurses.h ]; then echo -D_GNU_SOURCE -I/usr/include/ncursesw > ${cflags} - echo -lncursesw -lmenuw -lpanelw > ${libs} + echo -lmenuw -lpanelw -lncursesw > ${libs} exit 0 fi if [ -f /usr/include/ncurses/ncurses.h ]; then echo -D_GNU_SOURCE -I/usr/include/ncurses > ${cflags} - echo -lncurses -lmenu -lpanel > ${libs} + echo -lmenu -lpanel -lncurses > ${libs} exit 0 fi if [ -f /usr/include/ncurses.h ]; then echo -D_GNU_SOURCE > ${cflags} - echo -lncurses -lmenu -lpanel > ${libs} + echo -lmenu -lpanel -lncurses > ${libs} exit 0 fi -- Gitee From 2a8dd82081dae31e6a4f23334d2cdd194043c6e1 Mon Sep 17 00:00:00 2001 From: Naohiko Shimizu Date: Sun, 4 Jan 2026 21:59:36 +0800 Subject: [PATCH 1144/1449] riscv: clocksource: Fix stimecmp update hazard on RV32 ANBZ: #35228 commit 0df7ecb393db7ced2a95303d5cdb08a465a90f23 stable. commit eaa9bb1d39d59e7c17b06cec12622b7c586ab629 upstream. On RV32, updating the 64-bit stimecmp (or vstimecmp) CSR requires two separate 32-bit writes. A race condition exists if the timer triggers during these two writes. The RISC-V Privileged Specification (e.g., Section 3.2.1 for mtimecmp) recommends a specific 3-step sequence to avoid spurious interrupts when updating 64-bit comparison registers on 32-bit systems: 1. Set the low-order bits (stimecmp) to all ones (ULONG_MAX). 2. Set the high-order bits (stimecmph) to the desired value. 3. Set the low-order bits (stimecmp) to the desired value. Current implementation writes the LSB first without ensuring a future value, which may lead to a transient state where the 64-bit comparison is incorrectly evaluated as "expired" by the hardware. This results in spurious timer interrupts. This patch adopts the spec-recommended 3-step sequence to ensure the intermediate 64-bit state is never smaller than the current time. Fixes: 9f7a8ff6391f ("RISC-V: Prefer sstc extension if available") Signed-off-by: Naohiko Shimizu Reviewed-by: Anup Patel Link: https://patch.msgid.link/20260104135938.524-2-naohiko.shimizu@gmail.com Signed-off-by: Paul Walmsley Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/clocksource/timer-riscv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index 6d9e344e98f8..a454a75acc95 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -39,8 +39,9 @@ static int riscv_clock_next_event(unsigned long delta, csr_set(CSR_IE, IE_TIE); if (static_branch_likely(&riscv_sstc_available)) { #if defined(CONFIG_32BIT) - csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF); + csr_write(CSR_STIMECMP, ULONG_MAX); csr_write(CSR_STIMECMPH, next_tval >> 32); + csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF); #else csr_write(CSR_STIMECMP, next_tval); #endif -- Gitee From e5e1c7a932fad9525ccfa5a436159d6757df84e2 Mon Sep 17 00:00:00 2001 From: David Jeffery Date: Wed, 14 Jan 2026 00:08:13 +0800 Subject: [PATCH 1145/1449] scsi: core: Wake up the error handler when final completions race against each other ANBZ: #35228 commit 9fdc6f28d5e81350ab1d2cac8389062bd09e61e1 stable. commit fe2f8ad6f0999db3b318359a01ee0108c703a8c3 upstream. The fragile ordering between marking commands completed or failed so that the error handler only wakes when the last running command completes or times out has race conditions. These race conditions can cause the SCSI layer to fail to wake the error handler, leaving I/O through the SCSI host stuck as the error state cannot advance. First, there is an memory ordering issue within scsi_dec_host_busy(). The write which clears SCMD_STATE_INFLIGHT may be reordered with reads counting in scsi_host_busy(). While the local CPU will see its own write, reordering can allow other CPUs in scsi_dec_host_busy() or scsi_eh_inc_host_failed() to see a raised busy count, causing no CPU to see a host busy equal to the host_failed count. This race condition can be prevented with a memory barrier on the error path to force the write to be visible before counting host busy commands. Second, there is a general ordering issue with scsi_eh_inc_host_failed(). By counting busy commands before incrementing host_failed, it can race with a final command in scsi_dec_host_busy(), such that scsi_dec_host_busy() does not see host_failed incremented but scsi_eh_inc_host_failed() counts busy commands before SCMD_STATE_INFLIGHT is cleared by scsi_dec_host_busy(), resulting in neither waking the error handler task. This needs the call to scsi_host_busy() to be moved after host_failed is incremented to close the race condition. Fixes: 6eb045e092ef ("scsi: core: avoid host-wide host_busy counter for scsi_mq") Signed-off-by: David Jeffery Reviewed-by: Bart Van Assche Link: https://patch.msgid.link/20260113161036.6730-1-djeffery@redhat.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/scsi_error.c | 11 ++++++++++- drivers/scsi/scsi_lib.c | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 5882b5f80c04..c4c05cf38aa5 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -282,11 +282,20 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head) { struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu); struct Scsi_Host *shost = scmd->device->host; - unsigned int busy = scsi_host_busy(shost); + unsigned int busy; unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); shost->host_failed++; + spin_unlock_irqrestore(shost->host_lock, flags); + /* + * The counting of busy requests needs to occur after adding to + * host_failed or after the lock acquire for adding to host_failed + * to prevent a race with host unbusy and missing an eh wakeup. + */ + busy = scsi_host_busy(shost); + + spin_lock_irqsave(shost->host_lock, flags); scsi_eh_wakeup(shost, busy); spin_unlock_irqrestore(shost->host_lock, flags); } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index bd75e3ebc14d..efd1f1d6e4e9 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -278,6 +278,14 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd) rcu_read_lock(); __clear_bit(SCMD_STATE_INFLIGHT, &cmd->state); if (unlikely(scsi_host_in_recovery(shost))) { + /* + * Ensure the clear of SCMD_STATE_INFLIGHT is visible to + * other CPUs before counting busy requests. Otherwise, + * reordering can cause CPUs to race and miss an eh wakeup + * when no CPU sees all busy requests as done or timed out. + */ + smp_mb(); + unsigned int busy = scsi_host_busy(shost); spin_lock_irqsave(shost->host_lock, flags); -- Gitee From cbcd5e109efc9e26daccf24054f9bfa6e6c8be2e Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Wed, 7 Jan 2026 04:53:44 +0800 Subject: [PATCH 1146/1449] scsi: qla2xxx: Sanitize payload size to prevent member overflow ANBZ: #35228 commit 408bfa8d70f79ac696cec1bdbdfb3bf43a02e6d0 stable. commit 19bc5f2a6962dfaa0e32d0e0bc2271993d85d414 upstream. In qla27xx_copy_fpin_pkt() and qla27xx_copy_multiple_pkt(), the frame_size reported by firmware is used to calculate the copy length into item->iocb. However, the iocb member is defined as a fixed-size 64-byte array within struct purex_item. If the reported frame_size exceeds 64 bytes, subsequent memcpy calls will overflow the iocb member boundary. While extra memory might be allocated, this cross-member write is unsafe and triggers warnings under CONFIG_FORTIFY_SOURCE. Fix this by capping total_bytes to the size of the iocb member (64 bytes) before allocation and copying. This ensures all copies remain within the bounds of the destination structure member. Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe") Signed-off-by: Jiasheng Jiang Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20260106205344.18031-1-jiashengjiangcool@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_isr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index a85d3a40ee49..ae2bea27a18a 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -878,6 +878,9 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt, payload_size = sizeof(purex->els_frame_payload); } + if (total_bytes > sizeof(item->iocb.iocb)) + total_bytes = sizeof(item->iocb.iocb); + pending_bytes = total_bytes; no_bytes = (pending_bytes > payload_size) ? payload_size : pending_bytes; @@ -1163,6 +1166,10 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt, total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF) - PURX_ELS_HEADER_SIZE; + + if (total_bytes > sizeof(item->iocb.iocb)) + total_bytes = sizeof(item->iocb.iocb); + pending_bytes = total_bytes; entry_count = entry_count_remaining = purex->entry_count; no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ? -- Gitee From 8edd232fe0c42d58535f060edd8baa0ebb8c28c7 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Sat, 17 Jan 2026 06:58:04 +0800 Subject: [PATCH 1147/1449] ALSA: usb: Increase volume range that triggers a warning ANBZ: #35228 commit 7f523dd499b72c7cd29e63a033554791274784cb stable. commit 6b971191fcfc9e3c2c0143eea22534f1f48dbb62 upstream. On at least the HyperX Cloud III, the range is 18944 (-18944 -> 0 in steps of 1), so the original check for 255 steps is definitely obsolete. Let's give ourselves a little more headroom before we emit a warning. Fixes: 80acefff3bc7 ("ALSA: usb-audio - Add volume range check and warn if it too big") Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: linux-sound@vger.kernel.org Signed-off-by: Arun Raghavan Link: https://patch.msgid.link/20260116225804.3845935-1-arunr@valvesoftware.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/mixer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index e19d962fab87..76aac42c3c80 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1807,11 +1807,10 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer, range = (cval->max - cval->min) / cval->res; /* - * Are there devices with volume range more than 255? I use a bit more - * to be sure. 384 is a resolution magic number found on Logitech - * devices. It will definitively catch all buggy Logitech devices. + * There are definitely devices with a range of ~20,000, so let's be + * conservative and allow for a bit more. */ - if (range > 384) { + if (range > 65535) { usb_audio_warn(mixer->chip, "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.", range); -- Gitee From 4ea52b62dd720a9a3eabe473174d107138e92b35 Mon Sep 17 00:00:00 2001 From: Yun Lu Date: Fri, 16 Jan 2026 17:53:08 +0800 Subject: [PATCH 1148/1449] netdevsim: fix a race issue related to the operation on bpf_bound_progs list ANBZ: #35228 commit f1f9cfd2f46a73b7de2982d01be822eac3a0efaa stable. commit b97d5eedf4976cc94321243be83b39efe81a0e15 upstream. The netdevsim driver lacks a protection mechanism for operations on the bpf_bound_progs list. When the nsim_bpf_create_prog() performs list_add_tail, it is possible that nsim_bpf_destroy_prog() is simultaneously performs list_del. Concurrent operations on the list may lead to list corruption and trigger a kernel crash as follows: [ 417.290971] kernel BUG at lib/list_debug.c:62! [ 417.290983] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [ 417.290992] CPU: 10 PID: 168 Comm: kworker/10:1 Kdump: loaded Not tainted 6.19.0-rc5 #1 [ 417.291003] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 417.291007] Workqueue: events bpf_prog_free_deferred [ 417.291021] RIP: 0010:__list_del_entry_valid_or_report+0xa7/0xc0 [ 417.291034] Code: a8 ff 0f 0b 48 89 fe 48 89 ca 48 c7 c7 48 a1 eb ae e8 ed fb a8 ff 0f 0b 48 89 fe 48 89 c2 48 c7 c7 80 a1 eb ae e8 d9 fb a8 ff <0f> 0b 48 89 d1 48 c7 c7 d0 a1 eb ae 48 89 f2 48 89 c6 e8 c2 fb a8 [ 417.291040] RSP: 0018:ffffb16a40807df8 EFLAGS: 00010246 [ 417.291046] RAX: 000000000000006d RBX: ffff8e589866f500 RCX: 0000000000000000 [ 417.291051] RDX: 0000000000000000 RSI: ffff8e59f7b23180 RDI: ffff8e59f7b23180 [ 417.291055] RBP: ffffb16a412c9000 R08: 0000000000000000 R09: 0000000000000003 [ 417.291059] R10: ffffb16a40807c80 R11: ffffffffaf9edce8 R12: ffff8e594427ac20 [ 417.291063] R13: ffff8e59f7b44780 R14: ffff8e58800b7a05 R15: 0000000000000000 [ 417.291074] FS: 0000000000000000(0000) GS:ffff8e59f7b00000(0000) knlGS:0000000000000000 [ 417.291079] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 417.291083] CR2: 00007fc4083efe08 CR3: 00000001c3626006 CR4: 0000000000770ee0 [ 417.291088] PKRU: 55555554 [ 417.291091] Call Trace: [ 417.291096] [ 417.291103] nsim_bpf_destroy_prog+0x31/0x80 [netdevsim] [ 417.291154] __bpf_prog_offload_destroy+0x2a/0x80 [ 417.291163] bpf_prog_dev_bound_destroy+0x6f/0xb0 [ 417.291171] bpf_prog_free_deferred+0x18e/0x1a0 [ 417.291178] process_one_work+0x18a/0x3a0 [ 417.291188] worker_thread+0x27b/0x3a0 [ 417.291197] ? __pfx_worker_thread+0x10/0x10 [ 417.291207] kthread+0xe5/0x120 [ 417.291214] ? __pfx_kthread+0x10/0x10 [ 417.291221] ret_from_fork+0x31/0x50 [ 417.291230] ? __pfx_kthread+0x10/0x10 [ 417.291236] ret_from_fork_asm+0x1a/0x30 [ 417.291246] Add a mutex lock, to prevent simultaneous addition and deletion operations on the list. Fixes: 31d3ad832948 ("netdevsim: add bpf offload support") Reported-by: Yinhao Hu Reported-by: Kaiyan Mei Signed-off-by: Yun Lu Link: https://patch.msgid.link/20260116095308.11441-1-luyun_611@163.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/netdevsim/bpf.c | 6 ++++++ drivers/net/netdevsim/dev.c | 2 ++ drivers/net/netdevsim/netdevsim.h | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c index 608953d4f98d..ca64136372fc 100644 --- a/drivers/net/netdevsim/bpf.c +++ b/drivers/net/netdevsim/bpf.c @@ -244,7 +244,9 @@ static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev, &state->state, &nsim_bpf_string_fops); debugfs_create_bool("loaded", 0400, state->ddir, &state->is_loaded); + mutex_lock(&nsim_dev->progs_list_lock); list_add_tail(&state->l, &nsim_dev->bpf_bound_progs); + mutex_unlock(&nsim_dev->progs_list_lock); prog->aux->offload->dev_priv = state; @@ -273,12 +275,16 @@ static int nsim_bpf_translate(struct bpf_prog *prog) static void nsim_bpf_destroy_prog(struct bpf_prog *prog) { struct nsim_bpf_bound_prog *state; + struct nsim_dev *nsim_dev; state = prog->aux->offload->dev_priv; + nsim_dev = state->nsim_dev; WARN(state->is_loaded, "offload state destroyed while program still bound"); debugfs_remove_recursive(state->ddir); + mutex_lock(&nsim_dev->progs_list_lock); list_del(&state->l); + mutex_unlock(&nsim_dev->progs_list_lock); kfree(state); } diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 3e0b61202f0c..2614d6509954 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -1545,6 +1545,7 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; spin_lock_init(&nsim_dev->fa_cookie_lock); + mutex_init(&nsim_dev->progs_list_lock); dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); @@ -1683,6 +1684,7 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev) devl_unregister(devlink); kfree(nsim_dev->vfconfigs); kfree(nsim_dev->fa_cookie); + mutex_destroy(&nsim_dev->progs_list_lock); devl_unlock(devlink); devlink_free(devlink); dev_set_drvdata(&nsim_bus_dev->dev, NULL); diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index dfc6e00b718e..f2a31acc5e2e 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -295,6 +295,7 @@ struct nsim_dev { u32 prog_id_gen; struct list_head bpf_bound_progs; struct list_head bpf_bound_maps; + struct mutex progs_list_lock; struct netdev_phys_item_id switch_id; struct list_head port_list; bool fw_update_status; -- Gitee From d100a0ea920012135799deeee0d4c809fdccf31e Mon Sep 17 00:00:00 2001 From: David Yang Date: Tue, 20 Jan 2026 00:07:37 +0800 Subject: [PATCH 1149/1449] net: hns3: fix data race in hns3_fetch_stats ANBZ: #35228 commit a111d1fb91ae3429d6ca72129361bc2a6aa8dc83 stable. commit 748a81c8ceda1fdbdcd0af595947422e810442aa upstream. In hns3_fetch_stats(), ring statistics, protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. These statistics are already accumulated by hns3_ring_stats_update(). Fix this by reading them into a temporary buffer first. Fixes: b20d7fe51e0d ("net: hns3: add some statitics info to tx process") Signed-off-by: David Yang Link: https://patch.msgid.link/20260119160759.1455950-1-mmyangfl@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 69 ++++++++++--------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index b921fdc5b465..bb337d59de8c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2771,44 +2771,47 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb, static void hns3_fetch_stats(struct rtnl_link_stats64 *stats, struct hns3_enet_ring *ring, bool is_tx) { + struct ring_stats ring_stats; unsigned int start; do { start = u64_stats_fetch_begin(&ring->syncp); - if (is_tx) { - stats->tx_bytes += ring->stats.tx_bytes; - stats->tx_packets += ring->stats.tx_pkts; - stats->tx_dropped += ring->stats.sw_err_cnt; - stats->tx_dropped += ring->stats.tx_vlan_err; - stats->tx_dropped += ring->stats.tx_l4_proto_err; - stats->tx_dropped += ring->stats.tx_l2l3l4_err; - stats->tx_dropped += ring->stats.tx_tso_err; - stats->tx_dropped += ring->stats.over_max_recursion; - stats->tx_dropped += ring->stats.hw_limitation; - stats->tx_dropped += ring->stats.copy_bits_err; - stats->tx_dropped += ring->stats.skb2sgl_err; - stats->tx_dropped += ring->stats.map_sg_err; - stats->tx_errors += ring->stats.sw_err_cnt; - stats->tx_errors += ring->stats.tx_vlan_err; - stats->tx_errors += ring->stats.tx_l4_proto_err; - stats->tx_errors += ring->stats.tx_l2l3l4_err; - stats->tx_errors += ring->stats.tx_tso_err; - stats->tx_errors += ring->stats.over_max_recursion; - stats->tx_errors += ring->stats.hw_limitation; - stats->tx_errors += ring->stats.copy_bits_err; - stats->tx_errors += ring->stats.skb2sgl_err; - stats->tx_errors += ring->stats.map_sg_err; - } else { - stats->rx_bytes += ring->stats.rx_bytes; - stats->rx_packets += ring->stats.rx_pkts; - stats->rx_dropped += ring->stats.l2_err; - stats->rx_errors += ring->stats.l2_err; - stats->rx_errors += ring->stats.l3l4_csum_err; - stats->rx_crc_errors += ring->stats.l2_err; - stats->multicast += ring->stats.rx_multicast; - stats->rx_length_errors += ring->stats.err_pkt_len; - } + ring_stats = ring->stats; } while (u64_stats_fetch_retry(&ring->syncp, start)); + + if (is_tx) { + stats->tx_bytes += ring_stats.tx_bytes; + stats->tx_packets += ring_stats.tx_pkts; + stats->tx_dropped += ring_stats.sw_err_cnt; + stats->tx_dropped += ring_stats.tx_vlan_err; + stats->tx_dropped += ring_stats.tx_l4_proto_err; + stats->tx_dropped += ring_stats.tx_l2l3l4_err; + stats->tx_dropped += ring_stats.tx_tso_err; + stats->tx_dropped += ring_stats.over_max_recursion; + stats->tx_dropped += ring_stats.hw_limitation; + stats->tx_dropped += ring_stats.copy_bits_err; + stats->tx_dropped += ring_stats.skb2sgl_err; + stats->tx_dropped += ring_stats.map_sg_err; + stats->tx_errors += ring_stats.sw_err_cnt; + stats->tx_errors += ring_stats.tx_vlan_err; + stats->tx_errors += ring_stats.tx_l4_proto_err; + stats->tx_errors += ring_stats.tx_l2l3l4_err; + stats->tx_errors += ring_stats.tx_tso_err; + stats->tx_errors += ring_stats.over_max_recursion; + stats->tx_errors += ring_stats.hw_limitation; + stats->tx_errors += ring_stats.copy_bits_err; + stats->tx_errors += ring_stats.skb2sgl_err; + stats->tx_errors += ring_stats.map_sg_err; + } else { + stats->rx_bytes += ring_stats.rx_bytes; + stats->rx_packets += ring_stats.rx_pkts; + stats->rx_dropped += ring_stats.l2_err; + stats->rx_errors += ring_stats.l2_err; + stats->rx_errors += ring_stats.l3l4_csum_err; + stats->rx_crc_errors += ring_stats.l2_err; + stats->multicast += ring_stats.rx_multicast; + stats->rx_length_errors += ring_stats.err_pkt_len; + } } static void hns3_nic_get_stats64(struct net_device *netdev, -- Gitee From 81bd9888342e18089e0c5e7b48b37299de001850 Mon Sep 17 00:00:00 2001 From: David Yang Date: Mon, 19 Jan 2026 23:34:36 +0800 Subject: [PATCH 1150/1449] be2net: fix data race in be_get_new_eqd ANBZ: #35228 commit 42e16254f1d3ececd77653219d75f44c29e4512c stable. commit 302e5b481caa7b3d11ec0e058434c1fc95195e50 upstream. In be_get_new_eqd(), statistics of pkts, protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. Before the commit in question, these statistics were retrieved one by one directly from queues. Fix this by reading them into temporary variables first. Fixes: 209477704187 ("be2net: set interrupt moderation for Skyhawk-R using EQ-DB") Signed-off-by: David Yang Reviewed-by: Vadim Fedorenko Link: https://patch.msgid.link/20260119153440.1440578-1-mmyangfl@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/emulex/benet/be_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 8c3314445aca..71565b27893e 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2141,7 +2141,7 @@ static int be_get_new_eqd(struct be_eq_obj *eqo) struct be_aic_obj *aic; struct be_rx_obj *rxo; struct be_tx_obj *txo; - u64 rx_pkts = 0, tx_pkts = 0; + u64 rx_pkts = 0, tx_pkts = 0, pkts; ulong now; u32 pps, delta; int i; @@ -2157,15 +2157,17 @@ static int be_get_new_eqd(struct be_eq_obj *eqo) for_all_rx_queues_on_eq(adapter, eqo, rxo, i) { do { start = u64_stats_fetch_begin(&rxo->stats.sync); - rx_pkts += rxo->stats.rx_pkts; + pkts = rxo->stats.rx_pkts; } while (u64_stats_fetch_retry(&rxo->stats.sync, start)); + rx_pkts += pkts; } for_all_tx_queues_on_eq(adapter, eqo, txo, i) { do { start = u64_stats_fetch_begin(&txo->stats.sync); - tx_pkts += txo->stats.tx_reqs; + pkts = txo->stats.tx_reqs; } while (u64_stats_fetch_retry(&txo->stats.sync, start)); + tx_pkts += pkts; } /* Skip, if wrapped around or first calculation */ -- Gitee From 842bff4320c155d6905bd47cae2d4b2ebf9bdbec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 18 Jan 2026 21:25:28 +0800 Subject: [PATCH 1151/1449] mISDN: annotate data-race around dev->work ANBZ: #35228 commit fc8ba17fd3337bd8b1913c30b95df0fee00d8fb7 stable. commit 8175dbf174d487afab81e936a862a8d9b8a1ccb6 upstream. dev->work can re read locklessly in mISDN_read() and mISDN_poll(). Add READ_ONCE()/WRITE_ONCE() annotations. BUG: KCSAN: data-race in mISDN_ioctl / mISDN_read write to 0xffff88812d848280 of 4 bytes by task 10864 on cpu 1: misdn_add_timer drivers/isdn/mISDN/timerdev.c:175 [inline] mISDN_ioctl+0x2fb/0x550 drivers/isdn/mISDN/timerdev.c:233 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xce/0x140 fs/ioctl.c:583 __x64_sys_ioctl+0x43/0x50 fs/ioctl.c:583 x64_sys_call+0x14b0/0x3000 arch/x86/include/generated/asm/syscalls_64.h:17 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd8/0x2c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f read to 0xffff88812d848280 of 4 bytes by task 10857 on cpu 0: mISDN_read+0x1f2/0x470 drivers/isdn/mISDN/timerdev.c:112 do_loop_readv_writev fs/read_write.c:847 [inline] vfs_readv+0x3fb/0x690 fs/read_write.c:1020 do_readv+0xe7/0x210 fs/read_write.c:1080 __do_sys_readv fs/read_write.c:1165 [inline] __se_sys_readv fs/read_write.c:1162 [inline] __x64_sys_readv+0x45/0x50 fs/read_write.c:1162 x64_sys_call+0x2831/0x3000 arch/x86/include/generated/asm/syscalls_64.h:20 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd8/0x2c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f value changed: 0x00000000 -> 0x00000001 Fixes: 1b2b03f8e514 ("Add mISDN core files") Reported-by: syzbot Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260118132528.2349573-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/isdn/mISDN/timerdev.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 83d6b484d3c6..2ea1887ca2fa 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -109,14 +109,14 @@ mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off) spin_unlock_irq(&dev->lock); if (filep->f_flags & O_NONBLOCK) return -EAGAIN; - wait_event_interruptible(dev->wait, (dev->work || + wait_event_interruptible(dev->wait, (READ_ONCE(dev->work) || !list_empty(list))); if (signal_pending(current)) return -ERESTARTSYS; spin_lock_irq(&dev->lock); } if (dev->work) - dev->work = 0; + WRITE_ONCE(dev->work, 0); if (!list_empty(list)) { timer = list_first_entry(list, struct mISDNtimer, list); list_del(&timer->list); @@ -141,13 +141,16 @@ mISDN_poll(struct file *filep, poll_table *wait) if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p, %p)\n", __func__, filep, wait); if (dev) { + u32 work; + poll_wait(filep, &dev->wait, wait); mask = 0; - if (dev->work || !list_empty(&dev->expired)) + work = READ_ONCE(dev->work); + if (work || !list_empty(&dev->expired)) mask |= (EPOLLIN | EPOLLRDNORM); if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__, - dev->work, list_empty(&dev->expired)); + work, list_empty(&dev->expired)); } return mask; } @@ -172,7 +175,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) struct mISDNtimer *timer; if (!timeout) { - dev->work = 1; + WRITE_ONCE(dev->work, 1); wake_up_interruptible(&dev->wait); id = 0; } else { -- Gitee From f1243b2e3a13011a9703634e63271d9685d05e7b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 18 Jan 2026 23:29:41 +0800 Subject: [PATCH 1152/1449] ipv6: annotate data-race in ndisc_router_discovery() ANBZ: #35228 commit fad8f4ff7928f4d52a062ffdcffa484989c79c47 stable. commit 9a063f96d87efc3a6cc667f8de096a3d38d74bb5 upstream. syzbot found that ndisc_router_discovery() could read and write in6_dev->ra_mtu without holding a lock [1] This looks fine, IFLA_INET6_RA_MTU is best effort. Add READ_ONCE()/WRITE_ONCE() to document the race. Note that we might also reject illegal MTU values (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) in a future patch. [1] BUG: KCSAN: data-race in ndisc_router_discovery / ndisc_router_discovery read to 0xffff888119809c20 of 4 bytes by task 25817 on cpu 1: ndisc_router_discovery+0x151d/0x1c90 net/ipv6/ndisc.c:1558 ndisc_rcv+0x2ad/0x3d0 net/ipv6/ndisc.c:1841 icmpv6_rcv+0xe5a/0x12f0 net/ipv6/icmp.c:989 ip6_protocol_deliver_rcu+0xb2a/0x10d0 net/ipv6/ip6_input.c:438 ip6_input_finish+0xf0/0x1d0 net/ipv6/ip6_input.c:489 NF_HOOK include/linux/netfilter.h:318 [inline] ip6_input+0x5e/0x140 net/ipv6/ip6_input.c:500 ip6_mc_input+0x27c/0x470 net/ipv6/ip6_input.c:590 dst_input include/net/dst.h:474 [inline] ip6_rcv_finish+0x336/0x340 net/ipv6/ip6_input.c:79 ... write to 0xffff888119809c20 of 4 bytes by task 25816 on cpu 0: ndisc_router_discovery+0x155a/0x1c90 net/ipv6/ndisc.c:1559 ndisc_rcv+0x2ad/0x3d0 net/ipv6/ndisc.c:1841 icmpv6_rcv+0xe5a/0x12f0 net/ipv6/icmp.c:989 ip6_protocol_deliver_rcu+0xb2a/0x10d0 net/ipv6/ip6_input.c:438 ip6_input_finish+0xf0/0x1d0 net/ipv6/ip6_input.c:489 NF_HOOK include/linux/netfilter.h:318 [inline] ip6_input+0x5e/0x140 net/ipv6/ip6_input.c:500 ip6_mc_input+0x27c/0x470 net/ipv6/ip6_input.c:590 dst_input include/net/dst.h:474 [inline] ip6_rcv_finish+0x336/0x340 net/ipv6/ip6_input.c:79 ... value changed: 0x00000000 -> 0xe5400659 Fixes: 49b99da2c9ce ("ipv6: add IFLA_INET6_RA_MTU to expose mtu value") Reported-by: syzbot Signed-off-by: Eric Dumazet Cc: Rocco Yue Link: https://patch.msgid.link/20260118152941.2563857-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/ndisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d8e5e2833ede..80ceb401ecf2 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1574,8 +1574,8 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu)); mtu = ntohl(n); - if (in6_dev->ra_mtu != mtu) { - in6_dev->ra_mtu = mtu; + if (READ_ONCE(in6_dev->ra_mtu) != mtu) { + WRITE_ONCE(in6_dev->ra_mtu, mtu); send_ifinfo_notify = true; } -- Gitee From cd9f754507983e1b46e6193e61dd6a9b194f7961 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Mon, 19 Jan 2026 15:55:18 +0800 Subject: [PATCH 1153/1449] usbnet: limit max_mtu based on device's hard_mtu ANBZ: #35228 commit c378cdae4636961dcd21f77002d3339a42ab79f4 stable. commit c7159e960f1472a5493ac99aff0086ab1d683594 upstream. The usbnet driver initializes net->max_mtu to ETH_MAX_MTU before calling the device's bind() callback. When the bind() callback sets dev->hard_mtu based the device's actual capability (from CDC Ethernet's wMaxSegmentSize descriptor), max_mtu is never updated to reflect this hardware limitation). This allows userspace (DHCP or IPv6 RA) to configure MTU larger than the device can handle, leading to silent packet drops when the backend sends packet exceeding the device's buffer size. Fix this by limiting net->max_mtu to the device's hard_mtu after the bind callback returns. See https://gitlab.com/qemu-project/qemu/-/issues/3268 and https://bugs.passt.top/attachment.cgi?bugid=189 Fixes: f77f0aee4da4 ("net: use core MTU range checking in USB NIC drivers") Signed-off-by: Laurent Vivier Link: https://bugs.passt.top/show_bug.cgi?id=189 Reviewed-by: Stefano Brivio Link: https://patch.msgid.link/20260119075518.2774373-1-lvivier@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/usbnet.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index e6a1864f03f9..e41649365eff 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1799,9 +1799,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) if ((dev->driver_info->flags & FLAG_NOARP) != 0) net->flags |= IFF_NOARP; - /* maybe the remote can't receive an Ethernet MTU */ - if (net->mtu > (dev->hard_mtu - net->hard_header_len)) - net->mtu = dev->hard_mtu - net->hard_header_len; + if (net->max_mtu > (dev->hard_mtu - net->hard_header_len)) + net->max_mtu = dev->hard_mtu - net->hard_header_len; + + if (net->mtu > net->max_mtu) + net->mtu = net->max_mtu; + } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { -- Gitee From 83a9fe8a5bf68c6c958d2cfd50d777e24e4db58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Tue, 20 Jan 2026 04:36:23 +0800 Subject: [PATCH 1154/1449] drm/amd/pm: Don't clear SI SMC table when setting power limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 2c1fc0547a870a096d382fd94b0df7d5b87e6c8a stable. commit d5077426e1a76d269e518e048bde2e9fc49b32ad upstream. There is no reason to clear the SMC table. We also don't need to recalculate the power limit then. Fixes: 841686df9f7d ("drm/amdgpu: add SI DPM support (v4)") Reviewed-by: Alex Deucher Signed-off-by: Timur Kristóf Signed-off-by: Alex Deucher (cherry picked from commit e214d626253f5b180db10dedab161b7caa41f5e9) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index e5f68b2b8def..e8ca74fc089b 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -2257,8 +2257,6 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev, if (scaling_factor == 0) return -EINVAL; - memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE)); - ret = si_calculate_adjusted_tdp_limits(adev, false, /* ??? */ adev->pm.dpm.tdp_adjustment, @@ -2312,16 +2310,8 @@ static int si_populate_smc_tdp_limits_2(struct amdgpu_device *adev, if (ni_pi->enable_power_containment) { SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable; - u32 scaling_factor = si_get_smc_power_scaling_factor(adev); int ret; - memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE)); - - smc_table->dpm2Params.NearTDPLimit = - cpu_to_be32(si_scale_power_for_smc(adev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) * 1000); - smc_table->dpm2Params.SafePowerLimit = - cpu_to_be32(si_scale_power_for_smc((adev->pm.dpm.near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000); - ret = amdgpu_si_copy_bytes_to_smc(adev, (si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) + -- Gitee From ad8d12a8c438994af54a53cbde335c9f32f835d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Tue, 20 Jan 2026 04:36:24 +0800 Subject: [PATCH 1155/1449] drm/amd/pm: Workaround SI powertune issue on Radeon 430 (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit baafbbc23d42179fe9d271239be65f82c70627db stable. commit 764a90eb02268a23b1bb98be5f4a13671346804a upstream. Radeon 430 and 520 are OEM GPUs from 2016~2017 They have the same device id: 0x6611 and revision: 0x87 On the Radeon 430, powertune is buggy and throttles the GPU, never allowing it to reach its maximum SCLK. Work around this bug by raising the TDP limits we program to the SMC from 24W (specified by the VBIOS on Radeon 430) to 32W. Disabling powertune entirely is not a viable workaround, because it causes the Radeon 520 to heat up above 100 C, which I prefer to avoid. Additionally, revise the maximum SCLK limit. Considering the above issue, these GPUs never reached a high SCLK on Linux, and the workarounds were added before the GPUs were released, so the workaround likely didn't target these specifically. Use 780 MHz (the maximum SCLK according to the VBIOS on the Radeon 430). Note that the Radeon 520 VBIOS has a higher maximum SCLK: 905 MHz, but in practice it doesn't seem to perform better with the higher clock, only heats up more. v2: Move the workaround to si_populate_smc_tdp_limits. Fixes: 841686df9f7d ("drm/amdgpu: add SI DPM support (v4)") Reviewed-by: Alex Deucher Signed-off-by: Timur Kristóf Signed-off-by: Alex Deucher (cherry picked from commit 966d70f1e160bdfdecaf7ff2b3f22ad088516e9f) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index e8ca74fc089b..caf590caaf2c 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -2265,6 +2265,12 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev, if (ret) return ret; + if (adev->pdev->device == 0x6611 && adev->pdev->revision == 0x87) { + /* Workaround buggy powertune on Radeon 430 and 520. */ + tdp_limit = 32; + near_tdp_limit = 28; + } + smc_table->dpm2Params.TDPLimit = cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000); smc_table->dpm2Params.NearTDPLimit = @@ -3448,10 +3454,15 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, (adev->pdev->revision == 0x80) || (adev->pdev->revision == 0x81) || (adev->pdev->revision == 0x83) || - (adev->pdev->revision == 0x87) || + (adev->pdev->revision == 0x87 && + adev->pdev->device != 0x6611) || (adev->pdev->device == 0x6604) || (adev->pdev->device == 0x6605)) { max_sclk = 75000; + } else if (adev->pdev->revision == 0x87 && + adev->pdev->device == 0x6611) { + /* Radeon 430 and 520 */ + max_sclk = 78000; } } -- Gitee From ace8e2938bb9cb4c0f89cf55adb4c87ce8110352 Mon Sep 17 00:00:00 2001 From: Andrey Vatoropin Date: Tue, 20 Jan 2026 19:37:47 +0800 Subject: [PATCH 1156/1449] be2net: Fix NULL pointer dereference in be_cmd_get_mac_from_list ANBZ: #35228 commit e206fb415db36bad52bb90c08d46ce71ffbe8a80 stable. commit 8215794403d264739cc676668087512950b2ff31 upstream. When the parameter pmac_id_valid argument of be_cmd_get_mac_from_list() is set to false, the driver may request the PMAC_ID from the firmware of the network card, and this function will store that PMAC_ID at the provided address pmac_id. This is the contract of this function. However, there is a location within the driver where both pmac_id_valid == false and pmac_id == NULL are being passed. This could result in dereferencing a NULL pointer. To resolve this issue, it is necessary to pass the address of a stub variable to the function. Fixes: 95046b927a54 ("be2net: refactor MAC-addr setup code") Signed-off-by: Andrey Vatoropin Link: https://patch.msgid.link/20260120113734.20193-1-a.vatoropin@crpt.ru Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/emulex/benet/be_cmds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 779f1324bb5f..0cda78b78fb8 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3797,6 +3797,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac) { int status; bool pmac_valid = false; + u32 pmac_id; eth_zero_addr(mac); @@ -3809,7 +3810,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac) adapter->if_handle, 0); } else { status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid, - NULL, adapter->if_handle, 0); + &pmac_id, adapter->if_handle, 0); } return status; -- Gitee From 54b82a825d455a096967884e122e065e94acba19 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Tue, 20 Jan 2026 21:39:30 +0800 Subject: [PATCH 1157/1449] selftests: net: amt: wait longer for connection before sending packets ANBZ: #35228 commit a142ae1c56131089f617819a5529969a3b8204db stable. commit 04708606fd7bdc34b69089a4ff848ff36d7088f9 upstream. Both send_mcast4() and send_mcast6() use sleep 2 to wait for the tunnel connection between the gateway and the relay, and for the listener socket to be created in the LISTENER namespace. However, tests sometimes fail because packets are sent before the connection is fully established. Increase the waiting time to make the tests more reliable, and use wait_local_port_listen() to explicitly wait for the listener socket. Fixes: c08e8baea78e ("selftests: add amt interface selftest script") Signed-off-by: Taehee Yoo Link: https://patch.msgid.link/20260120133930.863845-1-ap420073@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/amt.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/amt.sh b/tools/testing/selftests/net/amt.sh index 7e7ed6c558da..ea40b469a8c1 100755 --- a/tools/testing/selftests/net/amt.sh +++ b/tools/testing/selftests/net/amt.sh @@ -73,6 +73,8 @@ # +------------------------+ #============================================================================== +source lib.sh + readonly LISTENER=$(mktemp -u listener-XXXXXXXX) readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX) readonly RELAY=$(mktemp -u relay-XXXXXXXX) @@ -240,14 +242,15 @@ test_ipv6_forward() send_mcast4() { - sleep 2 + sleep 5 + wait_local_port_listen ${LISTENER} 4000 udp ip netns exec "${SOURCE}" bash -c \ 'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' & } send_mcast6() { - sleep 2 + wait_local_port_listen ${LISTENER} 6000 udp ip netns exec "${SOURCE}" bash -c \ 'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' & } -- Gitee From 0d8e0f43b8e4f7ab8fbbaa57721c870897769873 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 21 Jan 2026 00:17:44 +0800 Subject: [PATCH 1158/1449] bonding: provide a net pointer to __skb_flow_dissect() ANBZ: #35228 commit 0efee0b992f28bd5ee01c7a86ef6a307c42eb907 stable. commit 5f9b329096596b7e53e07d041d7fca4cbe1be752 upstream. After 3cbf4ffba5ee ("net: plumb network namespace into __skb_flow_dissect") we have to provide a net pointer to __skb_flow_dissect(), either via skb->dev, skb->sk, or a user provided pointer. In the following case, syzbot was able to cook a bare skb. WARNING: net/core/flow_dissector.c:1131 at __skb_flow_dissect+0xb57/0x68b0 net/core/flow_dissector.c:1131, CPU#1: syz.2.1418/11053 Call Trace: bond_flow_dissect drivers/net/bonding/bond_main.c:4093 [inline] __bond_xmit_hash+0x2d7/0xba0 drivers/net/bonding/bond_main.c:4157 bond_xmit_hash_xdp drivers/net/bonding/bond_main.c:4208 [inline] bond_xdp_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5139 [inline] bond_xdp_get_xmit_slave+0x1fd/0x710 drivers/net/bonding/bond_main.c:5515 xdp_master_redirect+0x13f/0x2c0 net/core/filter.c:4388 bpf_prog_run_xdp include/net/xdp.h:700 [inline] bpf_test_run+0x6b2/0x7d0 net/bpf/test_run.c:421 bpf_prog_test_run_xdp+0x795/0x10e0 net/bpf/test_run.c:1390 bpf_prog_test_run+0x2c7/0x340 kernel/bpf/syscall.c:4703 __sys_bpf+0x562/0x860 kernel/bpf/syscall.c:6182 __do_sys_bpf kernel/bpf/syscall.c:6274 [inline] __se_sys_bpf kernel/bpf/syscall.c:6272 [inline] __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:6272 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xec/0xf80 arch/x86/entry/syscall_64.c:94 Fixes: 58deb77cc52d ("bonding: balance ICMP echoes in layer3+4 mode") Reported-by: syzbot+c46409299c70a221415e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/696faa23.050a0220.4cb9c.001f.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Cc: Matteo Croce Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20260120161744.1893263-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/bonding/bond_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f6f2d2285bfc..f684e035d7e3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4186,8 +4186,9 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, const v case BOND_XMIT_POLICY_ENCAP23: case BOND_XMIT_POLICY_ENCAP34: memset(fk, 0, sizeof(*fk)); - return __skb_flow_dissect(NULL, skb, &flow_keys_bonding, - fk, data, l2_proto, nhoff, hlen, 0); + return __skb_flow_dissect(dev_net(bond->dev), skb, + &flow_keys_bonding, fk, data, + l2_proto, nhoff, hlen, 0); default: break; } -- Gitee From f2bbb66464cedf7a2a4da8eda05a14ce0b6330eb Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Wed, 21 Jan 2026 05:10:39 +0800 Subject: [PATCH 1159/1449] net: dsa: fix off-by-one in maximum bridge ID determination ANBZ: #35228 commit 4ad32b1e0ca42cd3544621325af336a5e115dad2 stable. commit dfca045cd4d0ea07ff4198ba392be3e718acaddc upstream. Prior to the blamed commit, the bridge_num range was from 0 to ds->max_num_bridges - 1. After the commit, it is from 1 to ds->max_num_bridges. So this check: if (bridge_num >= max) return 0; must be updated to: if (bridge_num > max) return 0; in order to allow the last bridge_num value (==max) to be used. This is easiest visible when a driver sets ds->max_num_bridges=1. The observed behaviour is that even the first created bridge triggers the netlink extack "Range of offloadable bridges exceeded" warning, and is handled in software rather than being offloaded. Fixes: 3f9bb0301d50 ("net: dsa: make dp->bridge_num one-based") Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20260120211039.3228999-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/dsa/dsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index c9bf1a9a6c99..ea3082740936 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -158,7 +158,7 @@ unsigned int dsa_bridge_num_get(const struct net_device *bridge_dev, int max) bridge_num = find_next_zero_bit(&dsa_fwd_offloading_bridges, DSA_MAX_NUM_OFFLOADING_BRIDGES, 1); - if (bridge_num >= max) + if (bridge_num > max) return 0; set_bit(bridge_num, &dsa_fwd_offloading_bridges); -- Gitee From aa888e622c3215cf498194eae6190cee96d8f025 Mon Sep 17 00:00:00 2001 From: Ratheesh Kannoth Date: Wed, 21 Jan 2026 11:39:34 +0800 Subject: [PATCH 1160/1449] octeontx2-af: Fix error handling ANBZ: #35228 commit 77c6aa2c388e95332a55e517ec279b483f63a641 stable. commit 19e4175e997a5b85eab97d522f00cc99abd1873c upstream. This commit adds error handling and rollback logic to rvu_mbox_handler_attach_resources() to properly clean up partially attached resources when rvu_attach_block() fails. Fixes: 746ea74241fa0 ("octeontx2-af: Add RVU block LF provisioning support") Signed-off-by: Ratheesh Kannoth Link: https://patch.msgid.link/20260121033934.1900761-1-rkannoth@marvell.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/marvell/octeontx2/af/rvu.c | 86 ++++++++++++++----- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index 67e6d755b30e..846049b6c4d6 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -1541,8 +1541,8 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, return -ENODEV; } -static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype, - int num_lfs, struct rsrc_attach *attach) +static int rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype, + int num_lfs, struct rsrc_attach *attach) { struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); struct rvu_hwinfo *hw = rvu->hw; @@ -1552,21 +1552,21 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype, u64 cfg; if (!num_lfs) - return; + return -EINVAL; blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc, attach); if (blkaddr < 0) - return; + return -EFAULT; block = &hw->block[blkaddr]; if (!block->lf.bmap) - return; + return -ESRCH; for (slot = 0; slot < num_lfs; slot++) { /* Allocate the resource */ lf = rvu_alloc_rsrc(&block->lf); if (lf < 0) - return; + return -EFAULT; cfg = (1ULL << 63) | (pcifunc << 8) | slot; rvu_write64(rvu, blkaddr, block->lfcfg_reg | @@ -1577,6 +1577,8 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype, /* Set start MSIX vector for this LF within this PF/VF */ rvu_set_msix_offset(rvu, pfvf, block, lf); } + + return 0; } static int rvu_check_rsrc_availability(struct rvu *rvu, @@ -1714,22 +1716,31 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, int err; /* If first request, detach all existing attached resources */ - if (!attach->modify) - rvu_detach_rsrcs(rvu, NULL, pcifunc); + if (!attach->modify) { + err = rvu_detach_rsrcs(rvu, NULL, pcifunc); + if (err) + return err; + } mutex_lock(&rvu->rsrc_lock); /* Check if the request can be accommodated */ err = rvu_check_rsrc_availability(rvu, attach, pcifunc); if (err) - goto exit; + goto fail1; /* Now attach the requested resources */ - if (attach->npalf) - rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach); + if (attach->npalf) { + err = rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach); + if (err) + goto fail1; + } - if (attach->nixlf) - rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach); + if (attach->nixlf) { + err = rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach); + if (err) + goto fail2; + } if (attach->sso) { /* RVU func doesn't know which exact LF or slot is attached @@ -1739,33 +1750,64 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu, */ if (attach->modify) rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO); - rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO, - attach->sso, attach); + err = rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO, + attach->sso, attach); + if (err) + goto fail3; } if (attach->ssow) { if (attach->modify) rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW); - rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW, - attach->ssow, attach); + err = rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW, + attach->ssow, attach); + if (err) + goto fail4; } if (attach->timlfs) { if (attach->modify) rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM); - rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM, - attach->timlfs, attach); + err = rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM, + attach->timlfs, attach); + if (err) + goto fail5; } if (attach->cptlfs) { if (attach->modify && rvu_attach_from_same_block(rvu, BLKTYPE_CPT, attach)) rvu_detach_block(rvu, pcifunc, BLKTYPE_CPT); - rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT, - attach->cptlfs, attach); + err = rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT, + attach->cptlfs, attach); + if (err) + goto fail6; } -exit: + mutex_unlock(&rvu->rsrc_lock); + return 0; + +fail6: + if (attach->timlfs) + rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM); + +fail5: + if (attach->ssow) + rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW); + +fail4: + if (attach->sso) + rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO); + +fail3: + if (attach->nixlf) + rvu_detach_block(rvu, pcifunc, BLKTYPE_NIX); + +fail2: + if (attach->npalf) + rvu_detach_block(rvu, pcifunc, BLKTYPE_NPA); + +fail1: mutex_unlock(&rvu->rsrc_lock); return err; } -- Gitee From ae6694bb66afc17203437a4534883641b10ac9ca Mon Sep 17 00:00:00 2001 From: David Yang Date: Wed, 21 Jan 2026 15:29:26 +0800 Subject: [PATCH 1161/1449] net: openvswitch: fix data race in ovs_vport_get_upcall_stats ANBZ: #35228 commit c70e99dd37163e95aafe5ad33733f68d953c5aff stable. commit cc4816bdb08639e5cd9acb295a02d6f0f09736b4 upstream. In ovs_vport_get_upcall_stats(), some statistics protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. These statistics are already accumulated by u64_stats_inc(). Fix this by reading them into temporary variables first. Fixes: 1933ea365aa7 ("net: openvswitch: Add support to count upcall packets") Signed-off-by: David Yang Acked-by: Ilya Maximets Reviewed-by: Eric Dumazet Reviewed-by: Aaron Conole Link: https://patch.msgid.link/20260121072932.2360971-1-mmyangfl@gmail.com Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/openvswitch/vport.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 972ae01a70f7..0faa6e097829 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -310,22 +310,23 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats) */ int ovs_vport_get_upcall_stats(struct vport *vport, struct sk_buff *skb) { + u64 tx_success = 0, tx_fail = 0; struct nlattr *nla; int i; - __u64 tx_success = 0; - __u64 tx_fail = 0; - for_each_possible_cpu(i) { const struct vport_upcall_stats_percpu *stats; + u64 n_success, n_fail; unsigned int start; stats = per_cpu_ptr(vport->upcall_stats, i); do { start = u64_stats_fetch_begin(&stats->syncp); - tx_success += u64_stats_read(&stats->n_success); - tx_fail += u64_stats_read(&stats->n_fail); + n_success = u64_stats_read(&stats->n_success); + n_fail = u64_stats_read(&stats->n_fail); } while (u64_stats_fetch_retry(&stats->syncp, start)); + tx_success += n_success; + tx_fail += n_fail; } nla = nla_nest_start_noflag(skb, OVS_VPORT_ATTR_UPCALL_STATS); -- Gitee From 5c72c397da3e0390d4e7363e862cc161622c0d08 Mon Sep 17 00:00:00 2001 From: Melbin K Mathew Date: Wed, 21 Jan 2026 17:36:25 +0800 Subject: [PATCH 1162/1449] vsock/virtio: fix potential underflow in virtio_transport_get_credit() ANBZ: #35228 commit 02f9af192b98d15883c70dd41ac76d1b0217c899 stable. commit 3ef3d52a1a9860d094395c7a3e593f3aa26ff012 upstream. The credit calculation in virtio_transport_get_credit() uses unsigned arithmetic: ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); If the peer shrinks its advertised buffer (peer_buf_alloc) while bytes are in flight, the subtraction can underflow and produce a large positive value, potentially allowing more data to be queued than the peer can handle. Reuse virtio_transport_has_space() which already handles this case and add a comment to make it clear why we are doing that. Fixes: 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko") Suggested-by: Stefano Garzarella Signed-off-by: Melbin K Mathew [Stefano: use virtio_transport_has_space() instead of duplicating the code] [Stefano: tweak the commit message] Signed-off-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Link: https://patch.msgid.link/20260121093628.9941-2-sgarzare@redhat.com Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/vmw_vsock/virtio_transport_common.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index c57fe7ddcf73..1401177e2622 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -28,6 +28,7 @@ static void virtio_transport_cancel_close_work(struct vsock_sock *vsk, bool cancel_timeout); +static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs); static const struct virtio_transport * virtio_transport_get_ops(struct vsock_sock *vsk) @@ -316,9 +317,7 @@ u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit) return 0; spin_lock_bh(&vvs->tx_lock); - ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); - if (ret > credit) - ret = credit; + ret = min_t(u32, credit, virtio_transport_has_space(vvs)); vvs->tx_cnt += ret; spin_unlock_bh(&vvs->tx_lock); @@ -684,11 +683,14 @@ u32 virtio_transport_seqpacket_has_data(struct vsock_sock *vsk) } EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_has_data); -static s64 virtio_transport_has_space(struct vsock_sock *vsk) +static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs) { - struct virtio_vsock_sock *vvs = vsk->trans; s64 bytes; + /* Use s64 arithmetic so if the peer shrinks peer_buf_alloc while + * we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction + * does not underflow. + */ bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); if (bytes < 0) bytes = 0; @@ -702,7 +704,7 @@ s64 virtio_transport_stream_has_space(struct vsock_sock *vsk) s64 bytes; spin_lock_bh(&vvs->tx_lock); - bytes = virtio_transport_has_space(vsk); + bytes = virtio_transport_has_space(vvs); spin_unlock_bh(&vvs->tx_lock); return bytes; @@ -1301,7 +1303,7 @@ static bool virtio_transport_space_update(struct sock *sk, spin_lock_bh(&vvs->tx_lock); vvs->peer_buf_alloc = le32_to_cpu(hdr->buf_alloc); vvs->peer_fwd_cnt = le32_to_cpu(hdr->fwd_cnt); - space_available = virtio_transport_has_space(vsk); + space_available = virtio_transport_has_space(vvs); spin_unlock_bh(&vvs->tx_lock); return space_available; } -- Gitee From ee55320b7b43bd0853ff8b5bde31890a1fb455e8 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 21 Jan 2026 17:36:26 +0800 Subject: [PATCH 1163/1449] vsock/test: fix seqpacket message bounds test ANBZ: #35228 commit 17c9b158bc4d7ab67f0a013a965be19d2cd0c2c1 stable. commit 0a98de80136968bab7db37b16282b37f044694d3 upstream. The test requires the sender (client) to send all messages before waking up the receiver (server). Since virtio-vsock had a bug and did not respect the size of the TX buffer, this test worked, but now that we are going to fix the bug, the test hangs because the sender would fill the TX buffer before waking up the receiver. Set the buffer size in the sender (client) as well, as we already do for the receiver (server). Fixes: 5c338112e48a ("test/vsock: rework message bounds test") Signed-off-by: Stefano Garzarella Link: https://patch.msgid.link/20260121093628.9941-3-sgarzare@redhat.com Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/vsock/vsock_test.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index 5dc7767039f6..793d688cd4da 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -396,6 +396,7 @@ static void test_stream_msg_peek_server(const struct test_opts *opts) static void test_seqpacket_msg_bounds_client(const struct test_opts *opts) { + unsigned long long sock_buf_size; unsigned long curr_hash; size_t max_msg_size; int page_size; @@ -408,6 +409,16 @@ static void test_seqpacket_msg_bounds_client(const struct test_opts *opts) exit(EXIT_FAILURE); } + sock_buf_size = SOCK_BUF_SIZE; + + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); + + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); + /* Wait, until receiver sets buffer size. */ control_expectln("SRVREADY"); -- Gitee From 09881abf069dd62fbea1a0fee57a7681b3637d9f Mon Sep 17 00:00:00 2001 From: Melbin K Mathew Date: Wed, 21 Jan 2026 17:36:27 +0800 Subject: [PATCH 1164/1449] vsock/virtio: cap TX credit to local buffer size ANBZ: #35228 commit d9d5f222558b42f6277eafaaa6080966faf37676 stable. commit 8ee784fdf006cbe8739cfa093f54d326cbf54037 upstream. The virtio transports derives its TX credit directly from peer_buf_alloc, which is set from the remote endpoint's SO_VM_SOCKETS_BUFFER_SIZE value. On the host side this means that the amount of data we are willing to queue for a connection is scaled by a guest-chosen buffer size, rather than the host's own vsock configuration. A malicious guest can advertise a large buffer and read slowly, causing the host to allocate a correspondingly large amount of sk_buff memory. The same thing would happen in the guest with a malicious host, since virtio transports share the same code base. Introduce a small helper, virtio_transport_tx_buf_size(), that returns min(peer_buf_alloc, buf_alloc), and use it wherever we consume peer_buf_alloc. This ensures the effective TX window is bounded by both the peer's advertised buffer and our own buf_alloc (already clamped to buffer_max_size via SO_VM_SOCKETS_BUFFER_MAX_SIZE), so a remote peer cannot force the other to queue more data than allowed by its own vsock settings. On an unpatched Ubuntu 22.04 host (~64 GiB RAM), running a PoC with 32 guest vsock connections advertising 2 GiB each and reading slowly drove Slab/SUnreclaim from ~0.5 GiB to ~57 GiB; the system only recovered after killing the QEMU process. That said, if QEMU memory is limited with cgroups, the maximum memory used will be limited. With this patch applied: Before: MemFree: ~61.6 GiB Slab: ~142 MiB SUnreclaim: ~117 MiB After 32 high-credit connections: MemFree: ~61.5 GiB Slab: ~178 MiB SUnreclaim: ~152 MiB Only ~35 MiB increase in Slab/SUnreclaim, no host OOM, and the guest remains responsive. Compatibility with non-virtio transports: - VMCI uses the AF_VSOCK buffer knobs to size its queue pairs per socket based on the local vsk->buffer_* values; the remote side cannot enlarge those queues beyond what the local endpoint configured. - Hyper-V's vsock transport uses fixed-size VMBus ring buffers and an MTU bound; there is no peer-controlled credit field comparable to peer_buf_alloc, and the remote endpoint cannot drive in-flight kernel memory above those ring sizes. - The loopback path reuses virtio_transport_common.c, so it naturally follows the same semantics as the virtio transport. This change is limited to virtio_transport_common.c and thus affects virtio-vsock, vhost-vsock, and loopback, bringing them in line with the "remote window intersected with local policy" behaviour that VMCI and Hyper-V already effectively have. Fixes: 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko") Suggested-by: Stefano Garzarella Signed-off-by: Melbin K Mathew [Stefano: small adjustments after changing the previous patch] [Stefano: tweak the commit message] Signed-off-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Link: https://patch.msgid.link/20260121093628.9941-4-sgarzare@redhat.com Acked-by: Michael S. Tsirkin Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/vmw_vsock/virtio_transport_common.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index 1401177e2622..4c374c36c29d 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -628,6 +628,15 @@ virtio_transport_seqpacket_dequeue(struct vsock_sock *vsk, } EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_dequeue); +static u32 virtio_transport_tx_buf_size(struct virtio_vsock_sock *vvs) +{ + /* The peer advertises its receive buffer via peer_buf_alloc, but we + * cap it to our local buf_alloc so a remote peer cannot force us to + * queue more data than our own buffer configuration allows. + */ + return min(vvs->peer_buf_alloc, vvs->buf_alloc); +} + int virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk, struct msghdr *msg, @@ -637,7 +646,7 @@ virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk, spin_lock_bh(&vvs->tx_lock); - if (len > vvs->peer_buf_alloc) { + if (len > virtio_transport_tx_buf_size(vvs)) { spin_unlock_bh(&vvs->tx_lock); return -EMSGSIZE; } @@ -691,7 +700,8 @@ static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs) * we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction * does not underflow. */ - bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); + bytes = (s64)virtio_transport_tx_buf_size(vvs) - + (vvs->tx_cnt - vvs->peer_fwd_cnt); if (bytes < 0) bytes = 0; -- Gitee From 76b16e9564f04412b6d58b208637e41b05c46f29 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 21 Jan 2026 21:37:24 +0800 Subject: [PATCH 1165/1449] net/sched: act_ife: avoid possible NULL deref ANBZ: #35228 commit 03710cebfc0bcfe247a9e04381e79ea33896e278 stable. commit 27880b0b0d35ad1c98863d09788254e36f874968 upstream. tcf_ife_encode() must make sure ife_encode() does not return NULL. syzbot reported: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:ife_tlv_meta_encode+0x41/0xa0 net/ife/ife.c:166 CPU: 3 UID: 0 PID: 8990 Comm: syz.0.696 Not tainted syzkaller #0 PREEMPT(full) Call Trace: ife_encode_meta_u32+0x153/0x180 net/sched/act_ife.c:101 tcf_ife_encode net/sched/act_ife.c:841 [inline] tcf_ife_act+0x1022/0x1de0 net/sched/act_ife.c:877 tc_act include/net/tc_wrapper.h:130 [inline] tcf_action_exec+0x1c0/0xa20 net/sched/act_api.c:1152 tcf_exts_exec include/net/pkt_cls.h:349 [inline] mall_classify+0x1a0/0x2a0 net/sched/cls_matchall.c:42 tc_classify include/net/tc_wrapper.h:197 [inline] __tcf_classify net/sched/cls_api.c:1764 [inline] tcf_classify+0x7f2/0x1380 net/sched/cls_api.c:1860 multiq_classify net/sched/sch_multiq.c:39 [inline] multiq_enqueue+0xe0/0x510 net/sched/sch_multiq.c:66 dev_qdisc_enqueue+0x45/0x250 net/core/dev.c:4147 __dev_xmit_skb net/core/dev.c:4262 [inline] __dev_queue_xmit+0x2998/0x46c0 net/core/dev.c:4798 Fixes: 295a6e06d21e ("net/sched: act_ife: Change to use ife module") Reported-by: syzbot+5cf914f193dffde3bd3c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6970d61d.050a0220.706b.0010.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Cc: Yotam Gigi Reviewed-by: Jamal Hadi Salim Link: https://patch.msgid.link/20260121133724.3400020-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/act_ife.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 431921204f66..567a58d30df8 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -821,6 +821,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a, /* could be stupid policy setup or mtu config * so lets be conservative.. */ if ((action == TC_ACT_SHOT) || exceed_mtu) { +drop: qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats)); return TC_ACT_SHOT; } @@ -829,6 +830,8 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a, skb_push(skb, skb->dev->hard_header_len); ife_meta = ife_encode(skb, metalen); + if (!ife_meta) + goto drop; spin_lock(&ife->tcf_lock); @@ -844,8 +847,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a, if (err < 0) { /* too corrupt to keep around if overwritten */ spin_unlock(&ife->tcf_lock); - qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats)); - return TC_ACT_SHOT; + goto drop; } skboff += err; } -- Gitee From bcd08121d48701824997af811b8212286727b5d4 Mon Sep 17 00:00:00 2001 From: Cedric Xing Date: Fri, 23 Jan 2026 08:39:15 +0800 Subject: [PATCH 1166/1449] x86: make page fault handling disable interrupts properly ANBZ: #35228 commit 93dfcc59b2bf36f92b7fc3ce71867f624ca8e52d stable. commit 614da1d3d4cdbd6e41aea06bc97ec15aacff6daf upstream. There's a big comment in the x86 do_page_fault() about our interrupt disabling code: * User address page fault handling might have reenabled * interrupts. Fixing up all potential exit points of * do_user_addr_fault() and its leaf functions is just not * doable w/o creating an unholy mess or turning the code * upside down. but it turns out that comment is subtly wrong, and the code as a result is also wrong. Because it's certainly true that we may have re-enabled interrupts when handling user page faults. And it's most certainly true that we don't want to bother fixing up all the cases. But what isn't true is that it's limited to user address page faults. The confusion stems from the fact that we have logic here that depends on the address range of the access, but other code then depends on the _context_ the access was done in. The two are not related, even though both of them are about user-vs-kernel. In other words, both user and kernel addresses can cause interrupts to have been enabled (eg when __bad_area_nosemaphore() gets called for user accesses to kernel addresses). As a result we should make sure to disable interrupts again regardless of the address range before returning to the low-level fault handling code. The __bad_area_nosemaphore() code actually did disable interrupts again after enabling them, just not consistently. Ironically, as noted in the original comment, fixing up all the cases is just not worth it, when the simple solution is to just do it unconditionally in one single place. So remove the incomplete case that unsuccessfully tried to do what the comment said was "not doable" in commit ca4c6a9858c2 ("x86/traps: Make interrupt enable/disable symmetric in C code"), and just make it do the simple and straightforward thing. Signed-off-by: Cedric Xing Reviewed-by: Dave Hansen Fixes: ca4c6a9858c2 ("x86/traps: Make interrupt enable/disable symmetric in C code") Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/mm/fault.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 75c438104995..c9564e97bf56 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -816,8 +816,6 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, force_sig_pkuerr((void __user *)address, pkey); else force_sig_fault(SIGSEGV, si_code, (void __user *)address); - - local_irq_disable(); } static noinline void @@ -1469,15 +1467,12 @@ handle_page_fault(struct pt_regs *regs, unsigned long error_code, do_kern_addr_fault(regs, error_code, address); } else { do_user_addr_fault(regs, error_code, address); - /* - * User address page fault handling might have reenabled - * interrupts. Fixing up all potential exit points of - * do_user_addr_fault() and its leaf functions is just not - * doable w/o creating an unholy mess or turning the code - * upside down. - */ - local_irq_disable(); } + /* + * page fault handling might have reenabled interrupts, + * make sure to disable them again. + */ + local_irq_disable(); } DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault) -- Gitee From 4c28167c129b4cc2800643e2840adb7107024434 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 12 Dec 2025 00:37:27 +0800 Subject: [PATCH 1167/1449] leds: led-class: Only Add LED to leds_list when it is fully ready ANBZ: #35228 commit 2757f7748ce2d0fa44112024907bafb37e104d6e stable. commit d1883cefd31752f0504b94c3bcfa1f6d511d6e87 upstream. Before this change the LED was added to leds_list before led_init_core() gets called adding it the list before led_classdev.set_brightness_work gets initialized. This leaves a window where led_trigger_register() of a LED's default trigger will call led_trigger_set() which calls led_set_brightness() which in turn will end up queueing the *uninitialized* led_classdev.set_brightness_work. This race gets hit by the lenovo-thinkpad-t14s EC driver which registers 2 LEDs with a default trigger provided by snd_ctl_led.ko in quick succession. The first led_classdev_register() causes an async modprobe of snd_ctl_led to run and that async modprobe manages to exactly hit the window where the second LED is on the leds_list without led_init_core() being called for it, resulting in: ------------[ cut here ]------------ WARNING: CPU: 11 PID: 5608 at kernel/workqueue.c:4234 __flush_work+0x344/0x390 Hardware name: LENOVO 21N2S01F0B/21N2S01F0B, BIOS N42ET93W (2.23 ) 09/01/2025 ... Call trace: __flush_work+0x344/0x390 (P) flush_work+0x2c/0x50 led_trigger_set+0x1c8/0x340 led_trigger_register+0x17c/0x1c0 led_trigger_register_simple+0x84/0xe8 snd_ctl_led_init+0x40/0xf88 [snd_ctl_led] do_one_initcall+0x5c/0x318 do_init_module+0x9c/0x2b8 load_module+0x7e0/0x998 Close the race window by moving the adding of the LED to leds_list to after the led_init_core() call. Cc: stable@vger.kernel.org Fixes: d23a22a74fde ("leds: delay led_set_brightness if stopping soft-blink") Signed-off-by: Hans de Goede Reviewed-by: Sebastian Reichel Link: https://patch.msgid.link/20251211163727.366441-1-johannes.goede@oss.qualcomm.com Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/leds/led-class.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index e7d75716632b..ac803768e407 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -546,11 +546,6 @@ int led_classdev_register_ext(struct device *parent, #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED led_cdev->brightness_hw_changed = -1; #endif - /* add to the list of leds */ - down_write(&leds_list_lock); - list_add_tail(&led_cdev->node, &leds_list); - up_write(&leds_list_lock); - if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; @@ -558,6 +553,11 @@ int led_classdev_register_ext(struct device *parent, led_init_core(led_cdev); + /* add to the list of leds */ + down_write(&leds_list_lock); + list_add_tail(&led_cdev->node, &leds_list); + up_write(&leds_list_lock); + #ifdef CONFIG_LEDS_TRIGGERS led_trigger_set_default(led_cdev); #endif -- Gitee From 001da276f59ebb21c7db6c88f360a9c53cc4d6ed Mon Sep 17 00:00:00 2001 From: Weigang He Date: Sat, 17 Jan 2026 17:12:38 +0800 Subject: [PATCH 1168/1449] of: fix reference count leak in of_alias_scan() ANBZ: #35228 commit f4c270975fe1ddcdbe4170d552e183bd688e2bfc stable. commit 81122fba08fa3ccafab6ed272a5c6f2203923a7e upstream. of_find_node_by_path() returns a device_node with its refcount incremented. When kstrtoint() fails or dt_alloc() fails, the function continues to the next iteration without calling of_node_put(), causing a reference count leak. Add of_node_put(np) before continue on both error paths to properly release the device_node reference. Fixes: 611cad720148 ("dt: add of_alias_scan and of_alias_get_id") Cc: stable@vger.kernel.org Signed-off-by: Weigang He Link: https://patch.msgid.link/20260117091238.481243-1-geoffreyhe2@gmail.com Signed-off-by: Rob Herring (Arm) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/of/base.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index ccadc22f18c0..d10248a5c0a5 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1788,13 +1788,17 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) end--; len = end - start; - if (kstrtoint(end, 10, &id) < 0) + if (kstrtoint(end, 10, &id) < 0) { + of_node_put(np); continue; + } /* Allocate an alias_prop with enough space for the stem */ ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap)); - if (!ap) + if (!ap) { + of_node_put(np); continue; + } memset(ap, 0, sizeof(*ap) + len + 1); ap->alias = start; of_alias_add(ap, np, id, start, len); -- Gitee From 6315c502e809a6ff9a2c5e160ada2ab5fd3e9716 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Wed, 14 Jan 2026 09:51:58 +0800 Subject: [PATCH 1169/1449] of: platform: Use default match table for /firmware ANBZ: #35228 commit c0ebc3d8ad6b5904b5d32c7f62d44bab30c4a098 stable. commit 48e6a9c4a20870e09f85ff1a3628275d6bce31c0 upstream. Calling of_platform_populate() without a match table will only populate the immediate child nodes under /firmware. This is usually fine, but in the case of something like a "simple-mfd" node such as "raspberrypi,bcm2835-firmware", those child nodes will not be populated. And subsequent calls won't work either because the /firmware node is marked as processed already. Switch the call to of_platform_default_populate() to solve this problem. It should be a nop for existing cases. Fixes: 3aa0582fdb82 ("of: platform: populate /firmware/ node from of_platform_default_populate_init()") Cc: stable@vger.kernel.org Reviewed-by: Sudeep Holla Link: https://patch.msgid.link/20260114015158.692170-2-robh@kernel.org Signed-off-by: Rob Herring (Arm) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/of/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f235ab55b91e..ccf7f0ffa67f 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -616,7 +616,7 @@ static int __init of_platform_default_populate_init(void) node = of_find_node_by_path("/firmware"); if (node) { - of_platform_populate(node, NULL, NULL, NULL); + of_platform_default_populate(node, NULL, NULL); of_node_put(node); } -- Gitee From 7073e56159dd67dd86c9956df0e32a51b5a8d638 Mon Sep 17 00:00:00 2001 From: Markus Koeniger Date: Wed, 7 Jan 2026 23:32:18 +0800 Subject: [PATCH 1170/1449] iio: accel: iis328dq: fix gain values ANBZ: #35228 commit 9e77ef924fe31714bf57ce3c689a70bf541257a0 stable. commit b8f15d1df2e73322e2112de21a4a7f3553c7fb60 upstream. The sensors IIS328DQ and H3LIS331DL share one configuration but H3LIS331DL has different gain parameters, configs therefore need to be split up. The gain parameters for the IIS328DQ are 0.98, 1.95 and 3.91, depending on the selected measurement range. See sensor manuals, chapter 2.1 "mechanical characteristics", parameter "Sensitivity". Datasheet: https://www.st.com/resource/en/datasheet/iis328dq.pdf Datasheet: https://www.st.com/resource/en/datasheet/h3lis331dl.pdf Fixes: 46e33707fe95 ("iio: accel: add support for IIS328DQ variant") Reviewed-by: Dimitri Fedrau Signed-off-by: Markus Koeniger Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/accel/st_accel_core.c | 72 ++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index d2104e14e255..51d8de18e6d6 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c @@ -517,7 +517,6 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, .sensors_supported = { [0] = H3LIS331DL_ACCEL_DEV_NAME, - [1] = IIS328DQ_ACCEL_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_accel_12bit_channels, .odr = { @@ -584,6 +583,77 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { .multi_read_bit = true, .bootime = 2, }, + { + .wai = 0x32, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = IIS328DQ_ACCEL_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_accel_12bit_channels, + .odr = { + .addr = 0x20, + .mask = 0x18, + .odr_avl = { + { .hz = 50, .value = 0x00, }, + { .hz = 100, .value = 0x01, }, + { .hz = 400, .value = 0x02, }, + { .hz = 1000, .value = 0x03, }, + }, + }, + .pw = { + .addr = 0x20, + .mask = 0x20, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .enable_axis = { + .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, + .mask = ST_SENSORS_DEFAULT_AXIS_MASK, + }, + .fs = { + .addr = 0x23, + .mask = 0x30, + .fs_avl = { + [0] = { + .num = ST_ACCEL_FS_AVL_100G, + .value = 0x00, + .gain = IIO_G_TO_M_S_2(980), + }, + [1] = { + .num = ST_ACCEL_FS_AVL_200G, + .value = 0x01, + .gain = IIO_G_TO_M_S_2(1950), + }, + [2] = { + .num = ST_ACCEL_FS_AVL_400G, + .value = 0x03, + .gain = IIO_G_TO_M_S_2(3910), + }, + }, + }, + .bdu = { + .addr = 0x23, + .mask = 0x80, + }, + .drdy_irq = { + .int1 = { + .addr = 0x22, + .mask = 0x02, + }, + .int2 = { + .addr = 0x22, + .mask = 0x10, + }, + .addr_ihl = 0x22, + .mask_ihl = 0x80, + }, + .sim = { + .addr = 0x23, + .value = BIT(0), + }, + .multi_read_bit = true, + .bootime = 2, + }, { /* No WAI register present */ .sensors_supported = { -- Gitee From 82cb9b051a9d7a39c8c0a8e6b17c8ac7013947d3 Mon Sep 17 00:00:00 2001 From: Tomas Melin Date: Wed, 3 Dec 2025 17:28:11 +0800 Subject: [PATCH 1171/1449] iio: adc: ad9467: fix ad9434 vref mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 8271e1860c7cdddfdd1277b84b7a41fc0d45e58e stable. commit 92452b1760ff2d1d411414965d4d06f75e1bda9a upstream. The mask setting is 5 bits wide for the ad9434 (ref. data sheet register 0x18 FLEX_VREF). Apparently the settings from ad9265 were copied by mistake when support for the device was added to the driver. Fixes: 4606d0f4b05f ("iio: adc: ad9467: add support for AD9434 high-speed ADC") Reviewed-by: Andy Shevchenko Reviewed-by: Nuno Sá Reviewed-by: David Lechner Signed-off-by: Tomas Melin Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/ad9467.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 4c08f8a04f96..26829ff29d35 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -90,7 +90,7 @@ #define CHIPID_AD9434 0x6A #define AD9434_DEF_OUTPUT_MODE 0x00 -#define AD9434_REG_VREF_MASK 0xC0 +#define AD9434_REG_VREF_MASK GENMASK(4, 0) /* * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC -- Gitee From 8ca6ae570d521084af2c0e54dbf6ba6dda4c8fa6 Mon Sep 17 00:00:00 2001 From: Pei Xiao Date: Wed, 29 Oct 2025 10:40:16 +0800 Subject: [PATCH 1172/1449] iio: adc: at91-sama5d2_adc: Fix potential use-after-free in sama5d2_adc driver ANBZ: #35228 commit 9795fe80976f8c31cafda7d44edfc0f532d1f7c4 stable. commit dbdb442218cd9d613adeab31a88ac973f22c4873 upstream. at91_adc_interrupt can call at91_adc_touch_data_handler function to start the work by schedule_work(&st->touch_st.workq). If we remove the module which will call at91_adc_remove to make cleanup, it will free indio_dev through iio_device_unregister but quite a bit later. While the work mentioned above will be used. The sequence of operations that may lead to a UAF bug is as follows: CPU0 CPU1 | at91_adc_workq_handler at91_adc_remove | iio_device_unregister(indio_dev) | //free indio_dev a bit later | | iio_push_to_buffers(indio_dev) | //use indio_dev Fix it by ensuring that the work is canceled before proceeding with the cleanup in at91_adc_remove. Fixes: 23ec2774f1cc ("iio: adc: at91-sama5d2_adc: add support for position and pressure channels") Signed-off-by: Pei Xiao Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/at91-sama5d2_adc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index b54e4481fafb..4ca39a2527c2 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -2504,6 +2504,7 @@ static int at91_adc_remove(struct platform_device *pdev) struct at91_adc_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); + cancel_work_sync(&st->touch_st.workq); at91_adc_dma_disable(st); -- Gitee From a78e4e1a95147e364d70874ec06500822757a56c Mon Sep 17 00:00:00 2001 From: Fiona Klute Date: Sun, 14 Dec 2025 00:32:26 +0800 Subject: [PATCH 1173/1449] iio: chemical: scd4x: fix reported channel endianness ANBZ: #35228 commit c2d6e00829cbf87129242fdb54b188eb73a82c5d stable. commit 81d5a5366d3c20203fb9d7345e1aa46d668445a2 upstream. The driver converts values read from the sensor from BE to CPU endianness in scd4x_read_meas(). The result is then pushed into the buffer in scd4x_trigger_handler(), so on LE architectures parsing the buffer using the reported BE type gave wrong results. scd4x_read_raw() which provides sysfs *_raw values is not affected, it used the values returned by scd4x_read_meas() without further conversion. Fixes: 49d22b695cbb6 ("drivers: iio: chemical: Add support for Sensirion SCD4x CO2 sensor") Signed-off-by: Fiona Klute Reviewed-by: David Lechner Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/chemical/scd4x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c index ca6b20270711..6fd0fa3d3fbe 100644 --- a/drivers/iio/chemical/scd4x.c +++ b/drivers/iio/chemical/scd4x.c @@ -585,7 +585,7 @@ static const struct iio_chan_spec scd4x_channels[] = { .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_BE, + .endianness = IIO_CPU, }, }, { @@ -600,7 +600,7 @@ static const struct iio_chan_spec scd4x_channels[] = { .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_BE, + .endianness = IIO_CPU, }, }, { @@ -613,7 +613,7 @@ static const struct iio_chan_spec scd4x_channels[] = { .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_BE, + .endianness = IIO_CPU, }, }, }; -- Gitee From 15dfc702a902653ef11342ba7ff945bc58fc681d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=BCbrich=2C=20Andreas?= Date: Mon, 17 Nov 2025 20:35:13 +0800 Subject: [PATCH 1174/1449] iio: dac: ad5686: add AD5695R to ad5686_chip_info_tbl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit cbe409f68380ac8b8f11a52086f8e5364ed07aea stable. commit 441ac29923c9172bc5e4b2c4f52ae756192f5715 upstream. The chip info for this variant (I2C, four channels, 14 bit, internal reference) seems to have been left out due to oversight, so ad5686_chip_info_tbl[ID_AD5695R] is all zeroes. Initialisation of an AD5695R still succeeds, but the resulting IIO device has no channels and no /dev/iio:device* node. Add the missing chip info to the table. Fixes: 4177381b4401 ("iio:dac:ad5686: Add AD5671R/75R/94/94R/95R/96/96R support") Signed-off-by: Andreas Kübrich Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/dac/ad5686.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 57cc0f0eedc6..4c9f7ade52b3 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -434,6 +434,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { .num_channels = 4, .regmap_type = AD5686_REGMAP, }, + [ID_AD5695R] = { + .channels = ad5685r_channels, + .int_vref_mv = 2500, + .num_channels = 4, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5696] = { .channels = ad5686_channels, .num_channels = 4, -- Gitee From 7d426f7caddadb4d13d39a361bb8ae87f51d22be Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Jan 2026 21:32:07 +0800 Subject: [PATCH 1175/1449] ALSA: ctxfi: Fix potential OOB access in audio mixer handling ANBZ: #35228 commit a8c42d11b0526a89192bd2f79facb4c60c8a1f38 stable. commit 61006c540cbdedea83b05577dc7fb7fa18fe1276 upstream. In the audio mixer handling code of ctxfi driver, the conf field is used as a kind of loop index, and it's referred in the index callbacks (amixer_index() and sum_index()). As spotted recently by fuzzers, the current code causes OOB access at those functions. | UBSAN: array-index-out-of-bounds in /build/reproducible-path/linux-6.17.8/sound/pci/ctxfi/ctamixer.c:347:48 | index 8 is out of range for type 'unsigned char [8]' After the analysis, the cause was found to be the lack of the proper (re-)initialization of conj field. This patch addresses those OOB accesses by adding the proper initializations of the loop indices. Reported-by: Salvatore Bonaccorso Tested-by: Karsten Hohmeier Closes: https://bugs.debian.org/1121535 Cc: Link: https://lore.kernel.org/all/aSk8KJI35H7gFru6@eldamar.lan/ Link: https://patch.msgid.link/20260119133212.189129-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/ctxfi/ctamixer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c index d074727c3e21..5922b9dc5890 100644 --- a/sound/pci/ctxfi/ctamixer.c +++ b/sound/pci/ctxfi/ctamixer.c @@ -205,6 +205,7 @@ static int amixer_rsc_init(struct amixer *amixer, /* Set amixer specific operations */ amixer->rsc.ops = &amixer_basic_rsc_ops; + amixer->rsc.conj = 0; amixer->ops = &amixer_ops; amixer->input = NULL; amixer->sum = NULL; @@ -369,6 +370,7 @@ static int sum_rsc_init(struct sum *sum, return err; sum->rsc.ops = &sum_basic_rsc_ops; + sum->rsc.conj = 0; return 0; } -- Gitee From d4d242d287ad9802c9feef4d96fbc1fcb4d7134c Mon Sep 17 00:00:00 2001 From: Berk Cem Goksel Date: Tue, 20 Jan 2026 18:28:55 +0800 Subject: [PATCH 1176/1449] ALSA: usb-audio: Fix use-after-free in snd_usb_mixer_free() ANBZ: #35228 commit 7bff0156d13f0ad9436e5178b979b063d59f572a stable. commit 930e69757b74c3ae083b0c3c7419bfe7f0edc7b2 upstream. When snd_usb_create_mixer() fails, snd_usb_mixer_free() frees mixer->id_elems but the controls already added to the card still reference the freed memory. Later when snd_card_register() runs, the OSS mixer layer calls their callbacks and hits a use-after-free read. Call trace: get_ctl_value+0x63f/0x820 sound/usb/mixer.c:411 get_min_max_with_quirks.isra.0+0x240/0x1f40 sound/usb/mixer.c:1241 mixer_ctl_feature_info+0x26b/0x490 sound/usb/mixer.c:1381 snd_mixer_oss_build_test+0x174/0x3a0 sound/core/oss/mixer_oss.c:887 ... snd_card_register+0x4ed/0x6d0 sound/core/init.c:923 usb_audio_probe+0x5ef/0x2a90 sound/usb/card.c:1025 Fix by calling snd_ctl_remove() for all mixer controls before freeing id_elems. We save the next pointer first because snd_ctl_remove() frees the current element. Fixes: 6639b6c2367f ("[ALSA] usb-audio - add mixer control notifications") Cc: stable@vger.kernel.org Cc: Andrey Konovalov Signed-off-by: Berk Cem Goksel Link: https://patch.msgid.link/20260120102855.7300-1-berkcgoksel@gmail.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/mixer.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 76aac42c3c80..ab39d86bd08d 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2938,10 +2938,23 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) { + struct usb_mixer_elem_list *list, *next; + int id; + /* kill pending URBs */ snd_usb_mixer_disconnect(mixer); - kfree(mixer->id_elems); + /* Unregister controls first, snd_ctl_remove() frees the element */ + if (mixer->id_elems) { + for (id = 0; id < MAX_ID_ELEMS; id++) { + for (list = mixer->id_elems[id]; list; list = next) { + next = list->next_id_elem; + if (list->kctl) + snd_ctl_remove(mixer->chip->card, list->kctl); + } + } + kfree(mixer->id_elems); + } if (mixer->urb) { kfree(mixer->urb->transfer_buffer); usb_free_urb(mixer->urb); -- Gitee From d36070b594f0fc58c83019c910b484a228e724ac Mon Sep 17 00:00:00 2001 From: Matthew Schwartz Date: Tue, 30 Dec 2025 04:45:26 +0800 Subject: [PATCH 1177/1449] mmc: rtsx_pci_sdmmc: implement sdmmc_card_busy function ANBZ: #35228 commit bcb72b6a39e908038d16b416e50dad35a8cd3381 stable. commit 122610220134b32c742cc056eaf64f7017ac8cd9 upstream. rtsx_pci_sdmmc does not have an sdmmc_card_busy function, so any voltage switches cause a kernel warning, "mmc0: cannot verify signal voltage switch." Copy the sdmmc_card_busy function from rtsx_pci_usb to rtsx_pci_sdmmc to fix this. Fixes: ff984e57d36e ("mmc: Add realtek pcie sdmmc host driver") Signed-off-by: Matthew Schwartz Tested-by: Ricky WU Reviewed-by: Ricky WU Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mmc/host/rtsx_pci_sdmmc.c | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 87d78432a1e0..195cd25c2e05 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -1307,6 +1307,46 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios) return err; } +static int sdmmc_card_busy(struct mmc_host *mmc) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + int err; + u8 stat; + u8 mask = SD_DAT3_STATUS | SD_DAT2_STATUS | SD_DAT1_STATUS + | SD_DAT0_STATUS; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + err = rtsx_pci_write_register(pcr, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, + SD_CLK_TOGGLE_EN); + if (err) + goto out; + + mdelay(1); + + err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat); + if (err) + goto out; + + err = rtsx_pci_write_register(pcr, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); +out: + mutex_unlock(&pcr->pcr_mutex); + + if (err) + return err; + + /* check if any pin between dat[0:3] is low */ + if ((stat & mask) != mask) + return 1; + else + return 0; +} + static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct realtek_pci_sdmmc *host = mmc_priv(mmc); @@ -1405,6 +1445,7 @@ static const struct mmc_host_ops realtek_pci_sdmmc_ops = { .get_ro = sdmmc_get_ro, .get_cd = sdmmc_get_cd, .start_signal_voltage_switch = sdmmc_switch_voltage, + .card_busy = sdmmc_card_busy, .execute_tuning = sdmmc_execute_tuning, .init_sd_express = sdmmc_init_sd_express, }; -- Gitee From 62e0984843c25ffb1b8ff67abb39347a0ef16589 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 8 Dec 2025 23:35:23 +0800 Subject: [PATCH 1178/1449] intel_th: fix device leak on output open() ANBZ: #35228 commit bf7785434b5d05d940d936b78925080950bd54dd stable. commit 95fc36a234da24bbc5f476f8104a5a15f99ed3e3 upstream. Make sure to drop the reference taken when looking up the th device during output device open() on errors and on close(). Note that a recent commit fixed the leak in a couple of open() error paths but not all of them, and the reference is still leaking on successful open(). Fixes: 39f4034693b7 ("intel_th: Add driver infrastructure for Intel(R) Trace Hub devices") Fixes: 6d5925b667e4 ("intel_th: Fix error handling in intel_th_output_open") Cc: stable@vger.kernel.org # 4.4: 6d5925b667e4 Cc: Alexander Shishkin Cc: Ma Ke Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251208153524.68637-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwtracing/intel_th/core.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 40a08f53bfb4..17d9c33c95b6 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -818,9 +818,12 @@ static int intel_th_output_open(struct inode *inode, struct file *file) int err; dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev); - if (!dev || !dev->driver) { + if (!dev) + return -ENODEV; + + if (!dev->driver) { err = -ENODEV; - goto out_no_device; + goto out_put_device; } thdrv = to_intel_th_driver(dev->driver); @@ -844,12 +847,22 @@ static int intel_th_output_open(struct inode *inode, struct file *file) out_put_device: put_device(dev); -out_no_device: + return err; } +static int intel_th_output_release(struct inode *inode, struct file *file) +{ + struct intel_th_device *thdev = file->private_data; + + put_device(&thdev->dev); + + return 0; +} + static const struct file_operations intel_th_output_fops = { .open = intel_th_output_open, + .release = intel_th_output_release, .llseek = noop_llseek, }; -- Gitee From 86a94025dbdc6a11a9a6c881c7dbf4be48363b0d Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 22 Dec 2025 15:11:25 +0800 Subject: [PATCH 1179/1449] mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode ANBZ: #35228 commit f2677d6e2bbc5ba2030825522d2afd0542b038a3 stable. commit 3009738a855cf938bbfc9078bec725031ae623a4 upstream. When operating in HS200 or HS400 timing modes, reducing the clock frequency below 52MHz will lead to link broken as the Rockchip DWC MSHC controller requires maintaining a minimum clock of 52MHz in these modes. Add a check to prevent illegal clock reduction through debugfs: root@debian:/# echo 50000000 > /sys/kernel/debug/mmc0/clock root@debian:/# [ 30.090146] mmc0: running CQE recovery mmc0: cqhci: Failed to halt mmc0: cqhci: spurious TCN for tag 0 WARNING: drivers/mmc/host/cqhci-core.c:797 at cqhci_irq+0x254/0x818, CPU#1: kworker/1:0H/24 Modules linked in: CPU: 1 UID: 0 PID: 24 Comm: kworker/1:0H Not tainted 6.19.0-rc1-00001-g09db0998649d-dirty #204 PREEMPT Hardware name: Rockchip RK3588 EVB1 V10 Board (DT) Workqueue: kblockd blk_mq_run_work_fn pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : cqhci_irq+0x254/0x818 lr : cqhci_irq+0x254/0x818 ... Fixes: c6f361cba51c ("mmc: sdhci-of-dwcmshc: add support for rk3588") Cc: Sebastian Reichel Cc: Yifeng Zhao Signed-off-by: Shawn Lin Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/mmc/host/sdhci-of-dwcmshc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index afe448657ef8..346ac604546e 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -614,6 +614,13 @@ static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock sdhci_writel(host, extra, reg); if (clock <= 52000000) { + if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || + host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { + dev_err(mmc_dev(host->mmc), + "Can't reduce the clock below 52MHz in HS200/HS400 mode"); + return; + } + /* * Disable DLL and reset both of sample and drive clock. * The bypass bit and start bit need to be set if DLL is not locked. -- Gitee From 7995dafc6af81873d67c7af3f94102ebeb9c939d Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 6 Jan 2026 05:04:38 +0800 Subject: [PATCH 1180/1449] wifi: ath10k: fix dma_free_coherent() pointer ANBZ: #35228 commit 1928851334ecfd6e0d663121ab69ac639d4217a6 stable. commit 9282a1e171ad8d2205067e8ec3bbe4e3cef4f29f upstream. dma_alloc_coherent() allocates a DMA mapped buffer and stores the addresses in XXX_unaligned fields. Those should be reused when freeing the buffer rather than the aligned addresses. Fixes: 2a1e1ad3fd37 ("ath10k: Add support for 64 bit ce descriptor") Cc: stable@vger.kernel.org Signed-off-by: Thomas Fourier Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260105210439.20131-2-fourier.thomas@gmail.com Signed-off-by: Jeff Johnson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/ath/ath10k/ce.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index afae4a8027f8..1bb006dd229b 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -1725,8 +1725,8 @@ static void _ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) (ce_state->src_ring->nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), - ce_state->src_ring->base_addr_owner_space, - ce_state->src_ring->base_addr_ce_space); + ce_state->src_ring->base_addr_owner_space_unaligned, + ce_state->src_ring->base_addr_ce_space_unaligned); kfree(ce_state->src_ring); } @@ -1735,8 +1735,8 @@ static void _ath10k_ce_free_pipe(struct ath10k *ar, int ce_id) (ce_state->dest_ring->nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), - ce_state->dest_ring->base_addr_owner_space, - ce_state->dest_ring->base_addr_ce_space); + ce_state->dest_ring->base_addr_owner_space_unaligned, + ce_state->dest_ring->base_addr_ce_space_unaligned); kfree(ce_state->dest_ring); } @@ -1756,8 +1756,8 @@ static void _ath10k_ce_free_pipe_64(struct ath10k *ar, int ce_id) (ce_state->src_ring->nentries * sizeof(struct ce_desc_64) + CE_DESC_RING_ALIGN), - ce_state->src_ring->base_addr_owner_space, - ce_state->src_ring->base_addr_ce_space); + ce_state->src_ring->base_addr_owner_space_unaligned, + ce_state->src_ring->base_addr_ce_space_unaligned); kfree(ce_state->src_ring); } @@ -1766,8 +1766,8 @@ static void _ath10k_ce_free_pipe_64(struct ath10k *ar, int ce_id) (ce_state->dest_ring->nentries * sizeof(struct ce_desc_64) + CE_DESC_RING_ALIGN), - ce_state->dest_ring->base_addr_owner_space, - ce_state->dest_ring->base_addr_ce_space); + ce_state->dest_ring->base_addr_owner_space_unaligned, + ce_state->dest_ring->base_addr_ce_space_unaligned); kfree(ce_state->dest_ring); } -- Gitee From a6f7c9ab4f59abe46d9e01a8fec8b004634be1f8 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 6 Jan 2026 16:49:04 +0800 Subject: [PATCH 1181/1449] wifi: ath12k: fix dma_free_coherent() pointer ANBZ: #35228 commit 36e0bc5e8b282564906fca636c4ebc99814de4e7 stable. commit bb97131fbf9b708dd9616ac2bdc793ad102b5c48 upstream. dma_alloc_coherent() allocates a DMA mapped buffer and stores the addresses in XXX_unaligned fields. Those should be reused when freeing the buffer rather than the aligned addresses. Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Cc: stable@vger.kernel.org Signed-off-by: Thomas Fourier Reviewed-by: Baochen Qiang Link: https://patch.msgid.link/20260106084905.18622-2-fourier.thomas@gmail.com Signed-off-by: Jeff Johnson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/ath/ath12k/ce.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index b66d23d6b2bd..a25943a1bff8 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -893,8 +893,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) dma_free_coherent(ab->dev, pipe->src_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, - pipe->src_ring->base_addr_owner_space, - pipe->src_ring->base_addr_ce_space); + pipe->src_ring->base_addr_owner_space_unaligned, + pipe->src_ring->base_addr_ce_space_unaligned); kfree(pipe->src_ring); pipe->src_ring = NULL; } @@ -904,8 +904,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) dma_free_coherent(ab->dev, pipe->dest_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, - pipe->dest_ring->base_addr_owner_space, - pipe->dest_ring->base_addr_ce_space); + pipe->dest_ring->base_addr_owner_space_unaligned, + pipe->dest_ring->base_addr_ce_space_unaligned); kfree(pipe->dest_ring); pipe->dest_ring = NULL; } @@ -916,8 +916,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab) dma_free_coherent(ab->dev, pipe->status_ring->nentries * desc_sz + CE_DESC_RING_ALIGN, - pipe->status_ring->base_addr_owner_space, - pipe->status_ring->base_addr_ce_space); + pipe->status_ring->base_addr_owner_space_unaligned, + pipe->status_ring->base_addr_ce_space_unaligned); kfree(pipe->status_ring); pipe->status_ring = NULL; } -- Gitee From 8006fce7894678368bb92dc0df6f6daaa903b6f2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 9 Jan 2026 04:00:24 +0800 Subject: [PATCH 1182/1449] wifi: mwifiex: Fix a loop in mwifiex_update_ampdu_rxwinsize() ANBZ: #35228 commit 5d0ab96350e06bfa922ddcd8ca1e35cfcd6391b8 stable. commit 2120f3a3738a65730c81bf10447b1ff776078915 upstream. The "i" iterator variable is used to count two different things but unfortunately we can't store two different numbers in the same variable. Use "i" for the outside loop and "j" for the inside loop. Cc: stable@vger.kernel.org Fixes: d219b7eb3792 ("mwifiex: handle BT coex event to adjust Rx BA window size") Signed-off-by: Dan Carpenter Reviewed-by: Jeff Chen Link: https://patch.msgid.link/aWAM2MGUWRP0zWUd@stanley.mountain Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c index 10690e82358b..99f888bfd105 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c @@ -827,7 +827,7 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags) static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter, bool coex_flag) { - u8 i; + u8 i, j; u32 rx_win_size; struct mwifiex_private *priv; @@ -867,8 +867,8 @@ static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter, if (rx_win_size != priv->add_ba_param.rx_win_size) { if (!priv->media_connected) continue; - for (i = 0; i < MAX_NUM_TID; i++) - mwifiex_11n_delba(priv, i); + for (j = 0; j < MAX_NUM_TID; j++) + mwifiex_11n_delba(priv, j); } } } -- Gitee From 6e8faf32da3bdfdc0dd4511ccaa3f70e8adcc743 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 10 Jan 2026 07:56:29 +0800 Subject: [PATCH 1183/1449] wifi: rsi: Fix memory corruption due to not set vif driver data size ANBZ: #35228 commit 7761d7801f40e61069b4df3db88b36d80d089f8a stable. commit 4f431d88ea8093afc7ba55edf4652978c5a68f33 upstream. The struct ieee80211_vif contains trailing space for vif driver data, when struct ieee80211_vif is allocated, the total memory size that is allocated is sizeof(struct ieee80211_vif) + size of vif driver data. The size of vif driver data is set by each WiFi driver as needed. The RSI911x driver does not set vif driver data size, no trailing space for vif driver data is therefore allocated past struct ieee80211_vif . The RSI911x driver does however use the vif driver data to store its vif driver data structure "struct vif_priv". An access to vif->drv_priv leads to access out of struct ieee80211_vif bounds and corruption of some memory. In case of the failure observed locally, rsi_mac80211_add_interface() would write struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv; vif_info->vap_id = vap_idx. This write corrupts struct fq_tin member struct list_head new_flows . The flow = list_first_entry(head, struct fq_flow, flowchain); in fq_tin_reset() then reports non-NULL bogus address, which when accessed causes a crash. The trigger is very simple, boot the machine with init=/bin/sh , mount devtmpfs, sysfs, procfs, and then do "ip link set wlan0 up", "sleep 1", "ip link set wlan0 down" and the crash occurs. Fix this by setting the correct size of vif driver data, which is the size of "struct vif_priv", so that memory is allocated and the driver can store its driver data in it, instead of corrupting memory around it. Cc: stable@vger.kernel.org Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver") Signed-off-by: Marek Vasut Link: https://patch.msgid.link/20260109235817.150330-1-marex@nabladev.com Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 05890536e353..d7ad5329e525 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -2023,6 +2023,7 @@ int rsi_mac80211_attach(struct rsi_common *common) hw->queues = MAX_HW_QUEUES; hw->extra_tx_headroom = RSI_NEEDED_HEADROOM; + hw->vif_data_size = sizeof(struct vif_priv); hw->max_rates = 1; hw->max_rate_tries = MAX_RETRIES; -- Gitee From 545830b20f9a96277c765f80e7c8679242cb8d2c Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Tue, 20 Jan 2026 14:51:06 +0000 Subject: [PATCH 1184/1449] arm64/fpsimd: signal: Allocate SSVE storage when restoring ZA ANBZ: #35228 commit 19b2c3f3ca1b4b6dccd2a42aca2692d8c79c4214 stable. commit ea8ccfddbce0bee6310da4f3fc560ad520f5e6b4 upstream. The code to restore a ZA context doesn't attempt to allocate the task's sve_state before setting TIF_SME. Consequently, restoring a ZA context can place a task into an invalid state where TIF_SME is set but the task's sve_state is NULL. In legitimate but uncommon cases where the ZA signal context was NOT created by the kernel in the context of the same task (e.g. if the task is saved/restored with something like CRIU), we have no guarantee that sve_state had been allocated previously. In these cases, userspace can enter streaming mode without trapping while sve_state is NULL, causing a later NULL pointer dereference when the kernel attempts to store the register state: | # ./sigreturn-za | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 | Mem abort info: | ESR = 0x0000000096000046 | EC = 0x25: DABT (current EL), IL = 32 bits | SET = 0, FnV = 0 | EA = 0, S1PTW = 0 | FSC = 0x06: level 2 translation fault | Data abort info: | ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000 | CM = 0, WnR = 1, TnD = 0, TagAccess = 0 | GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 | user pgtable: 4k pages, 52-bit VAs, pgdp=0000000101f47c00 | [0000000000000000] pgd=08000001021d8403, p4d=0800000102274403, pud=0800000102275403, pmd=0000000000000000 | Internal error: Oops: 0000000096000046 [#1] SMP | Modules linked in: | CPU: 0 UID: 0 PID: 153 Comm: sigreturn-za Not tainted 6.19.0-rc1 #1 PREEMPT | Hardware name: linux,dummy-virt (DT) | pstate: 214000c9 (nzCv daIF +PAN -UAO -TCO +DIT -SSBS BTYPE=--) | pc : sve_save_state+0x4/0xf0 | lr : fpsimd_save_user_state+0xb0/0x1c0 | sp : ffff80008070bcc0 | x29: ffff80008070bcc0 x28: fff00000c1ca4c40 x27: 63cfa172fb5cf658 | x26: fff00000c1ca5228 x25: 0000000000000000 x24: 0000000000000000 | x23: 0000000000000000 x22: fff00000c1ca4c40 x21: fff00000c1ca4c40 | x20: 0000000000000020 x19: fff00000ff6900f0 x18: 0000000000000000 | x17: fff05e8e0311f000 x16: 0000000000000000 x15: 028fca8f3bdaf21c | x14: 0000000000000212 x13: fff00000c0209f10 x12: 0000000000000020 | x11: 0000000000200b20 x10: 0000000000000000 x9 : fff00000ff69dcc0 | x8 : 00000000000003f2 x7 : 0000000000000001 x6 : fff00000c1ca5b48 | x5 : fff05e8e0311f000 x4 : 0000000008000000 x3 : 0000000000000000 | x2 : 0000000000000001 x1 : fff00000c1ca5970 x0 : 0000000000000440 | Call trace: | sve_save_state+0x4/0xf0 (P) | fpsimd_thread_switch+0x48/0x198 | __switch_to+0x20/0x1c0 | __schedule+0x36c/0xce0 | schedule+0x34/0x11c | exit_to_user_mode_loop+0x124/0x188 | el0_interrupt+0xc8/0xd8 | __el0_irq_handler_common+0x18/0x24 | el0t_64_irq_handler+0x10/0x1c | el0t_64_irq+0x198/0x19c | Code: 54000040 d51b4408 d65f03c0 d503245f (e5bb5800) | ---[ end trace 0000000000000000 ]--- Fix this by having restore_za_context() ensure that the task's sve_state is allocated, matching what we do when taking an SME trap. Any live SVE/SSVE state (which is restored earlier from a separate signal context) must be preserved, and hence this is not zeroed. Fixes: 39782210eb7e ("arm64/sme: Implement ZA signal handling") Signed-off-by: Mark Rutland Cc: Cc: Mark Brown Cc: Will Deacon Reviewed-by: Mark Brown Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/arm64/kernel/signal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 962c12451876..f24d0c19a9c4 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -475,6 +475,10 @@ static int restore_za_context(struct user_ctxs *user) if (user->za_size < ZA_SIG_CONTEXT_SIZE(vq)) return -EINVAL; + sve_alloc(current, false); + if (!current->thread.sve_state) + return -ENOMEM; + sme_alloc(current, true); if (!current->thread.sme_state) { current->thread.svcr &= ~SVCR_ZA_MASK; -- Gitee From 0cfceefdbb7778bfc73ff4864b27d4d90f271944 Mon Sep 17 00:00:00 2001 From: Zhaoyang Huang Date: Thu, 22 Jan 2026 19:49:25 +0800 Subject: [PATCH 1185/1449] arm64: Set __nocfi on swsusp_arch_resume() ANBZ: #35228 commit 8557bdd9af8dd04911fba56ff92b17842b0b5c7f stable. commit e2f8216ca2d8e61a23cb6ec355616339667e0ba6 upstream. A DABT is reported[1] on an android based system when resume from hiberate. This happens because swsusp_arch_suspend_exit() is marked with SYM_CODE_*() and does not have a CFI hash, but swsusp_arch_resume() will attempt to verify the CFI hash when calling a copy of swsusp_arch_suspend_exit(). Given that there's an existing requirement that the entrypoint to swsusp_arch_suspend_exit() is the first byte of the .hibernate_exit.text section, we cannot fix this by marking swsusp_arch_suspend_exit() with SYM_FUNC_*(). The simplest fix for now is to disable the CFI check in swsusp_arch_resume(). Mark swsusp_arch_resume() as __nocfi to disable the CFI check. [1] [ 22.991934][ T1] Unable to handle kernel paging request at virtual address 0000000109170ffc [ 22.991934][ T1] Mem abort info: [ 22.991934][ T1] ESR = 0x0000000096000007 [ 22.991934][ T1] EC = 0x25: DABT (current EL), IL = 32 bits [ 22.991934][ T1] SET = 0, FnV = 0 [ 22.991934][ T1] EA = 0, S1PTW = 0 [ 22.991934][ T1] FSC = 0x07: level 3 translation fault [ 22.991934][ T1] Data abort info: [ 22.991934][ T1] ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000 [ 22.991934][ T1] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 22.991934][ T1] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 22.991934][ T1] [0000000109170ffc] user address but active_mm is swapper [ 22.991934][ T1] Internal error: Oops: 0000000096000007 [#1] PREEMPT SMP [ 22.991934][ T1] Dumping ftrace buffer: [ 22.991934][ T1] (ftrace buffer empty) [ 22.991934][ T1] Modules linked in: [ 22.991934][ T1] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.6.98-android15-8-g0b1d2aee7fc3-dirty-4k #1 688c7060a825a3ac418fe53881730b355915a419 [ 22.991934][ T1] Hardware name: Unisoc UMS9360-base Board (DT) [ 22.991934][ T1] pstate: 804000c5 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 22.991934][ T1] pc : swsusp_arch_resume+0x2ac/0x344 [ 22.991934][ T1] lr : swsusp_arch_resume+0x294/0x344 [ 22.991934][ T1] sp : ffffffc08006b960 [ 22.991934][ T1] x29: ffffffc08006b9c0 x28: 0000000000000000 x27: 0000000000000000 [ 22.991934][ T1] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000820 [ 22.991934][ T1] x23: ffffffd0817e3000 x22: ffffffd0817e3000 x21: 0000000000000000 [ 22.991934][ T1] x20: ffffff8089171000 x19: ffffffd08252c8c8 x18: ffffffc080061058 [ 22.991934][ T1] x17: 00000000529c6ef0 x16: 00000000529c6ef0 x15: 0000000000000004 [ 22.991934][ T1] x14: ffffff8178c88000 x13: 0000000000000006 x12: 0000000000000000 [ 22.991934][ T1] x11: 0000000000000015 x10: 0000000000000001 x9 : ffffffd082533000 [ 22.991934][ T1] x8 : 0000000109171000 x7 : 205b5d3433393139 x6 : 392e32322020205b [ 22.991934][ T1] x5 : 000000010916f000 x4 : 000000008164b000 x3 : ffffff808a4e0530 [ 22.991934][ T1] x2 : ffffffd08058e784 x1 : 0000000082326000 x0 : 000000010a283000 [ 22.991934][ T1] Call trace: [ 22.991934][ T1] swsusp_arch_resume+0x2ac/0x344 [ 22.991934][ T1] hibernation_restore+0x158/0x18c [ 22.991934][ T1] load_image_and_restore+0xb0/0xec [ 22.991934][ T1] software_resume+0xf4/0x19c [ 22.991934][ T1] software_resume_initcall+0x34/0x78 [ 22.991934][ T1] do_one_initcall+0xe8/0x370 [ 22.991934][ T1] do_initcall_level+0xc8/0x19c [ 22.991934][ T1] do_initcalls+0x70/0xc0 [ 22.991934][ T1] do_basic_setup+0x1c/0x28 [ 22.991934][ T1] kernel_init_freeable+0xe0/0x148 [ 22.991934][ T1] kernel_init+0x20/0x1a8 [ 22.991934][ T1] ret_from_fork+0x10/0x20 [ 22.991934][ T1] Code: a9400a61 f94013e0 f9438923 f9400a64 (b85fc110) Co-developed-by: Jeson Gao Signed-off-by: Jeson Gao Signed-off-by: Zhaoyang Huang Acked-by: Will Deacon Acked-by: Mark Rutland Cc: [catalin.marinas@arm.com: commit log updated by Mark Rutland] Signed-off-by: Catalin Marinas Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/kernel/hibernate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 02870beb271e..17c436387f1b 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -396,7 +396,7 @@ int swsusp_arch_suspend(void) * Memory allocated by get_safe_page() will be dealt with by the hibernate code, * we don't need to free it here. */ -int swsusp_arch_resume(void) +int __nocfi swsusp_arch_resume(void) { int rc; void *zero_page; -- Gitee From 142c7b0ddaaeb36e588cb8c4ca76dc2ac8875edd Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 14 Jan 2026 20:31:06 +0800 Subject: [PATCH 1186/1449] octeontx2: Fix otx2_dma_map_page() error return code ANBZ: #35228 commit d2846f8a89fd63b3bafd206032945612865c180c stable. commit d998b0e5afffa90d0f03770bad31083767079858 upstream. 0 is a valid DMA address [1] so using it as the error value can lead to errors. The error value of dma_map_XXX() functions is DMA_MAPPING_ERROR which is ~0. The callers of otx2_dma_map_page() use dma_mapping_error() to test the return value of otx2_dma_map_page(). This means that they would not detect an error in otx2_dma_map_page(). Make otx2_dma_map_page() return the raw value of dma_map_page_attrs(). [1] https://lore.kernel.org/all/f977f68b-cec5-4ab7-b4bd-2cf6aca46267@intel.com Fixes: caa2da34fd25 ("octeontx2-pf: Initialize and config queues") Cc: Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20260114123107.42387-2-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index c5de3ba33e2f..47bfa8f7ca53 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -893,13 +893,8 @@ static inline dma_addr_t otx2_dma_map_page(struct otx2_nic *pfvf, size_t offset, size_t size, enum dma_data_direction dir) { - dma_addr_t iova; - - iova = dma_map_page_attrs(pfvf->dev, page, + return dma_map_page_attrs(pfvf->dev, page, offset, size, dir, DMA_ATTR_SKIP_CPU_SYNC); - if (unlikely(dma_mapping_error(pfvf->dev, iova))) - return (dma_addr_t)NULL; - return iova; } static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf, -- Gitee From 34315aeddcc729d5fa361f6fd3cc82d10d62281d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 26 Nov 2025 22:53:25 +0800 Subject: [PATCH 1187/1449] slimbus: core: fix runtime PM imbalance on report present ANBZ: #35228 commit dd58835fba5d6c5f6c6e647e9380250a6c1a6e65 stable. commit 0eb4ff6596114aabba1070a66afa2c2f5593739f upstream. Make sure to balance the runtime PM usage count in case slimbus device or address allocation fails on report present, which would otherwise prevent the controller from suspending. Fixes: 4b14e62ad3c9 ("slimbus: Add support for 'clock-pause' feature") Cc: stable@vger.kernel.org # 4.16 Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251126145329.5022-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/slimbus/core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c index 01cbd4621981..ef3f2a530750 100644 --- a/drivers/slimbus/core.c +++ b/drivers/slimbus/core.c @@ -496,21 +496,23 @@ int slim_device_report_present(struct slim_controller *ctrl, if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) { dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n", ctrl->sched.clk_state, ret); - goto slimbus_not_active; + goto out_put_rpm; } sbdev = slim_get_device(ctrl, e_addr); - if (IS_ERR(sbdev)) - return -ENODEV; + if (IS_ERR(sbdev)) { + ret = -ENODEV; + goto out_put_rpm; + } if (sbdev->is_laddr_valid) { *laddr = sbdev->laddr; - return 0; + ret = 0; + } else { + ret = slim_device_alloc_laddr(sbdev, true); } - ret = slim_device_alloc_laddr(sbdev, true); - -slimbus_not_active: +out_put_rpm: pm_runtime_mark_last_busy(ctrl->dev); pm_runtime_put_autosuspend(ctrl->dev); return ret; -- Gitee From 49077bb16fe305d754dcb68c1830c933b8d910ce Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 26 Nov 2025 22:53:26 +0800 Subject: [PATCH 1188/1449] slimbus: core: fix device reference leak on report present ANBZ: #35228 commit 2ddc09f6a0a221b1d91a7cbc8cc2cefdbd334fe6 stable. commit 9391380eb91ea5ac792aae9273535c8da5b9aa01 upstream. Slimbus devices can be allocated dynamically upon reception of report-present messages. Make sure to drop the reference taken when looking up already registered devices. Note that this requires taking an extra reference in case the device has not yet been registered and has to be allocated. Fixes: 46a2bb5a7f7e ("slimbus: core: Add slim controllers support") Cc: stable@vger.kernel.org # 4.16 Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251126145329.5022-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/slimbus/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c index ef3f2a530750..fdc099abd2cc 100644 --- a/drivers/slimbus/core.c +++ b/drivers/slimbus/core.c @@ -378,6 +378,8 @@ struct slim_device *slim_get_device(struct slim_controller *ctrl, sbdev = slim_alloc_device(ctrl, e_addr, NULL); if (!sbdev) return ERR_PTR(-ENOMEM); + + get_device(&sbdev->dev); } return sbdev; @@ -512,6 +514,7 @@ int slim_device_report_present(struct slim_controller *ctrl, ret = slim_device_alloc_laddr(sbdev, true); } + put_device(&sbdev->dev); out_put_rpm: pm_runtime_mark_last_busy(ctrl->dev); pm_runtime_put_autosuspend(ctrl->dev); -- Gitee From 7bae17e3407e0371478207f3496e6bba80efd935 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 23 Jan 2026 08:48:24 +0800 Subject: [PATCH 1189/1449] tracing: Fix crash on synthetic stacktrace field usage ANBZ: #35228 commit 98ecbfb2598c9c7ca755a29f402da9d36c057077 stable. commit 90f9f5d64cae4e72defd96a2a22760173cb3c9ec upstream. When creating a synthetic event based on an existing synthetic event that had a stacktrace field and the new synthetic event used that field a kernel crash occurred: ~# cd /sys/kernel/tracing ~# echo 's:stack unsigned long stack[];' > dynamic_events ~# echo 'hist:keys=prev_pid:s0=common_stacktrace if prev_state & 3' >> events/sched/sched_switch/trigger ~# echo 'hist:keys=next_pid:s1=$s0:onmatch(sched.sched_switch).trace(stack,$s1)' >> events/sched/sched_switch/trigger The above creates a synthetic event that takes a stacktrace when a task schedules out in a non-running state and passes that stacktrace to the sched_switch event when that task schedules back in. It triggers the "stack" synthetic event that has a stacktrace as its field (called "stack"). ~# echo 's:syscall_stack s64 id; unsigned long stack[];' >> dynamic_events ~# echo 'hist:keys=common_pid:s2=stack' >> events/synthetic/stack/trigger ~# echo 'hist:keys=common_pid:s3=$s2,i0=id:onmatch(synthetic.stack).trace(syscall_stack,$i0,$s3)' >> events/raw_syscalls/sys_exit/trigger The above makes another synthetic event called "syscall_stack" that attaches the first synthetic event (stack) to the sys_exit trace event and records the stacktrace from the stack event with the id of the system call that is exiting. When enabling this event (or using it in a historgram): ~# echo 1 > events/synthetic/syscall_stack/enable Produces a kernel crash! BUG: unable to handle page fault for address: 0000000000400010 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP PTI CPU: 6 UID: 0 PID: 1257 Comm: bash Not tainted 6.16.3+deb14-amd64 #1 PREEMPT(lazy) Debian 6.16.3-1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 RIP: 0010:trace_event_raw_event_synth+0x90/0x380 Code: c5 00 00 00 00 85 d2 0f 84 e1 00 00 00 31 db eb 34 0f 1f 00 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 2e 0f 1f 84 00 00 00 00 00 <49> 8b 04 24 48 83 c3 01 8d 0c c5 08 00 00 00 01 cd 41 3b 5d 40 0f RSP: 0018:ffffd2670388f958 EFLAGS: 00010202 RAX: ffff8ba1065cc100 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000001 RSI: fffff266ffda7b90 RDI: ffffd2670388f9b0 RBP: 0000000000000010 R08: ffff8ba104e76000 R09: ffffd2670388fa50 R10: ffff8ba102dd42e0 R11: ffffffff9a908970 R12: 0000000000400010 R13: ffff8ba10a246400 R14: ffff8ba10a710220 R15: fffff266ffda7b90 FS: 00007fa3bc63f740(0000) GS:ffff8ba2e0f48000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000400010 CR3: 0000000107f9e003 CR4: 0000000000172ef0 Call Trace: ? __tracing_map_insert+0x208/0x3a0 action_trace+0x67/0x70 event_hist_trigger+0x633/0x6d0 event_triggers_call+0x82/0x130 trace_event_buffer_commit+0x19d/0x250 trace_event_raw_event_sys_exit+0x62/0xb0 syscall_exit_work+0x9d/0x140 do_syscall_64+0x20a/0x2f0 ? trace_event_raw_event_sched_switch+0x12b/0x170 ? save_fpregs_to_fpstate+0x3e/0x90 ? _raw_spin_unlock+0xe/0x30 ? finish_task_switch.isra.0+0x97/0x2c0 ? __rseq_handle_notify_resume+0xad/0x4c0 ? __schedule+0x4b8/0xd00 ? restore_fpregs_from_fpstate+0x3c/0x90 ? switch_fpu_return+0x5b/0xe0 ? do_syscall_64+0x1ef/0x2f0 ? do_fault+0x2e9/0x540 ? __handle_mm_fault+0x7d1/0xf70 ? count_memcg_events+0x167/0x1d0 ? handle_mm_fault+0x1d7/0x2e0 ? do_user_addr_fault+0x2c3/0x7f0 entry_SYSCALL_64_after_hwframe+0x76/0x7e The reason is that the stacktrace field is not labeled as such, and is treated as a normal field and not as a dynamic event that it is. In trace_event_raw_event_synth() the event is field is still treated as a dynamic array, but the retrieval of the data is considered a normal field, and the reference is just the meta data: // Meta data is retrieved instead of a dynamic array str_val = (char *)(long)var_ref_vals[val_idx]; // Then when it tries to process it: len = *((unsigned long *)str_val) + 1; It triggers a kernel page fault. To fix this, first when defining the fields of the first synthetic event, set the filter type to FILTER_STACKTRACE. This is used later by the second synthetic event to know that this field is a stacktrace. When creating the field of the new synthetic event, have it use this FILTER_STACKTRACE to know to create a stacktrace field to copy the stacktrace into. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Tom Zanussi Link: https://patch.msgid.link/20260122194824.6905a38e@gandalf.local.home Fixes: 00cf3d672a9d ("tracing: Allow synthetic events to pass around stacktraces") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/trace/trace_events_hist.c | 9 +++++++++ kernel/trace/trace_events_synth.c | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index e6d2f2a94235..99d1e8b57f85 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -2047,6 +2047,15 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, hist_field->fn_num = HIST_FIELD_FN_RELDYNSTRING; else hist_field->fn_num = HIST_FIELD_FN_PSTRING; + } else if (field->filter_type == FILTER_STACKTRACE) { + flags |= HIST_FIELD_FL_STACKTRACE; + + hist_field->size = MAX_FILTER_STR_VAL; + hist_field->type = kstrdup_const(field->type, GFP_KERNEL); + if (!hist_field->type) + goto free; + + hist_field->fn_num = HIST_FIELD_FN_STACK; } else { hist_field->size = field->size; hist_field->is_signed = field->is_signed; diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 181af676f93d..02e2440da829 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -137,7 +137,9 @@ static int synth_event_define_fields(struct trace_event_call *call) struct synth_event *event = call->data; unsigned int i, size, n_u64; char *name, *type; + int filter_type; bool is_signed; + bool is_stack; int ret = 0; for (i = 0, n_u64 = 0; i < event->n_fields; i++) { @@ -145,8 +147,12 @@ static int synth_event_define_fields(struct trace_event_call *call) is_signed = event->fields[i]->is_signed; type = event->fields[i]->type; name = event->fields[i]->name; + is_stack = event->fields[i]->is_stack; + + filter_type = is_stack ? FILTER_STACKTRACE : FILTER_OTHER; + ret = trace_define_field(call, type, name, offset, size, - is_signed, FILTER_OTHER); + is_signed, filter_type); if (ret) break; -- Gitee From 7dadce21b663104cca8e19c2d8d3697c84129b71 Mon Sep 17 00:00:00 2001 From: Wenkai Lin Date: Tue, 2 Dec 2025 14:12:53 +0800 Subject: [PATCH 1190/1449] uacce: fix cdev handling in the cleanup path ANBZ: #35228 commit d9031575a2f8aabc53af3025dd79af313a2e046b stable. commit a3bece3678f6c88db1f44c602b2a63e84b4040ac upstream. When cdev_device_add fails, it internally releases the cdev memory, and if cdev_device_del is then executed, it will cause a hang error. To fix it, we check the return value of cdev_device_add() and clear uacce->cdev to avoid calling cdev_device_del in the uacce_remove. Fixes: 015d239ac014 ("uacce: add uacce driver") Cc: stable@vger.kernel.org Signed-off-by: Wenkai Lin Signed-off-by: Chenghai Huang Acked-by: Zhangfei Gao Link: https://patch.msgid.link/20251202061256.4158641-2-huangchenghai2@huawei.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/misc/uacce/uacce.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index c237955e3d85..1f4aad80257e 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -516,6 +516,8 @@ EXPORT_SYMBOL_GPL(uacce_alloc); */ int uacce_register(struct uacce_device *uacce) { + int ret; + if (!uacce) return -ENODEV; @@ -526,7 +528,11 @@ int uacce_register(struct uacce_device *uacce) uacce->cdev->ops = &uacce_fops; uacce->cdev->owner = THIS_MODULE; - return cdev_device_add(uacce->cdev, &uacce->dev); + ret = cdev_device_add(uacce->cdev, &uacce->dev); + if (ret) + uacce->cdev = NULL; + + return ret; } EXPORT_SYMBOL_GPL(uacce_register); -- Gitee From b513b7db372c24eccadc404a430509f7a8f30553 Mon Sep 17 00:00:00 2001 From: Chenghai Huang Date: Tue, 2 Dec 2025 14:12:54 +0800 Subject: [PATCH 1191/1449] uacce: fix isolate sysfs check condition ANBZ: #35228 commit 9ab05cdcac354b1b1139918f49c6418b9005d042 stable. commit 98eec349259b1fd876f350b1c600403bcef8f85d upstream. uacce supports the device isolation feature. If the driver implements the isolate_err_threshold_read and isolate_err_threshold_write callback functions, uacce will create sysfs files now. Users can read and configure the isolation policy through sysfs. Currently, sysfs files are created as long as either isolate_err_threshold_read or isolate_err_threshold_write callback functions are present. However, accessing a non-existent callback function may cause the system to crash. Therefore, intercept the creation of sysfs if neither read nor write exists; create sysfs if either is supported, but intercept unsupported operations at the call site. Fixes: e3e289fbc0b5 ("uacce: supports device isolation feature") Cc: stable@vger.kernel.org Signed-off-by: Chenghai Huang Acked-by: Zhangfei Gao Link: https://patch.msgid.link/20251202061256.4158641-3-huangchenghai2@huawei.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/misc/uacce/uacce.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 1f4aad80257e..a3b084b3f4d6 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -379,6 +379,9 @@ static ssize_t isolate_strategy_show(struct device *dev, struct device_attribute struct uacce_device *uacce = to_uacce_device(dev); u32 val; + if (!uacce->ops->isolate_err_threshold_read) + return -ENOENT; + val = uacce->ops->isolate_err_threshold_read(uacce); return sysfs_emit(buf, "%u\n", val); @@ -391,6 +394,9 @@ static ssize_t isolate_strategy_store(struct device *dev, struct device_attribut unsigned long val; int ret; + if (!uacce->ops->isolate_err_threshold_write) + return -ENOENT; + if (kstrtoul(buf, 0, &val) < 0) return -EINVAL; -- Gitee From 0c9e665966c675b027c198dae16dae6677f0e2d9 Mon Sep 17 00:00:00 2001 From: Yang Shen Date: Tue, 2 Dec 2025 14:12:55 +0800 Subject: [PATCH 1192/1449] uacce: implement mremap in uacce_vm_ops to return -EPERM ANBZ: #35228 commit 4c042bc71474dbe417c268f4bfb8ec196f802f07 stable. commit 02695347be532b628f22488300d40c4eba48b9b7 upstream. The current uacce_vm_ops does not support the mremap operation of vm_operations_struct. Implement .mremap to return -EPERM to remind users. The reason we need to explicitly disable mremap is that when the driver does not implement .mremap, it uses the default mremap method. This could lead to a risk scenario: An application might first mmap address p1, then mremap to p2, followed by munmap(p1), and finally munmap(p2). Since the default mremap copies the original vma's vm_private_data (i.e., q) to the new vma, both munmap operations would trigger vma_close, causing q->qfr to be freed twice(qfr will be set to null here, so repeated release is ok). Fixes: 015d239ac014 ("uacce: add uacce driver") Cc: stable@vger.kernel.org Signed-off-by: Yang Shen Signed-off-by: Chenghai Huang Acked-by: Zhangfei Gao Link: https://patch.msgid.link/20251202061256.4158641-4-huangchenghai2@huawei.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/misc/uacce/uacce.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index a3b084b3f4d6..d9bbd841d417 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -211,8 +211,14 @@ static void uacce_vma_close(struct vm_area_struct *vma) } } +static int uacce_vma_mremap(struct vm_area_struct *area) +{ + return -EPERM; +} + static const struct vm_operations_struct uacce_vm_ops = { .close = uacce_vma_close, + .mremap = uacce_vma_mremap, }; static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) -- Gitee From 21593b5c1fd932f092053d905b9605a51c8f0c00 Mon Sep 17 00:00:00 2001 From: Chenghai Huang Date: Tue, 2 Dec 2025 14:12:56 +0800 Subject: [PATCH 1193/1449] uacce: ensure safe queue release with state management ANBZ: #35228 commit 43f233eb6e7b9d88536881a9bc43726d0e34800d stable. commit 26c08dabe5475d99a13f353d8dd70e518de45663 upstream. Directly calling `put_queue` carries risks since it cannot guarantee that resources of `uacce_queue` have been fully released beforehand. So adding a `stop_queue` operation for the UACCE_CMD_PUT_Q command and leaving the `put_queue` operation to the final resource release ensures safety. Queue states are defined as follows: - UACCE_Q_ZOMBIE: Initial state - UACCE_Q_INIT: After opening `uacce` - UACCE_Q_STARTED: After `start` is issued via `ioctl` When executing `poweroff -f` in virt while accelerator are still working, `uacce_fops_release` and `uacce_remove` may execute concurrently. This can cause `uacce_put_queue` within `uacce_fops_release` to access a NULL `ops` pointer. Therefore, add state checks to prevent accessing freed pointers. Fixes: 015d239ac014 ("uacce: add uacce driver") Cc: stable@vger.kernel.org Signed-off-by: Chenghai Huang Signed-off-by: Yang Shen Acked-by: Zhangfei Gao Link: https://patch.msgid.link/20251202061256.4158641-5-huangchenghai2@huawei.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/misc/uacce/uacce.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index d9bbd841d417..5b0175e296af 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -37,20 +37,34 @@ static int uacce_start_queue(struct uacce_queue *q) return 0; } -static int uacce_put_queue(struct uacce_queue *q) +static int uacce_stop_queue(struct uacce_queue *q) { struct uacce_device *uacce = q->uacce; - if ((q->state == UACCE_Q_STARTED) && uacce->ops->stop_queue) + if (q->state != UACCE_Q_STARTED) + return 0; + + if (uacce->ops->stop_queue) uacce->ops->stop_queue(q); - if ((q->state == UACCE_Q_INIT || q->state == UACCE_Q_STARTED) && - uacce->ops->put_queue) + q->state = UACCE_Q_INIT; + + return 0; +} + +static void uacce_put_queue(struct uacce_queue *q) +{ + struct uacce_device *uacce = q->uacce; + + uacce_stop_queue(q); + + if (q->state != UACCE_Q_INIT) + return; + + if (uacce->ops->put_queue) uacce->ops->put_queue(q); q->state = UACCE_Q_ZOMBIE; - - return 0; } static long uacce_fops_unl_ioctl(struct file *filep, @@ -77,7 +91,7 @@ static long uacce_fops_unl_ioctl(struct file *filep, ret = uacce_start_queue(q); break; case UACCE_CMD_PUT_Q: - ret = uacce_put_queue(q); + ret = uacce_stop_queue(q); break; default: if (uacce->ops->ioctl) -- Gitee From ff58f9c9f11590130c4f9e5b6da6a12b22550167 Mon Sep 17 00:00:00 2001 From: Jeongjun Park Date: Mon, 19 Jan 2026 14:33:59 +0800 Subject: [PATCH 1194/1449] netrom: fix double-free in nr_route_frame() ANBZ: #35228 commit bd8955337e3764f912f49b360e176d8aaecf7016 stable. commit ba1096c315283ee3292765f6aea4cca15816c4f7 upstream. In nr_route_frame(), old_skb is immediately freed without checking if nr_neigh->ax25 pointer is NULL. Therefore, if nr_neigh->ax25 is NULL, the caller function will free old_skb again, causing a double-free bug. Therefore, to prevent this, we need to modify it to check whether nr_neigh->ax25 is NULL before freeing old_skb. Cc: Reported-by: syzbot+999115c3bf275797dc27@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/69694d6f.050a0220.58bed.0029.GAE@google.com/ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Jeongjun Park Link: https://patch.msgid.link/20260119063359.10604-1-aha310510@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netrom/nr_route.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 0b270893ee14..89e4bf4aa652 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c @@ -752,7 +752,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) unsigned char *dptr; ax25_cb *ax25s; int ret; - struct sk_buff *skbn; + struct sk_buff *nskb, *oskb; /* * Reject malformed packets early. Check that it contains at least 2 @@ -811,14 +811,16 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) /* We are going to change the netrom headers so we should get our own skb, we also did not know until now how much header space we had to reserve... - RXQ */ - if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) { + nskb = skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC); + + if (!nskb) { nr_node_unlock(nr_node); nr_node_put(nr_node); dev_put(dev); return 0; } - kfree_skb(skb); - skb=skbn; + oskb = skb; + skb = nskb; skb->data[14]--; dptr = skb_push(skb, 1); @@ -837,6 +839,9 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) nr_node_unlock(nr_node); nr_node_put(nr_node); + if (ret) + kfree_skb(oskb); + return ret; } -- Gitee From 848aba03ddc5a326af9f2e628dd35fcd5710b214 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 16 Jan 2026 04:31:12 +0800 Subject: [PATCH 1195/1449] platform/x86: hp-bioscfg: Fix automatic module loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 6384f7851838fb00bc71dd51ae7ac16cd494c860 stable. commit 467d4afc6caa64b84a6db1634f8091e931f4a7cb upstream. hp-bioscfg has a MODULE_DEVICE_TABLE with a GUID in it that looks plausible, but the module doesn't automatically load on applicable systems. This is because the GUID has some lower case characters and so it doesn't match the modalias during boot. Update the GUIDs to be all uppercase. Cc: stable@vger.kernel.org Fixes: 5f94f181ca25 ("platform/x86: hp-bioscfg: bioscfg-h") Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20260115203725.828434-4-mario.limonciello@amd.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h index 6b6748e4be21..f1eec0e4ba07 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h @@ -57,14 +57,14 @@ enum mechanism_values { #define PASSWD_MECHANISM_TYPES "password" -#define HP_WMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" +#define HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" -#define HP_WMI_BIOS_STRING_GUID "988D08E3-68F4-4c35-AF3E-6A1B8106F83C" +#define HP_WMI_BIOS_STRING_GUID "988D08E3-68F4-4C35-AF3E-6A1B8106F83C" #define HP_WMI_BIOS_INTEGER_GUID "8232DE3D-663D-4327-A8F4-E293ADB9BF05" #define HP_WMI_BIOS_ENUMERATION_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133" #define HP_WMI_BIOS_ORDERED_LIST_GUID "14EA9746-CE1F-4098-A0E0-7045CB4DA745" #define HP_WMI_BIOS_PASSWORD_GUID "322F2028-0F84-4901-988E-015176049E2D" -#define HP_WMI_SET_BIOS_SETTING_GUID "1F4C91EB-DC5C-460b-951D-C7CB9B4B8D5E" +#define HP_WMI_SET_BIOS_SETTING_GUID "1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E" enum hp_wmi_spm_commandtype { HPWMI_SECUREPLATFORM_GET_STATE = 0x10, -- Gitee From ee8b7472683c69e01595d9fc0daa24847a247b32 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Fri, 5 Dec 2025 09:54:25 +0800 Subject: [PATCH 1196/1449] pmdomain: imx8m-blk-ctrl: Remove separate rst and clk mask for 8mq vpu ANBZ: #35228 commit cad7003d951e8899db58ee2fef211586af726f09 stable. commit 3de49966499634454fd59e0e6fecd50baab7febd upstream. For i.MX8MQ platform, the ADB in the VPUMIX domain has no separate reset and clock enable bits, but is ungated and reset together with the VPUs. So we can't reset G1 or G2 separately, it may led to the system hang. Remove rst_mask and clk_mask of imx8mq_vpu_blk_ctl_domain_data. Let imx8mq_vpu_power_notifier() do really vpu reset. Fixes: 608d7c325e85 ("soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl") Signed-off-by: Ming Qian Reviewed-by: Benjamin Gaignard Reviewed-by: Peng Fan Reviewed-by: Frank Li Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/imx8m-blk-ctrl.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c index 0dfaf1d14035..ce452c2b1746 100644 --- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c @@ -845,22 +845,25 @@ static int imx8mq_vpu_power_notifier(struct notifier_block *nb, return NOTIFY_OK; } +/* + * For i.MX8MQ, the ADB in the VPUMIX domain has no separate reset and clock + * enable bits, but is ungated and reset together with the VPUs. + * Resetting G1 or G2 separately may led to system hang. + * Remove the rst_mask and clk_mask from the domain data of G1 and G2, + * Let imx8mq_vpu_power_notifier() do really vpu reset. + */ static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = { [IMX8MQ_VPUBLK_PD_G1] = { .name = "vpublk-g1", .clk_names = (const char *[]){ "g1", }, .num_clks = 1, .gpc_name = "g1", - .rst_mask = BIT(1), - .clk_mask = BIT(1), }, [IMX8MQ_VPUBLK_PD_G2] = { .name = "vpublk-g2", .clk_names = (const char *[]){ "g2", }, .num_clks = 1, .gpc_name = "g2", - .rst_mask = BIT(0), - .clk_mask = BIT(0), }, }; -- Gitee From 8341ca05d553f56dfc7069c293f092536d30d3b4 Mon Sep 17 00:00:00 2001 From: Fernand Sieber Date: Fri, 12 Dec 2025 02:36:04 +0800 Subject: [PATCH 1197/1449] perf/x86/intel: Do not enable BTS for guests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit dd40d94ffd7c812118db5746a1cb13eb4d103585 stable. commit 91dcfae0ff2b9b9ab03c1ec95babaceefbffb9f4 upstream. By default when users program perf to sample branch instructions (PERF_COUNT_HW_BRANCH_INSTRUCTIONS) with a sample period of 1, perf interprets this as a special case and enables BTS (Branch Trace Store) as an optimization to avoid taking an interrupt on every branch. Since BTS doesn't virtualize, this optimization doesn't make sense when the request originates from a guest. Add an additional check that prevents this optimization for virtualized events (exclude_host). Reported-by: Jan H. Schönherr Suggested-by: Peter Zijlstra Signed-off-by: Fernand Sieber Signed-off-by: Peter Zijlstra (Intel) Cc: Link: https://patch.msgid.link/20251211183604.868641-1-sieberf@amazon.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/events/perf_event.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 26b50ce73ce6..91109217188c 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1570,13 +1570,22 @@ static inline bool intel_pmu_has_bts_period(struct perf_event *event, u64 period struct hw_perf_event *hwc = &event->hw; unsigned int hw_event, bts_event; - if (event->attr.freq) + /* + * Only use BTS for fixed rate period==1 events. + */ + if (event->attr.freq || period != 1) + return false; + + /* + * BTS doesn't virtualize. + */ + if (event->attr.exclude_host) return false; hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); - return hw_event == bts_event && period == 1; + return hw_event == bts_event; } static inline bool intel_pmu_has_bts(struct perf_event *event) -- Gitee From 3420c2323e929b417c6a98779005fc68472ae9e7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 Jan 2026 04:15:12 +0800 Subject: [PATCH 1198/1449] irqchip/gic-v3-its: Avoid truncating memory addresses ANBZ: #35228 commit 1b323391560354d8c515de8658b057a1daa82adb stable. commit 8d76a7d89c12d08382b66e2f21f20d0627d14859 upstream. On 32-bit machines with CONFIG_ARM_LPAE, it is possible for lowmem allocations to be backed by addresses physical memory above the 32-bit address limit, as found while experimenting with larger VMSPLIT configurations. This caused the qemu virt model to crash in the GICv3 driver, which allocates the 'itt' object using GFP_KERNEL. Since all memory below the 4GB physical address limit is in ZONE_DMA in this configuration, kmalloc() defaults to higher addresses for ZONE_NORMAL, and the ITS driver stores the physical address in a 32-bit 'unsigned long' variable. Change the itt_addr variable to the correct phys_addr_t type instead, along with all other variables in this driver that hold a physical address. The gicv5 driver correctly uses u64 variables, while all other irqchip drivers don't call virt_to_phys or similar interfaces. It's expected that other device drivers have similar issues, but fixing this one is sufficient for booting a virtio based guest. Fixes: cc2d3216f53c ("irqchip: GICv3: ITS command queue") Signed-off-by: Arnd Bergmann Signed-off-by: Thomas Gleixner Reviewed-by: Marc Zyngier Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260119201603.2713066-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/irqchip/irq-gic-v3-its.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index d22275ca180d..743bb107be44 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -836,7 +836,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_node *its, struct its_cmd_block *cmd, struct its_cmd_desc *desc) { - unsigned long itt_addr; + phys_addr_t itt_addr; u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites); itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt); @@ -1067,7 +1067,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, struct its_cmd_desc *desc) { struct its_vpe *vpe = valid_vpe(its, desc->its_vmapp_cmd.vpe); - unsigned long vpt_addr, vconf_addr; + phys_addr_t vpt_addr, vconf_addr; u64 target; bool alloc; @@ -2689,10 +2689,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, baser->psz = psz; tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz; - pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n", + pr_info("ITS@%pa: allocated %d %s @%llx (%s, esz %d, psz %dK, shr %d)\n", &its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp), its_base_type_string[type], - (unsigned long)virt_to_phys(base), + (u64)virt_to_phys(base), indirect ? "indirect" : "flat", (int)esz, psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT); -- Gitee From ccb098c917dce1e41a9291fa44a44777905f2531 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 10 Jan 2026 19:52:27 +0800 Subject: [PATCH 1199/1449] can: ems_usb: ems_usb_read_bulk_callback(): fix URB memory leak ANBZ: #35228 commit e9410fdd4d5f7eaa6526d8c80e83029d7c86a8e8 stable. commit 0ce73a0eb5a27070957b67fd74059b6da89cc516 upstream. Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak"). In ems_usb_open(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback ems_usb_read_bulk_callback(), the URBs are processed and resubmitted. In ems_usb_close() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted). However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in ems_usb_close(). Fix the memory leak by anchoring the URB in the ems_usb_read_bulk_callback() to the dev->rx_submitted anchor. Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260116-can_usb-fix-memory-leak-v2-1-4b8cb2915571@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/ems_usb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 5355bac4dccb..fac8ac79df59 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -486,11 +486,17 @@ static void ems_usb_read_bulk_callback(struct urb *urb) urb->transfer_buffer, RX_BUFFER_SIZE, ems_usb_read_bulk_callback, dev); + usb_anchor_urb(urb, &dev->rx_submitted); + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (!retval) + return; + + usb_unanchor_urb(urb); if (retval == -ENODEV) netif_device_detach(netdev); - else if (retval) + else netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", retval); } -- Gitee From ce0237e12b7fe88b09408341701708300deb1a77 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 10 Jan 2026 19:52:27 +0800 Subject: [PATCH 1200/1449] can: kvaser_usb: kvaser_usb_read_bulk_callback(): fix URB memory leak ANBZ: #35228 commit 7c308f7530bffafa994e0aa8dc651a312f4b9ff4 stable. commit 248e8e1a125fa875158df521b30f2cc7e27eeeaa upstream. Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak"). In kvaser_usb_set_{,data_}bittiming() -> kvaser_usb_setup_rx_urbs(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback kvaser_usb_read_bulk_callback(), the URBs are processed and resubmitted. In kvaser_usb_remove_interfaces() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted). However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs(). Fix the memory leak by anchoring the URB in the kvaser_usb_read_bulk_callback() to the dev->rx_submitted anchor. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260116-can_usb-fix-memory-leak-v2-3-4b8cb2915571@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index 022b5b79247c..8af206c93d19 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -349,7 +349,14 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) urb->transfer_buffer, KVASER_USB_RX_BUFFER_SIZE, kvaser_usb_read_bulk_callback, dev); + usb_anchor_urb(urb, &dev->rx_submitted); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (!err) + return; + + usb_unanchor_urb(urb); + if (err == -ENODEV) { for (i = 0; i < dev->nchannels; i++) { if (!dev->nets[i]) @@ -357,7 +364,7 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) netif_device_detach(dev->nets[i]->netdev); } - } else if (err) { + } else { dev_err(&dev->intf->dev, "Failed resubmitting read bulk urb: %d\n", err); } -- Gitee From a30f571dedd58d1d73fcc5590f80f9e1c4d0410a Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 10 Jan 2026 19:52:27 +0800 Subject: [PATCH 1201/1449] can: mcba_usb: mcba_usb_read_bulk_callback(): fix URB memory leak ANBZ: #35228 commit 179f6f0cf5ae489743273b7c1644324c0c477ea9 stable. commit 710a7529fb13c5a470258ff5508ed3c498d54729 upstream. Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak"). In mcba_usb_probe() -> mcba_usb_start(), the URBs for USB-in transfers are allocated, added to the priv->rx_submitted anchor and submitted. In the complete callback mcba_usb_read_bulk_callback(), the URBs are processed and resubmitted. In mcba_usb_close() -> mcba_urb_unlink() the URBs are freed by calling usb_kill_anchored_urbs(&priv->rx_submitted). However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs(). Fix the memory leak by anchoring the URB in the mcba_usb_read_bulk_callback()to the priv->rx_submitted anchor. Fixes: 51f3baad7de9 ("can: mcba_usb: Add support for Microchip CAN BUS Analyzer") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260116-can_usb-fix-memory-leak-v2-4-4b8cb2915571@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/mcba_usb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c index ecc489afb841..b0fceff59b32 100644 --- a/drivers/net/can/usb/mcba_usb.c +++ b/drivers/net/can/usb/mcba_usb.c @@ -608,11 +608,17 @@ static void mcba_usb_read_bulk_callback(struct urb *urb) urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE, mcba_usb_read_bulk_callback, priv); + usb_anchor_urb(urb, &priv->rx_submitted); + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (!retval) + return; + + usb_unanchor_urb(urb); if (retval == -ENODEV) netif_device_detach(netdev); - else if (retval) + else netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", retval); } -- Gitee From bf780a4d8923867e23f3e9c8b0e5340b64e705cc Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 10 Jan 2026 19:52:27 +0800 Subject: [PATCH 1202/1449] can: usb_8dev: usb_8dev_read_bulk_callback(): fix URB memory leak ANBZ: #35228 commit 59ff56992bba28051ad67cd8cc7b0edfe7280796 stable. commit f7a980b3b8f80fe367f679da376cf76e800f9480 upstream. Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak"). In usb_8dev_open() -> usb_8dev_start(), the URBs for USB-in transfers are allocated, added to the priv->rx_submitted anchor and submitted. In the complete callback usb_8dev_read_bulk_callback(), the URBs are processed and resubmitted. In usb_8dev_close() -> unlink_all_urbs() the URBs are freed by calling usb_kill_anchored_urbs(&priv->rx_submitted). However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs(). Fix the memory leak by anchoring the URB in the usb_8dev_read_bulk_callback() to the priv->rx_submitted anchor. Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260116-can_usb-fix-memory-leak-v2-5-4b8cb2915571@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/usb_8dev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index 8a5596ce4e46..0fedfc287f1f 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c @@ -541,11 +541,17 @@ static void usb_8dev_read_bulk_callback(struct urb *urb) urb->transfer_buffer, RX_BUFFER_SIZE, usb_8dev_read_bulk_callback, priv); + usb_anchor_urb(urb, &priv->rx_submitted); + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (!retval) + return; + + usb_unanchor_urb(urb); if (retval == -ENODEV) netif_device_detach(netdev); - else if (retval) + else netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", retval); } -- Gitee From e29da33d7f2e8870c900c4674160e7460bf75a66 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Fri, 9 Jan 2026 04:13:42 +0000 Subject: [PATCH 1203/1449] migrate: correct lock ordering for hugetlb file folios ANBZ: #35228 commit 526394af4e8ade89cacd1a9ce2b97712712fcc34 stable. commit b7880cb166ab62c2409046b2347261abf701530e upstream. Syzbot has found a deadlock (analyzed by Lance Yang): 1) Task (5749): Holds folio_lock, then tries to acquire i_mmap_rwsem(read lock). 2) Task (5754): Holds i_mmap_rwsem(write lock), then tries to acquire folio_lock. migrate_pages() -> migrate_hugetlbs() -> unmap_and_move_huge_page() <- Takes folio_lock! -> remove_migration_ptes() -> __rmap_walk_file() -> i_mmap_lock_read() <- Waits for i_mmap_rwsem(read lock)! hugetlbfs_fallocate() -> hugetlbfs_punch_hole() <- Takes i_mmap_rwsem(write lock)! -> hugetlbfs_zero_partial_page() -> filemap_lock_hugetlb_folio() -> filemap_lock_folio() -> __filemap_get_folio <- Waits for folio_lock! The migration path is the one taking locks in the wrong order according to the documentation at the top of mm/rmap.c. So expand the scope of the existing i_mmap_lock to cover the calls to remove_migration_ptes() too. This is (mostly) how it used to be after commit c0d0381ade79. That was removed by 336bf30eb765 for both file & anon hugetlb pages when it should only have been removed for anon hugetlb pages. Link: https://lkml.kernel.org/r/20260109041345.3863089-2-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) Fixes: 336bf30eb765 ("hugetlbfs: fix anon huge page migration race") Reported-by: syzbot+2d9c96466c978346b55f@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/68e9715a.050a0220.1186a4.000d.GAE@google.com Debugged-by: Lance Yang Acked-by: David Hildenbrand (Red Hat) Acked-by: Zi Yan Cc: Alistair Popple Cc: Byungchul Park Cc: Gregory Price Cc: Jann Horn Cc: Joshua Hahn Cc: Liam Howlett Cc: Lorenzo Stoakes Cc: Matthew Brost Cc: Rakie Kim Cc: Rik van Riel Cc: Vlastimil Babka Cc: Ying Huang Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- mm/migrate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index de7a950db819..d5f47fea5fa6 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1427,6 +1427,7 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, int page_was_mapped = 0; struct anon_vma *anon_vma = NULL; struct address_space *mapping = NULL; + enum ttu_flags ttu = 0; if (folio_ref_count(src) == 1) { /* page was freed from under us. So we are done. */ @@ -1468,8 +1469,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, goto put_anon; if (folio_mapped(src)) { - enum ttu_flags ttu = 0; - if (!folio_test_anon(src)) { /* * In shared mappings, try_to_unmap could potentially @@ -1486,9 +1485,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, try_to_migrate(src, ttu); page_was_mapped = 1; - - if (ttu & TTU_RMAP_LOCKED) - i_mmap_unlock_write(mapping); } if (!folio_mapped(src)) @@ -1496,7 +1492,11 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio, if (page_was_mapped) remove_migration_ptes(src, - rc == MIGRATEPAGE_SUCCESS ? dst : src, 0); + rc == MIGRATEPAGE_SUCCESS ? dst : src, + ttu ? RMP_LOCKED : 0); + + if (ttu & TTU_RMAP_LOCKED) + i_mmap_unlock_write(mapping); unlock_put_anon: folio_unlock(dst); -- Gitee From 58a6f7be56c8cff454c4796217da41e6f891f27d Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Fri, 11 Oct 2024 23:31:07 +0800 Subject: [PATCH 1204/1449] selftests/bpf: Check for timeout in perf_link test ANBZ: #35228 commit 1da48da947d0cbf0cb78a3a61486fba6a8f1af24 stable. commit e6c209da7e0e9aaf955a7b59e91ed78c2b6c96fb upstream. Recently perf_link test started unreliably failing on libbpf CI: * https://github.com/libbpf/libbpf/actions/runs/11260672407/job/31312405473 * https://github.com/libbpf/libbpf/actions/runs/11260992334/job/31315514626 * https://github.com/libbpf/libbpf/actions/runs/11263162459/job/31320458251 Part of the test is running a dummy loop for a while and then checking for a counter incremented by the test program. Instead of waiting for an arbitrary number of loop iterations once, check for the test counter in a loop and use get_time_ns() helper to enforce a 100ms timeout. v1: https://lore.kernel.org/bpf/zuRd072x9tumn2iN4wDNs5av0nu5nekMNV4PkR-YwCT10eFFTrUtZBRkLWFbrcCe7guvLStGQlhibo8qWojCO7i2-NGajes5GYIyynexD-w=@pm.me/ Signed-off-by: Ihor Solodrai Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20241011153104.249800-1-ihor.solodrai@pm.me Signed-off-by: Shung-Hsi Yu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../testing/selftests/bpf/prog_tests/perf_link.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/perf_link.c b/tools/testing/selftests/bpf/prog_tests/perf_link.c index 3a25f1c743a1..d940ff87fa08 100644 --- a/tools/testing/selftests/bpf/prog_tests/perf_link.c +++ b/tools/testing/selftests/bpf/prog_tests/perf_link.c @@ -4,8 +4,12 @@ #include #include #include +#include "testing_helpers.h" #include "test_perf_link.skel.h" +#define BURN_TIMEOUT_MS 100 +#define BURN_TIMEOUT_NS BURN_TIMEOUT_MS * 1000000 + static void burn_cpu(void) { volatile int j = 0; @@ -32,6 +36,7 @@ void serial_test_perf_link(void) int run_cnt_before, run_cnt_after; struct bpf_link_info info; __u32 info_len = sizeof(info); + __u64 timeout_time_ns; /* create perf event */ memset(&attr, 0, sizeof(attr)); @@ -63,8 +68,14 @@ void serial_test_perf_link(void) ASSERT_GT(info.prog_id, 0, "link_prog_id"); /* ensure we get at least one perf_event prog execution */ - burn_cpu(); - ASSERT_GT(skel->bss->run_cnt, 0, "run_cnt"); + timeout_time_ns = get_time_ns() + BURN_TIMEOUT_NS; + while (true) { + burn_cpu(); + if (skel->bss->run_cnt > 0) + break; + if (!ASSERT_LT(get_time_ns(), timeout_time_ns, "run_cnt_timeout")) + break; + } /* perf_event is still active, but we close link and BPF program * shouldn't be executed anymore -- Gitee From ab1cf1b96a877955db454c3274df7a1aab6c73a4 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 20 Oct 2025 15:54:41 +0800 Subject: [PATCH 1205/1449] bpf: Do not let BPF test infra emit invalid GSO types to stack ANBZ: #35228 commit 8670b53b8ee91f028f7240531064020b7413c461 stable. commit 04a899573fb87273a656f178b5f920c505f68875 upstream. Yinhao et al. reported that their fuzzer tool was able to trigger a skb_warn_bad_offload() from netif_skb_features() -> gso_features_check(). When a BPF program - triggered via BPF test infra - pushes the packet to the loopback device via bpf_clone_redirect() then mentioned offload warning can be seen. GSO-related features are then rightfully disabled. We get into this situation due to convert___skb_to_skb() setting gso_segs and gso_size but not gso_type. Technically, it makes sense that this warning triggers since the GSO properties are malformed due to the gso_type. Potentially, the gso_type could be marked non-trustworthy through setting it at least to SKB_GSO_DODGY without any other specific assumptions, but that also feels wrong given we should not go further into the GSO engine in the first place. The checks were added in 121d57af308d ("gso: validate gso_type in GSO handlers") because there were malicious (syzbot) senders that combine a protocol with a non-matching gso_type. If we would want to drop such packets, gso_features_check() currently only returns feature flags via netif_skb_features(), so one location for potentially dropping such skbs could be validate_xmit_unreadable_skb(), but then otoh it would be an additional check in the fast-path for a very corner case. Given bpf_clone_redirect() is the only place where BPF test infra could emit such packets, lets reject them right there. Fixes: 850a88cc4096 ("bpf: Expose __sk_buff wire_len/gso_segs to BPF_PROG_TEST_RUN") Fixes: cf62089b0edd ("bpf: Add gso_size to __sk_buff") Reported-by: Yinhao Hu Reported-by: Kaiyan Mei Reported-by: Dongliang Mu Signed-off-by: Daniel Borkmann Signed-off-by: Martin KaFai Lau Link: https://patch.msgid.link/20251020075441.127980-1-daniel@iogearbox.net Signed-off-by: Shung-Hsi Yu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bpf/test_run.c | 5 +++++ net/core/filter.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 53db2f64e567..a343143c7888 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -924,6 +924,11 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb) if (__skb->gso_segs > GSO_MAX_SEGS) return -EINVAL; + + /* Currently GSO type is zero/unset. If this gets extended with + * a small list of accepted GSO types in future, the filter for + * an unset GSO type in bpf_clone_redirect() can be lifted. + */ skb_shinfo(skb)->gso_segs = __skb->gso_segs; skb_shinfo(skb)->gso_size = __skb->gso_size; skb_shinfo(skb)->hwtstamps.hwtstamp = __skb->hwtstamp; diff --git a/net/core/filter.c b/net/core/filter.c index f68f91ab9a1f..a39a0385b053 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2451,6 +2451,13 @@ BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags) if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL))) return -EINVAL; + /* BPF test infra's convert___skb_to_skb() can create type-less + * GSO packets. gso_features_check() will detect this as a bad + * offload. However, lets not leak them out in the first place. + */ + if (unlikely(skb_is_gso(skb) && !skb_shinfo(skb)->gso_type)) + return -EBADMSG; + dev = dev_get_by_index_rcu(dev_net(skb->dev), ifindex); if (unlikely(!dev)) return -EINVAL; -- Gitee From 27324f8dd6159099683b696b1e37bdbf7203f971 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 10 Jan 2026 19:52:27 +0800 Subject: [PATCH 1206/1449] can: esd_usb: esd_usb_read_bulk_callback(): fix URB memory leak ANBZ: #35228 commit adec5e1f9c99fe079ec4c92cca3f1109a3e257c3 stable. commit 5a4391bdc6c8357242f62f22069c865b792406b3 upstream. Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb: gs_usb_receive_bulk_callback(): fix URB memory leak"). In esd_usb_open(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback esd_usb_read_bulk_callback(), the URBs are processed and resubmitted. In esd_usb_close() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted). However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in esd_usb_close(). Fix the memory leak by anchoring the URB in the esd_usb_read_bulk_callback() to the dev->rx_submitted anchor. Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260116-can_usb-fix-memory-leak-v2-2-4b8cb2915571@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/esd_usb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c index 03ad10b01867..fdf2136824b3 100644 --- a/drivers/net/can/usb/esd_usb.c +++ b/drivers/net/can/usb/esd_usb.c @@ -539,13 +539,20 @@ static void esd_usb_read_bulk_callback(struct urb *urb) urb->transfer_buffer, ESD_USB_RX_BUFFER_SIZE, esd_usb_read_bulk_callback, dev); + usb_anchor_urb(urb, &dev->rx_submitted); + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (!retval) + return; + + usb_unanchor_urb(urb); + if (retval == -ENODEV) { for (i = 0; i < dev->net_count; i++) { if (dev->nets[i]) netif_device_detach(dev->nets[i]->netdev); } - } else if (retval) { + } else { dev_err(dev->udev->dev.parent, "failed resubmitting read bulk urb: %d\n", retval); } -- Gitee From fb6260d6b5de7949caaee619b466fdfa5d97929d Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Thu, 25 Dec 2025 10:30:37 +0800 Subject: [PATCH 1207/1449] mm/damon/sysfs-scheme: cleanup access_pattern subdirs on scheme dir setup failure ANBZ: #35228 commit e9711bd0e64812c694a228cf58c9e6032decee54 stable. commit 392b3d9d595f34877dd745b470c711e8ebcd225c upstream. When a DAMOS-scheme DAMON sysfs directory setup fails after setup of access_pattern/ directory, subdirectories of access_pattern/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked. Cleanup the directories under such failures. Link: https://lkml.kernel.org/r/20251225023043.18579-5-sj@kernel.org Fixes: 9bbb820a5bd5 ("mm/damon/sysfs: support DAMOS quotas") Signed-off-by: SeongJae Park Cc: chongjiapeng Cc: # 5.18.x Signed-off-by: Andrew Morton Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/sysfs-schemes.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c index 19d661889cf7..2d081df6b2c1 100644 --- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -1282,9 +1282,10 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme) err = damon_sysfs_scheme_set_access_pattern(scheme); if (err) return err; + err = damon_sysfs_scheme_set_quotas(scheme); if (err) - goto put_access_pattern_out; + goto rmdir_put_access_pattern_out; err = damon_sysfs_scheme_set_watermarks(scheme); if (err) goto put_quotas_access_pattern_out; @@ -1311,7 +1312,8 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme) put_quotas_access_pattern_out: kobject_put(&scheme->quotas->kobj); scheme->quotas = NULL; -put_access_pattern_out: +rmdir_put_access_pattern_out: + damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern); kobject_put(&scheme->access_pattern->kobj); scheme->access_pattern = NULL; return err; -- Gitee From c8548deaec6d5983c2e91c54a4587b207f978707 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Thu, 25 Dec 2025 10:30:36 +0800 Subject: [PATCH 1208/1449] mm/damon/sysfs-scheme: cleanup quotas subdirs on scheme dir setup failure ANBZ: #35228 commit 5596ce564a8c3168cfa8fb1b2e1e52fc09e9aa51 stable. commit dc7e1d75fd8c505096d0cddeca9e2efb2b55aaf9 upstream. When a DAMOS-scheme DAMON sysfs directory setup fails after setup of quotas/ directory, subdirectories of quotas/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked. Cleanup the directories under such failures. Link: https://lkml.kernel.org/r/20251225023043.18579-4-sj@kernel.org Fixes: 1b32234ab087 ("mm/damon/sysfs: support DAMOS watermarks") Signed-off-by: SeongJae Park Cc: chongjiapeng Cc: # 5.18.x Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/damon/sysfs-schemes.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c index 2d081df6b2c1..c774f1e5c0a5 100644 --- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -1288,7 +1288,7 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme) goto rmdir_put_access_pattern_out; err = damon_sysfs_scheme_set_watermarks(scheme); if (err) - goto put_quotas_access_pattern_out; + goto rmdir_put_quotas_access_pattern_out; err = damon_sysfs_scheme_set_filters(scheme); if (err) goto put_watermarks_quotas_access_pattern_out; @@ -1309,7 +1309,8 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme) put_watermarks_quotas_access_pattern_out: kobject_put(&scheme->watermarks->kobj); scheme->watermarks = NULL; -put_quotas_access_pattern_out: +rmdir_put_quotas_access_pattern_out: + damon_sysfs_quotas_rm_dirs(scheme->quotas); kobject_put(&scheme->quotas->kobj); scheme->quotas = NULL; rmdir_put_access_pattern_out: -- Gitee From db48f26a20358ff468928747750a669c0e19703c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 27 Jan 2026 02:28:54 +0800 Subject: [PATCH 1209/1449] iio: core: add missing mutex_destroy in iio_dev_release() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 31c3c9f3b1b9bacc823f7208b40a0de6a9ac69da stable. commit f5d203467a31798191365efeb16cd619d2c8f23a upstream. Add missing mutex_destroy() call in iio_dev_release() to properly clean up the mutex initialized in iio_device_alloc(). Ensure proper resource cleanup and follows kernel practices. Found by code review. While at it, create a lockdep key before mutex initialisation. This will help with converting it to the better API in the future. Fixes: 847ec80bbaa7 ("Staging: IIO: core support for device registration and management") Fixes: ac917a81117c ("staging:iio:core set the iio_dev.info pointer to null on unregister under lock.") Signed-off-by: Andy Shevchenko Reviewed-by: Nuno Sá Signed-off-by: Jonathan Cameron Stable-dep-of: 9910159f0659 ("iio: core: add separate lockdep class for info_exist_lock") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/industrialio-core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 121bde49ccb7..00a82f168837 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1618,6 +1618,9 @@ static void iio_dev_release(struct device *device) iio_device_detach_buffers(indio_dev); + mutex_destroy(&iio_dev_opaque->info_exist_lock); + mutex_destroy(&iio_dev_opaque->mlock); + lockdep_unregister_key(&iio_dev_opaque->mlock_key); ida_free(&iio_ida, iio_dev_opaque->id); @@ -1663,8 +1666,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) indio_dev->dev.type = &iio_device_type; indio_dev->dev.bus = &iio_bus_type; device_initialize(&indio_dev->dev); - mutex_init(&iio_dev_opaque->mlock); - mutex_init(&iio_dev_opaque->info_exist_lock); + INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); iio_dev_opaque->id = ida_alloc(&iio_ida, GFP_KERNEL); @@ -1687,6 +1689,9 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) lockdep_register_key(&iio_dev_opaque->mlock_key); lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); + mutex_init(&iio_dev_opaque->mlock); + mutex_init(&iio_dev_opaque->info_exist_lock); + return indio_dev; } EXPORT_SYMBOL(iio_device_alloc); -- Gitee From edce32280c1916ed5875d68558b5ffea9026fb4f Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 27 Jan 2026 02:28:55 +0800 Subject: [PATCH 1210/1449] iio: core: add separate lockdep class for info_exist_lock ANBZ: #35228 commit 522e5805241068cfecc1f23acc854bac26caa3a1 stable. commit 9910159f06590c17df4fbddedaabb4c0201cc4cb upstream. When one iio device is a consumer of another, it is possible that the ->info_exist_lock of both ends up being taken when reading the value of the consumer device. Since they currently belong to the same lockdep class (being initialized in a single location with mutex_init()), that results in a lockdep warning CPU0 ---- lock(&iio_dev_opaque->info_exist_lock); lock(&iio_dev_opaque->info_exist_lock); *** DEADLOCK *** May be due to missing lock nesting notation 4 locks held by sensors/414: #0: c31fd6dc (&p->lock){+.+.}-{3:3}, at: seq_read_iter+0x44/0x4e4 #1: c4f5a1c4 (&of->mutex){+.+.}-{3:3}, at: kernfs_seq_start+0x1c/0xac #2: c2827548 (kn->active#34){.+.+}-{0:0}, at: kernfs_seq_start+0x30/0xac #3: c1dd2b68 (&iio_dev_opaque->info_exist_lock){+.+.}-{3:3}, at: iio_read_channel_processed_scale+0x24/0xd8 stack backtrace: CPU: 0 UID: 0 PID: 414 Comm: sensors Not tainted 6.17.11 #5 NONE Hardware name: Generic AM33XX (Flattened Device Tree) Call trace: unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x44/0x60 dump_stack_lvl from print_deadlock_bug+0x2b8/0x334 print_deadlock_bug from __lock_acquire+0x13a4/0x2ab0 __lock_acquire from lock_acquire+0xd0/0x2c0 lock_acquire from __mutex_lock+0xa0/0xe8c __mutex_lock from mutex_lock_nested+0x1c/0x24 mutex_lock_nested from iio_read_channel_raw+0x20/0x6c iio_read_channel_raw from rescale_read_raw+0x128/0x1c4 rescale_read_raw from iio_channel_read+0xe4/0xf4 iio_channel_read from iio_read_channel_processed_scale+0x6c/0xd8 iio_read_channel_processed_scale from iio_hwmon_read_val+0x68/0xbc iio_hwmon_read_val from dev_attr_show+0x18/0x48 dev_attr_show from sysfs_kf_seq_show+0x80/0x110 sysfs_kf_seq_show from seq_read_iter+0xdc/0x4e4 seq_read_iter from vfs_read+0x238/0x2e4 vfs_read from ksys_read+0x6c/0xec ksys_read from ret_fast_syscall+0x0/0x1c Just as the mlock_key already has its own lockdep class, add a lock_class_key for the info_exist mutex. Note that this has in theory been a problem since before IIO first left staging, but it only occurs when a chain of consumers is in use and that is not often done. Fixes: ac917a81117c ("staging:iio:core set the iio_dev.info pointer to null on unregister under lock.") Signed-off-by: Rasmus Villemoes Reviewed-by: Peter Rosin Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/industrialio-core.c | 3 ++- include/linux/iio/iio-opaque.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 00a82f168837..f3e0788f51ca 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1621,6 +1621,7 @@ static void iio_dev_release(struct device *device) mutex_destroy(&iio_dev_opaque->info_exist_lock); mutex_destroy(&iio_dev_opaque->mlock); + lockdep_unregister_key(&iio_dev_opaque->info_exist_key); lockdep_unregister_key(&iio_dev_opaque->mlock_key); ida_free(&iio_ida, iio_dev_opaque->id); @@ -1687,7 +1688,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers); lockdep_register_key(&iio_dev_opaque->mlock_key); - lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); + lockdep_register_key(&iio_dev_opaque->info_exist_key); mutex_init(&iio_dev_opaque->mlock); mutex_init(&iio_dev_opaque->info_exist_lock); diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h index 5aec3945555b..0e184cd5d6ac 100644 --- a/include/linux/iio/iio-opaque.h +++ b/include/linux/iio/iio-opaque.h @@ -14,6 +14,7 @@ * @mlock: lock used to prevent simultaneous device state changes * @mlock_key: lockdep class for iio_dev lock * @info_exist_lock: lock to prevent use during removal + * @info_exist_key: lockdep class for info_exist lock * @trig_readonly: mark the current trigger immutable * @event_interface: event chrdevs associated with interrupt lines * @attached_buffers: array of buffers statically attached by the driver @@ -47,6 +48,7 @@ struct iio_dev_opaque { struct mutex mlock; struct lock_class_key mlock_key; struct mutex info_exist_lock; + struct lock_class_key info_exist_key; bool trig_readonly; struct iio_event_interface *event_interface; struct iio_buffer **attached_buffers; -- Gitee From 933b6ac1dae91f9ec9b2446a2a4a2e951241cdde Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (Red Hat)" Date: Mon, 26 Jan 2026 12:55:51 -0500 Subject: [PATCH 1211/1449] mm/rmap: fix two comments related to huge_pmd_unshare() ANBZ: #35228 commit fb3c1f24f3b7ea6c57d7f0041967ff3b84a8d87e stable. commit a8682d500f691b6dfaa16ae1502d990aeb86e8be upstream. PMD page table unsharing no longer touches the refcount of a PMD page table. Also, it is not about dropping the refcount of a "PMD page" but the "PMD page table". Let's just simplify by saying that the PMD page table was unmapped, consequently also unmapping the folio that was mapped into this page. This code should be deduplicated in the future. Link: https://lkml.kernel.org/r/20251223214037.580860-4-david@kernel.org Fixes: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count") Signed-off-by: David Hildenbrand (Red Hat) Reviewed-by: Rik van Riel Tested-by: Laurence Oberman Reviewed-by: Lorenzo Stoakes Acked-by: Oscar Salvador Cc: Liu Shixin Cc: Harry Yoo Cc: Lance Yang Cc: "Uschakow, Stanislav" Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- mm/rmap.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 58a76e2be2ff..0ce21d315cc7 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1854,14 +1854,8 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, flush_tlb_range(vma, range.start, range.end); /* - * The ref count of the PMD page was - * dropped which is part of the way map - * counting is done for shared PMDs. - * Return 'true' here. When there is - * no other sharing, huge_pmd_unshare - * returns false and we will unmap the - * actual page and drop map count - * to zero. + * The PMD table was unmapped, + * consequently unmapping the folio. */ goto walk_done; } @@ -2260,14 +2254,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, range.start, range.end); /* - * The ref count of the PMD page was - * dropped which is part of the way map - * counting is done for shared PMDs. - * Return 'true' here. When there is - * no other sharing, huge_pmd_unshare - * returns false and we will unmap the - * actual page and drop map count - * to zero. + * The PMD table was unmapped, + * consequently unmapping the folio. */ page_vma_mapped_walk_done(&pvmw); break; -- Gitee From 511fe9ea7ce27650bbda795300d00a6845d6254f Mon Sep 17 00:00:00 2001 From: Geraldo Nascimento Date: Tue, 27 Jan 2026 00:13:38 +0800 Subject: [PATCH 1212/1449] arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s ANBZ: #35228 commit 6b20590c43538c6e77dc2c52e3fed1b8782e543c stable. commit ce652c98a7bfa0b7c675ef5cd85c44c186db96af upstream. This is already the default in rk3399-base.dtsi, remove redundant declaration from rk3399-nanopi-r4s.dtsi. Fixes: db792e9adbf8 ("rockchip: rk3399: Add support for FriendlyARM NanoPi R4S") Cc: stable@vger.kernel.org Reported-by: Dragan Simic Reviewed-by: Dragan Simic Signed-off-by: Geraldo Nascimento Acked-by: Shawn Lin Link: https://patch.msgid.link/6694456a735844177c897581f785cc00c064c7d1.1763415706.git.geraldogabriel@gmail.com Signed-off-by: Heiko Stuebner [ adapted file path from rk3399-nanopi-r4s.dtsi to rk3399-nanopi-r4s.dts ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts index 6a6b36c36ce2..0a55aa44effe 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts @@ -73,7 +73,6 @@ &i2c4 { }; &pcie0 { - max-link-speed = <1>; num-lanes = <1>; vpcie3v3-supply = <&vcc3v3_sys>; }; -- Gitee From c82c38119d0562f70a24df3a4a146ec4df909d3a Mon Sep 17 00:00:00 2001 From: Samasth Norway Ananda Date: Wed, 28 Jan 2026 05:08:23 +0800 Subject: [PATCH 1213/1449] ALSA: scarlett2: Fix buffer overflow in config retrieval ANBZ: #35228 commit 91a756d22f0482eac5bedb113c8922f90b254449 stable. commit 6f5c69f72e50d51be3a8c028ae7eda42c82902cb upstream. The scarlett2_usb_get_config() function has a logic error in the endianness conversion code that can cause buffer overflows when count > 1. The code checks `if (size == 2)` where `size` is the total buffer size in bytes, then loops `count` times treating each element as u16 (2 bytes). This causes the loop to access `count * 2` bytes when the buffer only has `size` bytes allocated. Fix by checking the element size (config_item->size) instead of the total buffer size. This ensures the endianness conversion matches the actual element type. Fixes: ac34df733d2d ("ALSA: usb-audio: scarlett2: Update get_config to do endian conversion") Cc: stable@vger.kernel.org Signed-off-by: Samasth Norway Ananda Link: https://patch.msgid.link/20260117012706.1715574-1-samasth.norway.ananda@oracle.com Signed-off-by: Takashi Iwai [ add 32-bit handling block ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/mixer_scarlett2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 316f1abefd51..6112c3fb8ba6 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -1408,11 +1408,16 @@ static int scarlett2_usb_get_config( err = scarlett2_usb_get(mixer, config_item->offset, buf, size); if (err < 0) return err; - if (size == 2) { + if (config_item->size == 16) { u16 *buf_16 = buf; for (i = 0; i < count; i++, buf_16++) *buf_16 = le16_to_cpu(*(__le16 *)buf_16); + } else if (config_item->size == 32) { + u32 *buf_32 = (u32 *)buf; + + for (i = 0; i < count; i++, buf_32++) + *buf_32 = le32_to_cpu(*(__le32 *)buf_32); } return 0; } -- Gitee From 3d4942eb1cadbb69fae95bd7c877012e9b989105 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 28 Jan 2026 02:26:19 +0800 Subject: [PATCH 1214/1449] iio: adc: exynos_adc: fix OF populate on driver rebind ANBZ: #35228 commit 041863dd410bd02783cc7bc04376762cc2d63069 stable. commit ea6b4feba85e996e840e0b661bc42793df6eb701 upstream. Since commit c6e126de43e7 ("of: Keep track of populated platform devices") child devices will not be created by of_platform_populate() if the devices had previously been deregistered individually so that the OF_POPULATED flag is still set in the corresponding OF nodes. Switch to using of_platform_depopulate() instead of open coding so that the child devices are created if the driver is rebound. Fixes: c6e126de43e7 ("of: Keep track of populated platform devices") Cc: stable@vger.kernel.org # 3.16 Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jonathan Cameron [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/iio/adc/exynos_adc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 43c8af41b4a9..a935ef1840a6 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -721,14 +721,7 @@ static const struct iio_chan_spec exynos_adc_iio_channels[] = { ADC_CHANNEL(9, "adc9"), }; -static int exynos_adc_remove_devices(struct device *dev, void *c) -{ - struct platform_device *pdev = to_platform_device(dev); - - platform_device_unregister(pdev); - return 0; -} static int exynos_adc_ts_open(struct input_dev *dev) { @@ -929,8 +922,7 @@ static int exynos_adc_probe(struct platform_device *pdev) return 0; err_of_populate: - device_for_each_child(&indio_dev->dev, NULL, - exynos_adc_remove_devices); + of_platform_depopulate(&indio_dev->dev); if (has_ts) { input_unregister_device(info->input); free_irq(info->tsirq, info); @@ -959,8 +951,7 @@ static int exynos_adc_remove(struct platform_device *pdev) free_irq(info->tsirq, info); input_unregister_device(info->input); } - device_for_each_child(&indio_dev->dev, NULL, - exynos_adc_remove_devices); + of_platform_depopulate(&indio_dev->dev); iio_device_unregister(indio_dev); free_irq(info->irq, info); if (info->data->exit_hw) -- Gitee From 8958e56405c548f7cec5663dfd13f55d49f41de7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 21 Jan 2026 20:15:50 +0800 Subject: [PATCH 1215/1449] dmaengine: stm32: dmamux: fix device leak on route allocation ANBZ: #35228 commit 1a179ac01ff3993ab97e33cc77c316ed7415cda1 stable. commit dd6e4943889fb354efa3f700e42739da9bddb6ef upstream. Make sure to drop the reference taken when looking up the DMA mux platform device during route allocation. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") Cc: stable@vger.kernel.org # 4.15 Cc: Pierre-Yves MORDRET Signed-off-by: Johan Hovold Reviewed-by: Amelie Delaunay Link: https://patch.msgid.link/20251117161258.10679-11-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/stm32-dmamux.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c index 8d77e2a7939a..791179760782 100644 --- a/drivers/dma/stm32-dmamux.c +++ b/drivers/dma/stm32-dmamux.c @@ -90,23 +90,25 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev); struct stm32_dmamux *mux; u32 i, min, max; - int ret; + int ret = -EINVAL; unsigned long flags; if (dma_spec->args_count != 3) { dev_err(&pdev->dev, "invalid number of dma mux args\n"); - return ERR_PTR(-EINVAL); + goto err_put_pdev; } if (dma_spec->args[0] > dmamux->dmamux_requests) { dev_err(&pdev->dev, "invalid mux request number: %d\n", dma_spec->args[0]); - return ERR_PTR(-EINVAL); + goto err_put_pdev; } mux = kzalloc(sizeof(*mux), GFP_KERNEL); - if (!mux) - return ERR_PTR(-ENOMEM); + if (!mux) { + ret = -ENOMEM; + goto err_put_pdev; + } spin_lock_irqsave(&dmamux->lock, flags); mux->chan_id = find_first_zero_bit(dmamux->dma_inuse, @@ -133,7 +135,6 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1); if (!dma_spec->np) { dev_err(&pdev->dev, "can't get dma master\n"); - ret = -EINVAL; goto error; } @@ -160,6 +161,8 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n", mux->request, mux->master, mux->chan_id); + put_device(&pdev->dev); + return mux; error: @@ -167,6 +170,9 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, error_chan_id: kfree(mux); +err_put_pdev: + put_device(&pdev->dev); + return ERR_PTR(ret); } -- Gitee From bdc2ead5c3d9334d5bd9e18bd440ec6c8720feec Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 21 Jan 2026 20:20:47 +0800 Subject: [PATCH 1216/1449] dmaengine: stm32: dmamux: fix OF node leak on route allocation failure ANBZ: #35228 commit 93464499df42ba3e64c1992563abc7001e92b2af stable. commit b1b590a590af13ded598e70f0b72bc1e515787a1 upstream. Make sure to drop the reference taken to the DMA master OF node also on late route allocation failures. Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") Cc: stable@vger.kernel.org # 4.15 Cc: Pierre-Yves MORDRET Signed-off-by: Johan Hovold Reviewed-by: Amelie Delaunay Link: https://patch.msgid.link/20251117161258.10679-12-johan@kernel.org Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/dma/stm32-dmamux.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c index 791179760782..2bd218dbabbb 100644 --- a/drivers/dma/stm32-dmamux.c +++ b/drivers/dma/stm32-dmamux.c @@ -143,7 +143,7 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { spin_unlock_irqrestore(&dmamux->lock, flags); - goto error; + goto err_put_dma_spec_np; } spin_unlock_irqrestore(&dmamux->lock, flags); @@ -165,6 +165,8 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, return mux; +err_put_dma_spec_np: + of_node_put(dma_spec->np); error: clear_bit(mux->chan_id, dmamux->dma_inuse); -- Gitee From f8b618387f0612ebd67421ada30b03761cc2958d Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Wed, 21 Jan 2026 07:03:39 -0500 Subject: [PATCH 1217/1449] mm/page_alloc: prevent pcp corruption with SMP=n ANBZ: #35228 commit 4a04ff9cd816e7346fcc8126f00ed80481f6569d stable. commit 038a102535eb49e10e93eafac54352fcc5d78847 upstream. The kernel test robot has reported: BUG: spinlock trylock failure on UP on CPU#0, kcompactd0/28 lock: 0xffff888807e35ef0, .magic: dead4ead, .owner: kcompactd0/28, .owner_cpu: 0 CPU: 0 UID: 0 PID: 28 Comm: kcompactd0 Not tainted 6.18.0-rc5-00127-ga06157804399 #1 PREEMPT 8cc09ef94dcec767faa911515ce9e609c45db470 Call Trace: __dump_stack (lib/dump_stack.c:95) dump_stack_lvl (lib/dump_stack.c:123) dump_stack (lib/dump_stack.c:130) spin_dump (kernel/locking/spinlock_debug.c:71) do_raw_spin_trylock (kernel/locking/spinlock_debug.c:?) _raw_spin_trylock (include/linux/spinlock_api_smp.h:89 kernel/locking/spinlock.c:138) __free_frozen_pages (mm/page_alloc.c:2973) ___free_pages (mm/page_alloc.c:5295) __free_pages (mm/page_alloc.c:5334) tlb_remove_table_rcu (include/linux/mm.h:? include/linux/mm.h:3122 include/asm-generic/tlb.h:220 mm/mmu_gather.c:227 mm/mmu_gather.c:290) ? __cfi_tlb_remove_table_rcu (mm/mmu_gather.c:289) ? rcu_core (kernel/rcu/tree.c:?) rcu_core (include/linux/rcupdate.h:341 kernel/rcu/tree.c:2607 kernel/rcu/tree.c:2861) rcu_core_si (kernel/rcu/tree.c:2879) handle_softirqs (arch/x86/include/asm/jump_label.h:36 include/trace/events/irq.h:142 kernel/softirq.c:623) __irq_exit_rcu (arch/x86/include/asm/jump_label.h:36 kernel/softirq.c:725) irq_exit_rcu (kernel/softirq.c:741) sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052) RIP: 0010:_raw_spin_unlock_irqrestore (arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:152 kernel/locking/spinlock.c:194) free_pcppages_bulk (mm/page_alloc.c:1494) drain_pages_zone (include/linux/spinlock.h:391 mm/page_alloc.c:2632) __drain_all_pages (mm/page_alloc.c:2731) drain_all_pages (mm/page_alloc.c:2747) kcompactd (mm/compaction.c:3115) kthread (kernel/kthread.c:465) ? __cfi_kcompactd (mm/compaction.c:3166) ? __cfi_kthread (kernel/kthread.c:412) ret_from_fork (arch/x86/kernel/process.c:164) ? __cfi_kthread (kernel/kthread.c:412) ret_from_fork_asm (arch/x86/entry/entry_64.S:255) Matthew has analyzed the report and identified that in drain_page_zone() we are in a section protected by spin_lock(&pcp->lock) and then get an interrupt that attempts spin_trylock() on the same lock. The code is designed to work this way without disabling IRQs and occasionally fail the trylock with a fallback. However, the SMP=n spinlock implementation assumes spin_trylock() will always succeed, and thus it's normally a no-op. Here the enabled lock debugging catches the problem, but otherwise it could cause a corruption of the pcp structure. The problem has been introduced by commit 574907741599 ("mm/page_alloc: leave IRQs enabled for per-cpu page allocations"). The pcp locking scheme recognizes the need for disabling IRQs to prevent nesting spin_trylock() sections on SMP=n, but the need to prevent the nesting in spin_lock() has not been recognized. Fix it by introducing local wrappers that change the spin_lock() to spin_lock_iqsave() with SMP=n and use them in all places that do spin_lock(&pcp->lock). [vbabka@suse.cz: add pcp_ prefix to the spin_lock_irqsave wrappers, per Steven] Link: https://lkml.kernel.org/r/20260105-fix-pcp-up-v1-1-5579662d2071@suse.cz Fixes: 574907741599 ("mm/page_alloc: leave IRQs enabled for per-cpu page allocations") Signed-off-by: Vlastimil Babka Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202512101320.e2f2dd6f-lkp@intel.com Analyzed-by: Matthew Wilcox Link: https://lore.kernel.org/all/aUW05pyc9nZkvY-1@casper.infradead.org/ Acked-by: Mel Gorman Cc: Brendan Jackman Cc: Johannes Weiner Cc: Michal Hocko Cc: Sebastian Andrzej Siewior Cc: Steven Rostedt Cc: Suren Baghdasaryan Cc: Zi Yan Cc: Signed-off-by: Andrew Morton [ drop changes to decay_pcp_high() and zone_pcp_update_cacheinfo() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- mm/page_alloc.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f88b0f036bd1..76eb11f1b044 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -168,6 +168,33 @@ static DEFINE_MUTEX(pcp_batch_high_lock); #define pcp_spin_unlock(ptr) \ pcpu_spin_unlock(lock, ptr) +/* + * With the UP spinlock implementation, when we spin_lock(&pcp->lock) (for i.e. + * a potentially remote cpu drain) and get interrupted by an operation that + * attempts pcp_spin_trylock(), we can't rely on the trylock failure due to UP + * spinlock assumptions making the trylock a no-op. So we have to turn that + * spin_lock() to a spin_lock_irqsave(). This works because on UP there are no + * remote cpu's so we can only be locking the only existing local one. + */ +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) +static inline void __flags_noop(unsigned long *flags) { } +#define pcp_spin_lock_maybe_irqsave(ptr, flags) \ +({ \ + __flags_noop(&(flags)); \ + spin_lock(&(ptr)->lock); \ +}) +#define pcp_spin_unlock_maybe_irqrestore(ptr, flags) \ +({ \ + spin_unlock(&(ptr)->lock); \ + __flags_noop(&(flags)); \ +}) +#else +#define pcp_spin_lock_maybe_irqsave(ptr, flags) \ + spin_lock_irqsave(&(ptr)->lock, flags) +#define pcp_spin_unlock_maybe_irqrestore(ptr, flags) \ + spin_unlock_irqrestore(&(ptr)->lock, flags) +#endif + #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID DEFINE_PER_CPU(int, numa_node); EXPORT_PER_CPU_SYMBOL(numa_node); @@ -2462,14 +2489,15 @@ int decay_pcp_high(struct zone *zone, struct per_cpu_pages *pcp) */ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) { + unsigned long UP_flags; int to_drain, batch; batch = READ_ONCE(pcp->batch); to_drain = min(pcp->count, batch); if (to_drain > 0) { - spin_lock(&pcp->lock); + pcp_spin_lock_maybe_irqsave(pcp, UP_flags); free_pcppages_bulk(zone, to_drain, pcp, 0); - spin_unlock(&pcp->lock); + pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags); } } #endif @@ -2481,9 +2509,10 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) { struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); int count, batch_scale_max = READ_ONCE(pcp_batch_scale_max); + unsigned long UP_flags; do { - spin_lock(&pcp->lock); + pcp_spin_lock_maybe_irqsave(pcp, UP_flags); count = pcp->count; if (count) { int to_drain = min(count, pcp->batch << batch_scale_max); @@ -2491,7 +2520,7 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) free_pcppages_bulk(zone, to_drain, pcp, 0); count -= to_drain; } - spin_unlock(&pcp->lock); + pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags); } while (count); } -- Gitee From 3804bcd86f5b4e1c6ce652e3f623fe91b672a927 Mon Sep 17 00:00:00 2001 From: Ryan Roberts Date: Wed, 21 Jan 2026 18:55:42 +0800 Subject: [PATCH 1218/1449] mm: kmsan: fix poisoning of high-order non-compound pages ANBZ: #35228 commit d6705bcc5fe7c2e2035b58e04b1ca11b41ffcb7b stable. commit 4795d205d78690a46b60164f44b8bb7b3e800865 upstream. kmsan_free_page() is called by the page allocator's free_pages_prepare() during page freeing. Its job is to poison all the memory covered by the page. It can be called with an order-0 page, a compound high-order page or a non-compound high-order page. But page_size() only works for order-0 and compound pages. For a non-compound high-order page it will incorrectly return PAGE_SIZE. The implication is that the tail pages of a high-order non-compound page do not get poisoned at free, so any invalid access while they are free could go unnoticed. It looks like the pages will be poisoned again at allocation time, so that would bookend the window. Fix this by using the order parameter to calculate the size. Link: https://lkml.kernel.org/r/20260104134348.3544298-1-ryan.roberts@arm.com Fixes: b073d7f8aee4 ("mm: kmsan: maintain KMSAN metadata for page operations") Signed-off-by: Ryan Roberts Reviewed-by: Alexander Potapenko Tested-by: Alexander Potapenko Cc: Dmitriy Vyukov Cc: Dmitry Vyukov Cc: Marco Elver Cc: Ryan Roberts Cc: Signed-off-by: Andrew Morton [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/kmsan/shadow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c index 87318f9170f1..8b619191299d 100644 --- a/mm/kmsan/shadow.c +++ b/mm/kmsan/shadow.c @@ -210,7 +210,7 @@ void kmsan_free_page(struct page *page, unsigned int order) return; kmsan_enter_runtime(); kmsan_internal_poison_memory(page_address(page), - page_size(page), + PAGE_SIZE << order, GFP_KERNEL, KMSAN_POISON_CHECK | KMSAN_POISON_FREE); kmsan_leave_runtime(); -- Gitee From 4a85383a6276c0ab95c582c92a28d8934fbf3e78 Mon Sep 17 00:00:00 2001 From: Dragan Simic Date: Wed, 21 Jan 2026 09:49:10 +0800 Subject: [PATCH 1219/1449] phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the probe path ANBZ: #35228 commit 479fab9aeade18da4a29cea023a0b0c3caa61565 stable. commit 40452520850683f6771094ca218ff206d1fcb022 upstream. Improve error handling in the probe path by using function dev_err_probe() instead of function dev_err(), where appropriate. Signed-off-by: Dragan Simic Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/d4ccd9fc278fb46ea868406bf77811ee507f0e4e.1725524803.git.dsimic@manjaro.org Signed-off-by: Vinod Koul Stable-dep-of: e07dea3de508 ("phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index a7b7f631cdac..16bddb814b76 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -420,11 +420,9 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy) if (of_property_read_bool(node, "extcon")) { edev = extcon_get_edev_by_phandle(rphy->dev, 0); - if (IS_ERR(edev)) { - if (PTR_ERR(edev) != -EPROBE_DEFER) - dev_err(rphy->dev, "Invalid or missing extcon\n"); - return PTR_ERR(edev); - } + if (IS_ERR(edev)) + return dev_err_probe(rphy->dev, PTR_ERR(edev), + "invalid or missing extcon\n"); } else { /* Initialize extcon device */ edev = devm_extcon_dev_allocate(rphy->dev, @@ -434,10 +432,9 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy) return -ENOMEM; ret = devm_extcon_dev_register(rphy->dev, edev); - if (ret) { - dev_err(rphy->dev, "failed to register extcon device\n"); - return ret; - } + if (ret) + return dev_err_probe(rphy->dev, ret, + "failed to register extcon device\n"); } rphy->edev = edev; @@ -1396,10 +1393,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) } ret = rockchip_usb2phy_clk480m_register(rphy); - if (ret) { - dev_err(dev, "failed to register 480m output clock\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to register 480m output clock\n"); if (rphy->phy_cfg->phy_tuning) { ret = rphy->phy_cfg->phy_tuning(rphy); @@ -1419,8 +1414,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops); if (IS_ERR(phy)) { - dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n"); - ret = PTR_ERR(phy); + ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n"); goto put_child; } @@ -1457,8 +1451,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) "rockchip_usb2phy", rphy); if (ret) { - dev_err(rphy->dev, - "failed to request usb2phy irq handle\n"); + dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n"); goto put_child; } } -- Gitee From c637f62cb6caca6e79852f4cddfd022184e53ad2 Mon Sep 17 00:00:00 2001 From: Wentao Liang Date: Wed, 21 Jan 2026 09:49:11 +0800 Subject: [PATCH 1220/1449] phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe() ANBZ: #35228 commit ebae26dd15140b840cf65be5e1c0daee949ba70b stable. commit e07dea3de508cd6950c937cec42de7603190e1ca upstream. The for_each_available_child_of_node() calls of_node_put() to release child_np in each success loop. After breaking from the loop with the child_np has been released, the code will jump to the put_child label and will call the of_node_put() again if the devm_request_threaded_irq() fails. These cause a double free bug. Fix by returning directly to avoid the duplicate of_node_put(). Fixes: ed2b5a8e6b98 ("phy: phy-rockchip-inno-usb2: support muxed interrupts") Cc: stable@vger.kernel.org Signed-off-by: Wentao Liang Reviewed-by: Neil Armstrong Link: https://patch.msgid.link/20260109154626.2452034-1-vulab@iscas.ac.cn Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 16bddb814b76..a806a22b5eef 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -1452,7 +1452,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev) rphy); if (ret) { dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n"); - goto put_child; + return ret; } } -- Gitee From 6a7c4dcb55edf9e7be95590ac0ff218d311a8c9e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 21 Jan 2026 09:39:05 +0800 Subject: [PATCH 1221/1449] ASoC: codecs: wsa881x: Drop unused version readout ANBZ: #35228 commit ea2474ea2eef4052d32f2234cb476621072d7b8e stable. commit 3d2a69eb503d15171a7ba51cf0b562728ac396b7 upstream. Driver does not use the device version after reading it from the registers, so simplify by dropping unneeded code. Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20240710-asoc-wsa88xx-version-v1-1-f1c54966ccde@linaro.org Signed-off-by: Mark Brown Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/wsa881x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 53b828f68102..2b0c26664762 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -680,7 +680,6 @@ struct wsa881x_priv { * For backwards compatibility. */ unsigned int sd_n_val; - int version; int active_ports; bool port_prepared[WSA881X_MAX_SWR_PORTS]; bool port_enable[WSA881X_MAX_SWR_PORTS]; @@ -691,7 +690,6 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x) struct regmap *rm = wsa881x->regmap; unsigned int val = 0; - regmap_read(rm, WSA881X_CHIP_ID1, &wsa881x->version); regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0, ARRAY_SIZE(wsa881x_rev_2_0)); -- Gitee From 0a211ea2dfb75b3d56cd935079be22f437fa6712 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 21 Jan 2026 09:39:06 +0800 Subject: [PATCH 1222/1449] ASoC: codecs: wsa881x: fix unnecessary initialisation ANBZ: #35228 commit 0ded4420b54e9e8d207abc523a7d50e900c1e37d stable. commit 29d71b8a5a40708b3eed9ba4953bfc2312c9c776 upstream. The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED. Fixes: a0aab9e1404a ("ASoC: codecs: add wsa881x amplifier support") Cc: stable@vger.kernel.org # 5.6 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-3-johan@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/wsa881x.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 2b0c26664762..c1f1414aa512 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -681,6 +681,7 @@ struct wsa881x_priv { */ unsigned int sd_n_val; int active_ports; + bool hw_init; bool port_prepared[WSA881X_MAX_SWR_PORTS]; bool port_enable[WSA881X_MAX_SWR_PORTS]; }; @@ -690,6 +691,9 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x) struct regmap *rm = wsa881x->regmap; unsigned int val = 0; + if (wsa881x->hw_init) + return; + regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0, ARRAY_SIZE(wsa881x_rev_2_0)); @@ -727,6 +731,8 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x) regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A); regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2); regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05); + + wsa881x->hw_init = true; } static int wsa881x_component_probe(struct snd_soc_component *comp) @@ -1071,6 +1077,9 @@ static int wsa881x_update_status(struct sdw_slave *slave, { struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev); + if (status == SDW_SLAVE_UNATTACHED) + wsa881x->hw_init = false; + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) wsa881x_init(wsa881x); -- Gitee From f3266f1f69d36dddfa613d9ac1efc5f8ec537b41 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 20 Jan 2026 00:58:47 +0800 Subject: [PATCH 1223/1449] ASoC: codecs: wsa883x: fix unnecessary initialisation ANBZ: #35228 commit f83824b023c751ac8047f24c751d8da2f0d12c55 stable. commit 49aadf830eb048134d33ad7329d92ecff45d8dbb upstream. The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED. This avoids repeated initialisation of the codecs during boot of machines like the Lenovo ThinkPad X13s: [ 11.614523] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.618022] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.621377] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.624065] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.631382] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.634424] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") Cc: stable@vger.kernel.org # 6.0 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-2-johan@kernel.org Signed-off-by: Mark Brown [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/wsa883x.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 1831d4487ba9..8d712781018a 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -444,6 +444,7 @@ struct wsa883x_priv { int active_ports; int dev_mode; int comp_offset; + bool hw_init; }; enum { @@ -1003,6 +1004,9 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x) struct regmap *regmap = wsa883x->regmap; int variant, version, ret; + if (wsa883x->hw_init) + return 0; + ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant); if (ret) return ret; @@ -1046,6 +1050,8 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x) wsa883x->comp_offset); } + wsa883x->hw_init = true; + return 0; } @@ -1054,6 +1060,9 @@ static int wsa883x_update_status(struct sdw_slave *slave, { struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + if (status == SDW_SLAVE_UNATTACHED) + wsa883x->hw_init = false; + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) return wsa883x_init(wsa883x); -- Gitee From 44f65d62946248603fe391168dce9e86f9cc2188 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 21 Jan 2026 10:52:26 +0800 Subject: [PATCH 1224/1449] nvme-fc: rename free_ctrl callback to match name pattern ANBZ: #35228 commit ca88419cf0623dcdbb2beacb8fad30206ed7faf3 stable. commit 205fb5fa6fde1b5b426015eb1ff69f2ff25ef5bb upstream. Rename nvme_fc_nvme_ctrl_freed to nvme_fc_free_ctrl to match the name pattern for the callback. Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Reviewed-by: Hannes Reinecke Signed-off-by: Daniel Wagner Signed-off-by: Keith Busch Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/fc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 2954f0a27474..abf6d028ef96 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2384,7 +2384,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ctrl) * controller. Called after last nvme_put_ctrl() call */ static void -nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl) +nvme_fc_free_ctrl(struct nvme_ctrl *nctrl) { struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); @@ -3349,7 +3349,7 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = { .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, - .free_ctrl = nvme_fc_nvme_ctrl_freed, + .free_ctrl = nvme_fc_free_ctrl, .submit_async_event = nvme_fc_submit_async_event, .delete_ctrl = nvme_fc_delete_ctrl, .get_address = nvmf_get_address, -- Gitee From 7837b99365a31b6b1d310b7bc815b658271d92af Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 21 Jan 2026 10:52:27 +0800 Subject: [PATCH 1225/1449] nvme-pci: do not directly handle subsys reset fallout ANBZ: #35228 commit 7dfb39b0186ddd929400686fbacfb9b0915888d7 stable. commit 210b1f6576e8b367907e7ff51ef425062e1468e4 upstream. Scheduling reset_work after a nvme subsystem reset is expected to fail on pcie, but this also prevents potential handling the platform's pcie services may provide that might successfully recovering the link without re-enumeration. Such examples include AER, DPC, and power's EEH. Provide a pci specific operation that safely initiates a subsystem reset, and instead of scheduling reset work, read back the status register to trigger a pcie read error. Since this only affects pci, the other fabrics drivers subscribe to a generic nvmf subsystem reset that is exactly the same as before. The loop fabric doesn't use it because nvmet doesn't support setting that property anyway. And since we're using the magic NSSR value in two places now, provide a symbolic define for it. Reported-by: Nilay Shroff Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/fabrics.c | 15 +++++++++++++++ drivers/nvme/host/fabrics.h | 1 + drivers/nvme/host/fc.c | 1 + drivers/nvme/host/nvme.h | 14 +++----------- drivers/nvme/host/pci.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/nvme/host/rdma.c | 1 + drivers/nvme/host/tcp.c | 1 + include/linux/nvme.h | 3 +++ 8 files changed, 61 insertions(+), 11 deletions(-) diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 92ba315cfe19..5963e8b695ff 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c @@ -279,6 +279,21 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val) } EXPORT_SYMBOL_GPL(nvmf_reg_write32); +int nvmf_subsystem_reset(struct nvme_ctrl *ctrl) +{ + int ret; + + if (!nvme_wait_reset(ctrl)) + return -EBUSY; + + ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, NVME_SUBSYS_RESET); + if (ret) + return ret; + + return nvme_try_sched_reset(ctrl); +} +EXPORT_SYMBOL_GPL(nvmf_subsystem_reset); + /** * nvmf_log_connect_error() - Error-parsing-diagnostic print out function for * connect() errors. diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h index 80e15ad3936f..e75c68738240 100644 --- a/drivers/nvme/host/fabrics.h +++ b/drivers/nvme/host/fabrics.h @@ -206,6 +206,7 @@ static inline unsigned int nvmf_nr_io_queues(struct nvmf_ctrl_options *opts) int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val); int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val); int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val); +int nvmf_subsystem_reset(struct nvme_ctrl *ctrl); int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl); int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid); int nvmf_register_transport(struct nvmf_transport_ops *ops); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index abf6d028ef96..4fdb62ae996b 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3349,6 +3349,7 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = { .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, + .subsystem_reset = nvmf_subsystem_reset, .free_ctrl = nvme_fc_free_ctrl, .submit_async_event = nvme_fc_submit_async_event, .delete_ctrl = nvme_fc_delete_ctrl, diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index a5031f61304c..30eac70c19fd 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -569,6 +569,7 @@ struct nvme_ctrl_ops { int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val); void (*free_ctrl)(struct nvme_ctrl *ctrl); void (*submit_async_event)(struct nvme_ctrl *ctrl); + int (*subsystem_reset)(struct nvme_ctrl *ctrl); void (*delete_ctrl)(struct nvme_ctrl *ctrl); void (*stop_ctrl)(struct nvme_ctrl *ctrl); int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); @@ -667,18 +668,9 @@ int nvme_try_sched_reset(struct nvme_ctrl *ctrl); static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) { - int ret; - - if (!ctrl->subsystem) + if (!ctrl->subsystem || !ctrl->ops->subsystem_reset) return -ENOTTY; - if (!nvme_wait_reset(ctrl)) - return -EBUSY; - - ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); - if (ret) - return ret; - - return nvme_try_sched_reset(ctrl); + return ctrl->ops->subsystem_reset(ctrl); } /* diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index b20965a0247b..452c8d5f4f7c 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1171,6 +1171,41 @@ static void nvme_pci_submit_async_event(struct nvme_ctrl *ctrl) spin_unlock(&nvmeq->sq_lock); } +static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl) +{ + struct nvme_dev *dev = to_nvme_dev(ctrl); + int ret = 0; + + /* + * Taking the shutdown_lock ensures the BAR mapping is not being + * altered by reset_work. Holding this lock before the RESETTING state + * change, if successful, also ensures nvme_remove won't be able to + * proceed to iounmap until we're done. + */ + mutex_lock(&dev->shutdown_lock); + if (!dev->bar_mapped_size) { + ret = -ENODEV; + goto unlock; + } + + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) { + ret = -EBUSY; + goto unlock; + } + + writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); + nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); + + /* + * Read controller status to flush the previous write and trigger a + * pcie read error. + */ + readl(dev->bar + NVME_REG_CSTS); +unlock: + mutex_unlock(&dev->shutdown_lock); + return ret; +} + static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) { struct nvme_command c = { }; @@ -3010,6 +3045,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = { .reg_read64 = nvme_pci_reg_read64, .free_ctrl = nvme_pci_free_ctrl, .submit_async_event = nvme_pci_submit_async_event, + .subsystem_reset = nvme_pci_subsystem_reset, .get_address = nvme_pci_get_address, .print_device_info = nvme_pci_print_device_info, .supports_pci_p2pdma = nvme_pci_supports_pci_p2pdma, diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 395bb6d31a2b..418329a8ac47 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -2174,6 +2174,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = { .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, + .subsystem_reset = nvmf_subsystem_reset, .free_ctrl = nvme_rdma_free_ctrl, .submit_async_event = nvme_rdma_submit_async_event, .delete_ctrl = nvme_rdma_delete_ctrl, diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index e08b5823e13d..d08db81d24bc 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2600,6 +2600,7 @@ static const struct nvme_ctrl_ops nvme_tcp_ctrl_ops = { .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, + .subsystem_reset = nvmf_subsystem_reset, .free_ctrl = nvme_tcp_free_ctrl, .submit_async_event = nvme_tcp_submit_async_event, .delete_ctrl = nvme_tcp_delete_ctrl, diff --git a/include/linux/nvme.h b/include/linux/nvme.h index c93599e8d642..e2fd1912bed2 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -28,6 +28,9 @@ #define NVME_NSID_ALL 0xffffffff +/* Special NSSR value, 'NVMe' */ +#define NVME_SUBSYS_RESET 0x4E564D65 + enum nvme_subsys_type { /* Referral to another discovery type target subsystem */ NVME_NQN_DISC = 1, -- Gitee From 8e3304cb86824986369839532179c1a8fde546d5 Mon Sep 17 00:00:00 2001 From: Nilay Shroff Date: Wed, 21 Jan 2026 10:52:28 +0800 Subject: [PATCH 1226/1449] nvme: fix PCIe subsystem reset controller state transition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d89f3037d54d3a0d5902aa1b962ad9a594f22993 stable. commit 0edb475ac0a7d153318a24d4dca175a270a5cc4f upstream. The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”) disallows controller state transitions directly from RESETTING to LIVE. However, the NVMe PCIe subsystem reset path relies on this transition to recover the controller on PowerPC (PPC) systems. On PPC systems, issuing a subsystem reset causes a temporary loss of communication with the NVMe adapter. A subsequent PCIe MMIO read then triggers EEH recovery, which restores the PCIe link and brings the controller back online. For EEH recovery to proceed correctly, the controller must transition back to the LIVE state. Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”), the controller can no longer transition directly from RESETTING to LIVE. As a result, EEH recovery exits prematurely, leaving the controller stuck in the RESETTING state. Fix this by explicitly transitioning the controller state from RESETTING to CONNECTING and then to LIVE. This satisfies the updated state transition rules and allows the controller to be successfully recovered on PPC systems following a PCIe subsystem reset. Cc: stable@vger.kernel.org Fixes: d2fe192348f9 ("nvme: only allow entering LIVE from CONNECTING state") Reviewed-by: Daniel Wagner Signed-off-by: Nilay Shroff Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 452c8d5f4f7c..8d249d9d6386 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1194,7 +1194,10 @@ static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl) } writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); - nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); + + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) || + !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) + goto unlock; /* * Read controller status to flush the previous write and trigger a -- Gitee From 21a9be2d50fcbab4ddb04e3558781679790960ae Mon Sep 17 00:00:00 2001 From: Maninder Singh Date: Wed, 21 Jan 2026 12:16:18 +0800 Subject: [PATCH 1227/1449] NFSD: fix race between nfsd registration and exports_proc ANBZ: #35228 commit 8120e420013d947c890f358f30a2d98ba8ac20bc stable. commit f7fb730cac9aafda8b9813b55d04e28a9664d17c upstream. As of now nfsd calls create_proc_exports_entry() at start of init_nfsd and cleanup by remove_proc_entry() at last of exit_nfsd. Which causes kernel OOPs if there is race between below 2 operations: (i) exportfs -r (ii) mount -t nfsd none /proc/fs/nfsd for 5.4 kernel ARM64: CPU 1: el1_irq+0xbc/0x180 arch_counter_get_cntvct+0x14/0x18 running_clock+0xc/0x18 preempt_count_add+0x88/0x110 prep_new_page+0xb0/0x220 get_page_from_freelist+0x2d8/0x1778 __alloc_pages_nodemask+0x15c/0xef0 __vmalloc_node_range+0x28c/0x478 __vmalloc_node_flags_caller+0x8c/0xb0 kvmalloc_node+0x88/0xe0 nfsd_init_net+0x6c/0x108 [nfsd] ops_init+0x44/0x170 register_pernet_operations+0x114/0x270 register_pernet_subsys+0x34/0x50 init_nfsd+0xa8/0x718 [nfsd] do_one_initcall+0x54/0x2e0 CPU 2 : Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 PC is at : exports_net_open+0x50/0x68 [nfsd] Call trace: exports_net_open+0x50/0x68 [nfsd] exports_proc_open+0x2c/0x38 [nfsd] proc_reg_open+0xb8/0x198 do_dentry_open+0x1c4/0x418 vfs_open+0x38/0x48 path_openat+0x28c/0xf18 do_filp_open+0x70/0xe8 do_sys_open+0x154/0x248 Sometimes it crashes at exports_net_open() and sometimes cache_seq_next_rcu(). and same is happening on latest 6.14 kernel as well: [ 0.000000] Linux version 6.14.0-rc5-next-20250304-dirty ... [ 285.455918] Unable to handle kernel paging request at virtual address 00001f4800001f48 ... [ 285.464902] pc : cache_seq_next_rcu+0x78/0xa4 ... [ 285.469695] Call trace: [ 285.470083] cache_seq_next_rcu+0x78/0xa4 (P) [ 285.470488] seq_read+0xe0/0x11c [ 285.470675] proc_reg_read+0x9c/0xf0 [ 285.470874] vfs_read+0xc4/0x2fc [ 285.471057] ksys_read+0x6c/0xf4 [ 285.471231] __arm64_sys_read+0x1c/0x28 [ 285.471428] invoke_syscall+0x44/0x100 [ 285.471633] el0_svc_common.constprop.0+0x40/0xe0 [ 285.471870] do_el0_svc_compat+0x1c/0x34 [ 285.472073] el0_svc_compat+0x2c/0x80 [ 285.472265] el0t_32_sync_handler+0x90/0x140 [ 285.472473] el0t_32_sync+0x19c/0x1a0 [ 285.472887] Code: f9400885 93407c23 937d7c27 11000421 (f86378a3) [ 285.473422] ---[ end trace 0000000000000000 ]--- It reproduced simply with below script: while [ 1 ] do /exportfs -r done & while [ 1 ] do insmod /nfsd.ko mount -t nfsd none /proc/fs/nfsd umount /proc/fs/nfsd rmmod nfsd done & So exporting interfaces to user space shall be done at last and cleanup at first place. With change there is no Kernel OOPs. Co-developed-by: Shubham Rana Signed-off-by: Shubham Rana Signed-off-by: Maninder Singh Reviewed-by: Jeff Layton Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever [ The context change is due to the commit bd9d6a3efa97 ("NFSD: add rpc_status netlink support") and the proper adoption is done. ] Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/nfsctl.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 185994185fac..78ebdf20c1ef 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1582,12 +1582,9 @@ static int __init init_nfsd(void) if (retval) goto out_free_pnfs; nfsd_lockd_init(); /* lockd->nfsd callbacks */ - retval = create_proc_exports_entry(); - if (retval) - goto out_free_lockd; retval = register_pernet_subsys(&nfsd_net_ops); if (retval < 0) - goto out_free_exports; + goto out_free_lockd; retval = register_cld_notifier(); if (retval) goto out_free_subsys; @@ -1595,18 +1592,20 @@ static int __init init_nfsd(void) if (retval) goto out_free_cld; retval = register_filesystem(&nfsd_fs_type); + if (retval) + goto out_free_nfsd4; + retval = create_proc_exports_entry(); if (retval) goto out_free_all; return 0; out_free_all: + unregister_filesystem(&nfsd_fs_type); +out_free_nfsd4: nfsd4_destroy_laundry_wq(); out_free_cld: unregister_cld_notifier(); out_free_subsys: unregister_pernet_subsys(&nfsd_net_ops); -out_free_exports: - remove_proc_entry("fs/nfs/exports", NULL); - remove_proc_entry("fs/nfs", NULL); out_free_lockd: nfsd_lockd_shutdown(); nfsd_drc_slab_free(); @@ -1619,13 +1618,13 @@ static int __init init_nfsd(void) static void __exit exit_nfsd(void) { + remove_proc_entry("fs/nfs/exports", NULL); + remove_proc_entry("fs/nfs", NULL); unregister_filesystem(&nfsd_fs_type); nfsd4_destroy_laundry_wq(); unregister_cld_notifier(); unregister_pernet_subsys(&nfsd_net_ops); nfsd_drc_slab_free(); - remove_proc_entry("fs/nfs/exports", NULL); - remove_proc_entry("fs/nfs", NULL); nfsd_lockd_shutdown(); nfsd4_free_slabs(); nfsd4_exit_pnfs(); -- Gitee From ddff312b6697447b1b266025ef902b4110042727 Mon Sep 17 00:00:00 2001 From: Zqiang Date: Wed, 21 Jan 2026 14:51:59 +0800 Subject: [PATCH 1228/1449] usbnet: Fix using smp_processor_id() in preemptible code warnings ANBZ: #35228 commit 17fbad93879e87a334062882b45fa727ba1b3dd7 stable. commit 327cd4b68b4398b6c24f10eb2b2533ffbfc10185 upstream. Syzbot reported the following warning: BUG: using smp_processor_id() in preemptible [00000000] code: dhcpcd/2879 caller is usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331 CPU: 1 UID: 0 PID: 2879 Comm: dhcpcd Not tainted 6.15.0-rc4-syzkaller-00098-g615dca38c2ea #0 PREEMPT(voluntary) Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120 check_preemption_disabled+0xd0/0xe0 lib/smp_processor_id.c:49 usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331 usbnet_resume_rx+0x4b/0x170 drivers/net/usb/usbnet.c:708 usbnet_change_mtu+0x1be/0x220 drivers/net/usb/usbnet.c:417 __dev_set_mtu net/core/dev.c:9443 [inline] netif_set_mtu_ext+0x369/0x5c0 net/core/dev.c:9496 netif_set_mtu+0xb0/0x160 net/core/dev.c:9520 dev_set_mtu+0xae/0x170 net/core/dev_api.c:247 dev_ifsioc+0xa31/0x18d0 net/core/dev_ioctl.c:572 dev_ioctl+0x223/0x10e0 net/core/dev_ioctl.c:821 sock_do_ioctl+0x19d/0x280 net/socket.c:1204 sock_ioctl+0x42f/0x6a0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:906 [inline] __se_sys_ioctl fs/ioctl.c:892 [inline] __x64_sys_ioctl+0x190/0x200 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f For historical and portability reasons, the netif_rx() is usually run in the softirq or interrupt context, this commit therefore add local_bh_disable/enable() protection in the usbnet_resume_rx(). Fixes: 43daa96b166c ("usbnet: Stop RX Q on MTU change") Link: https://syzkaller.appspot.com/bug?id=81f55dfa587ee544baaaa5a359a060512228c1e1 Suggested-by: Jakub Kicinski Signed-off-by: Zqiang Link: https://patch.msgid.link/20251011070518.7095-1-qiang.zhang@linux.dev Signed-off-by: Paolo Abeni [ The context change is due to the commit 2c04d279e857 ("net: usb: Convert tasklet API to new bottom half workqueue mechanism") in v6.17 which is irrelevant to the logic of this patch.] Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/usbnet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index e41649365eff..a26a7435d84b 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -702,6 +702,7 @@ void usbnet_resume_rx(struct usbnet *dev) struct sk_buff *skb; int num = 0; + local_bh_disable(); clear_bit(EVENT_RX_PAUSED, &dev->flags); while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) { @@ -710,6 +711,7 @@ void usbnet_resume_rx(struct usbnet *dev) } tasklet_schedule(&dev->bh); + local_bh_enable(); netif_dbg(dev, rx_status, dev->net, "paused rx queue disabled, %d skbs requeued\n", num); -- Gitee From ec4d30715b997d8ce46386369c995f8cb7fddea7 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Tue, 27 Jan 2026 16:31:49 +0800 Subject: [PATCH 1229/1449] ksmbd: fix use-after-free in ksmbd_session_rpc_open ANBZ: #35228 commit 1067361a1cc6ad9cdf7acfc47f90012b72ad1502 stable. commit a1f46c99d9ea411f9bf30025b912d881d36fc709 upstream. A UAF issue can occur due to a race condition between ksmbd_session_rpc_open() and __session_rpc_close(). Add rpc_lock to the session to protect it. Cc: stable@vger.kernel.org Reported-by: Norbert Szetei Tested-by: Norbert Szetei Signed-off-by: Namjae Jeon Signed-off-by: Steve French [ KSMBD_DEFAULT_GFP is introduced by commit 0066f623bce8 ("ksmbd: use __GFP_RETRY_MAYFAIL") after linux-6.13. Here we still use GFP_KERNEL. ] Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/mgmt/user_session.c | 20 ++++++++++++++------ fs/smb/server/mgmt/user_session.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 0ca788009c93..450a9f8ca7c7 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -59,10 +59,12 @@ static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess) struct ksmbd_session_rpc *entry; long index; + down_write(&sess->rpc_lock); xa_for_each(&sess->rpc_handle_list, index, entry) { xa_erase(&sess->rpc_handle_list, index); __session_rpc_close(sess, entry); } + up_write(&sess->rpc_lock); xa_destroy(&sess->rpc_handle_list); } @@ -92,7 +94,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) { struct ksmbd_session_rpc *entry, *old; struct ksmbd_rpc_command *resp; - int method; + int method, id; method = __rpc_method(rpc_name); if (!method) @@ -102,26 +104,29 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) if (!entry) return -ENOMEM; + down_read(&sess->rpc_lock); entry->method = method; - entry->id = ksmbd_ipc_id_alloc(); - if (entry->id < 0) + entry->id = id = ksmbd_ipc_id_alloc(); + if (id < 0) goto free_entry; - old = xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL); + old = xa_store(&sess->rpc_handle_list, id, entry, GFP_KERNEL); if (xa_is_err(old)) goto free_id; - resp = ksmbd_rpc_open(sess, entry->id); + resp = ksmbd_rpc_open(sess, id); if (!resp) goto erase_xa; + up_read(&sess->rpc_lock); kvfree(resp); - return entry->id; + return id; erase_xa: xa_erase(&sess->rpc_handle_list, entry->id); free_id: ksmbd_rpc_id_free(entry->id); free_entry: kfree(entry); + up_read(&sess->rpc_lock); return -EINVAL; } @@ -129,9 +134,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id) { struct ksmbd_session_rpc *entry; + down_write(&sess->rpc_lock); entry = xa_erase(&sess->rpc_handle_list, id); if (entry) __session_rpc_close(sess, entry); + up_write(&sess->rpc_lock); } int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) @@ -438,6 +445,7 @@ static struct ksmbd_session *__session_create(int protocol) sess->sequence_number = 1; rwlock_init(&sess->tree_conns_lock); atomic_set(&sess->refcnt, 2); + init_rwsem(&sess->rpc_lock); ret = __init_smb2_session(sess); if (ret) diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h index f21348381d59..c5749d6ec715 100644 --- a/fs/smb/server/mgmt/user_session.h +++ b/fs/smb/server/mgmt/user_session.h @@ -63,6 +63,7 @@ struct ksmbd_session { rwlock_t tree_conns_lock; atomic_t refcnt; + struct rw_semaphore rpc_lock; }; static inline int test_session_flag(struct ksmbd_session *sess, int bit) -- Gitee From 70add26dc853d58fe8f1153ac68b625c8bc3a711 Mon Sep 17 00:00:00 2001 From: Bartlomiej Kubik Date: Fri, 23 Jan 2026 14:57:53 +0800 Subject: [PATCH 1230/1449] fs/ntfs3: Initialize allocated memory before use ANBZ: #35228 commit 7d52c592cf53f5bb7163967edc01d2d7d80de44a stable. commit a8a3ca23bbd9d849308a7921a049330dc6c91398 upstream. KMSAN reports: Multiple uninitialized values detected: - KMSAN: uninit-value in ntfs_read_hdr (3) - KMSAN: uninit-value in bcmp (3) Memory is allocated by __getname(), which is a wrapper for kmem_cache_alloc(). This memory is used before being properly cleared. Change kmem_cache_alloc() to kmem_cache_zalloc() to properly allocate and clear memory before use. Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations") Tested-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=332bd4e9d148f11a87dc Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations") Tested-by: syzbot+0399100e525dd9696764@syzkaller.appspotmail.com Reported-by: syzbot+0399100e525dd9696764@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=0399100e525dd9696764 Reviewed-by: Khalid Aziz Signed-off-by: Bartlomiej Kubik Signed-off-by: Konstantin Komarov Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/ntfs3/inode.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 3da73f716dda..a0693a44e65c 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -1289,7 +1289,7 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, fa |= FILE_ATTRIBUTE_READONLY; /* Allocate PATH_MAX bytes. */ - new_de = __getname(); + new_de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); if (!new_de) { err = -ENOMEM; goto out1; @@ -1718,10 +1718,9 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) struct NTFS_DE *de; /* Allocate PATH_MAX bytes. */ - de = __getname(); + de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); if (!de) return -ENOMEM; - memset(de, 0, PATH_MAX); /* Mark rw ntfs as dirty. It will be cleared at umount. */ ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); @@ -1757,7 +1756,7 @@ int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry) return -EINVAL; /* Allocate PATH_MAX bytes. */ - de = __getname(); + de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); if (!de) return -ENOMEM; -- Gitee From 9a4e2e6f77ad549f9122f9fb1f89537351c1ab0a Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Wed, 28 Jan 2026 11:22:38 +0800 Subject: [PATCH 1231/1449] drm/amdgpu: csa unmap use uninterruptible lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 8d2979b9bb1be0f4a52dff600e56d780403e04ac stable. commit a0fa7873f2f869087b1e7793f7fac3713a1e3afe upstream. After process exit to unmap csa and free GPU vm, if signal is accepted and then waiting to take vm lock is interrupted and return, it causes memory leaking and below warning backtrace. Change to use uninterruptible wait lock fix the issue. WARNING: CPU: 69 PID: 167800 at amd/amdgpu/amdgpu_kms.c:1525 amdgpu_driver_postclose_kms+0x294/0x2a0 [amdgpu] Call Trace: drm_file_free.part.0+0x1da/0x230 [drm] drm_close_helper.isra.0+0x65/0x70 [drm] drm_release+0x6a/0x120 [drm] amdgpu_drm_release+0x51/0x60 [amdgpu] __fput+0x9f/0x280 ____fput+0xe/0x20 task_work_run+0x67/0xa0 do_exit+0x217/0x3c0 do_group_exit+0x3b/0xb0 get_signal+0x14a/0x8d0 arch_do_signal_or_restart+0xde/0x100 exit_to_user_mode_loop+0xc1/0x1a0 exit_to_user_mode_prepare+0xf4/0x100 syscall_exit_to_user_mode+0x17/0x40 do_syscall_64+0x69/0xc0 Signed-off-by: Philip Yang Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit 7dbbfb3c171a6f63b01165958629c9c26abf38ab) Cc: stable@vger.kernel.org [The third parameter of drm_exec_init() was introduced by commit 05d249352f1a ("drm/exec: Pass in initial # of objects") after Linux 6.8. This code targets linux 6.6, so the current implementation is used and the third parameter is not needed.] Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c index 720011019741..bff44fc21e8b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c @@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct drm_exec exec; int r; - drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); + drm_exec_init(&exec, 0); drm_exec_until_all_locked(&exec) { r = amdgpu_vm_lock_pd(vm, &exec, 0); if (likely(!r)) -- Gitee From 569384892c156f15cd0273f5bf876372a5ec296e Mon Sep 17 00:00:00 2001 From: P Praneesh Date: Wed, 28 Jan 2026 11:27:15 +0800 Subject: [PATCH 1232/1449] wifi: ath11k: fix RCU stall while reaping monitor destination ring ANBZ: #35228 commit 8db5de0cf02fccf4c759aa58edbe65659daf607c stable. commit 16c6c35c03ea73054a1f6d3302a4ce4a331b427d upstream. While processing the monitor destination ring, MSDUs are reaped from the link descriptor based on the corresponding buf_id. However, sometimes the driver cannot obtain a valid buffer corresponding to the buf_id received from the hardware. This causes an infinite loop in the destination processing, resulting in a kernel crash. kernel log: ath11k_pci 0000:58:00.0: data msdu_pop: invalid buf_id 309 ath11k_pci 0000:58:00.0: data dp_rx_monitor_link_desc_return failed ath11k_pci 0000:58:00.0: data msdu_pop: invalid buf_id 309 ath11k_pci 0000:58:00.0: data dp_rx_monitor_link_desc_return failed Fix this by skipping the problematic buf_id and reaping the next entry, replacing the break with the next MSDU processing. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Signed-off-by: P Praneesh Signed-off-by: Kang Yang Acked-by: Kalle Valo Acked-by: Jeff Johnson Link: https://patch.msgid.link/20241219110531.2096-2-quic_kangyang@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/ath/ath11k/dp_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 8cc51ab699de..dc54ea16c12a 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -4728,7 +4728,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k *ar, int mac_id, if (!msdu) { ath11k_dbg(ar->ab, ATH11K_DBG_DATA, "msdu_pop: invalid buf_id %d\n", buf_id); - break; + goto next_msdu; } rxcb = ATH11K_SKB_RXCB(msdu); if (!rxcb->unmapped) { @@ -5362,7 +5362,7 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct ath11k *ar, "full mon msdu_pop: invalid buf_id %d\n", buf_id); spin_unlock_bh(&rx_ring->idr_lock); - break; + goto next_msdu; } idr_remove(&rx_ring->bufs_idr, buf_id); spin_unlock_bh(&rx_ring->idr_lock); -- Gitee From 077b42aa6bfb98910f9c4bef33cd7a59a43dd595 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Mon, 19 Jan 2026 23:28:25 +0800 Subject: [PATCH 1233/1449] x86/fpu: Clear XSTATE_BV[i] in guest XSAVE state whenever XFD[i]=1 ANBZ: #35228 commit 1e2848bda819af569dfe7ab186223855e092a2cb stable. commit b45f721775947a84996deb5c661602254ce25ce6 upstream. When loading guest XSAVE state via KVM_SET_XSAVE, and when updating XFD in response to a guest WRMSR, clear XFD-disabled features in the saved (or to be restored) XSTATE_BV to ensure KVM doesn't attempt to load state for features that are disabled via the guest's XFD. Because the kernel executes XRSTOR with the guest's XFD, saving XSTATE_BV[i]=1 with XFD[i]=1 will cause XRSTOR to #NM and panic the kernel. E.g. if fpu_update_guest_xfd() sets XFD without clearing XSTATE_BV: ------------[ cut here ]------------ WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#29: amx_test/848 Modules linked in: kvm_intel kvm irqbypass CPU: 29 UID: 1000 PID: 848 Comm: amx_test Not tainted 6.19.0-rc2-ffa07f7fd437-x86_amx_nm_xfd_non_init-vm #171 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:exc_device_not_available+0x101/0x110 Call Trace: asm_exc_device_not_available+0x1a/0x20 RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90 switch_fpu_return+0x4a/0xb0 kvm_arch_vcpu_ioctl_run+0x1245/0x1e40 [kvm] kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm] __x64_sys_ioctl+0x8f/0xd0 do_syscall_64+0x62/0x940 entry_SYSCALL_64_after_hwframe+0x4b/0x53 ---[ end trace 0000000000000000 ]--- This can happen if the guest executes WRMSR(MSR_IA32_XFD) to set XFD[18] = 1, and a host IRQ triggers kernel_fpu_begin() prior to the vmexit handler's call to fpu_update_guest_xfd(). and if userspace stuffs XSTATE_BV[i]=1 via KVM_SET_XSAVE: ------------[ cut here ]------------ WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#14: amx_test/867 Modules linked in: kvm_intel kvm irqbypass CPU: 14 UID: 1000 PID: 867 Comm: amx_test Not tainted 6.19.0-rc2-2dace9faccd6-x86_amx_nm_xfd_non_init-vm #168 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:exc_device_not_available+0x101/0x110 Call Trace: asm_exc_device_not_available+0x1a/0x20 RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90 fpu_swap_kvm_fpstate+0x6b/0x120 kvm_load_guest_fpu+0x30/0x80 [kvm] kvm_arch_vcpu_ioctl_run+0x85/0x1e40 [kvm] kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm] __x64_sys_ioctl+0x8f/0xd0 do_syscall_64+0x62/0x940 entry_SYSCALL_64_after_hwframe+0x4b/0x53 ---[ end trace 0000000000000000 ]--- The new behavior is consistent with the AMX architecture. Per Intel's SDM, XSAVE saves XSTATE_BV as '0' for components that are disabled via XFD (and non-compacted XSAVE saves the initial configuration of the state component): If XSAVE, XSAVEC, XSAVEOPT, or XSAVES is saving the state component i, the instruction does not generate #NM when XCR0[i] = IA32_XFD[i] = 1; instead, it operates as if XINUSE[i] = 0 (and the state component was in its initial state): it saves bit i of XSTATE_BV field of the XSAVE header as 0; in addition, XSAVE saves the initial configuration of the state component (the other instructions do not save state component i). Alternatively, KVM could always do XRSTOR with XFD=0, e.g. by using a constant XFD based on the set of enabled features when XSAVEing for a struct fpu_guest. However, having XSTATE_BV[i]=1 for XFD-disabled features can only happen in the above interrupt case, or in similar scenarios involving preemption on preemptible kernels, because fpu_swap_kvm_fpstate()'s call to save_fpregs_to_fpstate() saves the outgoing FPU state with the current XFD; and that is (on all but the first WRMSR to XFD) the guest XFD. Therefore, XFD can only go out of sync with XSTATE_BV in the above interrupt case, or in similar scenarios involving preemption on preemptible kernels, and it we can consider it (de facto) part of KVM ABI that KVM_GET_XSAVE returns XSTATE_BV[i]=0 for XFD-disabled features. Reported-by: Paolo Bonzini Cc: stable@vger.kernel.org Fixes: 820a6ee944e7 ("kvm: x86: Add emulation for IA32_XFD", 2022-01-14) Signed-off-by: Sean Christopherson [Move clearing of XSTATE_BV from fpu_copy_uabi_to_guest_fpstate to kvm_vcpu_ioctl_x86_set_xsave. - Paolo] Reviewed-by: Binbin Wu Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/kernel/fpu/core.c | 32 +++++++++++++++++++++++++++++--- arch/x86/kvm/x86.c | 9 +++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 5ead758b743e..09b46f100961 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -296,10 +296,29 @@ EXPORT_SYMBOL_GPL(fpu_enable_guest_xfd_features); #ifdef CONFIG_X86_64 void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd) { + struct fpstate *fpstate = guest_fpu->fpstate; + fpregs_lock(); - guest_fpu->fpstate->xfd = xfd; - if (guest_fpu->fpstate->in_use) - xfd_update_state(guest_fpu->fpstate); + + /* + * KVM's guest ABI is that setting XFD[i]=1 *can* immediately revert the + * save state to its initial configuration. Likewise, KVM_GET_XSAVE does + * the same as XSAVE and returns XSTATE_BV[i]=0 whenever XFD[i]=1. + * + * If the guest's FPU state is in hardware, just update XFD: the XSAVE + * in fpu_swap_kvm_fpstate will clear XSTATE_BV[i] whenever XFD[i]=1. + * + * If however the guest's FPU state is NOT resident in hardware, clear + * disabled components in XSTATE_BV now, or a subsequent XRSTOR will + * attempt to load disabled components and generate #NM _in the host_. + */ + if (xfd && test_thread_flag(TIF_NEED_FPU_LOAD)) + fpstate->regs.xsave.header.xfeatures &= ~xfd; + + fpstate->xfd = xfd; + if (fpstate->in_use) + xfd_update_state(fpstate); + fpregs_unlock(); } EXPORT_SYMBOL_GPL(fpu_update_guest_xfd); @@ -407,6 +426,13 @@ int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf, if (ustate->xsave.header.xfeatures & ~xcr0) return -EINVAL; + /* + * Disabled features must be in their initial state, otherwise XRSTOR + * causes an exception. + */ + if (WARN_ON_ONCE(ustate->xsave.header.xfeatures & kstate->xfd)) + return -EINVAL; + /* * Nullify @vpkru to preserve its current value if PKRU's bit isn't set * in the header. KVM's odd ABI is to leave PKRU untouched in this diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4679ed2c8c5e..5edbec1e8be3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5467,9 +5467,18 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, struct kvm_xsave *guest_xsave) { + union fpregs_state *xstate = (union fpregs_state *)guest_xsave->region; + if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) return 0; + /* + * For backwards compatibility, do not expect disabled features to be in + * their initial state. XSTATE_BV[i] must still be cleared whenever + * XFD[i]=1, or XRSTOR would cause a #NM. + */ + xstate->xsave.header.xfeatures &= ~vcpu->arch.guest_fpu.fpstate->xfd; + return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu, guest_xsave->region, kvm_caps.supported_xcr0, -- Gitee From d91d60a339d3ac9fee36dec0bf6af01c1bd3d741 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 16 Jan 2026 14:53:32 +0800 Subject: [PATCH 1234/1449] net: phy: move phy_link_change() prior to mdio_bus_phy_may_suspend() ANBZ: #35228 commit b5a933535cc34084f28c106cbfaab9b950959b81 stable. commit f40a673d6b4a128fe95dd9b8c3ed02da50a6a862 upstream. In an upcoming change, mdio_bus_phy_may_suspend() will need to distinguish a phylib-based PHY client from a phylink PHY client. For that, it will need to compare the phydev->phy_link_change() function pointer with the eponymous phy_link_change() provided by phylib. To avoid forward function declarations, the default PHY link state change method should be moved upwards. There is no functional change associated with this patch, it is only to reduce the noise from a real bug fix. Signed-off-by: Vladimir Oltean Reviewed-by: Russell King (Oracle) Link: https://patch.msgid.link/20250407093900.2155112-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski [ Minor context change fixed ] Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/phy_device.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 875788918bcb..2c4af6f96390 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -268,6 +268,19 @@ static struct phy_driver genphy_driver; static LIST_HEAD(phy_fixup_list); static DEFINE_MUTEX(phy_fixup_lock); +static void phy_link_change(struct phy_device *phydev, bool up) +{ + struct net_device *netdev = phydev->attached_dev; + + if (up) + netif_carrier_on(netdev); + else + netif_carrier_off(netdev); + phydev->adjust_link(netdev); + if (phydev->mii_ts && phydev->mii_ts->link_state) + phydev->mii_ts->link_state(phydev->mii_ts, phydev); +} + static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) { struct device_driver *drv = phydev->mdio.dev.driver; @@ -1069,19 +1082,6 @@ struct phy_device *phy_find_first(struct mii_bus *bus) } EXPORT_SYMBOL(phy_find_first); -static void phy_link_change(struct phy_device *phydev, bool up) -{ - struct net_device *netdev = phydev->attached_dev; - - if (up) - netif_carrier_on(netdev); - else - netif_carrier_off(netdev); - phydev->adjust_link(netdev); - if (phydev->mii_ts && phydev->mii_ts->link_state) - phydev->mii_ts->link_state(phydev->mii_ts, phydev); -} - /** * phy_prepare_link - prepares the PHY layer to monitor link status * @phydev: target phy_device struct -- Gitee From 596d4806d5092cbb8ff19961ea1a30fe5c655bbf Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 16 Jan 2026 14:53:33 +0800 Subject: [PATCH 1235/1449] net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY ANBZ: #35228 commit 043aa41c43f8cb9cce75367ea07895ce68b5abb0 stable. commit fc75ea20ffb452652f0d4033f38fe88d7cfdae35 upstream. DSA has 2 kinds of drivers: 1. Those who call dsa_switch_suspend() and dsa_switch_resume() from their device PM ops: qca8k-8xxx, bcm_sf2, microchip ksz 2. Those who don't: all others. The above methods should be optional. For type 1, dsa_switch_suspend() calls dsa_user_suspend() -> phylink_stop(), and dsa_switch_resume() calls dsa_user_resume() -> phylink_start(). These seem good candidates for setting mac_managed_pm = true because that is essentially its definition [1], but that does not seem to be the biggest problem for now, and is not what this change focuses on. Talking strictly about the 2nd category of DSA drivers here (which do not have MAC managed PM, meaning that for their attached PHYs, mdio_bus_phy_suspend() and mdio_bus_phy_resume() should run in full), I have noticed that the following warning from mdio_bus_phy_resume() is triggered: WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY && phydev->state != PHY_UP); because the PHY state machine is running. It's running as a result of a previous dsa_user_open() -> ... -> phylink_start() -> phy_start() having been initiated by the user. The previous mdio_bus_phy_suspend() was supposed to have called phy_stop_machine(), but it didn't. So this is why the PHY is in state PHY_NOLINK by the time mdio_bus_phy_resume() runs. mdio_bus_phy_suspend() did not call phy_stop_machine() because for phylink, the phydev->adjust_link function pointer is NULL. This seems a technicality introduced by commit fddd91016d16 ("phylib: fix PAL state machine restart on resume"). That commit was written before phylink existed, and was intended to avoid crashing with consumer drivers which don't use the PHY state machine - phylink always does, when using a PHY. But phylink itself has historically not been developed with suspend/resume in mind, and apparently not tested too much in that scenario, allowing this bug to exist unnoticed for so long. Plus, prior to the WARN_ON(), it would have likely been invisible. This issue is not in fact restricted to type 2 DSA drivers (according to the above ad-hoc classification), but can be extrapolated to any MAC driver with phylink and MDIO-bus-managed PHY PM ops. DSA is just where the issue was reported. Assuming mac_managed_pm is set correctly, a quick search indicates the following other drivers might be affected: $ grep -Zlr PHYLINK_NETDEV drivers/ | xargs -0 grep -L mac_managed_pm drivers/net/ethernet/atheros/ag71xx.c drivers/net/ethernet/microchip/sparx5/sparx5_main.c drivers/net/ethernet/microchip/lan966x/lan966x_main.c drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c drivers/net/ethernet/freescale/dpaa/dpaa_eth.c drivers/net/ethernet/freescale/ucc_geth.c drivers/net/ethernet/freescale/enetc/enetc_pf_common.c drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c drivers/net/ethernet/marvell/mvneta.c drivers/net/ethernet/marvell/prestera/prestera_main.c drivers/net/ethernet/mediatek/mtk_eth_soc.c drivers/net/ethernet/altera/altera_tse_main.c drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c drivers/net/ethernet/meta/fbnic/fbnic_phylink.c drivers/net/ethernet/tehuti/tn40_phy.c drivers/net/ethernet/mscc/ocelot_net.c Make the existing conditions dependent on the PHY device having a phydev->phy_link_change() implementation equal to the default phy_link_change() provided by phylib. Otherwise, we implicitly know that the phydev has the phylink-provided phylink_phy_change() callback, and when phylink is used, the PHY state machine always needs to be stopped/ started on the suspend/resume path. The code is structured as such that if phydev->phy_link_change() is absent, it is a matter of time until the kernel will crash - no need to further complicate the test. Thus, for the situation where the PM is not managed by the MAC, we will make the MDIO bus PM ops treat identically the phylink-controlled PHYs with the phylib-controlled PHYs where an adjust_link() callback is supplied. In both cases, the MDIO bus PM ops should stop and restart the PHY state machine. [1] https://lore.kernel.org/netdev/Z-1tiW9zjcoFkhwc@shell.armlinux.org.uk/ Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state") Reported-by: Wei Fang Tested-by: Wei Fang Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20250407094042.2155633-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/phy_device.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 2c4af6f96390..59f0f3a534e4 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -281,6 +281,33 @@ static void phy_link_change(struct phy_device *phydev, bool up) phydev->mii_ts->link_state(phydev->mii_ts, phydev); } +/** + * phy_uses_state_machine - test whether consumer driver uses PAL state machine + * @phydev: the target PHY device structure + * + * Ultimately, this aims to indirectly determine whether the PHY is attached + * to a consumer which uses the state machine by calling phy_start() and + * phy_stop(). + * + * When the PHY driver consumer uses phylib, it must have previously called + * phy_connect_direct() or one of its derivatives, so that phy_prepare_link() + * has set up a hook for monitoring state changes. + * + * When the PHY driver is used by the MAC driver consumer through phylink (the + * only other provider of a phy_link_change() method), using the PHY state + * machine is not optional. + * + * Return: true if consumer calls phy_start() and phy_stop(), false otherwise. + */ +static bool phy_uses_state_machine(struct phy_device *phydev) +{ + if (phydev->phy_link_change == phy_link_change) + return phydev->attached_dev && phydev->adjust_link; + + /* phydev->phy_link_change is implicitly phylink_phy_change() */ + return true; +} + static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) { struct device_driver *drv = phydev->mdio.dev.driver; @@ -341,7 +368,7 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev) * may call phy routines that try to grab the same lock, and that may * lead to a deadlock. */ - if (phydev->attached_dev && phydev->adjust_link) + if (phy_uses_state_machine(phydev)) phy_stop_machine(phydev); if (!mdio_bus_phy_may_suspend(phydev)) @@ -395,7 +422,7 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev) } } - if (phydev->attached_dev && phydev->adjust_link) + if (phy_uses_state_machine(phydev)) phy_start_machine(phydev); return 0; -- Gitee From 7f727d05bb062ba5b8e71eba353b3bcccc5883e6 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Fri, 16 Jan 2026 14:53:34 +0800 Subject: [PATCH 1236/1449] net: phy: fix phy_uses_state_machine() ANBZ: #35228 commit 96aa13ff68ef5501b2d879d9be73ebed72128510 stable. commit e0d1c55501d377163eb57feed863777ed1c973ad upstream. The blamed commit changed the conditions which phylib uses to stop and start the state machine in the suspend and resume paths, and while improving it, has caused two issues. The original code used this test: phydev->attached_dev && phydev->adjust_link and if true, the paths would handle the PHY state machine. This test evaluates true for normal drivers that are using phylib directly while the PHY is attached to the network device, but false in all other cases, which include the following cases: - when the PHY has never been attached to a network device. - when the PHY has been detached from a network device (as phy_detach() sets phydev->attached_dev to NULL, phy_disconnect() calls phy_detach() and additionally sets phydev->adjust_link NULL.) - when phylink is using the driver (as phydev->adjust_link is NULL.) Only the third case was incorrect, and the blamed commit attempted to fix this by changing this test to (simplified for brevity, see phy_uses_state_machine()): phydev->phy_link_change == phy_link_change ? phydev->attached_dev && phydev->adjust_link : true However, this also incorrectly evaluates true in the first two cases. Fix the first case by ensuring that phy_uses_state_machine() returns false when phydev->phy_link_change is NULL. Fix the second case by ensuring that phydev->phy_link_change is set to NULL when phy_detach() is called. Reported-by: Xu Yang Link: https://lore.kernel.org/r/20250806082931.3289134-1-xu.yang_2@nxp.com Fixes: fc75ea20ffb4 ("net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY") Signed-off-by: Russell King (Oracle) Reviewed-by: Vladimir Oltean Link: https://patch.msgid.link/E1uvMEz-00000003Aoe-3qWe@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/phy_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 59f0f3a534e4..3dd59376a89e 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -304,8 +304,7 @@ static bool phy_uses_state_machine(struct phy_device *phydev) if (phydev->phy_link_change == phy_link_change) return phydev->attached_dev && phydev->adjust_link; - /* phydev->phy_link_change is implicitly phylink_phy_change() */ - return true; + return !!phydev->phy_link_change; } static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) @@ -1853,6 +1852,8 @@ void phy_detach(struct phy_device *phydev) phydev->attached_dev->phydev = NULL; phydev->attached_dev = NULL; } + + phydev->phy_link_change = NULL; phydev->phylink = NULL; if (!phydev->is_on_sfp_module) -- Gitee From 33898e1f167327bb852da80012bf6f175081132b Mon Sep 17 00:00:00 2001 From: Jia-Hong Su Date: Sun, 18 Jan 2026 20:08:59 +0800 Subject: [PATCH 1237/1449] Bluetooth: hci_uart: fix null-ptr-deref in hci_uart_write_work ANBZ: #35228 commit 186d147cf7689ba1f9b3ddb753ab634a84940cc9 stable. commit 0c3cd7a0b862c37acbee6d9502107146cc944398 upstream. hci_uart_set_proto() sets HCI_UART_PROTO_INIT before calling hci_uart_register_dev(), which calls proto->open() to initialize hu->priv. However, if a TTY write wakeup occurs during this window, hci_uart_tx_wakeup() may schedule write_work before hu->priv is initialized, leading to a NULL pointer dereference in hci_uart_write_work() when proto->dequeue() accesses hu->priv. The race condition is: CPU0 CPU1 ---- ---- hci_uart_set_proto() set_bit(HCI_UART_PROTO_INIT) hci_uart_register_dev() tty write wakeup hci_uart_tty_wakeup() hci_uart_tx_wakeup() schedule_work(&hu->write_work) proto->open(hu) // initializes hu->priv hci_uart_write_work() hci_uart_dequeue() proto->dequeue(hu) // accesses hu->priv (NULL!) Fix this by moving set_bit(HCI_UART_PROTO_INIT) after proto->open() succeeds, ensuring hu->priv is initialized before any work can be scheduled. Fixes: 5df5dafc171b ("Bluetooth: hci_uart: Fix another race during initialization") Link: https://lore.kernel.org/linux-bluetooth/6969764f.170a0220.2b9fc4.35a7@mx.google.com/ Signed-off-by: Jia-Hong Su Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bluetooth/hci_ldisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 70320b8f1aa1..e38f3c4458c9 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -682,6 +682,8 @@ static int hci_uart_register_dev(struct hci_uart *hu) return err; } + set_bit(HCI_UART_PROTO_INIT, &hu->flags); + if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) return 0; @@ -709,8 +711,6 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) hu->proto = p; - set_bit(HCI_UART_PROTO_INIT, &hu->flags); - err = hci_uart_register_dev(hu); if (err) { return err; -- Gitee From 90f28d2facc1bd53a883b7c956279b339fc92292 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Tue, 20 Jan 2026 21:46:40 +0800 Subject: [PATCH 1238/1449] net/mlx5: Fix memory leak in esw_acl_ingress_lgcy_setup() ANBZ: #35228 commit dc5d1eb935be012352af5ab8b11c80eecf3739cb stable. commit 108948f723b13874b7ebf6b3f1cc598a7de38622 upstream. In esw_acl_ingress_lgcy_setup(), if esw_acl_table_create() fails, the function returns directly without releasing the previously created counter, leading to a memory leak. Fix this by jumping to the out label instead of returning directly, which aligns with the error handling logic of other paths in this function. Compile tested only. Issue found using a prototype static analysis tool and code review. Fixes: 07bab9502641 ("net/mlx5: E-Switch, Refactor eswitch ingress acl codes") Signed-off-by: Zilin Guan Reviewed-by: Tariq Toukan Link: https://patch.msgid.link/20260120134640.2717808-1-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c index 093ed86a0acd..db51c500ed35 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c @@ -188,7 +188,7 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, if (IS_ERR(vport->ingress.acl)) { err = PTR_ERR(vport->ingress.acl); vport->ingress.acl = NULL; - return err; + goto out; } err = esw_acl_ingress_lgcy_groups_create(esw, vport); -- Gitee From 07182547d7e71af58fa228a279b234a0701ec3df Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 20 Jan 2026 17:40:22 +0800 Subject: [PATCH 1239/1449] can: gs_usb: gs_usb_receive_bulk_callback(): fix error message ANBZ: #35228 commit 923379f1d7e3af8ccbf11edbbcf41f1bb3e9cfe6 stable. commit 494fc029f662c331e06b7c2031deff3c64200eed upstream. Sinc commit 79a6d1bfe114 ("can: gs_usb: gs_usb_receive_bulk_callback(): unanchor URL on usb_submit_urb() error") a failing resubmit URB will print an info message. In the case of a short read where netdev has not yet been assigned, initialize as NULL to avoid dereferencing an undefined value. Also report the error value of the failed resubmit. Fixes: 79a6d1bfe114 ("can: gs_usb: gs_usb_receive_bulk_callback(): unanchor URL on usb_submit_urb() error") Reported-by: Jakub Kicinski Closes: https://lore.kernel.org/all/20260119181904.1209979-1-kuba@kernel.org/ Link: https://patch.msgid.link/20260120-gs_usb-fix-error-message-v1-1-6be04de572bc@pengutronix.de Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/can/usb/gs_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 63439affd59d..7a3c6493a353 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -607,7 +607,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) { struct gs_usb *parent = urb->context; struct gs_can *dev; - struct net_device *netdev; + struct net_device *netdev = NULL; int rc; struct net_device_stats *stats; struct gs_host_frame *hf = urb->transfer_buffer; @@ -765,7 +765,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) } } else if (rc != -ESHUTDOWN && net_ratelimit()) { netdev_info(netdev, "failed to re-submit IN URB: %pe\n", - ERR_PTR(urb->status)); + ERR_PTR(rc)); } } -- Gitee From 384eb2c197857645daa16105d81ecb83f4a9a6a3 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Fri, 23 Jan 2026 03:40:01 +0800 Subject: [PATCH 1240/1449] net: bcmasp: fix early exit leak with fixed phy ANBZ: #35228 commit 724c9d346a3ac16fd0421f3e9e2a091a1135cbb6 stable. commit 6de4436bf369e1444606445e4cd5df5bcfc74b48 upstream. We are not deregistering the fixed phy link when hitting the early exit condition. Add the correct early exit sequence. Fixes: 490cb412007d ("net: bcmasp: Add support for ASP2.0 Ethernet controller") Signed-off-by: Justin Chen Reviewed-by: Florian Fainelli Link: https://patch.msgid.link/20260122194001.1098859-1-justin.chen@broadcom.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c index f0647286c68b..3127f335e0b7 100644 --- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c +++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c @@ -1272,7 +1272,7 @@ struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv, netdev_err(intf->ndev, "invalid PHY mode: %s for port %d\n", phy_modes(intf->phy_interface), intf->port); ret = -EINVAL; - goto err_free_netdev; + goto err_deregister_fixed_link; } ret = of_get_ethdev_address(ndev_dn, ndev); @@ -1295,6 +1295,9 @@ struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv, return intf; +err_deregister_fixed_link: + if (of_phy_is_fixed_link(ndev_dn)) + of_phy_deregister_fixed_link(ndev_dn); err_free_netdev: free_netdev(ndev); err: -- Gitee From 865d69cb5313e3c8d43b7471ffbfdfd9c6219712 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 21 Jan 2026 21:05:51 +0800 Subject: [PATCH 1241/1449] octeon_ep: Fix memory leak in octep_device_setup() ANBZ: #35228 commit 5058d3f8f17202e673f90af1446252322bd0850f stable. commit 8016dc5ee19a77678c264f8ba368b1e873fa705b upstream. In octep_device_setup(), if octep_ctrl_net_init() fails, the function returns directly without unmapping the mapped resources and freeing the allocated configuration memory. Fix this by jumping to the unsupported_dev label, which performs the necessary cleanup. This aligns with the error handling logic of other paths in this function. Compile tested only. Issue found using a prototype static analysis tool and code review. Fixes: 577f0d1b1c5f ("octeon_ep: add separate mailbox command and response queues") Signed-off-by: Zilin Guan Reviewed-by: Vadim Fedorenko Link: https://patch.msgid.link/20260121130551.3717090-1-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/marvell/octeon_ep/octep_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c index 7a30095b3486..c38508454663 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c @@ -998,7 +998,7 @@ int octep_device_setup(struct octep_device *oct) ret = octep_ctrl_net_init(oct); if (ret) - return ret; + goto unsupported_dev; atomic_set(&oct->hb_miss_cnt, 0); INIT_DELAYED_WORK(&oct->hb_task, octep_hb_timeout_task); -- Gitee From ca6d7252671e81804729a1adc62c174fb84b9b88 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 23 Jan 2026 00:29:14 +0800 Subject: [PATCH 1242/1449] bonding: annotate data-races around slave->last_rx ANBZ: #35228 commit 8c0be3277e7aefb2f900fc37ca3fe7df362e26f5 stable. commit f6c3665b6dc53c3ab7d31b585446a953a74340ef upstream. slave->last_rx and slave->target_last_arp_rx[...] can be read and written locklessly. Add READ_ONCE() and WRITE_ONCE() annotations. syzbot reported: BUG: KCSAN: data-race in bond_rcv_validate / bond_rcv_validate write to 0xffff888149f0d428 of 8 bytes by interrupt on cpu 1: bond_rcv_validate+0x202/0x7a0 drivers/net/bonding/bond_main.c:3335 bond_handle_frame+0xde/0x5e0 drivers/net/bonding/bond_main.c:1533 __netif_receive_skb_core+0x5b1/0x1950 net/core/dev.c:6039 __netif_receive_skb_one_core net/core/dev.c:6150 [inline] __netif_receive_skb+0x59/0x270 net/core/dev.c:6265 netif_receive_skb_internal net/core/dev.c:6351 [inline] netif_receive_skb+0x4b/0x2d0 net/core/dev.c:6410 ... write to 0xffff888149f0d428 of 8 bytes by interrupt on cpu 0: bond_rcv_validate+0x202/0x7a0 drivers/net/bonding/bond_main.c:3335 bond_handle_frame+0xde/0x5e0 drivers/net/bonding/bond_main.c:1533 __netif_receive_skb_core+0x5b1/0x1950 net/core/dev.c:6039 __netif_receive_skb_one_core net/core/dev.c:6150 [inline] __netif_receive_skb+0x59/0x270 net/core/dev.c:6265 netif_receive_skb_internal net/core/dev.c:6351 [inline] netif_receive_skb+0x4b/0x2d0 net/core/dev.c:6410 br_netif_receive_skb net/bridge/br_input.c:30 [inline] NF_HOOK include/linux/netfilter.h:318 [inline] ... value changed: 0x0000000100005365 -> 0x0000000100005366 Fixes: f5b2b966f032 ("[PATCH] bonding: Validate probe replies in ARP monitor") Signed-off-by: Eric Dumazet Reported-by: syzbot Link: https://patch.msgid.link/20260122162914.2299312-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/bonding/bond_main.c | 18 ++++++++++-------- drivers/net/bonding/bond_options.c | 8 ++++---- include/net/bonding.h | 13 +++++++------ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f684e035d7e3..59adea3f7f58 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3137,8 +3137,8 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 __func__, &sip); return; } - slave->last_rx = jiffies; - slave->target_last_arp_rx[i] = jiffies; + WRITE_ONCE(slave->last_rx, jiffies); + WRITE_ONCE(slave->target_last_arp_rx[i], jiffies); } static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, @@ -3357,8 +3357,8 @@ static void bond_validate_na(struct bonding *bond, struct slave *slave, __func__, saddr); return; } - slave->last_rx = jiffies; - slave->target_last_arp_rx[i] = jiffies; + WRITE_ONCE(slave->last_rx, jiffies); + WRITE_ONCE(slave->target_last_arp_rx[i], jiffies); } static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond, @@ -3428,7 +3428,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, (slave_do_arp_validate_only(bond) && is_ipv6) || #endif !slave_do_arp_validate_only(bond)) - slave->last_rx = jiffies; + WRITE_ONCE(slave->last_rx, jiffies); return RX_HANDLER_ANOTHER; } else if (is_arp) { return bond_arp_rcv(skb, bond, slave); @@ -3496,7 +3496,7 @@ static void bond_loadbalance_arp_mon(struct bonding *bond) if (slave->link != BOND_LINK_UP) { if (bond_time_in_interval(bond, last_tx, 1) && - bond_time_in_interval(bond, slave->last_rx, 1)) { + bond_time_in_interval(bond, READ_ONCE(slave->last_rx), 1)) { bond_propose_link_state(slave, BOND_LINK_UP); slave_state_changed = 1; @@ -3520,8 +3520,10 @@ static void bond_loadbalance_arp_mon(struct bonding *bond) * when the source ip is 0, so don't take the link down * if we don't know our ip yet */ - if (!bond_time_in_interval(bond, last_tx, bond->params.missed_max) || - !bond_time_in_interval(bond, slave->last_rx, bond->params.missed_max)) { + if (!bond_time_in_interval(bond, last_tx, + bond->params.missed_max) || + !bond_time_in_interval(bond, READ_ONCE(slave->last_rx), + bond->params.missed_max)) { bond_propose_link_state(slave, BOND_LINK_DOWN); slave_state_changed = 1; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index a2fa068193e3..5a2a935945c4 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -1124,7 +1124,7 @@ static void _bond_options_arp_ip_target_set(struct bonding *bond, int slot, if (slot >= 0 && slot < BOND_MAX_ARP_TARGETS) { bond_for_each_slave(bond, slave, iter) - slave->target_last_arp_rx[slot] = last_rx; + WRITE_ONCE(slave->target_last_arp_rx[slot], last_rx); targets[slot] = target; } } @@ -1193,8 +1193,8 @@ static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target) bond_for_each_slave(bond, slave, iter) { targets_rx = slave->target_last_arp_rx; for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++) - targets_rx[i] = targets_rx[i+1]; - targets_rx[i] = 0; + WRITE_ONCE(targets_rx[i], READ_ONCE(targets_rx[i+1])); + WRITE_ONCE(targets_rx[i], 0); } for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++) targets[i] = targets[i+1]; @@ -1349,7 +1349,7 @@ static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot, if (slot >= 0 && slot < BOND_MAX_NS_TARGETS) { bond_for_each_slave(bond, slave, iter) { - slave->target_last_arp_rx[slot] = last_rx; + WRITE_ONCE(slave->target_last_arp_rx[slot], last_rx); slave_set_ns_maddr(bond, slave, target, &targets[slot]); } targets[slot] = *target; diff --git a/include/net/bonding.h b/include/net/bonding.h index e25be8d9e1a6..5d6ffdf59fbf 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -521,13 +521,14 @@ static inline int bond_is_ip6_target_ok(struct in6_addr *addr) static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond, struct slave *slave) { + unsigned long tmp, ret = READ_ONCE(slave->target_last_arp_rx[0]); int i = 1; - unsigned long ret = slave->target_last_arp_rx[0]; - - for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++) - if (time_before(slave->target_last_arp_rx[i], ret)) - ret = slave->target_last_arp_rx[i]; + for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++) { + tmp = READ_ONCE(slave->target_last_arp_rx[i]); + if (time_before(tmp, ret)) + ret = tmp; + } return ret; } @@ -537,7 +538,7 @@ static inline unsigned long slave_last_rx(struct bonding *bond, if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL) return slave_oldest_target_arp_rx(bond, slave); - return slave->last_rx; + return READ_ONCE(slave->last_rx); } static inline void slave_update_last_tx(struct slave *slave) -- Gitee From 034c537560e956b6bef4652e13c515fe1663ed40 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Fri, 23 Jan 2026 14:57:16 +0800 Subject: [PATCH 1243/1449] net: mvpp2: cls: Fix memory leak in mvpp2_ethtool_cls_rule_ins() ANBZ: #35228 commit 509b526d642908f758c4618cd5ac9d19066ee984 stable. commit 09f979d1f312627b31d2ee1e46f9692e442610cd upstream. In mvpp2_ethtool_cls_rule_ins(), the ethtool_rule is allocated by ethtool_rx_flow_rule_create(). If the subsequent conversion to flow type fails, the function jumps to the clean_rule label. However, the clean_rule label only frees efs, skipping the cleanup of ethtool_rule, which leads to a memory leak. Fix this by jumping to the clean_eth_rule label, which properly calls ethtool_rx_flow_rule_destroy() before freeing efs. Compile tested only. Issue found using a prototype static analysis tool and code review. Fixes: f4f1ba18195d ("net: mvpp2: cls: Report an error for unsupported flow types") Signed-off-by: Zilin Guan Reviewed-by: Maxime Chevallier Link: https://patch.msgid.link/20260123065716.2248324-1-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c index d2757cc11613..038382a0b8e9 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c @@ -1389,7 +1389,7 @@ int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port, efs->rule.flow_type = mvpp2_cls_ethtool_flow_to_type(info->fs.flow_type); if (efs->rule.flow_type < 0) { ret = efs->rule.flow_type; - goto clean_rule; + goto clean_eth_rule; } ret = mvpp2_cls_rfs_parse_rule(&efs->rule); -- Gitee From 2dcfda1f990dc6fd39a0dfc78c63285f9fe3eac2 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Thu, 22 Jan 2026 03:44:08 +0800 Subject: [PATCH 1244/1449] ipv6: use the right ifindex when replying to icmpv6 from localhost ANBZ: #35228 commit 96595848c6fd6625e64a1a75a5d987e7ed10ea65 stable. commit 03cbcdf93866e61beb0063392e6dbb701f03aea2 upstream. When replying to a ICMPv6 echo request that comes from localhost address the right output ifindex is 1 (lo) and not rt6i_idev dev index. Use the skb device ifindex instead. This fixes pinging to a local address from localhost source address. $ ping6 -I ::1 2001:1:1::2 -c 3 PING 2001:1:1::2 (2001:1:1::2) from ::1 : 56 data bytes 64 bytes from 2001:1:1::2: icmp_seq=1 ttl=64 time=0.037 ms 64 bytes from 2001:1:1::2: icmp_seq=2 ttl=64 time=0.069 ms 64 bytes from 2001:1:1::2: icmp_seq=3 ttl=64 time=0.122 ms 2001:1:1::2 ping statistics 3 packets transmitted, 3 received, 0% packet loss, time 2032ms rtt min/avg/max/mdev = 0.037/0.076/0.122/0.035 ms Fixes: 1b70d792cf67 ("ipv6: Use rt6i_idev index for echo replies to a local address") Signed-off-by: Fernando Fernandez Mancera Reviewed-by: David Ahern Link: https://patch.msgid.link/20260121194409.6749-1-fmancera@suse.de Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/icmp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index fd91fd139d76..c7e815b7ca08 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -768,7 +768,9 @@ static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb) fl6.daddr = ipv6_hdr(skb)->saddr; if (saddr) fl6.saddr = *saddr; - fl6.flowi6_oif = icmp6_iif(skb); + fl6.flowi6_oif = ipv6_addr_loopback(&fl6.daddr) ? + skb->dev->ifindex : + icmp6_iif(skb); fl6.fl6_icmp_type = type; fl6.flowi6_mark = mark; fl6.flowi6_uid = sock_net_uid(net, NULL); -- Gitee From de7a597e503b2c00b6bbe88f78f146a8054f609c Mon Sep 17 00:00:00 2001 From: Kery Qi Date: Fri, 23 Jan 2026 01:04:01 +0800 Subject: [PATCH 1245/1449] net: wwan: t7xx: fix potential skb->frags overflow in RX path ANBZ: #35228 commit 2a0522f564acd34442652ea083091c329fa7c5d5 stable. commit f0813bcd2d9d97fdbdf2efb9532ab03ae92e99e6 upstream. When receiving data in the DPMAIF RX path, the t7xx_dpmaif_set_frag_to_skb() function adds page fragments to an skb without checking if the number of fragments has exceeded MAX_SKB_FRAGS. This could lead to a buffer overflow in skb_shinfo(skb)->frags[] array, corrupting adjacent memory and potentially causing kernel crashes or other undefined behavior. This issue was identified through static code analysis by comparing with a similar vulnerability fixed in the mt76 driver commit b102f0c522cf ("mt76: fix array overflow on receiving too many fragments for a packet"). The vulnerability could be triggered if the modem firmware sends packets with excessive fragments. While under normal protocol conditions (MTU 3080 bytes, BAT buffer 3584 bytes), a single packet should not require additional fragments, the kernel should not blindly trust firmware behavior. Malicious, buggy, or compromised firmware could potentially craft packets with more fragments than the kernel expects. Fix this by adding a bounds check before calling skb_add_rx_frag() to ensure nr_frags does not exceed MAX_SKB_FRAGS. The check must be performed before unmapping to avoid a page leak and double DMA unmap during device teardown. Fixes: d642b012df70a ("net: wwan: t7xx: Add data path interface") Signed-off-by: Kery Qi Link: https://patch.msgid.link/20260122170401.1986-2-qikeyu2017@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c b/drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c index 7c4a11f60f91..52b036fe6cfe 100644 --- a/drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c +++ b/drivers/net/wwan/t7xx/t7xx_hif_dpmaif_rx.c @@ -394,6 +394,7 @@ static int t7xx_dpmaif_set_frag_to_skb(const struct dpmaif_rx_queue *rxq, struct sk_buff *skb) { unsigned long long data_bus_addr, data_base_addr; + struct skb_shared_info *shinfo = skb_shinfo(skb); struct device *dev = rxq->dpmaif_ctrl->dev; struct dpmaif_bat_page *page_info; unsigned int data_len; @@ -401,18 +402,22 @@ static int t7xx_dpmaif_set_frag_to_skb(const struct dpmaif_rx_queue *rxq, page_info = rxq->bat_frag->bat_skb; page_info += t7xx_normal_pit_bid(pkt_info); - dma_unmap_page(dev, page_info->data_bus_addr, page_info->data_len, DMA_FROM_DEVICE); if (!page_info->page) return -EINVAL; + if (shinfo->nr_frags >= MAX_SKB_FRAGS) + return -EINVAL; + + dma_unmap_page(dev, page_info->data_bus_addr, page_info->data_len, DMA_FROM_DEVICE); + data_bus_addr = le32_to_cpu(pkt_info->pd.data_addr_h); data_bus_addr = (data_bus_addr << 32) + le32_to_cpu(pkt_info->pd.data_addr_l); data_base_addr = page_info->data_bus_addr; data_offset = data_bus_addr - data_base_addr; data_offset += page_info->offset; data_len = FIELD_GET(PD_PIT_DATA_LEN, le32_to_cpu(pkt_info->header)); - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page_info->page, + skb_add_rx_frag(skb, shinfo->nr_frags, page_info->page, data_offset, data_len, page_info->data_len); page_info->page = NULL; -- Gitee From 00d82ee166086d2d487ca17b037102ea9950c5ba Mon Sep 17 00:00:00 2001 From: Kery Qi Date: Sat, 24 Jan 2026 05:10:31 +0800 Subject: [PATCH 1246/1449] rocker: fix memory leak in rocker_world_port_post_fini() ANBZ: #35228 commit d448bf96889f1905e740c554780f5c9fa0440566 stable. commit 8d7ba71e46216b8657a82ca2ec118bc93812a4d0 upstream. In rocker_world_port_pre_init(), rocker_port->wpriv is allocated with kzalloc(wops->port_priv_size, GFP_KERNEL). However, in rocker_world_port_post_fini(), the memory is only freed when wops->port_post_fini callback is set: if (!wops->port_post_fini) return; wops->port_post_fini(rocker_port); kfree(rocker_port->wpriv); Since rocker_ofdpa_ops does not implement port_post_fini callback (it is NULL), the wpriv memory allocated for each port is never freed when ports are removed. This leads to a memory leak of sizeof(struct ofdpa_port) bytes per port on every device removal. Fix this by always calling kfree(rocker_port->wpriv) regardless of whether the port_post_fini callback exists. Fixes: e420114eef4a ("rocker: introduce worlds infrastructure") Signed-off-by: Kery Qi Reviewed-by: Simon Horman Link: https://patch.msgid.link/20260123211030.2109-2-qikeyu2017@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/rocker/rocker_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c index 2e2826c901fc..b741d335b1dc 100644 --- a/drivers/net/ethernet/rocker/rocker_main.c +++ b/drivers/net/ethernet/rocker/rocker_main.c @@ -1525,9 +1525,8 @@ static void rocker_world_port_post_fini(struct rocker_port *rocker_port) { struct rocker_world_ops *wops = rocker_port->rocker->wops; - if (!wops->port_post_fini) - return; - wops->port_post_fini(rocker_port); + if (wops->port_post_fini) + wops->port_post_fini(rocker_port); kfree(rocker_port->wpriv); } -- Gitee From ef22ee3e5dc76d6932047b7e2c45af1737a071d1 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Sun, 25 Jan 2026 08:59:28 +0800 Subject: [PATCH 1247/1449] nfc: llcp: Fix memleak in nfc_llcp_send_ui_frame(). ANBZ: #35228 commit f8d002626d434f5fea9085e2557711c16a15cec6 stable. commit 165c34fb6068ff153e3fc99a932a80a9d5755709 upstream. syzbot reported various memory leaks related to NFC, struct nfc_llcp_sock, sk_buff, nfc_dev, etc. [0] The leading log hinted that nfc_llcp_send_ui_frame() failed to allocate skb due to sock_error(sk) being -ENXIO. ENXIO is set by nfc_llcp_socket_release() when struct nfc_llcp_local is destroyed by local_cleanup(). The problem is that there is no synchronisation between nfc_llcp_send_ui_frame() and local_cleanup(), and skb could be put into local->tx_queue after it was purged in local_cleanup(): CPU1 CPU2 ---- ---- nfc_llcp_send_ui_frame() local_cleanup() |- do { ' |- pdu = nfc_alloc_send_skb(..., &err) | . | |- nfc_llcp_socket_release(local, false, ENXIO); | |- skb_queue_purge(&local->tx_queue); | | ' | |- skb_queue_tail(&local->tx_queue, pdu); | ... | |- pdu = nfc_alloc_send_skb(..., &err) | ^._________________________________.' local_cleanup() is called for struct nfc_llcp_local only after nfc_llcp_remove_local() unlinks it from llcp_devices. If we hold local->tx_queue.lock then, we can synchronise the thread and nfc_llcp_send_ui_frame(). Let's do that and check list_empty(&local->list) before queuing skb to local->tx_queue in nfc_llcp_send_ui_frame(). [0]: [ 56.074943][ T6096] llcp: nfc_llcp_send_ui_frame: Could not allocate PDU (error=-6) [ 64.318868][ T5813] kmemleak: 6 new suspected memory leaks (see /sys/kernel/debug/kmemleak) BUG: memory leak unreferenced object 0xffff8881272f6800 (size 1024): comm "syz.0.17", pid 6096, jiffies 4294942766 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 27 00 03 40 00 00 00 00 00 00 00 00 00 00 00 00 '..@............ backtrace (crc da58d84d): kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline] slab_post_alloc_hook mm/slub.c:4979 [inline] slab_alloc_node mm/slub.c:5284 [inline] __do_kmalloc_node mm/slub.c:5645 [inline] __kmalloc_noprof+0x3e3/0x6b0 mm/slub.c:5658 kmalloc_noprof include/linux/slab.h:961 [inline] sk_prot_alloc+0x11a/0x1b0 net/core/sock.c:2239 sk_alloc+0x36/0x360 net/core/sock.c:2295 nfc_llcp_sock_alloc+0x37/0x130 net/nfc/llcp_sock.c:979 llcp_sock_create+0x71/0xd0 net/nfc/llcp_sock.c:1044 nfc_sock_create+0xc9/0xf0 net/nfc/af_nfc.c:31 __sock_create+0x1a9/0x340 net/socket.c:1605 sock_create net/socket.c:1663 [inline] __sys_socket_create net/socket.c:1700 [inline] __sys_socket+0xb9/0x1a0 net/socket.c:1747 __do_sys_socket net/socket.c:1761 [inline] __se_sys_socket net/socket.c:1759 [inline] __x64_sys_socket+0x1b/0x30 net/socket.c:1759 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f BUG: memory leak unreferenced object 0xffff88810fbd9800 (size 240): comm "syz.0.17", pid 6096, jiffies 4294942850 hex dump (first 32 bytes): 68 f0 ff 08 81 88 ff ff 68 f0 ff 08 81 88 ff ff h.......h....... 00 00 00 00 00 00 00 00 00 68 2f 27 81 88 ff ff .........h/'.... backtrace (crc 6cc652b1): kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline] slab_post_alloc_hook mm/slub.c:4979 [inline] slab_alloc_node mm/slub.c:5284 [inline] kmem_cache_alloc_node_noprof+0x36f/0x5e0 mm/slub.c:5336 __alloc_skb+0x203/0x240 net/core/skbuff.c:660 alloc_skb include/linux/skbuff.h:1383 [inline] alloc_skb_with_frags+0x69/0x3f0 net/core/skbuff.c:6671 sock_alloc_send_pskb+0x379/0x3e0 net/core/sock.c:2965 sock_alloc_send_skb include/net/sock.h:1859 [inline] nfc_alloc_send_skb+0x45/0x80 net/nfc/core.c:724 nfc_llcp_send_ui_frame+0x162/0x360 net/nfc/llcp_commands.c:766 llcp_sock_sendmsg+0x14c/0x1d0 net/nfc/llcp_sock.c:814 sock_sendmsg_nosec net/socket.c:727 [inline] __sock_sendmsg net/socket.c:742 [inline] __sys_sendto+0x2d8/0x2f0 net/socket.c:2244 __do_sys_sendto net/socket.c:2251 [inline] __se_sys_sendto net/socket.c:2247 [inline] __x64_sys_sendto+0x28/0x30 net/socket.c:2247 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xa4/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 94f418a20664 ("NFC: UI frame sending routine implementation") Reported-by: syzbot+f2d245f1d76bbfa50e4c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/697569c7.a00a0220.33ccc7.0014.GAE@google.com/T/#u Signed-off-by: Kuniyuki Iwashima Reviewed-by: Simon Horman Link: https://patch.msgid.link/20260125010214.1572439-1-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/nfc/llcp_commands.c | 17 ++++++++++++++++- net/nfc/llcp_core.c | 4 +++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index e2680a3bef79..b652323bc2c1 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -778,8 +778,23 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, if (likely(frag_len > 0)) skb_put_data(pdu, msg_ptr, frag_len); + spin_lock(&local->tx_queue.lock); + + if (list_empty(&local->list)) { + spin_unlock(&local->tx_queue.lock); + + kfree_skb(pdu); + + len -= remaining_len; + if (len == 0) + len = -ENXIO; + break; + } + /* No need to check for the peer RW for UI frames */ - skb_queue_tail(&local->tx_queue, pdu); + __skb_queue_tail(&local->tx_queue, pdu); + + spin_unlock(&local->tx_queue.lock); remaining_len -= frag_len; msg_ptr += frag_len; diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index 18be13fb9b75..ced99d2a90cc 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -314,7 +314,9 @@ static struct nfc_llcp_local *nfc_llcp_remove_local(struct nfc_dev *dev) spin_lock(&llcp_devices_lock); list_for_each_entry_safe(local, tmp, &llcp_devices, list) if (local->dev == dev) { - list_del(&local->list); + spin_lock(&local->tx_queue.lock); + list_del_init(&local->list); + spin_unlock(&local->tx_queue.lock); spin_unlock(&llcp_devices_lock); return local; } -- Gitee From ca4c3153a0e0274a6a90b5c3de30664ac2de9d80 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 2 Dec 2025 07:38:52 +0800 Subject: [PATCH 1248/1449] ice: stop counting UDP csum mismatch as rx_errors ANBZ: #35228 commit fd30aa82df73ba0302142f418fddf97956dcda57 stable. commit 05faf2c0a76581d0a7fdbb8ec46477ba183df95b upstream. Since the beginning, the Intel ice driver has counted receive checksum offload mismatches into the rx_errors member of the rtnl_link_stats64 struct. In ethtool -S these show up as rx_csum_bad.nic. I believe counting these in rx_errors is fundamentally wrong, as it's pretty clear from the comments in if_link.h and from every other statistic the driver is summing into rx_errors, that all of them would cause a "hardware drop" except for the UDP checksum mismatch, as well as the fact that all the other causes for rx_errors are L2 reasons, and this L4 UDP "mismatch" is an outlier. A last nail in the coffin is that rx_errors is monitored in production and can indicate a bad NIC/cable/Switch port, but instead some random series of UDP packets with bad checksums will now trigger this alert. This false positive makes the alert useless and affects us as well as other companies. This packet with presumably a bad UDP checksum is *already* passed to the stack, just not marked as offloaded by the hardware/driver. If it is dropped by the stack it will show up as UDP_MIB_CSUMERRORS. And one more thing, none of the other Intel drivers, and at least bnxt_en and mlx5 both don't appear to count UDP offload mismatches as rx_errors. Here is a related customer complaint: https://community.intel.com/t5/Ethernet-Products/ice-rx-errros-is-too-sensitive-to-IP-TCP-attack-packets-Intel/td-p/1662125 Fixes: 4f1fe43c920b ("ice: Add more Rx errors to netdev's rx_error counter") Cc: Tony Nguyen Cc: Jake Keller Cc: IWL Signed-off-by: Jesse Brandeburg Acked-by: Jacob Keller Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/intel/ice/ice_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index a645161a337d..611c44752c0b 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -6711,7 +6711,6 @@ void ice_update_vsi_stats(struct ice_vsi *vsi) pf->stats.illegal_bytes + pf->stats.rx_len_errors + pf->stats.rx_undersize + - pf->hw_csum_rx_error + pf->stats.rx_jabber + pf->stats.rx_fragments + pf->stats.rx_oversize; -- Gitee From baf335fe275fe3e71158c51a260a8b57bd973e39 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Mon, 26 Jan 2026 15:14:54 +0800 Subject: [PATCH 1249/1449] net/mlx5e: TC, delete flows only for existing peers ANBZ: #35228 commit 62e1d8920f6920543f4b095a65fb964448c9901d stable. commit f67666938ae626cbda63fbf5176b3583c07e7124 upstream. When deleting TC steering flows, iterate only over actual devcom peers instead of assuming all possible ports exist. This avoids touching non-existent peers and ensures cleanup is limited to devices the driver is currently connected to. BUG: kernel NULL pointer dereference, address: 0000000000000008 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 133c8a067 P4D 0 Oops: Oops: 0002 [#1] SMP CPU: 19 UID: 0 PID: 2169 Comm: tc Not tainted 6.18.0+ #156 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:mlx5e_tc_del_fdb_peers_flow+0xbe/0x200 [mlx5_core] Code: 00 00 a8 08 74 a8 49 8b 46 18 f6 c4 02 74 9f 4c 8d bf a0 12 00 00 4c 89 ff e8 0e e7 96 e1 49 8b 44 24 08 49 8b 0c 24 4c 89 ff <48> 89 41 08 48 89 08 49 89 2c 24 49 89 5c 24 08 e8 7d ce 96 e1 49 RSP: 0018:ff11000143867528 EFLAGS: 00010246 RAX: 0000000000000000 RBX: dead000000000122 RCX: 0000000000000000 RDX: ff11000143691580 RSI: ff110001026e5000 RDI: ff11000106f3d2a0 RBP: dead000000000100 R08: 00000000000003fd R09: 0000000000000002 R10: ff11000101c75690 R11: ff1100085faea178 R12: ff11000115f0ae78 R13: 0000000000000000 R14: ff11000115f0a800 R15: ff11000106f3d2a0 FS: 00007f35236bf740(0000) GS:ff110008dc809000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 0000000157a01001 CR4: 0000000000373eb0 Call Trace: mlx5e_tc_del_flow+0x46/0x270 [mlx5_core] mlx5e_flow_put+0x25/0x50 [mlx5_core] mlx5e_delete_flower+0x2a6/0x3e0 [mlx5_core] tc_setup_cb_reoffload+0x20/0x80 fl_reoffload+0x26f/0x2f0 [cls_flower] ? mlx5e_tc_reoffload_flows_work+0xc0/0xc0 [mlx5_core] ? mlx5e_tc_reoffload_flows_work+0xc0/0xc0 [mlx5_core] tcf_block_playback_offloads+0x9e/0x1c0 tcf_block_unbind+0x7b/0xd0 tcf_block_setup+0x186/0x1d0 tcf_block_offload_cmd.isra.0+0xef/0x130 tcf_block_offload_unbind+0x43/0x70 __tcf_block_put+0x85/0x160 ingress_destroy+0x32/0x110 [sch_ingress] __qdisc_destroy+0x44/0x100 qdisc_graft+0x22b/0x610 tc_get_qdisc+0x183/0x4d0 rtnetlink_rcv_msg+0x2d7/0x3d0 ? rtnl_calcit.isra.0+0x100/0x100 netlink_rcv_skb+0x53/0x100 netlink_unicast+0x249/0x320 ? __alloc_skb+0x102/0x1f0 netlink_sendmsg+0x1e3/0x420 __sock_sendmsg+0x38/0x60 ____sys_sendmsg+0x1ef/0x230 ? copy_msghdr_from_user+0x6c/0xa0 ___sys_sendmsg+0x7f/0xc0 ? ___sys_recvmsg+0x8a/0xc0 ? __sys_sendto+0x119/0x180 __sys_sendmsg+0x61/0xb0 do_syscall_64+0x55/0x640 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7f35238bb764 Code: 15 b9 86 0c 00 f7 d8 64 89 02 b8 ff ff ff ff eb bf 0f 1f 44 00 00 f3 0f 1e fa 80 3d e5 08 0d 00 00 74 13 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 4c c3 0f 1f 00 55 48 89 e5 48 83 ec 20 89 55 RSP: 002b:00007ffed4c35638 EFLAGS: 00000202 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 000055a2efcc75e0 RCX: 00007f35238bb764 RDX: 0000000000000000 RSI: 00007ffed4c356a0 RDI: 0000000000000003 RBP: 00007ffed4c35710 R08: 0000000000000010 R09: 00007f3523984b20 R10: 0000000000000004 R11: 0000000000000202 R12: 00007ffed4c35790 R13: 000000006947df8f R14: 000055a2efcc75e0 R15: 00007ffed4c35780 Fixes: 9be6c21fdcf8 ("net/mlx5e: Handle offloads flows per peer") Signed-off-by: Mark Bloch Reviewed-by: Shay Drori Signed-off-by: Tariq Toukan Reviewed-by: Simon Horman Link: https://patch.msgid.link/1769411695-18820-3-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 2be9c69daad5..f1f422505731 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -2025,11 +2025,14 @@ static void mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *flow, static void mlx5e_tc_del_fdb_peers_flow(struct mlx5e_tc_flow *flow) { + struct mlx5_devcom_comp_dev *devcom; + struct mlx5_devcom_comp_dev *pos; + struct mlx5_eswitch *peer_esw; int i; - for (i = 0; i < MLX5_MAX_PORTS; i++) { - if (i == mlx5_get_dev_index(flow->priv->mdev)) - continue; + devcom = flow->priv->mdev->priv.eswitch->devcom; + mlx5_devcom_for_each_peer_entry(devcom, peer_esw, pos) { + i = mlx5_get_dev_index(peer_esw->dev); mlx5e_tc_del_fdb_peer_flow(flow, i); } } @@ -5404,12 +5407,16 @@ int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags) void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw) { + struct mlx5_devcom_comp_dev *devcom; + struct mlx5_devcom_comp_dev *pos; struct mlx5e_tc_flow *flow, *tmp; + struct mlx5_eswitch *peer_esw; int i; - for (i = 0; i < MLX5_MAX_PORTS; i++) { - if (i == mlx5_get_dev_index(esw->dev)) - continue; + devcom = esw->devcom; + + mlx5_devcom_for_each_peer_entry(devcom, peer_esw, pos) { + i = mlx5_get_dev_index(peer_esw->dev); list_for_each_entry_safe(flow, tmp, &esw->offloads.peer_flows[i], peer[i]) mlx5e_tc_del_fdb_peers_flow(flow); } -- Gitee From 07c73f000a1de1ce2d310c5517d30a165ac18797 Mon Sep 17 00:00:00 2001 From: Yafang Shao Date: Tue, 10 Dec 2024 10:27:06 +0800 Subject: [PATCH 1250/1449] net/mlx5e: Report rx_discards_phy via rx_dropped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e014f11f741be9d5f0b77046c725c238220ef503 stable. commit c9cfced17365b1df8c6ae6cd5db56aebd7ed9b57 upstream. We noticed a high number of rx_discards_phy events on certain servers while running `ethtool -S`. However, this critical counter is not currently included in the standard /proc/net/dev statistics file, making it difficult to monitor effectively—especially given the diversity of vendors across a large fleet of servers. Let's report it via the standard rx_dropped metric. Suggested-by: Jakub Kicinski Signed-off-by: Yafang Shao Cc: Saeed Mahameed Cc: Leon Romanovsky Cc: Gal Pressman Reviewed-by: Simon Horman Reviewed-by: Tariq Toukan Link: https://patch.msgid.link/20241210022706.6665-1-laoar.shao@gmail.com Signed-off-by: Jakub Kicinski Stable-dep-of: 476681f10cc1 ("net/mlx5e: Account for netdev stats in ndo_get_stats64") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 1517e7f97e56..0b472e6da0cc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3760,6 +3760,7 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) } stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer; + stats->rx_dropped = PPORT_2863_GET(pstats, if_in_discards); stats->rx_length_errors = PPORT_802_3_GET(pstats, a_in_range_length_errors) + -- Gitee From 03f6f39f00d56a33bcb2f74e6e68a13c10ae4588 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Mon, 26 Jan 2026 15:14:55 +0800 Subject: [PATCH 1251/1449] net/mlx5e: Account for netdev stats in ndo_get_stats64 ANBZ: #35228 commit 970526dde368674cb3d75867f90d75dc9d5d6ae9 stable. commit 476681f10cc1e0e56e26856684e75d4678b072b2 upstream. The driver's ndo_get_stats64 callback is only reporting mlx5 counters, without accounting for the netdev stats, causing errors from the network stack to be invisible in statistics. Add netdev_stats_to_stats64() call to first populate the counters, then add mlx5 counters on top, ensuring both are accounted for (where appropriate). Fixes: f62b8bb8f2d3 ("net/mlx5: Extend mlx5_core to support ConnectX-4 Ethernet functionality") Signed-off-by: Gal Pressman Signed-off-by: Tariq Toukan Reviewed-by: Simon Horman Link: https://patch.msgid.link/1769411695-18820-4-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/mellanox/mlx5/core/en_main.c | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 0b472e6da0cc..39d36ed7b207 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3743,6 +3743,8 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) mlx5e_queue_update_stats(priv); } + netdev_stats_to_stats64(stats, &dev->stats); + if (mlx5e_is_uplink_rep(priv)) { struct mlx5e_vport_stats *vstats = &priv->stats.vport; @@ -3759,21 +3761,21 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) mlx5e_fold_sw_stats64(priv, stats); } - stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer; - stats->rx_dropped = PPORT_2863_GET(pstats, if_in_discards); + stats->rx_missed_errors += priv->stats.qcnt.rx_out_of_buffer; + stats->rx_dropped += PPORT_2863_GET(pstats, if_in_discards); - stats->rx_length_errors = + stats->rx_length_errors += PPORT_802_3_GET(pstats, a_in_range_length_errors) + PPORT_802_3_GET(pstats, a_out_of_range_length_field) + PPORT_802_3_GET(pstats, a_frame_too_long_errors) + VNIC_ENV_GET(&priv->stats.vnic, eth_wqe_too_small); - stats->rx_crc_errors = + stats->rx_crc_errors += PPORT_802_3_GET(pstats, a_frame_check_sequence_errors); - stats->rx_frame_errors = PPORT_802_3_GET(pstats, a_alignment_errors); - stats->tx_aborted_errors = PPORT_2863_GET(pstats, if_out_discards); - stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors + - stats->rx_frame_errors; - stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors; + stats->rx_frame_errors += PPORT_802_3_GET(pstats, a_alignment_errors); + stats->tx_aborted_errors += PPORT_2863_GET(pstats, if_out_discards); + stats->rx_errors += stats->rx_length_errors + stats->rx_crc_errors + + stats->rx_frame_errors; + stats->tx_errors += stats->tx_aborted_errors + stats->tx_carrier_errors; } static void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv) -- Gitee From edc0b25bb0b7b6ae3d090aa234f003eb0af55138 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Tue, 27 Jan 2026 12:03:59 +0800 Subject: [PATCH 1252/1449] nfc: nci: Fix race between rfkill and nci_unregister_device(). ANBZ: #35228 commit 546eba0b10989de9ccc7fd619e874a30561e2b88 stable. commit d2492688bb9fed6ab6e313682c387ae71a66ebae upstream. syzbot reported the splat below [0] without a repro. It indicates that struct nci_dev.cmd_wq had been destroyed before nci_close_device() was called via rfkill. nci_dev.cmd_wq is only destroyed in nci_unregister_device(), which (I think) was called from virtual_ncidev_close() when syzbot close()d an fd of virtual_ncidev. The problem is that nci_unregister_device() destroys nci_dev.cmd_wq first and then calls nfc_unregister_device(), which removes the device from rfkill by rfkill_unregister(). So, the device is still visible via rfkill even after nci_dev.cmd_wq is destroyed. Let's unregister the device from rfkill first in nci_unregister_device(). Note that we cannot call nfc_unregister_device() before nci_close_device() because 1) nfc_unregister_device() calls device_del() which frees all memory allocated by devm_kzalloc() and linked to ndev->conn_info_list 2) nci_rx_work() could try to queue nci_conn_info to ndev->conn_info_list which could be leaked Thus, nfc_unregister_device() is split into two functions so we can remove rfkill interfaces only before nci_close_device(). [0]: DEBUG_LOCKS_WARN_ON(1) WARNING: kernel/locking/lockdep.c:238 at hlock_class kernel/locking/lockdep.c:238 [inline], CPU#0: syz.0.8675/6349 WARNING: kernel/locking/lockdep.c:238 at check_wait_context kernel/locking/lockdep.c:4854 [inline], CPU#0: syz.0.8675/6349 WARNING: kernel/locking/lockdep.c:238 at __lock_acquire+0x39d/0x2cf0 kernel/locking/lockdep.c:5187, CPU#0: syz.0.8675/6349 Modules linked in: CPU: 0 UID: 0 PID: 6349 Comm: syz.0.8675 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/13/2026 RIP: 0010:hlock_class kernel/locking/lockdep.c:238 [inline] RIP: 0010:check_wait_context kernel/locking/lockdep.c:4854 [inline] RIP: 0010:__lock_acquire+0x3a4/0x2cf0 kernel/locking/lockdep.c:5187 Code: 18 00 4c 8b 74 24 08 75 27 90 e8 17 f2 fc 02 85 c0 74 1c 83 3d 50 e0 4e 0e 00 75 13 48 8d 3d 43 f7 51 0e 48 c7 c6 8b 3a de 8d <67> 48 0f b9 3a 90 31 c0 0f b6 98 c4 00 00 00 41 8b 45 20 25 ff 1f RSP: 0018:ffffc9000c767680 EFLAGS: 00010046 RAX: 0000000000000001 RBX: 0000000000040000 RCX: 0000000000080000 RDX: ffffc90013080000 RSI: ffffffff8dde3a8b RDI: ffffffff8ff24ca0 RBP: 0000000000000003 R08: ffffffff8fef35a3 R09: 1ffffffff1fde6b4 R10: dffffc0000000000 R11: fffffbfff1fde6b5 R12: 00000000000012a2 R13: ffff888030338ba8 R14: ffff888030338000 R15: ffff888030338b30 FS: 00007fa5995f66c0(0000) GS:ffff8881256f8000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7e72f842d0 CR3: 00000000485a0000 CR4: 00000000003526f0 Call Trace: lock_acquire+0x106/0x330 kernel/locking/lockdep.c:5868 touch_wq_lockdep_map+0xcb/0x180 kernel/workqueue.c:3940 __flush_workqueue+0x14b/0x14f0 kernel/workqueue.c:3982 nci_close_device+0x302/0x630 net/nfc/nci/core.c:567 nci_dev_down+0x3b/0x50 net/nfc/nci/core.c:639 nfc_dev_down+0x152/0x290 net/nfc/core.c:161 nfc_rfkill_set_block+0x2d/0x100 net/nfc/core.c:179 rfkill_set_block+0x1d2/0x440 net/rfkill/core.c:346 rfkill_fop_write+0x461/0x5a0 net/rfkill/core.c:1301 vfs_write+0x29a/0xb90 fs/read_write.c:684 ksys_write+0x150/0x270 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fa59b39acb9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fa5995f6028 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007fa59b615fa0 RCX: 00007fa59b39acb9 RDX: 0000000000000008 RSI: 0000200000000080 RDI: 0000000000000007 RBP: 00007fa59b408bf7 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fa59b616038 R14: 00007fa59b615fa0 R15: 00007ffc82218788 Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation") Reported-by: syzbot+f9c5fd1a0874f9069dce@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/695e7f56.050a0220.1c677c.036c.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima Reviewed-by: Simon Horman Link: https://patch.msgid.link/20260127040411.494931-1-kuniyu@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/nfc/nfc.h | 2 ++ net/nfc/core.c | 27 ++++++++++++++++++++++++--- net/nfc/nci/core.c | 4 +++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 5dee575fbe86..b82f4f2a27fb 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -215,6 +215,8 @@ static inline void nfc_free_device(struct nfc_dev *dev) int nfc_register_device(struct nfc_dev *dev); +void nfc_unregister_rfkill(struct nfc_dev *dev); +void nfc_remove_device(struct nfc_dev *dev); void nfc_unregister_device(struct nfc_dev *dev); /** diff --git a/net/nfc/core.c b/net/nfc/core.c index 5352571b6214..a02ede8b067b 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -1147,14 +1147,14 @@ int nfc_register_device(struct nfc_dev *dev) EXPORT_SYMBOL(nfc_register_device); /** - * nfc_unregister_device - unregister a nfc device in the nfc subsystem + * nfc_unregister_rfkill - unregister a nfc device in the rfkill subsystem * * @dev: The nfc device to unregister */ -void nfc_unregister_device(struct nfc_dev *dev) +void nfc_unregister_rfkill(struct nfc_dev *dev) { - int rc; struct rfkill *rfk = NULL; + int rc; pr_debug("dev_name=%s\n", dev_name(&dev->dev)); @@ -1175,7 +1175,16 @@ void nfc_unregister_device(struct nfc_dev *dev) rfkill_unregister(rfk); rfkill_destroy(rfk); } +} +EXPORT_SYMBOL(nfc_unregister_rfkill); +/** + * nfc_remove_device - remove a nfc device in the nfc subsystem + * + * @dev: The nfc device to remove + */ +void nfc_remove_device(struct nfc_dev *dev) +{ if (dev->ops->check_presence) { del_timer_sync(&dev->check_pres_timer); cancel_work_sync(&dev->check_pres_work); @@ -1188,6 +1197,18 @@ void nfc_unregister_device(struct nfc_dev *dev) device_del(&dev->dev); mutex_unlock(&nfc_devlist_mutex); } +EXPORT_SYMBOL(nfc_remove_device); + +/** + * nfc_unregister_device - unregister a nfc device in the nfc subsystem + * + * @dev: The nfc device to unregister + */ +void nfc_unregister_device(struct nfc_dev *dev) +{ + nfc_unregister_rfkill(dev); + nfc_remove_device(dev); +} EXPORT_SYMBOL(nfc_unregister_device); static int __init nfc_init(void) diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index c4d2932c5903..b7d4952a7dcf 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -1292,6 +1292,8 @@ void nci_unregister_device(struct nci_dev *ndev) { struct nci_conn_info *conn_info, *n; + nfc_unregister_rfkill(ndev->nfc_dev); + /* This set_bit is not protected with specialized barrier, * However, it is fine because the mutex_lock(&ndev->req_lock); * in nci_close_device() will help to emit one. @@ -1309,7 +1311,7 @@ void nci_unregister_device(struct nci_dev *ndev) /* conn_info is allocated with devm_kzalloc */ } - nfc_unregister_device(ndev->nfc_dev); + nfc_remove_device(ndev->nfc_dev); } EXPORT_SYMBOL(nci_unregister_device); -- Gitee From d324f1f92fcebb2552c9ea2fd285ef9aa8702c96 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Tue, 27 Jan 2026 18:19:23 +0800 Subject: [PATCH 1253/1449] net: bridge: fix static key check ANBZ: #35228 commit e43fdee29a96f7337c8bebe7cd2f35a68b240222 stable. commit cc0cf10fdaeadf5542d64a55b5b4120d3df90b7d upstream. Fix the check if netfilter's static keys are available. netfilter defines and exports static keys if CONFIG_JUMP_LABEL is enabled. (HAVE_JUMP_LABEL is never defined.) Fixes: 971502d77faa ("bridge: netfilter: unroll NF_HOOK helper in bridge input path") Signed-off-by: Martin Kaiser Reviewed-by: Florian Westphal Reviewed-by: Nikolay Aleksandrov Link: https://patch.msgid.link/20260127101925.1754425-1-martin@kaiser.cx Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bridge/br_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 2d5b81ebbaa6..847fe03a08ee 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -260,7 +260,7 @@ static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb) int ret; net = dev_net(skb->dev); -#ifdef HAVE_JUMP_LABEL +#ifdef CONFIG_JUMP_LABEL if (!static_key_false(&nf_hooks_needed[NFPROTO_BRIDGE][NF_BR_PRE_ROUTING])) goto frame_finish; #endif -- Gitee From b4e3a523bfdd5dc4a315495c5155322a38d8d1a2 Mon Sep 17 00:00:00 2001 From: Jianbo Liu Date: Tue, 27 Jan 2026 16:52:41 +0800 Subject: [PATCH 1254/1449] net/mlx5e: Skip ESN replay window setup for IPsec crypto offload ANBZ: #35228 commit 0d434670eb0bbea93f14481067871eeeddda8eb2 stable. commit 011be342dd24b5168a5dcf408b14c3babe503341 upstream. Commit a5e400a985df ("net/mlx5e: Honor user choice of IPsec replay window size") introduced logic to setup the ESN replay window size. This logic is only valid for packet offload. However, the check to skip this block only covered outbound offloads. It was not skipped for crypto offload, causing it to fall through to the new switch statement and trigger its WARN_ON default case (for instance, if a window larger than 256 bits was configured). Fix this by amending the condition to also skip the replay window setup if the offload type is not XFRM_DEV_OFFLOAD_PACKET. Fixes: a5e400a985df ("net/mlx5e: Honor user choice of IPsec replay window size") Signed-off-by: Jianbo Liu Reviewed-by: Leon Romanovsky Reviewed-by: Simon Horman Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/1769503961-124173-5-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 5161bf51fa11..fdf664e9c46e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -350,7 +350,8 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, attrs->replay_esn.esn = sa_entry->esn_state.esn; attrs->replay_esn.esn_msb = sa_entry->esn_state.esn_msb; attrs->replay_esn.overlap = sa_entry->esn_state.overlap; - if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) + if (attrs->dir == XFRM_DEV_OFFLOAD_OUT || + x->xso.type != XFRM_DEV_OFFLOAD_PACKET) goto skip_replay_window; switch (x->replay_esn->replay_window) { -- Gitee From 1ac817253c29729bfa5198a8a94da1986a88d302 Mon Sep 17 00:00:00 2001 From: Kery Qi Date: Wed, 21 Jan 2026 19:45:15 +0800 Subject: [PATCH 1255/1449] scsi: firewire: sbp-target: Fix overflow in sbp_make_tpg() ANBZ: #35228 commit ac3a2ea06f3c86b8b05a93828eb1bc4788bf8114 stable. commit b2d6b1d443009ed4da2d69f5423ab38e5780505a upstream. The code in sbp_make_tpg() limits "tpgt" to UINT_MAX but the data type of "tpg->tport_tpgt" is u16. This causes a type truncation issue. When a user creates a TPG via configfs mkdir, for example: mkdir /sys/kernel/config/target/sbp//tpgt_70000 The value 70000 passes the "tpgt > UINT_MAX" check since 70000 is far less than 4294967295. However, when assigned to the u16 field tpg->tport_tpgt, the value is silently truncated to 4464 (70000 & 0xFFFF). This causes the value the user specified to differ from what is actually stored, leading to confusion and potential unexpected behavior. Fix this by changing the type of "tpgt" to u16 and using kstrtou16() which will properly reject values outside the u16 range. Fixes: a511ce339780 ("sbp-target: Initial merge of firewire/ieee-1394 target mode support") Signed-off-by: Kery Qi Link: https://patch.msgid.link/20260121114515.1829-2-qikeyu2017@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/target/sbp/sbp_target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 2a761bc09193..ac20c3cd7106 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1961,12 +1961,12 @@ static struct se_portal_group *sbp_make_tpg(struct se_wwn *wwn, container_of(wwn, struct sbp_tport, tport_wwn); struct sbp_tpg *tpg; - unsigned long tpgt; + u16 tpgt; int ret; if (strstr(name, "tpgt_") != name) return ERR_PTR(-EINVAL); - if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX) + if (kstrtou16(name + 5, 10, &tpgt)) return ERR_PTR(-EINVAL); if (tport->tpg) { -- Gitee From 55d3ba7974d8d1655953435c9fabed886cb34603 Mon Sep 17 00:00:00 2001 From: Han Gao Date: Wed, 28 Jan 2026 03:07:11 +0800 Subject: [PATCH 1256/1449] riscv: compat: fix COMPAT_UTS_MACHINE definition ANBZ: #35228 commit 929e568a83da5bf6fd1aa6fd9368c4e04626c424 stable. commit 0ea05c4f7527a98f5946f96c829733788934311d upstream. The COMPAT_UTS_MACHINE for riscv was incorrectly defined as "riscv". Change it to "riscv32" to reflect the correct 32-bit compat name. Fixes: 06d0e3723647 ("riscv: compat: Add basic compat data type implementation") Cc: stable@vger.kernel.org Signed-off-by: Han Gao Reviewed-by: Guo Ren (Alibaba Damo Academy) Link: https://patch.msgid.link/20260127190711.2264664-1-gaohan@iscas.ac.cn Signed-off-by: Paul Walmsley Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/riscv/include/asm/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h index 6b79287baecc..2290b8b9b16f 100644 --- a/arch/riscv/include/asm/compat.h +++ b/arch/riscv/include/asm/compat.h @@ -2,7 +2,7 @@ #ifndef __ASM_COMPAT_H #define __ASM_COMPAT_H -#define COMPAT_UTS_MACHINE "riscv\0\0" +#define COMPAT_UTS_MACHINE "riscv32\0\0" /* * Architecture specific compatibility types -- Gitee From ccb21f339a2642fa15d6a4df0617f09d698380ea Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 16 Jan 2026 02:38:32 +0800 Subject: [PATCH 1257/1449] rust: kbuild: give `--config-path` to `rustfmt` in `.rsi` target ANBZ: #35228 commit 018e9e9cae7b383c180062fef3d3e9f33f279916 stable. commit af20ae33e7dd949f2e770198e74ac8f058cb299d upstream. `rustfmt` is configured via the `.rustfmt.toml` file in the source tree, and we apply `rustfmt` to the macro expanded sources generated by the `.rsi` target. However, under an `O=` pointing to an external folder (i.e. not just a subdir), `rustfmt` will not find the file when checking the parent folders. Since the edition is configured in this file, this can lead to errors when it encounters newer syntax, e.g. error: expected one of `!`, `.`, `::`, `;`, `?`, `where`, `{`, or an operator, found `"rust_minimal"` --> samples/rust/rust_minimal.rsi:29:49 | 28 | impl ::kernel::ModuleMetadata for RustMinimal { | - while parsing this item list starting here 29 | const NAME: &'static ::kernel::str::CStr = c"rust_minimal"; | ^^^^^^^^^^^^^^ expected one of 8 possible tokens 30 | } | - the item list ends here | = note: you may be trying to write a c-string literal = note: c-string literals require Rust 2021 or later = help: pass `--edition 2024` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide A workaround is to use `RUSTFMT=n`, which is documented in the `Makefile` help for cases where macro expanded source may happen to break `rustfmt` for other reasons, but this is not one of those cases. One solution would be to pass `--edition`, but we want `rustfmt` to use the entire configuration, even if currently we essentially use the default configuration. Thus explicitly give the path to the config file to `rustfmt` instead. Reported-by: Alice Ryhl Fixes: 2f7ab1267dc9 ("Kbuild: add Rust support") Cc: stable@vger.kernel.org Reviewed-by: Nathan Chancellor Reviewed-by: Gary Guo Link: https://patch.msgid.link/20260115183832.46595-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- scripts/Makefile.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5c4e437f9d85..b897c7806711 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -294,7 +294,7 @@ $(obj)/%.o: $(src)/%.rs FORCE quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ cmd_rustc_rsi_rs = \ $(rust_common_cmd) -Zunpretty=expanded $< >$@; \ - command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@ + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) --config-path $(srctree)/.rustfmt.toml $@ $(obj)/%.rsi: $(src)/%.rs FORCE $(call if_changed_dep,rustc_rsi_rs) -- Gitee From 268c40131ac2ea0f79c0a711f25c688144281e7f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 19 Jan 2026 04:50:30 +0800 Subject: [PATCH 1258/1449] ASoC: fsl: imx-card: Do not force slot width to sample width ANBZ: #35228 commit 28a1e5e97c899938c292a089dcec3d6845096e9d stable. commit 9210f5ff6318163835d9e42ee68006be4da0f531 upstream. imx-card currently sets the slot width to the physical sample width for I2S links. This breaks controllers that use fixed-width slots (e.g. 32-bit FIFO words), causing the unused bits in the slot to contain undefined data when playing 16-bit streams. Do not override the slot width in the machine driver and let the CPU DAI select an appropriate default instead. This matches the behavior of simple-audio-card and avoids embedding controller-specific policy in the machine driver. On an i.MX8MP-based board using SAI as the I2S master with 32-bit slots, playing 16-bit audio resulted in spurious frequencies and an incorrect SAI data waveform, as the slot width was forced to 16 bits. After this change, audio artifacts are eliminated and the 16-bit samples correctly occupy the first half of the 32-bit slot, with the remaining bits padded with zeroes. Cc: stable@vger.kernel.org Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") Signed-off-by: Fabio Estevam Acked-by: Shengjiu Wang Link: https://patch.msgid.link/20260118205030.1532696-1-festevam@gmail.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/fsl/imx-card.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index bb304de5cc38..01f656e0e092 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -314,7 +314,6 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream, SND_SOC_DAIFMT_PDM; } else { slots = 2; - slot_width = params_physical_width(params); fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) | SND_SOC_DAIFMT_I2S; } -- Gitee From 1d0dd06c533bc6ebe8a0dadf7e3f24eb94a34aed Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Sat, 13 Dec 2025 16:36:43 +0800 Subject: [PATCH 1259/1449] scsi: be2iscsi: Fix a memory leak in beiscsi_boot_get_sinfo() ANBZ: #35228 commit 441d129ba899e6c315304334b41559987fe822b9 stable. commit 4747bafaa50115d9667ece446b1d2d4aba83dc7f upstream. If nonemb_cmd->va fails to be allocated, free the allocation previously made by alloc_mcc_wrb(). Fixes: 50a4b824be9e ("scsi: be2iscsi: Fix to make boot discovery non-blocking") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Link: https://patch.msgid.link/20251213083643.301240-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/be2iscsi/be_mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 4e899ec1477d..b1cba986f0fb 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -1025,6 +1025,7 @@ unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba) &nonemb_cmd->dma, GFP_KERNEL); if (!nonemb_cmd->va) { + free_mcc_wrb(ctrl, tag); mutex_unlock(&ctrl->mbox_lock); return 0; } -- Gitee From 28e70068aa289c8913d8d2d742697cdf16e867ef Mon Sep 17 00:00:00 2001 From: Zhang Heng Date: Mon, 26 Jan 2026 09:49:52 +0800 Subject: [PATCH 1260/1449] ASoC: amd: yc: Add DMI quirk for Acer TravelMate P216-41-TCO ANBZ: #35228 commit c2fc0aae3cf42b2246f3430b3295c1637b6821fb stable. commit 9502b7df5a3c7e174f74f20324ac1fe781fc5c2d upstream. Add a DMI quirk for the Acer TravelMate P216-41-TCO fixing the issue where the internal microphone was not detected. Link: https://bugzilla.kernel.org/show_bug.cgi?id=220983 Cc: stable@vger.kernel.org Signed-off-by: Zhang Heng Link: https://patch.msgid.link/20260126014952.3674450-1-zhangheng@kylinos.cn Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/amd/yc/acp6x-mach.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 54dac6bfc9d1..00e4ffeb6fb0 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -661,6 +661,14 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "RB"), + DMI_MATCH(DMI_BOARD_NAME, "XyloD5_RBU"), + } + }, + {} }; -- Gitee From 109bd8232a846c6de9b367bca4c7820a1270ddb7 Mon Sep 17 00:00:00 2001 From: Tagir Garaev Date: Wed, 21 Jan 2026 23:24:35 +0800 Subject: [PATCH 1261/1449] ASoC: Intel: sof_es8336: fix headphone GPIO logic inversion ANBZ: #35228 commit 2f45c46661911b923eb890aacd33d75278a0b014 stable. commit 213c4e51267fd825cd21a08a055450cac7e0b7fb upstream. The headphone GPIO should be set to the inverse of speaker_en. When speakers are enabled, headphones should be disabled and vice versa. Currently both GPIOs are set to the same value (speaker_en), causing audio to play through both speakers and headphones simultaneously when headphones are plugged in. Tested on Huawei Matebook (BOD-WXX9) with ES8336 codec. Fixes: 6e1ff1459e00 ("ASoC: Intel: sof_es8336: support a separate gpio to control headphone") Signed-off-by: Tagir Garaev Link: https://patch.msgid.link/20260121152435.101698-1-tgaraev653@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/intel/boards/sof_es8336.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 9904a9e33ccc..c9d9381c7679 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -120,7 +120,7 @@ static void pcm_pop_work_events(struct work_struct *work) gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en); if (quirk & SOF_ES8336_HEADPHONE_GPIO) - gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en); + gpiod_set_value_cansleep(priv->gpio_headphone, !priv->speaker_en); } -- Gitee From de8b6378e3f2ea584458efda0747bbb2b7c97344 Mon Sep 17 00:00:00 2001 From: Denis Sergeev Date: Mon, 26 Jan 2026 11:59:14 +0800 Subject: [PATCH 1262/1449] gpiolib: acpi: use BIT_ULL() for u64 mask in address space handler ANBZ: #35228 commit 0368794dc28a153e06c5dc2073faeab7a9f5e655 stable. commit c0ae43d303e45764918fa8c1dc13d6a5db59c479 upstream. The BIT() macro uses unsigned long, which is 32 bits on 32-bit architectures. When iterating over GPIO pins with index >= 32, the expression (*value & BIT(i)) causes undefined behavior due to shifting by a value >= type width. Since 'value' is a pointer to u64, use BIT_ULL() to ensure correct 64-bit mask on all architectures. Found by Linux Verification Center (linuxtesting.org) with Svace. Fixes: 2c4d00cb8fc5 ("gpiolib: acpi: Use BIT() macro to increase readability") Signed-off-by: Denis Sergeev Reviewed-by: Mika Westerberg Link: https://lore.kernel.org/r/20260126035914.16586-1-denserg.edu@gmail.com Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpiolib-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 86de8740c0d4..69d4297ae575 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -1228,7 +1228,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, mutex_unlock(&achip->conn_lock); if (function == ACPI_WRITE) - gpiod_set_raw_value_cansleep(desc, !!(*value & BIT(i))); + gpiod_set_raw_value_cansleep(desc, !!(*value & BIT_ULL(i))); else *value |= (u64)gpiod_get_raw_value_cansleep(desc) << i; } -- Gitee From aba3985eb98d1149c9ec5938f8e9731bc89cec43 Mon Sep 17 00:00:00 2001 From: Sai Sree Kartheek Adivi Date: Wed, 28 Jan 2026 21:35:54 +0800 Subject: [PATCH 1263/1449] dma/pool: distinguish between missing and exhausted atomic pools ANBZ: #35228 commit be1cebabb3cd2627f8e94ac22ed7f267c05e27d8 stable. commit 56c430c7f06d838fe3b2077dbbc4cc0bf992312b upstream. Currently, dma_alloc_from_pool() unconditionally warns and dumps a stack trace when an allocation fails, with the message "Failed to get suitable pool". This conflates two distinct failure modes: 1. Configuration error: No atomic pool is available for the requested DMA mask (a fundamental system setup issue) 2. Resource Exhaustion: A suitable pool exists but is currently full (a recoverable runtime state) This lack of distinction prevents drivers from using __GFP_NOWARN to suppress error messages during temporary pressure spikes, such as when awaiting synchronous reclaim of descriptors. Refactor the error handling to distinguish these cases: - If no suitable pool is found, keep the unconditional WARN regarding the missing pool. - If a pool was found but is exhausted, respect __GFP_NOWARN and update the warning message to explicitly state "DMA pool exhausted". Fixes: 9420139f516d ("dma-pool: fix coherent pool allocations for IOMMU mappings") Signed-off-by: Sai Sree Kartheek Adivi Reviewed-by: Robin Murphy Signed-off-by: Marek Szyprowski Link: https://lore.kernel.org/r/20260128133554.3056582-1-s-adivi@ti.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/dma/pool.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index b3b9c7ec5fc5..8a15b5008b20 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -268,15 +268,20 @@ struct page *dma_alloc_from_pool(struct device *dev, size_t size, { struct gen_pool *pool = NULL; struct page *page; + bool pool_found = false; while ((pool = dma_guess_pool(pool, gfp))) { + pool_found = true; page = __dma_alloc_from_pool(dev, size, pool, cpu_addr, phys_addr_ok); if (page) return page; } - WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev)); + if (pool_found) + WARN(!(gfp & __GFP_NOWARN), "DMA pool exhausted for %s\n", dev_name(dev)); + else + WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev)); return NULL; } -- Gitee From 4d222bd957783f6758e946a1497d82e4a9f8de56 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 5 Jan 2026 23:05:08 +0800 Subject: [PATCH 1264/1449] pinctrl: meson: mark the GPIO controller as sleeping ANBZ: #35228 commit 8519c9231ce238a3b35c884d579c9f5d05351798 stable. commit 28f24068387169722b508bba6b5257cb68b86e74 upstream. The GPIO controller is configured as non-sleeping but it uses generic pinctrl helpers which use a mutex for synchronization. This can cause the following lockdep splat with shared GPIOs enabled on boards which have multiple devices using the same GPIO: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:591 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 142, name: kworker/u25:3 preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 INFO: lockdep is turned off. irq event stamp: 46379 hardirqs last enabled at (46379): [] _raw_spin_unlock_irqrestore+0x74/0x78 hardirqs last disabled at (46378): [] _raw_spin_lock_irqsave+0x84/0x88 softirqs last enabled at (46330): [] handle_softirqs+0x4c4/0x4dc softirqs last disabled at (46295): [] __do_softirq+0x14/0x20 CPU: 1 UID: 0 PID: 142 Comm: kworker/u25:3 Tainted: G C 6.19.0-rc4-next-20260105+ #11963 PREEMPT Tainted: [C]=CRAP Hardware name: Khadas VIM3 (DT) Workqueue: events_unbound deferred_probe_work_func Call trace: show_stack+0x18/0x24 (C) dump_stack_lvl+0x90/0xd0 dump_stack+0x18/0x24 __might_resched+0x144/0x248 __might_sleep+0x48/0x98 __mutex_lock+0x5c/0x894 mutex_lock_nested+0x24/0x30 pinctrl_get_device_gpio_range+0x44/0x128 pinctrl_gpio_set_config+0x40/0xdc gpiochip_generic_config+0x28/0x3c gpio_do_set_config+0xa8/0x194 gpiod_set_config+0x34/0xfc gpio_shared_proxy_set_config+0x6c/0xfc [gpio_shared_proxy] gpio_do_set_config+0xa8/0x194 gpiod_set_transitory+0x4c/0xf0 gpiod_configure_flags+0xa4/0x480 gpiod_find_and_request+0x1a0/0x574 gpiod_get_index+0x58/0x84 devm_gpiod_get_index+0x20/0xb4 devm_gpiod_get+0x18/0x24 mmc_pwrseq_emmc_probe+0x40/0xb8 platform_probe+0x5c/0xac really_probe+0xbc/0x298 __driver_probe_device+0x78/0x12c driver_probe_device+0xdc/0x164 __device_attach_driver+0xb8/0x138 bus_for_each_drv+0x80/0xdc __device_attach+0xa8/0x1b0 Fixes: 6ac730951104 ("pinctrl: add driver for Amlogic Meson SoCs") Cc: stable@vger.kernel.org Reported-by: Marek Szyprowski Closes: https://lore.kernel.org/all/00107523-7737-4b92-a785-14ce4e93b8cb@samsung.com/ Signed-off-by: Bartosz Golaszewski Reviewed-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/meson/pinctrl-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 5cc00fdc48d8..4f613f908208 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -618,7 +618,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) pc->chip.set = meson_gpio_set; pc->chip.base = -1; pc->chip.ngpio = pc->data->num_pins; - pc->chip.can_sleep = false; + pc->chip.can_sleep = true; ret = gpiochip_add_data(&pc->chip, pc); if (ret) { -- Gitee From 64a675f24b9cc114a4747c82135be285fcaf7801 Mon Sep 17 00:00:00 2001 From: Martin Larsson Date: Wed, 21 Jan 2026 20:57:22 +0800 Subject: [PATCH 1265/1449] gpio: pca953x: mask interrupts in irq shutdown ANBZ: #35228 commit 122751f43f930799a4ba818edc73047d82dee237 stable. commit d02f20a4de0c498fbba2b0e3c1496e72c630a91e upstream. In the existing implementation irq_shutdown does not mask the interrupts in hardware. This can cause spurious interrupts from the IO expander. Add masking to irq_shutdown to prevent spurious interrupts. Cc: stable@vger.kernel.org Signed-off-by: Martin Larsson Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20260121125631.2758346-1-martin.larsson@actia.se Signed-off-by: Bartosz Golaszewski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-pca953x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 633493b860f2..bf701766f4d0 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -811,6 +811,8 @@ static void pca953x_irq_shutdown(struct irq_data *d) clear_bit(hwirq, chip->irq_trig_fall); clear_bit(hwirq, chip->irq_trig_level_low); clear_bit(hwirq, chip->irq_trig_level_high); + + pca953x_irq_mask(d); } static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p) -- Gitee From 8c0e2182fc99d22bc2d97fd66bb782680110ab78 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 12 Jan 2026 21:43:24 +0800 Subject: [PATCH 1266/1449] scsi: qla2xxx: edif: Fix dma_free_coherent() size ANBZ: #35228 commit a9c96f113a5f3b274b8fb51ff778c2fa800f1cd2 stable. commit 56bd3c0f749f45793d1eae1d0ddde4255c749bf6 upstream. Earlier in the function, the ha->flt buffer is allocated with size sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE but freed in the error path with size SFP_DEV_SIZE. Fixes: 84318a9f01ce ("scsi: qla2xxx: edif: Add send, receive, and accept for auth_els") Cc: stable@vger.kernel.org Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20260112134326.55466-2-fourier.thomas@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ef894dc80b8f..d10389ee92ba 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4482,7 +4482,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, fail_elsrej: dma_pool_destroy(ha->purex_dma_pool); fail_flt: - dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, + dma_free_coherent(&ha->pdev->dev, sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, ha->flt, ha->flt_dma); fail_flt_buffer: -- Gitee From 498ce61ca8ce3d5290fc9b49edc5afcbdcb55bc7 Mon Sep 17 00:00:00 2001 From: Kohei Enju Date: Sun, 18 Jan 2026 00:00:45 +0800 Subject: [PATCH 1267/1449] efivarfs: fix error propagation in efivar_entry_get() ANBZ: #35228 commit 510a16f1c5c1690b33504052bc13fbc2772c23f8 stable. commit 4b22ec1685ce1fc0d862dcda3225d852fb107995 upstream. efivar_entry_get() always returns success even if the underlying __efivar_entry_get() fails, masking errors. This may result in uninitialized heap memory being copied to userspace in the efivarfs_file_read() path. Fix it by returning the error from __efivar_entry_get(). Fixes: 2d82e6227ea1 ("efi: vars: Move efivar caching layer into efivarfs") Cc: # v6.1+ Signed-off-by: Kohei Enju Signed-off-by: Ard Biesheuvel Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/efivarfs/vars.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c index 13bc60698955..b10aa5afd7f7 100644 --- a/fs/efivarfs/vars.c +++ b/fs/efivarfs/vars.c @@ -609,7 +609,7 @@ int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, err = __efivar_entry_get(entry, attributes, size, data); efivar_unlock(); - return 0; + return err; } /** -- Gitee From d6c562e8d947f6c8c3dd3a4a33689494ab94fbf8 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 28 Jan 2026 03:27:25 +0800 Subject: [PATCH 1268/1449] mptcp: only reset subflow errors when propagated ANBZ: #35228 commit d761d42be060bcf6a72edd155a85947ea3458e1e stable. commit dccf46179ddd6c04c14be8ed584dc54665f53f0e upstream. Some subflow socket errors need to be reported to the MPTCP socket: the initial subflow connect (MP_CAPABLE), and the ones from the fallback sockets. The others are not propagated. The issue is that sock_error() was used to retrieve the error, which was also resetting the sk_err field. Because of that, when notifying the userspace about subflow close events later on from the MPTCP worker, the ssk->sk_err field was always 0. Now, the error (sk_err) is only reset when propagating it to the msk. Fixes: 15cc10453398 ("mptcp: deliver ssk errors to msk") Cc: stable@vger.kernel.org Reviewed-by: Geliang Tang Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-3-7f71e1bc4feb@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 0dbf2e0d9762..18e81b306a6f 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -796,11 +796,8 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk) static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk) { - int err = sock_error(ssk); int ssk_state; - - if (!err) - return false; + int err; /* only propagate errors on fallen-back sockets or * on MPC connect @@ -808,6 +805,10 @@ static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk) if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(mptcp_sk(sk))) return false; + err = sock_error(ssk); + if (!err) + return false; + /* We need to propagate only transition to CLOSE state. * Orphaned socket will see such state change via * subflow_sched_work_if_closed() and that path will properly -- Gitee From 9e883cd452e86b316725934aa75549e5efb94dcb Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 28 Jan 2026 03:27:24 +0800 Subject: [PATCH 1269/1449] selftests: mptcp: check no dup close events after error ANBZ: #35228 commit 8b5061c3400a747887afdf6731b51dccf377aa58 stable. commit 8467458dfa61b37e259e3485a5d3e415d08193c1 upstream. This validates the previous commit: subflow closed events are re-sent with less info when the initial subflow is disconnected after an error and each time a subflow is closed after that. In this new test, the userspace PM is involved because that's how it was discovered, but it is not specific to it. The initial subflow is terminated with a RESET, and that will cause the subflow disconnect. Then, a new subflow is initiated, but also got rejected, which cause a second subflow closed event, but not a third one. While at it, in case of failure to get the expected amount of events, the events are printed. The 'Fixes' tag here below is the same as the one from the previous commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID. Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events") Cc: stable@vger.kernel.org Reviewed-by: Geliang Tang Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-2-7f71e1bc4feb@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../testing/selftests/net/mptcp/mptcp_join.sh | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index 2c025c73e19f..e0cf60ff3a15 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -3569,11 +3569,32 @@ chk_evt_nr() count=$(grep -cw "type:${evt}" "${evts}") if [ "${count}" != "${exp}" ]; then fail_test "got ${count} events, expected ${exp}" + cat "${evts}" else print_ok fi } +# $1: ns ; $2: event type ; $3: expected count +wait_event() +{ + local ns="${1}" + local evt_name="${2}" + local exp="${3}" + + local evt="${!evt_name}" + local evts="${evts_ns1}" + local count + + [ "${ns}" == "ns2" ] && evts="${evts_ns2}" + + for _ in $(seq 100); do + count=$(grep -cw "type:${evt}" "${evts}") + [ "${count}" -ge "${exp}" ] && break + sleep 0.1 + done +} + userspace_tests() { # userspace pm type prevents add_addr @@ -3730,6 +3751,36 @@ userspace_tests() kill_events_pids mptcp_lib_kill_group_wait $tests_pid fi + + # userspace pm no duplicated spurious close events after an error + if reset_with_events "userspace pm no dup close events after error" && + continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then + set_userspace_pm $ns2 + pm_nl_set_limits $ns1 0 2 + { timeout_test=120 test_linkfail=128 speed=slow \ + run_tests $ns1 $ns2 10.0.1.1 & } 2>/dev/null + local tests_pid=$! + wait_event ns2 MPTCP_LIB_EVENT_ESTABLISHED 1 + userspace_pm_add_sf $ns2 10.0.3.2 20 + chk_mptcp_info subflows 1 subflows 1 + chk_subflows_total 2 2 + + # force quick loss + ip netns exec $ns2 sysctl -q net.ipv4.tcp_syn_retries=1 + if ip netns exec "${ns1}" ${iptables} -A INPUT -s "10.0.1.2" \ + -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset && + ip netns exec "${ns2}" ${iptables} -A INPUT -d "10.0.1.2" \ + -p tcp --tcp-option 30 -j REJECT --reject-with tcp-reset; then + wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 1 + wait_event ns1 MPTCP_LIB_EVENT_SUB_CLOSED 1 + chk_subflows_total 1 1 + userspace_pm_add_sf $ns2 10.0.1.2 0 + wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 + chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 + fi + kill_events_pids + mptcp_lib_kill_group_wait $tests_pid + fi } endpoint_tests() -- Gitee From 274264eb6557397af64219052c28b9b39429f0ac Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 28 Jan 2026 03:27:26 +0800 Subject: [PATCH 1270/1449] selftests: mptcp: check subflow errors in close events ANBZ: #35228 commit ba58cd70a42232a1c7292dedc3a1d390ae2a0784 stable. commit 2ef9e3a3845d0a20b62b01f5b731debd0364688d upstream. This validates the previous commit: subflow closed events should contain an error field when a subflow got closed with an error, e.g. reset or timeout. For this test, the chk_evt_nr helper has been extended to check attributes in the matched events. In this test, the 2 subflow closed events should have an error. The 'Fixes' tag here below is the same as the one from the previous commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID. Fixes: 15cc10453398 ("mptcp: deliver ssk errors to msk") Cc: stable@vger.kernel.org Reviewed-by: Geliang Tang Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-4-7f71e1bc4feb@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../testing/selftests/net/mptcp/mptcp_join.sh | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index e0cf60ff3a15..c88d78639948 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -3544,21 +3544,28 @@ userspace_pm_chk_get_addr() fi } -# $1: ns ; $2: event type ; $3: count +# $1: ns ; $2: event type ; $3: count ; [ $4: attr ; $5: attr count ] chk_evt_nr() { local ns=${1} local evt_name="${2}" local exp="${3}" + local attr="${4}" + local attr_exp="${5}" local evts="${evts_ns1}" local evt="${!evt_name}" + local attr_name local count + if [ -n "${attr}" ]; then + attr_name=", ${attr}: ${attr_exp}" + fi + evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_ [ "${ns}" == "ns2" ] && evts="${evts_ns2}" - print_check "event ${ns} ${evt_name} (${exp})" + print_check "event ${ns} ${evt_name} (${exp}${attr_name})" if [[ "${evt_name}" = "LISTENER_"* ]] && ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then @@ -3570,6 +3577,16 @@ chk_evt_nr() if [ "${count}" != "${exp}" ]; then fail_test "got ${count} events, expected ${exp}" cat "${evts}" + return + elif [ -z "${attr}" ]; then + print_ok + return + fi + + count=$(grep -w "type:${evt}" "${evts}" | grep -c ",${attr}:") + if [ "${count}" != "${attr_exp}" ]; then + fail_test "got ${count} event attributes, expected ${attr_exp}" + grep -w "type:${evt}" "${evts}" else print_ok fi @@ -3776,7 +3793,7 @@ userspace_tests() chk_subflows_total 1 1 userspace_pm_add_sf $ns2 10.0.1.2 0 wait_event ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 - chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 + chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2 error 2 fi kill_events_pids mptcp_lib_kill_group_wait $tests_pid -- Gitee From d36927984cb0360d626d1b44b4ec20c4e78fe33d Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 28 Jan 2026 03:27:27 +0800 Subject: [PATCH 1271/1449] selftests: mptcp: join: fix local endp not being tracked ANBZ: #35228 commit 4bed436cdef70da05d197503a9b71c5536316958 stable. commit c5d5ecf21fdd9ce91e6116feb3aa83cee73352cc upstream. When running this mptcp_join.sh selftest on older kernel versions not supporting local endpoints tracking, this test fails because 3 MP_JOIN ACKs have been received, while only 2 were expected. It is not clear why only 2 MP_JOIN ACKs were expected on old kernel versions, while 3 MP_JOIN SYN and SYN+ACK were expected. When testing on the v5.15.197 kernel, 3 MP_JOIN ACKs are seen, which is also what is expected in the selftests included in this kernel version, see commit f4480eaad489 ("selftests: mptcp: add missing join check"). Switch the expected MP_JOIN ACKs to 3. While at it, move this chk_join_nr helper out of the special condition for older kernel versions as it is now the same as with more recent ones. Also, invert the condition to be more logical: what's expected on newer kernel versions having such helper first. Fixes: d4c81bbb8600 ("selftests: mptcp: join: support local endpoint being tracked or not") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-5-7f71e1bc4feb@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/mptcp/mptcp_join.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index c88d78639948..c571563a42c5 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -2203,17 +2203,16 @@ signal_address_tests() ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 + chk_join_nr 3 3 3 # It is not directly linked to the commit introducing this # symbol but for the parent one which is linked anyway. - if ! mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then - chk_join_nr 3 3 2 - chk_add_nr 4 4 - else - chk_join_nr 3 3 3 + if mptcp_lib_kallsyms_has "mptcp_pm_subflow_check_next$"; then # the server will not signal the address terminating # the MPC subflow chk_add_nr 3 3 + else + chk_add_nr 4 4 fi fi } -- Gitee From d5071e315aa0a37b78a953f096fd1f4441887c9d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 21 Jan 2026 19:27:30 +0800 Subject: [PATCH 1272/1449] flex_proportions: make fprop_new_period() hardirq safe ANBZ: #35228 commit 884b2590ffcc7222cbbd6298051f4c243cc36f5d stable. commit dd9e2f5b38f1fdd49b1ab6d3a85f81c14369eacc upstream. Bernd has reported a lockdep splat from flexible proportions code that is essentially complaining about the following race: run_timer_softirq - we are in softirq context call_timer_fn writeout_period fprop_new_period write_seqcount_begin(&p->sequence); ... blk_mq_end_request() blk_update_request() ext4_end_bio() folio_end_writeback() __wb_writeout_add() __fprop_add_percpu_max() if (unlikely(max_frac < FPROP_FRAC_BASE)) { fprop_fraction_percpu() seq = read_seqcount_begin(&p->sequence); - sees odd sequence so loops indefinitely Note that a deadlock like this is only possible if the bdi has configured maximum fraction of writeout throughput which is very rare in general but frequent for example for FUSE bdis. To fix this problem we have to make sure write section of the sequence counter is irqsafe. Link: https://lkml.kernel.org/r/20260121112729.24463-2-jack@suse.cz Fixes: a91befde3503 ("lib/flex_proportions.c: remove local_irq_ops in fprop_new_period()") Signed-off-by: Jan Kara Reported-by: Bernd Schubert Link: https://lore.kernel.org/all/9b845a47-9aee-43dd-99bc-1a82bea00442@bsbernd.com/ Reviewed-by: Matthew Wilcox (Oracle) Cc: Joanne Koong Cc: Miklos Szeredi Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- lib/flex_proportions.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/flex_proportions.c b/lib/flex_proportions.c index 83332fefa6f4..27193fa008f6 100644 --- a/lib/flex_proportions.c +++ b/lib/flex_proportions.c @@ -64,13 +64,14 @@ void fprop_global_destroy(struct fprop_global *p) bool fprop_new_period(struct fprop_global *p, int periods) { s64 events = percpu_counter_sum(&p->events); + unsigned long flags; /* * Don't do anything if there are no events. */ if (events <= 1) return false; - preempt_disable_nested(); + local_irq_save(flags); write_seqcount_begin(&p->sequence); if (periods < 64) events -= events >> periods; @@ -78,7 +79,7 @@ bool fprop_new_period(struct fprop_global *p, int periods) percpu_counter_add(&p->events, -events); p->period += periods; write_seqcount_end(&p->sequence); - preempt_enable_nested(); + local_irq_restore(flags); return true; } -- Gitee From 6a7c7f096a3739e259d059bd13f1ff17acae03b0 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 23 Jul 2025 23:39:40 +0800 Subject: [PATCH 1273/1449] scripts: generate_rust_analyzer: Add compiler_builtins -> core dep ANBZ: #35228 commit cdaf07ec0b6980f705b44d6211b77076ffe930d4 stable. commit 5157c328edb35bac05ce77da473c3209d20e0bbb upstream. Add a dependency edge from `compiler_builtins` to `core` to `scripts/generate_rust_analyzer.py` to match `rust/Makefile`. This has been incorrect since commit 8c4555ccc55c ("scripts: add `generate_rust_analyzer.py`") Signed-off-by: Tamir Duberstein Reviewed-by: Jesung Yang Acked-by: Benno Lossin Fixes: 8c4555ccc55c ("scripts: add `generate_rust_analyzer.py`") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250723-rust-analyzer-pin-init-v1-1-3c6956173c78@kernel.org Signed-off-by: Miguel Ojeda Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- scripts/generate_rust_analyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index c99173e4b8f3..99d5b177a43c 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -73,7 +73,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): append_crate( "compiler_builtins", srctree / "rust" / "compiler_builtins.rs", - [], + ["core"], ) append_crate( -- Gitee From 4ee6170c2fc24a83715df59d123e76b12dd32165 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 31 Oct 2025 00:34:56 +0800 Subject: [PATCH 1274/1449] drm/imx/tve: fix probe device leak ANBZ: #35228 commit 9a15d3fdc22d48f597792aee0cf1bf0947fc62e6 stable. commit e535c23513c63f02f67e3e09e0787907029efeaf upstream. Make sure to drop the reference taken to the DDC device during probe on probe failure (e.g. probe deferral) and on driver unbind. Fixes: fcbc51e54d2a ("staging: drm/imx: Add support for Television Encoder (TVEv2)") Cc: stable@vger.kernel.org # 3.10 Cc: Philipp Zabel Reviewed-by: Frank Li Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251030163456.15807-1-johan@kernel.org Signed-off-by: Maxime Ripard Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/imx/ipuv3/imx-tve.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/imx/ipuv3/imx-tve.c b/drivers/gpu/drm/imx/ipuv3/imx-tve.c index d6832f506322..b9391ccb6d3c 100644 --- a/drivers/gpu/drm/imx/ipuv3/imx-tve.c +++ b/drivers/gpu/drm/imx/ipuv3/imx-tve.c @@ -521,6 +521,13 @@ static const struct component_ops imx_tve_ops = { .bind = imx_tve_bind, }; +static void imx_tve_put_device(void *_dev) +{ + struct device *dev = _dev; + + put_device(dev); +} + static int imx_tve_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -542,6 +549,12 @@ static int imx_tve_probe(struct platform_device *pdev) if (ddc_node) { tve->ddc = of_find_i2c_adapter_by_node(ddc_node); of_node_put(ddc_node); + if (tve->ddc) { + ret = devm_add_action_or_reset(dev, imx_tve_put_device, + &tve->ddc->dev); + if (ret) + return ret; + } } tve->mode = of_get_tve_mode(np); -- Gitee From 8db892d698a03d33a7949b4486734fdd1d92ded0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 17 Jan 2026 06:33:05 +0800 Subject: [PATCH 1275/1449] drm/amdgpu/soc21: fix xclk for APUs ANBZ: #35228 commit cbf4d79e5c619450eec11f5b85e49758342fdea6 stable. commit e7fbff9e7622a00c2b53cb14df481916f0019742 upstream. The reference clock is supposed to be 100Mhz, but it appears to actually be slightly lower (99.81Mhz). Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14451 Reviewed-by: Jesse Zhang Signed-off-by: Alex Deucher (cherry picked from commit 637fee3954d4bd509ea9d95ad1780fc174489860) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/soc21.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index 7819f5d584f5..115fdb6a25fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -218,7 +218,13 @@ static u32 soc21_get_config_memsize(struct amdgpu_device *adev) static u32 soc21_get_xclk(struct amdgpu_device *adev) { - return adev->clock.spll.reference_freq; + u32 reference_clock = adev->clock.spll.reference_freq; + + /* reference clock is actually 99.81 Mhz rather than 100 Mhz */ + if ((adev->flags & AMD_IS_APU) && reference_clock == 10000) + return 9981; + + return reference_clock; } -- Gitee From de5487d6e95a0e430cd740589e62db85df21d9a9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 29 Jan 2026 09:51:08 +0800 Subject: [PATCH 1276/1449] drm/amdgpu/gfx10: fix wptr reset in KGQ init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit c61c93218956c29e4e3ea5998c16f47525a22dc0 stable. commit cc4f433b14e05eaa4a98fd677b836e9229422387 upstream. wptr is a 64 bit value and we need to update the full value, not just 32 bits. Align with what we already do for KCQs. Reviewed-by: Timur Kristóf Reviewed-by: Jesse Zhang Signed-off-by: Alex Deucher (cherry picked from commit e80b1d1aa1073230b6c25a1a72e88f37e425ccda) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 53c99bc6abb3..1c29b4d04a2c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -6459,7 +6459,7 @@ static int gfx_v10_0_gfx_init_queue(struct amdgpu_ring *ring) memcpy_toio(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd)); /* reset the ring */ ring->wptr = 0; - *ring->wptr_cpu_addr = 0; + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0); amdgpu_ring_clear_ring(ring); } -- Gitee From d19cc5835e15cf1b42edb05e1310357cd590d658 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 29 Jan 2026 07:09:03 +0800 Subject: [PATCH 1277/1449] drm/amdgpu/gfx11: fix wptr reset in KGQ init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e618b52a1589a822d313ba64d352ae4eb5052164 stable. commit b1f810471c6a6bd349f7f9f2f2fed96082056d46 upstream. wptr is a 64 bit value and we need to update the full value, not just 32 bits. Align with what we already do for KCQs. Reviewed-by: Timur Kristóf Reviewed-by: Jesse Zhang Signed-off-by: Alex Deucher (cherry picked from commit 1f16866bdb1daed7a80ca79ae2837a9832a74fbc) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 7591a2803ae1..ed3e47a7eca1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -3699,7 +3699,7 @@ static int gfx_v11_0_gfx_init_queue(struct amdgpu_ring *ring) memcpy_toio(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd)); /* reset the ring */ ring->wptr = 0; - *ring->wptr_cpu_addr = 0; + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0); amdgpu_ring_clear_ring(ring); } -- Gitee From 4ed0b7195c5b11ac4a4045ded12c98c3402001a9 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Mon, 26 Jan 2026 20:12:26 +0800 Subject: [PATCH 1278/1449] gpio: rockchip: Stop calling pinctrl for set_direction ANBZ: #35228 commit 38c32baf6d2c79ba6c432454fdad7db19a638334 stable. commit 7ca497be00163610afb663867db24ac408752f13 upstream. Marking the whole controller as sleeping due to the pinctrl calls in the .direction_{input,output} callbacks has the unfortunate side effect that legitimate invocations of .get and .set, which cannot themselves sleep, in atomic context now spew WARN()s from gpiolib. However, as Heiko points out, the driver doing this is a bit silly to begin with, as the pinctrl .gpio_set_direction hook doesn't even care about the direction, the hook is only used to claim the mux. And sure enough, the .gpio_request_enable hook exists to serve this very purpose, so switch to that and remove the problematic business entirely. Cc: stable@vger.kernel.org Fixes: 20cf2aed89ac ("gpio: rockchip: mark the GPIO controller as sleeping") Suggested-by: Heiko Stuebner Signed-off-by: Robin Murphy Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/bddc0469f25843ca5ae0cf578ab3671435ae98a7.1769429546.git.robin.murphy@arm.com Signed-off-by: Bartosz Golaszewski [ Backport past pinctrl API change for the deleted calls ] Signed-off-by: Robin Murphy Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-rockchip.c | 8 -------- drivers/pinctrl/pinctrl-rockchip.c | 9 ++++----- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index 4173ea19550e..752bbc0c3d9d 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -157,12 +156,6 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip, unsigned long flags; u32 data = input ? 0 : 1; - - if (input) - pinctrl_gpio_direction_input(bank->pin_base + offset); - else - pinctrl_gpio_direction_output(bank->pin_base + offset); - raw_spin_lock_irqsave(&bank->slock, flags); rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); raw_spin_unlock_irqrestore(&bank->slock, flags); @@ -584,7 +577,6 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) gc->ngpio = bank->nr_pins; gc->label = bank->name; gc->parent = bank->dev; - gc->can_sleep = true; ret = gpiochip_add_data(gc, bank); if (ret) { diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index b5a02335617d..0c2382480c24 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2749,10 +2749,9 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset, - bool input) +static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) { struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct rockchip_pin_bank *bank; @@ -2766,7 +2765,7 @@ static const struct pinmux_ops rockchip_pmx_ops = { .get_function_name = rockchip_pmx_get_func_name, .get_function_groups = rockchip_pmx_get_groups, .set_mux = rockchip_pmx_set, - .gpio_set_direction = rockchip_pmx_gpio_set_direction, + .gpio_request_enable = rockchip_pmx_gpio_request_enable, }; /* -- Gitee From c48922bd5338bc8327b751b6a1c3924008f20dd3 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 29 Jan 2026 04:33:48 +0800 Subject: [PATCH 1279/1449] arm64/fpsimd: signal: Mandate SVE payload for streaming-mode state ANBZ: #35228 commit 15110f9cdc877d9ce439e7b0da7bb99b9067021e stable. commit b465ace42620970e840c7aeb2c44a6e3b1002fec upstream. Non-streaming SVE state may be preserved without an SVE payload, in which case the SVE context only has a header with VL==0, and all state can be restored from the FPSIMD context. Streaming SVE state is always preserved with an SVE payload, where the SVE context header has VL!=0, and the SVE_SIG_FLAG_SM flag is set. The kernel never preserves an SVE context where SVE_SIG_FLAG_SM is set without an SVE payload. However, restore_sve_fpsimd_context() doesn't forbid restoring such a context, and will handle this case by clearing PSTATE.SM and restoring the FPSIMD context into non-streaming mode, which isn't consistent with the SVE_SIG_FLAG_SM flag. Forbid this case, and mandate an SVE payload when the SVE_SIG_FLAG_SM flag is set. This avoids an awkward ABI quirk and reduces the risk that later rework to this code permits configuring a task with PSTATE.SM==1 and fp_type==FP_STATE_FPSIMD. I've marked this as a fix given that we never intended to support this case, and we don't want anyone to start relying upon the old behaviour once we re-enable SME. Fixes: 85ed24dad290 ("arm64/sme: Implement streaming SVE signal handling") Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Marc Zyngier Cc: Mark Brown Cc: Will Deacon Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20250508132644.1395904-4-mark.rutland@arm.com Signed-off-by: Will Deacon Stable-dep-of: d2907cbe9ea0 ("arm64/fpsimd: signal: Fix restoration of SVE context") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm64/kernel/signal.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index f24d0c19a9c4..d61c3527752d 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -302,6 +302,7 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) unsigned int vl, vq; struct user_fpsimd_state fpsimd; u16 user_vl, flags; + bool sm; if (user->sve_size < sizeof(*user->sve)) return -EINVAL; @@ -311,7 +312,8 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) if (err) return err; - if (flags & SVE_SIG_FLAG_SM) { + sm = flags & SVE_SIG_FLAG_SM; + if (sm) { if (!system_supports_sme()) return -EINVAL; @@ -331,7 +333,16 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) if (user_vl != vl) return -EINVAL; - if (user->sve_size == sizeof(*user->sve)) { + /* + * Non-streaming SVE state may be preserved without an SVE payload, in + * which case the SVE context only has a header with VL==0, and all + * state can be restored from the FPSIMD context. + * + * Streaming SVE state is always preserved with an SVE payload. For + * consistency and robustness, reject restoring streaming SVE state + * without an SVE payload. + */ + if (!sm && user->sve_size == sizeof(*user->sve)) { clear_thread_flag(TIF_SVE); current->thread.svcr &= ~SVCR_SM_MASK; current->thread.fp_type = FP_STATE_FPSIMD; -- Gitee From 62a531637608b195807cf218d72e343bef468e21 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 28 Jan 2026 15:33:49 -0500 Subject: [PATCH 1280/1449] arm64/fpsimd: signal: Consistently read FPSIMD context ANBZ: #35228 commit 40b73f0519d3cd4d8e03169d54f55cd8aa0624a5 stable. commit be625d803c3bbfa9652697eb57589fe6f2f24b89 upstream. For historical reasons, restore_sve_fpsimd_context() has an open-coded copy of the logic from read_fpsimd_context(), which is used to either restore an FPSIMD-only context, or to merge FPSIMD state into an SVE state when restoring an SVE+FPSIMD context. The logic is *almost* identical. Refactor the logic to avoid duplication and make this clearer. This comes with two functional changes that I do not believe will be problematic in practice: * The user_fpsimd_state::size field will be checked in all restore paths that consume it user_fpsimd_state. The kernel always populates this field when delivering a signal, and so this should contain the expected value unless it has been corrupted. * If a read of user_fpsimd_state fails, we will return early without modifying TIF_SVE, the saved SVCR, or the save fp_type. This will leave the task in a consistent state, without potentially resurrecting stale FPSIMD state. A read of user_fpsimd_state should never fail unless the structure has been corrupted or the stack has been unmapped. Suggested-by: Will Deacon Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Marc Zyngier Cc: Mark Brown Cc: Will Deacon Link: https://lore.kernel.org/r/20250508132644.1395904-5-mark.rutland@arm.com [will: Ensure read_fpsimd_context() returns negative error code or zero] Signed-off-by: Will Deacon Stable-dep-of: d2907cbe9ea0 ("arm64/fpsimd: signal: Fix restoration of SVE context") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/arm64/kernel/signal.c | 57 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index d61c3527752d..3e1f92b20f7c 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -208,29 +208,39 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) return err ? -EFAULT : 0; } -static int restore_fpsimd_context(struct user_ctxs *user) +static int read_fpsimd_context(struct user_fpsimd_state *fpsimd, + struct user_ctxs *user) { - struct user_fpsimd_state fpsimd; - int err = 0; + int err; /* check the size information */ if (user->fpsimd_size != sizeof(struct fpsimd_context)) return -EINVAL; /* copy the FP and status/control registers */ - err = __copy_from_user(fpsimd.vregs, &(user->fpsimd->vregs), - sizeof(fpsimd.vregs)); - __get_user_error(fpsimd.fpsr, &(user->fpsimd->fpsr), err); - __get_user_error(fpsimd.fpcr, &(user->fpsimd->fpcr), err); + err = __copy_from_user(fpsimd->vregs, &(user->fpsimd->vregs), + sizeof(fpsimd->vregs)); + __get_user_error(fpsimd->fpsr, &(user->fpsimd->fpsr), err); + __get_user_error(fpsimd->fpcr, &(user->fpsimd->fpcr), err); + + return err ? -EFAULT : 0; +} + +static int restore_fpsimd_context(struct user_ctxs *user) +{ + struct user_fpsimd_state fpsimd; + int err; + + err = read_fpsimd_context(&fpsimd, user); + if (err) + return err; clear_thread_flag(TIF_SVE); current->thread.fp_type = FP_STATE_FPSIMD; /* load the hardware registers from the fpsimd_state structure */ - if (!err) - fpsimd_update_current_state(&fpsimd); - - return err ? -EFAULT : 0; + fpsimd_update_current_state(&fpsimd); + return 0; } static int preserve_fpmr_context(struct fpmr_context __user *ctx) @@ -342,12 +352,8 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) * consistency and robustness, reject restoring streaming SVE state * without an SVE payload. */ - if (!sm && user->sve_size == sizeof(*user->sve)) { - clear_thread_flag(TIF_SVE); - current->thread.svcr &= ~SVCR_SM_MASK; - current->thread.fp_type = FP_STATE_FPSIMD; - goto fpsimd_only; - } + if (!sm && user->sve_size == sizeof(*user->sve)) + return restore_fpsimd_context(user); vq = sve_vq_from_vl(vl); @@ -373,19 +379,14 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) set_thread_flag(TIF_SVE); current->thread.fp_type = FP_STATE_SVE; -fpsimd_only: - /* copy the FP and status/control registers */ - /* restore_sigframe() already checked that user->fpsimd != NULL. */ - err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs, - sizeof(fpsimd.vregs)); - __get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err); - __get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err); + err = read_fpsimd_context(&fpsimd, user); + if (err) + return err; - /* load the hardware registers from the fpsimd_state structure */ - if (!err) - fpsimd_update_current_state(&fpsimd); + /* Merge the FPSIMD registers into the SVE state */ + fpsimd_update_current_state(&fpsimd); - return err ? -EFAULT : 0; + return 0; } #else /* ! CONFIG_ARM64_SVE */ -- Gitee From 725c76169f709874a297b5cd745984c6ef3be756 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 28 Jan 2026 15:33:50 -0500 Subject: [PATCH 1281/1449] arm64/fpsimd: signal: Fix restoration of SVE context ANBZ: #35228 commit ce820dd4e6e2d711242dc4331713b9bb4fe06d09 stable. commit d2907cbe9ea0a54cbe078076f9d089240ee1e2d9 upstream. When SME is supported, Restoring SVE signal context can go wrong in a few ways, including placing the task into an invalid state where the kernel may read from out-of-bounds memory (and may potentially take a fatal fault) and/or may kill the task with a SIGKILL. (1) Restoring a context with SVE_SIG_FLAG_SM set can place the task into an invalid state where SVCR.SM is set (and sve_state is non-NULL) but TIF_SME is clear, consequently resuting in out-of-bounds memory reads and/or killing the task with SIGKILL. This can only occur in unusual (but legitimate) cases where the SVE signal context has either been modified by userspace or was saved in the context of another task (e.g. as with CRIU), as otherwise the presence of an SVE signal context with SVE_SIG_FLAG_SM implies that TIF_SME is already set. While in this state, task_fpsimd_load() will NOT configure SMCR_ELx (leaving some arbitrary value configured in hardware) before restoring SVCR and attempting to restore the streaming mode SVE registers from memory via sve_load_state(). As the value of SMCR_ELx.LEN may be larger than the task's streaming SVE vector length, this may read memory outside of the task's allocated sve_state, reading unrelated data and/or triggering a fault. While this can result in secrets being loaded into streaming SVE registers, these values are never exposed. As TIF_SME is clear, fpsimd_bind_task_to_cpu() will configure CPACR_ELx.SMEN to trap EL0 accesses to streaming mode SVE registers, so these cannot be accessed directly at EL0. As fpsimd_save_user_state() verifies the live vector length before saving (S)SVE state to memory, no secret values can be saved back to memory (and hence cannot be observed via ptrace, signals, etc). When the live vector length doesn't match the expected vector length for the task, fpsimd_save_user_state() will send a fatal SIGKILL signal to the task. Hence the task may be killed after executing userspace for some period of time. (2) Restoring a context with SVE_SIG_FLAG_SM clear does not clear the task's SVCR.SM. If SVCR.SM was set prior to restoring the context, then the task will be left in streaming mode unexpectedly, and some register state will be combined inconsistently, though the task will be left in legitimate state from the kernel's PoV. This can only occur in unusual (but legitimate) cases where ptrace has been used to set SVCR.SM after entry to the sigreturn syscall, as syscall entry clears SVCR.SM. In these cases, the the provided SVE register data will be loaded into the task's sve_state using the non-streaming SVE vector length and the FPSIMD registers will be merged into this using the streaming SVE vector length. Fix (1) by setting TIF_SME when setting SVCR.SM. This also requires ensuring that the task's sme_state has been allocated, but as this could contain live ZA state, it should not be zeroed. Fix (2) by clearing SVCR.SM when restoring a SVE signal context with SVE_SIG_FLAG_SM clear. For consistency, I've pulled the manipulation of SVCR, TIF_SVE, TIF_SME, and fp_type earlier, immediately after the allocation of sve_state/sme_state, before the restore of the actual register state. This makes it easier to ensure that these are always modified consistently, even if a fault is taken while reading the register data from the signal context. I do not expect any software to depend on the exact state restored when a fault is taken while reading the context. Fixes: 85ed24dad290 ("arm64/sme: Implement streaming SVE signal handling") Signed-off-by: Mark Rutland Cc: Cc: Mark Brown Cc: Will Deacon Reviewed-by: Mark Brown Signed-off-by: Catalin Marinas [ preserved fpsimd_flush_task_state() call before new SME allocation logic ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/arm64/kernel/signal.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 3e1f92b20f7c..fd4ff1069e56 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -360,12 +360,28 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) if (user->sve_size < SVE_SIG_CONTEXT_SIZE(vq)) return -EINVAL; + if (sm) { + sme_alloc(current, false); + if (!current->thread.sme_state) + return -ENOMEM; + } + sve_alloc(current, true); if (!current->thread.sve_state) { clear_thread_flag(TIF_SVE); return -ENOMEM; } + if (sm) { + current->thread.svcr |= SVCR_SM_MASK; + set_thread_flag(TIF_SME); + } else { + current->thread.svcr &= ~SVCR_SM_MASK; + set_thread_flag(TIF_SVE); + } + + current->thread.fp_type = FP_STATE_SVE; + err = __copy_from_user(current->thread.sve_state, (char __user const *)user->sve + SVE_SIG_REGS_OFFSET, @@ -373,12 +389,6 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) if (err) return -EFAULT; - if (flags & SVE_SIG_FLAG_SM) - current->thread.svcr |= SVCR_SM_MASK; - else - set_thread_flag(TIF_SVE); - current->thread.fp_type = FP_STATE_SVE; - err = read_fpsimd_context(&fpsimd, user); if (err) return err; -- Gitee From 5db26e6eacae6d088c63686f616a91d8b57c3aed Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 29 Jan 2026 05:36:08 +0800 Subject: [PATCH 1282/1449] mei: trace: treat reg parameter as string ANBZ: #35228 commit 143980bd2be75258d4a28305043cf7b74f6483b9 stable. commit 06d5a7afe1d0b47102936d8fba568572c2b4b941 upstream. The commit afd2627f727b ("tracing: Check "%s" dereference via the field and not the TP_printk format") forbids to emit event with a plain char* without a wrapper. The reg parameter always passed as static string and wrapper is not strictly required, contrary to dev parameter. Use the string wrapper anyway to check sanity of the reg parameters, store it value independently and prevent internal kernel data leaks. Since some code refactoring has taken place, explicit backporting may be needed for kernels older than 6.10. Cc: stable@vger.kernel.org # v6.11+ Fixes: a0a927d06d79 ("mei: me: add io register tracing") Signed-off-by: Alexander Usyskin Link: https://patch.msgid.link/20260111145125.1754912-1-alexander.usyskin@intel.com Signed-off-by: Greg Kroah-Hartman [ adapted __assign_str() calls to use two arguments ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/misc/mei/mei-trace.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/misc/mei/mei-trace.h b/drivers/misc/mei/mei-trace.h index fe46ff2b9d69..770e7897b88c 100644 --- a/drivers/misc/mei/mei-trace.h +++ b/drivers/misc/mei/mei-trace.h @@ -21,18 +21,18 @@ TRACE_EVENT(mei_reg_read, TP_ARGS(dev, reg, offs, val), TP_STRUCT__entry( __string(dev, dev_name(dev)) - __field(const char *, reg) + __string(reg, reg) __field(u32, offs) __field(u32, val) ), TP_fast_assign( __assign_str(dev, dev_name(dev)); - __entry->reg = reg; + __assign_str(reg, reg); __entry->offs = offs; __entry->val = val; ), TP_printk("[%s] read %s:[%#x] = %#x", - __get_str(dev), __entry->reg, __entry->offs, __entry->val) + __get_str(dev), __get_str(reg), __entry->offs, __entry->val) ); TRACE_EVENT(mei_reg_write, @@ -40,18 +40,18 @@ TRACE_EVENT(mei_reg_write, TP_ARGS(dev, reg, offs, val), TP_STRUCT__entry( __string(dev, dev_name(dev)) - __field(const char *, reg) + __string(reg, reg) __field(u32, offs) __field(u32, val) ), TP_fast_assign( __assign_str(dev, dev_name(dev)); - __entry->reg = reg; + __assign_str(reg, reg); __entry->offs = offs; __entry->val = val; ), TP_printk("[%s] write %s[%#x] = %#x", - __get_str(dev), __entry->reg, __entry->offs, __entry->val) + __get_str(dev), __get_str(reg), __entry->offs, __entry->val) ); TRACE_EVENT(mei_pci_cfg_read, @@ -59,18 +59,18 @@ TRACE_EVENT(mei_pci_cfg_read, TP_ARGS(dev, reg, offs, val), TP_STRUCT__entry( __string(dev, dev_name(dev)) - __field(const char *, reg) + __string(reg, reg) __field(u32, offs) __field(u32, val) ), TP_fast_assign( __assign_str(dev, dev_name(dev)); - __entry->reg = reg; + __assign_str(reg, reg); __entry->offs = offs; __entry->val = val; ), TP_printk("[%s] pci cfg read %s:[%#x] = %#x", - __get_str(dev), __entry->reg, __entry->offs, __entry->val) + __get_str(dev), __get_str(reg), __entry->offs, __entry->val) ); #endif /* _MEI_TRACE_H_ */ -- Gitee From d6fabae071cd95ddd76ac983cbc02f18805eb44d Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Thu, 29 Jan 2026 05:36:14 +0800 Subject: [PATCH 1283/1449] ksmbd: smbd: fix dma_unmap_sg() nents ANBZ: #35228 commit 4d1e9a4a450aae47277763562122cc80ed703ab2 stable. commit 98e3e2b561bc88f4dd218d1c05890672874692f6 upstream. The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned. Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") Cc: Signed-off-by: Thomas Fourier Acked-by: Namjae Jeon Signed-off-by: Steve French [ Context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/transport_rdma.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index 91e85a1a154f..4bab3f89d2c8 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -1108,14 +1108,12 @@ static int get_sg_list(void *buf, int size, struct scatterlist *sg_list, int nen static int get_mapped_sg_list(struct ib_device *device, void *buf, int size, struct scatterlist *sg_list, int nentries, - enum dma_data_direction dir) + enum dma_data_direction dir, int *npages) { - int npages; - - npages = get_sg_list(buf, size, sg_list, nentries); - if (npages < 0) + *npages = get_sg_list(buf, size, sg_list, nentries); + if (*npages < 0) return -EINVAL; - return ib_dma_map_sg(device, sg_list, npages, dir); + return ib_dma_map_sg(device, sg_list, *npages, dir); } static int post_sendmsg(struct smb_direct_transport *t, @@ -1184,12 +1182,13 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t, for (i = 0; i < niov; i++) { struct ib_sge *sge; int sg_cnt; + int npages; sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1); sg_cnt = get_mapped_sg_list(t->cm_id->device, iov[i].iov_base, iov[i].iov_len, sg, SMB_DIRECT_MAX_SEND_SGES - 1, - DMA_TO_DEVICE); + DMA_TO_DEVICE, &npages); if (sg_cnt <= 0) { pr_err("failed to map buffer\n"); ret = -ENOMEM; @@ -1197,7 +1196,7 @@ static int smb_direct_post_send_data(struct smb_direct_transport *t, } else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES) { pr_err("buffer not fitted into sges\n"); ret = -E2BIG; - ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt, + ib_dma_unmap_sg(t->cm_id->device, sg, npages, DMA_TO_DEVICE); goto err; } -- Gitee From c15a4ad70126dbfb9a993bc590ed0f94d46ee77c Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Thu, 29 Jan 2026 17:13:25 +0800 Subject: [PATCH 1284/1449] drm/amdgpu: Replace Mutex with Spinlock for RLCG register access to avoid Priority Inversion in SRIOV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d1bda2ab0cf956a16dd369a473a6c43dfbed5855 stable. commit dc0297f3198bd60108ccbd167ee5d9fa4af31ed0 upstream. RLCG Register Access is a way for virtual functions to safely access GPU registers in a virtualized environment., including TLB flushes and register reads. When multiple threads or VFs try to access the same registers simultaneously, it can lead to race conditions. By using the RLCG interface, the driver can serialize access to the registers. This means that only one thread can access the registers at a time, preventing conflicts and ensuring that operations are performed correctly. Additionally, when a low-priority task holds a mutex that a high-priority task needs, ie., If a thread holding a spinlock tries to acquire a mutex, it can lead to priority inversion. register access in amdgpu_virt_rlcg_reg_rw especially in a fast code path is critical. The call stack shows that the function amdgpu_virt_rlcg_reg_rw is being called, which attempts to acquire the mutex. This function is invoked from amdgpu_sriov_wreg, which in turn is called from gmc_v11_0_flush_gpu_tlb. The [ BUG: Invalid wait context ] indicates that a thread is trying to acquire a mutex while it is in a context that does not allow it to sleep (like holding a spinlock). Fixes the below: [ 253.013423] ============================= [ 253.013434] [ BUG: Invalid wait context ] [ 253.013446] 6.12.0-amdstaging-drm-next-lol-050225 #14 Tainted: G U OE [ 253.013464] ----------------------------- [ 253.013475] kworker/0:1/10 is trying to lock: [ 253.013487] ffff9f30542e3cf8 (&adev->virt.rlcg_reg_lock){+.+.}-{3:3}, at: amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu] [ 253.013815] other info that might help us debug this: [ 253.013827] context-{4:4} [ 253.013835] 3 locks held by kworker/0:1/10: [ 253.013847] #0: ffff9f3040050f58 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x3f5/0x680 [ 253.013877] #1: ffffb789c008be40 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_one_work+0x1d6/0x680 [ 253.013905] #2: ffff9f3054281838 (&adev->gmc.invalidate_lock){+.+.}-{2:2}, at: gmc_v11_0_flush_gpu_tlb+0x198/0x4f0 [amdgpu] [ 253.014154] stack backtrace: [ 253.014164] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Tainted: G U OE 6.12.0-amdstaging-drm-next-lol-050225 #14 [ 253.014189] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE [ 253.014203] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/18/2024 [ 253.014224] Workqueue: events work_for_cpu_fn [ 253.014241] Call Trace: [ 253.014250] [ 253.014260] dump_stack_lvl+0x9b/0xf0 [ 253.014275] dump_stack+0x10/0x20 [ 253.014287] __lock_acquire+0xa47/0x2810 [ 253.014303] ? srso_alias_return_thunk+0x5/0xfbef5 [ 253.014321] lock_acquire+0xd1/0x300 [ 253.014333] ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu] [ 253.014562] ? __lock_acquire+0xa6b/0x2810 [ 253.014578] __mutex_lock+0x85/0xe20 [ 253.014591] ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu] [ 253.014782] ? sched_clock_noinstr+0x9/0x10 [ 253.014795] ? srso_alias_return_thunk+0x5/0xfbef5 [ 253.014808] ? local_clock_noinstr+0xe/0xc0 [ 253.014822] ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu] [ 253.015012] ? srso_alias_return_thunk+0x5/0xfbef5 [ 253.015029] mutex_lock_nested+0x1b/0x30 [ 253.015044] ? mutex_lock_nested+0x1b/0x30 [ 253.015057] amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu] [ 253.015249] amdgpu_sriov_wreg+0xc5/0xd0 [amdgpu] [ 253.015435] gmc_v11_0_flush_gpu_tlb+0x44b/0x4f0 [amdgpu] [ 253.015667] gfx_v11_0_hw_init+0x499/0x29c0 [amdgpu] [ 253.015901] ? __pfx_smu_v13_0_update_pcie_parameters+0x10/0x10 [amdgpu] [ 253.016159] ? srso_alias_return_thunk+0x5/0xfbef5 [ 253.016173] ? smu_hw_init+0x18d/0x300 [amdgpu] [ 253.016403] amdgpu_device_init+0x29ad/0x36a0 [amdgpu] [ 253.016614] amdgpu_driver_load_kms+0x1a/0xc0 [amdgpu] [ 253.017057] amdgpu_pci_probe+0x1c2/0x660 [amdgpu] [ 253.017493] local_pci_probe+0x4b/0xb0 [ 253.017746] work_for_cpu_fn+0x1a/0x30 [ 253.017995] process_one_work+0x21e/0x680 [ 253.018248] worker_thread+0x190/0x330 [ 253.018500] ? __pfx_worker_thread+0x10/0x10 [ 253.018746] kthread+0xe7/0x120 [ 253.018988] ? __pfx_kthread+0x10/0x10 [ 253.019231] ret_from_fork+0x3c/0x60 [ 253.019468] ? __pfx_kthread+0x10/0x10 [ 253.019701] ret_from_fork_asm+0x1a/0x30 [ 253.019939] v2: s/spin_trylock/spin_lock_irqsave to be safe (Christian). Fixes: e864180ee49b ("drm/amdgpu: Add lock around VF RLCG interface") Cc: lin cao Cc: Jingwen Chen Cc: Victor Skvortsov Cc: Zhigang Luo Cc: Christian König Cc: Alex Deucher Signed-off-by: Srinivasan Shanmugam Suggested-by: Alex Deucher Reviewed-by: Christian König Signed-off-by: Alex Deucher [ Minor conflict resolved. ] Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 017552e79178..9481d450809b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3582,7 +3582,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->grbm_idx_mutex); mutex_init(&adev->mn_lock); mutex_init(&adev->virt.vf_errors.lock); - mutex_init(&adev->virt.rlcg_reg_lock); hash_init(adev->mn_hash); mutex_init(&adev->psp.mutex); mutex_init(&adev->notifier_lock); @@ -3604,6 +3603,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, spin_lock_init(&adev->se_cac_idx_lock); spin_lock_init(&adev->audio_endpt_idx_lock); spin_lock_init(&adev->mm_stats.lock); + spin_lock_init(&adev->virt.rlcg_reg_lock); INIT_LIST_HEAD(&adev->shadow_list); mutex_init(&adev->shadow_list_lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 5a4b1b625f03..0f4661d1f23b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -1007,6 +1007,7 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v void *scratch_reg2; void *scratch_reg3; void *spare_int; + unsigned long flags; if (!adev->gfx.rlc.rlcg_reg_access_supported) { dev_err(adev->dev, @@ -1028,7 +1029,7 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2; scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3; - mutex_lock(&adev->virt.rlcg_reg_lock); + spin_lock_irqsave(&adev->virt.rlcg_reg_lock, flags); if (reg_access_ctrl->spare_int) spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; @@ -1086,7 +1087,7 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v ret = readl(scratch_reg0); - mutex_unlock(&adev->virt.rlcg_reg_lock); + spin_unlock_irqrestore(&adev->virt.rlcg_reg_lock, flags); return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index 891713757a8f..bffbb7ef40d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -267,7 +267,8 @@ struct amdgpu_virt { /* the ucode id to signal the autoload */ uint32_t autoload_ucode_id; - struct mutex rlcg_reg_lock; + /* Spinlock to protect access to the RLCG register interface */ + spinlock_t rlcg_reg_lock; }; struct amdgpu_video_codec_info; -- Gitee From 12db608148f908d0e3108b53a5788ce31bc70333 Mon Sep 17 00:00:00 2001 From: Yunseong Kim Date: Mon, 2 Feb 2026 11:17:39 +0800 Subject: [PATCH 1285/1449] ksmbd: Fix race condition in RPC handle list access ANBZ: #35228 commit 6b615a8fb3af0baf8126cde3d4fee97d57222ffc stable. commit 305853cce379407090a73b38c5de5ba748893aee upstream. The 'sess->rpc_handle_list' XArray manages RPC handles within a ksmbd session. Access to this list is intended to be protected by 'sess->rpc_lock' (an rw_semaphore). However, the locking implementation was flawed, leading to potential race conditions. In ksmbd_session_rpc_open(), the code incorrectly acquired only a read lock before calling xa_store() and xa_erase(). Since these operations modify the XArray structure, a write lock is required to ensure exclusive access and prevent data corruption from concurrent modifications. Furthermore, ksmbd_session_rpc_method() accessed the list using xa_load() without holding any lock at all. This could lead to reading inconsistent data or a potential use-after-free if an entry is concurrently removed and the pointer is dereferenced. Fix these issues by: 1. Using down_write() and up_write() in ksmbd_session_rpc_open() to ensure exclusive access during XArray modification, and ensuring the lock is correctly released on error paths. 2. Adding down_read() and up_read() in ksmbd_session_rpc_method() to safely protect the lookup. Fixes: a1f46c99d9ea ("ksmbd: fix use-after-free in ksmbd_session_rpc_open") Fixes: b685757c7b08 ("ksmbd: Implements sess->rpc_handle_list as xarray") Cc: stable@vger.kernel.org Signed-off-by: Yunseong Kim Acked-by: Namjae Jeon Signed-off-by: Steve French [ Minor conflict resolved. ] Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/mgmt/user_session.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 450a9f8ca7c7..5986d6d0a90b 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -104,29 +104,32 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) if (!entry) return -ENOMEM; - down_read(&sess->rpc_lock); entry->method = method; entry->id = id = ksmbd_ipc_id_alloc(); if (id < 0) goto free_entry; + + down_write(&sess->rpc_lock); old = xa_store(&sess->rpc_handle_list, id, entry, GFP_KERNEL); - if (xa_is_err(old)) + if (xa_is_err(old)) { + up_write(&sess->rpc_lock); goto free_id; + } resp = ksmbd_rpc_open(sess, id); - if (!resp) - goto erase_xa; + if (!resp) { + xa_erase(&sess->rpc_handle_list, entry->id); + up_write(&sess->rpc_lock); + goto free_id; + } - up_read(&sess->rpc_lock); + up_write(&sess->rpc_lock); kvfree(resp); return id; -erase_xa: - xa_erase(&sess->rpc_handle_list, entry->id); free_id: ksmbd_rpc_id_free(entry->id); free_entry: kfree(entry); - up_read(&sess->rpc_lock); return -EINVAL; } @@ -144,9 +147,14 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id) int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) { struct ksmbd_session_rpc *entry; + int method; + down_read(&sess->rpc_lock); entry = xa_load(&sess->rpc_handle_list, id); - return entry ? entry->method : 0; + method = entry ? entry->method : 0; + up_read(&sess->rpc_lock); + + return method; } void ksmbd_session_destroy(struct ksmbd_session *sess) -- Gitee From 30f6b32c13a9ea1172014b83468556eb0bc2c8fd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 3 Feb 2026 00:47:45 +0800 Subject: [PATCH 1286/1449] wifi: mac80211: move TDLS work to wiphy work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit fb2b9a1e85bddee9f5c9091e7dd20164782192a3 stable. commit 777b26002b73127e81643d9286fadf3d41e0e477 upstream. Again, to have the wiphy locked for it. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg (cherry picked from commit 777b26002b73127e81643d9286fadf3d41e0e477) Signed-off-by: Hanne-Lotta Mäenpää Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/ieee80211_i.h | 4 ++-- net/mac80211/mlme.c | 7 ++++--- net/mac80211/tdls.c | 11 ++++++----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 44aad3394084..639268d70f96 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -530,7 +530,7 @@ struct ieee80211_if_managed { /* TDLS support */ u8 tdls_peer[ETH_ALEN] __aligned(2); - struct delayed_work tdls_peer_del_work; + struct wiphy_delayed_work tdls_peer_del_work; struct sk_buff *orig_teardown_skb; /* The original teardown skb */ struct sk_buff *teardown_skb; /* A copy to send through the AP */ spinlock_t teardown_lock; /* To lock changing teardown_skb */ @@ -2599,7 +2599,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, const u8 *extra_ies, size_t extra_ies_len); int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, enum nl80211_tdls_operation oper); -void ieee80211_tdls_peer_del_work(struct work_struct *wk); +void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk); int ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev, const u8 *addr, u8 oper_class, struct cfg80211_chan_def *chandef); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index aa7cee830b00..78b9206f99f4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -6866,8 +6866,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ieee80211_beacon_connection_loss_work); wiphy_work_init(&ifmgd->csa_connection_drop_work, ieee80211_csa_connection_drop_work); - INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work, - ieee80211_tdls_peer_del_work); + wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work, + ieee80211_tdls_peer_del_work); wiphy_delayed_work_init(&ifmgd->ml_reconf_work, ieee80211_ml_reconf_work); timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0); @@ -7881,7 +7881,8 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) &ifmgd->beacon_connection_loss_work); wiphy_work_cancel(sdata->local->hw.wiphy, &ifmgd->csa_connection_drop_work); - cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work); + wiphy_delayed_work_cancel(sdata->local->hw.wiphy, + &ifmgd->tdls_peer_del_work); wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &ifmgd->ml_reconf_work); diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index f3cdbd2133f6..0fd353fec9fc 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -21,7 +21,7 @@ /* give usermode some time for retries in setting up the TDLS session */ #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) -void ieee80211_tdls_peer_del_work(struct work_struct *wk) +void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk) { struct ieee80211_sub_if_data *sdata; struct ieee80211_local *local; @@ -1224,9 +1224,9 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, return ret; } - ieee80211_queue_delayed_work(&sdata->local->hw, - &sdata->u.mgd.tdls_peer_del_work, - TDLS_PEER_SETUP_TIMEOUT); + wiphy_delayed_work_queue(sdata->local->hw.wiphy, + &sdata->u.mgd.tdls_peer_del_work, + TDLS_PEER_SETUP_TIMEOUT); return 0; out_unlock: @@ -1526,7 +1526,8 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, } if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { - cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work); + wiphy_delayed_work_cancel(sdata->local->hw.wiphy, + &sdata->u.mgd.tdls_peer_del_work); eth_zero_addr(sdata->u.mgd.tdls_peer); } -- Gitee From 1e76ec8622ba65c4780556c4ee5902b3b63e6e5f Mon Sep 17 00:00:00 2001 From: Kang Yang Date: Tue, 3 Feb 2026 11:13:45 +0800 Subject: [PATCH 1287/1449] wifi: ath11k: add srng->lock for ath11k_hal_srng_* in monitor mode ANBZ: #35228 commit 27ca8004ba93a0665faa6d477eaeb551e03de6c8 stable. commit 63b7af49496d0e32f7a748b6af3361ec138b1bd3 upstream. ath11k_hal_srng_* should be used with srng->lock to protect srng data. For ath11k_dp_rx_mon_dest_process() and ath11k_dp_full_mon_process_rx(), they use ath11k_hal_srng_* for many times but never call srng->lock. So when running (full) monitor mode, warning will occur: RIP: 0010:ath11k_hal_srng_dst_peek+0x18/0x30 [ath11k] Call Trace: ? ath11k_hal_srng_dst_peek+0x18/0x30 [ath11k] ath11k_dp_rx_process_mon_status+0xc45/0x1190 [ath11k] ? idr_alloc_u32+0x97/0xd0 ath11k_dp_rx_process_mon_rings+0x32a/0x550 [ath11k] ath11k_dp_service_srng+0x289/0x5a0 [ath11k] ath11k_pcic_ext_grp_napi_poll+0x30/0xd0 [ath11k] __napi_poll+0x30/0x1f0 net_rx_action+0x198/0x320 __do_softirq+0xdd/0x319 So add srng->lock for them to avoid such warnings. Inorder to fetch the srng->lock, should change srng's definition from 'void' to 'struct hal_srng'. And initialize them elsewhere to prevent one line of code from being too long. This is consistent with other ring process functions, such as ath11k_dp_process_rx(). Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Signed-off-by: Kang Yang Acked-by: Jeff Johnson Link: https://patch.msgid.link/20241219110531.2096-3-quic_kangyang@quicinc.com Signed-off-by: Jeff Johnson Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/ath/ath11k/dp_rx.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index dc54ea16c12a..ed1ea61c8142 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -5093,7 +5093,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; const struct ath11k_hw_hal_params *hal_params; void *ring_entry; - void *mon_dst_srng; + struct hal_srng *mon_dst_srng; u32 ppdu_id; u32 rx_bufs_used; u32 ring_id; @@ -5117,6 +5117,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, spin_lock_bh(&pmon->mon_lock); + spin_lock_bh(&mon_dst_srng->lock); ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng); ppdu_id = pmon->mon_ppdu_info.ppdu_id; @@ -5175,6 +5176,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, mon_dst_srng); } ath11k_hal_srng_access_end(ar->ab, mon_dst_srng); + spin_unlock_bh(&mon_dst_srng->lock); spin_unlock_bh(&pmon->mon_lock); @@ -5564,7 +5566,7 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id, struct hal_sw_mon_ring_entries *sw_mon_entries; struct ath11k_pdev_mon_stats *rx_mon_stats; struct sk_buff *head_msdu, *tail_msdu; - void *mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id]; + struct hal_srng *mon_dst_srng; void *ring_entry; u32 rx_bufs_used = 0, mpdu_rx_bufs_used; int quota = 0, ret; @@ -5580,6 +5582,9 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id, goto reap_status_ring; } + mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id]; + spin_lock_bh(&mon_dst_srng->lock); + ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng); while ((ring_entry = ath11k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { head_msdu = NULL; @@ -5623,6 +5628,7 @@ static int ath11k_dp_full_mon_process_rx(struct ath11k_base *ab, int mac_id, } ath11k_hal_srng_access_end(ar->ab, mon_dst_srng); + spin_unlock_bh(&mon_dst_srng->lock); spin_unlock_bh(&pmon->mon_lock); if (rx_bufs_used) { -- Gitee From 506e2dcb77625930e60866f3fc85629b83f4d9c3 Mon Sep 17 00:00:00 2001 From: "Nikola Z. Ivanov" Date: Tue, 3 Feb 2026 12:45:57 +0800 Subject: [PATCH 1288/1449] team: Move team device type change at the end of team_port_add ANBZ: #35228 commit e26235840fd961e4ebe5568f11a2a078cf726663 stable. commit 0ae9cfc454ea5ead5f3ddbdfe2e70270d8e2c8ef upstream. Attempting to add a port device that is already up will expectedly fail, but not before modifying the team device header_ops. In the case of the syzbot reproducer the gre0 device is already in state UP when it attempts to add it as a port device of team0, this fails but before that header_ops->create of team0 is changed from eth_header to ipgre_header in the call to team_dev_type_check_change. Later when we end up in ipgre_header() struct ip_tunnel* points to nonsense as the private data of the device still holds a struct team. Example sequence of iproute2 commands to reproduce the hang/BUG(): ip link add dev team0 type team ip link add dev gre0 type gre ip link set dev gre0 up ip link set dev gre0 master team0 ip link set dev team0 up ping -I team0 1.1.1.1 Move team_dev_type_check_change down where all other checks have passed as it changes the dev type with no way to restore it in case one of the checks that follow it fail. Also make sure to preserve the origial mtu assignment: - If port_dev is not the same type as dev, dev takes mtu from port_dev - If port_dev is the same type as dev, port_dev takes mtu from dev This is done by adding a conditional before the call to dev_set_mtu to prevent it from assigning port_dev->mtu = dev->mtu and instead letting team_dev_type_check_change assign dev->mtu = port_dev->mtu. The conditional is needed because the patch moves the call to team_dev_type_check_change past dev_set_mtu. Testing: - team device driver in-tree selftests - Add/remove various devices as slaves of team device - syzbot Reported-by: syzbot+a2a3b519de727b0f7903@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=a2a3b519de727b0f7903 Fixes: 1d76efe1577b ("team: add support for non-ethernet devices") Signed-off-by: Nikola Z. Ivanov Reviewed-by: Jiri Pirko Link: https://patch.msgid.link/20251122002027.695151-1-zlatistiv@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/team/team.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 9baa13808933..deb6eb3a240a 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1184,10 +1184,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev, return -EPERM; } - err = team_dev_type_check_change(dev, port_dev); - if (err) - return err; - if (port_dev->flags & IFF_UP) { NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port"); netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n", @@ -1205,10 +1201,16 @@ static int team_port_add(struct team *team, struct net_device *port_dev, INIT_LIST_HEAD(&port->qom_list); port->orig.mtu = port_dev->mtu; - err = dev_set_mtu(port_dev, dev->mtu); - if (err) { - netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); - goto err_set_mtu; + /* + * MTU assignment will be handled in team_dev_type_check_change + * if dev and port_dev are of different types + */ + if (dev->type == port_dev->type) { + err = dev_set_mtu(port_dev, dev->mtu); + if (err) { + netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); + goto err_set_mtu; + } } memcpy(port->orig.dev_addr, port_dev->dev_addr, port_dev->addr_len); @@ -1283,6 +1285,10 @@ static int team_port_add(struct team *team, struct net_device *port_dev, } } + err = team_dev_type_check_change(dev, port_dev); + if (err) + goto err_set_dev_type; + if (dev->flags & IFF_UP) { netif_addr_lock_bh(dev); dev_uc_sync_multiple(port_dev, dev); @@ -1301,6 +1307,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev, return 0; +err_set_dev_type: err_set_slave_promisc: __team_option_inst_del_port(team, port); -- Gitee From 14e6345974768395998d88efe6fce5bdd903b40d Mon Sep 17 00:00:00 2001 From: Robert McClinton Date: Mon, 2 Feb 2026 15:58:31 +0800 Subject: [PATCH 1289/1449] drm/radeon: delete radeon_fence_process in is_signaled, no deadlock ANBZ: #35228 commit 9d0ed508a9e2af82951ce7d834f58c139fc2bd9b stable. commit 9eb00b5f5697bd56baa3222c7a1426fa15bacfb5 upstream. Delete the attempt to progress the queue when checking if fence is signaled. This avoids deadlock. dma-fence_ops::signaled can be called with the fence lock in unknown state. For radeon, the fence lock is also the wait queue lock. This can cause a self deadlock when signaled() tries to make forward progress on the wait queue. But advancing the queue is unneeded because incorrectly returning false from signaled() is perfectly acceptable. Link: https://github.com/brave/brave-browser/issues/49182 Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4641 Cc: Alex Deucher Signed-off-by: Robert McClinton Signed-off-by: Alex Deucher (cherry picked from commit 527ba26e50ec2ca2be9c7c82f3ad42998a75d0db) Cc: stable@vger.kernel.org [ Minor conflict resolved. ] Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/radeon/radeon_fence.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 6d5e828fa39e..1462837fda5a 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -362,14 +362,6 @@ static bool radeon_fence_is_signaled(struct dma_fence *f) return true; } - if (down_read_trylock(&rdev->exclusive_lock)) { - radeon_fence_process(rdev, ring); - up_read(&rdev->exclusive_lock); - - if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) { - return true; - } - } return false; } -- Gitee From 121f95cc9fa8bf1bbe9dbc42cfa7c7d523c150fe Mon Sep 17 00:00:00 2001 From: JP Kobryn Date: Sun, 1 Feb 2026 15:09:53 +0800 Subject: [PATCH 1290/1449] btrfs: prevent use-after-free on page private data in btrfs_subpage_clear_uptodate() ANBZ: #35228 commit 1d14f86e813f63bc17b34fe23a971330130a2516 stable. This is a stable-only patch. The issue was inadvertently fixed in 6.17 [0] as part of a refactoring, but this patch serves as a minimal targeted fix for prior kernels. Users of find_lock_page() need to guard against the situation where releasepage() has been invoked during reclaim but the page was ultimately not removed from the page cache. This patch covers one location that was overlooked. After acquiring the page, use set_page_extent_mapped() to ensure the page private state is valid. This is especially important in the subpage case, where the private field is an allocated struct containing bitmap and lock data. Without this protection, the race below is possible: [mm] page cache reclaim path [fs] relocation in subpage mode shrink_page_list() trylock_page() /* lock acquired */ try_to_release_page() mapping->a_ops->releasepage() btrfs_releasepage() __btrfs_releasepage() clear_page_extent_mapped() btrfs_detach_subpage() subpage = detach_page_private(page) btrfs_free_subpage(subpage) kfree(subpage) /* point A */ prealloc_file_extent_cluster() find_lock_page() page_cache_get_speculative() lock_page() /* wait for lock */ if (...) ... else if (!mapping || !__remove_mapping(..)) /* * __remove_mapping() returns zero when * page_ref_freeze(page, refcount) fails /* point B */ */ goto keep_locked /* page remains in cache */ keep_locked: unlock_page(page) /* lock released */ /* lock acquired */ btrfs_subpage_clear_uptodate() /* use-after-free */ subpage = page->private [0] 4e346baee95f ("btrfs: reloc: unconditionally invalidate the page cache for each cluster") Fixes: 9d9ea1e68a05 ("btrfs: subpage: fix relocation potentially overwriting last page data") Cc: stable@vger.kernel.org # 5.15 - 6.9 Signed-off-by: JP Kobryn Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/relocation.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index b21b5e0f8905..0f05eb97925f 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2847,6 +2847,19 @@ static noinline_for_stack int prealloc_file_extent_cluster( * will re-read the whole page anyway. */ if (page) { + /* + * releasepage() could have cleared the page private data while + * we were not holding the lock. Reset the mapping if needed so + * subpage operations can access a valid private page state. + */ + ret = set_page_extent_mapped(page); + if (ret) { + unlock_page(page); + put_page(page); + + return ret; + } + btrfs_subpage_clear_uptodate(fs_info, page, i_size, round_up(i_size, PAGE_SIZE) - i_size); unlock_page(page); -- Gitee From cc1f878e067d3d347c8d2b1007a1b62a6bb9a937 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Wed, 12 Nov 2025 15:27:09 +0800 Subject: [PATCH 1291/1449] net/sched: act_ife: convert comma to semicolon ANBZ: #35228 commit db24153fc77a82a7eb48322af792c2d41c58f5e9 stable. commit 205305c028ad986d0649b8b100bab6032dcd1bb5 upstream. Replace comma between expressions with semicolons. Using a ',' in place of a ';' can have unintended side effects. Although that is not the case here, it is seems best to use ';' unless ',' is intended. Found by inspection. No functional change intended. Compile tested only. Signed-off-by: Chen Ni Reviewed-by: Jamal Hadi Salim Link: https://patch.msgid.link/20251112072709.73755-1-nichen@iscas.ac.cn Signed-off-by: Jakub Kicinski Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/act_ife.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 567a58d30df8..58c1ab02bd0d 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -649,9 +649,9 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind, memset(&opt, 0, sizeof(opt)); - opt.index = ife->tcf_index, - opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref, - opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind, + opt.index = ife->tcf_index; + opt.refcnt = refcount_read(&ife->tcf_refcnt) - ref; + opt.bindcnt = atomic_read(&ife->tcf_bindcnt) - bind; spin_lock_bh(&ife->tcf_lock); opt.action = ife->tcf_action; -- Gitee From e663cc1f17fa2cc264ab24787212c1e25ddcc655 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 26 Nov 2025 18:08:31 +0800 Subject: [PATCH 1292/1449] ALSA: usb-audio: Fix missing unlock at error path of maxpacksize check ANBZ: #35228 commit daf8a4eb70ff406c0afdcd18adff376923fd14b7 stable. commit fdf0dc82eb60091772ecea73cbc5a8fb7562fc45 upstream. The recent backport of the upstream commit 05a1fc5efdd8 ("ALSA: usb-audio: Fix potential overflow of PCM transfer buffer") on the older stable kernels like 6.12.y was broken since it doesn't consider the mutex unlock, where the upstream code manages with guard(). In the older code, we still need an explicit unlock. This is a fix that corrects the error path, applied only on old stable trees. Reported-by: Pavel Machek Closes: https://lore.kernel.org/aSWtH0AZH5+aeb+a@duo.ucw.cz Fixes: 98e9d5e33bda ("ALSA: usb-audio: Fix potential overflow of PCM transfer buffer") Reviewed-by: Pavel Machek Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Signed-off-by: Wentao Guan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/usb/endpoint.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index b05ad2eb623d..17ae74b067c5 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -1386,7 +1386,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, if (ep->packsize[1] > ep->maxpacksize) { usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", ep->maxpacksize, ep->cur_rate, ep->pps); - return -EINVAL; + err = -EINVAL; + goto unlock; } /* calculate the frequency in 16.16 format */ -- Gitee From ce558af7c9a970fa2415c881d781a4283589a167 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 4 Feb 2026 07:29:44 +0800 Subject: [PATCH 1293/1449] pinctrl: lpass-lpi: implement .get_direction() for the GPIO driver ANBZ: #35228 commit e228ad913b0d2e0921b0953c213097becc61b3e0 stable. commit 4f0d22ec60cee420125f4055af76caa0f373a3fe upstream. GPIO controller driver should typically implement the .get_direction() callback as GPIOLIB internals may try to use it to determine the state of a pin. Add it for the LPASS LPI driver. Reported-by: Abel Vesa Cc: stable@vger.kernel.org Fixes: 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver") Signed-off-by: Bartosz Golaszewski Reviewed-by: Konrad Dybcio Tested-by: Konrad Dybcio # X1E CRD Tested-by: Abel Vesa Signed-off-by: Linus Walleij [ PIN_CONFIG_LEVEL => PIN_CONFIG_OUTPUT ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c index 2b32da357af3..a17c71b3bc8b 100644 --- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c @@ -279,6 +279,22 @@ static const struct pinconf_ops lpi_gpio_pinconf_ops = { .pin_config_group_set = lpi_config_set, }; +static int lpi_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) +{ + unsigned long config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, 0); + struct lpi_pinctrl *state = gpiochip_get_data(chip); + unsigned long arg; + int ret; + + ret = lpi_config_get(state->ctrl, pin, &config); + if (ret) + return ret; + + arg = pinconf_to_config_argument(config); + + return arg ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; +} + static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) { struct lpi_pinctrl *state = gpiochip_get_data(chip); @@ -377,6 +393,7 @@ static void lpi_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) #endif static const struct gpio_chip lpi_gpio_template = { + .get_direction = lpi_gpio_get_direction, .direction_input = lpi_gpio_direction_input, .direction_output = lpi_gpio_direction_output, .get = lpi_gpio_get, -- Gitee From c702a3c605a401cebaf7670c0b2c5171a1a8854e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Feb 2026 05:17:52 +0800 Subject: [PATCH 1294/1449] drm/msm/a6xx: fix bogus hwcg register updates ANBZ: #35228 commit e57bda247f29c4b36619b3f1067ee0320a9021ec stable. commit dedb897f11c5d7e32c0e0a0eff7cec23a8047167 upstream. The hw clock gating register sequence consists of register value pairs that are written to the GPU during initialisation. The a690 hwcg sequence has two GMU registers in it that used to amount to random writes in the GPU mapping, but since commit 188db3d7fe66 ("drm/msm/a6xx: Rebase GMU register offsets") they trigger a fault as the updated offsets now lie outside the mapping. This in turn breaks boot of machines like the Lenovo ThinkPad X13s. Note that the updates of these GMU registers is already taken care of properly since commit 40c297eb245b ("drm/msm/a6xx: Set GMU CGC properties on a6xx too"), but for some reason these two entries were left in the table. Fixes: 5e7665b5e484 ("drm/msm/adreno: Add Adreno A690 support") Cc: stable@vger.kernel.org # 6.5 Cc: Bjorn Andersson Cc: Konrad Dybcio Signed-off-by: Johan Hovold Reviewed-by: Konrad Dybcio Reviewed-by: Akhil P Oommen Fixes: 188db3d7fe66 ("drm/msm/a6xx: Rebase GMU register offsets") Patchwork: https://patchwork.freedesktop.org/patch/695778/ Message-ID: <20251221164552.19990-1-johan@kernel.org> Signed-off-by: Rob Clark (cherry picked from commit dcbd2f8280eea2c965453ed8c3c69d6f121e950b) [ Applied fix to a6xx_gpu.c instead of a6xx_catalog.c ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 4654c0f362c7..6666d8f6c17a 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -690,8 +690,6 @@ const struct adreno_reglist a690_hwcg[] = { {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111}, {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555}, {REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200}, - {REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111}, - {REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555}, {} }; -- Gitee From 4762295656d9b060507b5241669206b97fba4398 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 4 Feb 2026 04:27:45 +0800 Subject: [PATCH 1295/1449] perf: sched: Fix perf crash with new is_user_task() helper ANBZ: #35228 commit d84a4836dc246b7dc244e46a08ff992956b68db0 stable. commit 76ed27608f7dd235b727ebbb12163438c2fbb617 upstream. In order to do a user space stacktrace the current task needs to be a user task that has executed in user space. It use to be possible to test if a task is a user task or not by simply checking the task_struct mm field. If it was non NULL, it was a user task and if not it was a kernel task. But things have changed over time, and some kernel tasks now have their own mm field. An idea was made to instead test PF_KTHREAD and two functions were used to wrap this check in case it became more complex to test if a task was a user task or not[1]. But this was rejected and the C code simply checked the PF_KTHREAD directly. It was later found that not all kernel threads set PF_KTHREAD. The io-uring helpers instead set PF_USER_WORKER and this needed to be added as well. But checking the flags is still not enough. There's a very small window when a task exits that it frees its mm field and it is set back to NULL. If perf were to trigger at this moment, the flags test would say its a user space task but when perf would read the mm field it would crash with at NULL pointer dereference. Now there are flags that can be used to test if a task is exiting, but they are set in areas that perf may still want to profile the user space task (to see where it exited). The only real test is to check both the flags and the mm field. Instead of making this modification in every location, create a new is_user_task() helper function that does all the tests needed to know if it is safe to read the user space memory or not. [1] https://lore.kernel.org/all/20250425204120.639530125@goodmis.org/ Fixes: 90942f9fac05 ("perf: Use current->flags & PF_KTHREAD|PF_USER_WORKER instead of current->mm == NULL") Closes: https://lore.kernel.org/all/0d877e6f-41a7-4724-875d-0b0a27b8a545@roeck-us.net/ Reported-by: Guenter Roeck Signed-off-by: Steven Rostedt (Google) Signed-off-by: Peter Zijlstra (Intel) Tested-by: Guenter Roeck Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260129102821.46484722@gandalf.local.home [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/sched.h | 5 +++++ kernel/events/callchain.c | 2 +- kernel/events/core.c | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 912d46660c3b..eb567323385e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1961,6 +1961,11 @@ static __always_inline bool is_percpu_thread(void) #endif } +static __always_inline bool is_user_task(struct task_struct *task) +{ + return task->mm && !(task->flags & (PF_KTHREAD | PF_USER_WORKER)); +} + /* Per-process atomic flags. */ #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c index ee01cfcc3506..0bd9cb625111 100644 --- a/kernel/events/callchain.c +++ b/kernel/events/callchain.c @@ -206,7 +206,7 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, if (user && !crosstask) { if (!user_mode(regs)) { - if (current->flags & (PF_KTHREAD | PF_USER_WORKER)) + if (!is_user_task(current)) regs = NULL; else regs = task_pt_regs(current); diff --git a/kernel/events/core.c b/kernel/events/core.c index 7ac6eb809970..ae9a2de1d2ff 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6992,7 +6992,7 @@ static void perf_sample_regs_user(struct perf_regs *regs_user, if (user_mode(regs)) { regs_user->abi = perf_reg_abi(current); regs_user->regs = regs; - } else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) { + } else if (is_user_task(current)) { perf_get_regs_user(regs_user, regs); } else { regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; @@ -7627,7 +7627,7 @@ static u64 perf_virt_to_phys(u64 virt) * Try IRQ-safe get_user_page_fast_only first. * If failed, leave phys_addr as 0. */ - if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) { + if (is_user_task(current)) { struct page *p; pagefault_disable(); @@ -7740,7 +7740,7 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs) { bool kernel = !event->attr.exclude_callchain_kernel; bool user = !event->attr.exclude_callchain_user && - !(current->flags & (PF_KTHREAD | PF_USER_WORKER)); + is_user_task(current); /* Disallow cross-task user callchains. */ bool crosstask = event->ctx->task && event->ctx->task != current; const u32 max_stack = event->attr.sample_max_stack; -- Gitee From 40c1e0cd5242e2c1fa877f73f30e9b018c50fcbb Mon Sep 17 00:00:00 2001 From: Laveesh Bansal Date: Wed, 4 Feb 2026 04:12:22 +0800 Subject: [PATCH 1296/1449] writeback: fix 100% CPU usage when dirtytime_expire_interval is 0 ANBZ: #35228 commit 73408fa92742b88433ee23dd3136908fef13c307 stable. commit 543467d6fe97e27e22a26e367fda972dbefebbff upstream. When vm.dirtytime_expire_seconds is set to 0, wakeup_dirtytime_writeback() schedules delayed work with a delay of 0, causing immediate execution. The function then reschedules itself with 0 delay again, creating an infinite busy loop that causes 100% kworker CPU usage. Fix by: - Only scheduling delayed work in wakeup_dirtytime_writeback() when dirtytime_expire_interval is non-zero - Cancelling the delayed work in dirtytime_interval_handler() when the interval is set to 0 - Adding a guard in start_dirtytime_writeback() for defensive coding Tested by booting kernel in QEMU with virtme-ng: - Before fix: kworker CPU spikes to ~73% - After fix: CPU remains at normal levels - Setting interval back to non-zero correctly resumes writeback Fixes: a2f4870697a5 ("fs: make sure the timestamps for lazytime inodes eventually get written") Cc: stable@vger.kernel.org Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220227 Signed-off-by: Laveesh Bansal Link: https://patch.msgid.link/20260106145059.543282-2-laveeshb@laveeshbansal.com Reviewed-by: Jan Kara Signed-off-by: Christian Brauner [ adapted system_percpu_wq to system_wq for the workqueue used in dirtytime_interval_handler() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/fs-writeback.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 05514dbfecd5..38d34e3204bd 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -2390,12 +2390,14 @@ static void wakeup_dirtytime_writeback(struct work_struct *w) wb_wakeup(wb); } rcu_read_unlock(); - schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + if (dirtytime_expire_interval) + schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); } static int __init start_dirtytime_writeback(void) { - schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + if (dirtytime_expire_interval) + schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); return 0; } __initcall(start_dirtytime_writeback); @@ -2406,8 +2408,12 @@ int dirtytime_interval_handler(struct ctl_table *table, int write, int ret; ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); - if (ret == 0 && write) - mod_delayed_work(system_wq, &dirtytime_work, 0); + if (ret == 0 && write) { + if (dirtytime_expire_interval) + mod_delayed_work(system_wq, &dirtytime_work, 0); + else + cancel_delayed_work_sync(&dirtytime_work); + } return ret; } -- Gitee From 07db174c9a74246f200f3901644f776f59bb7c61 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 4 Feb 2026 02:04:30 +0800 Subject: [PATCH 1297/1449] mptcp: avoid dup SUB_CLOSED events after disconnect ANBZ: #35228 commit 38a0f2215aee4aefc31f4d1065a171e553ba18ac stable. commit 280d654324e33f8e6e3641f76764694c7b64c5db upstream. In case of subflow disconnect(), which can also happen with the first subflow in case of errors like timeout or reset, mptcp_subflow_ctx_reset will reset most fields from the mptcp_subflow_context structure, including close_event_done. Then, when another subflow is closed, yet another SUB_CLOSED event for the disconnected initial subflow is sent. Because of the previous reset, there are no source address and destination port. A solution is then to also check the subflow's local id: it shouldn't be negative anyway. Another solution would be not to reset subflow->close_event_done at disconnect time, but when reused. But then, probably the whole reset could be done when being reused. Let's not change this logic, similar to TCP with tcp_disconnect(). Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events") Cc: stable@vger.kernel.org Reported-by: Marco Angaroni Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/603 Reviewed-by: Geliang Tang Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-1-7f71e1bc4feb@kernel.org Signed-off-by: Jakub Kicinski [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/protocol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 18e81b306a6f..f3856856aa44 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2554,8 +2554,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, void mptcp_close_ssk(struct sock *sk, struct sock *ssk, struct mptcp_subflow_context *subflow) { - /* The first subflow can already be closed and still in the list */ - if (subflow->close_event_done) + /* The first subflow can already be closed or disconnected */ + if (subflow->close_event_done || READ_ONCE(subflow->local_id) < 0) return; subflow->close_event_done = true; -- Gitee From f1dfb90cedeb5a97b2e064f7cd98b3de9c02a011 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 4 Feb 2026 01:04:00 +0800 Subject: [PATCH 1298/1449] pinctrl: qcom: sm8350-lpass-lpi: Merge with SC7280 to fix I2S2 and SWR TX pins ANBZ: #35228 commit 21bad75012f76337022eeb00dadcaa07aa89f1f7 stable. commit 1fbe3abb449c5ef2178e1c3e3e8b9a43a7a410ac upstream. Qualcomm SC7280 and SM8350 SoCs have slightly different LPASS audio blocks (v9.4.5 and v9.2), however the LPASS LPI pin controllers are exactly the same. The driver for SM8350 has two issues, which can be fixed by simply moving over to SC7280 driver which has them correct: 1. "i2s2_data_groups" listed twice GPIO12, but should have both GPIO12 and GPIO13, 2. "swr_tx_data_groups" contained GPIO5 for "swr_tx_data2" function, but that function is also available on GPIO14, thus listing it twice is not necessary. OTOH, GPIO5 has also "swr_rx_data1", so selecting swr_rx_data function should not block the TX one. Fixes: be9f6d56381d ("pinctrl: qcom: sm8350-lpass-lpi: add SM8350 LPASS TLMM") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Reviewed-by: Bartosz Golaszewski Reviewed-by: Konrad Dybcio Signed-off-by: Linus Walleij [ Context, no dedicated config option ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pinctrl/qcom/Kconfig | 15 +- drivers/pinctrl/qcom/Makefile | 1 - .../pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c | 3 + .../pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c | 167 ------------------ 4 files changed, 6 insertions(+), 180 deletions(-) delete mode 100644 drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index f84c0d3b7951..36d7ef4097c0 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -60,13 +60,14 @@ config PINCTRL_LPASS_LPI (Low Power Island) found on the Qualcomm Technologies Inc SoCs. config PINCTRL_SC7280_LPASS_LPI - tristate "Qualcomm Technologies Inc SC7280 LPASS LPI pin controller driver" + tristate "Qualcomm Technologies Inc SC7280 and SM8350 LPASS LPI pin controller driver" depends on ARM64 || COMPILE_TEST depends on PINCTRL_LPASS_LPI help This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI - (Low Power Island) found on the Qualcomm Technologies Inc SC7280 platform. + (Low Power Island) found on the Qualcomm Technologies Inc SC7280 + and SM8350 platforms. config PINCTRL_SM6115_LPASS_LPI tristate "Qualcomm Technologies Inc SM6115 LPASS LPI pin controller driver" @@ -86,16 +87,6 @@ config PINCTRL_SM8250_LPASS_LPI Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI (Low Power Island) found on the Qualcomm Technologies Inc SM8250 platform. -config PINCTRL_SM8350_LPASS_LPI - tristate "Qualcomm Technologies Inc SM8350 LPASS LPI pin controller driver" - depends on ARM64 || COMPILE_TEST - depends on PINCTRL_LPASS_LPI - help - This is the pinctrl, pinmux, pinconf and gpiolib driver for the - Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI - (Low Power Island) found on the Qualcomm Technologies Inc SM8350 - platform. - config PINCTRL_SM8450_LPASS_LPI tristate "Qualcomm Technologies Inc SM8450 LPASS LPI pin controller driver" depends on ARM64 || COMPILE_TEST diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 5910e08c84ce..d1179d8b2c42 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -53,7 +53,6 @@ obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o obj-$(CONFIG_PINCTRL_SM8250_LPASS_LPI) += pinctrl-sm8250-lpass-lpi.o obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o -obj-$(CONFIG_PINCTRL_SM8350_LPASS_LPI) += pinctrl-sm8350-lpass-lpi.o obj-$(CONFIG_PINCTRL_SM8450) += pinctrl-sm8450.o obj-$(CONFIG_PINCTRL_SM8450_LPASS_LPI) += pinctrl-sm8450-lpass-lpi.o obj-$(CONFIG_PINCTRL_SM8550) += pinctrl-sm8550.o diff --git a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c index d615b6c55b89..74cc5b4ac982 100644 --- a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c @@ -147,6 +147,9 @@ static const struct of_device_id lpi_pinctrl_of_match[] = { { .compatible = "qcom,sc7280-lpass-lpi-pinctrl", .data = &sc7280_lpi_data, + }, { + .compatible = "qcom,sm8350-lpass-lpi-pinctrl", + .data = &sc7280_lpi_data, }, { } }; diff --git a/drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c deleted file mode 100644 index f889c779bccd..000000000000 --- a/drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. - * Copyright (c) 2020-2023 Linaro Ltd. - */ - -#include -#include -#include - -#include "pinctrl-lpass-lpi.h" - -enum lpass_lpi_functions { - LPI_MUX_dmic1_clk, - LPI_MUX_dmic1_data, - LPI_MUX_dmic2_clk, - LPI_MUX_dmic2_data, - LPI_MUX_dmic3_clk, - LPI_MUX_dmic3_data, - LPI_MUX_i2s1_clk, - LPI_MUX_i2s1_data, - LPI_MUX_i2s1_ws, - LPI_MUX_i2s2_clk, - LPI_MUX_i2s2_data, - LPI_MUX_i2s2_ws, - LPI_MUX_qua_mi2s_data, - LPI_MUX_qua_mi2s_sclk, - LPI_MUX_qua_mi2s_ws, - LPI_MUX_swr_rx_clk, - LPI_MUX_swr_rx_data, - LPI_MUX_swr_tx_clk, - LPI_MUX_swr_tx_data, - LPI_MUX_wsa_swr_clk, - LPI_MUX_wsa_swr_data, - LPI_MUX_gpio, - LPI_MUX__, -}; - -static int gpio0_pins[] = { 0 }; -static int gpio1_pins[] = { 1 }; -static int gpio2_pins[] = { 2 }; -static int gpio3_pins[] = { 3 }; -static int gpio4_pins[] = { 4 }; -static int gpio5_pins[] = { 5 }; -static int gpio6_pins[] = { 6 }; -static int gpio7_pins[] = { 7 }; -static int gpio8_pins[] = { 8 }; -static int gpio9_pins[] = { 9 }; -static int gpio10_pins[] = { 10 }; -static int gpio11_pins[] = { 11 }; -static int gpio12_pins[] = { 12 }; -static int gpio13_pins[] = { 13 }; -static int gpio14_pins[] = { 14 }; - -static const struct pinctrl_pin_desc sm8350_lpi_pins[] = { - PINCTRL_PIN(0, "gpio0"), - PINCTRL_PIN(1, "gpio1"), - PINCTRL_PIN(2, "gpio2"), - PINCTRL_PIN(3, "gpio3"), - PINCTRL_PIN(4, "gpio4"), - PINCTRL_PIN(5, "gpio5"), - PINCTRL_PIN(6, "gpio6"), - PINCTRL_PIN(7, "gpio7"), - PINCTRL_PIN(8, "gpio8"), - PINCTRL_PIN(9, "gpio9"), - PINCTRL_PIN(10, "gpio10"), - PINCTRL_PIN(11, "gpio11"), - PINCTRL_PIN(12, "gpio12"), - PINCTRL_PIN(13, "gpio13"), - PINCTRL_PIN(14, "gpio14"), -}; - -static const char * const swr_tx_clk_groups[] = { "gpio0" }; -static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio5", "gpio14" }; -static const char * const swr_rx_clk_groups[] = { "gpio3" }; -static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" }; -static const char * const dmic1_clk_groups[] = { "gpio6" }; -static const char * const dmic1_data_groups[] = { "gpio7" }; -static const char * const dmic2_clk_groups[] = { "gpio8" }; -static const char * const dmic2_data_groups[] = { "gpio9" }; -static const char * const i2s2_clk_groups[] = { "gpio10" }; -static const char * const i2s2_ws_groups[] = { "gpio11" }; -static const char * const dmic3_clk_groups[] = { "gpio12" }; -static const char * const dmic3_data_groups[] = { "gpio13" }; -static const char * const qua_mi2s_sclk_groups[] = { "gpio0" }; -static const char * const qua_mi2s_ws_groups[] = { "gpio1" }; -static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4" }; -static const char * const i2s1_clk_groups[] = { "gpio6" }; -static const char * const i2s1_ws_groups[] = { "gpio7" }; -static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" }; -static const char * const wsa_swr_clk_groups[] = { "gpio10" }; -static const char * const wsa_swr_data_groups[] = { "gpio11" }; -static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" }; - -static const struct lpi_pingroup sm8350_groups[] = { - LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _), - LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _), - LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _), - LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _), - LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _), - LPI_PINGROUP(5, 12, swr_tx_data, swr_rx_data, _, _), - LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _), - LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _), - LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _), - LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, _, _), - LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _), - LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _), - LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s2_data, _, _), - LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s2_data, _, _), - LPI_PINGROUP(14, 6, swr_tx_data, _, _, _), -}; - -static const struct lpi_function sm8350_functions[] = { - LPI_FUNCTION(dmic1_clk), - LPI_FUNCTION(dmic1_data), - LPI_FUNCTION(dmic2_clk), - LPI_FUNCTION(dmic2_data), - LPI_FUNCTION(dmic3_clk), - LPI_FUNCTION(dmic3_data), - LPI_FUNCTION(i2s1_clk), - LPI_FUNCTION(i2s1_data), - LPI_FUNCTION(i2s1_ws), - LPI_FUNCTION(i2s2_clk), - LPI_FUNCTION(i2s2_data), - LPI_FUNCTION(i2s2_ws), - LPI_FUNCTION(qua_mi2s_data), - LPI_FUNCTION(qua_mi2s_sclk), - LPI_FUNCTION(qua_mi2s_ws), - LPI_FUNCTION(swr_rx_clk), - LPI_FUNCTION(swr_rx_data), - LPI_FUNCTION(swr_tx_clk), - LPI_FUNCTION(swr_tx_data), - LPI_FUNCTION(wsa_swr_clk), - LPI_FUNCTION(wsa_swr_data), -}; - -static const struct lpi_pinctrl_variant_data sm8350_lpi_data = { - .pins = sm8350_lpi_pins, - .npins = ARRAY_SIZE(sm8350_lpi_pins), - .groups = sm8350_groups, - .ngroups = ARRAY_SIZE(sm8350_groups), - .functions = sm8350_functions, - .nfunctions = ARRAY_SIZE(sm8350_functions), -}; - -static const struct of_device_id lpi_pinctrl_of_match[] = { - { - .compatible = "qcom,sm8350-lpass-lpi-pinctrl", - .data = &sm8350_lpi_data, - }, - { } -}; -MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); - -static struct platform_driver lpi_pinctrl_driver = { - .driver = { - .name = "qcom-sm8350-lpass-lpi-pinctrl", - .of_match_table = lpi_pinctrl_of_match, - }, - .probe = lpi_pinctrl_probe, - .remove = lpi_pinctrl_remove, -}; -module_platform_driver(lpi_pinctrl_driver); - -MODULE_AUTHOR("Krzysztof Kozlowski "); -MODULE_DESCRIPTION("QTI SM8350 LPI GPIO pin control driver"); -MODULE_LICENSE("GPL"); -- Gitee From be4457cfe3831a2878ce0a19dbaebd3d6c37ed8a Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Wed, 4 Feb 2026 08:26:44 +0800 Subject: [PATCH 1299/1449] drm/amdkfd: Don't use sw fault filter if retry cam enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit a3f75ee1a436edfe87c4de66bfe58e7233a59da4 stable. commit e61801f162ddcf8874c820639483ec4849b0fb0b upstream. If retry cam enabled, we don't use sw retry fault filter and add fault into sw filter ring, so we shouldn't remove fault from sw filter. Signed-off-by: Philip Yang Reviewed-by: Christian König Signed-off-by: Alex Deucher Stable-dep-of: 8b1ecc9377bc ("drm/amdgpu: fix NULL pointer dereference in amdgpu_gmc_filter_faults_remove") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 0b6a0e149f1c..9b225acdcf97 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -452,7 +452,10 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr, uint32_t hash; uint64_t tmp; - ih = adev->irq.retry_cam_enabled ? &adev->irq.ih_soft : &adev->irq.ih1; + if (adev->irq.retry_cam_enabled) + return; + + ih = &adev->irq.ih1; /* Get the WPTR of the last entry in IH ring */ last_wptr = amdgpu_ih_get_wptr(adev, ih); /* Order wptr with ring data. */ -- Gitee From 67fb786f74582807c4faf4c73b59645deeecf2f2 Mon Sep 17 00:00:00 2001 From: Jon Doron Date: Wed, 4 Feb 2026 08:26:45 +0800 Subject: [PATCH 1300/1449] drm/amdgpu: fix NULL pointer dereference in amdgpu_gmc_filter_faults_remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit c74e2dbb5316898fb2113a8ea3a93b27698dbf68 stable. commit 8b1ecc9377bc641533cd9e76dfa3aee3cd04a007 upstream. On APUs such as Raven and Renoir (GC 9.1.0, 9.2.2, 9.3.0), the ih1 and ih2 interrupt ring buffers are not initialized. This is by design, as these secondary IH rings are only available on discrete GPUs. See vega10_ih_sw_init() which explicitly skips ih1/ih2 initialization when AMD_IS_APU is set. However, amdgpu_gmc_filter_faults_remove() unconditionally uses ih1 to get the timestamp of the last interrupt entry. When retry faults are enabled on APUs (noretry=0), this function is called from the SVM page fault recovery path, resulting in a NULL pointer dereference when amdgpu_ih_decode_iv_ts_helper() attempts to access ih->ring[]. The crash manifests as: BUG: kernel NULL pointer dereference, address: 0000000000000004 RIP: 0010:amdgpu_ih_decode_iv_ts_helper+0x22/0x40 [amdgpu] Call Trace: amdgpu_gmc_filter_faults_remove+0x60/0x130 [amdgpu] svm_range_restore_pages+0xae5/0x11c0 [amdgpu] amdgpu_vm_handle_fault+0xc8/0x340 [amdgpu] gmc_v9_0_process_interrupt+0x191/0x220 [amdgpu] amdgpu_irq_dispatch+0xed/0x2c0 [amdgpu] amdgpu_ih_process+0x84/0x100 [amdgpu] This issue was exposed by commit 1446226d32a4 ("drm/amdgpu: Remove GC HW IP 9.3.0 from noretry=1") which changed the default for Renoir APU from noretry=1 to noretry=0, enabling retry fault handling and thus exercising the buggy code path. Fix this by adding a check for ih1.ring_size before attempting to use it. Also restore the soft_ih support from commit dd299441654f ("drm/amdgpu: Rework retry fault removal"). This is needed if the hardware doesn't support secondary HW IH rings. v2: additional updates (Alex) Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3814 Fixes: dd299441654f ("drm/amdgpu: Rework retry fault removal") Reviewed-by: Timur Kristóf Reviewed-by: Philip Yang Signed-off-by: Jon Doron Signed-off-by: Alex Deucher (cherry picked from commit 6ce8d536c80aa1f059e82184f0d1994436b1d526) Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 9b225acdcf97..3c24637f3d6e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -454,8 +454,13 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr, if (adev->irq.retry_cam_enabled) return; + else if (adev->irq.ih1.ring_size) + ih = &adev->irq.ih1; + else if (adev->irq.ih_soft.enabled) + ih = &adev->irq.ih_soft; + else + return; - ih = &adev->irq.ih1; /* Get the WPTR of the last entry in IH ring */ last_wptr = amdgpu_ih_get_wptr(adev, ih); /* Order wptr with ring data. */ -- Gitee From f99a92a6105333f5c54d6d0c8460846b1c74f3b1 Mon Sep 17 00:00:00 2001 From: "e.kubanski" Date: Wed, 4 Feb 2026 16:29:20 +0800 Subject: [PATCH 1301/1449] xsk: Fix race condition in AF_XDP generic RX path ANBZ: #35228 commit b6978c565ce33658543c637060852434b4248d30 stable. commit a1356ac7749cafc4e27aa62c0c4604b5dca4983e upstream. Move rx_lock from xsk_socket to xsk_buff_pool. Fix synchronization for shared umem mode in generic RX path where multiple sockets share single xsk_buff_pool. RX queue is exclusive to xsk_socket, while FILL queue can be shared between multiple sockets. This could result in race condition where two CPU cores access RX path of two different sockets sharing the same umem. Protect both queues by acquiring spinlock in shared xsk_buff_pool. Lock contention may be minimized in the future by some per-thread FQ buffering. It's safe and necessary to move spin_lock_bh(rx_lock) after xsk_rcv_check(): * xs->pool and spinlock_init is synchronized by xsk_bind() -> xsk_is_bound() memory barriers. * xsk_rcv_check() may return true at the moment of xsk_release() or xsk_unbind_dev(), however this will not cause any data races or race conditions. xsk_unbind_dev() removes xdp socket from all maps and waits for completion of all outstanding rx operations. Packets in RX path will either complete safely or drop. Signed-off-by: Eryk Kubanski Fixes: bf0bdd1343efb ("xdp: fix race on generic receive path") Acked-by: Magnus Karlsson Link: https://patch.msgid.link/20250416101908.10919-1-e.kubanski@partner.samsung.com Signed-off-by: Jakub Kicinski [ Conflict is resolved when backporting this fix. ] Signed-off-by: Jianqiang kang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/net/xdp_sock.h | 3 --- include/net/xsk_buff_pool.h | 2 ++ net/xdp/xsk.c | 6 +++--- net/xdp/xsk_buff_pool.c | 1 + 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h index 69b472604b86..660c22521a29 100644 --- a/include/net/xdp_sock.h +++ b/include/net/xdp_sock.h @@ -63,9 +63,6 @@ struct xdp_sock { struct xsk_queue *tx ____cacheline_aligned_in_smp; struct list_head tx_list; - /* Protects generic receive. */ - spinlock_t rx_lock; - /* Statistics */ u64 rx_dropped; u64 rx_queue_full; diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h index 4d1797ec6526..568e5937a86e 100644 --- a/include/net/xsk_buff_pool.h +++ b/include/net/xsk_buff_pool.h @@ -54,6 +54,8 @@ struct xsk_buff_pool { refcount_t users; struct xdp_umem *umem; struct work_struct work; + /* Protects generic receive in shared and non-shared umem mode. */ + spinlock_t rx_lock; struct list_head free_list; struct list_head xskb_list; u32 heads_cnt; diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 93c802cfb9c6..569d39f19c56 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -339,13 +339,14 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) u32 len = xdp_get_buff_len(xdp); int err; - spin_lock_bh(&xs->rx_lock); err = xsk_rcv_check(xs, xdp, len); if (!err) { + spin_lock_bh(&xs->pool->rx_lock); err = __xsk_rcv(xs, xdp, len); xsk_flush(xs); + spin_unlock_bh(&xs->pool->rx_lock); } - spin_unlock_bh(&xs->rx_lock); + return err; } @@ -1647,7 +1648,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, xs = xdp_sk(sk); xs->state = XSK_READY; mutex_init(&xs->mutex); - spin_lock_init(&xs->rx_lock); INIT_LIST_HEAD(&xs->map_list); spin_lock_init(&xs->map_list_lock); diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c index e83b707da25b..380b0b3f3d8d 100644 --- a/net/xdp/xsk_buff_pool.c +++ b/net/xdp/xsk_buff_pool.c @@ -85,6 +85,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, XDP_PACKET_HEADROOM; pool->umem = umem; pool->addrs = umem->addrs; + spin_lock_init(&pool->rx_lock); INIT_LIST_HEAD(&pool->free_list); INIT_LIST_HEAD(&pool->xskb_list); INIT_LIST_HEAD(&pool->xsk_tx_list); -- Gitee From f1e148fe3983cd9aef247972126bb76a663cad4d Mon Sep 17 00:00:00 2001 From: Marios Makassikis Date: Wed, 4 Feb 2026 10:22:05 +0800 Subject: [PATCH 1302/1449] ksmbd: fix recursive locking in RPC handle list access ANBZ: #35228 commit 1891abe832cbf5a11039e088766131d0f1642d02 stable. commit 88f170814fea74911ceab798a43cbd7c5599bed4 upstream. Since commit 305853cce3794 ("ksmbd: Fix race condition in RPC handle list access"), ksmbd_session_rpc_method() attempts to lock sess->rpc_lock. This causes hung connections / tasks when a client attempts to open a named pipe. Using Samba's rpcclient tool: $ rpcclient //192.168.1.254 -U user%password $ rpcclient $> srvinfo Kernel side: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:kworker/0:0 state:D stack:0 pid:5021 tgid:5021 ppid:2 flags:0x00200000 Workqueue: ksmbd-io handle_ksmbd_work Call trace: __schedule from schedule+0x3c/0x58 schedule from schedule_preempt_disabled+0xc/0x10 schedule_preempt_disabled from rwsem_down_read_slowpath+0x1b0/0x1d8 rwsem_down_read_slowpath from down_read+0x28/0x30 down_read from ksmbd_session_rpc_method+0x18/0x3c ksmbd_session_rpc_method from ksmbd_rpc_open+0x34/0x68 ksmbd_rpc_open from ksmbd_session_rpc_open+0x194/0x228 ksmbd_session_rpc_open from create_smb2_pipe+0x8c/0x2c8 create_smb2_pipe from smb2_open+0x10c/0x27ac smb2_open from handle_ksmbd_work+0x238/0x3dc handle_ksmbd_work from process_scheduled_works+0x160/0x25c process_scheduled_works from worker_thread+0x16c/0x1e8 worker_thread from kthread+0xa8/0xb8 kthread from ret_from_fork+0x14/0x38 Exception stack(0x8529ffb0 to 0x8529fff8) The task deadlocks because the lock is already held: ksmbd_session_rpc_open down_write(&sess->rpc_lock) ksmbd_rpc_open ksmbd_session_rpc_method down_read(&sess->rpc_lock) <-- deadlock Adjust ksmbd_session_rpc_method() callers to take the lock when necessary. Fixes: 305853cce3794 ("ksmbd: Fix race condition in RPC handle list access") Signed-off-by: Marios Makassikis Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Li hongliang <1468888505@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/mgmt/user_session.c | 7 ++----- fs/smb/server/smb2pdu.c | 9 ++++++++- fs/smb/server/transport_ipc.c | 12 ++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 5986d6d0a90b..e344475a41bd 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -147,14 +147,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id) int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id) { struct ksmbd_session_rpc *entry; - int method; - down_read(&sess->rpc_lock); + lockdep_assert_held(&sess->rpc_lock); entry = xa_load(&sess->rpc_handle_list, id); - method = entry ? entry->method : 0; - up_read(&sess->rpc_lock); - return method; + return entry ? entry->method : 0; } void ksmbd_session_destroy(struct ksmbd_session *sess) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 35f0bc9c81f2..d024eba3719d 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4614,8 +4614,15 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess, * pipe without opening it, checking error condition here */ id = req->VolatileFileId; - if (!ksmbd_session_rpc_method(sess, id)) + + lockdep_assert_not_held(&sess->rpc_lock); + + down_read(&sess->rpc_lock); + if (!ksmbd_session_rpc_method(sess, id)) { + up_read(&sess->rpc_lock); return -ENOENT; + } + up_read(&sess->rpc_lock); ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n", req->FileInfoClass, req->VolatileFileId); diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c index a5b90d0b9f2d..53bfcf57f167 100644 --- a/fs/smb/server/transport_ipc.c +++ b/fs/smb/server/transport_ipc.c @@ -778,6 +778,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle if (!msg) return NULL; + lockdep_assert_not_held(&sess->rpc_lock); + + down_read(&sess->rpc_lock); msg->type = KSMBD_EVENT_RPC_REQUEST; req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; @@ -786,6 +789,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle req->flags |= KSMBD_RPC_WRITE_METHOD; req->payload_sz = payload_sz; memcpy(req->payload, payload, payload_sz); + up_read(&sess->rpc_lock); resp = ipc_msg_send_request(msg, req->handle); ipc_msg_free(msg); @@ -802,6 +806,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle) if (!msg) return NULL; + lockdep_assert_not_held(&sess->rpc_lock); + + down_read(&sess->rpc_lock); msg->type = KSMBD_EVENT_RPC_REQUEST; req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; @@ -809,6 +816,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle) req->flags |= rpc_context_flags(sess); req->flags |= KSMBD_RPC_READ_METHOD; req->payload_sz = 0; + up_read(&sess->rpc_lock); resp = ipc_msg_send_request(msg, req->handle); ipc_msg_free(msg); @@ -829,6 +837,9 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle if (!msg) return NULL; + lockdep_assert_not_held(&sess->rpc_lock); + + down_read(&sess->rpc_lock); msg->type = KSMBD_EVENT_RPC_REQUEST; req = (struct ksmbd_rpc_command *)msg->payload; req->handle = handle; @@ -837,6 +848,7 @@ struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle req->flags |= KSMBD_RPC_IOCTL_METHOD; req->payload_sz = payload_sz; memcpy(req->payload, payload, payload_sz); + up_read(&sess->rpc_lock); resp = ipc_msg_send_request(msg, req->handle); ipc_msg_free(msg); -- Gitee From 6cdb753dd33266ee9b7035b31f2f24ca825ebe1f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 4 Feb 2026 19:55:59 +0800 Subject: [PATCH 1303/1449] ptr_ring: do not block hard interrupts in ptr_ring_resize_multiple() ANBZ: #35228 commit 572777a258c048e0d0fb3a0c47430eadcefe80c0 stable. commit a126061c80d5efb4baef4bcf346094139cd81df6 upstream. Jakub added a lockdep_assert_no_hardirq() check in __page_pool_put_page() to increase test coverage. syzbot found a splat caused by hard irq blocking in ptr_ring_resize_multiple() [1] As current users of ptr_ring_resize_multiple() do not require hard irqs being masked, replace it to only block BH. Rename helpers to better reflect they are safe against BH only. - ptr_ring_resize_multiple() to ptr_ring_resize_multiple_bh() - skb_array_resize_multiple() to skb_array_resize_multiple_bh() [1] WARNING: CPU: 1 PID: 9150 at net/core/page_pool.c:709 __page_pool_put_page net/core/page_pool.c:709 [inline] WARNING: CPU: 1 PID: 9150 at net/core/page_pool.c:709 page_pool_put_unrefed_netmem+0x157/0xa40 net/core/page_pool.c:780 Modules linked in: CPU: 1 UID: 0 PID: 9150 Comm: syz.1.1052 Not tainted 6.11.0-rc3-syzkaller-00202-gf8669d7b5f5d #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 RIP: 0010:__page_pool_put_page net/core/page_pool.c:709 [inline] RIP: 0010:page_pool_put_unrefed_netmem+0x157/0xa40 net/core/page_pool.c:780 Code: 74 0e e8 7c aa fb f7 eb 43 e8 75 aa fb f7 eb 3c 65 8b 1d 38 a8 6a 76 31 ff 89 de e8 a3 ae fb f7 85 db 74 0b e8 5a aa fb f7 90 <0f> 0b 90 eb 1d 65 8b 1d 15 a8 6a 76 31 ff 89 de e8 84 ae fb f7 85 RSP: 0018:ffffc9000bda6b58 EFLAGS: 00010083 RAX: ffffffff8997e523 RBX: 0000000000000000 RCX: 0000000000040000 RDX: ffffc9000fbd0000 RSI: 0000000000001842 RDI: 0000000000001843 RBP: 0000000000000000 R08: ffffffff8997df2c R09: 1ffffd40003a000d R10: dffffc0000000000 R11: fffff940003a000e R12: ffffea0001d00040 R13: ffff88802e8a4000 R14: dffffc0000000000 R15: 00000000ffffffff FS: 00007fb7aaf716c0(0000) GS:ffff8880b9300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa15a0d4b72 CR3: 00000000561b0000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: tun_ptr_free drivers/net/tun.c:617 [inline] __ptr_ring_swap_queue include/linux/ptr_ring.h:571 [inline] ptr_ring_resize_multiple_noprof include/linux/ptr_ring.h:643 [inline] tun_queue_resize drivers/net/tun.c:3694 [inline] tun_device_event+0xaaf/0x1080 drivers/net/tun.c:3714 notifier_call_chain+0x19f/0x3e0 kernel/notifier.c:93 call_netdevice_notifiers_extack net/core/dev.c:2032 [inline] call_netdevice_notifiers net/core/dev.c:2046 [inline] dev_change_tx_queue_len+0x158/0x2a0 net/core/dev.c:9024 do_setlink+0xff6/0x41f0 net/core/rtnetlink.c:2923 rtnl_setlink+0x40d/0x5a0 net/core/rtnetlink.c:3201 rtnetlink_rcv_msg+0x73f/0xcf0 net/core/rtnetlink.c:6647 netlink_rcv_skb+0x1e3/0x430 net/netlink/af_netlink.c:2550 Fixes: ff4e538c8c3e ("page_pool: add a lockdep check for recycling in hardirq") Reported-by: syzbot+f56a5c5eac2b28439810@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/671e10df.050a0220.2b8c0f.01cf.GAE@google.com/T/ Signed-off-by: Eric Dumazet Acked-by: Michael S. Tsirkin Acked-by: Jason Wang Link: https://patch.msgid.link/20241217135121.326370-1-edumazet@google.com Signed-off-by: Jakub Kicinski [ 2c321f3f70bc ("mm: change inlined allocation helpers to account at the call site") is not ported to Linux-6.6.y. So remove the suffix "_noprof". ] Signed-off-by: Alva Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/tap.c | 6 +++--- drivers/net/tun.c | 6 +++--- include/linux/ptr_ring.h | 17 ++++++++--------- include/linux/skb_array.h | 14 ++++++++------ net/sched/sch_generic.c | 4 ++-- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index e7212a64a591..2c4f9d19827f 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1330,9 +1330,9 @@ int tap_queue_resize(struct tap_dev *tap) list_for_each_entry(q, &tap->queue_list, next) rings[i++] = &q->ring; - ret = ptr_ring_resize_multiple(rings, n, - dev->tx_queue_len, GFP_KERNEL, - __skb_array_destroy_skb); + ret = ptr_ring_resize_multiple_bh(rings, n, + dev->tx_queue_len, GFP_KERNEL, + __skb_array_destroy_skb); kfree(rings); return ret; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index c1fdf8804d60..97dbec8d7807 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -3682,9 +3682,9 @@ static int tun_queue_resize(struct tun_struct *tun) list_for_each_entry(tfile, &tun->disabled, next) rings[i++] = &tfile->tx_ring; - ret = ptr_ring_resize_multiple(rings, n, - dev->tx_queue_len, GFP_KERNEL, - tun_ptr_free); + ret = ptr_ring_resize_multiple_bh(rings, n, + dev->tx_queue_len, GFP_KERNEL, + tun_ptr_free); kfree(rings); return ret; diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h index 808f9d3ee546..65da2155cce2 100644 --- a/include/linux/ptr_ring.h +++ b/include/linux/ptr_ring.h @@ -613,15 +613,14 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp, /* * Note: producer lock is nested within consumer lock, so if you * resize you must make sure all uses nest correctly. - * In particular if you consume ring in interrupt or BH context, you must - * disable interrupts/BH when doing so. + * In particular if you consume ring in BH context, you must + * disable BH when doing so. */ -static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, - unsigned int nrings, - int size, - gfp_t gfp, void (*destroy)(void *)) +static inline int ptr_ring_resize_multiple_bh(struct ptr_ring **rings, + unsigned int nrings, + int size, gfp_t gfp, + void (*destroy)(void *)) { - unsigned long flags; void ***queues; int i; @@ -636,12 +635,12 @@ static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, } for (i = 0; i < nrings; ++i) { - spin_lock_irqsave(&(rings[i])->consumer_lock, flags); + spin_lock_bh(&(rings[i])->consumer_lock); spin_lock(&(rings[i])->producer_lock); queues[i] = __ptr_ring_swap_queue(rings[i], queues[i], size, gfp, destroy); spin_unlock(&(rings[i])->producer_lock); - spin_unlock_irqrestore(&(rings[i])->consumer_lock, flags); + spin_unlock_bh(&(rings[i])->consumer_lock); } for (i = 0; i < nrings; ++i) diff --git a/include/linux/skb_array.h b/include/linux/skb_array.h index e2d45b7cb619..6c7f856e211a 100644 --- a/include/linux/skb_array.h +++ b/include/linux/skb_array.h @@ -198,16 +198,18 @@ static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp) return ptr_ring_resize(&a->ring, size, gfp, __skb_array_destroy_skb); } -static inline int skb_array_resize_multiple(struct skb_array **rings, - int nrings, unsigned int size, - gfp_t gfp) +static inline int skb_array_resize_multiple_bh(struct skb_array **rings, + int nrings, + unsigned int size, + gfp_t gfp) { BUILD_BUG_ON(offsetof(struct skb_array, ring)); - return ptr_ring_resize_multiple((struct ptr_ring **)rings, - nrings, size, gfp, - __skb_array_destroy_skb); + return ptr_ring_resize_multiple_bh((struct ptr_ring **)rings, + nrings, size, gfp, + __skb_array_destroy_skb); } + static inline void skb_array_cleanup(struct skb_array *a) { ptr_ring_cleanup(&a->ring, __skb_array_destroy_skb); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 1b51b3038b4b..c1c67da2d3fc 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -910,8 +910,8 @@ static int pfifo_fast_change_tx_queue_len(struct Qdisc *sch, bands[prio] = q; } - return skb_array_resize_multiple(bands, PFIFO_FAST_BANDS, new_len, - GFP_KERNEL); + return skb_array_resize_multiple_bh(bands, PFIFO_FAST_BANDS, new_len, + GFP_KERNEL); } struct Qdisc_ops pfifo_fast_ops __read_mostly = { -- Gitee From e17d435c2033e08338ca52ce3a49e18157b9c06c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 4 Feb 2026 20:43:45 +0800 Subject: [PATCH 1304/1449] drm/amd/display: use udelay rather than fsleep ANBZ: #35228 commit dd4c7800a905d96d82aabbf6f14e853c238a47ef stable. commit 27e4dc2c0543fd1808cc52bd888ee1e0533c4a2e upstream. This function can be called from an atomic context so we can't use fsleep(). Fixes: 01f60348d8fb ("drm/amd/display: Fix 'failed to blank crtc!'") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4549 Cc: Wen Chen Cc: Fangzhi Zuo Cc: Nicholas Kazlauskas Cc: Harry Wentland Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher [ Backport for file path changed ] Signed-off-by: Wentao Guan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index f0b472e84a53..e52c2bb1b626 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -781,7 +781,7 @@ enum dc_status dcn20_enable_stream_timing( return DC_ERROR_UNEXPECTED; } - fsleep(stream->timing.v_total * (stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz)); + udelay(stream->timing.v_total * (stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz)); params.vertical_total_min = stream->adjust.v_total_min; params.vertical_total_max = stream->adjust.v_total_max; -- Gitee From 0242ee4d5bdc7de24929d9827a5709c4f7d0ceff Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 4 Feb 2026 21:49:18 +0800 Subject: [PATCH 1305/1449] Revert "net: Allow to use SMP threads for backlog NAPI." ANBZ: #35228 commit 507692c05636311fffb39dac90d434a078f69215 stable. This reverts commit f3652768a89cfdaedbe2c9384299eea7ec435fef which is commit dad6b97702639fba27a2bd3e986982ad6f0db3a7 upstream. It is only for issues around PREEMPT_RT, which is not in the 6.6.y tree, so revert this for now. Link: https://lore.kernel.org/r/20260120103833.4kssDD1Y@linutronix.de Reported-by: Jakub Kicinski Reported-by: Sebastian Andrzej Siewior Cc: Paolo Abeni Cc: Wen Yang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/dev.c | 148 ++++++++++++------------------------------------- 1 file changed, 35 insertions(+), 113 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 8a7a5e16da00..3724735f62a4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -78,7 +78,6 @@ #include #include #include -#include #include #include #include @@ -218,31 +217,6 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) return &net->dev_index_head[ifindex & (NETDEV_HASHENTRIES - 1)]; } -#ifndef CONFIG_PREEMPT_RT - -static DEFINE_STATIC_KEY_FALSE(use_backlog_threads_key); - -static int __init setup_backlog_napi_threads(char *arg) -{ - static_branch_enable(&use_backlog_threads_key); - return 0; -} -early_param("thread_backlog_napi", setup_backlog_napi_threads); - -static bool use_backlog_threads(void) -{ - return static_branch_unlikely(&use_backlog_threads_key); -} - -#else - -static bool use_backlog_threads(void) -{ - return true; -} - -#endif - static inline void rps_lock_irqsave(struct softnet_data *sd, unsigned long *flags) { @@ -4533,7 +4507,6 @@ EXPORT_SYMBOL(__dev_direct_xmit); /************************************************************************* * Receiver routines *************************************************************************/ -static DEFINE_PER_CPU(struct task_struct *, backlog_napi); int netdev_max_backlog __read_mostly = 1000; EXPORT_SYMBOL(netdev_max_backlog); @@ -4566,16 +4539,12 @@ static inline void ____napi_schedule(struct softnet_data *sd, */ thread = READ_ONCE(napi->thread); if (thread) { - if (use_backlog_threads() && thread == raw_cpu_read(backlog_napi)) - goto use_local_napi; - set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); wake_up_process(thread); return; } } -use_local_napi: list_add_tail(&napi->poll_list, &sd->poll_list); WRITE_ONCE(napi->list_owner, smp_processor_id()); /* If not called from net_rx_action() @@ -4821,11 +4790,6 @@ static void napi_schedule_rps(struct softnet_data *sd) #ifdef CONFIG_RPS if (sd != mysd) { - if (use_backlog_threads()) { - __napi_schedule_irqoff(&sd->backlog); - return; - } - sd->rps_ipi_next = mysd->rps_ipi_list; mysd->rps_ipi_list = sd; @@ -6049,7 +6013,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) #ifdef CONFIG_RPS struct softnet_data *remsd = sd->rps_ipi_list; - if (!use_backlog_threads() && remsd) { + if (remsd) { sd->rps_ipi_list = NULL; local_irq_enable(); @@ -6064,7 +6028,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) { #ifdef CONFIG_RPS - return !use_backlog_threads() && sd->rps_ipi_list; + return sd->rps_ipi_list != NULL; #else return false; #endif @@ -6108,7 +6072,7 @@ static int process_backlog(struct napi_struct *napi, int quota) * We can use a plain write instead of clear_bit(), * and we dont need an smp_mb() memory barrier. */ - napi->state &= NAPIF_STATE_THREADED; + napi->state = 0; again = false; } else { skb_queue_splice_tail_init(&sd->input_pkt_queue, @@ -6774,48 +6738,43 @@ static void skb_defer_free_flush(struct softnet_data *sd) } } -static void napi_threaded_poll_loop(struct napi_struct *napi) +static int napi_threaded_poll(void *data) { + struct napi_struct *napi = data; struct softnet_data *sd; - unsigned long last_qs = jiffies; + void *have; - for (;;) { - bool repoll = false; - void *have; + while (!napi_thread_wait(napi)) { + unsigned long last_qs = jiffies; - local_bh_disable(); - sd = this_cpu_ptr(&softnet_data); - sd->in_napi_threaded_poll = true; + for (;;) { + bool repoll = false; - have = netpoll_poll_lock(napi); - __napi_poll(napi, &repoll); - netpoll_poll_unlock(have); + local_bh_disable(); + sd = this_cpu_ptr(&softnet_data); + sd->in_napi_threaded_poll = true; - sd->in_napi_threaded_poll = false; - barrier(); + have = netpoll_poll_lock(napi); + __napi_poll(napi, &repoll); + netpoll_poll_unlock(have); - if (sd_has_rps_ipi_waiting(sd)) { - local_irq_disable(); - net_rps_action_and_irq_enable(sd); - } - skb_defer_free_flush(sd); - local_bh_enable(); + sd->in_napi_threaded_poll = false; + barrier(); - if (!repoll) - break; - - rcu_softirq_qs_periodic(last_qs); - cond_resched(); - } -} - -static int napi_threaded_poll(void *data) -{ - struct napi_struct *napi = data; + if (sd_has_rps_ipi_waiting(sd)) { + local_irq_disable(); + net_rps_action_and_irq_enable(sd); + } + skb_defer_free_flush(sd); + local_bh_enable(); - while (!napi_thread_wait(napi)) - napi_threaded_poll_loop(napi); + if (!repoll) + break; + rcu_softirq_qs_periodic(last_qs); + cond_resched(); + } + } return 0; } @@ -11400,7 +11359,7 @@ static int dev_cpu_dead(unsigned int oldcpu) list_del_init(&napi->poll_list); if (napi->poll == process_backlog) - napi->state &= NAPIF_STATE_THREADED; + napi->state = 0; else ____napi_schedule(sd, napi); } @@ -11408,14 +11367,12 @@ static int dev_cpu_dead(unsigned int oldcpu) raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); - if (!use_backlog_threads()) { #ifdef CONFIG_RPS - remsd = oldsd->rps_ipi_list; - oldsd->rps_ipi_list = NULL; + remsd = oldsd->rps_ipi_list; + oldsd->rps_ipi_list = NULL; #endif - /* send out pending IPI's on offline CPU */ - net_rps_send_ipi(remsd); - } + /* send out pending IPI's on offline CPU */ + net_rps_send_ipi(remsd); /* Process offline CPU's input_pkt_queue */ while ((skb = __skb_dequeue(&oldsd->process_queue))) { @@ -11678,38 +11635,6 @@ static struct pernet_operations __net_initdata default_device_ops = { * */ -static int backlog_napi_should_run(unsigned int cpu) -{ - struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); - struct napi_struct *napi = &sd->backlog; - - return test_bit(NAPI_STATE_SCHED_THREADED, &napi->state); -} - -static void run_backlog_napi(unsigned int cpu) -{ - struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); - - napi_threaded_poll_loop(&sd->backlog); -} - -static void backlog_napi_setup(unsigned int cpu) -{ - struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); - struct napi_struct *napi = &sd->backlog; - - napi->thread = this_cpu_read(backlog_napi); - set_bit(NAPI_STATE_THREADED, &napi->state); -} - -static struct smp_hotplug_thread backlog_threads = { - .store = &backlog_napi, - .thread_should_run = backlog_napi_should_run, - .thread_fn = run_backlog_napi, - .thread_comm = "backlog_napi/%u", - .setup = backlog_napi_setup, -}; - /* * This is called single threaded during boot, so no need * to take the rtnl semaphore. @@ -11760,10 +11685,7 @@ static int __init net_dev_init(void) init_gro_hash(&sd->backlog); sd->backlog.poll = process_backlog; sd->backlog.weight = weight_p; - INIT_LIST_HEAD(&sd->backlog.poll_list); } - if (use_backlog_threads()) - smpboot_register_percpu_thread(&backlog_threads); dev_boot_phase = 0; -- Gitee From 45beafac32b5933e6c1affd462a02c62f328671e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 4 Feb 2026 21:51:26 +0800 Subject: [PATCH 1306/1449] Revert "net: Remove conditional threaded-NAPI wakeup based on task state." ANBZ: #35228 commit 5a530c8ead06e63e6d4f4997ad5e490575a48f3d stable. This reverts commit 03765d5c18084eab40351fda09bc6fc1a343cd07 which is commit 56364c910691f6d10ba88c964c9041b9ab777bd6 upstream. It is only for issues around PREEMPT_RT, which is not in the 6.6.y tree, so revert this for now. Link: https://lore.kernel.org/r/20260120103833.4kssDD1Y@linutronix.de Reported-by: Jakub Kicinski Reported-by: Sebastian Andrzej Siewior Cc: Paolo Abeni Cc: Wen Yang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/dev.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 3724735f62a4..206194bb8fca 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4539,7 +4539,13 @@ static inline void ____napi_schedule(struct softnet_data *sd, */ thread = READ_ONCE(napi->thread); if (thread) { - set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); + /* Avoid doing set_bit() if the thread is in + * INTERRUPTIBLE state, cause napi_thread_wait() + * makes sure to proceed with napi polling + * if the thread is explicitly woken from here. + */ + if (READ_ONCE(thread->__state) != TASK_INTERRUPTIBLE) + set_bit(NAPI_STATE_SCHED_THREADED, &napi->state); wake_up_process(thread); return; } @@ -6695,6 +6701,8 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll) static int napi_thread_wait(struct napi_struct *napi) { + bool woken = false; + set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { @@ -6703,13 +6711,15 @@ static int napi_thread_wait(struct napi_struct *napi) * Testing SCHED bit is not enough because SCHED bit might be * set by some other busy poll thread or by napi_disable(). */ - if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state)) { + if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) { WARN_ON(!list_empty(&napi->poll_list)); __set_current_state(TASK_RUNNING); return 0; } schedule(); + /* woken being true indicates this thread owns this napi. */ + woken = true; set_current_state(TASK_INTERRUPTIBLE); } __set_current_state(TASK_RUNNING); -- Gitee From b1f62e182b395f5c5686da3e1cca2df2d8e5f5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20Lothor=C3=A9=20=28eBPF=20Foundation=29?= Date: Thu, 27 Feb 2025 22:08:23 +0800 Subject: [PATCH 1307/1449] bpf/selftests: test_select_reuseport_kern: Remove unused header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 7e0d31c47b8a97db89b5af0ca8f355bebeff0c2e stable. commit 93cf4e537ed0c5bd9ba6cbdb2c33864547c1442f upstream. test_select_reuseport_kern.c is currently including , but it does not use any definition from there. Remove stdlib.h inclusion from test_select_reuseport_kern.c Signed-off-by: Alexis Lothoré (eBPF Foundation) Signed-off-by: Martin KaFai Lau Link: https://patch.msgid.link/20250227-remove_wrong_header-v1-1-bc94eb4e2f73@bootlin.com Signed-off-by: Alexei Starovoitov [shung-hsi.yu: Fix compilation error mentioned in footer of Alexis' patch with newer glibc header: [...] CLNG-BPF [test_progs-cpuv4] test_select_reuseport_kern.bpf.o In file included from progs/test_select_reuseport_kern.c:4: /usr/include/bits/floatn.h:83:52: error: unsupported machine mode '__TC__' 83 | typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__))); | ^ /usr/include/bits/floatn.h:97:9: error: __float128 is not supported on this target 97 | typedef __float128 _Float128; I'm not certain when the problem starts to occur, but I'm quite sure test_select_reuseport_kern.c were not meant to be using the C standard library in the first place.] Signed-off-by: Shung-Hsi Yu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c b/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c index 5eb25c6ad75b..a5be3267dbb0 100644 --- a/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c +++ b/tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018 Facebook */ -#include #include #include #include -- Gitee From b20db9ee5f73e1329232f23f77507bb36e4cc268 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 27 Jan 2026 05:10:46 +0800 Subject: [PATCH 1308/1449] x86/kfence: fix booting on 32bit non-PAE systems ANBZ: #35228 commit c56b4c84b3b21e9a7de4da39e0ba063bb1573952 stable. commit 16459fe7e0ca6520a6e8f603de4ccd52b90fd765 upstream. The original patch inverted the PTE unconditionally to avoid L1TF-vulnerable PTEs, but Linux doesn't make this adjustment in 2-level paging. Adjust the logic to use the flip_protnone_guard() helper, which is a nop on 2-level paging but inverts the address bits in all other paging modes. This doesn't matter for the Xen aspect of the original change. Linux no longer supports running 32bit PV under Xen, and Xen doesn't support running any 32bit PV guests without using PAE paging. Link: https://lkml.kernel.org/r/20260126211046.2096622-1-andrew.cooper3@citrix.com Fixes: b505f1944535 ("x86/kfence: avoid writing L1TF-vulnerable PTEs") Reported-by: Ryusuke Konishi Closes: https://lore.kernel.org/lkml/CAKFNMokwjw68ubYQM9WkzOuH51wLznHpEOMSqtMoV1Rn9JV_gw@mail.gmail.com/ Signed-off-by: Andrew Cooper Tested-by: Ryusuke Konishi Tested-by: Borislav Petkov (AMD) Cc: Alexander Potapenko Cc: Marco Elver Cc: Dmitry Vyukov Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Dave Hansen Cc: "H. Peter Anvin" Cc: Jann Horn Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/x86/include/asm/kfence.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/kfence.h b/arch/x86/include/asm/kfence.h index 9eb234296890..2a467aaa0eeb 100644 --- a/arch/x86/include/asm/kfence.h +++ b/arch/x86/include/asm/kfence.h @@ -43,7 +43,7 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) { unsigned int level; pte_t *pte = lookup_address(addr, &level); - pteval_t val; + pteval_t val, new; if (WARN_ON(!pte || level != PG_LEVEL_4K)) return false; @@ -58,11 +58,12 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) return true; /* - * Otherwise, invert the entire PTE. This avoids writing out an + * Otherwise, flip the Present bit, taking care to avoid writing an * L1TF-vulnerable PTE (not present, without the high address bits * set). */ - set_pte(pte, __pte(~val)); + new = val ^ _PAGE_PRESENT; + set_pte(pte, __pte(flip_protnone_guard(val, new, PTE_PFN_MASK))); /* * If the page was protected (non-present) and we're making it -- Gitee From 1d563ec22468d5c094544d93246745744fc79291 Mon Sep 17 00:00:00 2001 From: Kaushlendra Kumar Date: Wed, 24 Dec 2025 11:20:53 +0800 Subject: [PATCH 1309/1449] platform/x86: intel_telemetry: Fix swapped arrays in PSS output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 302651ccef698774ab540b4a64431cbf6ccac1a1 stable. commit 25e9e322d2ab5c03602eff4fbf4f7c40019d8de2 upstream. The LTR blocking statistics and wakeup event counters are incorrectly cross-referenced during debugfs output rendering. The code populates pss_ltr_blkd[] with LTR blocking data and pss_s0ix_wakeup[] with wakeup data, but the display loops reference the wrong arrays. This causes the "LTR Blocking Status" section to print wakeup events and the "Wakes Status" section to print LTR blockers, misleading power management analysis and S0ix residency debugging. Fix by aligning array usage with the intended output section labels. Fixes: 87bee290998d ("platform:x86: Add Intel Telemetry Debugfs interfaces") Cc: stable@vger.kernel.org Signed-off-by: Kaushlendra Kumar Link: https://patch.msgid.link/20251224032053.3915900-1-kaushlendra.kumar@intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/intel/telemetry/debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel/telemetry/debugfs.c b/drivers/platform/x86/intel/telemetry/debugfs.c index 1d4d0fbfd63c..e533de621ac4 100644 --- a/drivers/platform/x86/intel/telemetry/debugfs.c +++ b/drivers/platform/x86/intel/telemetry/debugfs.c @@ -449,7 +449,7 @@ static int telem_pss_states_show(struct seq_file *s, void *unused) for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) { seq_printf(s, "%-32s\t%u\n", debugfs_conf->pss_ltr_data[index].name, - pss_s0ix_wakeup[index]); + pss_ltr_blkd[index]); } seq_puts(s, "\n--------------------------------------\n"); @@ -459,7 +459,7 @@ static int telem_pss_states_show(struct seq_file *s, void *unused) for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) { seq_printf(s, "%-32s\t%u\n", debugfs_conf->pss_wakeup[index].name, - pss_ltr_blkd[index]); + pss_s0ix_wakeup[index]); } return 0; -- Gitee From 29db7d543fadbe3baedb9a786447106f60382ae5 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Fri, 23 Jan 2026 01:20:12 +0800 Subject: [PATCH 1310/1449] pmdomain: qcom: rpmpd: fix off-by-one error in clamping to the highest state ANBZ: #35228 commit c28dcc1cb4fda72d60893554d6b623b599ca9030 stable. commit 8aa6f7697f5981d336cac7af6ddd182a03c6da01 upstream. As it is indicated by the comment, the rpmpd_aggregate_corner() function tries to clamp the state to the highest corner/level supported by the given power domain, however the calculation of the highest state contains an off-by-one error. The 'max_state' member of the 'rpmpd' structure indicates the highest corner/level, and as such it does not needs to be decremented. Change the code to use the 'max_state' value directly to avoid the error. Fixes: 98c8b3efacae ("soc: qcom: rpmpd: Add sync_state") Signed-off-by: Gabor Juhos Reviewed-by: Konrad Dybcio Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/qcom/rpmpd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c index 3135dd1dafe0..d70a2cb4b529 100644 --- a/drivers/pmdomain/qcom/rpmpd.c +++ b/drivers/pmdomain/qcom/rpmpd.c @@ -825,7 +825,7 @@ static int rpmpd_aggregate_corner(struct rpmpd *pd) /* Clamp to the highest corner/level if sync_state isn't done yet */ if (!pd->state_synced) - this_active_corner = this_sleep_corner = pd->max_state - 1; + this_active_corner = this_sleep_corner = pd->max_state; else to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); -- Gitee From 9dc5604343bf58353dc8aa309bd5d89de4b0a2b3 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 4 Feb 2026 19:11:41 +0800 Subject: [PATCH 1311/1449] pmdomain: imx8mp-blk-ctrl: Keep gpc power domain on for system wakeup ANBZ: #35228 commit 1267af5b2033d1e1138b756d457d3e3f8f1a96f1 stable. commit e9ab2b83893dd03cf04d98faded81190e635233f upstream. Current design will power off all dependent GPC power domains in imx8mp_blk_ctrl_suspend(), even though the user device has enabled wakeup capability. The result is that wakeup function never works for such device. An example will be USB wakeup on i.MX8MP. PHY device '382f0040.usb-phy' is attached to power domain 'hsioblk-usb-phy2' which is spawned by hsio block control. A virtual power domain device 'genpd:3:32f10000.blk-ctrl' is created to build connection with 'hsioblk-usb-phy2' and it depends on GPC power domain 'usb-otg2'. If device '382f0040.usb-phy' enable wakeup, only power domain 'hsioblk-usb-phy2' keeps on during system suspend, power domain 'usb-otg2' is off all the time. So the wakeup event can't happen. In order to further establish a connection between the power domains related to GPC and block control during system suspend, register a genpd power on/off notifier for the power_dev. This allows us to prevent the GPC power domain from being powered off, in case the block control power domain is kept on to serve system wakeup. Suggested-by: Ulf Hansson Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl") Cc: stable@vger.kernel.org Signed-off-by: Xu Yang Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c index faf643a4a5d0..e4173e7a0c7b 100644 --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c @@ -65,6 +65,7 @@ struct imx8mp_blk_ctrl_domain { struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; struct device *power_dev; struct imx8mp_blk_ctrl *bc; + struct notifier_block power_nb; int num_paths; int id; }; @@ -594,6 +595,20 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd) return 0; } +static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct imx8mp_blk_ctrl_domain *domain = + container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb); + + if (action == GENPD_NOTIFY_PRE_OFF) { + if (domain->genpd.status == GENPD_STATE_ON) + return NOTIFY_BAD; + } + + return NOTIFY_OK; +} + static struct lock_class_key blk_ctrl_genpd_lock_class; static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) @@ -695,6 +710,14 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) goto cleanup_pds; } + domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier; + ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb); + if (ret) { + dev_err_probe(dev, ret, "failed to add power notifier\n"); + dev_pm_domain_detach(domain->power_dev, true); + goto cleanup_pds; + } + domain->genpd.name = data->name; domain->genpd.power_on = imx8mp_blk_ctrl_power_on; domain->genpd.power_off = imx8mp_blk_ctrl_power_off; @@ -704,6 +727,7 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ret = pm_genpd_init(&domain->genpd, NULL, true); if (ret) { dev_err_probe(dev, ret, "failed to init power domain\n"); + dev_pm_genpd_remove_notifier(domain->power_dev); dev_pm_domain_detach(domain->power_dev, true); goto cleanup_pds; } @@ -752,6 +776,7 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) cleanup_pds: for (i--; i >= 0; i--) { pm_genpd_remove(&bc->domains[i].genpd); + dev_pm_genpd_remove_notifier(bc->domains[i].power_dev); dev_pm_domain_detach(bc->domains[i].power_dev, true); } @@ -771,6 +796,7 @@ static int imx8mp_blk_ctrl_remove(struct platform_device *pdev) struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; pm_genpd_remove(&domain->genpd); + dev_pm_genpd_remove_notifier(domain->power_dev); dev_pm_domain_detach(domain->power_dev, true); } -- Gitee From 311ff2cb9cb147a556f785a3eea2c5aa557e5bd4 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Fri, 23 Jan 2026 10:51:26 +0800 Subject: [PATCH 1312/1449] pmdomain: imx: gpcv2: Fix the imx8mm gpu hang due to wrong adb400 reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e2e1c77319d52fa4b8fa008161d4f065cae22435 stable. commit ae0a24c5a8dcea20bf8e344eadf6593e6d1959c3 upstream. On i.MX8MM, the GPUMIX, GPU2D, and GPU3D blocks share a common reset domain. Due to this hardware limitation, powering off/on GPU2D or GPU3D also triggers a reset of the GPUMIX domain, including its ADB400 port. However, the ADB400 interface must always be placed into power‑down mode before being reset. Currently the GPUMIX and GPU2D/3D power domains rely on runtime PM to handle dependency ordering. In some corner cases, the GPUMIX power off sequence is skipped, leaving the ADB400 port active when GPU2D/3D reset. This causes the GPUMIX ADB400 port to be reset while still active, leading to unpredictable bus behavior and GPU hangs. To avoid this, refine the power‑domain control logic so that the GPUMIX ADB400 port is explicitly powered down and powered up as part of the GPU power domain on/off sequence. This ensures proper ordering and prevents incorrect ADB400 reset. Suggested-by: Lucas Stach Signed-off-by: Jacky Bai Reviewed-by: Lucas Stach Tested-by: Philipp Zabel Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/gpcv2.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c index 84d68c805cac..4db6ec044926 100644 --- a/drivers/pmdomain/imx/gpcv2.c +++ b/drivers/pmdomain/imx/gpcv2.c @@ -165,13 +165,11 @@ #define IMX8M_VPU_HSK_PWRDNREQN BIT(5) #define IMX8M_DISP_HSK_PWRDNREQN BIT(4) -#define IMX8MM_GPUMIX_HSK_PWRDNACKN BIT(29) -#define IMX8MM_GPU_HSK_PWRDNACKN (BIT(27) | BIT(28)) +#define IMX8MM_GPU_HSK_PWRDNACKN GENMASK(29, 27) #define IMX8MM_VPUMIX_HSK_PWRDNACKN BIT(26) #define IMX8MM_DISPMIX_HSK_PWRDNACKN BIT(25) #define IMX8MM_HSIO_HSK_PWRDNACKN (BIT(23) | BIT(24)) -#define IMX8MM_GPUMIX_HSK_PWRDNREQN BIT(11) -#define IMX8MM_GPU_HSK_PWRDNREQN (BIT(9) | BIT(10)) +#define IMX8MM_GPU_HSK_PWRDNREQN GENMASK(11, 9) #define IMX8MM_VPUMIX_HSK_PWRDNREQN BIT(8) #define IMX8MM_DISPMIX_HSK_PWRDNREQN BIT(7) #define IMX8MM_HSIO_HSK_PWRDNREQN (BIT(5) | BIT(6)) @@ -783,8 +781,6 @@ static const struct imx_pgc_domain imx8mm_pgc_domains[] = { .bits = { .pxx = IMX8MM_GPUMIX_SW_Pxx_REQ, .map = IMX8MM_GPUMIX_A53_DOMAIN, - .hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN, - .hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN, }, .pgc = BIT(IMX8MM_PGC_GPUMIX), .keep_clocks = true, -- Gitee From a43c0b4925ba1d320eb2596f2b00c81c683647bd Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 4 Feb 2026 19:11:42 +0800 Subject: [PATCH 1313/1449] pmdomain: imx8mp-blk-ctrl: Keep usb phy power domain on for system wakeup ANBZ: #35228 commit 7aa0c2bb0771a6d0ffb8b62642a48846eff58bff stable. commit e2c4c5b2bbd4f688a0f9f6da26cdf6d723c53478 upstream. USB system wakeup need its PHY on, so add the GENPD_FLAG_ACTIVE_WAKEUP flags to USB PHY genpd configuration. Signed-off-by: Xu Yang Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl") Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c index e4173e7a0c7b..4c3a225c1e44 100644 --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c @@ -53,6 +53,7 @@ struct imx8mp_blk_ctrl_domain_data { const char * const *path_names; int num_paths; const char *gpc_name; + const unsigned int flags; }; #define DOMAIN_MAX_CLKS 3 @@ -265,10 +266,12 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { [IMX8MP_HSIOBLK_PD_USB_PHY1] = { .name = "hsioblk-usb-phy1", .gpc_name = "usb-phy1", + .flags = GENPD_FLAG_ACTIVE_WAKEUP, }, [IMX8MP_HSIOBLK_PD_USB_PHY2] = { .name = "hsioblk-usb-phy2", .gpc_name = "usb-phy2", + .flags = GENPD_FLAG_ACTIVE_WAKEUP, }, [IMX8MP_HSIOBLK_PD_PCIE] = { .name = "hsioblk-pcie", @@ -721,6 +724,7 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) domain->genpd.name = data->name; domain->genpd.power_on = imx8mp_blk_ctrl_power_on; domain->genpd.power_off = imx8mp_blk_ctrl_power_off; + domain->genpd.flags = data->flags; domain->bc = bc; domain->id = i; -- Gitee From 63173aadf88e10b74bc8bee8e1504648509754de Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Fri, 30 Jan 2026 13:11:07 +0800 Subject: [PATCH 1314/1449] pmdomain: imx8m-blk-ctrl: fix out-of-range access of bc->domains ANBZ: #35228 commit 071159ff5c0bf2e5efff79501e23faf3775cbcd1 stable. commit 6bd8b4a92a901fae1a422e6f914801063c345e8d upstream. Fix out-of-range access of bc->domains in imx8m_blk_ctrl_remove(). Fixes: 2684ac05a8c4 ("soc: imx: add i.MX8M blk-ctrl driver") Cc: stable@kernel.org Signed-off-by: Xu Yang Reviewed-by: Daniel Baluta Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pmdomain/imx/imx8m-blk-ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c index ce452c2b1746..e52253694747 100644 --- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c @@ -337,7 +337,7 @@ static int imx8m_blk_ctrl_remove(struct platform_device *pdev) of_genpd_del_provider(pdev->dev.of_node); - for (i = 0; bc->onecell_data.num_domains; i++) { + for (i = 0; i < bc->onecell_data.num_domains; i++) { struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; pm_genpd_remove(&domain->genpd); -- Gitee From 14d78ca1fce3ae5bc0cc5e907535fe778a67d324 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Thu, 8 Jan 2026 05:37:55 +0800 Subject: [PATCH 1315/1449] rbd: check for EOD after exclusive lock is ensured to be held ANBZ: #35228 commit 4f9f1fdc0ebdfd65c9fe5f6235baba8ab3f0d97a stable. commit bd3884a204c3b507e6baa9a4091aa927f9af5404 upstream. Similar to commit 870611e4877e ("rbd: get snapshot context after exclusive lock is ensured to be held"), move the "beyond EOD" check into the image request state machine so that it's performed after exclusive lock is ensured to be held. This avoids various race conditions which can arise when the image is shrunk under I/O (in practice, mostly readahead). In one such scenario rbd_assert(objno < rbd_dev->object_map_size); can be triggered if a close-to-EOD read gets queued right before the shrink is initiated and the EOD check is performed against an outdated mapping_size. After the resize is done on the server side and exclusive lock is (re)acquired bringing along the new (now shrunk) object map, the read starts going through the state machine and rbd_obj_may_exist() gets invoked on an object that is out of bounds of rbd_dev->object_map array. Cc: stable@vger.kernel.org Signed-off-by: Ilya Dryomov Reviewed-by: Dongsheng Yang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/rbd.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 6fcd7f0fe4f0..6f68c2a74361 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3495,11 +3495,29 @@ static void rbd_img_object_requests(struct rbd_img_request *img_req) rbd_assert(!need_exclusive_lock(img_req) || __rbd_is_lock_owner(rbd_dev)); - if (rbd_img_is_write(img_req)) { - rbd_assert(!img_req->snapc); + if (test_bit(IMG_REQ_CHILD, &img_req->flags)) { + rbd_assert(!rbd_img_is_write(img_req)); + } else { + struct request *rq = blk_mq_rq_from_pdu(img_req); + u64 off = (u64)blk_rq_pos(rq) << SECTOR_SHIFT; + u64 len = blk_rq_bytes(rq); + u64 mapping_size; + down_read(&rbd_dev->header_rwsem); - img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc); + mapping_size = rbd_dev->mapping.size; + if (rbd_img_is_write(img_req)) { + rbd_assert(!img_req->snapc); + img_req->snapc = + ceph_get_snap_context(rbd_dev->header.snapc); + } up_read(&rbd_dev->header_rwsem); + + if (unlikely(off + len > mapping_size)) { + rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", + off, len, mapping_size); + img_req->pending.result = -EIO; + return; + } } for_each_obj_request(img_req, obj_req) { @@ -4725,7 +4743,6 @@ static void rbd_queue_workfn(struct work_struct *work) struct request *rq = blk_mq_rq_from_pdu(img_request); u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT; u64 length = blk_rq_bytes(rq); - u64 mapping_size; int result; /* Ignore/skip any zero-length requests */ @@ -4738,17 +4755,9 @@ static void rbd_queue_workfn(struct work_struct *work) blk_mq_start_request(rq); down_read(&rbd_dev->header_rwsem); - mapping_size = rbd_dev->mapping.size; rbd_img_capture_header(img_request); up_read(&rbd_dev->header_rwsem); - if (offset + length > mapping_size) { - rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", offset, - length, mapping_size); - result = -EIO; - goto err_img_request; - } - dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev, img_request, obj_op_name(op_type), offset, length); -- Gitee From 4cefaf1993d6975a79e9661810ce090701859020 Mon Sep 17 00:00:00 2001 From: Thomas Weissschuh Date: Wed, 7 Jan 2026 18:01:49 +0800 Subject: [PATCH 1316/1449] ARM: 9468/1: fix memset64() on big-endian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 7f7467be748ebacc61449606169ddbb9f86c77bb stable. commit 23ea2a4c72323feb6e3e025e8a6f18336513d5ad upstream. On big-endian systems the 32-bit low and high halves need to be swapped for the underlying assembly implementation to work correctly. Fixes: fd1d362600e2 ("ARM: implement memset32 & memset64") Cc: stable@vger.kernel.org Signed-off-by: Thomas Weißschuh Reviewed-by: Matthew Wilcox (Oracle) Reviewed-by: Arnd Bergmann Signed-off-by: Russell King (Oracle) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/arm/include/asm/string.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index 6c607c68f3ad..c35250c4991b 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -42,7 +42,10 @@ static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n) extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi); static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) { - return __memset64(p, v, n * 8, v >> 32); + if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) + return __memset64(p, v, n * 8, v >> 32); + else + return __memset64(p, v >> 32, n * 8, v); } /* -- Gitee From c44cd6f75bc90323151fe1e1779d2cc0c9ca484a Mon Sep 17 00:00:00 2001 From: Bert Karwatzki Date: Sun, 1 Feb 2026 08:24:45 +0800 Subject: [PATCH 1317/1449] Revert "drm/amd: Check if ASPM is enabled from PCIe subsystem" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit d2bddc2da2b3ba5d738877c476bf97932dba32e8 stable. commit 243b467dea1735fed904c2e54d248a46fa417a2d upstream. This reverts commit 7294863a6f01248d72b61d38478978d638641bee. This commit was erroneously applied again after commit 0ab5d711ec74 ("drm/amd: Refactor `amdgpu_aspm` to be evaluated per device") removed it, leading to very hard to debug crashes, when used with a system with two AMD GPUs of which only one supports ASPM. Link: https://lore.kernel.org/linux-acpi/20251006120944.7880-1-spasswolf@web.de/ Link: https://github.com/acpica/acpica/issues/1060 Fixes: 0ab5d711ec74 ("drm/amd: Refactor `amdgpu_aspm` to be evaluated per device") Signed-off-by: Bert Karwatzki Reviewed-by: Christian König Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher (cherry picked from commit 97a9689300eb2b393ba5efc17c8e5db835917080) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index b15ce4df7479..ded2cc476880 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2058,9 +2058,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, return -ENODEV; } - if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev)) - amdgpu_aspm = 0; - if (amdgpu_virtual_display || amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK)) supports_atomic = true; -- Gitee From d6fb6db27ca8e975b8b6e3db8efe41b843fb26a3 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 14 Jan 2026 01:46:05 +0800 Subject: [PATCH 1318/1449] KVM: Don't clobber irqfd routing type when deassigning irqfd ANBZ: #35228 commit b61f9b2fcf181451d0a319889478cc53c001123e stable. commit b4d37cdb77a0015f51fee083598fa227cc07aaf1 upstream. When deassigning a KVM_IRQFD, don't clobber the irqfd's copy of the IRQ's routing entry as doing so breaks kvm_arch_irq_bypass_del_producer() on x86 and arm64, which explicitly look for KVM_IRQ_ROUTING_MSI. Instead, to handle a concurrent routing update, verify that the irqfd is still active before consuming the routing information. As evidenced by the x86 and arm64 bugs, and another bug in kvm_arch_update_irqfd_routing() (see below), clobbering the entry type without notifying arch code is surprising and error prone. As a bonus, checking that the irqfd is active provides a convenient location for documenting _why_ KVM must not consume the routing entry for an irqfd that is in the process of being deassigned: once the irqfd is deleted from the list (which happens *before* the eventfd is detached), it will no longer receive updates via kvm_irq_routing_update(), and so KVM could deliver an event using stale routing information (relative to KVM_SET_GSI_ROUTING returning to userspace). As an even better bonus, explicitly checking for the irqfd being active fixes a similar bug to the one the clobbering is trying to prevent: if an irqfd is deactivated, and then its routing is changed, kvm_irq_routing_update() won't invoke kvm_arch_update_irqfd_routing() (because the irqfd isn't in the list). And so if the irqfd is in bypass mode, IRQs will continue to be posted using the old routing information. As for kvm_arch_irq_bypass_del_producer(), clobbering the routing type results in KVM incorrectly keeping the IRQ in bypass mode, which is especially problematic on AMD as KVM tracks IRQs that are being posted to a vCPU in a list whose lifetime is tied to the irqfd. Without the help of KASAN to detect use-after-free, the most common sympton on AMD is a NULL pointer deref in amd_iommu_update_ga() due to the memory for irqfd structure being re-allocated and zeroed, resulting in irqfd->irq_bypass_data being NULL when read by avic_update_iommu_vcpu_affinity(): BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 40cf2b9067 P4D 40cf2b9067 PUD 408362a067 PMD 0 Oops: Oops: 0000 [#1] SMP CPU: 6 UID: 0 PID: 40383 Comm: vfio_irq_test Tainted: G U W O 6.19.0-smp--5dddc257e6b2-irqfd #31 NONE Tainted: [U]=USER, [W]=WARN, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.78.2-0 09/05/2025 RIP: 0010:amd_iommu_update_ga+0x19/0xe0 Call Trace: avic_update_iommu_vcpu_affinity+0x3d/0x90 [kvm_amd] __avic_vcpu_load+0xf4/0x130 [kvm_amd] kvm_arch_vcpu_load+0x89/0x210 [kvm] vcpu_load+0x30/0x40 [kvm] kvm_arch_vcpu_ioctl_run+0x45/0x620 [kvm] kvm_vcpu_ioctl+0x571/0x6a0 [kvm] __se_sys_ioctl+0x6d/0xb0 do_syscall_64+0x6f/0x9d0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x46893b ---[ end trace 0000000000000000 ]--- If AVIC is inhibited when the irfd is deassigned, the bug will manifest as list corruption, e.g. on the next irqfd assignment. list_add corruption. next->prev should be prev (ffff8d474d5cd588), but was 0000000000000000. (next=ffff8d8658f86530). ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:31! Oops: invalid opcode: 0000 [#1] SMP CPU: 128 UID: 0 PID: 80818 Comm: vfio_irq_test Tainted: G U W O 6.19.0-smp--f19dc4d680ba-irqfd #28 NONE Tainted: [U]=USER, [W]=WARN, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.78.2-0 09/05/2025 RIP: 0010:__list_add_valid_or_report+0x97/0xc0 Call Trace: avic_pi_update_irte+0x28e/0x2b0 [kvm_amd] kvm_pi_update_irte+0xbf/0x190 [kvm] kvm_arch_irq_bypass_add_producer+0x72/0x90 [kvm] irq_bypass_register_consumer+0xcd/0x170 [irqbypass] kvm_irqfd+0x4c6/0x540 [kvm] kvm_vm_ioctl+0x118/0x5d0 [kvm] __se_sys_ioctl+0x6d/0xb0 do_syscall_64+0x6f/0x9d0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 ---[ end trace 0000000000000000 ]--- On Intel and arm64, the bug is less noisy, as the end result is that the device keeps posting IRQs to the vCPU even after it's been deassigned. Note, the worst of the breakage can be traced back to commit cb210737675e ("KVM: Pass new routing entries and irqfd when updating IRTEs"), as before that commit KVM would pull the routing information from the per-VM routing table. But as above, similar bugs have existed since support for IRQ bypass was added. E.g. if a routing change finished before irq_shutdown() invoked kvm_arch_irq_bypass_del_producer(), VMX and SVM would see stale routing information and potentially leave the irqfd in bypass mode. Alternatively, x86 could be fixed by explicitly checking irq_bypass_vcpu instead of irq_entry.type in kvm_arch_irq_bypass_del_producer(), and arm64 could be modified to utilize irq_bypass_vcpu in a similar manner. But (a) that wouldn't fix the routing updates bug, and (b) fixing core code doesn't preclude x86 (or arm64) from adding such code as a sanity check (spoiler alert). Fixes: f70c20aaf141 ("KVM: Add an arch specific hooks in 'struct kvm_kernel_irqfd'") Fixes: cb210737675e ("KVM: Pass new routing entries and irqfd when updating IRTEs") Fixes: a0d7e2fc61ab ("KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs") Cc: stable@vger.kernel.org Cc: Marc Zyngier Cc: Oliver Upton Link: https://patch.msgid.link/20260113174606.104978-2-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- virt/kvm/eventfd.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index a7c2667209d3..9923ff9e7183 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -164,21 +164,28 @@ irqfd_shutdown(struct work_struct *work) } -/* assumes kvm->irqfds.lock is held */ -static bool -irqfd_is_active(struct kvm_kernel_irqfd *irqfd) +static bool irqfd_is_active(struct kvm_kernel_irqfd *irqfd) { + /* + * Assert that either irqfds.lock or SRCU is held, as irqfds.lock must + * be held to prevent false positives (on the irqfd being active), and + * while false negatives are impossible as irqfds are never added back + * to the list once they're deactivated, the caller must at least hold + * SRCU to guard against routing changes if the irqfd is deactivated. + */ + lockdep_assert_once(lockdep_is_held(&irqfd->kvm->irqfds.lock) || + srcu_read_lock_held(&irqfd->kvm->irq_srcu)); + return list_empty(&irqfd->list) ? false : true; } /* * Mark the irqfd as inactive and schedule it for removal - * - * assumes kvm->irqfds.lock is held */ -static void -irqfd_deactivate(struct kvm_kernel_irqfd *irqfd) +static void irqfd_deactivate(struct kvm_kernel_irqfd *irqfd) { + lockdep_assert_held(&irqfd->kvm->irqfds.lock); + BUG_ON(!irqfd_is_active(irqfd)); list_del_init(&irqfd->list); @@ -219,8 +226,15 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key) seq = read_seqcount_begin(&irqfd->irq_entry_sc); irq = irqfd->irq_entry; } while (read_seqcount_retry(&irqfd->irq_entry_sc, seq)); - /* An event has been signaled, inject an interrupt */ - if (kvm_arch_set_irq_inatomic(&irq, kvm, + + /* + * An event has been signaled, inject an interrupt unless the + * irqfd is being deassigned (isn't active), in which case the + * routing information may be stale (once the irqfd is removed + * from the list, it will stop receiving routing updates). + */ + if (unlikely(!irqfd_is_active(irqfd)) || + kvm_arch_set_irq_inatomic(&irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false) == -EWOULDBLOCK) schedule_work(&irqfd->inject); @@ -568,18 +582,8 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args) spin_lock_irq(&kvm->irqfds.lock); list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) { - if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) { - /* - * This clearing of irq_entry.type is needed for when - * another thread calls kvm_irq_routing_update before - * we flush workqueue below (we synchronize with - * kvm_irq_routing_update using irqfds.lock). - */ - write_seqcount_begin(&irqfd->irq_entry_sc); - irqfd->irq_entry.type = 0; - write_seqcount_end(&irqfd->irq_entry_sc); + if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) irqfd_deactivate(irqfd); - } } spin_unlock_irq(&kvm->irqfds.lock); -- Gitee From 76326a6e0ad1d792b2fe03974d37050552547819 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 23 Apr 2025 03:52:44 +0800 Subject: [PATCH 1319/1449] netfilter: nft_set_pipapo: clamp maximum map bucket size to INT_MAX ANBZ: #35228 commit df524a68d9021c1401965d610bb6e42ee5d9611e stable. commit b85e3367a5716ed3662a4fe266525190d2af76df upstream. Otherwise, it is possible to hit WARN_ON_ONCE in __kvmalloc_node_noprof() when resizing hashtable because __GFP_NOWARN is unset. Similar to: b541ba7d1f5a ("netfilter: conntrack: clamp maximum hashtable size to INT_MAX") Reviewed-by: Stefano Brivio Signed-off-by: Pablo Neira Ayuso [ Keerthana: Handle freeing new_lt ] Signed-off-by: Keerthana K Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nft_set_pipapo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 4274831b6e67..ebd0f704c863 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -667,6 +667,11 @@ static int pipapo_resize(struct nft_pipapo_field *f, int old_rules, int rules) } mt: + if (rules > (INT_MAX / sizeof(*new_mt))) { + kvfree(new_lt); + return -ENOMEM; + } + new_mt = kvmalloc(rules * sizeof(*new_mt), GFP_KERNEL); if (!new_mt) { kvfree(new_lt); @@ -1359,6 +1364,9 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) src->bsize * sizeof(*dst->lt) * src->groups * NFT_PIPAPO_BUCKETS(src->bb)); + if (src->rules > (INT_MAX / sizeof(*src->mt))) + goto out_mt; + dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL); if (!dst->mt) goto out_mt; -- Gitee From 7c465c587d29f44a3d076bb0eaf28b1378cc246b Mon Sep 17 00:00:00 2001 From: Kang Chen Date: Tue, 9 Sep 2025 11:13:16 +0800 Subject: [PATCH 1320/1449] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() ANBZ: #35228 commit c3db89ea1ed3d540eebe8f3c36e806fb75ee4a1e stable. commit bea3e1d4467bcf292c8e54f080353d556d355e26 upstream. BUG: KASAN: slab-out-of-bounds in hfsplus_uni2asc+0xa71/0xb90 fs/hfsplus/unicode.c:186 Read of size 2 at addr ffff8880289ef218 by task syz.6.248/14290 CPU: 0 UID: 0 PID: 14290 Comm: syz.6.248 Not tainted 6.16.4 #1 PREEMPT(full) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1b0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xca/0x5f0 mm/kasan/report.c:482 kasan_report+0xca/0x100 mm/kasan/report.c:595 hfsplus_uni2asc+0xa71/0xb90 fs/hfsplus/unicode.c:186 hfsplus_listxattr+0x5b6/0xbd0 fs/hfsplus/xattr.c:738 vfs_listxattr+0xbe/0x140 fs/xattr.c:493 listxattr+0xee/0x190 fs/xattr.c:924 filename_listxattr fs/xattr.c:958 [inline] path_listxattrat+0x143/0x360 fs/xattr.c:988 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcb/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fe0e9fae16d Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fe0eae67f98 EFLAGS: 00000246 ORIG_RAX: 00000000000000c3 RAX: ffffffffffffffda RBX: 00007fe0ea205fa0 RCX: 00007fe0e9fae16d RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000200000000000 RBP: 00007fe0ea0480f0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fe0ea206038 R14: 00007fe0ea205fa0 R15: 00007fe0eae48000 Allocated by task 14290: kasan_save_stack+0x24/0x50 mm/kasan/common.c:47 kasan_save_track+0x14/0x30 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4333 [inline] __kmalloc_noprof+0x219/0x540 mm/slub.c:4345 kmalloc_noprof include/linux/slab.h:909 [inline] hfsplus_find_init+0x95/0x1f0 fs/hfsplus/bfind.c:21 hfsplus_listxattr+0x331/0xbd0 fs/hfsplus/xattr.c:697 vfs_listxattr+0xbe/0x140 fs/xattr.c:493 listxattr+0xee/0x190 fs/xattr.c:924 filename_listxattr fs/xattr.c:958 [inline] path_listxattrat+0x143/0x360 fs/xattr.c:988 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcb/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f When hfsplus_uni2asc is called from hfsplus_listxattr, it actually passes in a struct hfsplus_attr_unistr*. The size of the corresponding structure is different from that of hfsplus_unistr, so the previous fix (94458781aee6) is insufficient. The pointer on the unicode buffer is still going beyond the allocated memory. This patch introduces two warpper functions hfsplus_uni2asc_xattr_str and hfsplus_uni2asc_str to process two unicode buffers, struct hfsplus_attr_unistr* and struct hfsplus_unistr* respectively. When ustrlen value is bigger than the allocated memory size, the ustrlen value is limited to an safe size. Fixes: 94458781aee6 ("hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()") Signed-off-by: Kang Chen Reviewed-by: Viacheslav Dubeyko Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20250909031316.1647094-1-k.chen@smail.nju.edu.cn Signed-off-by: Viacheslav Dubeyko Signed-off-by: Jianqiang kang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/hfsplus/dir.c | 2 +- fs/hfsplus/hfsplus_fs.h | 8 ++++++-- fs/hfsplus/unicode.c | 24 +++++++++++++++++++----- fs/hfsplus/xattr.c | 6 +++--- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 33154c720a4e..d23f8c4cd717 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -204,7 +204,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx) fd.entrylength); type = be16_to_cpu(entry.type); len = NLS_MAX_CHARSET_SIZE * HFSPLUS_MAX_STRLEN; - err = hfsplus_uni2asc(sb, &fd.key->cat.name, strbuf, &len); + err = hfsplus_uni2asc_str(sb, &fd.key->cat.name, strbuf, &len); if (err) goto out; if (type == HFSPLUS_FOLDER) { diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 4e33630d5800..ed3555f0f325 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -520,8 +520,12 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *s1, const struct hfsplus_unistr *s2); int hfsplus_strcmp(const struct hfsplus_unistr *s1, const struct hfsplus_unistr *s2); -int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, - char *astr, int *len_p); +int hfsplus_uni2asc_str(struct super_block *sb, + const struct hfsplus_unistr *ustr, char *astr, + int *len_p); +int hfsplus_uni2asc_xattr_str(struct super_block *sb, + const struct hfsplus_attr_unistr *ustr, + char *astr, int *len_p); int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, int max_unistr_len, const char *astr, int len); int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str); diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index ebd326799f35..11e08a4a18b2 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -143,9 +143,8 @@ static u16 *hfsplus_compose_lookup(u16 *p, u16 cc) return NULL; } -int hfsplus_uni2asc(struct super_block *sb, - const struct hfsplus_unistr *ustr, - char *astr, int *len_p) +static int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, + int max_len, char *astr, int *len_p) { const hfsplus_unichr *ip; struct nls_table *nls = HFSPLUS_SB(sb)->nls; @@ -158,8 +157,8 @@ int hfsplus_uni2asc(struct super_block *sb, ip = ustr->unicode; ustrlen = be16_to_cpu(ustr->length); - if (ustrlen > HFSPLUS_MAX_STRLEN) { - ustrlen = HFSPLUS_MAX_STRLEN; + if (ustrlen > max_len) { + ustrlen = max_len; pr_err("invalid length %u has been corrected to %d\n", be16_to_cpu(ustr->length), ustrlen); } @@ -280,6 +279,21 @@ int hfsplus_uni2asc(struct super_block *sb, return res; } +inline int hfsplus_uni2asc_str(struct super_block *sb, + const struct hfsplus_unistr *ustr, char *astr, + int *len_p) +{ + return hfsplus_uni2asc(sb, ustr, HFSPLUS_MAX_STRLEN, astr, len_p); +} + +inline int hfsplus_uni2asc_xattr_str(struct super_block *sb, + const struct hfsplus_attr_unistr *ustr, + char *astr, int *len_p) +{ + return hfsplus_uni2asc(sb, (const struct hfsplus_unistr *)ustr, + HFSPLUS_ATTR_MAX_STRLEN, astr, len_p); +} + /* * Convert one or more ASCII characters into a single unicode character. * Returns the number of ASCII characters corresponding to the unicode char. diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index d5fd8e068486..a86399942745 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c @@ -737,9 +737,9 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size) goto end_listxattr; xattr_name_len = NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN; - if (hfsplus_uni2asc(inode->i_sb, - (const struct hfsplus_unistr *)&fd.key->attr.key_name, - strbuf, &xattr_name_len)) { + if (hfsplus_uni2asc_xattr_str(inode->i_sb, + &fd.key->attr.key_name, strbuf, + &xattr_name_len)) { pr_err("unicode conversion failed\n"); res = -EIO; goto end_listxattr; -- Gitee From 043b52c08059d196c46e53a53e17ecb0188e843e Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 12 Dec 2025 22:34:15 +0800 Subject: [PATCH 1321/1449] ublk: fix deadlock when reading partition table ANBZ: #35228 commit 64c0b7e2293757e8320f13434cd809f1c9257a62 stable. commit c258f5c4502c9667bccf5d76fa731ab9c96687c1 upstream. When one process(such as udev) opens ublk block device (e.g., to read the partition table via bdev_open()), a deadlock[1] can occur: 1. bdev_open() grabs disk->open_mutex 2. The process issues read I/O to ublk backend to read partition table 3. In __ublk_complete_rq(), blk_update_request() or blk_mq_end_request() runs bio->bi_end_io() callbacks 4. If this triggers fput() on file descriptor of ublk block device, the work may be deferred to current task's task work (see fput() implementation) 5. This eventually calls blkdev_release() from the same context 6. blkdev_release() tries to grab disk->open_mutex again 7. Deadlock: same task waiting for a mutex it already holds The fix is to run blk_update_request() and blk_mq_end_request() with bottom halves disabled. This forces blkdev_release() to run in kernel work-queue context instead of current task work context, and allows ublk server to make forward progress, and avoids the deadlock. Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") Link: https://github.com/ublk-org/ublksrv/issues/170 [1] Signed-off-by: Ming Lei Reviewed-by: Caleb Sander Mateos [axboe: rewrite comment in ublk] Signed-off-by: Jens Axboe [ The fix omits the change in __ublk_do_auto_buf_reg() since this function doesn't exist in Linux 6.6. ] Signed-off-by: Alva Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/block/ublk_drv.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 563b2a94d4c3..44f630a3f610 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1050,6 +1050,13 @@ static inline bool ubq_daemon_is_dying(struct ublk_queue *ubq) return ubq->ubq_daemon->flags & PF_EXITING; } +static void ublk_end_request(struct request *req, blk_status_t error) +{ + local_bh_disable(); + blk_mq_end_request(req, error); + local_bh_enable(); +} + /* todo: handle partial completion */ static inline void __ublk_complete_rq(struct request *req) { @@ -1057,6 +1064,7 @@ static inline void __ublk_complete_rq(struct request *req) struct ublk_io *io = &ubq->ios[req->tag]; unsigned int unmapped_bytes; blk_status_t res = BLK_STS_OK; + bool requeue; /* called from ublk_abort_queue() code path */ if (io->flags & UBLK_IO_FLAG_ABORTED) { @@ -1094,14 +1102,30 @@ static inline void __ublk_complete_rq(struct request *req) if (unlikely(unmapped_bytes < io->res)) io->res = unmapped_bytes; - if (blk_update_request(req, BLK_STS_OK, io->res)) + /* + * Run bio->bi_end_io() with softirqs disabled. If the final fput + * happens off this path, then that will prevent ublk's blkdev_release() + * from being called on current's task work, see fput() implementation. + * + * Otherwise, ublk server may not provide forward progress in case of + * reading the partition table from bdev_open() with disk->open_mutex + * held, and causes dead lock as we could already be holding + * disk->open_mutex here. + * + * Preferably we would not be doing IO with a mutex held that is also + * used for release, but this work-around will suffice for now. + */ + local_bh_disable(); + requeue = blk_update_request(req, BLK_STS_OK, io->res); + local_bh_enable(); + if (requeue) blk_mq_requeue_request(req, true); else __blk_mq_end_request(req, BLK_STS_OK); return; exit: - blk_mq_end_request(req, res); + ublk_end_request(req, res); } static void ublk_complete_rq(struct kref *ref) @@ -1160,7 +1184,7 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq, if (ublk_queue_can_use_recovery(ubq)) blk_mq_requeue_request(rq, false); else - blk_mq_end_request(rq, BLK_STS_IOERR); + ublk_end_request(rq, BLK_STS_IOERR); mod_delayed_work(system_wq, &ubq->dev->monitor_work, 0); } -- Gitee From 946e7d14590ae0edc14869cc0bab52332b6fa288 Mon Sep 17 00:00:00 2001 From: Harshit Agarwal Date: Wed, 26 Feb 2025 02:05:53 +0800 Subject: [PATCH 1322/1449] sched/rt: Fix race in push_rt_task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9f6022b2573ae068793810db719e131df3ded405 stable. commit 690e47d1403e90b7f2366f03b52ed3304194c793 upstream. Overview ======== When a CPU chooses to call push_rt_task and picks a task to push to another CPU's runqueue then it will call find_lock_lowest_rq method which would take a double lock on both CPUs' runqueues. If one of the locks aren't readily available, it may lead to dropping the current runqueue lock and reacquiring both the locks at once. During this window it is possible that the task is already migrated and is running on some other CPU. These cases are already handled. However, if the task is migrated and has already been executed and another CPU is now trying to wake it up (ttwu) such that it is queued again on the runqeue (on_rq is 1) and also if the task was run by the same CPU, then the current checks will pass even though the task was migrated out and is no longer in the pushable tasks list. Crashes ======= This bug resulted in quite a few flavors of crashes triggering kernel panics with various crash signatures such as assert failures, page faults, null pointer dereferences, and queue corruption errors all coming from scheduler itself. Some of the crashes: -> kernel BUG at kernel/sched/rt.c:1616! BUG_ON(idx >= MAX_RT_PRIO) Call Trace: ? __die_body+0x1a/0x60 ? die+0x2a/0x50 ? do_trap+0x85/0x100 ? pick_next_task_rt+0x6e/0x1d0 ? do_error_trap+0x64/0xa0 ? pick_next_task_rt+0x6e/0x1d0 ? exc_invalid_op+0x4c/0x60 ? pick_next_task_rt+0x6e/0x1d0 ? asm_exc_invalid_op+0x12/0x20 ? pick_next_task_rt+0x6e/0x1d0 __schedule+0x5cb/0x790 ? update_ts_time_stats+0x55/0x70 schedule_idle+0x1e/0x40 do_idle+0x15e/0x200 cpu_startup_entry+0x19/0x20 start_secondary+0x117/0x160 secondary_startup_64_no_verify+0xb0/0xbb -> BUG: kernel NULL pointer dereference, address: 00000000000000c0 Call Trace: ? __die_body+0x1a/0x60 ? no_context+0x183/0x350 ? __warn+0x8a/0xe0 ? exc_page_fault+0x3d6/0x520 ? asm_exc_page_fault+0x1e/0x30 ? pick_next_task_rt+0xb5/0x1d0 ? pick_next_task_rt+0x8c/0x1d0 __schedule+0x583/0x7e0 ? update_ts_time_stats+0x55/0x70 schedule_idle+0x1e/0x40 do_idle+0x15e/0x200 cpu_startup_entry+0x19/0x20 start_secondary+0x117/0x160 secondary_startup_64_no_verify+0xb0/0xbb -> BUG: unable to handle page fault for address: ffff9464daea5900 kernel BUG at kernel/sched/rt.c:1861! BUG_ON(rq->cpu != task_cpu(p)) -> kernel BUG at kernel/sched/rt.c:1055! BUG_ON(!rq->nr_running) Call Trace: ? __die_body+0x1a/0x60 ? die+0x2a/0x50 ? do_trap+0x85/0x100 ? dequeue_top_rt_rq+0xa2/0xb0 ? do_error_trap+0x64/0xa0 ? dequeue_top_rt_rq+0xa2/0xb0 ? exc_invalid_op+0x4c/0x60 ? dequeue_top_rt_rq+0xa2/0xb0 ? asm_exc_invalid_op+0x12/0x20 ? dequeue_top_rt_rq+0xa2/0xb0 dequeue_rt_entity+0x1f/0x70 dequeue_task_rt+0x2d/0x70 __schedule+0x1a8/0x7e0 ? blk_finish_plug+0x25/0x40 schedule+0x3c/0xb0 futex_wait_queue_me+0xb6/0x120 futex_wait+0xd9/0x240 do_futex+0x344/0xa90 ? get_mm_exe_file+0x30/0x60 ? audit_exe_compare+0x58/0x70 ? audit_filter_rules.constprop.26+0x65e/0x1220 __x64_sys_futex+0x148/0x1f0 do_syscall_64+0x30/0x80 entry_SYSCALL_64_after_hwframe+0x62/0xc7 -> BUG: unable to handle page fault for address: ffff8cf3608bc2c0 Call Trace: ? __die_body+0x1a/0x60 ? no_context+0x183/0x350 ? spurious_kernel_fault+0x171/0x1c0 ? exc_page_fault+0x3b6/0x520 ? plist_check_list+0x15/0x40 ? plist_check_list+0x2e/0x40 ? asm_exc_page_fault+0x1e/0x30 ? _cond_resched+0x15/0x30 ? futex_wait_queue_me+0xc8/0x120 ? futex_wait+0xd9/0x240 ? try_to_wake_up+0x1b8/0x490 ? futex_wake+0x78/0x160 ? do_futex+0xcd/0xa90 ? plist_check_list+0x15/0x40 ? plist_check_list+0x2e/0x40 ? plist_del+0x6a/0xd0 ? plist_check_list+0x15/0x40 ? plist_check_list+0x2e/0x40 ? dequeue_pushable_task+0x20/0x70 ? __schedule+0x382/0x7e0 ? asm_sysvec_reschedule_ipi+0xa/0x20 ? schedule+0x3c/0xb0 ? exit_to_user_mode_prepare+0x9e/0x150 ? irqentry_exit_to_user_mode+0x5/0x30 ? asm_sysvec_reschedule_ipi+0x12/0x20 Above are some of the common examples of the crashes that were observed due to this issue. Details ======= Let's look at the following scenario to understand this race. 1) CPU A enters push_rt_task a) CPU A has chosen next_task = task p. b) CPU A calls find_lock_lowest_rq(Task p, CPU Z’s rq). c) CPU A identifies CPU X as a destination CPU (X < Z). d) CPU A enters double_lock_balance(CPU Z’s rq, CPU X’s rq). e) Since X is lower than Z, CPU A unlocks CPU Z’s rq. Someone else has locked CPU X’s rq, and thus, CPU A must wait. 2) At CPU Z a) Previous task has completed execution and thus, CPU Z enters schedule, locks its own rq after CPU A releases it. b) CPU Z dequeues previous task and begins executing task p. c) CPU Z unlocks its rq. d) Task p yields the CPU (ex. by doing IO or waiting to acquire a lock) which triggers the schedule function on CPU Z. e) CPU Z enters schedule again, locks its own rq, and dequeues task p. f) As part of dequeue, it sets p.on_rq = 0 and unlocks its rq. 3) At CPU B a) CPU B enters try_to_wake_up with input task p. b) Since CPU Z dequeued task p, p.on_rq = 0, and CPU B updates B.state = WAKING. c) CPU B via select_task_rq determines CPU Y as the target CPU. 4) The race a) CPU A acquires CPU X’s lock and relocks CPU Z. b) CPU A reads task p.cpu = Z and incorrectly concludes task p is still on CPU Z. c) CPU A failed to notice task p had been dequeued from CPU Z while CPU A was waiting for locks in double_lock_balance. If CPU A knew that task p had been dequeued, it would return NULL forcing push_rt_task to give up the task p's migration. d) CPU B updates task p.cpu = Y and calls ttwu_queue. e) CPU B locks Ys rq. CPU B enqueues task p onto Y and sets task p.on_rq = 1. f) CPU B unlocks CPU Y, triggering memory synchronization. g) CPU A reads task p.on_rq = 1, cementing its assumption that task p has not migrated. h) CPU A decides to migrate p to CPU X. This leads to A dequeuing p from Y's queue and various crashes down the line. Solution ======== The solution here is fairly simple. After obtaining the lock (at 4a), the check is enhanced to make sure that the task is still at the head of the pushable tasks list. If not, then it is anyway not suitable for being pushed out. Testing ======= The fix is tested on a cluster of 3 nodes, where the panics due to this are hit every couple of days. A fix similar to this was deployed on such cluster and was stable for more than 30 days. Co-developed-by: Jon Kohler Signed-off-by: Jon Kohler Co-developed-by: Gauri Patwardhan Signed-off-by: Gauri Patwardhan Co-developed-by: Rahul Chunduru Signed-off-by: Rahul Chunduru Signed-off-by: Harshit Agarwal Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: "Steven Rostedt (Google)" Reviewed-by: Phil Auld Tested-by: Will Ton Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250225180553.167995-1-harshit@nutanix.com Signed-off-by: Rajani Kantha <681739313@139.com> Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/sched/rt.c | 52 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index a8a635c52b62..b4fba073701a 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1971,6 +1971,26 @@ static int find_lowest_rq(struct task_struct *task) return -1; } +static struct task_struct *pick_next_pushable_task(struct rq *rq) +{ + struct task_struct *p; + + if (!has_pushable_tasks(rq)) + return NULL; + + p = plist_first_entry(&rq->rt.pushable_tasks, + struct task_struct, pushable_tasks); + + BUG_ON(rq->cpu != task_cpu(p)); + BUG_ON(task_current(rq, p)); + BUG_ON(p->nr_cpus_allowed <= 1); + + BUG_ON(!task_on_rq_queued(p)); + BUG_ON(!rt_task(p)); + + return p; +} + /* Will lock the rq it finds */ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) { @@ -2001,18 +2021,16 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) /* * We had to unlock the run queue. In * the mean time, task could have - * migrated already or had its affinity changed. - * Also make sure that it wasn't scheduled on its rq. + * migrated already or had its affinity changed, + * therefore check if the task is still at the + * head of the pushable tasks list. * It is possible the task was scheduled, set * "migrate_disabled" and then got preempted, so we must * check the task migration disable flag here too. */ - if (unlikely(task_rq(task) != rq || + if (unlikely(is_migration_disabled(task) || !cpumask_test_cpu(lowest_rq->cpu, &task->cpus_mask) || - task_on_cpu(rq, task) || - !rt_task(task) || - is_migration_disabled(task) || - !task_on_rq_queued(task))) { + task != pick_next_pushable_task(rq))) { double_unlock_balance(rq, lowest_rq); lowest_rq = NULL; @@ -2032,26 +2050,6 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) return lowest_rq; } -static struct task_struct *pick_next_pushable_task(struct rq *rq) -{ - struct task_struct *p; - - if (!has_pushable_tasks(rq)) - return NULL; - - p = plist_first_entry(&rq->rt.pushable_tasks, - struct task_struct, pushable_tasks); - - BUG_ON(rq->cpu != task_cpu(p)); - BUG_ON(task_current(rq, p)); - BUG_ON(p->nr_cpus_allowed <= 1); - - BUG_ON(!task_on_rq_queued(p)); - BUG_ON(!rt_task(p)); - - return p; -} - /* * If the current CPU has more than one RT task, see if the non * running task can migrate over to a CPU that is running a task -- Gitee From 82a50d17f9b27b9fec0fde6f7a825757ea5ef890 Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Sat, 24 Jan 2026 01:57:02 +0800 Subject: [PATCH 1323/1449] binder: fix BR_FROZEN_REPLY error log ANBZ: #35228 commit ebb6aa6928d5cafd1c12e335ddb2bf05de008631 stable. commit 1769f90e5ba2a6d24bb46b85da33fe861c68f005 upstream. The error logging for failed transactions is misleading as it always reports "dead process or thread" even when the target is actually frozen. Additionally, the pid and tid are reversed which can further confuse debugging efforts. Fix both issues. Cc: stable@kernel.org Cc: Steven Moreland Fixes: a15dac8b2286 ("binder: additional transaction error logs") Signed-off-by: Carlos Llamas Reviewed-by: Alice Ryhl Link: https://patch.msgid.link/20260123175702.2154348-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/android/binder.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index e5096fcfad57..43f11f66970b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3663,8 +3663,9 @@ static void binder_transaction(struct binder_proc *proc, return; err_dead_proc_or_thread: - binder_txn_error("%d:%d dead process or thread\n", - thread->pid, proc->pid); + binder_txn_error("%d:%d %s process or thread\n", + proc->pid, thread->pid, + return_error == BR_FROZEN_REPLY ? "frozen" : "dead"); return_error_line = __LINE__; binder_dequeue_work(proc, tcomplete); err_translate_failed: -- Gitee From 41d4c8d7600de5ba23cbc59db759065ae40d7a32 Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Wed, 28 Jan 2026 07:55:11 +0800 Subject: [PATCH 1324/1449] binderfs: fix ida_alloc_max() upper bound ANBZ: #35228 commit 46c93903e4c1920d1e82d630ef0c17f1091e5167 stable. commit ec4ddc90d201d09ef4e4bef8a2c6d9624525ad68 upstream. The 'max' argument of ida_alloc_max() takes the maximum valid ID and not the "count". Using an ID of BINDERFS_MAX_MINOR (1 << 20) for dev->minor would exceed the limits of minor numbers (20-bits). Fix this off-by-one error by subtracting 1 from the 'max'. Cc: stable@vger.kernel.org Fixes: 3ad20fe393b3 ("binder: implement binderfs") Signed-off-by: Carlos Llamas Link: https://patch.msgid.link/20260127235545.2307876-2-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/android/binderfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 81effec17b3d..2967170e09c8 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -130,8 +130,8 @@ static int binderfs_binder_device_create(struct inode *ref_inode, mutex_lock(&binderfs_minors_mutex); if (++info->device_count <= info->mount_opts.max) minor = ida_alloc_max(&binderfs_minors, - use_reserve ? BINDERFS_MAX_MINOR : - BINDERFS_MAX_MINOR_CAPPED, + use_reserve ? BINDERFS_MAX_MINOR - 1 : + BINDERFS_MAX_MINOR_CAPPED - 1, GFP_KERNEL); else minor = -ENOSPC; @@ -421,8 +421,8 @@ static int binderfs_binder_ctl_create(struct super_block *sb) /* Reserve a new minor number for the new device. */ mutex_lock(&binderfs_minors_mutex); minor = ida_alloc_max(&binderfs_minors, - use_reserve ? BINDERFS_MAX_MINOR : - BINDERFS_MAX_MINOR_CAPPED, + use_reserve ? BINDERFS_MAX_MINOR - 1 : + BINDERFS_MAX_MINOR_CAPPED - 1, GFP_KERNEL); mutex_unlock(&binderfs_minors_mutex); if (minor < 0) { -- Gitee From 80124df83a157189098ac328538233214cb1b7ad Mon Sep 17 00:00:00 2001 From: Zhiquan Li Date: Sat, 7 Feb 2026 16:07:08 -0500 Subject: [PATCH 1325/1449] KVM: selftests: Add -U_FORTIFY_SOURCE to avoid some unpredictable test failures ANBZ: #35228 commit a8adf1ceee4e188b0521f0638c97bff278143924 stable. commit e396a74222654486d6ab45dca5d0c54c408b8b91 upstream. Some distributions (such as Ubuntu) configure GCC so that _FORTIFY_SOURCE is automatically enabled at -O1 or above. This results in some fortified version of definitions of standard library functions are included. While linker resolves the symbols, the fortified versions might override the definitions in lib/string_override.c and reference to those PLT entries in GLIBC. This is not a problem for the code in host, but it is a disaster for the guest code. E.g., if build and run x86/nested_emulation_test on Ubuntu 24.04 will encounter a L1 #PF due to memset() reference to __memset_chk@plt. The option -fno-builtin-memset is not helpful here, because those fortified versions are not built-in but some definitions which are included by header, they are for different intentions. In order to eliminate the unpredictable behaviors may vary depending on the linker and platform, add the "-U_FORTIFY_SOURCE" into CFLAGS to prevent from introducing the fortified definitions. Signed-off-by: Zhiquan Li Link: https://patch.msgid.link/20260122053551.548229-1-zhiquan_li@163.com Fixes: 6b6f71484bf4 ("KVM: selftests: Implement memcmp(), memcpy(), and memset() for guest use") Cc: stable@vger.kernel.org [sean: tag for stable] Signed-off-by: Sean Christopherson [ Makefile.kvm -> Makefile ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- tools/testing/selftests/kvm/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 197ba0aebf7a..08cf95d5c3cf 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -229,6 +229,7 @@ LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include endif CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ -Wno-gnu-variable-sized-type-not-at-end -MD -MP -DCONFIG_64BIT \ + -U_FORTIFY_SOURCE \ -fno-builtin-memcmp -fno-builtin-memcpy -fno-builtin-memset \ -fno-builtin-strnlen \ -fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \ -- Gitee From 793ab85b4c05e06edd86ab41316baecd9de017c2 Mon Sep 17 00:00:00 2001 From: Debarghya Kundu Date: Sun, 8 Feb 2026 01:13:22 +0800 Subject: [PATCH 1326/1449] gve: Fix stats report corruption on queue count change ANBZ: #35228 commit df54838ab61826ecc1a562ffa5e280c3ab7289a7 stable. commit 7b9ebcce0296e104a0d82a6b09d68564806158ff upstream. The driver and the NIC share a region in memory for stats reporting. The NIC calculates its offset into this region based on the total size of the stats region and the size of the NIC's stats. When the number of queues is changed, the driver's stats region is resized. If the queue count is increased, the NIC can write past the end of the allocated stats region, causing memory corruption. If the queue count is decreased, there is a gap between the driver and NIC stats, leading to incorrect stats reporting. This change fixes the issue by allocating stats region with maximum size, and the offset calculation for NIC stats is changed to match with the calculation of the NIC. Cc: stable@vger.kernel.org Fixes: 24aeb56f2d38 ("gve: Add Gvnic stats AQ command and ethtool show/set-priv-flags.") Signed-off-by: Debarghya Kundu Reviewed-by: Joshua Washington Signed-off-by: Harshitha Ramamurthy Reviewed-by: Jacob Keller Link: https://patch.msgid.link/20260202193925.3106272-2-hramamurthy@google.com Signed-off-by: Jakub Kicinski [ no stopped-queue feature in older trees ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/google/gve/gve_ethtool.c | 41 +++++++++++++------ drivers/net/ethernet/google/gve/gve_main.c | 4 +- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c index 22317acf16ba..59c509ade262 100644 --- a/drivers/net/ethernet/google/gve/gve_ethtool.c +++ b/drivers/net/ethernet/google/gve/gve_ethtool.c @@ -159,7 +159,8 @@ gve_get_ethtool_stats(struct net_device *netdev, tmp_tx_pkts, tmp_tx_bytes; u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_pkts, rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, tx_dropped; - int stats_idx, base_stats_idx, max_stats_idx; + int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx; + int stats_idx, stats_region_len, nic_stats_len; struct stats *report_stats; int *rx_qid_to_stats_idx; int *tx_qid_to_stats_idx; @@ -246,14 +247,32 @@ gve_get_ethtool_stats(struct net_device *netdev, data[i++] = priv->stats_report_trigger_cnt; i = GVE_MAIN_STATS_LEN; - /* For rx cross-reporting stats, start from nic rx stats in report */ - base_stats_idx = GVE_TX_STATS_REPORT_NUM * num_tx_queues + - GVE_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues; - max_stats_idx = NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues + - base_stats_idx; + rx_base_stats_idx = 0; + max_rx_stats_idx = 0; + max_tx_stats_idx = 0; + stats_region_len = priv->stats_report_len - + sizeof(struct gve_stats_report); + nic_stats_len = (NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues + + NIC_TX_STATS_REPORT_NUM * num_tx_queues) * sizeof(struct stats); + if (unlikely((stats_region_len - + nic_stats_len) % sizeof(struct stats))) { + net_err_ratelimited("Starting index of NIC stats should be multiple of stats size"); + } else { + /* For rx cross-reporting stats, + * start from nic rx stats in report + */ + rx_base_stats_idx = (stats_region_len - nic_stats_len) / + sizeof(struct stats); + max_rx_stats_idx = NIC_RX_STATS_REPORT_NUM * + priv->rx_cfg.num_queues + + rx_base_stats_idx; + max_tx_stats_idx = NIC_TX_STATS_REPORT_NUM * + num_tx_queues + + max_rx_stats_idx; + } /* Preprocess the stats report for rx, map queue id to start index */ skip_nic_stats = false; - for (stats_idx = base_stats_idx; stats_idx < max_stats_idx; + for (stats_idx = rx_base_stats_idx; stats_idx < max_rx_stats_idx; stats_idx += NIC_RX_STATS_REPORT_NUM) { u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name); u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id); @@ -323,13 +342,9 @@ gve_get_ethtool_stats(struct net_device *netdev, i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS; } - /* For tx cross-reporting stats, start from nic tx stats in report */ - base_stats_idx = max_stats_idx; - max_stats_idx = NIC_TX_STATS_REPORT_NUM * num_tx_queues + - max_stats_idx; - /* Preprocess the stats report for tx, map queue id to start index */ skip_nic_stats = false; - for (stats_idx = base_stats_idx; stats_idx < max_stats_idx; + /* NIC TX stats start right after NIC RX stats */ + for (stats_idx = max_rx_stats_idx; stats_idx < max_tx_stats_idx; stats_idx += NIC_TX_STATS_REPORT_NUM) { u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name); u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id); diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 241a541b8edd..b2c648fe3875 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -186,9 +186,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv) int tx_stats_num, rx_stats_num; tx_stats_num = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) * - gve_num_tx_queues(priv); + priv->tx_cfg.max_queues; rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) * - priv->rx_cfg.num_queues; + priv->rx_cfg.max_queues; priv->stats_report_len = struct_size(priv->stats_report, stats, size_add(tx_stats_num, rx_stats_num)); priv->stats_report = -- Gitee From a97ca9916afb967fed556dae466bd5d595b09894 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sun, 8 Feb 2026 00:52:19 +0800 Subject: [PATCH 1327/1449] tracing: Fix ftrace event field alignments ANBZ: #35228 commit d75245dad5cc665a8c0693b10ce5e638397571e1 stable. commit 033c55fe2e326bea022c3cc5178ecf3e0e459b82 upstream. The fields of ftrace specific events (events used to save ftrace internal events like function traces and trace_printk) are generated similarly to how normal trace event fields are generated. That is, the fields are added to a trace_events_fields array that saves the name, offset, size, alignment and signness of the field. It is used to produce the output in the format file in tracefs so that tooling knows how to parse the binary data of the trace events. The issue is that some of the ftrace event structures are packed. The function graph exit event structures are one of them. The 64 bit calltime and rettime fields end up 4 byte aligned, but the algorithm to show to userspace shows them as 8 byte aligned. The macros that create the ftrace events has one for embedded structure fields. There's two macros for theses fields: __field_desc() and __field_packed() The difference of the latter macro is that it treats the field as packed. Rename that field to __field_desc_packed() and create replace the __field_packed() to be a normal field that is packed and have the calltime and rettime use those. This showed up on 32bit architectures for function graph time fields. It had: ~# cat /sys/kernel/tracing/events/ftrace/funcgraph_exit/format [..] field:unsigned long func; offset:8; size:4; signed:0; field:unsigned int depth; offset:12; size:4; signed:0; field:unsigned int overrun; offset:16; size:4; signed:0; field:unsigned long long calltime; offset:24; size:8; signed:0; field:unsigned long long rettime; offset:32; size:8; signed:0; Notice that overrun is at offset 16 with size 4, where in the structure calltime is at offset 20 (16 + 4), but it shows the offset at 24. That's because it used the alignment of unsigned long long when used as a declaration and not as a member of a structure where it would be aligned by word size (in this case 4). By using the proper structure alignment, the format has it at the correct offset: ~# cat /sys/kernel/tracing/events/ftrace/funcgraph_exit/format [..] field:unsigned long func; offset:8; size:4; signed:0; field:unsigned int depth; offset:12; size:4; signed:0; field:unsigned int overrun; offset:16; size:4; signed:0; field:unsigned long long calltime; offset:20; size:8; signed:0; field:unsigned long long rettime; offset:28; size:8; signed:0; Cc: stable@vger.kernel.org Cc: Mathieu Desnoyers Cc: Mark Rutland Acked-by: Masami Hiramatsu (Google) Reported-by: "jempty.liang" Link: https://patch.msgid.link/20260204113628.53faec78@gandalf.local.home Fixes: 04ae87a52074e ("ftrace: Rework event_create_dir()") Closes: https://lore.kernel.org/all/20260130015740.212343-1-imntjempty@163.com/ Closes: https://lore.kernel.org/all/20260202123342.2544795-1-imntjempty@163.com/ Signed-off-by: Steven Rostedt (Google) [ adapted field types and macro arguments ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/trace/trace.h | 7 +++++-- kernel/trace/trace_entries.h | 26 +++++++++++++------------- kernel/trace/trace_export.c | 21 +++++++++++++++------ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c91f3c47ac64..7ba372c21fee 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -65,14 +65,17 @@ enum trace_type { #undef __field_fn #define __field_fn(type, item) type item; +#undef __field_packed +#define __field_packed(type, item) type item; + #undef __field_struct #define __field_struct(type, item) __field(type, item) #undef __field_desc #define __field_desc(type, container, item) -#undef __field_packed -#define __field_packed(type, container, item) +#undef __field_desc_packed +#define __field_desc_packed(type, container, item) #undef __array #define __array(type, item, size) type item[size]; diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index c47422b20908..3e3c08a18caf 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -78,8 +78,8 @@ FTRACE_ENTRY_PACKED(funcgraph_entry, ftrace_graph_ent_entry, F_STRUCT( __field_struct( struct ftrace_graph_ent, graph_ent ) - __field_packed( unsigned long, graph_ent, func ) - __field_packed( int, graph_ent, depth ) + __field_desc_packed( unsigned long, graph_ent, func ) + __field_desc_packed( int, graph_ent, depth ) ), F_printk("--> %ps (%d)", (void *)__entry->func, __entry->depth) @@ -94,12 +94,12 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, ftrace_graph_ret_entry, F_STRUCT( __field_struct( struct ftrace_graph_ret, ret ) - __field_packed( unsigned long, ret, func ) - __field_packed( unsigned long, ret, retval ) - __field_packed( int, ret, depth ) - __field_packed( unsigned int, ret, overrun ) - __field_packed( unsigned long long, ret, calltime) - __field_packed( unsigned long long, ret, rettime ) + __field_desc_packed( unsigned long, ret, func ) + __field_desc_packed( unsigned long, ret, retval ) + __field_desc_packed( int, ret, depth ) + __field_desc_packed( unsigned int, ret, overrun ) + __field_packed(unsigned long long, calltime) + __field_packed(unsigned long long, rettime ) ), F_printk("<-- %ps (%d) (start: %llx end: %llx) over: %d retval: %lx", @@ -116,11 +116,11 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, ftrace_graph_ret_entry, F_STRUCT( __field_struct( struct ftrace_graph_ret, ret ) - __field_packed( unsigned long, ret, func ) - __field_packed( int, ret, depth ) - __field_packed( unsigned int, ret, overrun ) - __field_packed( unsigned long long, ret, calltime) - __field_packed( unsigned long long, ret, rettime ) + __field_desc_packed( unsigned long, ret, func ) + __field_desc_packed( int, ret, depth ) + __field_desc_packed( unsigned int, ret, overrun ) + __field_packed(unsigned long long, calltime) + __field_packed(unsigned long long, rettime ) ), F_printk("<-- %ps (%d) (start: %llx end: %llx) over: %d", diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 1698fc22afa0..32a42ef31855 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -42,11 +42,14 @@ static int ftrace_event_register(struct trace_event_call *call, #undef __field_fn #define __field_fn(type, item) type item; +#undef __field_packed +#define __field_packed(type, item) type item; + #undef __field_desc #define __field_desc(type, container, item) type item; -#undef __field_packed -#define __field_packed(type, container, item) type item; +#undef __field_desc_packed +#define __field_desc_packed(type, container, item) type item; #undef __array #define __array(type, item, size) type item[size]; @@ -104,11 +107,14 @@ static void __always_unused ____ftrace_check_##name(void) \ #undef __field_fn #define __field_fn(_type, _item) __field_ext(_type, _item, FILTER_TRACE_FN) +#undef __field_packed +#define __field_packed(_type, _item) __field_ext_packed(_type, _item, FILTER_OTHER) + #undef __field_desc #define __field_desc(_type, _container, _item) __field_ext(_type, _item, FILTER_OTHER) -#undef __field_packed -#define __field_packed(_type, _container, _item) __field_ext_packed(_type, _item, FILTER_OTHER) +#undef __field_desc_packed +#define __field_desc_packed(_type, _container, _item) __field_ext_packed(_type, _item, FILTER_OTHER) #undef __array #define __array(_type, _item, _len) { \ @@ -146,11 +152,14 @@ static struct trace_event_fields ftrace_event_fields_##name[] = { \ #undef __field_fn #define __field_fn(type, item) +#undef __field_packed +#define __field_packed(type, item) + #undef __field_desc #define __field_desc(type, container, item) -#undef __field_packed -#define __field_packed(type, container, item) +#undef __field_desc_packed +#define __field_desc_packed(type, container, item) #undef __array #define __array(type, item, len) -- Gitee From c4dfb063448f7c572b9b3bf3f5133e9952cb45d8 Mon Sep 17 00:00:00 2001 From: Moon Hee Lee Date: Tue, 16 Dec 2025 11:59:32 +0800 Subject: [PATCH 1328/1449] wifi: mac80211: ocb: skip rx_no_sta when interface is not joined ANBZ: #35228 commit ffe1e19c3b0e5b9eb9e04fad4bce7d1dc407fd77 stable. commit ff4071c60018a668249dc6a2df7d16330543540e upstream. ieee80211_ocb_rx_no_sta() assumes a valid channel context, which is only present after JOIN_OCB. RX may run before JOIN_OCB is executed, in which case the OCB interface is not operational. Skip RX peer handling when the interface is not joined to avoid warnings in the RX path. Reported-by: syzbot+b364457b2d1d4e4a3054@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=b364457b2d1d4e4a3054 Tested-by: syzbot+b364457b2d1d4e4a3054@syzkaller.appspotmail.com Signed-off-by: Moon Hee Lee Link: https://patch.msgid.link/20251216035932.18332-1-moonhee.lee.ca@gmail.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/ocb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c index b44896e14522..1800d59d8b15 100644 --- a/net/mac80211/ocb.c +++ b/net/mac80211/ocb.c @@ -48,6 +48,9 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, struct sta_info *sta; int band; + if (!ifocb->joined) + return; + /* XXX: Consider removing the least recently used entry and * allow new one to be added. */ -- Gitee From 986e3afd7c25145eb1cd5f6df67aebe76e582873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C3=85strand?= Date: Wed, 3 Dec 2025 15:57:08 +0800 Subject: [PATCH 1329/1449] wifi: wlcore: ensure skb headroom before skb_push ANBZ: #35228 commit b167312390fdd461c81ead516f2b0b44e83a9edb stable. commit e75665dd096819b1184087ba5718bd93beafff51 upstream. This avoids occasional skb_under_panic Oops from wl1271_tx_work. In this case, headroom is less than needed (typically 110 - 94 = 16 bytes). Signed-off-by: Peter Astrand Link: https://patch.msgid.link/097bd417-e1d7-acd4-be05-47b199075013@lysator.liu.se Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/ti/wlcore/tx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 7bd3ce2f0804..75ad09667656 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -210,6 +210,11 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); if (total_blocks <= wl->tx_blocks_available) { + if (skb_headroom(skb) < (total_len - skb->len) && + pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) { + wl1271_free_tx_id(wl, id); + return -EAGAIN; + } desc = skb_push(skb, total_len - skb->len); wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks, -- Gitee From ae1e8ea8d70291b1032d028ae92f231a40447d32 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Thu, 11 Dec 2025 14:24:51 +0800 Subject: [PATCH 1330/1449] net: usb: sr9700: support devices with virtual driver CD ANBZ: #35228 commit 8365785e59ea4e0160aa07c4a79e2155bbb9944f stable. commit bf4172bd870c3a34d3065cbb39192c22cbd7b18d upstream. Some SR9700 devices have an SPI flash chip containing a virtual driver CD, in which case they appear as a device with two interfaces and product ID 0x9702. Interface 0 is the driver CD and interface 1 is the Ethernet device. Link: https://github.com/name-kurniawan/usb-lan Link: https://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=2185 Signed-off-by: Ethan Nelson-Moore Link: https://patch.msgid.link/20251211062451.139036-1-enelsonmoore@gmail.com [pabeni@redhat.com: fixes link tags] Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/usb/sr9700.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c index 9587eb98cdb3..213b4817cfdf 100644 --- a/drivers/net/usb/sr9700.c +++ b/drivers/net/usb/sr9700.c @@ -539,6 +539,11 @@ static const struct usb_device_id products[] = { USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */ .driver_info = (unsigned long)&sr9700_driver_info, }, + { + /* SR9700 with virtual driver CD-ROM - interface 0 is the CD-ROM device */ + USB_DEVICE_INTERFACE_NUMBER(0x0fe6, 0x9702, 1), + .driver_info = (unsigned long)&sr9700_driver_info, + }, {}, /* END */ }; -- Gitee From 7a369f58ba20454bb86bc2785a66964f8bc9128d Mon Sep 17 00:00:00 2001 From: shechenglong Date: Sun, 28 Dec 2025 21:04:26 +0800 Subject: [PATCH 1331/1449] block,bfq: fix aux stat accumulation destination ANBZ: #35228 commit b03415955ed31d14f1fc76cdaeb0cfad210612bf stable. commit 04bdb1a04d8a2a89df504c1e34250cd3c6e31a1c upstream. Route bfqg_stats_add_aux() time accumulation into the destination stats object instead of the source, aligning with other stat fields. Reviewed-by: Yu Kuai Signed-off-by: shechenglong Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- block/bfq-cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index 2c90e5de0acd..cb2a381193d1 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -380,7 +380,7 @@ static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from) blkg_rwstat_add_aux(&to->merged, &from->merged); blkg_rwstat_add_aux(&to->service_time, &from->service_time); blkg_rwstat_add_aux(&to->wait_time, &from->wait_time); - bfq_stat_add_aux(&from->time, &from->time); + bfq_stat_add_aux(&to->time, &from->time); bfq_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum); bfq_stat_add_aux(&to->avg_queue_size_samples, &from->avg_queue_size_samples); -- Gitee From 187b7041db522b8f400a8f0e99a8f5aee846c4f8 Mon Sep 17 00:00:00 2001 From: ZhangGuoDong Date: Sun, 28 Dec 2025 22:51:01 +0800 Subject: [PATCH 1332/1449] smb/server: call ksmbd_session_rpc_close() on error path in create_smb2_pipe() ANBZ: #35228 commit 04dd114b682a4ccaeba2c2bad049c8b50ce740d8 stable. commit 7c28f8eef5ac5312794d8a52918076dcd787e53b upstream. When ksmbd_iov_pin_rsp() fails, we should call ksmbd_session_rpc_close(). Signed-off-by: ZhangGuoDong Signed-off-by: ChenXiaoSong Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index d024eba3719d..fedb86a27d5e 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2274,7 +2274,7 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work) { struct smb2_create_rsp *rsp; struct smb2_create_req *req; - int id; + int id = -1; int err; char *name; @@ -2331,6 +2331,9 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work) break; } + if (id >= 0) + ksmbd_session_rpc_close(work->sess, id); + if (!IS_ERR(name)) kfree(name); -- Gitee From b967448ca1a850bd8a8c7a81b0995ffbece22604 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Wed, 31 Dec 2025 15:19:10 +0800 Subject: [PATCH 1333/1449] LoongArch: Set correct protection_map[] for VM_NONE/VM_SHARED ANBZ: #35228 commit 5fbdf95d2575ec53fd4a5c18e789b4d54a0281fe stable. commit d5be446948b379f1d1a8e7bc6656d13f44c5c7b1 upstream. For 32BIT platform _PAGE_PROTNONE is 0, so set a VMA to be VM_NONE or VM_SHARED will make pages non-present, then cause Oops with kernel page fault. Fix it by set correct protection_map[] for VM_NONE/VM_SHARED, replacing _PAGE_PROTNONE with _PAGE_PRESENT. Signed-off-by: Huacai Chen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/mm/cache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/mm/cache.c b/arch/loongarch/mm/cache.c index f6cda2b5d738..6cac632e4570 100644 --- a/arch/loongarch/mm/cache.c +++ b/arch/loongarch/mm/cache.c @@ -182,8 +182,8 @@ void cpu_cache_init(void) static const pgprot_t protection_map[16] = { [VM_NONE] = __pgprot(_CACHE_CC | _PAGE_USER | - _PAGE_PROTNONE | _PAGE_NO_EXEC | - _PAGE_NO_READ), + _PAGE_NO_EXEC | _PAGE_NO_READ | + (_PAGE_PROTNONE ? : _PAGE_PRESENT)), [VM_READ] = __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC), @@ -202,8 +202,8 @@ static const pgprot_t protection_map[16] = { [VM_EXEC | VM_WRITE | VM_READ] = __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT), [VM_SHARED] = __pgprot(_CACHE_CC | _PAGE_USER | - _PAGE_PROTNONE | _PAGE_NO_EXEC | - _PAGE_NO_READ), + _PAGE_NO_EXEC | _PAGE_NO_READ | + (_PAGE_PROTNONE ? : _PAGE_PRESENT)), [VM_SHARED | VM_READ] = __pgprot(_CACHE_CC | _PAGE_VALID | _PAGE_USER | _PAGE_PRESENT | _PAGE_NO_EXEC), -- Gitee From 8ca3381b670f6701b13467f78d3dd4b33af4ae3e Mon Sep 17 00:00:00 2001 From: ZhangGuoDong Date: Mon, 29 Dec 2025 11:15:18 +0800 Subject: [PATCH 1334/1449] smb/server: fix refcount leak in smb2_open() ANBZ: #35228 commit 2456fde2b137703328f1695f60c68fe488d17e36 stable. commit f416c556997aa56ec4384c6b6efd6a0e6ac70aa7 upstream. When ksmbd_vfs_getattr() fails, the reference count of ksmbd_file must be released. Suggested-by: Namjae Jeon Signed-off-by: ZhangGuoDong Signed-off-by: ChenXiaoSong Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index fedb86a27d5e..be996731856f 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2999,10 +2999,10 @@ int smb2_open(struct ksmbd_work *work) file_info = FILE_OPENED; rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat); + ksmbd_put_durable_fd(fp); if (rc) goto err_out2; - ksmbd_put_durable_fd(fp); goto reconnected_fp; } } else if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) -- Gitee From 6ea4ef59f93ee5213a01e0fe700d6e560f8e710e Mon Sep 17 00:00:00 2001 From: Chenghao Duan Date: Wed, 31 Dec 2025 15:19:20 +0800 Subject: [PATCH 1335/1449] LoongArch: Enable exception fixup for specific ADE subcode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 73ede654d9daa2ee41bdd17bc62946fc5a0258cb stable. commit 9bdc1ab5e4ce6f066119018d8f69631a46f9c5a0 upstream. This patch allows the LoongArch BPF JIT to handle recoverable memory access errors generated by BPF_PROBE_MEM* instructions. When a BPF program performs memory access operations, the instructions it executes may trigger ADEM exceptions. The kernel’s built-in BPF exception table mechanism (EX_TYPE_BPF) will generate corresponding exception fixup entries in the JIT compilation phase; however, the architecture-specific trap handling function needs to proactively call the common fixup routine to achieve exception recovery. do_ade(): fix EX_TYPE_BPF memory access exceptions for BPF programs, ensure safe execution. Relevant test cases: illegal address access tests in module_attach and subprogs_extable of selftests/bpf. Signed-off-by: Chenghao Duan Signed-off-by: Huacai Chen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- arch/loongarch/kernel/traps.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index d827ed3178b0..40c162fb645a 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -534,10 +534,15 @@ asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr) asmlinkage void noinstr do_ade(struct pt_regs *regs) { irqentry_state_t state = irqentry_enter(regs); + unsigned int esubcode = FIELD_GET(CSR_ESTAT_ESUBCODE, regs->csr_estat); + + if ((esubcode == EXSUBCODE_ADEM) && fixup_exception(regs)) + goto out; die_if_kernel("Kernel ade access", regs); force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)regs->csr_badvaddr); +out: irqentry_exit(regs, state); } -- Gitee From 537eeaf00e740f08af90e33480e495da748c0a36 Mon Sep 17 00:00:00 2001 From: ZhangGuoDong Date: Mon, 29 Dec 2025 10:13:29 +0800 Subject: [PATCH 1336/1449] smb/server: fix refcount leak in parse_durable_handle_context() ANBZ: #35228 commit 07df5ff4f6490a5c96715b7c562e0b2908422e04 stable. commit 3296c3012a9d9a27e81e34910384e55a6ff3cff0 upstream. When the command is a replay operation and -ENOEXEC is returned, the refcount of ksmbd_file must be released. Signed-off-by: ZhangGuoDong Signed-off-by: ChenXiaoSong Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/smb2pdu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index be996731856f..1299984659f0 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2805,6 +2805,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work, SMB2_CLIENT_GUID_SIZE)) { if (!(req->hdr.Flags & SMB2_FLAGS_REPLAY_OPERATION)) { err = -ENOEXEC; + ksmbd_put_durable_fd(dh_info->fp); goto out; } -- Gitee From ef2c306426e121a5dc948fc1c15db8dae2104a10 Mon Sep 17 00:00:00 2001 From: Zhang Lixu Date: Wed, 10 Dec 2025 10:53:28 +0800 Subject: [PATCH 1337/1449] HID: intel-ish-hid: Update ishtp bus match to support device ID table ANBZ: #35228 commit 5b25505b52dff9ee7119aa93b51634702353ebb3 stable. commit daeed86b686855adda79f13729e0c9b0530990be upstream. The ishtp_cl_bus_match() function previously only checked the first entry in the driver's device ID table. Update it to iterate over the entire table, allowing proper matching for drivers with multiple supported protocol GUIDs. Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/intel-ish-hid/ishtp/bus.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index 7fc738a22375..4d97d043aae4 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -240,9 +240,17 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv) { struct ishtp_cl_device *device = to_ishtp_cl_device(dev); struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv); + struct ishtp_fw_client *client = device->fw_client; + const struct ishtp_device_id *id; - return(device->fw_client ? guid_equal(&driver->id[0].guid, - &device->fw_client->props.protocol_name) : 0); + if (client) { + for (id = driver->id; !guid_is_null(&id->guid); id++) { + if (guid_equal(&id->guid, &client->props.protocol_name)) + return 1; + } + } + + return 0; } /** -- Gitee From 329e90aca1288ce00201f84d98c6147ec256f7a3 Mon Sep 17 00:00:00 2001 From: DaytonCL Date: Sun, 14 Dec 2025 21:34:36 +0800 Subject: [PATCH 1338/1449] HID: multitouch: add MT_QUIRK_STICKY_FINGERS to MT_CLS_VTL ANBZ: #35228 commit 9ab846d8dd0271a71bab35d0f47bb67a2df7111d stable. commit ff3f234ff1dcd6d626a989151db067a1b7f0f215 upstream. Some VTL-class touchpads (e.g. TOPS0102:00 35CC:0104) intermittently fail to release a finger contact. A previous slot remains logically active, accompanied by stale BTN_TOOL_DOUBLETAP state, causing gestures to stay latched and resulting in stuck two-finger scrolling and false right-clicks. Apply MT_QUIRK_STICKY_FINGERS to handle the unreleased contact correctly. Link: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1225 Suggested-by: Benjamin Tissoires Tested-by: DaytonCL Signed-off-by: DaytonCL Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-multitouch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index b9e67b408a4b..6d9a85c5fc40 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -379,6 +379,7 @@ static const struct mt_class mt_classes[] = { { .name = MT_CLS_VTL, .quirks = MT_QUIRK_ALWAYS_VALID | MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_STICKY_FINGERS | MT_QUIRK_FORCE_GET_FEATURE, }, { .name = MT_CLS_GOOGLE, -- Gitee From 112a9a1231dbba60cf9288a7b2dea0ad4f313cf3 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Sat, 13 Dec 2025 01:18:25 +0800 Subject: [PATCH 1339/1449] btrfs: fix reservation leak in some error paths when inserting inline extent ANBZ: #35228 commit 28b97fcbbf523779688e8de5fe55bf2dae3859f6 stable. commit c1c050f92d8f6aac4e17f7f2230160794fceef0c upstream. If we fail to allocate a path or join a transaction, we return from __cow_file_range_inline() without freeing the reserved qgroup data, resulting in a leak. Fix this by ensuring we call btrfs_qgroup_free_data() in such cases. Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/inode.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d9b2bf868de7..1cd9871ffb9c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -619,7 +619,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, struct btrfs_drop_extents_args drop_args = { 0 }; struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; - struct btrfs_trans_handle *trans; + struct btrfs_trans_handle *trans = NULL; u64 data_len = (compressed_size ?: size); int ret; struct btrfs_path *path; @@ -637,13 +637,16 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, return 1; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + if (!path) { + ret = -ENOMEM; + goto out; + } trans = btrfs_join_transaction(root); if (IS_ERR(trans)) { - btrfs_free_path(path); - return PTR_ERR(trans); + ret = PTR_ERR(trans); + trans = NULL; + goto out; } trans->block_rsv = &inode->block_rsv; @@ -690,7 +693,8 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size, */ btrfs_qgroup_free_data(inode, NULL, 0, PAGE_SIZE, NULL); btrfs_free_path(path); - btrfs_end_transaction(trans); + if (trans) + btrfs_end_transaction(trans); return ret; } -- Gitee From 0b7d109af19b94ba7ee57271e1183e3462c23195 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Fri, 2 Jan 2026 14:56:43 +0800 Subject: [PATCH 1340/1449] HID: quirks: Add another Chicony HP 5MP Cameras to hid_ignore_list ANBZ: #35228 commit 68ab5057e690e21ff892efe21503f9901fe15a33 stable. commit c06bc3557542307b9658fbd43cc946a14250347b upstream. Another Chicony Electronics HP 5MP Camera with USB ID 04F2:B882 reports a HID sensor interface that is not actually implemented. Add the device to the HID ignore list so the bogus sensor is never exposed to userspace. Then the system won't hang when runtime PM tries to wake the unresponsive device. Signed-off-by: Chris Chiu Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ca9c70c8f3cf..fbbd1dc5582e 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -307,6 +307,7 @@ #define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421 #define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA 0xb824 #define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2 0xb82c +#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA3 0xb882 #define USB_VENDOR_ID_CHUNGHWAT 0x2247 #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 192b8f63baaa..b2a3ce7bfb6b 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -763,6 +763,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA3) }, { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI4713) }, -- Gitee From f2672c6754294d1b764a94190d695b391a01b9f2 Mon Sep 17 00:00:00 2001 From: Kwok Kin Ming Date: Thu, 1 Jan 2026 02:18:26 +0800 Subject: [PATCH 1341/1449] HID: i2c-hid: fix potential buffer overflow in i2c_hid_get_report() ANBZ: #35228 commit cff3f619fd1cb40cdd89971df9001f075613d219 stable. commit 2497ff38c530b1af0df5130ca9f5ab22c5e92f29 upstream. `i2c_hid_xfer` is used to read `recv_len + sizeof(__le16)` bytes of data into `ihid->rawbuf`. The former can come from the userspace in the hidraw driver and is only bounded by HID_MAX_BUFFER_SIZE(16384) by default (unless we also set `max_buffer_size` field of `struct hid_ll_driver` which we do not). The latter has size determined at runtime by the maximum size of different report types you could receive on any particular device and can be a much smaller value. Fix this by truncating `recv_len` to `ihid->bufsize - sizeof(__le16)`. The impact is low since access to hidraw devices requires root. Signed-off-by: Kwok Kin Ming Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/i2c-hid/i2c-hid-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 172b78327420..0a350780407e 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -254,6 +254,7 @@ static int i2c_hid_get_report(struct i2c_hid *ihid, * In addition to report data device will supply data length * in the first 2 bytes of the response, so adjust . */ + recv_len = min(recv_len, ihid->bufsize - sizeof(__le16)); error = i2c_hid_xfer(ihid, ihid->cmdbuf, length, ihid->rawbuf, recv_len + sizeof(__le16)); if (error) { -- Gitee From 16e3d50ea33684591896ed382879c94e3ca0a441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Lugathe=20da=20Concei=C3=A7=C3=A3o=20Alves?= Date: Fri, 28 Nov 2025 06:03:57 +0800 Subject: [PATCH 1342/1449] HID: Apply quirk HID_QUIRK_ALWAYS_POLL to Edifier QR30 (2d99:a101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit f63f30607dd8ed1298ed518b36f90be732509ed4 stable. commit 85a866809333cd2bf8ddac93d9a3e3ba8e4f807d upstream. The USB speaker has a bug that causes it to reboot when changing the brightness using the physical knob. Add a new vendor and product ID entry in hid-ids.h, and register the corresponding device in hid-quirks.c with the required quirk. Signed-off-by: Rodrigo Lugathe da Conceição Alves Reviewed-by: Terry Junge Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index fbbd1dc5582e..931746cf3630 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -429,6 +429,9 @@ #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002 0xc002 +#define USB_VENDOR_ID_EDIFIER 0x2d99 +#define USB_DEVICE_ID_EDIFIER_QR30 0xa101 /* EDIFIER Hal0 2.0 SE */ + #define USB_VENDOR_ID_ELAN 0x04f3 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 #define USB_DEVICE_ID_HP_X2 0x074d diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index b2a3ce7bfb6b..1f531626192c 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -81,6 +81,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_EDIFIER, USB_DEVICE_ID_EDIFIER_QR30), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II), HID_QUIRK_MULTI_INPUT }, -- Gitee From 945167e6caf9d073f396874b95d046e8fd567020 Mon Sep 17 00:00:00 2001 From: Wupeng Ma Date: Sun, 28 Dec 2025 14:50:07 +0800 Subject: [PATCH 1343/1449] ring-buffer: Avoid softlockup in ring_buffer_resize() during memory free ANBZ: #35228 commit 1fbb409652e3d7e1b20f222a53ecb5e55b84e3b7 stable. commit 6435ffd6c7fcba330dfa91c58dc30aed2df3d0bf upstream. When user resize all trace ring buffer through file 'buffer_size_kb', then in ring_buffer_resize(), kernel allocates buffer pages for each cpu in a loop. If the kernel preemption model is PREEMPT_NONE and there are many cpus and there are many buffer pages to be freed, it may not give up cpu for a long time and finally cause a softlockup. To avoid it, call cond_resched() after each cpu buffer free as Commit f6bd2c92488c ("ring-buffer: Avoid softlockup in ring_buffer_resize()") does. Detailed call trace as follow: rcu: INFO: rcu_sched self-detected stall on CPU rcu: 24-....: (14837 ticks this GP) idle=521c/1/0x4000000000000000 softirq=230597/230597 fqs=5329 rcu: (t=15004 jiffies g=26003221 q=211022 ncpus=96) CPU: 24 UID: 0 PID: 11253 Comm: bash Kdump: loaded Tainted: G EL 6.18.2+ #278 NONE pc : arch_local_irq_restore+0x8/0x20 arch_local_irq_restore+0x8/0x20 (P) free_frozen_page_commit+0x28c/0x3b0 __free_frozen_pages+0x1c0/0x678 ___free_pages+0xc0/0xe0 free_pages+0x3c/0x50 ring_buffer_resize.part.0+0x6a8/0x880 ring_buffer_resize+0x3c/0x58 __tracing_resize_ring_buffer.part.0+0x34/0xd8 tracing_resize_ring_buffer+0x8c/0xd0 tracing_entries_write+0x74/0xd8 vfs_write+0xcc/0x288 ksys_write+0x74/0x118 __arm64_sys_write+0x24/0x38 Cc: Link: https://patch.msgid.link/20251228065008.2396573-1-mawupeng1@huawei.com Signed-off-by: Wupeng Ma Acked-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/trace/ring_buffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 62d93db72b0a..a305d1488387 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2364,6 +2364,8 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, list) { list_del_init(&bpage->list); free_buffer_page(bpage); + + cond_resched(); } } out_err_unlock: -- Gitee From 8a8c54358b6ad92a89dd85aad1a56b1c0ffb9190 Mon Sep 17 00:00:00 2001 From: Zhang Lixu Date: Fri, 12 Dec 2025 10:51:50 +0800 Subject: [PATCH 1344/1449] HID: intel-ish-hid: Reset enum_devices_done before enumeration ANBZ: #35228 commit 9edee94001b638f6713bf1bbce6855e3ddef9a7a stable. commit 56e230723e3a818373bd62331bccb1c6d2b3881b upstream. Some systems have enabled ISH without any sensors. In this case sending HOSTIF_DM_ENUM_DEVICES results in 0 sensors. This triggers ISH hardware reset on subsequent enumeration after S3/S4 resume. The enum_devices_done flag was not reset before sending the HOSTIF_DM_ENUM_DEVICES command. On subsequent enumeration calls (such as after S3/S4 resume), this flag retains its previous true value, causing the wait loop to be skipped and returning prematurely to hid_ishtp_cl_init(). If 0 HID devices are found, hid_ishtp_cl_init() skips getting HID device descriptors and sets init_done to true. When the delayed enumeration response arrives with init_done already true, the driver treats it as a bad packet and triggers an ISH hardware reset. Set enum_devices_done to false before sending the enumeration command, consistent with similar functions like ishtp_get_hid_descriptor() and ishtp_get_report_descriptor() which reset their respective flags. Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/intel-ish-hid/ishtp-hid-client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c index e3d70c5460e9..a0c1dc094149 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c @@ -496,6 +496,7 @@ static int ishtp_enum_enum_devices(struct ishtp_cl *hid_ishtp_cl) int rv; /* Send HOSTIF_DM_ENUM_DEVICES */ + client_data->enum_devices_done = false; memset(&msg, 0, sizeof(struct hostif_msg)); msg.hdr.command = HOSTIF_DM_ENUM_DEVICES; rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *)&msg, -- Gitee From c9fc6127a8cc5a10c0f182e1d136b827da7cc45c Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Wed, 12 Nov 2025 07:45:19 +0800 Subject: [PATCH 1345/1449] HID: playstation: Center initial joystick axes to prevent spurious events ANBZ: #35228 commit bfcfb9e548bc110236bdc076003ee91c328cba18 stable. commit e9143268d259d98e111a649affa061acb8e13c5b upstream. When a new PlayStation gamepad (DualShock 4 or DualSense) is initialized, the input subsystem sets the default value for its absolute axes (e.g., ABS_X, ABS_Y) to 0. However, the hardware's actual neutral/resting state for these joysticks is 128 (0x80). This creates a mismatch. When the first HID report arrives from the device, the driver sees the resting value of 128. The kernel compares this to its initial state of 0 and incorrectly interprets this as a delta (0 -> 128). Consequently, it generates EV_ABS events for this initial, non-existent movement. This behavior can fail userspace 'sanity check' tests (e.g., in Android CTS) that correctly assert no motion events should be generated from a device that is already at rest. This patch fixes the issue by explicitly setting the initial value of the main joystick axes (e.g., ABS_X, ABS_Y, ABS_RX, ABS_RY) to 128 (0x80) in the common ps_gamepad_create() function. This aligns the kernel's initial state with the hardware's expected neutral state, ensuring that the first report (at 128) produces no delta and thus, no spurious event. Signed-off-by: Siarhei Vishniakou Reviewed-by: Benjamin Tissoires Signed-off-by: Benjamin Tissoires Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hid/hid-playstation.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index 8ac8f7b8e317..32f65c45fdc8 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -711,11 +711,16 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev, if (IS_ERR(gamepad)) return ERR_CAST(gamepad); + /* Set initial resting state for joysticks to 128 (center) */ input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0); + gamepad->absinfo[ABS_X].value = 128; input_set_abs_params(gamepad, ABS_Y, 0, 255, 0, 0); + gamepad->absinfo[ABS_Y].value = 128; input_set_abs_params(gamepad, ABS_Z, 0, 255, 0, 0); input_set_abs_params(gamepad, ABS_RX, 0, 255, 0, 0); + gamepad->absinfo[ABS_RX].value = 128; input_set_abs_params(gamepad, ABS_RY, 0, 255, 0, 0); + gamepad->absinfo[ABS_RY].value = 128; input_set_abs_params(gamepad, ABS_RZ, 0, 255, 0, 0); input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0); -- Gitee From 17bae4b5e05acaf11c59f36c503d6125a3da7a8b Mon Sep 17 00:00:00 2001 From: Ruslan Krupitsa Date: Fri, 2 Jan 2026 07:53:36 +0800 Subject: [PATCH 1346/1449] ALSA: hda/realtek: add HP Laptop 15s-eq1xxx mute LED quirk ANBZ: #35228 commit a58fbeda600fe4b415451c494d1771366f421fd3 stable. commit 9ed7a28225af02b74f61e7880d460db49db83758 upstream. HP Laptop 15s-eq1xxx with ALC236 codec does not enable the mute LED automatically. This patch adds a quirk entry for subsystem ID 0x8706 using the ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 fixup, enabling correct mute LED behavior. Signed-off-by: Ruslan Krupitsa Link: https://patch.msgid.link/AS8P194MB112895B8EC2D87D53A876085BBBAA@AS8P194MB1128.EURP194.PROD.OUTLOOK.COM Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 65c9d47f03af..e7f6bba3e02b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10085,6 +10085,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x863e, "HP Spectre x360 15-df1xxx", ALC285_FIXUP_HP_SPECTRE_X360_DF1), SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), SND_PCI_QUIRK(0x103c, 0x86f9, "HP Spectre x360 13-aw0xxx", ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8706, "HP Laptop 15s-eq1xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), -- Gitee From 9c1ba4431c5222089a0a521ccf61515d32e5e5ab Mon Sep 17 00:00:00 2001 From: Daniel Gomez Date: Fri, 19 Dec 2025 13:13:20 +0800 Subject: [PATCH 1347/1449] netfilter: replace -EEXIST with -EBUSY ANBZ: #35228 commit 383bc94e906612b91b08b18584caa92f9b5f5efc stable. commit 2bafeb8d2f380c3a81d98bd7b78b854b564f9cd4 upstream. The -EEXIST error code is reserved by the module loading infrastructure to indicate that a module is already loaded. When a module's init function returns -EEXIST, userspace tools like kmod interpret this as "module already loaded" and treat the operation as successful, returning 0 to the user even though the module initialization actually failed. Replace -EEXIST with -EBUSY to ensure correct error reporting in the module initialization path. Affected modules: * ebtable_broute ebtable_filter ebtable_nat arptable_filter * ip6table_filter ip6table_mangle ip6table_nat ip6table_raw * ip6table_security iptable_filter iptable_mangle iptable_nat * iptable_raw iptable_security Signed-off-by: Daniel Gomez Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/bridge/netfilter/ebtables.c | 2 +- net/netfilter/nf_log.c | 4 ++-- net/netfilter/x_tables.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index ed62c1026fe9..f99e348c8f37 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1299,7 +1299,7 @@ int ebt_register_template(const struct ebt_table *t, int (*table_init)(struct ne list_for_each_entry(tmpl, &template_tables, list) { if (WARN_ON_ONCE(strcmp(t->name, tmpl->name) == 0)) { mutex_unlock(&ebt_mutex); - return -EEXIST; + return -EBUSY; } } diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index e16f158388bb..75c812f157e2 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -89,7 +89,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger) if (pf == NFPROTO_UNSPEC) { for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) { if (rcu_access_pointer(loggers[i][logger->type])) { - ret = -EEXIST; + ret = -EBUSY; goto unlock; } } @@ -97,7 +97,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger) rcu_assign_pointer(loggers[i][logger->type], logger); } else { if (rcu_access_pointer(loggers[pf][logger->type])) { - ret = -EEXIST; + ret = -EBUSY; goto unlock; } rcu_assign_pointer(loggers[pf][logger->type], logger); diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index e50c23b9c9c4..d892afc9a1ac 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1761,7 +1761,7 @@ EXPORT_SYMBOL_GPL(xt_hook_ops_alloc); int xt_register_template(const struct xt_table *table, int (*table_init)(struct net *net)) { - int ret = -EEXIST, af = table->af; + int ret = -EBUSY, af = table->af; struct xt_template *t; mutex_lock(&xt[af].mutex); -- Gitee From eb9063c7377c34c705e642f37be5e07eea0e5d45 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Mon, 22 Dec 2025 10:29:07 +0800 Subject: [PATCH 1348/1449] wifi: mac80211: collect station statistics earlier when disconnect ANBZ: #35228 commit db1bef623ae32d3062ba1d163bec43086ec8c6f2 stable. commit a203dbeeca15a9b924f0d51f510921f4bae96801 upstream. In __sta_info_destroy_part2(), station statistics are requested after the IEEE80211_STA_NONE -> IEEE80211_STA_NOTEXIST transition. This is problematic because the driver may be unable to handle the request due to the STA being in the NOTEXIST state (i.e. if the driver destroys the underlying data when transitioning to NOTEXIST). Move the statistics collection to before the state transition to avoid this issue. Signed-off-by: Baochen Qiang Link: https://patch.msgid.link/20251222-mac80211-move-station-stats-collection-earlier-v1-1-12cd4e42c633@oss.qualcomm.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/sta_info.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 64cf5589989b..9d7d7ee9d7ce 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1477,6 +1477,10 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc) } } + sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + if (sinfo) + sta_set_sinfo(sta, sinfo, true); + if (sta->uploaded) { ret = drv_sta_state(local, sdata, sta, IEEE80211_STA_NONE, IEEE80211_STA_NOTEXIST); @@ -1485,9 +1489,6 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc) sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); - if (sinfo) - sta_set_sinfo(sta, sinfo, true); cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL); kfree(sinfo); -- Gitee From f215a359ba56da1c93c1be1fc33eb467605eae36 Mon Sep 17 00:00:00 2001 From: Kery Qi Date: Wed, 7 Jan 2026 23:48:37 +0800 Subject: [PATCH 1349/1449] ASoC: davinci-evm: Fix reference leak in davinci_evm_probe ANBZ: #35228 commit 1d395dae332ba04528aa25adbae855b3b05bd0ea stable. commit 5b577d214fcc109707bcb77b4ae72a31cfd86798 upstream. The davinci_evm_probe() function calls of_parse_phandle() to acquire device nodes for "ti,audio-codec" and "ti,mcasp-controller". These functions return device nodes with incremented reference counts. However, in several error paths (e.g., when the second of_parse_phandle(), snd_soc_of_parse_card_name(), or devm_snd_soc_register_card() fails), the function returns directly without releasing the acquired nodes, leading to reference leaks. This patch adds an error handling path 'err_put' to properly release the device nodes using of_node_put() and clean up the pointers when an error occurs. Signed-off-by: Kery Qi Link: https://patch.msgid.link/20260107154836.1521-2-qikeyu2017@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/ti/davinci-evm.c | 39 ++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c index 544cb3da50eb..7cf900289dc7 100644 --- a/sound/soc/ti/davinci-evm.c +++ b/sound/soc/ti/davinci-evm.c @@ -196,27 +196,32 @@ static int davinci_evm_probe(struct platform_device *pdev) return -EINVAL; dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0); - if (!dai->cpus->of_node) - return -EINVAL; + if (!dai->cpus->of_node) { + ret = -EINVAL; + goto err_put; + } dai->platforms->of_node = dai->cpus->of_node; evm_soc_card.dev = &pdev->dev; ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); if (ret) - return ret; + goto err_put; mclk = devm_clk_get(&pdev->dev, "mclk"); if (PTR_ERR(mclk) == -EPROBE_DEFER) { - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto err_put; } else if (IS_ERR(mclk)) { dev_dbg(&pdev->dev, "mclk not found.\n"); mclk = NULL; } drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; + if (!drvdata) { + ret = -ENOMEM; + goto err_put; + } drvdata->mclk = mclk; @@ -226,7 +231,8 @@ static int davinci_evm_probe(struct platform_device *pdev) if (!drvdata->mclk) { dev_err(&pdev->dev, "No clock or clock rate defined.\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put; } drvdata->sysclk = clk_get_rate(drvdata->mclk); } else if (drvdata->mclk) { @@ -242,8 +248,25 @@ static int davinci_evm_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&evm_soc_card, drvdata); ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card); - if (ret) + if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + goto err_put; + } + + return ret; + +err_put: + dai->platforms->of_node = NULL; + + if (dai->cpus->of_node) { + of_node_put(dai->cpus->of_node); + dai->cpus->of_node = NULL; + } + + if (dai->codecs->of_node) { + of_node_put(dai->codecs->of_node); + dai->codecs->of_node = NULL; + } return ret; } -- Gitee From d6dfed552582d3b7ab327b44c6de25ba29977c41 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 20 Dec 2025 08:18:42 +0800 Subject: [PATCH 1350/1449] nvme-fc: release admin tagset if init fails ANBZ: #35228 commit 7c54d3f5ebbc5982daaa004260242dc07ac943ea stable. commit d1877cc7270302081a315a81a0ee8331f19f95c8 upstream. nvme_fabrics creates an NVMe/FC controller in following path: nvmf_dev_write() -> nvmf_create_ctrl() -> nvme_fc_create_ctrl() -> nvme_fc_init_ctrl() nvme_fc_init_ctrl() allocates the admin blk-mq resources right after nvme_add_ctrl() succeeds. If any of the subsequent steps fail (changing the controller state, scheduling connect work, etc.), we jump to the fail_ctrl path, which tears down the controller references but never frees the admin queue/tag set. The leaked blk-mq allocations match the kmemleak report seen during blktests nvme/fc. Check ctrl->ctrl.admin_tagset in the fail_ctrl path and call nvme_remove_admin_tag_set() when it is set so that all admin queue allocations are reclaimed whenever controller setup aborts. Reported-by: Yi Zhang Reviewed-by: Justin Tee Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/host/fc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 4fdb62ae996b..44de1bcd0c65 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3550,6 +3550,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, ctrl->ctrl.opts = NULL; + if (ctrl->ctrl.admin_tagset) + nvme_remove_admin_tag_set(&ctrl->ctrl); /* initiate nvme ctrl ref counting teardown */ nvme_uninit_ctrl(&ctrl->ctrl); -- Gitee From 3f06c7f0e350e752f631c261be8243dc52cb45eb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 18 Aug 2025 17:32:45 +0800 Subject: [PATCH 1351/1449] nvmet-tcp: fixup hang in nvmet_tcp_listen_data_ready() ANBZ: #35228 commit f532b29b0e313f42b964014038b0f52899b240ec stable. commit 2fa8961d3a6a1c2395d8d560ffed2c782681bade upstream. When the socket is closed while in TCP_LISTEN a callback is run to flush all outstanding packets, which in turns calls nvmet_tcp_listen_data_ready() with the sk_callback_lock held. So we need to check if we are in TCP_LISTEN before attempting to get the sk_callback_lock() to avoid a deadlock. Link: https://lore.kernel.org/linux-nvme/CAHj4cs-zu7eVB78yUpFjVe2UqMWFkLk8p+DaS3qj+uiGCXBAoA@mail.gmail.com/ Tested-by: Yi Zhang Reviewed-by: Sagi Grimberg Signed-off-by: Hannes Reinecke Signed-off-by: Keith Busch Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/nvme/target/tcp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 519bfba3c055..41d49ef17147 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1758,14 +1758,13 @@ static void nvmet_tcp_listen_data_ready(struct sock *sk) trace_sk_data_ready(sk); + if (sk->sk_state != TCP_LISTEN) + return; + read_lock_bh(&sk->sk_callback_lock); port = sk->sk_user_data; - if (!port) - goto out; - - if (sk->sk_state == TCP_LISTEN) + if (port) queue_work(nvmet_wq, &port->accept_work); -out: read_unlock_bh(&sk->sk_callback_lock); } -- Gitee From 7e1f2038f6fecd3cfd90bbf0c233fbed37f8f4f6 Mon Sep 17 00:00:00 2001 From: Radhi Bajahaw Date: Tue, 13 Jan 2026 04:38:14 +0800 Subject: [PATCH 1352/1449] ASoC: amd: yc: Fix microphone on ASUS M6500RE ANBZ: #35228 commit e2c03961b01a865350b86d9a3d57f795076b2c00 stable. commit 8e29db1b08808f709231e6fd4c79dcdee5b17a17 upstream. Add DMI match for ASUSTeK COMPUTER INC. M6500RE to enable the internal microphone. Signed-off-by: Radhi Bajahaw Link: https://patch.msgid.link/20260112203814.155-1-bajahawradhi@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 00e4ffeb6fb0..b0456be5d921 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -409,6 +409,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "M6500RE"), + } + }, { .driver_data = &acp6x_card, .matches = { -- Gitee From ddc64384c985d40af3e194139fe12ffc050e5b8f Mon Sep 17 00:00:00 2001 From: Dimitrios Katsaros Date: Tue, 13 Jan 2026 18:58:46 +0800 Subject: [PATCH 1353/1449] ASoC: tlv320adcx140: Propagate error codes during probe ANBZ: #35228 commit 254f303cd6663eec13919df5afcf1b1e031facee stable. commit d89aad92cfd15edbd704746f44c98fe687f9366f upstream. When scanning for the reset pin, we could get an -EPROBE_DEFER. The driver would assume that no reset pin had been defined, which would mean that the chip would never be powered. Now we both respect any error we get from devm_gpiod_get_optional. We also now properly report the missing GPIO definition when 'gpio_reset' is NULL. Signed-off-by: Dimitrios Katsaros Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-3-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/tlv320adcx140.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 78d95b8be2f2..c4ffbc573412 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -1157,6 +1157,9 @@ static int adcx140_i2c_probe(struct i2c_client *i2c) adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(adcx140->gpio_reset)) + return dev_err_probe(&i2c->dev, PTR_ERR(adcx140->gpio_reset), + "Failed to get Reset GPIO\n"); + if (!adcx140->gpio_reset) dev_info(&i2c->dev, "Reset GPIO not defined\n"); adcx140->supply_areg = devm_regulator_get_optional(adcx140->dev, -- Gitee From a0a14176474d3fd0daa3339aab176e480e8d731c Mon Sep 17 00:00:00 2001 From: Devyn Liu Date: Thu, 8 Jan 2026 15:53:23 +0800 Subject: [PATCH 1354/1449] spi: hisi-kunpeng: Fixed the wrong debugfs node name in hisi_spi debugfs initialization ANBZ: #35228 commit f9b06d28a60b374337dbdc78bc9187ac18d073ee stable. commit b062a899c997df7b9ce29c62164888baa7a85833 upstream. In hisi_spi_debugfs_init, spi controller pointer is calculated by container_of macro, and the member is hs->dev. But the host cannot be calculated offset directly by this. (hs->dev) points to (pdev->dev), and it is the (host->dev.parent) rather than (host->dev) points to the (pdev->dev), which is set in __spi_alloc_controller. In this patch, this issues is fixed by getting the spi_controller data from pdev->dev by dev_get_drvdata() directly. (dev->driver_data) points to the spi controller data in the probe stage. Signed-off-by: Devyn Liu Reviewed-by: Yang Shen Link: https://patch.msgid.link/20260108075323.3831574-1-liudingyuan@h-partners.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Signed-off-by: Weilin Tong --- drivers/spi/spi-hisi-kunpeng.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c index 78a35a75fc6e..3dc214898b27 100644 --- a/drivers/spi/spi-hisi-kunpeng.c +++ b/drivers/spi/spi-hisi-kunpeng.c @@ -162,10 +162,8 @@ static const struct debugfs_reg32 hisi_spi_regs[] = { static int hisi_spi_debugfs_init(struct hisi_spi *hs) { char name[32]; + struct spi_controller *host = dev_get_drvdata(hs->dev); - struct spi_controller *host; - - host = hs->dev->driver_data; snprintf(name, 32, "hisi_spi%d", host->bus_num); hs->debugfs = debugfs_create_dir(name, NULL); if (IS_ERR(hs->debugfs)) -- Gitee From 21e4ff2551666bca2887ce5a798aad2077cc4009 Mon Sep 17 00:00:00 2001 From: Kaushlendra Kumar Date: Mon, 5 Jan 2026 11:18:20 +0800 Subject: [PATCH 1355/1449] regmap: maple: free entry on mas_store_gfp() failure ANBZ: #35228 commit d61171cf097156030142643942c217759a9cc806 stable. commit f3f380ce6b3d5c9805c7e0b3d5bc28d9ec41e2e8 upstream. regcache_maple_write() allocates a new block ('entry') to merge adjacent ranges and then stores it with mas_store_gfp(). When mas_store_gfp() fails, the new 'entry' remains allocated and is never freed, leaking memory. Free 'entry' on the failure path; on success continue freeing the replaced neighbor blocks ('lower', 'upper'). Signed-off-by: Kaushlendra Kumar Link: https://patch.msgid.link/20260105031820.260119-1-kaushlendra.kumar@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/base/regmap/regcache-maple.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c index fb5761a5ef6e..86de71ce2c19 100644 --- a/drivers/base/regmap/regcache-maple.c +++ b/drivers/base/regmap/regcache-maple.c @@ -96,12 +96,13 @@ static int regcache_maple_write(struct regmap *map, unsigned int reg, mas_unlock(&mas); - if (ret == 0) { - kfree(lower); - kfree(upper); + if (ret) { + kfree(entry); + return ret; } - - return ret; + kfree(lower); + kfree(upper); + return 0; } static int regcache_maple_drop(struct regmap *map, unsigned int min, -- Gitee From b0b795aaa81ed336497fde616e2b9f736aaf9d38 Mon Sep 17 00:00:00 2001 From: Veerendranath Jakkam Date: Fri, 9 Jan 2026 23:00:04 +0800 Subject: [PATCH 1356/1449] wifi: cfg80211: Fix bitrate calculation overflow for HE rates ANBZ: #35228 commit 2f4f008f622d400773d815b2b98ef855aa82d198 stable. commit a3034bf0746d88a00cceda9541534a5721445a24 upstream. An integer overflow occurs in cfg80211_calculate_bitrate_he() when calculating bitrates for high throughput HE configurations. For example, with 160 MHz bandwidth, HE-MCS 13, HE-NSS 4, and HE-GI 0, the multiplication (result * rate->nss) overflows the 32-bit 'result' variable before division by 8, leading to significantly underestimated bitrate values. The overflow occurs because the NSS multiplication operates on a 32-bit integer that cannot accommodate intermediate values exceeding 4,294,967,295. When overflow happens, the value wraps around, producing incorrect bitrates for high MCS and NSS combinations. Fix this by utilizing the 64-bit 'tmp' variable for the NSS multiplication and subsequent divisions via do_div(). This approach preserves full precision throughout the entire calculation, with the final value assigned to 'result' only after completing all operations. Signed-off-by: Veerendranath Jakkam Link: https://patch.msgid.link/20260109-he_bitrate_overflow-v1-1-95575e466b6e@oss.qualcomm.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/wireless/util.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/wireless/util.c b/net/wireless/util.c index 24e5af65da58..640ec502e82d 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1563,12 +1563,14 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) tmp = result; tmp *= SCALE; do_div(tmp, mcs_divisors[rate->mcs]); - result = tmp; /* and take NSS, DCM into account */ - result = (result * rate->nss) / 8; + tmp *= rate->nss; + do_div(tmp, 8); if (rate->he_dcm) - result /= 2; + do_div(tmp, 2); + + result = tmp; return result / 10000; } -- Gitee From f4f3a27650ff60c4cc147621588daa7e800ffbcc Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 13 Jan 2026 00:53:52 +0800 Subject: [PATCH 1357/1449] scsi: target: iscsi: Fix use-after-free in iscsit_dec_session_usage_count() ANBZ: #35228 commit 11ebafffce31efc6abeb28c509017976fc49f1ca stable. commit 84dc6037390b8607c5551047d3970336cb51ba9a upstream. In iscsit_dec_session_usage_count(), the function calls complete() while holding the sess->session_usage_lock. Similar to the connection usage count logic, the waiter signaled by complete() (e.g., in the session release path) may wake up and free the iscsit_session structure immediately. This creates a race condition where the current thread may attempt to execute spin_unlock_bh() on a session structure that has already been deallocated, resulting in a KASAN slab-use-after-free. To resolve this, release the session_usage_lock before calling complete() to ensure all dereferences of the sess pointer are finished before the waiter is allowed to proceed with deallocation. Signed-off-by: Maurizio Lombardi Reported-by: Zhaojuan Guo Reviewed-by: Mike Christie Link: https://patch.msgid.link/20260112165352.138606-3-mlombard@redhat.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/target/iscsi/iscsi_target_util.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 91a75a4a7cc1..ee0cf2c74952 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -785,8 +785,11 @@ void iscsit_dec_session_usage_count(struct iscsit_session *sess) spin_lock_bh(&sess->session_usage_lock); sess->session_usage_count--; - if (!sess->session_usage_count && sess->session_waiting_on_uc) + if (!sess->session_usage_count && sess->session_waiting_on_uc) { + spin_unlock_bh(&sess->session_usage_lock); complete(&sess->session_waiting_on_uc_comp); + return; + } spin_unlock_bh(&sess->session_usage_lock); } -- Gitee From d46f691c0465bf1f741f58c2ec0aff598b546d41 Mon Sep 17 00:00:00 2001 From: Tim Guttzeit Date: Mon, 19 Jan 2026 23:15:55 +0800 Subject: [PATCH 1358/1449] ALSA: hda/realtek: Fix headset mic for TongFang X6AR55xU ANBZ: #35228 commit 29fe5ff92433a9cc1d0ee9166f3626251824df7f stable. commit b48fe9af1e60360baf09ca6b7a3cd6541f16e611 upstream. Add a PCI quirk to enable microphone detection on the headphone jack of TongFang X6AR55xU devices. Signed-off-by: Tim Guttzeit Signed-off-by: Werner Sembach Link: https://patch.msgid.link/20260119151626.35481-1-wse@tuxedocomputers.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e7f6bba3e02b..908672bab29e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11101,6 +11101,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60140}, {0x19, 0x04a11030}, {0x21, 0x04211020}), + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1d05, "TongFang", ALC274_FIXUP_HP_HEADSET_MIC, + {0x17, 0x90170110}, + {0x19, 0x03a11030}, + {0x21, 0x03211020}), SND_HDA_PIN_QUIRK(0x10ec0282, 0x1025, "Acer", ALC282_FIXUP_ACER_DISABLE_LINEOUT, ALC282_STANDARD_PINS, {0x12, 0x90a609c0}, -- Gitee From 42bd024368ab9d083480b3c9a1a5d7bf8c6bc889 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 13 Jan 2026 00:53:51 +0800 Subject: [PATCH 1359/1449] scsi: target: iscsi: Fix use-after-free in iscsit_dec_conn_usage_count() ANBZ: #35228 commit 73b487d44bf4f92942629d578381f89c326ff77f stable. commit 9411a89e9e7135cc459178fa77a3f1d6191ae903 upstream. In iscsit_dec_conn_usage_count(), the function calls complete() while holding the conn->conn_usage_lock. As soon as complete() is invoked, the waiter (such as iscsit_close_connection()) may wake up and proceed to free the iscsit_conn structure. If the waiter frees the memory before the current thread reaches spin_unlock_bh(), it results in a KASAN slab-use-after-free as the function attempts to release a lock within the already-freed connection structure. Fix this by releasing the spinlock before calling complete(). Signed-off-by: Maurizio Lombardi Reported-by: Zhaojuan Guo Reviewed-by: Mike Christie Link: https://patch.msgid.link/20260112165352.138606-2-mlombard@redhat.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/target/iscsi/iscsi_target_util.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index ee0cf2c74952..b7fa8eed213b 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -857,8 +857,11 @@ void iscsit_dec_conn_usage_count(struct iscsit_conn *conn) spin_lock_bh(&conn->conn_usage_lock); conn->conn_usage_count--; - if (!conn->conn_usage_count && conn->conn_waiting_on_uc) + if (!conn->conn_usage_count && conn->conn_waiting_on_uc) { + spin_unlock_bh(&conn->conn_usage_lock); complete(&conn->conn_waiting_on_uc_comp); + return; + } spin_unlock_bh(&conn->conn_usage_lock); } -- Gitee From 06c855296e1d8e79c01db924d60ef9d8e719a33b Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Mon, 12 Jan 2026 01:19:30 +0800 Subject: [PATCH 1360/1449] wifi: mac80211: correctly check if CSA is active ANBZ: #35228 commit ccd1843b63f64ac4c97e563205a2d0a4a74b79bf stable. commit db1d0b6ab11f612ea8a327663a578c8946efeee9 upstream. We are not adding an interface if an existing one is doing CSA. But the check won't work for MLO station interfaces, since for those, vif->bss_conf is zeroed out. Fix this by checking if any link of the vif has an active CSA. Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260111191912.7ceff62fc561.Ia38d27f42684d1cfd82d930d232bd5dea6ab9282@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/iface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index a531fb2b14de..c8c53f4d1bdb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -347,6 +347,8 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { + struct ieee80211_link_data *link; + /* * Only OCB and monitor mode may coexist */ @@ -373,8 +375,10 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, * will not add another interface while any channel * switch is active. */ - if (nsdata->vif.bss_conf.csa_active) - return -EBUSY; + for_each_link_data(nsdata, link) { + if (link->conf->csa_active) + return -EBUSY; + } /* * The remaining checks are only performed for interfaces -- Gitee From 3014bc383ace6caadfb936973a1b9bff829e8afe Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 18 Jan 2026 15:28:29 +0800 Subject: [PATCH 1361/1449] wifi: mac80211: don't increment crypto_tx_tailroom_needed_cnt twice ANBZ: #35228 commit bae0565fa975db80d53a1d009c5f009a0cddb2d1 stable. commit 3f3d8ff31496874a69b131866f62474eb24ed20a upstream. In reconfig, in case the driver asks to disconnect during the reconfig, all the keys of the interface are marked as tainted. Then ieee80211_reenable_keys will loop over all the interface keys, and for each one it will a) increment crypto_tx_tailroom_needed_cnt b) call ieee80211_key_enable_hw_accel, which in turn will detect that this key is tainted, so it will mark it as "not in hardware", which is paired with crypto_tx_tailroom_needed_cnt incrementation, so we get two incrementations for each tainted key. Then we get a warning in ieee80211_free_keys. To fix it, don't increment the count in ieee80211_reenable_keys for tainted keys Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260118092821.4ca111fddcda.Id6e554f4b1c83760aa02d5a9e4e3080edb197aa2@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mac80211/key.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index f5f1eb87797a..327ae7343451 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -981,7 +981,8 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata) if (ieee80211_sdata_running(sdata)) { list_for_each_entry(key, &sdata->key_list, list) { - increment_tailroom_need_count(sdata); + if (!(key->flags & KEY_FLAG_TAINTED)) + increment_tailroom_need_count(sdata); ieee80211_key_enable_hw_accel(key); } } -- Gitee From 971891eafa0df8d2fc4eb411a1878ff3a5e23511 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 26 Jan 2026 22:38:45 +0800 Subject: [PATCH 1362/1449] platform/x86: toshiba_haps: Fix memory leaks in add/remove routines ANBZ: #35228 commit ca9ff71c15bc8e48529c2033294a519a7749b272 stable. commit 128497456756e1b952bd5a912cd073836465109d upstream. toshiba_haps_add() leaks the haps object allocated by it if it returns an error after allocating that object successfully. toshiba_haps_remove() does not free the object pointed to by toshiba_haps before clearing that pointer, so it becomes unreachable allocated memory. Address these memory leaks by using devm_kzalloc() for allocating the memory in question. Fixes: 23d0ba0c908a ("platform/x86: Toshiba HDD Active Protection Sensor") Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/toshiba_haps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/toshiba_haps.c b/drivers/platform/x86/toshiba_haps.c index 8c9f76286b08..f2292d2412fd 100644 --- a/drivers/platform/x86/toshiba_haps.c +++ b/drivers/platform/x86/toshiba_haps.c @@ -183,7 +183,7 @@ static int toshiba_haps_add(struct acpi_device *acpi_dev) pr_info("Toshiba HDD Active Protection Sensor device\n"); - haps = kzalloc(sizeof(struct toshiba_haps_dev), GFP_KERNEL); + haps = devm_kzalloc(&acpi_dev->dev, sizeof(*haps), GFP_KERNEL); if (!haps) return -ENOMEM; -- Gitee From e2a8cb4d18421c6037102cea0d39ae2f24db7d0f Mon Sep 17 00:00:00 2001 From: Kaushlendra Kumar Date: Wed, 24 Dec 2025 14:11:44 +0800 Subject: [PATCH 1363/1449] platform/x86: intel_telemetry: Fix PSS event register mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9423990550a2ae094bf63e90fe3ee7c0bf773aa6 stable. commit 39e9c376ac42705af4ed4ae39eec028e8bced9b4 upstream. The PSS telemetry info parsing incorrectly applies TELEM_INFO_SRAMEVTS_MASK when extracting event register count from firmware response. This reads bits 15-8 instead of the correct bits 7-0, causing misdetection of hardware capabilities. The IOSS path correctly uses TELEM_INFO_NENABLES_MASK for register count. Apply the same mask to PSS parsing for consistency. Fixes: 9d16b482b059 ("platform:x86: Add Intel telemetry platform driver") Signed-off-by: Kaushlendra Kumar Link: https://patch.msgid.link/20251224061144.3925519-1-kaushlendra.kumar@intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/intel/telemetry/pltdrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/telemetry/pltdrv.c b/drivers/platform/x86/intel/telemetry/pltdrv.c index 06311d0e9451..a574615c6faa 100644 --- a/drivers/platform/x86/intel/telemetry/pltdrv.c +++ b/drivers/platform/x86/intel/telemetry/pltdrv.c @@ -610,7 +610,7 @@ static int telemetry_setup(struct platform_device *pdev) /* Get telemetry Info */ events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >> TELEM_INFO_SRAMEVTS_SHIFT; - event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK; + event_regs = read_buf & TELEM_INFO_NENABLES_MASK; if ((events < TELEM_MAX_EVENTS_SRAM) || (event_regs < TELEM_MAX_EVENTS_SRAM)) { dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n"); -- Gitee From f910f5e6eddbc3e70eda001db253743c093b1cc4 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 29 Jan 2026 03:04:45 +0800 Subject: [PATCH 1364/1449] platform/x86: hp-bioscfg: Skip empty attribute names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit f54886e18b8566453f48240cdcb21d9cebee9051 stable. commit 6222883af286e2feb3c9ff2bf9fd8fdf4220c55a upstream. Avoid registering kobjects with empty names when a BIOS attribute name decodes to an empty string. Fixes: a34fc329b1895 ("platform/x86: hp-bioscfg: bioscfg") Reported-by: Alain Cousinie Closes: https://lore.kernel.org/platform-driver-x86/22ed5f78-c8bf-4ab4-8c38-420cc0201e7e@laposte.net/ Signed-off-by: Mario Limonciello Link: https://patch.msgid.link/20260128190501.2170068-1-mario.limonciello@amd.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c index e9bade74997b..ec7a74bee803 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c @@ -701,6 +701,11 @@ static int hp_init_bios_package_attribute(enum hp_wmi_data_type attr_type, return ret; } + if (!str_value || !str_value[0]) { + pr_debug("Ignoring attribute with empty name\n"); + goto pack_attr_exit; + } + /* All duplicate attributes found are ignored */ duplicate = kset_find_obj(temp_kset, str_value); if (duplicate) { -- Gitee From 9b3d9f85dbeb007fee37e5432d28230bad2d94e0 Mon Sep 17 00:00:00 2001 From: ChenXiaoSong Date: Mon, 2 Feb 2026 16:24:07 +0800 Subject: [PATCH 1365/1449] smb/client: fix memory leak in smb2_open_file() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 3a6d6b332f92990958602c1e35ce0173e2dd62e9 stable. commit e3a43633023e3cacaca60d4b8972d084a2b06236 upstream. Reproducer: 1. server: directories are exported read-only 2. client: mount -t cifs //${server_ip}/export /mnt 3. client: dd if=/dev/zero of=/mnt/file bs=512 count=1000 oflag=direct 4. client: umount /mnt 5. client: sleep 1 6. client: modprobe -r cifs The error message is as follows: ============================================================================= BUG cifs_small_rq (Not tainted): Objects remaining on __kmem_cache_shutdown() ----------------------------------------------------------------------------- Object 0x00000000d47521be @offset=14336 ... WARNING: mm/slub.c:1251 at __kmem_cache_shutdown+0x34e/0x440, CPU#0: modprobe/1577 ... Call Trace: kmem_cache_destroy+0x94/0x190 cifs_destroy_request_bufs+0x3e/0x50 [cifs] cleanup_module+0x4e/0x540 [cifs] __se_sys_delete_module+0x278/0x400 __x64_sys_delete_module+0x5f/0x70 x64_sys_call+0x2299/0x2ff0 do_syscall_64+0x89/0x350 entry_SYSCALL_64_after_hwframe+0x76/0x7e ... kmem_cache_destroy cifs_small_rq: Slab cache still has objects when called from cifs_destroy_request_bufs+0x3e/0x50 [cifs] WARNING: mm/slab_common.c:532 at kmem_cache_destroy+0x16b/0x190, CPU#0: modprobe/1577 Link: https://lore.kernel.org/linux-cifs/9751f02d-d1df-4265-a7d6-b19761b21834@linux.dev/T/#mf14808c144448b715f711ce5f0477a071f08eaf6 Fixes: e255612b5ed9 ("cifs: Add fallback for SMB2 CREATE without FILE_READ_ATTRIBUTES") Reported-by: Paulo Alcantara Reviewed-by: Paulo Alcantara (Red Hat) Signed-off-by: ChenXiaoSong Reviewed-by: Pali Rohár Signed-off-by: Steve French Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/smb2file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index d7f2835e0b1c..d436057ed77e 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -122,6 +122,7 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, &err_buftype); if (rc == -EACCES && retry_without_read_attributes) { + free_rsp_buf(err_buftype, err_iov.iov_base); oparms->desired_access &= ~FILE_READ_ATTRIBUTES; rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, &err_buftype); -- Gitee From 51dd7ccc837c960831f1b5d5c053fb8d2974ecb0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 28 Jan 2026 22:15:38 +0800 Subject: [PATCH 1366/1449] net: add skb_header_pointer_careful() helper ANBZ: #35228 commit fcbda653b5a888338ce7cdc186ec53edc260fe39 stable. commit 13e00fdc9236bd4d0bff4109d2983171fbcb74c4 upstream. This variant of skb_header_pointer() should be used in contexts where @offset argument is user-controlled and could be negative. Negative offsets are supported, as long as the zone starts between skb->head and skb->data. Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260128141539.3404400-2-edumazet@google.com Signed-off-by: Jakub Kicinski Stable-dep-of: cabd1a976375 ("net/sched: cls_u32: use skb_header_pointer_careful()") Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/skbuff.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e48a70e03bc3..c4c27be611dc 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -4126,6 +4126,18 @@ skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer) skb_headlen(skb), buffer); } +/* Variant of skb_header_pointer() where @offset is user-controlled + * and potentially negative. + */ +static inline void * __must_check +skb_header_pointer_careful(const struct sk_buff *skb, int offset, + int len, void *buffer) +{ + if (unlikely(offset < 0 && -offset > skb_headroom(skb))) + return NULL; + return skb_header_pointer(skb, offset, len, buffer); +} + static inline void * __must_check skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len) { -- Gitee From e4cde75ebc585442713befeeade2f8621a8a4543 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 28 Jan 2026 22:15:39 +0800 Subject: [PATCH 1367/1449] net/sched: cls_u32: use skb_header_pointer_careful() ANBZ: #35228 commit 13336a6239b9d7c6e61483017bb8bdfe3ceb10a5 stable. commit cabd1a976375780dabab888784e356f574bbaed8 upstream. skb_header_pointer() does not fully validate negative @offset values. Use skb_header_pointer_careful() instead. GangMin Kim provided a report and a repro fooling u32_classify(): BUG: KASAN: slab-out-of-bounds in u32_classify+0x1180/0x11b0 net/sched/cls_u32.c:221 Fixes: fbc2e7d9cf49 ("cls_u32: use skb_header_pointer() to dereference data safely") Reported-by: GangMin Kim Closes: https://lore.kernel.org/netdev/CANn89iJkyUZ=mAzLzC4GdcAgLuPnUoivdLaOs6B9rq5_erj76w@mail.gmail.com/T/ Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20260128141539.3404400-3-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/sched/cls_u32.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 67f27be13848..1338d9b4c03a 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -161,10 +161,8 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb, int toff = off + key->off + (off2 & key->offmask); __be32 *data, hdata; - if (skb_headroom(skb) + toff > INT_MAX) - goto out; - - data = skb_header_pointer(skb, toff, 4, &hdata); + data = skb_header_pointer_careful(skb, toff, 4, + &hdata); if (!data) goto out; if ((*data ^ key->val) & key->mask) { @@ -214,8 +212,9 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb, if (ht->divisor) { __be32 *data, hdata; - data = skb_header_pointer(skb, off + n->sel.hoff, 4, - &hdata); + data = skb_header_pointer_careful(skb, + off + n->sel.hoff, + 4, &hdata); if (!data) goto out; sel = ht->divisor & u32_hash_fold(*data, &n->sel, @@ -229,7 +228,7 @@ TC_INDIRECT_SCOPE int u32_classify(struct sk_buff *skb, if (n->sel.flags & TC_U32_VAROFFSET) { __be16 *data, hdata; - data = skb_header_pointer(skb, + data = skb_header_pointer_careful(skb, off + n->sel.offoff, 2, &hdata); if (!data) -- Gitee From a60474e663d7d5fe7f4eac58c7aaca8d69a2f534 Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Wed, 28 Jan 2026 16:07:34 +0800 Subject: [PATCH 1368/1449] dpaa2-switch: prevent ZERO_SIZE_PTR dereference when num_ifs is zero ANBZ: #35228 commit b97415c4362f739e25ec6f71012277086fabdf6f stable. commit ed48a84a72fefb20a82dd90a7caa7807e90c6f66 upstream. The driver allocates arrays for ports, FDBs, and filter blocks using kcalloc() with ethsw->sw_attr.num_ifs as the element count. When the device reports zero interfaces (either due to hardware configuration or firmware issues), kcalloc(0, ...) returns ZERO_SIZE_PTR (0x10) instead of NULL. Later in dpaa2_switch_probe(), the NAPI initialization unconditionally accesses ethsw->ports[0]->netdev, which attempts to dereference ZERO_SIZE_PTR (address 0x10), resulting in a kernel panic. Add a check to ensure num_ifs is greater than zero after retrieving device attributes. This prevents the zero-sized allocations and subsequent invalid pointer dereference. Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 0b1b71370458 ("staging: dpaa2-switch: handle Rx path on control interface") Signed-off-by: Junrui Luo Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/SYBPR01MB7881BEABA8DA896947962470AF91A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index cdab37e9634d..6e3f65e3e882 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -2988,6 +2988,12 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) goto err_close; } + if (!ethsw->sw_attr.num_ifs) { + dev_err(dev, "DPSW device has no interfaces\n"); + err = -ENODEV; + goto err_close; + } + err = dpsw_get_api_version(ethsw->mc_io, 0, ðsw->major, ðsw->minor); -- Gitee From 013e0a5af1cc5035b558a02c85b30792de369316 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 28 Jan 2026 23:44:38 +0800 Subject: [PATCH 1369/1449] net: liquidio: Initialize netdev pointer before queue setup ANBZ: #35228 commit c0ed6c77ec34050971fd0df2a94dfdea66d09331 stable. commit 926ede0c85e1e57c97d64d9612455267d597bb2c upstream. In setup_nic_devices(), the netdev is allocated using alloc_etherdev_mq(). However, the pointer to this structure is stored in oct->props[i].netdev only after the calls to netif_set_real_num_rx_queues() and netif_set_real_num_tx_queues(). If either of these functions fails, setup_nic_devices() returns an error without freeing the allocated netdev. Since oct->props[i].netdev is still NULL at this point, the cleanup function liquidio_destroy_nic_device() will fail to find and free the netdev, resulting in a memory leak. Fix this by initializing oct->props[i].netdev before calling the queue setup functions. This ensures that the netdev is properly accessible for cleanup in case of errors. Compile tested only. Issue found using a prototype static analysis tool and code review. Fixes: c33c997346c3 ("liquidio: enhanced ethtool --set-channels feature") Signed-off-by: Zilin Guan Reviewed-by: Kory Maincent Link: https://patch.msgid.link/20260128154440.278369-2-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- .../net/ethernet/cavium/liquidio/lio_main.c | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 100daadbea2a..a1c50cbc44be 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -3519,6 +3519,23 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) */ netdev->netdev_ops = &lionetdevops; + lio = GET_LIO(netdev); + + memset(lio, 0, sizeof(struct lio)); + + lio->ifidx = ifidx_or_pfnum; + + props = &octeon_dev->props[i]; + props->gmxport = resp->cfg_info.linfo.gmxport; + props->netdev = netdev; + + /* Point to the properties for octeon device to which this + * interface belongs. + */ + lio->oct_dev = octeon_dev; + lio->octprops = props; + lio->netdev = netdev; + retval = netif_set_real_num_rx_queues(netdev, num_oqueues); if (retval) { dev_err(&octeon_dev->pci_dev->dev, @@ -3535,16 +3552,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) goto setup_nic_dev_free; } - lio = GET_LIO(netdev); - - memset(lio, 0, sizeof(struct lio)); - - lio->ifidx = ifidx_or_pfnum; - - props = &octeon_dev->props[i]; - props->gmxport = resp->cfg_info.linfo.gmxport; - props->netdev = netdev; - lio->linfo.num_rxpciq = num_oqueues; lio->linfo.num_txpciq = num_iqueues; for (j = 0; j < num_oqueues; j++) { @@ -3610,13 +3617,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) netdev->min_mtu = LIO_MIN_MTU_SIZE; netdev->max_mtu = LIO_MAX_MTU_SIZE; - /* Point to the properties for octeon device to which this - * interface belongs. - */ - lio->oct_dev = octeon_dev; - lio->octprops = props; - lio->netdev = netdev; - dev_dbg(&octeon_dev->pci_dev->dev, "if%d gmx: %d hw_addr: 0x%llx\n", i, lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr)); -- Gitee From 3b6b123ffe2fa77bb280b1548b649dd3fcc588f6 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 28 Jan 2026 23:44:39 +0800 Subject: [PATCH 1370/1449] net: liquidio: Fix off-by-one error in PF setup_nic_devices() cleanup ANBZ: #35228 commit a0d2389c8cdc1f05de5eb8663bffe9ed05dca769 stable. commit 8558aef4e8a1a83049ab906d21d391093cfa7e7f upstream. In setup_nic_devices(), the initialization loop jumps to the label setup_nic_dev_free on failure. The current cleanup loop while(i--) skip the failing index i, causing a memory leak. Fix this by changing the loop to iterate from the current index i down to 0. Also, decrement i in the devlink_alloc failure path to point to the last successfully allocated index. Compile tested only. Issue found using code review. Fixes: f21fb3ed364b ("Add support of Cavium Liquidio ethernet adapters") Suggested-by: Simon Horman Signed-off-by: Zilin Guan Reviewed-by: Kory Maincent Link: https://patch.msgid.link/20260128154440.278369-3-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/cavium/liquidio/lio_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index a1c50cbc44be..8e4e49d24dad 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -3764,6 +3764,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) if (!devlink) { device_unlock(&octeon_dev->pci_dev->dev); dev_err(&octeon_dev->pci_dev->dev, "devlink alloc failed\n"); + i--; goto setup_nic_dev_free; } @@ -3779,11 +3780,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) setup_nic_dev_free: - while (i--) { + do { dev_err(&octeon_dev->pci_dev->dev, "NIC ifidx:%d Setup failed\n", i); liquidio_destroy_nic_device(octeon_dev, i); - } + } while (i--); setup_nic_dev_done: -- Gitee From c02ef826ed3f3e10b6de4a478f45215107854ad4 Mon Sep 17 00:00:00 2001 From: Zilin Guan Date: Wed, 28 Jan 2026 23:44:40 +0800 Subject: [PATCH 1371/1449] net: liquidio: Fix off-by-one error in VF setup_nic_devices() cleanup ANBZ: #35228 commit 3bf519e39b51cb08a93c0599870b35a23db1031e stable. commit 6cbba46934aefdfb5d171e0a95aec06c24f7ca30 upstream. In setup_nic_devices(), the initialization loop jumps to the label setup_nic_dev_free on failure. The current cleanup loop while(i--) skip the failing index i, causing a memory leak. Fix this by changing the loop to iterate from the current index i down to 0. Compile tested only. Issue found using code review. Fixes: 846b46873eeb ("liquidio CN23XX: VF offload features") Suggested-by: Simon Horman Signed-off-by: Zilin Guan Reviewed-by: Kory Maincent Link: https://patch.msgid.link/20260128154440.278369-4-zilin@seu.edu.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 62c2eadc33e3..15ef647e8aad 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -2221,11 +2221,11 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) setup_nic_dev_free: - while (i--) { + do { dev_err(&octeon_dev->pci_dev->dev, "NIC ifidx:%d Setup failed\n", i); liquidio_destroy_nic_device(octeon_dev, i); - } + } while (i--); setup_nic_dev_done: -- Gitee From 8f268f4bf001bfcad391c8f576e9f8eccd3e3f1d Mon Sep 17 00:00:00 2001 From: Junrui Luo Date: Thu, 29 Jan 2026 00:55:13 +0800 Subject: [PATCH 1372/1449] dpaa2-switch: add bounds check for if_id in IRQ handler ANBZ: #35228 commit f89e33c9c37f0001b730e23b3b05ab7b1ecface2 stable. commit 31a7a0bbeb006bac2d9c81a2874825025214b6d8 upstream. The IRQ handler extracts if_id from the upper 16 bits of the hardware status register and uses it to index into ethsw->ports[] without validation. Since if_id can be any 16-bit value (0-65535) but the ports array is only allocated with sw_attr.num_ifs elements, this can lead to an out-of-bounds read potentially. Add a bounds check before accessing the array, consistent with the existing validation in dpaa2_switch_rx(). Reported-by: Yuhao Jiang Reported-by: Junrui Luo Fixes: 24ab724f8a46 ("dpaa2-switch: use the port index in the IRQ handler") Signed-off-by: Junrui Luo Link: https://patch.msgid.link/SYBPR01MB7881D420AB43FF1A227B84AFAF91A@SYBPR01MB7881.ausprd01.prod.outlook.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index 6e3f65e3e882..37e3224262ed 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -1530,6 +1530,10 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg) } if_id = (status & 0xFFFF0000) >> 16; + if (if_id >= ethsw->sw_attr.num_ifs) { + dev_err(dev, "Invalid if_id %d in IRQ status\n", if_id); + goto out; + } port_priv = ethsw->ports[if_id]; if (status & DPSW_IRQ_EVENT_LINK_CHANGED) { -- Gitee From efb9d03ae1c17a36fee4378d439afc725668e6c8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 30 Jan 2026 04:43:59 +0800 Subject: [PATCH 1373/1449] macvlan: fix error recovery in macvlan_common_newlink() ANBZ: #35228 commit 11ba9f0dc865136174cb98834280fb21bbc950c7 stable. commit f8db6475a83649689c087a8f52486fcc53e627e9 upstream. valis provided a nice repro to crash the kernel: ip link add p1 type veth peer p2 ip link set address 00:00:00:00:00:20 dev p1 ip link set up dev p1 ip link set up dev p2 ip link add mv0 link p2 type macvlan mode source ip link add invalid% link p2 type macvlan mode source macaddr add 00:00:00:00:00:20 ping -c1 -I p1 1.2.3.4 He also gave a very detailed analysis: The issue is triggered when a new macvlan link is created with MACVLAN_MODE_SOURCE mode and MACVLAN_MACADDR_ADD (or MACVLAN_MACADDR_SET) parameter, lower device already has a macvlan port and register_netdevice() called from macvlan_common_newlink() fails (e.g. because of the invalid link name). In this case macvlan_hash_add_source is called from macvlan_change_sources() / macvlan_common_newlink(): This adds a reference to vlan to the port's vlan_source_hash using macvlan_source_entry. vlan is a pointer to the priv data of the link that is being created. When register_netdevice() fails, the error is returned from macvlan_newlink() to rtnl_newlink_create(): if (ops->newlink) err = ops->newlink(dev, ¶ms, extack); else err = register_netdevice(dev); if (err < 0) { free_netdev(dev); goto out; } and free_netdev() is called, causing a kvfree() on the struct net_device that is still referenced in the source entry attached to the lower device's macvlan port. Now all packets sent on the macvlan port with a matching source mac address will trigger a use-after-free in macvlan_forward_source(). With all that, my fix is to make sure we call macvlan_flush_sources() regardless of @create value whenever "goto destroy_macvlan_port;" path is taken. Many thanks to valis for following up on this issue. Fixes: aa5fd0fb7748 ("driver: macvlan: Destroy new macvlan port if macvlan_common_newlink failed.") Signed-off-by: Eric Dumazet Reported-by: valis Reported-by: syzbot+7182fbe91e58602ec1fe@syzkaller.appspotmail.com Closes: https: //lore.kernel.org/netdev/695fb1e8.050a0220.1c677c.039f.GAE@google.com/T/#u Cc: Boudewijn van der Heide Link: https://patch.msgid.link/20260129204359.632556-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/macvlan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 09db43ce3176..fea7352e2a47 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1572,9 +1572,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, /* the macvlan port may be freed by macvlan_uninit when fail to register. * so we destroy the macvlan port only when it's valid. */ - if (create && macvlan_port_get_rtnl(lowerdev)) { + if (macvlan_port_get_rtnl(lowerdev)) { macvlan_flush_sources(port, vlan); - macvlan_port_destroy(port->dev); + if (create) + macvlan_port_destroy(port->dev); } return err; } -- Gitee From ecdcec399bcafdee593c3a3f7b67e6da6ffb9c12 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 30 Jan 2026 11:38:27 +0800 Subject: [PATCH 1374/1449] net: don't touch dev->stats in BPF redirect paths ANBZ: #35228 commit b2c9edad3620fa6a67298455c56d03425f1a304f stable. commit fdf3f6800be36377e045e2448087f12132b88d2f upstream. Gal reports that BPF redirect increments dev->stats.tx_errors on failure. This is not correct, most modern drivers completely ignore dev->stats so these drops will be invisible to the user. Core code should use the dedicated core stats which are folded into device stats in dev_get_stats(). Note that we're switching from tx_errors to tx_dropped. Core only has tx_dropped, hence presumably users already expect that counter to increment for "stack" Tx issues. Reported-by: Gal Pressman Link: https://lore.kernel.org/c5df3b60-246a-4030-9c9a-0a35cd1ca924@nvidia.com Fixes: b4ab31414970 ("bpf: Add redirect_neigh helper as redirect drop-in") Acked-by: Martin KaFai Lau Acked-by: Daniel Borkmann Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20260130033827.698841-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/filter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index a39a0385b053..e5768bd9fc2f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2281,12 +2281,12 @@ static int __bpf_redirect_neigh_v6(struct sk_buff *skb, struct net_device *dev, err = bpf_out_neigh_v6(net, skb, dev, nh); if (unlikely(net_xmit_eval(err))) - DEV_STATS_INC(dev, tx_errors); + dev_core_stats_tx_dropped_inc(dev); else ret = NET_XMIT_SUCCESS; goto out_xmit; out_drop: - DEV_STATS_INC(dev, tx_errors); + dev_core_stats_tx_dropped_inc(dev); kfree_skb(skb); out_xmit: return ret; @@ -2389,12 +2389,12 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev, err = bpf_out_neigh_v4(net, skb, dev, nh); if (unlikely(net_xmit_eval(err))) - DEV_STATS_INC(dev, tx_errors); + dev_core_stats_tx_dropped_inc(dev); else ret = NET_XMIT_SUCCESS; goto out_xmit; out_drop: - DEV_STATS_INC(dev, tx_errors); + dev_core_stats_tx_dropped_inc(dev); kfree_skb(skb); out_xmit: return ret; -- Gitee From 5b50bc1af899d3da51c1574ee3579ba6890cf834 Mon Sep 17 00:00:00 2001 From: Daniel Hodges Date: Sun, 1 Feb 2026 02:01:14 +0800 Subject: [PATCH 1375/1449] tipc: use kfree_sensitive() for session key material ANBZ: #35228 commit 17d340e81c4b5be6bb5f07bfef760af8a9f2747a stable. commit 74d9391e8849e70ded5309222d09b0ed0edbd039 upstream. The rx->skey field contains a struct tipc_aead_key with GCM-AES encryption keys used for TIPC cluster communication. Using plain kfree() leaves this sensitive key material in freed memory pages where it could potentially be recovered. Switch to kfree_sensitive() to ensure the key material is zeroed before the memory is freed. Fixes: 1ef6f7c9390f ("tipc: add automatic session key exchange") Signed-off-by: Daniel Hodges Link: https://patch.msgid.link/20260131180114.2121438-1-hodgesd@meta.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/tipc/crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index ea5bb131ebd0..2721baf9fd2b 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -1219,7 +1219,7 @@ void tipc_crypto_key_flush(struct tipc_crypto *c) rx = c; tx = tipc_net(rx->net)->crypto_tx; if (cancel_delayed_work(&rx->work)) { - kfree(rx->skey); + kfree_sensitive(rx->skey); rx->skey = NULL; atomic_xchg(&rx->key_distr, 0); tipc_node_put(rx->node); @@ -2394,7 +2394,7 @@ static void tipc_crypto_work_rx(struct work_struct *work) break; default: synchronize_rcu(); - kfree(rx->skey); + kfree_sensitive(rx->skey); rx->skey = NULL; break; } -- Gitee From 41a5ce0e205569f51bc5bf440b6fd5efde7b610a Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Mon, 2 Feb 2026 12:02:28 +0800 Subject: [PATCH 1376/1449] net: ethernet: adi: adin1110: Check return value of devm_gpiod_get_optional() in adin1110_check_spi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 00a7512ff71951a8c6bfbd43baedab43746bec79 stable. commit 78211543d2e44f84093049b4ef5f5bfa535f4645 upstream. The devm_gpiod_get_optional() function may return an ERR_PTR in case of genuine GPIO acquisition errors, not just NULL which indicates the legitimate absence of an optional GPIO. Add an IS_ERR() check after the call in adin1110_check_spi(). On error, return the error code to ensure proper failure handling rather than proceeding with invalid pointers. Fixes: 36934cac7aaf ("net: ethernet: adi: adin1110: add reset GPIO") Signed-off-by: Chen Ni Reviewed-by: Nuno Sá Link: https://patch.msgid.link/20260202040228.4129097-1-nichen@iscas.ac.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/adi/adin1110.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c index 3c26176316a3..2bf5c8119536 100644 --- a/drivers/net/ethernet/adi/adin1110.c +++ b/drivers/net/ethernet/adi/adin1110.c @@ -1087,6 +1087,9 @@ static int adin1110_check_spi(struct adin1110_priv *priv) reset_gpio = devm_gpiod_get_optional(&priv->spidev->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) + return dev_err_probe(&priv->spidev->dev, PTR_ERR(reset_gpio), + "failed to get reset gpio\n"); if (reset_gpio) { /* MISO pin is used for internal configuration, can't have * anyone else disturbing the SDO line. -- Gitee From 9cb4b7fd999f742f45f06ab8e5a9afe680dc758e Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Mon, 2 Feb 2026 19:43:14 +0800 Subject: [PATCH 1377/1449] net: gro: fix outer network offset ANBZ: #35228 commit 9d40a85138568696387ef04cd004c64612a70874 stable. commit 5c2c3c38be396257a6a2e55bd601a12bb9781507 upstream. The udp GRO complete stage assumes that all the packets inserted the RX have the `encapsulation` flag zeroed. Such assumption is not true, as a few H/W NICs can set such flag when H/W offloading the checksum for an UDP encapsulated traffic, the tun driver can inject GSO packets with UDP encapsulation and the problematic layout can also be created via a veth based setup. Due to the above, in the problematic scenarios, udp4_gro_complete() uses the wrong network offset (inner instead of outer) to compute the outer UDP header pseudo checksum, leading to csum validation errors later on in packet processing. Address the issue always clearing the encapsulation flag at GRO completion time. Such flag will be set again as needed for encapsulated packets by udp_gro_complete(). Fixes: 5ef31ea5d053 ("net: gro: fix udp bad offset in socket lookup by adding {inner_}network_offset to napi_gro_cb") Reviewed-by: Willem de Bruijn Signed-off-by: Paolo Abeni Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/562638dbebb3b15424220e26a180274b387e2a88.1770032084.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/core/gro.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/gro.c b/net/core/gro.c index b8cc44406e69..87889cb75d21 100644 --- a/net/core/gro.c +++ b/net/core/gro.c @@ -240,6 +240,8 @@ static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb) goto out; } + /* NICs can feed encapsulated packets into GRO */ + skb->encapsulation = 0; rcu_read_lock(); list_for_each_entry_rcu(ptype, head, list) { if (ptype->type != type || !ptype->callbacks.gro_complete) -- Gitee From 61b2d72a67cc1f50c47d7d2f24b634cc039c966a Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Tue, 3 Feb 2026 08:16:39 +0800 Subject: [PATCH 1378/1449] drm/mgag200: fix mgag200_bmc_stop_scanout() ANBZ: #35228 commit 3f89a4ef6505a8f0f20ac6a670beafc813700e24 stable. commit 0e0c8f4d16de92520623aa1ea485cadbf64e6929 upstream. The mgag200_bmc_stop_scanout() function is called by the .atomic_disable() handler for the MGA G200 VGA BMC encoder. This function performs a few register writes to inform the BMC of an upcoming mode change, and then polls to wait until the BMC actually stops. The polling is implemented using a busy loop with udelay() and an iteration timeout of 300, resulting in the function blocking for 300 milliseconds. The function gets called ultimately by the output_poll_execute work thread for the DRM output change polling thread of the mgag200 driver: kworker/0:0-mm_ 3528 [000] 4555.315364: ffffffffaa0e25b3 delay_halt.part.0+0x33 ffffffffc03f6188 mgag200_bmc_stop_scanout+0x178 ffffffffc087ae7a disable_outputs+0x12a ffffffffc087c12a drm_atomic_helper_commit_tail+0x1a ffffffffc03fa7b6 mgag200_mode_config_helper_atomic_commit_tail+0x26 ffffffffc087c9c1 commit_tail+0x91 ffffffffc087d51b drm_atomic_helper_commit+0x11b ffffffffc0509694 drm_atomic_commit+0xa4 ffffffffc05105e8 drm_client_modeset_commit_atomic+0x1e8 ffffffffc0510ce6 drm_client_modeset_commit_locked+0x56 ffffffffc0510e24 drm_client_modeset_commit+0x24 ffffffffc088a743 __drm_fb_helper_restore_fbdev_mode_unlocked+0x93 ffffffffc088a683 drm_fb_helper_hotplug_event+0xe3 ffffffffc050f8aa drm_client_dev_hotplug+0x9a ffffffffc088555a output_poll_execute+0x29a ffffffffa9b35924 process_one_work+0x194 ffffffffa9b364ee worker_thread+0x2fe ffffffffa9b3ecad kthread+0xdd ffffffffa9a08549 ret_from_fork+0x29 On a server running ptp4l with the mgag200 driver loaded, we found that ptp4l would sometimes get blocked from execution because of this busy waiting loop. Every so often, approximately once every 20 minutes -- though with large variance -- the output_poll_execute() thread would detect some sort of change that required performing a hotplug event which results in attempting to stop the BMC scanout, resulting in a 300msec delay on one CPU. On this system, ptp4l was pinned to a single CPU. When the output_poll_execute() thread ran on that CPU, it blocked ptp4l from executing for its 300 millisecond duration. This resulted in PTP service disruptions such as failure to send a SYNC message on time, failure to handle ANNOUNCE messages on time, and clock check warnings from the application. All of this despite the application being configured with FIFO_RT and a higher priority than the background workqueue tasks. (However, note that the kernel did not use CONFIG_PREEMPT...) It is unclear if the event is due to a faulty VGA connection, another bug, or actual events causing a change in the connection. At least on the system under test it is not a one-time event and consistently causes disruption to the time sensitive applications. The function has some helpful comments explaining what steps it is attempting to take. In particular, step 3a and 3b are explained as such: 3a - The third step is to verify if there is an active scan. We are waiting on a 0 on remhsyncsts (. 3b - This step occurs only if the remove is actually scanning. We are waiting for the end of the frame which is a 1 on remvsyncsts (). The actual steps 3a and 3b are implemented as while loops with a non-sleeping udelay(). The first step iterates while the tmp value at position 0 is *not* set. That is, it keeps iterating as long as the bit is zero. If the bit is already 0 (because there is no active scan), it will iterate the entire 300 attempts which wastes 300 milliseconds in total. This is opposite of what the description claims. The step 3b logic only executes if we do not iterate over the entire 300 attempts in the first loop. If it does trigger, it is trying to check and wait for a 1 on the remvsyncsts. However, again the condition is actually inverted and it will loop as long as the bit is 1, stopping once it hits zero (rather than the explained attempt to wait until we see a 1). Worse, both loops are implemented using non-sleeping waits which spin instead of allowing the scheduler to run other processes. If the kernel is not configured to allow arbitrary preemption, it will waste valuable CPU time doing nothing. There does not appear to be any documentation for the BMC register interface, beyond what is in the comments here. It seems more probable that the comment here is correct and the implementation accidentally got inverted from the intended logic. Reading through other DRM driver implementations, it does not appear that the .atomic_enable or .atomic_disable handlers need to delay instead of sleep. For example, the ast_astdp_encoder_helper_atomic_disable() function calls ast_dp_set_phy_sleep() which uses msleep(). The "atomic" in the name is referring to the atomic modesetting support, which is the support to enable atomic configuration from userspace, and not to the "atomic context" of the kernel. There is no reason to use udelay() here if a sleep would be sufficient. Replace the while loops with a read_poll_timeout() based implementation that will sleep between iterations, and which stops polling once the condition is met (instead of looping as long as the condition is met). This aligns with the commented behavior and avoids blocking on the CPU while doing nothing. Note the RREG_DAC is implemented using a statement expression to allow working properly with the read_poll_timeout family of functions. The other RREG_ macros ought to be cleaned up to have better semantics, and several places in the mgag200 driver could make use of RREG_DAC or similar RREG_* macros should likely be cleaned up for better semantics as well, but that task has been left as a future cleanup for a non-bugfix. Fixes: 414c45310625 ("mgag200: initial g200se driver (v2)") Suggested-by: Thomas Zimmermann Signed-off-by: Jacob Keller Reviewed-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Signed-off-by: Thomas Zimmermann Link: https://patch.msgid.link/20260202-jk-mgag200-fix-bad-udelay-v2-1-ce1e9665987d@intel.com Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/mgag200/mgag200_bmc.c | 31 +++++++++++---------------- drivers/gpu/drm/mgag200/mgag200_drv.h | 6 ++++++ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_bmc.c b/drivers/gpu/drm/mgag200/mgag200_bmc.c index 2ba2e3c5086a..852a82f6309b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_bmc.c +++ b/drivers/gpu/drm/mgag200/mgag200_bmc.c @@ -1,13 +1,14 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include #include "mgag200_drv.h" void mgag200_bmc_disable_vidrst(struct mga_device *mdev) { u8 tmp; - int iter_max; + int ret; /* * 1 - The first step is to inform the BMC of an upcoming mode @@ -37,30 +38,22 @@ void mgag200_bmc_disable_vidrst(struct mga_device *mdev) /* * 3a- The third step is to verify if there is an active scan. - * We are waiting for a 0 on remhsyncsts ). + * We are waiting for a 0 on remhsyncsts (). */ - iter_max = 300; - while (!(tmp & 0x1) && iter_max) { - WREG8(DAC_INDEX, MGA1064_SPAREREG); - tmp = RREG8(DAC_DATA); - udelay(1000); - iter_max--; - } + ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1), + 1000, 300000, false, + MGA1064_SPAREREG); + if (ret == -ETIMEDOUT) + return; /* - * 3b- This step occurs only if the remove is actually + * 3b- This step occurs only if the remote BMC is actually * scanning. We are waiting for the end of the frame which is * a 1 on remvsyncsts (XSPAREREG<1>) */ - if (iter_max) { - iter_max = 300; - while ((tmp & 0x2) && iter_max) { - WREG8(DAC_INDEX, MGA1064_SPAREREG); - tmp = RREG8(DAC_DATA); - udelay(1000); - iter_max--; - } - } + (void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2), + 1000, 300000, false, + MGA1064_SPAREREG); } void mgag200_bmc_enable_vidrst(struct mga_device *mdev) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 765e49fd8911..44281713db46 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -115,6 +115,12 @@ #define DAC_INDEX 0x3c00 #define DAC_DATA 0x3c0a +#define RREG_DAC(reg) \ + ({ \ + WREG8(DAC_INDEX, reg); \ + RREG8(DAC_DATA); \ + }) \ + #define WREG_DAC(reg, v) \ do { \ WREG8(DAC_INDEX, reg); \ -- Gitee From 3bc1cd7d05c81ad46c6059799f269896f472b3c7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 Feb 2026 00:34:36 +0800 Subject: [PATCH 1379/1449] hwmon: (occ) Mark occ_init_attribute() as __printf ANBZ: #35228 commit 8c934bafd10b968bc2be9ad83ab99710247ce251 stable. commit 831a2b27914cc880130ffe8fb8d1e65a5324d07f upstream. This is a printf-style function, which gcc -Werror=suggest-attribute=format correctly points out: drivers/hwmon/occ/common.c: In function 'occ_init_attribute': drivers/hwmon/occ/common.c:761:9: error: function 'occ_init_attribute' might be a candidate for 'gnu_printf' format attribute [-Werror=suggest-attribute=format] Add the attribute to avoid this warning and ensure any incorrect format strings are detected here. Fixes: 744c2fe950e9 ("hwmon: (occ) Rework attribute registration for stack usage") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20260203163440.2674340-1-arnd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/hwmon/occ/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c index 483f79b39429..755926fa0bf7 100644 --- a/drivers/hwmon/occ/common.c +++ b/drivers/hwmon/occ/common.c @@ -749,6 +749,7 @@ static ssize_t occ_show_extended(struct device *dev, * are dynamically allocated, we cannot use the existing kernel macros which * stringify the name argument. */ +__printf(7, 8) static void occ_init_attribute(struct occ_attribute *attr, int mode, ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf), ssize_t (*store)(struct device *dev, struct device_attribute *attr, -- Gitee From 85151a6737cb2dd29f95be6250b14f3a24f6c0c0 Mon Sep 17 00:00:00 2001 From: Andrew Fasano Date: Thu, 5 Feb 2026 00:46:58 +0800 Subject: [PATCH 1380/1449] netfilter: nf_tables: fix inverted genmask check in nft_map_catchall_activate() ANBZ: #35228 commit 42c574c1504aa089a0a142e4c13859327570473d stable. commit f41c5d151078c5348271ffaf8e7410d96f2d82f8 upstream. nft_map_catchall_activate() has an inverted element activity check compared to its non-catchall counterpart nft_mapelem_activate() and compared to what is logically required. nft_map_catchall_activate() is called from the abort path to re-activate catchall map elements that were deactivated during a failed transaction. It should skip elements that are already active (they don't need re-activation) and process elements that are inactive (they need to be restored). Instead, the current code does the opposite: it skips inactive elements and processes active ones. Compare the non-catchall activate callback, which is correct: nft_mapelem_activate(): if (nft_set_elem_active(ext, iter->genmask)) return 0; /* skip active, process inactive */ With the buggy catchall version: nft_map_catchall_activate(): if (!nft_set_elem_active(ext, genmask)) continue; /* skip inactive, process active */ The consequence is that when a DELSET operation is aborted, nft_setelem_data_activate() is never called for the catchall element. For NFT_GOTO verdict elements, this means nft_data_hold() is never called to restore the chain->use reference count. Each abort cycle permanently decrements chain->use. Once chain->use reaches zero, DELCHAIN succeeds and frees the chain while catchall verdict elements still reference it, resulting in a use-after-free. This is exploitable for local privilege escalation from an unprivileged user via user namespaces + nftables on distributions that enable CONFIG_USER_NS and CONFIG_NF_TABLES. Fix by removing the negation so the check matches nft_mapelem_activate(): skip active elements, process inactive ones. Fixes: 628bd3e49cba ("netfilter: nf_tables: drop map element references from preparation phase") Signed-off-by: Andrew Fasano Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index c00dd7dae5cb..120d9bd53321 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5608,7 +5608,7 @@ static void nft_map_catchall_activate(const struct nft_ctx *ctx, list_for_each_entry(catchall, &set->catchall_list, list) { ext = nft_set_elem_ext(set, catchall->elem); - if (!nft_set_elem_active(ext, genmask)) + if (nft_set_elem_active(ext, genmask)) continue; nft_clear(ctx->net, ext); -- Gitee From bb0f0b8fa7df4ae77c896d597064bf8ad8083e5b Mon Sep 17 00:00:00 2001 From: Shigeru Yoshida Date: Wed, 4 Feb 2026 17:58:37 +0800 Subject: [PATCH 1381/1449] ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF ANBZ: #35228 commit 50b7c7a255858a85c4636a1e990ca04591153dca stable. commit bbf4a17ad9ffc4e3d7ec13d73ecd59dea149ed25 upstream. syzbot reported a kernel BUG in fib6_add_rt2node() when adding an IPv6 route. [0] Commit f72514b3c569 ("ipv6: clear RA flags when adding a static route") introduced logic to clear RTF_ADDRCONF from existing routes when a static route with the same nexthop is added. However, this causes a problem when the existing route has a gateway. When RTF_ADDRCONF is cleared from a route that has a gateway, that route becomes eligible for ECMP, i.e. rt6_qualify_for_ecmp() returns true. The issue is that this route was never added to the fib6_siblings list. This leads to a mismatch between the following counts: - The sibling count computed by iterating fib6_next chain, which includes the newly ECMP-eligible route - The actual siblings in fib6_siblings list, which does not include that route When a subsequent ECMP route is added, fib6_add_rt2node() hits BUG_ON(sibling->fib6_nsiblings != rt->fib6_nsiblings) because the counts don't match. Fix this by only clearing RTF_ADDRCONF when the existing route does not have a gateway. Routes without a gateway cannot qualify for ECMP anyway (rt6_qualify_for_ecmp() requires fib_nh_gw_family), so clearing RTF_ADDRCONF on them is safe and matches the original intent of the commit. [0]: kernel BUG at net/ipv6/ip6_fib.c:1217! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 6010 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 RIP: 0010:fib6_add_rt2node+0x3433/0x3470 net/ipv6/ip6_fib.c:1217 [...] Call Trace: fib6_add+0x8da/0x18a0 net/ipv6/ip6_fib.c:1532 __ip6_ins_rt net/ipv6/route.c:1351 [inline] ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3946 ipv6_route_ioctl+0x35c/0x480 net/ipv6/route.c:4571 inet6_ioctl+0x219/0x280 net/ipv6/af_inet6.c:577 sock_do_ioctl+0xdc/0x300 net/socket.c:1245 sock_ioctl+0x576/0x790 net/socket.c:1366 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: f72514b3c569 ("ipv6: clear RA flags when adding a static route") Reported-by: syzbot+cb809def1baaac68ab92@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=cb809def1baaac68ab92 Tested-by: syzbot+cb809def1baaac68ab92@syzkaller.appspotmail.com Signed-off-by: Shigeru Yoshida Reviewed-by: Fernando Fernandez Mancera Link: https://patch.msgid.link/20260204095837.1285552-1-syoshida@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/ipv6/ip6_fib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 646ff1276aff..fe57884ca723 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1136,7 +1136,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, fib6_set_expires(iter, rt->expires); fib6_add_gc_list(iter); } - if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT))) { + if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) && + !iter->fib6_nh->fib_nh_gw_family) { iter->fib6_flags &= ~RTF_ADDRCONF; iter->fib6_flags &= ~RTF_PREFIX_RT; } -- Gitee From 4b60944c6b3a1df55d224ab6a95328cfbfb206b6 Mon Sep 17 00:00:00 2001 From: Chris Bainbridge Date: Tue, 3 Feb 2026 04:50:33 +0800 Subject: [PATCH 1382/1449] ASoC: amd: fix memory leak in acp3x pdm dma ops ANBZ: #35228 commit 0e0120214b5dcb0bf6b2171bb4e68e38968b2861 stable. commit 7f67ba5413f98d93116a756e7f17cd2c1d6c2bd6 upstream. Fixes: 4a767b1d039a8 ("ASoC: amd: add acp3x pdm driver dma ops") Signed-off-by: Chris Bainbridge Link: https://patch.msgid.link/20260202205034.7697-1-chris.bainbridge@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/amd/renoir/acp3x-pdm-dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c index c3b47e9bd239..39223ff37b14 100644 --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c @@ -301,9 +301,11 @@ static int acp_pdm_dma_close(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct pdm_dev_data *adata = dev_get_drvdata(component->dev); + struct pdm_stream_instance *rtd = substream->runtime->private_data; disable_pdm_interrupts(adata->acp_base); adata->capture_stream = NULL; + kfree(rtd); return 0; } -- Gitee From aa88ea157f3b4d152cb3eb0e8630186cc6649339 Mon Sep 17 00:00:00 2001 From: Boris Burkov Date: Thu, 2 Oct 2025 08:20:22 +0800 Subject: [PATCH 1383/1449] btrfs: fix racy bitfield write in btrfs_clear_space_info_full() ANBZ: #35228 commit d4a81b8ec639895999275ea2472c69825cd67ea4 stable. commit 38e818718c5e04961eea0fa8feff3f100ce40408 upstream. From the memory-barriers.txt document regarding memory barrier ordering guarantees: (*) These guarantees do not apply to bitfields, because compilers often generate code to modify these using non-atomic read-modify-write sequences. Do not attempt to use bitfields to synchronize parallel algorithms. (*) Even in cases where bitfields are protected by locks, all fields in a given bitfield must be protected by one lock. If two fields in a given bitfield are protected by different locks, the compiler's non-atomic read-modify-write sequences can cause an update to one field to corrupt the value of an adjacent field. btrfs_space_info has a bitfield sharing an underlying word consisting of the fields full, chunk_alloc, and flush: struct btrfs_space_info { struct btrfs_fs_info * fs_info; /* 0 8 */ struct btrfs_space_info * parent; /* 8 8 */ ... int clamp; /* 172 4 */ unsigned int full:1; /* 176: 0 4 */ unsigned int chunk_alloc:1; /* 176: 1 4 */ unsigned int flush:1; /* 176: 2 4 */ ... Therefore, to be safe from parallel read-modify-writes losing a write to one of the bitfield members protected by a lock, all writes to all the bitfields must use the lock. They almost universally do, except for btrfs_clear_space_info_full() which iterates over the space_infos and writes out found->full = 0 without a lock. Imagine that we have one thread completing a transaction in which we finished deleting a block_group and are thus calling btrfs_clear_space_info_full() while simultaneously the data reclaim ticket infrastructure is running do_async_reclaim_data_space(): T1 T2 btrfs_commit_transaction btrfs_clear_space_info_full data_sinfo->full = 0 READ: full:0, chunk_alloc:0, flush:1 do_async_reclaim_data_space(data_sinfo) spin_lock(&space_info->lock); if(list_empty(tickets)) space_info->flush = 0; READ: full: 0, chunk_alloc:0, flush:1 MOD/WRITE: full: 0, chunk_alloc:0, flush:0 spin_unlock(&space_info->lock); return; MOD/WRITE: full:0, chunk_alloc:0, flush:1 and now data_sinfo->flush is 1 but the reclaim worker has exited. This breaks the invariant that flush is 0 iff there is no work queued or running. Once this invariant is violated, future allocations that go into __reserve_bytes() will add tickets to space_info->tickets but will see space_info->flush is set to 1 and not queue the work. After this, they will block forever on the resulting ticket, as it is now impossible to kick the worker again. I also confirmed by looking at the assembly of the affected kernel that it is doing RMW operations. For example, to set the flush (3rd) bit to 0, the assembly is: andb $0xfb,0x60(%rbx) and similarly for setting the full (1st) bit to 0: andb $0xfe,-0x20(%rax) So I think this is really a bug on practical systems. I have observed a number of systems in this exact state, but am currently unable to reproduce it. Rather than leaving this footgun lying around for the future, take advantage of the fact that there is room in the struct anyway, and that it is already quite large and simply change the three bitfield members to bools. This avoids writes to space_info->full having any effect on writes to space_info->flush, regardless of locking. Fixes: 957780eb2788 ("Btrfs: introduce ticketed enospc infrastructure") Reviewed-by: Qu Wenruo Signed-off-by: Boris Burkov Reviewed-by: David Sterba Signed-off-by: David Sterba [ The context change is due to the commit cc0517fe779f ("btrfs: tweak extent/chunk allocation for space_info sub-space") in v6.16 which is irrelevant to the logic of this patch. ] Signed-off-by: Rahul Sharma Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/btrfs/block-group.c | 6 +++--- fs/btrfs/space-info.c | 22 +++++++++++----------- fs/btrfs/space-info.h | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 70680a7b9a7b..4725c28c702a 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -4158,7 +4158,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags, mutex_unlock(&fs_info->chunk_mutex); } else { /* Proceed with allocation */ - space_info->chunk_alloc = 1; + space_info->chunk_alloc = true; wait_for_alloc = false; spin_unlock(&space_info->lock); } @@ -4207,7 +4207,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags, spin_lock(&space_info->lock); if (ret < 0) { if (ret == -ENOSPC) - space_info->full = 1; + space_info->full = true; else goto out; } else { @@ -4217,7 +4217,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags, space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; out: - space_info->chunk_alloc = 0; + space_info->chunk_alloc = false; spin_unlock(&space_info->lock); mutex_unlock(&fs_info->chunk_mutex); diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 00d596a8176f..12f8f55bb993 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -182,7 +182,7 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info) struct btrfs_space_info *found; list_for_each_entry(found, head, list) - found->full = 0; + found->full = false; } /* @@ -361,7 +361,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, found->bytes_readonly += block_group->bytes_super; btrfs_space_info_update_bytes_zone_unusable(info, found, block_group->zone_unusable); if (block_group->length > 0) - found->full = 0; + found->full = false; btrfs_try_granting_tickets(info, found); spin_unlock(&found->lock); @@ -1103,7 +1103,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) spin_lock(&space_info->lock); to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info); if (!to_reclaim) { - space_info->flush = 0; + space_info->flush = false; spin_unlock(&space_info->lock); return; } @@ -1115,7 +1115,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) flush_space(fs_info, space_info, to_reclaim, flush_state, false); spin_lock(&space_info->lock); if (list_empty(&space_info->tickets)) { - space_info->flush = 0; + space_info->flush = false; spin_unlock(&space_info->lock); return; } @@ -1158,7 +1158,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work) flush_state = FLUSH_DELAYED_ITEMS_NR; commit_cycles--; } else { - space_info->flush = 0; + space_info->flush = false; } } else { flush_state = FLUSH_DELAYED_ITEMS_NR; @@ -1320,7 +1320,7 @@ static void btrfs_async_reclaim_data_space(struct work_struct *work) spin_lock(&space_info->lock); if (list_empty(&space_info->tickets)) { - space_info->flush = 0; + space_info->flush = false; spin_unlock(&space_info->lock); return; } @@ -1331,7 +1331,7 @@ static void btrfs_async_reclaim_data_space(struct work_struct *work) flush_space(fs_info, space_info, U64_MAX, ALLOC_CHUNK_FORCE, false); spin_lock(&space_info->lock); if (list_empty(&space_info->tickets)) { - space_info->flush = 0; + space_info->flush = false; spin_unlock(&space_info->lock); return; } @@ -1348,7 +1348,7 @@ static void btrfs_async_reclaim_data_space(struct work_struct *work) data_flush_states[flush_state], false); spin_lock(&space_info->lock); if (list_empty(&space_info->tickets)) { - space_info->flush = 0; + space_info->flush = false; spin_unlock(&space_info->lock); return; } @@ -1365,7 +1365,7 @@ static void btrfs_async_reclaim_data_space(struct work_struct *work) if (maybe_fail_all_tickets(fs_info, space_info)) flush_state = 0; else - space_info->flush = 0; + space_info->flush = false; } else { flush_state = 0; } @@ -1381,7 +1381,7 @@ static void btrfs_async_reclaim_data_space(struct work_struct *work) aborted_fs: maybe_fail_all_tickets(fs_info, space_info); - space_info->flush = 0; + space_info->flush = false; spin_unlock(&space_info->lock); } @@ -1750,7 +1750,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info, */ maybe_clamp_preempt(fs_info, space_info); - space_info->flush = 1; + space_info->flush = true; trace_btrfs_trigger_flush(fs_info, space_info->flags, orig_bytes, flush, diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h index 0670f074902d..6b93974a75a2 100644 --- a/fs/btrfs/space-info.h +++ b/fs/btrfs/space-info.h @@ -126,11 +126,11 @@ struct btrfs_space_info { flushing. The value is >> clamp, so turns out to be a 2^clamp divisor. */ - unsigned int full:1; /* indicates that we cannot allocate any more + bool full; /* indicates that we cannot allocate any more chunks for this space */ - unsigned int chunk_alloc:1; /* set if we are allocating a chunk */ + bool chunk_alloc; /* set if we are allocating a chunk */ - unsigned int flush:1; /* set if we are trying to make space */ + bool flush; /* set if we are trying to make space */ unsigned int force_alloc; /* set if we need to force a chunk alloc for this space */ -- Gitee From e2655324386ad4fe9bfddcd1b3b463dc5f6b6ee1 Mon Sep 17 00:00:00 2001 From: Max Yuan Date: Tue, 3 Feb 2026 03:39:25 +0800 Subject: [PATCH 1384/1449] gve: Correct ethtool rx_dropped calculation ANBZ: #35228 commit a168f2002b2b4a4c3dccef5fdbe94cf52021c362 stable. commit c7db85d579a1dccb624235534508c75fbf2dfe46 upstream. The gve driver's "rx_dropped" statistic, exposed via `ethtool -S`, incorrectly includes `rx_buf_alloc_fail` counts. These failures represent an inability to allocate receive buffers, not true packet drops where a received packet is discarded. This misrepresentation can lead to inaccurate diagnostics. This patch rectifies the ethtool "rx_dropped" calculation. It removes `rx_buf_alloc_fail` from the total and adds `xdp_tx_errors` and `xdp_redirect_errors`, which represent legitimate packet drops within the XDP path. Cc: stable@vger.kernel.org Fixes: 433e274b8f7b ("gve: Add stats for gve.") Signed-off-by: Max Yuan Reviewed-by: Jordan Rhee Reviewed-by: Joshua Washington Reviewed-by: Matt Olson Signed-off-by: Harshitha Ramamurthy Reviewed-by: Jacob Keller Link: https://patch.msgid.link/20260202193925.3106272-3-hramamurthy@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/ethernet/google/gve/gve_ethtool.c | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c index 59c509ade262..b1c4df3bab29 100644 --- a/drivers/net/ethernet/google/gve/gve_ethtool.c +++ b/drivers/net/ethernet/google/gve/gve_ethtool.c @@ -156,9 +156,11 @@ gve_get_ethtool_stats(struct net_device *netdev, { u64 tmp_rx_pkts, tmp_rx_bytes, tmp_rx_skb_alloc_fail, tmp_rx_buf_alloc_fail, tmp_rx_desc_err_dropped_pkt, - tmp_tx_pkts, tmp_tx_bytes; + tmp_tx_pkts, tmp_tx_bytes, + tmp_xdp_tx_errors, tmp_xdp_redirect_errors; u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_pkts, - rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, tx_dropped; + rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, tx_dropped, + xdp_tx_errors, xdp_redirect_errors; int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx; int stats_idx, stats_region_len, nic_stats_len; struct stats *report_stats; @@ -187,7 +189,9 @@ gve_get_ethtool_stats(struct net_device *netdev, return; } for (rx_pkts = 0, rx_bytes = 0, rx_skb_alloc_fail = 0, - rx_buf_alloc_fail = 0, rx_desc_err_dropped_pkt = 0, ring = 0; + rx_buf_alloc_fail = 0, rx_desc_err_dropped_pkt = 0, + xdp_tx_errors = 0, xdp_redirect_errors = 0, + ring = 0; ring < priv->rx_cfg.num_queues; ring++) { if (priv->rx) { do { @@ -201,6 +205,9 @@ gve_get_ethtool_stats(struct net_device *netdev, tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; tmp_rx_desc_err_dropped_pkt = rx->rx_desc_err_dropped_pkt; + tmp_xdp_tx_errors = rx->xdp_tx_errors; + tmp_xdp_redirect_errors = + rx->xdp_redirect_errors; } while (u64_stats_fetch_retry(&priv->rx[ring].statss, start)); rx_pkts += tmp_rx_pkts; @@ -208,6 +215,8 @@ gve_get_ethtool_stats(struct net_device *netdev, rx_skb_alloc_fail += tmp_rx_skb_alloc_fail; rx_buf_alloc_fail += tmp_rx_buf_alloc_fail; rx_desc_err_dropped_pkt += tmp_rx_desc_err_dropped_pkt; + xdp_tx_errors += tmp_xdp_tx_errors; + xdp_redirect_errors += tmp_xdp_redirect_errors; } } for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0; @@ -232,8 +241,8 @@ gve_get_ethtool_stats(struct net_device *netdev, data[i++] = rx_bytes; data[i++] = tx_bytes; /* total rx dropped packets */ - data[i++] = rx_skb_alloc_fail + rx_buf_alloc_fail + - rx_desc_err_dropped_pkt; + data[i++] = rx_skb_alloc_fail + rx_desc_err_dropped_pkt + + xdp_tx_errors + xdp_redirect_errors; data[i++] = tx_dropped; data[i++] = priv->tx_timeo_cnt; data[i++] = rx_skb_alloc_fail; @@ -300,6 +309,9 @@ gve_get_ethtool_stats(struct net_device *netdev, tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; tmp_rx_desc_err_dropped_pkt = rx->rx_desc_err_dropped_pkt; + tmp_xdp_tx_errors = rx->xdp_tx_errors; + tmp_xdp_redirect_errors = + rx->xdp_redirect_errors; } while (u64_stats_fetch_retry(&priv->rx[ring].statss, start)); data[i++] = tmp_rx_bytes; @@ -309,8 +321,9 @@ gve_get_ethtool_stats(struct net_device *netdev, data[i++] = rx->rx_frag_alloc_cnt; /* rx dropped packets */ data[i++] = tmp_rx_skb_alloc_fail + - tmp_rx_buf_alloc_fail + - tmp_rx_desc_err_dropped_pkt; + tmp_rx_desc_err_dropped_pkt + + tmp_xdp_tx_errors + + tmp_xdp_redirect_errors; data[i++] = rx->rx_copybreak_pkt; data[i++] = rx->rx_copied_pkt; /* stats from NIC */ -- Gitee From a4105cfb40079c0058181879ad6c0db64b954b55 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Mon, 2 Feb 2026 23:15:09 +0800 Subject: [PATCH 1385/1449] spi: tegra: Fix a memory leak in tegra_slink_probe() ANBZ: #35228 commit 126a09f4fcd2b895a818ca43fde078d907c1ac9a stable. commit 41d9a6795b95d6ea28439ac1e9ce8c95bbca20fc upstream. In tegra_slink_probe(), when platform_get_irq() fails, it directly returns from the function with an error code, which causes a memory leak. Replace it with a goto label to ensure proper cleanup. Fixes: eb9913b511f1 ("spi: tegra: Fix missing IRQ check in tegra_slink_probe()") Signed-off-by: Felix Gu Reviewed-by: Jon Hunter Link: https://patch.msgid.link/20260202-slink-v1-1-eac50433a6f9@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-tegra20-slink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index f5cd365c913a..f450409156c6 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -1086,8 +1086,10 @@ static int tegra_slink_probe(struct platform_device *pdev) reset_control_deassert(tspi->rst); spi_irq = platform_get_irq(pdev, 0); - if (spi_irq < 0) - return spi_irq; + if (spi_irq < 0) { + ret = spi_irq; + goto exit_pm_put; + } tspi->irq = spi_irq; ret = request_threaded_irq(tspi->irq, tegra_slink_isr, tegra_slink_isr_thread, IRQF_ONESHOT, -- Gitee From 60aaf2f7ae76b30517dccdb328cfc859d308e288 Mon Sep 17 00:00:00 2001 From: Vishwaroop A Date: Wed, 4 Feb 2026 22:12:12 +0800 Subject: [PATCH 1386/1449] spi: tegra114: Preserve SPI mode bits in def_command1_reg ANBZ: #35228 commit d0a6e43d7ccccf19374e9e140cd86f7b74a7e5e2 stable. commit a0a75b40c919b9f6d3a0b6c978e6ccf344c1be5a upstream. The COMMAND1 register bits [29:28] set the SPI mode, which controls the clock idle level. When a transfer ends, tegra_spi_transfer_end() writes def_command1_reg back to restore the default state, but this register value currently lacks the mode bits. This results in the clock always being configured as idle low, breaking devices that need it high. Fix this by storing the mode bits in def_command1_reg during setup, to prevent this field from always being cleared. Fixes: f333a331adfa ("spi/tegra114: add spi driver") Signed-off-by: Vishwaroop A Link: https://patch.msgid.link/20260204141212.1540382-1-va@nvidia.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-tegra114.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 8d7ce4c556aa..c99f72c9ab17 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -978,11 +978,14 @@ static int tegra_spi_setup(struct spi_device *spi) if (spi_get_csgpiod(spi, 0)) gpiod_set_value(spi_get_csgpiod(spi, 0), 0); + /* Update default register to include CS polarity and SPI mode */ val = tspi->def_command1_reg; if (spi->mode & SPI_CS_HIGH) val &= ~SPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0)); else val |= SPI_CS_POL_INACTIVE(spi_get_chipselect(spi, 0)); + val &= ~SPI_CONTROL_MODE_MASK; + val |= SPI_MODE_SEL(spi->mode & 0x3); tspi->def_command1_reg = val; tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); spin_unlock_irqrestore(&tspi->lock, flags); -- Gitee From 0bd03c33165c217b85ae1e7c30f3389a8392fc44 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Sat, 24 Jan 2026 06:12:24 +0800 Subject: [PATCH 1387/1449] ALSA: hda/realtek: Really fix headset mic for TongFang X6AR55xU. ANBZ: #35228 commit 23897ece6167cab657b1129c6d62fee460d9819f stable. commit 1aaedafb21f38cb872d44f7608b4828a1e14e795 upstream. Add a PCI quirk to enable microphone detection on the headphone jack of TongFang X6AR55xU devices. The former quirk entry did not acomplish this and is removed. Fixes: b48fe9af1e60 ("ALSA: hda/realtek: Fix headset mic for TongFang X6AR55xU") Signed-off-by: Tim Guttzeit Signed-off-by: Werner Sembach Link: https://patch.msgid.link/20260123221233.28273-1-wse@tuxedocomputers.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/hda/patch_realtek.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 908672bab29e..c60358a4a757 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10640,6 +10640,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1d05, 0x1409, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1d05, 0x300f, "TongFang X6AR5xxY", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1d05, 0x3019, "TongFang X6FR5xxY", ALC2XX_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1d05, 0x3031, "TongFang X6AR55xU", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1d17, 0x3288, "Haier Boyue G42", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS), SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), @@ -11101,10 +11102,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60140}, {0x19, 0x04a11030}, {0x21, 0x04211020}), - SND_HDA_PIN_QUIRK(0x10ec0274, 0x1d05, "TongFang", ALC274_FIXUP_HP_HEADSET_MIC, - {0x17, 0x90170110}, - {0x19, 0x03a11030}, - {0x21, 0x03211020}), SND_HDA_PIN_QUIRK(0x10ec0282, 0x1025, "Acer", ALC282_FIXUP_ACER_DISABLE_LINEOUT, ALC282_STANDARD_PINS, {0x12, 0x90a609c0}, -- Gitee From 151b4c720ab510c88b7a84b257c6cf9c332167d5 Mon Sep 17 00:00:00 2001 From: Henrique Carvalho Date: Wed, 28 Jan 2026 00:01:28 +0800 Subject: [PATCH 1388/1449] smb: client: split cached_fid bitfields to avoid shared-byte RMW races MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 4386f6af8aaedd0c5ad6f659b40cadcc8f423828 stable. commit ec306600d5ba7148c9dbf8f5a8f1f5c1a044a241 upstream. is_open, has_lease and on_list are stored in the same bitfield byte in struct cached_fid but are updated in different code paths that may run concurrently. Bitfield assignments generate byte read–modify–write operations (e.g. `orb $mask, addr` on x86_64), so updating one flag can restore stale values of the others. A possible interleaving is: CPU1: load old byte (has_lease=1, on_list=1) CPU2: clear both flags (store 0) CPU1: RMW store (old | IS_OPEN) -> reintroduces cleared bits To avoid this class of races, convert these flags to separate bool fields. Cc: stable@vger.kernel.org Fixes: ebe98f1447bbc ("cifs: enable caching of directories for which a lease is held") Signed-off-by: Henrique Carvalho Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/client/cached_dir.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index bc8a812ff95f..96697c78b3a6 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -34,10 +34,10 @@ struct cached_fid { struct list_head entry; struct cached_fids *cfids; const char *path; - bool has_lease:1; - bool is_open:1; - bool on_list:1; - bool file_all_info_is_valid:1; + bool has_lease; + bool is_open; + bool on_list; + bool file_all_info_is_valid; unsigned long time; /* jiffies of when lease was taken */ struct kref refcount; struct cifs_fid fid; -- Gitee From b686ede79f6e43b0233eb88c9585a1595af3d27c Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sat, 24 Jan 2026 09:55:46 +0800 Subject: [PATCH 1389/1449] ksmbd: fix infinite loop caused by next_smb2_rcv_hdr_off reset in error paths ANBZ: #35228 commit 5accdc5b7f28a81bbc5880ac0b8886e60c86e8c8 stable. commit 010eb01ce23b34b50531448b0da391c7f05a72af upstream. The problem occurs when a signed request fails smb2 signature verification check. In __process_request(), if check_sign_req() returns an error, set_smb2_rsp_status(work, STATUS_ACCESS_DENIED) is called. set_smb2_rsp_status() set work->next_smb2_rcv_hdr_off as zero. By resetting next_smb2_rcv_hdr_off to zero, the pointer to the next command in the chain is lost. Consequently, is_chained_smb2_message() continues to point to the same request header instead of advancing. If the header's NextCommand field is non-zero, the function returns true, causing __handle_ksmbd_work() to repeatedly process the same failed request in an infinite loop. This results in the kernel log being flooded with "bad smb2 signature" messages and high CPU usage. This patch fixes the issue by changing the return value from SERVER_HANDLER_CONTINUE to SERVER_HANDLER_ABORT. This ensures that the processing loop terminates immediately rather than attempting to continue from an invalidated offset. Reported-by: tianshuo han Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c index 80050b217898..598601a4bf92 100644 --- a/fs/smb/server/server.c +++ b/fs/smb/server/server.c @@ -126,21 +126,21 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, andx_again: if (command >= conn->max_cmds) { conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); - return SERVER_HANDLER_CONTINUE; + return SERVER_HANDLER_ABORT; } cmds = &conn->cmds[command]; if (!cmds->proc) { ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command); conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED); - return SERVER_HANDLER_CONTINUE; + return SERVER_HANDLER_ABORT; } if (work->sess && conn->ops->is_sign_req(work, command)) { ret = conn->ops->check_sign_req(work); if (!ret) { conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED); - return SERVER_HANDLER_CONTINUE; + return SERVER_HANDLER_ABORT; } } -- Gitee From 9f36b5ae8ea634cad1dd530f4765e193744b530b Mon Sep 17 00:00:00 2001 From: Henrique Carvalho Date: Thu, 5 Feb 2026 07:06:43 +0800 Subject: [PATCH 1390/1449] smb: server: fix leak of active_num_conn in ksmbd_tcp_new_connection() ANBZ: #35228 commit 787769c8cc50416af7b8b1a36e6bcd6aaa7680aa stable. commit 77ffbcac4e569566d0092d5f22627dfc0896b553 upstream. On kthread_run() failure in ksmbd_tcp_new_connection(), the transport is freed via free_transport(), which does not decrement active_num_conn, leaking this counter. Replace free_transport() with ksmbd_tcp_disconnect(). Fixes: 0d0d4680db22e ("ksmbd: add max connections parameter") Cc: stable@vger.kernel.org Signed-off-by: Henrique Carvalho Acked-by: Namjae Jeon Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/smb/server/transport_tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c index 08275db6446c..d05af46257cf 100644 --- a/fs/smb/server/transport_tcp.c +++ b/fs/smb/server/transport_tcp.c @@ -41,6 +41,7 @@ static struct ksmbd_transport_ops ksmbd_tcp_transport_ops; static void tcp_stop_kthread(struct task_struct *kthread); static struct interface *alloc_iface(char *ifname); +static void ksmbd_tcp_disconnect(struct ksmbd_transport *t); #define KSMBD_TRANS(t) (&(t)->transport) #define TCP_TRANS(t) ((struct tcp_transport *)container_of(t, \ @@ -219,7 +220,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) if (IS_ERR(handler)) { pr_err("cannot start conn thread\n"); rc = PTR_ERR(handler); - free_transport(t); + ksmbd_tcp_disconnect(KSMBD_TRANS(t)); } return rc; -- Gitee From 097e84ebbb6f1a4c0ca5927ff58e17aa494685cf Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Wed, 14 Jan 2026 00:28:43 +0800 Subject: [PATCH 1391/1449] driver core: enforce device_lock for driver_match_device() ANBZ: #35228 commit adc1796eced46b48e23ec200a219d635f33a38ee stable. commit dc23806a7c47ec5f1293aba407fb69519f976ee0 upstream. Currently, driver_match_device() is called from three sites. One site (__device_attach_driver) holds device_lock(dev), but the other two (bind_store and __driver_attach) do not. This inconsistency means that bus match() callbacks are not guaranteed to be called with the lock held. Fix this by introducing driver_match_device_locked(), which guarantees holding the device lock using a scoped guard. Replace the unlocked calls in bind_store() and __driver_attach() with this new helper. Also add a lock assertion to driver_match_device() to enforce this guarantee. This consistency also fixes a known race condition. The driver_override implementation relies on the device_lock, so the missing lock led to the use-after-free (UAF) reported in Bugzilla for buses using this field. Stress testing the two newly locked paths for 24 hours with CONFIG_PROVE_LOCKING and CONFIG_LOCKDEP enabled showed no UAF recurrence and no lockdep warnings. Cc: stable@vger.kernel.org Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 Suggested-by: Qiu-ji Chen Signed-off-by: Gui-Dong Han Fixes: 49b420a13ff9 ("driver core: check bus->match without holding device lock") Reviewed-by: Danilo Krummrich Reviewed-by: Greg Kroah-Hartman Reviewed-by: Rafael J. Wysocki (Intel) Link: https://patch.msgid.link/20260113162843.12712-1-hanguidong02@gmail.com Signed-off-by: Danilo Krummrich Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/base/base.h | 9 +++++++++ drivers/base/bus.c | 2 +- drivers/base/dd.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 0b491449b022..35e14bebbfb2 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -165,9 +165,18 @@ void device_set_deferred_probe_reason(const struct device *dev, struct va_format static inline int driver_match_device(struct device_driver *drv, struct device *dev) { + device_lock_assert(dev); + return drv->bus->match ? drv->bus->match(dev, drv) : 1; } +static inline int driver_match_device_locked(struct device_driver *drv, + struct device *dev) +{ + guard(device)(dev); + return driver_match_device(drv, dev); +} + static inline void dev_sync_state(struct device *dev) { if (dev->bus->sync_state) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index b97e13a52c33..27f8442a3aa9 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -263,7 +263,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, int err = -ENODEV; dev = bus_find_device_by_name(bus, NULL, buf); - if (dev && driver_match_device(drv, dev)) { + if (dev && driver_match_device_locked(drv, dev)) { err = device_driver_attach(drv, dev); if (!err) { /* success */ diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 7e2fb159bb89..07f1332dd3a4 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1169,7 +1169,7 @@ static int __driver_attach(struct device *dev, void *data) * is an error. */ - ret = driver_match_device(drv, dev); + ret = driver_match_device_locked(drv, dev); if (ret == 0) { /* no match */ return 0; -- Gitee From 5f940c9e2c992b6452f1f9a77fb9956b9b5325d2 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Thu, 29 Jan 2026 10:28:19 +0800 Subject: [PATCH 1392/1449] Bluetooth: btusb: Add USB ID 7392:e611 for Edimax EW-7611UXB ANBZ: #35228 commit 6dda9f06990544206289a8fa8524ae519a486f67 stable. commit 6c0568b7741a346088fd6dfced2d871f7d481d06 upstream. Add USB ID 7392:e611 for Edimax EW-7611UXB which is RTL8851BU-based Wi-Fi + Bluetooth adapter. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below: T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=7392 ProdID=e611 Rev= 0.00 S: Manufacturer=Realtek S: Product=802.11ax WLAN Adapter S: SerialNumber=00e04c000001 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 8 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtw89_8851bu_git E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Cc: stable@vger.kernel.org # 6.6.x Signed-off-by: Zenm Chen Reviewed-by: Paul Menzel Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c36394f0dd79..b5c2661db258 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -516,6 +516,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x2001, 0x332a), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8852AE Bluetooth devices */ { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK | -- Gitee From ea46d97dffd25f22552a0c67b0f947c367e39541 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Wed, 26 Nov 2025 17:46:13 +0800 Subject: [PATCH 1393/1449] crypto: octeontx - Fix length check to avoid truncation in ucode_load_store ANBZ: #35228 commit 7dbeeafcb6e50d201b016599d1dcb576fbecfead stable. commit 5565a72b24fa7935a9f30af386e92c8c9dfb23b9 upstream. OTX_CPT_UCODE_NAME_LENGTH limits the microcode name to 64 bytes. If a user writes a string of exactly 64 characters, the original code used 'strlen(buf) > 64' to check the length, but then strscpy() copies only 63 characters before adding a NUL terminator, silently truncating the copied string. Fix this off-by-one error by using 'count' directly for the length check to ensure long names are rejected early and copied without truncation. Cc: stable@vger.kernel.org Fixes: d9110b0b01ff ("crypto: marvell - add support for OCTEON TX CPT engine") Signed-off-by: Thorsten Blum Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c index 2c08e928e44e..c9fb10e5df45 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c @@ -1337,7 +1337,7 @@ static ssize_t ucode_load_store(struct device *dev, int del_grp_idx = -1; int ucode_idx = 0; - if (strlen(buf) > OTX_CPT_UCODE_NAME_LENGTH) + if (count >= OTX_CPT_UCODE_NAME_LENGTH) return -EINVAL; eng_grps = container_of(attr, struct otx_cpt_eng_grps, ucode_load_attr); -- Gitee From 9251dafd21d42edcf961c67cf2bd34e01c08f51c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 7 Feb 2026 11:49:54 +0800 Subject: [PATCH 1394/1449] crypto: omap - Allocate OMAP_CRYPTO_FORCE_COPY scatterlists correctly ANBZ: #35228 commit 6edf8df4bd29f7bfd245b67b2c31d905f1cfc14b stable. commit 1562b1fb7e17c1b3addb15e125c718b2be7f5512 upstream. The existing allocation of scatterlists in omap_crypto_copy_sg_lists() was allocating an array of scatterlist pointers, not scatterlist objects, resulting in a 4x too small allocation. Use sizeof(*new_sg) to get the correct object size. Fixes: 74ed87e7e7f7 ("crypto: omap - add base support library for common routines") Signed-off-by: Kees Cook Acked-by: Herbert Xu Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/omap-crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/omap-crypto.c b/drivers/crypto/omap-crypto.c index a4cc6bf146ec..0345c9383d50 100644 --- a/drivers/crypto/omap-crypto.c +++ b/drivers/crypto/omap-crypto.c @@ -21,7 +21,7 @@ static int omap_crypto_copy_sg_lists(int total, int bs, struct scatterlist *tmp; if (!(flags & OMAP_CRYPTO_FORCE_SINGLE_ENTRY)) { - new_sg = kmalloc_array(n, sizeof(*sg), GFP_KERNEL); + new_sg = kmalloc_array(n, sizeof(*new_sg), GFP_KERNEL); if (!new_sg) return -ENOMEM; -- Gitee From 0bd31c9ea4792afaf2bc4b4754ebb1594e05df30 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Tue, 13 Jan 2026 11:05:54 +0800 Subject: [PATCH 1395/1449] crypto: virtio - Add spinlock protection with virtqueue notification ANBZ: #35228 commit d6f0d586808689963e58fd739bed626ff5013b24 stable. commit b505047ffc8057555900d2d3a005d033e6967382 upstream. When VM boots with one virtio-crypto PCI device and builtin backend, run openssl benchmark command with multiple processes, such as openssl speed -evp aes-128-cbc -engine afalg -seconds 10 -multi 32 openssl processes will hangup and there is error reported like this: virtio_crypto virtio0: dataq.0:id 3 is not a head! It seems that the data virtqueue need protection when it is handled for virtio done notification. If the spinlock protection is added in virtcrypto_done_task(), openssl benchmark with multiple processes works well. Fixes: fed93fb62e05 ("crypto: virtio - Handle dataq logic with tasklet") Cc: stable@vger.kernel.org Signed-off-by: Bibo Mao Acked-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/virtio/virtio_crypto_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c index b909c6a2bf1c..6ec9a95b4db0 100644 --- a/drivers/crypto/virtio/virtio_crypto_core.c +++ b/drivers/crypto/virtio/virtio_crypto_core.c @@ -77,15 +77,20 @@ static void virtcrypto_done_task(unsigned long data) struct data_queue *data_vq = (struct data_queue *)data; struct virtqueue *vq = data_vq->vq; struct virtio_crypto_request *vc_req; + unsigned long flags; unsigned int len; + spin_lock_irqsave(&data_vq->lock, flags); do { virtqueue_disable_cb(vq); while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) { + spin_unlock_irqrestore(&data_vq->lock, flags); if (vc_req->alg_cb) vc_req->alg_cb(vc_req, len); + spin_lock_irqsave(&data_vq->lock, flags); } } while (!virtqueue_enable_cb(vq)); + spin_unlock_irqrestore(&data_vq->lock, flags); } static void virtcrypto_dataq_callback(struct virtqueue *vq) -- Gitee From 730e89953fd5ac524183246639d024ecca8217d3 Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Tue, 13 Jan 2026 11:05:55 +0800 Subject: [PATCH 1396/1449] crypto: virtio - Remove duplicated virtqueue_kick in virtio_crypto_skcipher_crypt_req ANBZ: #35228 commit dd1f6c920638577a5d68629e31e2676757813ddb stable. commit 14f86a1155cca1176abf55987b2fce7f7fcb2455 upstream. With function virtio_crypto_skcipher_crypt_req(), there is already virtqueue_kick() call with spinlock held in function __virtio_crypto_skcipher_do_req(). Remove duplicated virtqueue_kick() function call here. Fixes: d79b5d0bbf2e ("crypto: virtio - support crypto engine framework") Cc: stable@vger.kernel.org Signed-off-by: Bibo Mao Acked-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/crypto/virtio/virtio_crypto_skcipher_algs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c index 23c41d87d835..487f60e35df1 100644 --- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c +++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c @@ -550,8 +550,6 @@ int virtio_crypto_skcipher_crypt_req( if (ret < 0) return ret; - virtqueue_kick(data_vq->vq); - return 0; } -- Gitee From cb6b71bc276687ddfab85e7e5895a82427e786fa Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Sat, 20 Dec 2025 02:04:25 +0800 Subject: [PATCH 1397/1449] nilfs2: Fix potential block overflow that cause system hang ANBZ: #35228 commit df1e20796c9f3d541cca47fb72e4369ea135642d stable. commit ed527ef0c264e4bed6c7b2a158ddf516b17f5f66 upstream. When a user executes the FITRIM command, an underflow can occur when calculating nblocks if end_block is too small. Since nblocks is of type sector_t, which is u64, a negative nblocks value will become a very large positive integer. This ultimately leads to the block layer function __blkdev_issue_discard() taking an excessively long time to process the bio chain, and the ns_segctor_sem lock remains held for a long period. This prevents other tasks from acquiring the ns_segctor_sem lock, resulting in the hang reported by syzbot in [1]. If the ending block is too small, typically if it is smaller than 4KiB range, depending on the usage of the segment 0, it may be possible to attempt a discard request beyond the device size causing the hang. Exiting successfully and assign the discarded size (0 in this case) to range->len. Although the start and len values in the user input range are too small, a conservative strategy is adopted here to safely ignore them, which is equivalent to a no-op; it will not perform any trimming and will not throw an error. [1] task:segctord state:D stack:28968 pid:6093 tgid:6093 ppid:2 task_flags:0x200040 flags:0x00080000 Call Trace: rwbase_write_lock+0x3dd/0x750 kernel/locking/rwbase_rt.c:272 nilfs_transaction_lock+0x253/0x4c0 fs/nilfs2/segment.c:357 nilfs_segctor_thread_construct fs/nilfs2/segment.c:2569 [inline] nilfs_segctor_thread+0x6ec/0xe00 fs/nilfs2/segment.c:2684 [ryusuke: corrected part of the commit message about the consequences] Fixes: 82e11e857be3 ("nilfs2: add nilfs_sufile_trim_fs to trim clean segs") Reported-by: syzbot+7eedce5eb281acd832f0@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=7eedce5eb281acd832f0 Signed-off-by: Edward Adam Davis Signed-off-by: Ryusuke Konishi Cc: stable@vger.kernel.org Signed-off-by: Viacheslav Dubeyko Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nilfs2/sufile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 58ca7c936393..aa39cdce5993 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c @@ -1091,6 +1091,9 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct fstrim_range *range) else end_block = start_block + len - 1; + if (end_block < nilfs->ns_first_data_block) + goto out; + segnum = nilfs_get_segnum_of_block(nilfs, start_block); segnum_end = nilfs_get_segnum_of_block(nilfs, end_block); @@ -1188,6 +1191,7 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct fstrim_range *range) out_sem: up_read(&NILFS_MDT(sufile)->mi_sem); +out: range->len = ndiscarded << nilfs->ns_blocksize_bits; return ret; } -- Gitee From 6acdaeb3c6f70122116ca67390d166e9f697ed9a Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Wed, 24 Dec 2025 07:24:21 +0800 Subject: [PATCH 1398/1449] wifi: rtw88: Fix alignment fault in rtw_core_enable_beacon() ANBZ: #35228 commit 71dee092903adb496fe1f357b267d94087b679e0 stable. commit 0177aa828d966117ea30a44f2e1890fdb356118e upstream. rtw_core_enable_beacon() reads 4 bytes from an address that is not a multiple of 4. This results in a crash on some systems. Do 1 byte reads/writes instead. Unable to handle kernel paging request at virtual address ffff8000827e0522 Mem abort info: ESR = 0x0000000096000021 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x21: alignment fault Data abort info: ISV = 0, ISS = 0x00000021, ISS2 = 0x00000000 CM = 0, WnR = 0, TnD = 0, TagAccess = 0 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000005492000 [ffff8000827e0522] pgd=0000000000000000, p4d=10000001021d9403, pud=10000001021da403, pmd=100000011061c403, pte=00780000f3200f13 Internal error: Oops: 0000000096000021 [#1] SMP Modules linked in: [...] rtw88_8822ce rtw88_8822c rtw88_pci rtw88_core [...] CPU: 0 UID: 0 PID: 73 Comm: kworker/u32:2 Tainted: G W 6.17.9 #1-NixOS VOLUNTARY Tainted: [W]=WARN Hardware name: FriendlyElec NanoPC-T6 LTS (DT) Workqueue: phy0 rtw_c2h_work [rtw88_core] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : rtw_pci_read32+0x18/0x40 [rtw88_pci] lr : rtw_core_enable_beacon+0xe0/0x148 [rtw88_core] sp : ffff800080cc3ca0 x29: ffff800080cc3ca0 x28: ffff0001031fc240 x27: ffff000102100828 x26: ffffd2cb7c9b4088 x25: ffff0001031fc2c0 x24: ffff000112fdef00 x23: ffff000112fdef18 x22: ffff000111c29970 x21: 0000000000000001 x20: 0000000000000001 x19: ffff000111c22040 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000000 x10: 0000000000000000 x9 : ffffd2cb6507c090 x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000 x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 x2 : 0000000000007f10 x1 : 0000000000000522 x0 : ffff8000827e0522 Call trace: rtw_pci_read32+0x18/0x40 [rtw88_pci] (P) rtw_hw_scan_chan_switch+0x124/0x1a8 [rtw88_core] rtw_fw_c2h_cmd_handle+0x254/0x290 [rtw88_core] rtw_c2h_work+0x50/0x98 [rtw88_core] process_one_work+0x178/0x3f8 worker_thread+0x208/0x418 kthread+0x120/0x220 ret_from_fork+0x10/0x20 Code: d28fe202 8b020000 f9524400 8b214000 (b9400000) ---[ end trace 0000000000000000 ]--- Fixes: ad6741b1e044 ("wifi: rtw88: Stop high queue during scan") Cc: stable@vger.kernel.org Closes: https://github.com/lwfinger/rtw88/issues/418 Signed-off-by: Bitterblue Smith Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/6345300d-8c93-464c-9b05-d0d9af3c97ad@gmail.com Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/wireless/realtek/rtw88/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 0d0b5123b5fe..c7396ae9256b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -2401,10 +2401,10 @@ void rtw_core_enable_beacon(struct rtw_dev *rtwdev, bool enable) if (enable) { rtw_write32_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); - rtw_write32_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); + rtw_write8_clr(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); } else { rtw_write32_clr(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); - rtw_write32_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); + rtw_write8_set(rtwdev, REG_TXPAUSE, BIT_HIGH_QUEUE); } } -- Gitee From 19d4b02e1f38ce8f44acc5e783d96b1b475327c3 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 18:16:01 +0800 Subject: [PATCH 1399/1449] scsi: qla2xxx: Validate sp before freeing associated memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 949010291bb941d53733ed08a33454254d9afb1b stable. commit b6df15aec8c3441357d4da0eaf4339eb20f5999f upstream. System crash with the following signature [154563.214890] nvme nvme2: NVME-FC{1}: controller connect complete [154564.169363] qla2xxx [0000:b0:00.1]-3002:2: nvme: Sched: Set ZIO exchange threshold to 3. [154564.169405] qla2xxx [0000:b0:00.1]-ffffff:2: SET ZIO Activity exchange threshold to 5. [154565.539974] qla2xxx [0000:b0:00.1]-5013:2: RSCN database changed – 0078 0080 0000. [154565.545744] qla2xxx [0000:b0:00.1]-5013:2: RSCN database changed – 0078 00a0 0000. [154565.545857] qla2xxx [0000:b0:00.1]-11a2:2: FEC=enabled (data rate). [154565.552760] qla2xxx [0000:b0:00.1]-11a2:2: FEC=enabled (data rate). [154565.553079] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [154565.553080] #PF: supervisor read access in kernel mode [154565.553082] #PF: error_code(0x0000) - not-present page [154565.553084] PGD 80000010488ab067 P4D 80000010488ab067 PUD 104978a067 PMD 0 [154565.553089] Oops: 0000 1 PREEMPT SMP PTI [154565.553092] CPU: 10 PID: 858 Comm: qla2xxx_2_dpc Kdump: loaded Tainted: G OE ------- --- 5.14.0-503.11.1.el9_5.x86_64 #1 [154565.553096] Hardware name: HPE Synergy 660 Gen10/Synergy 660 Gen10 Compute Module, BIOS I43 09/30/2024 [154565.553097] RIP: 0010:qla_fab_async_scan.part.0+0x40b/0x870 [qla2xxx] [154565.553141] Code: 00 00 e8 58 a3 ec d4 49 89 e9 ba 12 20 00 00 4c 89 e6 49 c7 c0 00 ee a8 c0 48 c7 c1 66 c0 a9 c0 bf 00 80 00 10 e8 15 69 00 00 <4c> 8b 8d f8 00 00 00 4d 85 c9 74 35 49 8b 84 24 00 19 00 00 48 8b [154565.553143] RSP: 0018:ffffb4dbc8aebdd0 EFLAGS: 00010286 [154565.553145] RAX: 0000000000000000 RBX: ffff8ec2cf0908d0 RCX: 0000000000000002 [154565.553147] RDX: 0000000000000000 RSI: ffffffffc0a9c896 RDI: ffffb4dbc8aebd47 [154565.553148] RBP: 0000000000000000 R08: ffffb4dbc8aebd45 R09: 0000000000ffff0a [154565.553150] R10: 0000000000000000 R11: 000000000000000f R12: ffff8ec2cf0908d0 [154565.553151] R13: ffff8ec2cf090900 R14: 0000000000000102 R15: ffff8ec2cf084000 [154565.553152] FS: 0000000000000000(0000) GS:ffff8ed27f800000(0000) knlGS:0000000000000000 [154565.553154] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [154565.553155] CR2: 00000000000000f8 CR3: 000000113ae0a005 CR4: 00000000007706f0 [154565.553157] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [154565.553158] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [154565.553159] PKRU: 55555554 [154565.553160] Call Trace: [154565.553162] [154565.553165] ? show_trace_log_lvl+0x1c4/0x2df [154565.553172] ? show_trace_log_lvl+0x1c4/0x2df [154565.553177] ? qla_fab_async_scan.part.0+0x40b/0x870 [qla2xxx] [154565.553215] ? __die_body.cold+0x8/0xd [154565.553218] ? page_fault_oops+0x134/0x170 [154565.553223] ? snprintf+0x49/0x70 [154565.553229] ? exc_page_fault+0x62/0x150 [154565.553238] ? asm_exc_page_fault+0x22/0x30 Check for sp being non NULL before freeing any associated memory Fixes: a4239945b8ad ("scsi: qla2xxx: Add switch command to simplify fabric discovery") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-10-njavali@marvell.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_gs.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index d2bddca7045a..c09229b7c516 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3791,23 +3791,25 @@ int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) return rval; done_free_sp: - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } + if (sp) { + if (sp->u.iocb_cmd.u.ctarg.req) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.req_allocated_size, + sp->u.iocb_cmd.u.ctarg.req, + sp->u.iocb_cmd.u.ctarg.req_dma); + sp->u.iocb_cmd.u.ctarg.req = NULL; + } + if (sp->u.iocb_cmd.u.ctarg.rsp) { + dma_free_coherent(&vha->hw->pdev->dev, + sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, + sp->u.iocb_cmd.u.ctarg.rsp, + sp->u.iocb_cmd.u.ctarg.rsp_dma); + sp->u.iocb_cmd.u.ctarg.rsp = NULL; + } - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); + } spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; -- Gitee From f884fd538d6f7fe6a6ccc16e6f27f114e65a86e3 Mon Sep 17 00:00:00 2001 From: Shreyas Deodhar Date: Wed, 10 Dec 2025 18:15:58 +0800 Subject: [PATCH 1400/1449] scsi: qla2xxx: Allow recovery for tape devices ANBZ: #35228 commit ccbfcaa4b88e5b33d98b1e1227a4f7edee81d77d stable. commit b0335ee4fb94832a4ef68774ca7e7b33b473c7a6 upstream. Tape device doesn't show up after RSCNs. To fix this, remove tape device specific checks which allows recovery of tape devices. Fixes: 44c57f205876 ("scsi: qla2xxx: Changes to support FCP2 Target") Cc: stable@vger.kernel.org Signed-off-by: Shreyas Deodhar Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-7-njavali@marvell.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_gs.c | 3 --- drivers/scsi/qla2xxx/qla_init.c | 9 --------- 2 files changed, 12 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index c09229b7c516..19ce0344caca 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3356,9 +3356,6 @@ void qla_fab_scan_finish(scsi_qla_host_t *vha, srb_t *sp) atomic_read(&fcport->state) == FCS_ONLINE) || do_delete) { if (fcport->loop_id != FC_NO_LOOP_ID) { - if (fcport->flags & FCF_FCP2_DEVICE) - continue; - ql_log(ql_log_warn, vha, 0x20f0, "%s %d %8phC post del sess\n", __func__, __LINE__, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e881d704b45d..ddb44fb8f6a8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1859,15 +1859,6 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) case RSCN_PORT_ADDR: fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); if (fcport) { - if (ql2xfc2target && - fcport->flags & FCF_FCP2_DEVICE && - atomic_read(&fcport->state) == FCS_ONLINE) { - ql_dbg(ql_dbg_disc, vha, 0x2115, - "Delaying session delete for FCP2 portid=%06x %8phC ", - fcport->d_id.b24, fcport->port_name); - return; - } - if (vha->hw->flags.edif_enabled && DBELL_ACTIVE(vha)) { /* * On ipsec start by remote port, Target port -- Gitee From a20496b76d7edc90f255ed98627260b4af07f902 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 18:15:59 +0800 Subject: [PATCH 1401/1449] scsi: qla2xxx: Delay module unload while fabric scan in progress ANBZ: #35228 commit 528b2f1027edfb52af0171f0f4b227fb356dde05 stable. commit 8890bf450e0b6b283f48ac619fca5ac2f14ddd62 upstream. System crash seen during load/unload test in a loop. [105954.384919] RBP: ffff914589838dc0 R08: 0000000000000000 R09: 0000000000000086 [105954.384920] R10: 000000000000000f R11: ffffa31240904be5 R12: ffff914605f868e0 [105954.384921] R13: ffff914605f86910 R14: 0000000000008010 R15: 00000000ddb7c000 [105954.384923] FS: 0000000000000000(0000) GS:ffff9163fec40000(0000) knlGS:0000000000000000 [105954.384925] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [105954.384926] CR2: 000055d31ce1d6a0 CR3: 0000000119f5e001 CR4: 0000000000770ee0 [105954.384928] PKRU: 55555554 [105954.384929] Call Trace: [105954.384931] [105954.384934] qla24xx_sp_unmap+0x1f3/0x2a0 [qla2xxx] [105954.384962] ? qla_async_scan_sp_done+0x114/0x1f0 [qla2xxx] [105954.384980] ? qla24xx_els_ct_entry+0x4de/0x760 [qla2xxx] [105954.384999] ? __wake_up_common+0x80/0x190 [105954.385004] ? qla24xx_process_response_queue+0xc2/0xaa0 [qla2xxx] [105954.385023] ? qla24xx_msix_rsp_q+0x44/0xb0 [qla2xxx] [105954.385040] ? __handle_irq_event_percpu+0x3d/0x190 [105954.385044] ? handle_irq_event+0x58/0xb0 [105954.385046] ? handle_edge_irq+0x93/0x240 [105954.385050] ? __common_interrupt+0x41/0xa0 [105954.385055] ? common_interrupt+0x3e/0xa0 [105954.385060] ? asm_common_interrupt+0x22/0x40 The root cause of this was that there was a free (dma_free_attrs) in the interrupt context. There was a device discovery/fabric scan in progress. A module unload was issued which set the UNLOADING flag. As part of the discovery, after receiving an interrupt a work queue was scheduled (which involved a work to be queued). Since the UNLOADING flag is set, the work item was not allocated and the mapped memory had to be freed. The free occurred in interrupt context leading to system crash. Delay the driver unload until the fabric scan is complete to avoid the crash. Reported-by: kernel test robot Reported-by: Dan Carpenter Closes: https://lore.kernel.org/all/202512090414.07Waorz0-lkp@intel.com/ Fixes: 783e0dc4f66a ("qla2xxx: Check for device state before unloading the driver.") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-8-njavali@marvell.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_os.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d10389ee92ba..b08abdf5ebf4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1194,7 +1194,8 @@ qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha) while ((qla2x00_reset_active(vha) || ha->dpc_active || ha->flags.mbox_busy) || test_bit(FX00_RESET_RECOVERY, &vha->dpc_flags) || - test_bit(FX00_TARGET_SCAN, &vha->dpc_flags)) { + test_bit(FX00_TARGET_SCAN, &vha->dpc_flags) || + (vha->scan.scan_flags & SF_SCANNING)) { if (test_bit(UNLOADING, &base_vha->dpc_flags)) break; msleep(1000); -- Gitee From 3aed60bb2a41065de22763eaedeea3f7e81f8390 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 18:16:00 +0800 Subject: [PATCH 1402/1449] scsi: qla2xxx: Free sp in error path to fix system crash ANBZ: #35228 commit aed16d37696f494288a291b4b477484ed0be774b stable. commit 7adbd2b7809066c75f0433e5e2a8e114b429f30f upstream. System crash seen during load/unload test in a loop, [61110.449331] qla2xxx [0000:27:00.0]-0042:0: Disabled MSI-X. [61110.467494] ============================================================================= [61110.467498] BUG qla2xxx_srbs (Tainted: G OE -------- --- ): Objects remaining in qla2xxx_srbs on __kmem_cache_shutdown() [61110.467501] ----------------------------------------------------------------------------- [61110.467502] Slab 0x000000000ffc8162 objects=51 used=1 fp=0x00000000e25d3d85 flags=0x57ffffc0010200(slab|head|node=1|zone=2|lastcpupid=0x1fffff) [61110.467509] CPU: 53 PID: 455206 Comm: rmmod Kdump: loaded Tainted: G OE -------- --- 5.14.0-284.11.1.el9_2.x86_64 #1 [61110.467513] Hardware name: HPE ProLiant DL385 Gen10 Plus v2/ProLiant DL385 Gen10 Plus v2, BIOS A42 08/17/2023 [61110.467515] Call Trace: [61110.467516] [61110.467519] dump_stack_lvl+0x34/0x48 [61110.467526] slab_err.cold+0x53/0x67 [61110.467534] __kmem_cache_shutdown+0x16e/0x320 [61110.467540] kmem_cache_destroy+0x51/0x160 [61110.467544] qla2x00_module_exit+0x93/0x99 [qla2xxx] [61110.467607] ? __do_sys_delete_module.constprop.0+0x178/0x280 [61110.467613] ? syscall_trace_enter.constprop.0+0x145/0x1d0 [61110.467616] ? do_syscall_64+0x5c/0x90 [61110.467619] ? exc_page_fault+0x62/0x150 [61110.467622] ? entry_SYSCALL_64_after_hwframe+0x63/0xcd [61110.467626] [61110.467627] Disabling lock debugging due to kernel taint [61110.467635] Object 0x0000000026f7e6e6 @offset=16000 [61110.467639] ------------[ cut here ]------------ [61110.467639] kmem_cache_destroy qla2xxx_srbs: Slab cache still has objects when called from qla2x00_module_exit+0x93/0x99 [qla2xxx] [61110.467659] WARNING: CPU: 53 PID: 455206 at mm/slab_common.c:520 kmem_cache_destroy+0x14d/0x160 [61110.467718] CPU: 53 PID: 455206 Comm: rmmod Kdump: loaded Tainted: G B OE -------- --- 5.14.0-284.11.1.el9_2.x86_64 #1 [61110.467720] Hardware name: HPE ProLiant DL385 Gen10 Plus v2/ProLiant DL385 Gen10 Plus v2, BIOS A42 08/17/2023 [61110.467721] RIP: 0010:kmem_cache_destroy+0x14d/0x160 [61110.467724] Code: 99 7d 07 00 48 89 ef e8 e1 6a 07 00 eb b3 48 8b 55 60 48 8b 4c 24 20 48 c7 c6 70 fc 66 90 48 c7 c7 f8 ef a1 90 e8 e1 ed 7c 00 <0f> 0b eb 93 c3 cc cc cc cc 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 [61110.467725] RSP: 0018:ffffa304e489fe80 EFLAGS: 00010282 [61110.467727] RAX: 0000000000000000 RBX: ffffffffc0d9a860 RCX: 0000000000000027 [61110.467729] RDX: ffff8fd5ff9598a8 RSI: 0000000000000001 RDI: ffff8fd5ff9598a0 [61110.467730] RBP: ffff8fb6aaf78700 R08: 0000000000000000 R09: 0000000100d863b7 [61110.467731] R10: ffffa304e489fd20 R11: ffffffff913bef48 R12: 0000000040002000 [61110.467731] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [61110.467733] FS: 00007f64c89fb740(0000) GS:ffff8fd5ff940000(0000) knlGS:0000000000000000 [61110.467734] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [61110.467735] CR2: 00007f0f02bfe000 CR3: 00000020ad6dc005 CR4: 0000000000770ee0 [61110.467736] PKRU: 55555554 [61110.467737] Call Trace: [61110.467738] [61110.467739] qla2x00_module_exit+0x93/0x99 [qla2xxx] [61110.467755] ? __do_sys_delete_module.constprop.0+0x178/0x280 Free sp in the error path to fix the crash. Fixes: f352eeb75419 ("scsi: qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-9-njavali@marvell.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_gs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 19ce0344caca..4cef9a349343 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3622,8 +3622,8 @@ int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) if (vha->scan.scan_flags & SF_SCANNING) { spin_unlock_irqrestore(&vha->work_lock, flags); ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012, - "%s: scan active\n", __func__); - return rval; + "%s: scan active for sp:%p\n", __func__, sp); + goto done_free_sp; } vha->scan.scan_flags |= SF_SCANNING; if (!sp) -- Gitee From 52e54d09392c98fde6dda936accf7ada6920088b Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 18:16:02 +0800 Subject: [PATCH 1403/1449] scsi: qla2xxx: Query FW again before proceeding with login ANBZ: #35228 commit dccf7bc011d0ec05088d3d88afaf511302e8b24e stable. commit 42b2dab4340d39b71334151e10c6d7d9b0040ffa upstream. Issue occurred during a continuous reboot test of several thousand iterations specific to a fabric topo with dual mode target where it sends a PLOGI/PRLI and then sends a LOGO. The initiator was also in the process of discovery and sent a PLOGI to the switch. It then queried a list of ports logged in via mbx 75h and the GPDB response indicated that the target was logged in. This caused a mismatch in the states between the driver and FW. Requery the FW for the state and proceed with the rest of discovery process. Fixes: a4239945b8ad ("scsi: qla2xxx: Add switch command to simplify fabric discovery") Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-11-njavali@marvell.com Signed-off-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_init.c | 19 +++++++++++++++++-- drivers/scsi/qla2xxx/qla_isr.c | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index ddb44fb8f6a8..b736575e2d9f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2462,8 +2462,23 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) ea->sp->gen1, fcport->rscn_gen, ea->data[0], ea->data[1], ea->iop[0], ea->iop[1]); - if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || - (fcport->fw_login_state == DSC_LS_PRLI_PEND)) { + if (fcport->fw_login_state == DSC_LS_PLOGI_PEND) { + ql_dbg(ql_dbg_disc, vha, 0x20ea, + "%s %d %8phC Remote is trying to login\n", + __func__, __LINE__, fcport->port_name); + /* + * If we get here, there is port thats already logged in, + * but it's state has not moved ahead. Recheck with FW on + * what state it is in and proceed ahead + */ + if (!N2N_TOPO(vha->hw)) { + fcport->fw_login_state = DSC_LS_PRLI_COMP; + qla24xx_post_gpdb_work(vha, fcport, 0); + } + return; + } + + if (fcport->fw_login_state == DSC_LS_PRLI_PEND) { ql_dbg(ql_dbg_disc, vha, 0x20ea, "%s %d %8phC Remote is trying to login\n", __func__, __LINE__, fcport->port_name); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ae2bea27a18a..38214f8e30fa 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1676,13 +1676,28 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) /* Port logout */ fcport = qla2x00_find_fcport_by_loopid(vha, mb[1]); - if (!fcport) + if (!fcport) { + ql_dbg(ql_dbg_async, vha, 0x5011, + "Could not find fcport:%04x %04x %04x\n", + mb[1], mb[2], mb[3]); break; - if (atomic_read(&fcport->state) != FCS_ONLINE) + } + + if (atomic_read(&fcport->state) != FCS_ONLINE) { + ql_dbg(ql_dbg_async, vha, 0x5012, + "Port state is not online State:0x%x \n", + atomic_read(&fcport->state)); + ql_dbg(ql_dbg_async, vha, 0x5012, + "Scheduling session for deletion \n"); + fcport->logout_on_delete = 0; + qlt_schedule_sess_for_deletion(fcport); break; + } + ql_dbg(ql_dbg_async, vha, 0x508a, "Marking port lost loopid=%04x portid=%06x.\n", fcport->loop_id, fcport->d_id.b24); + if (qla_ini_mode_enabled(vha)) { fcport->logout_on_delete = 0; qlt_schedule_sess_for_deletion(fcport); -- Gitee From 732adb8d45898e8cfe4438616f1fd14b2c1bd866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 29 Jan 2026 16:22:27 +0800 Subject: [PATCH 1404/1449] net: sfp: Fix quirk for Ubiquiti U-Fiber Instant SFP module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 57770faaff8ee53c51c6777d33f7c706903a2409 stable. commit adcbadfd8e05d3558c9cfaa783f17c645181165f upstream. Commit fd580c9830316eda ("net: sfp: augment SFP parsing with phy_interface_t bitmap") did not add augumentation for the interface bitmap in the quirk for Ubiquiti U-Fiber Instant. The subsequent commit f81fa96d8a6c7a77 ("net: phylink: use phy_interface_t bitmaps for optical modules") then changed phylink code for selection of SFP interface: instead of using link mode bitmap, the interface bitmap is used, and the fastest interface mode supported by both SFP module and MAC is chosen. Since the interface bitmap contains also modes faster than 1000base-x, this caused a regression wherein this module stopped working out-of-the-box. Fix this. Fixes: fd580c9830316eda ("net: sfp: augment SFP parsing with phy_interface_t bitmap") Signed-off-by: Marek Behún Reviewed-by: Maxime Chevallier Reviewed-by: Russell King (Oracle) Link: https://patch.msgid.link/20260129082227.17443-1-kabel@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/phy/sfp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index dc62f141f403..ff438be4c186 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -431,6 +431,8 @@ static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id, */ linkmode_zero(modes); linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes); + phy_interface_zero(interfaces); + __set_bit(PHY_INTERFACE_MODE_1000BASEX, interfaces); } #define SFP_QUIRK(_v, _p, _m, _f) \ -- Gitee From 24951e50be5125f420f6bb2286e32cc7233853e8 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 7 Feb 2025 02:12:13 +0800 Subject: [PATCH 1405/1449] nfsd: don't ignore the return code of svc_proc_register() ANBZ: #35228 commit 30405b23b4d5e2a596fb756d48119d7293194e75 stable. commit 930b64ca0c511521f0abdd1d57ce52b2a6e3476b upstream. Currently, nfsd_proc_stat_init() ignores the return value of svc_proc_register(). If the procfile creation fails, then the kernel will WARN when it tries to remove the entry later. Fix nfsd_proc_stat_init() to return the same type of pointer as svc_proc_register(), and fix up nfsd_net_init() to check that and fail the nfsd_net construction if it occurs. svc_proc_register() can fail if the dentry can't be allocated, or if an identical dentry already exists. The second case is pretty unlikely in the nfsd_net construction codepath, so if this happens, return -ENOMEM. Reported-by: syzbot+e34ad04f27991521104c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-nfs/67a47501.050a0220.19061f.05f9.GAE@google.com/ Cc: stable@vger.kernel.org # v6.9 Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever [ Update the cleanup path to use nfsd_stat_counters_destroy. This ensures the teardown logic is correctly paired with nfsd_stat_counters_init, as required by the current NFSD implementation.] Signed-off-by: Jianqiang kang Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/nfsd/nfsctl.c | 9 ++++++++- fs/nfsd/stats.c | 4 ++-- fs/nfsd/stats.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 78ebdf20c1ef..4703e2a93568 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1526,17 +1526,24 @@ static __net_init int nfsd_net_init(struct net *net) retval = nfsd_stat_counters_init(nn); if (retval) goto out_repcache_error; + memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats)); nn->nfsd_svcstats.program = &nfsd_program; + if (!nfsd_proc_stat_init(net)) { + retval = -ENOMEM; + goto out_proc_error; + } + nn->nfsd_versions = NULL; nn->nfsd4_minorversions = NULL; nfsd4_init_leases_net(nn); get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key)); seqlock_init(&nn->writeverf_lock); - nfsd_proc_stat_init(net); return 0; +out_proc_error: + nfsd_stat_counters_destroy(nn); out_repcache_error: nfsd_idmap_shutdown(net); out_idmap_error: diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 9f606fa08bd4..0a629a18831f 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c @@ -115,11 +115,11 @@ void nfsd_stat_counters_destroy(struct nfsd_net *nn) nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM); } -void nfsd_proc_stat_init(struct net *net) +struct proc_dir_entry *nfsd_proc_stat_init(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); - svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops); + return svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops); } void nfsd_proc_stat_shutdown(struct net *net) diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h index d2753e975dfd..b1f7d21cbcd1 100644 --- a/fs/nfsd/stats.h +++ b/fs/nfsd/stats.h @@ -15,7 +15,7 @@ void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num); void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num); int nfsd_stat_counters_init(struct nfsd_net *nn); void nfsd_stat_counters_destroy(struct nfsd_net *nn); -void nfsd_proc_stat_init(struct net *net); +struct proc_dir_entry *nfsd_proc_stat_init(struct net *net); void nfsd_proc_stat_shutdown(struct net *net); static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn) -- Gitee From aab6f621e4d6c5da82948cfed0ec87a2c35c32cb Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 18 Sep 2024 20:19:45 +0800 Subject: [PATCH 1406/1449] netfilter: nf_tables: missing objects with no memcg accounting ANBZ: #35228 commit 1c4f72fa9699346e92c63049abba58758bdc8d73 stable. commit 69e687cea79fc99a17dfb0116c8644b9391b915e upstream. Several ruleset objects are still not using GFP_KERNEL_ACCOUNT for memory accounting, update them. This includes: - catchall elements - compat match large info area - log prefix - meta secctx - numgen counters - pipapo set backend datastructure - tunnel private objects Fixes: 33758c891479 ("memcg: enable accounting for nft objects") Signed-off-by: Pablo Neira Ayuso [ Adjust context ] Signed-off-by: Bin Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nf_tables_api.c | 2 +- net/netfilter/nft_compat.c | 6 +++--- net/netfilter/nft_log.c | 2 +- net/netfilter/nft_meta.c | 2 +- net/netfilter/nft_numgen.c | 2 +- net/netfilter/nft_set_pipapo.c | 10 +++++----- net/netfilter/nft_tunnel.c | 5 +++-- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 120d9bd53321..a0a5d19fa850 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -6615,7 +6615,7 @@ static int nft_setelem_catchall_insert(const struct net *net, } } - catchall = kmalloc(sizeof(*catchall), GFP_KERNEL); + catchall = kmalloc(sizeof(*catchall), GFP_KERNEL_ACCOUNT); if (!catchall) return -ENOMEM; diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 52cdfee17f73..7ca4f0d21fe2 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -535,7 +535,7 @@ nft_match_large_init(const struct nft_ctx *ctx, const struct nft_expr *expr, struct xt_match *m = expr->ops->data; int ret; - priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL); + priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL_ACCOUNT); if (!priv->info) return -ENOMEM; @@ -808,7 +808,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, goto err; } - ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL); + ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT); if (!ops) { err = -ENOMEM; goto err; @@ -898,7 +898,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, goto err; } - ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL); + ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT); if (!ops) { err = -ENOMEM; goto err; diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c index 5defe6e4fd98..e35588137995 100644 --- a/net/netfilter/nft_log.c +++ b/net/netfilter/nft_log.c @@ -163,7 +163,7 @@ static int nft_log_init(const struct nft_ctx *ctx, nla = tb[NFTA_LOG_PREFIX]; if (nla != NULL) { - priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL); + priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL_ACCOUNT); if (priv->prefix == NULL) return -ENOMEM; nla_strscpy(priv->prefix, nla, nla_len(nla) + 1); diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 8c8eb14d647b..05cd1e6e6a2f 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -952,7 +952,7 @@ static int nft_secmark_obj_init(const struct nft_ctx *ctx, if (tb[NFTA_SECMARK_CTX] == NULL) return -EINVAL; - priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL); + priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL_ACCOUNT); if (!priv->ctx) return -ENOMEM; diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c index 7d29db7c2ac0..bd058babfc82 100644 --- a/net/netfilter/nft_numgen.c +++ b/net/netfilter/nft_numgen.c @@ -66,7 +66,7 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx, if (priv->offset + priv->modulus - 1 < priv->offset) return -EOVERFLOW; - priv->counter = kmalloc(sizeof(*priv->counter), GFP_KERNEL); + priv->counter = kmalloc(sizeof(*priv->counter), GFP_KERNEL_ACCOUNT); if (!priv->counter) return -ENOMEM; diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index ebd0f704c863..63235c44f67a 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -874,7 +874,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f) return; } - new_lt = kvzalloc(lt_size + NFT_PIPAPO_ALIGN_HEADROOM, GFP_KERNEL); + new_lt = kvzalloc(lt_size + NFT_PIPAPO_ALIGN_HEADROOM, GFP_KERNEL_ACCOUNT); if (!new_lt) return; @@ -1150,7 +1150,7 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone, scratch = kzalloc_node(struct_size(scratch, map, bsize_max * 2) + NFT_PIPAPO_ALIGN_HEADROOM, - GFP_KERNEL, cpu_to_node(i)); + GFP_KERNEL_ACCOUNT, cpu_to_node(i)); if (!scratch) { /* On failure, there's no need to undo previous * allocations: this means that some scratch maps have @@ -1323,7 +1323,7 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) struct nft_pipapo_match *new; int i; - new = kmalloc(struct_size(new, f, old->field_count), GFP_KERNEL); + new = kmalloc(struct_size(new, f, old->field_count), GFP_KERNEL_ACCOUNT); if (!new) return ERR_PTR(-ENOMEM); @@ -1353,7 +1353,7 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) new_lt = kvzalloc(src->groups * NFT_PIPAPO_BUCKETS(src->bb) * src->bsize * sizeof(*dst->lt) + NFT_PIPAPO_ALIGN_HEADROOM, - GFP_KERNEL); + GFP_KERNEL_ACCOUNT); if (!new_lt) goto out_lt; @@ -1367,7 +1367,7 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) if (src->rules > (INT_MAX / sizeof(*src->mt))) goto out_mt; - dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL); + dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL_ACCOUNT); if (!dst->mt) goto out_mt; diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c index 3e3ae29dde33..f77a5bf69911 100644 --- a/net/netfilter/nft_tunnel.c +++ b/net/netfilter/nft_tunnel.c @@ -503,13 +503,14 @@ static int nft_tunnel_obj_init(const struct nft_ctx *ctx, return err; } - md = metadata_dst_alloc(priv->opts.len, METADATA_IP_TUNNEL, GFP_KERNEL); + md = metadata_dst_alloc(priv->opts.len, METADATA_IP_TUNNEL, + GFP_KERNEL_ACCOUNT); if (!md) return -ENOMEM; memcpy(&md->u.tun_info, &info, sizeof(info)); #ifdef CONFIG_DST_CACHE - err = dst_cache_init(&md->u.tun_info.dst_cache, GFP_KERNEL); + err = dst_cache_init(&md->u.tun_info.dst_cache, GFP_KERNEL_ACCOUNT); if (err < 0) { metadata_dst_free(md); return err; -- Gitee From abc1ced068477188aac4e626e20962a1ca81a910 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 23 Apr 2025 03:52:43 +0800 Subject: [PATCH 1407/1449] netfilter: nft_set_pipapo: prevent overflow in lookup table allocation ANBZ: #35228 commit a9e757473561da93c6a4136f0e59aba91ec777fc stable. commit 4c5c6aa9967dbe55bd017bb509885928d0f31206 upstream. When calculating the lookup table size, ensure the following multiplication does not overflow: - desc->field_len[] maximum value is U8_MAX multiplied by NFT_PIPAPO_GROUPS_PER_BYTE(f) that can be 2, worst case. - NFT_PIPAPO_BUCKETS(f->bb) is 2^8, worst case. - sizeof(unsigned long), from sizeof(*f->lt), lt in struct nft_pipapo_field. Then, use check_mul_overflow() to multiply by bucket size and then use check_add_overflow() to the alignment for avx2 (if needed). Finally, add lt_size_check_overflow() helper and use it to consolidate this. While at it, replace leftover allocation using the GFP_KERNEL to GFP_KERNEL_ACCOUNT for consistency, in pipapo_resize(). Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges") Signed-off-by: Pablo Neira Ayuso Reviewed-by: Stefano Brivio Signed-off-by: Pablo Neira Ayuso [ Adjust context ] Signed-off-by: Bin Lan Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/netfilter/nft_set_pipapo.c | 58 ++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 63235c44f67a..c3ada6798d4a 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -610,6 +610,30 @@ static void *nft_pipapo_get(const struct net *net, const struct nft_set *set, nft_genmask_cur(net), get_jiffies_64()); } + +/** + * lt_calculate_size() - Get storage size for lookup table with overflow check + * @groups: Amount of bit groups + * @bb: Number of bits grouped together in lookup table buckets + * @bsize: Size of each bucket in lookup table, in longs + * + * Return: allocation size including alignment overhead, negative on overflow + */ +static ssize_t lt_calculate_size(unsigned int groups, unsigned int bb, + unsigned int bsize) +{ + ssize_t ret = groups * NFT_PIPAPO_BUCKETS(bb) * sizeof(long); + + if (check_mul_overflow(ret, bsize, &ret)) + return -1; + if (check_add_overflow(ret, NFT_PIPAPO_ALIGN_HEADROOM, &ret)) + return -1; + if (ret > INT_MAX) + return -1; + + return ret; +} + /** * pipapo_resize() - Resize lookup or mapping table, or both * @f: Field containing lookup and mapping tables @@ -628,6 +652,7 @@ static int pipapo_resize(struct nft_pipapo_field *f, int old_rules, int rules) union nft_pipapo_map_bucket *new_mt, *old_mt = f->mt; size_t new_bucket_size, copy; int group, bucket; + ssize_t lt_size; new_bucket_size = DIV_ROUND_UP(rules, BITS_PER_LONG); #ifdef NFT_PIPAPO_ALIGN @@ -643,10 +668,11 @@ static int pipapo_resize(struct nft_pipapo_field *f, int old_rules, int rules) else copy = new_bucket_size; - new_lt = kvzalloc(f->groups * NFT_PIPAPO_BUCKETS(f->bb) * - new_bucket_size * sizeof(*new_lt) + - NFT_PIPAPO_ALIGN_HEADROOM, - GFP_KERNEL); + lt_size = lt_calculate_size(f->groups, f->bb, new_bucket_size); + if (lt_size < 0) + return -ENOMEM; + + new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT); if (!new_lt) return -ENOMEM; @@ -845,7 +871,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f) { unsigned long *new_lt; int groups, bb; - size_t lt_size; + ssize_t lt_size; lt_size = f->groups * NFT_PIPAPO_BUCKETS(f->bb) * f->bsize * sizeof(*f->lt); @@ -855,15 +881,17 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f) groups = f->groups * 2; bb = NFT_PIPAPO_GROUP_BITS_LARGE_SET; - lt_size = groups * NFT_PIPAPO_BUCKETS(bb) * f->bsize * - sizeof(*f->lt); + lt_size = lt_calculate_size(groups, bb, f->bsize); + if (lt_size < 0) + return; } else if (f->bb == NFT_PIPAPO_GROUP_BITS_LARGE_SET && lt_size < NFT_PIPAPO_LT_SIZE_LOW) { groups = f->groups / 2; bb = NFT_PIPAPO_GROUP_BITS_SMALL_SET; - lt_size = groups * NFT_PIPAPO_BUCKETS(bb) * f->bsize * - sizeof(*f->lt); + lt_size = lt_calculate_size(groups, bb, f->bsize); + if (lt_size < 0) + return; /* Don't increase group width if the resulting lookup table size * would exceed the upper size threshold for a "small" set. @@ -874,7 +902,7 @@ static void pipapo_lt_bits_adjust(struct nft_pipapo_field *f) return; } - new_lt = kvzalloc(lt_size + NFT_PIPAPO_ALIGN_HEADROOM, GFP_KERNEL_ACCOUNT); + new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT); if (!new_lt) return; @@ -1347,13 +1375,15 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) for (i = 0; i < old->field_count; i++) { unsigned long *new_lt; + ssize_t lt_size; memcpy(dst, src, offsetof(struct nft_pipapo_field, lt)); - new_lt = kvzalloc(src->groups * NFT_PIPAPO_BUCKETS(src->bb) * - src->bsize * sizeof(*dst->lt) + - NFT_PIPAPO_ALIGN_HEADROOM, - GFP_KERNEL_ACCOUNT); + lt_size = lt_calculate_size(src->groups, src->bb, src->bsize); + if (lt_size < 0) + goto out_lt; + + new_lt = kvzalloc(lt_size, GFP_KERNEL_ACCOUNT); if (!new_lt) goto out_lt; -- Gitee From c811a1de5e1fca138d4a4ff3f3cb5f98efdd3b14 Mon Sep 17 00:00:00 2001 From: Konstantin Shkolnyy Date: Tue, 3 Dec 2024 23:06:56 +0800 Subject: [PATCH 1408/1449] vsock/test: verify socket options after setting them ANBZ: #35228 commit 665e5706007338188db8bf833616f973d7a1e7d2 stable. commit 86814d8ffd55fd4ad19c512eccd721522a370fb2 upstream. Replace setsockopt() calls with calls to functions that follow setsockopt() with getsockopt() and check that the returned value and its size are the same as have been set. (Except in vsock_perf.) Signed-off-by: Konstantin Shkolnyy Reviewed-by: Stefano Garzarella Signed-off-by: Paolo Abeni [Stefano: patch needed to avoid vsock test build failure reported by Johan Korsnes after backporting commit 0a98de8013696 ("vsock/test: fix seqpacket message bounds test") in 6.6-stable tree. Several tests are missing here compared to upstream, so this version has been adapted by removing some hunks.] Signed-off-by: Stefano Garzarella Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/vsock/control.c | 9 +- tools/testing/vsock/util.c | 143 +++++++++++++++++++++++++++++++ tools/testing/vsock/util.h | 7 ++ tools/testing/vsock/vsock_test.c | 29 +++---- 4 files changed, 163 insertions(+), 25 deletions(-) diff --git a/tools/testing/vsock/control.c b/tools/testing/vsock/control.c index d2deb4b15b94..0066e0324d35 100644 --- a/tools/testing/vsock/control.c +++ b/tools/testing/vsock/control.c @@ -27,6 +27,7 @@ #include "timeout.h" #include "control.h" +#include "util.h" static int control_fd = -1; @@ -50,7 +51,6 @@ void control_init(const char *control_host, for (ai = result; ai; ai = ai->ai_next) { int fd; - int val = 1; fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (fd < 0) @@ -65,11 +65,8 @@ void control_init(const char *control_host, break; } - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - &val, sizeof(val)) < 0) { - perror("setsockopt"); - exit(EXIT_FAILURE); - } + setsockopt_int_check(fd, SOL_SOCKET, SO_REUSEADDR, 1, + "setsockopt SO_REUSEADDR"); if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) goto next; diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c index 751fe7c6632e..e67e26636f57 100644 --- a/tools/testing/vsock/util.c +++ b/tools/testing/vsock/util.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -420,3 +421,145 @@ unsigned long hash_djb2(const void *data, size_t len) return hash; } + +/* Set "unsigned long long" socket option and check that it's indeed set */ +void setsockopt_ull_check(int fd, int level, int optname, + unsigned long long val, char const *errmsg) +{ + unsigned long long chkval; + socklen_t chklen; + int err; + + err = setsockopt(fd, level, optname, &val, sizeof(val)); + if (err) { + fprintf(stderr, "setsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + chkval = ~val; /* just make storage != val */ + chklen = sizeof(chkval); + + err = getsockopt(fd, level, optname, &chkval, &chklen); + if (err) { + fprintf(stderr, "getsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + if (chklen != sizeof(chkval)) { + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), + chklen); + goto fail; + } + + if (chkval != val) { + fprintf(stderr, "value mismatch: set %llu got %llu\n", val, + chkval); + goto fail; + } + return; +fail: + fprintf(stderr, "%s val %llu\n", errmsg, val); + exit(EXIT_FAILURE); +; +} + +/* Set "int" socket option and check that it's indeed set */ +void setsockopt_int_check(int fd, int level, int optname, int val, + char const *errmsg) +{ + int chkval; + socklen_t chklen; + int err; + + err = setsockopt(fd, level, optname, &val, sizeof(val)); + if (err) { + fprintf(stderr, "setsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + chkval = ~val; /* just make storage != val */ + chklen = sizeof(chkval); + + err = getsockopt(fd, level, optname, &chkval, &chklen); + if (err) { + fprintf(stderr, "getsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + if (chklen != sizeof(chkval)) { + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), + chklen); + goto fail; + } + + if (chkval != val) { + fprintf(stderr, "value mismatch: set %d got %d\n", val, chkval); + goto fail; + } + return; +fail: + fprintf(stderr, "%s val %d\n", errmsg, val); + exit(EXIT_FAILURE); +} + +static void mem_invert(unsigned char *mem, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + mem[i] = ~mem[i]; +} + +/* Set "timeval" socket option and check that it's indeed set */ +void setsockopt_timeval_check(int fd, int level, int optname, + struct timeval val, char const *errmsg) +{ + struct timeval chkval; + socklen_t chklen; + int err; + + err = setsockopt(fd, level, optname, &val, sizeof(val)); + if (err) { + fprintf(stderr, "setsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + /* just make storage != val */ + chkval = val; + mem_invert((unsigned char *)&chkval, sizeof(chkval)); + chklen = sizeof(chkval); + + err = getsockopt(fd, level, optname, &chkval, &chklen); + if (err) { + fprintf(stderr, "getsockopt err: %s (%d)\n", + strerror(errno), errno); + goto fail; + } + + if (chklen != sizeof(chkval)) { + fprintf(stderr, "size mismatch: set %zu got %d\n", sizeof(val), + chklen); + goto fail; + } + + if (memcmp(&chkval, &val, sizeof(val)) != 0) { + fprintf(stderr, "value mismatch: set %ld:%ld got %ld:%ld\n", + val.tv_sec, val.tv_usec, chkval.tv_sec, chkval.tv_usec); + goto fail; + } + return; +fail: + fprintf(stderr, "%s val %ld:%ld\n", errmsg, val.tv_sec, val.tv_usec); + exit(EXIT_FAILURE); +} + +void enable_so_zerocopy_check(int fd) +{ + setsockopt_int_check(fd, SOL_SOCKET, SO_ZEROCOPY, 1, + "setsockopt SO_ZEROCOPY"); +} diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h index fb99208a95ea..a05438851919 100644 --- a/tools/testing/vsock/util.h +++ b/tools/testing/vsock/util.h @@ -50,4 +50,11 @@ void list_tests(const struct test_case *test_cases); void skip_test(struct test_case *test_cases, size_t test_cases_len, const char *test_id_str); unsigned long hash_djb2(const void *data, size_t len); +void setsockopt_ull_check(int fd, int level, int optname, + unsigned long long val, char const *errmsg); +void setsockopt_int_check(int fd, int level, int optname, int val, + char const *errmsg); +void setsockopt_timeval_check(int fd, int level, int optname, + struct timeval val, char const *errmsg); +void enable_so_zerocopy_check(int fd); #endif /* UTIL_H */ diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c index 793d688cd4da..01ad8cfa9bde 100644 --- a/tools/testing/vsock/vsock_test.c +++ b/tools/testing/vsock/vsock_test.c @@ -503,17 +503,13 @@ static void test_seqpacket_msg_bounds_server(const struct test_opts *opts) sock_buf_size = SOCK_BUF_SIZE; - if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, - &sock_buf_size, sizeof(sock_buf_size))) { - perror("setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); - exit(EXIT_FAILURE); - } + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)"); - if (setsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, - &sock_buf_size, sizeof(sock_buf_size))) { - perror("setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); - exit(EXIT_FAILURE); - } + setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE, + sock_buf_size, + "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)"); /* Ready to receive data. */ control_writeln("SRVREADY"); @@ -648,10 +644,8 @@ static void test_seqpacket_timeout_client(const struct test_opts *opts) tv.tv_sec = RCVTIMEO_TIMEOUT_SEC; tv.tv_usec = 0; - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv)) == -1) { - perror("setsockopt(SO_RCVTIMEO)"); - exit(EXIT_FAILURE); - } + setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv, + "setsockopt(SO_RCVTIMEO)"); read_enter_ns = current_nsec(); @@ -928,11 +922,8 @@ static void test_stream_poll_rcvlowat_client(const struct test_opts *opts) exit(EXIT_FAILURE); } - if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, - &lowat_val, sizeof(lowat_val))) { - perror("setsockopt(SO_RCVLOWAT)"); - exit(EXIT_FAILURE); - } + setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT, + lowat_val, "setsockopt(SO_RCVLOWAT)"); control_expectln("SRVSENT"); -- Gitee From 8d3837f0de72da0b113cc0221168d348924c97f5 Mon Sep 17 00:00:00 2001 From: Khairul Anuar Romli Date: Tue, 26 Aug 2025 08:33:58 +0800 Subject: [PATCH 1409/1449] spi: cadence-quadspi: Implement refcount to handle unbind during busy ANBZ: #35228 commit 8df235f768cea7a5829cb02525622646eb0df5f5 stable. commit 7446284023e8ef694fb392348185349c773eefb3 upstream. driver support indirect read and indirect write operation with assumption no force device removal(unbind) operation. However force device removal(removal) is still available to root superuser. Unbinding driver during operation causes kernel crash. This changes ensure driver able to handle such operation for indirect read and indirect write by implementing refcount to track attached devices to the controller and gracefully wait and until attached devices remove operation completed before proceed with removal operation. Signed-off-by: Khairul Anuar Romli Reviewed-by: Matthew Gerlach Reviewed-by: Niravkumar L Rabara Link: https://patch.msgid.link/8704fd6bd2ff4d37bba4a0eacf5eba3ba001079e.1756168074.git.khairul.anuar.romli@altera.com Signed-off-by: Mark Brown [Add cqspi defination in cqspi_exec_mem_op and minor context change fixed.] Signed-off-by: Robert Garcia Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/spi/spi-cadence-quadspi.c | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 404d1f342892..844cdffa595a 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -100,6 +100,8 @@ struct cqspi_st { bool apb_ahb_hazard; bool is_jh7110; /* Flag for StarFive JH7110 SoC */ + refcount_t refcount; + refcount_t inflight_ops; }; struct cqspi_driver_platdata { @@ -705,6 +707,9 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, u8 *rxbuf_end = rxbuf + n_rx; int ret = 0; + if (!refcount_read(&cqspi->refcount)) + return -ENODEV; + writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR); writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES); @@ -1021,6 +1026,9 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata, unsigned int write_bytes; int ret; + if (!refcount_read(&cqspi->refcount)) + return -ENODEV; + writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR); writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES); @@ -1412,11 +1420,29 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op) static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) { int ret; + struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller); + + if (refcount_read(&cqspi->inflight_ops) == 0) + return -ENODEV; + + if (!refcount_read(&cqspi->refcount)) + return -EBUSY; + + refcount_inc(&cqspi->inflight_ops); + + if (!refcount_read(&cqspi->refcount)) { + if (refcount_read(&cqspi->inflight_ops)) + refcount_dec(&cqspi->inflight_ops); + return -EBUSY; + } ret = cqspi_mem_process(mem, op); if (ret) dev_err(&mem->spi->dev, "operation failed with %d\n", ret); + if (refcount_read(&cqspi->inflight_ops) > 1) + refcount_dec(&cqspi->inflight_ops); + return ret; } @@ -1847,6 +1873,9 @@ static int cqspi_probe(struct platform_device *pdev) } } + refcount_set(&cqspi->refcount, 1); + refcount_set(&cqspi->inflight_ops, 1); + ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0, pdev->name, cqspi); if (ret) { @@ -1902,6 +1931,11 @@ static void cqspi_remove(struct platform_device *pdev) { struct cqspi_st *cqspi = platform_get_drvdata(pdev); + refcount_set(&cqspi->refcount, 0); + + if (!refcount_dec_and_test(&cqspi->inflight_ops)) + cqspi_wait_idle(cqspi); + spi_unregister_controller(cqspi->host); cqspi_controller_enable(cqspi, 0); -- Gitee From 94711e909eaa9705358b1fe9f40ee161f7450447 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Sat, 6 Dec 2025 02:55:15 +0800 Subject: [PATCH 1410/1449] selftests: mptcp: pm: ensure unknown flags are ignored ANBZ: #35228 commit 2b890bc3a5774018ca8307baeba1b69e10e4e938 stable. commit 29f4801e9c8dfd12bdcb33b61a6ac479c7162bd7 upstream. This validates the previous commit: the userspace can set unknown flags -- the 7th bit is currently unused -- without errors, but only the supported ones are printed in the endpoints dumps. The 'Fixes' tag here below is the same as the one from the previous commit: this patch here is not fixing anything wrong in the selftests, but it validates the previous fix for an issue introduced by this commit ID. Fixes: 01cacb00b35c ("mptcp: add netlink-based PM") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20251205-net-mptcp-misc-fixes-6-19-rc1-v1-2-9e4781a6c1b8@kernel.org Signed-off-by: Jakub Kicinski [ Conflicts in pm_netlink.sh, because some refactoring have been done later on: commit 0d16ed0c2e74 ("selftests: mptcp: add {get,format}_endpoint(s) helpers") and commit c99d57d0007a ("selftests: mptcp: use pm_nl endpoint ops") are not in this version. The same operation can still be done at the same place, without using the new helpers. ] Signed-off-by: Matthieu Baerts (NGI0) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- tools/testing/selftests/net/mptcp/pm_netlink.sh | 4 ++++ tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/tools/testing/selftests/net/mptcp/pm_netlink.sh b/tools/testing/selftests/net/mptcp/pm_netlink.sh index 3528e730e4d3..c089d4e06d59 100755 --- a/tools/testing/selftests/net/mptcp/pm_netlink.sh +++ b/tools/testing/selftests/net/mptcp/pm_netlink.sh @@ -127,6 +127,10 @@ id 8 flags signal 10.0.1.8" "id limit" ip netns exec $ns1 ./pm_nl_ctl flush check "ip netns exec $ns1 ./pm_nl_ctl dump" "" "flush addrs" +ip netns exec $ns1 ./pm_nl_ctl add 10.0.1.1 flags unknown +check "ip netns exec $ns1 ./pm_nl_ctl dump" "id 1 flags 10.0.1.1" "ignore unknown flags" +ip netns exec $ns1 ./pm_nl_ctl flush + ip netns exec $ns1 ./pm_nl_ctl limits 9 1 2>/dev/null check "ip netns exec $ns1 ./pm_nl_ctl limits" "$default_limits" "rcv addrs above hard limit" diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c index 234c267dd2aa..f586f1272bd7 100644 --- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c +++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c @@ -29,6 +29,8 @@ #define IPPROTO_MPTCP 262 #endif +#define MPTCP_PM_ADDR_FLAG_UNKNOWN _BITUL(7) + static void syntax(char *argv[]) { fprintf(stderr, "%s add|ann|rem|csf|dsf|get|set|del|flush|dump|events|listen|accept []\n", argv[0]); @@ -825,6 +827,8 @@ int add_addr(int fd, int pm_family, int argc, char *argv[]) flags |= MPTCP_PM_ADDR_FLAG_BACKUP; else if (!strcmp(tok, "fullmesh")) flags |= MPTCP_PM_ADDR_FLAG_FULLMESH; + else if (!strcmp(tok, "unknown")) + flags |= MPTCP_PM_ADDR_FLAG_UNKNOWN; else error(1, errno, "unknown flag %s", argv[arg]); @@ -1030,6 +1034,13 @@ static void print_addr(struct rtattr *attrs, int len) printf(","); } + if (flags & MPTCP_PM_ADDR_FLAG_UNKNOWN) { + printf("unknown"); + flags &= ~MPTCP_PM_ADDR_FLAG_UNKNOWN; + if (flags) + printf(","); + } + /* bump unknown flags, if any */ if (flags) printf("0x%x", flags); -- Gitee From 7cd0e6569bd182c1dfa70e03264ac7c37f2aa57f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 24 Jan 2026 18:59:18 +0800 Subject: [PATCH 1411/1449] mptcp: fix race in mptcp_pm_nl_flush_addrs_doit() ANBZ: #35228 commit 455e882192c9833f176f3fbbbb2f036b6c5bf555 stable. commit e2a9eeb69f7d4ca4cf4c70463af77664fdb6ab1d upstream. syzbot and Eulgyu Kim reported crashes in mptcp_pm_nl_get_local_id() and/or mptcp_pm_nl_is_backup() Root cause is list_splice_init() in mptcp_pm_nl_flush_addrs_doit() which is not RCU ready. list_splice_init_rcu() can not be called here while holding pernet->lock spinlock. Many thanks to Eulgyu Kim for providing a repro and testing our patches. Fixes: 141694df6573 ("mptcp: remove address when netlink flushes addrs") Signed-off-by: Eric Dumazet Reported-by: syzbot+5498a510ff9de39d37da@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/6970a46d.a00a0220.3ad28e.5cf0.GAE@google.com/T/ Reported-by: Eulgyu Kim Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/611 Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20260124-net-mptcp-race_nl_flush_addrs-v3-1-b2dc1b613e9d@kernel.org Signed-off-by: Jakub Kicinski [ Conflicts because the code has been moved from pm_netlink.c to pm_kernel.c later on in commit 8617e85e04bd ("mptcp: pm: split in-kernel PM specific code"). The same modifications can be applied in pm_netlink.c with one exception, because 'pernet->local_addr_list' has been renamed to 'pernet->endp_list' in commit 35e71e43a56d ("mptcp: pm: in-kernel: rename 'local_addr_list' to 'endp_list'"). The previous name is then still being used in this version. Also, another conflict is caused by commit 7bcf4d8022f9 ("mptcp: pm: rename helpers linked to 'flush'") which is not in this version: mptcp_nl_remove_addrs_list() has been renamed to mptcp_nl_flush_addrs_list(). The previous name has then been kept. ] Signed-off-by: Matthieu Baerts (NGI0) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- net/mptcp/pm_netlink.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 9f25cfd96f98..4b805d7f5769 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -1859,16 +1859,26 @@ static void __reset_counters(struct pm_nl_pernet *pernet) static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info) { struct pm_nl_pernet *pernet = genl_info_pm_nl(info); - LIST_HEAD(free_list); + struct list_head free_list; spin_lock_bh(&pernet->lock); - list_splice_init(&pernet->local_addr_list, &free_list); + free_list = pernet->local_addr_list; + INIT_LIST_HEAD_RCU(&pernet->local_addr_list); __reset_counters(pernet); pernet->next_id = 1; bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); spin_unlock_bh(&pernet->lock); - mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list); + + if (free_list.next == &pernet->local_addr_list) + return 0; + synchronize_rcu(); + + /* Adjust the pointers to free_list instead of pernet->local_addr_list */ + free_list.prev->next = &free_list; + free_list.next->prev = &free_list; + + mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list); __flush_addrs(&free_list); return 0; } -- Gitee From 250c14dd5bbdbf3d9d2f5c37f327c07815c79383 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 28 Jan 2026 04:17:12 +0800 Subject: [PATCH 1412/1449] gpio: omap: do not register driver in probe() ANBZ: #35228 commit 1c04c3a4de8d4bcb9202f94c44f26c57c2572308 stable. commit 730e5ebff40c852e3ea57b71bf02a4b89c69435f upstream. Commit 11a78b794496 ("ARM: OMAP: MPUIO wake updates") registers the omap_mpuio_driver from omap_mpuio_init(), which is called from omap_gpio_probe(). However, it neither makes sense to register drivers from probe() callbacks of other drivers, nor does the driver core allow registering drivers with a device lock already being held. The latter was revealed by commit dc23806a7c47 ("driver core: enforce device_lock for driver_match_device()") leading to a potential deadlock condition described in [1]. Additionally, the omap_mpuio_driver is never unregistered from the driver core, even if the module is unloaded. Hence, register the omap_mpuio_driver from the module initcall and unregister it in module_exit(). Link: https://lore.kernel.org/lkml/DFU7CEPUSG9A.1KKGVW4HIPMSH@kernel.org/ [1] Fixes: dc23806a7c47 ("driver core: enforce device_lock for driver_match_device()") Fixes: 11a78b794496 ("ARM: OMAP: MPUIO wake updates") Reviewed-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) Link: https://patch.msgid.link/20260127201725.35883-1-dakr@kernel.org Signed-off-by: Bartosz Golaszewski Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-omap.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index a927680c66f8..772fddc02b81 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -799,10 +799,13 @@ static struct platform_device omap_mpuio_device = { static inline void omap_mpuio_init(struct gpio_bank *bank) { - platform_set_drvdata(&omap_mpuio_device, bank); + static bool registered; - if (platform_driver_register(&omap_mpuio_driver) == 0) - (void) platform_device_register(&omap_mpuio_device); + platform_set_drvdata(&omap_mpuio_device, bank); + if (!registered) { + (void)platform_device_register(&omap_mpuio_device); + registered = true; + } } /*---------------------------------------------------------------------*/ @@ -1575,13 +1578,24 @@ static struct platform_driver omap_gpio_driver = { */ static int __init omap_gpio_drv_reg(void) { - return platform_driver_register(&omap_gpio_driver); + int ret; + + ret = platform_driver_register(&omap_mpuio_driver); + if (ret) + return ret; + + ret = platform_driver_register(&omap_gpio_driver); + if (ret) + platform_driver_unregister(&omap_mpuio_driver); + + return ret; } postcore_initcall(omap_gpio_drv_reg); static void __exit omap_gpio_exit(void) { platform_driver_unregister(&omap_gpio_driver); + platform_driver_unregister(&omap_mpuio_driver); } module_exit(omap_gpio_exit); -- Gitee From 30465b1cda031d390d383dd59cbb1c9c246b2b6e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 16 Feb 2026 23:41:21 +0800 Subject: [PATCH 1413/1449] Revert "driver core: enforce device_lock for driver_match_device()" ANBZ: #35228 commit 673dafb9a86349a12a93151fd467625614dc7e12 stable. This reverts commit adc1796eced46b48e23ec200a219d635f33a38ee which is commit dc23806a7c47ec5f1293aba407fb69519f976ee0 upstream. It causes boot regressions on some systems as all of the "fixes" for drivers are not properly backported yet. Once that is completed, only then can this be applied, if really necessary given the potential for explosions, perhaps we might want to wait a few -rc releases first... Cc: Danilo Krummrich Cc: Rafael J. Wysocki (Intel) Cc: Danilo Krummrich Cc: Gui-Dong Han Cc: Qiu-ji Chen Reported-by: Mark Brown Link: https://lore.kernel.org/r/7dfd0e63-a725-4fac-b2a0-f2e621d99d1b@sirena.org.uk Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/base/base.h | 9 --------- drivers/base/bus.c | 2 +- drivers/base/dd.c | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 35e14bebbfb2..0b491449b022 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -165,18 +165,9 @@ void device_set_deferred_probe_reason(const struct device *dev, struct va_format static inline int driver_match_device(struct device_driver *drv, struct device *dev) { - device_lock_assert(dev); - return drv->bus->match ? drv->bus->match(dev, drv) : 1; } -static inline int driver_match_device_locked(struct device_driver *drv, - struct device *dev) -{ - guard(device)(dev); - return driver_match_device(drv, dev); -} - static inline void dev_sync_state(struct device *dev) { if (dev->bus->sync_state) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 27f8442a3aa9..b97e13a52c33 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -263,7 +263,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, int err = -ENODEV; dev = bus_find_device_by_name(bus, NULL, buf); - if (dev && driver_match_device_locked(drv, dev)) { + if (dev && driver_match_device(drv, dev)) { err = device_driver_attach(drv, dev); if (!err) { /* success */ diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 07f1332dd3a4..7e2fb159bb89 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -1169,7 +1169,7 @@ static int __driver_attach(struct device *dev, void *data) * is an error. */ - ret = driver_match_device_locked(drv, dev); + ret = driver_match_device(drv, dev); if (ret == 0) { /* no match */ return 0; -- Gitee From ed9c0a197e9ed97810d98c84c135e74fe45c66b2 Mon Sep 17 00:00:00 2001 From: Anil Gurumurthy Date: Wed, 10 Dec 2025 18:16:03 +0800 Subject: [PATCH 1414/1449] scsi: qla2xxx: Fix bsg_done() causing double free ANBZ: #35228 commit 74e7458537cd9349cf019862e51491f670871707 stable. commit c2c68225b1456f4d0d393b5a8778d51bb0d5b1d0 upstream. Kernel panic observed on system, [5353358.825191] BUG: unable to handle page fault for address: ff5f5e897b024000 [5353358.825194] #PF: supervisor write access in kernel mode [5353358.825195] #PF: error_code(0x0002) - not-present page [5353358.825196] PGD 100006067 P4D 0 [5353358.825198] Oops: 0002 [#1] PREEMPT SMP NOPTI [5353358.825200] CPU: 5 PID: 2132085 Comm: qlafwupdate.sub Kdump: loaded Tainted: G W L ------- --- 5.14.0-503.34.1.el9_5.x86_64 #1 [5353358.825203] Hardware name: HPE ProLiant DL360 Gen11/ProLiant DL360 Gen11, BIOS 2.44 01/17/2025 [5353358.825204] RIP: 0010:memcpy_erms+0x6/0x10 [5353358.825211] RSP: 0018:ff591da8f4f6b710 EFLAGS: 00010246 [5353358.825212] RAX: ff5f5e897b024000 RBX: 0000000000007090 RCX: 0000000000001000 [5353358.825213] RDX: 0000000000001000 RSI: ff591da8f4fed090 RDI: ff5f5e897b024000 [5353358.825214] RBP: 0000000000010000 R08: ff5f5e897b024000 R09: 0000000000000000 [5353358.825215] R10: ff46cf8c40517000 R11: 0000000000000001 R12: 0000000000008090 [5353358.825216] R13: ff591da8f4f6b720 R14: 0000000000001000 R15: 0000000000000000 [5353358.825218] FS: 00007f1e88d47740(0000) GS:ff46cf935f940000(0000) knlGS:0000000000000000 [5353358.825219] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [5353358.825220] CR2: ff5f5e897b024000 CR3: 0000000231532004 CR4: 0000000000771ef0 [5353358.825221] PKRU: 55555554 [5353358.825222] Call Trace: [5353358.825223] [5353358.825224] ? show_trace_log_lvl+0x1c4/0x2df [5353358.825229] ? show_trace_log_lvl+0x1c4/0x2df [5353358.825232] ? sg_copy_buffer+0xc8/0x110 [5353358.825236] ? __die_body.cold+0x8/0xd [5353358.825238] ? page_fault_oops+0x134/0x170 [5353358.825242] ? kernelmode_fixup_or_oops+0x84/0x110 [5353358.825244] ? exc_page_fault+0xa8/0x150 [5353358.825247] ? asm_exc_page_fault+0x22/0x30 [5353358.825252] ? memcpy_erms+0x6/0x10 [5353358.825253] sg_copy_buffer+0xc8/0x110 [5353358.825259] qla2x00_process_vendor_specific+0x652/0x1320 [qla2xxx] [5353358.825317] qla24xx_bsg_request+0x1b2/0x2d0 [qla2xxx] Most routines in qla_bsg.c call bsg_done() only for success cases. However a few invoke it for failure case as well leading to a double free. Validate before calling bsg_done(). Cc: stable@vger.kernel.org Signed-off-by: Anil Gurumurthy Signed-off-by: Nilesh Javali Reviewed-by: Himanshu Madhani Link: https://patch.msgid.link/20251210101604.431868-12-njavali@marvell.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/scsi/qla2xxx/qla_bsg.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 10431a67d202..f43969ed87bf 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -1546,8 +1546,9 @@ qla2x00_update_optrom(struct bsg_job *bsg_job) ha->optrom_buffer = NULL; ha->optrom_state = QLA_SWAITING; mutex_unlock(&ha->optrom_mutex); - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!rval) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return rval; } @@ -2612,8 +2613,9 @@ qla2x00_manage_host_stats(struct bsg_job *bsg_job) sizeof(struct ql_vnd_mng_host_stats_resp)); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return ret; } @@ -2702,8 +2704,9 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, data, response_len); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); kfree(data); host_stat_out: @@ -2802,8 +2805,9 @@ qla2x00_get_tgt_stats(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, data, response_len); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); tgt_stat_out: kfree(data); @@ -2864,8 +2868,9 @@ qla2x00_manage_host_port(struct bsg_job *bsg_job) bsg_job->reply_payload.sg_cnt, &rsp_data, sizeof(struct ql_vnd_mng_host_port_resp)); bsg_reply->result = DID_OK; - bsg_job_done(bsg_job, bsg_reply->result, - bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); return ret; } @@ -3240,7 +3245,8 @@ int qla2x00_mailbox_passthru(struct bsg_job *bsg_job) bsg_job->reply_len = sizeof(*bsg_job->reply); bsg_reply->result = DID_OK << 16; - bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); + if (!ret) + bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); kfree(req_data); -- Gitee From 90de86f9c6688c7dba0f8aabbeb443496262e53d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 14 Feb 2026 09:49:22 +0800 Subject: [PATCH 1415/1449] PCI: endpoint: Remove unused field in struct pci_epf_group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 68c9fdb01af8ac31bc046268235fceb77c6c1ddd stable. commit 328e4dffbeecc0f2cc5a149dee6c11a0577c9671 upstream. In "struct pci_epf_group", the 'type_group' field is unused. This was added, but already unused, by commit 70b3740f2c19 ("PCI: endpoint: Automatically create a function specific attributes group"). Thus, remove it. Found with cppcheck, unusedStructMember. [kwilczynski: commit log] Link: https://lore.kernel.org/linux-pci/6507d44b6c60a19af35a605e2d58050be8872ab6.1712341008.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Stable-dep-of: 7c5c7d06bd1f ("PCI: endpoint: Avoid creating sub-groups asynchronously") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/endpoint/pci-ep-cfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 22a573ba148e..42a103c133d0 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -23,7 +23,6 @@ struct pci_epf_group { struct config_group group; struct config_group primary_epc_group; struct config_group secondary_epc_group; - struct config_group *type_group; struct delayed_work cfs_work; struct pci_epf *epf; int index; -- Gitee From 7f7d65529ce93de9536ecdfaaff8353909a47bd3 Mon Sep 17 00:00:00 2001 From: Liu Song Date: Sat, 14 Feb 2026 09:49:23 +0800 Subject: [PATCH 1416/1449] PCI: endpoint: Avoid creating sub-groups asynchronously ANBZ: #35228 commit 8cb905eca73944089a0db01443c7628a9e87012d stable. commit 7c5c7d06bd1f86d2c3ebe62be903a4ba42db4d2c upstream. The asynchronous creation of sub-groups by a delayed work could lead to a NULL pointer dereference when the driver directory is removed before the work completes. The crash can be easily reproduced with the following commands: # cd /sys/kernel/config/pci_ep/functions/pci_epf_test # for i in {1..20}; do mkdir test && rmdir test; done BUG: kernel NULL pointer dereference, address: 0000000000000088 ... Call Trace: configfs_register_group+0x3d/0x190 pci_epf_cfs_work+0x41/0x110 process_one_work+0x18f/0x350 worker_thread+0x25a/0x3a0 Fix this issue by using configfs_add_default_group() API which does not have the deadlock problem as configfs_register_group() and does not require the delayed work handler. Fixes: e85a2d783762 ("PCI: endpoint: Add support in configfs to associate two EPCs with EPF") Signed-off-by: Liu Song [mani: slightly reworded the description and added stable list] Signed-off-by: Manivannan Sadhasivam Signed-off-by: Bjorn Helgaas Cc: stable@kernel.org Link: https://patch.msgid.link/20250710143845409gLM6JdlwPhlHG9iX3F6jK@zte.com.cn Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/pci/endpoint/pci-ep-cfs.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 42a103c133d0..5b64203f100f 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -23,7 +23,6 @@ struct pci_epf_group { struct config_group group; struct config_group primary_epc_group; struct config_group secondary_epc_group; - struct delayed_work cfs_work; struct pci_epf *epf; int index; }; @@ -100,7 +99,7 @@ static struct config_group secondary_epc_group = &epf_group->secondary_epc_group; config_group_init_type_name(secondary_epc_group, "secondary", &pci_secondary_epc_type); - configfs_register_group(&epf_group->group, secondary_epc_group); + configfs_add_default_group(secondary_epc_group, &epf_group->group); return secondary_epc_group; } @@ -160,7 +159,7 @@ static struct config_group config_group_init_type_name(primary_epc_group, "primary", &pci_primary_epc_type); - configfs_register_group(&epf_group->group, primary_epc_group); + configfs_add_default_group(primary_epc_group, &epf_group->group); return primary_epc_group; } @@ -561,15 +560,13 @@ static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group) return; } - configfs_register_group(&epf_group->group, group); + configfs_add_default_group(group, &epf_group->group); } -static void pci_epf_cfs_work(struct work_struct *work) +static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group) { - struct pci_epf_group *epf_group; struct config_group *group; - epf_group = container_of(work, struct pci_epf_group, cfs_work.work); group = pci_ep_cfs_add_primary_group(epf_group); if (IS_ERR(group)) { pr_err("failed to create 'primary' EPC interface\n"); @@ -628,9 +625,7 @@ static struct config_group *pci_epf_make(struct config_group *group, kfree(epf_name); - INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work); - queue_delayed_work(system_wq, &epf_group->cfs_work, - msecs_to_jiffies(1)); + pci_epf_cfs_add_sub_groups(epf_group); return &epf_group->group; -- Gitee From f35b50bdcd5af5f39fe5cb63a3a79d683aecfc52 Mon Sep 17 00:00:00 2001 From: Chelsy Ratnawat Date: Sat, 14 Feb 2026 00:22:28 +0800 Subject: [PATCH 1417/1449] bus: fsl-mc: Replace snprintf and sprintf with sysfs_emit in sysfs show functions ANBZ: #35228 commit 3118a9c6875b8318f35123e7923783a0ab248a3a stable. commit a50522c805a6c575c80f41b04706e084d814e116 upstream. Use sysfs_emit() instead of snprintf()/sprintf() when writing to sysfs buffers, as recommended by the kernel documentation. Signed-off-by: Chelsy Ratnawat Acked-by: Ioana Ciornei Link: https://lore.kernel.org/r/20250822124339.1739290-1-chelsyratnawat2001@gmail.com Signed-off-by: Christophe Leroy Stable-dep-of: 148891e95014 ("bus: fsl-mc: fix use-after-free in driver_override_show()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bus/fsl-mc/fsl-mc-bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 324d388fb21c..df01b106174f 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -176,8 +176,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, { struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor, - mc_dev->obj_desc.type); + return sysfs_emit(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor, + mc_dev->obj_desc.type); } static DEVICE_ATTR_RO(modalias); @@ -203,7 +203,7 @@ static ssize_t driver_override_show(struct device *dev, { struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override); + return sysfs_emit(buf, "%s\n", mc_dev->driver_override); } static DEVICE_ATTR_RW(driver_override); -- Gitee From 6b12b0ea651c3ae38bf3c6f289b98a2e19cf3fe1 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Sat, 14 Feb 2026 00:22:29 +0800 Subject: [PATCH 1418/1449] bus: fsl-mc: fix use-after-free in driver_override_show() ANBZ: #35228 commit b1983840287303e0dfb401b1b6cecc5ea7471e90 stable. commit 148891e95014b5dc5878acefa57f1940c281c431 upstream. The driver_override_show() function reads the driver_override string without holding the device_lock. However, driver_override_store() uses driver_set_override(), which modifies and frees the string while holding the device_lock. This can result in a concurrent use-after-free if the string is freed by the store function while being read by the show function. Fix this by holding the device_lock around the read operation. Fixes: 1f86a00c1159 ("bus/fsl-mc: add support for 'driver_override' in the mc-bus") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Reviewed-by: Ioana Ciornei Link: https://lore.kernel.org/r/20251202174438.12658-1-hanguidong02@gmail.com Signed-off-by: Christophe Leroy (CS GROUP) Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/bus/fsl-mc/fsl-mc-bus.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index df01b106174f..8f361432eb69 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -202,8 +202,12 @@ static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr, char *buf) { struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + ssize_t len; - return sysfs_emit(buf, "%s\n", mc_dev->driver_override); + device_lock(dev); + len = sysfs_emit(buf, "%s\n", mc_dev->driver_override); + device_unlock(dev); + return len; } static DEVICE_ATTR_RW(driver_override); -- Gitee From e42510e832c6a660b8902fe1de15c649b6060b52 Mon Sep 17 00:00:00 2001 From: Tim Guttzeit Date: Mon, 19 Jan 2026 23:15:55 +0800 Subject: [PATCH 1419/1449] ALSA: hda/realtek: Fix headset mic for TongFang X6AR55xU ANBZ: #35228 commit 2accd79be906f2ea16b2e7205b136296f564a63e stable. commit b48fe9af1e60360baf09ca6b7a3cd6541f16e611 upstream. Add a PCI quirk to enable microphone detection on the headphone jack of TongFang X6AR55xU devices. Signed-off-by: Tim Guttzeit Signed-off-by: Werner Sembach Link: https://patch.msgid.link/20260119151626.35481-1-wse@tuxedocomputers.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c60358a4a757..95e650493dc5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11102,6 +11102,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60140}, {0x19, 0x04a11030}, {0x21, 0x04211020}), + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1d05, "TongFang", ALC274_FIXUP_HP_HEADSET_MIC, + {0x17, 0x90170110}, + {0x19, 0x03a11030}, + {0x21, 0x03211020}), SND_HDA_PIN_QUIRK(0x10ec0282, 0x1025, "Acer", ALC282_FIXUP_ACER_DISABLE_LINEOUT, ALC282_STANDARD_PINS, {0x12, 0x90a609c0}, -- Gitee From 1d938f33d2ab1f8a095f2e9702f71178a7bdee5d Mon Sep 17 00:00:00 2001 From: Anatolii Shirykalov Date: Mon, 19 Jan 2026 22:56:18 +0800 Subject: [PATCH 1420/1449] ASoC: amd: yc: Add ASUS ExpertBook PM1503CDA to quirks list ANBZ: #35228 commit 4cfb1aed47539626e4310652fef8bb13ad4d6154 stable. commit 018b211b1d321a52ed8d8de74ce83ce52a2e1224 upstream. Add ASUS ExpertBook PM1503CDA to the DMI quirks table to enable internal DMIC support via the ACP6x machine driver. Signed-off-by: Anatolii Shirykalov Link: https://patch.msgid.link/20260119145618.3171435-1-pipocavsobake@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index b0456be5d921..92d0d39d39d9 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -535,6 +535,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK PM1503CDA"), + } + }, { .driver_data = &acp6x_card, .matches = { -- Gitee From 76d78201627f9d2bc91995ca07bb9cf02b8e0b6d Mon Sep 17 00:00:00 2001 From: Xuewen Yan Date: Mon, 26 Jan 2026 17:42:09 +0800 Subject: [PATCH 1421/1449] gpio: sprd: Change sprd_gpio lock to raw_spin_lock ANBZ: #35228 commit b204c5ec24a238f5d06cfa688fb3b80d1afdb91c stable. commit 96313fcc1f062ba239f4832c9eff685da6c51c99 upstream. There was a lockdep warning in sprd_gpio: [ 6.258269][T329@C6] [ BUG: Invalid wait context ] [ 6.258270][T329@C6] 6.18.0-android17-0-g30527ad7aaae-ab00009-4k #1 Tainted: G W OE [ 6.258272][T329@C6] ----------------------------- [ 6.258273][T329@C6] modprobe/329 is trying to lock: [ 6.258275][T329@C6] ffffff8081c91690 (&sprd_gpio->lock){....}-{3:3}, at: sprd_gpio_irq_unmask+0x4c/0xa4 [gpio_sprd] [ 6.258282][T329@C6] other info that might help us debug this: [ 6.258283][T329@C6] context-{5:5} [ 6.258285][T329@C6] 3 locks held by modprobe/329: [ 6.258286][T329@C6] #0: ffffff808baca108 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xc4/0x204 [ 6.258295][T329@C6] #1: ffffff80965e7240 (request_class#4){+.+.}-{4:4}, at: __setup_irq+0x1cc/0x82c [ 6.258304][T329@C6] #2: ffffff80965e70c8 (lock_class#4){....}-{2:2}, at: __setup_irq+0x21c/0x82c [ 6.258313][T329@C6] stack backtrace: [ 6.258314][T329@C6] CPU: 6 UID: 0 PID: 329 Comm: modprobe Tainted: G W OE 6.18.0-android17-0-g30527ad7aaae-ab00009-4k #1 PREEMPT 3ad5b0f45741a16e5838da790706e16ceb6717df [ 6.258316][T329@C6] Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE [ 6.258317][T329@C6] Hardware name: Unisoc UMS9632-base Board (DT) [ 6.258318][T329@C6] Call trace: [ 6.258318][T329@C6] show_stack+0x20/0x30 (C) [ 6.258321][T329@C6] __dump_stack+0x28/0x3c [ 6.258324][T329@C6] dump_stack_lvl+0xac/0xf0 [ 6.258326][T329@C6] dump_stack+0x18/0x3c [ 6.258329][T329@C6] __lock_acquire+0x824/0x2c28 [ 6.258331][T329@C6] lock_acquire+0x148/0x2cc [ 6.258333][T329@C6] _raw_spin_lock_irqsave+0x6c/0xb4 [ 6.258334][T329@C6] sprd_gpio_irq_unmask+0x4c/0xa4 [gpio_sprd 814535e93c6d8e0853c45c02eab0fa88a9da6487] [ 6.258337][T329@C6] irq_startup+0x238/0x350 [ 6.258340][T329@C6] __setup_irq+0x504/0x82c [ 6.258342][T329@C6] request_threaded_irq+0x118/0x184 [ 6.258344][T329@C6] devm_request_threaded_irq+0x94/0x120 [ 6.258347][T329@C6] sc8546_init_irq+0x114/0x170 [sc8546_charger 223586ccafc27439f7db4f95b0c8e6e882349a99] [ 6.258352][T329@C6] sc8546_charger_probe+0x53c/0x5a0 [sc8546_charger 223586ccafc27439f7db4f95b0c8e6e882349a99] [ 6.258358][T329@C6] i2c_device_probe+0x2c8/0x350 [ 6.258361][T329@C6] really_probe+0x1a8/0x46c [ 6.258363][T329@C6] __driver_probe_device+0xa4/0x10c [ 6.258366][T329@C6] driver_probe_device+0x44/0x1b4 [ 6.258369][T329@C6] __driver_attach+0xd0/0x204 [ 6.258371][T329@C6] bus_for_each_dev+0x10c/0x168 [ 6.258373][T329@C6] driver_attach+0x2c/0x3c [ 6.258376][T329@C6] bus_add_driver+0x154/0x29c [ 6.258378][T329@C6] driver_register+0x70/0x10c [ 6.258381][T329@C6] i2c_register_driver+0x48/0xc8 [ 6.258384][T329@C6] init_module+0x28/0xfd8 [sc8546_charger 223586ccafc27439f7db4f95b0c8e6e882349a99] [ 6.258389][T329@C6] do_one_initcall+0x128/0x42c [ 6.258392][T329@C6] do_init_module+0x60/0x254 [ 6.258395][T329@C6] load_module+0x1054/0x1220 [ 6.258397][T329@C6] __arm64_sys_finit_module+0x240/0x35c [ 6.258400][T329@C6] invoke_syscall+0x60/0xec [ 6.258402][T329@C6] el0_svc_common+0xb0/0xe4 [ 6.258405][T329@C6] do_el0_svc+0x24/0x30 [ 6.258407][T329@C6] el0_svc+0x54/0x1c4 [ 6.258409][T329@C6] el0t_64_sync_handler+0x68/0xdc [ 6.258411][T329@C6] el0t_64_sync+0x1c4/0x1c8 This is because the spin_lock would change to rt_mutex in PREEMPT_RT, however the sprd_gpio->lock would use in hard-irq, this is unsafe. So change the spin_lock_t to raw_spin_lock_t to use the spinlock in hard-irq. Signed-off-by: Xuewen Yan Reviewed-by: Baolin Wang Reviewed-by: Sebastian Andrzej Siewior Link: https://lore.kernel.org/r/20260126094209.9855-1-xuewen.yan@unisoc.com [Bartosz: tweaked the commit message] Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpio-sprd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-sprd.c b/drivers/gpio/gpio-sprd.c index c117c11bfb29..192f05a2c19c 100644 --- a/drivers/gpio/gpio-sprd.c +++ b/drivers/gpio/gpio-sprd.c @@ -35,7 +35,7 @@ struct sprd_gpio { struct gpio_chip chip; void __iomem *base; - spinlock_t lock; + raw_spinlock_t lock; int irq; }; @@ -54,7 +54,7 @@ static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset, unsigned long flags; u32 tmp; - spin_lock_irqsave(&sprd_gpio->lock, flags); + raw_spin_lock_irqsave(&sprd_gpio->lock, flags); tmp = readl_relaxed(base + reg); if (val) @@ -63,7 +63,7 @@ static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset, tmp &= ~BIT(SPRD_GPIO_BIT(offset)); writel_relaxed(tmp, base + reg); - spin_unlock_irqrestore(&sprd_gpio->lock, flags); + raw_spin_unlock_irqrestore(&sprd_gpio->lock, flags); } static int sprd_gpio_read(struct gpio_chip *chip, unsigned int offset, u16 reg) @@ -234,7 +234,7 @@ static int sprd_gpio_probe(struct platform_device *pdev) if (IS_ERR(sprd_gpio->base)) return PTR_ERR(sprd_gpio->base); - spin_lock_init(&sprd_gpio->lock); + raw_spin_lock_init(&sprd_gpio->lock); sprd_gpio->chip.label = dev_name(&pdev->dev); sprd_gpio->chip.ngpio = SPRD_GPIO_NR; -- Gitee From cd14bc7cd99391ed395368fe2cd9aff0b859c92e Mon Sep 17 00:00:00 2001 From: Zhang Heng Date: Mon, 26 Jan 2026 15:35:08 +0800 Subject: [PATCH 1422/1449] ALSA: hda/realtek: Add quirk for Inspur S14-G1 ANBZ: #35228 commit 6834804ad484fabbc6bc994a77110f8d52cfe179 stable. commit 9e18920e783d0bcd4c127a7adc66565243ab9655 upstream. Inspur S14-G1 is equipped with ALC256. Enable "power saving mode" and Enable "headset jack mode". Signed-off-by: Zhang Heng Link: https://patch.msgid.link/20260126073508.3897461-2-zhangheng@kylinos.cn Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 95e650493dc5..5b836a91135c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10650,6 +10650,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1ee7, 0x2078, "HONOR BRB-X M1010", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x2014, 0x800a, "Positivo ARN50", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x2039, 0x0001, "Inspur S14-G1", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13), SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO), -- Gitee From 2354c3aba16fc9793bc6a405cdde3af56a3df40c Mon Sep 17 00:00:00 2001 From: Ricardo Rivera-Matos Date: Fri, 16 Jan 2026 03:25:10 +0800 Subject: [PATCH 1423/1449] ASoC: cs35l45: Corrects ASP_TX5 DAPM widget channel ANBZ: #35228 commit 79100c3bc0c4679df3bb63a46e51b5124351a9fd stable. commit 6dd0fdc908c02318c28ec2c0979661846ee0a9f7 upstream. ASP_TX5 was incorrectly mapped to a channel value of 3 corrects, the channel value of 4. Reviewed-by: Charles Keepax Signed-off-by: Ricardo Rivera-Matos Link: https://patch.msgid.link/20260115192523.1335742-2-rriveram@opensource.cirrus.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/cs35l45.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index 7e439c778c6b..11e28c340a70 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -316,7 +316,7 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("ASP_TX2", NULL, 1, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX2_EN_SHIFT, 0), SND_SOC_DAPM_AIF_OUT("ASP_TX3", NULL, 2, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX3_EN_SHIFT, 0), SND_SOC_DAPM_AIF_OUT("ASP_TX4", NULL, 3, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX4_EN_SHIFT, 0), - SND_SOC_DAPM_AIF_OUT("ASP_TX5", NULL, 3, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX5_EN_SHIFT, 0), + SND_SOC_DAPM_AIF_OUT("ASP_TX5", NULL, 4, CS35L45_ASP_ENABLES1, CS35L45_ASP_TX5_EN_SHIFT, 0), SND_SOC_DAPM_MUX("ASP_TX1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[0]), SND_SOC_DAPM_MUX("ASP_TX2 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[1]), -- Gitee From 29d0c8265336abe10fc76e69a528a025ef7fd066 Mon Sep 17 00:00:00 2001 From: Deepanshu Kartikey Date: Tue, 13 Jan 2026 16:40:37 +0800 Subject: [PATCH 1424/1449] romfs: check sb_set_blocksize() return value ANBZ: #35228 commit cbd9931e6456822067725354d83446c5bb813030 stable. commit ab7ad7abb3660c58ffffdf07ff3bb976e7e0afa0 upstream. romfs_fill_super() ignores the return value of sb_set_blocksize(), which can fail if the requested block size is incompatible with the block device's configuration. This can be triggered by setting a loop device's block size larger than PAGE_SIZE using ioctl(LOOP_SET_BLOCK_SIZE, 32768), then mounting a romfs filesystem on that device. When sb_set_blocksize(sb, ROMBSIZE) is called with ROMBSIZE=4096 but the device has logical_block_size=32768, bdev_validate_blocksize() fails because the requested size is smaller than the device's logical block size. sb_set_blocksize() returns 0 (failure), but romfs ignores this and continues mounting. The superblock's block size remains at the device's logical block size (32768). Later, when sb_bread() attempts I/O with this oversized block size, it triggers a kernel BUG in folio_set_bh(): kernel BUG at fs/buffer.c:1582! BUG_ON(size > PAGE_SIZE); Fix by checking the return value of sb_set_blocksize() and failing the mount with -EINVAL if it returns 0. Reported-by: syzbot+9c4e33e12283d9437c25@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9c4e33e12283d9437c25 Signed-off-by: Deepanshu Kartikey Link: https://patch.msgid.link/20260113084037.1167887-1-kartikey406@gmail.com Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/romfs/super.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/romfs/super.c b/fs/romfs/super.c index b1bdfbc211c3..82975173dcb0 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -467,7 +467,10 @@ static int romfs_fill_super(struct super_block *sb, struct fs_context *fc) #ifdef CONFIG_BLOCK if (!sb->s_mtd) { - sb_set_blocksize(sb, ROMBSIZE); + if (!sb_set_blocksize(sb, ROMBSIZE)) { + errorf(fc, "romfs: unable to set blocksize\n"); + return -EINVAL; + } } else { sb->s_blocksize = ROMBSIZE; sb->s_blocksize_bits = blksize_bits(ROMBSIZE); -- Gitee From 0f38bd9bdb7486d31ab988a1a41297a4e21a7965 Mon Sep 17 00:00:00 2001 From: Brahmajit Das Date: Tue, 2 Sep 2025 05:20:20 +0800 Subject: [PATCH 1425/1449] =?UTF-8?q?drm/tegra:=20hdmi:=20sor:=20Fix=20err?= =?UTF-8?q?or:=20variable=20=E2=80=98j=E2=80=99=20set=20but=20not=20used?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e120bae4c56d162f38e23ba67097077bf3e43cdd stable. commit 1beee8d0c263b3e239c8d6616e4f8bb700bed658 upstream. The variable j is set, however never used in or outside the loop, thus resulting in dead code. Building with GCC 16 results in a build error due to -Werror=unused-but-set-variable= enabled by default. This patch clean up the dead code and fixes the build error. Example build log: drivers/gpu/drm/tegra/sor.c:1867:19: error: variable ‘j’ set but not used [-Werror=unused-but-set-variable=] 1867 | size_t i, j; | ^ Signed-off-by: Brahmajit Das Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20250901212020.3757519-1-listout@listout.xyz Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpu/drm/tegra/hdmi.c | 4 ++-- drivers/gpu/drm/tegra/sor.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index 58c2ba94e7dd..2451c9b67024 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -656,7 +656,7 @@ static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, const void *data, { const u8 *ptr = data; unsigned long offset; - size_t i, j; + size_t i; u32 value; switch (ptr[0]) { @@ -689,7 +689,7 @@ static void tegra_hdmi_write_infopack(struct tegra_hdmi *hdmi, const void *data, * - subpack_low: bytes 0 - 3 * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00) */ - for (i = 3, j = 0; i < size; i += 7, j += 8) { + for (i = 3; i < size; i += 7) { size_t rem = size - i, num = min_t(size_t, rem, 4); value = tegra_hdmi_subpack(&ptr[i], num); diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 61b437a84806..1b03f8ca80a1 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -1861,7 +1861,7 @@ static void tegra_sor_hdmi_write_infopack(struct tegra_sor *sor, { const u8 *ptr = data; unsigned long offset; - size_t i, j; + size_t i; u32 value; switch (ptr[0]) { @@ -1894,7 +1894,7 @@ static void tegra_sor_hdmi_write_infopack(struct tegra_sor *sor, * - subpack_low: bytes 0 - 3 * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00) */ - for (i = 3, j = 0; i < size; i += 7, j += 8) { + for (i = 3; i < size; i += 7) { size_t rem = size - i, num = min_t(size_t, rem, 4); value = tegra_sor_hdmi_subpack(&ptr[i], num); -- Gitee From ccb1ab3c9a696fbd5f95d9b25c14ffed0494082c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 27 Jan 2026 04:02:40 +0800 Subject: [PATCH 1426/1449] platform/x86: classmate-laptop: Add missing NULL pointer checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 9cf4b9b8ad09d6e05307abc4e951cabdff4be652 stable. commit fe747d7112283f47169e9c16e751179a9b38611e upstream. In a few places in the Classmate laptop driver, code using the accel object may run before that object's address is stored in the driver data of the input device using it. For example, cmpc_accel_sensitivity_store_v4() is the "show" method of cmpc_accel_sensitivity_attr_v4 which is added in cmpc_accel_add_v4(), before calling dev_set_drvdata() for inputdev->dev. If the sysfs attribute is accessed prematurely, the dev_get_drvdata(&inputdev->dev) call in in cmpc_accel_sensitivity_store_v4() returns NULL which leads to a NULL pointer dereference going forward. Moreover, sysfs attributes using the input device are added before initializing that device by cmpc_add_acpi_notify_device() and if one of them is accessed before running that function, a NULL pointer dereference will occur. For example, cmpc_accel_sensitivity_attr_v4 is added before calling cmpc_add_acpi_notify_device() and if it is read prematurely, the dev_get_drvdata(&acpi->dev) call in cmpc_accel_sensitivity_show_v4() returns NULL which leads to a NULL pointer dereference going forward. Fix this by adding NULL pointer checks in all of the relevant places. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/12825381.O9o76ZdvQC@rafael.j.wysocki Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/classmate-laptop.c | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 2edaea2492df..053c8a86d5ec 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -208,7 +208,12 @@ static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev, acpi = to_acpi_device(dev); inputdev = dev_get_drvdata(&acpi->dev); + if (!inputdev) + return -ENXIO; + accel = dev_get_drvdata(&inputdev->dev); + if (!accel) + return -ENXIO; return sprintf(buf, "%d\n", accel->sensitivity); } @@ -225,7 +230,12 @@ static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev, acpi = to_acpi_device(dev); inputdev = dev_get_drvdata(&acpi->dev); + if (!inputdev) + return -ENXIO; + accel = dev_get_drvdata(&inputdev->dev); + if (!accel) + return -ENXIO; r = kstrtoul(buf, 0, &sensitivity); if (r) @@ -257,7 +267,12 @@ static ssize_t cmpc_accel_g_select_show_v4(struct device *dev, acpi = to_acpi_device(dev); inputdev = dev_get_drvdata(&acpi->dev); + if (!inputdev) + return -ENXIO; + accel = dev_get_drvdata(&inputdev->dev); + if (!accel) + return -ENXIO; return sprintf(buf, "%d\n", accel->g_select); } @@ -274,7 +289,12 @@ static ssize_t cmpc_accel_g_select_store_v4(struct device *dev, acpi = to_acpi_device(dev); inputdev = dev_get_drvdata(&acpi->dev); + if (!inputdev) + return -ENXIO; + accel = dev_get_drvdata(&inputdev->dev); + if (!accel) + return -ENXIO; r = kstrtoul(buf, 0, &g_select); if (r) @@ -303,6 +323,8 @@ static int cmpc_accel_open_v4(struct input_dev *input) acpi = to_acpi_device(input->dev.parent); accel = dev_get_drvdata(&input->dev); + if (!accel) + return -ENXIO; cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity); cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select); @@ -551,7 +573,12 @@ static ssize_t cmpc_accel_sensitivity_show(struct device *dev, acpi = to_acpi_device(dev); inputdev = dev_get_drvdata(&acpi->dev); + if (!inputdev) + return -ENXIO; + accel = dev_get_drvdata(&inputdev->dev); + if (!accel) + return -ENXIO; return sprintf(buf, "%d\n", accel->sensitivity); } @@ -568,7 +595,12 @@ static ssize_t cmpc_accel_sensitivity_store(struct device *dev, acpi = to_acpi_device(dev); inputdev = dev_get_drvdata(&acpi->dev); + if (!inputdev) + return -ENXIO; + accel = dev_get_drvdata(&inputdev->dev); + if (!accel) + return -ENXIO; r = kstrtoul(buf, 0, &sensitivity); if (r) -- Gitee From 636eaf4a9847cdcb7bf8d6a6154814df1d32f48b Mon Sep 17 00:00:00 2001 From: Tagir Garaev Date: Sun, 1 Feb 2026 20:17:28 +0800 Subject: [PATCH 1427/1449] ASoC: Intel: sof_es8336: Add DMI quirk for Huawei BOD-WXX9 ANBZ: #35228 commit d7d7b93aca648d991a8343f42388a910c5c13641 stable. commit 6b641122d31f9d33e7d60047ee0586d1659f3f54 upstream. Add DMI entry for Huawei Matebook D (BOD-WXX9) with HEADPHONE_GPIO and DMIC quirks. This device has ES8336 codec with: - GPIO 16 (headphone-enable) for headphone amplifier control - GPIO 17 (speakers-enable) for speaker amplifier control - GPIO 269 for jack detection IRQ - 2-channel DMIC Hardware investigation shows that both GPIO 16 and 17 are required for proper audio routing, as headphones and speakers share the same physical output (HPOL/HPOR) and are separated only via amplifier enable signals. RFC: Seeking advice on GPIO control issue: GPIO values change in driver (gpiod_get_value() shows logical value changes) but not physically (debugfs gpio shows no change). The same gpiod_set_value_cansleep() calls work correctly in probe context with msleep(), but fail when called from DAPM event callbacks. Context information from diagnostics: - in_atomic=0, in_interrupt=0, irqs_disabled=0 - Process context: pipewire - GPIO 17 (speakers): changes in driver, no physical change - GPIO 16 (headphone): changes in driver, no physical change In Windows, audio switching works without visible GPIO changes, suggesting possible ACPI/firmware involvement. Any suggestions on how to properly control these GPIOs from DAPM events would be appreciated. Signed-off-by: Tagir Garaev Link: https://patch.msgid.link/20260201121728.16597-1-tgaraev653@gmail.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/intel/boards/sof_es8336.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index c9d9381c7679..02b74ab62ff5 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -332,6 +332,15 @@ static int sof_es8336_quirk_cb(const struct dmi_system_id *id) * if the topology file is modified as well. */ static const struct dmi_system_id sof_es8336_quirk_table[] = { + { + .callback = sof_es8336_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"), + DMI_MATCH(DMI_PRODUCT_NAME, "BOD-WXX9"), + }, + .driver_data = (void *)(SOF_ES8336_HEADPHONE_GPIO | + SOF_ES8336_ENABLE_DMIC) + }, { .callback = sof_es8336_quirk_cb, .matches = { -- Gitee From 03e707048c69111ece73cb96883aa50d224e0a16 Mon Sep 17 00:00:00 2001 From: Dirk Su Date: Thu, 29 Jan 2026 14:50:19 +0800 Subject: [PATCH 1428/1449] ASoC: amd: yc: Add quirk for HP 200 G2a 16 ANBZ: #35228 commit c3876edb0184338fcfc6c30c92ff286e68b74547 stable. commit 611c7d2262d5645118e0b3a9a88475d35a8366f2 upstream. Fix the missing mic on HP 200 G2a 16 by adding quirk with the board ID 8EE4 Signed-off-by: Dirk Su Link: https://patch.msgid.link/20260129065038.39349-1-dirk.su@canonical.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 92d0d39d39d9..b6068d289f5f 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -633,6 +633,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "8BD6"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), + DMI_MATCH(DMI_BOARD_NAME, "8EE4"), + } + }, { .driver_data = &acp6x_card, .matches = { -- Gitee From 8b8d67132c99b87946a273b7474449c98fdf3673 Mon Sep 17 00:00:00 2001 From: gongqi <550230171hxy@gmail.com> Date: Thu, 22 Jan 2026 23:55:00 +0800 Subject: [PATCH 1429/1449] platform/x86/amd/pmc: Add quirk for MECHREVO Wujie 15X Pro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit e8f5d1306a3a5516fe699039614040c084bd6341 stable. commit 2b4e00d8e70ca8736fda82447be6a4e323c6d1f5 upstream. The MECHREVO Wujie 15X Pro suffers from spurious IRQ issues related to the AMD PMC. Add it to the quirk list to use the spurious_8042 fix. Signed-off-by: gongqi <550230171hxy@gmail.com> Link: https://patch.msgid.link/20260122155501.376199-4-550230171hxy@gmail.com Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/amd/pmc/pmc-quirks.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c index a5031339dac8..a6006b4ec2cc 100644 --- a/drivers/platform/x86/amd/pmc/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c @@ -296,6 +296,13 @@ static const struct dmi_system_id fwbug_list[] = { DMI_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"), } }, + { + .ident = "MECHREVO Wujie 15X Pro", + .driver_data = &quirk_spurious_8042, + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"), + } + }, {} }; -- Gitee From 4e73967e1ec237fe53500dfcc0ba5a2e64b86515 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 20 Jan 2026 23:43:44 +0800 Subject: [PATCH 1430/1449] platform/x86: panasonic-laptop: Fix sysfs group leak in error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 329bb274a3a9144d2fe5a16cdc9b3b05000116b3 stable. commit 43b0b7eff4b3fb684f257d5a24376782e9663465 upstream. The acpi_pcc_hotkey_add() error path leaks sysfs group pcc_attr_group if platform_device_register_simple() fails for the "panasonic" platform device. Address this by making it call sysfs_remove_group() in that case for the group in question. Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/3398370.44csPzL39Z@rafael.j.wysocki Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/platform/x86/panasonic-laptop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 7365286f6d2d..ad907c558997 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -1077,7 +1077,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) PLATFORM_DEVID_NONE, NULL, 0); if (IS_ERR(pcc->platform)) { result = PTR_ERR(pcc->platform); - goto out_backlight; + goto out_sysfs; } result = device_create_file(&pcc->platform->dev, &dev_attr_cdpower); @@ -1093,6 +1093,8 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) out_platform: platform_device_unregister(pcc->platform); +out_sysfs: + sysfs_remove_group(&device->dev.kobj, &pcc_attr_group); out_backlight: backlight_device_unregister(pcc->backlight); out_input: -- Gitee From d1888bb27c6fa0aea76614acc8920131bb1bbdb5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 30 Jan 2026 23:09:27 +0800 Subject: [PATCH 1431/1449] ASoC: cs42l43: Correct handling of 3-pole jack load detection ANBZ: #35228 commit f49d2497da140a4dbb7d6373264553ea04b37691 stable. commit e77a4081d7e324dfa876a9560b2a78969446ba82 upstream. The load detection process for 3-pole jacks requires slightly updated reference values to ensure an accurate result. Update the code to apply different tunings for the 3-pole and 4-pole cases. This also updates the thresholds overall so update the relevant comments to match. Signed-off-by: Charles Keepax Link: https://patch.msgid.link/20260130150927.2964664-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/codecs/cs42l43-jack.c | 37 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c index 6d8455c1bee6..f58d55d77693 100644 --- a/sound/soc/codecs/cs42l43-jack.c +++ b/sound/soc/codecs/cs42l43-jack.c @@ -496,7 +496,23 @@ void cs42l43_bias_sense_timeout(struct work_struct *work) pm_runtime_put_autosuspend(priv->dev); } -static void cs42l43_start_load_detect(struct cs42l43_codec *priv) +static const struct reg_sequence cs42l43_3pole_patch[] = { + { 0x4000, 0x00000055 }, + { 0x4000, 0x000000AA }, + { 0x17420, 0x8500F300 }, + { 0x17424, 0x36003E00 }, + { 0x4000, 0x00000000 }, +}; + +static const struct reg_sequence cs42l43_4pole_patch[] = { + { 0x4000, 0x00000055 }, + { 0x4000, 0x000000AA }, + { 0x17420, 0x7800E600 }, + { 0x17424, 0x36003800 }, + { 0x4000, 0x00000000 }, +}; + +static void cs42l43_start_load_detect(struct cs42l43_codec *priv, bool mic) { struct cs42l43 *cs42l43 = priv->core; @@ -520,6 +536,15 @@ static void cs42l43_start_load_detect(struct cs42l43_codec *priv) dev_err(priv->dev, "Load detect HP power down timed out\n"); } + if (mic) + regmap_multi_reg_write_bypassed(cs42l43->regmap, + cs42l43_4pole_patch, + ARRAY_SIZE(cs42l43_4pole_patch)); + else + regmap_multi_reg_write_bypassed(cs42l43->regmap, + cs42l43_3pole_patch, + ARRAY_SIZE(cs42l43_3pole_patch)); + regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3, CS42L43_ADC1_EN_MASK | CS42L43_ADC2_EN_MASK, 0); regmap_update_bits(cs42l43->regmap, CS42L43_DACCNFG2, CS42L43_HP_HPF_EN_MASK, 0); @@ -598,7 +623,7 @@ static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic) reinit_completion(&priv->load_detect); - cs42l43_start_load_detect(priv); + cs42l43_start_load_detect(priv, mic); time_left = wait_for_completion_timeout(&priv->load_detect, msecs_to_jiffies(CS42L43_LOAD_TIMEOUT_MS)); cs42l43_stop_load_detect(priv); @@ -622,11 +647,11 @@ static int cs42l43_run_load_detect(struct cs42l43_codec *priv, bool mic) } switch (val & CS42L43_AMP3_RES_DET_MASK) { - case 0x0: // low impedance - case 0x1: // high impedance + case 0x0: // < 22 Ohm impedance + case 0x1: // < 150 Ohm impedance + case 0x2: // < 1000 Ohm impedance return CS42L43_JACK_HEADPHONE; - case 0x2: // lineout - case 0x3: // Open circuit + case 0x3: // > 1000 Ohm impedance return CS42L43_JACK_LINEOUT; default: return -EINVAL; -- Gitee From 8e54724f4e316f2afba7f122660b287092cafce8 Mon Sep 17 00:00:00 2001 From: Ziyi Guo Date: Tue, 3 Feb 2026 01:41:12 +0800 Subject: [PATCH 1432/1449] ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put() ANBZ: #35228 commit 61e007657bf7740d54ca2aadce0fb5997839818e stable. commit f514248727606b9087bc38a284ff686e0093abf1 upstream. fsl_xcvr_activate_ctl() has lockdep_assert_held(&card->snd_card->controls_rwsem), but fsl_xcvr_mode_put() calls it without acquiring this lock. Other callers of fsl_xcvr_activate_ctl() in fsl_xcvr_startup() and fsl_xcvr_shutdown() properly acquire the lock with down_read()/up_read(). Add the missing down_read()/up_read() calls around fsl_xcvr_activate_ctl() in fsl_xcvr_mode_put() to fix the lockdep assertion and prevent potential race conditions when multiple userspace threads access the control. Signed-off-by: Ziyi Guo Link: https://patch.msgid.link/20260202174112.2018402-1-n7l8m4@u.northwestern.edu Signed-off-by: Mark Brown Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- sound/soc/fsl/fsl_xcvr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 90a0a24c05d8..3a5ab8b53672 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -206,10 +206,13 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + down_read(&card->snd_card->controls_rwsem); fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, (xcvr->mode == FSL_XCVR_MODE_ARC)); fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, (xcvr->mode == FSL_XCVR_MODE_EARC)); + up_read(&card->snd_card->controls_rwsem); + /* Allow playback for SPDIF only */ rtd = snd_soc_get_pcm_runtime(card, card->dai_link); rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = -- Gitee From c01906ca92eff699bf9aca9169e57e683e14d3b9 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Thu, 29 Jan 2026 22:59:44 +0800 Subject: [PATCH 1433/1449] gpiolib: acpi: Fix gpio count with string references ANBZ: #35228 commit 16f137fb74c178799271cb7c34e2eebe7dc0651f stable. commit c62e0658d458d8f100445445c3ddb106f3824a45 upstream. Since commit 9880702d123f2 ("ACPI: property: Support using strings in reference properties") it is possible to use strings instead of local references. This work fine with single GPIO but not with arrays as acpi_gpio_package_count() didn't handle this case. Update it to handle strings like local references to cover this case as well. Signed-off-by: Alban Bedel Reviewed-by: Mika Westerberg Link: https://patch.msgid.link/20260129145944.3372777-1-alban.bedel@lht.dlh.de Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/gpio/gpiolib-acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 69d4297ae575..4d4757eac9e5 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -1417,6 +1417,7 @@ static int acpi_gpio_package_count(const union acpi_object *obj) while (element < end) { switch (element->type) { case ACPI_TYPE_LOCAL_REFERENCE: + case ACPI_TYPE_STRING: element += 3; fallthrough; case ACPI_TYPE_INTEGER: -- Gitee From 928a0210e13739d3711d13a1e14536dce00a96b8 Mon Sep 17 00:00:00 2001 From: Kanglong Wang Date: Tue, 12 Nov 2024 16:35:39 +0800 Subject: [PATCH 1434/1449] LoongArch: Add WriteCombine shadow mapping in KASAN ANBZ: #35228 commit f507fc06c7cd440724f740dd29f6f1d7046b862e stable. commit 139d42ca51018c1d43ab5f35829179f060d1ab31 upstream. Currently, the kernel couldn't boot when ARCH_IOREMAP, ARCH_WRITECOMBINE and KASAN are enabled together. Because DMW2 is used by kernel now which is configured as 0xa000000000000000 for WriteCombine, but KASAN has no segment mapping for it. This patch fix this issue. Solution: Add the relevant definitions for WriteCombine (DMW2) in KASAN. Cc: stable@vger.kernel.org Fixes: 8e02c3b782ec ("LoongArch: Add writecombine support for DMW-based ioremap()") Signed-off-by: Kanglong Wang Signed-off-by: Huacai Chen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- arch/loongarch/include/asm/kasan.h | 11 ++++++++++- arch/loongarch/mm/kasan_init.c | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/include/asm/kasan.h b/arch/loongarch/include/asm/kasan.h index cb74a47f620e..7f52bd31b9d4 100644 --- a/arch/loongarch/include/asm/kasan.h +++ b/arch/loongarch/include/asm/kasan.h @@ -25,6 +25,7 @@ /* 64-bit segment value. */ #define XKPRANGE_UC_SEG (0x8000) #define XKPRANGE_CC_SEG (0x9000) +#define XKPRANGE_WC_SEG (0xa000) #define XKVRANGE_VC_SEG (0xffff) /* Cached */ @@ -41,10 +42,17 @@ #define XKPRANGE_UC_SHADOW_SIZE (XKPRANGE_UC_SIZE >> KASAN_SHADOW_SCALE_SHIFT) #define XKPRANGE_UC_SHADOW_END (XKPRANGE_UC_KASAN_OFFSET + XKPRANGE_UC_SHADOW_SIZE) +/* WriteCombine */ +#define XKPRANGE_WC_START WRITECOMBINE_BASE +#define XKPRANGE_WC_SIZE XRANGE_SIZE +#define XKPRANGE_WC_KASAN_OFFSET XKPRANGE_UC_SHADOW_END +#define XKPRANGE_WC_SHADOW_SIZE (XKPRANGE_WC_SIZE >> KASAN_SHADOW_SCALE_SHIFT) +#define XKPRANGE_WC_SHADOW_END (XKPRANGE_WC_KASAN_OFFSET + XKPRANGE_WC_SHADOW_SIZE) + /* VMALLOC (Cached or UnCached) */ #define XKVRANGE_VC_START MODULES_VADDR #define XKVRANGE_VC_SIZE round_up(KFENCE_AREA_END - MODULES_VADDR + 1, PGDIR_SIZE) -#define XKVRANGE_VC_KASAN_OFFSET XKPRANGE_UC_SHADOW_END +#define XKVRANGE_VC_KASAN_OFFSET XKPRANGE_WC_SHADOW_END #define XKVRANGE_VC_SHADOW_SIZE (XKVRANGE_VC_SIZE >> KASAN_SHADOW_SCALE_SHIFT) #define XKVRANGE_VC_SHADOW_END (XKVRANGE_VC_KASAN_OFFSET + XKVRANGE_VC_SHADOW_SIZE) @@ -55,6 +63,7 @@ #define XKPRANGE_CC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_CC_KASAN_OFFSET) #define XKPRANGE_UC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_UC_KASAN_OFFSET) +#define XKPRANGE_WC_SHADOW_OFFSET (KASAN_SHADOW_START + XKPRANGE_WC_KASAN_OFFSET) #define XKVRANGE_VC_SHADOW_OFFSET (KASAN_SHADOW_START + XKVRANGE_VC_KASAN_OFFSET) extern bool kasan_early_stage; diff --git a/arch/loongarch/mm/kasan_init.c b/arch/loongarch/mm/kasan_init.c index 853a004a45cf..6dd5bc8690b3 100644 --- a/arch/loongarch/mm/kasan_init.c +++ b/arch/loongarch/mm/kasan_init.c @@ -59,6 +59,9 @@ void *kasan_mem_to_shadow(const void *addr) case XKPRANGE_UC_SEG: offset = XKPRANGE_UC_SHADOW_OFFSET; break; + case XKPRANGE_WC_SEG: + offset = XKPRANGE_WC_SHADOW_OFFSET; + break; case XKVRANGE_VC_SEG: offset = XKVRANGE_VC_SHADOW_OFFSET; break; @@ -82,6 +85,8 @@ const void *kasan_shadow_to_mem(const void *shadow_addr) if (addr >= XKVRANGE_VC_SHADOW_OFFSET) return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START); + else if (addr >= XKPRANGE_WC_SHADOW_OFFSET) + return (void *)(((addr - XKPRANGE_WC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_WC_START); else if (addr >= XKPRANGE_UC_SHADOW_OFFSET) return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START); else if (addr >= XKPRANGE_CC_SHADOW_OFFSET) -- Gitee From 1755bd58b8eae888204082e20af3a2f278d9b42c Mon Sep 17 00:00:00 2001 From: Jane Chu Date: Tue, 16 Sep 2025 08:45:20 +0800 Subject: [PATCH 1435/1449] mm/hugetlb: fix copy_hugetlb_page_range() to use ->pt_share_count ANBZ: #35228 commit 8c9a1b0710510c3cc25526c815ca798705cb1936 stable. commit 14967a9c7d247841b0312c48dcf8cd29e55a4cc8 upstream. commit 59d9094df3d79 ("mm: hugetlb: independent PMD page table shared count") introduced ->pt_share_count dedicated to hugetlb PMD share count tracking, but omitted fixing copy_hugetlb_page_range(), leaving the function relying on page_count() for tracking that no longer works. When lazy page table copy for hugetlb is disabled, that is, revert commit bcd51a3c679d ("hugetlb: lazy page table copies in fork()") fork()'ing with hugetlb PMD sharing quickly lockup - [ 239.446559] watchdog: BUG: soft lockup - CPU#75 stuck for 27s! [ 239.446611] RIP: 0010:native_queued_spin_lock_slowpath+0x7e/0x2e0 [ 239.446631] Call Trace: [ 239.446633] [ 239.446636] _raw_spin_lock+0x3f/0x60 [ 239.446639] copy_hugetlb_page_range+0x258/0xb50 [ 239.446645] copy_page_range+0x22b/0x2c0 [ 239.446651] dup_mmap+0x3e2/0x770 [ 239.446654] dup_mm.constprop.0+0x5e/0x230 [ 239.446657] copy_process+0xd17/0x1760 [ 239.446660] kernel_clone+0xc0/0x3e0 [ 239.446661] __do_sys_clone+0x65/0xa0 [ 239.446664] do_syscall_64+0x82/0x930 [ 239.446668] ? count_memcg_events+0xd2/0x190 [ 239.446671] ? syscall_trace_enter+0x14e/0x1f0 [ 239.446676] ? syscall_exit_work+0x118/0x150 [ 239.446677] ? arch_exit_to_user_mode_prepare.constprop.0+0x9/0xb0 [ 239.446681] ? clear_bhb_loop+0x30/0x80 [ 239.446684] ? clear_bhb_loop+0x30/0x80 [ 239.446686] entry_SYSCALL_64_after_hwframe+0x76/0x7e There are two options to resolve the potential latent issue: 1. warn against PMD sharing in copy_hugetlb_page_range(), 2. fix it. This patch opts for the second option. While at it, simplify the comment, the details are not actually relevant anymore. Link: https://lkml.kernel.org/r/20250916004520.1604530-1-jane.chu@oracle.com Fixes: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count") Signed-off-by: Jane Chu Reviewed-by: Harry Yoo Acked-by: Oscar Salvador Acked-by: David Hildenbrand Cc: Jann Horn Cc: Liu Shixin Cc: Muchun Song Signed-off-by: Andrew Morton Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/mm_types.h | 5 +++++ mm/hugetlb.c | 15 +++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 73b5f691f331..89fe178215f3 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -538,6 +538,11 @@ static inline int ptdesc_pmd_pts_count(struct ptdesc *ptdesc) { return atomic_read(&ptdesc->pt_share_count); } + +static inline bool ptdesc_pmd_is_shared(struct ptdesc *ptdesc) +{ + return !!ptdesc_pmd_pts_count(ptdesc); +} #else static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc) { diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 6c9f257820d4..3e94101e8cce 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5197,18 +5197,13 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, break; } - /* - * If the pagetables are shared don't copy or take references. - * - * dst_pte == src_pte is the common case of src/dest sharing. - * However, src could have 'unshared' and dst shares with - * another vma. So page_count of ptep page is checked instead - * to reliably determine whether pte is shared. - */ - if (page_count(virt_to_page(dst_pte)) > 1) { +#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING + /* If the pagetables are shared, there is nothing to do */ + if (ptdesc_pmd_is_shared(virt_to_ptdesc(dst_pte))) { addr |= last_addr_mask; continue; } +#endif dst_ptl = huge_pte_lock(h, dst, dst_pte); src_ptl = huge_pte_lockptr(h, src, src_pte); @@ -7211,7 +7206,7 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, hugetlb_vma_assert_locked(vma); if (sz != PMD_SIZE) return 0; - if (!ptdesc_pmd_pts_count(virt_to_ptdesc(ptep))) + if (!ptdesc_pmd_is_shared(virt_to_ptdesc(ptep))) return 0; pud_clear(pud); -- Gitee From dd7d26a66b0e6975c28879a22cf0caccda2d703e Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (Red Hat)" Date: Wed, 24 Dec 2025 05:40:34 +0800 Subject: [PATCH 1436/1449] mm/hugetlb: fix hugetlb_pmd_shared() ANBZ: #35228 commit 51dcf459845fd28f5a0d83d408a379b274ec5cc5 stable. commit ca1a47cd3f5f4c46ca188b1c9a27af87d1ab2216 upstream. Patch series "mm/hugetlb: fixes for PMD table sharing (incl. using mmu_gather)", v3. One functional fix, one performance regression fix, and two related comment fixes. I cleaned up my prototype I recently shared [1] for the performance fix, deferring most of the cleanups I had in the prototype to a later point. While doing that I identified the other things. The goal of this patch set is to be backported to stable trees "fairly" easily. At least patch #1 and #4. Patch #1 fixes hugetlb_pmd_shared() not detecting any sharing Patch #2 + #3 are simple comment fixes that patch #4 interacts with. Patch #4 is a fix for the reported performance regression due to excessive IPI broadcasts during fork()+exit(). The last patch is all about TLB flushes, IPIs and mmu_gather. Read: complicated There are plenty of cleanups in the future to be had + one reasonable optimization on x86. But that's all out of scope for this series. Runtime tested, with a focus on fixing the performance regression using the original reproducer [2] on x86. This patch (of 4): We switched from (wrongly) using the page count to an independent shared count. Now, shared page tables have a refcount of 1 (excluding speculative references) and instead use ptdesc->pt_share_count to identify sharing. We didn't convert hugetlb_pmd_shared(), so right now, we would never detect a shared PMD table as such, because sharing/unsharing no longer touches the refcount of a PMD table. Page migration, like mbind() or migrate_pages() would allow for migrating folios mapped into such shared PMD tables, even though the folios are not exclusive. In smaps we would account them as "private" although they are "shared", and we would be wrongly setting the PM_MMAP_EXCLUSIVE in the pagemap interface. Fix it by properly using ptdesc_pmd_is_shared() in hugetlb_pmd_shared(). Link: https://lkml.kernel.org/r/20251223214037.580860-1-david@kernel.org Link: https://lkml.kernel.org/r/20251223214037.580860-2-david@kernel.org Link: https://lore.kernel.org/all/8cab934d-4a56-44aa-b641-bfd7e23bd673@kernel.org/ [1] Link: https://lore.kernel.org/all/8cab934d-4a56-44aa-b641-bfd7e23bd673@kernel.org/ [2] Fixes: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count") Signed-off-by: David Hildenbrand (Red Hat) Reviewed-by: Rik van Riel Reviewed-by: Lance Yang Tested-by: Lance Yang Reviewed-by: Harry Yoo Tested-by: Laurence Oberman Reviewed-by: Lorenzo Stoakes Acked-by: Oscar Salvador Cc: Liu Shixin Cc: "Uschakow, Stanislav" Cc: Signed-off-by: Andrew Morton Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- include/linux/hugetlb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index dbd3c7651185..26f63df596ff 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -1302,7 +1302,7 @@ static inline __init void hugetlb_cma_reserve(int order) #ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING static inline bool hugetlb_pmd_shared(pte_t *pte) { - return page_count(virt_to_page(pte)) > 1; + return ptdesc_pmd_is_shared(virt_to_ptdesc(pte)); } #else static inline bool hugetlb_pmd_shared(pte_t *pte) -- Gitee From 81e618798e05212e05672864f063caab7862faa4 Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (Red Hat)" Date: Wed, 24 Dec 2025 05:40:35 +0800 Subject: [PATCH 1437/1449] mm/hugetlb: fix two comments related to huge_pmd_unshare() ANBZ: #35228 commit 2eeca9383efebb27c85a5ed12ba261c282f7a716 stable. commit 3937027caecb4f8251e82dd857ba1d749bb5a428 upstream. Ever since we stopped using the page count to detect shared PMD page tables, these comments are outdated. The only reason we have to flush the TLB early is because once we drop the i_mmap_rwsem, the previously shared page table could get freed (to then get reallocated and used for other purpose). So we really have to flush the TLB before that could happen. So let's simplify the comments a bit. The "If we unshared PMDs, the TLB flush was not recorded in mmu_gather." part introduced as in commit a4a118f2eead ("hugetlbfs: flush TLBs correctly after huge_pmd_unshare") was confusing: sure it is recorded in the mmu_gather, otherwise tlb_flush_mmu_tlbonly() wouldn't do anything. So let's drop that comment while at it as well. We'll centralize these comments in a single helper as we rework the code next. Link: https://lkml.kernel.org/r/20251223214037.580860-3-david@kernel.org Fixes: 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count") Signed-off-by: David Hildenbrand (Red Hat) Reviewed-by: Rik van Riel Tested-by: Laurence Oberman Reviewed-by: Lorenzo Stoakes Acked-by: Oscar Salvador Reviewed-by: Harry Yoo Cc: Liu Shixin Cc: Lance Yang Cc: "Uschakow, Stanislav" Cc: Signed-off-by: Andrew Morton Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- mm/hugetlb.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 3e94101e8cce..01822d9cd258 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5541,17 +5541,10 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, tlb_end_vma(tlb, vma); /* - * If we unshared PMDs, the TLB flush was not recorded in mmu_gather. We - * could defer the flush until now, since by holding i_mmap_rwsem we - * guaranteed that the last refernece would not be dropped. But we must - * do the flushing before we return, as otherwise i_mmap_rwsem will be - * dropped and the last reference to the shared PMDs page might be - * dropped as well. - * - * In theory we could defer the freeing of the PMD pages as well, but - * huge_pmd_unshare() relies on the exact page_count for the PMD page to - * detect sharing, so we cannot defer the release of the page either. - * Instead, do flush now. + * There is nothing protecting a previously-shared page table that we + * unshared through huge_pmd_unshare() from getting freed after we + * release i_mmap_rwsem, so flush the TLB now. If huge_pmd_unshare() + * succeeded, flush the range corresponding to the pud. */ if (force_flush) tlb_flush_mmu_tlbonly(tlb); @@ -6829,11 +6822,10 @@ long hugetlb_change_protection(struct vm_area_struct *vma, cond_resched(); } /* - * Must flush TLB before releasing i_mmap_rwsem: x86's huge_pmd_unshare - * may have cleared our pud entry and done put_page on the page table: - * once we release i_mmap_rwsem, another task can do the final put_page - * and that page table be reused and filled with junk. If we actually - * did unshare a page of pmds, flush the range corresponding to the pud. + * There is nothing protecting a previously-shared page table that we + * unshared through huge_pmd_unshare() from getting freed after we + * release i_mmap_rwsem, so flush the TLB now. If huge_pmd_unshare() + * succeeded, flush the range corresponding to the pud. */ if (shared_pmd) flush_hugetlb_tlb_range(vma, range.start, range.end); -- Gitee From 0645b12c57b46041a41958b5241070b2a5349a1c Mon Sep 17 00:00:00 2001 From: "David Hildenbrand (Red Hat)" Date: Tue, 23 Dec 2025 22:40:37 +0100 Subject: [PATCH 1438/1449] mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather ANBZ: #35228 commit ff37dd18ce7739a26aab0cc2d31006a45e6bde63 stable. commit 8ce720d5bd91e9dc16db3604aa4b1bf76770a9a1 upstream. As reported, ever since commit 1013af4f585f ("mm/hugetlb: fix huge_pmd_unshare() vs GUP-fast race") we can end up in some situations where we perform so many IPI broadcasts when unsharing hugetlb PMD page tables that it severely regresses some workloads. In particular, when we fork()+exit(), or when we munmap() a large area backed by many shared PMD tables, we perform one IPI broadcast per unshared PMD table. There are two optimizations to be had: (1) When we process (unshare) multiple such PMD tables, such as during exit(), it is sufficient to send a single IPI broadcast (as long as we respect locking rules) instead of one per PMD table. Locking prevents that any of these PMD tables could get reused before we drop the lock. (2) When we are not the last sharer (> 2 users including us), there is no need to send the IPI broadcast. The shared PMD tables cannot become exclusive (fully unshared) before an IPI will be broadcasted by the last sharer. Concurrent GUP-fast could walk into a PMD table just before we unshared it. It could then succeed in grabbing a page from the shared page table even after munmap() etc succeeded (and supressed an IPI). But there is not difference compared to GUP-fast just sleeping for a while after grabbing the page and re-enabling IRQs. Most importantly, GUP-fast will never walk into page tables that are no-longer shared, because the last sharer will issue an IPI broadcast. (if ever required, checking whether the PUD changed in GUP-fast after grabbing the page like we do in the PTE case could handle this) So let's rework PMD sharing TLB flushing + IPI sync to use the mmu_gather infrastructure so we can implement these optimizations and demystify the code at least a bit. Extend the mmu_gather infrastructure to be able to deal with our special hugetlb PMD table sharing implementation. To make initialization of the mmu_gather easier when working on a single VMA (in particular, when dealing with hugetlb), provide tlb_gather_mmu_vma(). We'll consolidate the handling for (full) unsharing of PMD tables in tlb_unshare_pmd_ptdesc() and tlb_flush_unshared_tables(), and track in "struct mmu_gather" whether we had (full) unsharing of PMD tables. Because locking is very special (concurrent unsharing+reuse must be prevented), we disallow deferring flushing to tlb_finish_mmu() and instead require an explicit earlier call to tlb_flush_unshared_tables(). From hugetlb code, we call huge_pmd_unshare_flush() where we make sure that the expected lock protecting us from concurrent unsharing+reuse is still held. Check with a VM_WARN_ON_ONCE() in tlb_finish_mmu() that tlb_flush_unshared_tables() was properly called earlier. Document it all properly. Notes about tlb_remove_table_sync_one() interaction with unsharing: There are two fairly tricky things: (1) tlb_remove_table_sync_one() is a NOP on architectures without CONFIG_MMU_GATHER_RCU_TABLE_FREE. Here, the assumption is that the previous TLB flush would send an IPI to all relevant CPUs. Careful: some architectures like x86 only send IPIs to all relevant CPUs when tlb->freed_tables is set. The relevant architectures should be selecting MMU_GATHER_RCU_TABLE_FREE, but x86 might not do that in stable kernels and it might have been problematic before this patch. Also, the arch flushing behavior (independent of IPIs) is different when tlb->freed_tables is set. Do we have to enlighten them to also take care of tlb->unshared_tables? So far we didn't care, so hopefully we are fine. Of course, we could be setting tlb->freed_tables as well, but that might then unnecessarily flush too much, because the semantics of tlb->freed_tables are a bit fuzzy. This patch changes nothing in this regard. (2) tlb_remove_table_sync_one() is not a NOP on architectures with CONFIG_MMU_GATHER_RCU_TABLE_FREE that actually don't need a sync. Take x86 as an example: in the common case (!pv, !X86_FEATURE_INVLPGB) we still issue IPIs during TLB flushes and don't actually need the second tlb_remove_table_sync_one(). This optimized can be implemented on top of this, by checking e.g., in tlb_remove_table_sync_one() whether we really need IPIs. But as described in (1), it really must honor tlb->freed_tables then to send IPIs to all relevant CPUs. Notes on TLB flushing changes: (1) Flushing for non-shared PMD tables We're converting from flush_hugetlb_tlb_range() to tlb_remove_huge_tlb_entry(). Given that we properly initialize the MMU gather in tlb_gather_mmu_vma() to be hugetlb aware, similar to __unmap_hugepage_range(), that should be fine. (2) Flushing for shared PMD tables We're converting from various things (flush_hugetlb_tlb_range(), tlb_flush_pmd_range(), flush_tlb_range()) to tlb_flush_pmd_range(). tlb_flush_pmd_range() achieves the same that tlb_remove_huge_tlb_entry() would achieve in these scenarios. Note that tlb_remove_huge_tlb_entry() also calls __tlb_remove_tlb_entry(), however that is only implemented on powerpc, which does not support PMD table sharing. Similar to (1), tlb_gather_mmu_vma() should make sure that TLB flushing keeps on working as expected. Further, note that the ptdesc_pmd_pts_dec() in huge_pmd_share() is not a concern, as we are holding the i_mmap_lock the whole time, preventing concurrent unsharing. That ptdesc_pmd_pts_dec() usage will be removed separately as a cleanup later. There are plenty more cleanups to be had, but they have to wait until this is fixed. [david@kernel.org: fix kerneldoc] Link: https://lkml.kernel.org/r/f223dd74-331c-412d-93fc-69e360a5006c@kernel.org Link: https://lkml.kernel.org/r/20251223214037.580860-5-david@kernel.org Fixes: 1013af4f585f ("mm/hugetlb: fix huge_pmd_unshare() vs GUP-fast race") Signed-off-by: David Hildenbrand (Red Hat) Reported-by: "Uschakow, Stanislav" Closes: https://lore.kernel.org/all/4d3878531c76479d9f8ca9789dc6485d@amazon.de/ Tested-by: Laurence Oberman Acked-by: Harry Yoo Reviewed-by: Lorenzo Stoakes Cc: Lance Yang Cc: Liu Shixin Cc: Oscar Salvador Cc: Rik van Riel Cc: Signed-off-by: Andrew Morton Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Greg Kroah-Hartman Signed-off-by: Weilin Tong --- include/asm-generic/tlb.h | 77 +++++++++++++++++++++++- include/linux/hugetlb.h | 15 +++-- include/linux/mm_types.h | 1 + mm/hugetlb.c | 123 ++++++++++++++++++++++---------------- mm/mmu_gather.c | 33 ++++++++++ mm/rmap.c | 25 +++++--- 6 files changed, 208 insertions(+), 66 deletions(-) diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h index e402aef79c93..0e0caf6f6fbd 100644 --- a/include/asm-generic/tlb.h +++ b/include/asm-generic/tlb.h @@ -46,7 +46,8 @@ * * The mmu_gather API consists of: * - * - tlb_gather_mmu() / tlb_gather_mmu_fullmm() / tlb_finish_mmu() + * - tlb_gather_mmu() / tlb_gather_mmu_fullmm() / tlb_gather_mmu_vma() / + * tlb_finish_mmu() * * start and finish a mmu_gather * @@ -360,6 +361,20 @@ struct mmu_gather { unsigned int vma_huge : 1; unsigned int vma_pfn : 1; + /* + * Did we unshare (unmap) any shared page tables? For now only + * used for hugetlb PMD table sharing. + */ + unsigned int unshared_tables : 1; + + /* + * Did we unshare any page tables such that they are now exclusive + * and could get reused+modified by the new owner? When setting this + * flag, "unshared_tables" will be set as well. For now only used + * for hugetlb PMD table sharing. + */ + unsigned int fully_unshared_tables : 1; + unsigned int batch_count; #ifndef CONFIG_MMU_GATHER_NO_GATHER @@ -396,6 +411,7 @@ static inline void __tlb_reset_range(struct mmu_gather *tlb) tlb->cleared_pmds = 0; tlb->cleared_puds = 0; tlb->cleared_p4ds = 0; + tlb->unshared_tables = 0; /* * Do not reset mmu_gather::vma_* fields here, we do not * call into tlb_start_vma() again to set them if there is an @@ -475,7 +491,7 @@ static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) * these bits. */ if (!(tlb->freed_tables || tlb->cleared_ptes || tlb->cleared_pmds || - tlb->cleared_puds || tlb->cleared_p4ds)) + tlb->cleared_puds || tlb->cleared_p4ds || tlb->unshared_tables)) return; tlb_flush(tlb); @@ -764,6 +780,63 @@ static inline bool huge_pmd_needs_flush(pmd_t oldpmd, pmd_t newpmd) } #endif +#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING +static inline void tlb_unshare_pmd_ptdesc(struct mmu_gather *tlb, struct ptdesc *pt, + unsigned long addr) +{ + /* + * The caller must make sure that concurrent unsharing + exclusive + * reuse is impossible until tlb_flush_unshared_tables() was called. + */ + VM_WARN_ON_ONCE(!ptdesc_pmd_is_shared(pt)); + ptdesc_pmd_pts_dec(pt); + + /* Clearing a PUD pointing at a PMD table with PMD leaves. */ + tlb_flush_pmd_range(tlb, addr & PUD_MASK, PUD_SIZE); + + /* + * If the page table is now exclusively owned, we fully unshared + * a page table. + */ + if (!ptdesc_pmd_is_shared(pt)) + tlb->fully_unshared_tables = true; + tlb->unshared_tables = true; +} + +static inline void tlb_flush_unshared_tables(struct mmu_gather *tlb) +{ + /* + * As soon as the caller drops locks to allow for reuse of + * previously-shared tables, these tables could get modified and + * even reused outside of hugetlb context, so we have to make sure that + * any page table walkers (incl. TLB, GUP-fast) are aware of that + * change. + * + * Even if we are not fully unsharing a PMD table, we must + * flush the TLB for the unsharer now. + */ + if (tlb->unshared_tables) + tlb_flush_mmu_tlbonly(tlb); + + /* + * Similarly, we must make sure that concurrent GUP-fast will not + * walk previously-shared page tables that are getting modified+reused + * elsewhere. So broadcast an IPI to wait for any concurrent GUP-fast. + * + * We only perform this when we are the last sharer of a page table, + * as the IPI will reach all CPUs: any GUP-fast. + * + * Note that on configs where tlb_remove_table_sync_one() is a NOP, + * the expectation is that the tlb_flush_mmu_tlbonly() would have issued + * required IPIs already for us. + */ + if (tlb->fully_unshared_tables) { + tlb_remove_table_sync_one(); + tlb->fully_unshared_tables = false; + } +} +#endif /* CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING */ + #endif /* CONFIG_MMU */ #endif /* _ASM_GENERIC__TLB_H */ diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 26f63df596ff..d4930ac86f70 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -241,8 +241,9 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); unsigned long hugetlb_mask_last_page(struct hstate *h); -int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep); +int huge_pmd_unshare(struct mmu_gather *tlb, struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep); +void huge_pmd_unshare_flush(struct mmu_gather *tlb, struct vm_area_struct *vma); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end); @@ -304,13 +305,17 @@ static inline struct address_space *hugetlb_folio_mapping_lock_write( return NULL; } -static inline int huge_pmd_unshare(struct mm_struct *mm, - struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) +static inline int huge_pmd_unshare(struct mmu_gather *tlb, + struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { return 0; } +static inline void huge_pmd_unshare_flush(struct mmu_gather *tlb, + struct vm_area_struct *vma) +{ +} + static inline void adjust_range_if_pmd_sharing_possible( struct vm_area_struct *vma, unsigned long *start, unsigned long *end) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 89fe178215f3..ffd80dd3908e 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -1291,6 +1291,7 @@ static inline unsigned int mm_cid_size(void) struct mmu_gather; extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); +void tlb_gather_mmu_vma(struct mmu_gather *tlb, struct vm_area_struct *vma); extern void tlb_finish_mmu(struct mmu_gather *tlb); struct vm_fault; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 01822d9cd258..1fe59e051e2e 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5375,7 +5375,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, unsigned long last_addr_mask; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; - bool shared_pmd = false; + struct mmu_gather tlb; mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm, old_addr, old_end); @@ -5385,6 +5385,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, * range. */ flush_cache_range(vma, range.start, range.end); + tlb_gather_mmu_vma(&tlb, vma); mmu_notifier_invalidate_range_start(&range); last_addr_mask = hugetlb_mask_last_page(h); @@ -5401,8 +5402,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, if (huge_pte_none(huge_ptep_get(mm, old_addr, src_pte))) continue; - if (huge_pmd_unshare(mm, vma, old_addr, src_pte)) { - shared_pmd = true; + if (huge_pmd_unshare(&tlb, vma, old_addr, src_pte)) { old_addr |= last_addr_mask; new_addr |= last_addr_mask; continue; @@ -5413,15 +5413,16 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, break; move_huge_pte(vma, old_addr, new_addr, src_pte, dst_pte, sz); + tlb_remove_huge_tlb_entry(h, &tlb, src_pte, old_addr); } - if (shared_pmd) - flush_hugetlb_tlb_range(vma, range.start, range.end); - else - flush_hugetlb_tlb_range(vma, old_end - len, old_end); + tlb_flush_mmu_tlbonly(&tlb); + huge_pmd_unshare_flush(&tlb, vma); + mmu_notifier_invalidate_range_end(&range); i_mmap_unlock_write(mapping); hugetlb_vma_unlock_write(vma); + tlb_finish_mmu(&tlb); return len + old_addr - old_end; } @@ -5439,7 +5440,6 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); unsigned long last_addr_mask; - bool force_flush = false; WARN_ON(!is_vm_hugetlb_page(vma)); BUG_ON(start & ~huge_page_mask(h)); @@ -5462,10 +5462,8 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, address, ptep)) { + if (huge_pmd_unshare(tlb, vma, address, ptep)) { spin_unlock(ptl); - tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); - force_flush = true; address |= last_addr_mask; continue; } @@ -5540,14 +5538,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, } tlb_end_vma(tlb, vma); - /* - * There is nothing protecting a previously-shared page table that we - * unshared through huge_pmd_unshare() from getting freed after we - * release i_mmap_rwsem, so flush the TLB now. If huge_pmd_unshare() - * succeeded, flush the range corresponding to the pud. - */ - if (force_flush) - tlb_flush_mmu_tlbonly(tlb); + huge_pmd_unshare_flush(tlb, vma); } void __hugetlb_zap_begin(struct vm_area_struct *vma, @@ -6707,11 +6698,11 @@ long hugetlb_change_protection(struct vm_area_struct *vma, pte_t pte; struct hstate *h = hstate_vma(vma); long pages = 0, psize = huge_page_size(h); - bool shared_pmd = false; struct mmu_notifier_range range; unsigned long last_addr_mask; bool uffd_wp = cp_flags & MM_CP_UFFD_WP; bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; + struct mmu_gather tlb; /* * In the case of shared PMDs, the area to flush could be beyond @@ -6724,6 +6715,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, BUG_ON(address >= end); flush_cache_range(vma, range.start, range.end); + tlb_gather_mmu_vma(&tlb, vma); mmu_notifier_invalidate_range_start(&range); hugetlb_vma_lock_write(vma); @@ -6748,7 +6740,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, } } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, address, ptep)) { + if (huge_pmd_unshare(&tlb, vma, address, ptep)) { /* * When uffd-wp is enabled on the vma, unshare * shouldn't happen at all. Warn about it if it @@ -6757,7 +6749,6 @@ long hugetlb_change_protection(struct vm_area_struct *vma, WARN_ON_ONCE(uffd_wp || uffd_wp_resolve); pages++; spin_unlock(ptl); - shared_pmd = true; address |= last_addr_mask; continue; } @@ -6809,6 +6800,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, pte = huge_pte_clear_uffd_wp(pte); huge_ptep_modify_prot_commit(vma, address, ptep, old_pte, pte); pages++; + tlb_remove_huge_tlb_entry(h, &tlb, ptep, address); } else { /* None pte */ if (unlikely(uffd_wp)) @@ -6821,16 +6813,9 @@ long hugetlb_change_protection(struct vm_area_struct *vma, cond_resched(); } - /* - * There is nothing protecting a previously-shared page table that we - * unshared through huge_pmd_unshare() from getting freed after we - * release i_mmap_rwsem, so flush the TLB now. If huge_pmd_unshare() - * succeeded, flush the range corresponding to the pud. - */ - if (shared_pmd) - flush_hugetlb_tlb_range(vma, range.start, range.end); - else - flush_hugetlb_tlb_range(vma, start, end); + + tlb_flush_mmu_tlbonly(&tlb); + huge_pmd_unshare_flush(&tlb, vma); /* * No need to call mmu_notifier_arch_invalidate_secondary_tlbs() we are * downgrading page table protection not changing it to point to a new @@ -6841,6 +6826,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, i_mmap_unlock_write(vma->vm_file->f_mapping); hugetlb_vma_unlock_write(vma); mmu_notifier_invalidate_range_end(&range); + tlb_finish_mmu(&tlb); return pages > 0 ? (pages << h->order) : pages; } @@ -7178,18 +7164,27 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, return pte; } -/* - * unmap huge page backed by shared pte. +/** + * huge_pmd_unshare - Unmap a pmd table if it is shared by multiple users + * @tlb: the current mmu_gather. + * @vma: the vma covering the pmd table. + * @addr: the address we are trying to unshare. + * @ptep: pointer into the (pmd) page table. + * + * Called with the page table lock held, the i_mmap_rwsem held in write mode + * and the hugetlb vma lock held in write mode. * - * Called with page table lock held. + * Note: The caller must call huge_pmd_unshare_flush() before dropping the + * i_mmap_rwsem. * - * returns: 1 successfully unmapped a shared pte page - * 0 the underlying pte page is not shared, or it is the last user + * Returns: 1 if it was a shared PMD table and it got unmapped, or 0 if it + * was not a shared PMD table. */ -int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) +int huge_pmd_unshare(struct mmu_gather *tlb, struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) { unsigned long sz = huge_page_size(hstate_vma(vma)); + struct mm_struct *mm = vma->vm_mm; pgd_t *pgd = pgd_offset(mm, addr); p4d_t *p4d = p4d_offset(pgd, addr); pud_t *pud = pud_offset(p4d, addr); @@ -7202,18 +7197,36 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, return 0; pud_clear(pud); - /* - * Once our caller drops the rmap lock, some other process might be - * using this page table as a normal, non-hugetlb page table. - * Wait for pending gup_fast() in other threads to finish before letting - * that happen. - */ - tlb_remove_table_sync_one(); - ptdesc_pmd_pts_dec(virt_to_ptdesc(ptep)); + + tlb_unshare_pmd_ptdesc(tlb, virt_to_ptdesc(ptep), addr); + mm_dec_nr_pmds(mm); return 1; } +/* + * huge_pmd_unshare_flush - Complete a sequence of huge_pmd_unshare() calls + * @tlb: the current mmu_gather. + * @vma: the vma covering the pmd table. + * + * Perform necessary TLB flushes or IPI broadcasts to synchronize PMD table + * unsharing with concurrent page table walkers. + * + * This function must be called after a sequence of huge_pmd_unshare() + * calls while still holding the i_mmap_rwsem. + */ +void huge_pmd_unshare_flush(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ + /* + * We must synchronize page table unsharing such that nobody will + * try reusing a previously-shared page table while it might still + * be in use by previous sharers (TLB, GUP_fast). + */ + i_mmap_assert_write_locked(vma->vm_file->f_mapping); + + tlb_flush_unshared_tables(tlb); +} + #else /* !CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING */ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, @@ -7222,12 +7235,16 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, return NULL; } -int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) +int huge_pmd_unshare(struct mmu_gather *tlb, struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) { return 0; } +void huge_pmd_unshare_flush(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ +} + void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end) { @@ -7460,6 +7477,7 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; struct mmu_notifier_range range; + struct mmu_gather tlb; unsigned long address; spinlock_t *ptl; pte_t *ptep; @@ -7471,6 +7489,8 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, return; flush_cache_range(vma, start, end); + tlb_gather_mmu_vma(&tlb, vma); + /* * No need to call adjust_range_if_pmd_sharing_possible(), because * we have already done the PUD_SIZE alignment. @@ -7489,10 +7509,10 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, if (!ptep) continue; ptl = huge_pte_lock(h, mm, ptep); - huge_pmd_unshare(mm, vma, address, ptep); + huge_pmd_unshare(&tlb, vma, address, ptep); spin_unlock(ptl); } - flush_hugetlb_tlb_range(vma, start, end); + huge_pmd_unshare_flush(&tlb, vma); if (take_locks) { i_mmap_unlock_write(vma->vm_file->f_mapping); hugetlb_vma_unlock_write(vma); @@ -7502,6 +7522,7 @@ static void hugetlb_unshare_pmds(struct vm_area_struct *vma, * Documentation/mm/mmu_notifier.rst. */ mmu_notifier_invalidate_range_end(&range); + tlb_finish_mmu(&tlb); } /* diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c index 7aa6f18c500b..a2f50a71cb63 100644 --- a/mm/mmu_gather.c +++ b/mm/mmu_gather.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -417,6 +418,7 @@ static void __tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, tlb->page_size = 0; #endif + tlb->fully_unshared_tables = 0; __tlb_reset_range(tlb); inc_tlb_flush_pending(tlb->mm); } @@ -450,6 +452,31 @@ void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm) __tlb_gather_mmu(tlb, mm, true); } +/** + * tlb_gather_mmu_vma - initialize an mmu_gather structure for operating on a + * single VMA + * @tlb: the mmu_gather structure to initialize + * @vma: the vm_area_struct + * + * Called to initialize an (on-stack) mmu_gather structure for operating on + * a single VMA. In contrast to tlb_gather_mmu(), calling this function will + * not require another call to tlb_start_vma(). In contrast to tlb_start_vma(), + * this function will *not* call flush_cache_range(). + * + * For hugetlb VMAs, this function will also initialize the mmu_gather + * page_size accordingly, not requiring a separate call to + * tlb_change_page_size(). + * + */ +void tlb_gather_mmu_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ + tlb_gather_mmu(tlb, vma->vm_mm); + tlb_update_vma_flags(tlb, vma); + if (is_vm_hugetlb_page(vma)) + /* All entries have the same size. */ + tlb_change_page_size(tlb, huge_page_size(hstate_vma(vma))); +} + /** * tlb_finish_mmu - finish an mmu_gather structure * @tlb: the mmu_gather structure to finish @@ -459,6 +486,12 @@ void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm) */ void tlb_finish_mmu(struct mmu_gather *tlb) { + /* + * We expect an earlier huge_pmd_unshare_flush() call to sort this out, + * due to complicated locking requirements with page table unsharing. + */ + VM_WARN_ON_ONCE(tlb->fully_unshared_tables); + /* * If there are parallel threads are doing PTE changes on same range * under non-exclusive lock (e.g., mmap_lock read-side) but defer TLB diff --git a/mm/rmap.c b/mm/rmap.c index 0ce21d315cc7..64fbabd67356 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -76,7 +76,7 @@ #include #include -#include +#include #define CREATE_TRACE_POINTS #include @@ -1846,13 +1846,17 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, * if unsuccessful. */ if (!anon) { + struct mmu_gather tlb; + VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); if (!hugetlb_vma_trylock_write(vma)) goto walk_abort; - if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { + + tlb_gather_mmu_vma(&tlb, vma); + if (huge_pmd_unshare(&tlb, vma, address, pvmw.pte)) { hugetlb_vma_unlock_write(vma); - flush_tlb_range(vma, - range.start, range.end); + huge_pmd_unshare_flush(&tlb, vma); + tlb_finish_mmu(&tlb); /* * The PMD table was unmapped, * consequently unmapping the folio. @@ -1860,6 +1864,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, goto walk_done; } hugetlb_vma_unlock_write(vma); + tlb_finish_mmu(&tlb); } pteval = huge_ptep_clear_flush(vma, address, pvmw.pte); } else { @@ -2242,17 +2247,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, * fail if unsuccessful. */ if (!anon) { + struct mmu_gather tlb; + VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); if (!hugetlb_vma_trylock_write(vma)) { page_vma_mapped_walk_done(&pvmw); ret = false; break; } - if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { - hugetlb_vma_unlock_write(vma); - flush_tlb_range(vma, - range.start, range.end); + tlb_gather_mmu_vma(&tlb, vma); + if (huge_pmd_unshare(&tlb, vma, address, pvmw.pte)) { + hugetlb_vma_unlock_write(vma); + huge_pmd_unshare_flush(&tlb, vma); + tlb_finish_mmu(&tlb); /* * The PMD table was unmapped, * consequently unmapping the folio. @@ -2261,6 +2269,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, break; } hugetlb_vma_unlock_write(vma); + tlb_finish_mmu(&tlb); } /* Nuke the hugetlb page table entry */ pteval = huge_ptep_clear_flush(vma, address, pvmw.pte); -- Gitee From 5ced36e54f36c04de9075e63d817bd567a90ec84 Mon Sep 17 00:00:00 2001 From: Chen Ridong Date: Wed, 14 Jan 2026 09:51:29 +0800 Subject: [PATCH 1439/1449] cpuset: Fix missing adaptation for cpuset_is_populated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #35228 commit 6e5eccdef67ee879d7c0474c7e19e8b683f27dbe stable. Commit b1bcaed1e39a ("cpuset: Treat cpusets in attaching as populated") was backported to the long‑term support (LTS) branches. However, because commit d5cf4d34a333 ("cgroup/cpuset: Don't track # of local child partitions") was not backported, a corresponding adaptation to the backported code is still required. To ensure correct behavior, replace cgroup_is_populated with cpuset_is_populated in the partition_is_populated function. Cc: stable@vger.kernel.org # 6.1+ Fixes: b1bcaed1e39a ("cpuset: Treat cpusets in attaching as populated") Cc: Waiman Long Cc: Tejun Heo Signed-off-by: Chen Ridong Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- kernel/cgroup/cpuset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 8c0bbbc1e1e4..38aa58d32e4d 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -487,7 +487,7 @@ static inline bool partition_is_populated(struct cpuset *cs, cs->attach_in_progress) return true; if (!excluded_child && !cs->nr_subparts_cpus) - return cgroup_is_populated(cs->css.cgroup); + return cpuset_is_populated(cs); rcu_read_lock(); cpuset_for_each_descendant_pre(cp, pos_css, cs) { -- Gitee From 4e078ab1debed71c24fbb5196f6a5d3f70d3cc55 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Sun, 7 Dec 2025 15:25:32 +0800 Subject: [PATCH 1440/1449] fbdev: rivafb: fix divide error in nv3_arb() ANBZ: #35228 commit 78daf5984d96edec3b920c72a93bd6821b8710b7 stable. commit 0209e21e3c372fa2da04c39214bec0b64e4eb5f4 upstream. A userspace program can trigger the RIVA NV3 arbitration code by calling the FBIOPUT_VSCREENINFO ioctl on /dev/fb*. When doing so, the driver recomputes FIFO arbitration parameters in nv3_arb(), using state->mclk_khz (derived from the PRAMDAC MCLK PLL) as a divisor without validating it first. In a normal setup, state->mclk_khz is provided by the real hardware and is non-zero. However, an attacker can construct a malicious or misconfigured device (e.g. a crafted/emulated PCI device) that exposes a bogus PLL configuration, causing state->mclk_khz to become zero. Once nv3_get_param() calls nv3_arb(), the division by state->mclk_khz in the gns calculation causes a divide error and crashes the kernel. Fix this by checking whether state->mclk_khz is zero and bailing out before doing the division. The following log reveals it: rivafb: setting virtual Y resolution to 2184 divide error: 0000 [#1] PREEMPT SMP KASAN PTI CPU: 0 PID: 2187 Comm: syz-executor.0 Not tainted 5.18.0-rc1+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 RIP: 0010:nv3_arb drivers/video/fbdev/riva/riva_hw.c:439 [inline] RIP: 0010:nv3_get_param+0x3ab/0x13b0 drivers/video/fbdev/riva/riva_hw.c:546 Call Trace: nv3CalcArbitration.constprop.0+0x255/0x460 drivers/video/fbdev/riva/riva_hw.c:603 nv3UpdateArbitrationSettings drivers/video/fbdev/riva/riva_hw.c:637 [inline] CalcStateExt+0x447/0x1b90 drivers/video/fbdev/riva/riva_hw.c:1246 riva_load_video_mode+0x8a9/0xea0 drivers/video/fbdev/riva/fbdev.c:779 rivafb_set_par+0xc0/0x5f0 drivers/video/fbdev/riva/fbdev.c:1196 fb_set_var+0x604/0xeb0 drivers/video/fbdev/core/fbmem.c:1033 do_fb_ioctl+0x234/0x670 drivers/video/fbdev/core/fbmem.c:1109 fb_ioctl+0xdd/0x130 drivers/video/fbdev/core/fbmem.c:1188 __x64_sys_ioctl+0x122/0x190 fs/ioctl.c:856 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/fbdev/riva/riva_hw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c index 8b829b720064..f292079566cf 100644 --- a/drivers/video/fbdev/riva/riva_hw.c +++ b/drivers/video/fbdev/riva/riva_hw.c @@ -436,6 +436,9 @@ static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_in vmisses = 2; eburst_size = state->memory_width * 1; mburst_size = 32; + if (!state->mclk_khz) + return (0); + gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000; ainfo->wcmocc = 0; -- Gitee From 7e889019ece85234969c147478f684739e4b35ab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 28 Dec 2025 21:17:03 +0800 Subject: [PATCH 1441/1449] fbdev: smscufx: properly copy ioctl memory to kernelspace ANBZ: #35228 commit 0634e8d650993602fc5b389ff7ac525f6542e141 stable. commit 120adae7b42faa641179270c067864544a50ab69 upstream. The UFX_IOCTL_REPORT_DAMAGE ioctl does not properly copy data from userspace to kernelspace, and instead directly references the memory, which can cause problems if invalid data is passed from userspace. Fix this all up by correctly copying the memory before accessing it within the kernel. Reported-by: Tianchu Chen Cc: stable Cc: Steve Glendinning Cc: Helge Deller Signed-off-by: Greg Kroah-Hartman Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/video/fbdev/smscufx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index 387d18706fec..b590763b0108 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -988,7 +988,6 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct ufx_data *dev = info->par; - struct dloarea *area = NULL; if (!atomic_read(&dev->usb_active)) return 0; @@ -1003,6 +1002,10 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, /* TODO: Help propose a standard fb.h ioctl to report mmap damage */ if (cmd == UFX_IOCTL_REPORT_DAMAGE) { + struct dloarea *area __free(kfree) = kmalloc(sizeof(*area), GFP_KERNEL); + if (!area) + return -ENOMEM; + /* If we have a damage-aware client, turn fb_defio "off" * To avoid perf imact of unnecessary page fault handling. * Done by resetting the delay for this fb_info to a very @@ -1012,7 +1015,8 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, if (info->fbdefio) info->fbdefio->delay = UFX_DEFIO_WRITE_DISABLE; - area = (struct dloarea *)arg; + if (copy_from_user(area, (u8 __user *)arg, sizeof(*area))) + return -EFAULT; if (area->x < 0) area->x = 0; -- Gitee From 48e0f623dc8835d47da2a9cba0bd409a4f93ee07 Mon Sep 17 00:00:00 2001 From: Zhiguo Niu Date: Fri, 26 Dec 2025 10:56:04 +0800 Subject: [PATCH 1442/1449] f2fs: fix to add gc count stat in f2fs_gc_range ANBZ: #35228 commit 81193503af1fb9102fdd0c5f906af4dc39551e21 stable. commit 761dac9073cd67d4705a94cd1af674945a117f4c upstream. It missed the stat count in f2fs_gc_range. Cc: stable@kernel.org Fixes: 9bf1dcbdfdc8 ("f2fs: fix to account gc stats correctly") Signed-off-by: Zhiguo Niu Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/gc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index e99041582414..8122135bb1ff 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1998,6 +1998,7 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi, unsigned int segno; unsigned int gc_secs = dry_run_sections; + stat_inc_gc_call_count(sbi, FOREGROUND); for (segno = start_seg; segno <= end_seg; segno += SEGS_PER_SEC(sbi)) { struct gc_inode_list gc_list = { .ilist = LIST_HEAD_INIT(gc_list.ilist), -- Gitee From 41d0694891f5a2d0fec214eccad81484e79affba Mon Sep 17 00:00:00 2001 From: Yongpeng Yang Date: Wed, 7 Jan 2026 10:33:46 +0800 Subject: [PATCH 1443/1449] f2fs: fix out-of-bounds access in sysfs attribute read/write ANBZ: #35228 commit eebd72cff518ac87e660aefb8a41224bd88c32ce stable. commit 98ea0039dbfdd00e5cc1b9a8afa40434476c0955 upstream. Some f2fs sysfs attributes suffer from out-of-bounds memory access and incorrect handling of integer values whose size is not 4 bytes. For example: vm:~# echo 65537 > /sys/fs/f2fs/vde/carve_out vm:~# cat /sys/fs/f2fs/vde/carve_out 65537 vm:~# echo 4294967297 > /sys/fs/f2fs/vde/atgc_age_threshold vm:~# cat /sys/fs/f2fs/vde/atgc_age_threshold 1 carve_out maps to {struct f2fs_sb_info}->carve_out, which is a 8-bit integer. However, the sysfs interface allows setting it to a value larger than 255, resulting in an out-of-range update. atgc_age_threshold maps to {struct atgc_management}->age_threshold, which is a 64-bit integer, but its sysfs interface cannot correctly set values larger than UINT_MAX. The root causes are: 1. __sbi_store() treats all default values as unsigned int, which prevents updating integers larger than 4 bytes and causes out-of-bounds writes for integers smaller than 4 bytes. 2. f2fs_sbi_show() also assumes all default values are unsigned int, leading to out-of-bounds reads and incorrect access to integers larger than 4 bytes. This patch introduces {struct f2fs_attr}->size to record the actual size of the integer associated with each sysfs attribute. With this information, sysfs read and write operations can correctly access and update values according to their real data size, avoiding memory corruption and truncation. Fixes: b59d0bae6ca3 ("f2fs: add sysfs support for controlling the gc_thread") Cc: stable@kernel.org Signed-off-by: Jinbao Liu Signed-off-by: Yongpeng Yang Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/sysfs.c | 60 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index c4b0661888a1..436bbf23f8e7 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -58,6 +58,7 @@ struct f2fs_attr { const char *buf, size_t len); int struct_type; int offset; + int size; int id; }; @@ -285,11 +286,30 @@ static ssize_t main_blkaddr_show(struct f2fs_attr *a, (unsigned long long)MAIN_BLKADDR(sbi)); } +static ssize_t __sbi_show_value(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf, + unsigned char *value) +{ + switch (a->size) { + case 1: + return sysfs_emit(buf, "%u\n", *(u8 *)value); + case 2: + return sysfs_emit(buf, "%u\n", *(u16 *)value); + case 4: + return sysfs_emit(buf, "%u\n", *(u32 *)value); + case 8: + return sysfs_emit(buf, "%llu\n", *(u64 *)value); + default: + f2fs_bug_on(sbi, 1); + return sysfs_emit(buf, + "show sysfs node value with wrong type\n"); + } +} + static ssize_t f2fs_sbi_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { unsigned char *ptr = NULL; - unsigned int *ui; ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) @@ -372,9 +392,30 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, atomic_read(&sbi->cp_call_count[BACKGROUND])); #endif - ui = (unsigned int *)(ptr + a->offset); + return __sbi_show_value(a, sbi, buf, ptr + a->offset); +} - return sysfs_emit(buf, "%u\n", *ui); +static void __sbi_store_value(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, + unsigned char *ui, unsigned long value) +{ + switch (a->size) { + case 1: + *(u8 *)ui = value; + break; + case 2: + *(u16 *)ui = value; + break; + case 4: + *(u32 *)ui = value; + break; + case 8: + *(u64 *)ui = value; + break; + default: + f2fs_bug_on(sbi, 1); + f2fs_err(sbi, "store sysfs node value with wrong type"); + } } static ssize_t __sbi_store(struct f2fs_attr *a, @@ -746,7 +787,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a, return count; } - *ui = (unsigned int)t; + __sbi_store_value(a, sbi, ptr + a->offset, t); return count; } @@ -860,24 +901,27 @@ static struct f2fs_attr f2fs_attr_sb_##_name = { \ .id = F2FS_FEATURE_##_feat, \ } -#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ +#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset, _size) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ .struct_type = _struct_type, \ - .offset = _offset \ + .offset = _offset, \ + .size = _size \ } #define F2FS_RO_ATTR(struct_type, struct_name, name, elname) \ F2FS_ATTR_OFFSET(struct_type, name, 0444, \ f2fs_sbi_show, NULL, \ - offsetof(struct struct_name, elname)) + offsetof(struct struct_name, elname), \ + sizeof_field(struct struct_name, elname)) #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ F2FS_ATTR_OFFSET(struct_type, name, 0644, \ f2fs_sbi_show, f2fs_sbi_store, \ - offsetof(struct struct_name, elname)) + offsetof(struct struct_name, elname), \ + sizeof_field(struct struct_name, elname)) #define F2FS_GENERAL_RO_ATTR(name) \ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) -- Gitee From 27cf99cc5062508cd7f48ecd0088d1fa0cceb1fa Mon Sep 17 00:00:00 2001 From: Yongpeng Yang Date: Tue, 17 Feb 2026 23:45:24 +0800 Subject: [PATCH 1444/1449] f2fs: fix IS_CHECKPOINTED flag inconsistency issue caused by concurrent atomic commit and checkpoint writes ANBZ: #35228 commit 75e19da068adf0dc5dd269dd157392434b9117d4 stable. commit 7633a7387eb4d0259d6bea945e1d3469cd135bbc upstream. During SPO tests, when mounting F2FS, an -EINVAL error was returned from f2fs_recover_inode_page. The issue occurred under the following scenario Thread A Thread B f2fs_ioc_commit_atomic_write - f2fs_do_sync_file // atomic = true - f2fs_fsync_node_pages : last_folio = inode folio : schedule before folio_lock(last_folio) f2fs_write_checkpoint - block_operations// writeback last_folio - schedule before f2fs_flush_nat_entries : set_fsync_mark(last_folio, 1) : set_dentry_mark(last_folio, 1) : folio_mark_dirty(last_folio) - __write_node_folio(last_folio) : f2fs_down_read(&sbi->node_write)//block - f2fs_flush_nat_entries : {struct nat_entry}->flag |= BIT(IS_CHECKPOINTED) - unblock_operations : f2fs_up_write(&sbi->node_write) f2fs_write_checkpoint//return : f2fs_do_write_node_page() f2fs_ioc_commit_atomic_write//return SPO Thread A calls f2fs_need_dentry_mark(sbi, ino), and the last_folio has already been written once. However, the {struct nat_entry}->flag did not have the IS_CHECKPOINTED set, causing set_dentry_mark(last_folio, 1) and write last_folio again after Thread B finishes f2fs_write_checkpoint. After SPO and reboot, it was detected that {struct node_info}->blk_addr was not NULL_ADDR because Thread B successfully write the checkpoint. This issue only occurs in atomic write scenarios. For regular file fsync operations, the folio must be dirty. If block_operations->f2fs_sync_node_pages successfully submit the folio write, this path will not be executed. Otherwise, the f2fs_write_checkpoint will need to wait for the folio write submission to complete, as sbi->nr_pages[F2FS_DIRTY_NODES] > 0. Therefore, the situation where f2fs_need_dentry_mark checks that the {struct nat_entry}->flag /wo the IS_CHECKPOINTED flag, but the folio write has already been submitted, will not occur. Therefore, for atomic file fsync, sbi->node_write should be acquired through __write_node_folio to ensure that the IS_CHECKPOINTED flag correctly indicates that the checkpoint write has been completed. Fixes: 608514deba38 ("f2fs: set fsync mark only for the last dnode") Cc: stable@kernel.org Signed-off-by: Sheng Yong Signed-off-by: Jinbao Liu Signed-off-by: Yongpeng Yang Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim [ folio => page ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/node.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 1b404937743c..133141f10d94 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1696,8 +1696,13 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, goto redirty_out; } - if (atomic && !test_opt(sbi, NOBARRIER) && !f2fs_sb_has_blkzoned(sbi)) - fio.op_flags |= REQ_PREFLUSH | REQ_FUA; + if (atomic) { + if (!test_opt(sbi, NOBARRIER) && !f2fs_sb_has_blkzoned(sbi)) + fio.op_flags |= REQ_PREFLUSH | REQ_FUA; + if (IS_INODE(page)) + set_dentry_mark(page, + f2fs_need_dentry_mark(sbi, ino_of_node(page))); + } /* should add to global list before clearing PAGECACHE status */ if (f2fs_in_warm_node_list(sbi, page)) { @@ -1852,8 +1857,9 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, if (is_inode_flag_set(inode, FI_DIRTY_INODE)) f2fs_update_inode(inode, page); - set_dentry_mark(page, - f2fs_need_dentry_mark(sbi, ino)); + if (!atomic) + set_dentry_mark(page, + f2fs_need_dentry_mark(sbi, ino)); } /* may be written by other thread */ if (!PageDirty(page)) -- Gitee From 0478819f2c45237ddc30ae4863a3df31e091123c Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 17 Feb 2026 23:35:47 +0800 Subject: [PATCH 1445/1449] f2fs: fix to avoid UAF in f2fs_write_end_io() ANBZ: #35228 commit acc2c97fc0005846e5cf11b5ba3189fef130c9b3 stable. commit ce2739e482bce8d2c014d76c4531c877f382aa54 upstream. As syzbot reported an use-after-free issue in f2fs_write_end_io(). It is caused by below race condition: loop device umount - worker_thread - loop_process_work - do_req_filebacked - lo_rw_aio - lo_rw_aio_complete - blk_mq_end_request - blk_update_request - f2fs_write_end_io - dec_page_count - folio_end_writeback - kill_f2fs_super - kill_block_super - f2fs_put_super : free(sbi) : get_pages(, F2FS_WB_CP_DATA) accessed sbi which is freed In kill_f2fs_super(), we will drop all page caches of f2fs inodes before call free(sbi), it guarantee that all folios should end its writeback, so it should be safe to access sbi before last folio_end_writeback(). Let's relocate ckpt thread wakeup flow before folio_end_writeback() to resolve this issue. Cc: stable@kernel.org Fixes: e234088758fc ("f2fs: avoid wait if IO end up when do_checkpoint for better performance") Reported-by: syzbot+b4444e3c972a7a124187@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=b4444e3c972a7a124187 Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ folio => page ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 94017a6e08db..7bd2773a25e5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -358,14 +358,20 @@ static void f2fs_write_end_io(struct bio *bio) page->index != nid_of_node(page)); dec_page_count(sbi, type); + + /* + * we should access sbi before end_page_writeback() to + * avoid racing w/ kill_f2fs_super() + */ + if (type == F2FS_WB_CP_DATA && !get_pages(sbi, type) && + wq_has_sleeper(&sbi->cp_wait)) + wake_up(&sbi->cp_wait); + if (f2fs_in_warm_node_list(sbi, page)) f2fs_del_fsync_node_entry(sbi, page); clear_page_private_gcing(page); end_page_writeback(page); } - if (!get_pages(sbi, F2FS_WB_CP_DATA) && - wq_has_sleeper(&sbi->cp_wait)) - wake_up(&sbi->cp_wait); bio_put(bio); } -- Gitee From 09c7e957228eb9bf673b97c47c8865e04ddf1fde Mon Sep 17 00:00:00 2001 From: Wenjie Qi Date: Tue, 17 Feb 2026 23:20:31 +0800 Subject: [PATCH 1446/1449] f2fs: fix zoned block device information initialization ANBZ: #35228 commit 20a8bad29d18127890f7292f0638075103a21076 stable. commit 0f9b12142be1af8555cfe53c6fbecb8e60a40dac upstream. If the max open zones of zoned devices are less than the active logs of F2FS, the device may error due to insufficient zone resources when multiple active logs are being written at the same time. Signed-off-by: Wenjie Qi Signed-off-by: Chao Yu Reviewed-by: Daeho Jeong Signed-off-by: Jaegeuk Kim Stable-dep-of: 5c145c03188b ("f2fs: fix to avoid mapping wrong physical block for swapfile") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/f2fs.h | 1 + fs/f2fs/super.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9a4eabd11c73..d7afa8bc0ff8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1567,6 +1567,7 @@ struct f2fs_sb_info { #ifdef CONFIG_BLK_DEV_ZONED unsigned int blocks_per_blkz; /* F2FS blocks per zone */ + unsigned int max_open_zones; /* max open zone resources of the zoned device */ #endif /* for node-related operations */ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 9305bf465ddc..f9e6d001d574 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2374,6 +2374,17 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) if (err) goto restore_opts; +#ifdef CONFIG_BLK_DEV_ZONED + if (f2fs_sb_has_blkzoned(sbi) && + sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { + f2fs_err(sbi, + "zoned: max open zones %u is too small, need at least %u open zones", + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); + err = -EINVAL; + goto restore_opts; + } +#endif + /* flush outstanding errors before changing fs state */ flush_work(&sbi->s_error_work); @@ -3917,11 +3928,24 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) sector_t nr_sectors = bdev_nr_sectors(bdev); struct f2fs_report_zones_args rep_zone_arg; u64 zone_sectors; + unsigned int max_open_zones; int ret; if (!f2fs_sb_has_blkzoned(sbi)) return 0; + if (bdev_is_zoned(FDEV(devi).bdev)) { + max_open_zones = bdev_max_open_zones(bdev); + if (max_open_zones && (max_open_zones < sbi->max_open_zones)) + sbi->max_open_zones = max_open_zones; + if (sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) { + f2fs_err(sbi, + "zoned: max open zones %u is too small, need at least %u open zones", + sbi->max_open_zones, F2FS_OPTION(sbi).active_logs); + return -EINVAL; + } + } + zone_sectors = bdev_zone_sectors(bdev); if (sbi->blocks_per_blkz && sbi->blocks_per_blkz != SECTOR_TO_BLOCK(zone_sectors)) @@ -4203,6 +4227,9 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) logical_blksize = bdev_logical_block_size(sbi->sb->s_bdev); sbi->aligned_blksize = true; +#ifdef CONFIG_BLK_DEV_ZONED + sbi->max_open_zones = UINT_MAX; +#endif for (i = 0; i < max_devices; i++) { if (i == 0) -- Gitee From 7587b8110a699ddd8f5dc52ea0b3b66c4cd81a75 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 17 Feb 2026 23:20:32 +0800 Subject: [PATCH 1447/1449] f2fs: fix to avoid mapping wrong physical block for swapfile ANBZ: #35228 commit d4534a7f6c92baaf7e12a45fc6e37332cafafc33 stable. commit 5c145c03188bc9ba1c29e0bc4d527a5978fc47f9 upstream. Xiaolong Guo reported a f2fs bug in bugzilla [1] [1] https://bugzilla.kernel.org/show_bug.cgi?id=220951 Quoted: "When using stress-ng's swap stress test on F2FS filesystem with kernel 6.6+, the system experiences data corruption leading to either: 1 dm-verity corruption errors and device reboot 2 F2FS node corruption errors and boot hangs The issue occurs specifically when: 1 Using F2FS filesystem (ext4 is unaffected) 2 Swapfile size is less than F2FS section size (2MB) 3 Swapfile has fragmented physical layout (multiple non-contiguous extents) 4 Kernel version is 6.6+ (6.1 is unaffected) The root cause is in check_swap_activate() function in fs/f2fs/data.c. When the first extent of a small swapfile (< 2MB) is not aligned to section boundaries, the function incorrectly treats it as the last extent, failing to map subsequent extents. This results in incorrect swap_extent creation where only the first extent is mapped, causing subsequent swap writes to overwrite wrong physical locations (other files' data). Steps to Reproduce 1 Setup a device with F2FS-formatted userdata partition 2 Compile stress-ng from https://github.com/ColinIanKing/stress-ng 3 Run swap stress test: (Android devices) adb shell "cd /data/stressng; ./stress-ng-64 --metrics-brief --timeout 60 --swap 0" Log: 1 Ftrace shows in kernel 6.6, only first extent is mapped during second f2fs_map_blocks call in check_swap_activate(): stress-ng-swap-8990: f2fs_map_blocks: ino=11002, file offset=0, start blkaddr=0x43143, len=0x1 (Only 4KB mapped, not the full swapfile) 2 in kernel 6.1, both extents are correctly mapped: stress-ng-swap-5966: f2fs_map_blocks: ino=28011, file offset=0, start blkaddr=0x13cd4, len=0x1 stress-ng-swap-5966: f2fs_map_blocks: ino=28011, file offset=1, start blkaddr=0x60c84b, len=0xff The problematic code is in check_swap_activate(): if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec || nr_pblocks % blks_per_sec || !f2fs_valid_pinned_area(sbi, pblock)) { bool last_extent = false; not_aligned++; nr_pblocks = roundup(nr_pblocks, blks_per_sec); if (cur_lblock + nr_pblocks > sis->max) nr_pblocks -= blks_per_sec; /* this extent is last one */ if (!nr_pblocks) { nr_pblocks = last_lblock - cur_lblock; last_extent = true; } ret = f2fs_migrate_blocks(inode, cur_lblock, nr_pblocks); if (ret) { if (ret == -ENOENT) ret = -EINVAL; goto out; } if (!last_extent) goto retry; } When the first extent is unaligned and roundup(nr_pblocks, blks_per_sec) exceeds sis->max, we subtract blks_per_sec resulting in nr_pblocks = 0. The code then incorrectly assumes this is the last extent, sets nr_pblocks = last_lblock - cur_lblock (entire swapfile), and performs migration. After migration, it doesn't retry mapping, so subsequent extents are never processed. " In order to fix this issue, we need to lookup block mapping info after we migrate all blocks in the tail of swapfile. Cc: stable@kernel.org Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices") Cc: Daeho Jeong Reported-and-tested-by: Xiaolong Guo Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220951 Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ f2fs_is_sequential_zone_area() => !f2fs_valid_pinned_area() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- fs/f2fs/data.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 7bd2773a25e5..1102c16d4374 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3952,6 +3952,7 @@ static int check_swap_activate(struct swap_info_struct *sis, while (cur_lblock < last_lblock && cur_lblock < sis->max) { struct f2fs_map_blocks map; + bool last_extent = false; retry: cond_resched(); @@ -3977,11 +3978,10 @@ static int check_swap_activate(struct swap_info_struct *sis, pblock = map.m_pblk; nr_pblocks = map.m_len; - if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec || - nr_pblocks % blks_per_sec || - !f2fs_valid_pinned_area(sbi, pblock)) { - bool last_extent = false; - + if (!last_extent && + ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec || + nr_pblocks % blks_per_sec || + !f2fs_valid_pinned_area(sbi, pblock))) { not_aligned++; nr_pblocks = roundup(nr_pblocks, blks_per_sec); @@ -4002,8 +4002,8 @@ static int check_swap_activate(struct swap_info_struct *sis, goto out; } - if (!last_extent) - goto retry; + /* lookup block mapping info after block migration */ + goto retry; } if (cur_lblock + nr_pblocks >= sis->max) -- Gitee From 3b15beab9ce87776e2f9f9b8d5d7225986b099d1 Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Fri, 23 Jan 2026 23:19:16 +0800 Subject: [PATCH 1448/1449] USB: serial: option: add Telit FN920C04 RNDIS compositions ANBZ: #35228 commit 35ac888bf8aca1366a5b99531cccbc1a370d2d08 stable. commit 509f403f3ccec14188036212118651bf23599396 upstream. Add the following compositions: 0x10a1: RNDIS + tty (AT/NMEA) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10a1 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN920 S: SerialNumber=d128dba9 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10a6: RNDIS + tty (AT/NMEA) + tty (AT) + tty (diag) T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10a6 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN920 S: SerialNumber=d128dba9 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms 0x10ab: RNDIS + tty (AT) + tty (diag) + DPL (Data Packet Logging) + adb T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 11 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10ab Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FN920 S: SerialNumber=d128dba9 C: #Ifs= 6 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Cc: stable@vger.kernel.org Signed-off-by: Fabio Porcedda Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 60993836cf91..58f34c8d2b84 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1401,12 +1401,16 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a1, 0xff), /* Telit FN20C04 (RNDIS) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a3, 0xff), /* Telit FN920C04 (ECM) */ .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a6, 0xff), /* Telit FN920C04 (RNDIS) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a8, 0xff), /* Telit FN920C04 (ECM) */ @@ -1415,6 +1419,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10ab, 0xff), /* Telit FN920C04 (RNDIS) */ + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x30), /* Telit FE990B (rmnet) */ .driver_info = NCTRL(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x40) }, -- Gitee From c208a1370193e6cb2e121f6c0fdd04d1dd5f9c6d Mon Sep 17 00:00:00 2001 From: Menglong Dong Date: Wed, 9 Oct 2024 10:28:21 +0800 Subject: [PATCH 1449/1449] net: tunnel: make skb_vlan_inet_prepare() return drop reasons ANBZ: #35228 commit f478b8239d6564b20bbf2972e441c31f945a2b76 stable. commit 9990ddf47d4168088e2246c3d418bf526e40830d upstream. Make skb_vlan_inet_prepare return the skb drop reasons, which is just what pskb_may_pull_reason() returns. Meanwhile, adjust all the call of it. Signed-off-by: Menglong Dong Reviewed-by: Simon Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Assisted-by: PatchPilot Signed-off-by: Weilin Tong --- drivers/net/bareudp.c | 4 ++-- drivers/net/geneve.c | 4 ++-- include/net/ip_tunnels.h | 13 ++++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index 54767154de26..cfbc0240126e 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -319,7 +319,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev, __be32 saddr; int err; - if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB))) + if (skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB))) return -EINVAL; if (!sock) @@ -385,7 +385,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev, __be16 sport; int err; - if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB))) + if (skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB))) return -EINVAL; if (!sock) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 27761334e1bf..33dae09f7fb2 100755 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -927,7 +927,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, __be16 sport; int err; - if (!skb_vlan_inet_prepare(skb, inner_proto_inherit)) + if (skb_vlan_inet_prepare(skb, inner_proto_inherit)) return -EINVAL; sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); @@ -1026,7 +1026,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, __be16 sport; int err; - if (!skb_vlan_inet_prepare(skb, inner_proto_inherit)) + if (skb_vlan_inet_prepare(skb, inner_proto_inherit)) return -EINVAL; sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 3d36794cb189..1051af74285c 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -362,11 +362,12 @@ static inline bool pskb_inet_may_pull(struct sk_buff *skb) /* Variant of pskb_inet_may_pull(). */ -static inline bool skb_vlan_inet_prepare(struct sk_buff *skb, - bool inner_proto_inherit) +static inline enum skb_drop_reason +skb_vlan_inet_prepare(struct sk_buff *skb, bool inner_proto_inherit) { int nhlen = 0, maclen = inner_proto_inherit ? 0 : ETH_HLEN; __be16 type = skb->protocol; + enum skb_drop_reason reason; /* Essentially this is skb_protocol(skb, true) * And we get MAC len. @@ -387,11 +388,13 @@ static inline bool skb_vlan_inet_prepare(struct sk_buff *skb, /* For ETH_P_IPV6/ETH_P_IP we make sure to pull * a base network header in skb->head. */ - if (!pskb_may_pull(skb, maclen + nhlen)) - return false; + reason = pskb_may_pull_reason(skb, maclen + nhlen); + if (reason) + return reason; skb_set_network_header(skb, maclen); - return true; + + return SKB_NOT_DROPPED_YET; } static inline int ip_encap_hlen(struct ip_tunnel_encap *e) -- Gitee