From: Greg Kroah-Hartman Date: Thu, 15 Jul 2021 14:16:00 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.4.133~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=96f21adbd2fffad4fa7b15dac797708ab971ce8e;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: asoc-tegra-set-driver_name-tegra-for-all-machine-drivers.patch coresight-propagate-symlink-failure.patch coresight-tmc-etf-fix-global-out-of-bounds-in-tmc_update_etf_buffer.patch dm-btree-remove-assign-new_root-only-when-removal-succeeds.patch dm-writecache-flush-origin-device-when-writing-and-cache-is-full.patch dm-zoned-check-zone-capacity.patch extcon-intel-mrfld-sync-hardware-and-software-state-on-init.patch i40e-fix-ptp-on-5gb-links.patch ipack-carriers-tpci200-fix-a-double-free-in-tpci200_pci_probe.patch ipmi-watchdog-stop-watchdog-timer-when-the-current-action-is-none.patch lkdtm-bugs-xfail-unaligned_load_store_write.patch media-subdev-disallow-ioctl-for-saa6588-davinci.patch mfd-syscon-free-the-allocated-name-field-of-struct-regmap_config.patch nvmem-core-add-a-missing-of_node_put.patch pci-aardvark-fix-checking-for-pio-non-posted-request.patch pci-aardvark-implement-workaround-for-the-readback-value-of-vend_id.patch pci-leave-apple-thunderbolt-controllers-on-for-s2idle-or-standby.patch power-supply-ab8500-fix-an-old-bug.patch qemu_fw_cfg-make-fw_cfg_rev_attr-a-proper-kobj_attribute.patch rq-qos-fix-missed-wake-ups-in-rq_qos_throttle-try-two.patch selftests-lkdtm-fix-expected-text-for-cr4-pinning.patch seq_buf-fix-overflow-in-seq_buf_putmem_hex.patch thermal-drivers-int340x-processor_thermal-fix-tcc-setting.patch tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch tracing-simplify-fix-saved_tgids-logic.patch ubifs-fix-races-between-xattr_-set-get-and-listxattr-operations.patch xfrm-policy-read-seqcount-outside-of-rcu-read-side-in-xfrm_policy_lookup_bytype.patch --- diff --git a/queue-5.10/asoc-tegra-set-driver_name-tegra-for-all-machine-drivers.patch b/queue-5.10/asoc-tegra-set-driver_name-tegra-for-all-machine-drivers.patch new file mode 100644 index 00000000000..2fceccdafff --- /dev/null +++ b/queue-5.10/asoc-tegra-set-driver_name-tegra-for-all-machine-drivers.patch @@ -0,0 +1,131 @@ +From f6eb84fa596abf28959fc7e0b626f925eb1196c7 Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Sat, 29 May 2021 18:46:46 +0300 +Subject: ASoC: tegra: Set driver_name=tegra for all machine drivers + +From: Dmitry Osipenko + +commit f6eb84fa596abf28959fc7e0b626f925eb1196c7 upstream. + +The driver_name="tegra" is now required by the newer ALSA UCMs, otherwise +Tegra UCMs don't match by the path/name. + +All Tegra machine drivers are specifying the card's name, but it has no +effect if model name is specified in the device-tree since it overrides +the card's name. We need to set the driver_name to "tegra" in order to +get a usable lookup path for the updated ALSA UCMs. The new UCM lookup +path has a form of driver_name/card_name. + +The old lookup paths that are based on driver module name continue to +work as before. Note that UCM matching never worked for Tegra ASoC drivers +if they were compiled as built-in, this is fixed by supporting the new +naming scheme. + +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Osipenko +Link: https://lore.kernel.org/r/20210529154649.25936-2-digetx@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/tegra/tegra_alc5632.c | 1 + + sound/soc/tegra/tegra_max98090.c | 1 + + sound/soc/tegra/tegra_rt5640.c | 1 + + sound/soc/tegra/tegra_rt5677.c | 1 + + sound/soc/tegra/tegra_sgtl5000.c | 1 + + sound/soc/tegra/tegra_wm8753.c | 1 + + sound/soc/tegra/tegra_wm8903.c | 1 + + sound/soc/tegra/tegra_wm9712.c | 1 + + sound/soc/tegra/trimslice.c | 1 + + 9 files changed, 9 insertions(+) + +--- a/sound/soc/tegra/tegra_alc5632.c ++++ b/sound/soc/tegra/tegra_alc5632.c +@@ -139,6 +139,7 @@ static struct snd_soc_dai_link tegra_alc + + static struct snd_soc_card snd_soc_tegra_alc5632 = { + .name = "tegra-alc5632", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_alc5632_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_max98090.c ++++ b/sound/soc/tegra/tegra_max98090.c +@@ -182,6 +182,7 @@ static struct snd_soc_dai_link tegra_max + + static struct snd_soc_card snd_soc_tegra_max98090 = { + .name = "tegra-max98090", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_max98090_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_rt5640.c ++++ b/sound/soc/tegra/tegra_rt5640.c +@@ -132,6 +132,7 @@ static struct snd_soc_dai_link tegra_rt5 + + static struct snd_soc_card snd_soc_tegra_rt5640 = { + .name = "tegra-rt5640", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_rt5640_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_rt5677.c ++++ b/sound/soc/tegra/tegra_rt5677.c +@@ -175,6 +175,7 @@ static struct snd_soc_dai_link tegra_rt5 + + static struct snd_soc_card snd_soc_tegra_rt5677 = { + .name = "tegra-rt5677", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_rt5677_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_sgtl5000.c ++++ b/sound/soc/tegra/tegra_sgtl5000.c +@@ -97,6 +97,7 @@ static struct snd_soc_dai_link tegra_sgt + + static struct snd_soc_card snd_soc_tegra_sgtl5000 = { + .name = "tegra-sgtl5000", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_sgtl5000_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_wm8753.c ++++ b/sound/soc/tegra/tegra_wm8753.c +@@ -101,6 +101,7 @@ static struct snd_soc_dai_link tegra_wm8 + + static struct snd_soc_card snd_soc_tegra_wm8753 = { + .name = "tegra-wm8753", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_wm8753_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_wm8903.c ++++ b/sound/soc/tegra/tegra_wm8903.c +@@ -235,6 +235,7 @@ static struct snd_soc_dai_link tegra_wm8 + + static struct snd_soc_card snd_soc_tegra_wm8903 = { + .name = "tegra-wm8903", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_wm8903_dai, + .num_links = 1, +--- a/sound/soc/tegra/tegra_wm9712.c ++++ b/sound/soc/tegra/tegra_wm9712.c +@@ -54,6 +54,7 @@ static struct snd_soc_dai_link tegra_wm9 + + static struct snd_soc_card snd_soc_tegra_wm9712 = { + .name = "tegra-wm9712", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &tegra_wm9712_dai, + .num_links = 1, +--- a/sound/soc/tegra/trimslice.c ++++ b/sound/soc/tegra/trimslice.c +@@ -94,6 +94,7 @@ static struct snd_soc_dai_link trimslice + + static struct snd_soc_card snd_soc_trimslice = { + .name = "tegra-trimslice", ++ .driver_name = "tegra", + .owner = THIS_MODULE, + .dai_link = &trimslice_tlv320aic23_dai, + .num_links = 1, diff --git a/queue-5.10/coresight-propagate-symlink-failure.patch b/queue-5.10/coresight-propagate-symlink-failure.patch new file mode 100644 index 00000000000..6259a19462f --- /dev/null +++ b/queue-5.10/coresight-propagate-symlink-failure.patch @@ -0,0 +1,35 @@ +From 51dd19a7e9f8fbbb7cd92b8a357091911eae7f78 Mon Sep 17 00:00:00 2001 +From: Jeremy Linton +Date: Mon, 14 Jun 2021 11:59:01 -0600 +Subject: coresight: Propagate symlink failure + +From: Jeremy Linton + +commit 51dd19a7e9f8fbbb7cd92b8a357091911eae7f78 upstream. + +If the symlink is unable to be created, the driver goes +ahead and continues device creation. Instead lets propagate +the failure, and fail the probe. + +Link: https://lore.kernel.org/r/20210526204042.2681700-1-jeremy.linton@arm.com +Fixes: 8a7365c2d418 ("coresight: Expose device connections via sysfs") +Cc: stable@vger.kernel.org +Signed-off-by: Jeremy Linton +Signed-off-by: Mathieu Poirier +Link: https://lore.kernel.org/r/20210614175901.532683-7-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwtracing/coresight/coresight-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwtracing/coresight/coresight-core.c ++++ b/drivers/hwtracing/coresight/coresight-core.c +@@ -1347,7 +1347,7 @@ static int coresight_fixup_device_conns( + } + } + +- return 0; ++ return ret; + } + + static int coresight_remove_match(struct device *dev, void *data) diff --git a/queue-5.10/coresight-tmc-etf-fix-global-out-of-bounds-in-tmc_update_etf_buffer.patch b/queue-5.10/coresight-tmc-etf-fix-global-out-of-bounds-in-tmc_update_etf_buffer.patch new file mode 100644 index 00000000000..c8883686915 --- /dev/null +++ b/queue-5.10/coresight-tmc-etf-fix-global-out-of-bounds-in-tmc_update_etf_buffer.patch @@ -0,0 +1,87 @@ +From 5fae8a946ac2df879caf3f79a193d4766d00239b Mon Sep 17 00:00:00 2001 +From: Sai Prakash Ranjan +Date: Mon, 14 Jun 2021 11:59:00 -0600 +Subject: coresight: tmc-etf: Fix global-out-of-bounds in tmc_update_etf_buffer() + +From: Sai Prakash Ranjan + +commit 5fae8a946ac2df879caf3f79a193d4766d00239b upstream. + +commit 6f755e85c332 ("coresight: Add helper for inserting synchronization +packets") removed trailing '\0' from barrier_pkt array and updated the +call sites like etb_update_buffer() to have proper checks for barrier_pkt +size before read but missed updating tmc_update_etf_buffer() which still +reads barrier_pkt past the array size resulting in KASAN out-of-bounds +bug. Fix this by adding a check for barrier_pkt size before accessing +like it is done in etb_update_buffer(). + + BUG: KASAN: global-out-of-bounds in tmc_update_etf_buffer+0x4b8/0x698 + Read of size 4 at addr ffffffd05b7d1030 by task perf/2629 + + Call trace: + dump_backtrace+0x0/0x27c + show_stack+0x20/0x2c + dump_stack+0x11c/0x188 + print_address_description+0x3c/0x4a4 + __kasan_report+0x140/0x164 + kasan_report+0x10/0x18 + __asan_report_load4_noabort+0x1c/0x24 + tmc_update_etf_buffer+0x4b8/0x698 + etm_event_stop+0x248/0x2d8 + etm_event_del+0x20/0x2c + event_sched_out+0x214/0x6f0 + group_sched_out+0xd0/0x270 + ctx_sched_out+0x2ec/0x518 + __perf_event_task_sched_out+0x4fc/0xe6c + __schedule+0x1094/0x16a0 + preempt_schedule_irq+0x88/0x170 + arm64_preempt_schedule_irq+0xf0/0x18c + el1_irq+0xe8/0x180 + perf_event_exec+0x4d8/0x56c + setup_new_exec+0x204/0x400 + load_elf_binary+0x72c/0x18c0 + search_binary_handler+0x13c/0x420 + load_script+0x500/0x6c4 + search_binary_handler+0x13c/0x420 + exec_binprm+0x118/0x654 + __do_execve_file+0x77c/0xba4 + __arm64_compat_sys_execve+0x98/0xac + el0_svc_common+0x1f8/0x5e0 + el0_svc_compat_handler+0x84/0xb0 + el0_svc_compat+0x10/0x50 + + The buggy address belongs to the variable: + barrier_pkt+0x10/0x40 + + Memory state around the buggy address: + ffffffd05b7d0f00: fa fa fa fa 04 fa fa fa fa fa fa fa 00 00 00 00 + ffffffd05b7d0f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + >ffffffd05b7d1000: 00 00 00 00 00 00 fa fa fa fa fa fa 00 00 00 03 + ^ + ffffffd05b7d1080: fa fa fa fa 00 02 fa fa fa fa fa fa 03 fa fa fa + ffffffd05b7d1100: fa fa fa fa 00 00 00 00 05 fa fa fa fa fa fa fa + ================================================================== + +Link: https://lore.kernel.org/r/20210505093430.18445-1-saiprakash.ranjan@codeaurora.org +Fixes: 0c3fc4d5fa26 ("coresight: Add barrier packet for synchronisation") +Cc: stable@vger.kernel.org +Signed-off-by: Sai Prakash Ranjan +Signed-off-by: Suzuki K Poulose +Signed-off-by: Mathieu Poirier +Link: https://lore.kernel.org/r/20210614175901.532683-6-mathieu.poirier@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwtracing/coresight/coresight-tmc-etf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c +@@ -528,7 +528,7 @@ static unsigned long tmc_update_etf_buff + buf_ptr = buf->data_pages[cur] + offset; + *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); + +- if (lost && *barrier) { ++ if (lost && i < CORESIGHT_BARRIER_PKT_SIZE) { + *buf_ptr = *barrier; + barrier++; + } diff --git a/queue-5.10/dm-btree-remove-assign-new_root-only-when-removal-succeeds.patch b/queue-5.10/dm-btree-remove-assign-new_root-only-when-removal-succeeds.patch new file mode 100644 index 00000000000..9450012aa81 --- /dev/null +++ b/queue-5.10/dm-btree-remove-assign-new_root-only-when-removal-succeeds.patch @@ -0,0 +1,60 @@ +From b6e58b5466b2959f83034bead2e2e1395cca8aeb Mon Sep 17 00:00:00 2001 +From: Hou Tao +Date: Thu, 17 Jun 2021 15:45:47 +0800 +Subject: dm btree remove: assign new_root only when removal succeeds + +From: Hou Tao + +commit b6e58b5466b2959f83034bead2e2e1395cca8aeb upstream. + +remove_raw() in dm_btree_remove() may fail due to IO read error +(e.g. read the content of origin block fails during shadowing), +and the value of shadow_spine::root is uninitialized, but +the uninitialized value is still assign to new_root in the +end of dm_btree_remove(). + +For dm-thin, the value of pmd->details_root or pmd->root will become +an uninitialized value, so if trying to read details_info tree again +out-of-bound memory may occur as showed below: + + general protection fault, probably for non-canonical address 0x3fdcb14c8d7520 + CPU: 4 PID: 515 Comm: dmsetup Not tainted 5.13.0-rc6 + Hardware name: QEMU Standard PC + RIP: 0010:metadata_ll_load_ie+0x14/0x30 + Call Trace: + sm_metadata_count_is_more_than_one+0xb9/0xe0 + dm_tm_shadow_block+0x52/0x1c0 + shadow_step+0x59/0xf0 + remove_raw+0xb2/0x170 + dm_btree_remove+0xf4/0x1c0 + dm_pool_delete_thin_device+0xc3/0x140 + pool_message+0x218/0x2b0 + target_message+0x251/0x290 + ctl_ioctl+0x1c4/0x4d0 + dm_ctl_ioctl+0xe/0x20 + __x64_sys_ioctl+0x7b/0xb0 + do_syscall_64+0x40/0xb0 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +Fixing it by only assign new_root when removal succeeds + +Signed-off-by: Hou Tao +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/persistent-data/dm-btree-remove.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/md/persistent-data/dm-btree-remove.c ++++ b/drivers/md/persistent-data/dm-btree-remove.c +@@ -549,7 +549,8 @@ int dm_btree_remove(struct dm_btree_info + delete_at(n, index); + } + +- *new_root = shadow_root(&spine); ++ if (!r) ++ *new_root = shadow_root(&spine); + exit_shadow_spine(&spine); + + return r; diff --git a/queue-5.10/dm-writecache-flush-origin-device-when-writing-and-cache-is-full.patch b/queue-5.10/dm-writecache-flush-origin-device-when-writing-and-cache-is-full.patch new file mode 100644 index 00000000000..a908515819d --- /dev/null +++ b/queue-5.10/dm-writecache-flush-origin-device-when-writing-and-cache-is-full.patch @@ -0,0 +1,62 @@ +From ee55b92a7391bf871939330f662651b54be51b73 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 15 Jun 2021 13:45:55 -0400 +Subject: dm writecache: flush origin device when writing and cache is full + +From: Mikulas Patocka + +commit ee55b92a7391bf871939330f662651b54be51b73 upstream. + +Commit d53f1fafec9d086f1c5166436abefdaef30e0363 ("dm writecache: do +direct write if the cache is full") changed dm-writecache, so that it +writes directly to the origin device if the cache is full. +Unfortunately, it doesn't forward flush requests to the origin device, +so that there is a bug where flushes are being ignored. + +Fix this by adding missing flush forwarding. + +For PMEM mode, we fix this bug by disabling direct writes to the origin +device, because it performs better. + +Signed-off-by: Mikulas Patocka +Fixes: d53f1fafec9d ("dm writecache: do direct write if the cache is full") +Cc: stable@vger.kernel.org # v5.7+ +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-writecache.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-writecache.c ++++ b/drivers/md/dm-writecache.c +@@ -1297,8 +1297,12 @@ static int writecache_map(struct dm_targ + writecache_flush(wc); + if (writecache_has_error(wc)) + goto unlock_error; ++ if (unlikely(wc->cleaner)) ++ goto unlock_remap_origin; + goto unlock_submit; + } else { ++ if (dm_bio_get_target_bio_nr(bio)) ++ goto unlock_remap_origin; + writecache_offload_bio(wc, bio); + goto unlock_return; + } +@@ -1377,7 +1381,7 @@ read_next_block: + } + e = writecache_pop_from_freelist(wc, (sector_t)-1); + if (unlikely(!e)) { +- if (!found_entry) { ++ if (!WC_MODE_PMEM(wc) && !found_entry) { + direct_write: + e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING); + if (e) { +@@ -2483,7 +2487,7 @@ overflow: + goto bad; + } + +- ti->num_flush_bios = 1; ++ ti->num_flush_bios = WC_MODE_PMEM(wc) ? 1 : 2; + ti->flush_supported = true; + ti->num_discard_bios = 1; + diff --git a/queue-5.10/dm-zoned-check-zone-capacity.patch b/queue-5.10/dm-zoned-check-zone-capacity.patch new file mode 100644 index 00000000000..eb8983e42db --- /dev/null +++ b/queue-5.10/dm-zoned-check-zone-capacity.patch @@ -0,0 +1,40 @@ +From bab68499428ed934f0493ac74197ed6f36204260 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Wed, 19 May 2021 10:26:16 +0900 +Subject: dm zoned: check zone capacity + +From: Damien Le Moal + +commit bab68499428ed934f0493ac74197ed6f36204260 upstream. + +The dm-zoned target cannot support zoned block devices with zones that +have a capacity smaller than the zone size (e.g. NVMe zoned namespaces) +due to the current chunk zone mapping implementation as it is assumed +that zones and chunks have the same size with all blocks usable. +If a zoned drive is found to have zones with a capacity different from +the zone size, fail the target initialization. + +Signed-off-by: Damien Le Moal +Cc: stable@vger.kernel.org # v5.9+ +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-zoned-metadata.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/md/dm-zoned-metadata.c ++++ b/drivers/md/dm-zoned-metadata.c +@@ -1390,6 +1390,13 @@ static int dmz_init_zone(struct blk_zone + return -ENXIO; + } + ++ /* ++ * Devices that have zones with a capacity smaller than the zone size ++ * (e.g. NVMe zoned namespaces) are not supported. ++ */ ++ if (blkz->capacity != blkz->len) ++ return -ENXIO; ++ + switch (blkz->type) { + case BLK_ZONE_TYPE_CONVENTIONAL: + set_bit(DMZ_RND, &zone->flags); diff --git a/queue-5.10/extcon-intel-mrfld-sync-hardware-and-software-state-on-init.patch b/queue-5.10/extcon-intel-mrfld-sync-hardware-and-software-state-on-init.patch new file mode 100644 index 00000000000..59086908db9 --- /dev/null +++ b/queue-5.10/extcon-intel-mrfld-sync-hardware-and-software-state-on-init.patch @@ -0,0 +1,48 @@ +From ecb5bdff901139850fb3ca3ae2d0cccac045bc52 Mon Sep 17 00:00:00 2001 +From: Ferry Toth +Date: Tue, 18 May 2021 23:27:09 +0200 +Subject: extcon: intel-mrfld: Sync hardware and software state on init + +From: Ferry Toth + +commit ecb5bdff901139850fb3ca3ae2d0cccac045bc52 upstream. + +extcon driver for Basin Cove PMIC shadows the switch status used for dwc3 +DRD to detect a change in the switch position. This change initializes the +status at probe time. + +Cc: stable@vger.kernel.org +Fixes: 492929c54791 ("extcon: mrfld: Introduce extcon driver for Basin Cove PMIC") +Reviewed-by: Andy Shevchenko +Signed-off-by: Ferry Toth +Signed-off-by: Chanwoo Choi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/extcon/extcon-intel-mrfld.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/extcon/extcon-intel-mrfld.c ++++ b/drivers/extcon/extcon-intel-mrfld.c +@@ -197,6 +197,7 @@ static int mrfld_extcon_probe(struct pla + struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent); + struct regmap *regmap = pmic->regmap; + struct mrfld_extcon_data *data; ++ unsigned int status; + unsigned int id; + int irq, ret; + +@@ -244,6 +245,14 @@ static int mrfld_extcon_probe(struct pla + /* Get initial state */ + mrfld_extcon_role_detect(data); + ++ /* ++ * Cached status value is used for cable detection, see comments ++ * in mrfld_extcon_cable_detect(), we need to sync cached value ++ * with a real state of the hardware. ++ */ ++ regmap_read(regmap, BCOVE_SCHGRIRQ1, &status); ++ data->status = status; ++ + mrfld_extcon_clear(data, BCOVE_MIRQLVL1, BCOVE_LVL1_CHGR); + mrfld_extcon_clear(data, BCOVE_MCHGRIRQ1, BCOVE_CHGRIRQ_ALL); + diff --git a/queue-5.10/i40e-fix-ptp-on-5gb-links.patch b/queue-5.10/i40e-fix-ptp-on-5gb-links.patch new file mode 100644 index 00000000000..11bbb637ee0 --- /dev/null +++ b/queue-5.10/i40e-fix-ptp-on-5gb-links.patch @@ -0,0 +1,55 @@ +From 26b0ce8dd3dd704393dbace4dc416adfeffe531f Mon Sep 17 00:00:00 2001 +From: Jesse Brandeburg +Date: Fri, 7 May 2021 11:56:25 -0700 +Subject: i40e: fix PTP on 5Gb links + +From: Jesse Brandeburg + +commit 26b0ce8dd3dd704393dbace4dc416adfeffe531f upstream. + +As reported by Alex Sergeev, the i40e driver is incrementing the PTP +clock at 40Gb speeds when linked at 5Gb. Fix this bug by making +sure that the right multiplier is selected when linked at 5Gb. + +Fixes: 3dbdd6c2f70a ("i40e: Add support for 5Gbps cards") +Cc: stable@vger.kernel.org +Reported-by: Alex Sergeev +Suggested-by: Alex Sergeev +Signed-off-by: Jesse Brandeburg +Tested-by: Tony Brelinski +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/i40e/i40e_ptp.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c +@@ -11,13 +11,14 @@ + * operate with the nanosecond field directly without fear of overflow. + * + * Much like the 82599, the update period is dependent upon the link speed: +- * At 40Gb link or no link, the period is 1.6ns. +- * At 10Gb link, the period is multiplied by 2. (3.2ns) ++ * At 40Gb, 25Gb, or no link, the period is 1.6ns. ++ * At 10Gb or 5Gb link, the period is multiplied by 2. (3.2ns) + * At 1Gb link, the period is multiplied by 20. (32ns) + * 1588 functionality is not supported at 100Mbps. + */ + #define I40E_PTP_40GB_INCVAL 0x0199999999ULL + #define I40E_PTP_10GB_INCVAL_MULT 2 ++#define I40E_PTP_5GB_INCVAL_MULT 2 + #define I40E_PTP_1GB_INCVAL_MULT 20 + + #define I40E_PRTTSYN_CTL1_TSYNTYPE_V1 BIT(I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT) +@@ -465,6 +466,9 @@ void i40e_ptp_set_increment(struct i40e_ + case I40E_LINK_SPEED_10GB: + mult = I40E_PTP_10GB_INCVAL_MULT; + break; ++ case I40E_LINK_SPEED_5GB: ++ mult = I40E_PTP_5GB_INCVAL_MULT; ++ break; + case I40E_LINK_SPEED_1GB: + mult = I40E_PTP_1GB_INCVAL_MULT; + break; diff --git a/queue-5.10/ipack-carriers-tpci200-fix-a-double-free-in-tpci200_pci_probe.patch b/queue-5.10/ipack-carriers-tpci200-fix-a-double-free-in-tpci200_pci_probe.patch new file mode 100644 index 00000000000..e14577347f9 --- /dev/null +++ b/queue-5.10/ipack-carriers-tpci200-fix-a-double-free-in-tpci200_pci_probe.patch @@ -0,0 +1,45 @@ +From 9272e5d0028d45a3b45b58c9255e6e0df53f7ad9 Mon Sep 17 00:00:00 2001 +From: Lv Yunlong +Date: Mon, 24 May 2021 02:32:05 -0700 +Subject: ipack/carriers/tpci200: Fix a double free in tpci200_pci_probe + +From: Lv Yunlong + +commit 9272e5d0028d45a3b45b58c9255e6e0df53f7ad9 upstream. + +In the out_err_bus_register error branch of tpci200_pci_probe, +tpci200->info->cfg_regs is freed by tpci200_uninstall()-> +tpci200_unregister()->pci_iounmap(..,tpci200->info->cfg_regs) +in the first time. + +But later, iounmap() is called to free tpci200->info->cfg_regs +again. + +My patch sets tpci200->info->cfg_regs to NULL after tpci200_uninstall() +to avoid the double free. + +Fixes: cea2f7cdff2af ("Staging: ipack/bridges/tpci200: Use the TPCI200 in big endian mode") +Cc: stable +Acked-by: Samuel Iglesias Gonsalvez +Signed-off-by: Lv Yunlong +Link: https://lore.kernel.org/r/20210524093205.8333-1-lyl2019@mail.ustc.edu.cn +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ipack/carriers/tpci200.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/ipack/carriers/tpci200.c ++++ b/drivers/ipack/carriers/tpci200.c +@@ -596,8 +596,11 @@ static int tpci200_pci_probe(struct pci_ + + out_err_bus_register: + tpci200_uninstall(tpci200); ++ /* tpci200->info->cfg_regs is unmapped in tpci200_uninstall */ ++ tpci200->info->cfg_regs = NULL; + out_err_install: +- iounmap(tpci200->info->cfg_regs); ++ if (tpci200->info->cfg_regs) ++ iounmap(tpci200->info->cfg_regs); + out_err_ioremap: + pci_release_region(pdev, TPCI200_CFG_MEM_BAR); + out_err_pci_request: diff --git a/queue-5.10/ipmi-watchdog-stop-watchdog-timer-when-the-current-action-is-none.patch b/queue-5.10/ipmi-watchdog-stop-watchdog-timer-when-the-current-action-is-none.patch new file mode 100644 index 00000000000..07325024ebf --- /dev/null +++ b/queue-5.10/ipmi-watchdog-stop-watchdog-timer-when-the-current-action-is-none.patch @@ -0,0 +1,72 @@ +From 2253042d86f57d90a621ac2513a7a7a13afcf809 Mon Sep 17 00:00:00 2001 +From: Petr Pavlu +Date: Thu, 13 May 2021 14:26:36 +0200 +Subject: ipmi/watchdog: Stop watchdog timer when the current action is 'none' + +From: Petr Pavlu + +commit 2253042d86f57d90a621ac2513a7a7a13afcf809 upstream. + +When an IPMI watchdog timer is being stopped in ipmi_close() or +ipmi_ioctl(WDIOS_DISABLECARD), the current watchdog action is updated to +WDOG_TIMEOUT_NONE and _ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB) is called +to install this action. The latter function ends up invoking +__ipmi_set_timeout() which makes the actual 'Set Watchdog Timer' IPMI +request. + +For IPMI 1.0, this operation results in fully stopping the watchdog timer. +For IPMI >= 1.5, function __ipmi_set_timeout() always specifies the "don't +stop" flag in the prepared 'Set Watchdog Timer' IPMI request. This causes +that the watchdog timer has its action correctly updated to 'none' but the +timer continues to run. A problem is that IPMI firmware can then still log +an expiration event when the configured timeout is reached, which is +unexpected because the watchdog timer was requested to be stopped. + +The patch fixes this problem by not setting the "don't stop" flag in +__ipmi_set_timeout() when the current action is WDOG_TIMEOUT_NONE which +results in stopping the watchdog timer. This makes the behaviour for +IPMI >= 1.5 consistent with IPMI 1.0. It also matches the logic in +__ipmi_heartbeat() which does not allow to reset the watchdog if the +current action is WDOG_TIMEOUT_NONE as that would start the timer. + +Signed-off-by: Petr Pavlu +Message-Id: <10a41bdc-9c99-089c-8d89-fa98ce5ea080@suse.com> +Cc: stable@vger.kernel.org +Signed-off-by: Corey Minyard +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/ipmi/ipmi_watchdog.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/char/ipmi/ipmi_watchdog.c ++++ b/drivers/char/ipmi/ipmi_watchdog.c +@@ -371,16 +371,18 @@ static int __ipmi_set_timeout(struct ipm + data[0] = 0; + WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); + +- if ((ipmi_version_major > 1) +- || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { +- /* This is an IPMI 1.5-only feature. */ +- data[0] |= WDOG_DONT_STOP_ON_SET; +- } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { +- /* +- * In ipmi 1.0, setting the timer stops the watchdog, we +- * need to start it back up again. +- */ +- hbnow = 1; ++ if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { ++ if ((ipmi_version_major > 1) || ++ ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { ++ /* This is an IPMI 1.5-only feature. */ ++ data[0] |= WDOG_DONT_STOP_ON_SET; ++ } else { ++ /* ++ * In ipmi 1.0, setting the timer stops the watchdog, we ++ * need to start it back up again. ++ */ ++ hbnow = 1; ++ } + } + + data[1] = 0; diff --git a/queue-5.10/lkdtm-bugs-xfail-unaligned_load_store_write.patch b/queue-5.10/lkdtm-bugs-xfail-unaligned_load_store_write.patch new file mode 100644 index 00000000000..4533f2148db --- /dev/null +++ b/queue-5.10/lkdtm-bugs-xfail-unaligned_load_store_write.patch @@ -0,0 +1,33 @@ +From a15676ac8f24a9ac5fd881cf17be4be13fa0910a Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 23 Jun 2021 13:39:31 -0700 +Subject: lkdtm/bugs: XFAIL UNALIGNED_LOAD_STORE_WRITE + +From: Kees Cook + +commit a15676ac8f24a9ac5fd881cf17be4be13fa0910a upstream. + +When built under CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, this test is +expected to fail (i.e. not trip an exception). + +Fixes: 46d1a0f03d66 ("selftests/lkdtm: Add tests for LKDTM targets") +Cc: stable@vger.kernel.org +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20210623203936.3151093-5-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/lkdtm/bugs.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/misc/lkdtm/bugs.c ++++ b/drivers/misc/lkdtm/bugs.c +@@ -144,6 +144,9 @@ void lkdtm_UNALIGNED_LOAD_STORE_WRITE(vo + if (*p == 0) + val = 0x87654321; + *p = val; ++ ++ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) ++ pr_err("XFAIL: arch has CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS\n"); + } + + void lkdtm_SOFTLOCKUP(void) diff --git a/queue-5.10/media-subdev-disallow-ioctl-for-saa6588-davinci.patch b/queue-5.10/media-subdev-disallow-ioctl-for-saa6588-davinci.patch new file mode 100644 index 00000000000..c539b0c0ee9 --- /dev/null +++ b/queue-5.10/media-subdev-disallow-ioctl-for-saa6588-davinci.patch @@ -0,0 +1,169 @@ +From 0a7790be182d32b9b332a37cb4206e24fe94b728 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 14 Jun 2021 12:34:09 +0200 +Subject: media: subdev: disallow ioctl for saa6588/davinci + +From: Arnd Bergmann + +commit 0a7790be182d32b9b332a37cb4206e24fe94b728 upstream. + +The saa6588_ioctl() function expects to get called from other kernel +functions with a 'saa6588_command' pointer, but I found nothing stops it +from getting called from user space instead, which seems rather dangerous. + +The same thing happens in the davinci vpbe driver with its VENC_GET_FLD +command. + +As a quick fix, add a separate .command() callback pointer for this +driver and change the two callers over to that. This change can easily +get backported to stable kernels if necessary, but since there are only +two drivers, we may want to eventually replace this with a set of more +specialized callbacks in the long run. + +Fixes: c3fda7f835b0 ("V4L/DVB (10537): saa6588: convert to v4l2_subdev.") +Cc: stable@vger.kernel.org +Signed-off-by: Arnd Bergmann +Reviewed-by: Laurent Pinchart +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/i2c/saa6588.c | 4 ++-- + drivers/media/pci/bt8xx/bttv-driver.c | 6 +++--- + drivers/media/pci/saa7134/saa7134-video.c | 6 +++--- + drivers/media/platform/davinci/vpbe_display.c | 2 +- + drivers/media/platform/davinci/vpbe_venc.c | 6 ++---- + include/media/v4l2-subdev.h | 4 ++++ + 6 files changed, 15 insertions(+), 13 deletions(-) + +--- a/drivers/media/i2c/saa6588.c ++++ b/drivers/media/i2c/saa6588.c +@@ -380,7 +380,7 @@ static void saa6588_configure(struct saa + + /* ---------------------------------------------------------------------- */ + +-static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) ++static long saa6588_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) + { + struct saa6588 *s = to_saa6588(sd); + struct saa6588_command *a = arg; +@@ -433,7 +433,7 @@ static int saa6588_s_tuner(struct v4l2_s + /* ----------------------------------------------------------------------- */ + + static const struct v4l2_subdev_core_ops saa6588_core_ops = { +- .ioctl = saa6588_ioctl, ++ .command = saa6588_command, + }; + + static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = { +--- a/drivers/media/pci/bt8xx/bttv-driver.c ++++ b/drivers/media/pci/bt8xx/bttv-driver.c +@@ -3187,7 +3187,7 @@ static int radio_release(struct file *fi + + btv->radio_user--; + +- bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); ++ bttv_call_all(btv, core, command, SAA6588_CMD_CLOSE, &cmd); + + if (btv->radio_user == 0) + btv->has_radio_tuner = 0; +@@ -3268,7 +3268,7 @@ static ssize_t radio_read(struct file *f + cmd.result = -ENODEV; + radio_enable(btv); + +- bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); ++ bttv_call_all(btv, core, command, SAA6588_CMD_READ, &cmd); + + return cmd.result; + } +@@ -3289,7 +3289,7 @@ static __poll_t radio_poll(struct file * + cmd.instance = file; + cmd.event_list = wait; + cmd.poll_mask = res; +- bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); ++ bttv_call_all(btv, core, command, SAA6588_CMD_POLL, &cmd); + + return cmd.poll_mask; + } +--- a/drivers/media/pci/saa7134/saa7134-video.c ++++ b/drivers/media/pci/saa7134/saa7134-video.c +@@ -1178,7 +1178,7 @@ static int video_release(struct file *fi + + saa_call_all(dev, tuner, standby); + if (vdev->vfl_type == VFL_TYPE_RADIO) +- saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); ++ saa_call_all(dev, core, command, SAA6588_CMD_CLOSE, &cmd); + mutex_unlock(&dev->lock); + + return 0; +@@ -1197,7 +1197,7 @@ static ssize_t radio_read(struct file *f + cmd.result = -ENODEV; + + mutex_lock(&dev->lock); +- saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); ++ saa_call_all(dev, core, command, SAA6588_CMD_READ, &cmd); + mutex_unlock(&dev->lock); + + return cmd.result; +@@ -1213,7 +1213,7 @@ static __poll_t radio_poll(struct file * + cmd.event_list = wait; + cmd.poll_mask = 0; + mutex_lock(&dev->lock); +- saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); ++ saa_call_all(dev, core, command, SAA6588_CMD_POLL, &cmd); + mutex_unlock(&dev->lock); + + return rc | cmd.poll_mask; +--- a/drivers/media/platform/davinci/vpbe_display.c ++++ b/drivers/media/platform/davinci/vpbe_display.c +@@ -47,7 +47,7 @@ static int venc_is_second_field(struct v + + ret = v4l2_subdev_call(vpbe_dev->venc, + core, +- ioctl, ++ command, + VENC_GET_FLD, + &val); + if (ret < 0) { +--- a/drivers/media/platform/davinci/vpbe_venc.c ++++ b/drivers/media/platform/davinci/vpbe_venc.c +@@ -521,9 +521,7 @@ static int venc_s_routing(struct v4l2_su + return ret; + } + +-static long venc_ioctl(struct v4l2_subdev *sd, +- unsigned int cmd, +- void *arg) ++static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) + { + u32 val; + +@@ -542,7 +540,7 @@ static long venc_ioctl(struct v4l2_subde + } + + static const struct v4l2_subdev_core_ops venc_core_ops = { +- .ioctl = venc_ioctl, ++ .command = venc_command, + }; + + static const struct v4l2_subdev_video_ops venc_video_ops = { +--- a/include/media/v4l2-subdev.h ++++ b/include/media/v4l2-subdev.h +@@ -162,6 +162,9 @@ struct v4l2_subdev_io_pin_config { + * @s_gpio: set GPIO pins. Very simple right now, might need to be extended with + * a direction argument if needed. + * ++ * @command: called by in-kernel drivers in order to call functions internal ++ * to subdev drivers driver that have a separate callback. ++ * + * @ioctl: called at the end of ioctl() syscall handler at the V4L2 core. + * used to provide support for private ioctls used on the driver. + * +@@ -193,6 +196,7 @@ struct v4l2_subdev_core_ops { + int (*load_fw)(struct v4l2_subdev *sd); + int (*reset)(struct v4l2_subdev *sd, u32 val); + int (*s_gpio)(struct v4l2_subdev *sd, u32 val); ++ long (*command)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); + long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); + #ifdef CONFIG_COMPAT + long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, diff --git a/queue-5.10/mfd-syscon-free-the-allocated-name-field-of-struct-regmap_config.patch b/queue-5.10/mfd-syscon-free-the-allocated-name-field-of-struct-regmap_config.patch new file mode 100644 index 00000000000..ab0f3899676 --- /dev/null +++ b/queue-5.10/mfd-syscon-free-the-allocated-name-field-of-struct-regmap_config.patch @@ -0,0 +1,47 @@ +From 56a1188159cb2b87fbcb5a7a7afb38a4dd9db0c1 Mon Sep 17 00:00:00 2001 +From: Limeng +Date: Wed, 7 Apr 2021 13:25:25 +0800 +Subject: mfd: syscon: Free the allocated name field of struct regmap_config + +From: Limeng + +commit 56a1188159cb2b87fbcb5a7a7afb38a4dd9db0c1 upstream. + +The commit 529a1101212a("mfd: syscon: Don't free allocated name +for regmap_config") doesn't free the allocated name field of struct +regmap_config, but introduce a memory leak. There is another +commit 94cc89eb8fa5("regmap: debugfs: Fix handling of name string +for debugfs init delays") fixing this debugfs init issue from root +cause. With this fixing, the name field in struct regmap_debugfs_node +is removed. When initialize debugfs for syscon driver, the name +field of struct regmap_config is not used anymore. So, the allocated +name field of struct regmap_config is need to be freed directly after +regmap initialization to avoid memory leak. + +Cc: stable@vger.kernel.org +Fixes: 529a1101212a("mfd: syscon: Don't free allocated name for regmap_config") +Signed-off-by: Meng Li +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mfd/syscon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mfd/syscon.c ++++ b/drivers/mfd/syscon.c +@@ -108,6 +108,7 @@ static struct syscon *of_syscon_register + syscon_config.max_register = resource_size(&res) - reg_io_width; + + regmap = regmap_init_mmio(NULL, base, &syscon_config); ++ kfree(syscon_config.name); + if (IS_ERR(regmap)) { + pr_err("regmap init failed\n"); + ret = PTR_ERR(regmap); +@@ -144,7 +145,6 @@ err_clk: + regmap_exit(regmap); + err_regmap: + iounmap(base); +- kfree(syscon_config.name); + err_map: + kfree(syscon); + return ERR_PTR(ret); diff --git a/queue-5.10/nvmem-core-add-a-missing-of_node_put.patch b/queue-5.10/nvmem-core-add-a-missing-of_node_put.patch new file mode 100644 index 00000000000..007a7e26956 --- /dev/null +++ b/queue-5.10/nvmem-core-add-a-missing-of_node_put.patch @@ -0,0 +1,58 @@ +From 63879e2964bceee2aa5bbe8b99ea58bba28bb64f Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Fri, 11 Jun 2021 11:23:21 +0100 +Subject: nvmem: core: add a missing of_node_put + +From: Christophe JAILLET + +commit 63879e2964bceee2aa5bbe8b99ea58bba28bb64f upstream. + +'for_each_child_of_node' performs an of_node_get on each iteration, so a +return from the middle of the loop requires an of_node_put. + +Fixes: e888d445ac33 ("nvmem: resolve cells from DT at registration time") +Cc: +Signed-off-by: Christophe JAILLET +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20210611102321.11509-1-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvmem/core.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -549,15 +549,17 @@ static int nvmem_add_cells_from_of(struc + continue; + if (len < 2 * sizeof(u32)) { + dev_err(dev, "nvmem: invalid reg on %pOF\n", child); ++ of_node_put(child); + return -EINVAL; + } + + cell = kzalloc(sizeof(*cell), GFP_KERNEL); +- if (!cell) ++ if (!cell) { ++ of_node_put(child); + return -ENOMEM; ++ } + + cell->nvmem = nvmem; +- cell->np = of_node_get(child); + cell->offset = be32_to_cpup(addr++); + cell->bytes = be32_to_cpup(addr); + cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); +@@ -578,11 +580,12 @@ static int nvmem_add_cells_from_of(struc + cell->name, nvmem->stride); + /* Cells already added will be freed later. */ + kfree_const(cell->name); +- of_node_put(cell->np); + kfree(cell); ++ of_node_put(child); + return -EINVAL; + } + ++ cell->np = of_node_get(child); + nvmem_cell_add(cell); + } + diff --git a/queue-5.10/pci-aardvark-fix-checking-for-pio-non-posted-request.patch b/queue-5.10/pci-aardvark-fix-checking-for-pio-non-posted-request.patch new file mode 100644 index 00000000000..fa1eb8de330 --- /dev/null +++ b/queue-5.10/pci-aardvark-fix-checking-for-pio-non-posted-request.patch @@ -0,0 +1,36 @@ +From 8ceeac307a79f68c0d0c72d6e48b82fa424204ec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Thu, 24 Jun 2021 23:33:43 +0200 +Subject: PCI: aardvark: Fix checking for PIO Non-posted Request +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +commit 8ceeac307a79f68c0d0c72d6e48b82fa424204ec upstream. + +PIO_NON_POSTED_REQ for PIO_STAT register is incorrectly defined. Bit 10 in +register PIO_STAT indicates the response is to a non-posted request. + +Link: https://lore.kernel.org/r/20210624213345.3617-2-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -56,7 +56,7 @@ + #define PIO_COMPLETION_STATUS_UR 1 + #define PIO_COMPLETION_STATUS_CRS 2 + #define PIO_COMPLETION_STATUS_CA 4 +-#define PIO_NON_POSTED_REQ BIT(0) ++#define PIO_NON_POSTED_REQ BIT(10) + #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) + #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) + #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) diff --git a/queue-5.10/pci-aardvark-implement-workaround-for-the-readback-value-of-vend_id.patch b/queue-5.10/pci-aardvark-implement-workaround-for-the-readback-value-of-vend_id.patch new file mode 100644 index 00000000000..fbd0d421a2c --- /dev/null +++ b/queue-5.10/pci-aardvark-implement-workaround-for-the-readback-value-of-vend_id.patch @@ -0,0 +1,65 @@ +From 7f71a409fe3d9358da07c77f15bb5b7960f12253 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Fri, 25 Jun 2021 00:26:20 +0200 +Subject: PCI: aardvark: Implement workaround for the readback value of VEND_ID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +commit 7f71a409fe3d9358da07c77f15bb5b7960f12253 upstream. + +Marvell Armada 3700 Functional Errata, Guidelines, and Restrictions +document describes in erratum 4.1 PCIe value of vendor ID (Ref #: 243): + + The readback value of VEND_ID (RD0070000h [15:0]) is 1B4Bh, while it + should read 11ABh. + + The firmware can write the correct value, 11ABh, through VEND_ID + (RD0076044h [15:0]). + +Implement this workaround in aardvark driver for both PCI vendor id and PCI +subsystem vendor id. + +This change affects and fixes PCI vendor id of emulated PCIe root bridge. +After this change emulated PCIe root bridge has correct vendor id. + +Link: https://lore.kernel.org/r/20210624222621.4776-5-pali@kernel.org +Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -124,6 +124,7 @@ + #define LTSSM_MASK 0x3f + #define LTSSM_L0 0x10 + #define RC_BAR_CONFIG 0x300 ++#define VENDOR_ID_REG (LMI_BASE_ADDR + 0x44) + + /* PCIe core controller registers */ + #define CTRL_CORE_BASE_ADDR 0x18000 +@@ -385,6 +386,16 @@ static void advk_pcie_setup_hw(struct ad + reg |= (IS_RC_MSK << IS_RC_SHIFT); + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + ++ /* ++ * Replace incorrect PCI vendor id value 0x1b4b by correct value 0x11ab. ++ * VENDOR_ID_REG contains vendor id in low 16 bits and subsystem vendor ++ * id in high 16 bits. Updating this register changes readback value of ++ * read-only vendor id bits in PCIE_CORE_DEV_ID_REG register. Workaround ++ * for erratum 4.1: "The value of device and vendor ID is incorrect". ++ */ ++ reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; ++ advk_writel(pcie, reg, VENDOR_ID_REG); ++ + /* Set Advanced Error Capabilities and Control PF0 register */ + reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | + PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | diff --git a/queue-5.10/pci-leave-apple-thunderbolt-controllers-on-for-s2idle-or-standby.patch b/queue-5.10/pci-leave-apple-thunderbolt-controllers-on-for-s2idle-or-standby.patch new file mode 100644 index 00000000000..2b725e4c5ef --- /dev/null +++ b/queue-5.10/pci-leave-apple-thunderbolt-controllers-on-for-s2idle-or-standby.patch @@ -0,0 +1,65 @@ +From 4694ae373dc2114f9a82f6ae15737e65af0c6dea Mon Sep 17 00:00:00 2001 +From: Konstantin Kharlamov +Date: Fri, 21 May 2021 02:55:01 +0300 +Subject: PCI: Leave Apple Thunderbolt controllers on for s2idle or standby + +From: Konstantin Kharlamov + +commit 4694ae373dc2114f9a82f6ae15737e65af0c6dea upstream. + +On Macbook 2013, resuming from suspend-to-idle or standby resulted in the +external monitor no longer being detected, a stacktrace, and errors like +this in dmesg: + + pcieport 0000:06:00.0: can't change power state from D3hot to D0 (config space inaccessible) + +The reason is that we know how to turn power to the Thunderbolt controller +*off* via the SXIO/SXFP/SXLF methods, but we don't know how to turn power +back on. We have to rely on firmware to turn the power back on. + +When going to the "suspend-to-idle" or "standby" system sleep states, +firmware is not involved either on the suspend side or the resume side, so +we can't use SXIO/SXFP/SXLF to turn the power off. + +Skip SXIO/SXFP/SXLF when firmware isn't involved in suspend, e.g., when +we're going to the "suspend-to-idle" or "standby" system sleep states. + +Fixes: 1df5172c5c25 ("PCI: Suspend/resume quirks for Apple thunderbolt") +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212767 +Link: https://lore.kernel.org/r/20210520235501.917397-1-Hi-Angel@yandex.ru +Signed-off-by: Konstantin Kharlamov +Signed-off-by: Bjorn Helgaas +Reviewed-by: Lukas Wunner +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/quirks.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include /* isa_dma_bridge_buggy */ + #include "pci.h" +@@ -3667,6 +3668,16 @@ static void quirk_apple_poweroff_thunder + return; + if (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) + return; ++ ++ /* ++ * SXIO/SXFP/SXLF turns off power to the Thunderbolt controller. ++ * We don't know how to turn it back on again, but firmware does, ++ * so we can only use SXIO/SXFP/SXLF if we're suspending via ++ * firmware. ++ */ ++ if (!pm_suspend_via_firmware()) ++ return; ++ + bridge = ACPI_HANDLE(&dev->dev); + if (!bridge) + return; diff --git a/queue-5.10/power-supply-ab8500-fix-an-old-bug.patch b/queue-5.10/power-supply-ab8500-fix-an-old-bug.patch new file mode 100644 index 00000000000..192b2b2c549 --- /dev/null +++ b/queue-5.10/power-supply-ab8500-fix-an-old-bug.patch @@ -0,0 +1,38 @@ +From f1c74a6c07e76fcb31a4bcc1f437c4361a2674ce Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Sun, 27 Jun 2021 01:47:49 +0200 +Subject: power: supply: ab8500: Fix an old bug + +From: Linus Walleij + +commit f1c74a6c07e76fcb31a4bcc1f437c4361a2674ce upstream. + +Trying to get the AB8500 charging driver working I ran into a bit +of bitrot: we haven't used the driver for a while so errors in +refactorings won't be noticed. + +This one is pretty self evident: use argument to the macro or we +end up with a random pointer to something else. + +Cc: stable@vger.kernel.org +Cc: Krzysztof Kozlowski +Cc: Marcus Cooper +Fixes: 297d716f6260 ("power_supply: Change ownership from driver to core") +Signed-off-by: Linus Walleij +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/mfd/abx500/ux500_chargalg.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/mfd/abx500/ux500_chargalg.h ++++ b/include/linux/mfd/abx500/ux500_chargalg.h +@@ -15,7 +15,7 @@ + * - POWER_SUPPLY_TYPE_USB, + * because only them store as drv_data pointer to struct ux500_charger. + */ +-#define psy_to_ux500_charger(x) power_supply_get_drvdata(psy) ++#define psy_to_ux500_charger(x) power_supply_get_drvdata(x) + + /* Forward declaration */ + struct ux500_charger; diff --git a/queue-5.10/qemu_fw_cfg-make-fw_cfg_rev_attr-a-proper-kobj_attribute.patch b/queue-5.10/qemu_fw_cfg-make-fw_cfg_rev_attr-a-proper-kobj_attribute.patch new file mode 100644 index 00000000000..74648c15480 --- /dev/null +++ b/queue-5.10/qemu_fw_cfg-make-fw_cfg_rev_attr-a-proper-kobj_attribute.patch @@ -0,0 +1,65 @@ +From fca41af18e10318e4de090db47d9fa7169e1bf2f Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Thu, 11 Feb 2021 12:42:58 -0700 +Subject: qemu_fw_cfg: Make fw_cfg_rev_attr a proper kobj_attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nathan Chancellor + +commit fca41af18e10318e4de090db47d9fa7169e1bf2f upstream. + +fw_cfg_showrev() is called by an indirect call in kobj_attr_show(), +which violates clang's CFI checking because fw_cfg_showrev()'s second +parameter is 'struct attribute', whereas the ->show() member of 'struct +kobj_structure' expects the second parameter to be of type 'struct +kobj_attribute'. + +$ cat /sys/firmware/qemu_fw_cfg/rev +3 + +$ dmesg | grep "CFI failure" +[ 26.016832] CFI failure (target: fw_cfg_showrev+0x0/0x8): + +Fix this by converting fw_cfg_rev_attr to 'struct kobj_attribute' where +this would have been caught automatically by the incompatible pointer +types compiler warning. Update fw_cfg_showrev() accordingly. + +Fixes: 75f3e8e47f38 ("firmware: introduce sysfs driver for QEMU's fw_cfg device") +Link: https://github.com/ClangBuiltLinux/linux/issues/1299 +Signed-off-by: Nathan Chancellor +Reviewed-by: Sami Tolvanen +Tested-by: Sedat Dilek +Reviewed-by: Sami Tolvanen +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Kees Cook +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210211194258.4137998-1-nathan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/qemu_fw_cfg.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/firmware/qemu_fw_cfg.c ++++ b/drivers/firmware/qemu_fw_cfg.c +@@ -299,15 +299,13 @@ static int fw_cfg_do_platform_probe(stru + return 0; + } + +-static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf) ++static ssize_t fw_cfg_showrev(struct kobject *k, struct kobj_attribute *a, ++ char *buf) + { + return sprintf(buf, "%u\n", fw_cfg_rev); + } + +-static const struct { +- struct attribute attr; +- ssize_t (*show)(struct kobject *k, struct attribute *a, char *buf); +-} fw_cfg_rev_attr = { ++static const struct kobj_attribute fw_cfg_rev_attr = { + .attr = { .name = "rev", .mode = S_IRUSR }, + .show = fw_cfg_showrev, + }; diff --git a/queue-5.10/rq-qos-fix-missed-wake-ups-in-rq_qos_throttle-try-two.patch b/queue-5.10/rq-qos-fix-missed-wake-ups-in-rq_qos_throttle-try-two.patch new file mode 100644 index 00000000000..766171efa28 --- /dev/null +++ b/queue-5.10/rq-qos-fix-missed-wake-ups-in-rq_qos_throttle-try-two.patch @@ -0,0 +1,98 @@ +From 11c7aa0ddea8611007768d3e6b58d45dc60a19e1 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 7 Jun 2021 13:26:13 +0200 +Subject: rq-qos: fix missed wake-ups in rq_qos_throttle try two + +From: Jan Kara + +commit 11c7aa0ddea8611007768d3e6b58d45dc60a19e1 upstream. + +Commit 545fbd0775ba ("rq-qos: fix missed wake-ups in rq_qos_throttle") +tried to fix a problem that a process could be sleeping in rq_qos_wait() +without anyone to wake it up. However the fix is not complete and the +following can still happen: + +CPU1 (waiter1) CPU2 (waiter2) CPU3 (waker) +rq_qos_wait() rq_qos_wait() + acquire_inflight_cb() -> fails + acquire_inflight_cb() -> fails + + completes IOs, inflight + decreased + prepare_to_wait_exclusive() + prepare_to_wait_exclusive() + has_sleeper = !wq_has_single_sleeper() -> true as there are two sleepers + has_sleeper = !wq_has_single_sleeper() -> true + io_schedule() io_schedule() + +Deadlock as now there's nobody to wakeup the two waiters. The logic +automatically blocking when there are already sleepers is really subtle +and the only way to make it work reliably is that we check whether there +are some waiters in the queue when adding ourselves there. That way, we +are guaranteed that at least the first process to enter the wait queue +will recheck the waiting condition before going to sleep and thus +guarantee forward progress. + +Fixes: 545fbd0775ba ("rq-qos: fix missed wake-ups in rq_qos_throttle") +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20210607112613.25344-1-jack@suse.cz +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-rq-qos.c | 4 ++-- + include/linux/wait.h | 2 +- + kernel/sched/wait.c | 9 +++++++-- + 3 files changed, 10 insertions(+), 5 deletions(-) + +--- a/block/blk-rq-qos.c ++++ b/block/blk-rq-qos.c +@@ -266,8 +266,8 @@ void rq_qos_wait(struct rq_wait *rqw, vo + if (!has_sleeper && acquire_inflight_cb(rqw, private_data)) + return; + +- prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE); +- has_sleeper = !wq_has_single_sleeper(&rqw->wait); ++ has_sleeper = !prepare_to_wait_exclusive(&rqw->wait, &data.wq, ++ TASK_UNINTERRUPTIBLE); + do { + /* The memory barrier in set_task_state saves us here. */ + if (data.got_token) +--- a/include/linux/wait.h ++++ b/include/linux/wait.h +@@ -1126,7 +1126,7 @@ do { \ + * Waitqueues which are removed from the waitqueue_head at wakeup time + */ + void prepare_to_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); +-void prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); ++bool prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); + long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); + void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); + long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout); +--- a/kernel/sched/wait.c ++++ b/kernel/sched/wait.c +@@ -249,17 +249,22 @@ prepare_to_wait(struct wait_queue_head * + } + EXPORT_SYMBOL(prepare_to_wait); + +-void ++/* Returns true if we are the first waiter in the queue, false otherwise. */ ++bool + prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state) + { + unsigned long flags; ++ bool was_empty = false; + + wq_entry->flags |= WQ_FLAG_EXCLUSIVE; + spin_lock_irqsave(&wq_head->lock, flags); +- if (list_empty(&wq_entry->entry)) ++ if (list_empty(&wq_entry->entry)) { ++ was_empty = list_empty(&wq_head->head); + __add_wait_queue_entry_tail(wq_head, wq_entry); ++ } + set_current_state(state); + spin_unlock_irqrestore(&wq_head->lock, flags); ++ return was_empty; + } + EXPORT_SYMBOL(prepare_to_wait_exclusive); + diff --git a/queue-5.10/selftests-lkdtm-fix-expected-text-for-cr4-pinning.patch b/queue-5.10/selftests-lkdtm-fix-expected-text-for-cr4-pinning.patch new file mode 100644 index 00000000000..a7893877fe4 --- /dev/null +++ b/queue-5.10/selftests-lkdtm-fix-expected-text-for-cr4-pinning.patch @@ -0,0 +1,31 @@ +From c2eb472bbe25b3f360990f23b293b3fbadfa4bc0 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 23 Jun 2021 13:39:29 -0700 +Subject: selftests/lkdtm: Fix expected text for CR4 pinning + +From: Kees Cook + +commit c2eb472bbe25b3f360990f23b293b3fbadfa4bc0 upstream. + +The error text for CR4 pinning changed. Update the test to match. + +Fixes: a13b9d0b9721 ("x86/cpu: Use pinning mask for CR4 bits needing to be 0") +Cc: stable@vger.kernel.org +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20210623203936.3151093-3-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/lkdtm/tests.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/testing/selftests/lkdtm/tests.txt ++++ b/tools/testing/selftests/lkdtm/tests.txt +@@ -11,7 +11,7 @@ CORRUPT_LIST_ADD list_add corruption + CORRUPT_LIST_DEL list_del corruption + STACK_GUARD_PAGE_LEADING + STACK_GUARD_PAGE_TRAILING +-UNSET_SMEP CR4 bits went missing ++UNSET_SMEP pinned CR4 bits changed: + DOUBLE_FAULT + CORRUPT_PAC + UNALIGNED_LOAD_STORE_WRITE diff --git a/queue-5.10/seq_buf-fix-overflow-in-seq_buf_putmem_hex.patch b/queue-5.10/seq_buf-fix-overflow-in-seq_buf_putmem_hex.patch new file mode 100644 index 00000000000..11b16112278 --- /dev/null +++ b/queue-5.10/seq_buf-fix-overflow-in-seq_buf_putmem_hex.patch @@ -0,0 +1,41 @@ +From d3b16034a24a112bb83aeb669ac5b9b01f744bb7 Mon Sep 17 00:00:00 2001 +From: Yun Zhou +Date: Sat, 26 Jun 2021 11:21:55 +0800 +Subject: seq_buf: Fix overflow in seq_buf_putmem_hex() + +From: Yun Zhou + +commit d3b16034a24a112bb83aeb669ac5b9b01f744bb7 upstream. + +There's two variables being increased in that loop (i and j), and i +follows the raw data, and j follows what is being written into the buffer. +We should compare 'i' to MAX_MEMHEX_BYTES or compare 'j' to HEX_CHARS. +Otherwise, if 'j' goes bigger than HEX_CHARS, it will overflow the +destination buffer. + +Link: https://lore.kernel.org/lkml/20210625122453.5e2fe304@oasis.local.home/ +Link: https://lkml.kernel.org/r/20210626032156.47889-1-yun.zhou@windriver.com + +Cc: stable@vger.kernel.org +Fixes: 5e3ca0ec76fce ("ftrace: introduce the "hex" output method") +Signed-off-by: Yun Zhou +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + lib/seq_buf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/lib/seq_buf.c ++++ b/lib/seq_buf.c +@@ -229,8 +229,10 @@ int seq_buf_putmem_hex(struct seq_buf *s + + WARN_ON(s->size == 0); + ++ BUILD_BUG_ON(MAX_MEMHEX_BYTES * 2 >= HEX_CHARS); ++ + while (len) { +- start_len = min(len, HEX_CHARS - 1); ++ start_len = min(len, MAX_MEMHEX_BYTES); + #ifdef __BIG_ENDIAN + for (i = 0, j = 0; i < start_len; i++) { + #else diff --git a/queue-5.10/series b/queue-5.10/series index e110cc3fdc8..c89f1e436a3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -172,3 +172,30 @@ arm64-tlb-fix-the-ttl-value-of-tlb_get_level.patch cpu-hotplug-cure-the-cpusets-trainwreck.patch clocksource-arm_arch_timer-improve-allwinner-a64-timer-workaround.patch fpga-stratix10-soc-add-missing-fpga_mgr_free-call.patch +asoc-tegra-set-driver_name-tegra-for-all-machine-drivers.patch +i40e-fix-ptp-on-5gb-links.patch +qemu_fw_cfg-make-fw_cfg_rev_attr-a-proper-kobj_attribute.patch +ipmi-watchdog-stop-watchdog-timer-when-the-current-action-is-none.patch +xfrm-policy-read-seqcount-outside-of-rcu-read-side-in-xfrm_policy_lookup_bytype.patch +thermal-drivers-int340x-processor_thermal-fix-tcc-setting.patch +ubifs-fix-races-between-xattr_-set-get-and-listxattr-operations.patch +power-supply-ab8500-fix-an-old-bug.patch +mfd-syscon-free-the-allocated-name-field-of-struct-regmap_config.patch +nvmem-core-add-a-missing-of_node_put.patch +lkdtm-bugs-xfail-unaligned_load_store_write.patch +selftests-lkdtm-fix-expected-text-for-cr4-pinning.patch +extcon-intel-mrfld-sync-hardware-and-software-state-on-init.patch +seq_buf-fix-overflow-in-seq_buf_putmem_hex.patch +rq-qos-fix-missed-wake-ups-in-rq_qos_throttle-try-two.patch +tracing-simplify-fix-saved_tgids-logic.patch +tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch +ipack-carriers-tpci200-fix-a-double-free-in-tpci200_pci_probe.patch +coresight-propagate-symlink-failure.patch +coresight-tmc-etf-fix-global-out-of-bounds-in-tmc_update_etf_buffer.patch +dm-zoned-check-zone-capacity.patch +dm-writecache-flush-origin-device-when-writing-and-cache-is-full.patch +dm-btree-remove-assign-new_root-only-when-removal-succeeds.patch +pci-leave-apple-thunderbolt-controllers-on-for-s2idle-or-standby.patch +pci-aardvark-fix-checking-for-pio-non-posted-request.patch +pci-aardvark-implement-workaround-for-the-readback-value-of-vend_id.patch +media-subdev-disallow-ioctl-for-saa6588-davinci.patch diff --git a/queue-5.10/thermal-drivers-int340x-processor_thermal-fix-tcc-setting.patch b/queue-5.10/thermal-drivers-int340x-processor_thermal-fix-tcc-setting.patch new file mode 100644 index 00000000000..d2dbe6311da --- /dev/null +++ b/queue-5.10/thermal-drivers-int340x-processor_thermal-fix-tcc-setting.patch @@ -0,0 +1,89 @@ +From fe6a6de6692e7f7159c1ff42b07ecd737df712b4 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Mon, 28 Jun 2021 14:58:03 -0700 +Subject: thermal/drivers/int340x/processor_thermal: Fix tcc setting + +From: Srinivas Pandruvada + +commit fe6a6de6692e7f7159c1ff42b07ecd737df712b4 upstream. + +The following fixes are done for tcc sysfs interface: +- TCC is 6 bits only from bit 29-24 +- TCC of 0 is valid +- When BIT(31) is set, this register is read only +- Check for invalid tcc value +- Error for negative values + +Fixes: fdf4f2fb8e899 ("drivers: thermal: processor_thermal_device: Export sysfs interface for TCC offset") +Signed-off-by: Srinivas Pandruvada +Cc: stable@vger.kernel.org +Acked-by: Zhang Rui +Signed-off-by: Daniel Lezcano +Link: https://lore.kernel.org/r/20210628215803.75038-1-srinivas.pandruvada@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thermal/intel/int340x_thermal/processor_thermal_device.c | 20 ++++++---- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c ++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +@@ -156,24 +156,27 @@ static ssize_t tcc_offset_degree_celsius + if (err) + return err; + +- val = (val >> 24) & 0xff; ++ val = (val >> 24) & 0x3f; + return sprintf(buf, "%d\n", (int)val); + } + +-static int tcc_offset_update(int tcc) ++static int tcc_offset_update(unsigned int tcc) + { + u64 val; + int err; + +- if (!tcc) ++ if (tcc > 63) + return -EINVAL; + + err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); + if (err) + return err; + +- val &= ~GENMASK_ULL(31, 24); +- val |= (tcc & 0xff) << 24; ++ if (val & BIT(31)) ++ return -EPERM; ++ ++ val &= ~GENMASK_ULL(29, 24); ++ val |= (tcc & 0x3f) << 24; + + err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val); + if (err) +@@ -182,14 +185,15 @@ static int tcc_offset_update(int tcc) + return 0; + } + +-static int tcc_offset_save; ++static unsigned int tcc_offset_save; + + static ssize_t tcc_offset_degree_celsius_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) + { ++ unsigned int tcc; + u64 val; +- int tcc, err; ++ int err; + + err = rdmsrl_safe(MSR_PLATFORM_INFO, &val); + if (err) +@@ -198,7 +202,7 @@ static ssize_t tcc_offset_degree_celsius + if (!(val & BIT(30))) + return -EACCES; + +- if (kstrtoint(buf, 0, &tcc)) ++ if (kstrtouint(buf, 0, &tcc)) + return -EINVAL; + + err = tcc_offset_update(tcc); diff --git a/queue-5.10/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch b/queue-5.10/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch new file mode 100644 index 00000000000..2a97d4a728c --- /dev/null +++ b/queue-5.10/tracing-resize-tgid_map-to-pid_max-not-pid_max_default.patch @@ -0,0 +1,176 @@ +From 4030a6e6a6a4a42ff8c18414c9e0c93e24cc70b8 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Thu, 1 Jul 2021 10:24:07 -0700 +Subject: tracing: Resize tgid_map to pid_max, not PID_MAX_DEFAULT + +From: Paul Burton + +commit 4030a6e6a6a4a42ff8c18414c9e0c93e24cc70b8 upstream. + +Currently tgid_map is sized at PID_MAX_DEFAULT entries, which means that +on systems where pid_max is configured higher than PID_MAX_DEFAULT the +ftrace record-tgid option doesn't work so well. Any tasks with PIDs +higher than PID_MAX_DEFAULT are simply not recorded in tgid_map, and +don't show up in the saved_tgids file. + +In particular since systemd v243 & above configure pid_max to its +highest possible 1<<22 value by default on 64 bit systems this renders +the record-tgids option of little use. + +Increase the size of tgid_map to the configured pid_max instead, +allowing it to cover the full range of PIDs up to the maximum value of +PID_MAX_LIMIT if the system is configured that way. + +On 64 bit systems with pid_max == PID_MAX_LIMIT this will increase the +size of tgid_map from 256KiB to 16MiB. Whilst this 64x increase in +memory overhead sounds significant 64 bit systems are presumably best +placed to accommodate it, and since tgid_map is only allocated when the +record-tgid option is actually used presumably the user would rather it +spends sufficient memory to actually record the tgids they expect. + +The size of tgid_map could also increase for CONFIG_BASE_SMALL=y +configurations, but these seem unlikely to be systems upon which people +are both configuring a large pid_max and running ftrace with record-tgid +anyway. + +Of note is that we only allocate tgid_map once, the first time that the +record-tgid option is enabled. Therefore its size is only set once, to +the value of pid_max at the time the record-tgid option is first +enabled. If a user increases pid_max after that point, the saved_tgids +file will not contain entries for any tasks with pids beyond the earlier +value of pid_max. + +Link: https://lkml.kernel.org/r/20210701172407.889626-2-paulburton@google.com + +Fixes: d914ba37d714 ("tracing: Add support for recording tgid of tasks") +Cc: Ingo Molnar +Cc: Joel Fernandes +Cc: +Signed-off-by: Paul Burton +[ Fixed comment coding style ] +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 63 ++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 47 insertions(+), 16 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -2181,8 +2181,15 @@ void tracing_reset_all_online_cpus(void) + } + } + ++/* ++ * The tgid_map array maps from pid to tgid; i.e. the value stored at index i ++ * is the tgid last observed corresponding to pid=i. ++ */ + static int *tgid_map; + ++/* The maximum valid index into tgid_map. */ ++static size_t tgid_map_max; ++ + #define SAVED_CMDLINES_DEFAULT 128 + #define NO_CMDLINE_MAP UINT_MAX + static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED; +@@ -2455,24 +2462,41 @@ void trace_find_cmdline(int pid, char co + preempt_enable(); + } + ++static int *trace_find_tgid_ptr(int pid) ++{ ++ /* ++ * Pairs with the smp_store_release in set_tracer_flag() to ensure that ++ * if we observe a non-NULL tgid_map then we also observe the correct ++ * tgid_map_max. ++ */ ++ int *map = smp_load_acquire(&tgid_map); ++ ++ if (unlikely(!map || pid > tgid_map_max)) ++ return NULL; ++ ++ return &map[pid]; ++} ++ + int trace_find_tgid(int pid) + { +- if (unlikely(!tgid_map || !pid || pid > PID_MAX_DEFAULT)) +- return 0; ++ int *ptr = trace_find_tgid_ptr(pid); + +- return tgid_map[pid]; ++ return ptr ? *ptr : 0; + } + + static int trace_save_tgid(struct task_struct *tsk) + { ++ int *ptr; ++ + /* treat recording of idle task as a success */ + if (!tsk->pid) + return 1; + +- if (unlikely(!tgid_map || tsk->pid > PID_MAX_DEFAULT)) ++ ptr = trace_find_tgid_ptr(tsk->pid); ++ if (!ptr) + return 0; + +- tgid_map[tsk->pid] = tsk->tgid; ++ *ptr = tsk->tgid; + return 1; + } + +@@ -4847,6 +4871,8 @@ int trace_keep_overwrite(struct tracer * + + int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled) + { ++ int *map; ++ + if ((mask == TRACE_ITER_RECORD_TGID) || + (mask == TRACE_ITER_RECORD_CMD)) + lockdep_assert_held(&event_mutex); +@@ -4869,10 +4895,19 @@ int set_tracer_flag(struct trace_array * + trace_event_enable_cmd_record(enabled); + + if (mask == TRACE_ITER_RECORD_TGID) { +- if (!tgid_map) +- tgid_map = kvcalloc(PID_MAX_DEFAULT + 1, +- sizeof(*tgid_map), +- GFP_KERNEL); ++ if (!tgid_map) { ++ tgid_map_max = pid_max; ++ map = kvcalloc(tgid_map_max + 1, sizeof(*tgid_map), ++ GFP_KERNEL); ++ ++ /* ++ * Pairs with smp_load_acquire() in ++ * trace_find_tgid_ptr() to ensure that if it observes ++ * the tgid_map we just allocated then it also observes ++ * the corresponding tgid_map_max value. ++ */ ++ smp_store_release(&tgid_map, map); ++ } + if (!tgid_map) { + tr->trace_flags &= ~TRACE_ITER_RECORD_TGID; + return -ENOMEM; +@@ -5286,18 +5321,14 @@ static void *saved_tgids_next(struct seq + { + int pid = ++(*pos); + +- if (pid > PID_MAX_DEFAULT) +- return NULL; +- +- return &tgid_map[pid]; ++ return trace_find_tgid_ptr(pid); + } + + static void *saved_tgids_start(struct seq_file *m, loff_t *pos) + { +- if (!tgid_map || *pos > PID_MAX_DEFAULT) +- return NULL; ++ int pid = *pos; + +- return &tgid_map[*pos]; ++ return trace_find_tgid_ptr(pid); + } + + static void saved_tgids_stop(struct seq_file *m, void *v) diff --git a/queue-5.10/tracing-simplify-fix-saved_tgids-logic.patch b/queue-5.10/tracing-simplify-fix-saved_tgids-logic.patch new file mode 100644 index 00000000000..ab5de7e7b9d --- /dev/null +++ b/queue-5.10/tracing-simplify-fix-saved_tgids-logic.patch @@ -0,0 +1,111 @@ +From b81b3e959adb107cd5b36c7dc5ba1364bbd31eb2 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Tue, 29 Jun 2021 17:34:05 -0700 +Subject: tracing: Simplify & fix saved_tgids logic + +From: Paul Burton + +commit b81b3e959adb107cd5b36c7dc5ba1364bbd31eb2 upstream. + +The tgid_map array records a mapping from pid to tgid, where the index +of an entry within the array is the pid & the value stored at that index +is the tgid. + +The saved_tgids_next() function iterates over pointers into the tgid_map +array & dereferences the pointers which results in the tgid, but then it +passes that dereferenced value to trace_find_tgid() which treats it as a +pid & does a further lookup within the tgid_map array. It seems likely +that the intent here was to skip over entries in tgid_map for which the +recorded tgid is zero, but instead we end up skipping over entries for +which the thread group leader hasn't yet had its own tgid recorded in +tgid_map. + +A minimal fix would be to remove the call to trace_find_tgid, turning: + + if (trace_find_tgid(*ptr)) + +into: + + if (*ptr) + +..but it seems like this logic can be much simpler if we simply let +seq_read() iterate over the whole tgid_map array & filter out empty +entries by returning SEQ_SKIP from saved_tgids_show(). Here we take that +approach, removing the incorrect logic here entirely. + +Link: https://lkml.kernel.org/r/20210630003406.4013668-1-paulburton@google.com + +Fixes: d914ba37d714 ("tracing: Add support for recording tgid of tasks") +Cc: Ingo Molnar +Cc: Joel Fernandes +Cc: +Signed-off-by: Paul Burton +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 38 +++++++++++++------------------------- + 1 file changed, 13 insertions(+), 25 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -5284,37 +5284,20 @@ static const struct file_operations trac + + static void *saved_tgids_next(struct seq_file *m, void *v, loff_t *pos) + { +- int *ptr = v; ++ int pid = ++(*pos); + +- if (*pos || m->count) +- ptr++; +- +- (*pos)++; +- +- for (; ptr <= &tgid_map[PID_MAX_DEFAULT]; ptr++) { +- if (trace_find_tgid(*ptr)) +- return ptr; +- } ++ if (pid > PID_MAX_DEFAULT) ++ return NULL; + +- return NULL; ++ return &tgid_map[pid]; + } + + static void *saved_tgids_start(struct seq_file *m, loff_t *pos) + { +- void *v; +- loff_t l = 0; +- +- if (!tgid_map) ++ if (!tgid_map || *pos > PID_MAX_DEFAULT) + return NULL; + +- v = &tgid_map[0]; +- while (l <= *pos) { +- v = saved_tgids_next(m, v, &l); +- if (!v) +- return NULL; +- } +- +- return v; ++ return &tgid_map[*pos]; + } + + static void saved_tgids_stop(struct seq_file *m, void *v) +@@ -5323,9 +5306,14 @@ static void saved_tgids_stop(struct seq_ + + static int saved_tgids_show(struct seq_file *m, void *v) + { +- int pid = (int *)v - tgid_map; ++ int *entry = (int *)v; ++ int pid = entry - tgid_map; ++ int tgid = *entry; ++ ++ if (tgid == 0) ++ return SEQ_SKIP; + +- seq_printf(m, "%d %d\n", pid, trace_find_tgid(pid)); ++ seq_printf(m, "%d %d\n", pid, tgid); + return 0; + } + diff --git a/queue-5.10/ubifs-fix-races-between-xattr_-set-get-and-listxattr-operations.patch b/queue-5.10/ubifs-fix-races-between-xattr_-set-get-and-listxattr-operations.patch new file mode 100644 index 00000000000..da922afdeee --- /dev/null +++ b/queue-5.10/ubifs-fix-races-between-xattr_-set-get-and-listxattr-operations.patch @@ -0,0 +1,220 @@ +From f4e3634a3b642225a530c292fdb1e8a4007507f5 Mon Sep 17 00:00:00 2001 +From: Zhihao Cheng +Date: Mon, 31 May 2021 20:52:09 +0800 +Subject: ubifs: Fix races between xattr_{set|get} and listxattr operations + +From: Zhihao Cheng + +commit f4e3634a3b642225a530c292fdb1e8a4007507f5 upstream. + +UBIFS may occur some problems with concurrent xattr_{set|get} and +listxattr operations, such as assertion failure, memory corruption, +stale xattr value[1]. + +Fix it by importing a new rw-lock in @ubifs_inode to serilize write +operations on xattr, concurrent read operations are still effective, +just like ext4. + +[1] https://lore.kernel.org/linux-mtd/20200630130438.141649-1-houtao1@huawei.com + +Fixes: 1e51764a3c2ac05a23 ("UBIFS: add new flash file system") +Cc: stable@vger.kernel.org # v2.6+ +Signed-off-by: Zhihao Cheng +Reviewed-by: Sascha Hauer +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman +--- + fs/ubifs/super.c | 1 + + fs/ubifs/ubifs.h | 2 ++ + fs/ubifs/xattr.c | 44 +++++++++++++++++++++++++++++++++----------- + 3 files changed, 36 insertions(+), 11 deletions(-) + +--- a/fs/ubifs/super.c ++++ b/fs/ubifs/super.c +@@ -275,6 +275,7 @@ static struct inode *ubifs_alloc_inode(s + memset((void *)ui + sizeof(struct inode), 0, + sizeof(struct ubifs_inode) - sizeof(struct inode)); + mutex_init(&ui->ui_mutex); ++ init_rwsem(&ui->xattr_sem); + spin_lock_init(&ui->ui_lock); + return &ui->vfs_inode; + }; +--- a/fs/ubifs/ubifs.h ++++ b/fs/ubifs/ubifs.h +@@ -356,6 +356,7 @@ struct ubifs_gced_idx_leb { + * @ui_mutex: serializes inode write-back with the rest of VFS operations, + * serializes "clean <-> dirty" state changes, serializes bulk-read, + * protects @dirty, @bulk_read, @ui_size, and @xattr_size ++ * @xattr_sem: serilizes write operations (remove|set|create) on xattr + * @ui_lock: protects @synced_i_size + * @synced_i_size: synchronized size of inode, i.e. the value of inode size + * currently stored on the flash; used only for regular file +@@ -409,6 +410,7 @@ struct ubifs_inode { + unsigned int bulk_read:1; + unsigned int compr_type:2; + struct mutex ui_mutex; ++ struct rw_semaphore xattr_sem; + spinlock_t ui_lock; + loff_t synced_i_size; + loff_t ui_size; +--- a/fs/ubifs/xattr.c ++++ b/fs/ubifs/xattr.c +@@ -285,6 +285,7 @@ int ubifs_xattr_set(struct inode *host, + if (!xent) + return -ENOMEM; + ++ down_write(&ubifs_inode(host)->xattr_sem); + /* + * The extended attribute entries are stored in LNC, so multiple + * look-ups do not involve reading the flash. +@@ -319,6 +320,7 @@ int ubifs_xattr_set(struct inode *host, + iput(inode); + + out_free: ++ up_write(&ubifs_inode(host)->xattr_sem); + kfree(xent); + return err; + } +@@ -341,18 +343,19 @@ ssize_t ubifs_xattr_get(struct inode *ho + if (!xent) + return -ENOMEM; + ++ down_read(&ubifs_inode(host)->xattr_sem); + xent_key_init(c, &key, host->i_ino, &nm); + err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); + if (err) { + if (err == -ENOENT) + err = -ENODATA; +- goto out_unlock; ++ goto out_cleanup; + } + + inode = iget_xattr(c, le64_to_cpu(xent->inum)); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); +- goto out_unlock; ++ goto out_cleanup; + } + + ui = ubifs_inode(inode); +@@ -374,7 +377,8 @@ ssize_t ubifs_xattr_get(struct inode *ho + out_iput: + mutex_unlock(&ui->ui_mutex); + iput(inode); +-out_unlock: ++out_cleanup: ++ up_read(&ubifs_inode(host)->xattr_sem); + kfree(xent); + return err; + } +@@ -406,16 +410,21 @@ ssize_t ubifs_listxattr(struct dentry *d + dbg_gen("ino %lu ('%pd'), buffer size %zd", host->i_ino, + dentry, size); + ++ down_read(&host_ui->xattr_sem); + len = host_ui->xattr_names + host_ui->xattr_cnt; +- if (!buffer) ++ if (!buffer) { + /* + * We should return the minimum buffer size which will fit a + * null-terminated list of all the extended attribute names. + */ +- return len; ++ err = len; ++ goto out_err; ++ } + +- if (len > size) +- return -ERANGE; ++ if (len > size) { ++ err = -ERANGE; ++ goto out_err; ++ } + + lowest_xent_key(c, &key, host->i_ino); + while (1) { +@@ -437,8 +446,9 @@ ssize_t ubifs_listxattr(struct dentry *d + pxent = xent; + key_read(c, &xent->key, &key); + } +- + kfree(pxent); ++ up_read(&host_ui->xattr_sem); ++ + if (err != -ENOENT) { + ubifs_err(c, "cannot find next direntry, error %d", err); + return err; +@@ -446,6 +456,10 @@ ssize_t ubifs_listxattr(struct dentry *d + + ubifs_assert(c, written <= size); + return written; ++ ++out_err: ++ up_read(&host_ui->xattr_sem); ++ return err; + } + + static int remove_xattr(struct ubifs_info *c, struct inode *host, +@@ -504,6 +518,7 @@ int ubifs_purge_xattrs(struct inode *hos + ubifs_warn(c, "inode %lu has too many xattrs, doing a non-atomic deletion", + host->i_ino); + ++ down_write(&ubifs_inode(host)->xattr_sem); + lowest_xent_key(c, &key, host->i_ino); + while (1) { + xent = ubifs_tnc_next_ent(c, &key, &nm); +@@ -523,7 +538,7 @@ int ubifs_purge_xattrs(struct inode *hos + ubifs_ro_mode(c, err); + kfree(pxent); + kfree(xent); +- return err; ++ goto out_err; + } + + ubifs_assert(c, ubifs_inode(xino)->xattr); +@@ -535,7 +550,7 @@ int ubifs_purge_xattrs(struct inode *hos + kfree(xent); + iput(xino); + ubifs_err(c, "cannot remove xattr, error %d", err); +- return err; ++ goto out_err; + } + + iput(xino); +@@ -544,14 +559,19 @@ int ubifs_purge_xattrs(struct inode *hos + pxent = xent; + key_read(c, &xent->key, &key); + } +- + kfree(pxent); ++ up_write(&ubifs_inode(host)->xattr_sem); ++ + if (err != -ENOENT) { + ubifs_err(c, "cannot find next direntry, error %d", err); + return err; + } + + return 0; ++ ++out_err: ++ up_write(&ubifs_inode(host)->xattr_sem); ++ return err; + } + + /** +@@ -594,6 +614,7 @@ static int ubifs_xattr_remove(struct ino + if (!xent) + return -ENOMEM; + ++ down_write(&ubifs_inode(host)->xattr_sem); + xent_key_init(c, &key, host->i_ino, &nm); + err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); + if (err) { +@@ -618,6 +639,7 @@ static int ubifs_xattr_remove(struct ino + iput(inode); + + out_free: ++ up_write(&ubifs_inode(host)->xattr_sem); + kfree(xent); + return err; + } diff --git a/queue-5.10/xfrm-policy-read-seqcount-outside-of-rcu-read-side-in-xfrm_policy_lookup_bytype.patch b/queue-5.10/xfrm-policy-read-seqcount-outside-of-rcu-read-side-in-xfrm_policy_lookup_bytype.patch new file mode 100644 index 00000000000..853a74ac058 --- /dev/null +++ b/queue-5.10/xfrm-policy-read-seqcount-outside-of-rcu-read-side-in-xfrm_policy_lookup_bytype.patch @@ -0,0 +1,103 @@ +From d7b0408934c749f546b01f2b33d07421a49b6f3e Mon Sep 17 00:00:00 2001 +From: Varad Gautam +Date: Fri, 28 May 2021 18:04:06 +0200 +Subject: xfrm: policy: Read seqcount outside of rcu-read side in xfrm_policy_lookup_bytype + +From: Varad Gautam + +commit d7b0408934c749f546b01f2b33d07421a49b6f3e upstream. + +xfrm_policy_lookup_bytype loops on seqcount mutex xfrm_policy_hash_generation +within an RCU read side critical section. Although ill advised, this is fine if +the loop is bounded. + +xfrm_policy_hash_generation wraps mutex hash_resize_mutex, which is used to +serialize writers (xfrm_hash_resize, xfrm_hash_rebuild). This is fine too. + +On PREEMPT_RT=y, the read_seqcount_begin call within xfrm_policy_lookup_bytype +emits a mutex lock/unlock for hash_resize_mutex. Mutex locking is fine, since +RCU read side critical sections are allowed to sleep with PREEMPT_RT. + +xfrm_hash_resize can, however, block on synchronize_rcu while holding +hash_resize_mutex. + +This leads to the following situation on PREEMPT_RT, where the writer is +blocked on RCU grace period expiry, while the reader is blocked on a lock held +by the writer: + +Thead 1 (xfrm_hash_resize) Thread 2 (xfrm_policy_lookup_bytype) + + rcu_read_lock(); +mutex_lock(&hash_resize_mutex); + read_seqcount_begin(&xfrm_policy_hash_generation); + mutex_lock(&hash_resize_mutex); // block +xfrm_bydst_resize(); +synchronize_rcu(); // block + + +Move the read_seqcount_begin call outside of the RCU read side critical section, +and do an rcu_read_unlock/retry if we got stale data within the critical section. + +On non-PREEMPT_RT, this shortens the time spent within RCU read side critical +section in case the seqcount needs a retry, and avoids unbounded looping. + +Fixes: 77cc278f7b20 ("xfrm: policy: Use sequence counters with associated lock") +Signed-off-by: Varad Gautam +Cc: linux-rt-users +Cc: netdev@vger.kernel.org +Cc: stable@vger.kernel.org # v4.9 +Cc: Steffen Klassert +Cc: Herbert Xu +Cc: "David S. Miller" +Cc: Jakub Kicinski +Cc: Florian Westphal +Cc: "Ahmed S. Darwish" +Signed-off-by: Steffen Klassert +Acked-by: Ahmed S. Darwish +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_policy.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -2092,12 +2092,15 @@ static struct xfrm_policy *xfrm_policy_l + if (unlikely(!daddr || !saddr)) + return NULL; + +- rcu_read_lock(); + retry: +- do { +- sequence = read_seqcount_begin(&xfrm_policy_hash_generation); +- chain = policy_hash_direct(net, daddr, saddr, family, dir); +- } while (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)); ++ sequence = read_seqcount_begin(&xfrm_policy_hash_generation); ++ rcu_read_lock(); ++ ++ chain = policy_hash_direct(net, daddr, saddr, family, dir); ++ if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)) { ++ rcu_read_unlock(); ++ goto retry; ++ } + + ret = NULL; + hlist_for_each_entry_rcu(pol, chain, bydst) { +@@ -2128,11 +2131,15 @@ static struct xfrm_policy *xfrm_policy_l + } + + skip_inexact: +- if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)) ++ if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)) { ++ rcu_read_unlock(); + goto retry; ++ } + +- if (ret && !xfrm_pol_hold_rcu(ret)) ++ if (ret && !xfrm_pol_hold_rcu(ret)) { ++ rcu_read_unlock(); + goto retry; ++ } + fail: + rcu_read_unlock(); +