From: Greg Kroah-Hartman Date: Mon, 26 Feb 2024 12:33:10 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v4.19.308~57 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=785efaac13af4d1442ff3c506e1cf2ad40dbe286;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: ata-libata-core-do-not-try-to-set-sleeping-devices-to-standby.patch cachefiles-fix-memory-leak-in-cachefiles_add_cache.patch crypto-virtio-akcipher-fix-stack-overflow-on-memcpy.patch cxl-pci-fix-disabling-memory-if-dvsec-cxl-range-does-not-match-a-cfmws-window.patch dm-crypt-don-t-modify-the-data-when-using-authenticated-encryption.patch dm-crypt-recheck-the-integrity-tag-after-a-failure.patch dm-integrity-recheck-the-integrity-tag-after-a-failure.patch dm-verity-recheck-the-hash-after-a-failure.patch drm-ttm-fix-an-invalid-freeing-on-already-freed-page-in-error-path.patch gtp-fix-use-after-free-and-null-ptr-deref-in-gtp_genl_dump_pdp.patch irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch kvm-arm64-vgic-its-test-for-valid-irq-in-its_sync_lpi_pending_table.patch kvm-arm64-vgic-its-test-for-valid-irq-in-movall-handler.patch l2tp-pass-correct-message-length-to-ip6_append_data.patch loongarch-disable-irq-before-init_fn-for-nonboot-cpus.patch md-fix-missing-release-of-active_io-for-flush.patch mm-damon-lru_sort-fix-quota-status-loss-due-to-online-tunings.patch mm-memcontrol-clarify-swapaccount-0-deprecation-warning.patch mm-swap-fix-race-when-skipping-swapcache.patch pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch platform-x86-intel-vbtn-stop-calling-vbdl-from-notify_handler.patch platform-x86-touchscreen_dmi-allow-partial-prefix-matches-for-acpi-names.patch revert-parisc-only-list-existing-cpus-in-cpu_possible_mask.patch s390-cio-fix-invalid-ebusy-on-ccw_device_start.patch scsi-core-consult-supported-vpd-page-list-prior-to-fetching-page.patch scsi-target-pscsi-fix-bio_put-for-error-case.patch --- diff --git a/queue-6.1/ata-libata-core-do-not-try-to-set-sleeping-devices-to-standby.patch b/queue-6.1/ata-libata-core-do-not-try-to-set-sleeping-devices-to-standby.patch new file mode 100644 index 00000000000..400da329f9d --- /dev/null +++ b/queue-6.1/ata-libata-core-do-not-try-to-set-sleeping-devices-to-standby.patch @@ -0,0 +1,34 @@ +From 4b085736e44dbbe69b5eea1a8a294f404678a1f4 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Thu, 11 Jan 2024 20:51:22 +0900 +Subject: ata: libata-core: Do not try to set sleeping devices to standby + +From: Damien Le Moal + +commit 4b085736e44dbbe69b5eea1a8a294f404678a1f4 upstream. + +In ata ata_dev_power_set_standby(), check that the target device is not +sleeping. If it is, there is no need to do anything. + +Fixes: aa3998dbeb3a ("ata: libata-scsi: Disable scsi device manage_system_start_stop") +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Signed-off-by: Niklas Cassel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2005,6 +2005,10 @@ void ata_dev_power_set_active(struct ata + struct ata_taskfile tf; + unsigned int err_mask; + ++ /* If the device is already sleeping, do nothing. */ ++ if (dev->flags & ATA_DFLAG_SLEEPING) ++ return; ++ + /* + * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only + * if supported by the device. diff --git a/queue-6.1/cachefiles-fix-memory-leak-in-cachefiles_add_cache.patch b/queue-6.1/cachefiles-fix-memory-leak-in-cachefiles_add_cache.patch new file mode 100644 index 00000000000..824ad33cc07 --- /dev/null +++ b/queue-6.1/cachefiles-fix-memory-leak-in-cachefiles_add_cache.patch @@ -0,0 +1,68 @@ +From e21a2f17566cbd64926fb8f16323972f7a064444 Mon Sep 17 00:00:00 2001 +From: Baokun Li +Date: Sat, 17 Feb 2024 16:14:31 +0800 +Subject: cachefiles: fix memory leak in cachefiles_add_cache() + +From: Baokun Li + +commit e21a2f17566cbd64926fb8f16323972f7a064444 upstream. + +The following memory leak was reported after unbinding /dev/cachefiles: + +================================================================== +unreferenced object 0xffff9b674176e3c0 (size 192): + comm "cachefilesd2", pid 680, jiffies 4294881224 + hex dump (first 32 bytes): + 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace (crc ea38a44b): + [] kmem_cache_alloc+0x2d5/0x370 + [] prepare_creds+0x26/0x2e0 + [] cachefiles_determine_cache_security+0x1f/0x120 + [] cachefiles_add_cache+0x13c/0x3a0 + [] cachefiles_daemon_write+0x146/0x1c0 + [] vfs_write+0xcb/0x520 + [] ksys_write+0x69/0xf0 + [] do_syscall_64+0x72/0x140 + [] entry_SYSCALL_64_after_hwframe+0x6e/0x76 +================================================================== + +Put the reference count of cache_cred in cachefiles_daemon_unbind() to +fix the problem. And also put cache_cred in cachefiles_add_cache() error +branch to avoid memory leaks. + +Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") +CC: stable@vger.kernel.org +Signed-off-by: Baokun Li +Link: https://lore.kernel.org/r/20240217081431.796809-1-libaokun1@huawei.com +Acked-by: David Howells +Reviewed-by: Jingbo Xu +Reviewed-by: Jeff Layton +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/cachefiles/cache.c | 2 ++ + fs/cachefiles/daemon.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/fs/cachefiles/cache.c ++++ b/fs/cachefiles/cache.c +@@ -168,6 +168,8 @@ error_unsupported: + dput(root); + error_open_root: + cachefiles_end_secure(cache, saved_cred); ++ put_cred(cache->cache_cred); ++ cache->cache_cred = NULL; + error_getsec: + fscache_relinquish_cache(cache_cookie); + cache->cache = NULL; +--- a/fs/cachefiles/daemon.c ++++ b/fs/cachefiles/daemon.c +@@ -805,6 +805,7 @@ static void cachefiles_daemon_unbind(str + cachefiles_put_directory(cache->graveyard); + cachefiles_put_directory(cache->store); + mntput(cache->mnt); ++ put_cred(cache->cache_cred); + + kfree(cache->rootdirname); + kfree(cache->secctx); diff --git a/queue-6.1/crypto-virtio-akcipher-fix-stack-overflow-on-memcpy.patch b/queue-6.1/crypto-virtio-akcipher-fix-stack-overflow-on-memcpy.patch new file mode 100644 index 00000000000..18bccb764ed --- /dev/null +++ b/queue-6.1/crypto-virtio-akcipher-fix-stack-overflow-on-memcpy.patch @@ -0,0 +1,52 @@ +From c0ec2a712daf133d9996a8a1b7ee2d4996080363 Mon Sep 17 00:00:00 2001 +From: zhenwei pi +Date: Tue, 30 Jan 2024 19:27:40 +0800 +Subject: crypto: virtio/akcipher - Fix stack overflow on memcpy + +From: zhenwei pi + +commit c0ec2a712daf133d9996a8a1b7ee2d4996080363 upstream. + +sizeof(struct virtio_crypto_akcipher_session_para) is less than +sizeof(struct virtio_crypto_op_ctrl_req::u), copying more bytes from +stack variable leads stack overflow. Clang reports this issue by +commands: +make -j CC=clang-14 mrproper >/dev/null 2>&1 +make -j O=/tmp/crypto-build CC=clang-14 allmodconfig >/dev/null 2>&1 +make -j O=/tmp/crypto-build W=1 CC=clang-14 drivers/crypto/virtio/ + virtio_crypto_akcipher_algs.o + +Fixes: 59ca6c93387d ("virtio-crypto: implement RSA algorithm") +Link: https://lore.kernel.org/all/0a194a79-e3a3-45e7-be98-83abd3e1cb7e@roeck-us.net/ +Cc: +Signed-off-by: zhenwei pi +Tested-by: Nathan Chancellor # build +Acked-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/virtio/virtio_crypto_akcipher_algs.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c ++++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c +@@ -104,7 +104,8 @@ static void virtio_crypto_dataq_akcipher + } + + static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher_ctx *ctx, +- struct virtio_crypto_ctrl_header *header, void *para, ++ struct virtio_crypto_ctrl_header *header, ++ struct virtio_crypto_akcipher_session_para *para, + const uint8_t *key, unsigned int keylen) + { + struct scatterlist outhdr_sg, key_sg, inhdr_sg, *sgs[3]; +@@ -128,7 +129,7 @@ static int virtio_crypto_alg_akcipher_in + + ctrl = &vc_ctrl_req->ctrl; + memcpy(&ctrl->header, header, sizeof(ctrl->header)); +- memcpy(&ctrl->u, para, sizeof(ctrl->u)); ++ memcpy(&ctrl->u.akcipher_create_session.para, para, sizeof(*para)); + input = &vc_ctrl_req->input; + input->status = cpu_to_le32(VIRTIO_CRYPTO_ERR); + diff --git a/queue-6.1/cxl-pci-fix-disabling-memory-if-dvsec-cxl-range-does-not-match-a-cfmws-window.patch b/queue-6.1/cxl-pci-fix-disabling-memory-if-dvsec-cxl-range-does-not-match-a-cfmws-window.patch new file mode 100644 index 00000000000..7db4e7ba614 --- /dev/null +++ b/queue-6.1/cxl-pci-fix-disabling-memory-if-dvsec-cxl-range-does-not-match-a-cfmws-window.patch @@ -0,0 +1,56 @@ +From 0cab687205986491302cd2e440ef1d253031c221 Mon Sep 17 00:00:00 2001 +From: Robert Richter +Date: Fri, 16 Feb 2024 17:01:13 +0100 +Subject: cxl/pci: Fix disabling memory if DVSEC CXL Range does not match a CFMWS window + +From: Robert Richter + +commit 0cab687205986491302cd2e440ef1d253031c221 upstream. + +The Linux CXL subsystem is built on the assumption that HPA == SPA. +That is, the host physical address (HPA) the HDM decoder registers are +programmed with are system physical addresses (SPA). + +During HDM decoder setup, the DVSEC CXL range registers (cxl-3.1, +8.1.3.8) are checked if the memory is enabled and the CXL range is in +a HPA window that is described in a CFMWS structure of the CXL host +bridge (cxl-3.1, 9.18.1.3). + +Now, if the HPA is not an SPA, the CXL range does not match a CFMWS +window and the CXL memory range will be disabled then. The HDM decoder +stops working which causes system memory being disabled and further a +system hang during HDM decoder initialization, typically when a CXL +enabled kernel boots. + +Prevent a system hang and do not disable the HDM decoder if the +decoder's CXL range is not found in a CFMWS window. + +Note the change only fixes a hardware hang, but does not implement +HPA/SPA translation. Support for this can be added in a follow on +patch series. + +Signed-off-by: Robert Richter +Fixes: 34e37b4c432c ("cxl/port: Enable HDM Capability after validating DVSEC Ranges") +Cc: +Link: https://lore.kernel.org/r/20240216160113.407141-1-rrichter@amd.com +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cxl/core/pci.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/cxl/core/pci.c ++++ b/drivers/cxl/core/pci.c +@@ -376,9 +376,9 @@ static bool __cxl_hdm_decode_init(struct + allowed++; + } + +- if (!allowed) { +- cxl_set_mem_enable(cxlds, 0); +- info->mem_enabled = 0; ++ if (!allowed && info->mem_enabled) { ++ dev_err(dev, "Range register decodes outside platform defined CXL ranges.\n"); ++ return -ENXIO; + } + + /* diff --git a/queue-6.1/dm-crypt-don-t-modify-the-data-when-using-authenticated-encryption.patch b/queue-6.1/dm-crypt-don-t-modify-the-data-when-using-authenticated-encryption.patch new file mode 100644 index 00000000000..0e8681a7869 --- /dev/null +++ b/queue-6.1/dm-crypt-don-t-modify-the-data-when-using-authenticated-encryption.patch @@ -0,0 +1,43 @@ +From 50c70240097ce41fe6bce6478b80478281e4d0f7 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 19 Feb 2024 21:30:10 +0100 +Subject: dm-crypt: don't modify the data when using authenticated encryption + +From: Mikulas Patocka + +commit 50c70240097ce41fe6bce6478b80478281e4d0f7 upstream. + +It was said that authenticated encryption could produce invalid tag when +the data that is being encrypted is modified [1]. So, fix this problem by +copying the data into the clone bio first and then encrypt them inside the +clone bio. + +This may reduce performance, but it is needed to prevent the user from +corrupting the device by writing data with O_DIRECT and modifying them at +the same time. + +[1] https://lore.kernel.org/all/20240207004723.GA35324@sol.localdomain/T/ + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-crypt.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -2078,6 +2078,12 @@ static void kcryptd_crypt_write_convert( + io->ctx.bio_out = clone; + io->ctx.iter_out = clone->bi_iter; + ++ if (crypt_integrity_aead(cc)) { ++ bio_copy_data(clone, io->base_bio); ++ io->ctx.bio_in = clone; ++ io->ctx.iter_in = clone->bi_iter; ++ } ++ + sector += bio_sectors(clone); + + crypt_inc_pending(io); diff --git a/queue-6.1/dm-crypt-recheck-the-integrity-tag-after-a-failure.patch b/queue-6.1/dm-crypt-recheck-the-integrity-tag-after-a-failure.patch new file mode 100644 index 00000000000..2f7e92c87d4 --- /dev/null +++ b/queue-6.1/dm-crypt-recheck-the-integrity-tag-after-a-failure.patch @@ -0,0 +1,212 @@ +From 42e15d12070b4ff9af2b980f1b65774c2dab0507 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 19 Feb 2024 21:31:11 +0100 +Subject: dm-crypt: recheck the integrity tag after a failure + +From: Mikulas Patocka + +commit 42e15d12070b4ff9af2b980f1b65774c2dab0507 upstream. + +If a userspace process reads (with O_DIRECT) multiple blocks into the same +buffer, dm-crypt reports an authentication error [1]. The error is +reported in a log and it may cause RAID leg being kicked out of the +array. + +This commit fixes dm-crypt, so that if integrity verification fails, the +data is read again into a kernel buffer (where userspace can't modify it) +and the integrity tag is rechecked. If the recheck succeeds, the content +of the kernel buffer is copied into the user buffer; if the recheck fails, +an integrity error is reported. + +[1] https://people.redhat.com/~mpatocka/testcases/blk-auth-modify/read2.c + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-crypt.c | 89 +++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 73 insertions(+), 16 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -61,6 +61,8 @@ struct convert_context { + struct skcipher_request *req; + struct aead_request *req_aead; + } r; ++ bool aead_recheck; ++ bool aead_failed; + + }; + +@@ -81,6 +83,8 @@ struct dm_crypt_io { + blk_status_t error; + sector_t sector; + ++ struct bvec_iter saved_bi_iter; ++ + struct rb_node rb_node; + } CRYPTO_MINALIGN_ATTR; + +@@ -1365,10 +1369,13 @@ static int crypt_convert_block_aead(stru + if (r == -EBADMSG) { + sector_t s = le64_to_cpu(*sector); + +- DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", +- ctx->bio_in->bi_bdev, s); +- dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", +- ctx->bio_in, s, 0); ++ ctx->aead_failed = true; ++ if (ctx->aead_recheck) { ++ DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", ++ ctx->bio_in->bi_bdev, s); ++ dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", ++ ctx->bio_in, s, 0); ++ } + } + + if (!r && cc->iv_gen_ops && cc->iv_gen_ops->post) +@@ -1724,6 +1731,8 @@ static void crypt_io_init(struct dm_cryp + io->base_bio = bio; + io->sector = sector; + io->error = 0; ++ io->ctx.aead_recheck = false; ++ io->ctx.aead_failed = false; + io->ctx.r.req = NULL; + io->integrity_metadata = NULL; + io->integrity_metadata_from_pool = false; +@@ -1735,6 +1744,8 @@ static void crypt_inc_pending(struct dm_ + atomic_inc(&io->io_pending); + } + ++static void kcryptd_queue_read(struct dm_crypt_io *io); ++ + /* + * One of the bios was finished. Check for completion of + * the whole request and correctly clean up the buffer. +@@ -1748,6 +1759,15 @@ static void crypt_dec_pending(struct dm_ + if (!atomic_dec_and_test(&io->io_pending)) + return; + ++ if (likely(!io->ctx.aead_recheck) && unlikely(io->ctx.aead_failed) && ++ cc->on_disk_tag_size && bio_data_dir(base_bio) == READ) { ++ io->ctx.aead_recheck = true; ++ io->ctx.aead_failed = false; ++ io->error = 0; ++ kcryptd_queue_read(io); ++ return; ++ } ++ + if (io->ctx.r.req) + crypt_free_req(cc, io->ctx.r.req, base_bio); + +@@ -1783,15 +1803,19 @@ static void crypt_endio(struct bio *clon + struct dm_crypt_io *io = clone->bi_private; + struct crypt_config *cc = io->cc; + unsigned int rw = bio_data_dir(clone); +- blk_status_t error; ++ blk_status_t error = clone->bi_status; ++ ++ if (io->ctx.aead_recheck && !error) { ++ kcryptd_queue_crypt(io); ++ return; ++ } + + /* + * free the processed pages + */ +- if (rw == WRITE) ++ if (rw == WRITE || io->ctx.aead_recheck) + crypt_free_buffer_pages(cc, clone); + +- error = clone->bi_status; + bio_put(clone); + + if (rw == READ && !error) { +@@ -1812,6 +1836,22 @@ static int kcryptd_io_read(struct dm_cry + struct crypt_config *cc = io->cc; + struct bio *clone; + ++ if (io->ctx.aead_recheck) { ++ if (!(gfp & __GFP_DIRECT_RECLAIM)) ++ return 1; ++ crypt_inc_pending(io); ++ clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size); ++ if (unlikely(!clone)) { ++ crypt_dec_pending(io); ++ return 1; ++ } ++ clone->bi_iter.bi_sector = cc->start + io->sector; ++ crypt_convert_init(cc, &io->ctx, clone, clone, io->sector); ++ io->saved_bi_iter = clone->bi_iter; ++ dm_submit_bio_remap(io->base_bio, clone); ++ return 0; ++ } ++ + /* + * We need the original biovec array in order to decrypt the whole bio + * data *afterwards* -- thanks to immutable biovecs we don't need to +@@ -2074,6 +2114,14 @@ dec: + + static void kcryptd_crypt_read_done(struct dm_crypt_io *io) + { ++ if (io->ctx.aead_recheck) { ++ if (!io->error) { ++ io->ctx.bio_in->bi_iter = io->saved_bi_iter; ++ bio_copy_data(io->base_bio, io->ctx.bio_in); ++ } ++ crypt_free_buffer_pages(io->cc, io->ctx.bio_in); ++ bio_put(io->ctx.bio_in); ++ } + crypt_dec_pending(io); + } + +@@ -2103,11 +2151,17 @@ static void kcryptd_crypt_read_convert(s + + crypt_inc_pending(io); + +- crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, +- io->sector); ++ if (io->ctx.aead_recheck) { ++ io->ctx.cc_sector = io->sector + cc->iv_offset; ++ r = crypt_convert(cc, &io->ctx, ++ test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); ++ } else { ++ crypt_convert_init(cc, &io->ctx, io->base_bio, io->base_bio, ++ io->sector); + +- r = crypt_convert(cc, &io->ctx, +- test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); ++ r = crypt_convert(cc, &io->ctx, ++ test_bit(DM_CRYPT_NO_READ_WORKQUEUE, &cc->flags), true); ++ } + /* + * Crypto API backlogged the request, because its queue was full + * and we're in softirq context, so continue from a workqueue +@@ -2150,10 +2204,13 @@ static void kcryptd_async_done(struct cr + if (error == -EBADMSG) { + sector_t s = le64_to_cpu(*org_sector_of_dmreq(cc, dmreq)); + +- DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", +- ctx->bio_in->bi_bdev, s); +- dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", +- ctx->bio_in, s, 0); ++ ctx->aead_failed = true; ++ if (ctx->aead_recheck) { ++ DMERR_LIMIT("%pg: INTEGRITY AEAD ERROR, sector %llu", ++ ctx->bio_in->bi_bdev, s); ++ dm_audit_log_bio(DM_MSG_PREFIX, "integrity-aead", ++ ctx->bio_in, s, 0); ++ } + io->error = BLK_STS_PROTECTION; + } else if (error < 0) + io->error = BLK_STS_IOERR; +@@ -3079,7 +3136,7 @@ static int crypt_ctr_optional(struct dm_ + sval = strchr(opt_string + strlen("integrity:"), ':') + 1; + if (!strcasecmp(sval, "aead")) { + set_bit(CRYPT_MODE_INTEGRITY_AEAD, &cc->cipher_flags); +- } else if (strcasecmp(sval, "none")) { ++ } else if (strcasecmp(sval, "none")) { + ti->error = "Unknown integrity profile"; + return -EINVAL; + } diff --git a/queue-6.1/dm-integrity-recheck-the-integrity-tag-after-a-failure.patch b/queue-6.1/dm-integrity-recheck-the-integrity-tag-after-a-failure.patch new file mode 100644 index 00000000000..dada0bfb91b --- /dev/null +++ b/queue-6.1/dm-integrity-recheck-the-integrity-tag-after-a-failure.patch @@ -0,0 +1,159 @@ +From c88f5e553fe38b2ffc4c33d08654e5281b297677 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 19 Feb 2024 21:27:39 +0100 +Subject: dm-integrity: recheck the integrity tag after a failure + +From: Mikulas Patocka + +commit c88f5e553fe38b2ffc4c33d08654e5281b297677 upstream. + +If a userspace process reads (with O_DIRECT) multiple blocks into the same +buffer, dm-integrity reports an error [1]. The error is reported in a log +and it may cause RAID leg being kicked out of the array. + +This commit fixes dm-integrity, so that if integrity verification fails, +the data is read again into a kernel buffer (where userspace can't modify +it) and the integrity tag is rechecked. If the recheck succeeds, the +content of the kernel buffer is copied into the user buffer; if the +recheck fails, an integrity error is reported. + +[1] https://people.redhat.com/~mpatocka/testcases/blk-auth-modify/read2.c + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-integrity.c | 93 +++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 84 insertions(+), 9 deletions(-) + +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -279,6 +279,8 @@ struct dm_integrity_c { + + atomic64_t number_of_mismatches; + ++ mempool_t recheck_pool; ++ + struct notifier_block reboot_notifier; + }; + +@@ -1699,6 +1701,79 @@ failed: + get_random_bytes(result, ic->tag_size); + } + ++static void integrity_recheck(struct dm_integrity_io *dio) ++{ ++ struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); ++ struct dm_integrity_c *ic = dio->ic; ++ struct bvec_iter iter; ++ struct bio_vec bv; ++ sector_t sector, logical_sector, area, offset; ++ char checksum_onstack[max_t(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; ++ struct page *page; ++ void *buffer; ++ ++ get_area_and_offset(ic, dio->range.logical_sector, &area, &offset); ++ dio->metadata_block = get_metadata_sector_and_offset(ic, area, offset, ++ &dio->metadata_offset); ++ sector = get_data_sector(ic, area, offset); ++ logical_sector = dio->range.logical_sector; ++ ++ page = mempool_alloc(&ic->recheck_pool, GFP_NOIO); ++ buffer = page_to_virt(page); ++ ++ __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { ++ unsigned pos = 0; ++ ++ do { ++ char *mem; ++ int r; ++ struct dm_io_request io_req; ++ struct dm_io_region io_loc; ++ io_req.bi_opf = REQ_OP_READ; ++ io_req.mem.type = DM_IO_KMEM; ++ io_req.mem.ptr.addr = buffer; ++ io_req.notify.fn = NULL; ++ io_req.client = ic->io; ++ io_loc.bdev = ic->dev->bdev; ++ io_loc.sector = sector; ++ io_loc.count = ic->sectors_per_block; ++ ++ r = dm_io(&io_req, 1, &io_loc, NULL); ++ if (unlikely(r)) { ++ dio->bi_status = errno_to_blk_status(r); ++ goto free_ret; ++ } ++ ++ integrity_sector_checksum(ic, logical_sector, buffer, ++ checksum_onstack); ++ r = dm_integrity_rw_tag(ic, checksum_onstack, &dio->metadata_block, ++ &dio->metadata_offset, ic->tag_size, TAG_CMP); ++ if (r) { ++ if (r > 0) { ++ DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx", ++ bio->bi_bdev, logical_sector); ++ atomic64_inc(&ic->number_of_mismatches); ++ dm_audit_log_bio(DM_MSG_PREFIX, "integrity-checksum", ++ bio, logical_sector, 0); ++ r = -EILSEQ; ++ } ++ dio->bi_status = errno_to_blk_status(r); ++ goto free_ret; ++ } ++ ++ mem = bvec_kmap_local(&bv); ++ memcpy(mem + pos, buffer, ic->sectors_per_block << SECTOR_SHIFT); ++ kunmap_local(mem); ++ ++ pos += ic->sectors_per_block << SECTOR_SHIFT; ++ sector += ic->sectors_per_block; ++ logical_sector += ic->sectors_per_block; ++ } while (pos < bv.bv_len); ++ } ++free_ret: ++ mempool_free(page, &ic->recheck_pool); ++} ++ + static void integrity_metadata(struct work_struct *w) + { + struct dm_integrity_io *dio = container_of(w, struct dm_integrity_io, work); +@@ -1784,15 +1859,8 @@ again: + checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE); + if (unlikely(r)) { + if (r > 0) { +- sector_t s; +- +- s = sector - ((r + ic->tag_size - 1) / ic->tag_size); +- DMERR_LIMIT("%pg: Checksum failed at sector 0x%llx", +- bio->bi_bdev, s); +- r = -EILSEQ; +- atomic64_inc(&ic->number_of_mismatches); +- dm_audit_log_bio(DM_MSG_PREFIX, "integrity-checksum", +- bio, s, 0); ++ integrity_recheck(dio); ++ goto skip_io; + } + if (likely(checksums != checksums_onstack)) + kfree(checksums); +@@ -4208,6 +4276,12 @@ static int dm_integrity_ctr(struct dm_ta + goto bad; + } + ++ r = mempool_init_page_pool(&ic->recheck_pool, 1, 0); ++ if (r) { ++ ti->error = "Cannot allocate mempool"; ++ goto bad; ++ } ++ + ic->metadata_wq = alloc_workqueue("dm-integrity-metadata", + WQ_MEM_RECLAIM, METADATA_WORKQUEUE_MAX_ACTIVE); + if (!ic->metadata_wq) { +@@ -4572,6 +4646,7 @@ static void dm_integrity_dtr(struct dm_t + kvfree(ic->bbs); + if (ic->bufio) + dm_bufio_client_destroy(ic->bufio); ++ mempool_exit(&ic->recheck_pool); + mempool_exit(&ic->journal_io_mempool); + if (ic->io) + dm_io_client_destroy(ic->io); diff --git a/queue-6.1/dm-verity-recheck-the-hash-after-a-failure.patch b/queue-6.1/dm-verity-recheck-the-hash-after-a-failure.patch new file mode 100644 index 00000000000..3d260a8d47b --- /dev/null +++ b/queue-6.1/dm-verity-recheck-the-hash-after-a-failure.patch @@ -0,0 +1,189 @@ +From 9177f3c0dea6143d05cac1bbd28668fd0e216d11 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 19 Feb 2024 21:28:09 +0100 +Subject: dm-verity: recheck the hash after a failure + +From: Mikulas Patocka + +commit 9177f3c0dea6143d05cac1bbd28668fd0e216d11 upstream. + +If a userspace process reads (with O_DIRECT) multiple blocks into the same +buffer, dm-verity reports an error [1]. + +This commit fixes dm-verity, so that if hash verification fails, the data +is read again into a kernel buffer (where userspace can't modify it) and +the hash is rechecked. If the recheck succeeds, the content of the kernel +buffer is copied into the user buffer; if the recheck fails, an error is +reported. + +[1] https://people.redhat.com/~mpatocka/testcases/blk-auth-modify/read2.c + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-verity-target.c | 86 +++++++++++++++++++++++++++++++++++++++--- + drivers/md/dm-verity.h | 6 ++ + 2 files changed, 86 insertions(+), 6 deletions(-) + +--- a/drivers/md/dm-verity-target.c ++++ b/drivers/md/dm-verity-target.c +@@ -474,6 +474,63 @@ int verity_for_bv_block(struct dm_verity + return 0; + } + ++static int verity_recheck_copy(struct dm_verity *v, struct dm_verity_io *io, ++ u8 *data, size_t len) ++{ ++ memcpy(data, io->recheck_buffer, len); ++ io->recheck_buffer += len; ++ ++ return 0; ++} ++ ++static int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, ++ struct bvec_iter start, sector_t cur_block) ++{ ++ struct page *page; ++ void *buffer; ++ int r; ++ struct dm_io_request io_req; ++ struct dm_io_region io_loc; ++ ++ page = mempool_alloc(&v->recheck_pool, GFP_NOIO); ++ buffer = page_to_virt(page); ++ ++ io_req.bi_opf = REQ_OP_READ; ++ io_req.mem.type = DM_IO_KMEM; ++ io_req.mem.ptr.addr = buffer; ++ io_req.notify.fn = NULL; ++ io_req.client = v->io; ++ io_loc.bdev = v->data_dev->bdev; ++ io_loc.sector = cur_block << (v->data_dev_block_bits - SECTOR_SHIFT); ++ io_loc.count = 1 << (v->data_dev_block_bits - SECTOR_SHIFT); ++ r = dm_io(&io_req, 1, &io_loc, NULL); ++ if (unlikely(r)) ++ goto free_ret; ++ ++ r = verity_hash(v, verity_io_hash_req(v, io), buffer, ++ 1 << v->data_dev_block_bits, ++ verity_io_real_digest(v, io), true); ++ if (unlikely(r)) ++ goto free_ret; ++ ++ if (memcmp(verity_io_real_digest(v, io), ++ verity_io_want_digest(v, io), v->digest_size)) { ++ r = -EIO; ++ goto free_ret; ++ } ++ ++ io->recheck_buffer = buffer; ++ r = verity_for_bv_block(v, io, &start, verity_recheck_copy); ++ if (unlikely(r)) ++ goto free_ret; ++ ++ r = 0; ++free_ret: ++ mempool_free(page, &v->recheck_pool); ++ ++ return r; ++} ++ + static int verity_bv_zero(struct dm_verity *v, struct dm_verity_io *io, + u8 *data, size_t len) + { +@@ -500,9 +557,7 @@ static int verity_verify_io(struct dm_ve + { + bool is_zero; + struct dm_verity *v = io->v; +-#if defined(CONFIG_DM_VERITY_FEC) + struct bvec_iter start; +-#endif + struct bvec_iter iter_copy; + struct bvec_iter *iter; + struct crypto_wait wait; +@@ -553,10 +608,7 @@ static int verity_verify_io(struct dm_ve + if (unlikely(r < 0)) + return r; + +-#if defined(CONFIG_DM_VERITY_FEC) +- if (verity_fec_is_enabled(v)) +- start = *iter; +-#endif ++ start = *iter; + r = verity_for_io_block(v, io, iter, &wait); + if (unlikely(r < 0)) + return r; +@@ -578,6 +630,10 @@ static int verity_verify_io(struct dm_ve + * tasklet since it may sleep, so fallback to work-queue. + */ + return -EAGAIN; ++ } else if (verity_recheck(v, io, start, cur_block) == 0) { ++ if (v->validated_blocks) ++ set_bit(cur_block, v->validated_blocks); ++ continue; + #if defined(CONFIG_DM_VERITY_FEC) + } else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, + cur_block, NULL, &start) == 0) { +@@ -928,6 +984,10 @@ static void verity_dtr(struct dm_target + if (v->verify_wq) + destroy_workqueue(v->verify_wq); + ++ mempool_exit(&v->recheck_pool); ++ if (v->io) ++ dm_io_client_destroy(v->io); ++ + if (v->bufio) + dm_bufio_client_destroy(v->bufio); + +@@ -1364,6 +1424,20 @@ static int verity_ctr(struct dm_target * + } + v->hash_blocks = hash_position; + ++ r = mempool_init_page_pool(&v->recheck_pool, 1, 0); ++ if (unlikely(r)) { ++ ti->error = "Cannot allocate mempool"; ++ goto bad; ++ } ++ ++ v->io = dm_io_client_create(); ++ if (IS_ERR(v->io)) { ++ r = PTR_ERR(v->io); ++ v->io = NULL; ++ ti->error = "Cannot allocate dm io"; ++ goto bad; ++ } ++ + v->bufio = dm_bufio_client_create(v->hash_dev->bdev, + 1 << v->hash_dev_block_bits, 1, sizeof(struct buffer_aux), + dm_bufio_alloc_callback, NULL, +--- a/drivers/md/dm-verity.h ++++ b/drivers/md/dm-verity.h +@@ -11,6 +11,7 @@ + #ifndef DM_VERITY_H + #define DM_VERITY_H + ++#include + #include + #include + #include +@@ -68,6 +69,9 @@ struct dm_verity { + unsigned long *validated_blocks; /* bitset blocks validated */ + + char *signature_key_desc; /* signature keyring reference */ ++ ++ struct dm_io_client *io; ++ mempool_t recheck_pool; + }; + + struct dm_verity_io { +@@ -84,6 +88,8 @@ struct dm_verity_io { + + struct work_struct work; + ++ char *recheck_buffer; ++ + /* + * Three variably-size fields follow this struct: + * diff --git a/queue-6.1/drm-ttm-fix-an-invalid-freeing-on-already-freed-page-in-error-path.patch b/queue-6.1/drm-ttm-fix-an-invalid-freeing-on-already-freed-page-in-error-path.patch new file mode 100644 index 00000000000..be951dc2c11 --- /dev/null +++ b/queue-6.1/drm-ttm-fix-an-invalid-freeing-on-already-freed-page-in-error-path.patch @@ -0,0 +1,49 @@ +From 40510a941d27d405a82dc3320823d875f94625df Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= +Date: Wed, 21 Feb 2024 08:33:24 +0100 +Subject: drm/ttm: Fix an invalid freeing on already freed page in error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Hellström + +commit 40510a941d27d405a82dc3320823d875f94625df upstream. + +If caching mode change fails due to, for example, OOM we +free the allocated pages in a two-step process. First the pages +for which the caching change has already succeeded. Secondly +the pages for which a caching change did not succeed. + +However the second step was incorrectly freeing the pages already +freed in the first step. + +Fix. + +Signed-off-by: Thomas Hellström +Fixes: 379989e7cbdc ("drm/ttm/pool: Fix ttm_pool_alloc error path") +Cc: Christian König +Cc: Dave Airlie +Cc: Christian Koenig +Cc: Huang Rui +Cc: dri-devel@lists.freedesktop.org +Cc: # v6.4+ +Reviewed-by: Matthew Auld +Reviewed-by: Christian König +Link: https://patchwork.freedesktop.org/patch/msgid/20240221073324.3303-1-thomas.hellstrom@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ttm/ttm_pool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/ttm/ttm_pool.c ++++ b/drivers/gpu/drm/ttm/ttm_pool.c +@@ -383,7 +383,7 @@ static void ttm_pool_free_range(struct t + enum ttm_caching caching, + pgoff_t start_page, pgoff_t end_page) + { +- struct page **pages = tt->pages; ++ struct page **pages = &tt->pages[start_page]; + unsigned int order; + pgoff_t i, nr; + diff --git a/queue-6.1/gtp-fix-use-after-free-and-null-ptr-deref-in-gtp_genl_dump_pdp.patch b/queue-6.1/gtp-fix-use-after-free-and-null-ptr-deref-in-gtp_genl_dump_pdp.patch new file mode 100644 index 00000000000..76b5eadb9e0 --- /dev/null +++ b/queue-6.1/gtp-fix-use-after-free-and-null-ptr-deref-in-gtp_genl_dump_pdp.patch @@ -0,0 +1,97 @@ +From 136cfaca22567a03bbb3bf53a43d8cb5748b80ec Mon Sep 17 00:00:00 2001 +From: Vasiliy Kovalev +Date: Wed, 14 Feb 2024 19:27:33 +0300 +Subject: gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp() + +From: Vasiliy Kovalev + +commit 136cfaca22567a03bbb3bf53a43d8cb5748b80ec upstream. + +The gtp_net_ops pernet operations structure for the subsystem must be +registered before registering the generic netlink family. + +Syzkaller hit 'general protection fault in gtp_genl_dump_pdp' bug: + +general protection fault, probably for non-canonical address +0xdffffc0000000002: 0000 [#1] PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] +CPU: 1 PID: 5826 Comm: gtp Not tainted 6.8.0-rc3-std-def-alt1 #1 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-alt1 04/01/2014 +RIP: 0010:gtp_genl_dump_pdp+0x1be/0x800 [gtp] +Code: c6 89 c6 e8 64 e9 86 df 58 45 85 f6 0f 85 4e 04 00 00 e8 c5 ee 86 + df 48 8b 54 24 18 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> + 3c 02 00 0f 85 de 05 00 00 48 8b 44 24 18 4c 8b 30 4c 39 f0 74 +RSP: 0018:ffff888014107220 EFLAGS: 00010202 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000 +RDX: 0000000000000002 RSI: 0000000000000000 RDI: 0000000000000000 +RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: ffff88800fcda588 R14: 0000000000000001 R15: 0000000000000000 +FS: 00007f1be4eb05c0(0000) GS:ffff88806ce80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f1be4e766cf CR3: 000000000c33e000 CR4: 0000000000750ef0 +PKRU: 55555554 +Call Trace: + + ? show_regs+0x90/0xa0 + ? die_addr+0x50/0xd0 + ? exc_general_protection+0x148/0x220 + ? asm_exc_general_protection+0x22/0x30 + ? gtp_genl_dump_pdp+0x1be/0x800 [gtp] + ? __alloc_skb+0x1dd/0x350 + ? __pfx___alloc_skb+0x10/0x10 + genl_dumpit+0x11d/0x230 + netlink_dump+0x5b9/0xce0 + ? lockdep_hardirqs_on_prepare+0x253/0x430 + ? __pfx_netlink_dump+0x10/0x10 + ? kasan_save_track+0x10/0x40 + ? __kasan_kmalloc+0x9b/0xa0 + ? genl_start+0x675/0x970 + __netlink_dump_start+0x6fc/0x9f0 + genl_family_rcv_msg_dumpit+0x1bb/0x2d0 + ? __pfx_genl_family_rcv_msg_dumpit+0x10/0x10 + ? genl_op_from_small+0x2a/0x440 + ? cap_capable+0x1d0/0x240 + ? __pfx_genl_start+0x10/0x10 + ? __pfx_genl_dumpit+0x10/0x10 + ? __pfx_genl_done+0x10/0x10 + ? security_capable+0x9d/0xe0 + +Cc: stable@vger.kernel.org +Signed-off-by: Vasiliy Kovalev +Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") +Link: https://lore.kernel.org/r/20240214162733.34214-1-kovalev@altlinux.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/gtp.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1906,20 +1906,20 @@ static int __init gtp_init(void) + if (err < 0) + goto error_out; + +- err = genl_register_family(>p_genl_family); ++ err = register_pernet_subsys(>p_net_ops); + if (err < 0) + goto unreg_rtnl_link; + +- err = register_pernet_subsys(>p_net_ops); ++ err = genl_register_family(>p_genl_family); + if (err < 0) +- goto unreg_genl_family; ++ goto unreg_pernet_subsys; + + pr_info("GTP module loaded (pdp ctx size %zd bytes)\n", + sizeof(struct pdp_ctx)); + return 0; + +-unreg_genl_family: +- genl_unregister_family(>p_genl_family); ++unreg_pernet_subsys: ++ unregister_pernet_subsys(>p_net_ops); + unreg_rtnl_link: + rtnl_link_unregister(>p_link_ops); + error_out: diff --git a/queue-6.1/irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch b/queue-6.1/irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch new file mode 100644 index 00000000000..168a163b39b --- /dev/null +++ b/queue-6.1/irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch @@ -0,0 +1,55 @@ +From ec4308ecfc887128a468f03fb66b767559c57c23 Mon Sep 17 00:00:00 2001 +From: Oliver Upton +Date: Mon, 19 Feb 2024 18:58:06 +0000 +Subject: irqchip/gic-v3-its: Do not assume vPE tables are preallocated + +From: Oliver Upton + +commit ec4308ecfc887128a468f03fb66b767559c57c23 upstream. + +The GIC/ITS code is designed to ensure to pick up any preallocated LPI +tables on the redistributors, as enabling LPIs is a one-way switch. There +is no such restriction for vLPIs, and for GICv4.1 it is expected to +allocate a new vPE table at boot. + +This works as intended when initializing an ITS, however when setting up a +redistributor in cpu_init_lpis() the early return for preallocated RD +tables skips straight past the GICv4 setup. This all comes to a head when +trying to kexec() into a new kernel, as the new kernel silently fails to +set up GICv4, leading to a complete loss of SGIs and LPIs for KVM VMs. + +Slap a band-aid on the problem by ensuring its_cpu_init_lpis() always +initializes GICv4 on the way out, even if the other RD tables were +preallocated. + +Fixes: 6479450f72c1 ("irqchip/gic-v4: Fix occasional VLPI drop") +Reported-by: George Cherian +Co-developed-by: Marc Zyngier +Signed-off-by: Marc Zyngier +Signed-off-by: Oliver Upton +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240219185809.286724-2-oliver.upton@linux.dev +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-gic-v3-its.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -3161,6 +3161,7 @@ static void its_cpu_init_lpis(void) + val |= GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + ++out: + if (gic_rdists->has_vlpis && !gic_rdists->has_rvpeid) { + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); + +@@ -3196,7 +3197,6 @@ static void its_cpu_init_lpis(void) + + /* Make sure the GIC has seen the above */ + dsb(sy); +-out: + gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED; + pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", + smp_processor_id(), diff --git a/queue-6.1/irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch b/queue-6.1/irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch new file mode 100644 index 00000000000..5cc092c68f5 --- /dev/null +++ b/queue-6.1/irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch @@ -0,0 +1,69 @@ +From 9c92006b896c767218aabe8947b62026a571cfd0 Mon Sep 17 00:00:00 2001 +From: Nam Cao +Date: Wed, 31 Jan 2024 09:19:33 +0100 +Subject: irqchip/sifive-plic: Enable interrupt if needed before EOI + +From: Nam Cao + +commit 9c92006b896c767218aabe8947b62026a571cfd0 upstream. + +RISC-V PLIC cannot "end-of-interrupt" (EOI) disabled interrupts, as +explained in the description of Interrupt Completion in the PLIC spec: + +"The PLIC signals it has completed executing an interrupt handler by +writing the interrupt ID it received from the claim to the claim/complete +register. The PLIC does not check whether the completion ID is the same +as the last claim ID for that target. If the completion ID does not match +an interrupt source that *is currently enabled* for the target, the +completion is silently ignored." + +Commit 69ea463021be ("irqchip/sifive-plic: Fixup EOI failed when masked") +ensured that EOI is successful by enabling interrupt first, before EOI. + +Commit a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask +operations") removed the interrupt enabling code from the previous +commit, because it assumes that interrupt should already be enabled at the +point of EOI. + +However, this is incorrect: there is a window after a hart claiming an +interrupt and before irq_desc->lock getting acquired, interrupt can be +disabled during this window. Thus, EOI can be invoked while the interrupt +is disabled, effectively nullify this EOI. This results in the interrupt +never gets asserted again, and the device who uses this interrupt appears +frozen. + +Make sure that interrupt is really enabled before EOI. + +Fixes: a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask operations") +Signed-off-by: Nam Cao +Signed-off-by: Thomas Gleixner +Cc: Palmer Dabbelt +Cc: Paul Walmsley +Cc: Samuel Holland +Cc: Marc Zyngier +Cc: Guo Ren +Cc: linux-riscv@lists.infradead.org +Cc: +Link: https://lore.kernel.org/r/20240131081933.144512-1-namcao@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-sifive-plic.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-sifive-plic.c ++++ b/drivers/irqchip/irq-sifive-plic.c +@@ -144,7 +144,13 @@ static void plic_irq_eoi(struct irq_data + { + struct plic_handler *handler = this_cpu_ptr(&plic_handlers); + +- writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); ++ if (unlikely(irqd_irq_disabled(d))) { ++ plic_toggle(handler, d->hwirq, 1); ++ writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); ++ plic_toggle(handler, d->hwirq, 0); ++ } else { ++ writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); ++ } + } + + #ifdef CONFIG_SMP diff --git a/queue-6.1/kvm-arm64-vgic-its-test-for-valid-irq-in-its_sync_lpi_pending_table.patch b/queue-6.1/kvm-arm64-vgic-its-test-for-valid-irq-in-its_sync_lpi_pending_table.patch new file mode 100644 index 00000000000..20f1b4aae33 --- /dev/null +++ b/queue-6.1/kvm-arm64-vgic-its-test-for-valid-irq-in-its_sync_lpi_pending_table.patch @@ -0,0 +1,36 @@ +From 8d3a7dfb801d157ac423261d7cd62c33e95375f8 Mon Sep 17 00:00:00 2001 +From: Oliver Upton +Date: Wed, 21 Feb 2024 09:27:31 +0000 +Subject: KVM: arm64: vgic-its: Test for valid IRQ in its_sync_lpi_pending_table() + +From: Oliver Upton + +commit 8d3a7dfb801d157ac423261d7cd62c33e95375f8 upstream. + +vgic_get_irq() may not return a valid descriptor if there is no ITS that +holds a valid translation for the specified INTID. If that is the case, +it is safe to silently ignore it and continue processing the LPI pending +table. + +Cc: stable@vger.kernel.org +Fixes: 33d3bc9556a7 ("KVM: arm64: vgic-its: Read initial LPI pending table") +Signed-off-by: Oliver Upton +Link: https://lore.kernel.org/r/20240221092732.4126848-2-oliver.upton@linux.dev +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/vgic/vgic-its.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -462,6 +462,9 @@ static int its_sync_lpi_pending_table(st + } + + irq = vgic_get_irq(vcpu->kvm, NULL, intids[i]); ++ if (!irq) ++ continue; ++ + raw_spin_lock_irqsave(&irq->irq_lock, flags); + irq->pending_latch = pendmask & (1U << bit_nr); + vgic_queue_irq_unlock(vcpu->kvm, irq, flags); diff --git a/queue-6.1/kvm-arm64-vgic-its-test-for-valid-irq-in-movall-handler.patch b/queue-6.1/kvm-arm64-vgic-its-test-for-valid-irq-in-movall-handler.patch new file mode 100644 index 00000000000..e7e7b71f0ef --- /dev/null +++ b/queue-6.1/kvm-arm64-vgic-its-test-for-valid-irq-in-movall-handler.patch @@ -0,0 +1,35 @@ +From 85a71ee9a0700f6c18862ef3b0011ed9dad99aca Mon Sep 17 00:00:00 2001 +From: Oliver Upton +Date: Wed, 21 Feb 2024 09:27:32 +0000 +Subject: KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler + +From: Oliver Upton + +commit 85a71ee9a0700f6c18862ef3b0011ed9dad99aca upstream. + +It is possible that an LPI mapped in a different ITS gets unmapped while +handling the MOVALL command. If that is the case, there is no state that +can be migrated to the destination. Silently ignore it and continue +migrating other LPIs. + +Cc: stable@vger.kernel.org +Fixes: ff9c114394aa ("KVM: arm/arm64: GICv4: Handle MOVALL applied to a vPE") +Signed-off-by: Oliver Upton +Link: https://lore.kernel.org/r/20240221092732.4126848-3-oliver.upton@linux.dev +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/vgic/vgic-its.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm64/kvm/vgic/vgic-its.c ++++ b/arch/arm64/kvm/vgic/vgic-its.c +@@ -1427,6 +1427,8 @@ static int vgic_its_cmd_handle_movall(st + + for (i = 0; i < irq_count; i++) { + irq = vgic_get_irq(kvm, NULL, intids[i]); ++ if (!irq) ++ continue; + + update_affinity(irq, vcpu2); + diff --git a/queue-6.1/l2tp-pass-correct-message-length-to-ip6_append_data.patch b/queue-6.1/l2tp-pass-correct-message-length-to-ip6_append_data.patch new file mode 100644 index 00000000000..a37d756f55e --- /dev/null +++ b/queue-6.1/l2tp-pass-correct-message-length-to-ip6_append_data.patch @@ -0,0 +1,50 @@ +From 359e54a93ab43d32ee1bff3c2f9f10cb9f6b6e79 Mon Sep 17 00:00:00 2001 +From: Tom Parkin +Date: Tue, 20 Feb 2024 12:21:56 +0000 +Subject: l2tp: pass correct message length to ip6_append_data + +From: Tom Parkin + +commit 359e54a93ab43d32ee1bff3c2f9f10cb9f6b6e79 upstream. + +l2tp_ip6_sendmsg needs to avoid accounting for the transport header +twice when splicing more data into an already partially-occupied skbuff. + +To manage this, we check whether the skbuff contains data using +skb_queue_empty when deciding how much data to append using +ip6_append_data. + +However, the code which performed the calculation was incorrect: + + ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; + +...due to C operator precedence, this ends up setting ulen to +transhdrlen for messages with a non-zero length, which results in +corrupted packets on the wire. + +Add parentheses to correct the calculation in line with the original +intent. + +Fixes: 9d4c75800f61 ("ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data()") +Cc: David Howells +Cc: stable@vger.kernel.org +Signed-off-by: Tom Parkin +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240220122156.43131-1-tparkin@katalix.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ip6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -630,7 +630,7 @@ static int l2tp_ip6_sendmsg(struct sock + + back_from_confirm: + lock_sock(sk); +- ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; ++ ulen = len + (skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0); + err = ip6_append_data(sk, ip_generic_getfrag, msg, + ulen, transhdrlen, &ipc6, + &fl6, (struct rt6_info *)dst, diff --git a/queue-6.1/loongarch-disable-irq-before-init_fn-for-nonboot-cpus.patch b/queue-6.1/loongarch-disable-irq-before-init_fn-for-nonboot-cpus.patch new file mode 100644 index 00000000000..1ce06d613ef --- /dev/null +++ b/queue-6.1/loongarch-disable-irq-before-init_fn-for-nonboot-cpus.patch @@ -0,0 +1,74 @@ +From 1001db6c42e4012b55e5ee19405490f23e033b5a Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Fri, 23 Feb 2024 14:36:31 +0800 +Subject: LoongArch: Disable IRQ before init_fn() for nonboot CPUs + +From: Huacai Chen + +commit 1001db6c42e4012b55e5ee19405490f23e033b5a upstream. + +Disable IRQ before init_fn() for nonboot CPUs when hotplug, in order to +silence such warnings (and also avoid potential errors due to unexpected +interrupts): + +WARNING: CPU: 1 PID: 0 at kernel/rcu/tree.c:4503 rcu_cpu_starting+0x214/0x280 +CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.6.17+ #1198 +pc 90000000048e3334 ra 90000000047bd56c tp 900000010039c000 sp 900000010039fdd0 +a0 0000000000000001 a1 0000000000000006 a2 900000000802c040 a3 0000000000000000 +a4 0000000000000001 a5 0000000000000004 a6 0000000000000000 a7 90000000048e3f4c +t0 0000000000000001 t1 9000000005c70968 t2 0000000004000000 t3 000000000005e56e +t4 00000000000002e4 t5 0000000000001000 t6 ffffffff80000000 t7 0000000000040000 +t8 9000000007931638 u0 0000000000000006 s9 0000000000000004 s0 0000000000000001 +s1 9000000006356ac0 s2 9000000007244000 s3 0000000000000001 s4 0000000000000001 +s5 900000000636f000 s6 7fffffffffffffff s7 9000000002123940 s8 9000000001ca55f8 + ra: 90000000047bd56c tlb_init+0x24c/0x528 + ERA: 90000000048e3334 rcu_cpu_starting+0x214/0x280 + CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE) + PRMD: 00000000 (PPLV0 -PIE -PWE) + EUEN: 00000000 (-FPE -SXE -ASXE -BTE) + ECFG: 00071000 (LIE=12 VS=7) +ESTAT: 000c0000 [BRK] (IS= ECode=12 EsubCode=0) + PRID: 0014c010 (Loongson-64bit, Loongson-3A5000) +CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.6.17+ #1198 +Stack : 0000000000000000 9000000006375000 9000000005b61878 900000010039c000 + 900000010039fa30 0000000000000000 900000010039fa38 900000000619a140 + 9000000006456888 9000000006456880 900000010039f950 0000000000000001 + 0000000000000001 cb0cb028ec7e52e1 0000000002b90000 9000000100348700 + 0000000000000000 0000000000000001 ffffffff916d12f1 0000000000000003 + 0000000000040000 9000000007930370 0000000002b90000 0000000000000004 + 9000000006366000 900000000619a140 0000000000000000 0000000000000004 + 0000000000000000 0000000000000009 ffffffffffc681f2 9000000002123940 + 9000000001ca55f8 9000000006366000 90000000047a4828 00007ffff057ded8 + 00000000000000b0 0000000000000000 0000000000000000 0000000000071000 + ... +Call Trace: +[<90000000047a4828>] show_stack+0x48/0x1a0 +[<9000000005b61874>] dump_stack_lvl+0x84/0xcc +[<90000000047f60ac>] __warn+0x8c/0x1e0 +[<9000000005b0ab34>] report_bug+0x1b4/0x280 +[<9000000005b63110>] do_bp+0x2d0/0x480 +[<90000000047a2e20>] handle_bp+0x120/0x1c0 +[<90000000048e3334>] rcu_cpu_starting+0x214/0x280 +[<90000000047bd568>] tlb_init+0x248/0x528 +[<90000000047a4c44>] per_cpu_trap_init+0x124/0x160 +[<90000000047a19f4>] cpu_probe+0x494/0xa00 +[<90000000047b551c>] start_secondary+0x3c/0xc0 +[<9000000005b66134>] smpboot_entry+0x50/0x58 + +Cc: stable@vger.kernel.org +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/loongarch/kernel/smp.c ++++ b/arch/loongarch/kernel/smp.c +@@ -297,6 +297,7 @@ void play_dead(void) + addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0); + } while (addr == 0); + ++ local_irq_disable(); + init_fn = (void *)TO_CACHE(addr); + iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR); + diff --git a/queue-6.1/md-fix-missing-release-of-active_io-for-flush.patch b/queue-6.1/md-fix-missing-release-of-active_io-for-flush.patch new file mode 100644 index 00000000000..bbbfb928fb5 --- /dev/null +++ b/queue-6.1/md-fix-missing-release-of-active_io-for-flush.patch @@ -0,0 +1,58 @@ +From 855678ed8534518e2b428bcbcec695de9ba248e8 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Thu, 1 Feb 2024 17:25:51 +0800 +Subject: md: Fix missing release of 'active_io' for flush + +From: Yu Kuai + +commit 855678ed8534518e2b428bcbcec695de9ba248e8 upstream. + +submit_flushes + atomic_set(&mddev->flush_pending, 1); + rdev_for_each_rcu(rdev, mddev) + atomic_inc(&mddev->flush_pending); + bi->bi_end_io = md_end_flush + submit_bio(bi); + /* flush io is done first */ + md_end_flush + if (atomic_dec_and_test(&mddev->flush_pending)) + percpu_ref_put(&mddev->active_io) + -> active_io is not released + + if (atomic_dec_and_test(&mddev->flush_pending)) + -> missing release of active_io + +For consequence, mddev_suspend() will wait for 'active_io' to be zero +forever. + +Fix this problem by releasing 'active_io' in submit_flushes() if +'flush_pending' is decreased to zero. + +Fixes: fa2bbff7b0b4 ("md: synchronize flush io with array reconfiguration") +Cc: stable@vger.kernel.org # v6.1+ +Reported-by: Blazej Kucman +Closes: https://lore.kernel.org/lkml/20240130172524.0000417b@linux.intel.com/ +Signed-off-by: Yu Kuai +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20240201092559.910982-7-yukuai1@huaweicloud.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/md.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -564,8 +564,12 @@ static void submit_flushes(struct work_s + rcu_read_lock(); + } + rcu_read_unlock(); +- if (atomic_dec_and_test(&mddev->flush_pending)) ++ if (atomic_dec_and_test(&mddev->flush_pending)) { ++ /* The pair is percpu_ref_get() from md_flush_request() */ ++ percpu_ref_put(&mddev->active_io); ++ + queue_work(md_wq, &mddev->flush_work); ++ } + } + + static void md_submit_flush_data(struct work_struct *ws) diff --git a/queue-6.1/mm-damon-lru_sort-fix-quota-status-loss-due-to-online-tunings.patch b/queue-6.1/mm-damon-lru_sort-fix-quota-status-loss-due-to-online-tunings.patch new file mode 100644 index 00000000000..646244f4b31 --- /dev/null +++ b/queue-6.1/mm-damon-lru_sort-fix-quota-status-loss-due-to-online-tunings.patch @@ -0,0 +1,101 @@ +From 13d0599ab3b2ff17f798353f24bcbef1659d3cfc Mon Sep 17 00:00:00 2001 +From: SeongJae Park +Date: Fri, 16 Feb 2024 11:40:25 -0800 +Subject: mm/damon/lru_sort: fix quota status loss due to online tunings + +From: SeongJae Park + +commit 13d0599ab3b2ff17f798353f24bcbef1659d3cfc upstream. + +For online parameters change, DAMON_LRU_SORT creates new schemes based on +latest values of the parameters and replaces the old schemes with the new +one. When creating it, the internal status of the quotas of the old +schemes is not preserved. As a result, charging of the quota starts from +zero after the online tuning. The data that collected to estimate the +throughput of the scheme's action is also reset, and therefore the +estimation should start from the scratch again. Because the throughput +estimation is being used to convert the time quota to the effective size +quota, this could result in temporal time quota inaccuracy. It would be +recovered over time, though. In short, the quota accuracy could be +temporarily degraded after online parameters update. + +Fix the problem by checking the case and copying the internal fields for +the status. + +Link: https://lkml.kernel.org/r/20240216194025.9207-3-sj@kernel.org +Fixes: 40e983cca927 ("mm/damon: introduce DAMON-based LRU-lists Sorting") +Signed-off-by: SeongJae Park +Cc: [6.0+] +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/damon/lru_sort.c | 43 ++++++++++++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 7 deletions(-) + +--- a/mm/damon/lru_sort.c ++++ b/mm/damon/lru_sort.c +@@ -185,9 +185,21 @@ static struct damos *damon_lru_sort_new_ + return damon_lru_sort_new_scheme(&pattern, DAMOS_LRU_DEPRIO); + } + ++static void damon_lru_sort_copy_quota_status(struct damos_quota *dst, ++ struct damos_quota *src) ++{ ++ dst->total_charged_sz = src->total_charged_sz; ++ dst->total_charged_ns = src->total_charged_ns; ++ dst->charged_sz = src->charged_sz; ++ dst->charged_from = src->charged_from; ++ dst->charge_target_from = src->charge_target_from; ++ dst->charge_addr_from = src->charge_addr_from; ++} ++ + static int damon_lru_sort_apply_parameters(void) + { +- struct damos *scheme; ++ struct damos *scheme, *hot_scheme, *cold_scheme; ++ struct damos *old_hot_scheme = NULL, *old_cold_scheme = NULL; + unsigned int hot_thres, cold_thres; + int err = 0; + +@@ -195,18 +207,35 @@ static int damon_lru_sort_apply_paramete + if (err) + return err; + ++ damon_for_each_scheme(scheme, ctx) { ++ if (!old_hot_scheme) { ++ old_hot_scheme = scheme; ++ continue; ++ } ++ old_cold_scheme = scheme; ++ } ++ + hot_thres = damon_max_nr_accesses(&damon_lru_sort_mon_attrs) * + hot_thres_access_freq / 1000; +- scheme = damon_lru_sort_new_hot_scheme(hot_thres); +- if (!scheme) ++ hot_scheme = damon_lru_sort_new_hot_scheme(hot_thres); ++ if (!hot_scheme) + return -ENOMEM; +- damon_set_schemes(ctx, &scheme, 1); ++ if (old_hot_scheme) ++ damon_lru_sort_copy_quota_status(&hot_scheme->quota, ++ &old_hot_scheme->quota); + + cold_thres = cold_min_age / damon_lru_sort_mon_attrs.aggr_interval; +- scheme = damon_lru_sort_new_cold_scheme(cold_thres); +- if (!scheme) ++ cold_scheme = damon_lru_sort_new_cold_scheme(cold_thres); ++ if (!cold_scheme) { ++ damon_destroy_scheme(hot_scheme); + return -ENOMEM; +- damon_add_scheme(ctx, scheme); ++ } ++ if (old_cold_scheme) ++ damon_lru_sort_copy_quota_status(&cold_scheme->quota, ++ &old_cold_scheme->quota); ++ ++ damon_set_schemes(ctx, &hot_scheme, 1); ++ damon_add_scheme(ctx, cold_scheme); + + return damon_set_region_biggest_system_ram_default(target, + &monitor_region_start, diff --git a/queue-6.1/mm-memcontrol-clarify-swapaccount-0-deprecation-warning.patch b/queue-6.1/mm-memcontrol-clarify-swapaccount-0-deprecation-warning.patch new file mode 100644 index 00000000000..58ffa6ab8e4 --- /dev/null +++ b/queue-6.1/mm-memcontrol-clarify-swapaccount-0-deprecation-warning.patch @@ -0,0 +1,59 @@ +From 118642d7f606fc9b9c92ee611275420320290ffb Mon Sep 17 00:00:00 2001 +From: Johannes Weiner +Date: Tue, 13 Feb 2024 03:16:34 -0500 +Subject: mm: memcontrol: clarify swapaccount=0 deprecation warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Johannes Weiner + +commit 118642d7f606fc9b9c92ee611275420320290ffb upstream. + +The swapaccount deprecation warning is throwing false positives. Since we +deprecated the knob and defaulted to enabling, the only reports we've been +getting are from folks that set swapaccount=1. While this is a nice +affirmation that always-enabling was the right choice, we certainly don't +want to warn when users request the supported mode. + +Only warn when disabling is requested, and clarify the warning. + +[colin.i.king@gmail.com: spelling: "commdandline" -> "commandline"] + Link: https://lkml.kernel.org/r/20240215090544.1649201-1-colin.i.king@gmail.com +Link: https://lkml.kernel.org/r/20240213081634.3652326-1-hannes@cmpxchg.org +Fixes: b25806dcd3d5 ("mm: memcontrol: deprecate swapaccounting=0 mode") +Signed-off-by: Colin Ian King +Reported-by: "Jonas Schäfer" +Reported-by: Narcis Garcia +Suggested-by: Yosry Ahmed +Signed-off-by: Johannes Weiner +Reviewed-by: Yosry Ahmed +Acked-by: Michal Hocko +Acked-by: Shakeel Butt +Cc: Roman Gushchin +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/memcontrol.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -7517,9 +7517,13 @@ bool mem_cgroup_swap_full(struct folio * + + static int __init setup_swap_account(char *s) + { +- pr_warn_once("The swapaccount= commandline option is deprecated. " +- "Please report your usecase to linux-mm@kvack.org if you " +- "depend on this functionality.\n"); ++ bool res; ++ ++ if (!kstrtobool(s, &res) && !res) ++ pr_warn_once("The swapaccount=0 commandline option is deprecated " ++ "in favor of configuring swap control via cgroupfs. " ++ "Please report your usecase to linux-mm@kvack.org if you " ++ "depend on this functionality.\n"); + return 1; + } + __setup("swapaccount=", setup_swap_account); diff --git a/queue-6.1/mm-swap-fix-race-when-skipping-swapcache.patch b/queue-6.1/mm-swap-fix-race-when-skipping-swapcache.patch new file mode 100644 index 00000000000..f52871d70fa --- /dev/null +++ b/queue-6.1/mm-swap-fix-race-when-skipping-swapcache.patch @@ -0,0 +1,226 @@ +From 13ddaf26be324a7f951891ecd9ccd04466d27458 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 7 Feb 2024 02:25:59 +0800 +Subject: mm/swap: fix race when skipping swapcache + +From: Kairui Song + +commit 13ddaf26be324a7f951891ecd9ccd04466d27458 upstream. + +When skipping swapcache for SWP_SYNCHRONOUS_IO, if two or more threads +swapin the same entry at the same time, they get different pages (A, B). +Before one thread (T0) finishes the swapin and installs page (A) to the +PTE, another thread (T1) could finish swapin of page (B), swap_free the +entry, then swap out the possibly modified page reusing the same entry. +It breaks the pte_same check in (T0) because PTE value is unchanged, +causing ABA problem. Thread (T0) will install a stalled page (A) into the +PTE and cause data corruption. + +One possible callstack is like this: + +CPU0 CPU1 +---- ---- +do_swap_page() do_swap_page() with same entry + + +swap_read_folio() <- read to page A swap_read_folio() <- read to page B + +... set_pte_at() + swap_free() <- entry is free + + +pte_same() <- Check pass, PTE seems + unchanged, but page A + is stalled! +swap_free() <- page B content lost! +set_pte_at() <- staled page A installed! + +And besides, for ZRAM, swap_free() allows the swap device to discard the +entry content, so even if page (B) is not modified, if swap_read_folio() +on CPU0 happens later than swap_free() on CPU1, it may also cause data +loss. + +To fix this, reuse swapcache_prepare which will pin the swap entry using +the cache flag, and allow only one thread to swap it in, also prevent any +parallel code from putting the entry in the cache. Release the pin after +PT unlocked. + +Racers just loop and wait since it's a rare and very short event. A +schedule_timeout_uninterruptible(1) call is added to avoid repeated page +faults wasting too much CPU, causing livelock or adding too much noise to +perf statistics. A similar livelock issue was described in commit +029c4628b2eb ("mm: swap: get rid of livelock in swapin readahead") + +Reproducer: + +This race issue can be triggered easily using a well constructed +reproducer and patched brd (with a delay in read path) [1]: + +With latest 6.8 mainline, race caused data loss can be observed easily: +$ gcc -g -lpthread test-thread-swap-race.c && ./a.out + Polulating 32MB of memory region... + Keep swapping out... + Starting round 0... + Spawning 65536 workers... + 32746 workers spawned, wait for done... + Round 0: Error on 0x5aa00, expected 32746, got 32743, 3 data loss! + Round 0: Error on 0x395200, expected 32746, got 32743, 3 data loss! + Round 0: Error on 0x3fd000, expected 32746, got 32737, 9 data loss! + Round 0 Failed, 15 data loss! + +This reproducer spawns multiple threads sharing the same memory region +using a small swap device. Every two threads updates mapped pages one by +one in opposite direction trying to create a race, with one dedicated +thread keep swapping out the data out using madvise. + +The reproducer created a reproduce rate of about once every 5 minutes, so +the race should be totally possible in production. + +After this patch, I ran the reproducer for over a few hundred rounds and +no data loss observed. + +Performance overhead is minimal, microbenchmark swapin 10G from 32G +zram: + +Before: 10934698 us +After: 11157121 us +Cached: 13155355 us (Dropping SWP_SYNCHRONOUS_IO flag) + +[kasong@tencent.com: v4] + Link: https://lkml.kernel.org/r/20240219082040.7495-1-ryncsn@gmail.com +Link: https://lkml.kernel.org/r/20240206182559.32264-1-ryncsn@gmail.com +Fixes: 0bcac06f27d7 ("mm, swap: skip swapcache for swapin of synchronous device") +Reported-by: "Huang, Ying" +Closes: https://lore.kernel.org/lkml/87bk92gqpx.fsf_-_@yhuang6-desk2.ccr.corp.intel.com/ +Link: https://github.com/ryncsn/emm-test-project/tree/master/swap-stress-race [1] +Signed-off-by: Kairui Song +Reviewed-by: "Huang, Ying" +Acked-by: Yu Zhao +Acked-by: David Hildenbrand +Acked-by: Chris Li +Cc: Hugh Dickins +Cc: Johannes Weiner +Cc: Matthew Wilcox (Oracle) +Cc: Michal Hocko +Cc: Minchan Kim +Cc: Yosry Ahmed +Cc: Yu Zhao +Cc: Barry Song <21cnbao@gmail.com> +Cc: SeongJae Park +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/swap.h | 5 +++++ + mm/memory.c | 20 ++++++++++++++++++++ + mm/swap.h | 5 +++++ + mm/swapfile.c | 13 +++++++++++++ + 4 files changed, 43 insertions(+) + +--- a/include/linux/swap.h ++++ b/include/linux/swap.h +@@ -571,6 +571,11 @@ static inline int swap_duplicate(swp_ent + return 0; + } + ++static inline int swapcache_prepare(swp_entry_t swp) ++{ ++ return 0; ++} ++ + static inline void swap_free(swp_entry_t swp) + { + } +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -3761,6 +3761,7 @@ vm_fault_t do_swap_page(struct vm_fault + struct page *page; + struct swap_info_struct *si = NULL; + rmap_t rmap_flags = RMAP_NONE; ++ bool need_clear_cache = false; + bool exclusive = false; + swp_entry_t entry; + pte_t pte; +@@ -3822,6 +3823,20 @@ vm_fault_t do_swap_page(struct vm_fault + if (!folio) { + if (data_race(si->flags & SWP_SYNCHRONOUS_IO) && + __swap_count(entry) == 1) { ++ /* ++ * Prevent parallel swapin from proceeding with ++ * the cache flag. Otherwise, another thread may ++ * finish swapin first, free the entry, and swapout ++ * reusing the same entry. It's undetectable as ++ * pte_same() returns true due to entry reuse. ++ */ ++ if (swapcache_prepare(entry)) { ++ /* Relax a bit to prevent rapid repeated page faults */ ++ schedule_timeout_uninterruptible(1); ++ goto out; ++ } ++ need_clear_cache = true; ++ + /* skip swapcache */ + folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, + vma, vmf->address, false); +@@ -4073,6 +4088,9 @@ vm_fault_t do_swap_page(struct vm_fault + unlock: + pte_unmap_unlock(vmf->pte, vmf->ptl); + out: ++ /* Clear the swap cache pin for direct swapin after PTL unlock */ ++ if (need_clear_cache) ++ swapcache_clear(si, entry); + if (si) + put_swap_device(si); + return ret; +@@ -4086,6 +4104,8 @@ out_release: + folio_unlock(swapcache); + folio_put(swapcache); + } ++ if (need_clear_cache) ++ swapcache_clear(si, entry); + if (si) + put_swap_device(si); + return ret; +--- a/mm/swap.h ++++ b/mm/swap.h +@@ -39,6 +39,7 @@ void __delete_from_swap_cache(struct fol + void delete_from_swap_cache(struct folio *folio); + void clear_shadow_from_swap_cache(int type, unsigned long begin, + unsigned long end); ++void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry); + struct folio *swap_cache_get_folio(swp_entry_t entry, + struct vm_area_struct *vma, unsigned long addr); + struct page *find_get_incore_page(struct address_space *mapping, pgoff_t index); +@@ -98,6 +99,10 @@ static inline int swap_writepage(struct + return 0; + } + ++static inline void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry) ++{ ++} ++ + static inline struct folio *swap_cache_get_folio(swp_entry_t entry, + struct vm_area_struct *vma, unsigned long addr) + { +--- a/mm/swapfile.c ++++ b/mm/swapfile.c +@@ -3373,6 +3373,19 @@ int swapcache_prepare(swp_entry_t entry) + return __swap_duplicate(entry, SWAP_HAS_CACHE); + } + ++void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry) ++{ ++ struct swap_cluster_info *ci; ++ unsigned long offset = swp_offset(entry); ++ unsigned char usage; ++ ++ ci = lock_cluster_or_swap_info(si, offset); ++ usage = __swap_entry_free_locked(si, offset, SWAP_HAS_CACHE); ++ unlock_cluster_or_swap_info(si, ci); ++ if (!usage) ++ free_swap_slot(entry); ++} ++ + struct swap_info_struct *swp_swap_info(swp_entry_t entry) + { + return swap_type_to_swap_info(swp_type(entry)); diff --git a/queue-6.1/pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch b/queue-6.1/pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch new file mode 100644 index 00000000000..0e691f530c4 --- /dev/null +++ b/queue-6.1/pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch @@ -0,0 +1,46 @@ +From db744ddd59be798c2627efbfc71f707f5a935a40 Mon Sep 17 00:00:00 2001 +From: Vidya Sagar +Date: Mon, 15 Jan 2024 19:26:49 +0530 +Subject: PCI/MSI: Prevent MSI hardware interrupt number truncation + +From: Vidya Sagar + +commit db744ddd59be798c2627efbfc71f707f5a935a40 upstream. + +While calculating the hardware interrupt number for a MSI interrupt, the +higher bits (i.e. from bit-5 onwards a.k.a domain_nr >= 32) of the PCI +domain number gets truncated because of the shifted value casting to return +type of pci_domain_nr() which is 'int'. This for example is resulting in +same hardware interrupt number for devices 0019:00:00.0 and 0039:00:00.0. + +To address this cast the PCI domain number to 'irq_hw_number_t' before left +shifting it to calculate the hardware interrupt number. + +Please note that this fixes the issue only on 64-bit systems and doesn't +change the behavior for 32-bit systems i.e. the 32-bit systems continue to +have the issue. Since the issue surfaces only if there are too many PCIe +controllers in the system which usually is the case in modern server +systems and they don't tend to run 32-bit kernels. + +Fixes: 3878eaefb89a ("PCI/MSI: Enhance core to support hierarchy irqdomain") +Signed-off-by: Vidya Sagar +Signed-off-by: Thomas Gleixner +Tested-by: Shanker Donthineni +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240115135649.708536-1-vidyas@nvidia.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/msi/irqdomain.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/msi/irqdomain.c ++++ b/drivers/pci/msi/irqdomain.c +@@ -60,7 +60,7 @@ static irq_hw_number_t pci_msi_domain_ca + + return (irq_hw_number_t)desc->msi_index | + pci_dev_id(dev) << 11 | +- (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; ++ ((irq_hw_number_t)(pci_domain_nr(dev->bus) & 0xFFFFFFFF)) << 27; + } + + static inline bool pci_msi_desc_is_multi_msi(struct msi_desc *desc) diff --git a/queue-6.1/platform-x86-intel-vbtn-stop-calling-vbdl-from-notify_handler.patch b/queue-6.1/platform-x86-intel-vbtn-stop-calling-vbdl-from-notify_handler.patch new file mode 100644 index 00000000000..f1625e4ae81 --- /dev/null +++ b/queue-6.1/platform-x86-intel-vbtn-stop-calling-vbdl-from-notify_handler.patch @@ -0,0 +1,50 @@ +From 84c16d01ff219bc0a5dca5219db6b8b86a6854fb Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 16 Feb 2024 21:33:00 +0100 +Subject: platform/x86: intel-vbtn: Stop calling "VBDL" from notify_handler + +From: Hans de Goede + +commit 84c16d01ff219bc0a5dca5219db6b8b86a6854fb upstream. + +Commit 14c200b7ca46 ("platform/x86: intel-vbtn: Fix missing +tablet-mode-switch events") causes 2 issues on the ThinkPad X1 Tablet Gen2: + +1. The ThinkPad will wake up immediately from suspend +2. When put in tablet mode SW_TABLET_MODE reverts to 0 after about 1 second + +Both these issues are caused by the "VBDL" ACPI method call added +at the end of the notify_handler. + +And it never became entirely clear if this call is even necessary to fix +the issue of missing tablet-mode-switch events on the Dell Inspiron 7352. + +Drop the "VBDL" ACPI method call again to fix the 2 issues this is +causing on the ThinkPad X1 Tablet Gen2. + +Fixes: 14c200b7ca46 ("platform/x86: intel-vbtn: Fix missing tablet-mode-switch events") +Reported-by: Alexander Kobel +Closes: https://lore.kernel.org/platform-driver-x86/295984ce-bd4b-49bd-adc5-ffe7c898d7f0@a-kobel.de/ +Cc: regressions@lists.linux.dev +Cc: Arnold Gozum +Cc: stable@vger.kernel.org +Signed-off-by: Hans de Goede +Tested-by: Alexander Kobel +Link: https://lore.kernel.org/r/20240216203300.245826-1-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/platform/x86/intel/vbtn.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/platform/x86/intel/vbtn.c ++++ b/drivers/platform/x86/intel/vbtn.c +@@ -200,9 +200,6 @@ static void notify_handler(acpi_handle h + autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE); + + sparse_keymap_report_event(input_dev, event, val, autorelease); +- +- /* Some devices need this to report further events */ +- acpi_evaluate_object(handle, "VBDL", NULL, NULL); + } + + /* diff --git a/queue-6.1/platform-x86-touchscreen_dmi-allow-partial-prefix-matches-for-acpi-names.patch b/queue-6.1/platform-x86-touchscreen_dmi-allow-partial-prefix-matches-for-acpi-names.patch new file mode 100644 index 00000000000..4342aff8c04 --- /dev/null +++ b/queue-6.1/platform-x86-touchscreen_dmi-allow-partial-prefix-matches-for-acpi-names.patch @@ -0,0 +1,58 @@ +From dbcbfd662a725641d118fb3ae5ffb7be4e3d0fb0 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 12 Feb 2024 13:06:07 +0100 +Subject: platform/x86: touchscreen_dmi: Allow partial (prefix) matches for ACPI names + +From: Hans de Goede + +commit dbcbfd662a725641d118fb3ae5ffb7be4e3d0fb0 upstream. + +On some devices the ACPI name of the touchscreen is e.g. either +MSSL1680:00 or MSSL1680:01 depending on the BIOS version. + +This happens for example on the "Chuwi Hi8 Air" tablet where the initial +commit's ts_data uses "MSSL1680:00" but the tablets from the github issue +and linux-hardware.org probe linked below both use "MSSL1680:01". + +Replace the strcmp() match on ts_data->acpi_name with a strstarts() +check to allow using a partial match on just the ACPI HID of "MSSL1680" +and change the ts_data->acpi_name for the "Chuwi Hi8 Air" accordingly +to fix the touchscreen not working on models where it is "MSSL1680:01". + +Note this drops the length check for I2C_NAME_SIZE. This never was +necessary since the ACPI names used are never more then 11 chars and +I2C_NAME_SIZE is 20 so the replaced strncmp() would always stop long +before reaching I2C_NAME_SIZE. + +Link: https://linux-hardware.org/?computer=AC4301C0542A +Fixes: bbb97d728f77 ("platform/x86: touchscreen_dmi: Add info for the Chuwi Hi8 Air tablet") +Closes: https://github.com/onitake/gsl-firmware/issues/91 +Cc: stable@vger.kernel.org +Reviewed-by: Kuppuswamy Sathyanarayanan +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20240212120608.30469-1-hdegoede@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/platform/x86/touchscreen_dmi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -50,7 +50,7 @@ static const struct property_entry chuwi + }; + + static const struct ts_dmi_data chuwi_hi8_air_data = { +- .acpi_name = "MSSL1680:00", ++ .acpi_name = "MSSL1680", + .properties = chuwi_hi8_air_props, + }; + +@@ -1776,7 +1776,7 @@ static void ts_dmi_add_props(struct i2c_ + int error; + + if (has_acpi_companion(dev) && +- !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) { ++ strstarts(client->name, ts_data->acpi_name)) { + error = device_create_managed_software_node(dev, ts_data->properties, NULL); + if (error) + dev_err(dev, "failed to add properties: %d\n", error); diff --git a/queue-6.1/revert-parisc-only-list-existing-cpus-in-cpu_possible_mask.patch b/queue-6.1/revert-parisc-only-list-existing-cpus-in-cpu_possible_mask.patch new file mode 100644 index 00000000000..66d42c0887e --- /dev/null +++ b/queue-6.1/revert-parisc-only-list-existing-cpus-in-cpu_possible_mask.patch @@ -0,0 +1,57 @@ +From 82b143aeb169b8b55798d7d2063032e1a6ceeeb0 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Mon, 5 Feb 2024 10:39:20 +0100 +Subject: Revert "parisc: Only list existing CPUs in cpu_possible_mask" + +From: Helge Deller + +commit 82b143aeb169b8b55798d7d2063032e1a6ceeeb0 upstream. + +This reverts commit 0921244f6f4f0d05698b953fe632a99b38907226. + +It broke CPU hotplugging because it modifies the __cpu_possible_mask +after bootup, so that it will be different than nr_cpu_ids, which +then effictively breaks the workqueue setup code and triggers crashes +when shutting down CPUs at runtime. + +Guenter was the first who noticed the wrong values in __cpu_possible_mask, +since the cpumask Kunit tests were failig. + +Reverting this commit fixes both issues, but sadly brings back this +uncritical runtime warning: +register_cpu_capacity_sysctl: too early to get CPU4 device! + +Signed-off-by: Helge Deller +Reported-by: Guenter Roeck +Link: https://lkml.org/lkml/2024/2/4/146 +Link: https://lore.kernel.org/lkml/Zb0mbHlIud_bqftx@slm.duckdns.org/t/ +Cc: stable@vger.kernel.org # 6.0+ +Signed-off-by: Greg Kroah-Hartman +--- + arch/parisc/kernel/processor.c | 8 -------- + 1 file changed, 8 deletions(-) + +--- a/arch/parisc/kernel/processor.c ++++ b/arch/parisc/kernel/processor.c +@@ -171,7 +171,6 @@ static int __init processor_probe(struct + p->cpu_num = cpu_info.cpu_num; + p->cpu_loc = cpu_info.cpu_loc; + +- set_cpu_possible(cpuid, true); + store_cpu_topology(cpuid); + + #ifdef CONFIG_SMP +@@ -466,13 +465,6 @@ static struct parisc_driver cpu_driver _ + */ + void __init processor_init(void) + { +- unsigned int cpu; +- + reset_cpu_topology(); +- +- /* reset possible mask. We will mark those which are possible. */ +- for_each_possible_cpu(cpu) +- set_cpu_possible(cpu, false); +- + register_parisc_driver(&cpu_driver); + } diff --git a/queue-6.1/s390-cio-fix-invalid-ebusy-on-ccw_device_start.patch b/queue-6.1/s390-cio-fix-invalid-ebusy-on-ccw_device_start.patch new file mode 100644 index 00000000000..cfc5aca0108 --- /dev/null +++ b/queue-6.1/s390-cio-fix-invalid-ebusy-on-ccw_device_start.patch @@ -0,0 +1,99 @@ +From 5ef1dc40ffa6a6cb968b0fdc43c3a61727a9e950 Mon Sep 17 00:00:00 2001 +From: Peter Oberparleiter +Date: Wed, 14 Feb 2024 16:06:28 +0100 +Subject: s390/cio: fix invalid -EBUSY on ccw_device_start + +From: Peter Oberparleiter + +commit 5ef1dc40ffa6a6cb968b0fdc43c3a61727a9e950 upstream. + +The s390 common I/O layer (CIO) returns an unexpected -EBUSY return code +when drivers try to start I/O while a path-verification (PV) process is +pending. This can lead to failed device initialization attempts with +symptoms like broken network connectivity after boot. + +Fix this by replacing the -EBUSY return code with a deferred condition +code 1 reply to make path-verification handling consistent from a +driver's point of view. + +The problem can be reproduced semi-regularly using the following process, +while repeating steps 2-3 as necessary (example assumes an OSA device +with bus-IDs 0.0.a000-0.0.a002 on CHPID 0.02): + +1. echo 0.0.a000,0.0.a001,0.0.a002 >/sys/bus/ccwgroup/drivers/qeth/group +2. echo 0 > /sys/bus/ccwgroup/devices/0.0.a000/online +3. echo 1 > /sys/bus/ccwgroup/devices/0.0.a000/online ; \ + echo on > /sys/devices/css0/chp0.02/status + +Background information: + +The common I/O layer starts path-verification I/Os when it receives +indications about changes in a device path's availability. This occurs +for example when hardware events indicate a change in channel-path +status, or when a manual operation such as a CHPID vary or configure +operation is performed. + +If a driver attempts to start I/O while a PV is running, CIO reports a +successful I/O start (ccw_device_start() return code 0). Then, after +completion of PV, CIO synthesizes an interrupt response that indicates +an asynchronous status condition that prevented the start of the I/O +(deferred condition code 1). + +If a PV indication arrives while a device is busy with driver-owned I/O, +PV is delayed until after I/O completion was reported to the driver's +interrupt handler. To ensure that PV can be started eventually, CIO +reports a device busy condition (ccw_device_start() return code -EBUSY) +if a driver tries to start another I/O while PV is pending. + +In some cases this -EBUSY return code causes device drivers to consider +a device not operational, resulting in failed device initialization. + +Note: The code that introduced the problem was added in 2003. Symptoms +started appearing with the following CIO commit that causes a PV +indication when a device is removed from the cio_ignore list after the +associated parent subchannel device was probed, but before online +processing of the CCW device has started: + +2297791c92d0 ("s390/cio: dont unregister subchannel from child-drivers") + +During boot, the cio_ignore list is modified by the cio_ignore dracut +module [1] as well as Linux vendor-specific systemd service scripts[2]. +When combined, this commit and boot scripts cause a frequent occurrence +of the problem during boot. + +[1] https://github.com/dracutdevs/dracut/tree/master/modules.d/81cio_ignore +[2] https://github.com/SUSE/s390-tools/blob/master/cio_ignore.service + +Cc: stable@vger.kernel.org # v5.15+ +Fixes: 2297791c92d0 ("s390/cio: dont unregister subchannel from child-drivers") +Tested-By: Thorsten Winkler +Reviewed-by: Thorsten Winkler +Signed-off-by: Peter Oberparleiter +Signed-off-by: Heiko Carstens +Signed-off-by: Greg Kroah-Hartman +--- + drivers/s390/cio/device_ops.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/s390/cio/device_ops.c ++++ b/drivers/s390/cio/device_ops.c +@@ -202,7 +202,8 @@ int ccw_device_start_timeout_key(struct + return -EINVAL; + if (cdev->private->state == DEV_STATE_NOT_OPER) + return -ENODEV; +- if (cdev->private->state == DEV_STATE_VERIFY) { ++ if (cdev->private->state == DEV_STATE_VERIFY || ++ cdev->private->flags.doverify) { + /* Remember to fake irb when finished. */ + if (!cdev->private->flags.fake_irb) { + cdev->private->flags.fake_irb = FAKE_CMD_IRB; +@@ -214,8 +215,7 @@ int ccw_device_start_timeout_key(struct + } + if (cdev->private->state != DEV_STATE_ONLINE || + ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) && +- !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) || +- cdev->private->flags.doverify) ++ !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS))) + return -EBUSY; + ret = cio_set_options (sch, flags); + if (ret) diff --git a/queue-6.1/scsi-core-consult-supported-vpd-page-list-prior-to-fetching-page.patch b/queue-6.1/scsi-core-consult-supported-vpd-page-list-prior-to-fetching-page.patch new file mode 100644 index 00000000000..000f83db795 --- /dev/null +++ b/queue-6.1/scsi-core-consult-supported-vpd-page-list-prior-to-fetching-page.patch @@ -0,0 +1,100 @@ +From b5fc07a5fb56216a49e6c1d0b172d5464d99a89b Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Wed, 14 Feb 2024 17:14:11 -0500 +Subject: scsi: core: Consult supported VPD page list prior to fetching page + +From: Martin K. Petersen + +commit b5fc07a5fb56216a49e6c1d0b172d5464d99a89b upstream. + +Commit c92a6b5d6335 ("scsi: core: Query VPD size before getting full +page") removed the logic which checks whether a VPD page is present on +the supported pages list before asking for the page itself. That was +done because SPC helpfully states "The Supported VPD Pages VPD page +list may or may not include all the VPD pages that are able to be +returned by the device server". Testing had revealed a few devices +that supported some of the 0xBn pages but didn't actually list them in +page 0. + +Julian Sikorski bisected a problem with his drive resetting during +discovery to the commit above. As it turns out, this particular drive +firmware will crash if we attempt to fetch page 0xB9. + +Various approaches were attempted to work around this. In the end, +reinstating the logic that consults VPD page 0 before fetching any +other page was the path of least resistance. A firmware update for the +devices which originally compelled us to remove the check has since +been released. + +Link: https://lore.kernel.org/r/20240214221411.2888112-1-martin.petersen@oracle.com +Fixes: c92a6b5d6335 ("scsi: core: Query VPD size before getting full page") +Cc: stable@vger.kernel.org +Cc: Bart Van Assche +Reported-by: Julian Sikorski +Tested-by: Julian Sikorski +Reviewed-by: Lee Duncan +Reviewed-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi.c | 22 ++++++++++++++++++++-- + include/scsi/scsi_device.h | 4 ---- + 2 files changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -328,21 +328,39 @@ static int scsi_vpd_inquiry(struct scsi_ + return result + 4; + } + ++enum scsi_vpd_parameters { ++ SCSI_VPD_HEADER_SIZE = 4, ++ SCSI_VPD_LIST_SIZE = 36, ++}; ++ + static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page) + { +- unsigned char vpd_header[SCSI_VPD_HEADER_SIZE] __aligned(4); ++ unsigned char vpd[SCSI_VPD_LIST_SIZE] __aligned(4); + int result; + + if (sdev->no_vpd_size) + return SCSI_DEFAULT_VPD_LEN; + + /* ++ * Fetch the supported pages VPD and validate that the requested page ++ * number is present. ++ */ ++ if (page != 0) { ++ result = scsi_vpd_inquiry(sdev, vpd, 0, sizeof(vpd)); ++ if (result < SCSI_VPD_HEADER_SIZE) ++ return 0; ++ ++ result -= SCSI_VPD_HEADER_SIZE; ++ if (!memchr(&vpd[SCSI_VPD_HEADER_SIZE], page, result)) ++ return 0; ++ } ++ /* + * Fetch the VPD page header to find out how big the page + * is. This is done to prevent problems on legacy devices + * which can not handle allocation lengths as large as + * potentially requested by the caller. + */ +- result = scsi_vpd_inquiry(sdev, vpd_header, page, sizeof(vpd_header)); ++ result = scsi_vpd_inquiry(sdev, vpd, page, SCSI_VPD_HEADER_SIZE); + if (result < 0) + return 0; + +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -100,10 +100,6 @@ struct scsi_vpd { + unsigned char data[]; + }; + +-enum scsi_vpd_parameters { +- SCSI_VPD_HEADER_SIZE = 4, +-}; +- + struct scsi_device { + struct Scsi_Host *host; + struct request_queue *request_queue; diff --git a/queue-6.1/scsi-target-pscsi-fix-bio_put-for-error-case.patch b/queue-6.1/scsi-target-pscsi-fix-bio_put-for-error-case.patch new file mode 100644 index 00000000000..90dee2228bf --- /dev/null +++ b/queue-6.1/scsi-target-pscsi-fix-bio_put-for-error-case.patch @@ -0,0 +1,47 @@ +From de959094eb2197636f7c803af0943cb9d3b35804 Mon Sep 17 00:00:00 2001 +From: Naohiro Aota +Date: Wed, 14 Feb 2024 23:43:56 +0900 +Subject: scsi: target: pscsi: Fix bio_put() for error case + +From: Naohiro Aota + +commit de959094eb2197636f7c803af0943cb9d3b35804 upstream. + +As of commit 066ff571011d ("block: turn bio_kmalloc into a simple kmalloc +wrapper"), a bio allocated by bio_kmalloc() must be freed by bio_uninit() +and kfree(). That is not done properly for the error case, hitting WARN and +NULL pointer dereference in bio_free(). + +Fixes: 066ff571011d ("block: turn bio_kmalloc into a simple kmalloc wrapper") +CC: stable@vger.kernel.org # 6.1+ +Signed-off-by: Naohiro Aota +Link: https://lore.kernel.org/r/20240214144356.101814-1-naohiro.aota@wdc.com +Reviewed-by: Christoph Hellwig +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/target_core_pscsi.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/target/target_core_pscsi.c ++++ b/drivers/target/target_core_pscsi.c +@@ -910,12 +910,15 @@ new_bio: + + return 0; + fail: +- if (bio) +- bio_put(bio); ++ if (bio) { ++ bio_uninit(bio); ++ kfree(bio); ++ } + while (req->bio) { + bio = req->bio; + req->bio = bio->bi_next; +- bio_put(bio); ++ bio_uninit(bio); ++ kfree(bio); + } + req->biotail = NULL; + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; diff --git a/queue-6.1/series b/queue-6.1/series index bd1abc7012e..34091c8430c 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -81,3 +81,30 @@ smb3-clarify-mount-warning.patch pmdomain-mediatek-fix-race-conditions-with-genpd.patch pmdomain-renesas-r8a77980-sysc-cr7-must-be-always-on.patch ib-hfi1-fix-sdma.h-tx-num_descs-off-by-one-error.patch +loongarch-disable-irq-before-init_fn-for-nonboot-cpus.patch +drm-ttm-fix-an-invalid-freeing-on-already-freed-page-in-error-path.patch +s390-cio-fix-invalid-ebusy-on-ccw_device_start.patch +ata-libata-core-do-not-try-to-set-sleeping-devices-to-standby.patch +dm-crypt-recheck-the-integrity-tag-after-a-failure.patch +revert-parisc-only-list-existing-cpus-in-cpu_possible_mask.patch +dm-integrity-recheck-the-integrity-tag-after-a-failure.patch +dm-crypt-don-t-modify-the-data-when-using-authenticated-encryption.patch +dm-verity-recheck-the-hash-after-a-failure.patch +cxl-pci-fix-disabling-memory-if-dvsec-cxl-range-does-not-match-a-cfmws-window.patch +scsi-target-pscsi-fix-bio_put-for-error-case.patch +scsi-core-consult-supported-vpd-page-list-prior-to-fetching-page.patch +mm-swap-fix-race-when-skipping-swapcache.patch +mm-damon-lru_sort-fix-quota-status-loss-due-to-online-tunings.patch +mm-memcontrol-clarify-swapaccount-0-deprecation-warning.patch +platform-x86-intel-vbtn-stop-calling-vbdl-from-notify_handler.patch +platform-x86-touchscreen_dmi-allow-partial-prefix-matches-for-acpi-names.patch +cachefiles-fix-memory-leak-in-cachefiles_add_cache.patch +md-fix-missing-release-of-active_io-for-flush.patch +kvm-arm64-vgic-its-test-for-valid-irq-in-movall-handler.patch +kvm-arm64-vgic-its-test-for-valid-irq-in-its_sync_lpi_pending_table.patch +gtp-fix-use-after-free-and-null-ptr-deref-in-gtp_genl_dump_pdp.patch +crypto-virtio-akcipher-fix-stack-overflow-on-memcpy.patch +irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch +irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch +pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch +l2tp-pass-correct-message-length-to-ip6_append_data.patch