From: Sasha Levin Date: Sun, 11 Aug 2024 12:55:09 +0000 (-0400) Subject: Fixes for 6.1 X-Git-Tag: v6.1.105~119 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=86b1618985b3bfba3d841a27578a19e340298b46;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/acpi-battery-create-alarm-sysfs-attribute-atomically.patch b/queue-6.1/acpi-battery-create-alarm-sysfs-attribute-atomically.patch new file mode 100644 index 00000000000..d91aef8ba32 --- /dev/null +++ b/queue-6.1/acpi-battery-create-alarm-sysfs-attribute-atomically.patch @@ -0,0 +1,79 @@ +From 13d7a7f105243b1ea15c79fc7413325b08fe588a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Jun 2024 09:27:16 +0200 +Subject: ACPI: battery: create alarm sysfs attribute atomically +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit a231eed10ed5a290129fda36ad7bcc263c53ff7d ] + +Let the power supply core register the attribute. +This ensures that the attribute is created before the device is +announced to userspace, avoid a race condition. + +Signed-off-by: Thomas Weißschuh +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/battery.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c +index 084f156bdfbc4..088740fdea355 100644 +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -667,12 +667,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, + return count; + } + +-static const struct device_attribute alarm_attr = { ++static struct device_attribute alarm_attr = { + .attr = {.name = "alarm", .mode = 0644}, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, + }; + ++static struct attribute *acpi_battery_attrs[] = { ++ &alarm_attr.attr, ++ NULL ++}; ++ATTRIBUTE_GROUPS(acpi_battery); ++ + /* + * The Battery Hooking API + * +@@ -809,7 +815,10 @@ static void __exit battery_hook_exit(void) + + static int sysfs_add_battery(struct acpi_battery *battery) + { +- struct power_supply_config psy_cfg = { .drv_data = battery, }; ++ struct power_supply_config psy_cfg = { ++ .drv_data = battery, ++ .attr_grp = acpi_battery_groups, ++ }; + bool full_cap_broken = false; + + if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && +@@ -854,7 +863,7 @@ static int sysfs_add_battery(struct acpi_battery *battery) + return result; + } + battery_hook_add_battery(battery); +- return device_create_file(&battery->bat->dev, &alarm_attr); ++ return 0; + } + + static void sysfs_remove_battery(struct acpi_battery *battery) +@@ -865,7 +874,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery) + return; + } + battery_hook_remove_battery(battery); +- device_remove_file(&battery->bat->dev, &alarm_attr); + power_supply_unregister(battery->bat); + battery->bat = NULL; + mutex_unlock(&battery->sysfs_lock); +-- +2.43.0 + diff --git a/queue-6.1/acpi-sbs-manage-alarm-sysfs-attribute-through-psy-co.patch b/queue-6.1/acpi-sbs-manage-alarm-sysfs-attribute-through-psy-co.patch new file mode 100644 index 00000000000..00a0eb55e95 --- /dev/null +++ b/queue-6.1/acpi-sbs-manage-alarm-sysfs-attribute-through-psy-co.patch @@ -0,0 +1,95 @@ +From bd90c16f75251a7ff781a77ab2a1cd966a86c5a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Jun 2024 13:13:28 +0200 +Subject: ACPI: SBS: manage alarm sysfs attribute through psy core +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit 6bad28cfc30988a845fb3f59a99f4b8a4ce8fe95 ] + +Let the power supply core register the attribute. + +This ensures that the attribute is created before the device is +announced to userspace, avoiding a race condition. + +Signed-off-by: Thomas Weißschuh +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/sbs.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c +index e6a01a8df1b81..7c0eba1a37d87 100644 +--- a/drivers/acpi/sbs.c ++++ b/drivers/acpi/sbs.c +@@ -77,7 +77,6 @@ struct acpi_battery { + u16 spec; + u8 id; + u8 present:1; +- u8 have_sysfs_alarm:1; + }; + + #define to_acpi_battery(x) power_supply_get_drvdata(x) +@@ -462,12 +461,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, + return count; + } + +-static const struct device_attribute alarm_attr = { ++static struct device_attribute alarm_attr = { + .attr = {.name = "alarm", .mode = 0644}, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, + }; + ++static struct attribute *acpi_battery_attrs[] = { ++ &alarm_attr.attr, ++ NULL ++}; ++ATTRIBUTE_GROUPS(acpi_battery); ++ + /* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ +@@ -509,7 +514,10 @@ static int acpi_battery_read(struct acpi_battery *battery) + static int acpi_battery_add(struct acpi_sbs *sbs, int id) + { + struct acpi_battery *battery = &sbs->battery[id]; +- struct power_supply_config psy_cfg = { .drv_data = battery, }; ++ struct power_supply_config psy_cfg = { ++ .drv_data = battery, ++ .attr_grp = acpi_battery_groups, ++ }; + int result; + + battery->id = id; +@@ -539,10 +547,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) + goto end; + } + +- result = device_create_file(&battery->bat->dev, &alarm_attr); +- if (result) +- goto end; +- battery->have_sysfs_alarm = 1; + end: + pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n", + ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), +@@ -554,11 +558,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) + { + struct acpi_battery *battery = &sbs->battery[id]; + +- if (battery->bat) { +- if (battery->have_sysfs_alarm) +- device_remove_file(&battery->bat->dev, &alarm_attr); ++ if (battery->bat) + power_supply_unregister(battery->bat); +- } + } + + static int acpi_charger_add(struct acpi_sbs *sbs) +-- +2.43.0 + diff --git a/queue-6.1/af_unix-don-t-retry-after-unix_state_lock_nested-in-.patch b/queue-6.1/af_unix-don-t-retry-after-unix_state_lock_nested-in-.patch new file mode 100644 index 00000000000..3772b279565 --- /dev/null +++ b/queue-6.1/af_unix-don-t-retry-after-unix_state_lock_nested-in-.patch @@ -0,0 +1,139 @@ +From f0374a50bf473b45d323b5d686b6ce6c6edc53f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jun 2024 13:56:15 -0700 +Subject: af_unix: Don't retry after unix_state_lock_nested() in + unix_stream_connect(). + +From: Kuniyuki Iwashima + +[ Upstream commit 1ca27e0c8c13ac50a4acf9cdf77069e2d94a547d ] + +When a SOCK_(STREAM|SEQPACKET) socket connect()s to another one, we need +to lock the two sockets to check their states in unix_stream_connect(). + +We use unix_state_lock() for the server and unix_state_lock_nested() for +client with tricky sk->sk_state check to avoid deadlock. + +The possible deadlock scenario are the following: + + 1) Self connect() + 2) Simultaneous connect() + +The former is simple, attempt to grab the same lock, and the latter is +AB-BA deadlock. + +After the server's unix_state_lock(), we check the server socket's state, +and if it's not TCP_LISTEN, connect() fails with -EINVAL. + +Then, we avoid the former deadlock by checking the client's state before +unix_state_lock_nested(). If its state is not TCP_LISTEN, we can make +sure that the client and the server are not identical based on the state. + +Also, the latter deadlock can be avoided in the same way. Due to the +server sk->sk_state requirement, AB-BA deadlock could happen only with +TCP_LISTEN sockets. So, if the client's state is TCP_LISTEN, we can +give up the second lock to avoid the deadlock. + + CPU 1 CPU 2 CPU 3 + connect(A -> B) connect(B -> A) listen(A) + --- --- --- + unix_state_lock(B) + B->sk_state == TCP_LISTEN + READ_ONCE(A->sk_state) == TCP_CLOSE + ^^^^^^^^^ + ok, will lock A unix_state_lock(A) + .--------------' WRITE_ONCE(A->sk_state, TCP_LISTEN) + | unix_state_unlock(A) + | + | unix_state_lock(A) + | A->sk_sk_state == TCP_LISTEN + | READ_ONCE(B->sk_state) == TCP_LISTEN + v ^^^^^^^^^^ + unix_state_lock_nested(A) Don't lock B !! + +Currently, while checking the client's state, we also check if it's +TCP_ESTABLISHED, but this is unlikely and can be checked after we know +the state is not TCP_CLOSE. + +Moreover, if it happens after the second lock, we now jump to the restart +label, but it's unlikely that the server is not found during the retry, +so the jump is mostly to revist the client state check. + +Let's remove the retry logic and check the state against TCP_CLOSE first. + +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/unix/af_unix.c | 34 +++++++++------------------------- + 1 file changed, 9 insertions(+), 25 deletions(-) + +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index db71f35b67b86..7d59f9a6c9046 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1461,6 +1461,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + struct unix_sock *u = unix_sk(sk), *newu, *otheru; + struct net *net = sock_net(sk); + struct sk_buff *skb = NULL; ++ unsigned char state; + long timeo; + int err; + +@@ -1505,7 +1506,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + goto out; + } + +- /* Latch state of peer */ + unix_state_lock(other); + + /* Apparently VFS overslept socket death. Retry. */ +@@ -1535,37 +1535,21 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, + goto restart; + } + +- /* Latch our state. +- +- It is tricky place. We need to grab our state lock and cannot +- drop lock on peer. It is dangerous because deadlock is +- possible. Connect to self case and simultaneous +- attempt to connect are eliminated by checking socket +- state. other is TCP_LISTEN, if sk is TCP_LISTEN we +- check this before attempt to grab lock. +- +- Well, and we have to recheck the state after socket locked. ++ /* self connect and simultaneous connect are eliminated ++ * by rejecting TCP_LISTEN socket to avoid deadlock. + */ +- switch (READ_ONCE(sk->sk_state)) { +- case TCP_CLOSE: +- /* This is ok... continue with connect */ +- break; +- case TCP_ESTABLISHED: +- /* Socket is already connected */ +- err = -EISCONN; +- goto out_unlock; +- default: +- err = -EINVAL; ++ state = READ_ONCE(sk->sk_state); ++ if (unlikely(state != TCP_CLOSE)) { ++ err = state == TCP_ESTABLISHED ? -EISCONN : -EINVAL; + goto out_unlock; + } + + unix_state_lock_nested(sk, U_LOCK_SECOND); + +- if (sk->sk_state != TCP_CLOSE) { ++ if (unlikely(sk->sk_state != TCP_CLOSE)) { ++ err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EINVAL; + unix_state_unlock(sk); +- unix_state_unlock(other); +- sock_put(other); +- goto restart; ++ goto out_unlock; + } + + err = security_unix_stream_connect(sk, other, newsk); +-- +2.43.0 + diff --git a/queue-6.1/block-change-rq_integrity_vec-to-respect-the-iterato.patch b/queue-6.1/block-change-rq_integrity_vec-to-respect-the-iterato.patch new file mode 100644 index 00000000000..103471af2f1 --- /dev/null +++ b/queue-6.1/block-change-rq_integrity_vec-to-respect-the-iterato.patch @@ -0,0 +1,106 @@ +From 71b7c7040f8d772ee6e6d153aa600376c0bf16a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 17:40:10 +0200 +Subject: block: change rq_integrity_vec to respect the iterator + +From: Mikulas Patocka + +[ Upstream commit cf546dd289e0f6d2594c25e2fb4e19ee67c6d988 ] + +If we allocate a bio that is larger than NVMe maximum request size, +attach integrity metadata to it and send it to the NVMe subsystem, the +integrity metadata will be corrupted. + +Splitting the bio works correctly. The function bio_split will clone the +bio, trim the iterator of the first bio and advance the iterator of the +second bio. + +However, the function rq_integrity_vec has a bug - it returns the first +vector of the bio's metadata and completely disregards the metadata +iterator that was advanced when the bio was split. Thus, the second bio +uses the same metadata as the first bio and this leads to metadata +corruption. + +This commit changes rq_integrity_vec, so that it calls mp_bvec_iter_bvec +instead of returning the first vector. mp_bvec_iter_bvec reads the +iterator and uses it to build a bvec for the current position in the +iterator. + +The "queue_max_integrity_segments(rq->q) > 1" check was removed, because +the updated rq_integrity_vec function works correctly with multiple +segments. + +Signed-off-by: Mikulas Patocka +Reviewed-by: Anuj Gupta +Reviewed-by: Kanchan Joshi +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/49d1afaa-f934-6ed2-a678-e0d428c63a65@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 6 +++--- + include/linux/blk-integrity.h | 14 +++++++------- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 27446fa847526..6f648b58cbd4d 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -873,9 +873,9 @@ static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req, + struct nvme_command *cmnd) + { + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); ++ struct bio_vec bv = rq_integrity_vec(req); + +- iod->meta_dma = dma_map_bvec(dev->dev, rq_integrity_vec(req), +- rq_dma_dir(req), 0); ++ iod->meta_dma = dma_map_bvec(dev->dev, &bv, rq_dma_dir(req), 0); + if (dma_mapping_error(dev->dev, iod->meta_dma)) + return BLK_STS_IOERR; + cmnd->rw.metadata = cpu_to_le64(iod->meta_dma); +@@ -1016,7 +1016,7 @@ static __always_inline void nvme_pci_unmap_rq(struct request *req) + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + + dma_unmap_page(dev->dev, iod->meta_dma, +- rq_integrity_vec(req)->bv_len, rq_dma_dir(req)); ++ rq_integrity_vec(req).bv_len, rq_dma_dir(req)); + } + + if (blk_rq_nr_phys_segments(req)) +diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h +index 378b2459efe2d..69f73d0546118 100644 +--- a/include/linux/blk-integrity.h ++++ b/include/linux/blk-integrity.h +@@ -105,14 +105,13 @@ static inline bool blk_integrity_rq(struct request *rq) + } + + /* +- * Return the first bvec that contains integrity data. Only drivers that are +- * limited to a single integrity segment should use this helper. ++ * Return the current bvec that contains the integrity data. bip_iter may be ++ * advanced to iterate over the integrity data. + */ +-static inline struct bio_vec *rq_integrity_vec(struct request *rq) ++static inline struct bio_vec rq_integrity_vec(struct request *rq) + { +- if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1)) +- return NULL; +- return rq->bio->bi_integrity->bip_vec; ++ return mp_bvec_iter_bvec(rq->bio->bi_integrity->bip_vec, ++ rq->bio->bi_integrity->bip_iter); + } + #else /* CONFIG_BLK_DEV_INTEGRITY */ + static inline int blk_rq_count_integrity_sg(struct request_queue *q, +@@ -178,7 +177,8 @@ static inline int blk_integrity_rq(struct request *rq) + + static inline struct bio_vec *rq_integrity_vec(struct request *rq) + { +- return NULL; ++ /* the optimizer will remove all calls to this function */ ++ return (struct bio_vec){ }; + } + #endif /* CONFIG_BLK_DEV_INTEGRITY */ + #endif /* _LINUX_BLK_INTEGRITY_H */ +-- +2.43.0 + diff --git a/queue-6.1/bluetooth-hci_sync-avoid-dup-filtering-when-passive-.patch b/queue-6.1/bluetooth-hci_sync-avoid-dup-filtering-when-passive-.patch new file mode 100644 index 00000000000..24d75012ec7 --- /dev/null +++ b/queue-6.1/bluetooth-hci_sync-avoid-dup-filtering-when-passive-.patch @@ -0,0 +1,53 @@ +From 420cd9b7f0546d1c61d9e57e7de89504686a8c15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Jul 2024 21:58:10 +0200 +Subject: Bluetooth: hci_sync: avoid dup filtering when passive scanning with + adv monitor + +From: Anton Khirnov + +[ Upstream commit b5431dc2803ac159d6d4645ae237d15c3cb252db ] + +This restores behaviour (including the comment) from now-removed +hci_request.c, and also matches existing code for active scanning. + +Without this, the duplicates filter is always active when passive +scanning, which makes it impossible to work with devices that send +nontrivial dynamic data in their advertisement reports. + +Fixes: abfeea476c68 ("Bluetooth: hci_sync: Convert MGMT_OP_START_DISCOVERY") +Signed-off-by: Anton Khirnov +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_sync.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index 320fc1e6dff2a..3d6a22812b498 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -2880,6 +2880,20 @@ static int hci_passive_scan_sync(struct hci_dev *hdev) + } else if (hci_is_adv_monitoring(hdev)) { + window = hdev->le_scan_window_adv_monitor; + interval = hdev->le_scan_int_adv_monitor; ++ ++ /* Disable duplicates filter when scanning for advertisement ++ * monitor for the following reasons. ++ * ++ * For HW pattern filtering (ex. MSFT), Realtek and Qualcomm ++ * controllers ignore RSSI_Sampling_Period when the duplicates ++ * filter is enabled. ++ * ++ * For SW pattern filtering, when we're not doing interleaved ++ * scanning, it is necessary to disable duplicates filter, ++ * otherwise hosts can only receive one advertisement and it's ++ * impossible to know if a peer is still in range. ++ */ ++ filter_dups = LE_SCAN_FILTER_DUP_DISABLE; + } else { + window = hdev->le_scan_window; + interval = hdev->le_scan_interval; +-- +2.43.0 + diff --git a/queue-6.1/bluetooth-l2cap-always-unlock-channel-in-l2cap_conle.patch b/queue-6.1/bluetooth-l2cap-always-unlock-channel-in-l2cap_conle.patch new file mode 100644 index 00000000000..fa3dac2c66e --- /dev/null +++ b/queue-6.1/bluetooth-l2cap-always-unlock-channel-in-l2cap_conle.patch @@ -0,0 +1,37 @@ +From b803d40b012ff8c8b5f3744d2865fe9487185a74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 12:19:36 +0300 +Subject: Bluetooth: l2cap: always unlock channel in l2cap_conless_channel() + +From: Dmitry Antipov + +[ Upstream commit c531e63871c0b50c8c4e62c048535a08886fba3e ] + +Add missing call to 'l2cap_chan_unlock()' on receive error handling +path in 'l2cap_conless_channel()'. + +Fixes: a24cce144b98 ("Bluetooth: Fix reference counting of global L2CAP channels") +Reported-by: syzbot+45ac74737e866894acb0@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=45ac74737e866894acb0 +Signed-off-by: Dmitry Antipov +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/l2cap_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 98dabbbe42938..209c6d458d336 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -7811,6 +7811,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, + bt_cb(skb)->l2cap.psm = psm; + + if (!chan->ops->recv(chan, skb)) { ++ l2cap_chan_unlock(chan); + l2cap_chan_put(chan); + return; + } +-- +2.43.0 + diff --git a/queue-6.1/btrfs-fix-bitmap-leak-when-loading-free-space-cache-.patch b/queue-6.1/btrfs-fix-bitmap-leak-when-loading-free-space-cache-.patch new file mode 100644 index 00000000000..b352120d92d --- /dev/null +++ b/queue-6.1/btrfs-fix-bitmap-leak-when-loading-free-space-cache-.patch @@ -0,0 +1,39 @@ +From 2b6609f664553490b6e541a7233f536a93cdfeb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Jul 2024 15:40:59 +0100 +Subject: btrfs: fix bitmap leak when loading free space cache on duplicate + entry + +From: Filipe Manana + +[ Upstream commit 320d8dc612660da84c3b70a28658bb38069e5a9a ] + +If we failed to link a free space entry because there's already a +conflicting entry for the same offset, we free the free space entry but +we don't free the associated bitmap that we had just allocated before. +Fix that by freeing the bitmap before freeing the entry. + +Reviewed-by: Johannes Thumshirn +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/free-space-cache.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index 76d52d682b3b0..21d262da386d5 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -865,6 +865,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, + spin_unlock(&ctl->tree_lock); + btrfs_err(fs_info, + "Duplicate entries in free space cache, dumping"); ++ kmem_cache_free(btrfs_free_space_bitmap_cachep, e->bitmap); + kmem_cache_free(btrfs_free_space_cachep, e); + goto free_cache; + } +-- +2.43.0 + diff --git a/queue-6.1/can-mcp251xfd-tef-prepare-to-workaround-broken-tef-f.patch b/queue-6.1/can-mcp251xfd-tef-prepare-to-workaround-broken-tef-f.patch new file mode 100644 index 00000000000..3be9c754582 --- /dev/null +++ b/queue-6.1/can-mcp251xfd-tef-prepare-to-workaround-broken-tef-f.patch @@ -0,0 +1,211 @@ +From 614511b422038768aebaab9bfeae2d03e7105627 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Jan 2023 21:30:41 +0100 +Subject: can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index + erratum +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marc Kleine-Budde + +[ Upstream commit b8e0ddd36ce9536ad7478dd27df06c9ae92370ba ] + +This is a preparatory patch to work around a problem similar to +erratum DS80000789E 6 of the mcp2518fd, the other variants of the chip +family (mcp2517fd and mcp251863) are probably also affected. + +Erratum DS80000789E 6 says "reading of the FIFOCI bits in the FIFOSTA +register for an RX FIFO may be corrupted". However observation shows +that this problem is not limited to RX FIFOs but also effects the TEF +FIFO. + +When handling the TEF interrupt, the driver reads the FIFO header +index from the TEF FIFO STA register of the chip. + +In the bad case, the driver reads a too large head index. In the +original code, the driver always trusted the read value, which caused +old CAN transmit complete events that were already processed to be +re-processed. + +Instead of reading and trusting the head index, read the head index +and calculate the number of CAN frames that were supposedly received - +replace mcp251xfd_tef_ring_update() with mcp251xfd_get_tef_len(). + +The mcp251xfd_handle_tefif() function reads the CAN transmit complete +events from the chip, iterates over them and pushes them into the +network stack. The original driver already contains code to detect old +CAN transmit complete events, that will be updated in the next patch. + +Cc: Stefan Althöfer +Cc: Thomas Kopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/spi/mcp251xfd/mcp251xfd-ring.c | 2 + + drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c | 54 +++++++++++++------ + drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 13 ++--- + 3 files changed, 43 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +index bf3f0f150199d..4d0246a0779a6 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +@@ -475,6 +475,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) + clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); + } + ++ tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) - ++ ilog2(tx_ring->obj_num); + tx_ring->obj_size = tx_obj_size; + + rem = priv->rx_obj_num; +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +index 237617b0c125f..b33192964cf7d 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2019, 2020, 2021 Pengutronix, ++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + // Based on: +@@ -16,6 +16,11 @@ + + #include "mcp251xfd.h" + ++static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta) ++{ ++ return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); ++} ++ + static inline int + mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, + u8 *tef_tail) +@@ -120,28 +125,44 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, + return 0; + } + +-static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) ++static int ++mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p) + { + const struct mcp251xfd_tx_ring *tx_ring = priv->tx; +- unsigned int new_head; +- u8 chip_tx_tail; ++ const u8 shift = tx_ring->obj_num_shift_to_u8; ++ u8 chip_tx_tail, tail, len; ++ u32 fifo_sta; + int err; + +- err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); ++ err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr), ++ &fifo_sta); + if (err) + return err; + +- /* chip_tx_tail, is the next TX-Object send by the HW. +- * The new TEF head must be >= the old head, ... ++ if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) { ++ *len_p = tx_ring->obj_num; ++ return 0; ++ } ++ ++ chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); ++ ++ err = mcp251xfd_check_tef_tail(priv); ++ if (err) ++ return err; ++ tail = mcp251xfd_get_tef_tail(priv); ++ ++ /* First shift to full u8. The subtraction works on signed ++ * values, that keeps the difference steady around the u8 ++ * overflow. The right shift acts on len, which is an u8. + */ +- new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; +- if (new_head <= priv->tef->head) +- new_head += tx_ring->obj_num; ++ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail)); ++ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail)); ++ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len)); + +- /* ... but it cannot exceed the TX head. */ +- priv->tef->head = min(new_head, tx_ring->head); ++ len = (chip_tx_tail << shift) - (tail << shift); ++ *len_p = len >> shift; + +- return mcp251xfd_check_tef_tail(priv); ++ return 0; + } + + static inline int +@@ -182,13 +203,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) + u8 tef_tail, len, l; + int err, i; + +- err = mcp251xfd_tef_ring_update(priv); ++ err = mcp251xfd_get_tef_len(priv, &len); + if (err) + return err; + + tef_tail = mcp251xfd_get_tef_tail(priv); +- len = mcp251xfd_get_tef_len(priv); +- l = mcp251xfd_get_tef_linear_len(priv); ++ l = mcp251xfd_get_tef_linear_len(priv, len); + err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); + if (err) + return err; +@@ -223,6 +243,8 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) + struct mcp251xfd_tx_ring *tx_ring = priv->tx; + int offset; + ++ ring->head += len; ++ + /* Increment the TEF FIFO tail pointer 'len' times in + * a single SPI message. + * +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +index b98ded7098a5a..78d12dda08a05 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -519,6 +519,7 @@ struct mcp251xfd_tef_ring { + + /* u8 obj_num equals tx_ring->obj_num */ + /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ ++ /* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */ + + union mcp251xfd_write_reg_buf irq_enable_buf; + struct spi_transfer irq_enable_xfer; +@@ -537,6 +538,7 @@ struct mcp251xfd_tx_ring { + u8 nr; + u8 fifo_nr; + u8 obj_num; ++ u8 obj_num_shift_to_u8; + u8 obj_size; + + struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; +@@ -843,17 +845,8 @@ static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv) + return priv->tef->tail & (priv->tx->obj_num - 1); + } + +-static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv) ++static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len) + { +- return priv->tef->head - priv->tef->tail; +-} +- +-static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv) +-{ +- u8 len; +- +- len = mcp251xfd_get_tef_len(priv); +- + return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); + } + +-- +2.43.0 + diff --git a/queue-6.1/can-mcp251xfd-tef-update-workaround-for-erratum-ds80.patch b/queue-6.1/can-mcp251xfd-tef-update-workaround-for-erratum-ds80.patch new file mode 100644 index 00000000000..ddaa24632c3 --- /dev/null +++ b/queue-6.1/can-mcp251xfd-tef-update-workaround-for-erratum-ds80.patch @@ -0,0 +1,151 @@ +From a3985bdad0d1f39db0041d065f4b2a242707e9b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Jan 2023 22:35:03 +0100 +Subject: can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of + mcp2518fd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marc Kleine-Budde + +[ Upstream commit 3a0a88fcbaf9e027ecca3fe8775be9700b4d6460 ] + +This patch updates the workaround for a problem similar to erratum +DS80000789E 6 of the mcp2518fd, the other variants of the chip +family (mcp2517fd and mcp251863) are probably also affected. + +Erratum DS80000789E 6 says "reading of the FIFOCI bits in the FIFOSTA +register for an RX FIFO may be corrupted". However observation shows +that this problem is not limited to RX FIFOs but also effects the TEF +FIFO. + +In the bad case, the driver reads a too large head index. As the FIFO +is implemented as a ring buffer, this results in re-handling old CAN +transmit complete events. + +Every transmit complete event contains with a sequence number that +equals to the sequence number of the corresponding TX request. This +way old TX complete events can be detected. + +If the original driver detects a non matching sequence number, it +prints an info message and tries again later. As wrong sequence +numbers can be explained by the erratum DS80000789E 6, demote the info +message to debug level, streamline the code and update the comments. + +Keep the behavior: If an old CAN TX complete event is detected, abort +the iteration and mark the number of valid CAN TX complete events as +processed in the chip by incrementing the FIFO's tail index. + +Cc: Stefan Althöfer +Cc: Thomas Kopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c | 71 +++++++------------ + 1 file changed, 27 insertions(+), 44 deletions(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +index b33192964cf7d..902eb767426d1 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +@@ -60,56 +60,39 @@ static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv) + return 0; + } + +-static int +-mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) +-{ +- const struct mcp251xfd_tx_ring *tx_ring = priv->tx; +- u32 tef_sta; +- int err; +- +- err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta); +- if (err) +- return err; +- +- if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) { +- netdev_err(priv->ndev, +- "Transmit Event FIFO buffer overflow.\n"); +- return -ENOBUFS; +- } +- +- netdev_info(priv->ndev, +- "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n", +- tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ? +- "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ? +- "not empty" : "empty", +- seq, priv->tef->tail, priv->tef->head, tx_ring->head); +- +- /* The Sequence Number in the TEF doesn't match our tef_tail. */ +- return -EAGAIN; +-} +- + static int + mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, + const struct mcp251xfd_hw_tef_obj *hw_tef_obj, + unsigned int *frame_len_ptr) + { + struct net_device_stats *stats = &priv->ndev->stats; ++ u32 seq, tef_tail_masked, tef_tail; + struct sk_buff *skb; +- u32 seq, seq_masked, tef_tail_masked, tef_tail; + +- seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, ++ /* Use the MCP2517FD mask on the MCP2518FD, too. We only ++ * compare 7 bits, this is enough to detect old TEF objects. ++ */ ++ seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK, + hw_tef_obj->flags); +- +- /* Use the MCP2517FD mask on the MCP2518FD, too. We only +- * compare 7 bits, this should be enough to detect +- * net-yet-completed, i.e. old TEF objects. +- */ +- seq_masked = seq & +- field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); + tef_tail_masked = priv->tef->tail & + field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); +- if (seq_masked != tef_tail_masked) +- return mcp251xfd_handle_tefif_recover(priv, seq); ++ ++ /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI ++ * bits of a FIFOSTA register, here the TX FIFO tail index ++ * might be corrupted and we might process past the TEF FIFO's ++ * head into old CAN frames. ++ * ++ * Compare the sequence number of the currently processed CAN ++ * frame with the expected sequence number. Abort with ++ * -EBADMSG if an old CAN frame is detected. ++ */ ++ if (seq != tef_tail_masked) { ++ netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__, ++ seq, tef_tail_masked); ++ stats->tx_fifo_errors++; ++ ++ return -EBADMSG; ++ } + + tef_tail = mcp251xfd_get_tef_tail(priv); + skb = priv->can.echo_skb[tef_tail]; +@@ -223,12 +206,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) + unsigned int frame_len = 0; + + err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); +- /* -EAGAIN means the Sequence Number in the TEF +- * doesn't match our tef_tail. This can happen if we +- * read the TEF objects too early. Leave loop let the +- * interrupt handler call us again. ++ /* -EBADMSG means we're affected by mcp2518fd erratum ++ * DS80000789E 6., i.e. the Sequence Number in the TEF ++ * doesn't match our tef_tail. Don't process any ++ * further and mark processed frames as good. + */ +- if (err == -EAGAIN) ++ if (err == -EBADMSG) + goto out_netif_wake_queue; + if (err) + return err; +-- +2.43.0 + diff --git a/queue-6.1/clocksource-drivers-sh_cmt-address-race-condition-fo.patch b/queue-6.1/clocksource-drivers-sh_cmt-address-race-condition-fo.patch new file mode 100644 index 00000000000..05bbe228735 --- /dev/null +++ b/queue-6.1/clocksource-drivers-sh_cmt-address-race-condition-fo.patch @@ -0,0 +1,144 @@ +From 4041a96a780e56dc9472762bfa2316299572ef5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2024 21:02:30 +0200 +Subject: clocksource/drivers/sh_cmt: Address race condition for clock events +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit db19d3aa77612983a02bd223b3f273f896b243cf ] + +There is a race condition in the CMT interrupt handler. In the interrupt +handler the driver sets a driver private flag, FLAG_IRQCONTEXT. This +flag is used to indicate any call to set_next_event() should not be +directly propagated to the device, but instead cached. This is done as +the interrupt handler itself reprograms the device when needed before it +completes and this avoids this operation to take place twice. + +It is unclear why this design was chosen, my suspicion is to allow the +struct clock_event_device.event_handler callback, which is called while +the FLAG_IRQCONTEXT is set, can update the next event without having to +write to the device twice. + +Unfortunately there is a race between when the FLAG_IRQCONTEXT flag is +set and later cleared where the interrupt handler have already started to +write the next event to the device. If set_next_event() is called in +this window the value is only cached in the driver but not written. This +leads to the board to misbehave, or worse lockup and produce a splat. + + rcu: INFO: rcu_preempt detected stalls on CPUs/tasks: + rcu: 0-...!: (0 ticks this GP) idle=f5e0/0/0x0 softirq=519/519 fqs=0 (false positive?) + rcu: (detected by 1, t=6502 jiffies, g=-595, q=77 ncpus=2) + Sending NMI from CPU 1 to CPUs 0: + NMI backtrace for cpu 0 + CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.10.0-rc5-arm64-renesas-00019-g74a6f86eaf1c-dirty #20 + Hardware name: Renesas Salvator-X 2nd version board based on r8a77965 (DT) + pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : tick_check_broadcast_expired+0xc/0x40 + lr : cpu_idle_poll.isra.0+0x8c/0x168 + sp : ffff800081c63d70 + x29: ffff800081c63d70 x28: 00000000580000c8 x27: 00000000bfee5610 + x26: 0000000000000027 x25: 0000000000000000 x24: 0000000000000000 + x23: ffff00007fbb9100 x22: ffff8000818f1008 x21: ffff8000800ef07c + x20: ffff800081c79ec0 x19: ffff800081c70c28 x18: 0000000000000000 + x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffffc2c717d8 + x14: 0000000000000000 x13: ffff000009c18080 x12: ffff8000825f7fc0 + x11: 0000000000000000 x10: ffff8000818f3cd4 x9 : 0000000000000028 + x8 : ffff800081c79ec0 x7 : ffff800081c73000 x6 : 0000000000000000 + x5 : 0000000000000000 x4 : ffff7ffffe286000 x3 : 0000000000000000 + x2 : ffff7ffffe286000 x1 : ffff800082972900 x0 : ffff8000818f1008 + Call trace: + tick_check_broadcast_expired+0xc/0x40 + do_idle+0x9c/0x280 + cpu_startup_entry+0x34/0x40 + kernel_init+0x0/0x11c + do_one_initcall+0x0/0x260 + __primary_switched+0x80/0x88 + rcu: rcu_preempt kthread timer wakeup didn't happen for 6501 jiffies! g-595 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 + rcu: Possible timer handling issue on cpu=0 timer-softirq=262 + rcu: rcu_preempt kthread starved for 6502 jiffies! g-595 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 ->cpu=0 + rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior. + rcu: RCU grace-period kthread stack dump: + task:rcu_preempt state:I stack:0 pid:15 tgid:15 ppid:2 flags:0x00000008 + Call trace: + __switch_to+0xbc/0x100 + __schedule+0x358/0xbe0 + schedule+0x48/0x148 + schedule_timeout+0xc4/0x138 + rcu_gp_fqs_loop+0x12c/0x764 + rcu_gp_kthread+0x208/0x298 + kthread+0x10c/0x110 + ret_from_fork+0x10/0x20 + +The design have been part of the driver since it was first merged in +early 2009. It becomes increasingly harder to trigger the issue the +older kernel version one tries. It only takes a few boots on v6.10-rc5, +while hundreds of boots are needed to trigger it on v5.10. + +Close the race condition by using the CMT channel lock for the two +competing sections. The channel lock was added to the driver after its +initial design. + +Signed-off-by: Niklas Söderlund +Link: https://lore.kernel.org/r/20240702190230.3825292-1-niklas.soderlund+renesas@ragnatech.se +Signed-off-by: Daniel Lezcano +Signed-off-by: Sasha Levin +--- + drivers/clocksource/sh_cmt.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c +index 7b952aa52c0b9..7a2b83157bf5f 100644 +--- a/drivers/clocksource/sh_cmt.c ++++ b/drivers/clocksource/sh_cmt.c +@@ -529,6 +529,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta) + static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) + { + struct sh_cmt_channel *ch = dev_id; ++ unsigned long flags; + + /* clear flags */ + sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & +@@ -559,6 +560,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) + + ch->flags &= ~FLAG_SKIPEVENT; + ++ raw_spin_lock_irqsave(&ch->lock, flags); ++ + if (ch->flags & FLAG_REPROGRAM) { + ch->flags &= ~FLAG_REPROGRAM; + sh_cmt_clock_event_program_verify(ch, 1); +@@ -571,6 +574,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) + + ch->flags &= ~FLAG_IRQCONTEXT; + ++ raw_spin_unlock_irqrestore(&ch->lock, flags); ++ + return IRQ_HANDLED; + } + +@@ -781,12 +786,18 @@ static int sh_cmt_clock_event_next(unsigned long delta, + struct clock_event_device *ced) + { + struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); ++ unsigned long flags; + + BUG_ON(!clockevent_state_oneshot(ced)); ++ ++ raw_spin_lock_irqsave(&ch->lock, flags); ++ + if (likely(ch->flags & FLAG_IRQCONTEXT)) + ch->next_match_value = delta - 1; + else +- sh_cmt_set_next(ch, delta - 1); ++ __sh_cmt_set_next(ch, delta - 1); ++ ++ raw_spin_unlock_irqrestore(&ch->lock, flags); + + return 0; + } +-- +2.43.0 + diff --git a/queue-6.1/drm-amd-display-add-null-check-for-afb-before-derefe.patch b/queue-6.1/drm-amd-display-add-null-check-for-afb-before-derefe.patch new file mode 100644 index 00000000000..a5bd58d1b21 --- /dev/null +++ b/queue-6.1/drm-amd-display-add-null-check-for-afb-before-derefe.patch @@ -0,0 +1,67 @@ +From 9d0f849d3e226cbc77fb0e6227f42f2441dc1287 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jun 2024 21:13:40 +0530 +Subject: drm/amd/display: Add NULL check for 'afb' before dereferencing in + amdgpu_dm_plane_handle_cursor_update + +From: Srinivasan Shanmugam + +[ Upstream commit 38e6f715b02b572f74677eb2f29d3b4bc6f1ddff ] + +This commit adds a null check for the 'afb' variable in the +amdgpu_dm_plane_handle_cursor_update function. Previously, 'afb' was +assumed to be null, but was used later in the code without a null check. +This could potentially lead to a null pointer dereference. + +Fixes the below: +drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_plane.c:1298 amdgpu_dm_plane_handle_cursor_update() error: we previously assumed 'afb' could be null (see line 1252) + +Cc: Tom Chung +Cc: Rodrigo Siqueira +Cc: Roman Li +Cc: Hersen Wu +Cc: Alex Hung +Cc: Aurabindo Pillai +Cc: Harry Wentland +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Harry Wentland +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +index cd6e99cf74a06..984a5affc5af1 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +@@ -1225,14 +1225,22 @@ void handle_cursor_update(struct drm_plane *plane, + { + struct amdgpu_device *adev = drm_to_adev(plane->dev); + struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb); +- struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc; +- struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; +- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); +- uint64_t address = afb ? afb->address : 0; ++ struct drm_crtc *crtc; ++ struct dm_crtc_state *crtc_state; ++ struct amdgpu_crtc *amdgpu_crtc; ++ u64 address; + struct dc_cursor_position position = {0}; + struct dc_cursor_attributes attributes; + int ret; + ++ if (!afb) ++ return; ++ ++ crtc = plane->state->crtc ? plane->state->crtc : old_plane_state->crtc; ++ crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; ++ amdgpu_crtc = to_amdgpu_crtc(crtc); ++ address = afb->address; ++ + if (!plane->state->fb && !old_plane_state->fb) + return; + +-- +2.43.0 + diff --git a/queue-6.1/drm-amd-display-add-null-checker-before-passing-vari.patch b/queue-6.1/drm-amd-display-add-null-checker-before-passing-vari.patch new file mode 100644 index 00000000000..673bae50c4f --- /dev/null +++ b/queue-6.1/drm-amd-display-add-null-checker-before-passing-vari.patch @@ -0,0 +1,59 @@ +From fd6866b8fd3425ddd537bec5b2fb999f366cc6c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 16:33:18 -0600 +Subject: drm/amd/display: Add null checker before passing variables + +From: Alex Hung + +[ Upstream commit 8092aa3ab8f7b737a34b71f91492c676a843043a ] + +Checks null pointer before passing variables to functions. + +This fixes 3 NULL_RETURNS issues reported by Coverity. + +Reviewed-by: Harry Wentland +Acked-by: Hamza Mahfooz +Signed-off-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 31bae620aeffc..6189685af1fda 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2636,7 +2636,8 @@ static int dm_suspend(void *handle) + + dm->cached_dc_state = dc_copy_state(dm->dc->current_state); + +- dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); ++ if (dm->cached_dc_state) ++ dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); + + amdgpu_dm_commit_zero_streams(dm->dc); + +@@ -6388,7 +6389,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector) + aconnector->dc_sink = aconnector->dc_link->local_sink ? + aconnector->dc_link->local_sink : + aconnector->dc_em_sink; +- dc_sink_retain(aconnector->dc_sink); ++ if (aconnector->dc_sink) ++ dc_sink_retain(aconnector->dc_sink); + } + } + +@@ -7121,7 +7123,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) + drm_add_modes_noedid(connector, 640, 480); + } else { + amdgpu_dm_connector_ddc_get_modes(connector, edid); +- amdgpu_dm_connector_add_common_modes(encoder, connector); ++ if (encoder) ++ amdgpu_dm_connector_add_common_modes(encoder, connector); + amdgpu_dm_connector_add_freesync_modes(connector, edid); + } + amdgpu_dm_fbc_init(connector); +-- +2.43.0 + diff --git a/queue-6.1/drm-amd-pm-fix-the-null-pointer-dereference-for-vega.patch b/queue-6.1/drm-amd-pm-fix-the-null-pointer-dereference-for-vega.patch new file mode 100644 index 00000000000..b075a5eec70 --- /dev/null +++ b/queue-6.1/drm-amd-pm-fix-the-null-pointer-dereference-for-vega.patch @@ -0,0 +1,114 @@ +From 90eedb8d754d4c233ce3822957b3887d835b89d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 15:01:22 +0800 +Subject: drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr + +From: Bob Zhou + +[ Upstream commit 50151b7f1c79a09117837eb95b76c2de76841dab ] + +Check return value and conduct null pointer handling to avoid null pointer dereference. + +Signed-off-by: Bob Zhou +Reviewed-by: Tim Huang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 29 ++++++++++++++++--- + 1 file changed, 25 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +index 2628f12e0eedc..f8333410cc3e4 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -3422,13 +3422,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co + const struct vega10_power_state *vega10_ps = + cast_const_phw_vega10_power_state(states->pnew_state); + struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); +- uint32_t sclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].gfx_clock; + struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); +- uint32_t mclk = vega10_ps->performance_levels +- [vega10_ps->performance_level_count - 1].mem_clock; ++ uint32_t sclk, mclk; + uint32_t i; + ++ if (vega10_ps == NULL) ++ return -EINVAL; ++ sclk = vega10_ps->performance_levels ++ [vega10_ps->performance_level_count - 1].gfx_clock; ++ mclk = vega10_ps->performance_levels ++ [vega10_ps->performance_level_count - 1].mem_clock; ++ + for (i = 0; i < sclk_table->count; i++) { + if (sclk == sclk_table->dpm_levels[i].value) + break; +@@ -3735,6 +3739,9 @@ static int vega10_generate_dpm_level_enable_mask( + cast_const_phw_vega10_power_state(states->pnew_state); + int i; + ++ if (vega10_ps == NULL) ++ return -EINVAL; ++ + PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps), + "Attempt to Trim DPM States Failed!", + return -1); +@@ -5002,6 +5009,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr, + + vega10_psa = cast_const_phw_vega10_power_state(pstate1); + vega10_psb = cast_const_phw_vega10_power_state(pstate2); ++ if (vega10_psa == NULL || vega10_psb == NULL) ++ return -EINVAL; + + /* If the two states don't even have the same number of performance levels + * they cannot be the same state. +@@ -5135,6 +5144,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) + return -EINVAL; + + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return -EINVAL; + + vega10_ps->performance_levels + [vega10_ps->performance_level_count - 1].gfx_clock = +@@ -5186,6 +5197,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) + return -EINVAL; + + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return -EINVAL; + + vega10_ps->performance_levels + [vega10_ps->performance_level_count - 1].mem_clock = +@@ -5427,6 +5440,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) + return; + + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return; ++ + max_level = vega10_ps->performance_level_count - 1; + + if (vega10_ps->performance_levels[max_level].gfx_clock != +@@ -5449,6 +5465,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) + + ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1)); + vega10_ps = cast_phw_vega10_power_state(&ps->hardware); ++ if (vega10_ps == NULL) ++ return; ++ + max_level = vega10_ps->performance_level_count - 1; + + if (vega10_ps->performance_levels[max_level].gfx_clock != +@@ -5639,6 +5658,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_ + return -EINVAL; + + vega10_ps = cast_const_phw_vega10_power_state(state); ++ if (vega10_ps == NULL) ++ return -EINVAL; + + i = index > vega10_ps->performance_level_count - 1 ? + vega10_ps->performance_level_count - 1 : index; +-- +2.43.0 + diff --git a/queue-6.1/drm-amdgpu-add-lock-around-vf-rlcg-interface.patch b/queue-6.1/drm-amdgpu-add-lock-around-vf-rlcg-interface.patch new file mode 100644 index 00000000000..874d108214b --- /dev/null +++ b/queue-6.1/drm-amdgpu-add-lock-around-vf-rlcg-interface.patch @@ -0,0 +1,78 @@ +From 0dcdfd1140a3f81ee232ad9a6058bf7e473612f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 16:10:43 -0400 +Subject: drm/amdgpu: Add lock around VF RLCG interface + +From: Victor Skvortsov + +[ Upstream commit e864180ee49b4d30e640fd1e1d852b86411420c9 ] + +flush_gpu_tlb may be called from another thread while +device_gpu_recover is running. + +Both of these threads access registers through the VF +RLCG interface during VF Full Access. Add a lock around this interface +to prevent race conditions between these threads. + +Signed-off-by: Victor Skvortsov +Reviewed-by: Zhigang Luo +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 6 ++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 2 ++ + 3 files changed, 9 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index d4faa489bd5fa..4d1c2eb63090f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3631,6 +3631,7 @@ 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); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +index 81549f1edfe01..5ee9211c503c4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +@@ -956,6 +956,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v + scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; + 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); ++ + if (reg_access_ctrl->spare_int) + spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; + +@@ -1009,6 +1012,9 @@ 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); ++ + return ret; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +index 2b9d806e23afb..dc6aaa4d67be7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +@@ -260,6 +260,8 @@ struct amdgpu_virt { + + /* the ucode id to signal the autoload */ + uint32_t autoload_ucode_id; ++ ++ struct mutex rlcg_reg_lock; + }; + + struct amdgpu_video_codec_info; +-- +2.43.0 + diff --git a/queue-6.1/drm-amdgpu-fix-the-null-pointer-dereference-to-ras_m.patch b/queue-6.1/drm-amdgpu-fix-the-null-pointer-dereference-to-ras_m.patch new file mode 100644 index 00000000000..529d5f96d18 --- /dev/null +++ b/queue-6.1/drm-amdgpu-fix-the-null-pointer-dereference-to-ras_m.patch @@ -0,0 +1,44 @@ +From 6ecbc3fcff3f9f1b60058900a9c1244f6c64fb20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 11 May 2024 15:48:02 +0800 +Subject: drm/amdgpu: Fix the null pointer dereference to ras_manager + +From: Ma Jun + +[ Upstream commit 4c11d30c95576937c6c35e6f29884761f2dddb43 ] + +Check ras_manager before using it + +Signed-off-by: Ma Jun +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index ee83d282b49a8..4b7b3278a05f1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -1679,12 +1679,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work) + int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, + struct ras_dispatch_if *info) + { +- struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); +- struct ras_ih_data *data = &obj->ih_data; ++ struct ras_manager *obj; ++ struct ras_ih_data *data; + ++ obj = amdgpu_ras_find_obj(adev, &info->head); + if (!obj) + return -EINVAL; + ++ data = &obj->ih_data; ++ + if (data->inuse == 0) + return 0; + +-- +2.43.0 + diff --git a/queue-6.1/drm-amdgpu-pm-fix-the-null-pointer-dereference-for-s.patch b/queue-6.1/drm-amdgpu-pm-fix-the-null-pointer-dereference-for-s.patch new file mode 100644 index 00000000000..11ddac653b6 --- /dev/null +++ b/queue-6.1/drm-amdgpu-pm-fix-the-null-pointer-dereference-for-s.patch @@ -0,0 +1,99 @@ +From ad4a72b332991b9663febaccd5f7e4c5cfd71651 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 May 2024 15:01:59 +0800 +Subject: drm/amdgpu/pm: Fix the null pointer dereference for smu7 + +From: Ma Jun + +[ Upstream commit c02c1960c93eede587576625a1221205a68a904f ] + +optimize the code to avoid pass a null pointer (hwmgr->backend) +to function smu7_update_edc_leakage_table. + +Signed-off-by: Ma Jun +Reviewed-by: Yang Wang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 50 +++++++++---------- + 1 file changed, 24 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index 5e9410117712c..9f2f3f6a79adb 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -2970,6 +2970,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr) + + static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + { ++ struct amdgpu_device *adev = hwmgr->adev; + struct smu7_hwmgr *data; + int result = 0; + +@@ -3006,40 +3007,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) + /* Initalize Dynamic State Adjustment Rule Settings */ + result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr); + +- if (0 == result) { +- struct amdgpu_device *adev = hwmgr->adev; ++ if (result) ++ goto fail; + +- data->is_tlu_enabled = false; ++ data->is_tlu_enabled = false; + +- hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = ++ hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = + SMU7_MAX_HARDWARE_POWERLEVELS; +- hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; +- hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; ++ hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; ++ hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; + +- data->pcie_gen_cap = adev->pm.pcie_gen_mask; +- if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) +- data->pcie_spc_cap = 20; +- else +- data->pcie_spc_cap = 16; +- data->pcie_lane_cap = adev->pm.pcie_mlw_mask; +- +- hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ +-/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ +- hwmgr->platform_descriptor.clockStep.engineClock = 500; +- hwmgr->platform_descriptor.clockStep.memoryClock = 500; +- smu7_thermal_parameter_init(hwmgr); +- } else { +- /* Ignore return value in here, we are cleaning up a mess. */ +- smu7_hwmgr_backend_fini(hwmgr); +- } ++ data->pcie_gen_cap = adev->pm.pcie_gen_mask; ++ if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) ++ data->pcie_spc_cap = 20; ++ else ++ data->pcie_spc_cap = 16; ++ data->pcie_lane_cap = adev->pm.pcie_mlw_mask; ++ ++ hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ ++ /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ ++ hwmgr->platform_descriptor.clockStep.engineClock = 500; ++ hwmgr->platform_descriptor.clockStep.memoryClock = 500; ++ smu7_thermal_parameter_init(hwmgr); + + result = smu7_update_edc_leakage_table(hwmgr); +- if (result) { +- smu7_hwmgr_backend_fini(hwmgr); +- return result; +- } ++ if (result) ++ goto fail; + + return 0; ++fail: ++ smu7_hwmgr_backend_fini(hwmgr); ++ return result; + } + + static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr) +-- +2.43.0 + diff --git a/queue-6.1/drm-amdgpu-pm-fix-the-null-pointer-dereference-in-ap.patch b/queue-6.1/drm-amdgpu-pm-fix-the-null-pointer-dereference-in-ap.patch new file mode 100644 index 00000000000..277d4687614 --- /dev/null +++ b/queue-6.1/drm-amdgpu-pm-fix-the-null-pointer-dereference-in-ap.patch @@ -0,0 +1,105 @@ +From f30e02ede36a3ebba40db547e938db9540cc106e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 May 2024 15:51:35 +0800 +Subject: drm/amdgpu/pm: Fix the null pointer dereference in + apply_state_adjust_rules + +From: Ma Jun + +[ Upstream commit d19fb10085a49b77578314f69fff21562f7cd054 ] + +Check the pointer value to fix potential null pointer +dereference + +Acked-by: Yang Wang +Signed-off-by: Ma Jun +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 7 +++++-- + .../gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c | 14 ++++++++------ + .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 7 +++++-- + 3 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +index 9f2f3f6a79adb..750b7527bdf83 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +@@ -3327,8 +3327,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + const struct pp_power_state *current_ps) + { + struct amdgpu_device *adev = hwmgr->adev; +- struct smu7_power_state *smu7_ps = +- cast_phw_smu7_power_state(&request_ps->hardware); ++ struct smu7_power_state *smu7_ps; + uint32_t sclk; + uint32_t mclk; + struct PP_Clocks minimum_clocks = {0}; +@@ -3345,6 +3344,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + uint32_t latency; + bool latency_allowed = false; + ++ smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware); ++ if (!smu7_ps) ++ return -EINVAL; ++ + data->battery_state = (PP_StateUILabel_Battery == + request_ps->classification.ui_label); + data->mclk_ignore_signal = false; +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +index b015a601b385a..eb744401e0567 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +@@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + struct pp_power_state *prequest_ps, + const struct pp_power_state *pcurrent_ps) + { +- struct smu8_power_state *smu8_ps = +- cast_smu8_power_state(&prequest_ps->hardware); +- +- const struct smu8_power_state *smu8_current_ps = +- cast_const_smu8_power_state(&pcurrent_ps->hardware); +- ++ struct smu8_power_state *smu8_ps; ++ const struct smu8_power_state *smu8_current_ps; + struct smu8_hwmgr *data = hwmgr->backend; + struct PP_Clocks clocks = {0, 0, 0, 0}; + bool force_high; + ++ smu8_ps = cast_smu8_power_state(&prequest_ps->hardware); ++ smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware); ++ ++ if (!smu8_ps || !smu8_current_ps) ++ return -EINVAL; ++ + smu8_ps->need_dfs_bypass = true; + + data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +index d8cd23438b762..2628f12e0eedc 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +@@ -3263,8 +3263,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + const struct pp_power_state *current_ps) + { + struct amdgpu_device *adev = hwmgr->adev; +- struct vega10_power_state *vega10_ps = +- cast_phw_vega10_power_state(&request_ps->hardware); ++ struct vega10_power_state *vega10_ps; + uint32_t sclk; + uint32_t mclk; + struct PP_Clocks minimum_clocks = {0}; +@@ -3282,6 +3281,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, + uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; + uint32_t latency; + ++ vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware); ++ if (!vega10_ps) ++ return -EINVAL; ++ + data->battery_state = (PP_StateUILabel_Battery == + request_ps->classification.ui_label); + +-- +2.43.0 + diff --git a/queue-6.1/drm-amdgpu-pm-fix-the-param-type-of-set_power_profil.patch b/queue-6.1/drm-amdgpu-pm-fix-the-param-type-of-set_power_profil.patch new file mode 100644 index 00000000000..709523245f9 --- /dev/null +++ b/queue-6.1/drm-amdgpu-pm-fix-the-param-type-of-set_power_profil.patch @@ -0,0 +1,151 @@ +From 7b56a67752c54fa59d8b2f4288ffd4e7daa0f1c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Apr 2024 15:58:10 +0800 +Subject: drm/amdgpu/pm: Fix the param type of set_power_profile_mode + +From: Ma Jun + +[ Upstream commit f683f24093dd94a831085fe0ea8e9dc4c6c1a2d1 ] + +Function .set_power_profile_mode need an array as input +parameter. So define variable workload as an array to fix +the below coverity warning. + +"Passing &workload to function hwmgr->hwmgr_func->set_power_profile_mode +which uses it as an array. This might corrupt or misinterpret adjacent +memory locations" + +Signed-off-by: Ma Jun +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c | 8 ++++---- + drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c | 8 ++++---- + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 16 ++++++++-------- + 3 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +index 179e1c593a53f..f3668911a88fd 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +@@ -928,7 +928,7 @@ static int pp_dpm_switch_power_profile(void *handle, + enum PP_SMC_POWER_PROFILE type, bool en) + { + struct pp_hwmgr *hwmgr = handle; +- long workload; ++ long workload[1]; + uint32_t index; + + if (!hwmgr || !hwmgr->pm_en) +@@ -946,12 +946,12 @@ static int pp_dpm_switch_power_profile(void *handle, + hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); + index = fls(hwmgr->workload_mask); + index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; +- workload = hwmgr->workload_setting[index]; ++ workload[0] = hwmgr->workload_setting[index]; + } else { + hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); + index = fls(hwmgr->workload_mask); + index = index <= Workload_Policy_Max ? index - 1 : 0; +- workload = hwmgr->workload_setting[index]; ++ workload[0] = hwmgr->workload_setting[index]; + } + + if (type == PP_SMC_POWER_PROFILE_COMPUTE && +@@ -961,7 +961,7 @@ static int pp_dpm_switch_power_profile(void *handle, + } + + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) +- hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); ++ hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); + + return 0; + } +diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +index 1d829402cd2e2..f4bd8e9357e22 100644 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +@@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set + struct pp_power_state *new_ps) + { + uint32_t index; +- long workload; ++ long workload[1]; + + if (hwmgr->not_vf) { + if (!skip_display_settings) +@@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { + index = fls(hwmgr->workload_mask); + index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; +- workload = hwmgr->workload_setting[index]; ++ workload[0] = hwmgr->workload_setting[index]; + +- if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) +- hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); ++ if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode) ++ hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); + } + + return 0; +diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +index 1d0693dad8185..91f0646eb3ee0 100644 +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -1834,7 +1834,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, + { + int ret = 0; + int index = 0; +- long workload; ++ long workload[1]; + struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); + + if (!skip_display_settings) { +@@ -1874,10 +1874,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { + index = fls(smu->workload_mask); + index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; +- workload = smu->workload_setting[index]; ++ workload[0] = smu->workload_setting[index]; + +- if (smu->power_profile_mode != workload) +- smu_bump_power_profile_mode(smu, &workload, 0); ++ if (smu->power_profile_mode != workload[0]) ++ smu_bump_power_profile_mode(smu, workload, 0); + } + + return ret; +@@ -1927,7 +1927,7 @@ static int smu_switch_power_profile(void *handle, + { + struct smu_context *smu = handle; + struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); +- long workload; ++ long workload[1]; + uint32_t index; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) +@@ -1940,17 +1940,17 @@ static int smu_switch_power_profile(void *handle, + smu->workload_mask &= ~(1 << smu->workload_prority[type]); + index = fls(smu->workload_mask); + index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; +- workload = smu->workload_setting[index]; ++ workload[0] = smu->workload_setting[index]; + } else { + smu->workload_mask |= (1 << smu->workload_prority[type]); + index = fls(smu->workload_mask); + index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; +- workload = smu->workload_setting[index]; ++ workload[0] = smu->workload_setting[index]; + } + + if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) +- smu_bump_power_profile_mode(smu, &workload, 0); ++ smu_bump_power_profile_mode(smu, workload, 0); + + return 0; + } +-- +2.43.0 + diff --git a/queue-6.1/ext4-fix-uninitialized-variable-in-ext4_inlinedir_to.patch b/queue-6.1/ext4-fix-uninitialized-variable-in-ext4_inlinedir_to.patch new file mode 100644 index 00000000000..c49af34572f --- /dev/null +++ b/queue-6.1/ext4-fix-uninitialized-variable-in-ext4_inlinedir_to.patch @@ -0,0 +1,48 @@ +From c062d36ace41f0def6d87cfa8dbc916a16a4b48a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 20:30:17 -0700 +Subject: ext4: fix uninitialized variable in ext4_inlinedir_to_tree + +From: Xiaxi Shen + +[ Upstream commit 8dc9c3da79c84b13fdb135e2fb0a149a8175bffe ] + +Syzbot has found an uninit-value bug in ext4_inlinedir_to_tree + +This error happens because ext4_inlinedir_to_tree does not +handle the case when ext4fs_dirhash returns an error + +This can be avoided by checking the return value of ext4fs_dirhash +and propagating the error, +similar to how it's done with ext4_htree_store_dirent + +Signed-off-by: Xiaxi Shen +Reported-and-tested-by: syzbot+eaba5abe296837a640c0@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=eaba5abe296837a640c0 +Link: https://patch.msgid.link/20240501033017.220000-1-shenxiaxi26@gmail.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/inline.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index 3a91be1d9bbe7..ee9d2faa5218f 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1439,7 +1439,11 @@ int ext4_inlinedir_to_tree(struct file *dir_file, + hinfo->hash = EXT4_DIRENT_HASH(de); + hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de); + } else { +- ext4fs_dirhash(dir, de->name, de->name_len, hinfo); ++ err = ext4fs_dirhash(dir, de->name, de->name_len, hinfo); ++ if (err) { ++ ret = err; ++ goto out; ++ } + } + if ((hinfo->hash < start_hash) || + ((hinfo->hash == start_hash) && +-- +2.43.0 + diff --git a/queue-6.1/irqchip-mbigen-fix-mbigen-node-address-layout.patch b/queue-6.1/irqchip-mbigen-fix-mbigen-node-address-layout.patch new file mode 100644 index 00000000000..b5c72b248e8 --- /dev/null +++ b/queue-6.1/irqchip-mbigen-fix-mbigen-node-address-layout.patch @@ -0,0 +1,89 @@ +From b3edba42e53f79f1da5276410b4e8070b7ead4b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jul 2024 09:44:00 +0800 +Subject: irqchip/mbigen: Fix mbigen node address layout + +From: Yipeng Zou + +[ Upstream commit 6be6cba9c4371d27f78d900ccfe34bb880d9ee20 ] + +The mbigen interrupt chip has its per node registers located in a +contiguous region of page sized chunks. The code maps them into virtual +address space as a contiguous region and determines the address of a node +by using the node ID as index. + + mbigen chip + |-----------------|------------|--------------| + mgn_node_0 mgn_node_1 ... mgn_node_i +|--------------| |--------------| |----------------------| +[0x0000, 0x0x0FFF] [0x1000, 0x1FFF] [i*0x1000, (i+1)*0x1000 - 1] + +This works correctly up to 10 nodes, but then fails because the 11th's +array slot is used for the MGN_CLEAR registers. + + mbigen chip + |-----------|--------|--------|---------------|--------| +mgn_node_0 mgn_node_1 ... mgn_clear_register ... mgn_node_i + |-----------------| + [0xA000, 0xAFFF] + +Skip the MGN_CLEAR register space when calculating the offset for node IDs +greater than or equal to ten. + +Fixes: a6c2f87b8820 ("irqchip/mbigen: Implement the mbigen irq chip operation functions") +Signed-off-by: Yipeng Zou +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/all/20240730014400.1751530-1-zouyipeng@huawei.com +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-mbigen.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c +index f3faf5c997706..23117a30c6275 100644 +--- a/drivers/irqchip/irq-mbigen.c ++++ b/drivers/irqchip/irq-mbigen.c +@@ -64,6 +64,20 @@ struct mbigen_device { + void __iomem *base; + }; + ++static inline unsigned int get_mbigen_node_offset(unsigned int nid) ++{ ++ unsigned int offset = nid * MBIGEN_NODE_OFFSET; ++ ++ /* ++ * To avoid touched clear register in unexpected way, we need to directly ++ * skip clear register when access to more than 10 mbigen nodes. ++ */ ++ if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET)) ++ offset += MBIGEN_NODE_OFFSET; ++ ++ return offset; ++} ++ + static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) + { + unsigned int nid, pin; +@@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) + nid = hwirq / IRQS_PER_MBIGEN_NODE + 1; + pin = hwirq % IRQS_PER_MBIGEN_NODE; + +- return pin * 4 + nid * MBIGEN_NODE_OFFSET +- + REG_MBIGEN_VEC_OFFSET; ++ return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET; + } + + static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, +@@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, + *mask = 1 << (irq_ofst % 32); + ofst = irq_ofst / 32 * 4; + +- *addr = ofst + nid * MBIGEN_NODE_OFFSET +- + REG_MBIGEN_TYPE_OFFSET; ++ *addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET; + } + + static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, +-- +2.43.0 + diff --git a/queue-6.1/jbd2-avoid-memleak-in-jbd2_journal_write_metadata_bu.patch b/queue-6.1/jbd2-avoid-memleak-in-jbd2_journal_write_metadata_bu.patch new file mode 100644 index 00000000000..99188f31ead --- /dev/null +++ b/queue-6.1/jbd2-avoid-memleak-in-jbd2_journal_write_metadata_bu.patch @@ -0,0 +1,37 @@ +From 665963f438b060c85c4cc0e786128f8d1d94878f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 May 2024 19:24:30 +0800 +Subject: jbd2: avoid memleak in jbd2_journal_write_metadata_buffer + +From: Kemeng Shi + +[ Upstream commit cc102aa24638b90e04364d64e4f58a1fa91a1976 ] + +The new_bh is from alloc_buffer_head, we should call free_buffer_head to +free it in error case. + +Signed-off-by: Kemeng Shi +Reviewed-by: Zhang Yi +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20240514112438.1269037-2-shikemeng@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/jbd2/journal.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index b136b46b63bc9..c8d59f7c47453 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -409,6 +409,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, + tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); + if (!tmp) { + brelse(new_bh); ++ free_buffer_head(new_bh); + return -ENOMEM; + } + spin_lock(&jh_in->b_state_lock); +-- +2.43.0 + diff --git a/queue-6.1/jump_label-fix-the-fix-brown-paper-bags-galore.patch b/queue-6.1/jump_label-fix-the-fix-brown-paper-bags-galore.patch new file mode 100644 index 00000000000..e00cc70be76 --- /dev/null +++ b/queue-6.1/jump_label-fix-the-fix-brown-paper-bags-galore.patch @@ -0,0 +1,62 @@ +From 9ba591b6a74a087995bbddef9200b2902759e05c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 12:43:21 +0200 +Subject: jump_label: Fix the fix, brown paper bags galore + +From: Peter Zijlstra + +[ Upstream commit 224fa3552029a3d14bec7acf72ded8171d551b88 ] + +Per the example of: + + !atomic_cmpxchg(&key->enabled, 0, 1) + +the inverse was written as: + + atomic_cmpxchg(&key->enabled, 1, 0) + +except of course, that while !old is only true for old == 0, old is +true for everything except old == 0. + +Fix it to read: + + atomic_cmpxchg(&key->enabled, 1, 0) == 1 + +such that only the 1->0 transition returns true and goes on to disable +the keys. + +Fixes: 83ab38ef0a0b ("jump_label: Fix concurrency issues in static_key_slow_dec()") +Reported-by: Darrick J. Wong +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Darrick J. Wong +Link: https://lkml.kernel.org/r/20240731105557.GY33588@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + kernel/jump_label.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/jump_label.c b/kernel/jump_label.c +index eec802175ccc6..1ed269b2c4035 100644 +--- a/kernel/jump_label.c ++++ b/kernel/jump_label.c +@@ -231,7 +231,7 @@ void static_key_disable_cpuslocked(struct static_key *key) + } + + jump_label_lock(); +- if (atomic_cmpxchg(&key->enabled, 1, 0)) ++ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) + jump_label_update(key); + jump_label_unlock(); + } +@@ -284,7 +284,7 @@ static void __static_key_slow_dec_cpuslocked(struct static_key *key) + return; + + guard(mutex)(&jump_label_mutex); +- if (atomic_cmpxchg(&key->enabled, 1, 0)) ++ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) + jump_label_update(key); + else + WARN_ON_ONCE(!static_key_slow_try_dec(key)); +-- +2.43.0 + diff --git a/queue-6.1/l2tp-fix-lockdep-splat.patch b/queue-6.1/l2tp-fix-lockdep-splat.patch new file mode 100644 index 00000000000..5720644d34d --- /dev/null +++ b/queue-6.1/l2tp-fix-lockdep-splat.patch @@ -0,0 +1,216 @@ +From 8d1b96ba8ab7a43fa034939644552032ccb91510 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Aug 2024 17:06:26 +0100 +Subject: l2tp: fix lockdep splat + +From: James Chapman + +[ Upstream commit 86a41ea9fd79ddb6145cb8ebf5aeafceabca6f7d ] + +When l2tp tunnels use a socket provided by userspace, we can hit +lockdep splats like the below when data is transmitted through another +(unrelated) userspace socket which then gets routed over l2tp. + +This issue was previously discussed here: +https://lore.kernel.org/netdev/87sfialu2n.fsf@cloudflare.com/ + +The solution is to have lockdep treat socket locks of l2tp tunnel +sockets separately than those of standard INET sockets. To do so, use +a different lockdep subclass where lock nesting is possible. + + ============================================ + WARNING: possible recursive locking detected + 6.10.0+ #34 Not tainted + -------------------------------------------- + iperf3/771 is trying to acquire lock: + ffff8881027601d8 (slock-AF_INET/1){+.-.}-{2:2}, at: l2tp_xmit_skb+0x243/0x9d0 + + but task is already holding lock: + ffff888102650d98 (slock-AF_INET/1){+.-.}-{2:2}, at: tcp_v4_rcv+0x1848/0x1e10 + + other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(slock-AF_INET/1); + lock(slock-AF_INET/1); + + *** DEADLOCK *** + + May be due to missing lock nesting notation + + 10 locks held by iperf3/771: + #0: ffff888102650258 (sk_lock-AF_INET){+.+.}-{0:0}, at: tcp_sendmsg+0x1a/0x40 + #1: ffffffff822ac220 (rcu_read_lock){....}-{1:2}, at: __ip_queue_xmit+0x4b/0xbc0 + #2: ffffffff822ac220 (rcu_read_lock){....}-{1:2}, at: ip_finish_output2+0x17a/0x1130 + #3: ffffffff822ac220 (rcu_read_lock){....}-{1:2}, at: process_backlog+0x28b/0x9f0 + #4: ffffffff822ac220 (rcu_read_lock){....}-{1:2}, at: ip_local_deliver_finish+0xf9/0x260 + #5: ffff888102650d98 (slock-AF_INET/1){+.-.}-{2:2}, at: tcp_v4_rcv+0x1848/0x1e10 + #6: ffffffff822ac220 (rcu_read_lock){....}-{1:2}, at: __ip_queue_xmit+0x4b/0xbc0 + #7: ffffffff822ac220 (rcu_read_lock){....}-{1:2}, at: ip_finish_output2+0x17a/0x1130 + #8: ffffffff822ac1e0 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0xcc/0x1450 + #9: ffff888101f33258 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2){+...}-{2:2}, at: __dev_queue_xmit+0x513/0x1450 + + stack backtrace: + CPU: 2 UID: 0 PID: 771 Comm: iperf3 Not tainted 6.10.0+ #34 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 + Call Trace: + + dump_stack_lvl+0x69/0xa0 + dump_stack+0xc/0x20 + __lock_acquire+0x135d/0x2600 + ? srso_alias_return_thunk+0x5/0xfbef5 + lock_acquire+0xc4/0x2a0 + ? l2tp_xmit_skb+0x243/0x9d0 + ? __skb_checksum+0xa3/0x540 + _raw_spin_lock_nested+0x35/0x50 + ? l2tp_xmit_skb+0x243/0x9d0 + l2tp_xmit_skb+0x243/0x9d0 + l2tp_eth_dev_xmit+0x3c/0xc0 + dev_hard_start_xmit+0x11e/0x420 + sch_direct_xmit+0xc3/0x640 + __dev_queue_xmit+0x61c/0x1450 + ? ip_finish_output2+0xf4c/0x1130 + ip_finish_output2+0x6b6/0x1130 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __ip_finish_output+0x217/0x380 + ? srso_alias_return_thunk+0x5/0xfbef5 + __ip_finish_output+0x217/0x380 + ip_output+0x99/0x120 + __ip_queue_xmit+0xae4/0xbc0 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? tcp_options_write.constprop.0+0xcb/0x3e0 + ip_queue_xmit+0x34/0x40 + __tcp_transmit_skb+0x1625/0x1890 + __tcp_send_ack+0x1b8/0x340 + tcp_send_ack+0x23/0x30 + __tcp_ack_snd_check+0xa8/0x530 + ? srso_alias_return_thunk+0x5/0xfbef5 + tcp_rcv_established+0x412/0xd70 + tcp_v4_do_rcv+0x299/0x420 + tcp_v4_rcv+0x1991/0x1e10 + ip_protocol_deliver_rcu+0x50/0x220 + ip_local_deliver_finish+0x158/0x260 + ip_local_deliver+0xc8/0xe0 + ip_rcv+0xe5/0x1d0 + ? __pfx_ip_rcv+0x10/0x10 + __netif_receive_skb_one_core+0xce/0xe0 + ? process_backlog+0x28b/0x9f0 + __netif_receive_skb+0x34/0xd0 + ? process_backlog+0x28b/0x9f0 + process_backlog+0x2cb/0x9f0 + __napi_poll.constprop.0+0x61/0x280 + net_rx_action+0x332/0x670 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? find_held_lock+0x2b/0x80 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + handle_softirqs+0xda/0x480 + ? __dev_queue_xmit+0xa2c/0x1450 + do_softirq+0xa1/0xd0 + + + __local_bh_enable_ip+0xc8/0xe0 + ? __dev_queue_xmit+0xa2c/0x1450 + __dev_queue_xmit+0xa48/0x1450 + ? ip_finish_output2+0xf4c/0x1130 + ip_finish_output2+0x6b6/0x1130 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __ip_finish_output+0x217/0x380 + ? srso_alias_return_thunk+0x5/0xfbef5 + __ip_finish_output+0x217/0x380 + ip_output+0x99/0x120 + __ip_queue_xmit+0xae4/0xbc0 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? tcp_options_write.constprop.0+0xcb/0x3e0 + ip_queue_xmit+0x34/0x40 + __tcp_transmit_skb+0x1625/0x1890 + tcp_write_xmit+0x766/0x2fb0 + ? __entry_text_end+0x102ba9/0x102bad + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __might_fault+0x74/0xc0 + ? srso_alias_return_thunk+0x5/0xfbef5 + __tcp_push_pending_frames+0x56/0x190 + tcp_push+0x117/0x310 + tcp_sendmsg_locked+0x14c1/0x1740 + tcp_sendmsg+0x28/0x40 + inet_sendmsg+0x5d/0x90 + sock_write_iter+0x242/0x2b0 + vfs_write+0x68d/0x800 + ? __pfx_sock_write_iter+0x10/0x10 + ksys_write+0xc8/0xf0 + __x64_sys_write+0x3d/0x50 + x64_sys_call+0xfaf/0x1f50 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + RIP: 0033:0x7f4d143af992 + Code: c3 8b 07 85 c0 75 24 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 e9 01 cc ff ff 41 54 b8 02 00 00 0 + RSP: 002b:00007ffd65032058 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f4d143af992 + RDX: 0000000000000025 RSI: 00007f4d143f3bcc RDI: 0000000000000005 + RBP: 00007f4d143f2b28 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 00007f4d143f3bcc + R13: 0000000000000005 R14: 0000000000000000 R15: 00007ffd650323f0 + + +Fixes: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()") +Suggested-by: Eric Dumazet +Reported-by: syzbot+6acef9e0a4d1f46c83d4@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=6acef9e0a4d1f46c83d4 +CC: gnault@redhat.com +CC: cong.wang@bytedance.com +Signed-off-by: James Chapman +Signed-off-by: Tom Parkin +Link: https://patch.msgid.link/20240806160626.1248317-1-jchapman@katalix.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/l2tp/l2tp_core.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index 8d21ff25f1602..70da78ab95202 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -88,6 +88,11 @@ + /* Default trace flags */ + #define L2TP_DEFAULT_DEBUG_FLAGS 0 + ++#define L2TP_DEPTH_NESTING 2 ++#if L2TP_DEPTH_NESTING == SINGLE_DEPTH_NESTING ++#error "L2TP requires its own lockdep subclass" ++#endif ++ + /* Private data stored for received packets in the skb. + */ + struct l2tp_skb_cb { +@@ -1041,7 +1046,13 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); + nf_reset_ct(skb); + +- bh_lock_sock_nested(sk); ++ /* L2TP uses its own lockdep subclass to avoid lockdep splats caused by ++ * nested socket calls on the same lockdep socket class. This can ++ * happen when data from a user socket is routed over l2tp, which uses ++ * another userspace socket. ++ */ ++ spin_lock_nested(&sk->sk_lock.slock, L2TP_DEPTH_NESTING); ++ + if (sock_owned_by_user(sk)) { + kfree_skb(skb); + ret = NET_XMIT_DROP; +@@ -1093,7 +1104,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns + ret = l2tp_xmit_queue(tunnel, skb, &inet->cork.fl); + + out_unlock: +- bh_unlock_sock(sk); ++ spin_unlock(&sk->sk_lock.slock); + + return ret; + } +-- +2.43.0 + diff --git a/queue-6.1/md-do-not-delete-safemode_timer-in-mddev_suspend.patch b/queue-6.1/md-do-not-delete-safemode_timer-in-mddev_suspend.patch new file mode 100644 index 00000000000..bfbfb0dca07 --- /dev/null +++ b/queue-6.1/md-do-not-delete-safemode_timer-in-mddev_suspend.patch @@ -0,0 +1,48 @@ +From cb829a569e9e351a12c7d2e74f06f58d2ce58948 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 May 2024 17:20:53 +0800 +Subject: md: do not delete safemode_timer in mddev_suspend + +From: Li Nan + +[ Upstream commit a8768a134518e406d41799a3594aeb74e0889cf7 ] + +The deletion of safemode_timer in mddev_suspend() is redundant and +potentially harmful now. If timer is about to be woken up but gets +deleted, 'in_sync' will remain 0 until the next write, causing array +to stay in the 'active' state instead of transitioning to 'clean'. + +Commit 0d9f4f135eb6 ("MD: Add del_timer_sync to mddev_suspend (fix +nasty panic))" introduced this deletion for dm, because if timer fired +after dm is destroyed, the resource which the timer depends on might +have been freed. + +However, commit 0dd84b319352 ("md: call __md_stop_writes in md_stop") +added __md_stop_writes() to md_stop(), which is called before freeing +resource. Timer is deleted in __md_stop_writes(), and the origin issue +is resolved. Therefore, delete safemode_timer can be removed safely now. + +Signed-off-by: Li Nan +Reviewed-by: Yu Kuai +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20240508092053.1447930-1-linan666@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 7dc1c42accccd..b87c6ef0da8ab 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -489,7 +489,6 @@ void mddev_suspend(struct mddev *mddev) + clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags); + wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); + +- del_timer_sync(&mddev->safemode_timer); + /* restrict memory reclaim I/O during raid array is suspend */ + mddev->noio_flag = memalloc_noio_save(); + } +-- +2.43.0 + diff --git a/queue-6.1/md-raid5-avoid-bug_on-while-continue-reshape-after-r.patch b/queue-6.1/md-raid5-avoid-bug_on-while-continue-reshape-after-r.patch new file mode 100644 index 00000000000..4984ade2b3c --- /dev/null +++ b/queue-6.1/md-raid5-avoid-bug_on-while-continue-reshape-after-r.patch @@ -0,0 +1,93 @@ +From a22bce75ca15f08fbba60316ba48532828461c78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Jun 2024 21:22:51 +0800 +Subject: md/raid5: avoid BUG_ON() while continue reshape after reassembling + +From: Yu Kuai + +[ Upstream commit 305a5170dc5cf3d395bb4c4e9239bca6d0b54b49 ] + +Currently, mdadm support --revert-reshape to abort the reshape while +reassembling, as the test 07revert-grow. However, following BUG_ON() +can be triggerred by the test: + +kernel BUG at drivers/md/raid5.c:6278! +invalid opcode: 0000 [#1] PREEMPT SMP PTI +irq event stamp: 158985 +CPU: 6 PID: 891 Comm: md0_reshape Not tainted 6.9.0-03335-g7592a0b0049a #94 +RIP: 0010:reshape_request+0x3f1/0xe60 +Call Trace: + + raid5_sync_request+0x43d/0x550 + md_do_sync+0xb7a/0x2110 + md_thread+0x294/0x2b0 + kthread+0x147/0x1c0 + ret_from_fork+0x59/0x70 + ret_from_fork_asm+0x1a/0x30 + + +Root cause is that --revert-reshape update the raid_disks from 5 to 4, +while reshape position is still set, and after reassembling the array, +reshape position will be read from super block, then during reshape the +checking of 'writepos' that is caculated by old reshape position will +fail. + +Fix this panic the easy way first, by converting the BUG_ON() to +WARN_ON(), and stop the reshape if checkings fail. + +Noted that mdadm must fix --revert-shape as well, and probably md/raid +should enhance metadata validation as well, however this means +reassemble will fail and there must be user tools to fix the wrong +metadata. + +Signed-off-by: Yu Kuai +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20240611132251.1967786-13-yukuai1@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/md/raid5.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index ed99b449d8fd4..4315dabd32023 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -6316,7 +6316,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk + safepos = conf->reshape_safe; + sector_div(safepos, data_disks); + if (mddev->reshape_backwards) { +- BUG_ON(writepos < reshape_sectors); ++ if (WARN_ON(writepos < reshape_sectors)) ++ return MaxSector; ++ + writepos -= reshape_sectors; + readpos += reshape_sectors; + safepos += reshape_sectors; +@@ -6334,14 +6336,18 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk + * to set 'stripe_addr' which is where we will write to. + */ + if (mddev->reshape_backwards) { +- BUG_ON(conf->reshape_progress == 0); ++ if (WARN_ON(conf->reshape_progress == 0)) ++ return MaxSector; ++ + stripe_addr = writepos; +- BUG_ON((mddev->dev_sectors & +- ~((sector_t)reshape_sectors - 1)) +- - reshape_sectors - stripe_addr +- != sector_nr); ++ if (WARN_ON((mddev->dev_sectors & ++ ~((sector_t)reshape_sectors - 1)) - ++ reshape_sectors - stripe_addr != sector_nr)) ++ return MaxSector; + } else { +- BUG_ON(writepos != sector_nr + reshape_sectors); ++ if (WARN_ON(writepos != sector_nr + reshape_sectors)) ++ return MaxSector; ++ + stripe_addr = sector_nr; + } + +-- +2.43.0 + diff --git a/queue-6.1/media-amphion-remove-lock-in-s_ctrl-callback.patch b/queue-6.1/media-amphion-remove-lock-in-s_ctrl-callback.patch new file mode 100644 index 00000000000..db6680a80e5 --- /dev/null +++ b/queue-6.1/media-amphion-remove-lock-in-s_ctrl-callback.patch @@ -0,0 +1,65 @@ +From 93aad2ac34ac79dd2e07cd7df884365a3d834070 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 May 2024 17:49:17 +0900 +Subject: media: amphion: Remove lock in s_ctrl callback + +From: Ming Qian + +[ Upstream commit 065927b51eb1f042c3e026cebfd55e72ccc26093 ] + +There is no need to add a lock in s_ctrl callback, it has been +synchronized by the ctrl_handler's lock, otherwise it may led to +a deadlock if the driver calls v4l2_ctrl_s_ctrl(). + +Signed-off-by: Ming Qian +Signed-off-by: Sebastian Fricke +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/amphion/vdec.c | 2 -- + drivers/media/platform/amphion/venc.c | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c +index dc35a87e628ec..2bfab4467b81c 100644 +--- a/drivers/media/platform/amphion/vdec.c ++++ b/drivers/media/platform/amphion/vdec.c +@@ -145,7 +145,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) + struct vdec_t *vdec = inst->priv; + int ret = 0; + +- vpu_inst_lock(inst); + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: + vdec->params.display_delay_enable = ctrl->val; +@@ -157,7 +156,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) + ret = -EINVAL; + break; + } +- vpu_inst_unlock(inst); + + return ret; + } +diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c +index 1df2b35c1a240..c9cfef16c5b92 100644 +--- a/drivers/media/platform/amphion/venc.c ++++ b/drivers/media/platform/amphion/venc.c +@@ -528,7 +528,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) + struct venc_t *venc = inst->priv; + int ret = 0; + +- vpu_inst_lock(inst); + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + venc->params.profile = ctrl->val; +@@ -589,7 +588,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) + ret = -EINVAL; + break; + } +- vpu_inst_unlock(inst); + + return ret; + } +-- +2.43.0 + diff --git a/queue-6.1/media-uvcvideo-fix-the-bandwdith-quirk-on-usb-3.x.patch b/queue-6.1/media-uvcvideo-fix-the-bandwdith-quirk-on-usb-3.x.patch new file mode 100644 index 00000000000..4abb3627130 --- /dev/null +++ b/queue-6.1/media-uvcvideo-fix-the-bandwdith-quirk-on-usb-3.x.patch @@ -0,0 +1,52 @@ +From 4797b6cc1c081e3e2e1a09326b0170295fb3e353 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Apr 2024 19:00:40 +0200 +Subject: media: uvcvideo: Fix the bandwdith quirk on USB 3.x + +From: Michal Pecio + +[ Upstream commit 9e3d55fbd160b3ca376599a68b4cddfdc67d4153 ] + +The bandwidth fixup quirk doesn't know that SuperSpeed exists and has +the same 8 service intervals per millisecond as High Speed, hence its +calculations are wrong. + +Assume that all speeds from HS up use 8 intervals per millisecond. + +No further changes are needed, updated code has been confirmed to work +with all speeds from FS to SS. + +Signed-off-by: Michal Pecio +Reviewed-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Link: https://lore.kernel.org/r/20240414190040.2255a0bc@foxbook +Signed-off-by: Laurent Pinchart +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_video.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c +index 7ca0760574598..aa0a879a9c64a 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -212,13 +212,13 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, + * Compute a bandwidth estimation by multiplying the frame + * size by the number of video frames per second, divide the + * result by the number of USB frames (or micro-frames for +- * high-speed devices) per second and add the UVC header size +- * (assumed to be 12 bytes long). ++ * high- and super-speed devices) per second and add the UVC ++ * header size (assumed to be 12 bytes long). + */ + bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; + bandwidth *= 10000000 / interval + 1; + bandwidth /= 1000; +- if (stream->dev->udev->speed == USB_SPEED_HIGH) ++ if (stream->dev->udev->speed >= USB_SPEED_HIGH) + bandwidth /= 8; + bandwidth += 12; + +-- +2.43.0 + diff --git a/queue-6.1/media-uvcvideo-ignore-empty-ts-packets.patch b/queue-6.1/media-uvcvideo-ignore-empty-ts-packets.patch new file mode 100644 index 00000000000..6fdc63fac82 --- /dev/null +++ b/queue-6.1/media-uvcvideo-ignore-empty-ts-packets.patch @@ -0,0 +1,129 @@ +From fe6a0b2f4f48e84fd1ddcbefb2220d2b12836e1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Mar 2024 10:48:03 +0000 +Subject: media: uvcvideo: Ignore empty TS packets + +From: Ricardo Ribalda + +[ Upstream commit 5cd7c25f6f0576073b3d03bc4cfb1e8ca63a1195 ] + +Some SunplusIT cameras took a borderline interpretation of the UVC 1.5 +standard, and fill the PTS and SCR fields with invalid data if the +package does not contain data. + +"STC must be captured when the first video data of a video frame is put +on the USB bus." + +Some SunplusIT devices send, e.g., + +buffer: 0xa7755c00 len 000012 header:0x8c stc 00000000 sof 0000 pts 00000000 +buffer: 0xa7755c00 len 000012 header:0x8c stc 00000000 sof 0000 pts 00000000 +buffer: 0xa7755c00 len 000668 header:0x8c stc 73779dba sof 070c pts 7376d37a + +While the UVC specification meant that the first two packets shouldn't +have had the SCR bit set in the header. + +This borderline/buggy interpretation has been implemented in a variety +of devices, from directly SunplusIT and from other OEMs that rebrand +SunplusIT products. So quirking based on VID:PID will be problematic. + +All the affected modules have the following extension unit: +VideoControl Interface Descriptor: + guidExtensionCode {82066163-7050-ab49-b8cc-b3855e8d221d} + +But the vendor plans to use that GUID in the future and fix the bug, +this means that we should use heuristic to figure out the broken +packets. + +This patch takes care of this. + +lsusb of one of the affected cameras: + +Bus 001 Device 003: ID 1bcf:2a01 Sunplus Innovation Technology Inc. +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.01 + bDeviceClass 239 Miscellaneous Device + bDeviceSubClass 2 ? + bDeviceProtocol 1 Interface Association + bMaxPacketSize0 64 + idVendor 0x1bcf Sunplus Innovation Technology Inc. + idProduct 0x2a01 + bcdDevice 0.02 + iManufacturer 1 SunplusIT Inc + iProduct 2 HanChen Wise Camera + iSerial 3 01.00.00 + bNumConfigurations 1 + +Tested-by: HungNien Chen +Reviewed-by: Sergey Senozhatsky +Reviewed-by: Laurent Pinchart +Signed-off-by: Ricardo Ribalda +Reviewed-by: Tomasz Figa +Link: https://lore.kernel.org/r/20240323-resend-hwtimestamp-v10-2-b08e590d97c7@chromium.org +Signed-off-by: Laurent Pinchart +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_video.c | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c +index a5ad3ff8bdbb9..7ca0760574598 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -476,6 +476,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + ktime_t time; + u16 host_sof; + u16 dev_sof; ++ u32 dev_stc; + + switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { + case UVC_STREAM_PTS | UVC_STREAM_SCR: +@@ -522,6 +523,34 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + if (dev_sof == stream->clock.last_sof) + return; + ++ dev_stc = get_unaligned_le32(&data[header_size - 6]); ++ ++ /* ++ * STC (Source Time Clock) is the clock used by the camera. The UVC 1.5 ++ * standard states that it "must be captured when the first video data ++ * of a video frame is put on the USB bus". This is generally understood ++ * as requiring devices to clear the payload header's SCR bit before ++ * the first packet containing video data. ++ * ++ * Most vendors follow that interpretation, but some (namely SunplusIT ++ * on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR ++ * field with 0's,and expect that the driver only processes the SCR if ++ * there is data in the packet. ++ * ++ * Ignore all the hardware timestamp information if we haven't received ++ * any data for this frame yet, the packet contains no data, and both ++ * STC and SOF are zero. This heuristics should be safe on compliant ++ * devices. This should be safe with compliant devices, as in the very ++ * unlikely case where a UVC 1.1 device would send timing information ++ * only before the first packet containing data, and both STC and SOF ++ * happen to be zero for a particular frame, we would only miss one ++ * clock sample from many and the clock recovery algorithm wouldn't ++ * suffer from this condition. ++ */ ++ if (buf && buf->bytesused == 0 && len == header_size && ++ dev_stc == 0 && dev_sof == 0) ++ return; ++ + stream->clock.last_sof = dev_sof; + + host_sof = usb_get_current_frame_number(stream->dev->udev); +@@ -560,7 +589,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, + spin_lock_irqsave(&stream->clock.lock, flags); + + sample = &stream->clock.samples[stream->clock.head]; +- sample->dev_stc = get_unaligned_le32(&data[header_size - 6]); ++ sample->dev_stc = dev_stc; + sample->dev_sof = dev_sof; + sample->host_sof = host_sof; + sample->host_time = time; +-- +2.43.0 + diff --git a/queue-6.1/media-xc2028-avoid-use-after-free-in-load_firmware_c.patch b/queue-6.1/media-xc2028-avoid-use-after-free-in-load_firmware_c.patch new file mode 100644 index 00000000000..a9323c15ad5 --- /dev/null +++ b/queue-6.1/media-xc2028-avoid-use-after-free-in-load_firmware_c.patch @@ -0,0 +1,129 @@ +From 92d21c015182f79d2dcbc6b8be0a5aa2665ac367 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Jun 2024 08:22:25 -0700 +Subject: media: xc2028: avoid use-after-free in load_firmware_cb() + +From: Chi Zhiling + +[ Upstream commit 68594cec291ff9523b9feb3f43fd853dcddd1f60 ] + +syzkaller reported use-after-free in load_firmware_cb() [1]. +The reason is because the module allocated a struct tuner in tuner_probe(), +and then the module initialization failed, the struct tuner was released. +A worker which created during module initialization accesses this struct +tuner later, it caused use-after-free. + +The process is as follows: + +task-6504 worker_thread +tuner_probe <= alloc dvb_frontend [2] +... +request_firmware_nowait <= create a worker +... +tuner_remove <= free dvb_frontend +... + request_firmware_work_func <= the firmware is ready + load_firmware_cb <= but now the dvb_frontend has been freed + +To fix the issue, check the dvd_frontend in load_firmware_cb(), if it is +null, report a warning and just return. + +[1]: + ================================================================== + BUG: KASAN: use-after-free in load_firmware_cb+0x1310/0x17a0 + Read of size 8 at addr ffff8000d7ca2308 by task kworker/2:3/6504 + + Call trace: + load_firmware_cb+0x1310/0x17a0 + request_firmware_work_func+0x128/0x220 + process_one_work+0x770/0x1824 + worker_thread+0x488/0xea0 + kthread+0x300/0x430 + ret_from_fork+0x10/0x20 + + Allocated by task 6504: + kzalloc + tuner_probe+0xb0/0x1430 + i2c_device_probe+0x92c/0xaf0 + really_probe+0x678/0xcd0 + driver_probe_device+0x280/0x370 + __device_attach_driver+0x220/0x330 + bus_for_each_drv+0x134/0x1c0 + __device_attach+0x1f4/0x410 + device_initial_probe+0x20/0x30 + bus_probe_device+0x184/0x200 + device_add+0x924/0x12c0 + device_register+0x24/0x30 + i2c_new_device+0x4e0/0xc44 + v4l2_i2c_new_subdev_board+0xbc/0x290 + v4l2_i2c_new_subdev+0xc8/0x104 + em28xx_v4l2_init+0x1dd0/0x3770 + + Freed by task 6504: + kfree+0x238/0x4e4 + tuner_remove+0x144/0x1c0 + i2c_device_remove+0xc8/0x290 + __device_release_driver+0x314/0x5fc + device_release_driver+0x30/0x44 + bus_remove_device+0x244/0x490 + device_del+0x350/0x900 + device_unregister+0x28/0xd0 + i2c_unregister_device+0x174/0x1d0 + v4l2_device_unregister+0x224/0x380 + em28xx_v4l2_init+0x1d90/0x3770 + + The buggy address belongs to the object at ffff8000d7ca2000 + which belongs to the cache kmalloc-2k of size 2048 + The buggy address is located 776 bytes inside of + 2048-byte region [ffff8000d7ca2000, ffff8000d7ca2800) + The buggy address belongs to the page: + page:ffff7fe00035f280 count:1 mapcount:0 mapping:ffff8000c001f000 index:0x0 + flags: 0x7ff800000000100(slab) + raw: 07ff800000000100 ffff7fe00049d880 0000000300000003 ffff8000c001f000 + raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000 + page dumped because: kasan: bad access detected + + Memory state around the buggy address: + ffff8000d7ca2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff8000d7ca2280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + >ffff8000d7ca2300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + ffff8000d7ca2380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff8000d7ca2400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ================================================================== + +[2] + Actually, it is allocated for struct tuner, and dvb_frontend is inside. + +Signed-off-by: Chi Zhiling +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/tuners/xc2028.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/tuners/xc2028.c b/drivers/media/tuners/xc2028.c +index 5a967edceca93..352b8a3679b72 100644 +--- a/drivers/media/tuners/xc2028.c ++++ b/drivers/media/tuners/xc2028.c +@@ -1361,9 +1361,16 @@ static void load_firmware_cb(const struct firmware *fw, + void *context) + { + struct dvb_frontend *fe = context; +- struct xc2028_data *priv = fe->tuner_priv; ++ struct xc2028_data *priv; + int rc; + ++ if (!fe) { ++ pr_warn("xc2028: No frontend in %s\n", __func__); ++ return; ++ } ++ ++ priv = fe->tuner_priv; ++ + tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); + if (!fw) { + tuner_err("Could not load firmware %s.\n", priv->fname); +-- +2.43.0 + diff --git a/queue-6.1/net-bridge-mcast-wait-for-previous-gc-cycles-when-re.patch b/queue-6.1/net-bridge-mcast-wait-for-previous-gc-cycles-when-re.patch new file mode 100644 index 00000000000..00c1224d37f --- /dev/null +++ b/queue-6.1/net-bridge-mcast-wait-for-previous-gc-cycles-when-re.patch @@ -0,0 +1,82 @@ +From 8accf48b5703b68a631538577532fd024384452c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Aug 2024 11:07:30 +0300 +Subject: net: bridge: mcast: wait for previous gc cycles when removing port + +From: Nikolay Aleksandrov + +[ Upstream commit 92c4ee25208d0f35dafc3213cdf355fbe449e078 ] + +syzbot hit a use-after-free[1] which is caused because the bridge doesn't +make sure that all previous garbage has been collected when removing a +port. What happens is: + CPU 1 CPU 2 + start gc cycle remove port + acquire gc lock first + wait for lock + call br_multicasg_gc() directly + acquire lock now but free port + the port can be freed + while grp timers still + running + +Make sure all previous gc cycles have finished by using flush_work before +freeing the port. + +[1] + BUG: KASAN: slab-use-after-free in br_multicast_port_group_expired+0x4c0/0x550 net/bridge/br_multicast.c:861 + Read of size 8 at addr ffff888071d6d000 by task syz.5.1232/9699 + + CPU: 1 PID: 9699 Comm: syz.5.1232 Not tainted 6.10.0-rc5-syzkaller-00021-g24ca36a562d6 #0 + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/07/2024 + Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:114 + print_address_description mm/kasan/report.c:377 [inline] + print_report+0xc3/0x620 mm/kasan/report.c:488 + kasan_report+0xd9/0x110 mm/kasan/report.c:601 + br_multicast_port_group_expired+0x4c0/0x550 net/bridge/br_multicast.c:861 + call_timer_fn+0x1a3/0x610 kernel/time/timer.c:1792 + expire_timers kernel/time/timer.c:1843 [inline] + __run_timers+0x74b/0xaf0 kernel/time/timer.c:2417 + __run_timer_base kernel/time/timer.c:2428 [inline] + __run_timer_base kernel/time/timer.c:2421 [inline] + run_timer_base+0x111/0x190 kernel/time/timer.c:2437 + +Reported-by: syzbot+263426984509be19c9a0@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=263426984509be19c9a0 +Fixes: e12cec65b554 ("net: bridge: mcast: destroy all entries via gc") +Signed-off-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20240802080730.3206303-1-razor@blackwall.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/bridge/br_multicast.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 9765f9f9bf7ff..3cd2b648408d6 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1890,16 +1890,14 @@ void br_multicast_del_port(struct net_bridge_port *port) + { + struct net_bridge *br = port->br; + struct net_bridge_port_group *pg; +- HLIST_HEAD(deleted_head); + struct hlist_node *n; + + /* Take care of the remaining groups, only perm ones should be left */ + spin_lock_bh(&br->multicast_lock); + hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) + br_multicast_find_del_pg(br, pg); +- hlist_move_list(&br->mcast_gc_list, &deleted_head); + spin_unlock_bh(&br->multicast_lock); +- br_multicast_gc(&deleted_head); ++ flush_work(&br->mcast_gc_work); + br_multicast_port_ctx_deinit(&port->multicast_ctx); + free_percpu(port->mcast_stats); + } +-- +2.43.0 + diff --git a/queue-6.1/net-dsa-bcm_sf2-fix-a-possible-memory-leak-in-bcm_sf.patch b/queue-6.1/net-dsa-bcm_sf2-fix-a-possible-memory-leak-in-bcm_sf.patch new file mode 100644 index 00000000000..ff10ce9df38 --- /dev/null +++ b/queue-6.1/net-dsa-bcm_sf2-fix-a-possible-memory-leak-in-bcm_sf.patch @@ -0,0 +1,50 @@ +From e41ed6112f4031c2b0447ab755a998ad6883871c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Aug 2024 10:13:27 +0900 +Subject: net: dsa: bcm_sf2: Fix a possible memory leak in + bcm_sf2_mdio_register() + +From: Joe Hattori + +[ Upstream commit e3862093ee93fcfbdadcb7957f5f8974fffa806a ] + +bcm_sf2_mdio_register() calls of_phy_find_device() and then +phy_device_remove() in a loop to remove existing PHY devices. +of_phy_find_device() eventually calls bus_find_device(), which calls +get_device() on the returned struct device * to increment the refcount. +The current implementation does not decrement the refcount, which causes +memory leak. + +This commit adds the missing phy_device_free() call to decrement the +refcount via put_device() to balance the refcount. + +Fixes: 771089c2a485 ("net: dsa: bcm_sf2: Ensure that MDIO diversion is used") +Signed-off-by: Joe Hattori +Tested-by: Florian Fainelli +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20240806011327.3817861-1-joe@pf.is.s.u-tokyo.ac.jp +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/bcm_sf2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index cd1f240c90f39..257df16768750 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -678,8 +678,10 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) + of_remove_property(child, prop); + + phydev = of_phy_find_device(child); +- if (phydev) ++ if (phydev) { + phy_device_remove(phydev); ++ phy_device_free(phydev); ++ } + } + + err = mdiobus_register(priv->slave_mii_bus); +-- +2.43.0 + diff --git a/queue-6.1/net-fec-stop-pps-on-driver-remove.patch b/queue-6.1/net-fec-stop-pps-on-driver-remove.patch new file mode 100644 index 00000000000..a21e2bd8eea --- /dev/null +++ b/queue-6.1/net-fec-stop-pps-on-driver-remove.patch @@ -0,0 +1,46 @@ +From 2efb29652c9c77b09b22bbbd2c79243b1624061f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Aug 2024 10:09:56 +0200 +Subject: net: fec: Stop PPS on driver remove +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Csókás, Bence + +[ Upstream commit 8fee6d5ad5fa18c270eedb2a2cdf58dbadefb94b ] + +PPS was not stopped in `fec_ptp_stop()`, called when +the adapter was removed. Consequentially, you couldn't +safely reload the driver with the PPS signal on. + +Fixes: 32cba57ba74b ("net: fec: introduce fec_ptp_stop and use in probe fail path") +Reviewed-by: Fabio Estevam +Link: https://lore.kernel.org/netdev/CAOMZO5BzcZR8PwKKwBssQq_wAGzVgf1ffwe_nhpQJjviTdxy-w@mail.gmail.com/T/#m01dcb810bfc451a492140f6797ca77443d0cb79f +Signed-off-by: Csókás, Bence +Reviewed-by: Andrew Lunn +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20240807080956.2556602-1-csokas.bence@prolan.hu +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/fec_ptp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c +index e0393dc159fc7..37d83ff5b30be 100644 +--- a/drivers/net/ethernet/freescale/fec_ptp.c ++++ b/drivers/net/ethernet/freescale/fec_ptp.c +@@ -635,6 +635,9 @@ void fec_ptp_stop(struct platform_device *pdev) + struct net_device *ndev = platform_get_drvdata(pdev); + struct fec_enet_private *fep = netdev_priv(ndev); + ++ if (fep->pps_enable) ++ fec_ptp_enable_pps(fep, 0); ++ + cancel_delayed_work_sync(&fep->time_keep); + if (fep->ptp_clock) + ptp_clock_unregister(fep->ptp_clock); +-- +2.43.0 + diff --git a/queue-6.1/net-linkwatch-use-system_unbound_wq.patch b/queue-6.1/net-linkwatch-use-system_unbound_wq.patch new file mode 100644 index 00000000000..afb9354f3cd --- /dev/null +++ b/queue-6.1/net-linkwatch-use-system_unbound_wq.patch @@ -0,0 +1,52 @@ +From 2135bdd28f0b54736201866a02461b868d951f29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 08:58:21 +0000 +Subject: net: linkwatch: use system_unbound_wq + +From: Eric Dumazet + +[ Upstream commit 3e7917c0cdad835a5121520fc5686d954b7a61ab ] + +linkwatch_event() grabs possibly very contended RTNL mutex. + +system_wq is not suitable for such work. + +Inspired by many noisy syzbot reports. + +3 locks held by kworker/0:7/5266: + #0: ffff888015480948 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work kernel/workqueue.c:3206 [inline] + #0: ffff888015480948 ((wq_completion)events){+.+.}-{0:0}, at: process_scheduled_works+0x90a/0x1830 kernel/workqueue.c:3312 + #1: ffffc90003f6fd00 ((linkwatch_work).work){+.+.}-{0:0}, at: process_one_work kernel/workqueue.c:3207 [inline] + , at: process_scheduled_works+0x945/0x1830 kernel/workqueue.c:3312 + #2: ffffffff8fa6f208 (rtnl_mutex){+.+.}-{3:3}, at: linkwatch_event+0xe/0x60 net/core/link_watch.c:276 + +Reported-by: syzbot +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20240805085821.1616528-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/link_watch.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/core/link_watch.c b/net/core/link_watch.c +index 13513efcfbfe8..cdabced98b116 100644 +--- a/net/core/link_watch.c ++++ b/net/core/link_watch.c +@@ -139,9 +139,9 @@ static void linkwatch_schedule_work(int urgent) + * override the existing timer. + */ + if (test_bit(LW_URGENT, &linkwatch_flags)) +- mod_delayed_work(system_wq, &linkwatch_work, 0); ++ mod_delayed_work(system_unbound_wq, &linkwatch_work, 0); + else +- schedule_delayed_work(&linkwatch_work, delay); ++ queue_delayed_work(system_unbound_wq, &linkwatch_work, delay); + } + + +-- +2.43.0 + diff --git a/queue-6.1/net-mlx5e-shampo-fix-invalid-wq-linked-list-unlink.patch b/queue-6.1/net-mlx5e-shampo-fix-invalid-wq-linked-list-unlink.patch new file mode 100644 index 00000000000..39db2cdaa00 --- /dev/null +++ b/queue-6.1/net-mlx5e-shampo-fix-invalid-wq-linked-list-unlink.patch @@ -0,0 +1,44 @@ +From 38cf8a27b66a97ea2ed80bac67d32d1c3b78e83f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 00:22:08 +0300 +Subject: net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink + +From: Dragos Tatulea + +[ Upstream commit fba8334721e266f92079632598e46e5f89082f30 ] + +When all the strides in a WQE have been consumed, the WQE is unlinked +from the WQ linked list (mlx5_wq_ll_pop()). For SHAMPO, it is possible +to receive CQEs with 0 consumed strides for the same WQE even after the +WQE is fully consumed and unlinked. This triggers an additional unlink +for the same wqe which corrupts the linked list. + +Fix this scenario by accepting 0 sized consumed strides without +unlinking the WQE again. + +Signed-off-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Link: https://lore.kernel.org/r/20240603212219.1037656-4-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 56d1bd22c7c66..97d1cfec4ec03 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -2146,6 +2146,9 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq + if (likely(wi->consumed_strides < rq->mpwqe.num_strides)) + return; + ++ if (unlikely(!cstrides)) ++ return; ++ + wq = &rq->mpwqe.wq; + wqe = mlx5_wq_ll_get_wqe(wq, wqe_id); + mlx5e_free_rx_mpwqe(rq, wi, true); +-- +2.43.0 + diff --git a/queue-6.1/net-usb-qmi_wwan-fix-memory-leak-for-not-ip-packets.patch b/queue-6.1/net-usb-qmi_wwan-fix-memory-leak-for-not-ip-packets.patch new file mode 100644 index 00000000000..dd819f4f33e --- /dev/null +++ b/queue-6.1/net-usb-qmi_wwan-fix-memory-leak-for-not-ip-packets.patch @@ -0,0 +1,38 @@ +From f82c5e8ca522ad33ef96bd15f15c25c77e62b74e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Aug 2024 15:55:12 +0200 +Subject: net: usb: qmi_wwan: fix memory leak for not ip packets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Daniele Palmas + +[ Upstream commit 7ab107544b777c3bd7feb9fe447367d8edd5b202 ] + +Free the unused skb when not ip packets arrive. + +Fixes: c6adf77953bc ("net: usb: qmi_wwan: add qmap mux protocol support") +Signed-off-by: Daniele Palmas +Acked-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 46e0e1f1c20e0..ee0ea3d0f50ee 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -200,6 +200,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + break; + default: + /* not ip - do not know what to do */ ++ kfree_skb(skbn); + goto skip; + } + +-- +2.43.0 + diff --git a/queue-6.1/pci-add-edimax-vendor-id-to-pci_ids.h.patch b/queue-6.1/pci-add-edimax-vendor-id-to-pci_ids.h.patch new file mode 100644 index 00000000000..2580dfb1af1 --- /dev/null +++ b/queue-6.1/pci-add-edimax-vendor-id-to-pci_ids.h.patch @@ -0,0 +1,38 @@ +From f07f94afbcfa46cec79965c4e60918cf9b1fa5a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Jun 2024 08:55:01 +0900 +Subject: PCI: Add Edimax Vendor ID to pci_ids.h + +From: FUJITA Tomonori + +[ Upstream commit eee5528890d54b22b46f833002355a5ee94c3bb4 ] + +Add the Edimax Vendor ID (0x1432) for an ethernet driver for Tehuti +Networks TN40xx chips. This ID can be used for Realtek 8180 and Ralink +rt28xx wireless drivers. + +Signed-off-by: FUJITA Tomonori +Acked-by: Bjorn Helgaas +Link: https://patch.msgid.link/20240623235507.108147-2-fujita.tomonori@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/pci_ids.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h +index 2c1371320c295..f680897794fa2 100644 +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -2109,6 +2109,8 @@ + + #define PCI_VENDOR_ID_CHELSIO 0x1425 + ++#define PCI_VENDOR_ID_EDIMAX 0x1432 ++ + #define PCI_VENDOR_ID_ADLINK 0x144a + + #define PCI_VENDOR_ID_SAMSUNG 0x144d +-- +2.43.0 + diff --git a/queue-6.1/platform-x86-intel-ifs-gen2-scan-test-support.patch b/queue-6.1/platform-x86-intel-ifs-gen2-scan-test-support.patch new file mode 100644 index 00000000000..77053171474 --- /dev/null +++ b/queue-6.1/platform-x86-intel-ifs-gen2-scan-test-support.patch @@ -0,0 +1,192 @@ +From 443532e2029005d0e56bc935bf38b68042f774b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 12:51:32 -0700 +Subject: platform/x86/intel/ifs: Gen2 Scan test support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jithu Joseph + +[ Upstream commit 72b96ee29ed6f7670bbb180ba694816e33d361d1 ] + +Width of chunk related bitfields is ACTIVATE_SCAN and SCAN_STATUS MSRs +are different in newer IFS generation compared to gen0. + +Make changes to scan test flow such that MSRs are populated +appropriately based on the generation supported by hardware. + +Account for the 8/16 bit MSR bitfield width differences between gen0 and +newer generations for the scan test trace event too. + +Signed-off-by: Jithu Joseph +Reviewed-by: Tony Luck +Reviewed-by: Ilpo Järvinen +Tested-by: Pengfei Xu +Link: https://lore.kernel.org/r/20231005195137.3117166-5-jithu.joseph@intel.com +Signed-off-by: Ilpo Järvinen +Stable-dep-of: 3114f77e9453 ("platform/x86/intel/ifs: Initialize union ifs_status to zero") +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/ifs/ifs.h | 28 ++++++++++++++++++----- + drivers/platform/x86/intel/ifs/runtest.c | 29 ++++++++++++++++++------ + include/trace/events/intel_ifs.h | 16 ++++++------- + 3 files changed, 52 insertions(+), 21 deletions(-) + +diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h +index 73c8e91cf144d..1902a1722df1e 100644 +--- a/drivers/platform/x86/intel/ifs/ifs.h ++++ b/drivers/platform/x86/intel/ifs/ifs.h +@@ -157,9 +157,17 @@ union ifs_chunks_auth_status { + union ifs_scan { + u64 data; + struct { +- u32 start :8; +- u32 stop :8; +- u32 rsvd :16; ++ union { ++ struct { ++ u8 start; ++ u8 stop; ++ u16 rsvd; ++ } gen0; ++ struct { ++ u16 start; ++ u16 stop; ++ } gen2; ++ }; + u32 delay :31; + u32 sigmce :1; + }; +@@ -169,9 +177,17 @@ union ifs_scan { + union ifs_status { + u64 data; + struct { +- u32 chunk_num :8; +- u32 chunk_stop_index :8; +- u32 rsvd1 :16; ++ union { ++ struct { ++ u8 chunk_num; ++ u8 chunk_stop_index; ++ u16 rsvd1; ++ } gen0; ++ struct { ++ u16 chunk_num; ++ u16 chunk_stop_index; ++ } gen2; ++ }; + u32 error_code :8; + u32 rsvd2 :22; + u32 control_error :1; +diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c +index b2ca2bb4501f6..d6bc2f0b61a34 100644 +--- a/drivers/platform/x86/intel/ifs/runtest.c ++++ b/drivers/platform/x86/intel/ifs/runtest.c +@@ -169,21 +169,31 @@ static void ifs_test_core(int cpu, struct device *dev) + union ifs_status status; + unsigned long timeout; + struct ifs_data *ifsd; ++ int to_start, to_stop; ++ int status_chunk; + u64 msrvals[2]; + int retries; + + ifsd = ifs_get_data(dev); + +- activate.rsvd = 0; ++ activate.gen0.rsvd = 0; + activate.delay = IFS_THREAD_WAIT; + activate.sigmce = 0; +- activate.start = 0; +- activate.stop = ifsd->valid_chunks - 1; ++ to_start = 0; ++ to_stop = ifsd->valid_chunks - 1; ++ ++ if (ifsd->generation) { ++ activate.gen2.start = to_start; ++ activate.gen2.stop = to_stop; ++ } else { ++ activate.gen0.start = to_start; ++ activate.gen0.stop = to_stop; ++ } + + timeout = jiffies + HZ / 2; + retries = MAX_IFS_RETRIES; + +- while (activate.start <= activate.stop) { ++ while (to_start <= to_stop) { + if (time_after(jiffies, timeout)) { + status.error_code = IFS_SW_TIMEOUT; + break; +@@ -194,13 +204,14 @@ static void ifs_test_core(int cpu, struct device *dev) + + status.data = msrvals[1]; + +- trace_ifs_status(cpu, activate, status); ++ trace_ifs_status(cpu, to_start, to_stop, status.data); + + /* Some cases can be retried, give up for others */ + if (!can_restart(status)) + break; + +- if (status.chunk_num == activate.start) { ++ status_chunk = ifsd->generation ? status.gen2.chunk_num : status.gen0.chunk_num; ++ if (status_chunk == to_start) { + /* Check for forward progress */ + if (--retries == 0) { + if (status.error_code == IFS_NO_ERROR) +@@ -209,7 +220,11 @@ static void ifs_test_core(int cpu, struct device *dev) + } + } else { + retries = MAX_IFS_RETRIES; +- activate.start = status.chunk_num; ++ if (ifsd->generation) ++ activate.gen2.start = status_chunk; ++ else ++ activate.gen0.start = status_chunk; ++ to_start = status_chunk; + } + } + +diff --git a/include/trace/events/intel_ifs.h b/include/trace/events/intel_ifs.h +index d7353024016cc..af0af3f1d9b7c 100644 +--- a/include/trace/events/intel_ifs.h ++++ b/include/trace/events/intel_ifs.h +@@ -10,25 +10,25 @@ + + TRACE_EVENT(ifs_status, + +- TP_PROTO(int cpu, union ifs_scan activate, union ifs_status status), ++ TP_PROTO(int cpu, int start, int stop, u64 status), + +- TP_ARGS(cpu, activate, status), ++ TP_ARGS(cpu, start, stop, status), + + TP_STRUCT__entry( + __field( u64, status ) + __field( int, cpu ) +- __field( u8, start ) +- __field( u8, stop ) ++ __field( u16, start ) ++ __field( u16, stop ) + ), + + TP_fast_assign( + __entry->cpu = cpu; +- __entry->start = activate.start; +- __entry->stop = activate.stop; +- __entry->status = status.data; ++ __entry->start = start; ++ __entry->stop = stop; ++ __entry->status = status; + ), + +- TP_printk("cpu: %d, start: %.2x, stop: %.2x, status: %llx", ++ TP_printk("cpu: %d, start: %.4x, stop: %.4x, status: %.16llx", + __entry->cpu, + __entry->start, + __entry->stop, +-- +2.43.0 + diff --git a/queue-6.1/platform-x86-intel-ifs-initialize-union-ifs_status-t.patch b/queue-6.1/platform-x86-intel-ifs-initialize-union-ifs_status-t.patch new file mode 100644 index 00000000000..eec247e5ab4 --- /dev/null +++ b/queue-6.1/platform-x86-intel-ifs-initialize-union-ifs_status-t.patch @@ -0,0 +1,47 @@ +From b04403980745cbc17e8fddaf9bb6de8de8b84ac9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jul 2024 15:59:30 +0000 +Subject: platform/x86/intel/ifs: Initialize union ifs_status to zero +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kuppuswamy Sathyanarayanan + +[ Upstream commit 3114f77e9453daa292ec0906f313a715c69b5943 ] + +If the IFS scan test exits prematurely due to a timeout before +completing a single run, the union ifs_status remains uninitialized, +leading to incorrect test status reporting. To prevent this, always +initialize the union ifs_status to zero. + +Fixes: 2b40e654b73a ("platform/x86/intel/ifs: Add scan test support") +Suggested-by: Ilpo Järvinen +Reviewed-by: Jithu Joseph +Reviewed-by: Ashok Raj +Signed-off-by: Kuppuswamy Sathyanarayanan +Link: https://lore.kernel.org/r/20240730155930.1754744-1-sathyanarayanan.kuppuswamy@linux.intel.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel/ifs/runtest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c +index d6bc2f0b61a34..aeb6a3b7a8fd9 100644 +--- a/drivers/platform/x86/intel/ifs/runtest.c ++++ b/drivers/platform/x86/intel/ifs/runtest.c +@@ -165,8 +165,8 @@ static int doscan(void *data) + */ + static void ifs_test_core(int cpu, struct device *dev) + { ++ union ifs_status status = {}; + union ifs_scan activate; +- union ifs_status status; + unsigned long timeout; + struct ifs_data *ifsd; + int to_start, to_stop; +-- +2.43.0 + diff --git a/queue-6.1/r8169-remove-detection-of-chip-version-11-early-rtl8.patch b/queue-6.1/r8169-remove-detection-of-chip-version-11-early-rtl8.patch new file mode 100644 index 00000000000..240fd22e9da --- /dev/null +++ b/queue-6.1/r8169-remove-detection-of-chip-version-11-early-rtl8.patch @@ -0,0 +1,41 @@ +From d52061b428850a08eabadb07139011dad47f63f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 May 2024 21:20:16 +0200 +Subject: r8169: remove detection of chip version 11 (early RTL8168b) + +From: Heiner Kallweit + +[ Upstream commit 982300c115d229565d7af8e8b38aa1ee7bb1f5bd ] + +This early RTL8168b version was the first PCIe chip version, and it's +quite quirky. Last sign of life is from more than 15 yrs ago. +Let's remove detection of this chip version, we'll see whether anybody +complains. If not, support for this chip version can be removed a few +kernel versions later. + +Signed-off-by: Heiner Kallweit +Link: https://lore.kernel.org/r/875cdcf4-843c-420a-ad5d-417447b68572@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/r8169_main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index b187371fa2f0a..2e9de2ca45abe 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -2119,7 +2119,9 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) + + /* 8168B family. */ + { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 }, +- { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, ++ /* This one is very old and rare, let's see if anybody complains. ++ * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, ++ */ + + /* 8101 family. */ + { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 }, +-- +2.43.0 + diff --git a/queue-6.1/rcu-fix-rcu_barrier-vs-post-cpuhp_teardown_cpu-invoc.patch b/queue-6.1/rcu-fix-rcu_barrier-vs-post-cpuhp_teardown_cpu-invoc.patch new file mode 100644 index 00000000000..ba34c076bf9 --- /dev/null +++ b/queue-6.1/rcu-fix-rcu_barrier-vs-post-cpuhp_teardown_cpu-invoc.patch @@ -0,0 +1,120 @@ +From fadaffe6f78415b7ed03e4b808748379d531150e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 May 2024 16:05:24 +0200 +Subject: rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation + +From: Frederic Weisbecker + +[ Upstream commit 55d4669ef1b76823083caecfab12a8bd2ccdcf64 ] + +When rcu_barrier() calls rcu_rdp_cpu_online() and observes a CPU off +rnp->qsmaskinitnext, it means that all accesses from the offline CPU +preceding the CPUHP_TEARDOWN_CPU are visible to RCU barrier, including +callbacks expiration and counter updates. + +However interrupts can still fire after stop_machine() re-enables +interrupts and before rcutree_report_cpu_dead(). The related accesses +happening between CPUHP_TEARDOWN_CPU and rnp->qsmaskinitnext clearing +are _NOT_ guaranteed to be seen by rcu_barrier() without proper +ordering, especially when callbacks are invoked there to the end, making +rcutree_migrate_callback() bypass barrier_lock. + +The following theoretical race example can make rcu_barrier() hang: + +CPU 0 CPU 1 +----- ----- +//cpu_down() +smpboot_park_threads() +//ksoftirqd is parked now + +rcu_sched_clock_irq() + invoke_rcu_core() +do_softirq() + rcu_core() + rcu_do_batch() + // callback storm + // rcu_do_batch() returns + // before completing all + // of them + // do_softirq also returns early because of + // timeout. It defers to ksoftirqd but + // it's parked + +stop_machine() + take_cpu_down() + rcu_barrier() + spin_lock(barrier_lock) + // observes rcu_segcblist_n_cbs(&rdp->cblist) != 0 + +do_softirq() + rcu_core() + rcu_do_batch() + //completes all pending callbacks + //smp_mb() implied _after_ callback number dec + + +rcutree_report_cpu_dead() + rnp->qsmaskinitnext &= ~rdp->grpmask; + +rcutree_migrate_callback() + // no callback, early return without locking + // barrier_lock + //observes !rcu_rdp_cpu_online(rdp) + rcu_barrier_entrain() + rcu_segcblist_entrain() + // Observe rcu_segcblist_n_cbs(rsclp) == 0 + // because no barrier between reading + // rnp->qsmaskinitnext and rsclp->len + rcu_segcblist_add_len() + smp_mb__before_atomic() + // will now observe the 0 count and empty + // list, but too late, we enqueue regardless + WRITE_ONCE(rsclp->len, rsclp->len + v); + // ignored barrier callback + // rcu barrier stall... + +This could be solved with a read memory barrier, enforcing the message +passing between rnp->qsmaskinitnext and rsclp->len, matching the full +memory barrier after rsclp->len addition in rcu_segcblist_add_len() +performed at the end of rcu_do_batch(). + +However the rcu_barrier() is complicated enough and probably doesn't +need too many more subtleties. CPU down is a slowpath and the +barrier_lock seldom contended. Solve the issue with unconditionally +locking the barrier_lock on rcutree_migrate_callbacks(). This makes sure +that either rcu_barrier() sees the empty queue or its entrained +callback will be migrated. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Paul E. McKenney +Signed-off-by: Sasha Levin +--- + kernel/rcu/tree.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index 61f9503a5fe9c..cd6144cea5a1a 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -4391,11 +4391,15 @@ void rcutree_migrate_callbacks(int cpu) + struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu); + bool needwake; + +- if (rcu_rdp_is_offloaded(rdp) || +- rcu_segcblist_empty(&rdp->cblist)) +- return; /* No callbacks to migrate. */ ++ if (rcu_rdp_is_offloaded(rdp)) ++ return; + + raw_spin_lock_irqsave(&rcu_state.barrier_lock, flags); ++ if (rcu_segcblist_empty(&rdp->cblist)) { ++ raw_spin_unlock_irqrestore(&rcu_state.barrier_lock, flags); ++ return; /* No callbacks to migrate. */ ++ } ++ + WARN_ON_ONCE(rcu_rdp_cpu_online(rdp)); + rcu_barrier_entrain(rdp); + my_rdp = this_cpu_ptr(&rcu_data); +-- +2.43.0 + diff --git a/queue-6.1/rcutorture-fix-rcu_torture_fwd_cb_cr-data-race.patch b/queue-6.1/rcutorture-fix-rcu_torture_fwd_cb_cr-data-race.patch new file mode 100644 index 00000000000..70e97b01d04 --- /dev/null +++ b/queue-6.1/rcutorture-fix-rcu_torture_fwd_cb_cr-data-race.patch @@ -0,0 +1,50 @@ +From 743e036131ed229cf6711a72dcc49e14512e726b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Apr 2024 12:02:11 -0700 +Subject: rcutorture: Fix rcu_torture_fwd_cb_cr() data race + +From: Paul E. McKenney + +[ Upstream commit 6040072f4774a575fa67b912efe7722874be337b ] + +On powerpc systems, spinlock acquisition does not order prior stores +against later loads. This means that this statement: + + rfcp->rfc_next = NULL; + +Can be reordered to follow this statement: + + WRITE_ONCE(*rfcpp, rfcp); + +Which is then a data race with rcu_torture_fwd_prog_cr(), specifically, +this statement: + + rfcpn = READ_ONCE(rfcp->rfc_next) + +KCSAN located this data race, which represents a real failure on powerpc. + +Signed-off-by: Paul E. McKenney +Acked-by: Marco Elver +Cc: Andrey Konovalov +Cc: +Signed-off-by: Sasha Levin +--- + kernel/rcu/rcutorture.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c +index 8c45df910763a..c14517912cfaa 100644 +--- a/kernel/rcu/rcutorture.c ++++ b/kernel/rcu/rcutorture.c +@@ -2547,7 +2547,7 @@ static void rcu_torture_fwd_cb_cr(struct rcu_head *rhp) + spin_lock_irqsave(&rfp->rcu_fwd_lock, flags); + rfcpp = rfp->rcu_fwd_cb_tail; + rfp->rcu_fwd_cb_tail = &rfcp->rfc_next; +- WRITE_ONCE(*rfcpp, rfcp); ++ smp_store_release(rfcpp, rfcp); + WRITE_ONCE(rfp->n_launders_cb, rfp->n_launders_cb + 1); + i = ((jiffies - rfp->rcu_fwd_startat) / (HZ / FWD_CBS_HIST_DIV)); + if (i >= ARRAY_SIZE(rfp->n_launders_hist)) +-- +2.43.0 + diff --git a/queue-6.1/s390-sclp-prevent-release-of-buffer-in-i-o.patch b/queue-6.1/s390-sclp-prevent-release-of-buffer-in-i-o.patch new file mode 100644 index 00000000000..f5fa98afd92 --- /dev/null +++ b/queue-6.1/s390-sclp-prevent-release-of-buffer-in-i-o.patch @@ -0,0 +1,52 @@ +From 8a6b5e40990321c111a9e9cf9f01273ba3213627 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jun 2024 14:20:27 +0200 +Subject: s390/sclp: Prevent release of buffer in I/O + +From: Peter Oberparleiter + +[ Upstream commit bf365071ea92b9579d5a272679b74052a5643e35 ] + +When a task waiting for completion of a Store Data operation is +interrupted, an attempt is made to halt this operation. If this attempt +fails due to a hardware or firmware problem, there is a chance that the +SCLP facility might store data into buffers referenced by the original +operation at a later time. + +Handle this situation by not releasing the referenced data buffers if +the halt attempt fails. For current use cases, this might result in a +leak of few pages of memory in case of a rare hardware/firmware +malfunction. + +Reviewed-by: Heiko Carstens +Signed-off-by: Peter Oberparleiter +Signed-off-by: Alexander Gordeev +Signed-off-by: Sasha Levin +--- + drivers/s390/char/sclp_sd.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/s390/char/sclp_sd.c b/drivers/s390/char/sclp_sd.c +index f9e164be7568f..944e75beb160c 100644 +--- a/drivers/s390/char/sclp_sd.c ++++ b/drivers/s390/char/sclp_sd.c +@@ -320,8 +320,14 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di) + &esize); + if (rc) { + /* Cancel running request if interrupted */ +- if (rc == -ERESTARTSYS) +- sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL); ++ if (rc == -ERESTARTSYS) { ++ if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) { ++ pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n", ++ (size_t)dsize * PAGE_SIZE); ++ data = NULL; ++ asce = 0; ++ } ++ } + vfree(data); + goto out; + } +-- +2.43.0 + diff --git a/queue-6.1/sctp-fix-null-ptr-deref-in-reuseport_add_sock.patch b/queue-6.1/sctp-fix-null-ptr-deref-in-reuseport_add_sock.patch new file mode 100644 index 00000000000..901338f14d0 --- /dev/null +++ b/queue-6.1/sctp-fix-null-ptr-deref-in-reuseport_add_sock.patch @@ -0,0 +1,169 @@ +From 2c7c24dc05872b325466f25829f041cca31bbf27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 16:46:24 -0700 +Subject: sctp: Fix null-ptr-deref in reuseport_add_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 9ab0faa7f9ffe31296dbb9bbe6f76c72c14eea18 ] + +syzbot reported a null-ptr-deref while accessing sk2->sk_reuseport_cb in +reuseport_add_sock(). [0] + +The repro first creates a listener with SO_REUSEPORT. Then, it creates +another listener on the same port and concurrently closes the first +listener. + +The second listen() calls reuseport_add_sock() with the first listener as +sk2, where sk2->sk_reuseport_cb is not expected to be cleared concurrently, +but the close() does clear it by reuseport_detach_sock(). + +The problem is SCTP does not properly synchronise reuseport_alloc(), +reuseport_add_sock(), and reuseport_detach_sock(). + +The caller of reuseport_alloc() and reuseport_{add,detach}_sock() must +provide synchronisation for sockets that are classified into the same +reuseport group. + +Otherwise, such sockets form multiple identical reuseport groups, and +all groups except one would be silently dead. + + 1. Two sockets call listen() concurrently + 2. No socket in the same group found in sctp_ep_hashtable[] + 3. Two sockets call reuseport_alloc() and form two reuseport groups + 4. Only one group hit first in __sctp_rcv_lookup_endpoint() receives + incoming packets + +Also, the reported null-ptr-deref could occur. + +TCP/UDP guarantees that would not happen by holding the hash bucket lock. + +Let's apply the locking strategy to __sctp_hash_endpoint() and +__sctp_unhash_endpoint(). + +[0]: +Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] PREEMPT SMP KASAN PTI +KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] +CPU: 1 UID: 0 PID: 10230 Comm: syz-executor119 Not tainted 6.10.0-syzkaller-12585-g301927d2d2eb #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/27/2024 +RIP: 0010:reuseport_add_sock+0x27e/0x5e0 net/core/sock_reuseport.c:350 +Code: 00 0f b7 5d 00 bf 01 00 00 00 89 de e8 1b a4 ff f7 83 fb 01 0f 85 a3 01 00 00 e8 6d a0 ff f7 49 8d 7e 12 48 89 f8 48 c1 e8 03 <42> 0f b6 04 28 84 c0 0f 85 4b 02 00 00 41 0f b7 5e 12 49 8d 7e 14 +RSP: 0018:ffffc9000b947c98 EFLAGS: 00010202 +RAX: 0000000000000002 RBX: ffff8880252ddf98 RCX: ffff888079478000 +RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000012 +RBP: 0000000000000001 R08: ffffffff8993e18d R09: 1ffffffff1fef385 +R10: dffffc0000000000 R11: fffffbfff1fef386 R12: ffff8880252ddac0 +R13: dffffc0000000000 R14: 0000000000000000 R15: 0000000000000000 +FS: 00007f24e45b96c0(0000) GS:ffff8880b9300000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007ffcced5f7b8 CR3: 00000000241be000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + __sctp_hash_endpoint net/sctp/input.c:762 [inline] + sctp_hash_endpoint+0x52a/0x600 net/sctp/input.c:790 + sctp_listen_start net/sctp/socket.c:8570 [inline] + sctp_inet_listen+0x767/0xa20 net/sctp/socket.c:8625 + __sys_listen_socket net/socket.c:1883 [inline] + __sys_listen+0x1b7/0x230 net/socket.c:1894 + __do_sys_listen net/socket.c:1902 [inline] + __se_sys_listen net/socket.c:1900 [inline] + __x64_sys_listen+0x5a/0x70 net/socket.c:1900 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f24e46039b9 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 91 1a 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 b0 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007f24e45b9228 EFLAGS: 00000246 ORIG_RAX: 0000000000000032 +RAX: ffffffffffffffda RBX: 00007f24e468e428 RCX: 00007f24e46039b9 +RDX: 00007f24e46039b9 RSI: 0000000000000003 RDI: 0000000000000004 +RBP: 00007f24e468e420 R08: 00007f24e45b96c0 R09: 00007f24e45b96c0 +R10: 00007f24e45b96c0 R11: 0000000000000246 R12: 00007f24e468e42c +R13: 00007f24e465a5dc R14: 0020000000000001 R15: 00007ffcced5f7d8 + +Modules linked in: + +Fixes: 6ba845740267 ("sctp: process sk_reuseport in sctp_get_port_local") +Reported-by: syzbot+e6979a5d2f10ecb700e4@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=e6979a5d2f10ecb700e4 +Tested-by: syzbot+e6979a5d2f10ecb700e4@syzkaller.appspotmail.com +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20240731234624.94055-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/input.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/net/sctp/input.c b/net/sctp/input.c +index 4f43afa8678f9..4ee9374dcfb92 100644 +--- a/net/sctp/input.c ++++ b/net/sctp/input.c +@@ -748,15 +748,19 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) + struct sock *sk = ep->base.sk; + struct net *net = sock_net(sk); + struct sctp_hashbucket *head; ++ int err = 0; + + ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port); + head = &sctp_ep_hashtable[ep->hashent]; + ++ write_lock(&head->lock); + if (sk->sk_reuseport) { + bool any = sctp_is_ep_boundall(sk); + struct sctp_endpoint *ep2; + struct list_head *list; +- int cnt = 0, err = 1; ++ int cnt = 0; ++ ++ err = 1; + + list_for_each(list, &ep->base.bind_addr.address_list) + cnt++; +@@ -774,24 +778,24 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) + if (!err) { + err = reuseport_add_sock(sk, sk2, any); + if (err) +- return err; ++ goto out; + break; + } else if (err < 0) { +- return err; ++ goto out; + } + } + + if (err) { + err = reuseport_alloc(sk, any); + if (err) +- return err; ++ goto out; + } + } + +- write_lock(&head->lock); + hlist_add_head(&ep->node, &head->chain); ++out: + write_unlock(&head->lock); +- return 0; ++ return err; + } + + /* Add an endpoint to the hash. Local BH-safe. */ +@@ -816,10 +820,9 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) + + head = &sctp_ep_hashtable[ep->hashent]; + ++ write_lock(&head->lock); + if (rcu_access_pointer(sk->sk_reuseport_cb)) + reuseport_detach_sock(sk); +- +- write_lock(&head->lock); + hlist_del_init(&ep->node); + write_unlock(&head->lock); + } +-- +2.43.0 + diff --git a/queue-6.1/selftests-bpf-fix-send_signal-test-with-nested-confi.patch b/queue-6.1/selftests-bpf-fix-send_signal-test-with-nested-confi.patch new file mode 100644 index 00000000000..d6176c05683 --- /dev/null +++ b/queue-6.1/selftests-bpf-fix-send_signal-test-with-nested-confi.patch @@ -0,0 +1,120 @@ +From 98e71f83c55cd250311a3d31ca39b139ca57ec34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jun 2024 13:12:03 -0700 +Subject: selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT + +From: Yonghong Song + +[ Upstream commit 7015843afcaf68c132784c89528dfddc0005e483 ] + +Alexei reported that send_signal test may fail with nested CONFIG_PARAVIRT +configs. In this particular case, the base VM is AMD with 166 cpus, and I +run selftests with regular qemu on top of that and indeed send_signal test +failed. I also tried with an Intel box with 80 cpus and there is no issue. + +The main qemu command line includes: + + -enable-kvm -smp 16 -cpu host + +The failure log looks like: + + $ ./test_progs -t send_signal + [ 48.501588] watchdog: BUG: soft lockup - CPU#9 stuck for 26s! [test_progs:2225] + [ 48.503622] Modules linked in: bpf_testmod(O) + [ 48.503622] CPU: 9 PID: 2225 Comm: test_progs Tainted: G O 6.9.0-08561-g2c1713a8f1c9-dirty #69 + [ 48.507629] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 + [ 48.511635] RIP: 0010:handle_softirqs+0x71/0x290 + [ 48.511635] Code: [...] 10 0a 00 00 00 31 c0 65 66 89 05 d5 f4 fa 7e fb bb ff ff ff ff <49> c7 c2 cb + [ 48.518527] RSP: 0018:ffffc90000310fa0 EFLAGS: 00000246 + [ 48.519579] RAX: 0000000000000000 RBX: 00000000ffffffff RCX: 00000000000006e0 + [ 48.522526] RDX: 0000000000000006 RSI: ffff88810791ae80 RDI: 0000000000000000 + [ 48.523587] RBP: ffffc90000fabc88 R08: 00000005a0af4f7f R09: 0000000000000000 + [ 48.525525] R10: 0000000561d2f29c R11: 0000000000006534 R12: 0000000000000280 + [ 48.528525] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 + [ 48.528525] FS: 00007f2f2885cd00(0000) GS:ffff888237c40000(0000) knlGS:0000000000000000 + [ 48.531600] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 48.535520] CR2: 00007f2f287059f0 CR3: 0000000106a28002 CR4: 00000000003706f0 + [ 48.537538] Call Trace: + [ 48.537538] + [ 48.537538] ? watchdog_timer_fn+0x1cd/0x250 + [ 48.539590] ? lockup_detector_update_enable+0x50/0x50 + [ 48.539590] ? __hrtimer_run_queues+0xff/0x280 + [ 48.542520] ? hrtimer_interrupt+0x103/0x230 + [ 48.544524] ? __sysvec_apic_timer_interrupt+0x4f/0x140 + [ 48.545522] ? sysvec_apic_timer_interrupt+0x3a/0x90 + [ 48.547612] ? asm_sysvec_apic_timer_interrupt+0x1a/0x20 + [ 48.547612] ? handle_softirqs+0x71/0x290 + [ 48.547612] irq_exit_rcu+0x63/0x80 + [ 48.551585] sysvec_apic_timer_interrupt+0x75/0x90 + [ 48.552521] + [ 48.553529] + [ 48.553529] asm_sysvec_apic_timer_interrupt+0x1a/0x20 + [ 48.555609] RIP: 0010:finish_task_switch.isra.0+0x90/0x260 + [ 48.556526] Code: [...] 9f 58 0a 00 00 48 85 db 0f 85 89 01 00 00 4c 89 ff e8 53 d9 bd 00 fb 66 90 <4d> 85 ed 74 + [ 48.562524] RSP: 0018:ffffc90000fabd38 EFLAGS: 00000282 + [ 48.563589] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff83385620 + [ 48.563589] RDX: ffff888237c73ae4 RSI: 0000000000000000 RDI: ffff888237c6fd00 + [ 48.568521] RBP: ffffc90000fabd68 R08: 0000000000000000 R09: 0000000000000000 + [ 48.569528] R10: 0000000000000001 R11: 0000000000000000 R12: ffff8881009d0000 + [ 48.573525] R13: ffff8881024e5400 R14: ffff88810791ae80 R15: ffff888237c6fd00 + [ 48.575614] ? finish_task_switch.isra.0+0x8d/0x260 + [ 48.576523] __schedule+0x364/0xac0 + [ 48.577535] schedule+0x2e/0x110 + [ 48.578555] pipe_read+0x301/0x400 + [ 48.579589] ? destroy_sched_domains_rcu+0x30/0x30 + [ 48.579589] vfs_read+0x2b3/0x2f0 + [ 48.579589] ksys_read+0x8b/0xc0 + [ 48.583590] do_syscall_64+0x3d/0xc0 + [ 48.583590] entry_SYSCALL_64_after_hwframe+0x4b/0x53 + [ 48.586525] RIP: 0033:0x7f2f28703fa1 + [ 48.587592] Code: [...] 00 00 00 0f 1f 44 00 00 f3 0f 1e fa 80 3d c5 23 14 00 00 74 13 31 c0 0f 05 <48> 3d 00 f0 + [ 48.593534] RSP: 002b:00007ffd90f8cf88 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 + [ 48.595589] RAX: ffffffffffffffda RBX: 00007ffd90f8d5e8 RCX: 00007f2f28703fa1 + [ 48.595589] RDX: 0000000000000001 RSI: 00007ffd90f8cfb0 RDI: 0000000000000006 + [ 48.599592] RBP: 00007ffd90f8d2f0 R08: 0000000000000064 R09: 0000000000000000 + [ 48.602527] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 + [ 48.603589] R13: 00007ffd90f8d608 R14: 00007f2f288d8000 R15: 0000000000f6bdb0 + [ 48.605527] + +In the test, two processes are communicating through pipe. Further debugging +with strace found that the above splat is triggered as read() syscall could +not receive the data even if the corresponding write() syscall in another +process successfully wrote data into the pipe. + +The failed subtest is "send_signal_perf". The corresponding perf event has +sample_period 1 and config PERF_COUNT_SW_CPU_CLOCK. sample_period 1 means every +overflow event will trigger a call to the BPF program. So I suspect this may +overwhelm the system. So I increased the sample_period to 100,000 and the test +passed. The sample_period 10,000 still has the test failed. + +In other parts of selftest, e.g., [1], sample_freq is used instead. So I +decided to use sample_freq = 1,000 since the test can pass as well. + + [1] https://lore.kernel.org/bpf/20240604070700.3032142-1-song@kernel.org/ + +Reported-by: Alexei Starovoitov +Signed-off-by: Yonghong Song +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20240605201203.2603846-1-yonghong.song@linux.dev +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index d63a20fbed339..210b806351bcf 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -152,7 +152,8 @@ static void test_send_signal_tracepoint(bool signal_thread) + static void test_send_signal_perf(bool signal_thread) + { + struct perf_event_attr attr = { +- .sample_period = 1, ++ .freq = 1, ++ .sample_freq = 1000, + .type = PERF_TYPE_SOFTWARE, + .config = PERF_COUNT_SW_CPU_CLOCK, + }; +-- +2.43.0 + diff --git a/queue-6.1/selftests-mptcp-join-test-both-signal-subflow.patch b/queue-6.1/selftests-mptcp-join-test-both-signal-subflow.patch new file mode 100644 index 00000000000..c07245ecaaa --- /dev/null +++ b/queue-6.1/selftests-mptcp-join-test-both-signal-subflow.patch @@ -0,0 +1,69 @@ +From 9980bc5799109587e228f3cc659f68d5ca1b2d5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 13:05:59 +0200 +Subject: selftests: mptcp: join: test both signal & subflow + +From: Matthieu Baerts (NGI0) + +[ Upstream commit 4d2868b5d191c74262f7407972d68d1bf3245d6a ] + +It should be quite uncommon to set both the subflow and the signal +flags: the initiator of the connection is typically the one creating new +subflows, not the other peer, then no need to announce additional local +addresses, and use it to create subflows. + +But some people might be confused about the flags, and set both "just to +be sure at least the right one is set". To verify the previous fix, and +avoid future regressions, this specific case is now validated: the +client announces a new address, and initiates a new subflow from the +same address. + +While working on this, another bug has been noticed, where the client +reset the new subflow because an ADD_ADDR echo got received as the 3rd +ACK: this new test also explicitly checks that no RST have been sent by +the client and server. + +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: 86e39e04482b ("mptcp: keep track of local endpoint still available for each msk") +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20240731-upstream-net-20240731-mptcp-endp-subflow-signal-v1-7-c8a9b036493b@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/mptcp/mptcp_join.sh | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh +index 51f68bb6bdb8a..feadee086128a 100755 +--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh ++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh +@@ -2064,6 +2064,21 @@ signal_address_tests() + chk_add_nr 1 1 + fi + ++ # uncommon: subflow and signal flags on the same endpoint ++ # or because the user wrongly picked both, but still expects the client ++ # to create additional subflows ++ if reset "subflow and signal together"; then ++ pm_nl_set_limits $ns1 0 2 ++ pm_nl_set_limits $ns2 0 2 ++ pm_nl_add_endpoint $ns2 10.0.3.2 flags signal,subflow ++ run_tests $ns1 $ns2 10.0.1.1 ++ chk_join_nr 1 1 1 ++ chk_add_nr 1 1 0 invert # only initiated by ns2 ++ chk_add_nr 0 0 0 # none initiated by ns1 ++ chk_rst_nr 0 0 invert # no RST sent by the client ++ chk_rst_nr 0 0 # no RST sent by the server ++ fi ++ + # accept and use add_addr with additional subflows + if reset "multiple subflows and signal"; then + pm_nl_set_limits $ns1 0 3 +-- +2.43.0 + diff --git a/queue-6.1/series b/queue-6.1/series new file mode 100644 index 00000000000..d6fe1fb1e26 --- /dev/null +++ b/queue-6.1/series @@ -0,0 +1,51 @@ +irqchip-mbigen-fix-mbigen-node-address-layout.patch +platform-x86-intel-ifs-gen2-scan-test-support.patch +platform-x86-intel-ifs-initialize-union-ifs_status-t.patch +jump_label-fix-the-fix-brown-paper-bags-galore.patch +x86-mm-fix-pti_clone_pgtable-alignment-assumption.patch +x86-mm-fix-pti_clone_entry_text-for-i386.patch +selftests-mptcp-join-test-both-signal-subflow.patch +sctp-fix-null-ptr-deref-in-reuseport_add_sock.patch +net-usb-qmi_wwan-fix-memory-leak-for-not-ip-packets.patch +net-bridge-mcast-wait-for-previous-gc-cycles-when-re.patch +net-linkwatch-use-system_unbound_wq.patch +bluetooth-l2cap-always-unlock-channel-in-l2cap_conle.patch +bluetooth-hci_sync-avoid-dup-filtering-when-passive-.patch +net-dsa-bcm_sf2-fix-a-possible-memory-leak-in-bcm_sf.patch +l2tp-fix-lockdep-splat.patch +net-fec-stop-pps-on-driver-remove.patch +rcutorture-fix-rcu_torture_fwd_cb_cr-data-race.patch +md-do-not-delete-safemode_timer-in-mddev_suspend.patch +md-raid5-avoid-bug_on-while-continue-reshape-after-r.patch +block-change-rq_integrity_vec-to-respect-the-iterato.patch +rcu-fix-rcu_barrier-vs-post-cpuhp_teardown_cpu-invoc.patch +clocksource-drivers-sh_cmt-address-race-condition-fo.patch +acpi-battery-create-alarm-sysfs-attribute-atomically.patch +acpi-sbs-manage-alarm-sysfs-attribute-through-psy-co.patch +wifi-nl80211-disallow-setting-special-ap-channel-wid.patch +r8169-remove-detection-of-chip-version-11-early-rtl8.patch +net-mlx5e-shampo-fix-invalid-wq-linked-list-unlink.patch +selftests-bpf-fix-send_signal-test-with-nested-confi.patch +af_unix-don-t-retry-after-unix_state_lock_nested-in-.patch +pci-add-edimax-vendor-id-to-pci_ids.h.patch +udf-prevent-integer-overflow-in-udf_bitmap_free_bloc.patch +wifi-nl80211-don-t-give-key-data-to-userspace.patch +can-mcp251xfd-tef-prepare-to-workaround-broken-tef-f.patch +can-mcp251xfd-tef-update-workaround-for-erratum-ds80.patch +btrfs-fix-bitmap-leak-when-loading-free-space-cache-.patch +drm-amdgpu-pm-fix-the-param-type-of-set_power_profil.patch +drm-amdgpu-pm-fix-the-null-pointer-dereference-for-s.patch +drm-amdgpu-fix-the-null-pointer-dereference-to-ras_m.patch +drm-amdgpu-pm-fix-the-null-pointer-dereference-in-ap.patch +drm-amdgpu-add-lock-around-vf-rlcg-interface.patch +drm-amd-pm-fix-the-null-pointer-dereference-for-vega.patch +media-amphion-remove-lock-in-s_ctrl-callback.patch +drm-amd-display-add-null-check-for-afb-before-derefe.patch +drm-amd-display-add-null-checker-before-passing-vari.patch +media-uvcvideo-ignore-empty-ts-packets.patch +media-uvcvideo-fix-the-bandwdith-quirk-on-usb-3.x.patch +media-xc2028-avoid-use-after-free-in-load_firmware_c.patch +ext4-fix-uninitialized-variable-in-ext4_inlinedir_to.patch +jbd2-avoid-memleak-in-jbd2_journal_write_metadata_bu.patch +s390-sclp-prevent-release-of-buffer-in-i-o.patch +sunrpc-fix-a-race-to-wake-a-sync-task.patch diff --git a/queue-6.1/sunrpc-fix-a-race-to-wake-a-sync-task.patch b/queue-6.1/sunrpc-fix-a-race-to-wake-a-sync-task.patch new file mode 100644 index 00000000000..29d7387d4b0 --- /dev/null +++ b/queue-6.1/sunrpc-fix-a-race-to-wake-a-sync-task.patch @@ -0,0 +1,53 @@ +From a641891877df2852bf23f70a357782b643fbbda4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Jul 2024 10:49:33 -0400 +Subject: SUNRPC: Fix a race to wake a sync task + +From: Benjamin Coddington + +[ Upstream commit ed0172af5d6fc07d1b40ca82f5ca3979300369f7 ] + +We've observed NFS clients with sync tasks sleeping in __rpc_execute +waiting on RPC_TASK_QUEUED that have not responded to a wake-up from +rpc_make_runnable(). I suspect this problem usually goes unnoticed, +because on a busy client the task will eventually be re-awoken by another +task completion or xprt event. However, if the state manager is draining +the slot table, a sync task missing a wake-up can result in a hung client. + +We've been able to prove that the waker in rpc_make_runnable() successfully +calls wake_up_bit() (ie- there's no race to tk_runstate), but the +wake_up_bit() call fails to wake the waiter. I suspect the waker is +missing the load of the bit's wait_queue_head, so waitqueue_active() is +false. There are some very helpful comments about this problem above +wake_up_bit(), prepare_to_wait(), and waitqueue_active(). + +Fix this by inserting smp_mb__after_atomic() before the wake_up_bit(), +which pairs with prepare_to_wait() calling set_current_state(). + +Signed-off-by: Benjamin Coddington +Reviewed-by: Jeff Layton +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + net/sunrpc/sched.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 6debf4fd42d4e..cef623ea15060 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -369,8 +369,10 @@ static void rpc_make_runnable(struct workqueue_struct *wq, + if (RPC_IS_ASYNC(task)) { + INIT_WORK(&task->u.tk_work, rpc_async_schedule); + queue_work(wq, &task->u.tk_work); +- } else ++ } else { ++ smp_mb__after_atomic(); + wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED); ++ } + } + + /* +-- +2.43.0 + diff --git a/queue-6.1/udf-prevent-integer-overflow-in-udf_bitmap_free_bloc.patch b/queue-6.1/udf-prevent-integer-overflow-in-udf_bitmap_free_bloc.patch new file mode 100644 index 00000000000..867ee6dab79 --- /dev/null +++ b/queue-6.1/udf-prevent-integer-overflow-in-udf_bitmap_free_bloc.patch @@ -0,0 +1,113 @@ +From 5ba4d6c1fd4276bb84e8be86d539f1f60bc51e90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jun 2024 10:24:13 +0300 +Subject: udf: prevent integer overflow in udf_bitmap_free_blocks() + +From: Roman Smirnov + +[ Upstream commit 56e69e59751d20993f243fb7dd6991c4e522424c ] + +An overflow may occur if the function is called with the last +block and an offset greater than zero. It is necessary to add +a check to avoid this. + +Found by Linux Verification Center (linuxtesting.org) with Svace. + +[JK: Make test cover also unalloc table freeing] + +Link: https://patch.msgid.link/20240620072413.7448-1-r.smirnov@omp.ru +Suggested-by: Jan Kara +Signed-off-by: Roman Smirnov +Signed-off-by: Jan Kara +Signed-off-by: Sasha Levin +--- + fs/udf/balloc.c | 36 +++++++++++++----------------------- + 1 file changed, 13 insertions(+), 23 deletions(-) + +diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c +index c4c18eeacb60c..aa73ab1b50a52 100644 +--- a/fs/udf/balloc.c ++++ b/fs/udf/balloc.c +@@ -22,6 +22,7 @@ + #include "udfdecl.h" + + #include ++#include + + #include "udf_i.h" + #include "udf_sb.h" +@@ -144,7 +145,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, + { + struct udf_sb_info *sbi = UDF_SB(sb); + struct buffer_head *bh = NULL; +- struct udf_part_map *partmap; + unsigned long block; + unsigned long block_group; + unsigned long bit; +@@ -153,19 +153,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb, + unsigned long overflow; + + mutex_lock(&sbi->s_alloc_mutex); +- partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; +- if (bloc->logicalBlockNum + count < count || +- (bloc->logicalBlockNum + count) > partmap->s_partition_len) { +- udf_debug("%u < %d || %u + %u > %u\n", +- bloc->logicalBlockNum, 0, +- bloc->logicalBlockNum, count, +- partmap->s_partition_len); +- goto error_return; +- } +- ++ /* We make sure this cannot overflow when mounting the filesystem */ + block = bloc->logicalBlockNum + offset + + (sizeof(struct spaceBitmapDesc) << 3); +- + do { + overflow = 0; + block_group = block >> (sb->s_blocksize_bits + 3); +@@ -395,7 +385,6 @@ static void udf_table_free_blocks(struct super_block *sb, + uint32_t count) + { + struct udf_sb_info *sbi = UDF_SB(sb); +- struct udf_part_map *partmap; + uint32_t start, end; + uint32_t elen; + struct kernel_lb_addr eloc; +@@ -404,16 +393,6 @@ static void udf_table_free_blocks(struct super_block *sb, + struct udf_inode_info *iinfo; + + mutex_lock(&sbi->s_alloc_mutex); +- partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; +- if (bloc->logicalBlockNum + count < count || +- (bloc->logicalBlockNum + count) > partmap->s_partition_len) { +- udf_debug("%u < %d || %u + %u > %u\n", +- bloc->logicalBlockNum, 0, +- bloc->logicalBlockNum, count, +- partmap->s_partition_len); +- goto error_return; +- } +- + iinfo = UDF_I(table); + udf_add_free_space(sb, sbi->s_partition, count); + +@@ -688,6 +667,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, + { + uint16_t partition = bloc->partitionReferenceNum; + struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; ++ uint32_t blk; ++ ++ if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) || ++ check_add_overflow(blk, count, &blk) || ++ bloc->logicalBlockNum + count > map->s_partition_len) { ++ udf_debug("Invalid request to free blocks: (%d, %u), off %u, " ++ "len %u, partition len %u\n", ++ partition, bloc->logicalBlockNum, offset, count, ++ map->s_partition_len); ++ return; ++ } + + if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { + udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, +-- +2.43.0 + diff --git a/queue-6.1/wifi-nl80211-disallow-setting-special-ap-channel-wid.patch b/queue-6.1/wifi-nl80211-disallow-setting-special-ap-channel-wid.patch new file mode 100644 index 00000000000..aa25f339a3f --- /dev/null +++ b/queue-6.1/wifi-nl80211-disallow-setting-special-ap-channel-wid.patch @@ -0,0 +1,62 @@ +From aa0539ca0f3d1b5f6b0f8a48a1b24483a3f763e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 May 2024 14:16:00 +0200 +Subject: wifi: nl80211: disallow setting special AP channel widths + +From: Johannes Berg + +[ Upstream commit 23daf1b4c91db9b26f8425cc7039cf96d22ccbfe ] + +Setting the AP channel width is meant for use with the normal +20/40/... MHz channel width progression, and switching around +in S1G or narrow channels isn't supported. Disallow that. + +Reported-by: syzbot+bc0f5b92cc7091f45fb6@syzkaller.appspotmail.com +Link: https://msgid.link/20240515141600.d4a9590bfe32.I19a32d60097e81b527eafe6b0924f6c5fbb2dc45@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/nl80211.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index a00df7b89ca86..603fcd921bd22 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3346,6 +3346,33 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, + if (chandef.chan != cur_chan) + return -EBUSY; + ++ /* only allow this for regular channel widths */ ++ switch (wdev->links[link_id].ap.chandef.width) { ++ case NL80211_CHAN_WIDTH_20_NOHT: ++ case NL80211_CHAN_WIDTH_20: ++ case NL80211_CHAN_WIDTH_40: ++ case NL80211_CHAN_WIDTH_80: ++ case NL80211_CHAN_WIDTH_80P80: ++ case NL80211_CHAN_WIDTH_160: ++ case NL80211_CHAN_WIDTH_320: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (chandef.width) { ++ case NL80211_CHAN_WIDTH_20_NOHT: ++ case NL80211_CHAN_WIDTH_20: ++ case NL80211_CHAN_WIDTH_40: ++ case NL80211_CHAN_WIDTH_80: ++ case NL80211_CHAN_WIDTH_80P80: ++ case NL80211_CHAN_WIDTH_160: ++ case NL80211_CHAN_WIDTH_320: ++ break; ++ default: ++ return -EINVAL; ++ } ++ + result = rdev_set_ap_chanwidth(rdev, dev, link_id, + &chandef); + if (result) +-- +2.43.0 + diff --git a/queue-6.1/wifi-nl80211-don-t-give-key-data-to-userspace.patch b/queue-6.1/wifi-nl80211-don-t-give-key-data-to-userspace.patch new file mode 100644 index 00000000000..760588afec0 --- /dev/null +++ b/queue-6.1/wifi-nl80211-don-t-give-key-data-to-userspace.patch @@ -0,0 +1,55 @@ +From dfd25ed104da8833cb65c5e1cd74583710482002 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Jun 2024 10:44:11 +0200 +Subject: wifi: nl80211: don't give key data to userspace + +From: Johannes Berg + +[ Upstream commit a7e5793035792cc46a1a4b0a783655ffa897dfe9 ] + +When a key is requested by userspace, there's really no need +to include the key data, the sequence counter is really what +userspace needs in this case. The fact that it's included is +just a historic quirk. + +Remove the key data. + +Reviewed-by: Miriam Rachel Korenblit +Link: https://patch.msgid.link/20240627104411.b6a4f097e4ea.I7e6cc976cb9e8a80ef25a3351330f313373b4578@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/nl80211.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 603fcd921bd22..214eee6105c7f 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -4421,10 +4421,7 @@ static void get_key_callback(void *c, struct key_params *params) + struct nlattr *key; + struct get_key_cookie *cookie = c; + +- if ((params->key && +- nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, +- params->key_len, params->key)) || +- (params->seq && ++ if ((params->seq && + nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, + params->seq_len, params->seq)) || + (params->cipher && +@@ -4436,10 +4433,7 @@ static void get_key_callback(void *c, struct key_params *params) + if (!key) + goto nla_put_failure; + +- if ((params->key && +- nla_put(cookie->msg, NL80211_KEY_DATA, +- params->key_len, params->key)) || +- (params->seq && ++ if ((params->seq && + nla_put(cookie->msg, NL80211_KEY_SEQ, + params->seq_len, params->seq)) || + (params->cipher && +-- +2.43.0 + diff --git a/queue-6.1/x86-mm-fix-pti_clone_entry_text-for-i386.patch b/queue-6.1/x86-mm-fix-pti_clone_entry_text-for-i386.patch new file mode 100644 index 00000000000..7dacce9936e --- /dev/null +++ b/queue-6.1/x86-mm-fix-pti_clone_entry_text-for-i386.patch @@ -0,0 +1,42 @@ +From 3307064a579cee96dc62b13350cb7ad16f9aeefb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Aug 2024 12:42:25 +0200 +Subject: x86/mm: Fix pti_clone_entry_text() for i386 + +From: Peter Zijlstra + +[ Upstream commit 3db03fb4995ef85fc41e86262ead7b4852f4bcf0 ] + +While x86_64 has PMD aligned text sections, i386 does not have this +luxery. Notably ALIGN_ENTRY_TEXT_END is empty and _etext has PAGE +alignment. + +This means that text on i386 can be page granular at the tail end, +which in turn means that the PTI text clones should consistently +account for this. + +Make pti_clone_entry_text() consistent with pti_clone_kernel_text(). + +Fixes: 16a3fe634f6a ("x86/mm/pti: Clone kernel-image on PTE level for 32 bit") +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Sasha Levin +--- + arch/x86/mm/pti.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c +index 2c4037174ed22..7b804c34c0201 100644 +--- a/arch/x86/mm/pti.c ++++ b/arch/x86/mm/pti.c +@@ -496,7 +496,7 @@ static void pti_clone_entry_text(void) + { + pti_clone_pgtable((unsigned long) __entry_text_start, + (unsigned long) __entry_text_end, +- PTI_CLONE_PMD); ++ PTI_LEVEL_KERNEL_IMAGE); + } + + /* +-- +2.43.0 + diff --git a/queue-6.1/x86-mm-fix-pti_clone_pgtable-alignment-assumption.patch b/queue-6.1/x86-mm-fix-pti_clone_pgtable-alignment-assumption.patch new file mode 100644 index 00000000000..5e24690842c --- /dev/null +++ b/queue-6.1/x86-mm-fix-pti_clone_pgtable-alignment-assumption.patch @@ -0,0 +1,68 @@ +From 1fc5b37dd707861132470dfa83cf1bcdd9e23e7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 18:31:05 +0200 +Subject: x86/mm: Fix pti_clone_pgtable() alignment assumption + +From: Peter Zijlstra + +[ Upstream commit 41e71dbb0e0a0fe214545fe64af031303a08524c ] + +Guenter reported dodgy crashes on an i386-nosmp build using GCC-11 +that had the form of endless traps until entry stack exhaust and then +#DF from the stack guard. + +It turned out that pti_clone_pgtable() had alignment assumptions on +the start address, notably it hard assumes start is PMD aligned. This +is true on x86_64, but very much not true on i386. + +These assumptions can cause the end condition to malfunction, leading +to a 'short' clone. Guess what happens when the user mapping has a +short copy of the entry text? + +Use the correct increment form for addr to avoid alignment +assumptions. + +Fixes: 16a3fe634f6a ("x86/mm/pti: Clone kernel-image on PTE level for 32 bit") +Reported-by: Guenter Roeck +Tested-by: Guenter Roeck +Suggested-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20240731163105.GG33588@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + arch/x86/mm/pti.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c +index 78414c6d1b5ed..2c4037174ed22 100644 +--- a/arch/x86/mm/pti.c ++++ b/arch/x86/mm/pti.c +@@ -374,14 +374,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + */ + *target_pmd = *pmd; + +- addr += PMD_SIZE; ++ addr = round_up(addr + 1, PMD_SIZE); + + } else if (level == PTI_CLONE_PTE) { + + /* Walk the page-table down to the pte level */ + pte = pte_offset_kernel(pmd, addr); + if (pte_none(*pte)) { +- addr += PAGE_SIZE; ++ addr = round_up(addr + 1, PAGE_SIZE); + continue; + } + +@@ -401,7 +401,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end, + /* Clone the PTE */ + *target_pte = *pte; + +- addr += PAGE_SIZE; ++ addr = round_up(addr + 1, PAGE_SIZE); + + } else { + BUG(); +-- +2.43.0 +